create-openclass-uniminuto 1.4.2 → 1.6.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.
Files changed (26) hide show
  1. package/bin/create-openclass-uniminuto.mjs +81 -1
  2. package/package.json +2 -2
  3. package/template/README.md +326 -326
  4. package/template/package-lock.json +11568 -11568
  5. package/template/package.json +63 -61
  6. package/template/public/imagenes/avion.png +0 -0
  7. package/template/public/imagenes/favicon.png +0 -0
  8. package/template/scripts/generar-desde-config.mjs +348 -511
  9. package/template/theme/uniminuto/components/AutoFitText.vue +7 -2
  10. package/template/theme/uniminuto/components/TitleRibbon.vue +222 -0
  11. package/template/theme/uniminuto/layouts/README.md +99 -0
  12. package/template/theme/uniminuto/layouts/slide-02-titulo.vue +29 -47
  13. package/template/theme/uniminuto/layouts/slide-03-imagen-izquierda.vue +43 -69
  14. package/template/theme/uniminuto/layouts/slide-04-imagen-derecha.vue +49 -75
  15. package/template/theme/uniminuto/layouts/slide-05-titulo-superior-texto-derecha.vue +34 -66
  16. package/template/theme/uniminuto/layouts/slide-06-titulo-superior-texto-izquierda.vue +28 -78
  17. package/template/theme/uniminuto/layouts/slide-07-multimedia-con-titulo.vue +10 -66
  18. package/template/theme/uniminuto/layouts/slide-08-titulo-texto.vue +24 -53
  19. package/template/theme/uniminuto/layouts/slide-09-objetivos.vue +26 -53
  20. package/template/theme/uniminuto/layouts/slide-10-titulo-dos-columnas.vue +27 -59
  21. package/template/theme/uniminuto/layouts/slide-11-dos-titulos-dos-columnas.vue +32 -65
  22. package/template/theme/uniminuto/layouts/slide-codigo.vue +16 -113
  23. package/template/theme/uniminuto/styles/base.css +214 -109
  24. package/template/public/fondos/slide-02-titulo.png +0 -0
  25. package/template/public/fondos/slide-03-imagen-izquierda.png +0 -0
  26. package/template/public/fondos/slide-04-imagen-derecha.png +0 -0
@@ -9,9 +9,9 @@
9
9
  lineHeight: lineHeight
10
10
  }"
11
11
  >
12
- <span ref="contentEl" class="auto-fit-text__content">
12
+ <div ref="contentEl" class="auto-fit-text__content">
13
13
  <slot />
14
- </span>
14
+ </div>
15
15
  </component>
16
16
  </template>
17
17
 
@@ -150,6 +150,11 @@ watch(
150
150
  line-height: inherit;
151
151
  letter-spacing: inherit;
152
152
  text-align: inherit;
153
+ box-sizing: border-box;
154
+ }
155
+
156
+ .auto-fit-text__content :deep(*) {
157
+ box-sizing: border-box;
153
158
  }
154
159
 
