<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Home on Popular</title><link>https://popular.mariatta.ca/</link><description>Recent content in Home on Popular</description><generator>Hugo</generator><language>en</language><atom:link href="https://popular.mariatta.ca/index.xml" rel="self" type="application/rss+xml"/><item><title>Mariatta</title><link>https://popular.mariatta.ca/organizers/mariatta/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://popular.mariatta.ca/organizers/mariatta/</guid><description/></item><item><title>Quick start</title><link>https://popular.mariatta.ca/docs/quick-start/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://popular.mariatta.ca/docs/quick-start/</guid><description>&lt;div class="g-fwswitch" role="tablist" aria-label="Framework"&gt;
 &lt;button data-fw="hugo" role="tab"&gt;&lt;i class="fa-solid fa-h" aria-hidden="true"&gt;&lt;/i&gt; Hugo&lt;/button&gt;
 &lt;button data-fw="astro" role="tab"&gt;&lt;i class="fa-solid fa-rocket" aria-hidden="true"&gt;&lt;/i&gt; Astro&lt;/button&gt;
&lt;/div&gt;
&lt;style&gt;
 .g-fwswitch { display: inline-flex; gap: 4px; padding: 4px; background: var(--surface-tertiary);
 border: var(--border-width) solid var(--border-subtle); border-radius: var(--radius-pill); margin: 0.4rem 0 1rem; }
 .g-fwswitch button { font-family: var(--font-sans); font-size: var(--text-sm); font-weight: var(--weight-semibold);
 border: none; background: transparent; color: var(--text-muted); padding: 0.45rem 1.1rem;
 border-radius: var(--radius-pill); cursor: pointer; display: inline-flex; gap: 0.45em; align-items: center; }
 .g-fwswitch button.is-active { background: var(--color-primary); color: var(--text-on-brand); }
 .fw-block { display: none; }
 .fw-block.is-active { display: block; }
&lt;/style&gt;
&lt;script&gt;
 (function () {
 if (window.__popularFw) return; window.__popularFw = true;
 function apply(fw) {
 try { localStorage.setItem("popular-fw", fw); } catch (e) {}
 document.querySelectorAll(".g-fwswitch button").forEach(function (b) {
 b.classList.toggle("is-active", b.getAttribute("data-fw") === fw);
 b.setAttribute("aria-selected", b.getAttribute("data-fw") === fw ? "true" : "false");
 });
 document.querySelectorAll(".fw-block").forEach(function (el) {
 el.classList.toggle("is-active", el.getAttribute("data-fw") === fw);
 });
 }
 document.addEventListener("click", function (e) {
 var b = e.target.closest(".g-fwswitch button");
 if (b) apply(b.getAttribute("data-fw"));
 });
 document.addEventListener("DOMContentLoaded", function () {
 var fw = new URLSearchParams(location.search).get("fw");
 try { fw = fw || localStorage.getItem("popular-fw"); } catch (e) {}
 apply(fw === "astro" ? "astro" : "hugo");
 });
 })();
&lt;/script&gt;

&lt;h2 id="1--get-the-theme"&gt;1 · Get the theme&lt;/h2&gt;
&lt;div class="fw-block" data-fw="hugo"&gt;
&lt;p&gt;Add the theme to your Hugo site as a git submodule (or copy the folder into &lt;code&gt;themes/popular&lt;/code&gt;; Hugo Modules users can instead import &lt;code&gt;github.com/Mariatta/hugo-theme-popular&lt;/code&gt;, see the README):&lt;/p&gt;</description></item><item><title>Configuration reference</title><link>https://popular.mariatta.ca/docs/configuration/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://popular.mariatta.ca/docs/configuration/</guid><description>&lt;div class="g-fwswitch" role="tablist" aria-label="Framework"&gt;
 &lt;button data-fw="hugo" role="tab"&gt;&lt;i class="fa-solid fa-h" aria-hidden="true"&gt;&lt;/i&gt; Hugo&lt;/button&gt;
 &lt;button data-fw="astro" role="tab"&gt;&lt;i class="fa-solid fa-rocket" aria-hidden="true"&gt;&lt;/i&gt; Astro&lt;/button&gt;
&lt;/div&gt;
&lt;style&gt;
 .g-fwswitch { display: inline-flex; gap: 4px; padding: 4px; background: var(--surface-tertiary);
 border: var(--border-width) solid var(--border-subtle); border-radius: var(--radius-pill); margin: 0.4rem 0 1rem; }
 .g-fwswitch button { font-family: var(--font-sans); font-size: var(--text-sm); font-weight: var(--weight-semibold);
 border: none; background: transparent; color: var(--text-muted); padding: 0.45rem 1.1rem;
 border-radius: var(--radius-pill); cursor: pointer; display: inline-flex; gap: 0.45em; align-items: center; }
 .g-fwswitch button.is-active { background: var(--color-primary); color: var(--text-on-brand); }
 .fw-block { display: none; }
 .fw-block.is-active { display: block; }
