narrarium-astro-reader 0.1.38 → 0.1.39

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "narrarium-astro-reader",
3
- "version": "0.1.38",
3
+ "version": "0.1.39",
4
4
  "type": "module",
5
5
  "description": "Astro reader and scaffolding CLI for Narrarium book repositories.",
6
6
  "license": "MIT",
@@ -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
- {previousChapter ? `Previous: ${previousChapter.metadata.title}` : "Start of book"}
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="label">Jump To</span>
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")} - ${chapter.metadata.title}`}
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
- {nextChapter ? `Next: ${nextChapter.metadata.title}` : "End of book"}
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-rail__meta">
221
- <div>
222
- <p class="eyebrow">Full read</p>
223
- <div class="focus-rail__title">{chapter.metadata.title}</div>
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
 
@@ -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: 1rem;
937
- align-items: stretch;
938
- border: 1px solid var(--line);
939
- background: var(--surface);
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.4rem;
949
- padding: 0.5rem 0.75rem;
945
+ gap: 0.75rem;
946
+ padding: 0.85rem 1.1rem;
950
947
  border: 1px solid var(--line);
951
- border-radius: 8px;
948
+ border-radius: 12px;
952
949
  background: var(--surface);
953
950
  color: var(--text-muted);
954
951
  text-decoration: none;
955
- font-size: 0.875rem;
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
- transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
996
+ max-width: 22ch;
961
997
  }
962
998
 
963
- .pager-link:last-child {
964
- text-align: right;
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) 22%, var(--line));
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: grid;
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: 1rem;
1234
+ bottom: 1.25rem;
1185
1235
  transform: translate(-50%, 0);
1186
1236
  z-index: 46;
1187
- width: min(760px, calc(100vw - 1rem));
1188
- padding: 1rem 1.25rem;
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-rail__meta {
1249
+ .focus-rail__row {
1198
1250
  display: flex;
1199
1251
  align-items: center;
1200
- justify-content: space-between;
1201
1252
  gap: 1rem;
1202
- margin-bottom: 0.8rem;
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.95rem;
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
- min-width: min(320px, 100%);
1289
+ flex: 1;
1290
+ min-width: 0;
1213
1291
  }
1214
1292
 
1215
1293
  .focus-rail__jump select {
1216
- min-width: min(320px, 100%);
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-rail__meta,
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
  }