0
Skip to Content
Kent Archaeological Society
Events
News
Books
Journal
Magazine
Papers
Reports
Audio
Images
Maps
Models
Notes
Records
Videos
About
Affiliates
Collections
Grants
Groups
Institutes
Library
People
Services
Kent Archaeological Society
Events
News
Books
Journal
Magazine
Papers
Reports
Audio
Images
Maps
Models
Notes
Records
Videos
About
Affiliates
Collections
Grants
Groups
Institutes
Library
People
Services
Events
News
Folder: Publications
Back
Books
Journal
Magazine
Papers
Reports
Folder: Resources
Back
Audio
Images
Maps
Models
Notes
Records
Videos
Folder: Society
Back
About
Affiliates
Collections
Grants
Groups
Institutes
Library
People
Services
Researches and Discoveries
Articles, Volume 144 Jacob Scott 25/06/2024 Articles, Volume 144 Jacob Scott 25/06/2024

Researches and Discoveries

Various Authors, 2023, Archaeologia Cantiana, Volume 144. Maidstone: Kent Archaeological Society.

Read More
The complex of Roman buildings excavated by MAAG at East Farleigh, 2005-17: an interim report
Articles, Volume 143 KAS 25/06/2024 Articles, Volume 143 KAS 25/06/2024

The complex of Roman buildings excavated by MAAG at East Farleigh, 2005-17: an interim report

Stephen Clifton, 2022, Archaeologia Cantiana, Volume 143. Maidstone: Kent Archaeological Society.

Read More
Obituaries and Contributors
Obituaries, Notes on Contributors, Volume 143 KAS 25/06/2024 Obituaries, Notes on Contributors, Volume 143 KAS 25/06/2024

Obituaries and Contributors

2022, Archaeologia Cantiana, Volume 143. Maidstone: Kent Archaeological Society.

Read More
The Roman building at Chart Sutton revisited
Articles, Volume 142 KAS 25/06/2024 Articles, Volume 142 KAS 25/06/2024

The Roman building at Chart Sutton revisited

Deborah Goacher, 2021, Archaeologia Cantiana, Volume 142. Maidstone: Kent Archaeological Society.

Read More
Notes on Contributors
Notes on Contributors, Volume 142 KAS 25/06/2024 Notes on Contributors, Volume 142 KAS 25/06/2024

Notes on Contributors

2021, Archaeologia Cantiana, Volume 142. Maidstone: Kent Archaeological Society.

Read More
Annual Bibliography of Kentish Archaeology and History 2013
Articles, Volume 135 KAS 25/06/2024 Articles, Volume 135 KAS 25/06/2024

Annual Bibliography of Kentish Archaeology and History 2013

2014, Archaeologia Cantiana, Volume 135, pp. 321-332. Maidstone: Kent Archaeological Society.

Read More
Notes on the Contributors
Volume 133 KAS 25/06/2024 Volume 133 KAS 25/06/2024

Notes on the Contributors

2013, Archaeologia Cantiana, Volume 133, pp. 361-364. Maidstone: Kent Archaeological Society.

Read More
Annual Report and Accounts for the Year 2012
Volume 133 KAS 25/06/2024 Volume 133 KAS 25/06/2024

Annual Report and Accounts for the Year 2012

2013, Archaeologia Cantiana, Volume 133, pp. 365-376. Maidstone: Kent Archaeological Society.

Read More
Annual Bibliography of Kentish Archaeology and History 2011
Articles, Volume 132 KAS 25/06/2024 Articles, Volume 132 KAS 25/06/2024

Annual Bibliography of Kentish Archaeology and History 2011

2012, Archaeologia Cantiana, Volume 132, pp. 375-384. Maidstone: Kent Archaeological Society.

Read More
Annual Bibliography of Kentish Archaeology and History 2010
Articles, Volume 131 KAS 25/06/2024 Articles, Volume 131 KAS 25/06/2024

Annual Bibliography of Kentish Archaeology and History 2010

2011, Archaeologia Cantiana, Volume 131, pp. 439-456. Maidstone: Kent Archaeological Society.

Read More
Brief Notes on Contributors
Articles, Volume 130 KAS 25/06/2024 Articles, Volume 130 KAS 25/06/2024

Brief Notes on Contributors

2010, Archaeologia Cantiana, Volume 130, pp. 441-442. Maidstone: Kent Archaeological Society.

Read More
Brief Notes on Contributors
Articles, Volume 129 KAS 25/06/2024 Articles, Volume 129 KAS 25/06/2024

Brief Notes on Contributors

