| [7bc636b] | 1 | <footer class="site-footer">
|
|---|
| [da6fd02] | 2 | <% if (typeof footerNewsletter !== 'undefined' && footerNewsletter && (typeof premiumUnlocked === 'undefined' || premiumUnlocked) && typeof site !== 'undefined' && site) { %>
|
|---|
| 3 | <div class="container footer-nl">
|
|---|
| 4 | <span class="footer-nl-label">📬 Blijf op de hoogte</span>
|
|---|
| 5 | <form method="post" action="<%= (typeof siteUrlBase !== 'undefined' && siteUrlBase) ? siteUrlBase : '' %>/nieuwsbrief" class="footer-nl-form">
|
|---|
| 6 | <input type="email" name="email" required placeholder="jouw@email.nl" autocomplete="email" aria-label="E-mailadres">
|
|---|
| 7 | <button type="submit">Inschrijven</button>
|
|---|
| 8 | </form>
|
|---|
| 9 | </div>
|
|---|
| 10 | <% } %>
|
|---|
| [7bc636b] | 11 | <div class="container site-footer-inner">
|
|---|
| 12 | <div>
|
|---|
| [8afbdd6] | 13 | <span>© <%= new Date().getFullYear() %> <%= (site && site.title) || 'Klonkt' %></span>
|
|---|
| [7bc636b] | 14 | </div>
|
|---|
| [93d6345] | 15 | <%# Install-app knop — in de footer-rij (midden), bespaart een hele extra rij.
|
|---|
| 16 | JS detecteert platform & opent een modal met PWA-install-stappen. %>
|
|---|
| 17 | <button type="button" class="install-app-btn install-app-btn--footer" data-pcms-install-app>
|
|---|
| 18 | <svg viewBox="0 0 24 24" width="16" height="16" aria-hidden="true"><path d="M5 20h14v-2H5v2zm7-18L5.33 9h3.84v6h5.66V9h3.84L12 2z" fill="currentColor"/></svg>
|
|---|
| 19 | <span>Installeer app</span>
|
|---|
| 20 | </button>
|
|---|
| [7bc636b] | 21 | <div class="footer-meta">
|
|---|
| [83faa57] | 22 | <span>Klonkt Beta<%= (typeof appVersion !== 'undefined' && appVersion) ? ' v' + appVersion : '' %></span>
|
|---|
| [7bc636b] | 23 | <%# Mobile-only theme toggle. On desktop the topnav has its own toggle
|
|---|
| 24 | so we hide this one to avoid two visible toggles at once. The same
|
|---|
| 25 | toggleTheme handler in topnav.ejs picks this button up by id. %>
|
|---|
| 26 | <button type="button" class="footer-theme-toggle" id="theme-toggle-footer"
|
|---|
| 27 | aria-label="Thema wisselen" title="Thema wisselen">
|
|---|
| 28 | <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|---|
| 29 | stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|---|
| 30 | <circle cx="12" cy="12" r="4"/>
|
|---|
| 31 | <path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/>
|
|---|
| 32 | </svg>
|
|---|
| 33 | </button>
|
|---|
| 34 | </div>
|
|---|
| 35 | </div>
|
|---|
| 36 |
|
|---|
| 37 | </footer>
|
|---|
| 38 |
|
|---|
| 39 | <style>
|
|---|
| 40 | /* Make sure the page itself is at least viewport-tall so the flex sticky-
|
|---|
| 41 | footer logic (body display:flex, main flex:1) can push the footer down.
|
|---|
| 42 | 100dvh is dynamic viewport height — handles mobile address-bar collapse. */
|
|---|
| 43 | html { min-height: 100dvh; }
|
|---|
| 44 |
|
|---|
| 45 | .site-footer {
|
|---|
| 46 | border-top: 1px solid var(--rule);
|
|---|
| 47 | margin-top: 4rem;
|
|---|
| 48 | padding: 2rem 0;
|
|---|
| 49 | padding-bottom: calc(2rem + env(safe-area-inset-bottom, 0));
|
|---|
| 50 | font-size: 0.85rem;
|
|---|
| 51 | color: var(--ink-muted);
|
|---|
| 52 | background: var(--paper);
|
|---|
| 53 | /* When fixed bars (mini-player / bottom-tab) sit at the bottom of the
|
|---|
| 54 | viewport they overlap the footer at scroll-end. The clearance below
|
|---|
| 55 | mirrors the .pcms-main rule in audio.css — content goes at the top of
|
|---|
| 56 | the footer, the player floats over the empty padding underneath. */
|
|---|
| 57 | transition: padding-bottom .2s ease;
|
|---|
| 58 | }
|
|---|
| 59 | /* Audio player visible (desktop, no bottom-tab): clear ~80px */
|
|---|
| 60 | body.has-audio-player .site-footer {
|
|---|
| 61 | padding-bottom: calc(2rem + 80px + env(safe-area-inset-bottom, 0));
|
|---|
| 62 | }
|
|---|
| 63 | @media (max-width: 767px) {
|
|---|
| 64 | /* Bottom-tab visible alone: ~56px tab */
|
|---|
| 65 | body.has-bottom-tab .site-footer {
|
|---|
| 66 | padding-bottom: calc(2rem + 56px + env(safe-area-inset-bottom, 0));
|
|---|
| 67 | }
|
|---|
| 68 | /* Bottom-tab + audio-player stacked: ~56px tab + ~72px player */
|
|---|
| 69 | body.has-bottom-tab.has-audio-player .site-footer {
|
|---|
| 70 | padding-bottom: calc(2rem + 56px + 72px + env(safe-area-inset-bottom, 0));
|
|---|
| 71 | }
|
|---|
| 72 | }
|
|---|
| [da6fd02] | 73 | .footer-nl {
|
|---|
| 74 | max-width: 800px; margin: 0 auto 1.5rem; padding: 0 1rem;
|
|---|
| 75 | display: flex; align-items: center; justify-content: center; gap: .8rem; flex-wrap: wrap;
|
|---|
| 76 | }
|
|---|
| 77 | .footer-nl-label { font-weight: 600; color: var(--ink); }
|
|---|
| 78 | .footer-nl-form { display: flex; gap: .5rem; flex-wrap: wrap; }
|
|---|
| 79 | .footer-nl-form input {
|
|---|
| 80 | padding: .5rem .7rem; border-radius: 8px; border: 1px solid var(--rule);
|
|---|
| 81 | background: var(--paper); color: var(--ink); font-size: .9rem; min-width: 200px;
|
|---|
| 82 | }
|
|---|
| 83 | .footer-nl-form button {
|
|---|
| 84 | padding: .5rem 1rem; border-radius: 8px; border: none; cursor: pointer;
|
|---|
| 85 | background: var(--accent); color: #fff; font-weight: 600; font-size: .9rem;
|
|---|
| 86 | }
|
|---|
| 87 | @media (max-width: 600px) { .footer-nl { flex-direction: column; } .footer-nl-form input { min-width: 0; flex: 1; } }
|
|---|
| 88 |
|
|---|
| [7bc636b] | 89 | .site-footer-inner {
|
|---|
| 90 | max-width: 800px;
|
|---|
| 91 | margin: 0 auto;
|
|---|
| 92 | padding: 0 1rem;
|
|---|
| 93 | display: flex;
|
|---|
| 94 | justify-content: space-between;
|
|---|
| 95 | align-items: center;
|
|---|
| 96 | flex-wrap: wrap;
|
|---|
| 97 | gap: 1rem;
|
|---|
| 98 | }
|
|---|
| 99 | .footer-meta {
|
|---|
| 100 | font-size: 0.8rem; opacity: 0.7;
|
|---|
| 101 | display: inline-flex; align-items: center; gap: 0.75rem;
|
|---|
| 102 | }
|
|---|
| 103 | .pcms-main { min-height: 50vh; }
|
|---|
| 104 |
|
|---|
| 105 | /* Mobile theme toggle in footer. Pill-style button matching topnav nav-btn.
|
|---|
| 106 | Hidden on desktop; the topnav already has a toggle there. */
|
|---|
| 107 | .footer-theme-toggle {
|
|---|
| 108 | display: none;
|
|---|
| 109 | align-items: center; justify-content: center;
|
|---|
| 110 | width: 36px; height: 36px;
|
|---|
| 111 | padding: 0; margin: 0;
|
|---|
| 112 | background: transparent; color: var(--ink);
|
|---|
| 113 | border: 1px solid var(--rule); border-radius: 999px;
|
|---|
| 114 | cursor: pointer;
|
|---|
| 115 | transition: background-color 120ms, border-color 120ms;
|
|---|
| 116 | -webkit-tap-highlight-color: transparent;
|
|---|
| 117 | opacity: 1; /* override .footer-meta dim */
|
|---|
| 118 | }
|
|---|
| 119 | .footer-theme-toggle:hover { background: var(--paper-2); border-color: var(--accent); }
|
|---|
| 120 | .footer-theme-toggle:active { transform: scale(0.96); }
|
|---|
| 121 | .footer-theme-toggle svg { width: 18px; height: 18px; }
|
|---|
| 122 |
|
|---|
| 123 | @media (max-width: 768px) {
|
|---|
| 124 | .footer-theme-toggle { display: inline-flex; }
|
|---|
| 125 | }
|
|---|
| 126 |
|
|---|
| [93d6345] | 127 | /* Compacte install-knop ín de footer-rij (midden) i.p.v. een grote losse CTA
|
|---|
| 128 | op een eigen regel — bespaart verticale ruimte. */
|
|---|
| 129 | .install-app-btn--footer {
|
|---|
| 130 | flex: 0 0 auto;
|
|---|
| 131 | width: auto !important; /* override de mobile .install-app-btn width:100% */
|
|---|
| 132 | padding: 0.42rem 0.95rem;
|
|---|
| 133 | font-size: 0.82rem;
|
|---|
| 134 | gap: 0.4rem;
|
|---|
| 135 | }
|
|---|
| 136 | .install-app-btn--footer svg { width: 15px; height: 15px; }
|
|---|
| 137 | /* Op smal scherm: laat de drie items netjes centreren als ze wrappen. */
|
|---|
| 138 | @media (max-width: 600px) {
|
|---|
| 139 | .site-footer-inner { justify-content: center; text-align: center; }
|
|---|
| [7bc636b] | 140 | }
|
|---|
| 141 | </style>
|
|---|