Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ Source Files → Astro Build → Static Output
```
src/
├── components/ # Reusable UI components
│ ├── AnnouncementBar.astro # Reusable top-of-page announcement strip (toggle via ANNOUNCEMENT.enabled)
│ ├── BaseHead.astro # <head> content (SEO, meta, hreflang, OG, JSON-LD)
│ ├── Footer.astro # Site footer
│ ├── WebMcp.astro # WebMCP progressive enhancement (agent-discoverable site map)
Expand Down
26 changes: 0 additions & 26 deletions public/images/product-hunt/featured-dark.svg

This file was deleted.

26 changes: 0 additions & 26 deletions public/images/product-hunt/featured-neutral.svg

This file was deleted.

17 changes: 10 additions & 7 deletions src/components/AnnouncementBar.astro
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
---
// Temporary Product Hunt launch announcement bar (launch day only).
// Reusable announcement bar.
//
// ON/OFF: controlled by `ANNOUNCEMENT.enabled` in
// `src/lib/constants/announcement.ts`. MainLayout renders this component only
// when that flag is true — flip it there to turn the bar on or off site-wide.
//
// The whole bar is a single link. It sits in normal document flow ABOVE the
// sticky header, so it simply scrolls away on scroll-down and reappears at the
Expand All @@ -11,9 +15,9 @@
// themes without a dark: variant.
//
// Copy is wired into the i18n system (t.announcementBar) so it ships in every
// active language. To retire it, remove this component and its <AnnouncementBar />
// usage in src/layouts/MainLayout.astro (the announcementBar translation keys can
// stay or be cleaned up later).
// active language; the link target lives in ANNOUNCEMENT.url. It was last used
// for the Product Hunt launch.
import { ANNOUNCEMENT } from '@/lib/constants/announcement';
import type { Language } from '@/lib/i18n';
import { getTranslations } from '@/lib/translations';

Expand All @@ -24,16 +28,15 @@ interface Props {
const { lang = 'en' } = Astro.props;
const t = getTranslations(lang as Language).announcementBar;

const PH_URL =
'https://www.producthunt.com/products/deep-work-plan?utm_source=launch-bar&utm_medium=banner&utm_campaign=launch-bar';
const ANN_URL = ANNOUNCEMENT.url;
---

<div
class="relative w-full border-b"
style="background-color: var(--color-main); border-color: rgba(255,255,255,0.08);"
>
<a
href={PH_URL}
href={ANN_URL}
target="_blank"
rel="noopener noreferrer"
class="ph-bar-link group mx-auto flex w-full max-w-7xl flex-wrap items-center justify-center gap-x-2 gap-y-1 px-4 py-2 text-sm leading-snug transition-colors"
Expand Down
30 changes: 0 additions & 30 deletions src/components/Footer.astro
Original file line number Diff line number Diff line change
Expand Up @@ -123,36 +123,6 @@ const links = [
/>
</a>

<!-- Product Hunt launch badge (temporary — launch day). Self-hosted SVGs
(snapshot of the official featured badge) so there's no third-party
request — keeps best-practices at 1.0 in CI and loads instantly. Light
mode uses the dark theme for ink-on-paper contrast; dark mode swaps to
the neutral theme. -->
<a
href="https://www.producthunt.com/products/deep-work-plan?embed=true&utm_source=badge-featured&utm_medium=badge&utm_campaign=badge-deep-work-plan"
target="_blank"
rel="noopener noreferrer"
class="inline-flex hover:opacity-80 transition-opacity"
aria-label="Deep Work Plan on Product Hunt"
>
<img
class="block h-10 w-auto dark:hidden"
src="/images/product-hunt/featured-dark.svg"
alt="Deep Work Plan - Models matter. Context matters more. Give your agent a plan. | Product Hunt"
width="250"
height="54"
loading="lazy"
/>
<img
class="hidden h-10 w-auto dark:block"
src="/images/product-hunt/featured-neutral.svg"
alt="Deep Work Plan - Models matter. Context matters more. Give your agent a plan. | Product Hunt"
width="250"
height="54"
loading="lazy"
/>
</a>

<div class="kicker text-center">
&copy; <span id="copyright-year">{new Date().getFullYear()}</span> Deep Work
Plan &middot; {t.footer.allRightsReserved}
Expand Down
3 changes: 2 additions & 1 deletion src/layouts/MainLayout.astro
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import BaseHead from '@/components/BaseHead.astro';
import Footer from '@/components/Footer.astro';
import Header from '@/components/layout/Header.svelte';
import WebMcp from '@/components/WebMcp.astro';
import { ANNOUNCEMENT } from '@/lib/constants/announcement';
import type { Language } from '@/lib/i18n';
import { getTranslations } from '@/lib/translations';

Expand Down Expand Up @@ -71,7 +72,7 @@ const nav = getTranslations(lang as Language).nav;
<a href="#main-content" class="sr-only focus:not-sr-only focus:absolute focus:top-4 focus:left-4 focus:z-[100] focus:bg-white focus:dark:bg-gray-900 focus:px-4 focus:py-2 focus:rounded focus:shadow-lg focus:text-secondary">
Skip to content
</a>
<AnnouncementBar lang={lang} />
{ANNOUNCEMENT.enabled && <AnnouncementBar lang={lang} />}
<Header client:load lang={lang} nav={nav} />
<main id="main-content" class="flex-1 bg-paper">
<slot />
Expand Down
26 changes: 26 additions & 0 deletions src/lib/constants/announcement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* Announcement bar configuration — single source of truth for the reusable
* top-of-page announcement strip (`src/components/AnnouncementBar.astro`).
*
* HOW TO TURN IT ON/OFF
* ---------------------
* - Flip `enabled` to `true` to show the bar site-wide, `false` to hide it.
* That single flag is the on/off switch — nothing else needs to change to
* mount or unmount it (MainLayout already renders it conditionally).
*
* HOW TO ANNOUNCE SOMETHING NEW
* -----------------------------
* 1. Set `enabled: true`.
* 2. Point `url` at the target (campaign params welcome).
* 3. Update the `announcementBar` copy (badge/text/tagline/linkText) in
* EVERY locale under `src/lib/translations/*.ts` so it ships translated.
*
* It was last used for the Product Hunt launch (hence the default URL); the
* copy lives in i18n (`t.announcementBar`), not here.
*/
export const ANNOUNCEMENT = {
/** Master on/off switch for the announcement bar. */
enabled: false,
/** Destination the whole bar links to (opens in a new tab). */
url: 'https://www.producthunt.com/products/deep-work-plan?utm_source=launch-bar&utm_medium=banner&utm_campaign=launch-bar',
} as const;
Loading