@gaulatti/giorgia 0.1.57

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.
Files changed (194) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +45 -0
  3. package/dist/carousels.d.ts +1 -0
  4. package/dist/carousels.js +65 -0
  5. package/dist/components/live-program/LiveProgram.d.ts +9 -0
  6. package/dist/components/live-program/LiveProgram.js +751 -0
  7. package/dist/components/live-program/assets.d.ts +14 -0
  8. package/dist/components/live-program/assets.js +14 -0
  9. package/dist/components/live-program/components/Marquee.d.ts +16 -0
  10. package/dist/components/live-program/components/Marquee.js +88 -0
  11. package/dist/components/live-program/components/MarqueeCurtain.d.ts +5 -0
  12. package/dist/components/live-program/components/MarqueeCurtain.js +30 -0
  13. package/dist/components/live-program/components/WorldClocks.d.ts +19 -0
  14. package/dist/components/live-program/components/WorldClocks.js +101 -0
  15. package/dist/components/live-program/components/slides/ArticleSlide.d.ts +14 -0
  16. package/dist/components/live-program/components/slides/ArticleSlide.js +32 -0
  17. package/dist/components/live-program/components/slides/CallsignSlide.d.ts +6 -0
  18. package/dist/components/live-program/components/slides/CallsignSlide.js +49 -0
  19. package/dist/components/live-program/components/slides/LiveEventSlide.d.ts +9 -0
  20. package/dist/components/live-program/components/slides/LiveEventSlide.js +86 -0
  21. package/dist/components/live-program/components/slides/slideStyles.d.ts +1 -0
  22. package/dist/components/live-program/components/slides/slideStyles.js +64 -0
  23. package/dist/components/live-program/events.d.ts +34 -0
  24. package/dist/components/live-program/events.js +167 -0
  25. package/dist/components/live-program/hooks/useSSE.d.ts +11 -0
  26. package/dist/components/live-program/hooks/useSSE.js +107 -0
  27. package/dist/components/live-program/i18n.d.ts +4 -0
  28. package/dist/components/live-program/i18n.js +305 -0
  29. package/dist/components/live-program/segments/ArticlesSegment.d.ts +6 -0
  30. package/dist/components/live-program/segments/ArticlesSegment.js +160 -0
  31. package/dist/components/live-program/segments/EarthquakeSegment.d.ts +16 -0
  32. package/dist/components/live-program/segments/EarthquakeSegment.js +130 -0
  33. package/dist/components/live-program/segments/LiveEventSegment.d.ts +4 -0
  34. package/dist/components/live-program/segments/LiveEventSegment.js +27 -0
  35. package/dist/components/live-program/segments/MarketsSegment.d.ts +12 -0
  36. package/dist/components/live-program/segments/MarketsSegment.js +76 -0
  37. package/dist/components/live-program/segments/WeatherSegment.d.ts +15 -0
  38. package/dist/components/live-program/segments/WeatherSegment.js +119 -0
  39. package/dist/components/live-program/segments/fetchLiveEvents.d.ts +20 -0
  40. package/dist/components/live-program/segments/fetchLiveEvents.js +76 -0
  41. package/dist/components/live-program/segments/index.d.ts +8 -0
  42. package/dist/components/live-program/segments/index.js +8 -0
  43. package/dist/components/live-program/segments/types.d.ts +23 -0
  44. package/dist/components/live-program/segments/types.js +1 -0
  45. package/dist/components/live-program/segments/usePlaylistEngine.d.ts +9 -0
  46. package/dist/components/live-program/segments/usePlaylistEngine.js +108 -0
  47. package/dist/components/live-program/utils/broadcastTime.d.ts +12 -0
  48. package/dist/components/live-program/utils/broadcastTime.js +33 -0
  49. package/dist/fonts/LDIcapOFNxEwR-Bd1O9uYNmnUQomAgE25imKSbHhROjLsZBWTSrQGD_jZtU.ttf +0 -0
  50. package/dist/fonts/LDIcapOFNxEwR-Bd1O9uYNmnUQomAgE25imKSbHhROjLsZBWTSrQGFPjZtU.ttf +0 -0
  51. package/dist/fonts/LDIcapOFNxEwR-Bd1O9uYNmnUQomAgE25imKSbHhROjLsZBWTSrQGGHiZtU.ttf +0 -0
  52. package/dist/fonts/LDIcapOFNxEwR-Bd1O9uYNmnUQomAgE25imKSbHhROjLsZBWTSrQGGHjZtU.ttf +0 -0
  53. package/dist/fonts/LDIcapOFNxEwR-Bd1O9uYNmnUQomAgE25imKSbHhROjLsZBWTSrQGIbkZtU.ttf +0 -0
  54. package/dist/fonts/LDIcapOFNxEwR-Bd1O9uYNmnUQomAgE25imKSbHhROjLsZBWTSrQGL_kZtU.ttf +0 -0
  55. package/dist/fonts/LDIcapOFNxEwR-Bd1O9uYNmnUQomAgE25imKSbHhROjLsZBWTSrQGMjkZtU.ttf +0 -0
  56. package/dist/fonts/LDIcapOFNxEwR-Bd1O9uYNmnUQomAgE25imKSbHhROjLsZBWTSrQGOHjZtU.ttf +0 -0
  57. package/dist/fonts/LDIcapOFNxEwR-Bd1O9uYNmnUQomAgE25imKSbHhROjLsZBWTSrQGOHkZtU.ttf +0 -0
  58. package/dist/fonts/SlGDmQSNjdsmc35JDF1K5E55YMjF_7DPuGi-2fRUAw.ttf +0 -0
  59. package/dist/fonts/SlGDmQSNjdsmc35JDF1K5E55YMjF_7DPuGi-6_RUAw.ttf +0 -0
  60. package/dist/fonts/SlGDmQSNjdsmc35JDF1K5E55YMjF_7DPuGi-DPNUAw.ttf +0 -0
  61. package/dist/fonts/SlGDmQSNjdsmc35JDF1K5E55YMjF_7DPuGi-NfNUAw.ttf +0 -0
  62. package/dist/fonts/SlGDmQSNjdsmc35JDF1K5E55YMjF_7DPuGi-a_NUAw.ttf +0 -0
  63. package/dist/fonts/SlGFmQSNjdsmc35JDF1K5GRwUjcdlttVFm-rI7c8R496.ttf +0 -0
  64. package/dist/fonts/SlGFmQSNjdsmc35JDF1K5GRwUjcdlttVFm-rI7dbR496.ttf +0 -0
  65. package/dist/fonts/SlGFmQSNjdsmc35JDF1K5GRwUjcdlttVFm-rI7diR496.ttf +0 -0
  66. package/dist/fonts/SlGFmQSNjdsmc35JDF1K5GRwUjcdlttVFm-rI7e8QI96.ttf +0 -0
  67. package/dist/fonts/SlGFmQSNjdsmc35JDF1K5GRwUjcdlttVFm-rI7eOQI96.ttf +0 -0
  68. package/dist/fonts/TK3_WkUHHAIjg75cFRf3bXL8LICs13FvgUE.ttf +0 -0
  69. package/dist/fonts/TK3_WkUHHAIjg75cFRf3bXL8LICs169vgUE.ttf +0 -0
  70. package/dist/fonts/TK3_WkUHHAIjg75cFRf3bXL8LICs18NvgUE.ttf +0 -0
  71. package/dist/fonts/TK3_WkUHHAIjg75cFRf3bXL8LICs1_FvgUE.ttf +0 -0
  72. package/dist/fonts/TK3_WkUHHAIjg75cFRf3bXL8LICs1xZogUE.ttf +0 -0
  73. package/dist/fonts/TK3_WkUHHAIjg75cFRf3bXL8LICs1y9ogUE.ttf +0 -0
  74. package/dist/fonts/fonts.css +378 -0
  75. package/dist/fonts/j8_16_LD37rqfuwxyIuaZhE6cRXOLtm2gfTGgQ.ttf +0 -0
  76. package/dist/fonts/j8_46_LD37rqfuwxyIuaZhE6cRXOLtm2gfT-BYipBw.ttf +0 -0
  77. package/dist/fonts/j8_46_LD37rqfuwxyIuaZhE6cRXOLtm2gfT-IYmpBw.ttf +0 -0
  78. package/dist/fonts/j8_46_LD37rqfuwxyIuaZhE6cRXOLtm2gfT-PYqpBw.ttf +0 -0
  79. package/dist/fonts/j8_46_LD37rqfuwxyIuaZhE6cRXOLtm2gfT-WYupBw.ttf +0 -0
  80. package/dist/fonts/jizMREVItHgc8qDIbSTKq4XkRiUawTk7f45UM9y05oYiRNDM.ttf +0 -0
  81. package/dist/fonts/jizMREVItHgc8qDIbSTKq4XkRiUawTk7f45UM9y05oZ8RNDM.ttf +0 -0
  82. package/dist/fonts/jizMREVItHgc8qDIbSTKq4XkRiUawTk7f45UM9y05oZ8RdDM.ttf +0 -0
  83. package/dist/fonts/jizMREVItHgc8qDIbSTKq4XkRiUawTk7f45UM9y05oZORNDM.ttf +0 -0
  84. package/dist/fonts/jizMREVItHgc8qDIbSTKq4XkRiUawTk7f45UM9y05oabQ9DM.ttf +0 -0
  85. package/dist/fonts/jizMREVItHgc8qDIbSTKq4XkRiUawTk7f45UM9y05oaiQ9DM.ttf +0 -0
  86. package/dist/fonts/jizMREVItHgc8qDIbSTKq4XkRiUawTk7f45UM9y05ob8Q9DM.ttf +0 -0
  87. package/dist/fonts/jizMREVItHgc8qDIbSTKq4XkRiUawTk7f45UM9y05ob8RNDM.ttf +0 -0
  88. package/dist/fonts/jizMREVItHgc8qDIbSTKq4XkRiUawTk7f45UM9y05obVQ9DM.ttf +0 -0
  89. package/dist/fonts/jizOREVItHgc8qDIbSTKq4XkRg8T88bjFuXOnduh8MKUBw.ttf +0 -0
  90. package/dist/fonts/jizOREVItHgc8qDIbSTKq4XkRg8T88bjFuXOnduhHMWUBw.ttf +0 -0
  91. package/dist/fonts/jizOREVItHgc8qDIbSTKq4XkRg8T88bjFuXOnduhLsSUBw.ttf +0 -0
  92. package/dist/fonts/jizOREVItHgc8qDIbSTKq4XkRg8T88bjFuXOnduhLsWUBw.ttf +0 -0
  93. package/dist/fonts/jizOREVItHgc8qDIbSTKq4XkRg8T88bjFuXOnduhcMWUBw.ttf +0 -0
  94. package/dist/fonts/jizOREVItHgc8qDIbSTKq4XkRg8T88bjFuXOnduhh8KUBw.ttf +0 -0
  95. package/dist/fonts/jizOREVItHgc8qDIbSTKq4XkRg8T88bjFuXOnduhrsKUBw.ttf +0 -0
  96. package/dist/fonts/jizOREVItHgc8qDIbSTKq4XkRg8T88bjFuXOnduhrsWUBw.ttf +0 -0
  97. package/dist/fonts/jizOREVItHgc8qDIbSTKq4XkRg8T88bjFuXOnduhycKUBw.ttf +0 -0
  98. package/dist/homepage-distributor.d.ts +55 -0
  99. package/dist/homepage-distributor.js +68 -0
  100. package/dist/instagram-image-template.d.ts +9 -0
  101. package/dist/instagram-image-template.js +51 -0
  102. package/dist/live-program/main.d.ts +1 -0
  103. package/dist/live-program/main.js +10 -0
  104. package/dist/live-program-page/fifthbell/audio/pipes.ogg +0 -0
  105. package/dist/live-program-page/fifthbell/images/berlin.jpg +0 -0
  106. package/dist/live-program-page/fifthbell/images/fifthbell.png +0 -0
  107. package/dist/live-program-page/fifthbell/images/nyc.jpg +0 -0
  108. package/dist/live-program-page/fifthbell/images/nyse.jpg +0 -0
  109. package/dist/live-program-page/fifthbell/images/santiago.jpg +0 -0
  110. package/dist/live-program-page/fifthbell/images/seismograph.jpg +0 -0
  111. package/dist/live-program-page/fifthbell/images/tokyo.jpg +0 -0
  112. package/dist/live-program-page/index.html +16 -0
  113. package/dist/live-program-page/live-program.css +3 -0
  114. package/dist/live-program-page/live-program.js +76 -0
  115. package/dist/outlet-config.d.ts +29 -0
  116. package/dist/outlet-config.js +29 -0
  117. package/dist/renderer.browser.d.ts +2 -0
  118. package/dist/renderer.browser.js +132 -0
  119. package/dist/renderer.core.d.ts +9 -0
  120. package/dist/renderer.core.js +354 -0
  121. package/dist/renderer.d.ts +6 -0
  122. package/dist/renderer.js +4 -0
  123. package/dist/renderer.node.d.ts +16 -0
  124. package/dist/renderer.node.js +166 -0
  125. package/dist/types/canonical-article.d.ts +249 -0
  126. package/dist/types/canonical-article.js +236 -0
  127. package/dist/utils/sofascore.d.ts +3 -0
  128. package/dist/utils/sofascore.js +31 -0
  129. package/dist/version.d.ts +1 -0
  130. package/dist/version.js +4 -0
  131. package/package.json +89 -0
  132. package/src/partial-deps.json +53 -0
  133. package/src/styles/compiled.css +2 -0
  134. package/src/templates/layouts/404.hbs +5 -0
  135. package/src/templates/layouts/article-page.hbs +5 -0
  136. package/src/templates/layouts/category-page.hbs +5 -0
  137. package/src/templates/layouts/homepage.hbs +5 -0
  138. package/src/templates/layouts/link-in-bio.hbs +226 -0
  139. package/src/templates/layouts/live-story.hbs +5 -0
  140. package/src/templates/layouts/media-page.hbs +5 -0
  141. package/src/templates/layouts/search-page.hbs +5 -0
  142. package/src/templates/partials/blocks/audio.hbs +12 -0
  143. package/src/templates/partials/blocks/data-table.hbs +23 -0
  144. package/src/templates/partials/blocks/divider.hbs +1 -0
  145. package/src/templates/partials/blocks/heading.hbs +9 -0
  146. package/src/templates/partials/blocks/image.hbs +6 -0
  147. package/src/templates/partials/blocks/info-box.hbs +8 -0
  148. package/src/templates/partials/blocks/instagram.hbs +28 -0
  149. package/src/templates/partials/blocks/key-points.hbs +8 -0
  150. package/src/templates/partials/blocks/list.hbs +13 -0
  151. package/src/templates/partials/blocks/live-update.hbs +24 -0
  152. package/src/templates/partials/blocks/pull-quote.hbs +6 -0
  153. package/src/templates/partials/blocks/rich-text.hbs +1 -0
  154. package/src/templates/partials/blocks/tiktok.hbs +15 -0
  155. package/src/templates/partials/blocks/x.hbs +74 -0
  156. package/src/templates/partials/blocks/youtube.hbs +12 -0
  157. package/src/templates/partials/components/article-main.hbs +159 -0
  158. package/src/templates/partials/components/breaking-news/live-updates-column.hbs +29 -0
  159. package/src/templates/partials/components/breaking-news.hbs +56 -0
  160. package/src/templates/partials/components/category/header.hbs +5 -0
  161. package/src/templates/partials/components/category/main-grid.hbs +55 -0
  162. package/src/templates/partials/components/category/main.hbs +7 -0
  163. package/src/templates/partials/components/category/more-grid.hbs +26 -0
  164. package/src/templates/partials/components/editorial-hero.hbs +73 -0
  165. package/src/templates/partials/components/headline.hbs +15 -0
  166. package/src/templates/partials/components/hero-editorial.hbs +1 -0
  167. package/src/templates/partials/components/hero.hbs +1 -0
  168. package/src/templates/partials/components/home/landing.hbs +111 -0
  169. package/src/templates/partials/components/home/main.hbs +63 -0
  170. package/src/templates/partials/components/home/more-stories.hbs +23 -0
  171. package/src/templates/partials/components/home/must-read.hbs +77 -0
  172. package/src/templates/partials/components/live-story/main.hbs +229 -0
  173. package/src/templates/partials/components/media/main.hbs +220 -0
  174. package/src/templates/partials/components/not-found/main.hbs +28 -0
  175. package/src/templates/partials/components/search/main.hbs +420 -0
  176. package/src/templates/partials/components/snack.hbs +92 -0
  177. package/src/templates/partials/components/spotlight-hero.hbs +59 -0
  178. package/src/templates/partials/components/trending.hbs +14 -0
  179. package/src/templates/partials/components/ui/accordion.hbs +30 -0
  180. package/src/templates/partials/components/ui/breadcrumb.hbs +16 -0
  181. package/src/templates/partials/components/ui/icon-button.hbs +19 -0
  182. package/src/templates/partials/components/ui/loading-spinner.hbs +27 -0
  183. package/src/templates/partials/components/ui/pagination.hbs +56 -0
  184. package/src/templates/partials/components/ui/scroll-area.hbs +12 -0
  185. package/src/templates/partials/components/ui/status-badge.hbs +21 -0
  186. package/src/templates/partials/footers/footer-full.hbs +79 -0
  187. package/src/templates/partials/footers/footer-minimal.hbs +5 -0
  188. package/src/templates/partials/headers/header-main.hbs +400 -0
  189. package/src/templates/partials/headers/header-minimal.hbs +16 -0
  190. package/src/templates/partials/nav/nav-categories.hbs +5 -0
  191. package/src/templates/partials/shell/doc-end.hbs +282 -0
  192. package/src/templates/partials/shell/doc-start-404.hbs +41 -0
  193. package/src/templates/partials/shell/doc-start-standard.hbs +86 -0
  194. package/src/templates/templates/instagram-image.hbs +175 -0