&lt;/style&gt;
&lt;script&gt;
 (function () {
 if (window.__popularFw) return; window.__popularFw = true;
 function apply(fw) {
 try { localStorage.setItem("popular-fw", fw); } catch (e) {}
 document.querySelectorAll(".g-fwswitch button").forEach(function (b) {
 b.classList.toggle("is-active", b.getAttribute("data-fw") === fw);
 b.setAttribute("aria-selected", b.getAttribute("data-fw") === fw ? "true" : "false");
 });
 document.querySelectorAll(".fw-block").forEach(function (el) {
 el.classList.toggle("is-active", el.getAttribute("data-fw") === fw);
 });
 }
 document.addEventListener("click", function (e) {
 var b = e.target.closest(".g-fwswitch button");
 if (b) apply(b.getAttribute("data-fw"));
 });
 document.addEventListener("DOMContentLoaded", function () {
 var fw = new URLSearchParams(location.search).get("fw");
 try { fw = fw || localStorage.getItem("popular-fw"); } catch (e) {}
 apply(fw === "astro" ? "astro" : "hugo");
 });
 })();
&lt;/script&gt;

&lt;h2 id="site-identity"&gt;Site identity&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;title&lt;/code&gt;, &lt;code&gt;tagline&lt;/code&gt;, &lt;code&gt;description&lt;/code&gt;, &lt;code&gt;brandName&lt;/code&gt; + &lt;code&gt;brandSub&lt;/code&gt; (the two-line wordmark in the header), &lt;code&gt;logo&lt;/code&gt;, &lt;code&gt;ogImage&lt;/code&gt;, and &lt;code&gt;landAcknowledgement&lt;/code&gt; (footer slot, leave empty to hide).&lt;/p&gt;</description></item><item><title>Content model</title><link>https://popular.mariatta.ca/docs/content-model/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://popular.mariatta.ca/docs/content-model/</guid><description>&lt;div class="g-fwswitch" role="tablist" aria-label="Framework"&gt;
 &lt;button data-fw="hugo" role="tab"&gt;&lt;i class="fa-solid fa-h" aria-hidden="true"&gt;&lt;/i&gt; Hugo&lt;/button&gt;
 &lt;button data-fw="astro" role="tab"&gt;&lt;i class="fa-solid fa-rocket" aria-hidden="true"&gt;&lt;/i&gt; Astro&lt;/button&gt;
&lt;/div&gt;
&lt;style&gt;
 .g-fwswitch { display: inline-flex; gap: 4px; padding: 4px; background: var(--surface-tertiary);
 border: var(--border-width) solid var(--border-subtle); border-radius: var(--radius-pill); margin: 0.4rem 0 1rem; }
 .g-fwswitch button { font-family: var(--font-sans); font-size: var(--text-sm); font-weight: var(--weight-semibold);
 border: none; background: transparent; color: var(--text-muted); padding: 0.45rem 1.1rem;
 border-radius: var(--radius-pill); cursor: pointer; display: inline-flex; gap: 0.45em; align-items: center; }
 .g-fwswitch button.is-active { background: var(--color-primary); color: var(--text-on-brand); }
 .fw-block { display: none; }
 .fw-block.is-active { display: block; }
&lt;/style&gt;
&lt;script&gt;
 (function () {
 if (window.__popularFw) return; window.__popularFw = true;
 function apply(fw) {
 try { localStorage.setItem("popular-fw", fw); } catch (e) {}
 document.querySelectorAll(".g-fwswitch button").forEach(function (b) {
 b.classList.toggle("is-active", b.getAttribute("data-fw") === fw);
 b.setAttribute("aria-selected", b.getAttribute("data-fw") === fw ? "true" : "false");
 });
 document.querySelectorAll(".fw-block").forEach(function (el) {
 el.classList.toggle("is-active", el.getAttribute("data-fw") === fw);
 });
 }
 document.addEventListener("click", function (e) {
 var b = e.target.closest(".g-fwswitch button");
 if (b) apply(b.getAttribute("data-fw"));
 });
 document.addEventListener("DOMContentLoaded", function () {
 var fw = new URLSearchParams(location.search).get("fw");
 try { fw = fw || localStorage.getItem("popular-fw"); } catch (e) {}
 apply(fw === "astro" ? "astro" : "hugo");
 });
 })();
&lt;/script&gt;