155
160
  .auto-fit-text--debug {
@@ -0,0 +1,222 @@
1
+ <template>
2
+ <div
3
+ class="title-ribbon"
4
+ :class="[
5
+ `title-ribbon--${side}`,
6
+ {
7
+ 'title-ribbon--with-plane': resolvedShowPlane,
8
+ 'title-ribbon--shadow': shadow,
9
+ },
10
+ ]"
11
+ :style="cssVars"
12
+ >
13
+ <img
14
+ v-if="resolvedShowPlane"
15
+ class="title-ribbon__plane"
16
+ :src="planeSrc"
17
+ alt=""
18
+ aria-hidden="true"
19
+ />
20
+
21
+ <div class="title-ribbon__bar">
22
+ <div class="title-ribbon__text">
23
+ <slot />
24
+ </div>
25
+ </div>
26
+ </div>
27
+ </template>
28
+
29
+ <script setup>
30
+ import { computed } from "vue";
31
+
32
+ const props = defineProps({
33
+ side: {
34
+ type: String,
35
+ default: "center",
36
+ },
37
+
38
+ showPlane: {
39
+ type: Boolean,
40
+ default: false,
41
+ },
42
+
43
+ withPlane: {
44
+ type: Boolean,
45
+ default: false,
46
+ },
47
+
48
+ planeSrc: {
49
+ type: String,
50
+ default: "/imagenes/avion.png",
51
+ },
52
+
53
+ width: {
54
+ type: String,
55
+ default: "100%",
56
+ },
57
+
58
+ minHeight: {
59
+ type: String,
60
+ default: "2.95rem",
61
+ },
62
+
63
+ paddingX: {
64
+ type: String,
65
+ default: "2rem",
66
+ },
67
+
68
+ paddingY: {
69
+ type: String,
70
+ default: "0.26rem",
71
+ },
72
+
73
+ fontSize: {
74
+ type: String,
75
+ default: "clamp(1.18rem, 1.72vw, 1.92rem)",
76
+ },
77
+
78
+ planeSize: {
79
+ type: String,
80
+ default: "7.4rem",
81
+ },
82
+
83
+ planeOffsetX: {
84
+ type: String,
85
+ default: "-42%",
86
+ },
87
+
88
+ planeOffsetY: {
89
+ type: String,
90
+ default: "0%",
91
+ },
92
+
93
+ ribbonColor: {
94
+ type: String,
95
+ default: "#243764",
96
+ },
97
+
98
+ textColor: {
99
+ type: String,
100
+ default: "#ffffff",
101
+ },
102
+
103
+ shadow: {
104
+ type: Boolean,
105
+ default: true,
106
+ },
107
+ });
108
+
109
+ const resolvedShowPlane = computed(() => props.showPlane || props.withPlane);
110
+
111
+ const cssVars = computed(() => ({
112
+ "--title-ribbon-width": props.width,
113
+ "--title-ribbon-min-height": props.minHeight,
114
+ "--title-ribbon-padding-x": props.paddingX,
115
+ "--title-ribbon-padding-y": props.paddingY,
116
+ "--title-ribbon-font-size": props.fontSize,
117
+ "--title-ribbon-color": props.ribbonColor,
118
+ "--title-ribbon-text-color": props.textColor,
119
+ "--title-ribbon-plane-size": props.planeSize,
120
+ "--title-ribbon-plane-offset-x": props.planeOffsetX,
121
+ "--title-ribbon-plane-offset-y": props.planeOffsetY,
122
+ }));
123
+ </script>
124
+
125
+ <style scoped>
126
+ .title-ribbon {
127
+ position: relative;
128
+ width: var(--title-ribbon-width);
129
+ min-height: var(--title-ribbon-min-height);
130
+ display: flex;
131
+ align-items: center;
132
+ justify-content: center;
133
+ overflow: visible;
134
+ z-index: 5;
135
+
136
+ /* ajuste fino */
137
+ margin-top: -0.18rem;
138
+ margin-bottom: 0.55rem;
139
+ }
140
+
141
+ .title-ribbon--left {
142
+ justify-content: flex-start;
143
+ }
144
+
145
+ .title-ribbon--center {
146
+ justify-content: center;
147
+ }
148
+
149
+ .title-ribbon--right {
150
+ justify-content: flex-end;
151
+ }
152
+
153
+ .title-ribbon__bar {
154
+ position: relative;
155
+ width: 100%;
156
+ min-height: var(--title-ribbon-min-height);
157
+ display: flex;
158
+ align-items: center;
159
+ justify-content: center;
160
+ padding: var(--title-ribbon-padding-y) var(--title-ribbon-padding-x);
161
+ background: var(--title-ribbon-color);
162
+ color: var(--title-ribbon-text-color);
163
+ box-sizing: border-box;
164
+ overflow: visible;
165
+ }
166
+
167
+ .title-ribbon--shadow .title-ribbon__bar {
168
+ box-shadow: 0 0.55rem 1rem rgba(16, 30, 64, 0.09);
169
+ }
170
+
171
+ .title-ribbon__text {
172
+ width: 100%;
173
+ max-width: none;
174
+ display: block;
175
+ color: var(--title-ribbon-text-color);
176
+ font-family: "Merriweather Sans", "Arial", sans-serif;
177
+ font-size: var(--title-ribbon-font-size);
178
+ font-weight: 900;
179
+ line-height: 1.08;
180
+ letter-spacing: -0.018em;
181
+ text-align: center;
182
+ text-wrap: balance;
183
+ overflow-wrap: normal;
184
+ word-break: normal;
185
+ hyphens: none;
186
+ text-shadow: 0 0.055em 0 rgba(0, 0, 0, 0.12);
187
+ }
188
+
189
+ .title-ribbon__text :deep(*) {
190
+ margin: 0;
191
+ color: inherit;
192
+ font: inherit;
193
+ line-height: inherit;
194
+ letter-spacing: inherit;
195
+ text-align: inherit;
196
+ }
197
+
198
+ .title-ribbon__plane {
199
+ position: absolute;
200
+ left: 0;
201
+ top: 50%;
202
+ width: var(--title-ribbon-plane-size);
203
+ height: auto;
204
+ transform:
205
+ translateX(var(--title-ribbon-plane-offset-x))
206
+ translateY(calc(-50% + var(--title-ribbon-plane-offset-y)));
207
+ z-index: 3;
208
+ pointer-events: none;
209
+ user-select: none;
210
+ filter: drop-shadow(0 0.55rem 0.75rem rgba(0, 0, 0, 0.14));
211
+ }
212
+
213
+ @media print {
214
+ .title-ribbon--shadow .title-ribbon__bar {
215
+ box-shadow: none;
216
+ }
217
+
218
+ .title-ribbon__plane {
219
+ filter: none;
220
+ }
221
+ }
222
+ </style>
@@ -0,0 +1,99 @@
1
+ # Layouts Open Class UNIMINUTO
2
+
3
+ ## Principio de diseño
4
+
5
+ Los fondos institucionales se usan como base limpia. Los títulos, franjas azules, avión y cajas de contenido se construyen por código para que puedan crecer y adaptarse al contenido.
6
+
7
+ ## Recursos obligatorios
8
+
9
+ ```text
10
+ public/fondos/slide-01-portada.png
11
+ public/fondos/slide-05-template.png
12
+ public/fondos/slide-06-cierre.png
13
+ public/imagenes/avion.png
14
+ public/imagenes/favicon.png
15
+ public/favicon.png
16
+ ```
17
+
18
+ `public/favicon.png` es el favicon del navegador.
19
+ `public/imagenes/favicon.png` es una imagen institucional que puedes usar dentro de las diapositivas.
20
+
21
+ ## slide-02-titulo
22
+
23
+ Uso recomendado:
24
+
25
+ ```md
26
+ ---
27
+ layout: slide-02-titulo
28
+ ---
29
+
30
+ ::title::
31
+ Extracción de características estadísticas y frecuenciales
32
+ ```
33
+
34
+ Este layout usa franja azul dinámica y avión pequeño. El título aprovecha todo el ancho de la franja con padding lateral.
35
+
36
+ ## Layouts con imagen y texto
37
+
38
+ ```md
39
+ ---
40
+ layout: slide-03-imagen-izquierda
41
+ ---
42
+
43
+ ::title::
44
+ ¿Qué puede “ver” una máquina?
45
+
46
+ ::image::
47
+ <img src="/imagenes/favicon.png" alt="Imagen de apoyo" />
48
+
49
+ ::content::
50
+ Texto de la diapositiva.
51
+ ```
52
+
53
+ En `slide-03-imagen-izquierda` y `slide-04-imagen-derecha`, la imagen se ajusta con `object-fit: contain`, por lo que funciona bien con imágenes 3:4.
54
+
55
+ ## Listas
56
+
57
+ Listas no ordenadas:
58
+
59
+ ```md
60
+ - Primer punto
61
+ - Segundo punto
62
+ - Tercer punto
63
+ ```
64
+
65
+ Listas numeradas:
66
+
67
+ ```md
68
+ 1. Primer paso
69
+ 2. Segundo paso
70
+ 3. Tercer paso
71
+ ```
72
+
73
+ Listas por letras:
74
+
75
+ ```html
76
+ <ol type="a">
77
+ <li>Primera opción</li>
78
+ <li>Segunda opción</li>
79
+ </ol>
80
+ ```
81
+
82
+ Listas romanas:
83
+
84
+ ```html
85
+ <ol type="i">
86
+ <li>Primer criterio</li>
87
+ <li>Segundo criterio</li>
88
+ </ol>
89
+ ```
90
+
91
+ ## Actualizar tema en cursos existentes
92
+
93
+ Cuando exista una nueva versión publicada del generador:
94
+
95
+ ```bash
96
+ npm create openclass-uniminuto@latest . -- --update-theme
97
+ ```
98
+
99
+ Esto actualiza layouts, componentes, estilos y recursos visuales sin tocar el contenido académico en `semanas/`.
@@ -1,63 +1,45 @@
1
1
  <script setup>
