diff --git a/public/client.js b/public/client.js index 4634899..22ba7f3 100644 --- a/public/client.js +++ b/public/client.js @@ -145,13 +145,126 @@ }); } + function getWestgateTopbar() { + if (!document || typeof document.querySelector !== 'function') { + return null; + } + + return document.querySelector('[data-wg-topbar]'); + } + + function closeWestgateTopbarPanels(topbar, exceptKey) { + if (!topbar || typeof topbar.querySelectorAll !== 'function') { + return; + } + + toArray(topbar.querySelectorAll('[data-wg-panel]')).forEach((panel) => { + if (panel.getAttribute('data-wg-panel') !== exceptKey) { + panel.classList.remove('is-open'); + } + }); + toArray(topbar.querySelectorAll('[data-wg-menu]')).forEach((trigger) => { + if (trigger.getAttribute('data-wg-menu') !== exceptKey) { + trigger.setAttribute('aria-expanded', 'false'); + } + }); + } + + function closeWestgateTopbarDrawer(topbar) { + if (!topbar) { + return; + } + + topbar.classList.remove('is-drawer-open'); + const burger = topbar.querySelector('[data-wg-burger]'); + if (burger) { + burger.setAttribute('aria-expanded', 'false'); + } + } + + function initWestgateTopbar() { + const topbar = getWestgateTopbar(); + if (!topbar) { + return; + } + + if (!window.westgateTheme.topbarEventsBound) { + document.addEventListener('click', (event) => { + const currentTopbar = getWestgateTopbar(); + if (!currentTopbar) { + return; + } + + const trigger = event.target.closest && event.target.closest('[data-wg-menu]'); + if (trigger && currentTopbar.contains(trigger)) { + event.preventDefault(); + event.stopPropagation(); + + const key = trigger.getAttribute('data-wg-menu'); + const panel = currentTopbar.querySelector(`[data-wg-panel="${key}"]`); + const shouldOpen = !!panel && !panel.classList.contains('is-open'); + closeWestgateTopbarPanels(currentTopbar, shouldOpen ? key : null); + if (panel) { + panel.classList.toggle('is-open', shouldOpen); + } + trigger.setAttribute('aria-expanded', String(shouldOpen)); + return; + } + + const burger = event.target.closest && event.target.closest('[data-wg-burger]'); + if (burger && currentTopbar.contains(burger)) { + event.preventDefault(); + event.stopPropagation(); + + const isOpen = !currentTopbar.classList.contains('is-drawer-open'); + currentTopbar.classList.toggle('is-drawer-open', isOpen); + burger.setAttribute('aria-expanded', String(isOpen)); + closeWestgateTopbarPanels(currentTopbar, null); + return; + } + + if (event.target.closest && event.target.closest('[data-wg-panel]')) { + return; + } + + closeWestgateTopbarPanels(currentTopbar, null); + if (!currentTopbar.contains(event.target)) { + closeWestgateTopbarDrawer(currentTopbar); + } + }); + + document.addEventListener('keydown', (event) => { + if (event.key !== 'Escape') { + return; + } + + const currentTopbar = getWestgateTopbar(); + closeWestgateTopbarPanels(currentTopbar, null); + closeWestgateTopbarDrawer(currentTopbar); + }); + + window.westgateTheme.topbarEventsBound = true; + } + + $(document) + .off('shown.bs.dropdown.westgateTopbar') + .on('shown.bs.dropdown.westgateTopbar', '.wg-topbar [component="sidebar/search"]', function () { + $(this).find('[component="search/fields"] input[name="query"]').trigger('focus'); + }); + } + window.westgateTheme = window.westgateTheme || {}; window.westgateTheme.wrapWikiTables = wrapWestgateWikiTables; + window.westgateTheme.initTopbar = initWestgateTopbar; $(document).ready(function () { wrapWestgateWikiTables(document); + initWestgateTopbar(); $(window).on('action:ajaxify.end', function () { wrapWestgateWikiTables(document); + initWestgateTopbar(); + closeWestgateTopbarPanels(getWestgateTopbar(), null); + closeWestgateTopbarDrawer(getWestgateTopbar()); }); require(['api'], function (api) { diff --git a/scss/westgate/_topbar.scss b/scss/westgate/_topbar.scss new file mode 100644 index 0000000..7ecec9e --- /dev/null +++ b/scss/westgate/_topbar.scss @@ -0,0 +1,418 @@ +.wg-layout-container { + min-height: 100vh; +} + +.wg-topbar { + top: 0; + z-index: 1020; + color: var(--wg-text-soft); + background: + linear-gradient(180deg, rgba(255, 241, 196, 0.035), transparent 42%), + linear-gradient(90deg, rgba(42, 18, 34, 0.96), rgba(15, 13, 18, 0.98) 38%, rgba(9, 8, 11, 0.99)); + border-bottom: 1px solid rgba(194, 163, 90, 0.2); + box-shadow: + inset 0 1px 0 rgba(255, 244, 221, 0.04), + 0 12px 32px rgba(0, 0, 0, 0.34); +} + +.wg-topbar__inner { + display: grid; + grid-template-columns: auto minmax(0, 1fr) auto auto; + align-items: center; + gap: 0.9rem; + width: min(100%, 1420px); + min-height: 64px; + margin: 0 auto; + padding: 0.55rem clamp(0.85rem, 2vw, 1.5rem); +} + +.wg-topbar__brand { + display: inline-flex; + align-items: center; + min-width: 0; + gap: 0.7rem; + color: var(--wg-text); + text-decoration: none; + + &:hover, + &:focus { + color: #f3ede4; + text-decoration: none; + } +} + +.wg-topbar__brand-mark { + display: inline-flex; + align-items: center; + justify-content: center; + width: 2.3rem; + height: 2.3rem; + border: 1px solid rgba(194, 163, 90, 0.36); + border-radius: 50%; + color: var(--wg-gold); + background: + radial-gradient(circle at 38% 24%, rgba(255, 238, 190, 0.2), transparent 30%), + linear-gradient(145deg, rgba(58, 24, 48, 0.7), rgba(10, 9, 13, 0.98)); + box-shadow: + inset 0 0 0 1px rgba(9, 8, 11, 0.66), + 0 8px 18px rgba(0, 0, 0, 0.35); + font-family: var(--wg-font-display); + font-weight: 700; +} + +.wg-topbar__brand-text { + display: flex; + flex-direction: column; + min-width: 0; + line-height: 1; +} + +.wg-topbar__brand-name { + max-width: 22ch; + overflow: hidden; + color: var(--wg-text); + font-family: var(--wg-font-display); + font-size: 0.96rem; + font-weight: 600; + letter-spacing: 0.08em; + text-overflow: ellipsis; + text-transform: uppercase; + white-space: nowrap; +} + +.wg-topbar__brand-subtitle { + margin-top: 0.28rem; + color: var(--wg-gold-soft); + font-family: var(--wg-font-code); + font-size: 0.62rem; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.wg-topbar__nav { + min-width: 0; +} + +.wg-topbar__nav-list, +.wg-topbar__utility-list { + gap: 0.28rem; +} + +.wg-topbar__nav-list { + min-width: 0; + overflow: hidden; +} + +.wg-topbar .nav-link, +.wg-topbar__nav-link, +.wg-topbar__forums-toggle { + min-height: 2.35rem; + border: 1px solid transparent; + border-radius: 6px; + padding: 0.42rem 0.62rem; + color: var(--wg-text-soft); + background: transparent; + font-family: var(--wg-font-ui); + font-size: 0.86rem; + line-height: 1.1; + text-decoration: none; +} + +.wg-topbar .nav-link:hover, +.wg-topbar .nav-link:focus, +.wg-topbar__nav-link:hover, +.wg-topbar__nav-link:focus, +.wg-topbar__forums-toggle:hover, +.wg-topbar__forums-toggle:focus, +.wg-topbar .nav-item.active > .nav-link, +.wg-topbar .nav-item.active > .navigation-link { + color: #f3ede4; + border-color: rgba(194, 163, 90, 0.2); + background: rgba(194, 163, 90, 0.075); + box-shadow: inset 0 1px 0 rgba(255, 244, 221, 0.035); +} + +.wg-topbar__forums { + position: relative; +} + +.wg-topbar__forums-toggle { + display: inline-flex; + align-items: center; + gap: 0.35rem; +} + +.wg-topbar__utilities { + justify-self: end; +} + +.wg-topbar__utility-list { + align-items: center; +} + +.wg-topbar__utility-list > .nav-item { + position: relative; +} + +.wg-topbar__utility-list :where(.nav-text, .visible-open) { + display: none !important; +} + +.wg-topbar__utility-list .nav-link { + justify-content: center; + width: 2.35rem; + height: 2.35rem; + padding: 0; +} + +.wg-topbar__utility-list [component$="/count"], +.wg-topbar__drawer-actions [component$="/count"], +.wg-topbar [component="navigation/count"] { + background: linear-gradient(to bottom, rgba(142, 52, 56, 0.92), rgba(84, 28, 39, 0.96)) !important; + border: 1px solid rgba(216, 194, 138, 0.26); + color: #fff0dc; +} + +.wg-topbar__utility-list .visible-closed { + display: inline-block !important; +} + +.wg-topbar__skin .dropend { + margin: 0 !important; +} + +.wg-topbar__skin .dropdown-menu, +.wg-topbar__dropdown, +.wg-topbar .search-dropdown, +.wg-topbar .notifications-dropdown, +.wg-topbar .chats-dropdown, +.wg-topbar .drafts-dropdown, +.wg-topbar .user-dropdown, +.wg-topbar__panel { + min-width: min(22rem, calc(100vw - 1.5rem)); + max-width: calc(100vw - 1.5rem); + border: 1px solid rgba(194, 163, 90, 0.22) !important; + border-radius: 8px !important; + color: var(--wg-text-soft) !important; + background: + linear-gradient(180deg, rgba(255, 244, 221, 0.028), transparent 36%), + var(--wg-velvet-panel) !important; + box-shadow: + inset 0 1px 0 rgba(255, 244, 221, 0.035), + 0 18px 42px rgba(0, 0, 0, 0.42) !important; +} + +.wg-topbar .notifications-dropdown, +.wg-topbar .chats-dropdown, +.wg-topbar .drafts-dropdown { + width: min(24rem, calc(100vw - 1.5rem)); +} + +.wg-topbar .dropdown-item, +.wg-topbar .btn.btn-ghost, +.wg-topbar .btn.btn-light { + color: var(--wg-text-soft) !important; +} + +.wg-topbar .dropdown-item:hover, +.wg-topbar .dropdown-item:focus, +.wg-topbar .btn.btn-ghost:hover, +.wg-topbar .btn.btn-ghost:focus, +.wg-topbar .btn.btn-light:hover, +.wg-topbar .btn.btn-light:focus { + color: var(--wg-text) !important; + background: rgba(194, 163, 90, 0.08) !important; +} + +.wg-topbar .btn-primary, +.wg-topbar__register { + border-color: rgba(194, 163, 90, 0.34) !important; + color: #1b1208 !important; + background: linear-gradient(to bottom, #d8c28a, var(--wg-gold)) !important; +} + +.wg-topbar__login, +.wg-topbar__register { + display: inline-flex; + align-items: center; + justify-content: center; + min-height: 2.35rem; + border-radius: 6px; + padding: 0.35rem 0.78rem; + font-family: var(--wg-font-ui); + font-size: 0.86rem; + font-weight: 600; + text-decoration: none; +} + +.wg-topbar__login { + color: var(--wg-text-soft); + border: 1px solid rgba(194, 163, 90, 0.2); + background: rgba(194, 163, 90, 0.055); +} + +.wg-topbar__login:hover, +.wg-topbar__login:focus { + color: var(--wg-text); + border-color: rgba(194, 163, 90, 0.3); + background: rgba(194, 163, 90, 0.1); +} + +.wg-topbar__panel { + position: absolute; + top: calc(100% + 0.45rem); + right: 0; + display: none; + padding: 0.42rem; +} + +.wg-topbar__panel.is-open { + display: grid; + gap: 0.2rem; +} + +.wg-topbar__panel--forums a { + display: flex; + align-items: center; + min-height: 2.25rem; + border-radius: 6px; + padding: 0.35rem 0.55rem; + color: var(--wg-text-soft); + font-size: 0.9rem; + text-decoration: none; +} + +.wg-topbar__panel--forums a:hover, +.wg-topbar__panel--forums a:focus { + color: var(--wg-text); + background: rgba(194, 163, 90, 0.08); +} + +.wg-topbar__burger { + display: none; + align-items: center; + justify-content: center; + width: 2.4rem; + height: 2.4rem; + border: 1px solid rgba(194, 163, 90, 0.22); + border-radius: 6px; + color: var(--wg-text-soft); + background: rgba(194, 163, 90, 0.055); +} + +.wg-topbar__burger:hover, +.wg-topbar__burger:focus { + color: var(--wg-text); + background: rgba(194, 163, 90, 0.1); +} + +.wg-topbar__drawer { + display: none; + border-top: 1px solid rgba(194, 163, 90, 0.12); + background: + linear-gradient(180deg, rgba(42, 18, 34, 0.98), rgba(12, 10, 15, 0.99)); +} + +.wg-topbar.is-drawer-open .wg-topbar__drawer { + display: block; +} + +.wg-topbar__drawer-inner { + display: grid; + gap: 0.8rem; + width: min(100%, 42rem); + margin: 0 auto; + padding: 0.85rem; +} + +.wg-topbar__drawer-search { + display: flex; + align-items: center; + gap: 0.55rem; + border: 1px solid rgba(194, 163, 90, 0.18); + border-radius: 8px; + padding: 0.5rem 0.65rem; + background: rgba(9, 8, 11, 0.45); +} + +.wg-topbar__drawer-search input { + min-width: 0; + width: 100%; + border: 0; + color: var(--wg-text); + background: transparent; + outline: 0; +} + +.wg-topbar__drawer-nav, +.wg-topbar__drawer-actions, +.wg-topbar__drawer-auth { + display: grid; + gap: 0.35rem; +} + +.wg-topbar__drawer-link, +.wg-topbar__drawer-actions a { + display: flex; + align-items: center; + justify-content: space-between; + gap: 0.55rem; + border: 1px solid rgba(194, 163, 90, 0.12); + border-radius: 7px; + padding: 0.62rem 0.7rem; + color: var(--wg-text-soft); + background: rgba(255, 244, 221, 0.02); + text-decoration: none; +} + +.wg-topbar__drawer-link:hover, +.wg-topbar__drawer-link:focus, +.wg-topbar__drawer-actions a:hover, +.wg-topbar__drawer-actions a:focus { + color: var(--wg-text); + border-color: rgba(194, 163, 90, 0.22); + background: rgba(194, 163, 90, 0.08); +} + +@media (max-width: 1199.98px) { + .wg-topbar__inner { + grid-template-columns: auto minmax(0, 1fr) auto; + } + + .wg-topbar__nav { + display: none; + } +} + +@media (max-width: 991.98px) { + .wg-topbar__inner { + grid-template-columns: minmax(0, 1fr) auto; + } + + .wg-topbar__brand-name { + max-width: 16ch; + } + + .wg-topbar__brand-subtitle, + .wg-topbar__forums, + .wg-topbar__utilities { + display: none; + } + + .wg-topbar__burger { + display: inline-flex; + } +} + +@media (max-width: 480px) { + .wg-topbar__brand-mark { + width: 2rem; + height: 2rem; + } + + .wg-topbar__brand-name { + max-width: 13ch; + font-size: 0.82rem; + letter-spacing: 0.05em; + } +} diff --git a/templates/footer.tpl b/templates/footer.tpl new file mode 100644 index 0000000..60e0878 --- /dev/null +++ b/templates/footer.tpl @@ -0,0 +1,20 @@ + + + + + +