@cuencor/styles 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,127 @@
1
+ /* ── Badges ─────────────────────────────────────────────────────────────── */
2
+
3
+ .fn-badge {
4
+ display: inline-flex;
5
+ align-items: center;
6
+ gap: 4px;
7
+ padding: 2px 8px;
8
+ border-radius: var(--fn-radius-full);
9
+ font-size: var(--fn-text-xs);
10
+ font-weight: 600;
11
+ line-height: 1.5;
12
+ white-space: nowrap;
13
+
14
+ &--primary { background: var(--fn-primary-100); color: var(--fn-primary-700); }
15
+ &--success { background: var(--fn-success-100); color: var(--fn-success-700); }
16
+ &--danger { background: var(--fn-danger-100); color: var(--fn-danger-700); }
17
+ &--warning { background: var(--fn-warning-100); color: var(--fn-warning-600); }
18
+ &--gray { background: var(--fn-gray-100); color: var(--fn-gray-600); }
19
+
20
+ /* With status dot */
21
+ &__dot {
22
+ width: 6px;
23
+ height: 6px;
24
+ border-radius: 50%;
25
+ background: currentColor;
26
+ flex-shrink: 0;
27
+ }
28
+ }
29
+
30
+ /* ── Alerts ─────────────────────────────────────────────────────────────── */
31
+
32
+ .fn-alert {
33
+ display: flex;
34
+ align-items: flex-start;
35
+ gap: 10px;
36
+ padding: 12px 16px;
37
+ border-radius: var(--fn-radius-md);
38
+ font-size: var(--fn-text-sm);
39
+ border: 1px solid transparent;
40
+ line-height: 1.5;
41
+
42
+ &--success { background: var(--fn-success-50); border-color: var(--fn-success-100); color: var(--fn-success-700); }
43
+ &--danger { background: var(--fn-danger-50); border-color: var(--fn-danger-100); color: var(--fn-danger-700); }
44
+ &--warning { background: var(--fn-warning-50); border-color: var(--fn-warning-100); color: var(--fn-warning-600); }
45
+ &--info { background: var(--fn-info-50); border-color: var(--fn-info-100); color: var(--fn-info-600); }
46
+ &--gray { background: var(--fn-gray-100); border-color: var(--fn-gray-200); color: var(--fn-gray-700); }
47
+
48
+ &__icon { flex-shrink: 0; font-size: 16px; margin-top: 1px; }
49
+ &__body { flex: 1; }
50
+ &__title { font-weight: 700; margin-bottom: 2px; }
51
+ }
52
+
53
+ /* ── Info box (banner) ──────────────────────────────────────────────────── */
54
+
55
+ .fn-info-box {
56
+ display: flex;
57
+ align-items: flex-start;
58
+ gap: 10px;
59
+ padding: 12px 16px;
60
+ border-radius: var(--fn-radius-md);
61
+ border: 1px solid transparent;
62
+ font-size: var(--fn-text-sm);
63
+
64
+ &--warning { background: var(--fn-warning-50); border-color: var(--fn-warning-100); color: var(--fn-warning-600); }
65
+ &--info { background: var(--fn-info-50); border-color: var(--fn-info-100); color: var(--fn-info-600); }
66
+ &--success { background: var(--fn-success-50); border-color: var(--fn-success-100); color: var(--fn-success-700); }
67
+ &--danger { background: var(--fn-danger-50); border-color: var(--fn-danger-100); color: var(--fn-danger-700); }
68
+
69
+ &__icon { flex-shrink: 0; margin-top: 1px; }
70
+ &__text { flex: 1; line-height: 1.6; margin: 0; }
71
+ }
72
+
73
+ /* ── Password expiry banner (global, top of main content) ── */
74
+ .fn-expiry-banner {
75
+ display: flex;
76
+ align-items: center;
77
+ justify-content: space-between;
78
+ gap: 12px;
79
+ padding: 10px 20px;
80
+ background: var(--fn-warning-50);
81
+ border-bottom: 1px solid var(--fn-warning-200);
82
+ color: var(--fn-warning-800);
83
+ font-size: var(--fn-text-sm);
84
+
85
+ &__content {
86
+ display: flex;
87
+ align-items: center;
88
+ gap: 10px;
89
+ flex: 1;
90
+
91
+ lucide-icon { flex-shrink: 0; color: var(--fn-warning-600); }
92
+ }
93
+
94
+ &__text {
95
+ margin: 0;
96
+ line-height: 1.5;
97
+
98
+ strong { font-weight: 700; }
99
+ }
100
+
101
+ &__link {
102
+ margin-left: 8px;
103
+ font-weight: 600;
104
+ color: var(--fn-warning-700);
105
+ text-decoration: underline;
106
+ text-underline-offset: 2px;
107
+
108
+ &:hover { color: var(--fn-warning-900); }
109
+ }
110
+
111
+ &__close {
112
+ display: flex;
113
+ align-items: center;
114
+ justify-content: center;
115
+ width: 28px;
116
+ height: 28px;
117
+ border: none;
118
+ background: transparent;
119
+ border-radius: var(--fn-radius);
120
+ color: var(--fn-warning-600);
121
+ cursor: pointer;
122
+ flex-shrink: 0;
123
+ transition: background var(--fn-transition);
124
+
125
+ &:hover { background: var(--fn-warning-100); }
126
+ }
127
+ }
package/_buttons.scss ADDED
@@ -0,0 +1,208 @@
1
+ /* ── Buttons ────────────────────────────────────────────────────────────── */
2
+
3
+ .fn-btn {
4
+ display: inline-flex;
5
+ align-items: center;
6
+ justify-content: center;
7
+ gap: 0.375rem;
8
+ font-weight: 600;
9
+ border: 1px solid;
10
+ border-radius: var(--fn-radius-md);
11
+ cursor: pointer;
12
+ text-decoration: none;
13
+ font-family: var(--fn-font-sans);
14
+ font-size: var(--fn-text-sm);
15
+ padding: 8px 16px;
16
+ line-height: 1.25;
17
+ transition:
18
+ background var(--fn-transition),
19
+ color var(--fn-transition),
20
+ border-color var(--fn-transition),
21
+ box-shadow var(--fn-transition),
22
+ opacity var(--fn-transition);
23
+
24
+ &:focus-visible {
25
+ outline: 2px solid var(--fn-primary-500);
26
+ outline-offset: 2px;
27
+ }
28
+
29
+ &:disabled,
30
+ &[disabled] {
31
+ opacity: 0.45;
32
+ cursor: not-allowed;
33
+ pointer-events: none;
34
+ }
35
+
36
+ /* ── Sizes ── */
37
+ &--xs {
38
+ padding: 3px 10px;
39
+ font-size: var(--fn-text-xs);
40
+ }
41
+ &--sm {
42
+ padding: 5px 12px;
43
+ font-size: var(--fn-text-xs);
44
+ }
45
+ &--lg {
46
+ padding: 10px 22px;
47
+ font-size: var(--fn-text-base);
48
+ }
49
+ &--xl {
50
+ padding: 12px 28px;
51
+ font-size: var(--fn-text-lg);
52
+ }
53
+ &--block {
54
+ width: 100%;
55
+ }
56
+ &--icon {
57
+ padding: 7px;
58
+ border-radius: var(--fn-radius-md);
59
+ }
60
+
61
+ /* ── Solid variants ── */
62
+ &--primary {
63
+ background: var(--fn-primary-700);
64
+ color: #fff;
65
+ border-color: var(--fn-primary-700);
66
+ &:hover {
67
+ background: var(--fn-primary-800);
68
+ border-color: var(--fn-primary-800);
69
+ }
70
+ }
71
+
72
+ &--secondary {
73
+ background: var(--fn-gray-100);
74
+ color: var(--fn-gray-700);
75
+ border-color: var(--fn-gray-200);
76
+ &:hover {
77
+ background: var(--fn-gray-200);
78
+ border-color: var(--fn-gray-300);
79
+ }
80
+ }
81
+
82
+ &--danger {
83
+ background: var(--fn-danger-600);
84
+ color: #fff;
85
+ border-color: var(--fn-danger-600);
86
+ &:hover {
87
+ background: var(--fn-danger-700);
88
+ border-color: var(--fn-danger-700);
89
+ }
90
+ }
91
+
92
+ &--success {
93
+ background: var(--fn-success-600);
94
+ color: #fff;
95
+ border-color: var(--fn-success-600);
96
+ &:hover {
97
+ background: var(--fn-success-700);
98
+ border-color: var(--fn-success-700);
99
+ }
100
+ }
101
+
102
+ &--warning {
103
+ background: var(--fn-warning-500);
104
+ color: #fff;
105
+ border-color: var(--fn-warning-500);
106
+ &:hover {
107
+ background: var(--fn-warning-600);
108
+ border-color: var(--fn-warning-600);
109
+ }
110
+ }
111
+
112
+ /* ── Outline variants ── */
113
+ &--outline {
114
+ background: transparent;
115
+
116
+ &.fn-btn--primary {
117
+ color: var(--fn-primary-700);
118
+ border-color: var(--fn-primary-300);
119
+ &:hover {
120
+ background: var(--fn-primary-50);
121
+ border-color: var(--fn-primary-500);
122
+ }
123
+ }
124
+ &.fn-btn--secondary {
125
+ color: var(--fn-gray-600);
126
+ border-color: var(--fn-gray-300);
127
+ &:hover {
128
+ background: var(--fn-gray-50);
129
+ }
130
+ }
131
+ &.fn-btn--danger {
132
+ color: var(--fn-danger-600);
133
+ border-color: var(--fn-danger-300);
134
+ &:hover {
135
+ background: var(--fn-danger-50);
136
+ border-color: var(--fn-danger-500);
137
+ }
138
+ }
139
+ &.fn-btn--success {
140
+ color: var(--fn-success-600);
141
+ border-color: var(--fn-success-500);
142
+ &:hover {
143
+ background: var(--fn-success-50);
144
+ }
145
+ }
146
+ &.fn-btn--warning {
147
+ color: var(--fn-warning-600);
148
+ border-color: var(--fn-warning-300);
149
+ &:hover {
150
+ background: var(--fn-warning-50);
151
+ border-color: var(--fn-warning-500);
152
+ }
153
+ }
154
+ }
155
+
156
+ /* ── Ghost variant (no border, no bg — color only on icon/text) ── */
157
+ &--ghost {
158
+ background: transparent;
159
+ border-color: transparent;
160
+ &.fn-btn--primary {
161
+ color: var(--fn-primary-700);
162
+ &:hover {
163
+ background: var(--fn-primary-50);
164
+ border-color: transparent;
165
+ }
166
+ }
167
+ &.fn-btn--danger {
168
+ color: var(--fn-danger-600);
169
+ &:hover {
170
+ background: var(--fn-danger-50);
171
+ border-color: transparent;
172
+ }
173
+ }
174
+ &.fn-btn--success {
175
+ color: var(--fn-success-600);
176
+ &:hover {
177
+ background: var(--fn-success-50);
178
+ border-color: transparent;
179
+ }
180
+ }
181
+ &.fn-btn--warning {
182
+ color: var(--fn-warning-600);
183
+ &:hover {
184
+ background: var(--fn-warning-50);
185
+ border-color: transparent;
186
+ }
187
+ }
188
+ &.fn-btn--gray {
189
+ color: var(--fn-gray-600);
190
+ &:hover {
191
+ background: var(--fn-gray-100);
192
+ border-color: transparent;
193
+ }
194
+ }
195
+ }
196
+
197
+ /* ── Spinner inside button ── */
198
+ &__spinner {
199
+ display: inline-block;
200
+ width: 14px;
201
+ height: 14px;
202
+ border: 2px solid currentColor;
203
+ border-top-color: transparent;
204
+ border-radius: 50%;
205
+ animation: fn-spin 0.65s linear infinite;
206
+ flex-shrink: 0;
207
+ }
208
+ }
package/_cards.scss ADDED
@@ -0,0 +1,160 @@
1
+ /* ── Cards ──────────────────────────────────────────────────────────────── */
2
+
3
+ .fn-card {
4
+ background: #fff;
5
+ border: 1px solid var(--fn-gray-200);
6
+ border-radius: var(--fn-radius-lg);
7
+ box-shadow: var(--fn-shadow-sm);
8
+ overflow: hidden;
9
+
10
+ &--hoverable {
11
+ transition: box-shadow var(--fn-transition-md), transform var(--fn-transition-md);
12
+ cursor: pointer;
13
+ &:hover { box-shadow: var(--fn-shadow-md); transform: translateY(-1px); }
14
+ }
15
+
16
+ &--selected {
17
+ border-color: var(--fn-primary-400);
18
+ box-shadow: 0 0 0 3px rgba(47, 75, 179, 0.12);
19
+ }
20
+
21
+ &--flat { box-shadow: none; }
22
+ }
23
+
24
+ .fn-card__header {
25
+ display: flex;
26
+ align-items: center;
27
+ justify-content: space-between;
28
+ gap: 12px;
29
+ padding: 16px 20px;
30
+ border-bottom: 1px solid var(--fn-gray-100);
31
+
32
+ // Cuando el header solo tiene ícono + título (sin acción a la derecha)
33
+ &--icon { justify-content: flex-start; gap: 10px; }
34
+ }
35
+
36
+ .fn-card__title {
37
+ font-size: var(--fn-text-base);
38
+ font-weight: 700;
39
+ color: var(--fn-gray-900);
40
+ margin: 0;
41
+ }
42
+
43
+ .fn-card__subtitle {
44
+ font-size: var(--fn-text-xs);
45
+ color: var(--fn-gray-500);
46
+ margin: 2px 0 0;
47
+ }
48
+
49
+ .fn-card__body {
50
+ padding: 20px;
51
+ }
52
+
53
+ .fn-card__footer {
54
+ padding: 12px 20px;
55
+ border-top: 1px solid var(--fn-gray-100);
56
+ display: flex;
57
+ align-items: center;
58
+ justify-content: flex-end;
59
+ gap: 8px;
60
+ background: var(--fn-gray-50);
61
+ }
62
+
63
+ /* ── Stat card ── */
64
+ .fn-stat {
65
+ background: #fff;
66
+ border: 1px solid var(--fn-gray-200);
67
+ border-radius: var(--fn-radius-lg);
68
+ padding: 20px;
69
+ box-shadow: var(--fn-shadow-sm);
70
+
71
+ &__label {
72
+ font-size: var(--fn-text-xs);
73
+ font-weight: 700;
74
+ color: var(--fn-gray-500);
75
+ text-transform: uppercase;
76
+ letter-spacing: 0.05em;
77
+ margin-bottom: 6px;
78
+ }
79
+
80
+ &__value {
81
+ font-size: var(--fn-text-3xl);
82
+ font-weight: 800;
83
+ color: var(--fn-gray-900);
84
+ line-height: 1;
85
+ margin-bottom: 6px;
86
+ }
87
+
88
+ &__trend {
89
+ font-size: var(--fn-text-xs);
90
+ display: flex;
91
+ align-items: center;
92
+ gap: 4px;
93
+ &--up { color: var(--fn-success-600); }
94
+ &--down { color: var(--fn-danger-600); }
95
+ }
96
+ }
97
+
98
+ /* ── Session cards (ISO 27001 sessions page) ── */
99
+ .fn-sessions-list {
100
+ display: flex;
101
+ flex-direction: column;
102
+ gap: 10px;
103
+ }
104
+
105
+ .fn-session-card {
106
+ display: flex;
107
+ align-items: flex-start;
108
+ gap: 14px;
109
+ background: #fff;
110
+ border: 1px solid var(--fn-gray-200);
111
+ border-radius: var(--fn-radius-lg);
112
+ padding: 16px;
113
+ box-shadow: var(--fn-shadow-sm);
114
+ transition: box-shadow var(--fn-transition);
115
+
116
+ &--current {
117
+ border-color: var(--fn-primary-300);
118
+ background: var(--fn-primary-50);
119
+ }
120
+
121
+ &--skeleton { pointer-events: none; }
122
+
123
+ &__icon { font-size: 22px; flex-shrink: 0; margin-top: 2px; }
124
+ &__body { flex: 1; min-width: 0; }
125
+
126
+ &__device {
127
+ display: flex;
128
+ flex-wrap: wrap;
129
+ align-items: center;
130
+ gap: 6px;
131
+ margin-bottom: 6px;
132
+ }
133
+
134
+ &__browser { font-weight: 700; font-size: var(--fn-text-sm); color: var(--fn-gray-900); }
135
+ &__sep { color: var(--fn-gray-400); }
136
+ &__os { font-size: var(--fn-text-sm); color: var(--fn-gray-600); }
137
+
138
+ &__meta {
139
+ display: flex;
140
+ flex-wrap: wrap;
141
+ gap: 4px 16px;
142
+ }
143
+
144
+ &__meta-item {
145
+ display: flex;
146
+ align-items: center;
147
+ gap: 4px;
148
+ font-size: var(--fn-text-xs);
149
+ color: var(--fn-gray-500);
150
+ }
151
+
152
+ &__meta-label { font-weight: 600; color: var(--fn-gray-700); }
153
+ &__actions { flex-shrink: 0; align-self: center; }
154
+ }
155
+
156
+ .fn-sessions-skeleton {
157
+ display: flex;
158
+ flex-direction: column;
159
+ gap: 10px;
160
+ }
@@ -0,0 +1,79 @@
1
+ /* ── Dropdowns & Menus ──────────────────────────────────────────────────── */
2
+
3
+ .fn-dropdown {
4
+ position: relative;
5
+ display: inline-block;
6
+ }
7
+
8
+ .fn-dropdown__menu {
9
+ position: absolute;
10
+ top: calc(100% + 4px);
11
+ right: 0;
12
+ min-width: 180px;
13
+ background: #fff;
14
+ border: 1px solid var(--fn-gray-200);
15
+ border-radius: var(--fn-radius-md);
16
+ box-shadow: var(--fn-shadow-lg);
17
+ padding: 4px 0;
18
+ z-index: 300;
19
+ animation: fn-dropdown-in 0.12s ease-out;
20
+
21
+ &--left { right: auto; left: 0; }
22
+ &--center { right: auto; left: 50%; transform: translateX(-50%); }
23
+ &--up { top: auto; bottom: calc(100% + 4px); }
24
+ &--wide { min-width: 240px; }
25
+ }
26
+
27
+ .fn-dropdown__item {
28
+ display: flex;
29
+ align-items: center;
30
+ gap: 8px;
31
+ padding: 8px 14px;
32
+ font-family: var(--fn-font-sans);
33
+ font-size: var(--fn-text-sm);
34
+ color: var(--fn-gray-700);
35
+ cursor: pointer;
36
+ transition: background var(--fn-transition);
37
+ text-decoration: none;
38
+ border: none;
39
+ background: transparent;
40
+ width: 100%;
41
+ text-align: left;
42
+
43
+ &:hover { background: var(--fn-gray-50); color: var(--fn-gray-900); }
44
+ &--active { background: var(--fn-primary-50); color: var(--fn-primary-700); font-weight: 600; }
45
+ &--danger { color: var(--fn-danger-600); &:hover { background: var(--fn-danger-50); } }
46
+ &--disabled { opacity: 0.4; cursor: not-allowed; pointer-events: none; }
47
+
48
+ &__icon { flex-shrink: 0; opacity: 0.7; font-size: 15px; }
49
+ &__label { flex: 1; }
50
+ &__shortcut { font-size: var(--fn-text-xs); color: var(--fn-gray-400); margin-left: auto; }
51
+ }
52
+
53
+ .fn-dropdown__divider {
54
+ height: 1px;
55
+ background: var(--fn-gray-200);
56
+ margin: 4px 0;
57
+ }
58
+
59
+ .fn-dropdown__header {
60
+ padding: 6px 14px 4px;
61
+ font-size: var(--fn-text-xs);
62
+ font-weight: 700;
63
+ color: var(--fn-gray-400);
64
+ text-transform: uppercase;
65
+ letter-spacing: 0.05em;
66
+ }
67
+
68
+ /* Context menu (right-click) — same styles, different trigger */
69
+ .fn-context-menu {
70
+ position: fixed;
71
+ background: #fff;
72
+ border: 1px solid var(--fn-gray-200);
73
+ border-radius: var(--fn-radius-md);
74
+ box-shadow: var(--fn-shadow-lg);
75
+ padding: 4px 0;
76
+ z-index: 500;
77
+ min-width: 160px;
78
+ animation: fn-dropdown-in 0.1s ease-out;
79
+ }
package/_feedback.scss ADDED
@@ -0,0 +1,84 @@
1
+ /* ── Toast notifications ────────────────────────────────────────────────── */
2
+
3
+ .fn-toast-container {
4
+ position: fixed;
5
+ bottom: 24px;
6
+ right: 24px;
7
+ z-index: 500;
8
+ display: flex;
9
+ flex-direction: column;
10
+ gap: 10px;
11
+ pointer-events: none;
12
+ max-width: 420px;
13
+ }
14
+
15
+ .fn-toast {
16
+ display: flex;
17
+ align-items: flex-start;
18
+ gap: 10px;
19
+ padding: 12px 16px;
20
+ border-radius: var(--fn-radius-md);
21
+ box-shadow: var(--fn-shadow-lg);
22
+ font-size: var(--fn-text-sm);
23
+ font-weight: 500;
24
+ pointer-events: auto;
25
+ animation: fn-toast-in 0.2s ease-out;
26
+ line-height: 1.4;
27
+
28
+ &--success { background: #166534; color: #fff; }
29
+ &--error { background: #991b1b; color: #fff; }
30
+ &--warning { background: #92400e; color: #fff; }
31
+ &--info { background: var(--fn-primary-700); color: #fff; }
32
+
33
+ &__icon { font-size: 16px; flex-shrink: 0; margin-top: 1px; }
34
+ &__message { flex: 1; }
35
+ &__close {
36
+ background: transparent;
37
+ border: none;
38
+ cursor: pointer;
39
+ color: inherit;
40
+ font-size: 18px;
41
+ opacity: 0.65;
42
+ flex-shrink: 0;
43
+ padding: 0;
44
+ line-height: 1;
45
+ &:hover { opacity: 1; }
46
+ }
47
+ }
48
+
49
+ /* ── Spinner ─────────────────────────────────────────────────────────────── */
50
+
51
+ .fn-spinner {
52
+ display: inline-block;
53
+ border-radius: 50%;
54
+ border: 2px solid var(--fn-gray-200);
55
+ border-top-color: var(--fn-primary-700);
56
+ animation: fn-spin 0.7s linear infinite;
57
+ flex-shrink: 0;
58
+
59
+ &--sm { width: 16px; height: 16px; }
60
+ &--md { width: 24px; height: 24px; border-width: 3px; }
61
+ &--lg { width: 40px; height: 40px; border-width: 3px; }
62
+ }
63
+
64
+ /* ── Skeleton loader ─────────────────────────────────────────────────────── */
65
+
66
+ .fn-skeleton {
67
+ background: linear-gradient(
68
+ 90deg,
69
+ var(--fn-gray-200) 25%,
70
+ var(--fn-gray-100) 50%,
71
+ var(--fn-gray-200) 75%
72
+ );
73
+ background-size: 200% 100%;
74
+ border-radius: var(--fn-radius);
75
+ animation: fn-shimmer 1.5s ease-in-out infinite;
76
+
77
+ &--icon { width: 32px; height: 32px; border-radius: var(--fn-radius-md); flex-shrink: 0; }
78
+ &--avatar { width: 40px; height: 40px; border-radius: 50%; }
79
+ &--title { height: 16px; width: 48%; margin-bottom: 8px; }
80
+ &--text { height: 12px; width: 72%; }
81
+ &--short { width: 36%; }
82
+ &--button { height: 34px; width: 90px; border-radius: var(--fn-radius); }
83
+ &--full { width: 100%; height: 12px; }
84
+ }