@@ -0,0 +1,400 @@
1
+ <header
2
+ class='border-b border-slate-200 dark:border-slate-700 relative z-[60] bg-white dark:bg-slate-900 transition-colors'
3
+ style='view-transition-name: site-header;'
4
+ >
5
+ <div class='container mx-auto px-4'>
6
+ <nav class='flex items-center justify-between h-16'>
7
+ <div class='flex items-center space-x-8'>
8
+ <div class='relative'>
9
+ <button
10
+ id='menu-button'
11
+ class='flex items-center space-x-2 p-2 hover:bg-slate-100 dark:hover:bg-slate-800 transition-colors text-black dark:text-white'
12
+ aria-label='Menu'
13
+ aria-expanded='false'
14
+ type='button'
15
+ >
16
+ <svg class='w-4 h-4' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'>
17
+ <line x1='3' y1='6' x2='21' y2='6'></line>
18
+ <line x1='3' y1='12' x2='21' y2='12'></line>
19
+ <line x1='3' y1='18' x2='21' y2='18'></line>
20
+ </svg>
21
+ </button>
22
+
23
+ <div
24
+ id='dropdown-menu'
25
+ class='fixed top-16 left-0 right-0 bottom-0 bg-white/98 dark:bg-slate-900/98 backdrop-blur-md shadow-lg z-50 pointer-events-none border-t border-slate-200 dark:border-slate-700 overflow-hidden transition-colors'
26
+ style='opacity: 0; transform: translateX(-100%); transition: transform 600ms ease-out, opacity 300ms ease-out 300ms;'
27
+ >
28
+ <div class='container mx-auto px-4 py-4 md:py-8 h-full overflow-y-auto overscroll-contain'>
29
+ <div class='grid grid-cols-1 lg:grid-cols-5 gap-6 lg:gap-8'>
30
+ <div class='lg:col-span-1'>
31
+ <h3
32
+ class='text-xs font-bold text-slate-400 dark:text-slate-600 uppercase tracking-wider mb-4 border-b border-slate-200 dark:border-slate-800 pb-2'
33
+ >SECTIONS</h3>
34
+ <div id='sections-links' class='space-y-3'>
35
+ <a
36
+ href='{{logoLink}}'
37
+ class='block text-lg font-bold text-black dark:text-white hover:text-[#8f0d00] dark:hover:text-[#ff2e1a] transition-colors'
38
+ >TOP STORIES</a>
39
+ <div id='category-links-container' class='space-y-3'>
40
+ <p class='text-sm text-slate-400 dark:text-slate-500'>Loading sections...</p>
41
+ </div>
42
+ </div>
43
+
44
+ <div class='mt-8 pt-6 border-t border-slate-200 dark:border-slate-800'>
45
+ <h3 class='text-xs font-bold text-slate-400 dark:text-slate-600 uppercase tracking-wider mb-4'>FOLLOW US</h3>
46
+ <div class='flex items-center gap-3'>
47
+ <a
48
+ href='https://bsky.app/profile/fifthbell.com'
49
+ target='_blank'
50
+ rel='noopener noreferrer'
51
+ class='text-slate-600 dark:text-slate-400 hover:text-[#0085ff] dark:hover:text-[#0085ff] transition-colors'
52
+ aria-label='Follow us on Bluesky'
53
+ >
54
+ <svg class='w-5 h-5' viewBox='0 0 600 530' fill='currentColor' xmlns='http://www.w3.org/2000/svg'>
55
+ <path
56
+ d='M135.72 44.03c66.496 49.921 138.02 151.14 164.28 205.46 26.262-54.316 97.782-155.54 164.28-205.46 47.98-36.021 125.72-63.892 125.72 24.795 0 17.712-10.155 148.79-16.111 170.07-20.703 73.984-96.144 92.854-163.25 81.433 117.3 19.964 147.14 86.092 82.697 152.22-122.39 125.59-175.91-31.511-189.63-71.766-2.514-7.3797-3.6904-10.832-3.7077-7.8964-.0174-2.9357-1.1937.51669-3.7077 7.8964-13.714 40.255-67.233 197.36-189.63 71.766-64.444-66.128-34.605-132.26 82.697-152.22-67.108 11.421-142.55-7.4491-163.25-81.433-5.9562-21.282-16.111-152.36-16.111-170.07 0-88.687 77.742-60.816 125.72-24.795z'
57
+ ></path>
58
+ </svg>
59
+ </a>
60
+ <a
61
+ href='https://x.com/thisisfifthbell'
62
+ target='_blank'
63
+ rel='noopener noreferrer'
64
+ class='text-slate-600 dark:text-slate-400 hover:text-[#000000] dark:hover:text-[#ffffff] transition-colors'
65
+ aria-label='Follow us on X (Twitter)'
66
+ >
67
+ <svg class='w-5 h-5' viewBox='0 0 24 24' fill='currentColor' xmlns='http://www.w3.org/2000/svg'>
68
+ <path
69
+ d='M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z'
70
+ ></path>
71
+ </svg>
72
+ </a>
73
+ <a
74
+ href='https://instagram.com/thisisfifthbell'
75
+ target='_blank'
76
+ rel='noopener noreferrer'
77
+ class='text-slate-600 dark:text-slate-400 hover:text-[#E4405F] dark:hover:text-[#E4405F] transition-colors'
78
+ aria-label='Follow us on Instagram'
79
+ >
80
+ <svg class='w-5 h-5' viewBox='0 0 24 24' fill='currentColor' xmlns='http://www.w3.org/2000/svg'>
81
+ <path
82
+ d='M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z'
83
+ ></path>
84
+ </svg>
85
+ </a>
86
+ <a
87
+ href='https://www.youtube.com/@thisisfifthbell'
88
+ target='_blank'
89
+ rel='noopener noreferrer'
90
+ class='text-slate-600 dark:text-slate-400 hover:text-[#FF0000] dark:hover:text-[#FF0000] transition-colors'
91
+ aria-label='Subscribe on YouTube'
92
+ >
93
+ <svg class='w-5 h-5' viewBox='0 0 24 24' fill='currentColor' xmlns='http://www.w3.org/2000/svg'>
94
+ <path
95
+ d='M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z'
96
+ ></path>
97
+ </svg>
98
+ </a>
99
+ </div>
100
+ </div>
101
+
102
+ {{#unless mourningMode}}
103
+ <div class='mt-8 pt-6 border-t border-slate-200 dark:border-slate-800'>
104
+ <h3 class='text-xs font-bold text-slate-400 dark:text-slate-600 uppercase tracking-wider mb-4'>THEME</h3>
105
+ <div class='flex items-center gap-2'>
106
+ <button
107
+ id='theme-light'
108
+ class='theme-btn flex items-center justify-center p-2 rounded hover:bg-slate-100 dark:hover:bg-slate-800 transition-colors text-slate-700 dark:text-slate-300'
109
+ aria-label='Light mode'
110
+ data-theme='light'
111
+ type='button'
112
+ >
113
+ <svg
114
+ class='w-5 h-5'
115
+ viewBox='0 0 24 24'
116
+ fill='none'
117
+ stroke='currentColor'
118
+ stroke-width='2'
119
+ stroke-linecap='round'
120
+ stroke-linejoin='round'
121
+ >
122
+ <circle cx='12' cy='12' r='4'></circle>
123
+ <path d='M12 2v2'></path>
124
+ <path d='M12 20v2'></path>
125
+ <path d='m4.93 4.93 1.41 1.41'></path>
126
+ <path d='m17.66 17.66 1.41 1.41'></path>
127
+ <path d='M2 12h2'></path>
128
+ <path d='M20 12h2'></path>
129
+ <path d='m6.34 17.66-1.41 1.41'></path>
130
+ <path d='m19.07 4.93-1.41 1.41'></path>
131
+ </svg>
132
+ </button>
133
+ <button
134
+ id='theme-dark'
135
+ class='theme-btn flex items-center justify-center p-2 rounded hover:bg-slate-100 dark:hover:bg-slate-800 transition-colors text-slate-700 dark:text-slate-300'
136
+ aria-label='Dark mode'
137
+ data-theme='dark'
138
+ type='button'
139
+ >
140
+ <svg
141
+ class='w-5 h-5'
142
+ viewBox='0 0 24 24'
143
+ fill='none'
144
+ stroke='currentColor'
145
+ stroke-width='2'
146
+ stroke-linecap='round'
147
+ stroke-linejoin='round'
148
+ >
149
+ <path d='M12 3a6 6 0 1 0 9 9 9 9 0 1 1-9-9z'></path>
150
+ </svg>
151
+ </button>
152
+ <button
153
+ id='theme-system'
154
+ class='theme-btn flex items-center justify-center p-2 rounded hover:bg-slate-100 dark:hover:bg-slate-800 transition-colors text-slate-700 dark:text-slate-300'
155
+ aria-label='System theme'
156
+ data-theme='system'
157
+ type='button'
158
+ >
159
+ <svg
160
+ class='w-5 h-5'
161
+ viewBox='0 0 24 24'
162
+ fill='none'
163
+ stroke='currentColor'
164
+ stroke-width='2'
165
+ stroke-linecap='round'
166
+ stroke-linejoin='round'
167
+ >
168
+ <rect x='2' y='3' width='20' height='14' rx='2' ry='2'></rect>
169
+ <line x1='8' y1='21' x2='16' y2='21'></line>
170
+ <line x1='12' y1='17' x2='12' y2='21'></line>
171
+ </svg>
172
+ </button>
173
+ </div>
174
+ </div>
175
+ {{/unless}}
176
+
177
+ <div class='mt-8 pt-6 border-t border-slate-200 dark:border-slate-800'>
178
+ <h3 class='text-xs font-bold text-slate-400 dark:text-slate-600 uppercase tracking-wider mb-4'>LANGUAGE</h3>
179
+ <div class='flex items-center gap-2'>
180
+ <button
181
+ class='lang-btn flex items-center justify-center px-3 py-2 rounded hover:bg-slate-100 dark:hover:bg-slate-800 transition-colors text-slate-700 dark:text-slate-300 font-medium text-sm'
182
+ aria-label='English'
183
+ data-lang='en'
184
+ type='button'
185
+ >
186
+ EN
187
+ </button>
188
+ <button
189
+ class='lang-btn flex items-center justify-center px-3 py-2 rounded hover:bg-slate-100 dark:hover:bg-slate-800 transition-colors text-slate-700 dark:text-slate-300 font-medium text-sm'
190
+ aria-label='Español'
191
+ data-lang='es'
192
+ type='button'
193
+ >
194
+ ES
195
+ </button>
196
+ <button
197
+ class='lang-btn flex items-center justify-center px-3 py-2 rounded hover:bg-slate-100 dark:hover:bg-slate-800 transition-colors text-slate-700 dark:text-slate-300 font-medium text-sm'
198
+ aria-label='Italiano'
199
+ data-lang='it'
200
+ type='button'
201
+ >
202
+ IT
203
+ </button>
204
+ </div>
205
+ </div>
206
+ </div>
207
+
208
+ <div id='mini-featured' class='lg:col-span-4 hidden lg:block'>
209
+ <div class='flex flex-col items-center justify-center py-20'>
210
+ <div class='animate-spin rounded-full h-12 w-12 border-b-2 border-slate-300 dark:border-slate-600'></div>
211
+ <p class='text-slate-400 dark:text-slate-500 mt-4'>Loading stories...</p>
212
+ </div>
213
+ </div>
214
+ </div>
215
+ </div>
216
+ </div>
217
+ </div>
218
+ </div>
219
+
220
+ <div class='absolute left-1/2 transform -translate-x-1/2 {{#if mourningMode}}bg-black{{else}}bg-[#b21100]{{/if}} text-white p-3'>
221
+ <a href='{{logoLink}}' aria-label='fifthbell - Home'>
222
+ <svg class='w-7 h-7' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'>
223
+ <path d='M10.268 21a2 2 0 0 0 3.464 0'></path>
224
+ <path d='M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326'></path>
225
+ <path d='M4 2C2.8 3.7 2 5.7 2 8'></path>
226
+ <path d='M22 8a10 10 0 0 0-2-6'></path>
227
+ </svg>
228
+ </a>
229
+ </div>
230
+
231
+ <div class='flex items-center space-x-4'>
232
+ <a
233
+ href='{{#if (eq language "en")}}/search{{else}}/{{language}}/search{{/if}}'
234
+ class='flex items-center justify-center p-2 border border-slate-300 dark:border-slate-700 hover:bg-slate-100 dark:hover:bg-slate-800 transition-colors text-slate-700 dark:text-slate-200'
235
+ aria-label='Search'
236
+ >
237
+ <svg class='w-4 h-4' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'>
238
+ <circle cx='11' cy='11' r='8'></circle>
239
+ <line x1='21' y1='21' x2='16.65' y2='16.65'></line>
240
+ </svg>
241
+ </a>
242
+ <form
243
+ class='hidden md:flex items-center'
244
+ role='search'
245
+ action='{{#if (eq language "en")}}/search{{else}}/{{language}}/search{{/if}}'
246
+ method='get'
247
+ >
248
+ <label for='header-search-input' class='sr-only'>Search</label>
249
+ <input
250
+ id='header-search-input'
251
+ name='q'
252
+ type='search'
253
+ autocomplete='off'
254
+ spellcheck='false'
255
+ placeholder='Search'
256
+ class='w-44 lg:w-56 px-3 py-2 border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm text-slate-900 dark:text-slate-100 placeholder:text-slate-400 dark:placeholder:text-slate-500 focus:outline-none focus:ring-2 focus:ring-[#b21100]/40'
257
+ />
258
+ </form>
259
+ <a
260
+ href='https://www.youtube.com/watch?v=-eYi7dd8VRY'
261
+ target='_blank'
262
+ rel='noopener noreferrer'
263
+ class='hidden md:flex items-center space-x-2 {{#if mourningMode}}bg-gray-600 hover:bg-gray-500{{else}}bg-[#b21100] hover:bg-[#8f0d00]{{/if}} text-white px-4 py-2 rounded font-bold transition-colors uppercase tracking-wide text-sm'
264
+ >
265
+ <svg class='w-5 h-5' viewBox='0 0 24 24' fill='currentColor'>
266
+ <path d='M8 5v14l11-7z'></path>
267
+ </svg>
268
+ <span>Watch Live</span>
269
+ </a>
270
+ </div>
271
+ </nav>
272
+ </div>
273
+ </header>
274
+
275
+ <script>
276
+ (function () { const menuButton = document.getElementById('menu-button'); const dropdownMenu = document.getElementById('dropdown-menu'); const sectionsLinks =
277
+ document.getElementById('sections-links'); const categoryLinksContainer = document.getElementById('category-links-container'); const miniFeatured =
278
+ document.getElementById('mini-featured'); if (!menuButton || !dropdownMenu) return; let isOpen = false; let contentLoaded = false; let currentCategoryKey =
279
+ '__home__'; let activeCategorySlug = ''; let requestVersion = 0; const cache = new Map(); function getCurrentLang() { const p = window.location.pathname ||
280
+ '/'; if (p.startsWith('/es')) return 'es'; if (p.startsWith('/it')) return 'it'; return 'en'; } function buildLocalePath(slug) { const lang =
281
+ getCurrentLang(); if (!slug) return lang === 'en' ? '/' : `/${lang}`; const normalized = String(slug).startsWith('/') ? String(slug) : `/${slug}`; if
282
+ (normalized.startsWith('/es/') || normalized.startsWith('/it/')) return normalized; if (lang === 'en') return normalized; return `/${lang}${normalized}`; }
283
+ function normalizePathInput(value) { if (typeof value !== 'string') return ''; const trimmed = value.trim(); if (!trimmed) return ''; try { if
284
+ (/^https?:\/\//i.test(trimmed)) { const parsed = new URL(trimmed); const normalizedAbsolute = `/${(parsed.pathname || '').replace(/^\/+/,
285
+ '')}`.replace(/\/{2,}/g, '/'); if (normalizedAbsolute !== '/' && normalizedAbsolute.endsWith('/')) { return normalizedAbsolute.slice(0, -1); } return
286
+ normalizedAbsolute || '/'; } } catch { /* Fall back to raw string normalization below */ } const withoutQueryOrHash = trimmed.split('#')[0].split('?')[0]; const
287
+ normalized = `/${withoutQueryOrHash.replace(/^\/+/, '')}`.replace(/\/{2,}/g, '/'); if (normalized !== '/' && normalized.endsWith('/')) { return
288
+ normalized.slice(0, -1); } return normalized; } function cleanPathSegment(value) { if (typeof value !== 'string') return ''; return
289
+ value.trim().replace(/^\/+|\/+$/g, ''); } function getArticleLeafPath(article) { const explicitUrl = normalizePathInput(article?.url); if (explicitUrl &&
290
+ explicitUrl !== '/') { return buildLocalePath(explicitUrl); } const canonicalUrl = normalizePathInput(article?.canonicalUrl); if (canonicalUrl && canonicalUrl
291
+ !== '/') { return buildLocalePath(canonicalUrl); } const slugRaw = typeof article?.slug === 'string' ? article.slug : ''; const normalizedSlugPath =
292
+ normalizePathInput(slugRaw); const slugSegments = normalizedSlugPath.split('/').filter(Boolean); if (slugSegments.length > 1) { return
293
+ buildLocalePath(normalizedSlugPath); } const slugSegment = cleanPathSegment(slugRaw); const primaryCategorySlug =
294
+ cleanPathSegment(article?.categories?.[0]?.slug) || cleanPathSegment(article?.category?.slug); if (slugSegment && primaryCategorySlug) { return
295
+ buildLocalePath(`/${primaryCategorySlug}/${slugSegment}`); } if (slugSegment) { return buildLocalePath(`/${slugSegment}`); } return buildLocalePath('/'); }
296
+ function getCdnUrl(categorySlug) { const lang = getCurrentLang(); const file = categorySlug ? `${categorySlug}-current-${lang}.json` :
297
+ `homepage-current-${lang}.json`; return `https://cdn.fifthbell.com/content/${file}?v=${Date.now()}-${Math.random().toString(36).slice(2)}`; } function
298
+ getArticlesFromPayload(payload) { if (!payload || typeof payload !== 'object') return []; return payload.docs || payload.articles || []; } function
299
+ showCategoryLinksLoading() { if (!categoryLinksContainer) return; categoryLinksContainer.innerHTML = `<p class='text-sm text-slate-400
300
+ dark:text-slate-500'>Loading sections...</p>`; } function showCategoryLinksError() { if (!categoryLinksContainer) return; categoryLinksContainer.innerHTML =
301
+ `<p class='text-sm text-red-500'>Failed to load sections</p>`; } function setActiveCategoryLink(categorySlug) { if (!sectionsLinks) return; activeCategorySlug
302
+ = categorySlug || ''; const links = sectionsLinks.querySelectorAll('.category-link'); links.forEach((link) => { const isActive =
303
+ (link.getAttribute('data-category-slug') || '') === activeCategorySlug; if (isActive) { link.classList.add('text-[#8f0d00]', 'dark:text-[#ff2e1a]');
304
+ link.classList.remove('text-black', 'dark:text-white'); link.setAttribute('aria-current', 'page'); } else { link.classList.remove('text-[#8f0d00]',
305
+ 'dark:text-[#ff2e1a]'); link.classList.add('text-black', 'dark:text-white'); link.setAttribute('aria-current', 'false'); } }); } function
306
+ renderCategories(categories) { if (!categoryLinksContainer) return; if (!Array.isArray(categories) || categories.length === 0) {
307
+ categoryLinksContainer.innerHTML = `<p class='text-sm text-slate-400 dark:text-slate-500'>No sections available</p>`; return; }
308
+ categoryLinksContainer.innerHTML = categories .map( (category) => `<a href="${buildLocalePath(category.slug)}" class="category-link block text-lg font-bold
309
+ text-black dark:text-white hover:text-[#8f0d00] dark:hover:text-[#ff2e1a] transition-colors" data-category-slug="${category.slug}"
310
+ aria-current="false">${String(category.name || '').toUpperCase()}</a>` ) .join(''); setActiveCategoryLink(activeCategorySlug); } function
311
+ showMiniFeaturedLoading() { if (!miniFeatured) return; miniFeatured.innerHTML = ` <div class='flex flex-col items-center justify-center py-20'> <div
312
+ class='animate-spin rounded-full h-12 w-12 border-b-2 border-slate-300 dark:border-slate-600'></div> <p class='text-slate-400 dark:text-slate-500
313
+ mt-4'>Loading stories...</p> </div> `; } function renderMiniFeatured(articles, categoryName) { if (!miniFeatured) return; if (!Array.isArray(articles) ||
314
+ articles.length === 0) { miniFeatured.innerHTML = `<h3 class='text-xs font-bold text-slate-400 uppercase tracking-wider mb-6 border-b border-slate-200
315
+ dark:border-slate-800 pb-2'>${(categoryName || 'Featured Stories').toUpperCase()}</h3>` + `<p class='text-slate-400 dark:text-slate-500'>No stories
316
+ available</p>`; return; } const top = (articles || []).slice(0, 2); const grid = (articles || []).slice(2, 11); const topHtml = top .map( (article) => ` <div>
317
+ <div class='relative mb-5'> <img src='${article?.featuredImage?.url || ''}' alt='${article?.featuredImage?.alt || article?.title || ''}' class='w-full h-50
318
+ object-cover rounded' /> </div> <div class='flex items-center text-slate-500 dark:text-slate-400 text-sm mb-3'> <span class='uppercase font-bold
319
+ tracking-wider'>${article?.categories?.[0]?.name || categoryName || 'GENERAL'}</span> <span class='mx-2'>•</span> <span>5 min</span> </div> <h2 class='text-xl
320
+ font-bold text-slate-900 dark:text-slate-100 leading-tight'> <a href='${getArticleLeafPath(article)}' class='hover:text-[#8f0d00] dark:hover:text-[#ff2e1a]
321
+ transition-colors'>${article?.title || ''}</a> </h2> </div> ` ) .join(''); const rows = []; for (let i = 0; i < grid.length; i += 3) { const row =
322
+ grid.slice(i, i + 3); if (!row.length) continue; rows.push(` <div class='grid grid-cols-3 gap-6 ${i > 0 ? 'pt-6 border-t border-slate-200 dark:border-slate-800' : ''}'> ${row .map( (article, idx) => ` <div class='${idx === 0 ? 'pr-4 border-r border-slate-200 dark:border-slate-800' : idx === 1 ?
323
+ 'px-4 border-r border-slate-200 dark:border-slate-800' : 'pl-4'}'> <div class='flex items-center text-slate-500 dark:text-slate-400 text-sm mb-3'> <span
324
+ class='uppercase font-bold'>${article?.categories?.[0]?.name || categoryName || 'GENERAL'}</span> </div> <h3 class='font-medium text-base leading-tight
325
+ text-slate-900 dark:text-slate-100'> <a href='${getArticleLeafPath(article)}' class='hover:text-[#8f0d00] dark:hover:text-[#ff2e1a]
326
+ transition-colors'>${article?.title || ''}</a> </h3> </div> ` ) .join('')} </div> `); } miniFeatured.innerHTML = ` <h3 class='text-xs font-bold text-slate-400
327
+ dark:text-slate-600 uppercase tracking-wider mb-6 border-b border-slate-200 dark:border-slate-800 pb-2'> ${(categoryName || 'Featured Stories').toUpperCase()}
328
+ </h3> <div class='grid grid-cols-2 gap-8 mb-10'>${topHtml}</div> <div class='space-y-6'>${rows.join('')}</div> `; } function getCategoryName(payload,
329
+ categorySlug) { if (!categorySlug) return 'Featured Stories'; const fromPrimaryCategory = payload?.category?.name; if (fromPrimaryCategory) return
330
+ fromPrimaryCategory; const fromCategoriesArray = (payload?.categories || []).find((category) => category?.slug === categorySlug)?.name; if
331
+ (fromCategoriesArray) return fromCategoriesArray; return String(categorySlug).replace(/-/g, ' '); } async function fetchPayload(categorySlug) { const response
332
+ = await fetch(getCdnUrl(categorySlug), { headers: { 'Content-Type': 'application/json' } }); if (!response.ok) throw new Error(`Failed to fetch ${categorySlug
333
+ || 'homepage'} data`); return response.json(); } async function loadCategoryContent(categorySlug) { const key = categorySlug || '__home__'; if (key ===
334
+ currentCategoryKey && cache.has(key)) return; currentCategoryKey = key; if (cache.has(key)) { const cached = cache.get(key);
335
+ renderMiniFeatured(cached.articles, cached.categoryName); return; } const requestId = ++requestVersion; showMiniFeaturedLoading(); try { const payload = await
336
+ fetchPayload(categorySlug); if (requestId !== requestVersion || key !== currentCategoryKey) return; const articles = getArticlesFromPayload(payload); const
337
+ categoryName = getCategoryName(payload, categorySlug); const data = { articles, categoryName }; cache.set(key, data); renderMiniFeatured(articles,
338
+ categoryName); } catch (error) { if (requestId !== requestVersion || key !== currentCategoryKey) return; if (miniFeatured) { miniFeatured.innerHTML = `<h3
339
+ class='text-xs font-bold text-slate-400 uppercase tracking-wider mb-6 border-b border-slate-200 dark:border-slate-800 pb-2'>ERROR</h3>` + `<p
340
+ class='text-red-500'>Failed to load stories</p>`; } } } function shouldPreviewOnClick(event) { if (!(miniFeatured instanceof HTMLElement)) return false; if
341
+ (!window.matchMedia('(min-width: 1024px)').matches) return false; if (event.button !== 0) return false; if (event.metaKey || event.ctrlKey || event.shiftKey
342
+ || event.altKey) return false; return true; } function attachSectionHandlers() { if (!sectionsLinks) return; const topStories =
343
+ sectionsLinks.querySelector('a[href="{{logoLink}}"]'); if (topStories) { topStories.classList.add('category-link');
344
+ topStories.setAttribute('data-category-slug', ''); } const links = sectionsLinks.querySelectorAll('.category-link'); links.forEach((link) => { const
345
+ selectCategory = () => { const slug = link.getAttribute('data-category-slug') || ''; setActiveCategoryLink(slug); loadCategoryContent(slug); };
346
+ link.addEventListener('mouseenter', selectCategory); link.addEventListener('focus', selectCategory); link.addEventListener('click', (event) => { if
347
+ (!shouldPreviewOnClick(event)) return; event.preventDefault(); selectCategory(); }); }); } async function initializeMenuContent() { if (contentLoaded) return;
348
+ showCategoryLinksLoading(); showMiniFeaturedLoading(); try { const payload = await fetchPayload(''); const categories = (payload.categories || []).filter((c) => c && c.slug && (c.featured ?? true)); renderCategories(categories); attachSectionHandlers(); const homeArticles = getArticlesFromPayload(payload); const
349
+ homeData = { articles: homeArticles, categoryName: 'Featured Stories' }; cache.set('__home__', homeData); currentCategoryKey = '__home__';
350
+ setActiveCategoryLink(''); renderMiniFeatured(homeArticles, homeData.categoryName); contentLoaded = true; } catch { showCategoryLinksError(); if
351
+ (miniFeatured) { miniFeatured.innerHTML = `<h3 class='text-xs font-bold text-slate-400 uppercase tracking-wider mb-6 border-b border-slate-200
352
+ dark:border-slate-800 pb-2'>ERROR</h3>` + `<p class='text-red-500'>Failed to load stories</p>`; } } } function toggleMenu() { isOpen = !isOpen;
353
+ menuButton.setAttribute('aria-expanded', String(isOpen)); dropdownMenu.style.pointerEvents = isOpen ? 'auto' : 'none'; dropdownMenu.style.transform = isOpen ?
354
+ 'translateX(0)' : 'translateX(-100%)'; dropdownMenu.style.opacity = isOpen ? '1' : '0'; document.body.style.overflow = isOpen ? 'hidden' : ''; if (isOpen) {
355
+ initializeMenuContent(); } } menuButton.addEventListener('click', (event) => { event.stopPropagation(); toggleMenu(); }); document.addEventListener('click',
356
+ (event) => { if (!isOpen) return; const target = event.target; if (target instanceof Node && dropdownMenu.contains(target)) return; if (target === menuButton)
357
+ return; toggleMenu(); }); })();
358
+ </script>
359
+
360
+ <script>
361
+ (function () { const MOURNING = {{#if mourningMode}}true{{else}}false{{/if}}; if (MOURNING) { document.documentElement.classList.add('dark'); return; }
362
+ const THEME_KEY = 'fifthbell_theme'; const themeButtons = document.querySelectorAll('.theme-btn'); if (!themeButtons.length) return; function
363
+ getSystemTheme() { return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; } function applyTheme(theme) { const actualTheme =
364
+ theme === 'system' ? getSystemTheme() : theme; if (actualTheme === 'dark') { document.documentElement.classList.add('dark'); } else {
365
+ document.documentElement.classList.remove('dark'); } } function updateActiveButton(theme) { themeButtons.forEach((button) => { const buttonTheme =
366
+ button.getAttribute('data-theme'); if (buttonTheme === theme) { button.classList.add('!bg-[#b21100]', '!text-white');
367
+ button.classList.remove('text-slate-700', 'dark:text-slate-300'); button.setAttribute('aria-pressed', 'true'); } else {
368
+ button.classList.remove('!bg-[#b21100]', '!text-white'); button.classList.add('text-slate-700', 'dark:text-slate-300'); button.setAttribute('aria-pressed',
369
+ 'false'); } }); } function setTheme(theme) { localStorage.setItem(THEME_KEY, theme); applyTheme(theme); updateActiveButton(theme); } function initTheme() {
370
+ const savedTheme = localStorage.getItem(THEME_KEY) || 'system'; applyTheme(savedTheme); updateActiveButton(savedTheme); } themeButtons.forEach((button) => {
371
+ button.addEventListener('click', () => { const theme = button.getAttribute('data-theme'); if (theme) setTheme(theme); }); });
372
+ window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => { if ((localStorage.getItem(THEME_KEY) || 'system') === 'system') {
373
+ applyTheme('system'); } }); initTheme(); })();
374
+ </script>
375
+
376
+ <script>
377
+ (function () { const langButtons = document.querySelectorAll('.lang-btn'); if (!langButtons.length) return; function getCurrentLanguageFromPath() { const path
378
+ = window.location.pathname || '/'; if (path.startsWith('/es')) return 'es'; if (path.startsWith('/it')) return 'it'; return 'en'; } function
379
+ updateActiveButton(lang) { langButtons.forEach((button) => { const buttonLang = button.getAttribute('data-lang'); if (buttonLang === lang) {
380
+ button.classList.add('!bg-[#b21100]', '!text-white'); button.classList.remove('text-slate-700', 'dark:text-slate-300'); button.setAttribute('aria-pressed',
381
+ 'true'); } else { button.classList.remove('!bg-[#b21100]', '!text-white'); button.classList.add('text-slate-700', 'dark:text-slate-300');
382
+ button.setAttribute('aria-pressed', 'false'); } }); } function getTargetPathForLanguage(targetLang) { const currentPath = window.location.pathname || '/';
383
+ const currentLang = getCurrentLanguageFromPath(); if (currentLang === targetLang) return null; let basePath = currentPath; if (currentLang === 'es' &&
384
+ currentPath.startsWith('/es')) { basePath = currentPath.substring(3) || '/'; } else if (currentLang === 'it' && currentPath.startsWith('/it')) { basePath =
385
+ currentPath.substring(3) || '/'; } const segments = basePath.split('/').filter(Boolean); let categorySlugs = new Set(['politics', 'world', 'business',
386
+ 'sports', 'technology', 'weather', 'crime', 'new-york']); try { const cached = localStorage.getItem('fifthbell_categories'); if (cached) { const parsed =
387
+ JSON.parse(cached); const categories = parsed?.data; if (Array.isArray(categories)) { categorySlugs = new Set(categories.map((item) => item.slug)); } } }
388
+ catch { /* ignore invalid local cache */ } const isHomepage = segments.length === 0; const isCategoryPage = segments.length === 1 &&
389
+ categorySlugs.has(segments[0]); const isSearchPage = segments.length >= 1 && segments[0] === 'search'; if (!isHomepage && !isCategoryPage &&
390
+ !isSearchPage) { return targetLang === 'en' ? '/' : `/${targetLang}`; } if (isSearchPage) { const currentSearch = window.location.search || ''; return
391
+ targetLang === 'en' ? `/search${currentSearch}` : `/${targetLang}/search${currentSearch}`; } if (targetLang === 'en') return
392
+ basePath === '/' ? '/' : basePath; return basePath === '/' ? `/${targetLang}` : `/${targetLang}${basePath}`; } function closeMenuIfOpen() { const menuButton =
393
+ document.getElementById('menu-button'); const dropdownMenu = document.getElementById('dropdown-menu'); if (!(menuButton instanceof HTMLElement) ||
394
+ !(dropdownMenu instanceof HTMLElement)) return; const isExpanded = menuButton.getAttribute('aria-expanded') === 'true'; if (!isExpanded) return;
395
+ menuButton.setAttribute('aria-expanded', 'false'); dropdownMenu.style.pointerEvents = 'none'; dropdownMenu.style.transform = 'translateX(-100%)';
396
+ dropdownMenu.style.opacity = '0'; document.body.style.overflow = ''; } langButtons.forEach((button) => { button.addEventListener('click', () => { const
397
+ targetLang = button.getAttribute('data-lang'); if (!targetLang) return; updateActiveButton(targetLang); closeMenuIfOpen(); const
398
+ targetPath = getTargetPathForLanguage(targetLang); if (targetPath) window.location.href = targetPath; }); });
399
+ updateActiveButton(getCurrentLanguageFromPath()); })();
400
+ </script>
@@ -0,0 +1,16 @@
1
+ <header class='border-b border-slate-200 dark:border-slate-700 relative z-[60] bg-white dark:bg-slate-900 transition-colors' style='view-transition-name: site-header;'>
2
+ <div class='container mx-auto px-4'>
3
+ <nav class='flex items-center justify-center h-16'>
4
+ <div class='{{#if mourningMode}}bg-black{{else}}bg-[#b21100]{{/if}} text-white p-3'>
5
+ <a href='{{logoLink}}' aria-label='fifthbell - Home'>
6
+ <svg class='w-7 h-7' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'>
7
+ <path d='M10.268 21a2 2 0 0 0 3.464 0'></path>
8
+ <path d='M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326'></path>
9
+ <path d='M4 2C2.8 3.7 2 5.7 2 8'></path>
10
+ <path d='M22 8a10 10 0 0 0-2-6'></path>
11
+ </svg>
12
+ </a>
13
+ </div>
14
+ </nav>
15
+ </div>
16
+ </header>
@@ -0,0 +1,5 @@
1
+ {{#if navigation.categories}}
2
+ {{#each navigation.categories}}
3
+ <a href='/{{slug}}' class='block text-lg font-bold text-black dark:text-white hover:text-[#8f0d00] dark:hover:text-[#ff2e1a] transition-colors'>{{uppercase name}}</a>
4
+ {{/each}}
5
+ {{/if}}