commit 48e26d671d51bbc876d6031a5733355ca787e2de Author: David Dyer Date: Sat Aug 29 19:32:20 2026 -0400 Initial commit: The Old Fitz Public House site Static-turned-PHP site for a pub in Marion, Indiana, with: - Hero section with tiled brick-texture background - Live-capable stat card (Facebook followers/reviews via Graph API, with graceful fallback to config.php constants when no token is set) - Open Graph / Twitter Card meta tags for social sharing - robots.txt config.php is gitignored (holds a Facebook Page Access Token once generated); config.sample.php is the tracked template — copy it to config.php and fill in values to run this locally or in deployment. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e61aad7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +# OS cruft +.DS_Store + +# Secrets — copy config.sample.php to config.php and fill in your own values. +# config.php will eventually hold a real Facebook Page Access Token. +config.php + +# Runtime-generated cache (facebook-stats.php writes here) +/cache/ + +# Original raw video footage, 27MB, not referenced anywhere on the live +# site (hero background ended up using assets/brick-texture.png instead). +# Remove this line if you want the raw footage tracked in git too. +assets/video.mp4 diff --git a/assets/brick-texture.png b/assets/brick-texture.png new file mode 100644 index 0000000..0971508 Binary files /dev/null and b/assets/brick-texture.png differ diff --git a/assets/hero-logo.png b/assets/hero-logo.png new file mode 100644 index 0000000..4906f9b Binary files /dev/null and b/assets/hero-logo.png differ diff --git a/assets/knot.png b/assets/knot.png new file mode 100644 index 0000000..a1299e1 Binary files /dev/null and b/assets/knot.png differ diff --git a/assets/og-image.png b/assets/og-image.png new file mode 100644 index 0000000..74e735e Binary files /dev/null and b/assets/og-image.png differ diff --git a/config.sample.php b/config.sample.php new file mode 100644 index 0000000..2e83e84 --- /dev/null +++ b/config.sample.php @@ -0,0 +1,43 @@ + FB_FALLBACK_RECOMMEND_PCT, + 'review_count' => FB_FALLBACK_REVIEW_COUNT, + 'followers' => FB_FALLBACK_FOLLOWERS, + 'source' => 'fallback', + 'fetched_at' => null, + ]; + + if (FB_PAGE_ACCESS_TOKEN === '') { + return $fallback; + } + + $cacheFile = __DIR__ . '/../cache/facebook-stats.json'; + + if (is_file($cacheFile)) { + $cached = json_decode((string) file_get_contents($cacheFile), true); + if (is_array($cached) && (time() - ($cached['fetched_at'] ?? 0)) < FB_STATS_CACHE_TTL) { + $cached['source'] = 'cache'; + return $cached; + } + } + + $fresh = fritz_fetch_facebook_stats($fallback); + $fresh['fetched_at'] = time(); + + $cacheDir = dirname($cacheFile); + if (!is_dir($cacheDir)) { + @mkdir($cacheDir, 0775, true); + } + @file_put_contents($cacheFile, json_encode($fresh)); + + return $fresh; +} + +function fritz_fetch_facebook_stats(array $fallback): array { + if (!function_exists('curl_init')) { + return $fallback; + } + + $url = sprintf( + 'https://graph.facebook.com/v21.0/%s?fields=followers_count,overall_star_rating,rating_count&access_token=%s', + FB_PAGE_ID, + urlencode(FB_PAGE_ACCESS_TOKEN) + ); + + $ch = curl_init($url); + curl_setopt_array($ch, [ + CURLOPT_RETURNTRANSFER => true, + CURLOPT_TIMEOUT => 5, + ]); + $body = curl_exec($ch); + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + + if ($body === false || $httpCode !== 200) { + return $fallback; + } + + $data = json_decode($body, true); + if (!is_array($data) || isset($data['error'])) { + return $fallback; + } + + $recommendPct = isset($data['overall_star_rating']) + ? (int) round(($data['overall_star_rating'] / 5) * 100) + : $fallback['recommend_pct']; + + return [ + 'recommend_pct' => $recommendPct, + 'review_count' => $data['rating_count'] ?? $fallback['review_count'], + 'followers' => $data['followers_count'] ?? $fallback['followers'], + 'source' => 'live', + ]; +} diff --git a/index.php b/index.php new file mode 100644 index 0000000..d8002ce --- /dev/null +++ b/index.php @@ -0,0 +1,266 @@ + + + + + + + + The Old Fitz Public House | Traditional Irish Pub in Marion, Indiana + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ +
+ +
+

