cynx-ui 1.3.19 → 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.
@@ -7,7 +7,7 @@ import { ChevronLeft, ChevronRight, Calendar } from 'lucide-react';
7
7
  // value – Date object or null
8
8
  // onChange – called with Date object
9
9
  // placeholder – string shown when no date selected
10
- // badges – object { 'YYYY-MM-DD': { dot: true, color: 'var(--accent)' } } for day badges
10
+ // badges – object { 'YYYY-MM-DD': { dot: true, color: 'var(--accent, #f99e2c)' } } for day badges
11
11
  // minDate – Date object, days before this are disabled
12
12
  // maxDate – Date object, days after this are disabled
13
13
  // disabled – boolean
@@ -246,7 +246,7 @@ export function DatePicker({ value, onChange, label, placeholder = 'Select date'
246
246
  {/* Weekday headers */}
247
247
  <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', marginBottom: 4 }}>
248
248
  {DAYS.map(d => (
249
- <div key={d} style={{ textAlign: 'center', fontSize: '.68rem', fontWeight: 700, color: 'var(--muted)', padding: '4px 0', fontFamily: 'var(--mono)' }}>{d}</div>
249
+ <div key={d} style={{ textAlign: 'center', fontSize: '.68rem', fontWeight: 700, color: 'var(--muted, #797b8d)', padding: '4px 0', fontFamily: 'var(--mono, ui-monospace, monospace)' }}>{d}</div>
250
250
  ))}
251
251
  </div>
252
252
  {/* Day cells */}
@@ -268,13 +268,13 @@ export function DatePicker({ value, onChange, label, placeholder = 'Select date'
268
268
  textAlign: 'center',
269
269
  padding: '6px 2px',
270
270
  fontSize: '.78rem',
271
- color: dis ? 'var(--border, #e5e7eb)' : 'var(--muted)',
271
+ color: dis ? 'var(--border, #e5e7eb)' : 'var(--muted, #797b8d)',
272
272
  cursor: dis ? 'not-allowed' : 'pointer',
273
273
  borderRadius: 'var(--radxs, 6px)',
274
274
  transition: 'background .12s',
275
275
  opacity: dis ? 0.35 : 0.7,
276
276
  }}
277
- onMouseEnter={e => { if (!dis) e.currentTarget.style.background = 'var(--grey-1)'; }}
277
+ onMouseEnter={e => { if (!dis) e.currentTarget.style.background = 'var(--grey-1, #f5f5f8)'; }}
278
278
  onMouseLeave={e => { if (!dis) e.currentTarget.style.background = 'transparent'; }}
279
279
  >
280
280
  {c.day}
@@ -294,20 +294,20 @@ export function DatePicker({ value, onChange, label, placeholder = 'Select date'
294
294
  position: 'relative', textAlign: 'center', padding: '6px 2px',
295
295
  fontSize: '.8rem', fontWeight: sel ? 700 : today ? 600 : 400,
296
296
  borderRadius: 'var(--radxs, 6px)', cursor: dis ? 'not-allowed' : 'pointer',
297
- background: sel ? 'var(--accent)' : 'transparent',
298
- color: sel ? 'var(--def-btn-text,#fff)' : dis ? 'var(--border)' : today ? 'var(--accent)' : 'var(--primary-text)',
299
- border: today && !sel ? '1.5px solid var(--accent)' : '1.5px solid transparent',
297
+ background: sel ? 'var(--accent, #f99e2c)' : 'transparent',
298
+ color: sel ? 'var(--def-btn-text,#fff)' : dis ? 'var(--border, #e2e8f0)' : today ? 'var(--accent, #f99e2c)' : 'var(--primary-text, #0f172a)',
299
+ border: today && !sel ? '1.5px solid var(--accent, #f99e2c)' : '1.5px solid transparent',
300
300
  transition: 'background .12s, color .12s',
301
301
  opacity: dis ? 0.35 : 1,
302
302
  }}
303
- onMouseEnter={e => { if (!sel && !dis) e.currentTarget.style.background = 'var(--grey-1)'; }}
303
+ onMouseEnter={e => { if (!sel && !dis) e.currentTarget.style.background = 'var(--grey-1, #f5f5f8)'; }}
304
304
  onMouseLeave={e => { if (!sel && !dis) e.currentTarget.style.background = 'transparent'; }}>
305
305
  {c.day}
306
306
  {badge && (
307
307
  <span style={{
308
308
  position: 'absolute', bottom: 2, left: '50%', transform: 'translateX(-50%)',
309
309
  width: 4, height: 4, borderRadius: '50%',
310
- background: badge.color || 'var(--accent)',
310
+ background: badge.color || 'var(--accent, #f99e2c)',
311
311
  }} />
312
312
  )}
313
313
  </div>
@@ -352,11 +352,11 @@ export function DatePicker({ value, onChange, label, placeholder = 'Select date'
352
352
  fontWeight: 600,
353
353
  cursor: dis ? 'not-allowed' : 'pointer',
354
354
  opacity: dis ? 0.35 : 1,
355
- background: sel ? 'var(--accent)' : 'transparent',
356
- color: sel ? 'var(--def-btn-text,#fff)' : dis ? 'var(--border)' : 'var(--primary-text)',
355
+ background: sel ? 'var(--accent, #f99e2c)' : 'transparent',
356
+ color: sel ? 'var(--def-btn-text,#fff)' : dis ? 'var(--border, #e2e8f0)' : 'var(--primary-text, #0f172a)',
357
357
  transition: 'background .12s',
358
358
  }}
359
- onMouseEnter={e => { if (!sel && !dis) e.currentTarget.style.background = 'var(--grey-1)'; }}
359
+ onMouseEnter={e => { if (!sel && !dis) e.currentTarget.style.background = 'var(--grey-1, #f5f5f8)'; }}
360
360
  onMouseLeave={e => { if (!sel && !dis) e.currentTarget.style.background = 'transparent'; }}
361
361
  >
362
362
  {name}
@@ -402,11 +402,11 @@ export function DatePicker({ value, onChange, label, placeholder = 'Select date'
402
402
  fontWeight: 600,
403
403
  cursor: dis ? 'not-allowed' : 'pointer',
404
404
  opacity: dis ? 0.35 : 1,
405
- background: sel ? 'var(--accent)' : 'transparent',
406
- color: sel ? 'var(--def-btn-text,#fff)' : dis ? 'var(--border)' : 'var(--primary-text)',
405
+ background: sel ? 'var(--accent, #f99e2c)' : 'transparent',
406
+ color: sel ? 'var(--def-btn-text,#fff)' : dis ? 'var(--border, #e2e8f0)' : 'var(--primary-text, #0f172a)',
407
407
  transition: 'background .12s',
408
408
  }}
409
- onMouseEnter={e => { if (!sel && !dis) e.currentTarget.style.background = 'var(--grey-1)'; }}
409
+ onMouseEnter={e => { if (!sel && !dis) e.currentTarget.style.background = 'var(--grey-1, #f5f5f8)'; }}
410
410
  onMouseLeave={e => { if (!sel && !dis) e.currentTarget.style.background = 'transparent'; }}
411
411
  >
412
412
  {yr}
@@ -450,15 +450,15 @@ export function DatePicker({ value, onChange, label, placeholder = 'Select date'
450
450
  onClick={(e) => { e.stopPropagation(); changeDay(-1); }}
451
451
  style={{
452
452
  display: 'flex', alignItems: 'center', justifyContent: 'center',
453
- width: 32, height: 32, borderRadius: 'var(--rads)',
454
- border: '1px solid var(--border)', background: 'var(--surface)',
453
+ width: 32, height: 32, borderRadius: 'var(--rads, 8px)',
454
+ border: '1px solid var(--border, #e2e8f0)', background: 'var(--surface, #ffffff)',
455
455
  cursor: dis ? 'not-allowed' : 'pointer', opacity: dis ? 0.35 : 1,
456
- color: 'var(--muted)', transition: 'all .15s', boxShadow: 'var(--shadow)',
456
+ color: 'var(--muted, #797b8d)', transition: 'all .15s', boxShadow: 'var(--shadow, 0 1px 3px rgba(0,0,0,.08), 0 1px 2px rgba(0,0,0,.06))',
457
457
  flexShrink: 0
458
458
  }}
459
459
  title="Previous day (-1)"
460
- onMouseEnter={e => { if (!dis) { e.currentTarget.style.borderColor = 'var(--accent)'; e.currentTarget.style.color = 'var(--accent)'; } }}
461
- onMouseLeave={e => { e.currentTarget.style.borderColor = 'var(--border)'; e.currentTarget.style.color = 'var(--muted)'; }}
460
+ onMouseEnter={e => { if (!dis) { e.currentTarget.style.borderColor = 'var(--accent, #f99e2c)'; e.currentTarget.style.color = 'var(--accent, #f99e2c)'; } }}
461
+ onMouseLeave={e => { e.currentTarget.style.borderColor = 'var(--border, #e2e8f0)'; e.currentTarget.style.color = 'var(--muted, #797b8d)'; }}
462
462
  >
463
463
  <ChevronLeft size={15} />
464
464
  </button>
@@ -474,15 +474,15 @@ export function DatePicker({ value, onChange, label, placeholder = 'Select date'
474
474
  onClick={(e) => { e.stopPropagation(); changeDay(1); }}
475
475
  style={{
476
476
  display: 'flex', alignItems: 'center', justifyContent: 'center',
477
- width: 32, height: 32, borderRadius: 'var(--rads)',
478
- border: '1px solid var(--border)', background: 'var(--surface)',
477
+ width: 32, height: 32, borderRadius: 'var(--rads, 8px)',
478
+ border: '1px solid var(--border, #e2e8f0)', background: 'var(--surface, #ffffff)',
479
479
  cursor: dis ? 'not-allowed' : 'pointer', opacity: dis ? 0.35 : 1,
480
- color: 'var(--muted)', transition: 'all .15s', boxShadow: 'var(--shadow)',
480
+ color: 'var(--muted, #797b8d)', transition: 'all .15s', boxShadow: 'var(--shadow, 0 1px 3px rgba(0,0,0,.08), 0 1px 2px rgba(0,0,0,.06))',
481
481
  flexShrink: 0
482
482
  }}
483
483
  title="Next day (+1)"
484
- onMouseEnter={e => { if (!dis) { e.currentTarget.style.borderColor = 'var(--accent)'; e.currentTarget.style.color = 'var(--accent)'; } }}
485
- onMouseLeave={e => { e.currentTarget.style.borderColor = 'var(--border)'; e.currentTarget.style.color = 'var(--muted)'; }}
484
+ onMouseEnter={e => { if (!dis) { e.currentTarget.style.borderColor = 'var(--accent, #f99e2c)'; e.currentTarget.style.color = 'var(--accent, #f99e2c)'; } }}
485
+ onMouseLeave={e => { e.currentTarget.style.borderColor = 'var(--border, #e2e8f0)'; e.currentTarget.style.color = 'var(--muted, #797b8d)'; }}
486
486
  >
487
487
  <ChevronRight size={15} />
488
488
  </button>
@@ -492,23 +492,23 @@ export function DatePicker({ value, onChange, label, placeholder = 'Select date'
492
492
  const renderTriggerBtn = () => (
493
493
  <button ref={btnRef} type="button" onClick={toggleOpen} style={{
494
494
  display: 'flex', alignItems: 'center', gap: 7,
495
- padding: '5px 10px', borderRadius: 'var(--rads)',
496
- border: '1px solid var(--border)', background: 'var(--surface)',
495
+ padding: '5px 10px', borderRadius: 'var(--rads, 8px)',
496
+ border: '1px solid var(--border, #e2e8f0)', background: 'var(--surface, #ffffff)',
497
497
  cursor: disabled ? 'not-allowed' : 'pointer', opacity: disabled ? 0.5 : 1,
498
- fontSize: '.8rem', color: formatted ? 'var(--primary-text)' : 'var(--muted)',
499
- fontFamily: 'var(--sans)', transition: 'border-color .15s',
500
- whiteSpace: 'nowrap', minWidth: 140, height: 32, boxShadow: 'var(--shadow)',
498
+ fontSize: '.8rem', color: formatted ? 'var(--primary-text, #0f172a)' : 'var(--muted, #797b8d)',
499
+ fontFamily: 'var(--sans, inherit)', transition: 'border-color .15s',
500
+ whiteSpace: 'nowrap', minWidth: 140, height: 32, boxShadow: 'var(--shadow, 0 1px 3px rgba(0,0,0,.08), 0 1px 2px rgba(0,0,0,.06))',
501
501
  }}
502
- onMouseEnter={e => { if (!disabled) e.currentTarget.style.borderColor = 'var(--accent)'; }}
503
- onMouseLeave={e => { e.currentTarget.style.borderColor = 'var(--border)'; }}>
504
- <Calendar size={13} style={{ color: 'var(--muted)', flexShrink: 0 }} />
502
+ onMouseEnter={e => { if (!disabled) e.currentTarget.style.borderColor = 'var(--accent, #f99e2c)'; }}
503
+ onMouseLeave={e => { e.currentTarget.style.borderColor = 'var(--border, #e2e8f0)'; }}>
504
+ <Calendar size={13} style={{ color: 'var(--muted, #797b8d)', flexShrink: 0 }} />
505
505
  <span style={{ flex: 1, textAlign: 'left' }}>{formatted || placeholder}</span>
506
506
  {value && (
507
507
  <span
508
508
  onClick={e => { e.stopPropagation(); onChange?.(null); }}
509
- style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--muted)', cursor: 'pointer', flexShrink: 0, fontSize: 13, lineHeight: 1, padding: '0 2px' }}
510
- onMouseEnter={e => { e.currentTarget.style.color = 'var(--danger)'; }}
511
- onMouseLeave={e => { e.currentTarget.style.color = 'var(--muted)'; }}>
509
+ style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--muted, #797b8d)', cursor: 'pointer', flexShrink: 0, fontSize: 13, lineHeight: 1, padding: '0 2px' }}
510
+ onMouseEnter={e => { e.currentTarget.style.color = 'var(--danger, #f64747)'; }}
511
+ onMouseLeave={e => { e.currentTarget.style.color = 'var(--muted, #797b8d)'; }}>
512
512
  ✕
513
513
  </span>
514
514
  )}
@@ -524,7 +524,7 @@ export function DatePicker({ value, onChange, label, placeholder = 'Select date'
524
524
  return (
525
525
  <div style={{ display: 'inline-flex', flexDirection: 'column', position: 'relative', width: style?.width || 'auto', boxSizing: 'border-box', minWidth: 0, ...style }}>
526
526
  {label && (
527
- <label style={{ fontSize: 11, fontWeight: 600, color: 'var(--t2, var(--muted))', textTransform: 'uppercase', letterSpacing: '.08em', display: 'block', marginBottom: 4 }}>
527
+ <label style={{ fontSize: 11, fontWeight: 600, color: 'var(--t2, var(--muted, #797b8d))', textTransform: 'uppercase', letterSpacing: '.08em', display: 'block', marginBottom: 4 }}>
528
528
  {label}
529
529
  </label>
530
530
  )}
@@ -544,8 +544,8 @@ export function DatePicker({ value, onChange, label, placeholder = 'Select date'
544
544
  {open && createPortal(
545
545
  <div ref={dropRef} style={{
546
546
  position: 'fixed', top: pos.top, left: pos.left, width: pos.width, zIndex: 9000,
547
- background: 'var(--surface)', border: '1px solid var(--border)',
548
- borderRadius: 'var(--rad, 10px)', boxShadow: 'var(--shadow-lg)',
547
+ background: 'var(--surface, #ffffff)', border: '1px solid var(--border, #e2e8f0)',
548
+ borderRadius: 'var(--rad, 10px)', boxShadow: 'var(--shadow-lg, 0 10px 15px -3px rgba(0,0,0,.1), 0 4px 6px -4px rgba(0,0,0,.06))',
549
549
  padding: '10px 12px',
550
550
  animation: 'dp-in .12s ease',
551
551
  }}>
@@ -560,15 +560,15 @@ export function DatePicker({ value, onChange, label, placeholder = 'Select date'
560
560
  cursor: isNavPrevDisabled() ? 'not-allowed' : 'pointer',
561
561
  opacity: isNavPrevDisabled() ? 0.35 : 1,
562
562
  padding: 4, borderRadius: 'var(--radxs, 6px)',
563
- color: 'var(--muted)', display: 'flex', alignItems: 'center'
563
+ color: 'var(--muted, #797b8d)', display: 'flex', alignItems: 'center'
564
564
  }}
565
- onMouseEnter={e => { if (!isNavPrevDisabled()) e.currentTarget.style.background = 'var(--grey-1)'; }}
565
+ onMouseEnter={e => { if (!isNavPrevDisabled()) e.currentTarget.style.background = 'var(--grey-1, #f5f5f8)'; }}
566
566
  onMouseLeave={e => e.currentTarget.style.background = 'none'}
567
567
  >
568
568
  <ChevronLeft size={15} />
569
569
  </button>
570
- <button type="button" onClick={cycleView} style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: '.82rem', fontWeight: 700, color: 'var(--primary-text)', padding: '4px 8px', borderRadius: 'var(--radxs, 6px)', fontFamily: 'var(--sans)' }}
571
- onMouseEnter={e => e.currentTarget.style.background = 'var(--grey-1)'}
570
+ <button type="button" onClick={cycleView} style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: '.82rem', fontWeight: 700, color: 'var(--primary-text, #0f172a)', padding: '4px 8px', borderRadius: 'var(--radxs, 6px)', fontFamily: 'var(--sans, inherit)' }}
571
+ onMouseEnter={e => e.currentTarget.style.background = 'var(--grey-1, #f5f5f8)'}
572
572
  onMouseLeave={e => e.currentTarget.style.background = 'none'}>
573
573
  {headerLabel}
574
574
  </button>
@@ -581,9 +581,9 @@ export function DatePicker({ value, onChange, label, placeholder = 'Select date'
581
581
  cursor: isNavNextDisabled() ? 'not-allowed' : 'pointer',
582
582
  opacity: isNavNextDisabled() ? 0.35 : 1,
583
583
  padding: 4, borderRadius: 'var(--radxs, 6px)',
584
- color: 'var(--muted)', display: 'flex', alignItems: 'center'
584
+ color: 'var(--muted, #797b8d)', display: 'flex', alignItems: 'center'
585
585
  }}
586
- onMouseEnter={e => { if (!isNavNextDisabled()) e.currentTarget.style.background = 'var(--grey-1)'; }}
586
+ onMouseEnter={e => { if (!isNavNextDisabled()) e.currentTarget.style.background = 'var(--grey-1, #f5f5f8)'; }}
587
587
  onMouseLeave={e => e.currentTarget.style.background = 'none'}
588
588
  >
589
589
  <ChevronRight size={15} />
@@ -48,7 +48,7 @@ export function Dropzone({
48
48
  return (
49
49
  <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
50
50
  {label && (
51
- <label style={{ fontSize: 11, fontWeight: 600, color: 'var(--t2)', textTransform: 'uppercase', letterSpacing: '.08em', display: 'block' }}>
51
+ <label style={{ fontSize: 11, fontWeight: 600, color: 'var(--t2, #797b8d)', textTransform: 'uppercase', letterSpacing: '.08em', display: 'block' }}>
52
52
  {label}
53
53
  </label>
54
54
  )}
@@ -65,10 +65,10 @@ export function Dropzone({
65
65
  alignItems: 'center',
66
66
  justifyContent: 'center',
67
67
  padding: '20px 20px',
68
- border: `2px dashed ${over ? 'var(--accent, #3b82f6)' : 'var(--border-light)'}`,
69
- borderRadius: 'var(--rad)',
68
+ border: `2px dashed ${over ? 'var(--accent, #3b82f6)' : 'var(--border-light, #ebebf0)'}`,
69
+ borderRadius: 'var(--rad, 10px)',
70
70
  cursor: 'pointer',
71
- background: over ? 'rgba(59, 130, 246, 0.08)' : 'var(--grey-1)',
71
+ background: over ? 'rgba(59, 130, 246, 0.08)' : 'var(--grey-1, #f5f5f8)',
72
72
  transition: 'all .2s ease',
73
73
  textAlign: 'center',
74
74
  }}
@@ -88,7 +88,7 @@ export function Dropzone({
88
88
  <span style={{ fontSize: '.82rem', fontWeight: 600, pointerEvents: 'none' }}>
89
89
  Выберите файлы, перетащите их сюда или вставьте через Ctrl+V
90
90
  </span>
91
- {hint && <span style={{ fontSize: '.72rem', color: 'var(--muted)', marginTop: 2, pointerEvents: 'none' }}>{hint}</span>}
91
+ {hint && <span style={{ fontSize: '.72rem', color: 'var(--muted, #797b8d)', marginTop: 2, pointerEvents: 'none' }}>{hint}</span>}
92
92
  </div>
93
93
 
94
94
  {/* Uploading progress items */}
@@ -102,19 +102,19 @@ export function Dropzone({
102
102
  flexDirection: 'column',
103
103
  gap: 4,
104
104
  padding: '8px 10px',
105
- background: 'var(--surface)',
106
- border: '1px solid var(--border-light)',
107
- borderRadius: 'var(--rads)',
105
+ background: 'var(--surface, #ffffff)',
106
+ border: '1px solid var(--border-light, #ebebf0)',
107
+ borderRadius: 'var(--rads, 8px)',
108
108
  fontSize: '.8rem',
109
109
  }}
110
110
  >
111
111
  <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
112
112
  <div style={{ display: 'flex', alignItems: 'center', gap: 6, minWidth: 0 }}>
113
- {item.status === 'uploading' && <Paperclip size={14} color="var(--accent)" />}
113
+ {item.status === 'uploading' && <Paperclip size={14} color="var(--accent, #f99e2c)" />}
114
114
  {item.status === 'done' && <FileCheck size={14} color="var(--success, #22c55e)" />}
115
115
  {item.status === 'error' && <X size={14} color="var(--err, #ef4444)" />}
116
116
  <span style={{ textOverflow: 'ellipsis', overflow: 'hidden', whiteSpace: 'nowrap', fontWeight: 500 }}>
117
- {item.name} <span style={{ color: 'var(--muted)', fontSize: '.72rem' }}>({formatBytes(item.size)})</span>
117
+ {item.name} <span style={{ color: 'var(--muted, #797b8d)', fontSize: '.72rem' }}>({formatBytes(item.size)})</span>
118
118
  </span>
119
119
  </div>
120
120
 
@@ -129,7 +129,7 @@ export function Dropzone({
129
129
  {onRemoveUploading && (
130
130
  <button
131
131
  onClick={(e) => { e.stopPropagation(); onRemoveUploading(item.tempId); }}
132
- style={{ border: 'none', background: 'none', cursor: 'pointer', padding: 2, color: 'var(--muted)' }}
132
+ style={{ border: 'none', background: 'none', cursor: 'pointer', padding: 2, color: 'var(--muted, #797b8d)' }}
133
133
  >
134
134
  <X size={14} />
135
135
  </button>
@@ -163,16 +163,16 @@ export function Dropzone({
163
163
  alignItems: 'center',
164
164
  justifyContent: 'space-between',
165
165
  padding: '6px 10px',
166
- background: 'var(--surface)',
167
- border: '1px solid var(--border-light)',
168
- borderRadius: 'var(--rads)',
166
+ background: 'var(--surface, #ffffff)',
167
+ border: '1px solid var(--border-light, #ebebf0)',
168
+ borderRadius: 'var(--rads, 8px)',
169
169
  fontSize: '.8rem',
170
170
  }}
171
171
  >
172
172
  <div style={{ display: 'flex', alignItems: 'center', gap: 6, minWidth: 0 }}>
173
- <Paperclip size={14} color="var(--accent)" />
173
+ <Paperclip size={14} color="var(--accent, #f99e2c)" />
174
174
  <span style={{ textOverflow: 'ellipsis', overflow: 'hidden', whiteSpace: 'nowrap', fontWeight: 500 }}>
175
- {f.original_name || f.originalName} <span style={{ color: 'var(--muted)', fontSize: '.72rem' }}>({formatBytes(f.file_size || f.fileSize)})</span>
175
+ {f.original_name || f.originalName} <span style={{ color: 'var(--muted, #797b8d)', fontSize: '.72rem' }}>({formatBytes(f.file_size || f.fileSize)})</span>
176
176
  </span>
177
177
  </div>
178
178
  <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
@@ -188,7 +188,7 @@ export function Dropzone({
188
188
  <Button
189
189
  variant="ghost"
190
190
  size="xs"
191
- icon={<Trash2 size={13} color="var(--err)" />}
191
+ icon={<Trash2 size={13} color="var(--err, #f64747)" />}
192
192
  onClick={(e) => { e.stopPropagation(); onRemoveExisting(f.id); }}
193
193
  />
194
194
  )}
@@ -48,7 +48,7 @@ export function FilePicker({
48
48
  return (
49
49
  <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
50
50
  {label && (
51
- <label style={{ fontSize: 11, fontWeight: 600, color: 'var(--t2)', textTransform: 'uppercase', letterSpacing: '.08em', display: 'block' }}>
51
+ <label style={{ fontSize: 11, fontWeight: 600, color: 'var(--t2, #797b8d)', textTransform: 'uppercase', letterSpacing: '.08em', display: 'block' }}>
52
52
  {label}
53
53
  </label>
54
54
  )}
@@ -65,10 +65,10 @@ export function FilePicker({
65
65
  alignItems: 'center',
66
66
  justifyContent: 'center',
67
67
  padding: '20px 20px',
68
- border: `2px dashed ${over ? 'var(--accent, #3b82f6)' : 'var(--border-light)'}`,
69
- borderRadius: 'var(--rad)',
68
+ border: `2px dashed ${over ? 'var(--accent, #3b82f6)' : 'var(--border-light, #ebebf0)'}`,
69
+ borderRadius: 'var(--rad, 10px)',
70
70
  cursor: 'pointer',
71
- background: over ? 'rgba(59, 130, 246, 0.08)' : 'var(--grey-1)',
71
+ background: over ? 'rgba(59, 130, 246, 0.08)' : 'var(--grey-1, #f5f5f8)',
72
72
  transition: 'all .2s ease',
73
73
  textAlign: 'center',
74
74
  }}
@@ -88,7 +88,7 @@ export function FilePicker({
88
88
  <span style={{ fontSize: '.82rem', fontWeight: 600, pointerEvents: 'none' }}>
89
89
  Выберите файлы, перетащите их сюда или вставьте через Ctrl+V
90
90
  </span>
91
- {hint && <span style={{ fontSize: '.72rem', color: 'var(--muted)', marginTop: 2, pointerEvents: 'none' }}>{hint}</span>}
91
+ {hint && <span style={{ fontSize: '.72rem', color: 'var(--muted, #797b8d)', marginTop: 2, pointerEvents: 'none' }}>{hint}</span>}
92
92
  </div>
93
93
 
94
94
  {/* Uploading progress items */}
@@ -102,19 +102,19 @@ export function FilePicker({
102
102
  flexDirection: 'column',
103
103
  gap: 4,
104
104
  padding: '8px 10px',
105
- background: 'var(--surface)',
106
- border: '1px solid var(--border-light)',
107
- borderRadius: 'var(--rads)',
105
+ background: 'var(--surface, #ffffff)',
106
+ border: '1px solid var(--border-light, #ebebf0)',
107
+ borderRadius: 'var(--rads, 8px)',
108
108
  fontSize: '.8rem',
109
109
  }}
110
110
  >
111
111
  <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
112
112
  <div style={{ display: 'flex', alignItems: 'center', gap: 6, minWidth: 0 }}>
113
- {item.status === 'uploading' && <Paperclip size={14} color="var(--accent)" />}
113
+ {item.status === 'uploading' && <Paperclip size={14} color="var(--accent, #f99e2c)" />}
114
114
  {item.status === 'done' && <FileCheck size={14} color="var(--success, #22c55e)" />}
115
115
  {item.status === 'error' && <X size={14} color="var(--err, #ef4444)" />}
116
116
  <span style={{ textOverflow: 'ellipsis', overflow: 'hidden', whiteSpace: 'nowrap', fontWeight: 500 }}>
117
- {item.name} <span style={{ color: 'var(--muted)', fontSize: '.72rem' }}>({formatBytes(item.size)})</span>
117
+ {item.name} <span style={{ color: 'var(--muted, #797b8d)', fontSize: '.72rem' }}>({formatBytes(item.size)})</span>
118
118
  </span>
119
119
  </div>
120
120
 
@@ -129,7 +129,7 @@ export function FilePicker({
129
129
  {onRemoveUploading && (
130
130
  <button
131
131
  onClick={(e) => { e.stopPropagation(); onRemoveUploading(item.tempId); }}
132
- style={{ border: 'none', background: 'none', cursor: 'pointer', padding: 2, color: 'var(--muted)' }}
132
+ style={{ border: 'none', background: 'none', cursor: 'pointer', padding: 2, color: 'var(--muted, #797b8d)' }}
133
133
  >
134
134
  <X size={14} />
135
135
  </button>
@@ -163,16 +163,16 @@ export function FilePicker({
163
163
  alignItems: 'center',
164
164
  justifyContent: 'space-between',
165
165
  padding: '6px 10px',
166
- background: 'var(--surface)',
167
- border: '1px solid var(--border-light)',
168
- borderRadius: 'var(--rads)',
166
+ background: 'var(--surface, #ffffff)',
167
+ border: '1px solid var(--border-light, #ebebf0)',
168
+ borderRadius: 'var(--rads, 8px)',
169
169
  fontSize: '.8rem',
170
170
  }}
171
171
  >
172
172
  <div style={{ display: 'flex', alignItems: 'center', gap: 6, minWidth: 0 }}>
173
- <Paperclip size={14} color="var(--accent)" />
173
+ <Paperclip size={14} color="var(--accent, #f99e2c)" />
174
174
  <span style={{ textOverflow: 'ellipsis', overflow: 'hidden', whiteSpace: 'nowrap', fontWeight: 500 }}>
175
- {f.original_name || f.originalName} <span style={{ color: 'var(--muted)', fontSize: '.72rem' }}>({formatBytes(f.file_size || f.fileSize)})</span>
175
+ {f.original_name || f.originalName} <span style={{ color: 'var(--muted, #797b8d)', fontSize: '.72rem' }}>({formatBytes(f.file_size || f.fileSize)})</span>
176
176
  </span>
177
177
  </div>
178
178
  <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
@@ -188,7 +188,7 @@ export function FilePicker({
188
188
  <Button
189
189
  variant="ghost"
190
190
  size="xs"
191
- icon={<Trash2 size={13} color="var(--err)" />}
191
+ icon={<Trash2 size={13} color="var(--err, #f64747)" />}
192
192
  onClick={(e) => { e.stopPropagation(); onRemoveExisting(f.id); }}
193
193
  />
194
194
  )}
@@ -50,7 +50,7 @@ export default function HoverCard({ trigger, children, position = 'top', width =
50
50
  zIndex: 9999,
51
51
  minWidth: width,
52
52
  background: 'var(--surface,#fff)',
53
- border: '1px solid var(--border)',
53
+ border: '1px solid var(--border, #e2e8f0)',
54
54
  borderRadius: 'var(--rads, 8px)',
55
55
  padding: '10px 14px',
56
56
  boxShadow: 'var(--smd, 0 4px 12px rgba(0,0,0,.12))',
@@ -64,9 +64,9 @@ export default function HoverCard({ trigger, children, position = 'top', width =
64
64
  [position === 'top' ? 'bottom' : 'top']: -5,
65
65
  transform: 'translateX(-50%) rotate(45deg)',
66
66
  width: 8, height: 8, background: 'var(--surface,#fff)',
67
- borderRight: '1px solid var(--border)',
68
- borderBottom: position === 'top' ? 'none' : '1px solid var(--border)',
69
- borderTop: position === 'top' ? '1px solid var(--border)' : 'none',
67
+ borderRight: '1px solid var(--border, #e2e8f0)',
68
+ borderBottom: position === 'top' ? 'none' : '1px solid var(--border, #e2e8f0)',
69
+ borderTop: position === 'top' ? '1px solid var(--border, #e2e8f0)' : 'none',
70
70
  }} />
71
71
  </div>
72
72
  )}
@@ -69,9 +69,9 @@ export default function ImageUpload({ value, file, onChange, onRemove, label = '
69
69
  <label
70
70
  style={{
71
71
  display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
72
- gap: 8, padding: '24px 16px', borderRadius: 'var(--rads)',
73
- border: `1.5px dashed ${dragOver ? 'var(--accent)' : 'var(--border)'}`,
74
- background: 'var(--grey-1)', cursor: 'pointer', transition: 'all .15s', textAlign: 'center',
72
+ gap: 8, padding: '24px 16px', borderRadius: 'var(--rads, 8px)',
73
+ border: `1.5px dashed ${dragOver ? 'var(--accent, #f99e2c)' : 'var(--border, #e2e8f0)'}`,
74
+ background: 'var(--grey-1, #f5f5f8)', cursor: 'pointer', transition: 'all .15s', textAlign: 'center',
75
75
  }}
76
76
  onDragOver={e => { e.preventDefault(); setDragOver(true); }}
77
77
  onDragLeave={() => setDragOver(false)}
@@ -82,21 +82,21 @@ export default function ImageUpload({ value, file, onChange, onRemove, label = '
82
82
  {pendingFile ? (
83
83
  <>
84
84
  <img src={URL.createObjectURL(pendingFile)} alt="preview" style={{ height: 48, maxWidth: 160, objectFit: 'contain', borderRadius: 4 }} />
85
- <div style={{ fontSize: '.76rem', fontWeight: 600, color: 'var(--accent)' }}>{pendingFile.name}</div>
86
- <div style={{ fontSize: '.68rem', color: 'var(--muted)' }}>{(pendingFile.size / 1024).toFixed(1)} KB — click to change</div>
85
+ <div style={{ fontSize: '.76rem', fontWeight: 600, color: 'var(--accent, #f99e2c)' }}>{pendingFile.name}</div>
86
+ <div style={{ fontSize: '.68rem', color: 'var(--muted, #797b8d)' }}>{(pendingFile.size / 1024).toFixed(1)} KB — click to change</div>
87
87
  </>
88
88
  ) : (
89
89
  <>
90
- <Upload size={20} style={{ color: 'var(--muted)' }} />
90
+ <Upload size={20} style={{ color: 'var(--muted, #797b8d)' }} />
91
91
  <div style={{ fontSize: '.82rem', fontWeight: 600 }}>Click or drag to upload</div>
92
- <div style={{ fontSize: '.72rem', color: 'var(--muted)' }}>PNG, JPG, SVG, ICO up to 2MB</div>
92
+ <div style={{ fontSize: '.72rem', color: 'var(--muted, #797b8d)' }}>PNG, JPG, SVG, ICO up to 2MB</div>
93
93
  </>
94
94
  )}
95
95
  </label>
96
96
  <div style={{ display: 'flex', alignItems: 'center', gap: 8, margin: '12px 0 4px' }}>
97
- <div style={{ flex: 1, height: 1, background: 'var(--border)' }} />
98
- <span style={{ fontSize: '.72rem', color: 'var(--muted)' }}>or enter URL directly</span>
99
- <div style={{ flex: 1, height: 1, background: 'var(--border)' }} />
97
+ <div style={{ flex: 1, height: 1, background: 'var(--border, #e2e8f0)' }} />
98
+ <span style={{ fontSize: '.72rem', color: 'var(--muted, #797b8d)' }}>or enter URL directly</span>
99
+ <div style={{ flex: 1, height: 1, background: 'var(--border, #e2e8f0)' }} />
100
100
  </div>
101
101
  <input
102
102
  type="url" placeholder="https://example.com/logo.png"
@@ -104,9 +104,9 @@ export default function ImageUpload({ value, file, onChange, onRemove, label = '
104
104
  onChange={e => { setUrlInput(e.target.value); setPendingFile(null); }}
105
105
  style={{
106
106
  width: '100%', padding: '8px 10px', fontSize: '.82rem',
107
- border: '1px solid var(--border)', borderRadius: 'var(--rads)',
108
- background: 'var(--input-bg)', color: 'var(--primary-text)',
109
- fontFamily: 'var(--sans)', outline: 'none',
107
+ border: '1px solid var(--border, #e2e8f0)', borderRadius: 'var(--rads, 8px)',
108
+ background: 'var(--input-bg, #ffffff)', color: 'var(--primary-text, #0f172a)',
109
+ fontFamily: 'var(--sans, inherit)', outline: 'none',
110
110
  }}
111
111
  />
112
112
  </div>
@@ -123,22 +123,22 @@ export default function ImageUpload({ value, file, onChange, onRemove, label = '
123
123
  <>
124
124
  <div style={{
125
125
  display: 'flex', alignItems: 'center', gap: 12,
126
- padding: '10px 12px', borderRadius: 'var(--rads)',
127
- border: '1px solid var(--border)', background: 'var(--grey-1)',
126
+ padding: '10px 12px', borderRadius: 'var(--rads, 8px)',
127
+ border: '1px solid var(--border, #e2e8f0)', background: 'var(--grey-1, #f5f5f8)',
128
128
  }}>
129
129
  {hasImage ? (
130
130
  <img src={previewUrl} alt={label} style={{ height: 32, maxWidth: 80, objectFit: 'contain', borderRadius: 4, flexShrink: 0 }} />
131
131
  ) : (
132
- <div style={{ width: 32, height: 32, borderRadius: 4, background: 'var(--grey-2)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
133
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="var(--muted)" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></svg>
132
+ <div style={{ width: 32, height: 32, borderRadius: 4, background: 'var(--grey-2, #ebebee)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
133
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="var(--muted, #797b8d)" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></svg>
134
134
  </div>
135
135
  )}
136
- <div style={{ flex: 1, fontSize: '.78rem', color: filename ? 'var(--primary-text)' : 'var(--muted)', fontFamily: filename ? 'var(--mono)' : 'inherit', wordBreak: 'break-all' }}>
136
+ <div style={{ flex: 1, fontSize: '.78rem', color: filename ? 'var(--primary-text, #0f172a)' : 'var(--muted, #797b8d)', fontFamily: filename ? 'var(--mono, ui-monospace, monospace)' : 'inherit', wordBreak: 'break-all' }}>
137
137
  {filename || 'Not set yet'}
138
138
  </div>
139
139
  <Button variant="ghost" size="xs" icon={<Pencil size={12} />} onClick={openEdit} style={{ flexShrink: 0 }}>Edit</Button>
140
140
  {hasImage && (
141
- <Button variant="ghost" size="xs" icon={<Trash2 size={12} />} style={{ color: 'var(--danger)', flexShrink: 0 }} onClick={onRemove}>Remove</Button>
141
+ <Button variant="ghost" size="xs" icon={<Trash2 size={12} />} style={{ color: 'var(--danger, #f64747)', flexShrink: 0 }} onClick={onRemove}>Remove</Button>
142
142
  )}
143
143
  </div>
144
144
  {modal}
@@ -1,10 +1,10 @@
1
1
  import { useRef, useState } from 'react';
2
2
 
3
3
  const SIZES = {
4
- xs: { height: 32, fontSize: 11, paddingH: 8 },
5
- sm: { height: 32, fontSize: 12, paddingH: 9 },
4
+ xs: { height: 24, fontSize: 11, paddingH: 6 },
5
+ sm: { height: 28, fontSize: 11.5, paddingH: 8 },
6
6
  md: { height: 32, fontSize: 13, paddingH: 11 },
7
- lg: { height: 32, fontSize: 14, paddingH: 14 },
7
+ lg: { height: 36, fontSize: 14, paddingH: 14 },
8
8
  };
9
9
 
10
10
  export default function Input({
@@ -13,7 +13,7 @@ export default function LineProgress({
13
13
  segments,
14
14
  size = 'md',
15
15
  customSize,
16
- color = 'var(--blue)',
16
+ color = 'var(--blue, #2782e4)',
17
17
  trackColor = 'var(--bd2, #e0e0e4)',
18
18
  label = '',
19
19
  showPercent = true,