&lt;h2 id="blog-posts"&gt;Blog posts&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;title&lt;/code&gt;, &lt;code&gt;date&lt;/code&gt;, &lt;code&gt;description&lt;/code&gt;, &lt;code&gt;image&lt;/code&gt;, &lt;code&gt;tags[]&lt;/code&gt;, plus authorship (see below) and an optional &lt;code&gt;speaker&lt;/code&gt; block (name, title, photo, bio) for recap posts.&lt;/p&gt;</description></item><item><title>Theming</title><link>https://popular.mariatta.ca/docs/theming/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://popular.mariatta.ca/docs/theming/</guid><description>&lt;div class="g-fwswitch" role="tablist" aria-label="Framework"&gt;
 &lt;button data-fw="hugo" role="tab"&gt;&lt;i class="fa-solid fa-h" aria-hidden="true"&gt;&lt;/i&gt; Hugo&lt;/button&gt;
 &lt;button data-fw="astro" role="tab"&gt;&lt;i class="fa-solid fa-rocket" aria-hidden="true"&gt;&lt;/i&gt; Astro&lt;/button&gt;
&lt;/div&gt;
&lt;style&gt;
 .g-fwswitch { display: inline-flex; gap: 4px; padding: 4px; background: var(--surface-tertiary);
 border: var(--border-width) solid var(--border-subtle); border-radius: var(--radius-pill); margin: 0.4rem 0 1rem; }
 .g-fwswitch button { font-family: var(--font-sans); font-size: var(--text-sm); font-weight: var(--weight-semibold);
 border: none; background: transparent; color: var(--text-muted); padding: 0.45rem 1.1rem;
 border-radius: var(--radius-pill); cursor: pointer; display: inline-flex; gap: 0.45em; align-items: center; }
 .g-fwswitch button.is-active { background: var(--color-primary); color: var(--text-on-brand); }
 .fw-block { display: none; }
 .fw-block.is-active { display: block; }
&lt;/style&gt;
&lt;script&gt;
 (function () {
 if (window.__popularFw) return; window.__popularFw = true;
 function apply(fw) {
 try { localStorage.setItem("popular-fw", fw); } catch (e) {}
 document.querySelectorAll(".g-fwswitch button").forEach(function (b) {
 b.classList.toggle("is-active", b.getAttribute("data-fw") === fw);
 b.setAttribute("aria-selected", b.getAttribute("data-fw") === fw ? "true" : "false");
 });
 document.querySelectorAll(".fw-block").forEach(function (el) {
 el.classList.toggle("is-active", el.getAttribute("data-fw") === fw);
 });
 }
 document.addEventListener("click", function (e) {
 var b = e.target.closest(".g-fwswitch button");
 if (b) apply(b.getAttribute("data-fw"));
 });
 document.addEventListener("DOMContentLoaded", function () {
 var fw = new URLSearchParams(location.search).get("fw");
 try { fw = fw || localStorage.getItem("popular-fw"); } catch (e) {}
 apply(fw === "astro" ? "astro" : "hugo");
 });
 })();
&lt;/script&gt;

&lt;h2 id="the-one-block-re-brand"&gt;The one-block re-brand&lt;/h2&gt;
&lt;p&gt;Every colour, font and radius in the theme resolves through CSS custom properties (design tokens). The &lt;code&gt;brand&lt;/code&gt; config block overrides the important ones at render time:&lt;/p&gt;</description></item><item><title>Components &amp; shortcodes</title><link>https://popular.mariatta.ca/docs/components/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://popular.mariatta.ca/docs/components/</guid><description>&lt;div class="g-fwswitch" role="tablist" aria-label="Framework"&gt;
 &lt;button data-fw="hugo" role="tab"&gt;&lt;i class="fa-solid fa-h" aria-hidden="true"&gt;&lt;/i&gt; Hugo&lt;/button&gt;
 &lt;button data-fw="astro" role="tab"&gt;&lt;i class="fa-solid fa-rocket" aria-hidden="true"&gt;&lt;/i&gt; Astro&lt;/button&gt;
&lt;/div&gt;
&lt;style&gt;
 .g-fwswitch { display: inline-flex; gap: 4px; padding: 4px; background: var(--surface-tertiary);
 border: var(--border-width) solid var(--border-subtle); border-radius: var(--radius-pill); margin: 0.4rem 0 1rem; }
 .g-fwswitch button { font-family: var(--font-sans); font-size: var(--text-sm); font-weight: var(--weight-semibold);
 border: none; background: transparent; color: var(--text-muted); padding: 0.45rem 1.1rem;
 border-radius: var(--radius-pill); cursor: pointer; display: inline-flex; gap: 0.45em; align-items: center; }
 .g-fwswitch button.is-active { background: var(--color-primary); color: var(--text-on-brand); }
 .fw-block { display: none; }
 .fw-block.is-active { display: block; }
