@charcoal-ui/react 6.1.0 → 6.1.1-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/layered.css CHANGED
@@ -6,49 +6,29 @@
6
6
  box-shadow: 0 0 0 4px rgba(0, 150, 250, 0.32);
7
7
  transition: 0.2s box-shadow;
8
8
  }
9
- .charcoal-clickable {
9
+ .charcoal-switch__label {
10
+ display: inline-grid;
11
+ grid-template-columns: auto 1fr;
12
+ align-items: center;
10
13
  cursor: pointer;
11
-
12
- /* Reset button appearance */
13
- -webkit-appearance: none;
14
- -moz-appearance: none;
15
- appearance: none;
16
- background: transparent;
17
- padding: 0;
18
- border-style: none;
19
- outline: none;
20
- color: inherit;
21
- text-rendering: inherit;
22
- letter-spacing: inherit;
23
- word-spacing: inherit;
24
- text-decoration: none;
25
-
26
- /* Change the font styles in all browsers. */
27
- font: inherit;
28
-
29
- /* Remove the margin in Firefox and Safari. */
30
- margin: 0;
31
-
32
- /* Show the overflow in Edge. */
33
- overflow: visible;
34
-
35
- /* Remove the inheritance of text transform in Firefox. */
36
- text-transform: none;
14
+ outline: 0;
15
+ gap: 4px;
37
16
  }
38
17
 
39
- .charcoal-clickable:disabled,
40
- .charcoal-clickable[aria-disabled]:not([aria-disabled='false']) {
18
+ .charcoal-switch__label[aria-disabled='true'] {
19
+ opacity: 0.32;
41
20
  cursor: default;
42
21
  }
43
22
 
44
- .charcoal-clickable:focus {
45
- outline: none;
46
- }
23
+ .charcoal-switch__label[aria-disabled='true'] > input {
24
+ opacity: 1;
25
+ }
47
26
 
48
- .charcoal-clickable::-moz-focus-inner {
49
- border-style: none;
50
- padding: 0;
51
- }
27
+ .charcoal-switch__label_div {
28
+ font-size: 14px;
29
+ line-height: 22px;
30
+ color: var(--charcoal-color-text-default);
31
+ }
52
32
  .charcoal-button {
53
33
  -webkit-appearance: none;
54
34
  -moz-appearance: none;
@@ -199,29 +179,148 @@
199
179
  .charcoal-button[data-full-width='true'] {
200
180
  width: 100%;
201
181
  }
202
- .charcoal-radio__label {
182
+ .charcoal-text-field-root {
203
183
  display: grid;
204
- grid-template-columns: auto 1fr;
184
+ grid-template-columns: 1fr;
205
185
  grid-gap: 4px;
206
- align-items: center;
207
- cursor: pointer;
208
186
  }
209
187
 
210
- .charcoal-radio__label[aria-disabled]:not([aria-disabled='false']) {
188
+ .charcoal-text-field-root[aria-disabled='true'] {
211
189
  opacity: 0.32;
212
- cursor: default;
213
190
  }
214
191
 
215
- .charcoal-radio__label_div {
192
+ .charcoal-text-field-container {
193
+ display: flex;
194
+ height: 40px;
195
+ transition:
196
+ 0.2s background-color,
197
+ 0.2s box-shadow;
198
+ color: var(--charcoal-color-text-secondary-default);
199
+ background-color: var(--charcoal-color-container-secondary-default-a);
200
+ border-radius: 4px;
201
+ padding: 0 8px;
202
+ line-height: 22px;
216
203
  font-size: 14px;
204
+ }
205
+
206
+ .charcoal-text-field-container[data-invalid='true'] {
207
+ box-shadow: 0 0 0 4px rgba(255, 43, 0, 0.32);
208
+ }
209
+
210
+ .charcoal-text-field-container:not([aria-disabled='true']):hover {
211
+ background-color: var(--charcoal-color-container-secondary-hover-a);
212
+ }
213
+
214
+ .charcoal-text-field-container:not([aria-disabled='true']):focus-within {
215
+ outline: none;
216
+ box-shadow: 0 0 0 4px rgba(0, 150, 250, 0.32);
217
+ }
218
+
219
+ .charcoal-text-field-container:not([aria-disabled='true'])[data-invalid='true']:focus-within {
220
+ box-shadow: 0 0 0 4px rgba(255, 43, 0, 0.32);
221
+ }
222
+
223
+ .charcoal-text-field-prefix {
224
+ display: flex;
225
+ align-items: center;
226
+ margin-right: 4px;
227
+ }
228
+
229
+ .charcoal-text-field-suffix {
230
+ display: flex;
231
+ align-items: center;
232
+ gap: 8px;
233
+ margin-left: 4px;
234
+ }
235
+
236
+ .charcoal-text-field-input-root {
237
+ flex: 1;
238
+ min-width: 0;
239
+ overflow: hidden;
240
+ }
241
+
242
+ .charcoal-text-field-input {
243
+ border: none;
244
+ box-sizing: border-box;
245
+ outline: none;
246
+ font-family: inherit;
247
+
248
+ /* Prevent zooming for iOS Safari */
249
+ transform-origin: top left;
250
+ transform: scale(0.875);
251
+ width: calc(100% / 0.875);
252
+ height: calc(100% / 0.875);
253
+ font-size: calc(14px / 0.875);
254
+ line-height: calc(22px / 0.875);
255
+ padding-left: 0;
256
+ padding-right: 0;
257
+ border-radius: calc(4px / 0.875);
258
+
259
+ /* Display box-shadow for iOS Safari */
260
+ -webkit-appearance: none;
261
+ -moz-appearance: none;
262
+ appearance: none;
263
+ background: transparent;
264
+
265
+ color: var(--charcoal-color-text-secondary-default);
266
+ }
267
+
268
+ .charcoal-text-field-input::-moz-placeholder {
269
+ color: var(--charcoal-color-text-placeholder-default);
270
+ }
271
+
272
+ .charcoal-text-field-input::placeholder {
273
+ color: var(--charcoal-color-text-placeholder-default);
274
+ }
275
+
276
+ .charcoal-text-field-line-counter {
217
277
  line-height: 22px;
218
- color: var(--charcoal-color-text-default);
278
+ font-size: 14px;
279
+ color: var(--charcoal-color-text-tertiary-default);
219
280
  }
220
- .charcoal-radio-group {
221
- display: grid;
222
- grid-template-columns: 1fr;
223
- grid-gap: 8px;
281
+ .charcoal-clickable {
282
+ cursor: pointer;
283
+
284
+ /* Reset button appearance */
285
+ -webkit-appearance: none;
286
+ -moz-appearance: none;
287
+ appearance: none;
288
+ background: transparent;
289
+ padding: 0;
290
+ border-style: none;
291
+ outline: none;
292
+ color: inherit;
293
+ text-rendering: inherit;
294
+ letter-spacing: inherit;
295
+ word-spacing: inherit;
296
+ text-decoration: none;
297
+
298
+ /* Change the font styles in all browsers. */
299
+ font: inherit;
300
+
301
+ /* Remove the margin in Firefox and Safari. */
302
+ margin: 0;
303
+
304
+ /* Show the overflow in Edge. */
305
+ overflow: visible;
306
+
307
+ /* Remove the inheritance of text transform in Firefox. */
308
+ text-transform: none;
224
309
  }
310
+
311
+ .charcoal-clickable:disabled,
312
+ .charcoal-clickable[aria-disabled]:not([aria-disabled='false']) {
313
+ cursor: default;
314
+ }
315
+
316
+ .charcoal-clickable:focus {
317
+ outline: none;
318
+ }
319
+
320
+ .charcoal-clickable::-moz-focus-inner {
321
+ border-style: none;
322
+ padding: 0;
323
+ }
225
324
  .charcoal-icon-button {
226
325
  cursor: pointer;
227
326
  -webkit-appearance: none;
@@ -346,519 +445,187 @@
346
445
  .charcoal-icon-button[aria-disabled='false']:focus:not(:focus-visible) {
347
446
  box-shadow: none;
348
447
  }
349
- .charcoal-multi-select {
448
+ .charcoal-text-area-root {
350
449
  display: grid;
351
- grid-template-columns: auto 1fr;
352
- align-items: center;
353
- position: relative;
354
- cursor: pointer;
355
- gap: 4px;
450
+ grid-template-columns: 1fr;
451
+ grid-gap: 4px;
356
452
  }
357
453
 
358
- .charcoal-multi-select:disabled,
359
- .charcoal-multi-select[aria-disabled]:not([aria-disabled='false']) {
454
+ .charcoal-text-area-root[aria-disabled='true'] {
360
455
  opacity: 0.32;
361
- cursor: default;
362
456
  }
363
457
 
364
- .charcoal-multi-select-label {
365
- display: flow-root;
366
- align-items: center;
367
- font-size: 14px;
368
- line-height: 22px;
369
- color: var(--charcoal-color-text-default);
370
- }
371
-
372
- .charcoal-multi-select-label::before {
373
- display: block;
374
- width: 0;
375
- height: 0;
376
- content: '';
377
- margin-top: -4px;
378
- }
458
+ .charcoal-text-area-container {
459
+ /* Runtime variable overridden by the React component. */
460
+ --charcoal-text-area-rows: 4;
379
461
 
380
- .charcoal-multi-select-label::after {
381
- display: block;
382
- width: 0;
383
- height: 0;
384
- content: '';
385
- margin-bottom: -4px;
386
- }
462
+ position: relative;
463
+ overflow: hidden;
387
464
 
388
- .charcoal-multi-select-input[type='checkbox'] {
389
- -webkit-appearance: none;
390
- -moz-appearance: none;
391
- appearance: none;
392
- display: block;
393
- width: 20px;
394
- height: 20px;
395
- margin: 0;
396
- background-color: var(--charcoal-color-container-neutral-default);
397
- border-radius: 999999px;
465
+ color: var(--charcoal-color-text-secondary-default);
466
+ background-color: var(--charcoal-color-container-secondary-default-a);
467
+ border-radius: 4px;
398
468
  transition:
399
469
  0.2s background-color,
400
470
  0.2s box-shadow;
471
+ height: calc(22px * var(--charcoal-text-area-rows) + 18px);
401
472
  }
402
473
 
403
- .charcoal-multi-select-input[type='checkbox']:checked {
404
- background-color: var(--charcoal-color-container-primary-default);
474
+ .charcoal-text-area-container[aria-invalid='true'] {
475
+ box-shadow: 0 0 0 4px rgba(255, 43, 0, 0.32);
405
476
  }
406
477
 
407
- .charcoal-multi-select-input[type='checkbox']:focus {
478
+ .charcoal-text-area-container:focus-within {
408
479
  outline: none;
409
480
  box-shadow: 0 0 0 4px rgba(0, 150, 250, 0.32);
410
481
  }
411
482
 
412
- .charcoal-multi-select-input[type='checkbox']:focus-visible {
413
- box-shadow: 0 0 0 4px rgba(0, 150, 250, 0.32);
414
- }
415
-
416
- .charcoal-multi-select-input[type='checkbox']:focus:not(:focus-visible) {
417
- box-shadow: none;
418
- }
419
-
420
- .charcoal-multi-select-input[type='checkbox']:hover:not(:disabled):not([aria-disabled]),
421
- .charcoal-multi-select-input[type='checkbox']:hover[aria-disabled='false'] {
422
- background-color: var(--charcoal-color-container-neutral-hover);
423
- }
424
-
425
- .charcoal-multi-select-input[type='checkbox']:active:not(:disabled):not([aria-disabled]),
426
- .charcoal-multi-select-input[type='checkbox']:active[aria-disabled='false'] {
427
- background-color: var(--charcoal-color-container-neutral-press);
428
- }
429
-
430
- .charcoal-multi-select-input[type='checkbox']:checked:hover:not(:disabled):not([aria-disabled]),
431
- .charcoal-multi-select-input[type='checkbox']:checked:hover[aria-disabled='false'] {
432
- background-color: var(--charcoal-color-container-primary-hover);
433
- }
434
-
435
- .charcoal-multi-select-input[type='checkbox']:checked:active:not(:disabled):not([aria-disabled]),
436
- .charcoal-multi-select-input[type='checkbox']:checked:active[aria-disabled='false'] {
437
- background-color: var(--charcoal-color-container-primary-press);
438
- }
439
-
440
- .charcoal-multi-select-input[type='checkbox'][aria-invalid='true'][data-overlay='false']:not(:disabled):not(
441
- [aria-disabled]
442
- ) {
443
- box-shadow: 0 0 0 4px rgba(255, 43, 0, 0.32);
444
- }
445
-
446
- .charcoal-multi-select-input[type='checkbox'][aria-invalid='true'][data-overlay='false'][aria-disabled='false'] {
447
- box-shadow: 0 0 0 4px rgba(255, 43, 0, 0.32);
448
- }
449
-
450
- .charcoal-multi-select-input[type='checkbox'][data-overlay='true'] {
451
- background-color: var(--charcoal-color-container-on-img-default);
452
- }
453
-
454
- .charcoal-multi-select-overlay {
455
- position: absolute;
456
- top: -2px;
457
- left: -2px;
458
- box-sizing: border-box;
459
- display: flex;
460
- align-items: center;
461
- justify-content: center;
462
- width: 24px;
463
- height: 24px;
464
- border-radius: 999999px;
465
- color: var(--charcoal-color-icon-on-primary-default);
466
- transition: 0.2s box-shadow;
467
- }
468
-
469
- .charcoal-multi-select-overlay[aria-invalid='true'][data-overlay='true']:not(:disabled):not(
470
- [aria-disabled]
471
- ) {
472
- box-shadow: 0 0 0 4px rgba(255, 43, 0, 0.32);
473
- }
474
-
475
- .charcoal-multi-select-overlay[aria-invalid='true'][data-overlay='true'][aria-disabled='false'] {
476
- box-shadow: 0 0 0 4px rgba(255, 43, 0, 0.32);
477
- }
478
-
479
- .charcoal-multi-select-overlay[data-overlay='true'] {
480
- border-color: var(--charcoal-color-border-hud);
481
- border-width: 2px;
482
- border-style: solid;
483
- }
484
- .charcoal-text-field-root {
485
- display: grid;
486
- grid-template-columns: 1fr;
487
- grid-gap: 4px;
488
- }
489
-
490
- .charcoal-text-field-root[aria-disabled='true'] {
491
- opacity: 0.32;
492
- }
493
-
494
- .charcoal-text-field-container {
495
- display: flex;
496
- height: 40px;
497
- transition:
498
- 0.2s background-color,
499
- 0.2s box-shadow;
500
- color: var(--charcoal-color-text-secondary-default);
501
- background-color: var(--charcoal-color-container-secondary-default-a);
502
- border-radius: 4px;
503
- padding: 0 8px;
504
- line-height: 22px;
505
- font-size: 14px;
506
- }
507
-
508
- .charcoal-text-field-container[data-invalid='true'] {
509
- box-shadow: 0 0 0 4px rgba(255, 43, 0, 0.32);
483
+ .charcoal-text-area-container:has([data-no-bottom-padding='true']) {
484
+ height: calc(22px * (var(--charcoal-text-area-rows) + 1) + 18px);
510
485
  }
511
486
 
512
- .charcoal-text-field-container:not([aria-disabled='true']):hover {
487
+ .charcoal-text-area-container:not([aria-disabled='true']):hover {
513
488
  background-color: var(--charcoal-color-container-secondary-hover-a);
514
489
  }
515
490
 
516
- .charcoal-text-field-container:not([aria-disabled='true']):focus-within {
517
- outline: none;
518
- box-shadow: 0 0 0 4px rgba(0, 150, 250, 0.32);
519
- }
520
-
521
- .charcoal-text-field-container:not([aria-disabled='true'])[data-invalid='true']:focus-within {
491
+ .charcoal-text-area-container[aria-invalid='true']:focus-within {
522
492
  box-shadow: 0 0 0 4px rgba(255, 43, 0, 0.32);
523
493
  }
524
494
 
525
- .charcoal-text-field-prefix {
526
- display: flex;
527
- align-items: center;
528
- margin-right: 4px;
529
- }
530
-
531
- .charcoal-text-field-suffix {
532
- display: flex;
533
- align-items: center;
534
- gap: 8px;
535
- margin-left: 4px;
536
- }
537
-
538
- .charcoal-text-field-input-root {
539
- flex: 1;
540
- min-width: 0;
541
- overflow: hidden;
542
- }
543
-
544
- .charcoal-text-field-input {
495
+ .charcoal-text-area-textarea {
545
496
  border: none;
546
- box-sizing: border-box;
547
497
  outline: none;
498
+ resize: none;
548
499
  font-family: inherit;
500
+ color: inherit;
501
+ box-sizing: border-box;
549
502
 
550
503
  /* Prevent zooming for iOS Safari */
504
+ --charcoal-textarea-safari-prevent-zoom-scale: 0.875;
505
+ --charcoal-textarea-line-height: calc(
506
+ 22px / var(--charcoal-textarea-safari-prevent-zoom-scale)
507
+ );
508
+ --charcoal-textarea-padding-y: calc(
509
+ 8px / var(--charcoal-textarea-safari-prevent-zoom-scale)
510
+ );
511
+ --charcoal-textarea-padding-x: calc(
512
+ 9px / var(--charcoal-textarea-safari-prevent-zoom-scale)
513
+ );
514
+
551
515
  transform-origin: top left;
552
- transform: scale(0.875);
553
- width: calc(100% / 0.875);
554
- height: calc(100% / 0.875);
555
- font-size: calc(14px / 0.875);
556
- line-height: calc(22px / 0.875);
557
- padding-left: 0;
558
- padding-right: 0;
559
- border-radius: calc(4px / 0.875);
516
+ transform: scale(var(--charcoal-textarea-safari-prevent-zoom-scale));
517
+ width: calc(100% / var(--charcoal-textarea-safari-prevent-zoom-scale));
518
+ font-size: calc(14px / var(--charcoal-textarea-safari-prevent-zoom-scale));
519
+ line-height: var(--charcoal-textarea-line-height);
520
+ padding: var(--charcoal-textarea-padding-y) var(--charcoal-textarea-padding-x);
521
+ height: calc(
522
+ var(--charcoal-textarea-line-height) * var(--charcoal-text-area-rows) +
523
+ var(--charcoal-textarea-padding-y) * 2
524
+ );
560
525
 
561
526
  /* Display box-shadow for iOS Safari */
562
527
  -webkit-appearance: none;
563
528
  -moz-appearance: none;
564
529
  appearance: none;
565
- background: transparent;
566
530
 
567
- color: var(--charcoal-color-text-secondary-default);
531
+ background: none;
568
532
  }
569
533
 
570
- .charcoal-text-field-input::-moz-placeholder {
534
+ .charcoal-text-area-textarea[data-no-bottom-padding='true'] {
535
+ padding: var(--charcoal-textarea-padding-y)
536
+ var(--charcoal-textarea-padding-x) 0;
537
+ height: calc(
538
+ var(--charcoal-textarea-line-height) * var(--charcoal-text-area-rows) +
539
+ var(--charcoal-textarea-padding-y)
540
+ );
541
+ }
542
+
543
+ .charcoal-text-area-textarea::-moz-placeholder {
571
544
  color: var(--charcoal-color-text-placeholder-default);
572
545
  }
573
546
 
574
- .charcoal-text-field-input::placeholder {
547
+ .charcoal-text-area-textarea::placeholder {
575
548
  color: var(--charcoal-color-text-placeholder-default);
576
549
  }
577
550
 
578
- .charcoal-text-field-line-counter {
551
+ .charcoal-text-area-counter {
552
+ position: absolute;
553
+ bottom: 9px;
554
+ right: 8px;
555
+
579
556
  line-height: 22px;
580
557
  font-size: 14px;
581
558
  color: var(--charcoal-color-text-tertiary-default);
582
559
  }
583
- .charcoal-loading-spinner {
584
- box-sizing: content-box;
585
- margin: auto;
586
- padding: 16px;
587
- border-radius: 8px;
588
- font-size: 48px;
589
- width: 48px;
590
- height: 48px;
591
- opacity: 0.84;
592
- color: var(--charcoal-color-icon-tertiary-default);
593
- background-color: var(--charcoal-color-background-default);
560
+ .charcoal-modal-background {
561
+ overflow: auto;
562
+ display: flex;
563
+ position: fixed;
564
+ top: 0;
565
+ left: 0;
566
+ width: 100%;
567
+ height: 100%;
568
+ justify-content: center;
569
+ padding: 40px 0;
570
+ box-sizing: border-box;
571
+
572
+ background-color: var(--charcoal-color-background-overlay);
594
573
  }
595
574
 
596
- .charcoal-loading-spinner[data-transparent='true'] {
597
- background-color: transparent;
575
+ @media (max-width: 743px) {
576
+ .charcoal-modal-background[data-bottom-sheet='true'],
577
+ .charcoal-modal-background[data-bottom-sheet='full'] {
578
+ padding: 0;
579
+ }
598
580
  }
599
581
 
600
- @keyframes charcoal-loading-spinner-icon-scale-out {
601
- from {
602
- transform: scale(0);
603
- opacity: 1;
604
- }
605
- to {
606
- transform: scale(1);
607
- opacity: 0;
608
- }
582
+ /* easeOutQuart。duration は useTransitionPresence の MODAL_TRANSITION_DURATION_MS と一致させること。
583
+ transition は entering / exiting に限定し、開いたままテーマ切り替え等で
584
+ 色や transform が変わってもアニメーションしないようにする */
585
+ .charcoal-modal-background[data-animation] {
586
+ overflow: hidden;
609
587
  }
610
588
 
611
- .charcoal-loading-spinner-icon {
612
- width: 1em;
613
- height: 1em;
614
- border-radius: 1em;
615
- background-color: currentColor;
616
- animation: charcoal-loading-spinner-icon-scale-out 1s infinite both ease-out;
589
+ .charcoal-modal-background[data-animation='entering'],
590
+ .charcoal-modal-background[data-animation='exiting'] {
591
+ transition: background-color 400ms cubic-bezier(0.25, 1, 0.5, 1);
617
592
  }
618
593
 
619
- .charcoal-loading-spinner-icon[data-reset-animation] {
620
- animation: none;
621
- }
594
+ /* 閉じアニメーション中はクリックを下のページへ通す(transitionend が来ない環境で
595
+ 透明なオーバーレイがタップを奪い続けるのも防ぐ) */
596
+ .charcoal-modal-background[data-animation='exited'],
597
+ .charcoal-modal-background[data-animation='exiting'] {
598
+ background-color: transparent;
599
+ pointer-events: none;
600
+ }
622
601
 
623
- .charcoal-loading-spinner-icon[data-once='true'] {
624
- animation-iteration-count: 1;
625
- }
626
- .charcoal-menu-item-group {
627
- display: block;
602
+ .charcoal-modal-background[data-animation='entered'] {
603
+ overflow: auto;
628
604
  }
629
605
 
630
- .charcoal-menu-item-group > span {
631
- display: block;
632
- color: var(--charcoal-color-text-tertiary-default);
633
- font-size: 12px;
634
- font-weight: bold;
635
- padding: 12px 0 8px 16px;
636
- }
637
-
638
- .charcoal-menu-item-group > ul {
639
- padding-left: 0;
640
- margin: 0;
641
- box-sizing: border-box;
642
- list-style: none;
643
- overflow: hidden;
644
- }
645
- .charcoal-text-area-root {
646
- display: grid;
647
- grid-template-columns: 1fr;
648
- grid-gap: 4px;
649
- }
650
-
651
- .charcoal-text-area-root[aria-disabled='true'] {
652
- opacity: 0.32;
653
- }
654
-
655
- .charcoal-text-area-container {
656
- /* Runtime variable overridden by the React component. */
657
- --charcoal-text-area-rows: 4;
658
-
659
- position: relative;
660
- overflow: hidden;
661
-
662
- color: var(--charcoal-color-text-secondary-default);
663
- background-color: var(--charcoal-color-container-secondary-default-a);
664
- border-radius: 4px;
665
- transition:
666
- 0.2s background-color,
667
- 0.2s box-shadow;
668
- height: calc(22px * var(--charcoal-text-area-rows) + 18px);
606
+ .charcoal-modal-background[data-animation='entering'] > .charcoal-modal-dialog,
607
+ .charcoal-modal-background[data-animation='exiting'] > .charcoal-modal-dialog {
608
+ transition: transform 400ms cubic-bezier(0.25, 1, 0.5, 1);
669
609
  }
670
610
 
671
- .charcoal-text-area-container[aria-invalid='true'] {
672
- box-shadow: 0 0 0 4px rgba(255, 43, 0, 0.32);
673
- }
674
-
675
- .charcoal-text-area-container:focus-within {
676
- outline: none;
677
- box-shadow: 0 0 0 4px rgba(0, 150, 250, 0.32);
678
- }
679
-
680
- .charcoal-text-area-container:has([data-no-bottom-padding='true']) {
681
- height: calc(22px * (var(--charcoal-text-area-rows) + 1) + 18px);
682
- }
683
-
684
- .charcoal-text-area-container:not([aria-disabled='true']):hover {
685
- background-color: var(--charcoal-color-container-secondary-hover-a);
686
- }
687
-
688
- .charcoal-text-area-container[aria-invalid='true']:focus-within {
689
- box-shadow: 0 0 0 4px rgba(255, 43, 0, 0.32);
690
- }
691
-
692
- .charcoal-text-area-textarea {
693
- border: none;
694
- outline: none;
695
- resize: none;
696
- font-family: inherit;
697
- color: inherit;
698
- box-sizing: border-box;
699
-
700
- /* Prevent zooming for iOS Safari */
701
- --charcoal-textarea-safari-prevent-zoom-scale: 0.875;
702
- --charcoal-textarea-line-height: calc(
703
- 22px / var(--charcoal-textarea-safari-prevent-zoom-scale)
704
- );
705
- --charcoal-textarea-padding-y: calc(
706
- 8px / var(--charcoal-textarea-safari-prevent-zoom-scale)
707
- );
708
- --charcoal-textarea-padding-x: calc(
709
- 9px / var(--charcoal-textarea-safari-prevent-zoom-scale)
710
- );
711
-
712
- transform-origin: top left;
713
- transform: scale(var(--charcoal-textarea-safari-prevent-zoom-scale));
714
- width: calc(100% / var(--charcoal-textarea-safari-prevent-zoom-scale));
715
- font-size: calc(14px / var(--charcoal-textarea-safari-prevent-zoom-scale));
716
- line-height: var(--charcoal-textarea-line-height);
717
- padding: var(--charcoal-textarea-padding-y) var(--charcoal-textarea-padding-x);
718
- height: calc(
719
- var(--charcoal-textarea-line-height) * var(--charcoal-text-area-rows) +
720
- var(--charcoal-textarea-padding-y) * 2
721
- );
722
-
723
- /* Display box-shadow for iOS Safari */
724
- -webkit-appearance: none;
725
- -moz-appearance: none;
726
- appearance: none;
727
-
728
- background: none;
611
+ .charcoal-modal-background[data-animation='exited'] > .charcoal-modal-dialog,
612
+ .charcoal-modal-background[data-animation='exiting'] > .charcoal-modal-dialog {
613
+ transform: translateY(100%);
729
614
  }
730
615
 
731
- .charcoal-text-area-textarea[data-no-bottom-padding='true'] {
732
- padding: var(--charcoal-textarea-padding-y)
733
- var(--charcoal-textarea-padding-x) 0;
734
- height: calc(
735
- var(--charcoal-textarea-line-height) * var(--charcoal-text-area-rows) +
736
- var(--charcoal-textarea-padding-y)
737
- );
738
- }
739
-
740
- .charcoal-text-area-textarea::-moz-placeholder {
741
- color: var(--charcoal-color-text-placeholder-default);
742
- }
743
-
744
- .charcoal-text-area-textarea::placeholder {
745
- color: var(--charcoal-color-text-placeholder-default);
746
- }
747
-
748
- .charcoal-text-area-counter {
616
+ .charcoal-modal-close-button {
749
617
  position: absolute;
750
- bottom: 9px;
618
+ top: 8px;
751
619
  right: 8px;
752
620
 
753
- line-height: 22px;
754
- font-size: 14px;
755
621
  color: var(--charcoal-color-text-tertiary-default);
622
+ transition: 0.2s color;
756
623
  }
757
- .charcoal-dropdown-selector-root {
758
- display: grid;
759
- grid-template-columns: 1fr;
760
- grid-gap: 4px;
761
- width: 100%;
762
- }
763
-
764
- .charcoal-dropdown-selector-root[aria-disabled='true'] {
765
- cursor: default;
766
- opacity: 0.32;
767
- }
768
-
769
- .charcoal-dropdown-selector-button {
770
- display: grid;
771
- grid-template-columns: 1fr auto;
772
- justify-content: space-between;
773
- align-items: center;
774
-
775
- height: 40px;
776
- width: 100%;
777
- box-sizing: border-box;
778
- border: none;
779
- cursor: pointer;
780
- gap: 4px;
781
-
782
- padding-right: 8px;
783
- padding-left: 8px;
784
- background-color: var(--charcoal-color-container-secondary-default-a);
785
- border-radius: 4px;
786
-
787
- transition:
788
- 0.2s box-shadow,
789
- 0.2s background-color;
790
- }
791
-
792
- .charcoal-dropdown-selector-button:disabled {
793
- cursor: default;
794
- }
795
-
796
- .charcoal-dropdown-selector-button:not(:disabled):focus {
797
- outline: none;
798
- box-shadow: 0 0 0 4px rgba(0, 150, 250, 0.32);
799
- }
800
-
801
- .charcoal-dropdown-selector-button:not(:disabled):focus-visible {
802
- box-shadow: 0 0 0 4px rgba(0, 150, 250, 0.32);
803
- }
804
-
805
- .charcoal-dropdown-selector-button:not(:disabled)[data-active='true'],
806
- .charcoal-dropdown-selector-button:not(:disabled):active {
807
- background-color: var(--charcoal-color-container-secondary-press-a);
808
- }
809
-
810
- .charcoal-dropdown-selector-button:not(:disabled):hover {
811
- background-color: var(--charcoal-color-container-secondary-hover-a);
812
- }
813
-
814
- .charcoal-dropdown-selector-button:not(:disabled):focus:not(:focus-visible) {
815
- box-shadow: none;
816
- }
817
-
818
- .charcoal-dropdown-selector-button[aria-invalid='true'],
819
- .charcoal-dropdown-selector-button:not(:disabled)[aria-invalid='true']:focus:not(:focus-visible) {
820
- box-shadow: 0 0 0 4px rgba(255, 43, 0, 0.32);
821
- }
822
-
823
- .charcoal-ui-dropdown-selector-text {
824
- text-align: left;
825
- font-size: 14px;
826
- line-height: 22px;
827
- display: flow-root;
828
- color: var(--charcoal-color-text-default);
829
- overflow: hidden;
830
- text-overflow: ellipsis;
831
- white-space: nowrap;
832
- }
833
-
834
- .charcoal-ui-dropdown-selector-text[data-placeholder='true'] {
835
- color: var(--charcoal-color-text-placeholder-default);
836
- }
837
-
838
- .charcoal-ui-dropdown-selector-icon {
839
- color: var(--charcoal-color-icon-secondary-default);
840
- }
841
- .charcoal-checkbox__label {
842
- position: relative;
843
- cursor: pointer;
844
- display: flex;
845
- gap: 4px;
846
- }
847
-
848
- .charcoal-checkbox__label[aria-disabled='true'] {
849
- cursor: default;
850
- opacity: 0.32;
851
- }
852
-
853
- .charcoal-checkbox__label[aria-disabled='true'] > input {
854
- opacity: 1;
855
- }
856
624
 
857
- .charcoal-checkbox__label_div {
858
- flex: 1;
859
- color: var(--charcoal-color-text-default);
860
- font-size: 14px;
861
- line-height: 20px;
625
+ .charcoal-modal-title {
626
+ margin: 0;
627
+ font-weight: inherit;
628
+ font-size: inherit;
862
629
  }
863
630
  .charcoal-icon {
864
631
  display: inline-flex;
@@ -903,20 +670,100 @@ pixiv-icon:not(:defined)[name^='Inline/'] {
903
670
  pixiv-icon:not(:defined)[name^='Inline/'][scale='2'] {
904
671
  --pixiv-icon-scale: 2;
905
672
  }
906
- .charcoal-dropdown-selector-menu-item {
907
- font-size: 14px;
908
- line-height: 22px;
909
- color: var(--charcoal-color-text-secondary-default);
910
- padding: 9px 0;
911
-
912
- display: flex;
913
- align-items: center;
914
- width: 100%;
915
- margin-left: 20px;
673
+ .charcoal-loading-spinner {
674
+ box-sizing: content-box;
675
+ margin: auto;
676
+ padding: 16px;
677
+ border-radius: 8px;
678
+ font-size: 48px;
679
+ width: 48px;
680
+ height: 48px;
681
+ opacity: 0.84;
682
+ color: var(--charcoal-color-icon-tertiary-default);
683
+ background-color: var(--charcoal-color-background-default);
916
684
  }
917
685
 
918
- .charcoal-dropdown-selector-menu-item[data-selected='true'] {
919
- margin-left: 0px;
686
+ .charcoal-loading-spinner[data-transparent='true'] {
687
+ background-color: transparent;
688
+ }
689
+
690
+ @keyframes charcoal-loading-spinner-icon-scale-out {
691
+ from {
692
+ transform: scale(0);
693
+ opacity: 1;
694
+ }
695
+ to {
696
+ transform: scale(1);
697
+ opacity: 0;
698
+ }
699
+ }
700
+
701
+ .charcoal-loading-spinner-icon {
702
+ width: 1em;
703
+ height: 1em;
704
+ border-radius: 1em;
705
+ background-color: currentColor;
706
+ animation: charcoal-loading-spinner-icon-scale-out 1s infinite both ease-out;
707
+ }
708
+
709
+ .charcoal-loading-spinner-icon[data-reset-animation] {
710
+ animation: none;
711
+ }
712
+
713
+ .charcoal-loading-spinner-icon[data-once='true'] {
714
+ animation-iteration-count: 1;
715
+ }
716
+ .charcoal-radio__label {
717
+ display: grid;
718
+ grid-template-columns: auto 1fr;
719
+ grid-gap: 4px;
720
+ align-items: center;
721
+ cursor: pointer;
722
+ }
723
+
724
+ .charcoal-radio__label[aria-disabled]:not([aria-disabled='false']) {
725
+ opacity: 0.32;
726
+ cursor: default;
727
+ }
728
+
729
+ .charcoal-radio__label_div {
730
+ font-size: 14px;
731
+ line-height: 22px;
732
+ color: var(--charcoal-color-text-default);
733
+ }
734
+ .charcoal-menu-item-group {
735
+ display: block;
736
+ }
737
+
738
+ .charcoal-menu-item-group > span {
739
+ display: block;
740
+ color: var(--charcoal-color-text-tertiary-default);
741
+ font-size: 12px;
742
+ font-weight: bold;
743
+ padding: 12px 0 8px 16px;
744
+ }
745
+
746
+ .charcoal-menu-item-group > ul {
747
+ padding-left: 0;
748
+ margin: 0;
749
+ box-sizing: border-box;
750
+ list-style: none;
751
+ overflow: hidden;
752
+ }
753
+ .charcoal-dropdown-selector-menu-item {
754
+ font-size: 14px;
755
+ line-height: 22px;
756
+ color: var(--charcoal-color-text-secondary-default);
757
+ padding: 9px 0;
758
+
759
+ display: flex;
760
+ align-items: center;
761
+ width: 100%;
762
+ margin-left: 20px;
763
+ }
764
+
765
+ .charcoal-dropdown-selector-menu-item[data-selected='true'] {
766
+ margin-left: 0px;
920
767
  }
921
768
 
922
769
  .charcoal-dropdown-selector-menu-item-icon {
@@ -943,29 +790,181 @@ pixiv-icon:not(:defined)[name^='Inline/'][scale='2'] {
943
790
  .charcoal-dropdown-selector-menu-fullwidth {
944
791
  width: 100%;
945
792
  }
946
- .charcoal-switch__label {
947
- display: inline-grid;
793
+ .charcoal-multi-select {
794
+ display: grid;
948
795
  grid-template-columns: auto 1fr;
949
796
  align-items: center;
797
+ position: relative;
950
798
  cursor: pointer;
951
- outline: 0;
952
799
  gap: 4px;
953
800
  }
954
801
 
955
- .charcoal-switch__label[aria-disabled='true'] {
802
+ .charcoal-multi-select:disabled,
803
+ .charcoal-multi-select[aria-disabled]:not([aria-disabled='false']) {
956
804
  opacity: 0.32;
957
805
  cursor: default;
958
806
  }
959
807
 
960
- .charcoal-switch__label[aria-disabled='true'] > input {
961
- opacity: 1;
962
- }
963
-
964
- .charcoal-switch__label_div {
808
+ .charcoal-multi-select-label {
809
+ display: flow-root;
810
+ align-items: center;
965
811
  font-size: 14px;
966
812
  line-height: 22px;
967
813
  color: var(--charcoal-color-text-default);
968
814
  }
815
+
816
+ .charcoal-multi-select-label::before {
817
+ display: block;
818
+ width: 0;
819
+ height: 0;
820
+ content: '';
821
+ margin-top: -4px;
822
+ }
823
+
824
+ .charcoal-multi-select-label::after {
825
+ display: block;
826
+ width: 0;
827
+ height: 0;
828
+ content: '';
829
+ margin-bottom: -4px;
830
+ }
831
+
832
+ .charcoal-multi-select-input[type='checkbox'] {
833
+ -webkit-appearance: none;
834
+ -moz-appearance: none;
835
+ appearance: none;
836
+ display: block;
837
+ width: 20px;
838
+ height: 20px;
839
+ margin: 0;
840
+ background-color: var(--charcoal-color-container-neutral-default);
841
+ border-radius: 999999px;
842
+ transition:
843
+ 0.2s background-color,
844
+ 0.2s box-shadow;
845
+ }
846
+
847
+ .charcoal-multi-select-input[type='checkbox']:checked {
848
+ background-color: var(--charcoal-color-container-primary-default);
849
+ }
850
+
851
+ .charcoal-multi-select-input[type='checkbox']:focus {
852
+ outline: none;
853
+ box-shadow: 0 0 0 4px rgba(0, 150, 250, 0.32);
854
+ }
855
+
856
+ .charcoal-multi-select-input[type='checkbox']:focus-visible {
857
+ box-shadow: 0 0 0 4px rgba(0, 150, 250, 0.32);
858
+ }
859
+
860
+ .charcoal-multi-select-input[type='checkbox']:focus:not(:focus-visible) {
861
+ box-shadow: none;
862
+ }
863
+
864
+ .charcoal-multi-select-input[type='checkbox']:hover:not(:disabled):not([aria-disabled]),
865
+ .charcoal-multi-select-input[type='checkbox']:hover[aria-disabled='false'] {
866
+ background-color: var(--charcoal-color-container-neutral-hover);
867
+ }
868
+
869
+ .charcoal-multi-select-input[type='checkbox']:active:not(:disabled):not([aria-disabled]),
870
+ .charcoal-multi-select-input[type='checkbox']:active[aria-disabled='false'] {
871
+ background-color: var(--charcoal-color-container-neutral-press);
872
+ }
873
+
874
+ .charcoal-multi-select-input[type='checkbox']:checked:hover:not(:disabled):not([aria-disabled]),
875
+ .charcoal-multi-select-input[type='checkbox']:checked:hover[aria-disabled='false'] {
876
+ background-color: var(--charcoal-color-container-primary-hover);
877
+ }
878
+
879
+ .charcoal-multi-select-input[type='checkbox']:checked:active:not(:disabled):not([aria-disabled]),
880
+ .charcoal-multi-select-input[type='checkbox']:checked:active[aria-disabled='false'] {
881
+ background-color: var(--charcoal-color-container-primary-press);
882
+ }
883
+
884
+ .charcoal-multi-select-input[type='checkbox'][aria-invalid='true'][data-overlay='false']:not(:disabled):not(
885
+ [aria-disabled]
886
+ ) {
887
+ box-shadow: 0 0 0 4px rgba(255, 43, 0, 0.32);
888
+ }
889
+
890
+ .charcoal-multi-select-input[type='checkbox'][aria-invalid='true'][data-overlay='false'][aria-disabled='false'] {
891
+ box-shadow: 0 0 0 4px rgba(255, 43, 0, 0.32);
892
+ }
893
+
894
+ .charcoal-multi-select-input[type='checkbox'][data-overlay='true'] {
895
+ background-color: var(--charcoal-color-container-on-img-default);
896
+ }
897
+
898
+ .charcoal-multi-select-overlay {
899
+ position: absolute;
900
+ top: -2px;
901
+ left: -2px;
902
+ box-sizing: border-box;
903
+ display: flex;
904
+ align-items: center;
905
+ justify-content: center;
906
+ width: 24px;
907
+ height: 24px;
908
+ border-radius: 999999px;
909
+ color: var(--charcoal-color-icon-on-primary-default);
910
+ transition: 0.2s box-shadow;
911
+ }
912
+
913
+ .charcoal-multi-select-overlay[aria-invalid='true'][data-overlay='true']:not(:disabled):not(
914
+ [aria-disabled]
915
+ ) {
916
+ box-shadow: 0 0 0 4px rgba(255, 43, 0, 0.32);
917
+ }
918
+
919
+ .charcoal-multi-select-overlay[aria-invalid='true'][data-overlay='true'][aria-disabled='false'] {
920
+ box-shadow: 0 0 0 4px rgba(255, 43, 0, 0.32);
921
+ }
922
+
923
+ .charcoal-multi-select-overlay[data-overlay='true'] {
924
+ border-color: var(--charcoal-color-border-hud);
925
+ border-width: 2px;
926
+ border-style: solid;
927
+ }
928
+ .charcoal-modal-header-root {
929
+ height: 64px;
930
+ display: grid;
931
+ align-content: center;
932
+ justify-content: center;
933
+ }
934
+
935
+ @media (max-width: 743px) {
936
+ .charcoal-modal-header-root[data-bottom-sheet='true'],
937
+ .charcoal-modal-header-root[data-bottom-sheet='full'] {
938
+ height: 48px;
939
+ }
940
+ }
941
+
942
+ .charcoal-modal-header-title {
943
+ color: var(--charcoal-color-text-default);
944
+ font-size: 16px;
945
+ line-height: 24px;
946
+ font-weight: bold;
947
+ display: flow-root;
948
+ }
949
+
950
+ .charcoal-modal-align {
951
+ padding-left: 16px;
952
+ padding-right: 16px;
953
+ }
954
+
955
+ .charcoal-modal-body {
956
+ padding-bottom: 40px;
957
+ }
958
+
959
+ .charcoal-modal-buttons {
960
+ display: grid;
961
+ grid-auto-flow: row;
962
+ grid-row-gap: 8px;
963
+
964
+ padding-top: 16px;
965
+ padding-left: 16px;
966
+ padding-right: 16px;
967
+ }
969
968
  .charcoal-segmented-control {
970
969
  display: inline-flex;
971
970
  align-items: center;
@@ -1037,294 +1036,729 @@ pixiv-icon:not(:defined)[name^='Inline/'][scale='2'] {
1037
1036
  white-space: nowrap;
1038
1037
  opacity: 0;
1039
1038
  }
1040
- .charcoal-modal-background {
1041
- overflow: auto;
1039
+ .charcoal-checkbox__label {
1040
+ position: relative;
1041
+ cursor: pointer;
1042
1042
  display: flex;
1043
- position: fixed;
1044
- top: 0;
1045
- left: 0;
1043
+ gap: 4px;
1044
+ }
1045
+
1046
+ .charcoal-checkbox__label[aria-disabled='true'] {
1047
+ cursor: default;
1048
+ opacity: 0.32;
1049
+ }
1050
+
1051
+ .charcoal-checkbox__label[aria-disabled='true'] > input {
1052
+ opacity: 1;
1053
+ }
1054
+
1055
+ .charcoal-checkbox__label_div {
1056
+ flex: 1;
1057
+ color: var(--charcoal-color-text-default);
1058
+ font-size: 14px;
1059
+ line-height: 20px;
1060
+ }
1061
+ .charcoal-dropdown-selector-root {
1062
+ display: grid;
1063
+ grid-template-columns: 1fr;
1064
+ grid-gap: 4px;
1065
+ width: 100%;
1066
+ }
1067
+
1068
+ .charcoal-dropdown-selector-root[aria-disabled='true'] {
1069
+ cursor: default;
1070
+ opacity: 0.32;
1071
+ }
1072
+
1073
+ .charcoal-dropdown-selector-button {
1074
+ display: grid;
1075
+ grid-template-columns: 1fr auto;
1076
+ justify-content: space-between;
1077
+ align-items: center;
1078
+
1079
+ height: 40px;
1046
1080
  width: 100%;
1047
- height: 100%;
1048
- justify-content: center;
1049
- padding: 40px 0;
1050
1081
  box-sizing: border-box;
1082
+ border: none;
1083
+ cursor: pointer;
1084
+ gap: 4px;
1051
1085
 
1052
- background-color: var(--charcoal-color-background-overlay);
1086
+ padding-right: 8px;
1087
+ padding-left: 8px;
1088
+ background-color: var(--charcoal-color-container-secondary-default-a);
1089
+ border-radius: 4px;
1090
+
1091
+ transition:
1092
+ 0.2s box-shadow,
1093
+ 0.2s background-color;
1053
1094
  }
1054
1095
 
1055
- @media (max-width: 743px) {
1056
- .charcoal-modal-background[data-bottom-sheet='true'],
1057
- .charcoal-modal-background[data-bottom-sheet='full'] {
1058
- padding: 0;
1096
+ .charcoal-dropdown-selector-button:disabled {
1097
+ cursor: default;
1098
+ }
1099
+
1100
+ .charcoal-dropdown-selector-button:not(:disabled):focus {
1101
+ outline: none;
1102
+ box-shadow: 0 0 0 4px rgba(0, 150, 250, 0.32);
1059
1103
  }
1104
+
1105
+ .charcoal-dropdown-selector-button:not(:disabled):focus-visible {
1106
+ box-shadow: 0 0 0 4px rgba(0, 150, 250, 0.32);
1107
+ }
1108
+
1109
+ .charcoal-dropdown-selector-button:not(:disabled)[data-active='true'],
1110
+ .charcoal-dropdown-selector-button:not(:disabled):active {
1111
+ background-color: var(--charcoal-color-container-secondary-press-a);
1112
+ }
1113
+
1114
+ .charcoal-dropdown-selector-button:not(:disabled):hover {
1115
+ background-color: var(--charcoal-color-container-secondary-hover-a);
1116
+ }
1117
+
1118
+ .charcoal-dropdown-selector-button:not(:disabled):focus:not(:focus-visible) {
1119
+ box-shadow: none;
1120
+ }
1121
+
1122
+ .charcoal-dropdown-selector-button[aria-invalid='true'],
1123
+ .charcoal-dropdown-selector-button:not(:disabled)[aria-invalid='true']:focus:not(:focus-visible) {
1124
+ box-shadow: 0 0 0 4px rgba(255, 43, 0, 0.32);
1060
1125
  }
1061
1126
 
1062
- /* easeOutQuart。duration は useTransitionPresence の MODAL_TRANSITION_DURATION_MS と一致させること。
1063
- transition は entering / exiting に限定し、開いたままテーマ切り替え等で
1064
- 色や transform が変わってもアニメーションしないようにする */
1065
- .charcoal-modal-background[data-animation] {
1127
+ .charcoal-ui-dropdown-selector-text {
1128
+ text-align: left;
1129
+ font-size: 14px;
1130
+ line-height: 22px;
1131
+ display: flow-root;
1132
+ color: var(--charcoal-color-text-default);
1066
1133
  overflow: hidden;
1134
+ text-overflow: ellipsis;
1135
+ white-space: nowrap;
1067
1136
  }
1068
1137
 
1069
- .charcoal-modal-background[data-animation='entering'],
1070
- .charcoal-modal-background[data-animation='exiting'] {
1071
- transition: background-color 400ms cubic-bezier(0.25, 1, 0.5, 1);
1138
+ .charcoal-ui-dropdown-selector-text[data-placeholder='true'] {
1139
+ color: var(--charcoal-color-text-placeholder-default);
1140
+ }
1141
+
1142
+ .charcoal-ui-dropdown-selector-icon {
1143
+ color: var(--charcoal-color-icon-secondary-default);
1072
1144
  }
1145
+ .charcoal-radio-group {
1146
+ display: grid;
1147
+ grid-template-columns: 1fr;
1148
+ grid-gap: 8px;
1149
+ }
1150
+ .charcoal-text-ellipsis {
1151
+ /* Runtime variables overridden by the React component. */
1152
+ --charcoal-text-ellipsis-line-limit: 1;
1153
+ --charcoal-text-ellipsis-line-height: inherit;
1073
1154
 
1074
- /* 閉じアニメーション中はクリックを下のページへ通す(transitionend が来ない環境で
1075
- 透明なオーバーレイがタップを奪い続けるのも防ぐ) */
1076
- .charcoal-modal-background[data-animation='exited'],
1077
- .charcoal-modal-background[data-animation='exiting'] {
1155
+ overflow: hidden;
1156
+ overflow-wrap: break-word;
1157
+ display: -webkit-box;
1158
+ -webkit-box-orient: vertical;
1159
+ -webkit-line-clamp: var(--charcoal-text-ellipsis-line-limit);
1160
+ }
1161
+
1162
+ .charcoal-text-ellipsis[data-has-line-height='true'] {
1163
+ line-height: var(--charcoal-text-ellipsis-line-height);
1164
+ }
1165
+
1166
+ .charcoal-text-ellipsis[data-has-line-height='false'] {
1167
+ line-height: inherit;
1168
+ }
1169
+
1170
+ .charcoal-text-ellipsis[data-line-limit='1'][data-use-nowrap='true'] {
1171
+ text-overflow: ellipsis;
1172
+ white-space: nowrap;
1173
+ }
1174
+ .charcoal-pagination {
1175
+ display: flex;
1176
+ justify-content: center;
1177
+ align-items: center;
1178
+ }
1179
+
1180
+ .charcoal-pagination[data-size='S'] .charcoal-pagination-button {
1181
+ min-width: 32px;
1182
+ min-height: 32px;
1183
+ }
1184
+
1185
+ .charcoal-pagination[data-size='M'] .charcoal-pagination-button {
1186
+ min-width: 40px;
1187
+ min-height: 40px;
1188
+ }
1189
+
1190
+ /* stylelint-disable no-descending-specificity */
1191
+ .charcoal-pagination-button {
1192
+ cursor: pointer;
1193
+ -webkit-appearance: none;
1194
+ -moz-appearance: none;
1195
+ appearance: none;
1196
+ padding: 0;
1197
+ border-style: none;
1198
+ outline: none;
1199
+ text-decoration: none;
1200
+ font-family: inherit;
1201
+ font-style: inherit;
1202
+ font-variant: inherit;
1203
+ margin: 0;
1204
+ -webkit-user-select: none;
1205
+ -moz-user-select: none;
1206
+ user-select: none;
1207
+
1208
+ display: flex;
1209
+ align-items: center;
1210
+ justify-content: center;
1211
+ font-size: 14px;
1212
+ font-weight: 700;
1213
+ line-height: 22px;
1214
+
1215
+ /* HACK:
1216
+ * Safari doesn't correctly repaint the elements when they're reordered in response to interaction.
1217
+ * This forces it to repaint them. This doesn't work if put on the parents either, has to be here.
1218
+ */
1219
+ -webkit-transform: translateZ(0);
1220
+
1221
+ color: var(--charcoal-color-text-tertiary-default);
1078
1222
  background-color: transparent;
1079
- pointer-events: none;
1223
+ border-radius: 20px;
1224
+ transition:
1225
+ 0.2s background-color,
1226
+ 0.2s box-shadow;
1227
+ }
1228
+ .charcoal-pagination-button:focus {
1229
+ outline: none;
1230
+ }
1231
+ .charcoal-pagination-button::-moz-focus-inner {
1232
+ border-style: none;
1233
+ padding: 0;
1234
+ }
1235
+ .charcoal-pagination-button[hidden] {
1236
+ visibility: hidden;
1237
+ display: block;
1238
+ }
1239
+ .charcoal-pagination-button:not(:disabled):not([aria-disabled]):hover,
1240
+ .charcoal-pagination-button[aria-disabled='false']:hover {
1241
+ color: var(--charcoal-color-text-tertiary-default);
1242
+ background-color: var(--charcoal-color-container-secondary-default);
1243
+ }
1244
+ .charcoal-pagination-button:not(:disabled):not([aria-disabled]):active,
1245
+ .charcoal-pagination-button[aria-disabled='false']:active {
1246
+ color: var(--charcoal-color-text-tertiary-press);
1247
+ background-color: var(--charcoal-color-container-tertiary-press);
1248
+ }
1249
+ .charcoal-pagination-button:not(:disabled):not([aria-disabled]):focus,
1250
+ .charcoal-pagination-button[aria-disabled='false']:focus {
1251
+ outline: none;
1252
+ box-shadow: 0 0 0 4px rgba(0, 150, 250, 0.32);
1253
+ }
1254
+ .charcoal-pagination-button:not(:disabled):not([aria-disabled]):focus-visible,
1255
+ .charcoal-pagination-button[aria-disabled='false']:focus-visible {
1256
+ box-shadow: 0 0 0 4px rgba(0, 150, 250, 0.32);
1257
+ }
1258
+ .charcoal-pagination-button:not(:disabled):not([aria-disabled]):focus:not(:focus-visible),
1259
+ .charcoal-pagination-button[aria-disabled='false']:focus:not(:focus-visible) {
1260
+ box-shadow: none;
1261
+ }
1262
+ .charcoal-pagination-button[aria-current] {
1263
+ cursor: default;
1264
+ background-color: var(--charcoal-color-container-hud-default);
1265
+ color: var(--charcoal-color-text-on-hud-default);
1266
+ }
1267
+ .charcoal-pagination-button[aria-current]:not(:disabled):not([aria-disabled]):hover,
1268
+ .charcoal-pagination-button[aria-current]:not(:disabled):not([aria-disabled]):active {
1269
+ background-color: var(--charcoal-color-container-hud-default);
1270
+ color: var(--charcoal-color-text-on-hud-default);
1271
+ }
1272
+ /* stylelint-enable no-descending-specificity */
1273
+
1274
+ .charcoal-pagination-nav-button[data-hidden] {
1275
+ visibility: hidden;
1276
+ }
1277
+
1278
+ .charcoal-pagination-spacer,
1279
+ .charcoal-pagination-spacer:hover,
1280
+ .charcoal-pagination-spacer:active {
1281
+ cursor: default;
1282
+ color: var(--charcoal-color-text-tertiary-default);
1283
+ background: none;
1284
+ }
1285
+
1286
+ .charcoal-pagination-spacer.charcoal-icon-button:disabled {
1287
+ opacity: 1;
1288
+ }
1289
+ .charcoal-tag-item {
1290
+ --charcoal-tag-item-color: var(--charcoal-color-text-on-primary-default);
1291
+ --charcoal-tag-item-size: 40px;
1292
+ --charcoal-tag-item-padding-left: 24px;
1293
+ --charcoal-tag-item-padding-right: 24px;
1294
+ --charcoal-tag-item-bg: ;
1295
+
1296
+ isolation: isolate;
1297
+ position: relative;
1298
+
1299
+ -webkit-appearance: none;
1300
+
1301
+ -moz-appearance: none;
1302
+
1303
+ appearance: none;
1304
+ outline: none;
1305
+ border-style: none;
1306
+
1307
+ display: inline-flex;
1308
+ gap: 8px;
1309
+ align-items: center;
1310
+ justify-content: center;
1311
+
1312
+ text-decoration: none;
1313
+ cursor: pointer;
1314
+ overflow: hidden;
1315
+
1316
+ color: var(--charcoal-tag-item-color);
1317
+ height: var(--charcoal-tag-item-size);
1318
+ padding-top: 4px;
1319
+ padding-bottom: 4px;
1320
+ padding-left: var(--charcoal-tag-item-padding-left);
1321
+ padding-right: var(--charcoal-tag-item-padding-right);
1322
+ box-sizing: border-box;
1323
+ border-radius: 4px;
1324
+
1325
+ transition: 0.2s box-shadow;
1326
+ }
1327
+
1328
+ .charcoal-tag-item[data-size='M'] {
1329
+ --charcoal-tag-item-size: 40px;
1330
+ --charcoal-tag-item-padding-left: 24px;
1331
+ --charcoal-tag-item-padding-right: 24px;
1332
+ }
1333
+
1334
+ .charcoal-tag-item[data-size='S'] {
1335
+ --charcoal-tag-item-size: 32px;
1336
+ --charcoal-tag-item-padding-left: 16px;
1337
+ --charcoal-tag-item-padding-right: 16px;
1338
+ }
1339
+
1340
+ .charcoal-tag-item[data-state='inactive'] {
1341
+ --charcoal-tag-item-color: var(--charcoal-color-text-secondary-default);
1342
+ }
1343
+
1344
+ .charcoal-tag-item[data-state='active'] {
1345
+ --charcoal-tag-item-padding-left: 16px;
1346
+ --charcoal-tag-item-padding-right: 8px;
1347
+ }
1348
+
1349
+ .charcoal-tag-item:disabled,
1350
+ .charcoal-tag-item[aria-disabled]:not([aria-disabled='false']) {
1351
+ opacity: 0.32;
1352
+ cursor: default;
1353
+ }
1354
+
1355
+ .charcoal-tag-item:not(:disabled):not([aria-disabled]):focus-visible,
1356
+ .charcoal-tag-item[aria-disabled='false']:focus-visible {
1357
+ outline: none;
1358
+ box-shadow: 0 0 0 4px rgba(0, 150, 250, 0.32);
1359
+ }
1360
+
1361
+ .charcoal-tag-item:not(:disabled):not([aria-disabled]):focus,
1362
+ .charcoal-tag-item[aria-disabled='false']:focus {
1363
+ outline: none;
1364
+ box-shadow: 0 0 0 4px rgba(0, 150, 250, 0.32);
1365
+ }
1366
+
1367
+ .charcoal-tag-item:not(:disabled):not([aria-disabled]):focus:not(:focus-visible),
1368
+ .charcoal-tag-item[aria-disabled='false']:focus:not(:focus-visible) {
1369
+ box-shadow: none;
1370
+ }
1371
+
1372
+ .charcoal-tag-item__bg {
1373
+ background-color: var(--charcoal-tag-item-bg);
1374
+ }
1375
+
1376
+ .charcoal-tag-item__bg[data-bg-variant='image'] {
1377
+ background-color: var(--charcoal-color-container-on-img-default);
1378
+ }
1379
+
1380
+ .charcoal-tag-item__bg[data-bg-variant='image']::before {
1381
+ content: '';
1382
+ position: absolute;
1383
+ z-index: 1;
1384
+ top: 0;
1385
+ left: 0;
1386
+ width: 100%;
1387
+ height: 100%;
1388
+ background-position: center;
1389
+ background-size: cover;
1390
+ background-image: var(--charcoal-tag-item-bg);
1391
+ mix-blend-mode: overlay;
1392
+ }
1393
+
1394
+ .charcoal-tag-item__bg[data-state='inactive'] {
1395
+ background-color: var(--charcoal-color-container-secondary-default);
1396
+ }
1397
+
1398
+ .charcoal-tag-item__label {
1399
+ height: 100%;
1400
+ display: flex;
1401
+ flex-direction: column;
1402
+ align-items: center;
1403
+ justify-content: center;
1404
+ }
1405
+
1406
+ .charcoal-tag-item__label[data-has-translate='true'] {
1407
+ justify-content: space-between;
1408
+ }
1409
+
1410
+ .charcoal-tag-item__label__translated {
1411
+ --charcoal-tag-item-text-font-size: 12px;
1412
+ --charcoal-tag-item-text-line-height: 20px;
1413
+ font-weight: bold;
1414
+ }
1415
+
1416
+ .charcoal-tag-item__label__translated::before {
1417
+ display: none;
1418
+ }
1419
+
1420
+ .charcoal-tag-item__label__text {
1421
+ --charcoal-tag-item-text-font-size: 14px;
1422
+ --charcoal-tag-item-text-line-height: 22px;
1423
+
1424
+ max-width: 152px;
1425
+ overflow: hidden;
1426
+ font-weight: bold;
1427
+
1428
+ color: inherit;
1429
+ white-space: nowrap;
1430
+ text-overflow: ellipsis;
1431
+ }
1432
+
1433
+ .charcoal-tag-item__label__text[data-has-translate='true'] {
1434
+ --charcoal-tag-item-text-font-size: 10px;
1435
+ --charcoal-tag-item-text-line-height: 14px;
1436
+ font-weight: normal;
1437
+ }
1438
+
1439
+ /* Kept flat: different class name from .charcoal-tag-item__label__text (note: "labe" typo in original) */
1440
+ .charcoal-tag-item__labe__text[data-has-translate='true']::after {
1441
+ display: none;
1442
+ }
1443
+ .charcoal-carousel {
1444
+ --charcoal-carousel-gap: 0px;
1445
+
1446
+ position: relative;
1447
+ display: block;
1448
+ }
1449
+
1450
+ .charcoal-carousel[data-full-width='true'] {
1451
+ width: 100vw;
1452
+ margin-inline: calc(50% - 50vw);
1453
+ }
1454
+
1455
+ .charcoal-carousel__viewport {
1456
+ position: relative;
1457
+ }
1458
+
1459
+ /* フォーカスリングは scroller ではなく viewport に描く。scroller に置くと
1460
+ hasGradient の mask(mask-clip: border-box)で外側の box-shadow ごと消えるため。 */
1461
+
1462
+ .charcoal-carousel__viewport[data-focus-visible] {
1463
+ box-shadow: 0 0 0 4px rgba(0, 150, 250, 0.32);
1464
+ }
1465
+
1466
+ /* スライド間隔は gap prop(--charcoal-carousel-gap)で注入する。
1467
+ スライド寸法は sandbox 同様、利用者が children 側で持つ。 */
1468
+ .charcoal-carousel__scroller {
1469
+ position: relative;
1470
+ display: flex;
1471
+ gap: var(--charcoal-carousel-gap);
1472
+ overflow-x: auto;
1473
+ overflow-y: hidden;
1474
+ overscroll-behavior-x: contain;
1475
+ scroll-behavior: smooth;
1476
+ scrollbar-width: none;
1477
+ outline: none;
1478
+ }
1479
+ .charcoal-carousel__scroller::-webkit-scrollbar {
1480
+ display: none;
1481
+ }
1482
+
1483
+ /* スクロールスナップ type は prop(scrollSnap.type)で scroller に出し分ける。
1484
+ align は基底 .charcoal-carousel__item の後(後述)に置く(no-descending-specificity 回避)。
1485
+ 未指定時の既定(M=none / S=mandatory / align=center)は JS 側で data 属性に解決する。 */
1486
+ .charcoal-carousel[data-scroll-snap-type='none'] .charcoal-carousel__scroller {
1487
+ scroll-snap-type: none;
1488
+ }
1489
+
1490
+ .charcoal-carousel[data-scroll-snap-type='proximity']
1491
+ .charcoal-carousel__scroller {
1492
+ scroll-snap-type: x proximity;
1080
1493
  }
1081
1494
 
1082
- .charcoal-modal-background[data-animation='entered'] {
1083
- overflow: auto;
1495
+ .charcoal-carousel[data-scroll-snap-type='mandatory']
1496
+ .charcoal-carousel__scroller {
1497
+ scroll-snap-type: x mandatory;
1084
1498
  }
1085
1499
 
1086
- .charcoal-modal-background[data-animation='entering'] > .charcoal-modal-dialog,
1087
- .charcoal-modal-background[data-animation='exiting'] > .charcoal-modal-dialog {
1088
- transition: transform 400ms cubic-bezier(0.25, 1, 0.5, 1);
1500
+ /* グラデーション: mask で端のアイテム自体を透明へフェードさせる(下の背景色を
1501
+ 問わない)。mask の色はアルファとしてだけ効く(#000=表示 / transparent=透過)。
1502
+ 左フェード・右フェードの 2 レイヤーを intersect で合成し、はみ出して
1503
+ スクロール可能な側のみ data-can-prev/next で 72px のフェード帯を枠内に置く。
1504
+ 無効な側はフェード帯ごと枠外へスライドして隠す(mask-image と違い
1505
+ mask-position は補間可能なので、切替が 0.2s のフェードになる)。 */
1506
+ .charcoal-carousel[data-has-gradient='true'] .charcoal-carousel__scroller {
1507
+ -webkit-mask-image:
1508
+ linear-gradient(to right, transparent, #000 72px),
1509
+ linear-gradient(to left, transparent, #000 72px);
1510
+ mask-image:
1511
+ linear-gradient(to right, transparent, #000 72px),
1512
+ linear-gradient(to left, transparent, #000 72px);
1513
+ /* 枠外へ 72px スライドしても反対側の端が欠けないよう、レイヤー幅に 72px 足す */
1514
+ -webkit-mask-size: calc(100% + 72px) 100%;
1515
+ mask-size: calc(100% + 72px) 100%;
1516
+ -webkit-mask-repeat: no-repeat;
1517
+ mask-repeat: no-repeat;
1518
+ -webkit-mask-composite: source-in, xor;
1519
+ mask-composite: intersect;
1520
+ -webkit-mask-position:
1521
+ -72px 0,
1522
+ 0 0;
1523
+ mask-position:
1524
+ -72px 0,
1525
+ 0 0;
1526
+ /* 0.2s ease-in は react-sandbox の LeftGradient と同じ値 */
1527
+ transition: 0.2s ease-in mask-position;
1089
1528
  }
1090
1529
 
1091
- .charcoal-modal-background[data-animation='exited'] > .charcoal-modal-dialog,
1092
- .charcoal-modal-background[data-animation='exiting'] > .charcoal-modal-dialog {
1093
- transform: translateY(100%);
1530
+ .charcoal-carousel[data-has-gradient='true'][data-can-prev='true']
1531
+ .charcoal-carousel__scroller {
1532
+ -webkit-mask-position:
1533
+ 0 0,
1534
+ 0 0;
1535
+ mask-position:
1536
+ 0 0,
1537
+ 0 0;
1094
1538
  }
1095
1539
 
1096
- .charcoal-modal-close-button {
1097
- position: absolute;
1098
- top: 8px;
1099
- right: 8px;
1540
+ .charcoal-carousel[data-has-gradient='true'][data-can-next='true']
1541
+ .charcoal-carousel__scroller {
1542
+ -webkit-mask-position:
1543
+ -72px 0,
1544
+ -72px 0;
1545
+ mask-position:
1546
+ -72px 0,
1547
+ -72px 0;
1548
+ }
1100
1549
 
1101
- color: var(--charcoal-color-text-tertiary-default);
1102
- transition: 0.2s color;
1550
+ .charcoal-carousel[data-has-gradient='true'][data-can-prev='true'][data-can-next='true']
1551
+ .charcoal-carousel__scroller {
1552
+ -webkit-mask-position:
1553
+ 0 0,
1554
+ -72px 0;
1555
+ mask-position:
1556
+ 0 0,
1557
+ -72px 0;
1103
1558
  }
1104
1559
 
1105
- .charcoal-modal-title {
1106
- margin: 0;
1107
- font-weight: inherit;
1108
- font-size: inherit;
1560
+ .charcoal-carousel__item {
1561
+ flex: 0 0 auto;
1562
+ min-width: 0;
1109
1563
  }
1110
- .charcoal-tag-item {
1111
- --charcoal-tag-item-color: var(--charcoal-color-text-on-primary-default);
1112
- --charcoal-tag-item-size: 40px;
1113
- --charcoal-tag-item-padding-left: 24px;
1114
- --charcoal-tag-item-padding-right: 24px;
1115
- --charcoal-tag-item-bg: ;
1116
1564
 
1117
- isolation: isolate;
1118
- position: relative;
1565
+ .charcoal-carousel[data-size='S'] .charcoal-carousel__item {
1566
+ flex: 0 0 100%;
1567
+ }
1119
1568
 
1120
- -webkit-appearance: none;
1569
+ /* scroll-snap-align は prop(scrollSnap.align)で出し分ける。基底 .charcoal-carousel__item
1570
+ より後に置くことで no-descending-specificity を回避する。 */
1571
+ .charcoal-carousel[data-scroll-snap-align='center'] .charcoal-carousel__item {
1572
+ scroll-snap-align: center;
1573
+ }
1121
1574
 
1122
- -moz-appearance: none;
1575
+ .charcoal-carousel[data-scroll-snap-align='start'] .charcoal-carousel__item {
1576
+ scroll-snap-align: start;
1577
+ }
1123
1578
 
1124
- appearance: none;
1125
- outline: none;
1126
- border-style: none;
1579
+ /* ── Navigation Buttons (charcoal IconButton, variant=Overlay size=S) ── */
1127
1580
 
1128
- display: inline-flex;
1129
- gap: 8px;
1581
+ /* マスクの透過域と同じ 72px 1fr 72px グリッド。各ボタンは 72px ゾーンの中央に置く。 */
1582
+ .charcoal-carousel__navigation {
1583
+ position: absolute;
1584
+ inset: 0;
1585
+ pointer-events: none;
1586
+ display: grid;
1587
+ grid-template-columns: 72px 1fr 72px;
1130
1588
  align-items: center;
1131
- justify-content: center;
1132
-
1133
- text-decoration: none;
1134
- cursor: pointer;
1135
- overflow: hidden;
1136
-
1137
- color: var(--charcoal-tag-item-color);
1138
- height: var(--charcoal-tag-item-size);
1139
- padding-top: 4px;
1140
- padding-bottom: 4px;
1141
- padding-left: var(--charcoal-tag-item-padding-left);
1142
- padding-right: var(--charcoal-tag-item-padding-right);
1143
- box-sizing: border-box;
1144
- border-radius: 4px;
1145
-
1146
- transition: 0.2s box-shadow;
1589
+ /* アイテム内のコンテンツより上にボタンを表示する */
1590
+ z-index: 1;
1591
+ /* sandbox 同様、通常は隠してカルーセル hover 時にフェードイン表示する。 */
1592
+ opacity: 0;
1593
+ transition: 0.4s opacity;
1147
1594
  }
1148
-
1149
- .charcoal-tag-item[data-size='M'] {
1150
- --charcoal-tag-item-size: 40px;
1151
- --charcoal-tag-item-padding-left: 24px;
1152
- --charcoal-tag-item-padding-right: 24px;
1595
+ .charcoal-carousel__navigation[data-visible='false'] {
1596
+ display: none;
1153
1597
  }
1154
1598
 
1155
- .charcoal-tag-item[data-size='S'] {
1156
- --charcoal-tag-item-size: 32px;
1157
- --charcoal-tag-item-padding-left: 16px;
1158
- --charcoal-tag-item-padding-right: 16px;
1159
- }
1599
+ /* hover で表示。キーボード操作でも到達できるよう、キーボード由来のフォーカスが
1600
+ カルーセル内にある間も表示する(:focus-within だとクリックで残ったフォーカスでも
1601
+ 表示され続けるため、react-aria が付与する data 属性で判定する)。 */
1602
+ .charcoal-carousel:hover .charcoal-carousel__navigation,
1603
+ .charcoal-carousel[data-focus-visible-within] .charcoal-carousel__navigation {
1604
+ opacity: 1;
1605
+ }
1160
1606
 
1161
- .charcoal-tag-item[data-state='inactive'] {
1162
- --charcoal-tag-item-color: var(--charcoal-color-text-secondary-default);
1163
- }
1607
+ .charcoal-carousel__navigation__item {
1608
+ pointer-events: auto;
1609
+ }
1164
1610
 
1165
- .charcoal-tag-item[data-state='active'] {
1166
- --charcoal-tag-item-padding-left: 16px;
1167
- --charcoal-tag-item-padding-right: 8px;
1168
- }
1611
+ /* ヒットエリアをグリッド端列(= mask のフェード帯と同じ 72px)全体へ広げる。
1612
+ 擬似要素上のクリックは元の button に届くため、帯のどこを押してもページ送りになる。
1613
+ position: absolute の基準は positioned な .charcoal-carousel__navigation(inset: 0)。 */
1169
1614
 
1170
- .charcoal-tag-item:disabled,
1171
- .charcoal-tag-item[aria-disabled]:not([aria-disabled='false']) {
1172
- opacity: 0.32;
1173
- cursor: default;
1615
+ .charcoal-carousel__navigation__item::after {
1616
+ content: '';
1617
+ position: absolute;
1618
+ top: 0;
1619
+ bottom: 0;
1620
+ width: 72px;
1174
1621
  }
1175
1622
 
1176
- .charcoal-tag-item:not(:disabled):not([aria-disabled]):focus-visible,
1177
- .charcoal-tag-item[aria-disabled='false']:focus-visible {
1178
- outline: none;
1179
- box-shadow: 0 0 0 4px rgba(0, 150, 250, 0.32);
1623
+ .charcoal-carousel__navigation__item[data-direction='prev'] {
1624
+ grid-column: 1;
1625
+ justify-self: center;
1180
1626
  }
1181
1627
 
1182
- .charcoal-tag-item:not(:disabled):not([aria-disabled]):focus,
1183
- .charcoal-tag-item[aria-disabled='false']:focus {
1184
- outline: none;
1185
- box-shadow: 0 0 0 4px rgba(0, 150, 250, 0.32);
1186
- }
1628
+ .charcoal-carousel__navigation__item[data-direction='prev']::after {
1629
+ left: 0;
1630
+ }
1187
1631
 
1188
- .charcoal-tag-item:not(:disabled):not([aria-disabled]):focus:not(:focus-visible),
1189
- .charcoal-tag-item[aria-disabled='false']:focus:not(:focus-visible) {
1190
- box-shadow: none;
1632
+ .charcoal-carousel__navigation__item[data-direction='next'] {
1633
+ grid-column: 3;
1634
+ justify-self: center;
1191
1635
  }
1192
1636
 
1193
- .charcoal-tag-item__bg {
1194
- background-color: var(--charcoal-tag-item-bg);
1637
+ .charcoal-carousel__navigation__item[data-direction='next']::after {
1638
+ right: 0;
1639
+ }
1640
+
1641
+ /* スクロール端では非表示。IconButton の disabled スタイル(opacity:0.32)より
1642
+ 高い詳細度で打ち消すため、ルートを前置する。 */
1643
+ .charcoal-carousel .charcoal-carousel__navigation__item[data-hidden='true'] {
1644
+ opacity: 0;
1645
+ pointer-events: none;
1195
1646
  }
1196
1647
 
1197
- .charcoal-tag-item__bg[data-bg-variant='image'] {
1198
- background-color: var(--charcoal-color-container-on-img-default);
1648
+ /* タッチデバイスではナビゲーションボタンを出さず、スワイプ操作に委ねる。 */
1649
+ @media (hover: none) and (pointer: coarse) {
1650
+ .charcoal-carousel__navigation {
1651
+ display: none;
1199
1652
  }
1653
+ }
1200
1654
 
1201
- .charcoal-tag-item__bg[data-bg-variant='image']::before {
1202
- content: '';
1203
- position: absolute;
1204
- z-index: 1;
1205
- top: 0;
1206
- left: 0;
1207
- width: 100%;
1208
- height: 100%;
1209
- background-position: center;
1210
- background-size: cover;
1211
- background-image: var(--charcoal-tag-item-bg);
1212
- mix-blend-mode: overlay;
1213
- }
1214
-
1215
- .charcoal-tag-item__bg[data-state='inactive'] {
1216
- background-color: var(--charcoal-color-container-secondary-default);
1217
- }
1655
+ /* ── Indicator: JS Fallback ── */
1218
1656
 
1219
- .charcoal-tag-item__label {
1220
- height: 100%;
1657
+ .charcoal-carousel__indicator {
1221
1658
  display: flex;
1222
- flex-direction: column;
1223
- align-items: center;
1224
1659
  justify-content: center;
1660
+ align-items: center;
1661
+ height: 40px;
1662
+ gap: 8px;
1225
1663
  }
1226
1664
 
1227
- .charcoal-tag-item__label[data-has-translate='true'] {
1228
- justify-content: space-between;
1665
+ .charcoal-carousel__indicator[data-visible='false'] {
1666
+ display: none;
1229
1667
  }
1230
1668
 
1231
- .charcoal-tag-item__label__translated {
1232
- --charcoal-tag-item-text-font-size: 12px;
1233
- --charcoal-tag-item-text-line-height: 20px;
1234
- font-weight: bold;
1669
+ .charcoal-carousel__indicator__item {
1670
+ -webkit-appearance: none;
1671
+ -moz-appearance: none;
1672
+ appearance: none;
1673
+ box-sizing: border-box;
1674
+ width: 8px;
1675
+ height: 8px;
1676
+ padding: 0;
1677
+ border: 0;
1678
+ border-radius: 50%;
1679
+ background-color: var(--charcoal-color-text-tertiary-default);
1680
+ cursor: pointer;
1681
+ transition: 0.2s background-color;
1235
1682
  }
1236
1683
 
1237
- .charcoal-tag-item__label__translated::before {
1238
- display: none;
1684
+ .charcoal-carousel__indicator__item:hover {
1685
+ background-color: var(--charcoal-color-text-secondary-default);
1239
1686
  }
1240
1687
 
1241
- .charcoal-tag-item__label__text {
1242
- --charcoal-tag-item-text-font-size: 14px;
1243
- --charcoal-tag-item-text-line-height: 22px;
1688
+ .charcoal-carousel__indicator__item:focus-visible {
1689
+ outline: 2px solid rgba(0, 150, 250, 0.56);
1690
+ outline-offset: 2px;
1691
+ }
1244
1692
 
1245
- max-width: 152px;
1246
- overflow: hidden;
1247
- font-weight: bold;
1693
+ .charcoal-carousel__indicator__item[data-active='true'] {
1694
+ background-color: var(--charcoal-color-text-default);
1695
+ }
1248
1696
 
1249
- color: inherit;
1250
- white-space: nowrap;
1251
- text-overflow: ellipsis;
1252
- }
1697
+ /* ── CSS Scroll Markers (progressive enhancement) ── */
1253
1698
 
1254
- .charcoal-tag-item__label__text[data-has-translate='true'] {
1255
- --charcoal-tag-item-text-font-size: 10px;
1256
- --charcoal-tag-item-text-line-height: 14px;
1257
- font-weight: normal;
1699
+ /* CSS Scroll Markers / Anchor Positioning の擬似要素・擬似クラスは新しい仕様のため、
1700
+ この @supports ブロックでは該当ルールを無効化する。 */
1701
+ /* stylelint-disable selector-pseudo-class-no-unknown */
1702
+ @supports (scroll-marker-group: after) {
1703
+ .charcoal-carousel[data-indicator='true'] {
1704
+ padding-bottom: 40px;
1258
1705
  }
1259
1706
 
1260
- /* Kept flat: different class name from .charcoal-tag-item__label__text (note: "labe" typo in original) */
1261
- .charcoal-tag-item__labe__text[data-has-translate='true']::after {
1262
- display: none;
1263
- }
1264
- .charcoal-text-ellipsis {
1265
- /* Runtime variables overridden by the React component. */
1266
- --charcoal-text-ellipsis-line-limit: 1;
1267
- --charcoal-text-ellipsis-line-height: inherit;
1707
+ .charcoal-carousel__scroller {
1708
+ anchor-name: --charcoal-carousel;
1709
+ scroll-marker-group: after;
1710
+ }
1268
1711
 
1269
- overflow: hidden;
1270
- overflow-wrap: break-word;
1271
- display: -webkit-box;
1272
- -webkit-box-orient: vertical;
1273
- -webkit-line-clamp: var(--charcoal-text-ellipsis-line-limit);
1274
- }
1712
+ .charcoal-carousel__scroller::scroll-button(*) {
1713
+ content: none;
1714
+ }
1275
1715
 
1276
- .charcoal-text-ellipsis[data-has-line-height='true'] {
1277
- line-height: var(--charcoal-text-ellipsis-line-height);
1278
- }
1716
+ .charcoal-carousel__scroller::scroll-marker-group {
1717
+ display: flex;
1718
+ justify-content: center;
1719
+ align-items: center;
1720
+ height: 40px;
1721
+ gap: 8px;
1279
1722
 
1280
- .charcoal-text-ellipsis[data-has-line-height='false'] {
1281
- line-height: inherit;
1282
- }
1723
+ position: absolute;
1724
+ position-anchor: --charcoal-carousel;
1725
+ top: anchor(bottom);
1726
+ justify-self: anchor-center;
1727
+ }
1283
1728
 
1284
- .charcoal-text-ellipsis[data-line-limit='1'][data-use-nowrap='true'] {
1285
- text-overflow: ellipsis;
1286
- white-space: nowrap;
1729
+ .charcoal-carousel[data-indicator='false'] .charcoal-carousel__scroller {
1730
+ scroll-marker-group: none;
1287
1731
  }
1288
- .charcoal-modal-header-root {
1289
- height: 64px;
1290
- display: grid;
1291
- align-content: center;
1292
- justify-content: center;
1293
- }
1294
1732
 
1295
- @media (max-width: 743px) {
1296
- .charcoal-modal-header-root[data-bottom-sheet='true'],
1297
- .charcoal-modal-header-root[data-bottom-sheet='full'] {
1298
- height: 48px;
1733
+ .charcoal-carousel__item::scroll-marker {
1734
+ content: '';
1735
+ width: 8px;
1736
+ height: 8px;
1737
+ border: 0;
1738
+ border-radius: 50%;
1739
+ background-color: var(--charcoal-color-text-tertiary-default);
1740
+ cursor: pointer;
1741
+ transition: 0.2s background-color;
1299
1742
  }
1300
- }
1301
-
1302
- .charcoal-modal-header-title {
1303
- color: var(--charcoal-color-text-default);
1304
- font-size: 16px;
1305
- line-height: 24px;
1306
- font-weight: bold;
1307
- display: flow-root;
1308
- }
1309
1743
 
1310
- .charcoal-modal-align {
1311
- padding-left: 16px;
1312
- padding-right: 16px;
1313
- }
1744
+ .charcoal-carousel__item::scroll-marker:hover {
1745
+ background-color: var(--charcoal-color-text-secondary-default);
1746
+ }
1314
1747
 
1315
- .charcoal-modal-body {
1316
- padding-bottom: 40px;
1317
- }
1748
+ .charcoal-carousel__item::scroll-marker:focus {
1749
+ outline: 2px solid rgba(0, 150, 250, 0.56);
1750
+ outline-offset: 2px;
1751
+ }
1318
1752
 
1319
- .charcoal-modal-buttons {
1320
- display: grid;
1321
- grid-auto-flow: row;
1322
- grid-row-gap: 8px;
1753
+ .charcoal-carousel__item::scroll-marker:target-current {
1754
+ background-color: var(--charcoal-color-text-default);
1755
+ }
1323
1756
 
1324
- padding-top: 16px;
1325
- padding-left: 16px;
1326
- padding-right: 16px;
1757
+ .charcoal-carousel__indicator {
1758
+ display: none;
1759
+ }
1327
1760
  }
1761
+ /* stylelint-enable selector-pseudo-class-no-unknown */
1328
1762
  .charcoal-hint-text {
1329
1763
  background-color: var(--charcoal-color-container-secondary-default);
1330
1764
  border-radius: 8px;
@@ -1356,126 +1790,11 @@ pixiv-icon:not(:defined)[name^='Inline/'][scale='2'] {
1356
1790
  color: var(--charcoal-color-text-secondary-default);
1357
1791
  font-size: 14px;
1358
1792
  line-height: 22px;
1359
- display: flow-root;
1360
- margin: 0;
1361
- min-width: 0;
1362
- overflow-wrap: break-word;
1363
- }
1364
- .charcoal-pagination {
1365
- display: flex;
1366
- justify-content: center;
1367
- align-items: center;
1368
- }
1369
-
1370
- .charcoal-pagination[data-size='S'] .charcoal-pagination-button {
1371
- min-width: 32px;
1372
- min-height: 32px;
1373
- }
1374
-
1375
- .charcoal-pagination[data-size='M'] .charcoal-pagination-button {
1376
- min-width: 40px;
1377
- min-height: 40px;
1378
- }
1379
-
1380
- /* stylelint-disable no-descending-specificity */
1381
- .charcoal-pagination-button {
1382
- cursor: pointer;
1383
- -webkit-appearance: none;
1384
- -moz-appearance: none;
1385
- appearance: none;
1386
- padding: 0;
1387
- border-style: none;
1388
- outline: none;
1389
- text-decoration: none;
1390
- font-family: inherit;
1391
- font-style: inherit;
1392
- font-variant: inherit;
1393
- margin: 0;
1394
- -webkit-user-select: none;
1395
- -moz-user-select: none;
1396
- user-select: none;
1397
-
1398
- display: flex;
1399
- align-items: center;
1400
- justify-content: center;
1401
- font-size: 14px;
1402
- font-weight: 700;
1403
- line-height: 22px;
1404
-
1405
- /* HACK:
1406
- * Safari doesn't correctly repaint the elements when they're reordered in response to interaction.
1407
- * This forces it to repaint them. This doesn't work if put on the parents either, has to be here.
1408
- */
1409
- -webkit-transform: translateZ(0);
1410
-
1411
- color: var(--charcoal-color-text-tertiary-default);
1412
- background-color: transparent;
1413
- border-radius: 20px;
1414
- transition:
1415
- 0.2s background-color,
1416
- 0.2s box-shadow;
1417
- }
1418
- .charcoal-pagination-button:focus {
1419
- outline: none;
1420
- }
1421
- .charcoal-pagination-button::-moz-focus-inner {
1422
- border-style: none;
1423
- padding: 0;
1424
- }
1425
- .charcoal-pagination-button[hidden] {
1426
- visibility: hidden;
1427
- display: block;
1428
- }
1429
- .charcoal-pagination-button:not(:disabled):not([aria-disabled]):hover,
1430
- .charcoal-pagination-button[aria-disabled='false']:hover {
1431
- color: var(--charcoal-color-text-tertiary-default);
1432
- background-color: var(--charcoal-color-container-secondary-default);
1433
- }
1434
- .charcoal-pagination-button:not(:disabled):not([aria-disabled]):active,
1435
- .charcoal-pagination-button[aria-disabled='false']:active {
1436
- color: var(--charcoal-color-text-tertiary-press);
1437
- background-color: var(--charcoal-color-container-tertiary-press);
1438
- }
1439
- .charcoal-pagination-button:not(:disabled):not([aria-disabled]):focus,
1440
- .charcoal-pagination-button[aria-disabled='false']:focus {
1441
- outline: none;
1442
- box-shadow: 0 0 0 4px rgba(0, 150, 250, 0.32);
1443
- }
1444
- .charcoal-pagination-button:not(:disabled):not([aria-disabled]):focus-visible,
1445
- .charcoal-pagination-button[aria-disabled='false']:focus-visible {
1446
- box-shadow: 0 0 0 4px rgba(0, 150, 250, 0.32);
1447
- }
1448
- .charcoal-pagination-button:not(:disabled):not([aria-disabled]):focus:not(:focus-visible),
1449
- .charcoal-pagination-button[aria-disabled='false']:focus:not(:focus-visible) {
1450
- box-shadow: none;
1451
- }
1452
- .charcoal-pagination-button[aria-current] {
1453
- cursor: default;
1454
- background-color: var(--charcoal-color-container-hud-default);
1455
- color: var(--charcoal-color-text-on-hud-default);
1456
- }
1457
- .charcoal-pagination-button[aria-current]:not(:disabled):not([aria-disabled]):hover,
1458
- .charcoal-pagination-button[aria-current]:not(:disabled):not([aria-disabled]):active {
1459
- background-color: var(--charcoal-color-container-hud-default);
1460
- color: var(--charcoal-color-text-on-hud-default);
1461
- }
1462
- /* stylelint-enable no-descending-specificity */
1463
-
1464
- .charcoal-pagination-nav-button[data-hidden] {
1465
- visibility: hidden;
1466
- }
1467
-
1468
- .charcoal-pagination-spacer,
1469
- .charcoal-pagination-spacer:hover,
1470
- .charcoal-pagination-spacer:active {
1471
- cursor: default;
1472
- color: var(--charcoal-color-text-tertiary-default);
1473
- background: none;
1474
- }
1475
-
1476
- .charcoal-pagination-spacer.charcoal-icon-button:disabled {
1477
- opacity: 1;
1478
- }
1793
+ display: flow-root;
1794
+ margin: 0;
1795
+ min-width: 0;
1796
+ overflow-wrap: break-word;
1797
+ }
1479
1798
  .charcoal-notification-region {
1480
1799
  left: 0;
1481
1800
  right: 0;
@@ -1521,468 +1840,233 @@ pixiv-icon:not(:defined)[name^='Inline/'][scale='2'] {
1521
1840
  line-height: var(--charcoal-text-line-height-caption-m);
1522
1841
  }
1523
1842
 
1524
- @media (prefers-reduced-motion: reduce) {
1525
- .charcoal-notification,
1526
- .charcoal-notification[data-exiting='true'] {
1527
- animation: none;
1528
- }
1529
- }
1530
- .charcoal-notification-region {
1531
- --charcoal-snackbar-offset: 16px;
1532
- }
1533
-
1534
- .charcoal-snackbar-region[data-position='top'] {
1535
- --charcoal-snackbar-enter-offset: calc(-1 * var(--charcoal-space-30));
1536
-
1537
- position: sticky;
1538
- top: calc(env(safe-area-inset-top, 0px) + var(--charcoal-snackbar-offset));
1539
- }
1540
-
1541
- .charcoal-snackbar-region[data-position='bottom'] {
1542
- --charcoal-snackbar-enter-offset: var(--charcoal-space-30);
1543
-
1544
- position: fixed;
1545
- bottom: calc(
1546
- env(safe-area-inset-bottom, 0px) + var(--charcoal-snackbar-offset)
1547
- );
1548
- }
1549
-
1550
- .charcoal-snackbar {
1551
- min-height: 44px;
1552
- padding: var(--charcoal-space-25) var(--charcoal-space-40);
1553
- background-color: var(--charcoal-color-container-default);
1554
- color: var(--charcoal-color-text-default);
1555
- border: var(--charcoal-border-width-m) solid
1556
- var(--charcoal-color-border-secondary);
1557
- animation: charcoal-snackbar-enter 0.3s ease-out both;
1558
- }
1559
-
1560
- .charcoal-snackbar[data-exiting='true'] {
1561
- animation: charcoal-snackbar-exit 0.3s ease-out both;
1562
- }
1563
-
1564
- .charcoal-snackbar[data-with-action='true'] {
1565
- min-height: 56px;
1566
- padding: var(--charcoal-space-25) var(--charcoal-space-30)
1567
- var(--charcoal-space-25) var(--charcoal-space-40);
1568
- }
1569
-
1570
- .charcoal-snackbar[data-dim='true'] {
1571
- background-color: var(--charcoal-color-container-hud-default);
1572
- color: var(--charcoal-color-text-on-hud-default);
1573
- border-color: var(--charcoal-color-border-hud);
1574
- }
1575
-
1576
- @keyframes charcoal-snackbar-enter {
1577
- from {
1578
- opacity: 0;
1579
- transform: translateY(var(--charcoal-snackbar-enter-offset));
1580
- }
1581
-
1582
- to {
1583
- opacity: 1;
1584
- transform: translateY(0);
1585
- }
1586
- }
1587
-
1588
- @keyframes charcoal-snackbar-exit {
1589
- from {
1590
- opacity: 1;
1591
- }
1592
-
1593
- to {
1594
- opacity: 0;
1595
- }
1596
- }
1597
- .charcoal-notification-region {
1598
- --charcoal-toast-offset: 16px;
1599
- }
1600
-
1601
- .charcoal-toast-region[data-position='top'] {
1602
- position: sticky;
1603
- --charcoal-toast-enter-offset: calc(-1 * var(--charcoal-space-30));
1604
-
1605
- top: calc(env(safe-area-inset-top, 0px) + var(--charcoal-toast-offset));
1606
- }
1607
-
1608
- .charcoal-toast-region[data-position='bottom'] {
1609
- position: fixed;
1610
- --charcoal-toast-enter-offset: var(--charcoal-space-30);
1611
-
1612
- bottom: calc(
1613
- env(safe-area-inset-bottom, 0px) + var(--charcoal-toast-offset)
1614
- );
1615
- }
1616
-
1617
- .charcoal-toast {
1618
- min-height: 40px;
1619
- padding: var(--charcoal-space-20) var(--charcoal-space-40);
1620
- color: var(--charcoal-color-text-on-positive-default);
1621
- border: var(--charcoal-border-width-m) solid var(--charcoal-color-border-hud);
1622
- animation: charcoal-toast-enter 0.3s ease-out both;
1623
- }
1624
-
1625
- .charcoal-toast[data-exiting='true'] {
1626
- animation: charcoal-toast-exit 0.3s ease-out both;
1627
- }
1628
-
1629
- .charcoal-toast[data-type='success'] {
1630
- background-color: var(--charcoal-color-container-positive-default);
1631
- }
1632
-
1633
- .charcoal-toast[data-type='error'] {
1634
- background-color: var(--charcoal-color-container-negative-default);
1635
- }
1636
-
1637
- @keyframes charcoal-toast-enter {
1638
- from {
1639
- opacity: 0;
1640
- transform: translateY(var(--charcoal-toast-enter-offset));
1641
- }
1642
-
1643
- to {
1644
- opacity: 1;
1645
- transform: translateY(0);
1646
- }
1647
- }
1648
-
1649
- @keyframes charcoal-toast-exit {
1650
- from {
1651
- opacity: 1;
1652
- }
1653
-
1654
- to {
1655
- opacity: 0;
1656
- }
1657
- }
1658
- .charcoal-carousel {
1659
- --charcoal-carousel-gap: 0px;
1660
-
1661
- position: relative;
1662
- display: block;
1663
- }
1664
-
1665
- .charcoal-carousel[data-full-width='true'] {
1666
- width: 100vw;
1667
- margin-inline: calc(50% - 50vw);
1668
- }
1669
-
1670
- .charcoal-carousel__viewport {
1671
- position: relative;
1672
- }
1673
-
1674
- /* フォーカスリングは scroller ではなく viewport に描く。scroller に置くと
1675
- hasGradient の mask(mask-clip: border-box)で外側の box-shadow ごと消えるため。 */
1676
-
1677
- .charcoal-carousel__viewport[data-focus-visible] {
1678
- box-shadow: 0 0 0 4px rgba(0, 150, 250, 0.32);
1679
- }
1680
-
1681
- /* スライド間隔は gap prop(--charcoal-carousel-gap)で注入する。
1682
- スライド寸法は sandbox 同様、利用者が children 側で持つ。 */
1683
- .charcoal-carousel__scroller {
1684
- position: relative;
1685
- display: flex;
1686
- gap: var(--charcoal-carousel-gap);
1687
- overflow-x: auto;
1688
- overflow-y: hidden;
1689
- overscroll-behavior-x: contain;
1690
- scroll-behavior: smooth;
1691
- scrollbar-width: none;
1692
- outline: none;
1693
- }
1694
- .charcoal-carousel__scroller::-webkit-scrollbar {
1695
- display: none;
1696
- }
1697
-
1698
- /* スクロールスナップ type は prop(scrollSnap.type)で scroller に出し分ける。
1699
- align は基底 .charcoal-carousel__item の後(後述)に置く(no-descending-specificity 回避)。
1700
- 未指定時の既定(M=none / S=mandatory / align=center)は JS 側で data 属性に解決する。 */
1701
- .charcoal-carousel[data-scroll-snap-type='none'] .charcoal-carousel__scroller {
1702
- scroll-snap-type: none;
1703
- }
1704
-
1705
- .charcoal-carousel[data-scroll-snap-type='proximity']
1706
- .charcoal-carousel__scroller {
1707
- scroll-snap-type: x proximity;
1708
- }
1709
-
1710
- .charcoal-carousel[data-scroll-snap-type='mandatory']
1711
- .charcoal-carousel__scroller {
1712
- scroll-snap-type: x mandatory;
1713
- }
1714
-
1715
- /* グラデーション: mask で端のアイテム自体を透明へフェードさせる(下の背景色を
1716
- 問わない)。mask の色はアルファとしてだけ効く(#000=表示 / transparent=透過)。
1717
- 左フェード・右フェードの 2 レイヤーを intersect で合成し、はみ出して
1718
- スクロール可能な側のみ data-can-prev/next で 72px のフェード帯を枠内に置く。
1719
- 無効な側はフェード帯ごと枠外へスライドして隠す(mask-image と違い
1720
- mask-position は補間可能なので、切替が 0.2s のフェードになる)。 */
1721
- .charcoal-carousel[data-has-gradient='true'] .charcoal-carousel__scroller {
1722
- -webkit-mask-image:
1723
- linear-gradient(to right, transparent, #000 72px),
1724
- linear-gradient(to left, transparent, #000 72px);
1725
- mask-image:
1726
- linear-gradient(to right, transparent, #000 72px),
1727
- linear-gradient(to left, transparent, #000 72px);
1728
- /* 枠外へ 72px スライドしても反対側の端が欠けないよう、レイヤー幅に 72px 足す */
1729
- -webkit-mask-size: calc(100% + 72px) 100%;
1730
- mask-size: calc(100% + 72px) 100%;
1731
- -webkit-mask-repeat: no-repeat;
1732
- mask-repeat: no-repeat;
1733
- -webkit-mask-composite: source-in, xor;
1734
- mask-composite: intersect;
1735
- -webkit-mask-position:
1736
- -72px 0,
1737
- 0 0;
1738
- mask-position:
1739
- -72px 0,
1740
- 0 0;
1741
- /* 0.2s ease-in は react-sandbox の LeftGradient と同じ値 */
1742
- transition: 0.2s ease-in mask-position;
1743
- }
1744
-
1745
- .charcoal-carousel[data-has-gradient='true'][data-can-prev='true']
1746
- .charcoal-carousel__scroller {
1747
- -webkit-mask-position:
1748
- 0 0,
1749
- 0 0;
1750
- mask-position:
1751
- 0 0,
1752
- 0 0;
1753
- }
1754
-
1755
- .charcoal-carousel[data-has-gradient='true'][data-can-next='true']
1756
- .charcoal-carousel__scroller {
1757
- -webkit-mask-position:
1758
- -72px 0,
1759
- -72px 0;
1760
- mask-position:
1761
- -72px 0,
1762
- -72px 0;
1763
- }
1764
-
1765
- .charcoal-carousel[data-has-gradient='true'][data-can-prev='true'][data-can-next='true']
1766
- .charcoal-carousel__scroller {
1767
- -webkit-mask-position:
1768
- 0 0,
1769
- -72px 0;
1770
- mask-position:
1771
- 0 0,
1772
- -72px 0;
1773
- }
1774
-
1775
- .charcoal-carousel__item {
1776
- flex: 0 0 auto;
1777
- min-width: 0;
1843
+ @media (prefers-reduced-motion: reduce) {
1844
+ .charcoal-notification,
1845
+ .charcoal-notification[data-exiting='true'] {
1846
+ animation: none;
1847
+ }
1778
1848
  }
1779
-
1780
- .charcoal-carousel[data-size='S'] .charcoal-carousel__item {
1781
- flex: 0 0 100%;
1849
+ .charcoal-notification-region {
1850
+ --charcoal-toast-offset: 16px;
1782
1851
  }
1783
1852
 
1784
- /* scroll-snap-align は prop(scrollSnap.align)で出し分ける。基底 .charcoal-carousel__item
1785
- より後に置くことで no-descending-specificity を回避する。 */
1786
- .charcoal-carousel[data-scroll-snap-align='center'] .charcoal-carousel__item {
1787
- scroll-snap-align: center;
1788
- }
1853
+ .charcoal-toast-region[data-position='top'] {
1854
+ position: sticky;
1855
+ --charcoal-toast-enter-offset: calc(-1 * var(--charcoal-space-30));
1789
1856
 
1790
- .charcoal-carousel[data-scroll-snap-align='start'] .charcoal-carousel__item {
1791
- scroll-snap-align: start;
1792
- }
1857
+ top: calc(env(safe-area-inset-top, 0px) + var(--charcoal-toast-offset));
1858
+ }
1793
1859
 
1794
- /* ── Navigation Buttons (charcoal IconButton, variant=Overlay size=S) ── */
1860
+ .charcoal-toast-region[data-position='bottom'] {
1861
+ position: fixed;
1862
+ --charcoal-toast-enter-offset: var(--charcoal-space-30);
1795
1863
 
1796
- /* マスクの透過域と同じ 72px 1fr 72px グリッド。各ボタンは 72px ゾーンの中央に置く。 */
1797
- .charcoal-carousel__navigation {
1798
- position: absolute;
1799
- inset: 0;
1800
- pointer-events: none;
1801
- display: grid;
1802
- grid-template-columns: 72px 1fr 72px;
1803
- align-items: center;
1804
- /* アイテム内のコンテンツより上にボタンを表示する */
1805
- z-index: 1;
1806
- /* sandbox 同様、通常は隠してカルーセル hover 時にフェードイン表示する。 */
1807
- opacity: 0;
1808
- transition: 0.4s opacity;
1809
- }
1810
- .charcoal-carousel__navigation[data-visible='false'] {
1811
- display: none;
1864
+ bottom: calc(
1865
+ env(safe-area-inset-bottom, 0px) + var(--charcoal-toast-offset)
1866
+ );
1812
1867
  }
1813
1868
 
1814
- /* hover で表示。キーボード操作でも到達できるよう、キーボード由来のフォーカスが
1815
- カルーセル内にある間も表示する(:focus-within だとクリックで残ったフォーカスでも
1816
- 表示され続けるため、react-aria が付与する data 属性で判定する)。 */
1817
- .charcoal-carousel:hover .charcoal-carousel__navigation,
1818
- .charcoal-carousel[data-focus-visible-within] .charcoal-carousel__navigation {
1819
- opacity: 1;
1820
- }
1821
-
1822
- .charcoal-carousel__navigation__item {
1823
- pointer-events: auto;
1869
+ .charcoal-toast {
1870
+ min-height: 40px;
1871
+ padding: var(--charcoal-space-20) var(--charcoal-space-40);
1872
+ color: var(--charcoal-color-text-on-positive-default);
1873
+ border: var(--charcoal-border-width-m) solid var(--charcoal-color-border-hud);
1874
+ animation: charcoal-toast-enter 0.3s ease-out both;
1824
1875
  }
1825
1876
 
1826
- /* ヒットエリアをグリッド端列(= mask のフェード帯と同じ 72px)全体へ広げる。
1827
- 擬似要素上のクリックは元の button に届くため、帯のどこを押してもページ送りになる。
1828
- position: absolute の基準は positioned な .charcoal-carousel__navigation(inset: 0)。 */
1829
-
1830
- .charcoal-carousel__navigation__item::after {
1831
- content: '';
1832
- position: absolute;
1833
- top: 0;
1834
- bottom: 0;
1835
- width: 72px;
1877
+ .charcoal-toast[data-exiting='true'] {
1878
+ animation: charcoal-toast-exit 0.3s ease-out both;
1836
1879
  }
1837
1880
 
1838
- .charcoal-carousel__navigation__item[data-direction='prev'] {
1839
- grid-column: 1;
1840
- justify-self: center;
1881
+ .charcoal-toast[data-type='success'] {
1882
+ background-color: var(--charcoal-color-container-positive-default);
1841
1883
  }
1842
1884
 
1843
- .charcoal-carousel__navigation__item[data-direction='prev']::after {
1844
- left: 0;
1845
- }
1846
-
1847
- .charcoal-carousel__navigation__item[data-direction='next'] {
1848
- grid-column: 3;
1849
- justify-self: center;
1885
+ .charcoal-toast[data-type='error'] {
1886
+ background-color: var(--charcoal-color-container-negative-default);
1850
1887
  }
1851
1888
 
1852
- .charcoal-carousel__navigation__item[data-direction='next']::after {
1853
- right: 0;
1854
- }
1889
+ @keyframes charcoal-toast-enter {
1890
+ from {
1891
+ opacity: 0;
1892
+ transform: translateY(var(--charcoal-toast-enter-offset));
1893
+ }
1855
1894
 
1856
- /* スクロール端では非表示。IconButton の disabled スタイル(opacity:0.32)より
1857
- 高い詳細度で打ち消すため、ルートを前置する。 */
1858
- .charcoal-carousel .charcoal-carousel__navigation__item[data-hidden='true'] {
1859
- opacity: 0;
1860
- pointer-events: none;
1895
+ to {
1896
+ opacity: 1;
1897
+ transform: translateY(0);
1898
+ }
1861
1899
  }
1862
1900
 
1863
- /* タッチデバイスではナビゲーションボタンを出さず、スワイプ操作に委ねる。 */
1864
- @media (hover: none) and (pointer: coarse) {
1865
- .charcoal-carousel__navigation {
1866
- display: none;
1901
+ @keyframes charcoal-toast-exit {
1902
+ from {
1903
+ opacity: 1;
1904
+ }
1905
+
1906
+ to {
1907
+ opacity: 0;
1867
1908
  }
1868
1909
  }
1910
+ .charcoal-notification-region {
1911
+ --charcoal-snackbar-offset: 16px;
1912
+ }
1869
1913
 
1870
- /* ── Indicator: JS Fallback ── */
1914
+ .charcoal-snackbar-region[data-position='top'] {
1915
+ --charcoal-snackbar-enter-offset: calc(-1 * var(--charcoal-space-30));
1871
1916
 
1872
- .charcoal-carousel__indicator {
1873
- display: flex;
1874
- justify-content: center;
1875
- align-items: center;
1876
- height: 40px;
1877
- gap: 8px;
1878
- }
1917
+ position: sticky;
1918
+ top: calc(env(safe-area-inset-top, 0px) + var(--charcoal-snackbar-offset));
1919
+ }
1879
1920
 
1880
- .charcoal-carousel__indicator[data-visible='false'] {
1881
- display: none;
1921
+ .charcoal-snackbar-region[data-position='bottom'] {
1922
+ --charcoal-snackbar-enter-offset: var(--charcoal-space-30);
1923
+
1924
+ position: fixed;
1925
+ bottom: calc(
1926
+ env(safe-area-inset-bottom, 0px) + var(--charcoal-snackbar-offset)
1927
+ );
1882
1928
  }
1883
1929
 
1884
- .charcoal-carousel__indicator__item {
1885
- -webkit-appearance: none;
1886
- -moz-appearance: none;
1887
- appearance: none;
1888
- box-sizing: border-box;
1889
- width: 8px;
1890
- height: 8px;
1891
- padding: 0;
1892
- border: 0;
1893
- border-radius: 50%;
1894
- background-color: var(--charcoal-color-text-tertiary-default);
1895
- cursor: pointer;
1896
- transition: 0.2s background-color;
1930
+ .charcoal-snackbar {
1931
+ min-height: 44px;
1932
+ padding: var(--charcoal-space-25) var(--charcoal-space-40);
1933
+ background-color: var(--charcoal-color-container-default);
1934
+ color: var(--charcoal-color-text-default);
1935
+ border: var(--charcoal-border-width-m) solid
1936
+ var(--charcoal-color-border-secondary);
1937
+ animation: charcoal-snackbar-enter 0.3s ease-out both;
1897
1938
  }
1898
1939
 
1899
- .charcoal-carousel__indicator__item:hover {
1900
- background-color: var(--charcoal-color-text-secondary-default);
1940
+ .charcoal-snackbar[data-exiting='true'] {
1941
+ animation: charcoal-snackbar-exit 0.3s ease-out both;
1901
1942
  }
1902
1943
 
1903
- .charcoal-carousel__indicator__item:focus-visible {
1904
- outline: 2px solid rgba(0, 150, 250, 0.56);
1905
- outline-offset: 2px;
1944
+ .charcoal-snackbar[data-with-action='true'] {
1945
+ min-height: 56px;
1946
+ padding: var(--charcoal-space-25) var(--charcoal-space-30)
1947
+ var(--charcoal-space-25) var(--charcoal-space-40);
1906
1948
  }
1907
1949
 
1908
- .charcoal-carousel__indicator__item[data-active='true'] {
1909
- background-color: var(--charcoal-color-text-default);
1950
+ .charcoal-snackbar[data-dim='true'] {
1951
+ background-color: var(--charcoal-color-container-hud-default);
1952
+ color: var(--charcoal-color-text-on-hud-default);
1953
+ border-color: var(--charcoal-color-border-hud);
1910
1954
  }
1911
1955
 
1912
- /* ── CSS Scroll Markers (progressive enhancement) ── */
1956
+ @keyframes charcoal-snackbar-enter {
1957
+ from {
1958
+ opacity: 0;
1959
+ transform: translateY(var(--charcoal-snackbar-enter-offset));
1960
+ }
1913
1961
 
1914
- /* CSS Scroll Markers / Anchor Positioning の擬似要素・擬似クラスは新しい仕様のため、
1915
- この @supports ブロックでは該当ルールを無効化する。 */
1916
- /* stylelint-disable selector-pseudo-class-no-unknown */
1917
- @supports (scroll-marker-group: after) {
1918
- .charcoal-carousel[data-indicator='true'] {
1919
- padding-bottom: 40px;
1962
+ to {
1963
+ opacity: 1;
1964
+ transform: translateY(0);
1920
1965
  }
1966
+ }
1921
1967
 
1922
- .charcoal-carousel__scroller {
1923
- anchor-name: --charcoal-carousel;
1924
- scroll-marker-group: after;
1968
+ @keyframes charcoal-snackbar-exit {
1969
+ from {
1970
+ opacity: 1;
1925
1971
  }
1926
1972
 
1927
- .charcoal-carousel__scroller::scroll-button(*) {
1928
- content: none;
1929
- }
1973
+ to {
1974
+ opacity: 0;
1975
+ }
1976
+ }
1977
+ .charcoal-text-field-assistive-text {
1978
+ font-size: 14px;
1979
+ line-height: 22px;
1980
+ margin: 0;
1981
+ color: var(--charcoal-color-text-secondary-default);
1982
+ }
1930
1983
 
1931
- .charcoal-carousel__scroller::scroll-marker-group {
1932
- display: flex;
1933
- justify-content: center;
1934
- align-items: center;
1935
- height: 40px;
1936
- gap: 8px;
1984
+ .charcoal-text-field-assistive-text[data-invalid='true'] {
1985
+ color: var(--charcoal-color-text-negative-default);
1986
+ }
1987
+ .charcoal-switch-input {
1988
+ cursor: pointer;
1989
+ -webkit-appearance: none;
1990
+ -moz-appearance: none;
1991
+ appearance: none;
1992
+ display: inline-flex;
1993
+ position: relative;
1994
+ box-sizing: border-box;
1995
+ width: 28px;
1996
+ border: 2px solid transparent;
1997
+
1998
+ transition-property: background-color, box-shadow;
1999
+ transition-duration: 0.2s;
2000
+
2001
+ outline: none;
2002
+ border-radius: 16px;
2003
+ height: 16px;
2004
+ margin: 0;
2005
+ background-color: var(--charcoal-color-container-neutral-default);
2006
+ }
2007
+
2008
+ .charcoal-switch-input:disabled,
2009
+ .charcoal-switch-input[readonly] {
2010
+ opacity: 0.32;
2011
+ cursor: default;
2012
+ }
2013
+
2014
+ .charcoal-switch-input::after {
2015
+ content: '';
2016
+ position: absolute;
2017
+ display: block;
2018
+ top: 0;
2019
+ left: 0;
2020
+ width: 12px;
2021
+ height: 12px;
2022
+ transform: translateX(0);
2023
+ transition: transform 0.2s;
2024
+ border-radius: 1024px;
2025
+ background-color: var(--charcoal-color-icon-on-primary-default);
2026
+ }
1937
2027
 
1938
- position: absolute;
1939
- position-anchor: --charcoal-carousel;
1940
- top: anchor(bottom);
1941
- justify-self: anchor-center;
1942
- }
2028
+ .charcoal-switch-input:checked::after {
2029
+ transform: translateX(12px);
2030
+ transition: transform 0.2s;
2031
+ }
1943
2032
 
1944
- .charcoal-carousel[data-indicator='false'] .charcoal-carousel__scroller {
1945
- scroll-marker-group: none;
1946
- }
2033
+ .charcoal-switch-input:checked {
2034
+ background-color: var(--charcoal-color-container-primary-default);
2035
+ }
1947
2036
 
1948
- .charcoal-carousel__item::scroll-marker {
1949
- content: '';
1950
- width: 8px;
1951
- height: 8px;
1952
- border: 0;
1953
- border-radius: 50%;
1954
- background-color: var(--charcoal-color-text-tertiary-default);
1955
- cursor: pointer;
1956
- transition: 0.2s background-color;
1957
- }
2037
+ .charcoal-switch-input:not(:disabled):hover {
2038
+ background-color: var(--charcoal-color-container-neutral-hover);
2039
+ }
1958
2040
 
1959
- .charcoal-carousel__item::scroll-marker:hover {
1960
- background-color: var(--charcoal-color-text-secondary-default);
1961
- }
2041
+ .charcoal-switch-input:not(:disabled):active {
2042
+ background-color: var(--charcoal-color-container-neutral-press);
2043
+ }
1962
2044
 
1963
- .charcoal-carousel__item::scroll-marker:focus {
1964
- outline: 2px solid rgba(0, 150, 250, 0.56);
1965
- outline-offset: 2px;
1966
- }
2045
+ .charcoal-switch-input:not(:disabled):focus {
2046
+ outline: none;
2047
+ box-shadow: 0 0 0 4px rgba(0, 150, 250, 0.32);
2048
+ }
2049
+ .charcoal-switch-input:not(:disabled):focus-visible {
2050
+ box-shadow: 0 0 0 4px rgba(0, 150, 250, 0.32);
2051
+ }
2052
+ .charcoal-switch-input:not(:disabled):focus:not(:focus-visible) {
2053
+ box-shadow: none;
2054
+ }
1967
2055
 
1968
- .charcoal-carousel__item::scroll-marker:target-current {
1969
- background-color: var(--charcoal-color-text-default);
1970
- }
2056
+ .charcoal-switch-input:not(:disabled)::after:hover {
2057
+ background-color: var(--charcoal-color-icon-on-primary-hover);
2058
+ }
1971
2059
 
1972
- .charcoal-carousel__indicator {
1973
- display: none;
1974
- }
2060
+ .charcoal-switch-input:not(:disabled)::after:active {
2061
+ background-color: var(--charcoal-color-icon-on-primary-press);
1975
2062
  }
1976
- /* stylelint-enable selector-pseudo-class-no-unknown */
1977
- .charcoal-text-field-assistive-text {
1978
- font-size: 14px;
1979
- line-height: 22px;
1980
- margin: 0;
1981
- color: var(--charcoal-color-text-secondary-default);
2063
+
2064
+ .charcoal-switch-input:not(:disabled):checked:hover {
2065
+ background-color: var(--charcoal-color-container-primary-hover);
1982
2066
  }
1983
2067
 
1984
- .charcoal-text-field-assistive-text[data-invalid='true'] {
1985
- color: var(--charcoal-color-text-negative-default);
2068
+ .charcoal-switch-input:not(:disabled):checked:active {
2069
+ background-color: var(--charcoal-color-container-primary-press);
1986
2070
  }
1987
2071
  .charcoal-field-label {
1988
2072
  font-size: 14px;
@@ -2021,6 +2105,51 @@ pixiv-icon:not(:defined)[name^='Inline/'][scale='2'] {
2021
2105
  .charcoal-field-label-root > .charcoal-field-label-sub-label {
2022
2106
  margin-left: auto;
2023
2107
  }
2108
+ .charcoal-modal-dialog {
2109
+ margin: auto;
2110
+ position: relative;
2111
+ height: -moz-fit-content;
2112
+ height: fit-content;
2113
+ width: 440px;
2114
+
2115
+ background-color: var(--charcoal-color-container-default);
2116
+ border-radius: 24px;
2117
+ }
2118
+
2119
+ .charcoal-modal-dialog[data-size='S'] {
2120
+ width: 336px;
2121
+ }
2122
+
2123
+ .charcoal-modal-dialog[data-size='M'] {
2124
+ width: 440px;
2125
+ }
2126
+
2127
+ .charcoal-modal-dialog[data-size='L'] {
2128
+ width: 648px;
2129
+ }
2130
+
2131
+ @media (max-width: 743px) {
2132
+ .charcoal-modal-dialog {
2133
+ max-width: 440px;
2134
+ width: calc(100% - 48px);
2135
+ }
2136
+
2137
+ .charcoal-modal-dialog[data-bottom-sheet='true'],
2138
+ .charcoal-modal-dialog[data-bottom-sheet='full'] {
2139
+ max-width: unset;
2140
+ width: 100%;
2141
+ border-radius: 0;
2142
+ margin: auto 0 0 0;
2143
+ }
2144
+
2145
+ .charcoal-modal-dialog[data-bottom-sheet='full'] {
2146
+ min-height: 100%;
2147
+ }
2148
+ }
2149
+
2150
+ .charcoal-modal-dialog:focus {
2151
+ outline: none;
2152
+ }
2024
2153
  .charcoal-radio-input {
2025
2154
  -webkit-appearance: none;
2026
2155
  -moz-appearance: none;
@@ -2251,135 +2380,6 @@ pixiv-icon:not(:defined)[name^='Inline/'][scale='2'] {
2251
2380
  opacity: 0.32;
2252
2381
  cursor: default;
2253
2382
  }
2254
- .charcoal-switch-input {
2255
- cursor: pointer;
2256
- -webkit-appearance: none;
2257
- -moz-appearance: none;
2258
- appearance: none;
2259
- display: inline-flex;
2260
- position: relative;
2261
- box-sizing: border-box;
2262
- width: 28px;
2263
- border: 2px solid transparent;
2264
-
2265
- transition-property: background-color, box-shadow;
2266
- transition-duration: 0.2s;
2267
-
2268
- outline: none;
2269
- border-radius: 16px;
2270
- height: 16px;
2271
- margin: 0;
2272
- background-color: var(--charcoal-color-container-neutral-default);
2273
- }
2274
-
2275
- .charcoal-switch-input:disabled,
2276
- .charcoal-switch-input[readonly] {
2277
- opacity: 0.32;
2278
- cursor: default;
2279
- }
2280
-
2281
- .charcoal-switch-input::after {
2282
- content: '';
2283
- position: absolute;
2284
- display: block;
2285
- top: 0;
2286
- left: 0;
2287
- width: 12px;
2288
- height: 12px;
2289
- transform: translateX(0);
2290
- transition: transform 0.2s;
2291
- border-radius: 1024px;
2292
- background-color: var(--charcoal-color-icon-on-primary-default);
2293
- }
2294
-
2295
- .charcoal-switch-input:checked::after {
2296
- transform: translateX(12px);
2297
- transition: transform 0.2s;
2298
- }
2299
-
2300
- .charcoal-switch-input:checked {
2301
- background-color: var(--charcoal-color-container-primary-default);
2302
- }
2303
-
2304
- .charcoal-switch-input:not(:disabled):hover {
2305
- background-color: var(--charcoal-color-container-neutral-hover);
2306
- }
2307
-
2308
- .charcoal-switch-input:not(:disabled):active {
2309
- background-color: var(--charcoal-color-container-neutral-press);
2310
- }
2311
-
2312
- .charcoal-switch-input:not(:disabled):focus {
2313
- outline: none;
2314
- box-shadow: 0 0 0 4px rgba(0, 150, 250, 0.32);
2315
- }
2316
- .charcoal-switch-input:not(:disabled):focus-visible {
2317
- box-shadow: 0 0 0 4px rgba(0, 150, 250, 0.32);
2318
- }
2319
- .charcoal-switch-input:not(:disabled):focus:not(:focus-visible) {
2320
- box-shadow: none;
2321
- }
2322
-
2323
- .charcoal-switch-input:not(:disabled)::after:hover {
2324
- background-color: var(--charcoal-color-icon-on-primary-hover);
2325
- }
2326
-
2327
- .charcoal-switch-input:not(:disabled)::after:active {
2328
- background-color: var(--charcoal-color-icon-on-primary-press);
2329
- }
2330
-
2331
- .charcoal-switch-input:not(:disabled):checked:hover {
2332
- background-color: var(--charcoal-color-container-primary-hover);
2333
- }
2334
-
2335
- .charcoal-switch-input:not(:disabled):checked:active {
2336
- background-color: var(--charcoal-color-container-primary-press);
2337
- }
2338
- .charcoal-modal-dialog {
2339
- margin: auto;
2340
- position: relative;
2341
- height: -moz-fit-content;
2342
- height: fit-content;
2343
- width: 440px;
2344
-
2345
- background-color: var(--charcoal-color-container-default);
2346
- border-radius: 24px;
2347
- }
2348
-
2349
- .charcoal-modal-dialog[data-size='S'] {
2350
- width: 336px;
2351
- }
2352
-
2353
- .charcoal-modal-dialog[data-size='M'] {
2354
- width: 440px;
2355
- }
2356
-
2357
- .charcoal-modal-dialog[data-size='L'] {
2358
- width: 648px;
2359
- }
2360
-
2361
- @media (max-width: 743px) {
2362
- .charcoal-modal-dialog {
2363
- max-width: 440px;
2364
- width: calc(100% - 48px);
2365
- }
2366
-
2367
- .charcoal-modal-dialog[data-bottom-sheet='true'],
2368
- .charcoal-modal-dialog[data-bottom-sheet='full'] {
2369
- max-width: unset;
2370
- width: 100%;
2371
- border-radius: 0;
2372
- margin: auto 0 0 0;
2373
- }
2374
-
2375
- .charcoal-modal-dialog[data-bottom-sheet='full'] {
2376
- min-height: 100%;
2377
- }
2378
- }
2379
-
2380
- .charcoal-modal-dialog:focus {
2381
- outline: none;
2382
- }
2383
2383
  .charcoal-popover {
2384
2384
  margin: 4px 0;
2385
2385
  list-style: none;