@devfellowship/components 1.5.0 → 3.0.0

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.
@@ -316,7 +316,7 @@
316
316
  --c-input-border: var(--s-border-subtle);
317
317
  --c-input-border-hover: var(--s-border-strong);
318
318
  --c-input-border-focus: var(--s-border-focus);
319
- --c-input-ring-focus: var(--s-brand-ring);
319
+ --c-input-ring-focus: var(--s-border-focus); /* solid amber — was --s-brand-ring (semi-transparent) */
320
320
  --c-input-border-error: var(--s-danger-solid);
321
321
  --c-input-radius: var(--p-radius-md);
322
322
 
@@ -358,10 +358,80 @@
358
358
  /* Avatar */
359
359
  --c-avatar-ring: var(--s-surface-panel);
360
360
  --c-avatar-fallback-bg: var(--s-surface-elevated);
361
+ --c-avatar-fallback-fg: var(--s-ink-primary);
362
+ /* Brand (amber) fallback tone — the DFL-branded avatar. */
363
+ --c-avatar-brand-bg: var(--s-brand-solid); /* #E07A4A */
364
+ --c-avatar-brand-fg: var(--s-ink-inverse); /* dark ink on amber */
365
+ /* Group separator ring — page-coloured so overlapping avatars read as distinct. */
366
+ --c-avatar-group-ring: var(--s-surface-page); /* #0a0908 */
367
+ /* Status indicator dots (bottom-right), ringed in page bg. */
368
+ --c-avatar-status-online: var(--s-success-solid); /* green */
369
+ --c-avatar-status-away: var(--s-warning-solid); /* amber */
370
+ --c-avatar-status-offline: var(--s-ink-muted); /* grey */
371
+ --c-avatar-status-ring: var(--s-surface-page);
372
+ /* Deterministic member palette (12 muted jewel tones on dark bg).
373
+ * Hashed from the member seed (initials/name) so a given person is always
374
+ * the same colour. Text stays --s-ink-primary (light) — all tones pass AA. */
375
+ --c-avatar-member-1: #b4534b; /* red */
376
+ --c-avatar-member-2: #c26a3b; /* orange */
377
+ --c-avatar-member-3: #b8893f; /* amber */
378
+ --c-avatar-member-4: #8a9a3f; /* lime */
379
+ --c-avatar-member-5: #4f9a5e; /* green */
380
+ --c-avatar-member-6: #3f9a86; /* teal */
381
+ --c-avatar-member-7: #3f8f9a; /* cyan */
382
+ --c-avatar-member-8: #4a7bb4; /* blue */
383
+ --c-avatar-member-9: #5a5eb4; /* indigo */
384
+ --c-avatar-member-10: #8a53b4; /* violet */
385
+ --c-avatar-member-11: #b4539a; /* pink */
386
+ --c-avatar-member-12: #b4536a; /* rose */
361
387
 
362
388
  /* Badge / Pill */
363
389
  --c-badge-radius: var(--p-radius-sm);
364
390
  --c-pill-radius: var(--p-radius-pill);
391
+ /* Solid-fill tone — count indicators / emphatic status. Solid intent bg +
392
+ * inverse ink (dark text on the bright fill). One per semantic intent. */
393
+ --c-badge-solid-fg: var(--s-ink-inverse);
394
+ --c-badge-solid-default-bg: var(--s-brand-solid);
395
+ --c-badge-solid-success-bg: var(--s-success-solid);
396
+ --c-badge-solid-warning-bg: var(--s-warning-solid);
397
+ --c-badge-solid-danger-bg: var(--s-danger-solid);
398
+ --c-badge-solid-info-bg: var(--s-info-solid);
399
+
400
+ /* Alert — neutral panel base + per-variant semantic skins.
401
+ * Default is a VISIBLE elevated panel (surface-panel), never page bg.
402
+ * Each variant maps to its --s-{intent}-{subtle,border,fg,solid} tokens. */
403
+ --c-alert-bg: var(--s-surface-panel);
404
+ --c-alert-radius: var(--p-radius-lg);
405
+ --c-alert-padding-y: var(--p-space-4);
406
+ --c-alert-padding-x: var(--p-space-4);
407
+ --c-alert-border: var(--s-border-subtle);
408
+ --c-alert-fg: var(--s-ink-primary);
409
+ --c-alert-desc-fg: var(--s-ink-secondary);
410
+ --c-alert-icon-size: 18px;
411
+ --c-alert-accent-w: 3px; /* left accent stripe */
412
+
413
+ --c-alert-default-icon: var(--s-ink-muted);
414
+ --c-alert-default-accent: var(--s-border-subtle);
415
+
416
+ --c-alert-info-bg: var(--s-info-subtle);
417
+ --c-alert-info-border: var(--s-info-border);
418
+ --c-alert-info-icon: var(--s-info-fg);
419
+ --c-alert-info-accent: var(--s-info-solid);
420
+
421
+ --c-alert-success-bg: var(--s-success-subtle);
422
+ --c-alert-success-border: var(--s-success-border);
423
+ --c-alert-success-icon: var(--s-success-fg);
424
+ --c-alert-success-accent: var(--s-success-solid);
425
+
426
+ --c-alert-warning-bg: var(--s-warning-subtle);
427
+ --c-alert-warning-border: var(--s-warning-border);
428
+ --c-alert-warning-icon: var(--s-warning-fg);
429
+ --c-alert-warning-accent: var(--s-warning-solid);
430
+
431
+ --c-alert-danger-bg: var(--s-danger-subtle);
432
+ --c-alert-danger-border: var(--s-danger-border);
433
+ --c-alert-danger-icon: var(--s-danger-fg);
434
+ --c-alert-danger-accent: var(--s-danger-solid);
365
435
 
366
436
  /* Layout chrome */
367
437
  --c-sidebar-w: 224px;
@@ -489,3 +559,1150 @@
489
559
  outline-offset: var(--ds-focus-ring-offset);
490
560
  transition: none; /* instant — no animation on focus */
491
561
  }
