@import "tailwindcss"; @import "tw-animate-css"; /* dark variant — `` 또는 자식이 `.dark` 안에 있으면 활성 */ @custom-variant dark (&:is(.dark *)); /* 스크롤 기능은 그대로 두고 스크롤바만 안 보이게 (채팅 쓰레드 등) */ @utility scrollbar-hide { scrollbar-width: none; /* Firefox */ -ms-overflow-style: none; /* 구 Edge/IE */ &::-webkit-scrollbar { display: none; /* Chrome/Safari */ } } /* shadcn/ui 토큰 → Tailwind 색상·반경 매핑 */ @theme inline { /* ABAP_OPENCODE DESIGN_SYSTEM.md 와 같은 시스템 산세리프. 메타 라벨(font-mono 클래스)도 같은 서체 — 그쪽 UI 가 10~11px 산세리프 메타를 쓰기 때문. 코드블럭은 CodeBlock 이 자체 monospace 지정. */ --font-sans: -apple-system, "Segoe UI", "Inter", Roboto, "Noto Sans KR", "Apple SD Gothic Neo", sans-serif; --font-mono: -apple-system, "Segoe UI", "Inter", Roboto, "Noto Sans KR", "Apple SD Gothic Neo", sans-serif; --color-success: var(--success); --color-warning: var(--warning); --color-background: var(--background); --color-foreground: var(--foreground); --color-card: var(--card); --color-card-foreground: var(--card-foreground); --color-popover: var(--popover); --color-popover-foreground: var(--popover-foreground); --color-border: var(--border); --color-input: var(--input); --color-ring: var(--ring); --color-primary: var(--primary); --color-primary-foreground: var(--primary-foreground); --color-secondary: var(--secondary); --color-secondary-foreground: var(--secondary-foreground); --color-muted: var(--muted); --color-muted-foreground: var(--muted-foreground); --color-accent: var(--accent); --color-accent-foreground: var(--accent-foreground); --color-destructive: var(--destructive); --color-destructive-foreground: var(--destructive-foreground); --color-sidebar: var(--sidebar); --color-sidebar-foreground: var(--sidebar-foreground); --color-sidebar-primary: var(--sidebar-primary); --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); --color-sidebar-accent: var(--sidebar-accent); --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); --color-sidebar-border: var(--sidebar-border); --color-sidebar-ring: var(--sidebar-ring); --radius-sm: calc(var(--radius) - 4px); --radius-md: calc(var(--radius) - 2px); --radius-lg: var(--radius); --radius-xl: calc(var(--radius) + 4px); } /* ──────────────────────────────────────────────────────────────────────────── 팔레트 — 기본은 ABAP_OPENCODE 의 "Dark Workspace" 테마(DESIGN_SYSTEM.md §1/§7)를 shadcn 토큰으로 옮긴 것. 계층(사이드바 < 패널 < 캔버스 < 카드)으로 깊이를 내고, 카드엔 항상 border, 악센트는 블루(선택·포커스)/그린(상태)/오렌지(경고) 셋만. palettes.ts 의 DEFAULT_THEME(=clean-blue, 이름 "워크스페이스") 가 라이트 값을 덮고, .dark 는 여기 값이 그대로 쓰임. index.html 이 첫 페인트 전 [data-theme]/.dark 박음. ──────────────────────────────────────────────────────────────────────────── */ :root { /* 라이트 — 회색 층 → 흰 카드 */ --background: #fafbfc; /* canvas */ --foreground: #1a1d22; /* text-hi */ --card: #ffffff; --card-foreground: #1a1d22; --popover: #ffffff; --popover-foreground: #1a1d22; --primary: #3563e9; /* blue (흰 배경 대비용으로 진하게) */ --primary-foreground: #ffffff; --secondary: #eff1f4; /* chip */ --secondary-foreground: #1a1d22; --muted: #f2f3f5; /* sidebar */ --muted-foreground: #494f59; /* text-md */ --accent: #e4e8ef; /* sel-bg */ --accent-foreground: #1a1d22; --destructive: oklch(0.577 0.245 27.325); --destructive-foreground: oklch(0.985 0 0); --success: #22a85c; /* green — 상태·진행 */ --warning: #d07e44; /* orange — 보조·경고 */ --border: #e1e3e8; --input: #e1e3e8; --ring: #3563e9; --radius: 0.5rem; /* 카드 8px, 소형 6px */ --shadow-float: 0 4px 14px rgba(23, 26, 31, 0.08), 0 1px 3px rgba(23, 26, 31, 0.06); /* 사이드바 */ --sidebar: #f2f3f5; --sidebar-foreground: #1a1d22; --sidebar-primary: #3563e9; --sidebar-primary-foreground: #ffffff; --sidebar-accent: #e9ebef; --sidebar-accent-foreground: #1a1d22; --sidebar-border: #e9ebef; --sidebar-ring: #3563e9; } /* 다크(기본 모드) — 어두운 층 → 밝은 카드. themeStore 가 .dark 토글. */ .dark { --background: #15171c; /* canvas */ --foreground: #e8eaed; /* text-hi (순백 금지) */ --card: #1a1d22; --card-foreground: #e8eaed; --popover: #1b1e24; /* float */ --popover-foreground: #e8eaed; --primary: #4c7dff; --primary-foreground: #ffffff; --secondary: #1d2127; /* chip */ --secondary-foreground: #c9cdd3; --muted: #191c21; /* item */ --muted-foreground: #9aa0a8; /* text-md */ --accent: #22262c; /* hover */ --accent-foreground: #e8eaed; --destructive: oklch(0.704 0.191 22.216); --destructive-foreground: oklch(0.985 0 0); --success: #35c96e; --warning: #e0915a; --border: #24272d; --input: #24272d; --ring: #4c7dff; --shadow-float: 0 6px 18px rgba(0, 0, 0, 0.45); --sidebar: #0c0d0f; --sidebar-foreground: #c9cdd3; --sidebar-primary: #4c7dff; --sidebar-primary-foreground: #ffffff; --sidebar-accent: #20242c; /* sel-bg */ --sidebar-accent-foreground: #e8eaed; --sidebar-border: #1e2126; --sidebar-ring: #4c7dff; } @layer base { * { @apply border-border; } html { @apply font-sans antialiased; } body { @apply bg-background text-foreground; font-feature-settings: "rlig" 1, "calt" 1; } /* Tailwind v4 가 버튼 기본 cursor 를 default 로 바꿔서 — 클릭되는 건 전부 손가락 모양 */ button:not(:disabled), [role="button"]:not([aria-disabled="true"]), a[href], label[for], select:not(:disabled), summary { cursor: pointer; } /* 스크롤바·선택·캐럿 — ABAP_OPENCODE 와 같은 얇은 오버레이 스타일 */ * { scrollbar-width: thin; scrollbar-color: var(--border) transparent; } ::-webkit-scrollbar { width: 8px; height: 8px; } ::-webkit-scrollbar-track { background: transparent; } ::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; } ::-webkit-scrollbar-thumb:hover { background: var(--accent); } ::selection { background: color-mix(in srgb, var(--primary) 28%, transparent); } :root { caret-color: var(--primary); } @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; } } } /* 시머 텍스트 — "생각하는 중…" 등 대기 문구에 밝은 띠가 좌→우로 쓸고 지나감. base=muted-foreground, 지나가는 띠=foreground 라 라이트/다크 둘 다 자동으로 보임. */ @keyframes shimmer-sweep { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } } @utility shimmer-text { background: linear-gradient( 90deg, var(--muted-foreground) 0%, var(--muted-foreground) 40%, var(--foreground) 50%, var(--muted-foreground) 60%, var(--muted-foreground) 100% ); background-size: 200% 100%; -webkit-background-clip: text; background-clip: text; color: transparent; animation: shimmer-sweep 1.6s linear infinite; }