{b.heading}
: null} {b.text ?{b.text}
: null} {b.items && b.items.length > 0 ?- {b.items.map((it, j) =>
- {it} )}
/* global React */ // Blog post — data-driven from assets/posts.json (?post=slug) const { useState, useEffect } = React; const NS_BP = window.GamekeepersCottageDesignSystem_070bc7; const { Button, Badge, Eyebrow, Card } = NS_BP; const Photo = window.GKPhoto; const useShell = window.GKuseShell; const IMG = window.GK_IMG; let _postsCache = null, _postsPromise = null; function loadPosts() { if (_postsCache) return Promise.resolve(_postsCache); if (_postsPromise) return _postsPromise; _postsPromise = (async () => { try { const res = await fetch('assets/posts.json', { cache: 'no-store' }); if (res.ok) { const d = await res.json(); if (d && Array.isArray(d.posts)) { _postsCache = d.posts; return _postsCache; } } } catch (e) { /* fall through */ } if (window.GK_POSTS && Array.isArray(window.GK_POSTS.posts)) { _postsCache = window.GK_POSTS.posts; return _postsCache; } _postsCache = []; return _postsCache; })(); return _postsPromise; } function usePosts() { const initial = _postsCache || (window.GK_POSTS && window.GK_POSTS.posts) || []; const [list, setList] = useState(initial); useEffect(() => { let live = true; loadPosts().then(p => { if (live) setList(p); }); return () => { live = false; }; }, []); return list; } function Starfield({ count = 160, height = 460 }) { let seed = 11; const rnd = () => (seed = (seed * 9301 + 49297) % 233280) / 233280; const shadows = []; for (let i = 0; i < count; i++) shadows.push(`${(rnd() * 100).toFixed(2)}vw ${Math.round(rnd() * height)}px rgba(255,255,255,${(0.25 + rnd() * 0.75).toFixed(2)})`); const big = []; for (let i = 0; i < 6; i++) big.push(`${(rnd() * 100).toFixed(2)}vw ${Math.round(rnd() * height)}px rgba(180,205,255,0.95)`); return (
); } function PostHero({ post }) { const eyebrow = (post.category || '') ; if (post.night) { return (We couldn't find that article — it may have been moved or removed.
{b.text}
: null} {b.items && b.items.length > 0 ?{rp.excerpt}
: null}The Gamekeeper's Cottage is hidden in its own hundred-acre Suffolk wood, near Southwold — a perfect base for exploring all of this.
Sleeps 5 · 3 bedrooms · four acres of private woodland