@edc-motor/ui 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +45 -0
  3. package/package.json +47 -0
  4. package/scss/_base.scss +33 -0
  5. package/scss/_forms.scss +33 -0
  6. package/scss/_shared-components.scss +1 -0
  7. package/scss/_theme.scss +74 -0
  8. package/scss/_tokens.scss +114 -0
  9. package/scss/components/_base-button.scss +113 -0
  10. package/scss/components/_blocks.scss +211 -0
  11. package/scss/components/_breadcrumbs.scss +31 -0
  12. package/scss/components/_checkbox.scss +42 -0
  13. package/scss/components/_chip.scss +23 -0
  14. package/scss/components/_confirm.scss +3 -0
  15. package/scss/components/_edit-modal.scss +11 -0
  16. package/scss/components/_font-upload.scss +91 -0
  17. package/scss/components/_form-field.scss +85 -0
  18. package/scss/components/_icon-button.scss +23 -0
  19. package/scss/components/_image-upload.scss +85 -0
  20. package/scss/components/_index.scss +24 -0
  21. package/scss/components/_locale-selector.scss +89 -0
  22. package/scss/components/_modal.scss +68 -0
  23. package/scss/components/_motor-badge.scss +21 -0
  24. package/scss/components/_numeric-input.scss +53 -0
  25. package/scss/components/_page-background.scss +22 -0
  26. package/scss/components/_palette-color-picker.scss +69 -0
  27. package/scss/components/_rich-text.scss +144 -0
  28. package/scss/components/_search-select.scss +138 -0
  29. package/scss/components/_tabs.scss +120 -0
  30. package/scss/components/_theme-selector.scss +34 -0
  31. package/scss/components/_toast-container.scss +16 -0
  32. package/scss/components/_toast.scss +25 -0
  33. package/scss/components/_translatable-input.scss +73 -0
  34. package/src/blocks/BlockCta.vue +32 -0
  35. package/src/blocks/BlockFaq.vue +25 -0
  36. package/src/blocks/BlockHeader.vue +13 -0
  37. package/src/blocks/BlockIndex.vue +20 -0
  38. package/src/blocks/BlockQuote.vue +16 -0
  39. package/src/blocks/BlockShell.vue +30 -0
  40. package/src/blocks/BlockText.vue +20 -0
  41. package/src/blocks/BlockTextCard.vue +23 -0
  42. package/src/blocks/PageBackground.vue +15 -0
  43. package/src/blocks/index.ts +25 -0
  44. package/src/components/AppBreadcrumbs.vue +44 -0
  45. package/src/components/BaseButton.vue +24 -0
  46. package/src/components/BaseCheckbox.vue +37 -0
  47. package/src/components/BaseInput.vue +53 -0
  48. package/src/components/BaseModal.vue +98 -0
  49. package/src/components/BaseSelect.vue +53 -0
  50. package/src/components/BaseTabs.vue +30 -0
  51. package/src/components/BaseTextarea.vue +45 -0
  52. package/src/components/BaseToast.vue +31 -0
  53. package/src/components/ConfirmDialog.vue +35 -0
  54. package/src/components/EditModal.vue +57 -0
  55. package/src/components/FontUpload.vue +123 -0
  56. package/src/components/IconButton.vue +24 -0
  57. package/src/components/ImageUpload.vue +142 -0
  58. package/src/components/LocaleSelector.vue +59 -0
  59. package/src/components/MotorBadge.vue +17 -0
  60. package/src/components/NumericInput.vue +115 -0
  61. package/src/components/PaletteColorPicker.vue +94 -0
  62. package/src/components/RichTextInput.vue +273 -0
  63. package/src/components/SearchSelect.vue +172 -0
  64. package/src/components/ThemeSelector.vue +28 -0
  65. package/src/components/ToastContainer.vue +23 -0
  66. package/src/components/TranslatableImage.vue +120 -0
  67. package/src/components/TranslatableInput.vue +135 -0
  68. package/src/composables/useConfirm.ts +49 -0
  69. package/src/composables/useHead.ts +54 -0
  70. package/src/composables/useTheme.ts +50 -0
  71. package/src/composables/useToast.ts +26 -0
  72. package/src/index.ts +39 -0
  73. package/src/lib/createApi.ts +42 -0
