Skip to content

Commit f4bd3d1

Browse files
authored
fix(site): use the animated mascot logo in the hero (#65)
## Related Issue No issue. The problem is described below. ## Problem The landing page hero rendered `/pythinker-hero-clean-v2.mp4` inside a play/pause `<button>`. That asset is no longer present in `apps/site/public`, so `pnpm -C apps/site run build` fails outright on `main`: ``` [vite]: Rollup failed to resolve import "/pythinker-hero-clean-v2.mp4" from ".../apps/site/src/App.vue" ``` ## What changed - The hero now renders the existing `PythinkerMascot` component instead of the video. It inlines the same artwork as `public/pythinker_animated.svg` — 34 identical `<path>` elements and the same four animations (blink, mouthTalk, antennaGlow, eyeShine) — and already ships a scoped `prefers-reduced-motion` guard, so no extra request and no new motion handling. - Removed the now-dead video machinery: `heroVideo` / `heroVideoPlaying` refs, `playHeroVideo`, `syncHeroMotionPreference`, `toggleHeroVideo`, their `matchMedia` listeners, and the `.hero-mascot-video` rules (radial mask + `mix-blend-mode: multiply`). `reducedMotionQuery` stays — the reveal-on-scroll observer still uses it. - `.hero-mascot` sizes the logo at `clamp(128px, 12vw, 164px)`, centered. The hero block is roughly 55px taller than the old 4:3 video, so content below shifts down slightly. - Deleted four assets nothing references: `pythinker-hero-clean-v2.mp4`, `arctecture.webp`, `logo.png`, `brand/linux.svg`. Deliberately kept, because they are addressed by URL or convention rather than by an import: `_headers` (Cloudflare Pages), `bimi-logo.svg` (DNS BIMI record), `code/oauth-success.html` (OAuth redirect landing page), and `icon-192.png` / `icon-512.png`. Verified: `pnpm -C apps/site run build` now succeeds, and `pnpm exec oxlint --type-aware apps/site/src/App.vue` is clean. ## Checklist - [x] I have read the [CONTRIBUTING](https://github.com/Pythoughts-labs/pythinker-code/blob/main/CONTRIBUTING.md) document. - [x] I have linked a related issue, or explained the problem above. - [x] I have added tests that prove my feature works. — `apps/site` has no test suite; the site build is the gate, and it goes from failing to passing with this change. - [x] Ran `gen-changesets` skill, or this PR needs no changeset. `[skip changeset]` — the only published package is `@pythoughts/pythinker-code`, and `@pythoughts/site` is a private marketing site that does not enter the CLI bundle, so nothing here reaches a release artifact. No site-only change in this repo has ever carried a changeset. - [x] Ran `gen-docs` skill, or this PR needs no doc update. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Replaced the hero mascot video with a static mascot illustration. * Removed video playback controls and related motion behavior. * Preserved terminal demo functionality and reduced-motion support. * Updated responsive styling for the mascot display. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 8f11dd8 commit f4bd3d1

5 files changed

Lines changed: 4 additions & 73 deletions

File tree

apps/site/public/arctecture.webp

-87.4 KB
Binary file not shown.

apps/site/public/brand/linux.svg

Lines changed: 0 additions & 1 deletion
This file was deleted.

apps/site/public/logo.png

-59 KB
Binary file not shown.
-792 KB
Binary file not shown.

apps/site/src/App.vue

Lines changed: 4 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,6 @@ const vscodeInstallCommand = 'code --install-extension pythoughts.pythinker-code
6161
6262
const copiedCommand = ref('');
6363
const mobileMenu = ref(null);
64-
const heroVideo = ref(null);
65-
const heroVideoPlaying = ref(false);
6664
const menuButton = ref(null);
6765
const menuOpen = ref(false);
6866
const activeTerminalDemo = ref(terminalDemos[0]);
@@ -171,30 +169,10 @@ function onDocumentKeydown(event) {
171169
if (event.key === 'Escape') closeMenu();
172170
}
173171
174-
async function playHeroVideo() {
175-
try {
176-
await heroVideo.value?.play();
177-
} catch {
178-
heroVideoPlaying.value = false;
179-
}
180-
}
181-
182-
function syncHeroMotionPreference() {
183-
if (reducedMotionQuery.matches) heroVideo.value?.pause();
184-
else void playHeroVideo();
185-
}
186-
187-
function toggleHeroVideo() {
188-
if (heroVideo.value?.paused) void playHeroVideo();
189-
else heroVideo.value?.pause();
190-
}
191-
192172
onMounted(() => {
193173
document.addEventListener('pointerdown', onDocumentPointerdown);
194174
document.addEventListener('keydown', onDocumentKeydown);
195175
reducedMotionQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
196-
reducedMotionQuery.addEventListener('change', syncHeroMotionPreference);
197-
syncHeroMotionPreference();
198176
playTerminalDemo();
199177
if (reducedMotionQuery.matches) return;
200178
@@ -214,7 +192,6 @@ onUnmounted(() => {
214192
clearTimeout(menuCloseTimer);
215193
clearTerminalPlayback();
216194
revealObserver?.disconnect();
217-
reducedMotionQuery?.removeEventListener('change', syncHeroMotionPreference);
218195
document.removeEventListener('pointerdown', onDocumentPointerdown);
219196
document.removeEventListener('keydown', onDocumentKeydown);
220197
});
@@ -250,28 +227,7 @@ onUnmounted(() => {
250227
<main id="top">
251228
<header class="hero container">
252229
<div class="hero-copy">
253-
<button
254-
class="hero-mascot-video"
255-
type="button"
256-
:aria-label="heroVideoPlaying ? 'Pause mascot animation' : 'Play mascot animation'"
257-
@click="toggleHeroVideo"
258-
>
259-
<video
260-
ref="heroVideo"
261-
autoplay
262-
muted
263-
loop
264-
playsinline
265-
preload="metadata"
266-
width="1280"
267-
height="720"
268-
aria-hidden="true"
269-
@play="heroVideoPlaying = true"
270-
@pause="heroVideoPlaying = false"
271-
>
272-
<source src="/pythinker-hero-clean-v2.mp4" type="video/mp4" />
273-
</video>
274-
</button>
230+
<PythinkerMascot class="hero-mascot" :width="164" :height="205" />
275231
<h1>Pythinker Code</h1>
276232
<p class="hero-accent">Think first, then code.</p>
277233
<p class="hero-lead">An open-source AI engineering agent for your terminal. It reads your repo, edits files, runs commands, and iterates until the job is done.</p>
@@ -768,35 +724,11 @@ onUnmounted(() => {
768724
line-height: 1.38;
769725
}
770726
771-
.hero-mascot-video {
772-
position: relative;
727+
.hero-mascot {
773728
display: block;
774-
width: clamp(160px, 16vw, 200px);
729+
width: clamp(128px, 12vw, 164px);
730+
height: auto;
775731
margin-inline: auto;
776-
padding: 0;
777-
border: 0;
778-
appearance: none;
779-
aspect-ratio: 4 / 3;
780-
background: transparent;
781-
color: var(--ink);
782-
cursor: pointer;
783-
}
784-
785-
.hero-mascot-video:focus-visible {
786-
outline: 2px solid var(--accent);
787-
outline-offset: 4px;
788-
border-radius: var(--radius-sm);
789-
}
790-
791-
.hero-mascot-video video {
792-
display: block;
793-
width: 100%;
794-
height: 100%;
795-
object-fit: cover;
796-
-webkit-mask-image: radial-gradient(ellipse 50% 50% at center, black 58%, transparent 100%);
797-
mask-image: radial-gradient(ellipse 50% 50% at center, black 58%, transparent 100%);
798-
mix-blend-mode: multiply;
799-
pointer-events: none;
800732
}
801733
802734
.works-with {

0 commit comments

Comments
 (0)