+ +

+

Marion, Indiana

+ + +
+ Traditional Irish PubFamily FriendlyNo Reservations +
+ +
+
+ +
+
+
+
+

About the Pub

+

A proper Irish pub, right on Washington Street.

+

The Old Fitz Public House pours a traditional Irish pub experience in the middle of Marion — no pretense, no reservations, just a good pint and a warm room. Walk in Thursday through Saturday evening, grab a seat at the bar or a table for the family, and settle in.

+

The kitchen runs until 9, the bar stays open later for snacks, and regulars and first-timers get treated the same.

+
+
+ As the Regulars See It +
%
+

recommend The Old Fitz

+

Source: Facebook reviews ()

+
+
+
+

people following along on Facebook

+

Source: Facebook followers

+
+
+
+
+
+ +
+
+
+

Hours & Visit

+

Three nights a week, doors open.

+
+
+
+

On Tap Thu–Sat

+
+
+
Thursday
+
4:00 – 10:00 PM
+
+
+
Friday
+
4:00 – 10:00 PM
+
+
+
Saturday
+
4:00 – 10:00 PM
+
+
+
Sun – Wed
+
Closed
+
+
+

Kitchen closes at 9 — bar snacks stay out later. Holiday hours may vary; check our Facebook page for the latest.

+
+
+ +

Find Us

+
+ 100 N Washington Street
+ Marion, Indiana +
+ + +
+
+
+
+ +
+
+
+
+

Live Music

+

Some nights, there's music.

+
+

The Old Fitz brings in local musicians for live sets on select evenings — recent nights have featured artists like Casey Morris. There's no fixed weekly lineup here, so the surest way to catch a show is to follow along on Facebook or Instagram, where new dates get posted first.