562
+
563
+ /* ─────────────────────────────────────────────────────────────────────────
564
+ * Button — semantic focus-ring knobs (atoms-button refactor, 2026-07-02)
565
+ *
566
+ * Brand spec: double box-shadow — 2px bg-color gap + 1px solid accent.
567
+ * Three accent colours; each resolves to an existing --s-* semantic token.
568
+ *
569
+ * --c-button-focus-gap the 2 px background-color separator
570
+ * --c-button-focus-brand amber — primary / secondary / outline / ghost / link
571
+ * --c-button-focus-danger red — destructive (semantic intent)
572
+ * --c-button-focus-success green — success (semantic intent)
573
+ * ─────────────────────────────────────────────────────────────────────── */
574
+
575
+ :root {
576
+ --c-button-focus-gap: var(--s-surface-page);
577
+ --c-button-focus-brand: var(--s-brand-solid);
578
+ --c-button-focus-danger: var(--s-danger-solid);
579
+ --c-button-focus-success: var(--s-success-solid);
580
+ }
581
+
582
+ /* ─────────────────────────────────────────────────────────────────────────
583
+ * LAYER 3 — ButtonLab playground (DesignPlayground experiment)
584
+ *
585
+ * Consumed ONLY by src/design-playground/ButtonLab.stories.tsx.
586
+ * NOT distributed via registry / npm. Delete this block once the
587
+ * recording experiment graduates (or is retired) via the playground
588
+ * → Components/Atoms/Button promotion flow.
589
+ *
590
+ * All values resolve to existing --s-* semantic tokens.
591
+ * ─────────────────────────────────────────────────────────────────────── */
592
+
593
+ :root {
594
+ /* Recording experiment — Active (pulsing amber dot, "Gravando…")
595
+ * Amber-brand treatment: signal ≠ error. NOT destructive/danger tokens. */
596
+ --c-buttonlab-recording-bg: var(--s-brand-subtle); /* rgba(224,122,74,.10) */
597
+ --c-buttonlab-recording-fg: var(--s-brand-fg); /* var(--p-amber-300) */
598
+ --c-buttonlab-recording-border: var(--s-brand-border); /* rgba(224,122,74,.22) */
599
+
600
+ /* Recording experiment — Idle (static dimmed dot, "Parado")
601
+ * Neutral treatment — same layout, subdued palette. */
602
+ --c-buttonlab-recording-idle-bg: var(--s-surface-page); /* transparent on page */
603
+ --c-buttonlab-recording-idle-fg: var(--s-ink-muted); /* var(--p-sand-400) */
604
+ --c-buttonlab-recording-idle-border: var(--s-border-subtle); /* var(--p-sand-700) */
605
+ }
606
+
607
+ /* ─────────────────────────────────────────────────────────────────────────
608
+ * LAYER 3 — Component (--c-toggle-* / --c-toggle-group-*)
609
+ * ToggleGroup / Toggle component-token knobs.
610
+ * Resolves to existing --s-* semantic tokens; no --p-* or --s-* are added.
611
+ * Consumers can override any --c-toggle-* to retheme without touching the
612
+ * semantic layer.
613
+ * ─────────────────────────────────────────────────────────────────────── */
614
+
615
+ :root {
616
+ /* Item backgrounds */
617
+ --c-toggle-bg: transparent;
618
+ --c-toggle-bg-hover: var(--s-surface-raised);
619
+ --c-toggle-bg-active: var(--s-brand-subtle); /* amber wash */
620
+ --c-toggle-bg-active-hover: rgba(224, 122, 74, 0.16); /* stronger wash on hover */
621
+
622
+ /* Item foreground (icon / text) */
623
+ --c-toggle-fg: var(--s-ink-muted);
624
+ --c-toggle-fg-hover: var(--s-ink-secondary);
625
+ --c-toggle-fg-active: var(--s-brand-fg); /* amber-300 */
626
+
627
+ /* Border — used by outline variant items and inter-item dividers */
628
+ --c-toggle-border: var(--s-border-subtle);
629
+
630
+ /* Group container radius */
631
+ --c-toggle-group-radius: var(--p-radius-md); /* 6px */
632
+
633
+ /* Focus ring — THE uniform 2px-gap + 1px-amber spec (ch.5.2) */
634
+ --c-toggle-focus-ring: 0 0 0 2px var(--s-surface-page), 0 0 0 3px #E07A4A;
635
+
636
+ /* Outline variant: inset top-highlight on active items */
637
+ --c-toggle-outline-active-shadow: inset 0 1px 0 rgba(224, 122, 74, 0.3);
638
+ }
639
+
640
+ /* ─────────────────────────────────────────────────────────────────────────
641
+ * LAYER 3 — Component (--c-alert-dialog-*)
642
+ *
643
+ * AlertDialog organism: scrim overlay + dialog card surface + typography.
644
+ * Resolves exclusively to --s-* semantic tokens and existing --c-dialog-*
645
+ * knobs (reuses the Dialog overlay/surface contract — AlertDialog shares
646
+ * the same visual elevation as Dialog).
647
+ *
648
+ * Action button variants (default/destructive) are driven by existing
649
+ * --c-button-* tokens via buttonVariants(). No new button knobs needed.
650
+ *
651
+ * Focus ring: uniform 2 px page-bg gap + 1 px #E07A4A — applied inline in
652
+ * the component via focus-visible: shadow override (see alert-dialog.tsx).
653
+ * ─────────────────────────────────────────────────────────────────────── */
654
+
655
+ :root {
656
+ /* AlertDialog */
657
+ --c-alert-dialog-bg: var(--c-dialog-bg); /* dialog card surface */
658
+ --c-alert-dialog-border: var(--c-dialog-border); /* card 1 px border */
659
+ --c-alert-dialog-radius: var(--c-dialog-radius); /* 14 px (--p-radius-xl) */
660
+ --c-alert-dialog-shadow: var(--c-dialog-shadow); /* deep overlay shadow */
661
+ --c-alert-dialog-scrim: var(--c-dialog-scrim); /* backdrop rgba scrim */
662
+ --c-alert-dialog-title-fg: var(--s-ink-primary); /* title text color */
663
+ --c-alert-dialog-desc-fg: var(--s-ink-muted); /* description text */
664
+
665
+ /* Checkbox — DFL Design System v0
666
+ * Two-layer amber focus ring: 0 0 0 2px page-bg gap + 0 0 0 3px amber ring.
667
+ * Error state keyed off aria-invalid (mirrors Input/Textarea pattern).
668
+ * Indeterminate state uses the Radix `checked="indeterminate"` prop + Minus icon. */
669
+ --c-checkbox-size: 16px;
670
+ --c-checkbox-radius: var(--p-radius-sm);
671
+ --c-checkbox-border-width: 1.5px;
672
+ --c-checkbox-bg: var(--s-surface-raised);
673
+ --c-checkbox-border: var(--s-border-subtle);
674
+ --c-checkbox-border-hover: var(--s-border-strong);
675
+ --c-checkbox-checked-bg: var(--s-brand-solid);
676
+ --c-checkbox-checked-border: var(--s-brand-solid);
677
+ --c-checkbox-checked-fg: var(--s-ink-inverse);
678
+ --c-checkbox-focus-ring: var(--s-border-focus); /* amber #E07A4A */
679
+ --c-checkbox-disabled-opacity: 0.40;
680
+ --c-checkbox-danger-border: var(--s-danger-solid);
681
+ --c-checkbox-danger-bg: rgba(224, 122, 122, 0.06); /* very subtle red tint */
682
+ --c-checkbox-danger-checked-bg: var(--s-danger-solid);
683
+
684
+ /* Kbd — single-key chip with physical-key depth shadow.
685
+ * Resolves: --c-kbd-* → --s-* → --p-* (3-layer contract).
686
+ * Override --c-kbd-* in isolation to retheme Kbd without touching shared semantics. */
687
+ --c-kbd-bg: var(--s-surface-raised); /* resting key surface #1a1714 */
688
+ --c-kbd-bg-depth: var(--s-surface-panel); /* bottom shadow ridge #141210 */
689
+ --c-kbd-border: var(--s-border-subtle); /* key border #2a2622 */
690
+ --c-kbd-fg: var(--s-ink-primary); /* label ink #f6f1e7 (↑ from ink-secondary for legibility) */
691
+ --c-kbd-shine: rgba(255, 255, 255, 0.055); /* top inset highlight — literal (no semantic equivalent) */
692
+ --c-kbd-radius: var(--p-radius-sm); /* 4px */
693
+
694
+ /* Label
695
+ * Layer 3 knobs that resolve into Layer 2 semantic tokens.
696
+ * Component code reaches for --c-label-* first; consuming apps may override
697
+ * just these vars without touching the shared --s-* semantic palette.
698
+ *
699
+ * Token chain:
700
+ * --c-label-fg → --s-ink-secondary (default variant color)
701
+ * --c-label-fg-muted → --s-ink-muted (mono variant color)
702
+ * --c-label-fg-error → --s-danger-fg (error state color)
703
+ * --c-label-fg-disabled → --s-ink-disabled (disabled state color)
704
+ * --c-label-required-color → --s-brand-solid (required asterisk)
705
+ * --c-label-font-size → --p-text-12 (default: 12px)
706
+ * --c-label-mono-font-size → 10.5px (mono: no exact primitive)
707
+ * --c-label-mono-tracking → 0.06em (mono letter-spacing)
708
+ */
709
+ --c-label-font: var(--p-font-sans);
710
+ --c-label-font-size: var(--p-text-12);
711
+ --c-label-line-height: var(--p-leading-snug);
712
+ --c-label-weight: var(--p-weight-500);
713
+ --c-label-fg: var(--s-ink-secondary);
714
+ --c-label-fg-muted: var(--s-ink-muted);
715
+ --c-label-fg-error: var(--s-danger-fg);
716
+ --c-label-fg-disabled: var(--s-ink-disabled);
717
+ --c-label-required-color: var(--s-brand-solid);
718
+ --c-label-mono-font: var(--p-font-mono);
719
+ --c-label-mono-font-size: 10.5px; /* no --p-text-10-5 primitive exists */
720
+ --c-label-mono-tracking: 0.06em;
721
+ }
722
+
723
+
724
+ /* ─────────────────────────────────────────────────────────────────────────
725
+ * LAYER 3 — Component (--c-progress-*)
726
+ * Track background lifted to --s-surface-elevated so the empty bar is
727
+ * legible against the page (#0a0908). Fill is brand amber by default;
728
+ * semantic variants map to their --s-{intent}-solid tokens.
729
+ * Height sizes: sm=4px / md=8px (default, replaces hardcoded h-4=16px) / lg=12px.
730
+ * ─────────────────────────────────────────────────────────────────────── */
731
+
732
+ :root {
733
+ /* Track */
734
+ --c-progress-track-bg: var(--s-surface-elevated); /* #1f1c18 — visible on page bg */
735
+ --c-progress-radius: var(--p-radius-pill); /* 999px */
736
+
737
+ /* Heights (size variants) */
738
+ --c-progress-h-sm: 4px;
739
+ --c-progress-h-md: 8px; /* default — replaces hardcoded h-4 (16px) */
740
+ --c-progress-h-lg: 12px;
741
+
742
+ /* Motion */
743
+ --c-progress-duration: var(--p-duration-slow); /* 280ms */
744
+ --c-progress-easing: var(--p-ease-in-out); /* cubic-bezier(0.4,0,0.2,1) */
745
+
746
+ /* Fill colors (variant layer) */
747
+ --c-progress-fill: var(--s-brand-solid); /* amber #E07A4A */
748
+ --c-progress-fill-success: var(--s-success-solid); /* green #5ec27e */
749
+ --c-progress-fill-danger: var(--s-danger-solid); /* red #e07a7a */
750
+ --c-progress-fill-warning: var(--s-warning-solid); /* yellow #e0b04a */
751
+ --c-progress-fill-info: var(--s-info-solid); /* blue #7aa2e0 */
752
+ }
753
+
754
+ /* ─────────────────────────────────────────────────────────────────────────
755
+ * LAYER 3 — RadioGroup (--c-radio-*)
756
+ *
757
+ * Resolves exclusively to existing --s-* semantic tokens (Layer 2).
758
+ * Never modify --s-* or --p-* here — append --c-* only.
759
+ * ─────────────────────────────────────────────────────────────────────── */
760
+
761
+ :root {
762
+ /* Geometry */
763
+ --c-radio-size: 16px;
764
+ --c-radio-indicator-size: 8px;
765
+ --c-radio-border-width: 1.5px;
766
+ --c-radio-radius: var(--p-radius-pill);
767
+
768
+ /* Colors — unselected (neutral), hover, checked */
769
+ --c-radio-bg: var(--s-surface-elevated);
770
+ --c-radio-border: var(--s-border-strong); /* neutral: #3a3530, NOT amber */
771
+ --c-radio-border-hover: var(--s-ink-muted); /* unchecked hover: #7d7568 */
772
+ --c-radio-border-checked: var(--s-brand-solid); /* checked / focus: #E07A4A */
773
+ --c-radio-indicator-color: var(--s-brand-solid); /* filled dot when checked */
774
+
775
+ /* Label */
776
+ --c-radio-label-fg: var(--s-ink-secondary);
777
+ --c-radio-label-fg-disabled: var(--s-ink-disabled);
778
+
779
+ /* Spacing */
780
+ --c-radio-item-gap: var(--p-space-3); /* 12px between items */
781
+ --c-radio-label-gap: var(--p-space-2); /* 8px between circle + label */
782
+ }
783
+
784
+ /* ─────────────────────────────────────────────────────────────────────────
785
+ * LAYER 3 — ScrollArea component tokens (--c-scroll-area-*)
786
+ *
787
+ * Thumb state hierarchy + track reveal + sizing for the dark-warm palette.
788
+ * Resolves entirely through --s-* semantic tokens; no raw primitives
789
+ * are referenced directly.
790
+ *
791
+ * Thumb: ink-muted at rest → brand-solid on hover → brand-pressed active.
792
+ * Track: transparent at rest; sand-700@50% reveals the rail on hover.
793
+ * Width: 8px (down from shadcn default 10px; slimmer = more content area).
794
+ * Radius: pill (999px) matching existing thumb treatment.
795
+ * ─────────────────────────────────────────────────────────────────────── */
796
+
797
+ :root {
798
+ /* Thumb state hierarchy */
799
+ --c-scroll-area-thumb: var(--s-ink-muted); /* #7d7568 — visible but recessive at rest */
800
+ --c-scroll-area-thumb-hover: var(--s-brand-solid); /* #E07A4A — amber brand accent on hover */
801
+ --c-scroll-area-thumb-active: var(--s-brand-pressed); /* #c2663b — pressed / dragging */
802
+
803
+ /* Track */
804
+ --c-scroll-area-track: transparent; /* track at rest: invisible */
805
+ --c-scroll-area-track-hover: rgba(42, 38, 34, 0.50); /* sand-700 @ 50% — reveals rail on hover */
806
+
807
+ /* Sizing */
808
+ --c-scroll-area-width: 8px; /* scrollbar rail + thumb width */
809
+ --c-scroll-area-radius: var(--p-radius-pill); /* 999px pill thumb */
810
+ }
811
+
812
+ /* ─────────────────────────────────────────────────────────────────────────
813
+ * LAYER 3 — Separator component tokens (--c-separator-*)
814
+ *
815
+ * Resolves exclusively to existing --s-* semantic tokens. Gives consumers
816
+ * a single override knob (--c-separator-color) instead of reaching into
817
+ * the semantic layer directly.
818
+ *
819
+ * Usage: override per-instance via inline style —
820
+ * style={{ "--c-separator-color": "var(--s-border-strong)" } as React.CSSProperties}
821
+ * ─────────────────────────────────────────────────────────────────────── */
822
+
823
+ :root {
824
+ /* Line fill — subtle border for inline dividers (default) */
825
+ --c-separator-color: var(--s-border-subtle);
826
+ /* Line fill — strong border for major section boundaries */
827
+ --c-separator-color-strong: var(--s-border-strong);
828
+ /* Line fill — brand-border tint for accent/featured separators */
829
+ --c-separator-color-brand: var(--s-brand-border);
830
+ /* Line weight (height for horizontal, width for vertical) */
831
+ --c-separator-thickness: 1px;
832
+
833
+ /* WithLabel composite — centered label typography */
834
+ --c-separator-label-fg: var(--s-ink-muted);
835
+ --c-separator-label-size: var(--p-text-11);
836
+ }
837
+
838
+ /* ─────────────────────────────────────────────────────────────────────────
839
+ * Skeleton component (--c-skeleton-*)
840
+ * Warm directional shimmer (sand-800 base → sand-700 sweep → sand-800).
841
+ * All colour tokens resolve to existing --s-* semantic tokens so the whole
842
+ * skeleton can be re-themed by overriding a single --c-skeleton-bg /
843
+ * --c-skeleton-shimmer pair in a scoped selector.
844
+ * Radius tiers follow the DS --p-radius-* scale (no --s-radius-* exists).
845
+ * ─────────────────────────────────────────────────────────────────────── */
846
+
847
+ :root {
848
+ /* Base fill = deepest surface tier (sand-800 = --s-surface-elevated) */
849
+ --c-skeleton-bg: var(--s-surface-elevated);
850
+ /* Shimmer highlight = one level warmer (sand-700 = --s-border-subtle) */
851
+ --c-skeleton-shimmer: var(--s-border-subtle);
852
+ /* Radius tiers — map directly to DS primitive radius scale */
853
+ --c-skeleton-radius-sm: var(--p-radius-sm); /* 4px — text lines, table cells */
854
+ --c-skeleton-radius-md: var(--p-radius-md); /* 6px — title blocks */
855
+ --c-skeleton-radius-lg: var(--p-radius-lg); /* 10px — hero / media blocks */
856
+ --c-skeleton-radius-circle: 50%; /* avatars */
857
+ /* Animation */
858
+ --c-skeleton-duration: 1.8s;
859
+ }
860
+
861
+ @keyframes skeleton-shimmer {
862
+ 0% { background-position: -600px 0; }
863
+ 100% { background-position: 600px 0; }
864
+ }
865
+
866
+ .dfl-skeleton {
867
+ display: block;
868
+ background: linear-gradient(
869
+ 90deg,
870
+ var(--c-skeleton-bg) 0%,
871
+ var(--c-skeleton-bg) 30%,
872
+ var(--c-skeleton-shimmer) 50%,
873
+ var(--c-skeleton-bg) 70%,
874
+ var(--c-skeleton-bg) 100%
875
+ );
876
+ background-size: 1200px 100%;
877
+ animation: skeleton-shimmer var(--c-skeleton-duration) ease-in-out infinite;
878
+ border-radius: var(--c-skeleton-radius-sm);
879
+ }
880
+
881
+ /* WCAG 2.3.3 — stop animation for users who prefer reduced motion;
882
+ * keep the sand-800 static fill visible so placeholders remain legible. */
883
+ @media (prefers-reduced-motion: reduce) {
884
+ .dfl-skeleton {
885
+ animation: none;
886
+ background: var(--c-skeleton-bg);
887
+ }
888
+ }
889
+
890
+ /* ─────────────────────────────────────────────────────────────────────────
891
+ * LAYER 3 — Slider component tokens (--c-slider-*)
892
+ *
893
+ * Resolves to existing --s-* semantic tokens. Track height reduced from
894
+ * h-4 (16px) to 4px (sleek DS-aligned line with protruding thumb).
895
+ * Focus ring uses DS uniform double-shadow spec (ch.5.2).
896
+ * ─────────────────────────────────────────────────────────────────────── */
897
+
898
+ :root {
899
+ /* Track */
900
+ --c-slider-track-h: 4px;
901
+ --c-slider-track-bg: var(--s-border-subtle); /* #2a2622 — subtle track line */
902
+
903
+ /* Range fill */
904
+ --c-slider-range-bg: var(--s-brand-solid); /* #E07A4A amber */
905
+
906
+ /* Thumb */
907
+ --c-slider-thumb-size: 20px;
908
+ --c-slider-thumb-bg: var(--s-surface-page); /* #0a0908 page-bg — creates border contrast */
909
+ --c-slider-thumb-border: var(--s-brand-solid); /* #E07A4A amber border */
910
+
911
+ /* Shadows — composed per state (base, hover, focus) */
912
+ --c-slider-thumb-shadow: 0 1px 4px rgba(0, 0, 0, 0.55);
913
+ --c-slider-thumb-hover-shadow: 0 0 0 7px rgba(224, 122, 74, 0.18), 0 1px 4px rgba(0, 0, 0, 0.55);
914
+ /* DS uniform focus ring: 2px bg gap + 3px amber ring + base shadow */
915
+ --c-slider-thumb-focus-shadow: 0 0 0 2px var(--s-surface-page), 0 0 0 3px var(--s-brand-solid), 0 1px 4px rgba(0, 0, 0, 0.55);
916
+ }
917
+
918
+ /* ─────────────────────────────────────────────────────────────────────────
919
+ * LAYER 3 — Sonner / Toast (--c-toast-*)
920
+ * Thin adapter over the sonner library. Maps DFL semantic tokens onto
921
+ * Sonner's CSS-variable API and defines per-type semantic surfaces.
922
+ * Implementation: passed as Sonner CSS vars via the SonnerToaster wrapper.
923
+ * ─────────────────────────────────────────────────────────────────────── */
924
+
925
+ :root {
926
+ /* Base surface — shared by Radix Toast (toast.tsx) AND Sonner (sonner.tsx).
927
+ * Single canonical --c-toast-* block (merged the former duplicate "Toast
928
+ * component tokens" block into here so both consumers resolve identically;
929
+ * eliminates the last-write-wins collision that made the semantic tints
930
+ * drift to the plain --s-*-subtle greens). */
931
+ --c-toast-bg: var(--s-surface-elevated); /* #1f1c18 */
932
+ --c-toast-border: var(--s-border-subtle); /* #2a2622 */
933
+ --c-toast-radius: var(--p-radius-lg); /* 10px */
934
+ --c-toast-shadow: 0 8px 24px rgba(0, 0, 0, 0.55), 0 2px 6px rgba(0, 0, 0, 0.35);
935
+ --c-toast-accent-w: 3px; /* left accent stripe width (toast.tsx) */
936
+
937
+ /* Ink — both naming schemes: sonner reads title-fg/desc-fg; toast.tsx reads fg/fg-desc */
938
+ --c-toast-title-fg: var(--s-ink-primary);
939
+ --c-toast-desc-fg: var(--s-ink-secondary);
940
+ --c-toast-fg: var(--s-ink-primary);
941
+ --c-toast-fg-desc: var(--s-ink-secondary);
942
+ --c-toast-close-fg: var(--s-ink-muted);
943
+ --c-toast-close-fg-hover: var(--s-ink-primary);
944
+
945
+ /* Action button — amber DFL brand */
946
+ --c-toast-action-fg: var(--s-brand-solid); /* #E07A4A */
947
+ --c-toast-action-border: var(--s-brand-border); /* rgba(224,122,74,0.22) */
948
+ --c-toast-action-bg-hover: var(--s-brand-subtle); /* rgba(224,122,74,0.10) */
949
+
950
+ /* Uniform focus ring (ch.5.2): 2px bg gap + 1px amber ring */
951
+ --c-toast-focus-ring: 0 0 0 2px var(--c-toast-bg), 0 0 0 3px #E07A4A;
952
+
953
+ /* Semantic type backgrounds — hand-tuned semi-transparent tints over page bg.
954
+ * These (NOT the flat --s-*-subtle) are the DS-approved toast surfaces. */
955
+ --c-toast-success-bg: rgba(20, 59, 34, 0.45); /* green-900 @ 45% */
956
+ --c-toast-success-border: rgba(94, 194, 126, 0.25); /* green-500 @ 25% */
957
+ --c-toast-success-fg: var(--s-success-fg); /* #7ad79a */
958
+
959
+ /* danger (toast.tsx) + error (sonner) — same underlying values */
960
+ --c-toast-danger-bg: rgba(76, 26, 26, 0.45); /* red-900 @ 45% */
961
+ --c-toast-danger-border: rgba(224, 122, 122, 0.25); /* red-500 @ 25% */
962
+ --c-toast-danger-fg: var(--s-danger-fg); /* #e89898 */
963
+ --c-toast-error-bg: rgba(76, 26, 26, 0.45);
964
+ --c-toast-error-border: rgba(224, 122, 122, 0.25);
965
+ --c-toast-error-fg: var(--s-danger-fg);
966
+
967
+ --c-toast-info-bg: rgba(26, 43, 76, 0.45); /* blue-900 @ 45% */
968
+ --c-toast-info-border: rgba(122, 162, 224, 0.25); /* blue-500 @ 25% */
969
+ --c-toast-info-fg: var(--s-info-fg); /* #9ab9e8 */
970
+
971
+ --c-toast-warning-bg: rgba(74, 59, 18, 0.45); /* yellow-900 @ 45% */
972
+ --c-toast-warning-border: rgba(224, 176, 74, 0.25); /* yellow-500 @ 25% */
973
+ --c-toast-warning-fg: var(--s-warning-fg); /* #f0c875 */
974
+ }
975
+
976
+ /* ─────────────────────────────────────────────────────────────────────────
977
+ * Component: Switch (--c-switch-*)
978
+ * Layer 3 knobs. All values resolve to existing --s-* semantic tokens
979
+ * except --c-switch-thumb-bg which maps to --p-sand-50 (warm off-white
980
+ * has no semantic alias — intentional; the thumb sits on both dark and
981
+ * amber surfaces and must contrast with both).
982
+ *
983
+ * Fixes two bugs in the original shadcn output:
984
+ * 1. Thumb was bg-background → #0a0908 (near-black, invisible on track)
985
+ * → now --c-switch-thumb-bg (#f6f1e7, warm off-white).
986
+ * 2. Focus ring was ring-2/ring-ring/ring-offset (outline approach)
987
+ * → now --c-switch-focus-ring (box-shadow only, uniform DS contract).
988
+ *
989
+ * PR: claude-main/refactor/atoms-switch
990
+ * ─────────────────────────────────────────────────────────────────────── */
991
+
992
+ :root {
993
+ /* Switch */
994
+ --c-switch-track-off-bg: var(--s-surface-elevated); /* #1f1c18 — elevated dark surface */
995
+ --c-switch-track-off-border: var(--s-border-subtle); /* #2a2622 — inset ring (via CSS border) */
996
+ --c-switch-track-on-bg: var(--s-brand-solid); /* #E07A4A — amber checked track */
997
+ --c-switch-track-on-bg-hover: var(--s-brand-hover); /* #ea915a — lighter amber on hover */
998
+ --c-switch-track-on-bg-active: var(--s-brand-pressed); /* #c2663b — darker amber on press */
999
+ --c-switch-thumb-bg: var(--p-sand-50); /* #f6f1e7 — warm off-white (no s-* alias) */
1000
+ --c-switch-focus-ring: 0 0 0 2px var(--s-surface-page), 0 0 0 3px var(--s-border-focus);
1001
+ --c-switch-disabled-opacity: 0.40;
1002
+ }
1003
+
1004
+ /* Textarea — uniform focus rings (DS v0 ch.5.2)
1005
+ * Structure: 2px page-bg gap + 1px solid outer ring.
1006
+ * Kept separate from the shared --c-input-ring-focus (single translucent spread)
1007
+ * to avoid cross-PR conflicts with Input/Select refactors. */
1008
+ :root {
1009
+ --c-textarea-ring-focus: 0 0 0 2px var(--s-surface-page), 0 0 0 3px var(--s-border-focus);
1010
+ --c-textarea-ring-focus-error: 0 0 0 2px var(--s-surface-page), 0 0 0 3px var(--s-danger-solid);
1011
+ }
1012
+
1013
+ /* ─────────────────────────────────────────────────────────────────────────
1014
+ * (The former duplicate "LAYER 3 — Toast component tokens" block was merged
1015
+ * into the single canonical --c-toast-* block above. Both Radix Toast
1016
+ * (toast.tsx) and Sonner (sonner.tsx) now read one consistent definition —
1017
+ * no more last-write-wins collision on the semantic tint surfaces.)
1018
+ * ─────────────────────────────────────────────────────────────────────── */
1019
+
1020
+ /* ─────────────────────────────────────────────────────────────────────────
1021
+ * Accordion component tokens (Layer 3 — appended, do not edit blocks above)
1022
+ * All values resolve to existing --s-* / --p-* tokens; no raw colour literals.
1023
+ * ─────────────────────────────────────────────────────────────────────── */
1024
+
1025
+ :root {
1026
+ /* Divider between items */
1027
+ --c-accordion-border: var(--s-border-subtle);
1028
+
1029
+ /* Trigger text */
1030
+ --c-accordion-trigger-fg: var(--s-ink-primary);
1031
+ --c-accordion-trigger-weight: var(--p-weight-500);
1032
+
1033
+ /* Trigger backgrounds (rest = transparent, applied inline) */
1034
+ --c-accordion-trigger-bg-hover: var(--s-surface-raised); /* #1a1714 — bg lift, not underline */
1035
+ --c-accordion-trigger-bg-active: var(--s-surface-elevated); /* #1f1c18 — press */
1036
+
1037
+ /* Content area */
1038
+ --c-accordion-content-fg: var(--s-ink-secondary); /* #c9c0b4 */
1039
+ --c-accordion-content-size: var(--p-text-14); /* 14px */
1040
+
1041
+ /* Chevron indicator */
1042
+ --c-accordion-indicator-color: var(--s-ink-muted); /* #7d7568 — muted at rest */
1043
+ --c-accordion-indicator-color-open: var(--s-brand-solid); /* #E07A4A — amber when open */
1044
+
1045
+ /* Shape */
1046
+ --c-accordion-item-radius: var(--p-radius-sm); /* 4px */
1047
+
1048
+ /* Spacing */
1049
+ --c-accordion-padding-x: var(--p-space-4); /* 16px */
1050
+ --c-accordion-padding-y: 14px; /* intentional: between --p-space-3 (12) and --p-space-4 (16) */
1051
+ }
1052
+
1053
+ /* ─────────────────────────────────────────────────────────────────────────
1054
+ * LAYER 3 — Breadcrumb (--c-breadcrumb-*)
1055
+ *
1056
+ * Resolves exclusively to Layer-2 semantic tokens (--s-*) and safe literal
1057
+ * values. Never reference --p-* primitives directly — use --s-* aliases so
1058
+ * the component responds correctly to surface-level theme overrides.
1059
+ * ─────────────────────────────────────────────────────────────────────── */
1060
+
1061
+ :root {
1062
+ /* Typography */
1063
+ --c-breadcrumb-font-size: 13px; /* slightly below body — secondary chrome */
1064
+ --c-breadcrumb-font-weight: 400;
1065
+ --c-breadcrumb-gap: 6px;
1066
+
1067
+ /* Link colors */
1068
+ --c-breadcrumb-link-fg: var(--s-ink-muted); /* ancestor links — recede */
1069
+ --c-breadcrumb-link-fg-hover: var(--s-ink-secondary); /* hover lift */
1070
+ --c-breadcrumb-link-fg-active: var(--s-brand-fg); /* most-recent clickable crumb */
1071
+
1072
+ /* Current page */
1073
+ --c-breadcrumb-page-fg: var(--s-ink-primary); /* highest contrast — "you are here" */
1074
+ --c-breadcrumb-page-weight: 500; /* weight-500 distinguishes from links */
1075
+
1076
+ /* Separator */
1077
+ --c-breadcrumb-separator-fg: var(--s-ink-disabled); /* lowest contrast — structural only */
1078
+ --c-breadcrumb-separator-size: 12px; /* smaller than body — de-emphasised */
1079
+
1080
+ /* Ellipsis collapse button */
1081
+ --c-breadcrumb-ellipsis-size: 28px; /* 28×28px touch target */
1082
+ --c-breadcrumb-ellipsis-radius: 4px; /* radius-sm */
1083
+
1084
+ /* Shape */
1085
+ --c-breadcrumb-radius: 4px; /* radius-sm — for focus ring clipping */
1086
+ }
1087
+
1088
+ /* Collapsible (Molecules) — panel with animated reveal + amber trigger affordance.
1089
+ * Resolves to existing --s-* semantic tokens; never touches --p-* primitives.
1090
+ * Ring: double-layer box-shadow — 2px page-bg gap + 1px amber outer ring. */
1091
+ :root {
1092
+ --c-collapsible-bg: var(--s-surface-panel);
1093
+ --c-collapsible-bg-hover: var(--s-surface-raised);
1094
+ --c-collapsible-border: var(--s-border-subtle);
1095
+ --c-collapsible-border-hover: var(--s-border-strong);
1096
+ --c-collapsible-radius: var(--p-radius-md);
1097
+ --c-collapsible-header-fg: var(--s-ink-primary);
1098
+ --c-collapsible-content-bg: var(--s-surface-raised);
1099
+ --c-collapsible-content-border: var(--s-border-subtle);
1100
+ --c-collapsible-item-fg: var(--s-ink-secondary);
1101
+ --c-collapsible-trigger-fg: var(--s-ink-muted);
1102
+ --c-collapsible-trigger-fg-hover: var(--s-brand-solid);
1103
+ --c-collapsible-trigger-ring: 0 0 0 2px var(--s-surface-page), 0 0 0 3px #E07A4A;
1104
+ }
1105
+
1106
+ /* ─────────────────────────────────────────────────────────────────────────
1107
+ * LAYER 3 — HoverCard component tokens (--c-hovercard-*)
1108
+ *
1109
+ * Panel uses the card/overlay radius tier (--p-radius-lg = 10px), NOT the
1110
+ * input/button tier (--p-radius-md = 6px). Focus ring is the DS uniform
1111
+ * double box-shadow: 2px page-bg gap + 3px amber outline.
1112
+ * ─────────────────────────────────────────────────────────────────────── */
1113
+
1114
+ :root {
1115
+ --c-hovercard-bg: var(--s-surface-raised); /* #1a1714 raised overlay */
1116
+ --c-hovercard-border: var(--s-border-subtle); /* #2a2622 */
1117
+ --c-hovercard-radius: var(--p-radius-lg); /* 10px — overlay/card tier */
1118
+ --c-hovercard-padding: var(--p-space-4); /* 16px */
1119
+ --c-hovercard-shadow: var(--p-shadow); /* 0 4px 12px rgba(0,0,0,0.45) */
1120
+ --c-hovercard-width: 288px;
1121
+ /* DS uniform focus ring: inner gap in page-bg colour + outer amber ring */
1122
+ --c-hovercard-focus-ring: 0 0 0 2px var(--s-surface-page), 0 0 0 3px var(--s-brand-solid);
1123
+ }
1124
+
1125
+ /* ─────────────────────────────────────────────────────────────────────────
1126
+ * InputOTP — component tokens (--c-otp-*)
1127
+ *
1128
+ * Layer 3 block. All values resolve through existing --s-* / --p-* tokens.
1129
+ * Consumers can override any knob to retheme the OTP widget in isolation.
1130
+ *
1131
+ * Active focus ring: box-shadow 0 0 0 2px var(--background), 0 0 0 3px #E07A4A
1132
+ * (the ONE uniform DFL ring — 2px page-bg gap + 1px amber outline; see §Focus Ring above).
1133
+ * ─────────────────────────────────────────────────────────────────────── */
1134
+
1135
+ :root {
1136
+ /* Geometry */
1137
+ --c-otp-slot-w: 48px; /* was 36px (shadcn baseline) */
1138
+ --c-otp-slot-h: 56px; /* was 36px — enlarged for touch + legibility */
1139
+ --c-otp-slot-radius: var(--p-radius-md); /* 6px */
1140
+ --c-otp-group-gap: 14px; /* gap between groups (not within) */
1141
+
1142
+ /* Backgrounds */
1143
+ --c-otp-slot-bg: var(--s-surface-raised); /* empty slot */
1144
+ --c-otp-slot-bg-filled: var(--s-surface-elevated); /* slot with digit / active */
1145
+
1146
+ /* Borders */
1147
+ --c-otp-slot-border: var(--s-border-subtle); /* idle */
1148
+ --c-otp-slot-border-active: var(--s-border-focus); /* amber #E07A4A — active slot */
1149
+ --c-otp-slot-border-error: var(--s-danger-solid); /* invalid code */
1150
+ --c-otp-slot-border-success: var(--s-success-solid); /* verified code */
1151
+
1152
+ /* Typography — JetBrains Mono for unambiguous digit rendering (0/O, 1/l) */
1153
+ --c-otp-slot-fg: var(--s-ink-primary);
1154
+ --c-otp-font: var(--p-font-mono); /* JetBrains Mono */
1155
+ --c-otp-font-size: 20px;
1156
+ --c-otp-font-weight: 600;
1157
+ }
1158
+ /* Pagination — compound nav (DS v0 amber active tile + DS focus ring).
1159
+ * All values resolve to existing --s-* or --p-* tokens — never raw hex. */
1160
+ :root {
1161
+ --c-pagination-item-size: 34px;
1162
+ --c-pagination-item-radius: var(--p-radius-sm); /* 4px — square-ish tiles */
1163
+ --c-pagination-nav-radius: var(--p-radius-md); /* 6px — nav controls */
1164
+ --c-pagination-item-font: var(--p-text-13); /* 13px */
1165
+ --c-pagination-item-weight: var(--p-weight-500);
1166
+ --c-pagination-item-fg: var(--s-ink-muted); /* inactive tile label */
1167
+ --c-pagination-item-fg-hover: var(--s-ink-primary);
1168
+ --c-pagination-item-bg-hover: var(--s-surface-raised);
1169
+ --c-pagination-active-bg: var(--s-brand-solid); /* #E07A4A amber solid fill */
1170
+ --c-pagination-active-fg: var(--p-sand-950); /* #0a0908 dark on amber */
1171
+ --c-pagination-active-weight: var(--p-weight-600);
1172
+ --c-pagination-nav-fg: var(--s-ink-secondary);
1173
+ --c-pagination-nav-fg-hover: var(--s-ink-primary);
1174
+ --c-pagination-nav-bg-hover: var(--s-surface-raised);
1175
+ --c-pagination-ellipsis-fg: var(--s-ink-muted);
1176
+ --c-pagination-disabled-opacity: 0.35;
1177
+ --c-pagination-gap: var(--p-space-1); /* 4px between tiles */
1178
+ }
1179
+
1180
+
1181
+ /* ─────────────────────────────────────────────────────────────────────────
1182
+ * COMPONENT — PasswordInput (--c-passwordinput-*)
1183
+ *
1184
+ * Layer 3 knobs for the PasswordInput molecule (Input atom + reveal toggle).
1185
+ * Resolves Tailwind-utility leaks (text-muted-foreground / hover:text-foreground)
1186
+ * to explicit DS semantic tokens so the toggle responds to theme overrides.
1187
+ *
1188
+ * Input border / error tokens are shared with --c-input-* (no duplication).
1189
+ * ─────────────────────────────────────────────────────────────────────── */
1190
+
1191
+ :root {
1192
+ /* Toggle button ink */
1193
+ --c-passwordinput-toggle-fg: var(--s-ink-muted); /* idle — was text-muted-foreground */
1194
+ --c-passwordinput-toggle-fg-hover: var(--s-ink-primary); /* hover — was hover:text-foreground */
1195
+ }
1196
+
1197
+ /* ─────────────────────────────────────────────────────────────────────────
1198
+ * LAYER 3 — Component: Popover (--c-popover-*)
1199
+ *
1200
+ * Floating content surface anchored to a trigger.
1201
+ * Built on @radix-ui/react-popover.
1202
+ *
1203
+ * All values resolve to existing --s-* semantic or --p-* primitive tokens.
1204
+ * Never edit --s-* / --p-* here; only --c-popover-* additions allowed.
1205
+ * ─────────────────────────────────────────────────────────────────────── */
1206
+
1207
+ :root {
1208
+ /* Surface — one step above raised for strong float contrast */
1209
+ --c-popover-bg: var(--s-surface-elevated); /* #1f1c18 */
1210
+ /* Foreground */
1211
+ --c-popover-fg: var(--s-ink-primary);
1212
+ --c-popover-fg-muted: var(--s-ink-muted);
1213
+ /* Border */
1214
+ --c-popover-border: var(--s-border-subtle); /* #2a2622 */
1215
+ /* Radius — overlays use lg (10px), not md (6px) which reads as input-level */
1216
+ --c-popover-radius: var(--p-radius-lg); /* 10px */
1217
+ /* Shadow — DS token, not Tailwind shadow-md */
1218
+ --c-popover-shadow: var(--p-shadow); /* 0 4px 12px rgba(0,0,0,.45) */
1219
+ /* Padding knob */
1220
+ --c-popover-padding: var(--p-space-4); /* 16px */
1221
+ }
1222
+
1223
+ /* ─────────────────────────────────────────────────────────────────────────
1224
+ * LAYER 3 — Component: Select (--c-select-*)
1225
+ *
1226
+ * 12 knobs covering trigger surface, dropdown menu, items and states.
1227
+ * All values resolve to existing --s-* semantic tokens (no new primitives).
1228
+ * Focus ring is handled by .ds-focus-ring (above) — no separate token needed.
1229
+ *
1230
+ * Trigger states:
1231
+ * resting → --c-select-border (sand-700)
1232
+ * hover → --c-select-border-hover (sand-600)
1233
+ * focus/open → --c-select-border-focus (amber-500) + 1px outline at 3px offset
1234
+ * disabled → opacity 0.45 (no border change)
1235
+ * error → --c-select-border-error (danger-solid)
1236
+ *
1237
+ * Item states:
1238
+ * hover/kbd-focus → --c-select-item-bg-hover (sand-850) — amber NEVER as hover bg
1239
+ * selected → --c-select-item-bg-selected (amber 10% alpha) + check icon amber
1240
+ * ─────────────────────────────────────────────────────────────────────── */
1241
+
1242
+ :root {
1243
+ /* Trigger surface */
1244
+ --c-select-bg: var(--s-surface-raised); /* sand-850 */
1245
+ --c-select-fg: var(--s-ink-primary); /* sand-50 */
1246
+ --c-select-placeholder: var(--s-ink-muted); /* sand-400 */
1247
+ --c-select-radius: var(--p-radius-md); /* 6px */
1248
+
1249
+ /* Trigger border states */
1250
+ --c-select-border: var(--s-border-subtle); /* sand-700 */
1251
+ --c-select-border-hover: var(--s-border-strong); /* sand-600 */
1252
+ --c-select-border-focus: var(--s-border-focus); /* amber-500 */
1253
+ --c-select-border-error: var(--s-danger-solid); /* red-500 */
1254
+
1255
+ /* Chevron icon */
1256
+ --c-select-icon-color: var(--s-ink-muted); /* sand-400 */
1257
+ --c-select-icon-color-hover: var(--s-ink-secondary); /* sand-200 */
1258
+
1259
+ /* Dropdown menu surface */
1260
+ --c-select-menu-bg: var(--s-surface-elevated); /* sand-800 */
1261
+ --c-select-menu-border: var(--s-border-subtle); /* sand-700 */
1262
+ --c-select-menu-shadow: var(--p-shadow-lg); /* 0 12px 30px rgba(0,0,0,.6) */
1263
+ --c-select-menu-radius: var(--p-radius-lg); /* 10px */
1264
+
1265
+ /* Menu items */
1266
+ --c-select-item-fg: var(--s-ink-secondary); /* sand-200 */
1267
+ --c-select-item-fg-hover: var(--s-ink-primary); /* sand-50 */
1268
+ --c-select-item-bg-hover: var(--s-surface-raised); /* sand-850 — NOT amber */
1269
+ --c-select-item-bg-selected: var(--s-brand-subtle); /* amber 10% alpha */
1270
+ --c-select-item-check-color: var(--s-brand-solid); /* amber-500 */
1271
+
1272
+ /* Group label + separator */
1273
+ --c-select-label-fg: var(--s-ink-muted); /* sand-400 */
1274
+ --c-select-separator-color: var(--s-border-subtle); /* sand-700 */
1275
+ }
1276
+
1277
+ /* ─────────────────────────────────────────────────────────────────────────
1278
+ * AppNavbar component tokens (--c-navbar-*)
1279
+ *
1280
+ * Resolves to existing --s-* semantic tokens — do NOT hardcode hex here.
1281
+ * The navbar surface is ALWAYS --s-surface-page (dark-first per DFL DS v0).
1282
+ * The `theme` prop on AppNavbar controls only the toggle icon (Moon ↔ Sun),
1283
+ * not the background. Per-component overrides: set --c-navbar-* on a parent.
1284
+ * ─────────────────────────────────────────────────────────────────────── */
1285
+
1286
+ :root {
1287
+ /* Structure */
1288
+ --c-navbar-bg: var(--s-surface-panel); /* batch2 appshell: elevated topbar (was surface-page) */
1289
+ --c-navbar-border: var(--s-border-subtle);
1290
+ --c-navbar-h: var(--c-header-h); /* batch2 appshell: indirect ref ==56px */ /* matches --c-header-h */
1291
+ --c-navbar-px: var(--p-space-4);
1292
+
1293
+ /* Breadcrumb ink */
1294
+ --c-navbar-breadcrumb-fg: var(--s-ink-muted);
1295
+ --c-navbar-breadcrumb-fg-current: var(--s-ink-primary);
1296
+ --c-navbar-breadcrumb-sep: var(--s-ink-muted);
1297
+
1298
+ /* Actions slot gap (between last crumb and injected CTA) */
1299
+ --c-navbar-action-gap: var(--p-space-2);
1300
+ }
1301
+
1302
+ /* AppSidebar organism — Layer 3 component tokens.
1303
+ * All values resolve to existing --s-* semantic tokens.
1304
+ * Override these to retheme the AppSidebar without touching semantics. */
1305
+ :root {
1306
+ --c-appsidebar-bg: var(--s-surface-page); /* batch2 appshell: sidebar flush w/ page (was surface-panel) */ /* #141210 — panel depth, NOT page bg */
1307
+ --c-appsidebar-item-active-bg: var(--s-brand-subtle); /* rgba(224,122,74,0.10) — brand tint */
1308
+ --c-appsidebar-item-active-fg: var(--s-brand-fg); /* #f0a872 — amber-300 text */
1309
+ --c-appsidebar-item-active-border: var(--s-brand-solid); /* #E07A4A — 3px left indicator */
1310
+ --c-appsidebar-focus-ring-gap: var(--s-surface-panel); /* 2px gap matches sidebar panel bg */
1311
+ --c-appsidebar-focus-ring-color: var(--s-brand-solid); /* 1px amber ring */
1312
+ }
1313
+
1314
+ /* Calendar — DFL DS v0 component tokens.
1315
+ * All knobs resolve to --s-* semantic tokens; none touch --p-* primitives
1316
+ * directly (except rgba tints that reference the amber primitive colour).
1317
+ *
1318
+ * Layer layout:
1319
+ * Container --c-cal-bg / --c-cal-border / --c-cal-radius / --c-cal-padding
1320
+ * Nav buttons --c-cal-nav-btn-*
1321
+ * Caption/head --c-cal-caption-fg / --c-cal-head-fg
1322
+ * Day cells --c-cal-day-{radius,fg,bg-hover,fg-outside}
1323
+ * Today state --c-cal-day-today-{bg,fg,border} ← tinted, NOT filled
1324
+ * Selected --c-cal-day-selected-{bg,fg,bg-hover} ← solid amber fill
1325
+ * Range mid --c-cal-range-mid-{bg,fg} ← amber 14% tint
1326
+ * Range end --c-cal-range-end-{bg,fg} ← same solid fill as selected
1327
+ * Disabled --c-cal-day-disabled-fg
1328
+ */
1329
+ :root {
1330
+ --c-cal-bg: var(--s-surface-panel);
1331
+ --c-cal-border: var(--s-border-subtle);
1332
+ --c-cal-radius: var(--p-radius-lg);
1333
+ --c-cal-padding: var(--p-space-4);
1334
+ }
1335
+
1336
+ :root {
1337
+ --c-cal-nav-btn-bg: transparent;
1338
+ --c-cal-nav-btn-bg-hover: var(--s-surface-elevated);
1339
+ --c-cal-nav-btn-fg: var(--s-ink-muted);
1340
+ --c-cal-nav-btn-fg-hover: var(--s-ink-primary);
1341
+ --c-cal-nav-btn-border: var(--s-border-subtle);
1342
+ --c-cal-nav-btn-border-hover: var(--s-border-strong);
1343
+ --c-cal-nav-btn-radius: var(--p-radius-md);
1344
+ }
1345
+
1346
+ :root {
1347
+ --c-cal-caption-fg: var(--s-ink-primary);
1348
+ --c-cal-head-fg: var(--s-ink-muted);
1349
+ }
1350
+
1351
+ :root {
1352
+ --c-cal-day-radius: var(--p-radius-md);
1353
+ --c-cal-day-fg: var(--s-ink-primary);
1354
+ --c-cal-day-bg-hover: var(--s-surface-elevated);
1355
+ --c-cal-day-fg-outside: var(--s-ink-disabled);
1356
+ }
1357
+
1358
+ /* Today: amber 12%-opacity tinted bg + 30%-opacity amber border.
1359
+ * Intentionally LIGHTER than the selected fill so the two states are visually
1360
+ * distinct even when both land on the same day. */
1361
+ :root {
1362
+ --c-cal-day-today-bg: rgba(224, 122, 74, 0.12);
1363
+ --c-cal-day-today-fg: var(--s-brand-fg);
1364
+ --c-cal-day-today-border: rgba(224, 122, 74, 0.30);
1365
+ }
1366
+
1367
+ /* Selected: solid amber fill (same brand-solid as button primary). */
1368
+ :root {
1369
+ --c-cal-day-selected-bg: var(--s-brand-solid);
1370
+ --c-cal-day-selected-fg: var(--p-sand-950);
1371
+ --c-cal-day-selected-bg-hover: var(--s-brand-hover);
1372
+ }
1373
+
1374
+ /* Range mid: amber 14% tint spanning the interior of a range selection. */
1375
+ :root {
1376
+ --c-cal-range-mid-bg: rgba(224, 122, 74, 0.14);
1377
+ --c-cal-range-mid-fg: var(--s-brand-fg);
1378
+ }
1379
+
1380
+ /* Range start / end caps: same solid fill as selected day. */
1381
+ :root {
1382
+ --c-cal-range-end-bg: var(--s-brand-solid);
1383
+ --c-cal-range-end-fg: var(--p-sand-950);
1384
+ }
1385
+
1386
+ /* Disabled: use --s-ink-disabled at 0.45 opacity via the component class. */
1387
+ :root {
1388
+ --c-cal-day-disabled-fg: var(--s-ink-disabled);
1389
+ }
1390
+
1391
+ /* Carousel — nav buttons + dot indicators (Layer 3 component knobs).
1392
+ * All values resolve to existing --s-* semantic tokens (or --p-* where no
1393
+ * semantic alias exists, e.g. amber-400 hover ink via --s-brand-hover).
1394
+ * Consumed by CarouselPrevious, CarouselNext, CarouselDots in carousel.tsx. */
1395
+ :root {
1396
+ --c-carousel-nav-bg: var(--s-surface-elevated); /* default button bg */
1397
+ --c-carousel-nav-border: var(--s-border-subtle); /* default button border */
1398
+ --c-carousel-nav-fg: var(--s-ink-secondary); /* default arrow color */
1399
+ --c-carousel-nav-bg-hover: var(--s-brand-subtle); /* hover/focus bg: amber 10% */
1400
+ --c-carousel-nav-border-hover: var(--s-brand-border); /* hover/focus border: amber 22% */
1401
+ --c-carousel-nav-fg-hover: var(--s-brand-hover); /* hover/focus arrow: amber-400 */
1402
+ --c-carousel-nav-fg-disabled: var(--s-ink-disabled); /* disabled arrow (no opacity hack) */
1403
+ --c-carousel-dot-bg: var(--s-border-strong); /* inactive dot */
1404
+ --c-carousel-dot-active: var(--s-brand-solid); /* active dot: amber-500 */
1405
+ --c-carousel-dot-radius: var(--p-radius-pill); /* dot shape */
1406
+ --c-carousel-radius: var(--p-radius-lg); /* track border-radius */
1407
+ }
1408
+
1409
+ /* Chart — tooltip + chrome component-token knobs.
1410
+ * Series palette lives in the Compatibility aliases block as --chart-1…5.
1411
+ * These knobs cover the tooltip surface and structural chrome only. */
1412
+ :root {
1413
+ --c-chart-tooltip-bg: var(--s-surface-elevated);
1414
+ --c-chart-tooltip-border: var(--s-border-strong);
1415
+ --c-chart-tooltip-fg: var(--s-ink-primary);
1416
+ --c-chart-tooltip-muted-fg: var(--s-ink-muted);
1417
+ --c-chart-tooltip-radius: var(--p-radius-md);
1418
+ --c-chart-tooltip-shadow: var(--p-shadow-lg);
1419
+ --c-chart-grid: var(--s-border-subtle);
1420
+ --c-chart-axis-fg: var(--s-ink-muted);
1421
+ }
1422
+ /* Command palette — --c-command-*
1423
+ * Layer 3 additions for Organisms/Command. All values resolve to existing
1424
+ * --s-* semantic tokens (no new primitives added).
1425
+ * Fix: bg-accent (#E07A4A) as item hover → surface-elevated + amber left-bar.
1426
+ * Fix: outline-hidden on input → uniform DFL focus ring via box-shadow.
1427
+ * Fix: shortcut font → --s-font-mono (JetBrains Mono). */
1428
+ :root {
1429
+ --c-command-bg: var(--s-surface-raised); /* #1a1714 */
1430
+ --c-command-border: var(--s-border-subtle); /* #2a2622 */
1431
+ --c-command-radius: var(--p-radius-lg); /* 10px */
1432
+ --c-command-shadow: var(--p-shadow); /* 0 4px 12px … */
1433
+ --c-command-input-sep: var(--s-border-subtle); /* separator below input */
1434
+ --c-command-group-fg: var(--s-ink-muted); /* headings + icons default */
1435
+ --c-command-item-fg: var(--s-ink-secondary); /* item text default */
1436
+ --c-command-item-hover-bg: var(--s-surface-elevated); /* #1f1c18 — replaces bg-accent */
1437
+ --c-command-item-hover-fg: var(--s-ink-primary); /* #f6f1e7 on hover/selected */
1438
+ --c-command-item-icon-hover-fg: var(--s-ink-secondary); /* #c9c0b4 icon on hover */
1439
+ --c-command-item-sel-bar: var(--s-brand-solid); /* amber 2px left indicator */
1440
+ --c-command-shortcut-fg: var(--s-ink-muted); /* shortcut text */
1441
+ --c-command-sep: var(--s-border-subtle); /* CommandSeparator line */
1442
+ --c-command-empty-fg: var(--s-ink-muted); /* empty state text */
1443
+ --c-command-focus-color: var(--s-border-focus); /* amber #E07A4A for focus ring */
1444
+ }
1445
+
1446
+
1447
+ /* ─────────────────────────────────────────────────────────────────────────
1448
+ * LAYER 3 — ContextMenu component tokens (--c-contextmenu-*)
1449
+ *
1450
+ * Resolves DS token hierarchy for right-click / context menus.
1451
+ * All knobs reference existing --s-* / --p-* tokens.
1452
+ * ─────────────────────────────────────────────────────────────────────── */
1453
+
1454
+ :root {
1455
+ /* Panel */
1456
+ --c-contextmenu-bg: var(--s-surface-elevated);
1457
+ --c-contextmenu-border: var(--s-border-subtle);
1458
+ --c-contextmenu-radius: var(--p-radius-md);
1459
+ --c-contextmenu-shadow: var(--p-shadow-lg), 0 0 0 1px var(--s-border-subtle);
1460
+
1461
+ /* Items — default text */
1462
+ --c-contextmenu-item-fg: var(--s-ink-secondary);
1463
+
1464
+ /* Items — hover / keyboard-highlighted (Radix data-[highlighted]) */
1465
+ --c-contextmenu-item-hover-bg: var(--s-brand-subtle);
1466
+ --c-contextmenu-item-hover-fg: var(--s-brand-fg);
1467
+
1468
+ /* Items — keyboard-focus inset ring (layered on top of hover bg) */
1469
+ --c-contextmenu-item-focus-ring: inset 0 0 0 1px rgba(224, 122, 74, 0.35);
1470
+
1471
+ /* Label / group heading */
1472
+ --c-contextmenu-label-fg: var(--s-ink-muted);
1473
+
1474
+ /* Separator */
1475
+ --c-contextmenu-separator: var(--s-border-subtle);
1476
+
1477
+ /* Shortcut badges — same muted hue as label */
1478
+ --c-contextmenu-shortcut-fg: var(--s-ink-muted);
1479
+
1480
+ /* Trigger focus ring (outer off-element DS spec ring) */
1481
+ --c-contextmenu-trigger-ring: 0 0 0 2px var(--s-surface-page), 0 0 0 3px var(--s-border-focus);
1482
+ }
1483
+ /* DropdownMenu — Organisms layer (DS v0 brand fixes)
1484
+ *
1485
+ * Fixes four critical brand failures vs vanilla shadcn:
1486
+ * 1. Focus ring: 2px bg-gap + 1px amber ring (box-shadow), NOT amber bg-flood
1487
+ * 2. Separator: --s-border-subtle (#2a2622) > popover bg (#1a1714) — now visible
1488
+ * 3. Label: --s-ink-muted (#7d7568) + uppercase + tight tracking — visual hierarchy
1489
+ * 4. Shortcut: --p-font-mono (JetBrains Mono) — brand-spec font for ⌘ keys
1490
+ */
1491
+ :root {
1492
+ --c-dropdownmenu-bg: var(--s-surface-raised);
1493
+ --c-dropdownmenu-border: var(--s-border-subtle);
1494
+ --c-dropdownmenu-radius: var(--p-radius-md);
1495
+ --c-dropdownmenu-item-radius: var(--p-radius-sm);
1496
+ --c-dropdownmenu-shadow: 0 4px 12px rgba(0,0,0,0.45), 0 1px 3px rgba(0,0,0,0.3);
1497
+ --c-dropdownmenu-item-fg: var(--s-ink-secondary);
1498
+ --c-dropdownmenu-item-bg-hover: var(--s-surface-elevated);
1499
+ --c-dropdownmenu-item-fg-hover: var(--s-ink-primary);
1500
+ --c-dropdownmenu-label-fg: var(--s-ink-muted);
1501
+ --c-dropdownmenu-separator: var(--s-border-subtle);
1502
+ --c-dropdownmenu-shortcut-fg: var(--s-ink-muted);
1503
+ --c-dropdownmenu-check-color: var(--s-brand-solid);
1504
+ --c-dropdownmenu-destructive-fg: var(--s-danger-fg);
1505
+ --c-dropdownmenu-destructive-bghov: var(--s-danger-subtle);
1506
+ }
1507
+ /* Focus ring: 2px gap (popover bg) + 1px amber — uniform DS ring spec.
1508
+ * The gap colour matches the popover bg so the ring "floats" above the item. */
1509
+ :root {
1510
+ --c-dropdownmenu-focus-ring: 0 0 0 2px var(--s-surface-raised), 0 0 0 3px var(--s-brand-solid);
1511
+ }
1512
+
1513
+
1514
+ /* Form — component knobs for the React Hook Form wrapper */
1515
+ :root {
1516
+ --c-form-gap: var(--p-space-2); /* 8px — gap between label / control / hint / message */
1517
+ --c-form-section-gap: var(--p-space-5); /* 20px — gap between FormItems */
1518
+ --c-form-label-fg: var(--s-ink-secondary);
1519
+ --c-form-label-error-fg: var(--s-danger-fg); /* softer #e89898 vs full-sat #e07a7a */
1520
+ --c-form-description-fg: var(--s-ink-muted);
1521
+ --c-form-message-error-fg: var(--s-danger-fg);
1522
+ }
1523
+
1524
+
1525
+ /* ======================================================================
1526
+ * DS-token redesign BATCH 2 — 29-component integration (new component tokens)
1527
+ * ====================================================================== */
1528
+ :root {
1529
+ /* -- organisms-gantt -- */
1530
+ --c-gantt-bg: var(--s-surface-panel);
1531
+ --c-gantt-header-bg: var(--s-surface-raised);
1532
+ --c-gantt-border: var(--s-border-subtle);
1533
+ --c-gantt-bar-radius: var(--p-radius-sm);
1534
+ --c-gantt-dep-color: var(--s-brand-solid);
1535
+ --c-gantt-name-col: 320px;
1536
+
1537
+ /* -- organisms-loginpage -- */
1538
+ --c-loginpage-card-bg: var(--c-card-bg); /* #141210 via --s-surface-panel */
1539
+ --c-loginpage-card-border: var(--c-card-border); /* #2a2622 via --s-border-subtle */
1540
+ --c-loginpage-card-radius: var(--c-card-radius); /* 10px via --p-radius-lg */
1541
+ --c-loginpage-card-shadow: var(--p-shadow-lg); /* 0 12px 30px rgba(0,0,0,0.6) */
1542
+ --c-loginpage-error-bg: var(--s-danger-subtle); /* rgba(224,122,122,0.12) */
1543
+ --c-loginpage-error-border: var(--s-danger-border); /* rgba(224,122,122,0.40) */
1544
+ --c-loginpage-error-fg: var(--s-danger-fg); /* #e89898 via --p-red-400 */
1545
+ --c-loginpage-focus-ring:
1546
+
1547
+ /* -- organisms-loginscreen -- */
1548
+ --c-loginscreen-bg: var(--s-surface-page);
1549
+ --c-loginscreen-title-font: var(--s-font-display);
1550
+ --c-loginscreen-title-size: var(--p-text-24);
1551
+ --c-loginscreen-error-fg: var(--s-danger-fg);
1552
+ --c-loginscreen-footer-fg: var(--s-brand-fg);
1553
+ --c-loginscreen-focus-gap: var(--s-surface-page);
1554
+ --c-loginscreen-focus-color: var(--s-border-focus);
1555
+
1556
+ /* -- organisms-menubar -- */
1557
+ --c-menubar-bar-bg: var(--s-surface-panel); /* #141210 — distinct from page bg */
1558
+ --c-menubar-bar-border: var(--s-border-subtle); /* #2a2622 */
1559
+ --c-menubar-bar-radius: var(--p-radius-md); /* 6px */
1560
+ --c-menubar-trigger-fg: var(--s-ink-secondary); /* #c9c0b4 — idle */
1561
+ --c-menubar-trigger-bg-hover: var(--s-surface-raised); /* #1a1714 */
1562
+ --c-menubar-trigger-bg-open: var(--s-surface-elevated); /* #1f1c18 */
1563
+ --c-menubar-trigger-radius: var(--p-radius-sm); /* 4px */
1564
+ --c-menubar-content-bg: var(--s-surface-raised); /* #1a1714 — dropdown panel */
1565
+ --c-menubar-item-fg: var(--s-ink-primary); /* #f6f1e7 */
1566
+ --c-menubar-item-bg-hover: var(--s-brand-subtle); /* rgba(224,122,74,0.10) — NOT solid amber */
1567
+ --c-menubar-item-radius: var(--p-radius-sm); /* 4px */
1568
+ --c-menubar-shortcut-font: var(--p-font-mono); /* JetBrains Mono — DS kbd rule */
1569
+ --c-menubar-shortcut-fg: var(--s-ink-muted); /* #7d7568 */
1570
+ --c-menubar-indicator-color: var(--s-brand-solid); /* #E07A4A — checkbox/radio checked mark */
1571
+ --c-menubar-dest-fg: var(--s-danger-fg); /* #e89898 */
1572
+ --c-menubar-dest-bg-hover: var(--s-danger-subtle); /* rgba(224,122,122,0.12) */
1573
+ --c-menubar-ring-trigger: 0 0 0 2px var(--c-menubar-bar-bg), 0 0 0 3px var(--s-border-focus);
1574
+ --c-menubar-ring-item: 0 0 0 2px var(--c-menubar-content-bg), 0 0 0 3px var(--s-border-focus);
1575
+
1576
+ /* -- organisms-navigationmenu -- */
1577
+ --c-nav-bg: transparent;
1578
+ --c-nav-fg: var(--s-ink-secondary);
1579
+ --c-nav-trigger-radius: var(--p-radius-md); /* 6px */
1580
+ --c-nav-trigger-h: 36px;
1581
+ --c-nav-trigger-px: 14px;
1582
+ --c-nav-trigger-hover-bg: var(--s-surface-elevated);
1583
+ --c-nav-trigger-hover-fg: var(--s-ink-primary);
1584
+ --c-nav-trigger-open-bg: var(--s-brand-subtle);
1585
+ --c-nav-trigger-open-fg: var(--s-brand-fg);
1586
+ --c-nav-trigger-open-border: var(--s-brand-border);
1587
+ --c-nav-content-bg: var(--s-surface-raised);
1588
+ --c-nav-content-border: var(--s-border-subtle);
1589
+ --c-nav-content-radius: 8px;
1590
+ --c-nav-content-shadow: var(--p-shadow);
1591
+ --c-nav-item-hover-bg: var(--s-surface-elevated);
1592
+ --c-nav-item-hover-fg: var(--s-ink-primary);
1593
+ --c-nav-item-active-bg: var(--s-brand-subtle);
1594
+ --c-nav-item-active-fg: var(--s-brand-fg);
1595
+ --c-nav-item-active-border: var(--s-brand-solid);
1596
+ --c-nav-indicator-color: var(--s-border-subtle);
1597
+
1598
+ /* -- organisms-publishdrawer -- */
1599
+ --c-publish-drawer-platform-fg: var(--s-danger-solid);
1600
+ --c-publish-drawer-success-fg: var(--s-success-solid);
1601
+ --c-publish-drawer-footer-bg: var(--s-surface-raised);
1602
+ --c-publish-drawer-header-sep: var(--s-border-subtle);
1603
+ --c-publish-drawer-postid-font: var(--p-font-mono);
1604
+
1605
+ /* -- organisms-resizable -- */
1606
+ --c-resizable-handle-track: var(--s-border-subtle); /* idle */
1607
+ --c-resizable-handle-track-hover: var(--s-border-strong); /* pointer-over */
1608
+ --c-resizable-handle-track-focus: var(--s-brand-solid); /* :focus-visible */
1609
+ --c-resizable-handle-track-drag: var(--s-brand-solid); /* dragging */
1610
+ --c-resizable-grip-bg: var(--s-surface-elevated); /* idle bg */
1611
+ --c-resizable-grip-border: var(--s-border-subtle); /* idle border */
1612
+ --c-resizable-grip-border-hover: var(--s-border-strong); /* hover border */
1613
+ --c-resizable-grip-border-focus: var(--s-brand-solid); /* focus border */
1614
+ --c-resizable-grip-border-drag: var(--s-brand-solid); /* drag border */
1615
+ --c-resizable-grip-icon: var(--s-ink-muted); /* idle dots */
1616
+ --c-resizable-grip-icon-drag: var(--s-brand-solid); /* drag dots */
1617
+
1618
+ /* -- organisms-sheet -- */
1619
+ --c-sheet-bg: var(--c-dialog-bg); /* --s-surface-raised = #1a1714 */
1620
+ --c-sheet-border: var(--c-dialog-border); /* --s-border-subtle = #2a2622 */
1621
+ --c-sheet-shadow: var(--c-dialog-shadow); /* 0 24px 60px rgba(0,0,0,0.7) */
1622
+ --c-sheet-scrim: var(--c-dialog-scrim); /* rgba(10,9,8,0.76) — token-native */
1623
+ --c-sheet-radius-bottom: var(--p-radius-xl); /* 14px */
1624
+ --c-sheet-close-ring: 0 0 0 2px var(--c-sheet-bg), 0 0 0 3px #E07A4A;
1625
+
1626
+ /* -- organisms-sidebar -- */
1627
+ --c-sidebar-bg: var(--s-surface-page);
1628
+ --c-sidebar-item-fg: var(--s-ink-secondary);
1629
+ --c-sidebar-item-hover-bg: var(--s-surface-raised);
1630
+ --c-sidebar-item-active-bg: var(--s-brand-subtle); /* rgba(224,122,74,.10) amber tint */
1631
+ --c-sidebar-item-active-fg: var(--s-brand-solid); /* #E07A4A amber text + icon */
1632
+ --c-sidebar-item-active-bar-w: 2px; /* left-edge indicator width */
1633
+ --c-sidebar-group-label-fg: var(--s-ink-muted); /* #7d7568 muted, Barlow Condensed */
1634
+ --c-sidebar-ring: var(--s-border-focus); /* #E07A4A */
1635
+ --c-sidebar-border: var(--s-border-subtle);
1636
+
1637
+ /* -- organisms-table -- */
1638
+ --c-table-row-selected-bg: var(--s-brand-subtle); /* rgba(224,122,74,0.10) */
1639
+ --c-table-row-selected-border: var(--s-brand-border); /* rgba(224,122,74,0.22) */
1640
+ --c-table-caption-fg: var(--s-ink-muted); /* #7d7568 */
1641
+
1642
+ /* -- organisms-usermenu -- */
1643
+ --c-usermenu-trigger-hover-bg: rgba(246, 241, 231, 0.06);
1644
+ --c-usermenu-trigger-open-bg: rgba(246, 241, 231, 0.08);
1645
+ --c-usermenu-panel-bg: var(--s-surface-elevated); /* #1f1c18 */
1646
+ --c-usermenu-panel-width: 208px; /* replaces hardcoded w-52 */
1647
+ --c-usermenu-item-hover-bg: var(--s-border-subtle);
1648
+ --c-usermenu-danger-fg: var(--s-danger-fg); /* #e89898 */
1649
+ --c-usermenu-danger-hover-bg: var(--s-danger-subtle); /* rgba(224,122,122,0.12) */
1650
+ --c-usermenu-item-focus-ring: 0 0 0 2px var(--s-surface-elevated), 0 0 0 3px var(--s-border-focus);
1651
+ --c-usermenu-item-danger-focus-ring: 0 0 0 2px var(--s-surface-elevated), 0 0 0 3px var(--s-danger-fg);
1652
+
1653
+ /* -- templates-dashboard -- */
1654
+ --c-dashboard-stat-font: var(--s-font-mono);
1655
+ --c-dashboard-stat-focus-ring: 0 0 0 2px var(--s-surface-page), 0 0 0 3px var(--s-brand-solid);
1656
+
1657
+ /* -- templates-kanban -- */
1658
+ --c-kanban-col-bg: var(--s-surface-panel); /* #141210 */
1659
+ --c-kanban-col-border: var(--s-border-subtle); /* #2a2622 */
1660
+ --c-kanban-col-radius: var(--p-radius-lg); /* 10px */
1661
+ --c-kanban-accent-todo: var(--s-border-strong); /* neutral #3a3530 */
1662
+ --c-kanban-accent-doing: var(--s-brand-solid); /* amber #E07A4A */
1663
+ --c-kanban-accent-review: var(--s-info-solid); /* blue #7aa2e0 */
1664
+ --c-kanban-accent-done: var(--s-success-solid); /* green #5ec27e */
1665
+ --c-kanban-count-bg: var(--s-surface-elevated); /* #1f1c18 */
1666
+ --c-kanban-count-border: var(--s-border-subtle); /* #2a2622 */
1667
+ --c-kanban-card-bg: var(--s-surface-raised); /* #1a1714 — floats above column */
1668
+ --c-kanban-card-bg-hover: var(--s-surface-elevated); /* #1f1c18 — hover lift */
1669
+ --c-kanban-card-border: var(--s-border-subtle); /* #2a2622 */
1670
+ --c-kanban-card-border-hover: var(--s-border-strong); /* #3a3530 */
1671
+ --c-kanban-card-radius: var(--p-radius-md); /* 6px */
1672
+ --c-kanban-card-drag-border: var(--s-brand-border); /* rgba(224,122,74,0.22) */
1673
+ --c-kanban-card-drag-bg: var(--s-surface-elevated); /* #1f1c18 */
1674
+ --c-kanban-card-drag-shadow: var(--p-shadow-lg); /* 0 12px 30px rgba(0,0,0,0.6) */
1675
+ --c-kanban-card-focus-ring: 0 0 0 2px var(--s-surface-page), 0 0 0 3px #E07A4A;
1676
+ --c-kanban-card-done-opacity: 0.6;
1677
+ --c-kanban-dropzone-border: var(--s-border-strong); /* 1.5px dashed #3a3530 */
1678
+ --c-kanban-dropzone-fg: var(--s-ink-muted); /* #7d7568 */
1679
+ --c-kanban-id-font: var(--s-font-mono); /* JetBrains Mono */
1680
+ --c-kanban-id-fg: var(--s-ink-muted); /* #7d7568 */
1681
+
1682
+ /* -- templates-listpage -- */
1683
+ --c-listpage-pagination-active-bg: var(--s-brand-subtle); /* rgba(224,122,74,0.10) */
1684
+ --c-listpage-pagination-active-border: var(--s-brand-border); /* rgba(224,122,74,0.22) */
1685
+ --c-listpage-pagination-active-fg: var(--s-brand-solid); /* #E07A4A amber text */
1686
+ --c-listpage-cell-id-fg: var(--s-ink-secondary); /* #c9c0b4 — ID is metadata, not primary data */
1687
+ --c-listpage-cell-amount-fg: var(--s-ink-primary); /* #f6f1e7 — amount is salient, full contrast */
1688
+ --c-listpage-empty-icon-bg: var(--s-surface-elevated); /* #1f1c18 — raised container */
1689
+ --c-listpage-empty-icon-border: var(--s-border-subtle); /* #2a2622 — container stroke */
1690
+ --c-listpage-empty-icon-fg: var(--s-ink-muted); /* #7d7568 — icon recedes, not accent */
1691
+ --c-listpage-empty-title-fg: var(--s-ink-secondary); /* #c9c0b4 — bold title, not primary ink */
1692
+ --c-listpage-empty-sub-fg: var(--s-ink-muted); /* #7d7568 — supporting copy, fully muted */
1693
+
1694
+ /* -- templates-appshell -- */
1695
+ --c-appshell-nav-active-bg: var(--s-brand-subtle); /* amber 10% fill on active item */
1696
+ --c-appshell-nav-active-fg: var(--s-brand-solid); /* #E07A4A text on active item */
1697
+ --c-appshell-nav-active-border: var(--s-brand-border); /* amber 22% border on active item */
1698
+ --c-appshell-nav-hover-bg: var(--s-surface-raised); /* #1a1714 hover surface */
1699
+ --c-appshell-nav-hover-fg: var(--s-ink-primary); /* #f6f1e7 hover text */
1700
+ --c-appshell-focus-ring: 0 0 0 2px var(--s-surface-page), 0 0 0 3px var(--s-brand-solid);
1701
+ }
1702
+
1703
+ /* AppShell interactive focus ring (box-shadow, not outline — survives sidebar overflow:hidden). */
1704
+ .c-appshell-focus:focus-visible {
1705
+ outline: none;
1706
+ box-shadow: var(--c-appshell-focus-ring);
1707
+ transition: none;
1708
+ }