slidev-theme-entaina 0.2.1 → 0.2.2

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/README.md CHANGED
@@ -21,8 +21,8 @@ Las fuentes (Lato, Comfortaa, JetBrains Mono, pesos 300–700) llegan como defau
21
21
  ## Qué incluye
22
22
 
23
23
  - **`styles/tokens.css`** — la paleta Entaina como defaults en `:root`, más las variantes de pilar: `htmlAttrs: { data-theme: technology | innovation | people }` en el headmatter del deck.
24
- - **`styles/base.css`** — el look, 100% sobre tokens: atmósfera por layout, escala display, kickers `.eyebrow`/`.cover-kicker`, cover/section/quote estilizados, splits a sangre con `.panel .panel-before/.panel-after`, tablas, la portada oscura `layout: cover` + `class: bleed` (con `.bleed-note`), y el reveal de entrada escalonado (respeta `prefers-reduced-motion` y print).
25
- - **`global-top.vue`** — chrome de navegación: barra de progreso, bolitas laterales que se expanden al hover mostrando títulos, flechas anterior/siguiente y contador `n / total · %`. Se oculta en export y en modo presentador. Teclado, transiciones, overview (`o`) y export siguen siendo de Slidev.
24
+ - **`styles/base.css`** — el look, 100% sobre tokens: atmósfera por layout, escala display, kickers `.eyebrow`/`.cover-kicker`, cover/section/quote estilizados, splits a sangre con `.panel .panel-before/.panel-after`, tablas, la portada oscura Full-Bleed (`layout: cover` + `class: bleed`) y el reveal de entrada escalonado (respeta `prefers-reduced-motion` y print). Cuando un `src:` import reemplaza la clase raíz, un descendiente `.bleed-note` es el marcador de compatibilidad soportado y activa la misma variante Full-Bleed.
25
+ - **`global-top.vue`** — chrome de navegación: barra de progreso, bolitas laterales que se expanden al hover o foco mostrando títulos y contador `n / total · %`. A partir de 50 diapositivas, el rail pasa automáticamente a modo compacto con scroll, manteniendo navegación por teclado, foco y etiquetas accesibles. Se oculta en export y en modo presentador. Anterior/siguiente, teclado, transiciones, overview (`o`) y export siguen siendo de Slidev (su propia barra de herramientas).
26
26
  - **Componentes** (clases sobre HTML plano en las slides):
27
27
  - KPI dashboard: `<div class="kpi-grid"><div class="kpi"><b>247</b><span>etiqueta</span></div>…</div>` — cifras display con rotación de colores de pilar, etiquetas mono; valores hero breves (≤6 caracteres).