&lt;/style&gt;
&lt;script&gt;
 (function () {
 if (window.__popularFw) return; window.__popularFw = true;
 function apply(fw) {
 try { localStorage.setItem("popular-fw", fw); } catch (e) {}
 document.querySelectorAll(".g-fwswitch button").forEach(function (b) {
 b.classList.toggle("is-active", b.getAttribute("data-fw") === fw);
 b.setAttribute("aria-selected", b.getAttribute("data-fw") === fw ? "true" : "false");
 });
 document.querySelectorAll(".fw-block").forEach(function (el) {
 el.classList.toggle("is-active", el.getAttribute("data-fw") === fw);
 });
 }
 document.addEventListener("click", function (e) {
 var b = e.target.closest(".g-fwswitch button");
 if (b) apply(b.getAttribute("data-fw"));
 });
 document.addEventListener("DOMContentLoaded", function () {
 var fw = new URLSearchParams(location.search).get("fw");
 try { fw = fw || localStorage.getItem("popular-fw"); } catch (e) {}
 apply(fw === "astro" ? "astro" : "hugo");
 });
 })();
&lt;/script&gt;

&lt;h2 id="callout"&gt;Callout&lt;/h2&gt;
&lt;p&gt;Info, tip and warning boxes with an optional title.&lt;/p&gt;</description></item><item><title>Importing content</title><link>https://popular.mariatta.ca/docs/importing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://popular.mariatta.ca/docs/importing/</guid><description>&lt;div class="g-fwswitch" role="tablist" aria-label="Framework"&gt;
 &lt;button data-fw="hugo" role="tab"&gt;&lt;i class="fa-solid fa-h" aria-hidden="true"&gt;&lt;/i&gt; Hugo&lt;/button&gt;
 &lt;button data-fw="astro" role="tab"&gt;&lt;i class="fa-solid fa-rocket" aria-hidden="true"&gt;&lt;/i&gt; Astro&lt;/button&gt;
&lt;/div&gt;
&lt;style&gt;
 .g-fwswitch { display: inline-flex; gap: 4px; padding: 4px; background: var(--surface-tertiary);
 border: var(--border-width) solid var(--border-subtle); border-radius: var(--radius-pill); margin: 0.4rem 0 1rem; }
 .g-fwswitch button { font-family: var(--font-sans); font-size: var(--text-sm); font-weight: var(--weight-semibold);
 border: none; background: transparent; color: var(--text-muted); padding: 0.45rem 1.1rem;
 border-radius: var(--radius-pill); cursor: pointer; display: inline-flex; gap: 0.45em; align-items: center; }
 .g-fwswitch button.is-active { background: var(--color-primary); color: var(--text-on-brand); }
 .fw-block { display: none; }
 .fw-block.is-active { display: block; }
&lt;/style&gt;
&lt;script&gt;
 (function () {
 if (window.__popularFw) return; window.__popularFw = true;
 function apply(fw) {
 try { localStorage.setItem("popular-fw", fw); } catch (e) {}
 document.querySelectorAll(".g-fwswitch button").forEach(function (b) {
 b.classList.toggle("is-active", b.getAttribute("data-fw") === fw);
 b.setAttribute("aria-selected", b.getAttribute("data-fw") === fw ? "true" : "false");
 });
 document.querySelectorAll(".fw-block").forEach(function (el) {
 el.classList.toggle("is-active", el.getAttribute("data-fw") === fw);
 });
 }
 document.addEventListener("click", function (e) {
 var b = e.target.closest(".g-fwswitch button");
 if (b) apply(b.getAttribute("data-fw"));
 });
 document.addEventListener("DOMContentLoaded", function () {
 var fw = new URLSearchParams(location.search).get("fw");
 try { fw = fw || localStorage.getItem("popular-fw"); } catch (e) {}
 apply(fw === "astro" ? "astro" : "hugo");
 });
 })();
&lt;/script&gt;

