1/* ============================================================================ 2 theme-boot.js â site-wide theme switch (runtime, no duplicate pages) 3 ---------------------------------------------------------------------------- 4 Include this FIRST in <head> of every page, as a BLOCKING script (no defer), 5 so the theme class lands on <html> before first paint (no flash-of-unstyled). 6 7 How theming works site-wide: 8 ⢠ALL new "editorial/navy" styling is written scoped under `.ed-theme`, 9 in a stylesheet loaded LAST on the page. This script adds/removes that 10 one class on <html>, so: 11 flag "editorial" â <html class="ed-theme"> â new look 12 flag "legacy" â class removed â original look (rules inert) 13 14 The flag (persisted, survives navigation + restarts): 15 localStorage['leif_theme'] = 'editorial' | 'legacy' (default: editorial) 16 17 Ways to flip it: 18 ⢠URL (also persists): ?theme=legacy ?theme=editorial 19 ⢠Console: leifTheme.toggle() 20 leifTheme.set('legacy') / leifTheme.set('editorial') 21 leifTheme.get() 22 Note: CSS re-themes live on toggle; page scripts that do one-time cosmetic 23 work (e.g. the homepage logo swap) fully apply on next reload. 24 ============================================================================ */ 25(function () { 26 'use strict'; 27 var KEY = 'leif_theme'; 28 var DEFAULT = 'editorial'; 29 30 function read() { 31 try { return localStorage.getItem(KEY) || DEFAULT; } catch (e) { return DEFAULT; } 32 } 33 function apply(t) { 34 var el = document.documentElement; 35 if (t !== 'legacy') el.classList.add('ed-theme'); 36 else el.classList.remove('ed-theme'); 37 } 38 39 // URL override (?theme=â¦) wins and persists so it sticks across pages. 40 try { 41 var q = new URLSearchParams(location.search).get('theme'); 42 if (q === 'legacy' || q === 'editorial') localStorage.setItem(KEY, q); 43 } catch (e) {} 44 45 apply(read()); 46 47 /* Session hint (layout only, never trusted for auth). 48 ------------------------------------------------------------------------ 49 Firebase persists its session in IndexedDB, which is async â so at first 50 paint the page cannot know whether a signed-in-only section like the 51 homepage's "Recommended for You" rail will end up visible. Left to 52 display:none it pops in a full row later and shoves everything below it 53 down the page. This flag, written by the auth listener on every state 54 change, lets CSS reserve that row's height up front for returning users 55 and reserve nothing for signed-out ones. Worst case it is one load stale, 56 which costs a reserved-but-unused row â never wrong content. */ 57 try { 58 if (localStorage.getItem('leif_had_session') === '1') { 59 document.documentElement.classList.add('leif-had-session'); 60 } 61 } catch (e) {} 62 63 window.leifTheme = { 64 get: read, 65 set: function (t) { 66 try { localStorage.setItem(KEY, t); } catch (e) {} 67 apply(read()); 68 }, 69 toggle: function () { this.set(read() === 'legacy' ? 'editorial' : 'legacy'); } 70 }; 71})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.