1- import { css } from 'lit' ;
1+ import { css , unsafeCSS } from 'lit' ;
22
3- export const styles = css `
3+ /* ── Base (light) ──
4+ 모든 --u-* 토큰에 light fallback을 부여해 토큰 미공급 환경에서도 자가-테마된다.
5+ 외부에서 --u-* 가 공급되면 그 값이 우선한다. 형제 컴포넌트(USimpleSheet/
6+ URichTable)의 NT-5 자가-테마 패턴과 동일한 slate 계열 light fallback을 사용한다. */
7+ const baseStyles = css `
48 : host {
59 dis play: block;
610 width: 100%;
@@ -19,8 +23,8 @@ export const styles = css`
1923 align-items : center;
2024 justify-content : space-between;
2125 padding : 0.75rem ;
22- background : var (--u-bg-color );
23- border : 1px solid var (--u-border-color );
26+ background : var (--u-bg-color , # fff );
27+ border : 1px solid var (--u-border-color , # e2e8f0 );
2428 border-radius : 8px ;
2529 }
2630
@@ -30,13 +34,13 @@ export const styles = css`
3034 }
3135
3236 .view-toggles u-button [active ] {
33- background : var (--u-blue-600 );
34- color : var (--u-neutral-0 );
37+ background : var (--u-blue-600 , # 1E88E5 );
38+ color : var (--u-neutral-0 , # fff );
3539 }
3640
3741 .info {
3842 font-size : 0.875rem ;
39- color : var (--u-txt-color-weak );
43+ color : var (--u-txt-color-weak , # 64748b );
4044 font-weight : 500 ;
4145 }
4246
@@ -56,24 +60,24 @@ export const styles = css`
5660
5761 /* Card Styles */
5862 .card {
59- background : var (--u-bg-color );
60- border : 1px solid var (--u-border-color );
63+ background : var (--u-bg-color , # fff );
64+ border : 1px solid var (--u-border-color , # e2e8f0 );
6165 border-radius : 8px ;
6266 padding : 1.25rem ;
6367 cursor : pointer;
6468 transition : all 0.15s ease;
6569 }
6670
6771 .card : hover {
68- border-color : var (--u-blue-600 );
69- box-shadow : 0 4px 12px var (--u-shadow-color-weak );
72+ border-color : var (--u-blue-600 , # 1E88E5 );
73+ box-shadow : 0 4px 12px var (--u-shadow-color-weak , rgba ( 0 , 0 , 0 , 0.08 ) );
7074 transform : translateY (-2px );
7175 }
7276
7377 .card .selected {
74- border-color : var (--u-blue-600 );
75- background : var (--u-bg-color-active );
76- box-shadow : 0 0 0 3px var (--u-blue-200 );
78+ border-color : var (--u-blue-600 , # 1E88E5 );
79+ background : var (--u-bg-color-active , # EEEEEE );
80+ box-shadow : 0 0 0 3px var (--u-blue-200 , # 90CAF9 );
7781 }
7882
7983 .card-content {
@@ -91,14 +95,14 @@ export const styles = css`
9195 .card-field .label {
9296 font-size : 0.875rem ;
9397 font-weight : 600 ;
94- color : var (--u-txt-color-weak );
98+ color : var (--u-txt-color-weak , # 64748b );
9599 min-width : 80px ;
96100 flex-shrink : 0 ;
97101 }
98102
99103 .card-field .value {
100104 font-size : 0.9375rem ;
101- color : var (--u-txt-color );
105+ color : var (--u-txt-color , # 0f172a );
102106 word-break : break-word;
103107 }
104108
@@ -116,18 +120,18 @@ export const styles = css`
116120 /* Table */
117121 .table-wrapper {
118122 overflow-x : auto;
119- border : 1px solid var (--u-border-color );
123+ border : 1px solid var (--u-border-color , # e2e8f0 );
120124 border-radius : 8px ;
121125 }
122126
123127 table {
124128 width : 100% ;
125129 border-collapse : collapse;
126- background : var (--u-bg-color );
130+ background : var (--u-bg-color , # fff );
127131 }
128132
129133 thead {
130- background : var (--u-neutral-50 );
134+ background : var (--u-neutral-50 , # f8fafc );
131135 position : sticky;
132136 top : 0 ;
133137 z-index : 10 ;
@@ -138,8 +142,8 @@ export const styles = css`
138142 text-align : left;
139143 font-size : 0.875rem ;
140144 font-weight : 600 ;
141- color : var (--u-txt-color-weak );
142- border-bottom : 2px solid var (--u-border-color );
145+ color : var (--u-txt-color-weak , # 64748b );
146+ border-bottom : 2px solid var (--u-border-color , # e2e8f0 );
143147 white-space : nowrap;
144148 }
145149
@@ -149,21 +153,21 @@ export const styles = css`
149153 }
150154
151155 tbody tr : hover {
152- background : var (--u-bg-color-hover );
156+ background : var (--u-bg-color-hover , # F5F5F5 );
153157 }
154158
155159 tbody tr .selected {
156- background : var (--u-bg-color-active );
160+ background : var (--u-bg-color-active , # EEEEEE );
157161 }
158162
159163 tbody tr : not (: last-child ) {
160- border-bottom : 1px solid var (--u-border-color-weak );
164+ border-bottom : 1px solid var (--u-border-color-weak , # f1f5f9 );
161165 }
162166
163167 td {
164168 padding : 0.875rem 1rem ;
165169 font-size : 0.9375rem ;
166- color : var (--u-txt-color );
170+ color : var (--u-txt-color , # 0f172a );
167171 }
168172
169173 /* Empty State */
@@ -172,7 +176,104 @@ export const styles = css`
172176 align-items : center;
173177 justify-content : center;
174178 min-height : 300px ;
175- color : var (--u-txt-color-weak );
179+ color : var (--u-txt-color-weak , # 64748b );
176180 font-size : 1rem ;
177181 }
178182` ;
183+
184+ /* ── Dark mode ──
185+ 외부에서 --u-* 변수가 제공되면 그 값을 사용하고, 없으면 dark fallback을 적용한다.
186+ 다크 규칙은 아래 3가지 컨텍스트에서 동일하게 적용된다:
187+ - :host([theme="dark"]) — 1급 theme 속성 (전 브라우저)
188+ - :host-context([theme="dark"]) — 조상 theme 속성, Theme 유틸 호환 (Chromium)
189+ - :host-context([data-theme="dark"]) — 조상 data-theme 속성만 쓰는 앱 (Chromium)
190+
191+ 셀렉터 리스트로 결합하면 :host-context 미지원 브라우저(Firefox/Safari)가
192+ 리스트 전체를 무효화하므로, 프리픽스별 개별 규칙으로 생성한다. */
193+ const DARK_PREFIXES = [
194+ ':host([theme="dark"])' ,
195+ ':host-context([theme="dark"])' ,
196+ ':host-context([data-theme="dark"])' ,
197+ ] ;
198+
199+ const darkRules = ( host : string ) => `
200+ ${ host } .toolbar {
201+ background: var(--u-bg-color, #121212);
202+ border-color: var(--u-border-color, #3D3D3D);
203+ }
204+
205+ ${ host } .view-toggles u-button[active] {
206+ background: var(--u-blue-600, #87B8F5);
207+ color: var(--u-neutral-0, #000);
208+ }
209+
210+ ${ host } .info {
211+ color: var(--u-txt-color-weak, #8A8A8A);
212+ }
213+
214+ ${ host } .card {
215+ background: var(--u-bg-color, #121212);
216+ border-color: var(--u-border-color, #3D3D3D);
217+ }
218+
219+ ${ host } .card:hover {
220+ border-color: var(--u-blue-600, #87B8F5);
221+ box-shadow: 0 4px 12px var(--u-shadow-color-weak, rgba(0, 0, 0, 0.25));
222+ }
223+
224+ ${ host } .card.selected {
225+ border-color: var(--u-blue-600, #87B8F5);
226+ background: var(--u-bg-color-active, #3D3D3D);
227+ box-shadow: 0 0 0 3px var(--u-blue-200, #2B4F7E);
228+ }
229+
230+ ${ host } .card-field .label {
231+ color: var(--u-txt-color-weak, #8A8A8A);
232+ }
233+
234+ ${ host } .card-field .value {
235+ color: var(--u-txt-color, #D4D4D4);
236+ }
237+
238+ ${ host } .table-wrapper {
239+ border-color: var(--u-border-color, #3D3D3D);
240+ }
241+
242+ ${ host } table {
243+ background: var(--u-bg-color, #121212);
244+ }
245+
246+ ${ host } thead {
247+ background: var(--u-neutral-50, #0A0A0A);
248+ }
249+
250+ ${ host } th {
251+ color: var(--u-txt-color-weak, #8A8A8A);
252+ border-bottom-color: var(--u-border-color, #3D3D3D);
253+ }
254+
255+ ${ host } tbody tr:hover {
256+ background: var(--u-bg-color-hover, #2A2A2A);
257+ }
258+
259+ ${ host } tbody tr.selected {
260+ background: var(--u-bg-color-active, #3D3D3D);
261+ }
262+
263+ ${ host } tbody tr:not(:last-child) {
264+ border-bottom-color: var(--u-border-color-weak, #2A2A2A);
265+ }
266+
267+ ${ host } td {
268+ color: var(--u-txt-color, #D4D4D4);
269+ }
270+
271+ ${ host } .empty {
272+ color: var(--u-txt-color-weak, #8A8A8A);
273+ }
274+ ` ;
275+
276+ export const styles = [
277+ baseStyles ,
278+ unsafeCSS ( DARK_PREFIXES . map ( darkRules ) . join ( '\n' ) ) ,
279+ ] ;
0 commit comments