import {
ArrowArcLeftIcon,
ArrowBendDownLeftIcon,
ArrowBendDownRightIcon,
ArrowRightIcon,
CaretUpIcon,
FlowerTulipIcon,
GhostIcon,
InfoIcon,
LockLaminatedIcon,
LockOpenIcon,
PasswordIcon,
PersonArmsSpreadIcon,
PersonIcon,
ScrollIcon,
SmileyIcon,
SparkleIcon,
VaultIcon,
} from "@phosphor-icons/react";
import { ReactLenis } from "lenis/react";
import { AnimatePresence, motion, useScroll, useTransform } from "motion/react";
import { useEffect, useRef, useState } from "react";
import stamp from "../assets/envelope/stamp.png";
import Logo from "../components/Logo.tsx";
import { Modal } from "../components/ui/Modal";
import "@fontsource/kavivanar/index.css";
import "@fontsource/space-mono/index.css";
import "@fontsource/redacted-script/index.css";
import "@fontsource/architects-daughter/index.css";
import { useNavigate } from "react-router-dom";
function HorizontalScroll({ children }: { children: React.ReactNode }) {
const ref = useRef(null);
const { scrollYProgress } = useScroll({ target: ref });
const x = useTransform(scrollYProgress, [0, 1], ["0%", "-50%"]);
return (
Your letters.{" "} Nobody else's.
When you write something here, it gets encrypted in your browser before anything leaves your device. What reaches the server isn't your letter. It's something unreadable — and the server has no way to change that, because the key never left you.
B@z1ng4A
Hello friend,
I've never told this to anyone...
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut semper, justo eget vehicula vestibulum, enim enim suscipit lectus, et sagittis nibh risus vel metus. Quisque eu ornare ante, et gravida mauris. Vivamus massa justo, sagittis non viverra sed, sodales non nisi. Nunc semper, massa a aliquet dictum, enim nisi malesuada orci, et elementum lectus turpis et velit. Nam vel felis vitae tortor dignissim malesuada. Nam suscipit, justo eu elementum pulvinar, magna sem tempor ex, vitae iaculis tellus odio non nisl. Duis dolor orci, viverra ut finibus sed, aliquet vitae tortor. Proin sodales ipsum ac ipsum hendrerit tempus. Nunc nec nibh nibh. Aenean consequat auctor posuere. Integer sed magna volutpat, efficitur nisl ut, dignissim neque. Vestibulum convallis nec dui a euismod. Duis dignissim magna in mattis pulvinar. Sed blandit nibh quis arcu ornare, sit amet fermentum nisi rhoncus.
9e54d05f88bdd67a675b03bf1cd0a1647e2109b5aa18185ff6a9ba4c6959a19d
SZ0Mq9M9sCZsdDB8HGjk7JfWG56Kaot8Lgma74MCusDUYibUGoR7VviWgvc341pvFV9/IAyot9KtlDvwIX1ZmUw9Oh340JMaajRQ7iNgVjHgAwmJAr2cLbReNqlF6xzaf3mIYkiK9BXNQekk2h/9XufklsqoIXpaK1re7xWQ8mdddzy6z4EQFVH/Ev3np5ERW/ss7Z1kqYWUnANK7olWNL/7GgZmhU+L29rgbR52kcH9fng7gnEI3KEuISYExYCg81G1VaJYspkW3A4qwcet+jXdgmbKvkux5qNw6gyNi9d/YqKV7OUNrmoH190rHdJ5A7HOIv3/SvPhb3Zm4sNF5PcMxmhM0+T9m5PejV1GhV9bMBHbbgacay7hZJU3O0+q+7fBAE/+pqfvZdv78lLDFSdtHAXUpYOvHPrI5BNNwuS3T+FK1zjurLnUPThlOSYRICoZSUcxVswXz897PoRmFNNvbal0dpKUmCFrBwV5c/W3d1+iZor5msbm/JxpbNtys59e0StSTwHKsxvxm/rTuUAxWSOmzt13MDBxxd2zyVnX8rtQ7mEjMJ8IHHpvhKjONoa2S11VBJY68Ee1vNrw7htu+wajvmXhHAyfh1lYql8pu8VvPUG7leEQ9I0pMY35Y/C1cYCBLkDT5zf8NeZFtbp0BNgHd+QDVSFH+GSnvTskU2BCio3YE+zE6cDhvLUOMy3e5RAtPqsi5VzpEUcdCwph+Z+1pFlTxiEZ62i4wNpqw2lhS3b/E9ifJgnncSgRHLtfw/VxHZCRc4tBQ24xSZ507lSlQch+5lQeO7rx2htgd2D7aGNx/UN/xmeuEd4a28AxNOVS3uYh3wTDh8CSXyBRCRPxrANOV1ZBojdfK+v5fOJNPgDn3r5/pG80L3FTkecRB0zFuKNG8jIzi5ADx9k4SlhRNo17gPl2if8gRA6tzTae4kbzieG+woxhUWj/qvXg0MQmg59VTK2HHS34exdKDP9a561svlw+lJ2AtM1EL9srJk8i3kiyEPUeIlaLl3AfgbbSuC2RhlzFFAYuQ06rbsSvEoe4rrYeMXxL9jwVsXX0xrp8H25mOJu3ahn5pFYzADMSGf4L11H1vDArpefj/lW+8zcmogxxBktYYNF/qU4v+9367hp4MEn/84tQPpmb47TL+XpVnl9tQ3r9OfOaW3zX7NkWZbqoX7OgdgHOtTLP/euQujSs2MAzMO4BmbuCS7pR/GTZwDqF1sXiWAkunjo2qpKHieqlvSVmtwEhh6wsNwYTKEkddmTqvKSx0fHRvs3D9lMGJfg7wLSz/3Otx3G65tk9l/3B3r87qQTvbqXmcfnFdEIaR8mO/yMyCKnxtJkJb3lEzNUOrvnSxwL7Gyn54TLTWA==
This means, both the encryption and decryption runs on your device, in
your browser.
Every letter has a{" "}
unique key which is
derived from your original password.
Both the letter and the key are encrypted securely and sent to the
server.
Now, the server holds{" "}
the envelope,{" "}
the seal and{" "}
another locked box{" "}
with a key inside that unseals your letter. But you,{" "}
only you, hold the only
thing that opens the box —{" "}
your password.
Nothing on the server is readable without your actual password.
Even if someone were to breach in, all they'd find is encrypted noise.
This level of privacy comes with a catch.{" "} No password reset.
You can also{" "}
Self-host{" "}
git clone https://git.ramvignesh.dev/me/pi-ku.git
cd pi-ku
./scripts/setup.sh
./scripts/start.sh
Found something to report or request?{" "} Please say so.
Built on the shoulders of open source.
Web Crypto API {" "} — the backbone of everything promised. Browser-native cryptography that runs entirely on your device. Without it, none of the privacy here would be possible — or credible.
DaisyUI {" "} ·{" "} Fabric.js {" "} ·{" "} Phosphor Icons {" "} — the beautiful work by others that let me focus on the core experience.
Open source is what made this possible. It felt right to give it back the same way.
"the most honest thing was always in the{" "} பி. கு."
Most of what we actually mean to say never gets said.
It sits in drafts , in half-written notes, in the pause before we
change the subject.
Those words{" "}
don't just disappear. They
{" "}
stay unsaid{" "}
— a quiet weight difficult to bear.
And that's okay...
A space for the letters you meant to send, the afterthoughts
that deserved more than silence.
A person who left. A relationship that ended without a real
ending. Someone who's still in your life but will never know
what you felt. Some conversations just close before they're
finished.
Write the letter anyway. Keep it close.
Not every letter is about distance. Sometimes you just need to say something properly — without a text thread, without the noise of a conversation already in motion. A letter slows it down.
Give people their due flowers while they can still smell them.
Not a journal. Not a note-to-self. A proper letter — to
whoever you'll be in a year, or five, or ten.
Ask yourself of the healed wounds, forgotten fears, or the
things you finally learned to live with.
Set a date and let a letter surprise you when you've long forgotten writing it.
Some unsaid words just need to leave your headspace. There's no
recipient, no subject line, no send button. Just the act of
putting it somewhere outside of yourself.
That's sometimes enough.
Say it once. All of it. Then let it fade.
If any of these felt familiar,
no matter how little,
this is for you.
Thank you so much for making it this far. Really.
This started as a{" "}
CS50W
{" "}
capstone, one I kept postponing until I ran out of reasons not to.
When I eventually sat down to build, I knew it had to be more than a
deadline; it had to be something that outlasted the grade. I wanted
to create a space for the feelings we usually keep to ourselves and
every hour spent on it was worth it. I've shared the edges of{" "}
I kept coming back to{" "} setHover({ visible: true, x: e.clientX, y: e.clientY, }) } onMouseMove={(e) => setHover((h) => ({ ...h, x: e.clientX, y: e.clientY, })) } onMouseLeave={() => setHover((h) => ({ ...h, visible: false }))} > Saajan {" "} from{" "} The Lunchbox {" "} —{" "} one of the most subtle yet brilliant portrayals by Irrfan Khan {" "} — the quiet emotional weight he carries throughout the film, going through the motions of a lonely life, until those letters arrive and something inside him finally loosens. Of course, the ending felt like a deep sigh of "it is what it is". But something about the act of writing and letting the unsaid out eased it, even briefly. I think about that a lot.
There's a lot that goes{" "}
unsaid
{" "}
now. Not that people feel less or for the lack of time, but because
the ways we reach each other have quietly changed. We're always
reachable digitally, yet somehow the
things that matter most end up staying inside.
Maybe writing will help with that. Maybe something about putting
words somewhere deliberate makes them feel less like something
you're carrying.
Or maybe it won't, but it's worth a try.
— Ram
"I think we forget things if there is nobody to tell them." ~ Saajan Fernandes, The Lunchbox