2009, Archaeologia Cantiana, Volume 129, pp. 437-440. Maidstone: Kent Archaeological Society.

Read More
Dating the Cremation in the Biconical Urn at the Early Bronze Age Barrow Hill Road Wouldham
Articles, Volume 127 KAS 25/06/2024 Articles, Volume 127 KAS 25/06/2024

Dating the Cremation in the Biconical Urn at the Early Bronze Age Barrow Hill Road Wouldham

John Cruse, 2007, Archaeologia Cantiana, Volume 127, pp. 163-174. Maidstone: Kent Archaeological Society.

Read More
Brief Notes on the Contributors
Articles, Volume 122 KAS 25/06/2024 Articles, Volume 122 KAS 25/06/2024

Brief Notes on the Contributors

2002, Archaeologia Cantiana, Volume 122, pp. 445-448. Maidstone: Kent Archaeological Society.

Read More
Excavations at the Mount Roman Villa, Maidstone, 1994
Articles, Volume 119 KAS 25/06/2024 Articles, Volume 119 KAS 25/06/2024

Excavations at the Mount Roman Villa, Maidstone, 1994

Read More
Excavations on a Romano-British Villa at Churchfields, Snodland, 1992-94
Articles, Volume 115 KAS 25/06/2024 Articles, Volume 115 KAS 25/06/2024

Excavations on a Romano-British Villa at Churchfields, Snodland, 1992-94

Read More
The Mount Roman villa, Maidstone
Articles, Volume 110 KAS 25/06/2024 Articles, Volume 110 KAS 25/06/2024

The Mount Roman villa, Maidstone

Read More
The diaries of Allen Grove
Articles, Volume 111 KAS 25/06/2024 Articles, Volume 111 KAS 25/06/2024

The diaries of Allen Grove

Read More
Further Investigation of the Acheulian Site at Cuxton
Articles, Volume 104 KAS 25/06/2024 Articles, Volume 104 KAS 25/06/2024

Further Investigation of the Acheulian Site at Cuxton

Read More
Accounts for the Year Ended 31st December 1986
Articles, Volume 104 KAS 25/06/2024 Articles, Volume 104 KAS 25/06/2024

Accounts for the Year Ended 31st December 1986

Read More
Older Posts
  • Articles
  • General Indexes
  • Lists of Contents
  • Volume 10
  • Volume 100
  • Volume 101
  • Volume 102
  • Volume 103
  • Volume 104
  • Volume 107
  • Volume 108
  • Volume 109
  • Volume 11
  • Volume 110
  • Volume 112
  • Volume 114
  • Volume 115
  • Volume 116
  • Volume 12
  • Volume 120
  • Volume 121
  • Volume 122
  • Volume 123
  • Volume 124
  • Volume 125
  • Volume 126
  • Volume 127
  • Volume 128
  • Volume 129
  • Volume 13
  • Volume 130
  • Volume 131
  • Volume 133
  • Volume 135
  • Volume 136
  • Volume 138
  • Volume 139
  • Volume 14
  • Volume 140
  • Volume 143
  • Volume 145
  • Volume 146
  • Volume 15
  • Volume 16
  • Volume 17
  • Volume 18
  • Volume 2
  • Volume 20
  • Volume 21
  • Volume 22
  • Volume 23
  • Volume 24
  • Volume 28
  • Volume 31
  • Volume 36
  • Volume 37
  • Volume 38
  • Volume 39
  • Volume 40
  • Volume 41
  • Volume 42
  • Volume 43
  • Volume 44
  • Volume 45
  • Volume 46
  • Volume 47
  • Volume 48
  • Volume 61
  • Volume 64
  • Volume 65
  • Volume 66
  • Volume 68
  • Volume 69
  • Volume 70
  • Volume 71
  • Volume 72
  • Volume 74
  • Volume 77
  • Volume 78
  • Volume 79
  • Volume 80
  • Volume 81
  • Volume 82
  • Volume 83
  • Volume 84
  • Volume 85
  • Volume 86
  • Volume 87
  • Volume 88
  • Volume 89
  • Volume 9
  • Volume 91
  • Volume 92
  • Volume 93
  • Volume 94
  • Volume 95
  • Volume 96
  • Volume 97
  • Volume 98
  • Volume 99
  • Agriculture
  • Appledore
  • Ashford
  • Ashford Archaeological Society
  • Bexley
  • Bromley
  • Canterbury
  • Chatham
  • Church History
  • Churches
  • Cliffe (Hoo)
  • Cobham
  • Cooling
  • Cranbrook
  • Darent
  • Darenth
  • Dartford
  • Dartford & District Archaeological Group (DDAG)
  • Dartford Historical and Antiquarian Society
  • Deal
  • Defences
  • Dover
  • Earthworks
  • Eastry
  • Eccles
  • Edenbridge
  • Faversham
  • Fieldwork and Research Grants
  • Folkestone
  • Frindsbury
  • Genealogy
  • Gravesend
  • Gravesend Historical Society
  • Hasted Prize
  • Heraldry
  • Herne Bay Historical Records Society
  • Hoo
  • Hythe
  • Ightham
  • Industrial
  • Inventories
  • Iron Age
  • Isle of Sheppey
  • Isle of Thanet
  • Isle of Thanet Archaeological Society
  • KAS Collections
  • KAS Library
  • Kent Archives Kent History and Library Centre
  • Kent Family History Society
  • Knole
  • Little Chart
  • London
  • Lullingstone
  • Lyminge
  • Maidstone
  • Maidstone Area Archaeological Group (MAAG)
  • Maidstone Museum
  • Maps
  • Margate
  • Maritime
  • Medieval
  • Megaliths
  • Memorials
  • Military History
  • Milton
  • Minster-in-Thanet
  • Modern
  • Monasticism
  • New Romney
  • Nonington
  • Orpington and District Archaeological Society (ODAS)
  • Ospringe
  • Otford
  • Plaxtol Local History Group
  • Prehistoric
  • Ramsgate
  • Reculver
  • Richborough
  • River Medway
  • Roads
  • Rochester
  • Romney Marsh
  • Sandwich
  • Sarre
  • Sevenoaks
  • Shoreham
  • Shorne
  • Sittingbourne
  • Springhead
  • The Faversham Society
  • The Woolhope Club
  • Tonbridge
  • Tonbridge Historical Society
  • Trust for Thanet Archaeology
  • Upchurch
  • Weald
  • Westerham
  • Wills
  • Wingham
  • Wye Historical Society

