refactor: fix whitespace indents in copy
CI / Generate Certificates (pull_request) Successful in 37s
CI / Frontend CI (pull_request) Successful in 1m8s
CI / Backend CI (pull_request) Successful in 1m8s
CI / E2E Tests (pull_request) Successful in 6m53s

This commit is contained in:
me
2026-05-08 23:20:27 +05:30
parent a3a56d4316
commit fff90902b5
14 changed files with 2556 additions and 2536 deletions
@@ -30,7 +30,8 @@ export function DrawerSection({
className={`bg-neutral/10 transition-all duration-1000 ease-in-out overflow-visible ${isOpen ? "max-h-125" : "max-h-0 pointer-events-none"}`}
>
<div
className={`transition-opacity ease-in-out ${isOpen
className={`transition-opacity ease-in-out ${
isOpen
? "opacity-100 py-3 border-b border-base-content/5 duration-700 delay-500"
: "opacity-0 duration-100"
}`}
@@ -56,7 +57,8 @@ export function DrawerSection({
<div className="flex-1">
<div
data-testid="drawer-section-title"
className={`font-sans text-xs tracking-widester uppercase transition-colors duration-800 ${isOpen
className={`font-sans text-xs tracking-widester uppercase transition-colors duration-800 ${
isOpen
? "text-base-content"
: "text-base-content/40 group-hover:text-base-content/80"
}`}
@@ -66,7 +68,8 @@ export function DrawerSection({
<div className="font-sans text-xs text-base-content/20 mt-1">
<span className="font-mono text-xs md:text-base -mt-1 absolute text-primary/30">
{count}
</span>&nbsp;
</span>
&nbsp;
<span className="ml-3">{subtext}</span>
</div>
<div className="absolute right-5 -translate-y-15 text-base-content/4">
@@ -84,7 +87,8 @@ export function DrawerSection({
/>
) : (
<div
className={`w-8 h-1 rounded-sm transition-all duration-300 bg-neutral ${isOpen
className={`w-8 h-1 rounded-sm transition-all duration-300 bg-neutral ${
isOpen
? "bg-primary/80! opacity-80 scale-110"
: "group-hover:bg-primary"
}`}
@@ -26,7 +26,8 @@ export function PostSealModal({
When you're ready,
<br />
you can&nbsp;
<span className="text-primary font-bold font-display">read</span> it,&nbsp;
<span className="text-primary font-bold font-display">read</span>
&nbsp; it,&nbsp;
<span className="text-accent font-bold font-display">send</span> it to
someone, or&nbsp;
<span className="text-error font-bold font-display">burn</span> it to
+1 -2
View File
@@ -270,8 +270,7 @@ export function VaultConfirmModal({
I'll remember to mail you this on the unlock date.
<br />
<span className={"font-bold text-primary"}>
&nbsp;
But I won't let you read or rewrite this letter until then.
&nbsp; But I won't let you read or rewrite this letter until then.
</span>
<br />
</p>
+12 -10
View File
@@ -25,9 +25,9 @@ export default function WelcomeModal({
</div>
<h3 className="font-display text-2xl font-bold text-primary">
Welcome to&nbsp;
<Logo />
<Logo type="inline" />
</h3>
<p className="text-sm md:text-base text-base-content/80 md:leading-relaxed">
<p className="inline text-sm md:text-base text-base-content/80">
Before we begin, let me make a small promise.
<HandPalmIcon
size={18}
@@ -38,17 +38,19 @@ export default function WelcomeModal({
Everything you write here is sealed with your password,&nbsp;
<span className="font-display text-success">cryptographically</span>
, before it leaves your hands.
<br />A fancy way of saying, I couldn't if I tried.
<br />
<br />A fancy way of saying, no one else can read them without your
key&mdash;not even me.
</p>
<div className="alert alert-warning flex items-start gap-3 text-left py-3">
<WarningIcon size={24} weight="fill" className="shrink-0" />
<div className="text-xs md:text-sm font-medium text-primary-content">
<div className="text-xs md:text-sm font-medium text-primary-content tracking-tight">
If you ever happen to forget your password, your letters are lost
to time, forever.
<br />
<span className="font-bold mt-2 block">
I highly, highly recommend storing this password in your&nbsp;
<span className="mt-2 block">
I highly, <span className="font-bold italic">highly</span>&nbsp;
recommend storing this password in your&nbsp;
<a
href="https://www.privacyguides.org/en/passwords/"
target="_blank"
@@ -56,8 +58,8 @@ export default function WelcomeModal({
rel="noopener noreferrer"
>
password manager
</a>&nbsp;
or somewhere safe to remember it.
</a>
&nbsp; or somewhere safe to remember it.
</span>
</div>
</div>
@@ -74,7 +76,7 @@ export default function WelcomeModal({
</div>
</div>
</Modal>
<div className="absolute bottom-0 right-0 z-1000 font-sans w-full">
<div className="absolute bottom-0 md:right-5/12 z-1000 font-sans w-full flex justify-center">
<Saajan
position="left"
message={"I've lost words before.\nI know what it feels like."}
@@ -23,8 +23,8 @@ export function PostActionOverlay({ revealState }: PostActionOverlayProps) {
May your <span className="italic text-primary">soul</span> find
solace,
<br />
just like your <span className="text-accent italic">unsaid</span>&nbsp;
words did.
just like your <span className="text-accent italic">unsaid</span>
&nbsp; words did.
</p>
<div className="divider mx-auto w-24 text-center"></div>
<button
@@ -59,8 +59,8 @@ export function ShareModal({ shareLink, setShareLink }: ShareModalProps) {
</div>
<div className="flex flex-col gap-1 uppercase tracking-widest text-base-content/30 font-sans">
<p className="textarea-xs flex items-center justify-center">
<EyeSlashIcon weight="duotone" size={18} className="mr-2" />&nbsp;
Zero-Knowledge Share:
<EyeSlashIcon weight="duotone" size={18} className="mr-2" />
&nbsp; Zero-Knowledge Share:
</p>
<p className="textarea-xs font-mono text-center">
The key never leaves your or the recipient's browser.
@@ -68,7 +68,7 @@ export function ShareModal({ shareLink, setShareLink }: ShareModalProps) {
</div>
</div>
</Modal>
<div className="absolute bottom-0 z-1000 font-sans w-full">
<div className="absolute bottom-0 md:right-5/11 z-1000 font-sans w-full">
<Saajan
position="top"
message={`Someone once said,\n"To send a letter is a good way to go somewhere without moving anything but your heart."\nThey were not wrong.`}
+72 -60
View File
@@ -228,27 +228,31 @@ function SpecsSection() {
<h2 className="text-xl md:text-3xl text-center mx-auto">
<Logo type={"inline"} /> uses&nbsp;
<span className="text-accent font-mono">Zero Knowledge</span>&nbsp;
<span className="group ul-wavy font-mono text-success">
<button
type="button"
className="group ul-wavy font-mono text-success"
>
E
<span className="hidden group-hover:inline group-focus-within:inline">
<span className="hidden group-hover:inline group-focus-within:inline text-neutral">
nd&mdash;
</span>
2
<span className="hidden group-hover:inline group-focus-within:inline">
<span className="hidden group-hover:inline group-focus-within:inline text-neutral">
&mdash;
</span>
E
<span className="hidden group-hover:inline group-focus-within:inline">
<span className="hidden group-hover:inline group-focus-within:inline text-neutral">
nd
</span>
<span className="hidden group-hover:inline group-focus-within:inline">
&nbsp;<span>E</span>
<span className="hidden group-hover:inline group-focus-within:inline">
<span className="hidden group-hover:inline group-focus-within:inline text-neutral">
ncryption
</span>
</span>
</span>&nbsp;
for your <span className="font-hand text-primary">letters</span>, with&nbsp;
</button>
&nbsp; for your&nbsp;
<span className="font-hand text-primary">letters</span>, with&nbsp;
<a
href="https://hackernoon.com/what-the-heck-is-envelope-encryption-in-cloud-security"
target="_blank"
@@ -256,8 +260,8 @@ function SpecsSection() {
className="font-mono text-neutral!"
>
Envelope Encryption
</a>&nbsp;
for the <span className="font-hand text-primary">keys</span>.
</a>
&nbsp; for the <span className="font-hand text-primary">keys</span>.
</h2>
<div className="text-sm md:text-xl leading-relaxed">
This means, both the&nbsp;
@@ -269,8 +273,8 @@ function SpecsSection() {
Every letter has a&nbsp;
<span className="font-mono text-primary/50 font-bold">
unique key
</span>&nbsp;
which is derived from your original password.
</span>
&nbsp; which is derived from your original password.
</li>
<li>
Both the letter and the key are encrypted securely and sent to the
@@ -278,8 +282,10 @@ function SpecsSection() {
</li>
<li>
Now, the server holds&nbsp;
<span className="text-primary/50 font-bold">the envelope</span>,&nbsp;
<span className="text-primary/50 font-bold">the seal</span> and&nbsp;
<span className="text-primary/50 font-bold">the envelope</span>
,&nbsp;
<span className="text-primary/50 font-bold">the seal</span>&nbsp;
and&nbsp;
<span className="text-primary/50 font-bold">
another locked box
</span>
@@ -296,17 +302,18 @@ function SpecsSection() {
Nothing on the server is readable without your actual password.
<br />
Even if someone were to breach in, all they'd find is encrypted
noise and ain't no way they crackin' it.&nbsp;
noise and ain't no way they crackin'
<br />
<a
href="https://xkcd.com/538/"
target="_blank"
rel="noopener noreferrer"
className="text-xxs md:text-sm text-neutral! font-hand"
>
(unless this happens)
&nbsp;(unless this happens)
</a>
</span>
<div className="w-18 h-18 flex shrink-0 items-center justify-end bg-success/20 rounded-full p-0 ">
<div className="flex shrink-0 items-center justify-end bg-success/20 rounded-full p-4 ">
<VaultIcon
size={36}
weight="duotone"
@@ -335,8 +342,8 @@ function SpecsSection() {
<p className="text-sm md:text-lg">
Of course, this level of&nbsp;
<span className="text-success font-bold">privacy</span> comes with a
catch. <span className="text-error font-bold">No password reset</span>&nbsp;
for you.
catch. <span className="text-error font-bold">No password reset</span>
&nbsp; for you.
</p>
<p className="text-xs md:text-base alert alert-warning font-medium">
<InfoIcon weight="duotone" /> Your original password is never stored
@@ -366,7 +373,8 @@ function OSSSection() {
<SmileyIcon weight="duotone" className="text-primary" />
<ArrowArcLeftIcon className="text-accent inline rotate-45 -translate-y" />
</span>
</span>&nbsp;
</span>
&nbsp;
<span className="text-success -rotate-3">open source !</span>
</h1>
<div className="flex flex-col items-center shrink-0 max-w-11/12 w-220 gap-4 p-4 md:p-6 text-neutral-content/80">
@@ -379,7 +387,8 @@ function OSSSection() {
</p>
<p className="text-sm md:text-lg">
You can also&nbsp;
<span className="uppercase font-mono text-primary">Self-host</span>&nbsp;
<span className="uppercase font-mono text-primary">Self-host</span>
&nbsp;
<Logo type={"inline"} /> in just 4 steps.
</p>
<div className="mockup-code w-110 max-w-11/12 text-xs">
@@ -449,16 +458,16 @@ function OSSSection() {
rel="noopener noreferrer"
>
DaisyUI
</a>&nbsp;
·&nbsp;
</a>
&nbsp; ·&nbsp;
<a
href="http://fabricjs.com"
target="_blank"
rel="noopener noreferrer"
>
Fabric.js
</a>&nbsp;
·&nbsp;
</a>
&nbsp; ·&nbsp;
<a
href="https://phosphoricons.com"
target="_blank"
@@ -583,9 +592,10 @@ function StorySection() {
cript
</span>
.
</button>&nbsp;
&mdash;the thing you add after you've already signed your name, what
you write when you thought you were finished, but weren't.
</button>
&nbsp; &mdash;the thing you add after you've already signed your
name, what you write when you thought you were finished, but
weren't.
</p>
<p>
<span className={"font-medium text-primary"}>
@@ -602,8 +612,8 @@ function StorySection() {
}
>
don't just disappear. They
</button>&nbsp;
stay&nbsp;
</button>
&nbsp; stay&nbsp;
<span className={"text-primary font-hand font-extrabold"}>
unsaid
</span>
@@ -640,10 +650,9 @@ function ForWhoSection() {
<Logo type={"mono"} /> wasn't built for one kind of person, but a
particular kind of feeling&mdash;
<span className="italic font-serif text-stone-900">
&nbsp;
the one that lingers very quietly
</span>&nbsp;
&mdash;fragile, yet never breaks.
&nbsp; the one that lingers very quietly
</span>
&nbsp; &mdash;fragile, yet never breaks.
</p>
<div className="pt-8 flex items-center gap-4">
@@ -681,8 +690,8 @@ function ArchetypesSection() {
open
>
<summary className="collapse-title md:text-xl leading-tight font-hand flex items-center gap-4">
<GhostIcon weight="duotone" className="text-accent" size={32} />&nbsp;
To someone you can't reach anymore.
<GhostIcon weight="duotone" className="text-accent" size={32} />
&nbsp; To someone you can't reach anymore.
</summary>
<div className="collapse-content text-sm md:text-lg flex flex-col gap-4">
<p>
@@ -712,8 +721,8 @@ function ArchetypesSection() {
weight="duotone"
className="text-accent"
size={32}
/>&nbsp;
To someone who's still here.
/>
&nbsp; To someone who's still here.
</summary>
<div className="collapse-content text-sm md:text-lg flex flex-col gap-4">
<p>
@@ -742,7 +751,8 @@ function ArchetypesSection() {
weight="duotone"
className="text-accent"
size={14}
/>&nbsp;
/>
&nbsp;
<PersonArmsSpreadIcon
weight="duotone"
className="text-accent"
@@ -775,8 +785,8 @@ function ArchetypesSection() {
name="my-accordion-det-1"
>
<summary className="collapse-title text-lg md:text-xl leading-tight font-hand flex items-center gap-4">
<SparkleIcon weight="duotone" className="text-accent" size={32} />&nbsp;
For liberation.
<SparkleIcon weight="duotone" className="text-accent" size={32} />
&nbsp; For liberation.
</summary>
<div className="collapse-content text-sm md:text-lg flex flex-col gap-4">
<p>
@@ -871,9 +881,9 @@ function AttributionSection() {
rel="noopener noreferrer"
>
CS50W
</a>&nbsp;
capstone&mdash;one I kept postponing until I ran out of excuses.
When I sat down to build it, it felt heavier than a typical
</a>
&nbsp; capstone&mdash;one I kept postponing until I ran out of
excuses. When I sat down to build it, it felt heavier than a typical
assignment&mdash;not just because things were difficult. It had to
be something that outlasted the grade. I wanted to make this one
count more than anything else I'd ever made. Something as close to
@@ -890,9 +900,9 @@ function AttributionSection() {
(only if I could've just made my mind up on one design system
sooner, instead of paddling in a sea of muses, muses everywhere)
</span>
. I know I've shared the nuts and bolts of <Logo type={"inline"} />&nbsp;
here&mdash;the core philosophies, how it all works&mdash;but the
heart of it is really something you have to find by exploring it
. I know I've shared the nuts and bolts of <Logo type={"inline"} />
&nbsp; here&mdash;the core philosophies, how it all works&mdash;but
the heart of it is really something you have to find by exploring it
yourself.
</p>
<p>
@@ -918,27 +928,29 @@ function AttributionSection() {
onMouseLeave={() => setHover((h) => ({ ...h, visible: false }))}
>
Saajan
</span>&nbsp;
from&nbsp;
</span>
&nbsp; from&nbsp;
<a
href="https://www.themoviedb.org/movie/191714-the-lunchbox"
target="_blank"
rel="noopener noreferrer"
>
The Lunchbox
</a>&nbsp;
&mdash;brought to life with such subtle brilliance by&nbsp;
</a>
&nbsp; &mdash;brought to life with such subtle brilliance by&nbsp;
<a
className="text-accent!"
href="https://www.themoviedb.org/person/76793-irrfan-khan"
rel="noopener noreferrer"
>
Irrfan Khan
</a>&nbsp;
</a>
&nbsp;
<PeaceIcon weight="duotone" className="inline text-accent" />
&mdash;the quiet emotional weight he carries through a lonely and
mechanized life, right up until those letters arrive and something
inside him finally loosens. The ending feels like a deep sigh of&nbsp;
inside him finally loosens. The ending feels like a deep sigh
of&nbsp;
<span className="font-hand font-bold text-accent">
"it is what it is"
</span>
@@ -950,12 +962,12 @@ function AttributionSection() {
There's a lot that goes&nbsp;
<span className={"text-primary font-hand text-lg md:text-xl"}>
unsaid
</span>&nbsp;
these days. Not for a lack of feeling, not for the lack of time, but
because the ways we reach each other have quietly changed. We're
always reachable <span className="italic">digitally,</span> yet
somehow the things that actually matter most end up staying
inside&mdash;a trapped one at that.
</span>
&nbsp; these days. Not for a lack of feeling, not for the lack of
time, but because the ways we reach each other have quietly changed.
We're always reachable <span className="italic">digitally,</span>
&nbsp; yet somehow the things that actually matter most end up
staying inside&mdash;a trapped one at that.
<br />
Maybe writing can/will help. Maybe putting words somewhere
deliberate makes them feel less like a weight you're carrying alone.
@@ -990,8 +1002,8 @@ function AttributionSection() {
weight="duotone"
size={48}
className="rotate-180 text-neutral-content"
/>&nbsp;
I think we forget things if there is nobody to tell them.
/>
&nbsp; I think we forget things if there is nobody to tell them.
<span className="block mt-2 text-sm not-italic text-base-200/70 w-full text-right">
~ Saajan Fernandes,&nbsp;
<span className="italic underline decoration-dotted">
+2 -1
View File
@@ -59,7 +59,8 @@ export default function Activate() {
You're in.
</h2>
<p className="opacity-70 leading-relaxed">
Welcome to <Logo scale={1} />
Welcome to&nbsp;
<Logo type="inline" />
<br />
Just one more step and you can start writing timeless letters.
</p>
+5 -6
View File
@@ -174,8 +174,8 @@ export default function Home() {
seal it&nbsp;
<span className="text-success font-mono tracking-tighter font-extrabold">
secure
</span>&nbsp;
and&nbsp;
</span>
&nbsp; and&nbsp;
<span className="text-info font-mono tracking-tighter italic">
private
</span>
@@ -225,8 +225,7 @@ export default function Home() {
),
}}
>
&nbsp;
or&nbsp;
&nbsp; or&nbsp;
</motion.span>
<span className="font-display text-success">
yourself in the future
@@ -250,8 +249,8 @@ export default function Home() {
}}
className="absolute text-4xl md:text-6xl text-center px-10 leading-tight"
>
and even <span className="font-display text-error">burn it</span>&nbsp;
to release the burden.
and even <span className="font-display text-error">burn it</span>
&nbsp; to release the burden.
</motion.h2>
{/* Outro */}
<motion.h2
+2 -1
View File
@@ -132,7 +132,8 @@ export default function Login() {
</div>
<div className="divider text-neutral my-0">or</div>
<div className="text-center text-sm font-medium text-neutral">
New to <Logo type="inline" />?&nbsp;
New to <Logo type="inline" />
?&nbsp;
<button
type="button"
name="register"
+4 -3
View File
@@ -77,7 +77,8 @@ export default function Register() {
<div className="glass-card w-full max-w-sm p-2 transition-all duration-500 hover:shadow-2xl fade-zoom">
<form onSubmit={handleSubmit(onSubmit)} className="card-body gap-4">
<div className="card-title font-display text-2xl justify-center text-primary/80 tracking-tight whitespace-nowrap">
Create a <Logo type="logo" scale={0.7} /> Account
Create a<Logo type="logo" scale={0.7} />
Account
</div>
{apiError && (
@@ -144,8 +145,8 @@ export default function Register() {
<p className="text-sm font-semibold">
Choose a password you won't forget. <br />
Just like life,&nbsp;
<span className="underline decoration-2">there is no reset</span>&nbsp;
here. If you lose it, your letters cannot be recovered.
<span className="underline decoration-2">there is no reset</span>
&nbsp; here. If you lose it, your letters cannot be recovered.
</p>
</div>
+2 -2
View File
@@ -23,8 +23,8 @@ export default function VerifyEmail() {
Check Your Mailbox
</h2>
<p className="text-sm opacity-80 leading-relaxed font-sans mt-6">
You're one train away from starting your <Logo scale={0.8} />&nbsp;
journey.
You're one train away from starting your <Logo scale={0.8} />
&nbsp; journey.
</p>
</div>