cynx-ui 1.3.20 → 1.3.21

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.
@@ -58,8 +58,8 @@ const STYLES = `
58
58
 
59
59
  .cynx-timepicker-stepper-btn:hover {
60
60
  background: var(--surface, #ffffff);
61
- border-color: var(--accent);
62
- color: var(--accent);
61
+ border-color: var(--accent, #f99e2c);
62
+ color: var(--accent, #f99e2c);
63
63
  }
64
64
 
65
65
  .cynx-timepicker-stepper-btn:active {
@@ -170,6 +170,7 @@ export function TimePicker({
170
170
  hideIcon = false, // Legacy prop alias for showIcon = false
171
171
  showFormatToggle = false, // Minimal default: false
172
172
  showPresets = false, // Minimal default: false
173
+ presets = null, // Custom presets array e.g. ['09:00', '18:00']
173
174
  showTimezoneSelect = false, // Minimal default: false
174
175
  showPlaceholder = false, // Minimal default: false
175
176
  timezone = 'Asia/Tashkent',
@@ -516,8 +517,6 @@ export function TimePicker({
516
517
  const hours12List = Array.from({ length: 12 }, (_, i) => i + 1);
517
518
  const fullMinutesList = Array.from({ length: 60 }, (_, i) => i);
518
519
 
519
- const presets24 = ['00:00', '07:00', '08:00', '09:00', '12:00', '18:00', '23:00'];
520
- const presets12 = ['07:00 AM', '09:00 AM', '12:00 PM', '03:00 PM', '06:00 PM', '11:00 PM'];
521
520
 
522
521
  const inputHeight = style?.height
523
522
  ? (typeof style.height === 'number' ? `${style.height}px` : style.height)
@@ -531,7 +530,7 @@ export function TimePicker({
531
530
  >
532
531
  {label && (
533
532
  <label
534
- style={{ fontSize: 11, fontWeight: 600, color: 'var(--t2, var(--muted))', textTransform: 'uppercase', letterSpacing: '.08em', display: 'block', marginBottom: 4 }}
533
+ style={{ fontSize: 11, fontWeight: 600, color: 'var(--t2, var(--muted, #797b8d))', textTransform: 'uppercase', letterSpacing: '.08em', display: 'block', marginBottom: 4 }}
535
534
  >
536
535
  {label}
537
536
  </label>
@@ -555,7 +554,7 @@ export function TimePicker({
555
554
  display: 'flex',
556
555
  alignItems: 'center',
557
556
  justifyContent: 'center',
558
- color: open ? 'var(--accent)' : 'var(--t2, var(--muted, #9b9daa))',
557
+ color: open ? 'var(--accent, #f99e2c)' : 'var(--t2, var(--muted, #9b9daa))',
559
558
  zIndex: 1,
560
559
  transition: 'color .15s ease',
561
560
  }}
@@ -584,7 +583,7 @@ export function TimePicker({
584
583
  height: inputHeight,
585
584
  paddingLeft: displayClockIcon ? (size === 'xs' ? 22 : 28) : (size === 'xs' ? 6 : 10),
586
585
  paddingRight: size === 'xs' ? 18 : 26,
587
- border: `1px solid ${open ? 'var(--accent)' : 'var(--bd, var(--border, #d7d8e0))'}`,
586
+ border: `1px solid ${open ? 'var(--accent, #f99e2c)' : 'var(--bd, var(--border, #d7d8e0))'}`,
588
587
  borderRadius: 'var(--rads, 8px)',
589
588
  fontSize: fontSize,
590
589
  background: disabled ? 'var(--grey-1, #f5f5f8)' : 'var(--input-bg, var(--surface, #ffffff))',
@@ -630,7 +629,7 @@ export function TimePicker({
630
629
  <ChevronDown
631
630
  size={13}
632
631
  style={{
633
- color: open ? 'var(--accent)' : 'var(--t2, var(--muted, #9b9daa))',
632
+ color: open ? 'var(--accent, #f99e2c)' : 'var(--t2, var(--muted, #9b9daa))',
634
633
  transform: open ? 'rotate(180deg)' : 'none',
635
634
  transition: 'transform .2s ease, color .15s ease',
636
635
  pointerEvents: 'none',
@@ -665,24 +664,24 @@ export function TimePicker({
665
664
  >
666
665
  {/* Header Bar: Variant Switcher */}
667
666
  {showVariantToggle && (
668
- <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 8, paddingBottom: 6, borderBottom: '1px solid var(--border-light, var(--border))' }}>
669
- <span style={{ fontSize: '.68rem', fontWeight: 700, color: 'var(--fg, var(--t1))', textTransform: 'uppercase', letterSpacing: '.05em' }}>
667
+ <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 8, paddingBottom: 6, borderBottom: '1px solid var(--border-light, var(--border, #e2e8f0))' }}>
668
+ <span style={{ fontSize: '.68rem', fontWeight: 700, color: 'var(--fg, var(--t1, #0f172a))', textTransform: 'uppercase', letterSpacing: '.05em' }}>
670
669
  Режим
671
670
  </span>
672
671
 
673
- <div style={{ display: 'inline-flex', background: 'var(--grey-1, var(--surface-hover))', padding: 2, borderRadius: 6, border: '1px solid var(--border-light, var(--border))' }}>
672
+ <div style={{ display: 'inline-flex', background: 'var(--grey-1, var(--surface-hover, #f5f5f8))', padding: 2, borderRadius: 6, border: '1px solid var(--border-light, var(--border, #e2e8f0))' }}>
674
673
  <button
675
674
  type="button"
676
675
  onClick={() => setActiveVariant('stepper')}
677
676
  className="cynx-timepicker-cell"
678
677
  style={{
679
- padding: '2px 8px',
678
+ padding: '2px 6px',
680
679
  borderRadius: 4,
681
680
  border: 'none',
682
681
  fontSize: '.68rem',
683
682
  fontWeight: activeVariant === 'stepper' ? 700 : 500,
684
- background: activeVariant === 'stepper' ? 'var(--surface, var(--bg))' : 'transparent',
685
- color: activeVariant === 'stepper' ? 'var(--accent, var(--blue))' : 'var(--muted, var(--t2))',
683
+ background: activeVariant === 'stepper' ? 'var(--surface, var(--bg, #f8fafc))' : 'transparent',
684
+ color: activeVariant === 'stepper' ? 'var(--accent, #f99e2c)' : 'var(--muted, var(--t2, #797b8d))',
686
685
  boxShadow: activeVariant === 'stepper' ? '0 1px 3px rgba(0,0,0,0.1)' : 'none',
687
686
  cursor: 'pointer',
688
687
  display: 'flex',
@@ -690,7 +689,7 @@ export function TimePicker({
690
689
  gap: 3,
691
690
  }}
692
691
  >
693
- <Sliders size={11} /> Спиннер (+/-)
692
+ <Sliders size={11} /> Спиннер
694
693
  </button>
695
694
 
696
695
  <button
@@ -698,13 +697,13 @@ export function TimePicker({
698
697
  onClick={() => setActiveVariant('list')}
699
698
  className="cynx-timepicker-cell"
700
699
  style={{
701
- padding: '2px 8px',
700
+ padding: '2px 6px',
702
701
  borderRadius: 4,
703
702
  border: 'none',
704
703
  fontSize: '.68rem',
705
704
  fontWeight: activeVariant === 'list' ? 700 : 500,
706
- background: activeVariant === 'list' ? 'var(--surface, var(--bg))' : 'transparent',
707
- color: activeVariant === 'list' ? 'var(--accent, var(--blue))' : 'var(--muted, var(--t2))',
705
+ background: activeVariant === 'list' ? 'var(--surface, var(--bg, #f8fafc))' : 'transparent',
706
+ color: activeVariant === 'list' ? 'var(--accent, #f99e2c)' : 'var(--muted, var(--t2, #797b8d))',
708
707
  boxShadow: activeVariant === 'list' ? '0 1px 3px rgba(0,0,0,0.1)' : 'none',
709
708
  cursor: 'pointer',
710
709
  display: 'flex',
@@ -712,7 +711,7 @@ export function TimePicker({
712
711
  gap: 3,
713
712
  }}
714
713
  >
715
- <List size={11} /> Список (00-59)
714
+ <List size={11} /> Список
716
715
  </button>
717
716
  </div>
718
717
  </div>
@@ -720,12 +719,12 @@ export function TimePicker({
720
719
 
721
720
  {/* Optional Format Switcher (24h / 12h) */}
722
721
  {showFormatToggle && (
723
- <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 8, paddingBottom: 6, borderBottom: '1px solid var(--border-light, var(--border))' }}>
724
- <span style={{ fontSize: '.68rem', fontWeight: 700, color: 'var(--fg, var(--t1))', textTransform: 'uppercase', letterSpacing: '.05em' }}>
722
+ <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 8, paddingBottom: 6, borderBottom: '1px solid var(--border-light, var(--border, #e2e8f0))' }}>
723
+ <span style={{ fontSize: '.68rem', fontWeight: 700, color: 'var(--fg, var(--t1, #0f172a))', textTransform: 'uppercase', letterSpacing: '.05em' }}>
725
724
  Формат
726
725
  </span>
727
726
 
728
- <div style={{ display: 'inline-flex', background: 'var(--grey-1, var(--surface-hover))', padding: 2, borderRadius: 6, border: '1px solid var(--border-light, var(--border))' }}>
727
+ <div style={{ display: 'inline-flex', background: 'var(--grey-1, var(--surface-hover, #f5f5f8))', padding: 2, borderRadius: 6, border: '1px solid var(--border-light, var(--border, #e2e8f0))' }}>
729
728
  <button
730
729
  type="button"
731
730
  onClick={() => switchMode('24h')}
@@ -736,8 +735,8 @@ export function TimePicker({
736
735
  border: 'none',
737
736
  fontSize: '.68rem',
738
737
  fontWeight: mode === '24h' ? 700 : 500,
739
- background: mode === '24h' ? 'var(--surface, var(--bg))' : 'transparent',
740
- color: mode === '24h' ? 'var(--accent, var(--blue))' : 'var(--muted, var(--t2))',
738
+ background: mode === '24h' ? 'var(--surface, var(--bg, #f8fafc))' : 'transparent',
739
+ color: mode === '24h' ? 'var(--accent, #f99e2c)' : 'var(--muted, var(--t2, #797b8d))',
741
740
  boxShadow: mode === '24h' ? '0 1px 3px rgba(0,0,0,0.1)' : 'none',
742
741
  cursor: 'pointer',
743
742
  }}
@@ -754,13 +753,13 @@ export function TimePicker({
754
753
  border: 'none',
755
754
  fontSize: '.68rem',
756
755
  fontWeight: mode === '12h' ? 700 : 500,
757
- background: mode === '12h' ? 'var(--surface, var(--bg))' : 'transparent',
758
- color: mode === '12h' ? 'var(--accent, var(--blue))' : 'var(--muted, var(--t2))',
756
+ background: mode === '12h' ? 'var(--surface, var(--bg, #f8fafc))' : 'transparent',
757
+ color: mode === '12h' ? 'var(--accent, #f99e2c)' : 'var(--muted, var(--t2, #797b8d))',
759
758
  boxShadow: mode === '12h' ? '0 1px 3px rgba(0,0,0,0.1)' : 'none',
760
759
  cursor: 'pointer',
761
760
  }}
762
761
  >
763
- 12h AM/PM
762
+ 12h
764
763
  </button>
765
764
  </div>
766
765
  </div>
@@ -780,23 +779,23 @@ export function TimePicker({
780
779
  width: '100%',
781
780
  padding: '4px 8px',
782
781
  borderRadius: 6,
783
- border: '1px solid var(--border-light, var(--border))',
784
- background: 'var(--grey-1, var(--surface-hover))',
782
+ border: '1px solid var(--border-light, var(--border, #e2e8f0))',
783
+ background: 'var(--grey-1, var(--surface-hover, #f5f5f8))',
785
784
  fontSize: '.68rem',
786
- color: 'var(--fg, var(--t1))',
785
+ color: 'var(--fg, var(--t1, #0f172a))',
787
786
  cursor: 'pointer',
788
787
  fontWeight: 500,
789
788
  }}
790
789
  >
791
790
  <span style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
792
- <Globe size={12} color="var(--accent, var(--blue))" />
791
+ <Globe size={12} color="var(--accent, #f99e2c)" />
793
792
  {COMMON_TIMEZONES.find(t => t.value === tz)?.label || tz}
794
793
  </span>
795
- <ChevronDown size={12} color="var(--muted, var(--t2))" />
794
+ <ChevronDown size={12} color="var(--muted, var(--t2, #797b8d))" />
796
795
  </button>
797
796
 
798
797
  {showTzPicker && (
799
- <div style={{ marginTop: 4, background: 'var(--surface, var(--bg))', border: '1px solid var(--border-light, var(--border))', borderRadius: 6, boxShadow: 'var(--shadow)', padding: 4, display: 'flex', flexDirection: 'column', gap: 2 }}>
798
+ <div style={{ marginTop: 4, background: 'var(--surface, var(--bg, #f8fafc))', border: '1px solid var(--border-light, var(--border, #e2e8f0))', borderRadius: 6, boxShadow: 'var(--shadow, 0 1px 3px rgba(0,0,0,.08), 0 1px 2px rgba(0,0,0,.06))', padding: 4, display: 'flex', flexDirection: 'column', gap: 2 }}>
800
799
  {COMMON_TIMEZONES.map(t => (
801
800
  <button
802
801
  key={t.value}
@@ -809,8 +808,8 @@ export function TimePicker({
809
808
  border: 'none',
810
809
  textAlign: 'left',
811
810
  fontSize: '.68rem',
812
- background: tz === t.value ? 'var(--accent, var(--blue))' : 'transparent',
813
- color: tz === t.value ? '#ffffff' : 'var(--fg, var(--t1))',
811
+ background: tz === t.value ? 'var(--accent, #f99e2c)' : 'transparent',
812
+ color: tz === t.value ? '#ffffff' : 'var(--fg, var(--t1, #0f172a))',
814
813
  cursor: 'pointer',
815
814
  fontWeight: tz === t.value ? 600 : 400,
816
815
  }}
@@ -823,10 +822,10 @@ export function TimePicker({
823
822
  </div>
824
823
  )}
825
824
 
826
- {/* Optional Quick Presets Bar */}
827
- {showPresets && (
828
- <div style={{ display: 'flex', gap: 4, flexWrap: 'wrap', marginBottom: 8, paddingBottom: 6, borderBottom: '1px solid var(--border-light, var(--border))' }}>
829
- {(mode === '12h' ? presets12 : presets24).map(p => (
825
+ {/* Optional Quick Presets Bar (only if presets array passed) */}
826
+ {Array.isArray(presets) && presets.length > 0 && (
827
+ <div style={{ display: 'flex', gap: 4, flexWrap: 'wrap', marginBottom: 8, paddingBottom: 6, borderBottom: '1px solid var(--border-light, var(--border, #e2e8f0))' }}>
828
+ {presets.map(p => (
830
829
  <button
831
830
  key={p}
832
831
  type="button"
@@ -839,9 +838,9 @@ export function TimePicker({
839
838
  padding: '3px 6px',
840
839
  borderRadius: 4,
841
840
  fontSize: '.68rem',
842
- border: '1px solid var(--border-light, var(--border))',
843
- background: inputValue === p ? 'var(--accent, var(--blue))' : 'var(--grey-1, var(--surface-hover))',
844
- color: inputValue === p ? '#ffffff' : 'var(--fg, var(--t1))',
841
+ border: '1px solid var(--border-light, var(--border, #e2e8f0))',
842
+ background: inputValue === p ? 'var(--accent, #f99e2c)' : 'var(--grey-1, var(--surface-hover, #f5f5f8))',
843
+ color: inputValue === p ? '#ffffff' : 'var(--fg, var(--t1, #0f172a))',
845
844
  cursor: 'pointer',
846
845
  fontWeight: 500,
847
846
  }}
@@ -863,16 +862,16 @@ export function TimePicker({
863
862
  flex: 1,
864
863
  padding: '4px 0',
865
864
  borderRadius: 6,
866
- border: '1px solid var(--border-light, var(--border))',
865
+ border: '1px solid var(--border-light, var(--border, #e2e8f0))',
867
866
  fontSize: '.75rem',
868
867
  fontWeight: parsed.ampm === 'AM' ? 700 : 500,
869
- background: parsed.ampm === 'AM' ? 'var(--accent, var(--blue))' : 'var(--grey-1, var(--surface-hover))',
870
- color: parsed.ampm === 'AM' ? '#ffffff' : 'var(--fg, var(--t1))',
868
+ background: parsed.ampm === 'AM' ? 'var(--accent, #f99e2c)' : 'var(--grey-1, var(--surface-hover, #f5f5f8))',
869
+ color: parsed.ampm === 'AM' ? '#ffffff' : 'var(--fg, var(--t1, #0f172a))',
871
870
  cursor: 'pointer',
872
871
  textAlign: 'center',
873
872
  }}
874
873
  >
875
- AM (Утро)
874
+ AM
876
875
  </button>
877
876
  <button
878
877
  type="button"
@@ -882,16 +881,16 @@ export function TimePicker({
882
881
  flex: 1,
883
882
  padding: '4px 0',
884
883
  borderRadius: 6,
885
- border: '1px solid var(--border-light, var(--border))',
884
+ border: '1px solid var(--border-light, var(--border, #e2e8f0))',
886
885
  fontSize: '.75rem',
887
886
  fontWeight: parsed.ampm === 'PM' ? 700 : 500,
888
- background: parsed.ampm === 'PM' ? 'var(--accent, var(--blue))' : 'var(--grey-1, var(--surface-hover))',
889
- color: parsed.ampm === 'PM' ? '#ffffff' : 'var(--fg, var(--t1))',
887
+ background: parsed.ampm === 'PM' ? 'var(--accent, #f99e2c)' : 'var(--grey-1, var(--surface-hover, #f5f5f8))',
888
+ color: parsed.ampm === 'PM' ? '#ffffff' : 'var(--fg, var(--t1, #0f172a))',
890
889
  cursor: 'pointer',
891
890
  textAlign: 'center',
892
891
  }}
893
892
  >
894
- PM (Вечер)
893
+ PM
895
894
  </button>
896
895
  </div>
897
896
  )}
@@ -901,13 +900,13 @@ export function TimePicker({
901
900
  <div style={{ display: 'grid', gridTemplateColumns: showSeconds ? '1fr 1fr 1fr' : '1fr 1fr', gap: 10, padding: '4px 0' }}>
902
901
  {/* Hours Stepper */}
903
902
  <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4 }}>
904
- <div style={{ fontSize: '.65rem', fontWeight: 600, color: 'var(--muted, var(--t2))' }}>
905
- {mode === '12h' ? 'Час (1-12)' : 'Час (0-23)'}
903
+ <div style={{ fontSize: '.65rem', fontWeight: 600, color: 'var(--muted, var(--t2, #797b8d))' }}>
904
+ Час
906
905
  </div>
907
906
  <button type="button" className="cynx-timepicker-stepper-btn" onClick={() => stepHour(1)} title="+1 Час">
908
907
  <ChevronUp size={14} />
909
908
  </button>
910
- <div style={{ fontSize: '1.2rem', fontWeight: 700, fontVariantNumeric: 'tabular-nums', padding: '6px 0', color: 'var(--accent, var(--blue))' }}>
909
+ <div style={{ fontSize: '1.2rem', fontWeight: 700, fontVariantNumeric: 'tabular-nums', padding: '6px 0', color: 'var(--accent, #f99e2c)' }}>
911
910
  {mode === '12h' ? parsed.h12 : parsed.h24}
912
911
  </div>
913
912
  <button type="button" className="cynx-timepicker-stepper-btn" onClick={() => stepHour(-1)} title="-1 Час">
@@ -917,11 +916,11 @@ export function TimePicker({
917
916
 
918
917
  {/* Minutes Stepper */}
919
918
  <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4 }}>
920
- <div style={{ fontSize: '.65rem', fontWeight: 600, color: 'var(--muted, var(--t2))' }}>Мин (0-59)</div>
919
+ <div style={{ fontSize: '.65rem', fontWeight: 600, color: 'var(--muted, var(--t2, #797b8d))' }}>Мин</div>
921
920
  <button type="button" className="cynx-timepicker-stepper-btn" onClick={() => stepMinute(1)} title="+1 Мин">
922
921
  <ChevronUp size={14} />
923
922
  </button>
924
- <div style={{ fontSize: '1.2rem', fontWeight: 700, fontVariantNumeric: 'tabular-nums', padding: '6px 0', color: 'var(--accent, var(--blue))' }}>
923
+ <div style={{ fontSize: '1.2rem', fontWeight: 700, fontVariantNumeric: 'tabular-nums', padding: '6px 0', color: 'var(--accent, #f99e2c)' }}>
925
924
  {parsed.m}
926
925
  </div>
927
926
  <button type="button" className="cynx-timepicker-stepper-btn" onClick={() => stepMinute(-1)} title="-1 Мин">
@@ -932,11 +931,11 @@ export function TimePicker({
932
931
  {/* Seconds Stepper */}
933
932
  {showSeconds && (
934
933
  <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4 }}>
935
- <div style={{ fontSize: '.65rem', fontWeight: 600, color: 'var(--muted, var(--t2))' }}>Сек (0-59)</div>
934
+ <div style={{ fontSize: '.65rem', fontWeight: 600, color: 'var(--muted, var(--t2, #797b8d))' }}>Сек</div>
936
935
  <button type="button" className="cynx-timepicker-stepper-btn" onClick={() => stepSecond(1)} title="+1 Сек">
937
936
  <ChevronUp size={14} />
938
937
  </button>
939
- <div style={{ fontSize: '1.2rem', fontWeight: 700, fontVariantNumeric: 'tabular-nums', padding: '6px 0', color: 'var(--accent, var(--blue))' }}>
938
+ <div style={{ fontSize: '1.2rem', fontWeight: 700, fontVariantNumeric: 'tabular-nums', padding: '6px 0', color: 'var(--accent, #f99e2c)' }}>
940
939
  {parsed.s}
941
940
  </div>
942
941
  <button type="button" className="cynx-timepicker-stepper-btn" onClick={() => stepSecond(-1)} title="-1 Сек">
@@ -950,8 +949,8 @@ export function TimePicker({
950
949
  <div style={{ display: 'grid', gridTemplateColumns: showSeconds ? '1fr 1fr 1fr' : '1fr 1fr', gap: 6 }}>
951
950
  {/* Hours Column */}
952
951
  <div>
953
- <div style={{ fontSize: '.65rem', fontWeight: 600, color: 'var(--muted, var(--t2))', marginBottom: 4, textAlign: 'center' }}>
954
- {mode === '12h' ? 'Час (1-12)' : 'Час (0-23)'}
952
+ <div style={{ fontSize: '.65rem', fontWeight: 600, color: 'var(--muted, var(--t2, #797b8d))', marginBottom: 4, textAlign: 'center' }}>
953
+ Час
955
954
  </div>
956
955
  <div style={{ maxHeight: 150, overflowY: 'auto', display: 'flex', flexDirection: 'column', gap: 2, paddingRight: 2 }}>
957
956
  {(mode === '12h' ? hours12List : hours24List).map(hNum => {
@@ -970,8 +969,8 @@ export function TimePicker({
970
969
  fontSize: '.75rem',
971
970
  cursor: 'pointer',
972
971
  fontWeight: isSelected ? 700 : 400,
973
- background: isSelected ? 'var(--accent, var(--blue))' : 'transparent',
974
- color: isSelected ? '#ffffff' : 'var(--fg, var(--t1))',
972
+ background: isSelected ? 'var(--accent, #f99e2c)' : 'transparent',
973
+ color: isSelected ? '#ffffff' : 'var(--fg, var(--t1, #0f172a))',
975
974
  }}
976
975
  >
977
976
  {pad(hNum)}
@@ -983,7 +982,7 @@ export function TimePicker({
983
982
 
984
983
  {/* Minutes Column: FULL LIST 00 to 59! */}
985
984
  <div>
986
- <div style={{ fontSize: '.65rem', fontWeight: 600, color: 'var(--muted, var(--t2))', marginBottom: 4, textAlign: 'center' }}>Мин (00-59)</div>
985
+ <div style={{ fontSize: '.65rem', fontWeight: 600, color: 'var(--muted, var(--t2, #797b8d))', marginBottom: 4, textAlign: 'center' }}>Мин</div>
987
986
  <div style={{ maxHeight: 150, overflowY: 'auto', display: 'flex', flexDirection: 'column', gap: 2, paddingRight: 2 }}>
988
987
  {fullMinutesList.map(mNum => {
989
988
  const mStr = pad(mNum);
@@ -1002,8 +1001,8 @@ export function TimePicker({
1002
1001
  fontSize: '.75rem',
1003
1002
  cursor: 'pointer',
1004
1003
  fontWeight: isSelected ? 700 : 400,
1005
- background: isSelected ? 'var(--accent, var(--blue))' : 'transparent',
1006
- color: isSelected ? '#ffffff' : 'var(--fg, var(--t1))',
1004
+ background: isSelected ? 'var(--accent, #f99e2c)' : 'transparent',
1005
+ color: isSelected ? '#ffffff' : 'var(--fg, var(--t1, #0f172a))',
1007
1006
  }}
1008
1007
  >
1009
1008
  {mStr}
@@ -1016,7 +1015,7 @@ export function TimePicker({
1016
1015
  {/* Seconds Column (if showSeconds): FULL LIST 00 to 59! */}
1017
1016
  {showSeconds && (
1018
1017
  <div>
1019
- <div style={{ fontSize: '.65rem', fontWeight: 600, color: 'var(--muted, var(--t2))', marginBottom: 4, textAlign: 'center' }}>Сек (00-59)</div>
1018
+ <div style={{ fontSize: '.65rem', fontWeight: 600, color: 'var(--muted, var(--t2, #797b8d))', marginBottom: 4, textAlign: 'center' }}>Сек</div>
1020
1019
  <div style={{ maxHeight: 150, overflowY: 'auto', display: 'flex', flexDirection: 'column', gap: 2 }}>
1021
1020
  {fullMinutesList.map(sNum => {
1022
1021
  const sStr = pad(sNum);
@@ -1035,8 +1034,8 @@ export function TimePicker({
1035
1034
  fontSize: '.75rem',
1036
1035
  cursor: 'pointer',
1037
1036
  fontWeight: isSelected ? 700 : 400,
1038
- background: isSelected ? 'var(--accent, var(--blue))' : 'transparent',
1039
- color: isSelected ? '#ffffff' : 'var(--fg, var(--t1))',
1037
+ background: isSelected ? 'var(--accent, #f99e2c)' : 'transparent',
1038
+ color: isSelected ? '#ffffff' : 'var(--fg, var(--t1, #0f172a))',
1040
1039
  }}
1041
1040
  >
1042
1041
  {sStr}
@@ -1050,12 +1049,12 @@ export function TimePicker({
1050
1049
  )}
1051
1050
 
1052
1051
  {/* Footer Actions */}
1053
- <div style={{ marginTop: 8, paddingTop: 6, borderTop: '1px solid var(--border-light, var(--border))', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
1052
+ <div style={{ marginTop: 8, paddingTop: 6, borderTop: '1px solid var(--border-light, var(--border, #e2e8f0))', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
1054
1053
  <button
1055
1054
  type="button"
1056
1055
  onClick={clearTime}
1057
1056
  className="cynx-timepicker-cell"
1058
- style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--danger)', fontSize: '.7rem', fontWeight: 500 }}
1057
+ style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--danger, #f64747)', fontSize: '.7rem', fontWeight: 500 }}
1059
1058
  >
1060
1059
  Сбросить
1061
1060
  </button>
@@ -1063,7 +1062,7 @@ export function TimePicker({
1063
1062
  type="button"
1064
1063
  onClick={closePicker}
1065
1064
  className="cynx-timepicker-cell"
1066
- style={{ padding: '3px 10px', borderRadius: 4, border: 'none', background: 'var(--accent, var(--blue))', color: '#ffffff', fontSize: '.7rem', cursor: 'pointer', fontWeight: 600, display: 'flex', alignItems: 'center', gap: 4 }}
1065
+ style={{ padding: '3px 10px', borderRadius: 4, border: 'none', background: 'var(--accent, #f99e2c)', color: '#ffffff', fontSize: '.7rem', cursor: 'pointer', fontWeight: 600, display: 'flex', alignItems: 'center', gap: 4 }}
1067
1066
  >
1068
1067
  <Check size={12} /> Готово
1069
1068
  </button>
@@ -90,8 +90,8 @@ export function Toast({ toasts, remove, position = 'top-right', style = {} }) {
90
90
  {toasts.map(t => (
91
91
  <div key={t.id} className={`toast ${t.type}`} onClick={() => remove(t.id)}>
92
92
  {t.type === 'ok' || t.type === 'success'
93
- ? <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="var(--success)" strokeWidth="2.5" strokeLinecap="round"><polyline points="20 6 9 17 4 12"/></svg>
94
- : <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="var(--danger)" strokeWidth="2.5" strokeLinecap="round"><circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/></svg>
93
+ ? <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="var(--success, #27ae60)" strokeWidth="2.5" strokeLinecap="round"><polyline points="20 6 9 17 4 12"/></svg>
94
+ : <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="var(--danger, #f64747)" strokeWidth="2.5" strokeLinecap="round"><circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/></svg>
95
95
  }
96
96
  {t.msg}
97
97
  </div>
@@ -2,8 +2,8 @@ import { useMemo, useState, useRef } from 'react';
2
2
 
3
3
  const card = {
4
4
  background: 'var(--surface,#fff)',
5
- border: '1px solid var(--border)',
6
- borderRadius: 'var(--rad)',
5
+ border: '1px solid var(--border, #e2e8f0)',
6
+ borderRadius: 'var(--rad, 10px)',
7
7
  boxShadow: 'var(--shadow, 0 1px 3px rgba(0,0,0,.06), 0 1px 2px rgba(0,0,0,.04))',
8
8
  };
9
9
 
@@ -19,9 +19,9 @@ export default function UptimeBar({
19
19
  successValues = [],
20
20
  failedValues = [],
21
21
  totalSlots = 90,
22
- greenColor = 'var(--success)',
23
- redColor = 'var(--danger)',
24
- emptyColor = 'var(--grey-1)',
22
+ greenColor = 'var(--success, #27ae60)',
23
+ redColor = 'var(--danger, #f64747)',
24
+ emptyColor = 'var(--grey-1, #f5f5f8)',
25
25
  barHeight = 28,
26
26
  barRadius = 3,
27
27
  leftLabel,
@@ -86,8 +86,8 @@ export default function UptimeBar({
86
86
  background: dotColor || greenColor, flexShrink: 0,
87
87
  }} />
88
88
  )}
89
- <span style={{ fontSize: '.78rem', fontWeight: 700, color: 'var(--primary-text)', letterSpacing: '-.01em' }}>{title}</span>
90
- {subtitle && <span style={{ fontSize: '.65rem', color: 'var(--muted)', fontWeight: 500 }}>{subtitle}</span>}
89
+ <span style={{ fontSize: '.78rem', fontWeight: 700, color: 'var(--primary-text, #0f172a)', letterSpacing: '-.01em' }}>{title}</span>
90
+ {subtitle && <span style={{ fontSize: '.65rem', color: 'var(--muted, #797b8d)', fontWeight: 500 }}>{subtitle}</span>}
91
91
  </div>
92
92
  {/* Legend */}
93
93
  <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
@@ -145,32 +145,32 @@ export default function UptimeBar({
145
145
  top: tooltipPos.y,
146
146
  transform: 'translate(-50%, -100%)',
147
147
  background: 'var(--surface,#fff)',
148
- border: '1px solid var(--border)',
149
- borderRadius: 'var(--rads)',
148
+ border: '1px solid var(--border, #e2e8f0)',
149
+ borderRadius: 'var(--rads, 8px)',
150
150
  boxShadow: 'var(--smd, 0 4px 12px rgba(0,0,0,.12))',
151
151
  padding: '8px 12px',
152
152
  pointerEvents: 'none',
153
153
  zIndex: 100,
154
154
  whiteSpace: 'nowrap',
155
155
  }}>
156
- <div style={{ fontSize: '.65rem', color: 'var(--muted)', fontWeight: 500, marginBottom: 4 }}>
156
+ <div style={{ fontSize: '.65rem', color: 'var(--muted, #797b8d)', fontWeight: 500, marginBottom: 4 }}>
157
157
  {formatDate(dates[hovered])}
158
158
  </div>
159
159
  <div style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
160
160
  {bars[hovered].success > 0 && (
161
161
  <div style={{ fontSize: '.7rem', fontWeight: 700, color: greenColor }}>
162
162
  {bars[hovered].success} success login{bars[hovered].success !== 1 ? 's' : ''}
163
- {bars[hovered].failed > 0 && <span style={{ fontWeight: 500, color: 'var(--muted)' }}> ({Math.round((bars[hovered].success / (bars[hovered].success + bars[hovered].failed)) * 100)}%)</span>}
163
+ {bars[hovered].failed > 0 && <span style={{ fontWeight: 500, color: 'var(--muted, #797b8d)' }}> ({Math.round((bars[hovered].success / (bars[hovered].success + bars[hovered].failed)) * 100)}%)</span>}
164
164
  </div>
165
165
  )}
166
166
  {bars[hovered].failed > 0 && (
167
167
  <div style={{ fontSize: '.7rem', fontWeight: 700, color: redColor }}>
168
168
  {bars[hovered].failed} failed login{bars[hovered].failed !== 1 ? 's' : ''}
169
- {bars[hovered].success > 0 && <span style={{ fontWeight: 500, color: 'var(--muted)' }}> ({Math.round((bars[hovered].failed / (bars[hovered].success + bars[hovered].failed)) * 100)}%)</span>}
169
+ {bars[hovered].success > 0 && <span style={{ fontWeight: 500, color: 'var(--muted, #797b8d)' }}> ({Math.round((bars[hovered].failed / (bars[hovered].success + bars[hovered].failed)) * 100)}%)</span>}
170
170
  </div>
171
171
  )}
172
172
  {bars[hovered].success === 0 && bars[hovered].failed === 0 && (
173
- <div style={{ fontSize: '.7rem', fontWeight: 500, color: 'var(--muted)' }}>
173
+ <div style={{ fontSize: '.7rem', fontWeight: 500, color: 'var(--muted, #797b8d)' }}>
174
174
  No logins
175
175
  </div>
176
176
  )}
@@ -180,11 +180,11 @@ export default function UptimeBar({
180
180
 
181
181
  {/* Footer */}
182
182
  <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
183
- <span style={{ fontSize: '.58rem', color: 'var(--muted)', fontWeight: 500 }}>{leftLabel || '90 days ago'}</span>
184
- <span style={{ fontSize: '.78rem', fontWeight: 700, color: greenColor, fontFamily: 'var(--mono)' }}>
183
+ <span style={{ fontSize: '.58rem', color: 'var(--muted, #797b8d)', fontWeight: 500 }}>{leftLabel || '90 days ago'}</span>
184
+ <span style={{ fontSize: '.78rem', fontWeight: 700, color: greenColor, fontFamily: 'var(--mono, ui-monospace, monospace)' }}>
185
185
  {uptimePercent}%
186
186
  </span>
187
- <span style={{ fontSize: '.58rem', color: 'var(--muted)', fontWeight: 500 }}>{rightLabel || 'Today'}</span>
187
+ <span style={{ fontSize: '.58rem', color: 'var(--muted, #797b8d)', fontWeight: 500 }}>{rightLabel || 'Today'}</span>
188
188
  </div>
189
189
  </div>
190
190
  );
@@ -194,7 +194,7 @@ function LegendDot({ color, label }) {
194
194
  return (
195
195
  <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
196
196
  <span style={{ width: 7, height: 7, borderRadius: 2, background: color, flexShrink: 0 }} />
197
- <span style={{ fontSize: '.55rem', color: 'var(--muted)', fontWeight: 500 }}>{label}</span>
197
+ <span style={{ fontSize: '.55rem', color: 'var(--muted, #797b8d)', fontWeight: 500 }}>{label}</span>
198
198
  </div>
199
199
  );
200
200
  }