28
28
  - Código: los bloques fenced van en caja navy de marca con tokens oscuros (`setup/shiki.ts`, one-dark-pro en ambos esquemas) y soportan el resaltado de líneas de Slidev (` ```ts {2-3} `). Chip de fichero flotante: `<div class="code-file">worker.ts</div>` justo antes del fence.
package/global-top.vue CHANGED
@@ -1,8 +1,8 @@
1
1
  <!--
2
2
  slidev-theme-entaina — deck navigation chrome: top progress bar, right-hand
3
- slide dots that expand on hover to show slide titles, prev/next arrows
4
- (bottom left) and a counter with reading percent (bottom right). Hidden in
5
- print/export and presenter mode. Styled through the theme tokens.
3
+ slide dots that expand on hover to show slide titles, and a counter with
4
+ reading percent (bottom right). Prev/next is Slidev's own toolbar's job.
5
+ Hidden in print/export and presenter mode. Styled through the theme tokens.
6
6
  -->
7
7
  <script setup lang="ts">
8
8
  import { computed } from 'vue'
@@ -11,6 +11,7 @@ import { useNav } from '@slidev/client'
11
11
  const nav = useNav()
12
12
  const current = computed(() => nav.currentPage.value)
13
13
  const total = computed(() => nav.total.value)
14
+ const isCompact = computed(() => total.value >= 50)
14
15
  const pct = computed(() => Math.round((current.value / total.value) * 100))
15
16
  const hidden = computed(() => nav.isPrintMode.value || (nav as any).isPresenter?.value)
16
17
  const titles = computed(() =>
@@ -25,7 +26,7 @@ const titles = computed(() =>
25
26
  <template>
26
27
  <div v-if="!hidden" class="deck-chrome">
27
28
  <div class="deck-progress" :style="{ width: pct + '%' }" />
28
- <nav class="deck-dots" aria-label="Navegación por diapositivas">
29
+ <nav :class="['deck-dots', { 'deck-dots--compact': isCompact }]" aria-label="Navegación por diapositivas">
29
30
  <button
30
31
  v-for="(t, i) in titles"
31
32
  :key="i"
@@ -38,10 +39,6 @@ const titles = computed(() =>
38
39
  <span class="deck-dot-label">{{ t }}</span>
39
40
  </button>
40
41
  </nav>
41
- <div class="deck-arrows">
42
- <button type="button" class="deck-arrow" :disabled="current <= 1" aria-label="Anterior" @click="nav.prev()">←</button>
43
- <button type="button" class="deck-arrow" :disabled="current >= total" aria-label="Siguiente" @click="nav.next()">→</button>
44
- </div>
45
42
  <div class="deck-counter">{{ current }} / {{ total }} · {{ pct }}%</div>
46
43
  </div>
47
44
  </template>
@@ -69,7 +66,8 @@ const titles = computed(() =>
69
66
  display: flex;
70
67
  flex-direction: column;
71
68
  gap: 5px;
72
- max-height: 70dvh;
69
+ /* Compensate for Slidev's canvas transform so the rendered rail stays at 70dvh. */
70
+ max-height: calc(70dvh / var(--slidev-slide-scale, 1));
73
71
  overflow: hidden auto;
74
72
  padding: 7px;
75
73
  pointer-events: auto;
@@ -78,8 +76,9 @@ const titles = computed(() =>
78
76
  top: 50%;
79
77
  transform: translateY(-50%);
80
78
  transition: width 0.2s;
81
- width: 34px;
79
+ width: 38px;
82
80
  }
81
+ .deck-dots--compact { gap: 1px; }
83
82
  .deck-dots:hover,
84
83
  .deck-dots:focus-within {
85
84
  border-radius: 16px;
@@ -97,6 +96,7 @@ const titles = computed(() =>
97
96
  gap: 0;
98
97
  grid-template-columns: 8px minmax(0, 1fr);
99
98
  min-height: 24px;
99
+ min-width: 24px;
100
100
  padding: 6px;
101
101
  text-align: left;
102
102
  }
@@ -119,31 +119,7 @@ const titles = computed(() =>
119
119
  .deck-dots:hover .deck-dot-label,
120
120
  .deck-dots:focus-within .deck-dot-label { max-width: 200px; opacity: 1; }
121
121
  .deck-dot[aria-current='true'] { background: var(--accent-dim); color: var(--accent); }
122
- .deck-dot:focus-visible,
123
- .deck-arrow:focus-visible { outline: 3px solid var(--node-b); outline-offset: 2px; }
124
-
125
- .deck-arrows {
126
- bottom: 12px;
127
- display: flex;
128
- gap: 6px;
129
- left: 20px;
130
- pointer-events: auto;
131
- position: absolute;
132
- }
133
- .deck-arrow {
134
- background: color-mix(in srgb, var(--surface-elevated) 80%, transparent);
135
- border: 1px solid var(--border-bright);
136
- border-radius: 50%;
137
- color: var(--accent-dark, var(--accent));
138
- cursor: pointer;
139
- display: grid;
140
- font-size: 14px;
141
- height: 30px;
142
- place-items: center;
143
- width: 30px;
144
- }
145
- .deck-arrow:hover:not(:disabled) { background: var(--accent-dim); }
146
- .deck-arrow:disabled { cursor: default; opacity: 0.35; }
122
+ .deck-dot:focus-visible { outline: 3px solid var(--node-b); outline-offset: 2px; }
147
123
 
148
124
  .deck-counter {
149
125
  bottom: 16px;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "slidev-theme-entaina",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "private": false,
5
5
  "packageManager": "npm@11.19.0",
6
6
  "publishConfig": {
package/styles/base.css CHANGED
@@ -232,7 +232,7 @@
232
232
  .slidev-layout tr:nth-child(even) td { background: var(--surface-elevated); }
233
233
 
234
234
  /* ---------- Full-bleed cover variant: `layout: cover` + `class: bleed` ---------- */
235
- .slidev-layout.cover.bleed {
235
+ .slidev-layout.cover:is(.bleed, :has(.bleed-note)) {
236
236
  align-items: flex-start;
237
237
  background:
238
238
  radial-gradient(circle at 80% 20%, color-mix(in srgb, var(--node-b) 55%, transparent), transparent 30%),
@@ -243,12 +243,13 @@
243
243
  padding: 3rem 3.5rem;
244
244
  text-align: left;
245
245
  }
246
- .slidev-layout.cover.bleed::before {
246
+ .slidev-layout.cover:is(.bleed, :has(.bleed-note))::before {
247
247
  background-image:
248
248
  linear-gradient(90deg, transparent 49.3%, rgba(255, 255, 255, 0.6) 49.3%, rgba(255, 255, 255, 0.6) 50.7%, transparent 50.7%),
249
249
  linear-gradient(0deg, transparent 49.3%, rgba(255, 255, 255, 0.6) 49.3%, rgba(255, 255, 255, 0.6) 50.7%, transparent 50.7%);
250
250
  background-size: 110px 110px;
251
251
  content: '';
252
+ height: auto;
252
253
  inset: 0;
253
254
  opacity: 0.34;
254
255
  pointer-events: none;
@@ -257,9 +258,9 @@
257
258
  transform-origin: bottom;
258
259
  z-index: 0;
259
260
  }
260
- .slidev-layout.cover.bleed > * { position: relative; z-index: 1; }
261
- .slidev-layout.cover.bleed > div { margin-bottom: 0; margin-top: auto; }
262
- .slidev-layout.cover.bleed h1 {
261
+ .slidev-layout.cover:is(.bleed, :has(.bleed-note)) > * { position: relative; z-index: 1; }
262
+ .slidev-layout.cover:is(.bleed, :has(.bleed-note)) > div { margin-bottom: 0; margin-top: auto; }
263
+ .slidev-layout.cover:is(.bleed, :has(.bleed-note)) h1 {
263
264
  color: #fff;
264
265
  font-size: 2.9rem;
265
266
  letter-spacing: -0.04em;
@@ -267,9 +268,9 @@
267
268
  max-width: none;
268
269
  text-align: left;
269
270
  }
270
- .slidev-layout.cover.bleed p { color: rgba(255, 255, 255, 0.8); }
271
- .slidev-layout.cover.bleed .cover-kicker,
272
- .slidev-layout.cover.bleed .eyebrow { color: rgba(255, 255, 255, 0.78); }
271
+ .slidev-layout.cover:is(.bleed, :has(.bleed-note)) p { color: rgba(255, 255, 255, 0.8); }
272
+ .slidev-layout.cover:is(.bleed, :has(.bleed-note)) .cover-kicker,
273
+ .slidev-layout.cover:is(.bleed, :has(.bleed-note)) .eyebrow { color: rgba(255, 255, 255, 0.78); }
273
274
  .bleed-note {
274
275
  background: rgba(0, 0, 0, 0.15);
275
276
  border: 1px solid rgba(255, 255, 255, 0.45);