@hanology/cham-browser 0.4.29 → 0.4.31

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": "@hanology/cham-browser",
3
- "version": "0.4.29",
3
+ "version": "0.4.31",
4
4
  "description": "CHAM — browser-compatible parser, serializer, and site generator for Classical Han Annotated Markdown",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -168,9 +168,8 @@ describe('useAnnotationTooltip', () => {
168
168
  left: 200, top: 300, bottom: 330, right: 250, width: 50, height: 30,
169
169
  })
170
170
  show(createMockEvent(target), [makeAnn({ id: 'a1', kind: 'semantic' })])
171
- // Default layout is vertical — positioned via right + top
172
- expect(style.value.right).toBeTruthy()
173
- expect(style.value.top).toBe('50%')
174
- expect(style.value.transform).toBe('translateY(-50%)')
171
+ // Default layout is vertical — positioned via left + top
172
+ expect(style.value.left).toBeTruthy()
173
+ expect(style.value.top).toBeTruthy()
175
174
  })
176
175
  })
@@ -384,6 +384,12 @@ onBeforeUnmount(() => {
384
384
  justify-content: center;
385
385
  }
386
386
 
387
+ .ann-pane.vertical .ann-pane-handle {
388
+ right: auto;
389
+ left: -6px;
390
+ cursor: col-resize;
391
+ }
392
+
387
393
  .ann-handle-grip {
388
394
  display: block;
389
395
  width: 3px;
@@ -411,7 +417,7 @@ onBeforeUnmount(() => {
411
417
  }
412
418
 
413
419
  @media (max-width: 768px) {
414
- .ann-pane {
420
+ .ann-pane:not(.vertical) {
415
421
  width: 100% !important;
416
422
  height: auto;
417
423
  max-height: 55vh;
@@ -422,70 +428,90 @@ onBeforeUnmount(() => {
422
428
  border-radius: 14px 14px 0 0;
423
429
  box-shadow: 0 -4px 24px rgba(var(--shadow-rgb), 0.08);
424
430
  }
425
- .ann-pane-handle {
431
+ .ann-pane:not(.vertical) .ann-pane-handle {
426
432
  display: none;
427
433
  }
428
- .ann-pane-enter-from,
429
- .ann-pane-leave-to {
434
+ .ann-pane:not(.vertical).ann-pane-enter-from,
435
+ .ann-pane:not(.vertical).ann-pane-leave-to {
430
436
  transform: translateY(100%);
431
437
  }
432
438
  }
433
439
 
434
440
  /* ─── Vertical mode ─── */
435
- /* Pane stays in horizontal-tb; only the headword uses vertical-rl */
441
+
442
+ .ann-pane.vertical {
443
+ writing-mode: vertical-rl;
444
+ text-orientation: mixed;
445
+ border-right: none;
446
+ border-left: 1px solid var(--border);
447
+ box-shadow: -4px 0 24px rgba(var(--shadow-rgb), 0.06);
448
+ }
449
+
450
+ .ann-pane.vertical .ann-pane-header {
451
+ writing-mode: vertical-rl;
452
+ text-orientation: mixed;
453
+ border-bottom: none;
454
+ border-left: 1px solid var(--border-light);
455
+ padding: 16px 12px;
456
+ flex-direction: row;
457
+ align-items: center;
458
+ }
459
+
460
+ .ann-pane.vertical .ann-pane-body {
461
+ overflow-y: hidden;
462
+ overflow-x: auto;
463
+ overscroll-behavior: contain;
464
+ }
436
465
 
437
466
  .ann-pane.vertical .ann-pane-entry {
467
+ padding: 12px 0;
468
+ border-bottom: none;
469
+ border-right: 1px solid var(--border-light);
470
+ border-left: none;
438
471
  display: flex;
439
- flex-direction: row-reverse;
440
- gap: 8px;
472
+ flex-direction: row;
441
473
  align-items: flex-start;
442
- border-left: none;
443
- border-right: 3px solid transparent;
474
+ gap: 0;
475
+ }
476
+
477
+ .ann-pane.vertical .ann-pane-entry:last-child {
478
+ border-right: none;
444
479
  }
445
480
 
446
481
  .ann-pane.vertical .ann-pane-entry.active {
482
+ border-left-color: transparent;
447
483
  border-right-color: var(--vermillion);
448
484
  }
449
485
 
450
486
  .ann-pane.vertical .ann-pane-entry.active.pronunciation {
487
+ border-left-color: transparent;
451
488
  border-right-color: var(--jade);
452
489
  }
453
490
 
454
- .ann-pane.vertical .ann-pane-entry-main {
455
- flex: 1;
456
- min-width: 0;
457
- }
458
-
459
- /* Vertical headword — only this element uses vertical writing */
460
- .ann-pane-v-word {
491
+ .ann-pane.vertical .ann-pane-v-word {
461
492
  writing-mode: vertical-rl;
462
493
  text-orientation: upright;
463
494
  display: flex;
464
- flex-direction: row;
495
+ flex-direction: column;
465
496
  align-items: center;
466
- gap: 6px;
467
- padding: 0 8px;
497
+ gap: 4px;
498
+ padding: 0 6px;
468
499
  border-left: 1px solid var(--border-light);
469
500
  flex-shrink: 0;
470
501
  }
471
502
 
472
- .ann-pane-word-v {
473
- font-family: var(--serif);
474
- font-size: 20px;
475
- font-weight: 900;
476
- letter-spacing: 6px;
477
- color: var(--ink);
503
+ .ann-pane.vertical .ann-pane-entry-main {
504
+ padding: 0 8px;
478
505
  }
479
506
 
480
- .ann-pane-idx-v {
481
- font-family: var(--serif);
482
- font-size: 12px;
483
- font-weight: 700;
484
- color: var(--vermillion);
507
+ .ann-pane.vertical .ann-pane-entry-head {
508
+ flex-direction: column;
509
+ align-items: flex-start;
510
+ gap: 4px;
485
511
  }
486
512
 
487
- .ann-pane-entry.active.pronunciation .ann-pane-idx-v {
488
- color: var(--jade);
513
+ .ann-pane.vertical .ann-pane-entry-body {
514
+ padding-left: 0;
489
515
  }
490
516
 
491
517
  .ann-pane.vertical .ann-pane-text {
@@ -493,6 +519,21 @@ onBeforeUnmount(() => {
493
519
  letter-spacing: 1px;
494
520
  }
495
521
 
522
+ .ann-pane.vertical .ann-pane-close {
523
+ margin-left: 0;
524
+ margin-top: auto;
525
+ }
526
+
527
+ .ann-pane.vertical .ann-pane-count,
528
+ .ann-pane.vertical .ann-pane-kind,
529
+ .ann-pane.vertical .ann-pane-layer {
530
+ writing-mode: horizontal-tb;
531
+ }
532
+
533
+ .ann-pane.vertical .ann-pane-pron {
534
+ writing-mode: horizontal-tb;
535
+ }
536
+
496
537
  @media (max-width: 768px) {
497
538
  .ann-pane.vertical {
498
539
  width: 80vw !important;
@@ -500,10 +541,11 @@ onBeforeUnmount(() => {
500
541
  max-height: none !important;
501
542
  top: 0 !important;
502
543
  bottom: auto !important;
503
- border-right: 1px solid var(--border) !important;
544
+ border-left: 1px solid var(--border) !important;
545
+ border-right: none !important;
504
546
  border-top: none !important;
505
547
  border-radius: 0 !important;
506
- box-shadow: 4px 0 24px rgba(var(--shadow-rgb), 0.06) !important;
548
+ box-shadow: -4px 0 24px rgba(var(--shadow-rgb), 0.06) !important;
507
549
  }
508
550
  .ann-pane.vertical .ann-pane-handle {
509
551
  display: flex !important;
@@ -417,6 +417,30 @@ onBeforeUnmount(() => {
417
417
  .ann-sheet { display: none; }
418
418
  }
419
419
 
420
+ /* ─── Mobile sheet vertical mode ─── */
421
+ .ann-sheet.vertical {
422
+ left: 0;
423
+ right: auto;
424
+ bottom: auto;
425
+ top: 0;
426
+ width: 85vw;
427
+ max-height: none;
428
+ height: 100vh;
429
+ border-top: none;
430
+ border-radius: 0;
431
+ border-right: 1px solid var(--border);
432
+ box-shadow: 4px 0 32px rgba(var(--shadow-rgb), 0.15);
433
+ }
434
+
435
+ .ann-sheet.vertical .ann-sheet-handle {
436
+ display: none;
437
+ }
438
+
439
+ .ann-sheet.vertical.ann-sheet-enter-from,
440
+ .ann-sheet.vertical.ann-sheet-leave-to {
441
+ transform: translateX(-100%);
442
+ }
443
+
420
444
  /* ─── Vertical mode ─── */
421
445
  .ann-card.vertical {
422
446
  writing-mode: vertical-rl;
@@ -427,10 +451,19 @@ onBeforeUnmount(() => {
427
451
  }
428
452
 
429
453
  .ann-card.vertical .ann-card-head {
430
- writing-mode: horizontal-tb;
431
- padding: 10px 6px;
454
+ writing-mode: vertical-rl;
455
+ text-orientation: upright;
456
+ padding: 6px 10px;
432
457
  border-bottom: none;
433
458
  border-left: 1px solid var(--border-light);
459
+ flex-direction: row;
460
+ align-items: center;
461
+ }
462
+ .ann-card.vertical .ann-headword {
463
+ letter-spacing: 6px;
464
+ }
465
+ .ann-card.vertical .ann-badge-count {
466
+ writing-mode: horizontal-tb;
434
467
  }
435
468
 
436
469
  .ann-card.vertical .ann-card-scroll {
@@ -482,7 +515,7 @@ onBeforeUnmount(() => {
482
515
  }
483
516
 
484
517
  .ann-sheet-body.vertical {
485
- flex-direction: row-reverse;
518
+ flex-direction: row;
486
519
  }
487
520
 
488
521
  .ann-sheet-body.vertical > .ann-sheet-head {
@@ -527,8 +560,13 @@ onBeforeUnmount(() => {
527
560
  }
528
561
 
529
562
  .ann-sheet-body.vertical .ann-sheet-scroll {
563
+ writing-mode: vertical-rl;
564
+ text-orientation: mixed;
530
565
  flex: 1;
531
566
  min-width: 0;
567
+ overflow-x: auto;
568
+ overflow-y: hidden;
569
+ padding: 4px 12px 24px;
532
570
  }
533
571
 
534
572
  .ann-sheet-body.vertical .ann-pron-h {
@@ -538,5 +576,16 @@ onBeforeUnmount(() => {
538
576
  .ann-sheet-body.vertical .ann-text {
539
577
  white-space: pre-line;
540
578
  line-height: 2;
579
+ letter-spacing: 1px;
580
+ }
581
+
582
+ .ann-sheet-body.vertical .ann-entry {
583
+ border-bottom: none;
584
+ border-right: 1px solid var(--border-light);
585
+ padding: 0 10px;
586
+ }
587
+
588
+ .ann-sheet-body.vertical .ann-entry:last-child {
589
+ border-right: none;
541
590
  }
542
591
  </style>
@@ -73,7 +73,7 @@ function onTap(event: MouseEvent) {
73
73
  }
74
74
  .h-display-line {
75
75
  font-size: var(--main-font-size, 24px); line-height: 2.6;
76
- letter-spacing: 4px; color: var(--ink);
76
+ letter-spacing: 4px; color: var(--ink); white-space: pre-wrap;
77
77
  }
78
78
  .h-verse-anim {
79
79
  animation: verseFade 0.45s var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1)) both;
@@ -89,7 +89,7 @@ function onTap(event: MouseEvent) {
89
89
  .v-scroll-body { margin-left: 24px; }
90
90
  .v-scroll-line {
91
91
  font-size: var(--main-font-size, 24px); line-height: 2.4; letter-spacing: 6px;
92
- color: var(--ink); display: block;
92
+ color: var(--ink); display: block; white-space: pre-wrap;
93
93
  }
94
94
  .v-verse-anim {
95
95
  animation: verseFadeV 0.4s var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1)) both;
@@ -849,22 +849,11 @@ function tcy(n: number): string {
849
849
  transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
850
850
  line-height: 1.6;
851
851
  position: relative;
852
- overflow: hidden;
853
- }
854
- .v-nav-btn::after {
855
- content: '';
856
- position: absolute;
857
- right: 0; top: 0; bottom: 0;
858
- width: 2px;
859
- background: linear-gradient(180deg, var(--gold), var(--vermillion));
860
- transform: scaleY(0);
861
- transition: transform 0.35s var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1));
862
852
  }
863
853
  .v-nav-btn:hover {
864
854
  border-color: var(--gold);
865
855
  box-shadow: 0 4px 20px rgba(var(--shadow-rgb), 0.1);
866
856
  }
867
- .v-nav-btn:hover::after { transform: scaleY(1); }
868
857
  .v-nav-btn:hover .v-nav-title { color: var(--vermillion); }
869
858
  .v-nav-dir {
870
859
  font-size: 16px; color: var(--vermillion);