&lt;p&gt;Both importers ship in both repos (&lt;code&gt;scripts/&lt;/code&gt; directory), work for either framework (the output format is auto-detected from your site), and follow the same safety rules:&lt;/p&gt;</description></item><item><title>Updating the theme</title><link>https://popular.mariatta.ca/docs/updating/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://popular.mariatta.ca/docs/updating/</guid><description>&lt;h2 id="hearing-about-releases"&gt;Hearing about releases&lt;/h2&gt;
&lt;p&gt;Popular is released with semver tags (&lt;code&gt;v0.2.0&lt;/code&gt;), in lockstep across the Hugo
and Astro repos: one version number covers both. Three ways to hear about a
new one:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Watch the repo&lt;/strong&gt;: on GitHub, Watch → Custom → Releases. You get a
notification per release, nothing else.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RSS&lt;/strong&gt;: subscribe to the &lt;a href="https://github.com/Mariatta/hugo-theme-popular/releases.atom"&gt;releases feed&lt;/a&gt;
in any feed reader.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The changelog&lt;/strong&gt;: &lt;a href="https://github.com/Mariatta/hugo-theme-popular/blob/main/CHANGELOG.md"&gt;CHANGELOG.md&lt;/a&gt;
ships in both repos and is the same file in each.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="before-you-update"&gt;Before you update&lt;/h2&gt;
&lt;p&gt;Read the release notes (or the changelog section, same text). During 0.x, a
minor version may contain breaking changes; when one does, the entry says so
and tells you what to change. The 1.0 release will mark the content model and
brand keys stable.&lt;/p&gt;</description></item><item><title>Demos &amp; deployment</title><link>https://popular.mariatta.ca/docs/demos/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://popular.mariatta.ca/docs/demos/</guid><description>&lt;div class="g-fwswitch" role="tablist" aria-label="Framework"&gt;
 &lt;button data-fw="hugo" role="tab"&gt;&lt;i class="fa-solid fa-h" aria-hidden="true"&gt;&lt;/i&gt; Hugo&lt;/button&gt;
 &lt;button data-fw="astro" role="tab"&gt;&lt;i class="fa-solid fa-rocket" aria-hidden="true"&gt;&lt;/i&gt; Astro&lt;/button&gt;
&lt;/div&gt;
&lt;style&gt;
 .g-fwswitch { display: inline-flex; gap: 4px; padding: 4px; background: var(--surface-tertiary);
 border: var(--border-width) solid var(--border-subtle); border-radius: var(--radius-pill); margin: 0.4rem 0 1rem; }
 .g-fwswitch button { font-family: var(--font-sans); font-size: var(--text-sm); font-weight: var(--weight-semibold);
 border: none; background: transparent; color: var(--text-muted); padding: 0.45rem 1.1rem;
 border-radius: var(--radius-pill); cursor: pointer; display: inline-flex; gap: 0.45em; align-items: center; }
 .g-fwswitch button.is-active { background: var(--color-primary); color: var(--text-on-brand); }
 .fw-block { display: none; }
 .fw-block.is-active { display: block; }
&lt;/style&gt;
&lt;script&gt;
 (function () {
 if (window.__popularFw) return; window.__popularFw = true;
 function apply(fw) {
 try { localStorage.setItem("popular-fw", fw); } catch (e) {}
 document.querySelectorAll(".g-fwswitch button").forEach(function (b) {
 b.classList.toggle("is-active", b.getAttribute("data-fw") === fw);
 b.setAttribute("aria-selected", b.getAttribute("data-fw") === fw ? "true" : "false");
 });
 document.querySelectorAll(".fw-block").forEach(function (el) {
 el.classList.toggle("is-active", el.getAttribute("data-fw") === fw);
 });
 }
 document.addEventListener("click", function (e) {
 var b = e.target.closest(".g-fwswitch button");
 if (b) apply(b.getAttribute("data-fw"));
 });
 document.addEventListener("DOMContentLoaded", function () {
 var fw = new URLSearchParams(location.search).get("fw");
 try { fw = fw || localStorage.getItem("popular-fw"); } catch (e) {}
 apply(fw === "astro" ? "astro" : "hugo");
 });
 })();
&lt;/script&gt;