@@ -0,0 +1,42 @@
1
+ @use "tokens" as *;
2
+
3
+ // Checkbox (portado de kontuan).
4
+ .checkbox {
5
+ display: inline-flex;
6
+ align-items: center;
7
+ gap: $space-2;
8
+ cursor: pointer;
9
+
10
+ &--disabled { opacity: $disabled-opacity; cursor: not-allowed; pointer-events: none; }
11
+
12
+ &__input {
13
+ position: absolute;
14
+ opacity: 0;
15
+ width: 0;
16
+ height: 0;
17
+
18
+ &:focus-visible + .checkbox__box { box-shadow: $focus-ring; }
19
+ &:checked + .checkbox__box {
20
+ background-color: $accent-500;
21
+ border-color: $accent-500;
22
+ color: #fff;
23
+ }
24
+ }
25
+
26
+ &__box {
27
+ display: flex;
28
+ align-items: center;
29
+ justify-content: center;
30
+ width: 18px;
31
+ height: 18px;
32
+ border: 1.5px solid $border-strong;
33
+ border-radius: $radius-sm;
34
+ background-color: $surface;
35
+ transition: background-color 0.15s, border-color 0.15s;
36
+ flex-shrink: 0;
37
+ }
38
+
39
+ &__icon { width: 14px; height: 14px; }
40
+
41
+ &__label { font-size: $fs-14; color: $text-1; user-select: none; }
42
+ }
@@ -0,0 +1,23 @@
1
+ @use "tokens" as *;
2
+
3
+ // El chip ÚNICO del motor (etiquetas de estado, idioma, contadores…), para
4
+ // app y admin. Contorno con esquinas POCO redondeadas (más cuadrado que una
5
+ // píldora) y NUNCA gris: sin estado explícito va en el color de ACENTO; los
6
+ // estados lo tiñen. Tamaño fijo $fs-12.
7
+ .chip {
8
+ display: inline-flex;
9
+ align-items: center;
10
+ gap: 2px;
11
+ padding: 1px $space-2;
12
+ border-radius: $radius-sm;
13
+ font-size: $fs-12;
14
+ font-weight: 600;
15
+ white-space: nowrap;
16
+ border: 1px solid color-mix(in srgb, $accent-500 45%, transparent);
17
+ color: $accent-500;
18
+
19
+ &.is-ok { color: $success; border-color: color-mix(in srgb, $success 45%, transparent); }
20
+ &.is-info { color: $info; border-color: color-mix(in srgb, $info 45%, transparent); }
21
+ &.is-missing { color: $warning; border-color: color-mix(in srgb, $warning 45%, transparent); }
22
+ &.is-failed { color: $danger; border-color: color-mix(in srgb, $danger 45%, transparent); }
23
+ }
@@ -0,0 +1,3 @@
1
+ @use "tokens" as *;
2
+
3
+ .confirm__message { margin: 0; color: $text-1; }
@@ -0,0 +1,11 @@
1
+ @use "tokens" as *;
2
+
3
+ .edit-modal {
4
+ &__form { display: contents; }
5
+
6
+ &__body {
7
+ display: flex;
8
+ flex-direction: column;
9
+ gap: $space-4;
10
+ }
11
+ }
@@ -0,0 +1,91 @@
1
+ @use "tokens" as *;
2
+
3
+ // Subida de fuente (hermano compacto de image-upload): una franja clicable
4
+ // con drag-and-drop; el fichero elegido se muestra con nombre y tamaño.
5
+ .font-upload {
6
+ display: grid;
7
+ gap: $space-1;
8
+
9
+ &__label {
10
+ font-size: $fs-13;
11
+ font-weight: $k-fw-medium;
12
+ color: $text-2;
13
+ }
14
+
15
+ &__zone {
16
+ display: flex;
17
+ align-items: center;
18
+ gap: $space-2;
19
+ min-height: 44px;
20
+ padding: $space-2 $space-3;
21
+ border: 1px dashed $border;
22
+ border-radius: $radius-md;
23
+ cursor: pointer;
24
+ transition: border-color 0.15s ease, background-color 0.15s ease;
25
+
26
+ &:hover {
27
+ border-color: $border-strong;
28
+ background-color: $surface-2;
29
+ }
30
+
31
+ &--dragging {
32
+ border-color: $accent-500;
33
+ background-color: color-mix(in srgb, $accent-500 8%, transparent);
34
+ }
35
+
36
+ &--has-file { border-style: solid; }
37
+ &--error { border-color: $danger; }
38
+ }
39
+
40
+ &__input { display: none; }
41
+
42
+ &__icon {
43
+ flex: 0 0 auto;
44
+ color: $text-3;
45
+ }
46
+
47
+ &__name {
48
+ min-width: 0;
49
+ overflow: hidden;
50
+ text-overflow: ellipsis;
51
+ white-space: nowrap;
52
+ font-size: $fs-13;
53
+ color: $text-1;
54
+ }
55
+
56
+ &__size {
57
+ flex: 0 0 auto;
58
+ font-size: $fs-12;
59
+ color: $text-3;
60
+ }
61
+
62
+ &__remove {
63
+ flex: 0 0 auto;
64
+ display: inline-flex;
65
+ align-items: center;
66
+ border: none;
67
+ background: none;
68
+ padding: $space-1;
69
+ color: $text-3;
70
+ cursor: pointer;
71
+
72
+ &:hover { color: $danger; }
73
+ }
74
+
75
+ &__text {
76
+ font-size: $fs-13;
77
+ color: $text-2;
78
+ }
79
+
80
+ &__hint {
81
+ margin-left: auto;
82
+ font-size: $fs-12;
83
+ color: $text-3;
84
+ }
85
+
86
+ &__error {
87
+ margin: 0;
88
+ font-size: $fs-12;
89
+ color: $danger;
90
+ }
91
+ }
@@ -0,0 +1,85 @@
1
+ @use "tokens" as *;
2
+
3
+ // Estilo compartido de los elementos de formulario (portado de kontuan):
4
+ // BaseInput, BaseTextarea, BaseSelect y TranslatableInput.
5
+ .form-field {
6
+ display: flex;
7
+ flex-direction: column;
8
+ gap: $space-1;
9
+ min-width: 0;
10
+
11
+ &__label {
12
+ font-size: $fs-13;
13
+ font-weight: $k-fw-medium;
14
+ color: $text-2;
15
+ }
16
+
17
+ &__required { color: $danger; }
18
+
19
+ &__input,
20
+ &__textarea,
21
+ &__select {
22
+ width: 100%;
23
+ background-color: $input-bg;
24
+ color: $input-text;
25
+ border: 1px solid $input-border;
26
+ border-radius: $input-radius;
27
+ font-family: $k-font-sans;
28
+ font-size: $fs-14;
29
+ transition: border-color 0.15s, box-shadow 0.15s;
30
+
31
+ &::placeholder { color: $input-placeholder; }
32
+ &:hover:not(:disabled):not(:focus) { border-color: $input-border-hover; }
33
+ &:focus {
34
+ outline: none;
35
+ border-color: $input-border-focus;
36
+ box-shadow: $input-focus-ring;
37
+ }
38
+ &:disabled { opacity: $disabled-opacity; cursor: not-allowed; }
39
+ }
40
+
41
+ &__input {
42
+ height: $input-height;
43
+ padding: 0 $input-padding-x;
44
+ }
45
+
46
+ &__textarea {
47
+ padding: $input-padding-y $input-padding-x;
48
+ line-height: $k-lh-body;
49
+ resize: vertical;
50
+ }
51
+
52
+ &__select-wrapper {
53
+ position: relative;
54
+ &::after {
55
+ content: '';
56
+ position: absolute;
57
+ right: 12px;
58
+ top: 50%;
59
+ transform: translateY(-50%);
60
+ width: 0;
61
+ height: 0;
62
+ border-left: 5px solid transparent;
63
+ border-right: 5px solid transparent;
64
+ border-top: 5px solid $text-3;
65
+ pointer-events: none;
66
+ }
67
+ }
68
+
69
+ &__select {
70
+ height: $input-height;
71
+ padding: 0 ($input-padding-x + 16px) 0 $input-padding-x;
72
+ appearance: none;
73
+ cursor: pointer;
74
+ }
75
+
76
+ &--error &__input,
77
+ &--error &__textarea,
78
+ &--error &__select {
79
+ border-color: $danger;
80
+ &:focus { box-shadow: 0 0 0 3px color-mix(in srgb, #{$danger} 20%, transparent); }
81
+ }
82
+
83
+ &__error { font-size: $fs-12; color: $danger; }
84
+ &__hint { font-size: $fs-12; color: $text-3; }
85
+ }
@@ -0,0 +1,23 @@
1
+ @use "tokens" as *;
2
+
3
+ .icon-btn {
4
+ display: inline-flex;
5
+ align-items: center;
6
+ justify-content: center;
7
+ padding: $space-2;
8
+ line-height: 0;
9
+ background: none;
10
+ border: none;
11
+ border-radius: $radius-md;
12
+ color: $color-text; // color del texto en reposo
13
+ cursor: pointer;
14
+ transition: color 0.12s ease, background-color 0.12s ease;
15
+
16
+ // hover: stroke + fondo semitransparente del color de la acción
17
+ &--neutral:hover { color: $color-text; background: rgba(255, 255, 255, 0.08); }
18
+ &--accent:hover { color: $color-accent; background: rgba(108, 92, 231, 0.18); }
19
+ &--danger:hover { color: #ff6b6b; background: rgba(255, 107, 107, 0.16); }
20
+ &--success:hover { color: #4ade80; background: rgba(74, 222, 128, 0.16); }
21
+ &--warning:hover { color: #fbbf24; background: rgba(251, 191, 36, 0.16); }
22
+ &--info:hover { color: #6c8cff; background: rgba(108, 140, 255, 0.16); }
23
+ }
@@ -0,0 +1,85 @@
1
+ @use "tokens" as *;
2
+
3
+ // Zona de subida con arrastrar-y-soltar (portado de kontuan).
4
+ .image-upload {
5
+ display: flex;
6
+ flex-direction: column;
7
+ gap: $space-1;
8
+
9
+ &__label {
10
+ font-size: $fs-13;
11
+ font-weight: $k-fw-medium;
12
+ color: $text-2;
13
+ }
14
+
15
+ &__input { display: none; }
16
+
17
+ &__zone {
18
+ position: relative;
19
+ display: flex;
20
+ align-self: flex-start;
21
+ align-items: center;
22
+ justify-content: center;
23
+ width: 160px;
24
+ height: 160px;
25
+ border: 2px dashed $border;
26
+ border-radius: $radius-md;
27
+ cursor: pointer;
28
+ overflow: hidden;
29
+ transition: border-color 0.15s, background-color 0.15s;
30
+
31
+ &:hover:not(.image-upload__zone--has-image) {
32
+ border-color: $border-strong;
33
+ background-color: $surface-2;
34
+ }
35
+ &--dragging {
36
+ border-color: $accent-500;
37
+ background-color: color-mix(in srgb, $accent-500 8%, transparent);
38
+ }
39
+ &--has-image { border-style: solid; cursor: default; }
40
+ &--error { border-color: $danger; }
41
+ }
42
+
43
+ &__preview {
44
+ width: 100%;
45
+ height: 100%;
46
+ object-fit: contain;
47
+ padding: $space-2;
48
+ }
49
+
50
+ &__remove {
51
+ position: absolute;
52
+ top: $space-1;
53
+ right: $space-1;
54
+ display: flex;
55
+ align-items: center;
56
+ justify-content: center;
57
+ width: 28px;
58
+ height: 28px;
59
+ border: none;
60
+ border-radius: $radius-sm;
61
+ background-color: color-mix(in srgb, $surface 70%, transparent);
62
+ color: $text-1;
63
+ cursor: pointer;
64
+ transition: background-color 0.15s, color 0.15s;
65
+
66
+ &:hover {
67
+ color: $danger;
68
+ background-color: color-mix(in srgb, $danger 12%, $surface);
69
+ }
70
+ }
71
+
72
+ &__placeholder {
73
+ display: flex;
74
+ flex-direction: column;
75
+ align-items: center;
76
+ gap: $space-1;
77
+ padding: $space-3;
78
+ text-align: center;
79
+ }
80
+
81
+ &__icon { width: 32px; height: 32px; color: $text-3; }
82
+ &__text { font-size: $fs-12; color: $text-2; }
83
+ &__hint { font-size: $fs-12; color: $text-3; }
84
+ &__error { font-size: $fs-12; color: $danger; }
85
+ }
@@ -0,0 +1,24 @@
1
+ @use "base-button";
2
+ @use "chip";
3
+ @use "icon-button";
4
+ @use "motor-badge";
5
+ @use "form-field";
6
+ @use "search-select";
7
+ @use "blocks";
8
+ @use "page-background";
9
+ @use "numeric-input";
10
+ @use "checkbox";
11
+ @use "palette-color-picker";
12
+ @use "rich-text";
13
+ @use "translatable-input";
14
+ @use "image-upload";
15
+ @use "font-upload";
16
+ @use "toast";
17
+ @use "toast-container";
18
+ @use "modal";
19
+ @use "tabs";
20
+ @use "confirm";
21
+ @use "edit-modal";
22
+ @use "theme-selector";
23
+ @use "locale-selector";
24
+ @use "breadcrumbs";
@@ -0,0 +1,89 @@
1
+ @use "tokens" as *;
2
+
3
+ .locale-selector {
4
+ position: relative;
5
+ }
6
+
7
+ .locale-trigger {
8
+ display: flex;
9
+ align-items: center;
10
+ gap: 2px;
11
+ background: $surface-2;
12
+ border: 1px solid $border;
13
+ border-radius: $radius-sm;
14
+ padding: $space-1 $space-2;
15
+ font-size: $fs-12;
16
+ font-weight: $k-fw-semibold;
17
+ color: $text-2;
18
+ cursor: pointer;
19
+ transition: all 0.15s ease;
20
+
21
+ &:hover {
22
+ background: $surface-3;
23
+ color: $text-1;
24
+ }
25
+ }
26
+
27
+ .locale-chevron {
28
+ flex-shrink: 0;
29
+ }
30
+
31
+ .locale-dropdown {
32
+ position: absolute;
33
+ top: calc(100% + 4px);
34
+ right: 0;
35
+ background: $surface;
36
+ border: 1px solid $border;
37
+ border-radius: $radius-md;
38
+ box-shadow: $shadow-md;
39
+ min-width: 160px;
40
+ padding: 4px;
41
+ z-index: 100;
42
+ }
43
+
44
+ .locale-option {
45
+ display: flex;
46
+ align-items: center;
47
+ gap: $space-2;
48
+ width: 100%;
49
+ padding: $space-2 $space-3;
50
+ border: none;
51
+ border-radius: $radius-sm;
52
+ background: transparent;
53
+ font-size: $fs-13;
54
+ color: $text-2;
55
+ cursor: pointer;
56
+ text-align: left;
57
+ transition: all 0.1s ease;
58
+
59
+ &:hover {
60
+ background: $ui-hover-bg;
61
+ color: $text-1;
62
+ }
63
+
64
+ &.active {
65
+ color: $accent-600;
66
+ font-weight: $k-fw-semibold;
67
+ }
68
+ }
69
+
70
+ .locale-code {
71
+ font-weight: $k-fw-bold;
72
+ font-size: $fs-12;
73
+ min-width: 24px;
74
+ }
75
+
76
+ .locale-label {
77
+ flex: 1;
78
+ }
79
+
80
+ // Transición del dropdown
81
+ .dropdown-enter-active,
82
+ .dropdown-leave-active {
83
+ transition: opacity 0.12s ease, transform 0.12s ease;
84
+ }
85
+ .dropdown-enter-from,
86
+ .dropdown-leave-to {
87
+ opacity: 0;
88
+ transform: translateY(-4px);
89
+ }
@@ -0,0 +1,68 @@
1
+ @use "tokens" as *;
2
+
3
+ .modal-overlay {
4
+ position: fixed;
5
+ inset: 0;
6
+ z-index: 1500;
7
+ background: rgba(0, 0, 0, 0.5);
8
+ display: flex;
9
+ align-items: center;
10
+ justify-content: center;
11
+ padding: $space-4;
12
+ }
13
+
14
+ .modal {
15
+ background: $surface;
16
+ border: 1px solid $border;
17
+ border-radius: $radius-lg;
18
+ box-shadow: $shadow-lg;
19
+ width: 100%;
20
+ // Nunca ocupa toda la pantalla; si el contenido no cabe, hace scroll el body.
21
+ max-height: 88vh;
22
+ overflow: hidden;
23
+ display: flex;
24
+ flex-direction: column;
25
+
26
+ &--sm { max-width: 380px; }
27
+ &--md { max-width: 560px; }
28
+ &--lg { max-width: 820px; }
29
+
30
+ &__header {
31
+ flex-shrink: 0;
32
+ display: flex; align-items: center; justify-content: space-between; gap: $space-3;
33
+ padding: $space-4 $space-5;
34
+ border-bottom: 1px solid $border;
35
+ background: $surface-2; // cabecera con fondo
36
+ border-radius: $radius-lg $radius-lg 0 0;
37
+ }
38
+ &__title { margin: 0; font-size: $fs-18; }
39
+
40
+ // Botón de cerrar: funciona como action-button; en hover se tiñe de rojo.
41
+ &__close {
42
+ display: inline-flex; align-items: center; justify-content: center;
43
+ width: 32px; height: 32px; border: none; background: none; color: $text-2;
44
+ cursor: pointer; border-radius: $radius-sm;
45
+ transition: background-color 0.15s ease, color 0.15s ease;
46
+ &:hover {
47
+ color: $danger;
48
+ background: color-mix(in srgb, #{$danger} 15%, transparent);
49
+ }
50
+ }
51
+
52
+ // El cuerpo es la única zona que scrollea (cabecera y pie quedan fijos).
53
+ &__body {
54
+ flex: 1 1 auto;
55
+ min-height: 0;
56
+ overflow-y: auto;
57
+ padding: $space-5;
58
+ }
59
+
60
+ &__footer {
61
+ flex-shrink: 0;
62
+ display: flex; justify-content: flex-end; gap: $space-3;
63
+ padding: $space-4 $space-5; border-top: 1px solid $border; background: $surface-2;
64
+ }
65
+ }
66
+
67
+ .modal-enter-active, .modal-leave-active { transition: opacity 0.2s ease; }
68
+ .modal-enter-from, .modal-leave-to { opacity: 0; }
@@ -0,0 +1,21 @@
1
+ @use "tokens" as *;
2
+
3
+ .edc-badge {
4
+ display: inline-flex;
5
+ align-items: center;
6
+ gap: $space-2;
7
+ padding: $space-1 $space-3;
8
+ border: 1px solid $color-border;
9
+ border-radius: $radius-pill;
10
+ background: $color-surface;
11
+ color: $color-text;
12
+ font-size: 0.85rem;
13
+ font-weight: 600;
14
+
15
+ &__dot {
16
+ width: 0.5rem;
17
+ height: 0.5rem;
18
+ border-radius: 50%;
19
+ background: $color-accent;
20
+ }
21
+ }
@@ -0,0 +1,53 @@
1
+ @use "tokens" as *;
2
+
3
+ // Campo numérico con botones -/+ (portado de kontuan).
4
+ .numeric-input {
5
+ display: flex;
6
+ align-items: center;
7
+ height: $input-height;
8
+ background-color: $input-bg;
9
+ border: 1px solid $input-border;
10
+ border-radius: $input-radius;
11
+ transition: border-color 0.15s, box-shadow 0.15s;
12
+
13
+ &:hover:not(.numeric-input--disabled) { border-color: $input-border-hover; }
14
+ &:focus-within { border-color: $input-border-focus; box-shadow: $input-focus-ring; }
15
+ &--disabled { opacity: $disabled-opacity; cursor: not-allowed; }
16
+
17
+ &__btn {
18
+ display: flex;
19
+ align-items: center;
20
+ justify-content: center;
21
+ flex-shrink: 0;
22
+ width: 32px;
23
+ height: 100%;
24
+ padding: 0;
25
+ border: none;
26
+ background: none;
27
+ color: $text-3;
28
+ cursor: pointer;
29
+ transition: color 0.15s;
30
+
31
+ &:hover:not(:disabled) { color: $text-1; }
32
+ &:disabled { opacity: 0.3; cursor: not-allowed; }
33
+ }
34
+
35
+ &__field {
36
+ flex: 1;
37
+ min-width: 0;
38
+ height: 100%;
39
+ padding: 0 $space-1;
40
+ border: none;
41
+ background: none;
42
+ color: $input-text;
43
+ font-family: $k-font-sans;
44
+ font-size: $fs-14;
45
+ text-align: center;
46
+ outline: none;
47
+
48
+ &::placeholder { color: $input-placeholder; }
49
+ &::-webkit-outer-spin-button,
50
+ &::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
51
+ -moz-appearance: textfield;
52
+ }
53
+ }
@@ -0,0 +1,22 @@
1
+ @use "tokens" as *;
2
+
3
+ // Imagen de fondo de la página del CRM (patrón CDL): capa fija a toda la
4
+ // ventana tras el contenido; la intensidad la decide el tema activo
5
+ // (--page-bg-opacity: 0.2 en claro, 0.1 en oscuro) y un grayscale suave
6
+ // evita que compita con el contenido.
7
+ .page-background {
8
+ position: fixed;
9
+ top: 0;
10
+ left: 0;
11
+ width: 100%;
12
+ height: 100vh; // fallback
13
+ height: 100lvh; // altura SIN la barra del navegador móvil
14
+ background-size: cover;
15
+ background-position: top;
16
+ background-repeat: no-repeat;
17
+ z-index: -1;
18
+ pointer-events: none;
19
+ opacity: var(--page-bg-opacity, 0.15);
20
+ filter: grayscale(60%);
21
+ transition: opacity 0.3s ease;
22
+ }