@@ -5,80 +5,131 @@ export function renderHeader() {
55
66 return `
77 <header class="border-b border-[var(--color-border)] bg-[var(--color-bg)] transition-colors duration-300">
8- <nav class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
9- <!-- Row 1: Logo + Language/Theme -->
10- <div class="flex items-center justify-between py-3">
11- <div class="flex items-center gap-2">
8+ <nav class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-3">
9+ <!-- Desktop: Logo spanning two rows, right side has nav + search -->
10+ <div class="hidden sm:flex items-stretch gap-6">
11+ <!-- Logo left, spanning both rows -->
12+ <div class="flex items-center">
1213 <a href="#/" class="no-underline flex flex-col items-start">
13- <img src="${ import . meta. env . BASE_URL } logo.png" alt="Semantic Anchors" class="max-h-16 sm:max-h-20 " />
14- <span class="hidden sm:block text-xs text-[var(--color-text-secondary)] leading-tight" data-i18n="header.slogan">${ i18n . t ( 'header.slogan' ) } </span>
14+ <img src="${ import . meta. env . BASE_URL } logo.png" alt="Semantic Anchors" class="max-h-24 " />
15+ <span class="text-xs text-[var(--color-text-secondary)] leading-tight" data-i18n="header.slogan">${ i18n . t ( 'header.slogan' ) } </span>
1516 </a>
1617 <button
1718 id="onboarding-info-btn"
18- class="rounded-full p-1 text-[var(--color-text-secondary)] hover:text-[var(--color-primary)] hover:bg-[var(--color-bg-secondary)] transition-colors"
19+ class="self-start mt-1 rounded-full p-1 text-[var(--color-text-secondary)] hover:text-[var(--color-primary)] hover:bg-[var(--color-bg-secondary)] transition-colors"
1920 data-i18n-aria="onboarding.infoButton"
2021 data-i18n-title="onboarding.infoButton"
2122 aria-label="${ i18n . t ( 'onboarding.infoButton' ) } "
2223 title="${ i18n . t ( 'onboarding.infoButton' ) } "
2324 >
2425 <svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
25- <path stroke-linecap="round" stroke-linejoin="round" d="M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z" />
26+ <path stroke-linecap="round" stroke-linejoin="round" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
27+ <path stroke-linecap="round" stroke-linejoin="round" d="M15.91 11.672a.375.375 0 010 .656l-5.603 3.113a.375.375 0 01-.557-.328V8.887c0-.286.307-.466.557-.327l5.603 3.112z" />
2628 </svg>
2729 </button>
2830 </div>
29- <div class="flex items-center gap-3">
30- <button
31- id="lang-toggle"
32- class="rounded-md px-2 py-1 text-sm font-medium text-[var(--color-text-secondary)] hover:text-[var(--color-text)] hover:bg-[var(--color-bg-secondary)] transition-colors"
33- aria-label="Toggle language"
34- >${ langLabel } </button>
35- <button
36- id="theme-toggle"
37- class="rounded-md p-2 text-[var(--color-text-secondary)] hover:text-[var(--color-text)] hover:bg-[var(--color-bg-secondary)] transition-colors"
38- data-i18n-aria="header.themeToggle.dark"
39- aria-label="Switch to dark mode"
40- >
41- <svg id="theme-icon-moon" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
42- <path stroke-linecap="round" stroke-linejoin="round" d="M21.752 15.002A9.718 9.718 0 0118 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 003 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 009.002-5.998z" />
43- </svg>
44- <svg id="theme-icon-sun" class="h-5 w-5 hidden" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
45- <path stroke-linecap="round" stroke-linejoin="round" d="M12 3v2.25m6.364.386l-1.591 1.591M21 12h-2.25m-.386 6.364l-1.591-1.591M12 18.75V21m-4.773-4.227l-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0z" />
46- </svg>
47- </button>
48- <button
49- id="mobile-menu-toggle"
50- class="sm:hidden rounded-md p-2 text-[var(--color-text-secondary)] hover:text-[var(--color-text)] hover:bg-[var(--color-bg-secondary)] transition-colors"
51- aria-label="Toggle menu"
52- aria-expanded="false"
53- >
54- <svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
55- <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
56- </svg>
57- </button>
31+
32+ <!-- Right side: two rows -->
33+ <div class="flex-1 flex flex-col justify-center gap-2">
34+ <!-- Row 1: Navigation + Language/Theme -->
35+ <div class="flex items-center justify-between">
36+ <div class="flex items-center gap-6 text-2xl">
37+ <a href="#/" class="nav-link text-[var(--color-text-secondary)] hover:text-[var(--color-text)] transition-colors" data-route="/" data-i18n="nav.catalog">${ i18n . t ( 'nav.catalog' ) } </a>
38+ <a href="#/about" class="nav-link text-[var(--color-text-secondary)] hover:text-[var(--color-text)] transition-colors" data-route="/about" data-i18n="nav.about">${ i18n . t ( 'nav.about' ) } </a>
39+ <a href="#/contributing" class="nav-link text-[var(--color-text-secondary)] hover:text-[var(--color-text)] transition-colors" data-route="/contributing" data-i18n="nav.contributing">${ i18n . t ( 'nav.contributing' ) } </a>
40+ </div>
41+ <div class="flex items-center gap-3">
42+ <button
43+ id="lang-toggle"
44+ class="rounded-md px-2 py-1 text-sm font-medium text-[var(--color-text-secondary)] hover:text-[var(--color-text)] hover:bg-[var(--color-bg-secondary)] transition-colors"
45+ aria-label="Toggle language"
46+ >${ langLabel } </button>
47+ <button
48+ id="theme-toggle"
49+ class="rounded-md p-2 text-[var(--color-text-secondary)] hover:text-[var(--color-text)] hover:bg-[var(--color-bg-secondary)] transition-colors"
50+ data-i18n-aria="header.themeToggle.dark"
51+ aria-label="Switch to dark mode"
52+ >
53+ <svg id="theme-icon-moon" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
54+ <path stroke-linecap="round" stroke-linejoin="round" d="M21.752 15.002A9.718 9.718 0 0118 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 003 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 009.002-5.998z" />
55+ </svg>
56+ <svg id="theme-icon-sun" class="h-5 w-5 hidden" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
57+ <path stroke-linecap="round" stroke-linejoin="round" d="M12 3v2.25m6.364.386l-1.591 1.591M21 12h-2.25m-.386 6.364l-1.591-1.591M12 18.75V21m-4.773-4.227l-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0z" />
58+ </svg>
59+ </button>
60+ </div>
61+ </div>
62+ <!-- Row 2: Search + Role filter + Anchor count -->
63+ <div class="flex items-center gap-3">
64+ <input
65+ id="header-search-input"
66+ type="search"
67+ data-i18n-placeholder="search.placeholder"
68+ placeholder="${ i18n . t ( 'search.placeholder' ) } "
69+ class="w-48 lg:w-64 rounded-lg border-2 border-[var(--color-border)] bg-[var(--color-bg)] px-4 py-2 text-base text-[var(--color-text)] placeholder-[var(--color-text-secondary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)] focus:border-[var(--color-primary)] transition-colors duration-300"
70+ />
71+ <select
72+ id="header-role-filter"
73+ class="rounded-lg border-2 border-[var(--color-border)] bg-[var(--color-bg)] px-4 py-2 text-base text-[var(--color-text)] focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)] focus:border-[var(--color-primary)] transition-colors duration-300"
74+ >
75+ <option value="" data-i18n="filter.allRoles">${ i18n . t ( 'filter.allRoles' ) } </option>
76+ </select>
77+ <span id="anchor-count" class="text-sm text-[var(--color-text-secondary)] ml-auto">
78+ <span id="visible-count">0</span> / <span id="total-count">0</span> <span data-i18n="filter.anchors">${ i18n . t ( 'filter.anchors' ) } </span>
79+ </span>
80+ </div>
5881 </div>
5982 </div>
6083
61- <!-- Row 2: Navigation + Search/Filter (desktop) -->
62- <div class="hidden sm:flex items-center justify-between pb-3">
63- <div class="flex items-center gap-6 text-2xl">
64- <a href="#/" class="nav-link text-[var(--color-text-secondary)] hover:text-[var(--color-text)] transition-colors" data-route="/" data-i18n="nav.catalog">${ i18n . t ( 'nav.catalog' ) } </a>
65- <a href="#/about" class="nav-link text-[var(--color-text-secondary)] hover:text-[var(--color-text)] transition-colors" data-route="/about" data-i18n="nav.about">${ i18n . t ( 'nav.about' ) } </a>
66- <a href="#/contributing" class="nav-link text-[var(--color-text-secondary)] hover:text-[var(--color-text)] transition-colors" data-route="/contributing" data-i18n="nav.contributing">${ i18n . t ( 'nav.contributing' ) } </a>
67- </div>
68- <div class="flex items-center gap-3">
69- <input
70- id="header-search-input"
71- type="search"
72- data-i18n-placeholder="search.placeholder"
73- placeholder="${ i18n . t ( 'search.placeholder' ) } "
74- class="w-48 lg:w-72 rounded-lg border-2 border-[var(--color-border)] bg-[var(--color-bg)] px-4 py-2 text-base text-[var(--color-text)] placeholder-[var(--color-text-secondary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)] focus:border-[var(--color-primary)] transition-colors duration-300"
75- />
76- <select
77- id="header-role-filter"
78- class="rounded-lg border-2 border-[var(--color-border)] bg-[var(--color-bg)] px-4 py-2 text-base text-[var(--color-text)] focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)] focus:border-[var(--color-primary)] transition-colors duration-300"
79- >
80- <option value="" data-i18n="filter.allRoles">${ i18n . t ( 'filter.allRoles' ) } </option>
81- </select>
84+ <!-- Mobile: stacked layout -->
85+ <div class="sm:hidden">
86+ <div class="flex items-center justify-between">
87+ <a href="#/" class="no-underline flex flex-col items-start">
88+ <img src="${ import . meta. env . BASE_URL } logo.png" alt="Semantic Anchors" class="max-h-16" />
89+ <span class="text-xs text-[var(--color-text-secondary)] leading-tight" data-i18n="header.slogan">${ i18n . t ( 'header.slogan' ) } </span>
90+ </a>
91+ <div class="flex items-center gap-3">
92+ <button
93+ id="onboarding-info-btn-mobile"
94+ class="rounded-full p-1 text-[var(--color-text-secondary)] hover:text-[var(--color-primary)] hover:bg-[var(--color-bg-secondary)] transition-colors"
95+ data-i18n-aria="onboarding.infoButton"
96+ data-i18n-title="onboarding.infoButton"
97+ aria-label="${ i18n . t ( 'onboarding.infoButton' ) } "
98+ title="${ i18n . t ( 'onboarding.infoButton' ) } "
99+ >
100+ <svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
101+ <path stroke-linecap="round" stroke-linejoin="round" d="M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z" />
102+ </svg>
103+ </button>
104+ <button
105+ id="lang-toggle-mobile"
106+ class="rounded-md px-2 py-1 text-sm font-medium text-[var(--color-text-secondary)] hover:text-[var(--color-text)] hover:bg-[var(--color-bg-secondary)] transition-colors"
107+ aria-label="Toggle language"
108+ >${ langLabel } </button>
109+ <button
110+ id="theme-toggle-mobile"
111+ class="rounded-md p-2 text-[var(--color-text-secondary)] hover:text-[var(--color-text)] hover:bg-[var(--color-bg-secondary)] transition-colors"
112+ data-i18n-aria="header.themeToggle.dark"
113+ aria-label="Switch to dark mode"
114+ >
115+ <svg id="theme-icon-moon-mobile" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
116+ <path stroke-linecap="round" stroke-linejoin="round" d="M21.752 15.002A9.718 9.718 0 0118 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 003 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 009.002-5.998z" />
117+ </svg>
118+ <svg id="theme-icon-sun-mobile" class="h-5 w-5 hidden" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
119+ <path stroke-linecap="round" stroke-linejoin="round" d="M12 3v2.25m6.364.386l-1.591 1.591M21 12h-2.25m-.386 6.364l-1.591-1.591M12 18.75V21m-4.773-4.227l-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0z" />
120+ </svg>
121+ </button>
122+ <button
123+ id="mobile-menu-toggle"
124+ class="rounded-md p-2 text-[var(--color-text-secondary)] hover:text-[var(--color-text)] hover:bg-[var(--color-bg-secondary)] transition-colors"
125+ aria-label="Toggle menu"
126+ aria-expanded="false"
127+ >
128+ <svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
129+ <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
130+ </svg>
131+ </button>
132+ </div>
82133 </div>
83134 </div>
84135
0 commit comments