&lt;h2 id="the-four-demos"&gt;The four demos&lt;/h2&gt;
&lt;p&gt;All four are complete example sites, every page, guides, blog and events. They exist to prove one claim: &lt;strong&gt;the entire visual difference between them is one config block.&lt;/strong&gt; None is more &amp;ldquo;official&amp;rdquo; than the others.&lt;/p&gt;</description></item><item><title>Migrating images from another theme</title><link>https://popular.mariatta.ca/docs/migrating-images/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://popular.mariatta.ca/docs/migrating-images/</guid><description>&lt;h2 id="the-short-version"&gt;The short version&lt;/h2&gt;
&lt;p&gt;Popular references images at site-relative paths like &lt;code&gt;/images/hero.png&lt;/code&gt;, and
Hugo serves anything in your &lt;code&gt;static/&lt;/code&gt; directory at the site root. So the
simplest migration is: &lt;strong&gt;put your images in &lt;code&gt;static/images/&lt;/code&gt;&lt;/strong&gt; and reference
them as &lt;code&gt;/images/...&lt;/code&gt;. Nothing else to configure.&lt;/p&gt;
&lt;p&gt;If your old theme kept images somewhere else (an assets pipeline, a
&lt;code&gt;page bundle&lt;/code&gt;, an &lt;code&gt;img/&lt;/code&gt; folder) and you&amp;rsquo;d rather not move them, you can
&lt;em&gt;mount&lt;/em&gt; that directory to &lt;code&gt;/images/&lt;/code&gt; instead.&lt;/p&gt;</description></item><item><title>SEO &amp; structured data</title><link>https://popular.mariatta.ca/docs/seo/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://popular.mariatta.ca/docs/seo/</guid><description>&lt;h2 id="whats-automatic"&gt;What&amp;rsquo;s automatic&lt;/h2&gt;
&lt;p&gt;Every page gets a description, canonical URL, full Open Graph and Twitter card
tags, &lt;code&gt;og:locale&lt;/code&gt;, and a &lt;code&gt;robots.txt&lt;/code&gt; advertising your sitemap. You don&amp;rsquo;t
configure any of it.&lt;/p&gt;
&lt;p&gt;The site also emits &lt;strong&gt;&lt;code&gt;/llms.txt&lt;/code&gt;&lt;/strong&gt;, a short plain-text summary for AI agents:
what the community is, the next upcoming event (regenerated every build so it
stays true), how to join, and links to the key pages and the calendar feed. On
Astro it is always generated; on Hugo add &lt;code&gt;LLMS&lt;/code&gt; to the home page&amp;rsquo;s outputs
(the demos and starter already do).&lt;/p&gt;</description></item><item><title>FAQ sections</title><link>https://popular.mariatta.ca/docs/faq/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://popular.mariatta.ca/docs/faq/</guid><description>&lt;h2 id="why"&gt;Why&lt;/h2&gt;
&lt;p&gt;First-timers have the same handful of questions: do I need experience, is it
free, how do I find the room. Answer them where people land. The FAQ block
also gives AI answer engines (ChatGPT, Perplexity, AI Overviews) clean
question → answer text to quote.&lt;/p&gt;
&lt;p&gt;Note: classic FAQ &lt;strong&gt;rich results&lt;/strong&gt; are not a goal. Google restricts them to
government and health sites, so don&amp;rsquo;t expect snippets. The value is on-page
clarity and AI-friendliness.&lt;/p&gt;</description></item><item><title>Beyond meetups</title><link>https://popular.mariatta.ca/docs/beyond-meetups/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://popular.mariatta.ca/docs/beyond-meetups/</guid><description>&lt;h2 id="the-theme-is-a-shape-not-a-topic"&gt;The theme is a shape, not a topic&lt;/h2&gt;
&lt;p&gt;Everything in the theme maps to a general community pattern:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Events&lt;/strong&gt; are anything scheduled: talks, watch parties, shifts, recording
sessions, class meetings, gigs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The blog&lt;/strong&gt; is anything published on a cadence: recaps, news, release
notes, episode notes, season announcements.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Organizers&lt;/strong&gt; are the people behind it: hosts, teachers, crew, captains.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The docs area&lt;/strong&gt; is the group&amp;rsquo;s operating knowledge: a handbook, runbooks,
a code of conduct, house rules.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If your group has &amp;ldquo;things that happen&amp;rdquo;, &amp;ldquo;things you write down&amp;rdquo;, and &amp;ldquo;people
who run it&amp;rdquo;, the theme fits, whatever you call yourselves. The section names
themselves are &lt;a href="https://popular.mariatta.ca/docs/configuration/#renaming-content-sections"&gt;renameable&lt;/a&gt;
(hosts instead of organizers, and so on), so the vocabulary matches your group.&lt;/p&gt;</description></item><item><title>Changelog</title><link>https://popular.mariatta.ca/changelog/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://popular.mariatta.ca/changelog/</guid><description>&lt;p&gt;One theme, two implementations: versions are tagged in lockstep in
&lt;a href="https://github.com/Mariatta/hugo-theme-popular"&gt;hugo-theme-popular&lt;/a&gt; and
&lt;a href="https://github.com/Mariatta/astro-theme-popular"&gt;astro-theme-popular&lt;/a&gt;, and this
file ships identically in both (PARITY.md Tier 1). Format follows
&lt;a href="https://keepachangelog.com/"&gt;Keep a Changelog&lt;/a&gt;; versions follow
&lt;a href="https://semver.org/"&gt;semver&lt;/a&gt;. During 0.x, minor versions may contain breaking
changes; they will be called out here.&lt;/p&gt;
&lt;p&gt;To hear about new releases: watch either repo on GitHub (Watch → Custom →
Releases) or subscribe to the releases feed
(&lt;code&gt;https://github.com/Mariatta/hugo-theme-popular/releases.atom&lt;/code&gt;).&lt;/p&gt;
&lt;h2 id="unreleased"&gt;[Unreleased]&lt;/h2&gt;
&lt;h2 id="070---2026-07-31"&gt;[0.7.0] - 2026-07-31&lt;/h2&gt;
&lt;h3 id="changed"&gt;Changed&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The footer shows the theme version (e.g. &lt;code&gt;v0.7.0&lt;/code&gt;) next to the Popular
credit, on the demos and the docs site.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="fixed"&gt;Fixed&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The &amp;ldquo;no upcoming events&amp;rdquo; empty state no longer renders on event-less sites
such as the docs site; it appears only on a community that has an events
section but nothing upcoming.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="added"&gt;Added&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Recaps toolkit: &lt;code&gt;gallery&lt;/code&gt; + &lt;code&gt;photo&lt;/code&gt; and &lt;code&gt;pullquote&lt;/code&gt; shortcodes (Hugo) /
&lt;code&gt;Gallery&lt;/code&gt; + &lt;code&gt;Photo&lt;/code&gt; and &lt;code&gt;Pullquote&lt;/code&gt; components (Astro). The gallery is a
CSS-grid figure list with no JavaScript and no lightbox (each photo links to
its full-size image); &lt;code&gt;alt&lt;/code&gt; is required and a missing one fails the build.
A recap is a blog post tagged &lt;code&gt;recap&lt;/code&gt; that uses both, with a worked example
in the KDrama demo.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;llms.txt&lt;/code&gt;: a build-time plain-text summary for AI agents at &lt;code&gt;/llms.txt&lt;/code&gt;,
naming the next upcoming event, how to join, and links to the key pages and
the calendar feed. Always generated on Astro; on Hugo the site adds &lt;code&gt;LLMS&lt;/code&gt;
to its home outputs (the demos, exampleSite, and docs site do).&lt;/li&gt;
&lt;li&gt;Docs: the deliberate non-features list (job board, member directory,
comments, photo lightbox) and the stats strip as the social-proof pattern.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="added-1"&gt;Added&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Talk archive. Events gain optional &lt;code&gt;recording&lt;/code&gt; / &lt;code&gt;slides&lt;/code&gt; (single-talk
meetups) and a &lt;code&gt;talks[]&lt;/code&gt; array (&lt;code&gt;title&lt;/code&gt; required; &lt;code&gt;speaker&lt;/code&gt;, &lt;code&gt;recording&lt;/code&gt;,
&lt;code&gt;slides&lt;/code&gt; optional); when &lt;code&gt;talks[]&lt;/code&gt; is present it wins over the event-level
fields. The event page renders a Talks section (or inline links for the
simple case), and past-event rows show a recording cue. An opt-in &lt;code&gt;/talks/&lt;/code&gt;
archive aggregates every talk newest-first, filterable by the parent event&amp;rsquo;s
tags: enable it with &lt;code&gt;content/talks/_index.md&lt;/code&gt; (Hugo) or &lt;code&gt;SITE.talks = true&lt;/code&gt;
(Astro). New UI strings &lt;code&gt;watchRecording&lt;/code&gt;, &lt;code&gt;viewSlides&lt;/code&gt;, &lt;code&gt;hasRecording&lt;/code&gt;,
&lt;code&gt;talks&lt;/code&gt;, &lt;code&gt;talksLead&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="changed-1"&gt;Changed&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Speaker, organizer, and author profile pages no longer repeat the bio: the
page hero is now a compact banner (eyebrow, name, back link) and the bio
lives only in the persona card below it.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="added-2"&gt;Added&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Community chat bridge and speaker pipeline. &lt;code&gt;params.community.chat = { url, label }&lt;/code&gt; adds a &amp;ldquo;Join the chat&amp;rdquo; CTA to the home hero, the footer, and
the no-events empty state (platform-agnostic: Discord, Slack, Matrix, Zulip).
The starter ships a &amp;ldquo;Start here&amp;rdquo; first-timer page (&lt;code&gt;/start/&lt;/code&gt;) and a &amp;ldquo;Speak
with us&amp;rdquo; call-for-speakers page (&lt;code&gt;/speak/&lt;/code&gt;). &lt;code&gt;params.speakers.invite = true&lt;/code&gt;
appends a &amp;ldquo;Your name here?&amp;rdquo; card to the speakers list (new strings
&lt;code&gt;speakerInviteTitle&lt;/code&gt;, &lt;code&gt;speakerInviteBody&lt;/code&gt;), off by default.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="fixed-1"&gt;Fixed&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Astro: the speakers and venues list pages (&lt;code&gt;/speakers/&lt;/code&gt;, &lt;code&gt;/venues/&lt;/code&gt;) were
missing, so the &amp;ldquo;All speakers&amp;rdquo; / &amp;ldquo;All venues&amp;rdquo; back links on detail pages led
to 404s. Both list pages now exist, mirroring the Hugo templates.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="added-3"&gt;Added&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Notice banner and designed empty states. &lt;code&gt;params.notice = { text, url? }&lt;/code&gt;
renders a static, non-dismissible banner above the header (inline-markdown
text, an optional link, no JavaScript). When there are no upcoming events,
the home page and the events list now render a designed empty state (a
message, the community chat CTA if configured, and the calendar-subscribe
link) instead of a blank section. New UI strings &lt;code&gt;learnMore&lt;/code&gt;, &lt;code&gt;joinChat&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="added-4"&gt;Added&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Venue access &amp;amp; logistics fields: &lt;code&gt;wheelchair&lt;/code&gt; (a badge on the venue and on
events held there), &lt;code&gt;transit&lt;/code&gt;, &lt;code&gt;parking&lt;/code&gt;, and a freeform &lt;code&gt;access&lt;/code&gt; note,
shown as a &amp;ldquo;Getting there &amp;amp; access&amp;rdquo; section. Inclusion as a data-model
concern. Matching spreadsheet-importer columns. New UI strings
&lt;code&gt;gettingThere&lt;/code&gt;, &lt;code&gt;wheelchairAccessible&lt;/code&gt;, &lt;code&gt;transit&lt;/code&gt;, &lt;code&gt;parking&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="added-5"&gt;Added&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Calendar feed: an iCalendar (&lt;code&gt;.ics&lt;/code&gt;) feed of events at
&lt;code&gt;/events/calendar.ics&lt;/code&gt;, so members subscribe once and every future meetup
appears in their calendar app. Reuses the event &lt;code&gt;time&lt;/code&gt; parsing (so the feed
and the Event structured data agree), marks cancelled events, and adds a
&amp;ldquo;Subscribe to calendar&amp;rdquo; link to the events list. &lt;code&gt;scripts/check-ics.py&lt;/code&gt;
validates it in CI. Hugo: add &lt;code&gt;Calendar&lt;/code&gt; to the events section outputs.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="fixed-2"&gt;Fixed&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Speaker, venue and organizer profile pages now show a back link to their
list (matching blog posts and events); the organizer link follows the
renamed team section. New UI strings &lt;code&gt;allSpeakers&lt;/code&gt;, &lt;code&gt;allVenues&lt;/code&gt;,
&lt;code&gt;allOrganizers&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="added-6"&gt;Added&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Astro package: component overrides. &lt;code&gt;popular({ overrides: { Header: './src/overrides/Header.astro' } })&lt;/code&gt; replaces any of Header, Footer, Hero,
EventRow, PostCard, OrganizerCard, AuthorBox, PageHero without forking the
theme. (Hugo adopters already override via native template lookup.)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="060---2026-07-23"&gt;[0.6.0] - 2026-07-23&lt;/h2&gt;
&lt;p&gt;Search-engine optimisation: structured data, crawl plumbing, Core Web Vitals,
and an FAQ block. Zero client JavaScript added.&lt;/p&gt;</description></item><item><title>About Popular</title><link>https://popular.mariatta.ca/about/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://popular.mariatta.ca/about/</guid><description>&lt;p&gt;&lt;strong&gt;Popular&lt;/strong&gt; wasn&amp;rsquo;t designed in the abstract: it was built by a real-life serial conference organizer, distilled from years of running meetups, workshops and conferences. The ops handbook, the runbooks with checkboxes, the &amp;ldquo;venue wanted&amp;rdquo; badge: every feature comes from something a real community needed. It works for communities of any kind: tech meetups, supper clubs, aquarium keepers, fan clubs.&lt;/p&gt;
&lt;h2 id="whos-behind-it"&gt;Who&amp;rsquo;s behind it&lt;/h2&gt;
&lt;p&gt;Popular is created and maintained by a multi-award-winning open source contributor and serial conference organizer. Open source isn&amp;rsquo;t a distribution channel here, it&amp;rsquo;s the root system: the theme is developed in the open, MIT licensed, and shaped by the same open source culture its creator has spent years building in.&lt;/p&gt;</description></item><item><title>Mariatta</title><link>https://popular.mariatta.ca/authors/mariatta/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://popular.mariatta.ca/authors/mariatta/</guid><description>&lt;p&gt;Mariatta started Popular after one too many community sites rebuilt from scratch. She maintains both implementations.&lt;/p&gt;</description></item></channel></rss>