2
- import AutoFitText from '../components/AutoFitText.vue'
2
+ import TitleRibbon from '../components/TitleRibbon.vue'
3
3
  </script>
4
4
 
5
5
  <template>
6
- <div class="slide-02-layout">
7
- <img
8
- class="slide-bg"
9
- src="/fondos/slide-02-titulo.png"
10
- alt="Fondo diapositiva título"
11
- />
12
-
13
- <div class="titulo-wrap">
14
- <AutoFitText
15
- tag="h1"
16
- class="titulo"
17
- :min="20"
18
- :max="42"
19
- line-height="1.05"
20
- >
21
- <slot name="title">Título de la presentación</slot>
22
- </AutoFitText>
23
- </div>
24
- </div>
6
+ <section class="slide-02-title">
7
+ <TitleRibbon
8
+ class="slide-02-title__ribbon"
9
+ align="center"
10
+ :show-plane="true"
11
+ width="76%"
12
+ min-height="clamp(72px, 9vh, 104px)"
13
+ padding-x="clamp(2.2rem, 4.2vw, 5.2rem)"
14
+ padding-y="0.6rem"
15
+ plane-size="clamp(14rem, 9vw, 11rem)"
16
+ plane-offset-x="-7rem"
17
+ plane-offset-y="-8%"
18
+ :min="30"
19
+ :max="42"
20
+ line-height="1.25"
21
+ >
22
+ <slot name="title">Título de la sesión</slot>
23
+ </TitleRibbon>
24
+ </section>
25
25
  </template>