Kent Archaeological Society

Registered Charity 1176989

Documents
Guidance
Licensing
Minutes
Privacy

//- Hero banners (() => { // --- Skip on certain site areas --- const url = window.location.href; const excludedSubstrings = [ "/p/", "/cart", ]; if (excludedSubstrings.some((s) => url.includes(s))) return; const run = async () => { if (document.getElementById("ka-hero")) return; // ✅ capture scroll BEFORE we insert anything const preInsertScrollY = window.pageYOffset || 0; const isItemView = document.body.classList.contains("view-item") || document.querySelector('meta[property="og:type"][content="article"]'); const path = window.location.pathname.replace(/\/+$/, ""); const segments = path.split("/").filter(Boolean); const looksLikeIndex = !!document.querySelector( [ ".summary-item-list", ".summary-item", ".blog-list", ".blog-list-wrapper", "main", "#page", ].join(",") ); const isRootIndexPage = !isItemView && segments.length === 1 && looksLikeIndex; // ✅ IMPORTANT: mark root index pages so CSS can be precise (and never hide the first section) if (isRootIndexPage && !isItemView) document.body.classList.add("ka-root-index"); /* ---------- URL decode helpers ---------- */ const decodeFromSquarespaceTagUrl = (slug) => { try { const normalized = String(slug || "").replace(/\+/g, "%20"); return decodeURIComponent(normalized); } catch { return String(slug || ""); } }; /* ✅ Filter detection + current filter label (tag/category) */ const getCurrentFilterInfo = () => { const p = window.location.pathname || ""; const usp = new URLSearchParams(window.location.search || ""); const findFromPath = (needle) => { const s = p.replace(/\/+$/, ""); const parts = s.split("/").filter(Boolean); const i = parts.indexOf(needle); if (i === -1) return ""; return parts[i + 1] || ""; }; // path style first const tagSlug = findFromPath("tag"); if (tagSlug) return { type: "tag", name: decodeFromSquarespaceTagUrl(tagSlug).trim() }; const catSlug = findFromPath("category") || findFromPath("categories"); if (catSlug) return { type: "category", name: decodeFromSquarespaceTagUrl(catSlug).trim() }; // query style const tagQ = (usp.get("tag") || "").trim(); if (tagQ) return { type: "tag", name: decodeFromSquarespaceTagUrl(tagQ).trim() }; const catQ = (usp.get("category") || usp.get("categories") || "").trim(); if (catQ) return { type: "category", name: decodeFromSquarespaceTagUrl(catQ).trim() }; return null; }; const filterInfo = getCurrentFilterInfo(); const isTagOrCategoryFiltered = !!filterInfo; // ✅ Treat filtered tag/category listing pages as "index-like" pages (still show hero) const isFilteredIndexLikePage = !isItemView && looksLikeIndex && isTagOrCategoryFiltered; /* ---------- Page-section helpers ---------- */ const TAG_CLOUD_SELECTOR = ".sqs-block-tagcloud, .sqs-tagcloud, .sqs-block-tagCloud"; const getPageSections = () => { const root = document.querySelector("main") || document.querySelector("#page") || document; return [...root.querySelectorAll('section[data-test="page-section"]')]; }; // ROOT INDEX: tags section is the SECOND page section (must contain a tag cloud) const getTagsSectionOnRootIndex = () => { const sections = getPageSections(); const second = sections[1] || null; if (!second) return null; return second.querySelector(TAG_CLOUD_SELECTOR) ? second : null; }; const getIndexSectionOnRootIndex = () => { const sections = getPageSections(); return sections[0] || null; }; // For filtered /tag/ /category/ pages (non-root), hide whichever section contains a tagcloud near the top. const hideTopTagsSectionOnFilteredPages = () => { const sections = getPageSections(); const target = sections.find((s) => s.querySelector(TAG_CLOUD_SELECTOR)) || null; if (target) target.style.display = "none"; }; // ✅ On root index pages: hide ONLY the tags section on initial load (never the index section) const hideTagsSectionOnRootIndexInitialLoad = () => { if (!isRootIndexPage || isItemView) return; const tagsSection = getTagsSectionOnRootIndex(); if (!tagsSection) return; tagsSection.style.display = "none"; tagsSection.dataset.kaHiddenByHero = "1"; }; hideTagsSectionOnRootIndexInitialLoad(); // ✅ For filtered list pages: hide the tagcloud section, but DO NOT exit (we still want the hero) if (isFilteredIndexLikePage) hideTopTagsSectionOnFilteredPages(); // If it's neither an item view nor a root index nor a filtered index-like page, do nothing. if (!isItemView && !isRootIndexPage && !isFilteredIndexLikePage) return; /* ---------- Smooth “fully into view” scrolling helper ---------- */ const scrollFullyIntoView = (el) => { if (!el) return; const top = el.getBoundingClientRect().top + window.pageYOffset; window.scrollTo({ top: Math.max(0, top), behavior: "smooth" }); }; /* ---------- Tags helpers (index-page sitemap augmentation = SECOND cloud only) ---------- */ const encodeForSquarespaceTagUrl = (tag) => encodeURIComponent(String(tag)).replace(/%20/g, "+"); const getSecondTagCloudUL = () => { const clouds = [ ...document.querySelectorAll(".sqs-block-tagcloud .sqs-tagcloud, .sqs-tagcloud"), ]; return clouds[1] || null; }; const getExistingTagNamesInSecondCloud = () => { const ul = getSecondTagCloudUL(); if (!ul) return new Set(); const names = new Set(); ul.querySelectorAll("li .name").forEach((n) => { const t = (n.textContent || "").trim(); if (t) names.add(t.toLowerCase()); }); return names; }; const addTagToSecondCloud = (tagName, sectionPath) => { const ul = getSecondTagCloudUL(); if (!ul) return false; const key = String(tagName || "").trim(); if (!key) return false; const exists = getExistingTagNamesInSecondCloud(); if (exists.has(key.toLowerCase())) return false; const li = document.createElement("li"); li.style.fontSize = "1.5em"; li.title = key; const a = document.createElement("a"); a.href = `${sectionPath}/tag/${encodeForSquarespaceTagUrl(key)}`; const span = document.createElement("span"); span.className = "name"; span.textContent = key; a.appendChild(span); li.appendChild(a); const items = [...ul.querySelectorAll("li")]; const idx = items.findIndex((existing) => { const existingName = (existing.querySelector(".name")?.textContent || "") .trim() .toLowerCase(); return existingName && existingName.localeCompare(key.toLowerCase()) > 0; }); if (idx === -1) ul.appendChild(li); else ul.insertBefore(li, items[idx]); return true; }; const loadSitemapAndAddMissingTagsToSecondCloud = async (sectionPath) => { const ul = getSecondTagCloudUL(); if (!ul) return; if (ul.dataset.kaTagsAugmented === "1") return; try { const res = await fetch("/sitemap.xml", { credentials: "same-origin" }); if (!res.ok) throw new Error(`sitemap fetch failed: ${res.status}`); const xmlText = await res.text(); const parser = new DOMParser(); const xml = parser.parseFromString(xmlText, "application/xml"); const locs = [...xml.getElementsByTagName("loc")] .map((n) => (n.textContent || "").trim()) .filter(Boolean); const sectionPathClean = sectionPath.replace(/\/+$/, ""); const wantedPrefixPath = `${sectionPathClean}/tag/`; const tagNames = new Set(); for (const loc of locs) { let u; try { u = new URL(loc, window.location.origin); } catch { continue; } if (!u.pathname.startsWith(wantedPrefixPath)) continue; const slug = u.pathname.slice(wantedPrefixPath.length).replace(/\/+$/, ""); if (!slug) continue; const tagName = decodeFromSquarespaceTagUrl(slug).trim(); if (tagName) tagNames.add(tagName); } tagNames.forEach((t) => addTagToSecondCloud(t, sectionPathClean)); ul.dataset.kaTagsAugmented = "1"; } catch (e) { console.warn("[KA] sitemap/tag merge failed", e); } }; /* ---------- Map helpers (FOCUS ON CURRENT PAGE LOCATION on item pages) ---------- */ const getMapLink = () => { const el = document.querySelector('meta[name="map-link"]') || document.querySelector('meta[property="map-link"]') || document.querySelector('meta[name="mapLink"]') || document.querySelector('meta[property="mapLink"]'); return (el?.getAttribute("content") || "").trim(); }; const getMetaContent = (selectorList) => { for (const sel of selectorList) { const v = document.querySelector(sel)?.getAttribute("content"); if (v && String(v).trim()) return String(v).trim(); } return ""; }; const getCoordinatesFromMeta = () => { const latitude = getMetaContent([ 'meta[property="og:latitude"]', 'meta[name="og:latitude"]', 'meta[property="place:location:latitude"]', 'meta[name="place:location:latitude"]', 'meta[name="latitude"]', 'meta[property="latitude"]', ]); const longitude = getMetaContent([ 'meta[property="og:longitude"]', 'meta[name="og:longitude"]', 'meta[property="place:location:longitude"]', 'meta[name="place:location:longitude"]', 'meta[name="longitude"]', 'meta[property="longitude"]', ]); return { latitude, longitude }; }; const MAP_BLUE = "#1b4f8a"; const buildMapSVG = (fill) => ` `; // ✅ Inline bookmark icon (category pages) — now BLUE by default const buildBookmarkSVG = (fill = MAP_BLUE) => ` `; const insertOrShowMapBelowHero = () => { const hero = document.getElementById("ka-hero"); if (!hero) return null; const existing = document.getElementById("ka-map-wrap"); if (existing) return existing; const mapLink = getMapLink(); if (!mapLink) return null; const { latitude, longitude } = getCoordinatesFromMeta(); const coordsHaveValues = !!latitude && !!longitude; const coordsNoData = latitude === "40.7207559" && longitude === "-74.0007613"; const coordsValid = coordsHaveValues && !coordsNoData; const coordinatesQuery = coordsValid ? `¢er=${longitude};${latitude}&level=14` : ""; const iframeSrc = `${mapLink}${coordinatesQuery}`; const wrap = document.createElement("section"); wrap.id = "ka-map-wrap"; const iframe = document.createElement("iframe"); iframe.setAttribute("loading", "lazy"); iframe.setAttribute("referrerpolicy", "no-referrer-when-downgrade"); iframe.title = "Location map"; iframe.src = iframeSrc; wrap.appendChild(iframe); if (coordsValid) { const disclaimer = document.createElement("div"); disclaimer.id = "ka-map-disclaimer"; disclaimer.innerHTML = `❗Please note location data is approximate. Be advised of local land ownership and public access restrictions.`; wrap.appendChild(disclaimer); } hero.insertAdjacentElement("afterend", wrap); return wrap; }; /* ---------- HERO CONTENT SETUP ---------- */ const getOGCurrent = (prop) => document.querySelector(`meta[property="${prop}"]`)?.content?.trim() || ""; const ogImageCurrent = getOGCurrent("og:image"); const rawTitleCurrent = getOGCurrent("og:title") || document.title || ""; const ogTitleCurrent = rawTitleCurrent.replace(/\s+—\s+Kent Archaeological Society\s*$/i, ""); const ogDescRawCurrent = getOGCurrent("og:description"); const ogDescCurrent = ogDescRawCurrent ? ogDescRawCurrent.replace(/\blink\b/gi, "").replace(/\s{2,}/g, " ").trim() : ""; // ✅ For /tag/ or /category/ listing pages, pull OG image/desc/title from the section landing page (e.g. /journal) const getLandingMetaForSection = async (sectionPath) => { const clean = String(sectionPath || "").replace(/\/+$/, ""); if (!clean) return null; const key = `kaLandingMeta:${clean}`; try { const cached = sessionStorage.getItem(key); if (cached) return JSON.parse(cached); } catch {} try { const res = await fetch(clean, { credentials: "same-origin" }); if (!res.ok) throw new Error(`landing fetch failed: ${res.status}`); const html = await res.text(); const doc = new DOMParser().parseFromString(html, "text/html"); const og = (prop) => doc.querySelector(`meta[property="${prop}"]`)?.getAttribute("content")?.trim() || ""; const image = og("og:image"); const rawTitle = og("og:title") || doc.title || ""; const title = rawTitle.replace(/\s+—\s+Kent Archaeological Society\s*$/i, ""); const descRaw = og("og:description"); const desc = descRaw ? descRaw.replace(/\blink\b/gi, "").replace(/\s{2,}/g, " ").trim() : ""; const out = { image, title, desc }; try { sessionStorage.setItem(key, JSON.stringify(out)); } catch {} return out; } catch (e) { console.warn("[KA] landing meta fetch failed", e); return null; } }; let ogImage = ogImageCurrent; let ogTitle = ogTitleCurrent; let ogDesc = ogDescCurrent; if (isFilteredIndexLikePage) { const sectionPath = segments[0] ? `/${segments[0]}` : ""; const landing = await getLandingMetaForSection(sectionPath); if (landing) { ogImage = landing.image || ogImage; ogTitle = landing.title || ogTitle; ogDesc = landing.desc || ogDesc; } } if (!ogTitle && !ogImage && !ogDesc) return; /* ---------- Map enable logic ---------- */ const mapLink = getMapLink(); const { latitude, longitude } = getCoordinatesFromMeta(); const coordsNoData = latitude === "40.7207559" && longitude === "-74.0007613"; const coordsValid = !!latitude && !!longitude && !coordsNoData; // ✅ Index/filtered pages: allow (needs mapLink). Item pages: only allow if coords valid. const mapEnabled = !!mapLink && (isItemView ? coordsValid : true); /* ---------- Link/PDF override ---------- */ let specialOverrideHref = null; let specialOverrideType = null; // "link" or "pdf" const findLinkOrPdfButton = () => { const anchors = Array.from( document.querySelectorAll( 'a.sqs-block-button-element, a.sqs-button-element, .sqs-block-button-container a' ) ); for (const a of anchors) { const txt = (a.textContent || "").trim(); const href = a.getAttribute("href"); if (!href) continue; if (txt === "Link") return { el: a, type: "link", href }; if (txt === "PDF") return { el: a, type: "pdf", href }; } return null; }; const removeLinkButtonBlock = (aEl) => { if (!aEl) return; const block = aEl.closest(".sqs-block-button") || aEl.closest(".button-block") || aEl.closest('[data-sqsp-block="button"]') || aEl.closest(".sqs-block-button-container"); if (block) block.remove(); else aEl.remove(); }; const btnInfo = findLinkOrPdfButton(); if (btnInfo) { specialOverrideHref = btnInfo.href; specialOverrideType = btnInfo.type; removeLinkButtonBlock(btnInfo.el); } const specialLabel = specialOverrideType === "pdf" ? "PDF" : "Link"; const specialIconSrc = specialOverrideType === "pdf" ? "/s/icon-download.svg" : "/s/icon-link.svg"; /* ---------- BUILD HERO ---------- */ const hero = document.createElement("section"); hero.id = "ka-hero"; if (ogImage) hero.style.setProperty("--ka-hero-image", `url("${ogImage}")`); // ✅ filtered listing pages: inline icon + text, centered, in place of excerpt const filterInlineHTML = isFilteredIndexLikePage && filterInfo?.name ? `
${ filterInfo.type === "category" ? buildBookmarkSVG(MAP_BLUE) : `` } ${filterInfo.name}
` : ""; const controlsHTML = isItemView ? `
${ specialOverrideHref ? `` : `` } ${ coordsValid ? `` : `` }
` : isRootIndexPage ? `
${ specialOverrideHref ? `` : `` }
` : `
${ specialOverrideHref ? `` : `` }
`; hero.innerHTML = `

