File size: 9,187 Bytes
d44ff09
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/* ============================================================================
   Reusable UI component styles — Section 7.4
   All draw from tokens (tokens.css). No one-off values.
   ========================================================================== */

/* --- Button (Primary / Secondary / Ghost / Destructive) --- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  height: var(--control-height); padding: 0 var(--space-5);
  border-radius: var(--radius); border: 1px solid transparent;
  font-size: var(--fs-14); font-weight: 600; line-height: 1;
  background: var(--color-primary); color: var(--color-on-primary); transition: background .15s, opacity .15s;
  white-space: nowrap;
}
.btn:hover { background: var(--color-primary-hover); }
.btn--secondary { background: var(--color-surface); color: var(--color-text-primary); border-color: var(--color-border); }
.btn--secondary:hover { background: var(--color-surface-muted); }
.btn--ghost { background: transparent; color: var(--color-primary); }
.btn--ghost:hover { background: var(--color-surface-muted); }
.btn--destructive { background: var(--color-error); color: var(--color-on-primary); }
.btn--destructive:hover { background: var(--color-error-hover); }
.btn--accent { background: var(--color-accent); color: var(--color-accent-fg); }
.btn--accent:hover { background: var(--color-accent-hover); }
.btn--compact { height: var(--control-height-compact); padding: 0 var(--space-4); font-size: var(--fs-12); }
.btn:disabled, .btn[disabled] { opacity: .5; cursor: not-allowed; }
.btn .spinner { width: 16px; height: 16px; border: 2px solid rgba(255,255,255,.4); border-top-color: var(--color-on-primary); border-radius: 50%; animation: spin .6s linear infinite; }
.btn--secondary .spinner, .btn--ghost .spinner { border-color: rgba(0,0,0,.2); border-top-color: var(--color-primary); }

@keyframes spin { to { transform: rotate(360deg); } }

/* --- Card (Default / Interactive / Status) --- */
.card {
  background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: var(--radius-lg); padding: var(--space-6);
}
.card--interactive { transition: box-shadow .15s, transform .15s; cursor: pointer; }
.card--interactive:hover { box-shadow: 0 4px 16px rgba(2,6,23,.08); transform: translateY(-1px); }
.card--status { border-left: 4px solid var(--color-border); }
.card--status.draft { border-left-color: var(--color-text-secondary); }
.card--status.generated { border-left-color: var(--color-success); }
.card--status.exported { border-left-color: var(--color-primary); }
.card--status.failed { border-left-color: var(--color-error); }

/* --- Badge (Status / Urgency) --- */
.badge {
  display: inline-flex; align-items: center; padding: 2px var(--space-2);
  border-radius: 999px; font-size: var(--fs-12); font-weight: 600; line-height: 1.4;
  background: var(--color-surface-muted); color: var(--color-text-secondary);
}
.badge.draft { background: var(--color-neutral-bg); color: var(--color-neutral-fg); }
.badge.generated { background: var(--color-success-bg); color: var(--color-success-fg); }
.badge.exported { background: var(--color-info-bg); color: var(--color-info-fg); }
.badge.failed, .badge.failed { background: var(--color-error-bg); color: var(--color-error-fg); }
.badge.generating { background: var(--color-warning-bg); color: var(--color-warning-fg); }
.badge.urgency-Low { background: var(--color-success-bg); color: var(--color-success-fg); }
.badge.urgency-Medium { background: var(--color-warning-bg); color: var(--color-warning-fg); }
.badge.urgency-High { background: var(--color-error-bg); color: var(--color-error-fg); }

/* --- Input field (Text / Textarea / Select) --- */
.field { margin-bottom: var(--space-4); display: flex; flex-direction: column; gap: var(--space-1); }
.field > label { font-size: var(--fs-14); font-weight: 600; }
.field .hint { font-size: var(--fs-12); color: var(--color-text-secondary); }
.field .error-text { font-size: var(--fs-12); color: var(--color-error); }
.input, .textarea, .select {
  height: var(--control-height); padding: 0 var(--space-3);
  border: 1px solid var(--color-border); border-radius: var(--radius);
  font-size: var(--fs-14); font-family: inherit; color: var(--color-text-primary);
  background: var(--color-surface); width: 100%;
}
.input:focus, .textarea:focus, .select:focus { outline: none; border-color: var(--color-primary); box-shadow: 0 0 0 3px rgba(13,125,107,.15); }
.input.invalid, .textarea.invalid, .select.invalid { border-color: var(--color-error); }
.textarea { height: auto; min-height: 80px; padding: var(--space-3); line-height: 1.5; resize: vertical; }

