diff --git a/public/phokus-aperture.svg b/public/phokus-aperture.svg new file mode 100644 index 0000000..df554c4 --- /dev/null +++ b/public/phokus-aperture.svg @@ -0,0 +1,43 @@ + + Phokus + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/website/src/App.tsx b/website/src/App.tsx index 7162128..3a2b9c1 100644 --- a/website/src/App.tsx +++ b/website/src/App.tsx @@ -1,3 +1,4 @@ +import { useRef, useState } from "react"; import { PhokusMark } from "./components/PhokusMark"; // Screenshots are 2560×1600 masters; imagetools downscales + transcodes to // AVIF/WebP at build (see the Shot helper). `as=picture` must be the last query @@ -58,10 +59,10 @@ function Shot({ function Header() { return (
-
+
- - Phokus + + Phokus Download + + +
); } +function MobileChapterNav() { + return ( + + ); +} + +function MobileChapter({ + number, + label, + title, + children, +}: { + number: string; + label: string; + title: string; + children: React.ReactNode; +}) { + return ( +
+
+ {number} + + {label} +
+

+ {title} +

+ {children} +
+ ); +} + function Hero() { return ( -
+
+
+
+ +
+
+ + Your folders. Your machine. + + + + Windows + +
+
+ +
+

+ See everything. +
+ Find anything. +

+

+ Search and curate the images and videos already on your computer. Everything stays local. +

+ +
+ + Local + no uploads + + + Private + no account + + + Offline + after setup + +
+
+
+ +
{/* Product leads: the gallery dominates the right and bleeds off the frame, cropped so the workspace appears to continue beyond the viewport. */} -
+
-
+

Local-first · Windows desktop

-

+

Your local media library,
made searchable. @@ -132,14 +245,6 @@ function Hero() {

- - {/* Mobile/tablet: product sits below the copy, still bleeding off the right. */} -
-
); @@ -161,9 +266,9 @@ function LocalFirst() { }, ]; return ( -
+
-
+

@@ -200,7 +305,31 @@ function SearchSection() { return ( + ); +} + +function MobileFeatureDeck() { + const [activeCard, setActiveCard] = useState(0); + const cardRefs = useRef>([]); + + function updateActiveCard(event: React.UIEvent) { + const deckCenter = event.currentTarget.scrollLeft + event.currentTarget.clientWidth / 2; + let nearestIndex = 0; + let nearestDistance = Number.POSITIVE_INFINITY; + + cardRefs.current.forEach((card, index) => { + if (!card) return; + const cardCenter = card.offsetLeft + card.offsetWidth / 2; + const distance = Math.abs(cardCenter - deckCenter); + if (distance < nearestDistance) { + nearestDistance = distance; + nearestIndex = index; + } + }); + + setActiveCard(nearestIndex); + } + + function showCard(index: number) { + cardRefs.current[index]?.scrollIntoView({ + behavior: window.matchMedia("(prefers-reduced-motion: reduce)").matches ? "auto" : "smooth", + block: "nearest", + inline: "center", + }); + } + + return ( +
+
+ +

+ Swipe through the core workflows. Each one stays focused on the media, not app chrome. +

+
+
+ +
+
{ cardRefs.current[0] = node; }} + className="w-[78vw] max-w-[19rem] shrink-0 snap-center overflow-hidden rounded-2xl border border-edge bg-canvas" + > +
+ +
+
+ EXPLORE +

See visual clusters.

+

+ Wander through related shots, then switch to a chronological timeline. +

+
+
+ +
{ cardRefs.current[1] = node; }} + className="w-[78vw] max-w-[19rem] shrink-0 snap-center overflow-hidden rounded-2xl border border-edge bg-canvas" + > +
+ +
+
+ CURATE +

Review without leaving.

+

+ Rate, favourite, tag, zoom, play video, and find similar images in place. +

+
+
+ +
{ cardRefs.current[2] = node; }} + className="w-[78vw] max-w-[19rem] shrink-0 snap-center overflow-hidden rounded-2xl border border-edge bg-canvas" + > +
+ +
+
+ CLEANUP +

Compare exact pairs.

+

+ Confirm byte-identical files and choose what to remove. Nothing is automatic. +

+
+
+
+ +
+ {[0, 1, 2].map((index) => ( +
); @@ -271,9 +525,9 @@ function EdgeMark({ side }: { side: "left" | "right" }) { function ExploreSection() { return ( -
+
-
+
@@ -308,9 +562,9 @@ function ExploreSection() { function CurateSection() { return ( -
+
-
+
+
-
+

@@ -381,7 +635,23 @@ function TechFactsSection() { { k: "License & build", v: "MIT, open source. The installer is currently unsigned — see the note below." }, ]; return ( -
+
+ +
+ {facts.map((fact, index) => ( +
+ + 0{index + 1} + {fact.k} + + + +

{fact.v}

+
+ ))} +
+
+ +

@@ -396,6 +666,7 @@ function TechFactsSection() {

))} +
); } @@ -404,30 +675,31 @@ function DownloadSection() { return (
-
- -

+
+ +

Point Phokus at a folder.

-

- Free and open source. Your library is indexed on your machine — the download is just the app. +

+ Turn a folder full of files into a library you can actually explore.

-
+ -

+

Heads up: this build isn't code-signed yet, so Windows SmartScreen will warn that the publisher is unrecognised — choose{" "} More info → Run anyway. An NVIDIA CUDA build is on the @@ -441,7 +713,7 @@ function DownloadSection() { function Footer() { return (