narrarium-astro-reader 0.1.38 → 0.1.40
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/package.json +1 -1
- package/src/components/ChapterPager.astro +14 -6
- package/src/pages/chapters/[chapter].astro +19 -19
- package/src/styles/global.css +122 -32
package/package.json
CHANGED
|
@@ -19,22 +19,30 @@ const nextChapter = currentIndex >= 0 && currentIndex < chapters.length - 1 ? ch
|
|
|
19
19
|
---
|
|
20
20
|
|
|
21
21
|
<nav class="chapter-pager" aria-label="Chapter navigation">
|
|
22
|
-
<a class:list={["pager-link", !previousChapter && "is-disabled"]} href={previousChapter ? `chapters/${previousChapter.slug}/` : undefined} aria-disabled={!previousChapter}>
|
|
23
|
-
|
|
22
|
+
<a class:list={["pager-link pager-link--prev", !previousChapter && "is-disabled"]} href={previousChapter ? `chapters/${previousChapter.slug}/` : undefined} aria-disabled={!previousChapter}>
|
|
23
|
+
<span class="pager-link__arrow" aria-hidden="true">←</span>
|
|
24
|
+
<span class="pager-link__body">
|
|
25
|
+
<span class="pager-link__label">Previous</span>
|
|
26
|
+
<span class="pager-link__title">{previousChapter ? previousChapter.metadata.title : "Start of book"}</span>
|
|
27
|
+
</span>
|
|
24
28
|
</a>
|
|
25
29
|
|
|
26
30
|
<label class="pager-jump">
|
|
27
|
-
<span class="
|
|
31
|
+
<span class="pager-jump__label">Jump to chapter</span>
|
|
28
32
|
<select onchange="if (this.value) window.location.href = this.value">
|
|
29
33
|
{chapters.map((chapter) => (
|
|
30
34
|
<option value={`chapters/${chapter.slug}/`} selected={chapter.slug === currentSlug}>
|
|
31
|
-
{`Chapter ${String(chapter.metadata.number).padStart(3, "0")}
|
|
35
|
+
{`Chapter ${String(chapter.metadata.number).padStart(3, "0")} — ${chapter.metadata.title}`}
|
|
32
36
|
</option>
|
|
33
37
|
))}
|
|
34
38
|
</select>
|
|
35
39
|
</label>
|
|
36
40
|
|
|
37
|
-
<a class:list={["pager-link", !nextChapter && "is-disabled"]} href={nextChapter ? `chapters/${nextChapter.slug}/` : undefined} aria-disabled={!nextChapter}>
|
|
38
|
-
|
|
41
|
+
<a class:list={["pager-link pager-link--next", !nextChapter && "is-disabled"]} href={nextChapter ? `chapters/${nextChapter.slug}/` : undefined} aria-disabled={!nextChapter}>
|
|
42
|
+
<span class="pager-link__body">
|
|
43
|
+
<span class="pager-link__label">Next</span>
|
|
44
|
+
<span class="pager-link__title">{nextChapter ? nextChapter.metadata.title : "End of book"}</span>
|
|
45
|
+
</span>
|
|
46
|
+
<span class="pager-link__arrow" aria-hidden="true">→</span>
|
|
39
47
|
</a>
|
|
40
48
|
</nav>
|
|
@@ -217,26 +217,26 @@ const renderedParagraphs = await Promise.all(
|
|
|
217
217
|
</div>
|
|
218
218
|
|
|
219
219
|
<aside class="focus-rail" aria-label="Full read controls">
|
|
220
|
-
<div class="focus-
|
|
221
|
-
<div>
|
|
222
|
-
<
|
|
223
|
-
<
|
|
220
|
+
<div class="focus-rail__row">
|
|
221
|
+
<div class="focus-rail__identity">
|
|
222
|
+
<span class="focus-rail__eyebrow">Full read</span>
|
|
223
|
+
<span class="focus-rail__title">{chapter.metadata.title}</span>
|
|
224
|
+
</div>
|
|
225
|
+
<div class="focus-rail__controls">
|
|
226
|
+
<a class:list={["focus-rail__link", !previousChapter && "is-disabled"]} href={previousChapter ? `chapters/${previousChapter.slug}/` : undefined} aria-disabled={!previousChapter}>← Prev</a>
|
|
227
|
+
<label class="focus-rail__jump">
|
|
228
|
+
<span class="sr-only">Jump to chapter</span>
|
|
229
|
+
<select data-reader-focus-jump aria-label="Jump to chapter">
|
|
230
|
+
{allChapters.map((entry) => (
|
|
231
|
+
<option value={entry.slug} selected={entry.slug === chapterSlug}>
|
|
232
|
+
{`Chapter ${String(entry.metadata.number).padStart(3, "0")} — ${entry.metadata.title}`}
|
|
233
|
+
</option>
|
|
234
|
+
))}
|
|
235
|
+
</select>
|
|
236
|
+
</label>
|
|
237
|
+
<a class:list={["focus-rail__link", !nextChapter && "is-disabled"]} href={nextChapter ? `chapters/${nextChapter.slug}/` : undefined} aria-disabled={!nextChapter}>Next →</a>
|
|
238
|
+
<button type="button" class="focus-rail__button" data-reader-focus-toggle>Exit</button>
|
|
224
239
|
</div>
|
|
225
|
-
</div>
|
|
226
|
-
<div class="focus-rail__controls">
|
|
227
|
-
<a class:list={["focus-rail__link", !previousChapter && "is-disabled"]} href={previousChapter ? `chapters/${previousChapter.slug}/` : undefined} aria-disabled={!previousChapter}>Previous</a>
|
|
228
|
-
<label class="focus-rail__jump">
|
|
229
|
-
<span class="sr-only">Jump to chapter</span>
|
|
230
|
-
<select data-reader-focus-jump aria-label="Jump to chapter">
|
|
231
|
-
{allChapters.map((entry) => (
|
|
232
|
-
<option value={entry.slug} selected={entry.slug === chapterSlug}>
|
|
233
|
-
{`Chapter ${String(entry.metadata.number).padStart(3, "0")} - ${entry.metadata.title}`}
|
|
234
|
-
</option>
|
|
235
|
-
))}
|
|
236
|
-
</select>
|
|
237
|
-
</label>
|
|
238
|
-
<a class:list={["focus-rail__link", !nextChapter && "is-disabled"]} href={nextChapter ? `chapters/${nextChapter.slug}/` : undefined} aria-disabled={!nextChapter}>Next</a>
|
|
239
|
-
<button type="button" class="focus-rail__button" data-reader-focus-toggle>Exit</button>
|
|
240
240
|
</div>
|
|
241
241
|
</aside>
|
|
242
242
|
|
package/src/styles/global.css
CHANGED
|
@@ -933,51 +933,101 @@ h3 {
|
|
|
933
933
|
.chapter-pager {
|
|
934
934
|
display: grid;
|
|
935
935
|
grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
|
|
936
|
-
gap:
|
|
937
|
-
align-items:
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
padding: 0.9rem 1.25rem;
|
|
941
|
-
margin-top: 1.5rem;
|
|
942
|
-
margin-bottom: 1.5rem;
|
|
936
|
+
gap: 0.75rem;
|
|
937
|
+
align-items: center;
|
|
938
|
+
margin-top: 2rem;
|
|
939
|
+
margin-bottom: 2rem;
|
|
943
940
|
}
|
|
944
941
|
|
|
945
942
|
.pager-link {
|
|
946
943
|
display: flex;
|
|
947
944
|
align-items: center;
|
|
948
|
-
gap: 0.
|
|
949
|
-
padding: 0.
|
|
945
|
+
gap: 0.75rem;
|
|
946
|
+
padding: 0.85rem 1.1rem;
|
|
950
947
|
border: 1px solid var(--line);
|
|
951
|
-
border-radius:
|
|
948
|
+
border-radius: 12px;
|
|
952
949
|
background: var(--surface);
|
|
953
950
|
color: var(--text-muted);
|
|
954
951
|
text-decoration: none;
|
|
955
|
-
|
|
952
|
+
transition: background 120ms ease, border-color 120ms ease, color 120ms ease, box-shadow 120ms ease;
|
|
953
|
+
min-width: 0;
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
.pager-link--next {
|
|
957
|
+
justify-content: flex-end;
|
|
958
|
+
text-align: right;
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
.pager-link__arrow {
|
|
962
|
+
flex-shrink: 0;
|
|
963
|
+
font-size: 1.1rem;
|
|
964
|
+
line-height: 1;
|
|
965
|
+
color: var(--text-muted);
|
|
966
|
+
transition: color 120ms ease;
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
.pager-link__body {
|
|
970
|
+
display: flex;
|
|
971
|
+
flex-direction: column;
|
|
972
|
+
gap: 0.15rem;
|
|
973
|
+
min-width: 0;
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
.pager-link--next .pager-link__body {
|
|
977
|
+
align-items: flex-end;
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
.pager-link__label {
|
|
981
|
+
font-size: 0.72rem;
|
|
982
|
+
font-weight: 600;
|
|
983
|
+
letter-spacing: 0.07em;
|
|
984
|
+
text-transform: uppercase;
|
|
985
|
+
color: var(--text-muted);
|
|
986
|
+
transition: color 120ms ease;
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
.pager-link__title {
|
|
990
|
+
font-size: 0.9rem;
|
|
956
991
|
font-weight: 500;
|
|
992
|
+
color: var(--text);
|
|
957
993
|
white-space: nowrap;
|
|
958
994
|
overflow: hidden;
|
|
959
995
|
text-overflow: ellipsis;
|
|
960
|
-
|
|
996
|
+
max-width: 22ch;
|
|
961
997
|
}
|
|
962
998
|
|
|
963
|
-
.pager-link
|
|
964
|
-
text-
|
|
965
|
-
justify-content: flex-end;
|
|
999
|
+
.pager-link.is-disabled .pager-link__title {
|
|
1000
|
+
color: var(--text-muted);
|
|
966
1001
|
}
|
|
967
1002
|
|
|
968
|
-
.pager-link:hover {
|
|
1003
|
+
.pager-link:not(.is-disabled):hover {
|
|
969
1004
|
background: var(--surface-muted);
|
|
970
|
-
border-color: color-mix(in srgb, var(--accent)
|
|
1005
|
+
border-color: color-mix(in srgb, var(--accent) 30%, var(--line));
|
|
971
1006
|
color: var(--text);
|
|
1007
|
+
box-shadow: 0 2px 8px color-mix(in srgb, var(--accent) 10%, transparent);
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
.pager-link:not(.is-disabled):hover .pager-link__arrow,
|
|
1011
|
+
.pager-link:not(.is-disabled):hover .pager-link__label {
|
|
1012
|
+
color: var(--accent);
|
|
972
1013
|
}
|
|
973
1014
|
|
|
974
1015
|
.pager-jump {
|
|
975
|
-
display:
|
|
1016
|
+
display: flex;
|
|
1017
|
+
flex-direction: column;
|
|
1018
|
+
align-items: center;
|
|
976
1019
|
gap: 0.3rem;
|
|
977
|
-
align-content: center;
|
|
978
1020
|
min-width: 0;
|
|
979
1021
|
}
|
|
980
1022
|
|
|
1023
|
+
.pager-jump__label {
|
|
1024
|
+
font-size: 0.72rem;
|
|
1025
|
+
font-weight: 600;
|
|
1026
|
+
letter-spacing: 0.07em;
|
|
1027
|
+
text-transform: uppercase;
|
|
1028
|
+
color: var(--text-muted);
|
|
1029
|
+
}
|
|
1030
|
+
|
|
981
1031
|
/* ─── Form controls ──────────────────────────────────────────── */
|
|
982
1032
|
.pager-jump select,
|
|
983
1033
|
.reader-control input,
|
|
@@ -1181,39 +1231,67 @@ mark {
|
|
|
1181
1231
|
display: none;
|
|
1182
1232
|
position: fixed;
|
|
1183
1233
|
left: 50%;
|
|
1184
|
-
bottom:
|
|
1234
|
+
bottom: 1.25rem;
|
|
1185
1235
|
transform: translate(-50%, 0);
|
|
1186
1236
|
z-index: 46;
|
|
1187
|
-
width: min(
|
|
1188
|
-
padding: 1rem
|
|
1189
|
-
background: var(--surface);
|
|
1237
|
+
width: min(820px, calc(100vw - 1.5rem));
|
|
1238
|
+
padding: 0.75rem 1rem;
|
|
1239
|
+
background: color-mix(in srgb, var(--surface) 96%, transparent);
|
|
1190
1240
|
border: 1px solid var(--line);
|
|
1191
1241
|
border-radius: 16px;
|
|
1192
|
-
box-shadow: var(--shadow);
|
|
1242
|
+
box-shadow: var(--shadow), 0 8px 32px rgba(0,0,0,0.18);
|
|
1243
|
+
backdrop-filter: blur(12px);
|
|
1244
|
+
-webkit-backdrop-filter: blur(12px);
|
|
1193
1245
|
opacity: 1;
|
|
1194
1246
|
transition: opacity 180ms ease, transform 180ms ease;
|
|
1195
1247
|
}
|
|
1196
1248
|
|
|
1197
|
-
.focus-
|
|
1249
|
+
.focus-rail__row {
|
|
1198
1250
|
display: flex;
|
|
1199
1251
|
align-items: center;
|
|
1200
|
-
justify-content: space-between;
|
|
1201
1252
|
gap: 1rem;
|
|
1202
|
-
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
.focus-rail__identity {
|
|
1256
|
+
display: flex;
|
|
1257
|
+
flex-direction: column;
|
|
1258
|
+
gap: 0.1rem;
|
|
1259
|
+
flex-shrink: 0;
|
|
1260
|
+
max-width: 18ch;
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
.focus-rail__eyebrow {
|
|
1264
|
+
font-size: 0.68rem;
|
|
1265
|
+
font-weight: 700;
|
|
1266
|
+
letter-spacing: 0.08em;
|
|
1267
|
+
text-transform: uppercase;
|
|
1268
|
+
color: var(--accent);
|
|
1203
1269
|
}
|
|
1204
1270
|
|
|
1205
1271
|
.focus-rail__title {
|
|
1206
1272
|
font-weight: 600;
|
|
1207
|
-
font-size: 0.
|
|
1273
|
+
font-size: 0.88rem;
|
|
1208
1274
|
color: var(--text);
|
|
1275
|
+
white-space: nowrap;
|
|
1276
|
+
overflow: hidden;
|
|
1277
|
+
text-overflow: ellipsis;
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1280
|
+
.focus-rail__controls {
|
|
1281
|
+
display: flex;
|
|
1282
|
+
align-items: center;
|
|
1283
|
+
gap: 0.5rem;
|
|
1284
|
+
flex: 1;
|
|
1285
|
+
min-width: 0;
|
|
1209
1286
|
}
|
|
1210
1287
|
|
|
1211
1288
|
.focus-rail__jump {
|
|
1212
|
-
|
|
1289
|
+
flex: 1;
|
|
1290
|
+
min-width: 0;
|
|
1213
1291
|
}
|
|
1214
1292
|
|
|
1215
1293
|
.focus-rail__jump select {
|
|
1216
|
-
|
|
1294
|
+
width: 100%;
|
|
1217
1295
|
}
|
|
1218
1296
|
|
|
1219
1297
|
.focus-hint {
|
|
@@ -1410,13 +1488,25 @@ mark {
|
|
|
1410
1488
|
.meta-row,
|
|
1411
1489
|
.scene-header,
|
|
1412
1490
|
.chapter-outline__header,
|
|
1413
|
-
.focus-
|
|
1414
|
-
.focus-rail__controls {
|
|
1491
|
+
.focus-rail__row {
|
|
1415
1492
|
grid-template-columns: 1fr;
|
|
1416
1493
|
flex-direction: column;
|
|
1417
1494
|
align-items: stretch;
|
|
1418
1495
|
}
|
|
1419
1496
|
|
|
1497
|
+
.pager-link--next {
|
|
1498
|
+
text-align: left;
|
|
1499
|
+
justify-content: flex-start;
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1502
|
+
.pager-link--next .pager-link__body {
|
|
1503
|
+
align-items: flex-start;
|
|
1504
|
+
}
|
|
1505
|
+
|
|
1506
|
+
.pager-jump {
|
|
1507
|
+
align-items: stretch;
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1420
1510
|
.site-search {
|
|
1421
1511
|
min-width: 0;
|
|
1422
1512
|
}
|