|
353 | 353 | color: white; |
354 | 354 | } |
355 | 355 |
|
356 | | - .frame-hint { |
| 356 | + /* Help dialog */ |
| 357 | + .help-container { |
| 358 | + position: fixed; |
| 359 | + top: 40px; |
| 360 | + left: 15px; |
| 361 | + background: #fff; |
| 362 | + border: 1px solid #ddd; |
| 363 | + border-radius: 6px; |
| 364 | + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); |
| 365 | + padding: 24px 30px 12px 16px; |
| 366 | + z-index: 1000; |
357 | 367 | display: none; |
| 368 | + } |
| 369 | + |
| 370 | + .help-container.active { |
| 371 | + display: block; |
| 372 | + } |
| 373 | + |
| 374 | + .help-list { |
| 375 | + margin: 0; |
| 376 | + padding: 0 0 0 18px; |
| 377 | + font-size: 0.85rem; |
| 378 | + color: #444; |
| 379 | + line-height: 1.7; |
| 380 | + } |
| 381 | + |
| 382 | + .help-footer { |
| 383 | + margin-top: 8px; |
| 384 | + font-size: 0.85rem; |
| 385 | + color: #666; |
| 386 | + font-style: italic; |
| 387 | + text-align: right; |
| 388 | + } |
| 389 | + |
| 390 | + .help-close { |
358 | 391 | position: absolute; |
359 | | - left: 50%; |
360 | | - transform: translateX(-50%); |
361 | | - top: 35px; |
362 | | - font-size: 11px; |
| 392 | + top: 6px; |
| 393 | + right: 8px; |
| 394 | + border: none; |
| 395 | + background: none; |
| 396 | + font-size: 14px; |
| 397 | + cursor: pointer; |
363 | 398 | color: #999; |
364 | | - z-index: 10; |
| 399 | + transition: color 0.2s; |
365 | 400 | } |
366 | 401 |
|
367 | | - body.frame-mode .frame-hint { |
368 | | - display: block; |
| 402 | + .help-close:hover { |
| 403 | + color: #bc4f5f; |
369 | 404 | } |
370 | 405 |
|
371 | 406 | .frame-container { |
|
396 | 431 | scrollbar-width: thin; |
397 | 432 | } |
398 | 433 |
|
| 434 | + body.frame-mode .frame-sidebar-left { |
| 435 | + justify-self: end; |
| 436 | + } |
| 437 | + |
| 438 | + body.frame-mode .frame-sidebar-right { |
| 439 | + justify-self: start; |
| 440 | + } |
| 441 | + |
399 | 442 | .frame-sidebar::-webkit-scrollbar { |
400 | 443 | width: 4px; |
401 | 444 | } |
|
426 | 469 | .frame-item-number { |
427 | 470 | background-color: #bc4f5f; |
428 | 471 | color: white; |
429 | | - font-size: 10px; |
430 | | - min-width: 18px; |
431 | | - height: 18px; |
432 | | - line-height: 18px; |
| 472 | + font-size: 0.75rem; |
| 473 | + min-width: 1.25rem; |
| 474 | + height: 1.25rem; |
| 475 | + line-height: 1.25rem; |
433 | 476 | text-align: center; |
434 | 477 | border-radius: 50%; |
435 | 478 | flex-shrink: 0; |
436 | 479 | } |
437 | 480 |
|
438 | 481 | .frame-item-title { |
439 | | - font-size: 13px; |
| 482 | + font-size: 1rem; |
440 | 483 | color: #333; |
441 | 484 | text-decoration: none; |
442 | 485 | transition: color 0.2s; |
|
456 | 499 | } |
457 | 500 |
|
458 | 501 | @keyframes pulse { |
459 | | - 0%, 100% { box-shadow: 0 0 20px 8px rgba(188, 79, 95, 0.9), 0 0 40px 15px rgba(188, 79, 95, 0.5); } |
460 | | - 50% { box-shadow: 0 0 25px 12px rgba(188, 79, 95, 1), 0 0 50px 20px rgba(188, 79, 95, 0.6); } |
| 502 | + |
| 503 | + 0%, |
| 504 | + 100% { |
| 505 | + box-shadow: 0 0 20px 8px rgba(188, 79, 95, 0.9), 0 0 40px 15px rgba(188, 79, 95, 0.5); |
| 506 | + } |
| 507 | + |
| 508 | + 50% { |
| 509 | + box-shadow: 0 0 25px 12px rgba(188, 79, 95, 1), 0 0 50px 20px rgba(188, 79, 95, 0.6); |
| 510 | + } |
461 | 511 | } |
462 | 512 |
|
463 | 513 | /* Hide frame mode on smaller screens */ |
464 | 514 | @media (max-width: 1100px) { |
465 | 515 | .frame-toggle { |
466 | 516 | display: none; |
467 | 517 | } |
| 518 | + |
468 | 519 | body.frame-mode .frame-container { |
469 | 520 | display: block; |
470 | 521 | } |
| 522 | + |
471 | 523 | body.frame-mode .frame-sidebar { |
472 | 524 | display: none; |
473 | 525 | } |
|
485 | 537 | {{ $i := "index.xml" }} |
486 | 538 | <a href="{{ $i | relURL }}" class="rss-link" title="RSS Feed"><img src="rss.svg"> </a> |
487 | 539 | <a href="#poster-info" class="header-link">about</a> |
| 540 | + <a href="#" class="header-link" id="help-toggle">help</a> |
488 | 541 | <button class="frame-toggle" id="frame-toggle" title="Show all annotations">Show All</button> |
489 | 542 | </div> |
490 | | - <div class="frame-hint">Hover to highlight · Click for details</div> |
| 543 | + |
| 544 | + <!-- Help dialog --> |
| 545 | + <div class="help-container" id="help-container"> |
| 546 | + <button class="help-close">✖</button> |
| 547 | + <div class="help-content"> |
| 548 | + <ul class="help-list"> |
| 549 | + <li>An interactive guide to the Unix Magic Poster (more in <a href="#poster-info">about</a>)</li> |
| 550 | + <li>Hover a marker or list item to highlight it</li> |
| 551 | + <li>Click to read the full annotation</li> |
| 552 | + <li>Show All displays reference lists alongside the poster</li> |
| 553 | + <li>Scroll down to read all annotations in order</li> |
| 554 | + <li>Use 🔗 Share to copy a link to any annotation</li> |
| 555 | + </ul> |
| 556 | + <div class="help-footer">Have fun!</div> |
| 557 | + </div> |
| 558 | + </div> |
491 | 559 |
|
492 | 560 | <div class="frame-container" id="frame-container"> |
493 | 561 | <!-- Left sidebar: markers 1-20 --> |
|
545 | 613 | {{ .Content | safeHTML }} |
546 | 614 | </div> |
547 | 615 | <div class="annotation-footer"> |
548 | | - <button class="share-btn" data-hash="{{ .File.BaseFileName }}" data-permalink="{{ .RelPermalink }}">🔗 Share</button> |
| 616 | + <button class="share-btn" data-hash="{{ .File.BaseFileName }}" |
| 617 | + data-permalink="{{ .RelPermalink }}">🔗 Share</button> |
549 | 618 | </div> |
550 | 619 | </div> |
551 | 620 | </div> |
|
609 | 678 | </div> |
610 | 679 |
|
611 | 680 | <div class="annotation-footer"> |
612 | | - <button class="share-btn" data-hash="{{ .File.BaseFileName }}" data-permalink="{{ .RelPermalink }}">🔗 Share</button> |
| 681 | + <button class="share-btn" data-hash="{{ .File.BaseFileName }}" data-permalink="{{ .RelPermalink }}">🔗 |
| 682 | + Share</button> |
613 | 683 | <a href="#" class="back-to-top">🔝</a> |
614 | 684 | </div> |
615 | 685 | </div> |
|
664 | 734 | const poster = document.getElementById('poster'); |
665 | 735 | const frameToggle = document.getElementById('frame-toggle'); |
666 | 736 | const frameItems = document.querySelectorAll('.frame-item'); |
| 737 | + const helpToggle = document.getElementById('help-toggle'); |
| 738 | + const helpContainer = document.getElementById('help-container'); |
| 739 | + const helpClose = helpContainer.querySelector('.help-close'); |
667 | 740 |
|
668 | 741 | window.addEventListener('resize', positionMarkers); |
669 | 742 | if (poster.complete) { |
|
677 | 750 | } |
678 | 751 |
|
679 | 752 | // Frame mode toggle |
680 | | - frameToggle.addEventListener('click', function() { |
| 753 | + frameToggle.addEventListener('click', function () { |
681 | 754 | document.body.classList.toggle('frame-mode'); |
682 | 755 | this.classList.toggle('active'); |
683 | 756 | this.textContent = this.classList.contains('active') ? 'Hide All' : 'Show All'; |
684 | 757 | // Reposition markers after layout change |
685 | 758 | setTimeout(positionMarkers, 50); |
686 | 759 | }); |
687 | 760 |
|
| 761 | + // Help toggle |
| 762 | + helpToggle.addEventListener('click', function (e) { |
| 763 | + e.preventDefault(); |
| 764 | + helpContainer.classList.add('active'); |
| 765 | + }); |
| 766 | + |
| 767 | + helpClose.addEventListener('click', function () { |
| 768 | + helpContainer.classList.remove('active'); |
| 769 | + }); |
| 770 | + |
| 771 | + // Close help when clicking outside |
| 772 | + document.addEventListener('click', function (e) { |
| 773 | + if (helpContainer.classList.contains('active') && |
| 774 | + !helpContainer.contains(e.target) && |
| 775 | + e.target !== helpToggle) { |
| 776 | + helpContainer.classList.remove('active'); |
| 777 | + } |
| 778 | + }); |
| 779 | + |
688 | 780 | // Bidirectional highlighting: frame items -> markers |
689 | 781 | frameItems.forEach(item => { |
690 | 782 | const markerNum = item.getAttribute('data-marker-number'); |
691 | 783 | const marker = document.querySelector(`.marker[data-number="${markerNum}"]`); |
692 | 784 |
|
693 | | - item.addEventListener('mouseenter', function() { |
| 785 | + item.addEventListener('mouseenter', function () { |
694 | 786 | if (marker) marker.classList.add('highlight'); |
695 | 787 | }); |
696 | 788 |
|
697 | | - item.addEventListener('mouseleave', function() { |
| 789 | + item.addEventListener('mouseleave', function () { |
698 | 790 | if (marker) marker.classList.remove('highlight'); |
699 | 791 | }); |
700 | 792 |
|
701 | 793 | // Click opens the detail panel |
702 | | - item.addEventListener('click', function() { |
| 794 | + item.addEventListener('click', function () { |
703 | 795 | if (marker) marker.click(); |
704 | 796 | }); |
705 | 797 | }); |
|
709 | 801 | const markerNum = marker.getAttribute('data-number'); |
710 | 802 | const frameItem = document.querySelector(`.frame-item[data-marker-number="${markerNum}"]`); |
711 | 803 |
|
712 | | - marker.addEventListener('mouseenter', function() { |
| 804 | + marker.addEventListener('mouseenter', function () { |
713 | 805 | if (frameItem && document.body.classList.contains('frame-mode')) { |
714 | 806 | frameItem.classList.add('highlight'); |
715 | | - frameItem.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); |
| 807 | + frameItem.scrollIntoView({behavior: 'smooth', block: 'nearest'}); |
716 | 808 | } |
717 | 809 | }); |
718 | 810 |
|
719 | | - marker.addEventListener('mouseleave', function() { |
| 811 | + marker.addEventListener('mouseleave', function () { |
720 | 812 | if (frameItem) frameItem.classList.remove('highlight'); |
721 | 813 | }); |
722 | 814 | }); |
|
749 | 841 | window.addEventListener('hashchange', handleHashChange); |
750 | 842 |
|
751 | 843 | document.querySelectorAll('.share-btn').forEach(btn => { |
752 | | - btn.addEventListener('click', function() { |
| 844 | + btn.addEventListener('click', function () { |
753 | 845 | const hash = this.getAttribute('data-hash'); |
754 | 846 | const permalink = this.getAttribute('data-permalink'); |
755 | 847 | const baseUrl = window.location.origin + window.location.pathname; |
|
0 commit comments