+ +
+
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/robots.txt b/robots.txt new file mode 100644 index 0000000..a0d45e1 --- /dev/null +++ b/robots.txt @@ -0,0 +1,11 @@ +User-agent: * +Allow: / +Disallow: /config.php +Disallow: /inc/ +Disallow: /cache/ + +# Crawl-delay and request-rate (optional, helps with server load) +Crawl-delay: 1 + +# Sitemap (optional, uncomment when you have one) +# Sitemap: https://theoldfitz.daviddyer.me/sitemap.xml diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..5d27a35 --- /dev/null +++ b/styles.css @@ -0,0 +1,410 @@ + :root{ + --ground:#171310; + --ground-2:#0f0c0a; + --surface:#221c16; + --surface-2:#2b2319; + --gold:#c9a35c; + --gold-bright:#e6c789; + --gold-dim:#a68b59; + --green:#33503f; + --green-deep:#203026; + --ink:#f1e8d8; + --ink-muted:#a89a83; + --rule:#42362590; + } + + *{ box-sizing:border-box; } + html{ scroll-behavior:smooth; } + @media (prefers-reduced-motion: reduce){ html{ scroll-behavior:auto; } } + + body{ + margin:0; + background:var(--ground); + color:var(--ink); + font-family:'Karla', ui-sans-serif, system-ui, sans-serif; + font-size:1rem; + line-height:1.65; + -webkit-font-smoothing:antialiased; + } + + a{ color:inherit; } + img,svg{ display:block; max-width:100%; } + + .container{ + width:100%; + max-width:70rem; + margin:0 auto; + padding-inline:1.5rem; + } + + h1,h2,h3{ + font-family:'Fraunces', Georgia, 'Times New Roman', serif; + font-weight:600; + line-height:1.08; + text-wrap:balance; + margin:0; + } + + .eyebrow{ + font-family:'IBM Plex Mono', ui-monospace, Menlo, monospace; + font-size:0.72rem; + letter-spacing:0.22em; + text-transform:uppercase; + color:var(--gold); + } + + p{ margin:0; } + .muted{ color:var(--ink-muted); } + + .visually-hidden{ + position:absolute; width:1px; height:1px; overflow:hidden; + clip:rect(0 0 0 0); white-space:nowrap; border:0; padding:0; margin:-1px; + } + + .skip-link{ + position:absolute; left:1rem; top:-3rem; + background:var(--gold); color:var(--ground-2); + padding:0.6rem 1rem; border-radius:0.125rem; + font-family:'IBM Plex Mono', monospace; font-size:0.85rem; + transition:top .15s ease; + z-index:100; + } + .skip-link:focus{ top:1rem; } + + :focus-visible{ outline:2px solid var(--gold-bright); outline-offset:3px; } + + /* ---------- knot mark ---------- */ + .knot{ + display:block; + width:1.75rem; height:1.75rem; + object-fit:contain; + flex-shrink:0; + } + .rule-row .knot{ width:1.375rem; height:1.375rem; opacity:0.9; } + .footer-brand .knot{ width:1.625rem; height:1.625rem; } + + .hero-brand{ + margin:0; + line-height:0; + } + + .hero-logo{ + display:block; + width:min(100%, 26.25rem); + max-width:100%; + height:auto; + margin:0 auto 1.75rem; + } + + @media (max-width: 35em){ + .hero-logo{ width:min(100%, 17.5rem); } + } + + /* ---------- brass rule divider ---------- */ + .rule-row{ + display:flex; align-items:center; gap:1rem; + max-width:13.75rem; margin-inline:auto; + } + .rule-row .line{ height:1px; flex:1; background:linear-gradient(90deg, transparent, var(--gold-dim), transparent); } + .rule-row.left-align{ margin-inline:0; } + + /* ---------- header / nav ---------- */ + header.site{ + position:sticky; top:0; z-index:50; + background:rgba(15,12,10,0.86); + backdrop-filter:saturate(140%) blur(0.5rem); + border-bottom:1px solid var(--rule); + } + .nav-inner{ + display:flex; align-items:center; justify-content:space-between; + gap:1rem; padding-block:0.75rem; + } + .brand{ + display:flex; align-items:center; gap:0.65rem; + text-decoration:none; + font-family:'Fraunces', serif; font-weight:600; + letter-spacing:0.02em; + font-size:1.05rem; + color:var(--ink); + } + nav.links{ + display:flex; align-items:center; gap:1.75rem; + } + nav.links a{ + text-decoration:none; + font-size:0.92rem; + letter-spacing:0.03em; + color:var(--ink-muted); + padding:0.4rem 0.2rem; + transition:color .15s ease; + } + nav.links a:hover{ color:var(--gold-bright); } + .nav-cta{ + display:inline-flex; align-items:center; + border:1px solid var(--gold-dim); + color:var(--gold-bright) !important; + padding:0.45rem 0.9rem; + border-radius:0.125rem; + font-family:'IBM Plex Mono', monospace; + font-size:0.75rem !important; + letter-spacing:0.06em; + } + .nav-cta:hover{ border-color:var(--gold); background:var(--surface); } + + @media (max-width: 47.5em){ + nav.links{ display:none; } + } + + /* ---------- hero ---------- */ + .hero{ + position:relative; + padding-block:5.5rem 6rem; + text-align:center; + overflow:hidden; + background:var(--ground); /* fallback if brick-texture.png fails to load */ + } + .hero::before{ + content:""; + position:absolute; inset:0; + z-index:1; + opacity:0.6; + background: + linear-gradient(to bottom, rgba(0,0,0,0.12), transparent 22%, transparent 78%, rgba(0,0,0,0.18)); + pointer-events:none; + } + .hero-media{ + position:absolute; inset:0; + z-index:0; + overflow:hidden; + background-image:url('./assets/brick-texture.png'); + background-repeat:repeat; + } + .hero-scrim{ + position:absolute; inset:0; + background: + linear-gradient(180deg, rgba(15,12,10,0.35) 0%, rgba(15,12,10,0.2) 45%, rgba(15,12,10,0.6) 100%), + radial-gradient(ellipse 60% 48% at 50% 18%, rgba(201,163,92,0.16), transparent 58%); + } + .hero-inner{ position:relative; z-index:2; } + .hero .eyebrow{ margin-bottom:1rem; } + .hero h1{ + font-size:clamp(3.1rem, 9vw, 6.2rem); + color:var(--gold-bright); + letter-spacing:-0.01em; + } + .hero .sub{ + font-family:'Fraunces', serif; font-style:italic; font-weight:400; + font-size:clamp(1.15rem, 2.6vw, 1.55rem); + color:var(--ink-muted); + margin-top:0.35rem; + } + .tagline-row{ + margin-top:2rem; + display:flex; justify-content:center; flex-wrap:wrap; + gap:0.6rem 0; + font-family:'IBM Plex Mono', monospace; + font-size:0.82rem; + letter-spacing:0.04em; + color:var(--ink-muted); + } + .tagline-row span:not(:last-child)::after{ + content:"·"; color:var(--gold-dim); margin-inline:0.7rem; + } + .hero-ctas{ + margin-top:2.5rem; + display:flex; justify-content:center; gap:0.9rem; flex-wrap:wrap; + } + + .btn{ + display:inline-flex; align-items:center; gap:0.5rem; + padding:0.8rem 1.5rem; + font-family:'IBM Plex Mono', monospace; + font-size:0.8rem; letter-spacing:0.05em; + text-decoration:none; + border-radius:0.125rem; + transition:transform .15s ease, background .15s ease, border-color .15s ease; + } + .btn:hover{ transform:translateY(-1px); } + .btn-primary{ + background:linear-gradient(180deg, var(--gold-bright), var(--gold)); + color:var(--ground-2); + font-weight:500; + } + .btn-primary:hover{ background:linear-gradient(180deg, var(--gold-bright), var(--gold-bright)); } + .btn-outline{ + border:1px solid var(--gold-dim); + color:var(--gold-bright); + } + .btn-outline:hover{ border-color:var(--gold); background:var(--surface); } + + /* ---------- sections ---------- */ + section{ padding-block:5.5rem; } + .section-head{ margin-bottom:2.75rem; } + .section-head h2{ font-size:clamp(1.9rem, 3.6vw, 2.6rem); color:var(--ink); margin-top:0.5rem; } + + /* about band */ + .about-grid{ + display:grid; grid-template-columns:1.3fr 1fr; gap:3.5rem; + align-items:start; + } + .about-grid p + p{ margin-top:1rem; } + .about-grid .lede{ max-width:56ch; color:var(--ink); font-size:1.05rem; } + + .stat-card{ + background:var(--surface); + border:1px solid var(--rule); + padding:2rem; + border-radius:0.2rem; + } + .stat-card .eyebrow{ display:block; margin-bottom:1.1rem; } + .stat-big{ + font-family:'Fraunces', serif; font-weight:600; font-style:italic; + font-size:3rem; color:var(--gold-bright); line-height:1; + } + .stat-card .stat-label{ margin-top:0.4rem; font-size:0.92rem; color:var(--ink-muted); } + .stat-card .stat-row{ margin-top:1.5rem; padding-top:1.5rem; border-top:1px solid var(--rule); } + .stat-card .stat-row .stat-big{ font-size:1.9rem; } + .stat-source{ + margin-top:1.5rem; font-family:'IBM Plex Mono', monospace; font-size:0.7rem; + color:var(--gold-dim); letter-spacing:0.05em; + } + + @media (max-width: 51.25em){ + .about-grid{ grid-template-columns:1fr; } + } + + /* hours / visit band */ + .visit{ background:var(--ground-2); } + .visit-grid{ + display:grid; grid-template-columns:1fr 1fr; gap:1.75rem; + } + .card{ + background:var(--surface); + border:1px solid var(--rule); + border-radius:0.2rem; + padding:2.25rem; + } + .card h3{ + font-size:1.3rem; color:var(--gold-bright); + margin-bottom:1.4rem; + } + .hours-list{ + margin:0; + padding:0; + font-family:'IBM Plex Mono', monospace; + font-variant-numeric:tabular-nums; + font-size:0.92rem; + } + .hours-row{ + display:flex; + justify-content:space-between; + align-items:center; + padding:0.55rem 0; + border-bottom:1px solid var(--rule); + } + .hours-row:last-child{ + border-bottom:none; + } + .hours-row dt{ + margin:0; + color:var(--ink-muted); + letter-spacing:0.04em; + font-weight:normal; + } + .hours-row dd{ + margin:0; + text-align:right; + color:var(--ink); + } + .card .note{ + margin-top:1.25rem; font-size:0.88rem; color:var(--ink-muted); + } + .card .note strong{ color:var(--ink); font-weight:600; } + + .find-us .pin{ width:2.125rem; height:2.125rem; margin-bottom:1rem; } + .find-us address{ font-style:normal; font-size:1rem; color:var(--ink); } + .find-us .contact-list{ margin-top:1.5rem; display:flex; flex-direction:column; gap:0.6rem; } + .find-us .contact-list a{ + text-decoration:none; color:var(--gold-bright); + font-size:0.92rem; display:inline-flex; align-items:center; gap:0.5rem; + width:fit-content; + border-bottom:1px solid transparent; + } + .find-us .contact-list a:hover{ border-bottom-color:var(--gold-dim); } + .social-row{ margin-top:1.5rem; display:flex; gap:0.9rem; } + .social-row a{ + display:inline-flex; align-items:center; justify-content:center; + width:2.375rem; height:2.375rem; + border:1px solid var(--rule); border-radius:0.125rem; + color:var(--ink-muted); + text-decoration:none; + transition:border-color .15s ease, color .15s ease; + } + .social-row a:hover{ border-color:var(--gold); color:var(--gold-bright); } + .social-row svg{ width:1.0625rem; height:1.0625rem; } + + @media (max-width: 45em){ + .visit-grid{ grid-template-columns:1fr; } + } + + /* live music band */ + .music{ + background:linear-gradient(180deg, var(--green-deep), var(--green)); + color:var(--ink); + text-align:center; + } + .music .section-head{ margin-bottom:1.75rem; } + .music .section-head .eyebrow{ color:var(--gold-bright); } + .music p.body{ max-width:58ch; margin:0 auto; font-size:1.02rem; color:#e4ddc9; } + .music .btn-outline{ border-color:rgba(230,199,137,0.45); } + .music .hero-ctas{ margin-top:2.25rem; } + + /* menu band */ + .menu-band .container{ max-width:47.5rem; text-align:center; } + .menu-band p.body{ font-size:1.02rem; color:var(--ink-muted); max-width:56ch; margin:0 auto; } + .menu-band .hero-ctas{ margin-top:2.25rem; justify-content:center; } + .menu-band .section-head{ text-align:center; } + .menu-band .rule-row{ margin-bottom:1.75rem; } + + /* footer */ + footer{ + background:var(--ground-2); + border-top:1px solid var(--rule); + padding-block:3.5rem 2.5rem; + } + .footer-grid{ + display:grid; grid-template-columns:1.2fr 1fr 1fr; gap:2.5rem; + } + .footer-brand{ display:flex; align-items:center; gap:0.6rem; text-decoration:none; } + .footer-brand .knot{ width:1.625rem; height:1.625rem; } + .footer-brand span{ + font-family:'Fraunces', serif; font-weight:600; color:var(--ink); font-size:1rem; + } + footer .col-title{ + font-family:'IBM Plex Mono', monospace; font-size:0.72rem; + letter-spacing:0.14em; text-transform:uppercase; color:var(--gold-dim); + margin-bottom:0.9rem; + } + footer address{ font-style:normal; color:var(--ink-muted); font-size:0.92rem; line-height:1.7; } + footer .hours-mini{ + font-family:'IBM Plex Mono', monospace; font-size:0.85rem; + color:var(--ink-muted); font-variant-numeric:tabular-nums; + display:flex; flex-direction:column; gap:0.35rem; + } + footer a.email{ color:var(--gold-bright); text-decoration:none; font-size:0.92rem; } + footer a.email:hover{ text-decoration:underline; } + .footer-bottom{ + margin-top:3rem; padding-top:1.75rem; border-top:1px solid var(--rule); + display:flex; justify-content:space-between; flex-wrap:wrap; gap:0.75rem; + font-size:0.78rem; color:var(--ink-muted); + } + @media (max-width: 45em){ + .footer-grid{ grid-template-columns:1fr; gap:2rem; } + } + + /* scroll reveal */ + .reveal{ opacity:0; transform:translateY(0.875rem); transition:opacity .6s ease, transform .6s ease; } + .reveal.is-visible{ opacity:1; transform:none; } + @media (prefers-reduced-motion: reduce){ + .reveal{ opacity:1; transform:none; transition:none; } + }