// Build Log · Issue 01
What we’ve shipped.
Every version since this site began. The build log of an empire in eight rounds.
v1.11
External audit fixes — 10 findings applied
· current
- HTML-01 (CRITICAL) — /coffee/ directory had malformed anchor markup on ranks 13-16 (closing </a> before child divs, rank 15 linking to wrong slug, rank 16 stray closing tag). Repaired all four entries with proper anchor structure.
- EDIT-01 — Cafe count contradictions resolved. Site-wide model: 16 published profiles · 25-cafe shortlist · 30 target slots. Every "29 cafes" / "Twenty-nine" / numberOfItems:25 conflict reconciled.
- EDIT-02 (editorial honesty) — data/index.json `editors_score: 47/48` for Albatross while page says pre-audit nulled. All 16 cafes now have `editors_score: null` + `scorecard_status: "pre-audit research preview"`.
- SCHEMA-01 — Review JSON-LD removed from Albatross pre-audit page. Will restore only after final audit with defensible reviewRating.
- SEO-04 — Homepage title 69ch → 55ch ("Pattaya Coffee — Independent Specialty Cafe Guide"). Descriptions trimmed: homepage 208→154ch, /standards 170→156ch, Albatross 212→156ch, /coffee/ og:desc reconciled to "16 cafes published" wording.
- SEO-05 — Homepage og:description had embedded <time> HTML inside the attribute (would terminate the attribute early in some parsers). Replaced with plain-text content.
- A11Y-01 (WCAG 4.1.2) — Closed drawer now has
inert+role="dialog"+aria-modal="true"+aria-hidden="true"on 51 pages. JS toggles inert on open/close. Keyboard users no longer Tab into hidden navigation. - A11Y-02 (WCAG 1.4.3) — Small-text accent usage switched from
--accent(#D4763C, 3.02:1) to--accent-deep(#B85C24, 4.25:1) for eyebrows, labels, meta, status pills, role chips, role text. Large display italics keep --accent. - A11Y-03 — aria-label="Close menu" / "Back to top" / "Open menu" added to icon-only controls on 51 pages where missing.
- MOBILE-01 — Inline newsletter input font-size 15 → 16px to prevent iOS auto-zoom (matches the global mobile rule shipped in v1.10).
- Service worker v1.11 — cache bust for the audit-fix round.
v1.10
Mobile deep audit — touch targets, safe-area, iOS zoom, viewport
- iOS safe-area-inset env() everywhere it matters — masthead respects left/right insets in landscape; .to-top + .install-btn float above the home indicator; footer .ftr-bottom adds inset-bottom padding; drawer panel padding-bottom env().
- WCAG 2.5.5 touch targets fixed — .nav-search 36 → 44px, .nav-hamburger 40 → 44px. Both pass the 44×44 minimum for mobile tap.
- iOS no-zoom on input focus — newsletter email input 15 → 16px, /compare select 15.5 → 16px. Mobile @media forces all inputs to 16px via !important.
- touch-action: manipulation on a, button, [role="button"] — removes the legacy 300ms tap delay on slow mobile browsers.
- text-size-adjust: 100% on html — iOS Safari no longer auto-rescales body text in landscape.
- viewport meta unified across all 55 pages — width=device-width, initial-scale=1, viewport-fit=cover, interactive-widget=resizes-content (Chrome 108+ handles the mobile keyboard by resizing the layout, not the visual viewport).
- Mobile @media tap-target enlargements — nav-links a padding 6 → 12px (~24px effective tap area → ~48px); footer .ftr-col li a gets 4px vertical padding; newsletter form stacks vertically on phones.
- Reduced-data backdrop-filter disable — heavy blur drops on iOS Low Power Mode / Save Data users.
- -webkit-touch-callout: default — long-press preview works on iOS again.
- Service worker v1.10 — cache bust to ship the mobile pass.
v1.9
Bug fix, schema completeness, header hardening
- BUG FIX — v1.8 SVG aria-hidden script inadvertently matched
<svg>inside CSSurl("data:image/svg+xml;utf8,...")data URIs, breaking the/compareselect-chevron rendering. Cleaned up; no remaining broken URIs. - Article mainEntityOfPage added to all 4 guide articles — Google rich-result eligibility upgrade.
- Speakable schema extended to /standards — voice-assistant reads the editorial method aloud.
- Per-page sitemap lastmod — sitemap.xml now uses real file mtime per URL, not a single today's date. More accurate signal for crawlers.
- Permissions-Policy expanded — Privacy Sandbox opt-outs: browsing-topics, join-ad-interest-group, run-ad-auction, attribution-reporting, private-aggregation, shared-storage, plus camera/mic/geolocation/payment/usb/sensors all disabled.
- HSTS bumped to 2 years (63072000) — required for hstspreload.org submission.
- CSP hardened — added block-all-mixed-content directive.
- X-Permitted-Cross-Domain-Policies: none — disables Adobe Flash/PDF cross-domain access (legacy hardening).
- Origin-Agent-Cluster: ?1 — opts in to origin-keyed agent clusters (better isolation, faster cross-origin postMessage).
- Service worker v1.9 — cache bust to ship the bug-fix + schema additions.
v1.8
Deeper audit — contrast, semantics, schema graph
- Color contrast fixed —
--fg-4darkened from#B5A696(2.20:1 against cream, fails WCAG AA) to#8E7B68(5.1:1, passes AA fully). Affects every "subtle" text element on the site. - 124 decorative SVGs marked aria-hidden="true" — screen readers now skip the cup-glyph, chevrons, search icons that have no meaning beyond visual flourish.
- Article schema author now references Person @id on all 4 guide articles — Tim Paemi as a single entity-graph node, not just a URL.
- <address> element wrapping the footer Direct column on 52 pages — semantic HTML5 for editorial contact.
- <time datetime> wrapping date strings on 7 editorial pages (changelog, brand, colophon, index, now, privacy, standards) — machine-readable dates.
- --rp CSS custom property declared with 0% default in :root — eliminates the one undefined-var the audit flagged.
- Service worker v1.8 — cache bust to ship the contrast + a11y fixes.
v1.7
Deep code audit — a11y, headings, meta, performance
- Heading hierarchy fixed — footer column titles upgraded from
<h5>to<div role="heading" aria-level="2">on 53 pages, eliminating the h2→h5 jump flagged by accessibility auditors. - Mobile hamburger a11y — aria-expanded and aria-controls added on 53 pages; JS syncs aria-expanded with drawer open/close via MutationObserver.
- Meta descriptions trimmed on 4 long pages (index, Albatross, scene guide, brewing glossary) to fit Google's 160-char SERP snippet.
- Just Specialty Coffee meta description expanded from 59ch to 175ch.
- Twitter:site / twitter:creator placeholder comments on homepage — ready to fill once @-handles are decided.
- Speculation Rules excludes /map — Leaflet-heavy page no longer prerendered on hover. Saves bandwidth for visitors.
- Service worker v1.7 — cache bust for the a11y + heading-hierarchy fixes.
v1.6
Full self-audit + network alignment
18 May 2026
- Self-audit pass — 55 pages all unique titles + descriptions, canonicals / hreflang / og:url consistent, zero orphans, zero broken links, zero missing alt-text. Audit report in commit log.
- Sister network expanded to the full Pattaya Authority Network on every page (53 footers updated): Coffee Guide · Restaurant Guide · School Guide · Pattaya Gym · Pattaya Visa Help · Pattaya Stream · Tim Paemi (main brand) · Pattaya Authority (media agency).
- Person schema sameAs on /masthead expanded — 7 cross-property URLs now declare Tim Paemi as the same person across the network. Crucial for AI knowledge graphs and entity disambiguation.
- Organization schema sameAs on homepage — same expansion for the publisher entity.
- Press founder bio rewritten to credit all six network properties with live links.
- llms.txt updated with the full network section — AI crawlers now see all six sister sites plus brand + agency.
- /map and /compare cross-link added to all 16 cafe pages via a slim utilities bar.
- og:url backfilled on 404, feedback, offline, press.
- og:image + og:image:alt backfilled on 404 and offline.
- Search Console / Bing / Yandex / Pinterest verification meta placeholders on homepage — commented, ready to fill when each property is added.
- Service worker v1.6 — cache bust to ship the network update.
v1.5
Compare tool, colophon, author byline, mobile PWA, SWR
18 May 2026
- /compare — pick any two cafes side-by-side. URL-shareable. Hours, prices, vibe tags, signature drink, neighbourhood — all twelve fields, instant filter.
- /colophon — the craft behind the site itself. Typefaces, colour codes, code stack, hosting, editorial workflow, standards implemented. Linked from footer Office column.
- Author byline block on every guide article — TP avatar, role, bio, links to /masthead#tim-paemi and email. Schema.org Person already wired.
- Mobile PWA screenshot — manifest now has both wide and narrow form-factor screenshots for Chrome's install UI.
- Stale-while-revalidate for /data/* in the service worker — directory data loads instantly from cache, refreshes in background.
- Service worker v1.5 precaches /compare and /colophon.
- 53 pages live — Issue 01 surface area complete.
v1.4
Typography, browser search, Atom, native share, reading UX
18 May 2026
- OpenSearch descriptor at /opensearch.xml — users can right-click the browser search bar and add "Pattaya Coffee" as a search engine. Chrome, Firefox, Safari, Edge all support this.
- Atom 1.0 feed at /feed.atom — third syndication format alongside RSS and JSON Feed. Some readers prefer Atom for the cleaner spec.
- Sitemap XSL stylesheet — /sitemap.xml renders as a beautiful human-readable directory page when visited in a browser. Helps curious humans who land there.
- text-wrap: balance on every headline and text-wrap: pretty on every lede — modern CSS that prevents orphans and widows in display type. Subtle but transformative.
- Container queries on issue and staff card grids — cards adapt to their container, not just the viewport.
- Reading progress bar on guide articles — top-of-page gradient bar tracks how far you have scrolled into the prose.
- Anchor links on h2/h3 in prose — hover any heading, click to copy a shareable section URL. Visible "Copied" flash confirms the action.
- Web Share API button on every cafe page — native iOS / Android / Chrome share sheet. Falls back gracefully on non-supporting browsers.
- PWA install soft-prompt button — when Chrome fires beforeinstallprompt, a discreet "Install" button appears in the bottom-right. Hidden after install.
- Lighthouse CI workflow on GitHub Actions — every push runs Lighthouse desktop + mobile against the live site with performance, a11y, best-practices and SEO score thresholds.
- Service worker v1.4 precaches /opensearch.xml, /feed.atom, and /sitemap.xsl.
v1.3
Schema depth, image SEO, keyboard UX
18 May 2026
- og:image:alt + twitter:image:alt on every page — descriptive social-card alt text for AI image search, Google Lens, and accessibility readers. Per-page contextual descriptions (47 pages updated).
- HowTo schema on /guide/how-to-order — five-step JSON-LD that may render as a step-by-step rich result for "how to order coffee in Pattaya" searches.
- DefinedTermSet schema on /guide/brewing-glossary — ten coffee terms with formal definitions, eligible for dictionary-style rich snippets.
- TouristTrip schema on /guide/walking-tour-beach-road — three-stop itinerary with TouristAttraction items, eligible for travel rich results.
- Cafe commerce schema on all 16 cafes — priceRange (฿/฿฿/฿฿฿), paymentAccepted (Cash, QR PromptPay, Credit Card), currenciesAccepted: THB, acceptsReservations: False, servesCuisine. Feeds Google Maps cards.
- Cmd+K / Ctrl+K global search shortcut — power-user keyboard navigation. "/" also opens search (Twitter/X / GitHub-style convention).
- Service worker v1.3 — cache bust to ship the new schema and shortcut.
v1.2
Map, archive, performance, trust signals
18 May 2026
- /map — interactive map of every cafe in Issue 01, powered by Leaflet + OpenStreetMap tiles. No Google, no third-party tracking. 16 markers, popups link to each cafe.
- /issue/ — editorial archive landing. Issue 01 (live, pre-audit), Issue 02 (Q3 2026), Issue 03 (Q1 2027 — roaster supplement).
- WebSite + SearchAction JSON-LD on homepage — enables Google sitelinks search box for branded queries.
- OpeningHoursSpecification JSON-LD on 15 cafe pages — feeds Google Maps and rich result cards.
- Speculation Rules API on every page — Chrome prerenders the next-likely navigation while the user hovers.
- Fraunces font preload on every page — LCP improvement for the hero serif headline.
- IndexNow API key deployed — Bing / Yandex / Seznam re-index in minutes when a new cafe ships.
- Trust signal pills in footer — Ad-free, No trackers, GDPR-compliant, HTTPS-only, Open Web.
- CSP updated to allow Leaflet from unpkg + tile.openstreetmap.org tiles only.
- Service worker v1.2 precaches /map and /issue/.
- 51 pages live — Issue 01 surface area complete.
v1.1
2026 standards round — AI, a11y, schema, PWA, future-proofing
18 May 2026
- /llms.txt — AI-crawler-readable orientation map. Tells GPT, Claude, Perplexity, Gemini what's worth citing, how to attribute, and what editorial honesty rules to respect.
- robots.txt upgrade — explicit allow rules for every modern AI training and search bot (GPTBot, ChatGPT-User, OAI-SearchBot, ClaudeBot, Claude-Web, PerplexityBot, Perplexity-User, Google-Extended, GoogleOther, AppleBot-Extended, Bytespider, cohere-ai, Diffbot, FacebookBot, meta-externalagent, YouBot, Kagibot). SEO scrapers (Semrush, Ahrefs, MJ12) explicitly disallowed.
- Hreflang en + x-default on every page — explicit Google language signal, ready for Issue 02 Thai-language edition.
- Sitemap suite — `sitemap-index.xml` linking pages (49), images (17), and a news sitemap (7) for Google News submission of the Issue 01 launch.
- PWA Manifest 2.0 — four app shortcuts (The 30, Today, Search, Method), three screenshots, share_target for /feedback, maskable + monochrome icons, display_override fallback chain.
- Apple PWA meta suite — apple-mobile-web-app-capable, status-bar-style, app-title, application-name, format-detection, color-scheme — across every page.
- Person schema on /masthead — Tim Paemi as Editor-in-Chief with knowsAbout, knowsLanguage, homeLocation, affiliation, and sameAs links to the sister sites in the Pattaya Authority network.
- Reading time + timeRequired schema on all four guide articles — calculated from real word counts (1128 / 894 / 1005 / 849), shown as inline byline plus PT5M / PT4M / PT4M / PT4M ISO duration in Article JSON-LD.
- Newsletter inline form — real HTML form with client-side email validation, accessible aria-live status, mailto: fallback ready to swap for a Buttondown / ConvertKit endpoint.
- View Transitions API — progressive-enhanced smooth page-to-page animation for supporting browsers (Chrome, Safari 18+). Falls back to instant nav elsewhere.
- Print stylesheet — editorial-grade print CSS. URLs spelled out after links, page-break-avoid on sections, monochrome treatment, proper @page margins.
- WCAG 2.2 focus-visible — explicit accent outline on keyboard focus, suppressed on mouse.
- prefers-reduced-motion + prefers-reduced-data — animations and backdrop-filter disabled for users who opt out.
- Service worker v1.1 precaches /llms.txt and /manifest.json.
v1.0
Transparency, privacy, brand kit
18 May 2026
- /now — public Now page documenting audit progress, photography schedule, and Issue 02 roadmap. Updated weekly while editors are in town.
- /privacy — full privacy notice. No trackers, no profiling, no third-party pixels, with a clear table of what we do collect (server logs, newsletter email) and why.
- /brand — press-grade brand kit. Wordmark, glyph, colour palette with hex codes, type specs, approved editor quote, and a do/don’t list.
- Speakable schema on all four guide articles — voice-assistant ready. Marks hero, lede, and TL;DR as the speakable selectors.
- Footer normalized — Office column now includes /now and /privacy links across every page in the site, so readers can always find both in one click.
- Service worker v1.0 precaches /now and /privacy alongside the existing core pages.
- 49 pages live — Issue 01 surface area complete pre-audit.
v0.9
Visual + a11y + engineering polish
18 May 2026
- 21 unique Open Graph cards — top-16 cafes, 4 guide articles, /coffee/ directory each get a unique 1200×630 social preview.
- aria-live region on search results — screen readers announce match counts as filters update.
- SiteNavigationElement JSON-LD on homepage — tells crawlers the primary navigation structure explicitly.
- /changelog page (you’re reading it) — version history for repeat visitors and the curious.
- apple-touch-icon.png (180×180) — proper iOS home-screen icon for PWA installs.
- GitHub Actions CI workflow — JSON-LD validation, build verification on every push.
- Service worker v0.9 precaches the top-5 OG cards for offline social sharing.
v0.8
Client-side search + per-cafe OG cards
18 May 2026
- /search — real client-side filter UI. Area, vibe, roaster type chips + name/drink/source text search. Fetches /data/index.json on load.
- 5 unique per-cafe OG cards for the top-5 anchor cafes.
- Smart 404 with 6 popular destinations.
- Build script auto-generates sitemap.xml from filesystem.
- Issue 02 teaser on homepage.
- Service worker v0.8 precaches /search and /data/index.json.
v0.7
Editorial layer — /guide/ + 4 articles
18 May 2026
- /guide/pattaya-coffee-scene — 1,200-word editorial essay on how Pattaya became a coffee city.
- /guide/how-to-order — visitor primer.
- /guide/brewing-glossary — 30+ specialty terms defined.
- /guide/walking-tour-beach-road — three-cafe editorial route.
- Today’s Brew rotation expanded 5 → 16 cafes.
- Editors’ Ten on homepage expanded 6 → 10 entries with honest pre-audit framing.
- Article schema added to /standards. Person + sameAs for Editor-in-Chief on homepage.
v0.6
Full taxonomy — 28 new pages
18 May 2026
- 11 more cafe stub pages (Strong Candidates tier — Benjamit, Why Specialty, Ordinary, Ratio, Fundamental, Malamute, Just Specialty, Dripoly, Brewed Bliss, King of Coffee, Secret Café).
- 5 neighbourhood pages — /area/naklua, /central-pattaya, /pratumnak, /jomtien, /banglamung.
- 6 vibe pages — work-friendly, garden, beachfront, aesthetic, cozy, view.
- 3 roaster-type pages — in-house, partner, Thai single origin.
- 3 taxonomy index landings — /area/, /vibe/, /roaster/.
- Cross-linking baked into every cafe stub (chip links to area/roaster/vibes).
- Site tripled from 13 → 41 pages.
v0.5
Heavy round — 13 empire improvements
18 May 2026
- PWA service worker fix — dropped broken .html precache entries, offline mode actually works.
- Cloudflare Pages middleware — protects *.pages.dev preview URLs from being indexed.
- Mobile drawer focus trap + aria-current sync + return-focus on close.
- color-scheme: light declared — prevents iOS dark-mode auto-inversion.
- /.well-known/security.txt + /feed.json (JSON Feed v1.1) + humans.txt linked.
- Noscript fallback + fonts trimmed 16 → 9 weights (~30% lighter).
- Honest copy — “25 cafes shortlisted verified” → “25 cafes cross-sourced”.
- Newsletter mailto replacing fake /api/subscribe.
v0.4
Pre-audit editorial honesty
18 May 2026
- Albatross Pre-Audit Preview banner — explicit "this isn’t a finished review" framing.
- Scorecard set to —/12 pending — removed all fabricated scores.
- Score-note prose rewritten as research-cited rather than personal-experience.
- Hours note made honest about pre-audit status.
- Security headers — CSP, HSTS, Permissions-Policy, COOP added.
- 13 vanity redirects — /about → /masthead etc.
v0.3
Full architecture — 13 pages
18 May 2026
- 14-section Albatross full template — at-a-glance, verdict, scorecard, room, play, best-for, hours, amenities, find-it, FAQ, drink-next.
- 4 cafe stub pages for Nitan, Sunset, Backstreet, SheeVa.
- Editorial credibility pages — /standards, /masthead, /press, /feedback.
- /coffee/ directory index with 25-entry ItemList.
- PWA — service worker, offline page, manifest with maskable icons.
- 5 JSON-LD schema types across the site.
v0.2
Editorial homepage
18 May 2026
- Real cafe data replaced placeholder “Cafe to be ranked” entries.
- Letter from the Editor section.
- Issue stamp, italic letterform background, paper-grain texture.
- OG image (1200×630) generated via PIL.
- Scroll-reveal animations, mobile drawer, scroll progress bar.
v0.1
Initial scaffold
18 May 2026
- First homepage, cream / espresso / terracotta palette, Fraunces serif.
- Restaurant Guide architecture mirrored.
- Cloudflare Pages config (wrangler.toml, _headers, _redirects).
- Initial build pipeline (scripts/build.mjs).