@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.
- package/LICENSE +674 -0
- package/README.md +45 -0
- package/package.json +47 -0
- package/scss/_base.scss +33 -0
- package/scss/_forms.scss +33 -0
- package/scss/_shared-components.scss +1 -0
- package/scss/_theme.scss +74 -0
- package/scss/_tokens.scss +114 -0
- package/scss/components/_base-button.scss +113 -0
- package/scss/components/_blocks.scss +211 -0
- package/scss/components/_breadcrumbs.scss +31 -0
- package/scss/components/_checkbox.scss +42 -0
- package/scss/components/_chip.scss +23 -0
- package/scss/components/_confirm.scss +3 -0
- package/scss/components/_edit-modal.scss +11 -0
- package/scss/components/_font-upload.scss +91 -0
- package/scss/components/_form-field.scss +85 -0
- package/scss/components/_icon-button.scss +23 -0
- package/scss/components/_image-upload.scss +85 -0
- package/scss/components/_index.scss +24 -0
- package/scss/components/_locale-selector.scss +89 -0
- package/scss/components/_modal.scss +68 -0
- package/scss/components/_motor-badge.scss +21 -0
- package/scss/components/_numeric-input.scss +53 -0
- package/scss/components/_page-background.scss +22 -0
- package/scss/components/_palette-color-picker.scss +69 -0
- package/scss/components/_rich-text.scss +144 -0
- package/scss/components/_search-select.scss +138 -0
- package/scss/components/_tabs.scss +120 -0
- package/scss/components/_theme-selector.scss +34 -0
- package/scss/components/_toast-container.scss +16 -0
- package/scss/components/_toast.scss +25 -0
- package/scss/components/_translatable-input.scss +73 -0
- package/src/blocks/BlockCta.vue +32 -0
- package/src/blocks/BlockFaq.vue +25 -0
- package/src/blocks/BlockHeader.vue +13 -0
- package/src/blocks/BlockIndex.vue +20 -0
- package/src/blocks/BlockQuote.vue +16 -0
- package/src/blocks/BlockShell.vue +30 -0
- package/src/blocks/BlockText.vue +20 -0
- package/src/blocks/BlockTextCard.vue +23 -0
- package/src/blocks/PageBackground.vue +15 -0
- package/src/blocks/index.ts +25 -0
- package/src/components/AppBreadcrumbs.vue +44 -0
- package/src/components/BaseButton.vue +24 -0
- package/src/components/BaseCheckbox.vue +37 -0
- package/src/components/BaseInput.vue +53 -0
- package/src/components/BaseModal.vue +98 -0
- package/src/components/BaseSelect.vue +53 -0
- package/src/components/BaseTabs.vue +30 -0
- package/src/components/BaseTextarea.vue +45 -0
- package/src/components/BaseToast.vue +31 -0
- package/src/components/ConfirmDialog.vue +35 -0
- package/src/components/EditModal.vue +57 -0
- package/src/components/FontUpload.vue +123 -0
- package/src/components/IconButton.vue +24 -0
- package/src/components/ImageUpload.vue +142 -0
- package/src/components/LocaleSelector.vue +59 -0
- package/src/components/MotorBadge.vue +17 -0
- package/src/components/NumericInput.vue +115 -0
- package/src/components/PaletteColorPicker.vue +94 -0
- package/src/components/RichTextInput.vue +273 -0
- package/src/components/SearchSelect.vue +172 -0
- package/src/components/ThemeSelector.vue +28 -0
- package/src/components/ToastContainer.vue +23 -0
- package/src/components/TranslatableImage.vue +120 -0
- package/src/components/TranslatableInput.vue +135 -0
- package/src/composables/useConfirm.ts +49 -0
- package/src/composables/useHead.ts +54 -0
- package/src/composables/useTheme.ts +50 -0
- package/src/composables/useToast.ts +26 -0
- package/src/index.ts +39 -0
- package/src/lib/createApi.ts +42 -0
package/README.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# @edc-motor/ui
|
|
2
|
+
|
|
3
|
+
Componentes públicos de **EdC Motor** (Espadas de Ceniza Motor): la capa Vue 3
|
|
4
|
+
de la web pública de un juego de mesa construido sobre
|
|
5
|
+
[`edc-motor/core`](https://packagist.org/packages/edc-motor/core) — componentes
|
|
6
|
+
base (botones, formularios, modales, chips, migas…), tokens SCSS con temas
|
|
7
|
+
claro/oscuro, i18n, editor de texto rico (TipTap) y los composables del motor
|
|
8
|
+
(API, head/SEO, tema).
|
|
9
|
+
|
|
10
|
+
## Instalación
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @edc-motor/ui
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Es un **paquete fuente** (`main: src/index.ts`): lo compila la app consumidora
|
|
17
|
+
con Vite. El consumidor necesita:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install -D vite @vitejs/plugin-vue sass-embedded typescript vue-tsc
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
y en su `vite.config.ts`, los tokens SCSS del paquete en `loadPaths`:
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
css: {
|
|
27
|
+
preprocessorOptions: {
|
|
28
|
+
scss: {
|
|
29
|
+
additionalData: '@use "tokens" as *;\n',
|
|
30
|
+
loadPaths: ['node_modules/@edc-motor/ui/scss'],
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Versionado
|
|
37
|
+
|
|
38
|
+
Versión *de tren* con `edc-motor/core` y `@edc-motor/admin-kit`: los tres
|
|
39
|
+
paquetes comparten número y se etiquetan juntos en el monorepo
|
|
40
|
+
[`bildurre/boardgame_motor`](https://github.com/bildurre/boardgame_motor),
|
|
41
|
+
donde viven el código, las guías, los issues y los pull requests.
|
|
42
|
+
|
|
43
|
+
## Licencia
|
|
44
|
+
|
|
45
|
+
[GPL-3.0-only](LICENSE).
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@edc-motor/ui",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "EdC Motor — componentes públicos Vue 3 + tokens SCSS para webs de juegos de mesa (paquete fuente: lo compila el consumidor con Vite)",
|
|
5
|
+
"license": "GPL-3.0-only",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "src/index.ts",
|
|
8
|
+
"types": "src/index.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": "./src/index.ts",
|
|
11
|
+
"./scss/*": "./scss/*"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"src",
|
|
15
|
+
"scss",
|
|
16
|
+
"LICENSE",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/bildurre/boardgame_motor.git",
|
|
22
|
+
"directory": "packages/ui"
|
|
23
|
+
},
|
|
24
|
+
"homepage": "https://github.com/bildurre/boardgame_motor/tree/main/packages/ui#readme",
|
|
25
|
+
"bugs": "https://github.com/bildurre/boardgame_motor/issues",
|
|
26
|
+
"keywords": [
|
|
27
|
+
"vue",
|
|
28
|
+
"boardgame",
|
|
29
|
+
"scss",
|
|
30
|
+
"edc-motor"
|
|
31
|
+
],
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"axios": "^1.7.0",
|
|
37
|
+
"@tiptap/vue-3": "^2.11.0",
|
|
38
|
+
"@tiptap/starter-kit": "^2.11.0",
|
|
39
|
+
"@tiptap/extension-image": "^2.11.0",
|
|
40
|
+
"@tiptap/pm": "^2.11.0"
|
|
41
|
+
},
|
|
42
|
+
"peerDependencies": {
|
|
43
|
+
"vue": "^3.5.0",
|
|
44
|
+
"@lucide/vue": "^1.0.0",
|
|
45
|
+
"vue-router": "^5.0.0"
|
|
46
|
+
}
|
|
47
|
+
}
|
package/scss/_base.scss
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
@use "tokens" as *;
|
|
2
|
+
// =========================================================
|
|
3
|
+
// Reset + base
|
|
4
|
+
// =========================================================
|
|
5
|
+
|
|
6
|
+
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
7
|
+
|
|
8
|
+
html {
|
|
9
|
+
font-size: 100%;
|
|
10
|
+
overflow-x: hidden;
|
|
11
|
+
-webkit-font-smoothing: antialiased;
|
|
12
|
+
-moz-osx-font-smoothing: grayscale;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
body {
|
|
16
|
+
font-family: $k-font-sans;
|
|
17
|
+
font-size: $fs-14;
|
|
18
|
+
line-height: $k-lh-body;
|
|
19
|
+
color: $text-1;
|
|
20
|
+
background-color: $bg;
|
|
21
|
+
overflow-x: hidden;
|
|
22
|
+
max-width: 100vw;
|
|
23
|
+
min-height: 100vh;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
#app { min-height: 100vh; max-width: 100%; }
|
|
27
|
+
|
|
28
|
+
h1, h2, h3, h4 { font-weight: $k-fw-semibold; line-height: $k-lh-tight; }
|
|
29
|
+
h1 { font-size: $fs-28; }
|
|
30
|
+
h2 { font-size: $fs-24; }
|
|
31
|
+
h3 { font-size: $fs-20; }
|
|
32
|
+
|
|
33
|
+
a { color: $accent-500; text-decoration: none; &:hover { color: $accent-600; } }
|
package/scss/_forms.scss
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
@use "tokens" as *;
|
|
2
|
+
// =========================================================
|
|
3
|
+
// Inputs y formularios genéricos
|
|
4
|
+
// =========================================================
|
|
5
|
+
|
|
6
|
+
.form { display: flex; flex-direction: column; gap: $space-4; }
|
|
7
|
+
.form-actions { margin-top: $space-2; display: flex; gap: $space-3; }
|
|
8
|
+
|
|
9
|
+
.field { display: flex; flex-direction: column; gap: $space-1; }
|
|
10
|
+
.field__label, .field label { font-size: $fs-13; color: $text-2; }
|
|
11
|
+
|
|
12
|
+
input[type="text"],
|
|
13
|
+
input[type="email"],
|
|
14
|
+
input[type="password"],
|
|
15
|
+
input[type="search"],
|
|
16
|
+
input[type="number"],
|
|
17
|
+
select,
|
|
18
|
+
textarea {
|
|
19
|
+
font: inherit;
|
|
20
|
+
width: 100%;
|
|
21
|
+
padding: 10px 12px;
|
|
22
|
+
background: $surface;
|
|
23
|
+
border: 1px solid $border;
|
|
24
|
+
border-radius: $radius-md;
|
|
25
|
+
color: $text-1;
|
|
26
|
+
&:hover { border-color: $border-strong; }
|
|
27
|
+
&:focus { outline: none; border-color: $accent-500; }
|
|
28
|
+
}
|
|
29
|
+
textarea { resize: vertical; }
|
|
30
|
+
input[type="color"] { width: 44px; height: 36px; padding: 2px; cursor: pointer; }
|
|
31
|
+
|
|
32
|
+
.error { color: $danger; margin: 0; }
|
|
33
|
+
.ok { color: $success; margin: 0; }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@use "components";
|
package/scss/_theme.scss
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// =========================================================
|
|
2
|
+
// CSS Custom Properties (theming light/dark) — acento morado
|
|
3
|
+
// El <html> arranca en data-theme="dark" (identidad EdC).
|
|
4
|
+
// =========================================================
|
|
5
|
+
|
|
6
|
+
:root {
|
|
7
|
+
color-scheme: light;
|
|
8
|
+
|
|
9
|
+
--accent-100: #ece9fb;
|
|
10
|
+
--accent-200: #cdc7f7;
|
|
11
|
+
--accent-300: #a99ff2;
|
|
12
|
+
--accent-400: #8577ec;
|
|
13
|
+
--accent-500: #6c5ce7;
|
|
14
|
+
--accent-600: #5b4bd6;
|
|
15
|
+
--accent-700: #4c3cc4;
|
|
16
|
+
|
|
17
|
+
--info: #6c8cff;
|
|
18
|
+
--success: #4ade80;
|
|
19
|
+
--warning: #fbbf24;
|
|
20
|
+
--danger: #ff6b6b;
|
|
21
|
+
|
|
22
|
+
--bg: #fafafa;
|
|
23
|
+
--surface: #ffffff;
|
|
24
|
+
--surface-2: #f2f3f4;
|
|
25
|
+
--surface-3: #eaecf0;
|
|
26
|
+
--text-1: #101216;
|
|
27
|
+
--text-2: #636a77;
|
|
28
|
+
--text-3: #7b8290;
|
|
29
|
+
--border: #e2e3e7;
|
|
30
|
+
--border-strong: #cfd2d9;
|
|
31
|
+
|
|
32
|
+
--shadow-sm: 0 2px 6px rgba(0, 0, 0, 0.06);
|
|
33
|
+
--shadow-md: 0 6px 18px rgba(0, 0, 0, 0.08);
|
|
34
|
+
--shadow-lg: 0 14px 36px rgba(0, 0, 0, 0.12);
|
|
35
|
+
|
|
36
|
+
--toast-success-bg: #ecfdf5;
|
|
37
|
+
--toast-warning-bg: #fffbeb;
|
|
38
|
+
--toast-danger-bg: #fef2f2;
|
|
39
|
+
--toast-info-bg: #eff6ff;
|
|
40
|
+
|
|
41
|
+
// CRM público (patrón CDL): el fondo de color de un bloque es un TINTE
|
|
42
|
+
// semitransparente del color elegido, y la imagen de fondo de la página
|
|
43
|
+
// va atenuada — en claro admiten más presencia que en oscuro.
|
|
44
|
+
--block-tint: 20%;
|
|
45
|
+
--page-bg-opacity: 0.2;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
[data-theme="dark"] {
|
|
49
|
+
color-scheme: dark;
|
|
50
|
+
|
|
51
|
+
--accent-100: #1e1b2e;
|
|
52
|
+
|
|
53
|
+
--bg: #0f1115;
|
|
54
|
+
--surface: #1a1d24;
|
|
55
|
+
--surface-2: #20242d;
|
|
56
|
+
--surface-3: #2b2f3a;
|
|
57
|
+
--text-1: #e6e8ee;
|
|
58
|
+
--text-2: #9aa0ad;
|
|
59
|
+
--text-3: #7b8290;
|
|
60
|
+
--border: #2b2f3a;
|
|
61
|
+
--border-strong: #3a4150;
|
|
62
|
+
|
|
63
|
+
--shadow-sm: 0 2px 6px rgba(0, 0, 0, 0.30);
|
|
64
|
+
--shadow-md: 0 8px 24px rgba(0, 0, 0, 0.35);
|
|
65
|
+
--shadow-lg: 0 18px 48px rgba(0, 0, 0, 0.45);
|
|
66
|
+
|
|
67
|
+
--toast-success-bg: #0d2818;
|
|
68
|
+
--toast-warning-bg: #2a2008;
|
|
69
|
+
--toast-danger-bg: #2a0e0e;
|
|
70
|
+
--toast-info-bg: #0e1a2e;
|
|
71
|
+
|
|
72
|
+
--block-tint: 12%;
|
|
73
|
+
--page-bg-opacity: 0.1;
|
|
74
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// =========================================================
|
|
2
|
+
// EdC Tokens — adaptados de kontuan (acento morado)
|
|
3
|
+
// =========================================================
|
|
4
|
+
|
|
5
|
+
// Acento (CSS vars, ver _theme.scss) — un juego puede sobreescribirlas
|
|
6
|
+
$accent-100: var(--accent-100);
|
|
7
|
+
$accent-200: var(--accent-200);
|
|
8
|
+
$accent-300: var(--accent-300);
|
|
9
|
+
$accent-400: var(--accent-400);
|
|
10
|
+
$accent-500: var(--accent-500);
|
|
11
|
+
$accent-600: var(--accent-600);
|
|
12
|
+
$accent-700: var(--accent-700);
|
|
13
|
+
|
|
14
|
+
// Semánticos
|
|
15
|
+
$info: #6c8cff;
|
|
16
|
+
$success: #4ade80;
|
|
17
|
+
$warning: #fbbf24;
|
|
18
|
+
$danger: #ff6b6b;
|
|
19
|
+
|
|
20
|
+
// Neutros (CSS vars, themed)
|
|
21
|
+
$bg: var(--bg);
|
|
22
|
+
$surface: var(--surface);
|
|
23
|
+
$surface-2: var(--surface-2);
|
|
24
|
+
$surface-3: var(--surface-3);
|
|
25
|
+
$text-1: var(--text-1);
|
|
26
|
+
$text-2: var(--text-2);
|
|
27
|
+
$text-3: var(--text-3);
|
|
28
|
+
$border: var(--border);
|
|
29
|
+
$border-strong: var(--border-strong);
|
|
30
|
+
|
|
31
|
+
// Tipografía
|
|
32
|
+
$k-font-sans: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
33
|
+
$k-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
34
|
+
$k-fw-regular: 400;
|
|
35
|
+
$k-fw-medium: 500;
|
|
36
|
+
$k-fw-semibold: 600;
|
|
37
|
+
$k-fw-bold: 700;
|
|
38
|
+
$k-lh-tight: 1.15;
|
|
39
|
+
$k-lh-ui: 1.35;
|
|
40
|
+
$k-lh-body: 1.55;
|
|
41
|
+
$fs-11: 11px; $fs-12: 12px; $fs-13: 13px; $fs-14: 14px; $fs-16: 16px; $fs-18: 18px; $fs-20: 20px; $fs-24: 24px; $fs-28: 28px;
|
|
42
|
+
|
|
43
|
+
// Espaciado (px, como kontuan)
|
|
44
|
+
$space-0: 0;
|
|
45
|
+
$space-1: 4px;
|
|
46
|
+
$space-2: 8px;
|
|
47
|
+
$space-3: 12px;
|
|
48
|
+
$space-4: 16px;
|
|
49
|
+
$space-5: 20px;
|
|
50
|
+
$space-6: 24px;
|
|
51
|
+
$space-7: 28px;
|
|
52
|
+
$space-8: 32px;
|
|
53
|
+
|
|
54
|
+
// Radios
|
|
55
|
+
$radius-sm: 6px;
|
|
56
|
+
$radius-md: 10px;
|
|
57
|
+
$radius-lg: 14px;
|
|
58
|
+
$radius-xl: 18px;
|
|
59
|
+
$radius-pill: 999px;
|
|
60
|
+
|
|
61
|
+
// Estados UI (hover, etc.)
|
|
62
|
+
$ui-hover-bg: $surface-2;
|
|
63
|
+
$ui-hover-bg-strong: $surface-3;
|
|
64
|
+
|
|
65
|
+
// Tracking (letter-spacing)
|
|
66
|
+
$k-track-wide: 0.02em;
|
|
67
|
+
|
|
68
|
+
// Layout (igual que kontuan)
|
|
69
|
+
$layout-sidebar-width: 280px;
|
|
70
|
+
$layout-content-max: 1400px;
|
|
71
|
+
$layout-page-padding: 24px;
|
|
72
|
+
|
|
73
|
+
// Iconos (Lucide)
|
|
74
|
+
$icon-stroke: 1.75;
|
|
75
|
+
|
|
76
|
+
// Breakpoints (mobile-first, min-width)
|
|
77
|
+
$bp-xs: 360px;
|
|
78
|
+
$bp-sm: 480px;
|
|
79
|
+
$bp-md: 768px;
|
|
80
|
+
$bp-lg: 1024px;
|
|
81
|
+
$bp-xl: 1280px;
|
|
82
|
+
|
|
83
|
+
// ---------------------------------------------------------
|
|
84
|
+
// Alias de compatibilidad (nombres antiguos -> tokens kontuan)
|
|
85
|
+
// para no reescribir cada propiedad de los componentes ya hechos.
|
|
86
|
+
// ---------------------------------------------------------
|
|
87
|
+
$color-bg: $bg;
|
|
88
|
+
$color-surface: $surface;
|
|
89
|
+
$color-border: $border;
|
|
90
|
+
$color-text: $text-1;
|
|
91
|
+
$color-text-muted: $text-2;
|
|
92
|
+
$color-accent: $accent-500;
|
|
93
|
+
$color-accent-dark: $accent-600;
|
|
94
|
+
$font-sans: $k-font-sans;
|
|
95
|
+
|
|
96
|
+
// Sombras (CSS vars)
|
|
97
|
+
$shadow-sm: var(--shadow-sm);
|
|
98
|
+
$shadow-md: var(--shadow-md);
|
|
99
|
+
$shadow-lg: var(--shadow-lg);
|
|
100
|
+
|
|
101
|
+
// Formularios (elementos estilo kontuan)
|
|
102
|
+
$focus-ring: 0 0 0 3px color-mix(in srgb, #{$accent-500} 25%, transparent);
|
|
103
|
+
$disabled-opacity: 0.45;
|
|
104
|
+
$input-height: 40px;
|
|
105
|
+
$input-padding-x: 12px;
|
|
106
|
+
$input-padding-y: 10px;
|
|
107
|
+
$input-radius: $radius-md;
|
|
108
|
+
$input-bg: $surface-2;
|
|
109
|
+
$input-text: $text-1;
|
|
110
|
+
$input-placeholder: $text-3;
|
|
111
|
+
$input-border: $border;
|
|
112
|
+
$input-border-hover: $border-strong;
|
|
113
|
+
$input-border-focus: $accent-500;
|
|
114
|
+
$input-focus-ring: $focus-ring;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
@use "tokens" as *;
|
|
2
|
+
|
|
3
|
+
.edc-button {
|
|
4
|
+
display: inline-flex;
|
|
5
|
+
align-items: center;
|
|
6
|
+
justify-content: center;
|
|
7
|
+
gap: $space-2;
|
|
8
|
+
padding: $space-2 $space-4;
|
|
9
|
+
border: 1px solid transparent;
|
|
10
|
+
border-radius: $radius-md;
|
|
11
|
+
font: inherit;
|
|
12
|
+
font-weight: 600;
|
|
13
|
+
cursor: pointer;
|
|
14
|
+
transition: background-color 0.15s ease, border-color 0.15s ease;
|
|
15
|
+
|
|
16
|
+
&:disabled {
|
|
17
|
+
opacity: 0.55;
|
|
18
|
+
cursor: not-allowed;
|
|
19
|
+
pointer-events: none;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
&__icon {
|
|
23
|
+
display: inline-flex;
|
|
24
|
+
align-items: center;
|
|
25
|
+
flex-shrink: 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
&__text {
|
|
29
|
+
display: inline-flex;
|
|
30
|
+
align-items: center;
|
|
31
|
+
gap: $space-2;
|
|
32
|
+
line-height: 1.2;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Con slot de icono (patrón kontuan): fila por defecto en todas partes;
|
|
36
|
+
// SOLO cuando el contenedor `content` (el área de contenido) es estrecho,
|
|
37
|
+
// el texto pasa a mini-etiqueta bajo el icono.
|
|
38
|
+
&--has-icon:not(.edc-button--text):not(.edc-button--text-danger) {
|
|
39
|
+
@container content (max-width: #{$bp-sm - 1px}) {
|
|
40
|
+
flex-direction: column;
|
|
41
|
+
gap: 2px;
|
|
42
|
+
padding: $space-1 $space-2;
|
|
43
|
+
|
|
44
|
+
.edc-button__text {
|
|
45
|
+
font-size: 10px;
|
|
46
|
+
line-height: 1;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
&--primary {
|
|
52
|
+
background: $color-accent;
|
|
53
|
+
color: #fff;
|
|
54
|
+
|
|
55
|
+
// Hover bien visible: accent-600 apenas se distingue del 500.
|
|
56
|
+
&:hover:not(:disabled) {
|
|
57
|
+
background: color-mix(in srgb, $color-accent 72%, black);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
&--secondary {
|
|
62
|
+
background: transparent;
|
|
63
|
+
border-color: $color-border;
|
|
64
|
+
color: $color-text;
|
|
65
|
+
|
|
66
|
+
&:hover:not(:disabled) {
|
|
67
|
+
background: color-mix(in srgb, $color-accent 14%, transparent);
|
|
68
|
+
border-color: $color-accent;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Botón tipo TEXTO (kontuan): sin fondo, sin borde ni padding; solo color.
|
|
74
|
+
.edc-button--text {
|
|
75
|
+
background: transparent;
|
|
76
|
+
border-color: transparent;
|
|
77
|
+
padding: 0;
|
|
78
|
+
color: $accent-500;
|
|
79
|
+
|
|
80
|
+
&:hover:not(:disabled) { color: $accent-700; background: transparent; }
|
|
81
|
+
}
|
|
82
|
+
.edc-button--text-danger {
|
|
83
|
+
background: transparent;
|
|
84
|
+
border-color: transparent;
|
|
85
|
+
padding: 0;
|
|
86
|
+
color: $danger;
|
|
87
|
+
|
|
88
|
+
&:hover:not(:disabled) {
|
|
89
|
+
color: color-mix(in srgb, $danger 80%, black);
|
|
90
|
+
background: transparent;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.edc-button--danger {
|
|
95
|
+
background: $danger;
|
|
96
|
+
color: #fff;
|
|
97
|
+
&:hover:not(:disabled) { background: color-mix(in srgb, $danger 72%, black); }
|
|
98
|
+
}
|
|
99
|
+
.edc-button--success {
|
|
100
|
+
background: $success;
|
|
101
|
+
color: #06281a;
|
|
102
|
+
&:hover:not(:disabled) { background: color-mix(in srgb, $success 72%, black); }
|
|
103
|
+
}
|
|
104
|
+
.edc-button--info {
|
|
105
|
+
background: $info;
|
|
106
|
+
color: #fff;
|
|
107
|
+
&:hover:not(:disabled) { background: color-mix(in srgb, $info 72%, black); }
|
|
108
|
+
}
|
|
109
|
+
.edc-button--warning {
|
|
110
|
+
background: $warning;
|
|
111
|
+
color: #2b2005;
|
|
112
|
+
&:hover:not(:disabled) { background: color-mix(in srgb, $warning 72%, black); }
|
|
113
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
@use "tokens" as *;
|
|
2
|
+
|
|
3
|
+
// Bloques públicos del CRM (doc 03): estilos base, cada juego los ajusta.
|
|
4
|
+
.block {
|
|
5
|
+
// Aire vertical entre bloques (CDL usa 4rem; aquí algo más contenido).
|
|
6
|
+
padding-block: $space-8 + $space-6; // 56px
|
|
7
|
+
background: var(--block-bg, transparent);
|
|
8
|
+
|
|
9
|
+
&__inner {
|
|
10
|
+
max-width: 960px; // 'wide' (por defecto)
|
|
11
|
+
margin: 0 auto;
|
|
12
|
+
padding: 0 $space-4;
|
|
13
|
+
display: grid;
|
|
14
|
+
gap: $space-5; // separación entre los elementos del bloque
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Anchura del contenido (campo común `width`): coherente entre bloques.
|
|
18
|
+
&--w-narrow .block__inner { max-width: 680px; }
|
|
19
|
+
&--w-full .block__inner { max-width: none; padding-inline: $space-6; }
|
|
20
|
+
|
|
21
|
+
&__title { margin: 0; }
|
|
22
|
+
&__subtitle { margin: 0; color: $text-2; font-size: $fs-18; }
|
|
23
|
+
&__text { color: $text-1; }
|
|
24
|
+
|
|
25
|
+
&__label {
|
|
26
|
+
display: inline-block;
|
|
27
|
+
justify-self: start;
|
|
28
|
+
font-size: $fs-12;
|
|
29
|
+
font-weight: $k-fw-semibold;
|
|
30
|
+
text-transform: uppercase;
|
|
31
|
+
letter-spacing: 0.05em;
|
|
32
|
+
color: $accent-500;
|
|
33
|
+
border: 1px solid color-mix(in srgb, $accent-500 45%, transparent);
|
|
34
|
+
border-radius: $radius-pill;
|
|
35
|
+
padding: 2px $space-3;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
&__card {
|
|
39
|
+
// Semitransparente: la imagen de fondo de la página se ve a través
|
|
40
|
+
// (patrón CDL, rgba(surface, .5)); el blur mantiene el texto legible.
|
|
41
|
+
background: color-mix(in srgb, $surface 65%, transparent);
|
|
42
|
+
backdrop-filter: blur(8px);
|
|
43
|
+
border: 1px solid $border;
|
|
44
|
+
border-radius: $radius-lg;
|
|
45
|
+
box-shadow: $shadow-sm;
|
|
46
|
+
padding: $space-8;
|
|
47
|
+
display: grid;
|
|
48
|
+
gap: $space-4;
|
|
49
|
+
|
|
50
|
+
.edc-button { justify-self: start; text-decoration: none; }
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
&--header .block__title { font-size: $fs-28; }
|
|
54
|
+
|
|
55
|
+
&__media-layout { display: grid; gap: $space-4; }
|
|
56
|
+
&__image {
|
|
57
|
+
max-width: 100%;
|
|
58
|
+
border-radius: $radius-md;
|
|
59
|
+
justify-self: center;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
&--image-left .block__media-layout,
|
|
63
|
+
&--image-right .block__media-layout {
|
|
64
|
+
@container content (min-width: #{$bp-sm}) {
|
|
65
|
+
grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
|
|
66
|
+
align-items: start;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
&--image-right .block__media-layout .block__image { order: 2; }
|
|
70
|
+
&--image-bottom .block__media-layout .block__image { order: 2; }
|
|
71
|
+
|
|
72
|
+
// Imagen flotada: el texto la rodea y sigue por debajo (cleartext, como
|
|
73
|
+
// CDL). En estrecho la imagen va arriba a lo ancho, sin flotar.
|
|
74
|
+
&--image-clear-left .block__media-layout,
|
|
75
|
+
&--image-clear-right .block__media-layout {
|
|
76
|
+
display: block;
|
|
77
|
+
|
|
78
|
+
// Clearfix: el bloque no se corta si la imagen es más alta que el texto.
|
|
79
|
+
&::after { content: ""; display: table; clear: both; }
|
|
80
|
+
|
|
81
|
+
.block__image { margin-bottom: $space-3; }
|
|
82
|
+
}
|
|
83
|
+
&--image-clear-left .block__media-layout .block__image {
|
|
84
|
+
@container content (min-width: #{$bp-sm}) {
|
|
85
|
+
float: left;
|
|
86
|
+
max-width: 50%;
|
|
87
|
+
margin-right: $space-4;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
&--image-clear-right .block__media-layout .block__image {
|
|
91
|
+
@container content (min-width: #{$bp-sm}) {
|
|
92
|
+
float: right;
|
|
93
|
+
max-width: 50%;
|
|
94
|
+
margin-left: $space-4;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Banner de la cabecera (a lo ancho del bloque).
|
|
99
|
+
&__banner {
|
|
100
|
+
width: 100%;
|
|
101
|
+
border-radius: $radius-md;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Retrato del autor de la cita.
|
|
105
|
+
&__avatar {
|
|
106
|
+
width: 64px;
|
|
107
|
+
height: 64px;
|
|
108
|
+
border-radius: 50%;
|
|
109
|
+
object-fit: cover;
|
|
110
|
+
margin-bottom: $space-2;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Cuerpo del CTA (texto + botón) dentro de su media-layout.
|
|
114
|
+
&__cta-body {
|
|
115
|
+
display: grid;
|
|
116
|
+
gap: $space-3;
|
|
117
|
+
justify-items: start;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
&--quote .block__quote {
|
|
121
|
+
margin: 0;
|
|
122
|
+
border-left: 3px solid $accent-500;
|
|
123
|
+
padding-left: $space-4;
|
|
124
|
+
// Fuente "especial" de la configuración de la web (doc 10); las fuentes
|
|
125
|
+
// decorativas piden un cuerpo mayor.
|
|
126
|
+
font-family: var(--font-special, inherit);
|
|
127
|
+
font-size: $fs-24;
|
|
128
|
+
font-style: italic;
|
|
129
|
+
}
|
|
130
|
+
&__author {
|
|
131
|
+
margin-top: $space-2;
|
|
132
|
+
color: $text-3;
|
|
133
|
+
// El autor no hereda la fuente especial de la cita.
|
|
134
|
+
font-family: var(--font-body, inherit);
|
|
135
|
+
font-style: normal;
|
|
136
|
+
font-size: $fs-14;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.block__index {
|
|
141
|
+
margin: 0;
|
|
142
|
+
padding-left: 1.2em;
|
|
143
|
+
display: grid;
|
|
144
|
+
gap: $space-1;
|
|
145
|
+
|
|
146
|
+
a { color: $accent-500; text-decoration: none; }
|
|
147
|
+
a:hover { text-decoration: underline; }
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// FAQ (doc 03): acordeón nativo details/summary del bloque `faq`.
|
|
151
|
+
.block__faq-item {
|
|
152
|
+
border: 1px solid $border;
|
|
153
|
+
border-radius: $radius-md;
|
|
154
|
+
background: color-mix(in srgb, $surface 65%, transparent);
|
|
155
|
+
|
|
156
|
+
& + & { margin-top: $space-2; }
|
|
157
|
+
|
|
158
|
+
&[open] .block__faq-question { color: $accent-500; }
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.block__faq-question {
|
|
162
|
+
padding: $space-3 $space-4;
|
|
163
|
+
font-weight: 600;
|
|
164
|
+
cursor: pointer;
|
|
165
|
+
|
|
166
|
+
&:hover { color: $accent-500; }
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.block__faq-answer {
|
|
170
|
+
padding: 0 $space-4 $space-3;
|
|
171
|
+
color: $text-2;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
// Botón de los bloques (CTA, doc 03): dos tipos con hover CRUZADO.
|
|
176
|
+
// Normal: fondo de acento + texto del color del texto; al pasar, fondo del
|
|
177
|
+
// color de fondo + texto de acento. Inverso: exactamente al revés.
|
|
178
|
+
.block-button {
|
|
179
|
+
display: inline-flex;
|
|
180
|
+
align-items: center;
|
|
181
|
+
gap: $space-2;
|
|
182
|
+
padding: $space-2 $space-5;
|
|
183
|
+
border: 1px solid $accent-500;
|
|
184
|
+
border-radius: $radius-md;
|
|
185
|
+
font-weight: 600;
|
|
186
|
+
text-decoration: none;
|
|
187
|
+
cursor: pointer;
|
|
188
|
+
transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
|
|
189
|
+
|
|
190
|
+
// El "fondo" de los estados cruzados es la SUPERFICIE ($surface, el
|
|
191
|
+
// segundo tono), no el fondo de página puro: menos negro / menos blanco.
|
|
192
|
+
&--primary {
|
|
193
|
+
background: $accent-500;
|
|
194
|
+
color: $text-1;
|
|
195
|
+
|
|
196
|
+
&:hover {
|
|
197
|
+
background: $surface;
|
|
198
|
+
color: $accent-500;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
&--secondary {
|
|
203
|
+
background: $surface;
|
|
204
|
+
color: $accent-500;
|
|
205
|
+
|
|
206
|
+
&:hover {
|
|
207
|
+
background: $accent-500;
|
|
208
|
+
color: $text-1;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
@use "tokens" as *;
|
|
2
|
+
|
|
3
|
+
.breadcrumbs {
|
|
4
|
+
display: flex;
|
|
5
|
+
align-items: center;
|
|
6
|
+
flex-wrap: wrap;
|
|
7
|
+
column-gap: 2px;
|
|
8
|
+
font-size: $fs-12;
|
|
9
|
+
color: $text-3;
|
|
10
|
+
margin-bottom: $space-8; // aire doble entre la miga y el contenido
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.breadcrumb-link {
|
|
14
|
+
color: $text-3;
|
|
15
|
+
text-decoration: none;
|
|
16
|
+
transition: color 0.15s ease;
|
|
17
|
+
|
|
18
|
+
&:hover {
|
|
19
|
+
color: $text-1;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.breadcrumb-current {
|
|
24
|
+
color: $text-1;
|
|
25
|
+
font-weight: $k-fw-medium;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.breadcrumb-separator {
|
|
29
|
+
color: $text-3;
|
|
30
|
+
flex-shrink: 0;
|
|
31
|
+
}
|