@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@400;500;600;700;800&display=swap'); /* ======================================== 設計系統核心變數 4px Grid System | 主色:綠色系 ======================================== */ :root { /* ========== 色彩系統 ========== */ /* Grey Scale - 0 (最深) 到 5 (白色) */ --grey-0: #1a1a1a; /* 主要文字 */ --grey-1: #4a4a4a; /* 次要文字 */ --grey-2: #6b6b6b; /* 輔助文字 */ --grey-3: #9e9e9e; /* 禁用狀態/Placeholder */ --grey-4: #e0e0e0; /* 邊框/分隔線 */ --grey-5: #ffffff; /* 白色背景 */ /* Primary Colors - 綠色主題 */ --primary-dark: #018a6a; /* Hover/Active 深色 */ --primary-main: #01ab83; /* 主要品牌色 */ --primary-light: #33bc9a; /* 淺色變化 */ --primary-lighter: #66cdb1; /* 更淺 */ --primary-lightest: #e6f7f3; /* 背景淺色 */ /* Semantic Colors - 語意色彩 */ --color-success: #01ab83; --color-error: #dc2626; --color-warning: #f59e0b; --color-info: #3b82f6; /* Background Colors - 背景色系統 */ /* 頁面背景 (Page Background) */ --bg-page: #f8fdfb; /* 主要頁面背景 - 淺綠色調 */ /* 卡片/容器背景 (Card/Container Background) */ --bg-card: #ffffff; /* 白色卡片背景 */ --bg-card-hover: #fafafa; /* 卡片 Hover 狀態 */ /* 輔助背景 (Secondary Backgrounds) */ --bg-light: #f8fdfb; /* 淺綠色背景 (同 --bg-page) */ --bg-light-grey: #f5f5f5; /* 淺灰色背景 */ --bg-white: #ffffff; /* 白色背景 (同 --bg-card) */ /* ========== 字體系統 ========== */ /* Font Sizes */ --font-display-lg: 4rem; /* 64px - 大標題 */ --font-display: 3rem; /* 48px - 展示標題 */ --font-h1: 2.5rem; /* 40px */ --font-h2: 2rem; /* 32px */ --font-h3: 1.75rem; /* 28px */ --font-h4: 1.5rem; /* 24px */ --font-h5: 1.25rem; /* 20px */ --font-body-lg: 1.125rem; /* 18px */ --font-body: 1rem; /* 16px - 預設 */ --font-body-sm: 0.875rem; /* 14px */ --font-caption: 0.75rem; /* 12px */ --font-overline: 0.6875rem; /* 11px */ /* Line Heights */ --line-display-lg: 4.5rem; /* 72px */ --line-display: 3.5rem; /* 56px */ --line-h1: 3rem; /* 48px */ --line-h2: 2.5rem; /* 40px */ --line-h3: 2.25rem; /* 36px */ --line-h4: 2rem; /* 32px */ --line-h5: 1.75rem; /* 28px */ --line-body-lg: 1.75rem; /* 28px */ --line-body: 1.5rem; /* 24px */ --line-body-sm: 1.25rem; /* 20px */ --line-caption: 1rem; /* 16px */ --line-overline: 1rem; /* 16px */ /* Font Weights */ --weight-regular: 400; --weight-medium: 500; --weight-semibold: 600; --weight-bold: 700; --weight-extrabold: 800; /* ========== 間距系統 (4px Grid) ========== */ --spacing-xs: 8px; --spacing-sm: 16px; --spacing-md: 24px; --spacing-lg: 40px; /* ========== 圓角系統 ========== */ --radius-none: 0px; --radius-sm: 4px; --radius: 8px; /* 預設圓角 */ --radius-md: 8px; --radius-lg: 12px; --radius-xl: 16px; --radius-2xl: 20px; --radius-3xl: 24px; --radius-full: 9999px; /* Semantic Radius - 語意化圓角 */ --radius-button: 8px; --radius-card: 12px; --radius-input: 8px; --radius-dialog: 12px; --radius-popover: 8px; /* ========== 陰影系統 ========== */ --elevation-sm: 0px 4px 12px 0px rgba(1, 171, 131, 0.08); --elevation-md: 0px 8px 24px 0px rgba(1, 171, 131, 0.12); /* ========== Tailwind Semantic Token Mapping ========== */ /* 這些是為了與 Tailwind 的預設類別整合 */ --background: var(--bg-page); /* 頁面背景 */ --foreground: var(--grey-0); --card: var(--bg-card); /* 卡片背景 */ --card-foreground: var(--grey-0); --popover: var(--bg-card); /* Popover 使用卡片背景 */ --popover-foreground: var(--grey-0); --primary: var(--primary-main); --primary-hover: var(--primary-dark); --primary-active: #016b54; --primary-foreground: var(--grey-5); --secondary: var(--bg-light-grey); --secondary-foreground: var(--grey-0); --muted: var(--grey-4); --muted-foreground: var(--grey-2); --accent: var(--primary-light); --accent-foreground: var(--grey-5); --destructive: var(--color-error); --destructive-hover: #ef4444; --destructive-foreground: var(--grey-5); --success: var(--color-success); --warning: var(--color-warning); --info: var(--color-info); --border: var(--grey-4); --input: var(--grey-3); --input-background: var(--grey-5); --ring: var(--primary-main); --chart-1: var(--primary-main); --chart-2: var(--primary-light); --chart-3: var(--color-warning); --chart-4: var(--color-info); --chart-5: var(--primary-lighter); --radius: 8px; } /* ======================================== Base Styles ======================================== */ @layer base { * { @apply border-border outline-ring/50; } body { @apply bg-background text-foreground; font-family: 'Noto Sans TC', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; font-size: var(--font-body); line-height: var(--line-body); } /* 強制所有表單元素使用白色背景 */ input, textarea, select, [role="combobox"] { background-color: var(--input-background); } } /* ======================================== Typography System 只影響沒有 text-* class 的元素 ======================================== */ @layer base { h1:not([class*="text-"]):not([class*=" text-"]) { font-size: var(--font-h1); font-weight: var(--weight-bold); line-height: var(--line-h1); } h2:not([class*="text-"]):not([class*=" text-"]) { font-size: var(--font-h2); font-weight: var(--weight-semibold); line-height: var(--line-h2); } h3:not([class*="text-"]):not([class*=" text-"]) { font-size: var(--font-h3); font-weight: var(--weight-semibold); line-height: var(--line-h3); } h4:not([class*="text-"]):not([class*=" text-"]) { font-size: var(--font-h4); font-weight: var(--weight-semibold); line-height: var(--line-h4); } h5:not([class*="text-"]):not([class*=" text-"]) { font-size: var(--font-h5); font-weight: var(--weight-semibold); line-height: var(--line-h5); } p:not([class*="text-"]):not([class*=" text-"]) { font-size: var(--font-body); font-weight: var(--weight-regular); line-height: var(--line-body); } label:not([class*="text-"]):not([class*=" text-"]) { font-size: var(--font-body-sm); font-weight: var(--weight-semibold); line-height: var(--line-body-sm); } button:not([class*="text-"]):not([class*=" text-"]) { font-size: var(--font-body); font-weight: var(--weight-semibold); line-height: var(--line-body); } input:not([class*="text-"]):not([class*=" text-"]), textarea:not([class*="text-"]):not([class*=" text-"]), select:not([class*="text-"]):not([class*=" text-"]) { font-size: var(--font-body); font-weight: var(--weight-regular); line-height: var(--line-body); } } /* ======================================== Typography Utility Classes ======================================== */ /* Size Classes */ .body-lg { font-size: var(--font-body-lg); font-weight: var(--weight-regular); line-height: var(--line-body-lg); } .body-sm { font-size: var(--font-body-sm); font-weight: var(--weight-regular); line-height: var(--line-body-sm); } .caption { font-size: var(--font-caption); font-weight: var(--weight-medium); line-height: var(--line-caption); } .overline { font-size: var(--font-overline); font-weight: var(--weight-semibold); line-height: var(--line-overline); text-transform: uppercase; letter-spacing: 0.05em; } /* Color Classes */ .text-primary { color: var(--grey-0); } .text-secondary { color: var(--grey-1); } .text-tertiary { color: var(--grey-2); } .text-disabled { color: var(--grey-3); } .text-error { color: var(--color-error); } .text-success { color: var(--color-success); } .text-warning { color: var(--color-warning); } .text-info { color: var(--color-info); } .text-link { color: var(--primary-main); cursor: pointer; } .text-link:hover { color: var(--primary-dark); } /* ======================================== Button System Filled = 主要動作 | Outlined = 次要動作 ======================================== */ /* Primary Buttons */ .button-filled-primary { background-color: var(--primary-main); color: var(--grey-5); } .button-filled-primary:hover { background-color: var(--primary-dark); } .button-filled-primary:active { background-color: var(--primary-active); } .button-filled-primary:disabled { background-color: #b3e5d9; color: var(--grey-5); cursor: not-allowed; pointer-events: none; } .button-outlined-primary { border: 2px solid var(--primary-main); background-color: transparent; color: var(--grey-0); } .button-outlined-primary:hover { background-color: var(--bg-light); } .button-text-primary { background-color: transparent; color: var(--primary-main); border: none; } .button-text-primary:hover { background-color: var(--bg-light); } /* Success Buttons */ .button-filled-success { background-color: var(--color-success); color: var(--grey-5); } .button-filled-success:hover { background-color: #33bc9a; } .button-filled-success:active { background-color: #018a6a; } .button-outlined-success { border: 2px solid var(--color-success); background-color: transparent; color: var(--grey-0); } /* Info Buttons */ .button-filled-info { background-color: var(--color-info); color: var(--grey-5); } .button-filled-info:hover { background-color: #60a5fa; } .button-filled-info:active { background-color: #2563eb; } .button-outlined-info { border: 2px solid var(--color-info); background-color: transparent; color: var(--grey-0); } /* Warning Buttons */ .button-filled-warning { background-color: var(--color-warning); color: var(--grey-5); } .button-filled-warning:hover { background-color: #fbbf24; } .button-filled-warning:active { background-color: #d97706; } .button-outlined-warning { border: 2px solid var(--color-warning); background-color: transparent; color: var(--grey-0); } /* Error Buttons */ .button-filled-error { background-color: var(--color-error); color: var(--grey-5); } .button-filled-error:hover { background-color: #ef4444; } .button-filled-error:active { background-color: #b91c1c; } .button-outlined-error { border: 2px solid var(--color-error); background-color: transparent; color: var(--grey-0); } /* Icon Buttons */ .button-icon { color: var(--grey-0); border: 2px solid var(--grey-0); background-color: var(--bg-light); aspect-ratio: 1/1; display: inline-flex; align-items: center; justify-content: center; } .button-icon:hover { color: var(--primary-main); border-color: var(--primary-main); background-color: var(--bg-white); } .button-icon:active { color: var(--primary-dark); border-color: var(--primary-dark); } .button-icon:focus { border-color: var(--primary-main); box-shadow: 0 0 0 3px rgba(1, 171, 131, 0.3); } .button-icon:disabled { color: var(--grey-3); border-color: var(--grey-4); background-color: var(--bg-light-grey); cursor: not-allowed; pointer-events: none; } .button-icon-selected { color: var(--grey-5); border-color: var(--primary-main); background-color: var(--primary-main); } .button-icon-selected:hover { border-color: var(--primary-dark); background-color: var(--primary-dark); } /* ======================================== Input/Textarea System 統一使用 border-2 (Outlined style) ======================================== */ .input-default, .textarea-default { border: 2px solid var(--grey-3); background-color: var(--grey-5); color: var(--grey-0); } .input-focus, .textarea-focus { border: 2px solid var(--primary-main); background-color: var(--grey-5); color: var(--grey-0); } .input-error, .textarea-error { border: 2px solid var(--color-error); background-color: var(--grey-5); color: var(--grey-0); } .input-disabled, .textarea-disabled { border: 2px solid var(--grey-4); background-color: var(--bg-light-grey); color: var(--grey-2); cursor: not-allowed; } .input-placeholder::placeholder, .textarea-placeholder::placeholder { color: var(--grey-3); } /* ======================================== Card/Container System ======================================== */ .card-default { background-color: var(--bg-white); border: 1px solid var(--grey-4); } .card-hover:hover { background-color: var(--bg-white); border-color: var(--grey-3); } .card-light { background-color: var(--bg-light); border-color: transparent; } .card-grey { background-color: var(--bg-light-grey); border-color: transparent; } /* ======================================== Badge/Status System ======================================== */ .badge-success { background-color: var(--color-success); color: var(--grey-5); } .badge-error { background-color: var(--color-error); color: var(--grey-5); } .badge-warning { background-color: var(--color-warning); color: var(--grey-5); } .badge-info { background-color: var(--color-info); color: var(--grey-5); } .badge-neutral { background-color: var(--grey-3); color: var(--grey-5); } /* ======================================== Divider System ======================================== */ .divider-light { border-color: var(--grey-4); } .divider-medium { border-color: var(--grey-3); } .divider-dark { border-color: var(--grey-2); } /* ======================================== Animations ======================================== */ @keyframes fade-in { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: translateY(0); } } .animate-fade-in { animation: fade-in 0.6s ease-out; } /* ======================================== Rounded (Border Radius) System ======================================== */ /* 基礎圓角 */ .rounded-none { border-radius: var(--radius-none); } .rounded-sm { border-radius: var(--radius-sm); } .rounded { border-radius: var(--radius); } .rounded-md { border-radius: var(--radius-md); } .rounded-lg { border-radius: var(--radius-lg); } .rounded-xl { border-radius: var(--radius-xl); } .rounded-2xl { border-radius: var(--radius-2xl); } .rounded-3xl { border-radius: var(--radius-3xl); } .rounded-full { border-radius: var(--radius-full); } /* 上方圓角 (Top) */ .rounded-t-none { border-top-left-radius: var(--radius-none); border-top-right-radius: var(--radius-none); } .rounded-t-sm { border-top-left-radius: var(--radius-sm); border-top-right-radius: var(--radius-sm); } .rounded-t { border-top-left-radius: var(--radius); border-top-right-radius: var(--radius); } .rounded-t-md { border-top-left-radius: var(--radius-md); border-top-right-radius: var(--radius-md); } .rounded-t-lg { border-top-left-radius: var(--radius-lg); border-top-right-radius: var(--radius-lg); } .rounded-t-xl { border-top-left-radius: var(--radius-xl); border-top-right-radius: var(--radius-xl); } .rounded-t-2xl { border-top-left-radius: var(--radius-2xl); border-top-right-radius: var(--radius-2xl); } .rounded-t-3xl { border-top-left-radius: var(--radius-3xl); border-top-right-radius: var(--radius-3xl); } .rounded-t-full { border-top-left-radius: var(--radius-full); border-top-right-radius: var(--radius-full); } /* 右方圓角 (Right) */ .rounded-r-none { border-top-right-radius: var(--radius-none); border-bottom-right-radius: var(--radius-none); } .rounded-r-sm { border-top-right-radius: var(--radius-sm); border-bottom-right-radius: var(--radius-sm); } .rounded-r { border-top-right-radius: var(--radius); border-bottom-right-radius: var(--radius); } .rounded-r-md { border-top-right-radius: var(--radius-md); border-bottom-right-radius: var(--radius-md); } .rounded-r-lg { border-top-right-radius: var(--radius-lg); border-bottom-right-radius: var(--radius-lg); } .rounded-r-xl { border-top-right-radius: var(--radius-xl); border-bottom-right-radius: var(--radius-xl); } .rounded-r-2xl { border-top-right-radius: var(--radius-2xl); border-bottom-right-radius: var(--radius-2xl); } .rounded-r-3xl { border-top-right-radius: var(--radius-3xl); border-bottom-right-radius: var(--radius-3xl); } .rounded-r-full { border-top-right-radius: var(--radius-full); border-bottom-right-radius: var(--radius-full); } /* 下方圓角 (Bottom) */ .rounded-b-none { border-bottom-left-radius: var(--radius-none); border-bottom-right-radius: var(--radius-none); } .rounded-b-sm { border-bottom-left-radius: var(--radius-sm); border-bottom-right-radius: var(--radius-sm); } .rounded-b { border-bottom-left-radius: var(--radius); border-bottom-right-radius: var(--radius); } .rounded-b-md { border-bottom-left-radius: var(--radius-md); border-bottom-right-radius: var(--radius-md); } .rounded-b-lg { border-bottom-left-radius: var(--radius-lg); border-bottom-right-radius: var(--radius-lg); } .rounded-b-xl { border-bottom-left-radius: var(--radius-xl); border-bottom-right-radius: var(--radius-xl); } .rounded-b-2xl { border-bottom-left-radius: var(--radius-2xl); border-bottom-right-radius: var(--radius-2xl); } .rounded-b-3xl { border-bottom-left-radius: var(--radius-3xl); border-bottom-right-radius: var(--radius-3xl); } .rounded-b-full { border-bottom-left-radius: var(--radius-full); border-bottom-right-radius: var(--radius-full); } /* 左方圓角 (Left) */ .rounded-l-none { border-top-left-radius: var(--radius-none); border-bottom-left-radius: var(--radius-none); } .rounded-l-sm { border-top-left-radius: var(--radius-sm); border-bottom-left-radius: var(--radius-sm); } .rounded-l { border-top-left-radius: var(--radius); border-bottom-left-radius: var(--radius); } .rounded-l-md { border-top-left-radius: var(--radius-md); border-bottom-left-radius: var(--radius-md); } .rounded-l-lg { border-top-left-radius: var(--radius-lg); border-bottom-left-radius: var(--radius-lg); } .rounded-l-xl { border-top-left-radius: var(--radius-xl); border-bottom-left-radius: var(--radius-xl); } .rounded-l-2xl { border-top-left-radius: var(--radius-2xl); border-bottom-left-radius: var(--radius-2xl); } .rounded-l-3xl { border-top-left-radius: var(--radius-3xl); border-bottom-left-radius: var(--radius-3xl); } .rounded-l-full { border-top-left-radius: var(--radius-full); border-bottom-left-radius: var(--radius-full); } /* 單一角圓角 (Individual Corners) */ .rounded-tl-none { border-top-left-radius: var(--radius-none); } .rounded-tl-sm { border-top-left-radius: var(--radius-sm); } .rounded-tl { border-top-left-radius: var(--radius); } .rounded-tl-md { border-top-left-radius: var(--radius-md); } .rounded-tl-lg { border-top-left-radius: var(--radius-lg); } .rounded-tl-xl { border-top-left-radius: var(--radius-xl); } .rounded-tl-2xl { border-top-left-radius: var(--radius-2xl); } .rounded-tl-3xl { border-top-left-radius: var(--radius-3xl); } .rounded-tl-full { border-top-left-radius: var(--radius-full); } .rounded-tr-none { border-top-right-radius: var(--radius-none); } .rounded-tr-sm { border-top-right-radius: var(--radius-sm); } .rounded-tr { border-top-right-radius: var(--radius); } .rounded-tr-md { border-top-right-radius: var(--radius-md); } .rounded-tr-lg { border-top-right-radius: var(--radius-lg); } .rounded-tr-xl { border-top-right-radius: var(--radius-xl); } .rounded-tr-2xl { border-top-right-radius: var(--radius-2xl); } .rounded-tr-3xl { border-top-right-radius: var(--radius-3xl); } .rounded-tr-full { border-top-right-radius: var(--radius-full); } .rounded-br-none { border-bottom-right-radius: var(--radius-none); } .rounded-br-sm { border-bottom-right-radius: var(--radius-sm); } .rounded-br { border-bottom-right-radius: var(--radius); } .rounded-br-md { border-bottom-right-radius: var(--radius-md); } .rounded-br-lg { border-bottom-right-radius: var(--radius-lg); } .rounded-br-xl { border-bottom-right-radius: var(--radius-xl); } .rounded-br-2xl { border-bottom-right-radius: var(--radius-2xl); } .rounded-br-3xl { border-bottom-right-radius: var(--radius-3xl); } .rounded-br-full { border-bottom-right-radius: var(--radius-full); } .rounded-bl-none { border-bottom-left-radius: var(--radius-none); } .rounded-bl-sm { border-bottom-left-radius: var(--radius-sm); } .rounded-bl { border-bottom-left-radius: var(--radius); } .rounded-bl-md { border-bottom-left-radius: var(--radius-md); } .rounded-bl-lg { border-bottom-left-radius: var(--radius-lg); } .rounded-bl-xl { border-bottom-left-radius: var(--radius-xl); } .rounded-bl-2xl { border-bottom-left-radius: var(--radius-2xl); } .rounded-bl-3xl { border-bottom-left-radius: var(--radius-3xl); } .rounded-bl-full { border-bottom-left-radius: var(--radius-full); }