${ isFilteredIndexLikePage ? (filterInlineHTML || "") : (ogDesc ? `

` : ``) }
${controlsHTML} `; hero.querySelector(".ka-hero__title").textContent = ogTitle; if (!isFilteredIndexLikePage && ogDesc) { hero.querySelector(".ka-hero__desc").textContent = ogDesc; } // ✅ INSERT HERO: // - Item pages: before article (as before) // - Everything else: insert at top (as before) const article = document.querySelector("article") || document.querySelector(".blog-item-wrapper") || document.querySelector(".content"); if (isItemView && article && article.parentNode) { article.parentNode.insertBefore(hero, article); } else { const target = document.querySelector("main") || document.querySelector("#page") || document.body; target.insertBefore(hero, target.firstChild); } /* ✅ AMENDMENT: remove .blog-item-top-wrapper (all other functionality unchanged) */ document.querySelectorAll(".blog-item-top-wrapper").forEach((el) => el.remove()); /* ✅ KEY AMENDMENT: On tag/category pages: after inserting the hero at the top, auto-scroll DOWN by the hero height so the hero starts ABOVE the viewport. Result: user must scroll UP to see the hero. */ if (isFilteredIndexLikePage) { requestAnimationFrame(() => { requestAnimationFrame(() => { const heroH = hero.getBoundingClientRect().height || hero.offsetHeight || 0; // Preserve any non-zero initial scroll (in case Squarespace restores position) const nextY = Math.max(0, preInsertScrollY + heroH + 1); // Use instant jump (no smooth) so it feels like the "natural" start position window.scrollTo(0, nextY); }); }); } /* ---------- CSS (hero + controls only) ---------- */ if (!document.getElementById("ka-hero-css")) { const css = document.createElement("style"); css.id = "ka-hero-css"; css.textContent = ` /* ✅ ROOT INDEX GUARANTEES */ body.ka-root-index section[data-test="page-section"]:first-of-type{ display:block !important; } body.ka-root-index:not(.ka-tags-open) section[data-test="page-section"]:nth-of-type(2){ display:none !important; } /* HERO */ #ka-hero{ --ka-hero-image:none; position:relative; width:100%; height:100vh; display:grid; place-items:center; overflow:hidden; margin:0; background:#111; } #ka-hero::before{ content:""; position:absolute; inset:0; background-image:var(--ka-hero-image); background-size:cover; background-position:center; transform:scale(1.02); } #ka-hero::after{ content:""; position:absolute; inset:0; background:rgba(0,0,0,.48); } .ka-hero__inner{ position:relative; z-index:2; max-width:1100px; padding:clamp(24px, 5vw, 72px); text-align:center; } .ka-hero__title{ margin:0 0 14px; color:#fff; font-weight:400; font-size:clamp(36px, 4.6vw, 72px); line-height:1.05; letter-spacing:-0.01em; text-wrap:balance; } .ka-hero__desc{ margin:0 0 16px; color:rgba(255,255,255,.92); font-size:clamp(16px, 1.7vw, 24px); line-height:1.4; max-width:70ch; margin-inline:auto; } /* ✅ Filter inline (tag/category pages): replaces excerpt */ .ka-hero__filter-inline{ margin:0 0 16px; display:inline-flex; align-items:center; justify-content:center; gap:10px; color:rgba(255,255,255,.92); font-size:clamp(16px, 2.0vw, 26px); line-height:1.2; max-width:70ch; margin-inline:auto; text-shadow:0 10px 24px rgba(0,0,0,.35); } /* ✅ wrapper contains inline SVG or img */ .ka-hero__filter-inline-icon{ width:26px; height:26px; display:inline-flex; align-items:center; justify-content:center; vertical-align:middle; filter:drop-shadow(0 6px 14px rgba(0,0,0,.35)); } .ka-hero__filter-inline-icon svg{ width:100%; height:100%; display:block; } .ka-hero__filter-inline-icon-img{ width:100%; height:100%; display:block; } .ka-hero__filter-inline-text{ display:inline-block; } /* Controls: position */ #ka-hero-controls{ position:absolute; left:50%; bottom:124px; transform:translateX(-50%); z-index:4; width:min(920px, 92vw); display:flex; justify-content:center; pointer-events:none; text-align:center; } #ka-hero-controls .ka-btn-row{ pointer-events:auto; width:100%; display:flex; justify-content:center; align-items:center; gap:18px; } #ka-hero-controls.is-index .ka-btn-row{ display:grid; grid-template-columns: 1fr auto 1fr; align-items:center; column-gap:18px; } #ka-hero-controls.is-index #ka-tags-btn{ justify-self:end; } #ka-hero-controls.is-index #ka-map-btn{ justify-self:start; } /* Glass buttons */ .ka-glass-btn{ appearance:none; border:1px solid rgba(255,255,255,.22); background:rgba(255,255,255,.14); color:rgba(255,255,255,.96); backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px); box-shadow:0 14px 34px rgba(0,0,0,.28), inset 0 1px 0 rgba(255,255,255,.22); border-radius:999px; display:inline-flex; align-items:center; gap:10px; padding:10px 16px; cursor:pointer; font-family:Georgia,"Times New Roman",Times,serif; font-size:16px; line-height:1; user-select:none; -webkit-tap-highlight-color:transparent; transform:translateZ(0); transition:transform .16s ease, filter .16s ease, background .16s ease, border-color .16s ease; text-decoration:none; white-space:nowrap; } .ka-glass-btn:hover, .ka-glass-btn:focus-visible{ transform:translateY(-2px) scale(1.06); filter:brightness(1.08); background:rgba(255,255,255,.18); border-color:rgba(255,255,255,.30); outline:none; } .ka-glass-btn.ka-disabled{ opacity:.55; cursor:not-allowed; pointer-events:none; } .ka-glass-btn img, .ka-glass-btn svg{ width:26px; height:26px; display:block; filter:drop-shadow(0 6px 14px rgba(0,0,0,.35)); } /* Narrow screens: controls up */ @media (max-width:640px){ #ka-hero-controls{ bottom:194px; } .ka-hero__filter-inline-icon{ width:22px; height:22px; } } body.view-item main, body.view-item #page{ padding-top:0 !important; } `; document.head.appendChild(css); } /* ---------- ROOT INDEX ONLY: Tags click -> move tags section under hero, hide index section ---------- */ const tagsBtn = hero.querySelector("#ka-tags-btn"); let tagsPlaceholder = null; const openTagsView = async () => { if (!isRootIndexPage || isItemView) return; const tagsSection = getTagsSectionOnRootIndex(); const indexSection = getIndexSectionOnRootIndex(); if (!tagsSection) return; if (!tagsPlaceholder) { tagsPlaceholder = document.createComment("ka-tags-placeholder"); tagsSection.parentNode.insertBefore(tagsPlaceholder, tagsSection); } tagsSection.style.display = ""; delete tagsSection.dataset.kaHiddenByHero; hero.insertAdjacentElement("afterend", tagsSection); if (indexSection) { indexSection.style.display = "none"; indexSection.dataset.kaHiddenByHero = "1"; } document.body.classList.add("ka-tags-open"); requestAnimationFrame(() => requestAnimationFrame(() => scrollFullyIntoView(tagsSection))); const sectionPath = `/${segments[0]}`; await loadSitemapAndAddMissingTagsToSecondCloud(sectionPath); }; const closeTagsView = () => { if (!isRootIndexPage || isItemView) return; const tagsSection = getTagsSectionOnRootIndex(); const indexSection = getIndexSectionOnRootIndex(); if (tagsSection && tagsPlaceholder && tagsPlaceholder.parentNode) { tagsPlaceholder.parentNode.insertBefore(tagsSection, tagsPlaceholder); tagsPlaceholder.parentNode.removeChild(tagsPlaceholder); tagsPlaceholder = null; tagsSection.style.display = "none"; tagsSection.dataset.kaHiddenByHero = "1"; } if (indexSection && indexSection.dataset.kaHiddenByHero === "1") { indexSection.style.display = ""; delete indexSection.dataset.kaHiddenByHero; } document.body.classList.remove("ka-tags-open"); }; if (tagsBtn) { tagsBtn.addEventListener("click", async () => { if (document.body.classList.contains("ka-tags-open")) closeTagsView(); else await openTagsView(); }); } /* ---------- Map click ---------- */ const mapBtn = hero.querySelector("#ka-map-btn"); if (mapBtn && mapEnabled) { mapBtn.addEventListener("click", () => { const mapSection = insertOrShowMapBelowHero(); if (!mapSection) return; requestAnimationFrame(() => requestAnimationFrame(() => scrollFullyIntoView(mapSection))); }); } /* ---------- Link/PDF click ---------- */ const linkBtn = hero.querySelector("#ka-link-btn"); if (linkBtn && specialOverrideHref) { linkBtn.addEventListener("click", () => { window.location.href = specialOverrideHref; }); } }; if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", () => run(), { once: true }); } else { run(); } })(); //- Tag icons on blog pages (() => { const add = () => { document .querySelectorAll('div.blog-meta-item--tags[data-content-field="tags"] a[rel="tag"]') .forEach((a) => { if (a.querySelector("img.ka-tags-icon")) return; const img = document.createElement("img"); img.className = "ka-tags-icon"; img.src = "/s/icon-tags.svg"; img.alt = ""; img.setAttribute("aria-hidden", "true"); a.prepend(img); }); }; if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", add); } else { add(); } })();