26
26
 
27
27
  <style scoped>
28
- .slide-02-layout {
28
+ .slide-02-title {
29
29
  position: relative;
30
30
  width: 100%;
31
31
  height: 100%;
32
32
  overflow: hidden;
33
- background: #ffffff;
34
- }
35
-
36
- .slide-bg {
37
- position: absolute;
38
- inset: 0;
39
- width: 100%;
40
- height: 100%;
41
- object-fit: cover;
33
+ background-image: url('/fondos/slide-05-template.png');
34
+ background-size: cover;
35
+ background-position: center;
36
+ background-repeat: no-repeat;
42
37
  }
43
38
 
44
- .titulo-wrap {
39
+ .slide-02-title__ribbon {
45
40
  position: absolute;
46
- z-index: 2;
47
- left: 33%;
48
- top: 52%;
49
- width: 43%;
50
- height: 7%;
51
- display: flex;
52
- align-items: center;
53
- justify-content: center;
54
- text-align: center;
55
- }
56
-
57
- .titulo {
58
- margin: 0 !important;
59
- color: #ffffff !important;
60
- font-family: var(--font-title, 'Merriweather Sans', Arial, sans-serif);
61
- font-weight: 800;
41
+ left: 51%;
42
+ top: 50.5%;
43
+ transform: translate(-50%, -50%);
62
44
  }
63
45
  </style>
@@ -1,27 +1,24 @@
1
1
  <script setup>
2
2
  import AutoFitText from '../components/AutoFitText.vue'
3
+ import TitleRibbon from '../components/TitleRibbon.vue'
3
4
  </script>
4
5
 
5
6
  <template>
6
7
  <div class="slide-layout">
7
- <img
8
- class="slide-bg"
9
- src="/fondos/slide-03-imagen-izquierda.png"
10
- alt="Fondo diapositiva imagen izquierda"
11
- />
8
+ <img class="slide-bg" src="/fondos/slide-05-template.png" alt="Fondo institucional" />
12
9
 
13
- <div class="image-wrap">
10
+ <div class="image-wrap uni-image-slot">
14
11
  <slot name="image" />
15
12
  </div>
16
13
 
17
14
  <div class="title-wrap">
18
- <AutoFitText tag="h1" class="title" :min="18" :max="34" line-height="1.05">
15
+ <TitleRibbon align="center" :show-plane="false" :min="25" :max="38" line-height="1.2">
19
16
  <slot name="title">Agrega un título</slot>
20
- </AutoFitText>
17
+ </TitleRibbon>
21
18
  </div>
22
19
 
23
20
  <div class="content-wrap">
24
- <AutoFitText tag="div" class="content-fit" :min="15" :max="28" line-height="1.25">
21
+ <AutoFitText tag="div" class="content-fit" :min="15" :max="30" line-height="1.26">
25
22
  <slot name="content" />
26
23
  </AutoFitText>
27
24
  </div>
@@ -29,82 +26,59 @@ import AutoFitText from '../components/AutoFitText.vue'
29
26
  </template>
30
27
 
31
28
  <style scoped>
32
- .slide-layout {
33
- position: relative;
34
- width: 100%;
35
- height: 100%;
36
- overflow: hidden;
37
- background: #ffffff;
38
- }
39
-
40
- .slide-bg {
41
- position: absolute;
42
- inset: 0;
43
- width: 100%;
44
- height: 100%;
45
- object-fit: cover;
46
- z-index: 1;
47
- }
29
+ .slide-layout { position: relative; width: 100%; height: 100%; overflow: hidden; background: #ffffff; }
30
+ .slide-bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 1; }
48
31
 
49
32
  .image-wrap {
50
33
  position: absolute;
51
34
  z-index: 2;
52
- left: 5.5%;
53
- top: 15%;
54
- width: 39%;
55
- height: 78%;
56
- display: flex;
57
- align-items: center;
58
- justify-content: center;
59
- overflow: hidden;
60
- }
61
-
62
- .image-wrap :deep(img),
63
- .image-wrap :deep(video),
64
- .image-wrap :deep(iframe) {
65
- width: 100%;
66
- height: 100%;
67
- object-fit: cover;
68
- border: 0;
69
- display: block;
35
+ left: 8%;
36
+ top: 16.3%;
37
+ width: 39.2%;
38
+ height: 75%;
70
39
  }
71
40
 
72
41
  .title-wrap {
73
42
  position: absolute;
74
- z-index: 2;
75
- left: 49.5%;
76
- top: 19.5%;
77
- width: 48%;
78
- height: 6.8%;
79
- display: flex;
80
- align-items: center;
81
- justify-content: center;
82
- text-align: center;
83
- padding: 0 1rem;
84
- box-sizing: border-box;
85
- }
86
-
87
- .title {
88
- margin: 0 !important;
89
- color: #ffffff !important;
90
- font-family: var(--font-title, 'Merriweather Sans', Arial, sans-serif);
91
- font-weight: 800;
43
+ z-index: 3;
44
+ left: 45.8%;
45
+ top: 16.0%;
46
+ width: 54.2%;
47
+ min-height: 9.2%;
48
+ --ribbon-min-height: clamp(60px, 7.8vh, 92px);
49
+ --ribbon-padding-x: 2.2rem;
92
50
  }
93
51
 
94
52
  .content-wrap {
95
53
  position: absolute;
96
54
  z-index: 2;
97
- left: 50.5%;
98
- top: 30%;
99
- width: 39%;
100
- height: 48%;
55
+ left: 49.3%;
56
+ top: 31.0%;
57
+ width: 43.8%;
58
+ height: 55.2%;
101
59
  color: #233763 !important;
102
60
  font-family: var(--font-body, 'Atkinson Hyperlegible', Arial, sans-serif);
103
61
  }
104
62
 
63
+ .image-wrap :deep(p) { margin: 0; width: 100%; height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.55rem; }
64
+ .image-wrap :deep(img), .image-wrap :deep(video), .image-wrap :deep(iframe) { display: block; width: auto; height: auto; max-width: 100%; max-height: 100%; object-fit: contain; object-position: center; border: 0; }
65
+
105
66
  .content-fit :deep(*) { color: #233763 !important; }
106
- .content-fit :deep(p) { margin: 0 0 0.7rem 0; }
107
- .content-fit :deep(ul) { list-style-type: disc !important; list-style-position: outside !important; margin: 0; padding-left: 1.6rem; }
108
- .content-fit :deep(li) { display: list-item !important; margin-bottom: 0.5rem; }
109
- .content-fit :deep(li::marker) { color: #233763 !important; font-size: 1em; }
67
+ .content-fit :deep(p) { margin: 0 0 0.75rem 0; }
68
+ .content-fit :deep(strong) { font-weight: 900; }
69
+ .content-fit :deep(ul),
70
+ .content-fit :deep(ol) {
71
+ list-style-position: outside !important;
72
+ margin: 0 0 0.75rem 0;
73
+ padding-left: 1.65rem;
74
+ }
75
+ .content-fit :deep(ul) { list-style-type: disc !important; }
76
+ .content-fit :deep(ol) { list-style-type: decimal !important; }
77
+ .content-fit :deep(ol[type='a']) { list-style-type: lower-alpha !important; }
78
+ .content-fit :deep(ol[type='A']) { list-style-type: upper-alpha !important; }
79
+ .content-fit :deep(ol[type='i']) { list-style-type: lower-roman !important; }
80
+ .content-fit :deep(ol[type='I']) { list-style-type: upper-roman !important; }
81
+ .content-fit :deep(li) { display: list-item !important; margin-bottom: 0.46rem; padding-left: 0.15rem; }
82
+ .content-fit :deep(li::marker) { color: #233763 !important; font-weight: 900; }
83
+ .content-fit :deep(pre) { font-size: 0.58em; line-height: 1.22; }
110
84
  </style>