/* --- Toggle --- */
.toggle { position: relative; display: inline-flex; align-items: center; gap: var(--space-2); cursor: pointer; }
.toggle input { position: absolute; opacity: 0; }
.toggle .track { width: 40px; height: 22px; background: var(--color-border); border-radius: 999px; position: relative; transition: background .15s; }
.toggle .track::after { content:''; position:absolute; top:2px; left:2px; width:18px; height:18px; background:var(--color-on-primary); border-radius:50%; transition: transform .15s; }
.toggle input:checked + .track { background: var(--color-primary); }
.toggle input:checked + .track::after { transform: translateX(18px); }

/* --- Checkbox --- */
.check { display:inline-flex; align-items:center; gap: var(--space-2); font-size: var(--fs-14); cursor: pointer; }

/* --- Tabs (underline) --- horizontal scroll on overflow, no layout break */
.tabs { display: flex; gap: var(--space-1); border-bottom: 1px solid var(--color-border); overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: thin; }
.tab { padding: var(--space-3) var(--space-4); background: none; border: none; border-bottom: 2px solid transparent; font-size: var(--fs-14); font-weight: 600; color: var(--color-text-secondary); position: relative; white-space: nowrap; flex-shrink: 0; }
.tab.active { color: var(--color-primary); border-bottom-color: var(--color-primary); }
.tab .unsaved-dot { position: absolute; top: 8px; right: 8px; width: 8px; height: 8px; border-radius: 50%; background: var(--color-accent); }

/* --- Modal --- */
.modal-backdrop { position: fixed; inset: 0; background: rgba(2,6,23,.5); display: flex; align-items: center; justify-content: center; z-index: 1000; padding: var(--space-4); }
.modal { background: var(--color-surface); border-radius: var(--radius-lg); max-width: 480px; width: 100%; padding: var(--space-6); box-shadow: 0 20px 50px rgba(0,0,0,.25); }
.modal h3 { font-size: var(--fs-20); margin-bottom: var(--space-3); }

/* --- Toast --- */
.toast-container { position: fixed; top: var(--space-6); right: var(--space-6); z-index: 1100; display: flex; flex-direction: column; gap: var(--space-2); max-width: 360px; }
.toast { padding: var(--space-3) var(--space-4); border-radius: var(--radius); background: var(--color-surface); border: 1px solid var(--color-border); border-left: 4px solid var(--color-text-secondary); box-shadow: 0 4px 12px rgba(0,0,0,.1); font-size: var(--fs-14); }
.toast.success { border-left-color: var(--color-success); }
.toast.error { border-left-color: var(--color-error); }
.toast.info { border-left-color: var(--color-primary); }

/* --- Progress / Step indicator / Skeleton --- */
.steps { display: flex; flex-direction: column; gap: var(--space-3); }
.step { display: flex; align-items: center; gap: var(--space-3); font-size: var(--fs-14); }
.step .dot { width: 22px; height: 22px; border-radius: 50%; border: 2px solid var(--color-border); display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.step.active .dot { border-color: var(--color-primary); }
.step.active .dot .spinner-sm { width: 14px; height: 14px; border: 2px solid var(--color-border); border-top-color: var(--color-primary); border-radius: 50%; animation: spin .6s linear infinite; }
.step.done .dot { border-color: var(--color-success); background: var(--color-success); color: var(--color-on-primary); }
.skeleton { background: linear-gradient(90deg, var(--color-surface-muted) 25%, var(--color-skeleton-mid) 50%, var(--color-surface-muted) 75%); background-size: 200% 100%; animation: shimmer 1.4s infinite; border-radius: var(--radius); }
@keyframes shimmer { to { background-position: -200% 0; } }

/* --- Accordion --- */
.accordion-item { border: 1px solid var(--color-border); border-radius: var(--radius); margin-bottom: var(--space-2); overflow: hidden; }
.accordion-head { padding: var(--space-3) var(--space-4); background: var(--color-surface-muted); cursor: pointer; display: flex; justify-content: space-between; align-items: center; font-weight: 600; font-size: var(--fs-14); }
.accordion-body { padding: var(--space-4); }

/* --- Layout helpers --- */
.row { display: flex; gap: var(--space-4); }
.col { display: flex; flex-direction: column; gap: var(--space-4); }
.between { justify-content: space-between; align-items: center; }
.grid { display: grid; gap: var(--space-4); }
.muted { color: var(--color-text-secondary); }
.mono-sm { font-family: var(--font-mono); font-size: var(--fs-12); }