chore: replace empty jsx space braces with nbsp
CI / Generate Certificates (pull_request) Successful in 41s
CI / Frontend CI (pull_request) Successful in 1m7s
CI / Backend CI (pull_request) Successful in 1m8s
CI / E2E Tests (pull_request) Successful in 6m55s

This commit is contained in:
me
2026-05-08 22:17:50 +05:30
parent 2ba5d6964f
commit a3a56d4316
13 changed files with 2528 additions and 2531 deletions
@@ -30,8 +30,7 @@ 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"
}`}
@@ -57,8 +56,7 @@ 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"
}`}
@@ -68,7 +66,7 @@ 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>{" "}
</span>&nbsp;
<span className="ml-3">{subtext}</span>
</div>
<div className="absolute right-5 -translate-y-15 text-base-content/4">
@@ -86,8 +84,7 @@ 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"
}`}
@@ -25,10 +25,10 @@ export function PostSealModal({
<p className="text-base-content/80 text-sm font-sans">
When you're ready,
<br />
you can{" "}
<span className="text-primary font-bold font-display">read</span> it,{" "}
you can&nbsp;
<span className="text-primary font-bold font-display">read</span> it,&nbsp;
<span className="text-accent font-bold font-display">send</span> it to
someone, or{" "}
someone, or&nbsp;
<span className="text-error font-bold font-display">burn</span> it to
release
</p>
@@ -36,12 +36,12 @@ export function PostSealModal({
<p className="text-base-content/80 text-sm font-sans">
Be assured that the letter will find you when the time is right.
<br />
Till then,{" "}
Till then,&nbsp;
<span className="font-bold font-display text-primary">
take a deep breath
</span>
, <span className="font-bold font-display text-accent">manifest</span>
, and{" "}
, and&nbsp;
<span className="font-bold font-display text-success">
let it rest
</span>
+1 -1
View File
@@ -270,7 +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.
</span>
<br />
@@ -35,7 +35,7 @@ export default function WelcomeModal({
weight="fill"
/>
<span className="divider my-0"></span>
Everything you write here is sealed with your password,{" "}
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.
@@ -48,7 +48,7 @@ export default function WelcomeModal({
to time, forever.
<br />
<span className="font-bold mt-2 block">
I highly, highly recommend storing this password in your{" "}
I highly, highly recommend storing this password in your&nbsp;
<a
href="https://www.privacyguides.org/en/passwords/"
target="_blank"
@@ -56,7 +56,7 @@ export default function WelcomeModal({
rel="noopener noreferrer"
>
password manager
</a>{" "}
</a>&nbsp;
or somewhere safe to remember it.
</span>
</div>
+2 -2
View File
@@ -58,8 +58,8 @@ export function BurnModal({
Let the echoes of your unsaid be finally released.
</p>
<div className="mt-4 font-sans text-sm">
<span className="text-error">Press</span> and{" "}
<span className="text-error">hold</span> the{" "}
<span className="text-error">Press</span> and&nbsp;
<span className="text-error">hold</span> the&nbsp;
<span className="text-amber-300">flame</span> to proceed.
</div>
<div className="modal-action w-full justify-center gap-3 mt-2">
@@ -23,7 +23,7 @@ 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>{" "}
just like your <span className="text-accent italic">unsaid</span>&nbsp;
words did.
</p>
<div className="divider mx-auto w-24 text-center"></div>
@@ -30,7 +30,7 @@ export function ShareModal({ shareLink, setShareLink }: ShareModalProps) {
<p className="text-base-content/80 text-sm font-sans mt-4">
You've carried these words long enough.
<br />
Send your letter now, and let the{" "}
Send your letter now, and let the&nbsp;
<span className="text-accent font-display">unsaid</span> finally
find its home.
</p>
@@ -59,7 +59,7 @@ 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" />{" "}
<EyeSlashIcon weight="duotone" size={18} className="mr-2" />&nbsp;
Zero-Knowledge Share:
</p>
<p className="textarea-xs font-mono text-center">
+57 -57
View File
@@ -98,11 +98,11 @@ function PrivacySection() {
</h1>
<div className="flex flex-col items-center shrink-0 gap-8 max-w-11/12 w-220">
<p className="text-xxs md:text-sm tracking-widester text-neutral-content/80 font-semibold uppercase mt-6">
<span className="text-accent">Your letters.</span>{" "}
<span className="text-accent">Your letters.</span>&nbsp;
<span className="text-error">Nobody else's.</span>
</p>
<p className="text-sm md:text-lg text-neutral">
When you write or upload anything{" "}
When you write or upload anything&nbsp;
<span className="font-hand">(yes, even images)</span> here, it gets
encrypted in your browser before anything leaves your device. What
reaches the server is something unreadable&mdash;and the server has no
@@ -226,8 +226,8 @@ function SpecsSection() {
</h1>
<div className="flex flex-col items-center shrink-0 gap-6 max-w-11/12 w-220 mt-4 md:mt-12 text-neutral-content/80">
<h2 className="text-xl md:text-3xl text-center mx-auto">
<Logo type={"inline"} /> uses{" "}
<span className="text-accent font-mono">Zero Knowledge</span>{" "}
<Logo type={"inline"} /> uses&nbsp;
<span className="text-accent font-mono">Zero Knowledge</span>&nbsp;
<span className="group ul-wavy font-mono text-success">
E
<span className="hidden group-hover:inline group-focus-within:inline">
@@ -247,8 +247,8 @@ function SpecsSection() {
ncryption
</span>
</span>
</span>{" "}
for your <span className="font-hand text-primary">letters</span>, with{" "}
</span>&nbsp;
for your <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,20 +256,20 @@ function SpecsSection() {
className="font-mono text-neutral!"
>
Envelope Encryption
</a>{" "}
</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{" "}
<span className="font-display text-info">encryption</span> and{" "}
This means, both the&nbsp;
<span className="font-display text-info">encryption</span> and&nbsp;
<span className="font-display text-info">decryption</span> runs on
your device, in your browser.
<ul className="list-decimal ml-6 md:ml-10 list-outside text-neutral marker:text-primary/30 marker:font-mono marker:text-xs marker:md:text-base">
<li>
Every letter has a{" "}
Every letter has a&nbsp;
<span className="font-mono text-primary/50 font-bold">
unique key
</span>{" "}
</span>&nbsp;
which is derived from your original password.
</li>
<li>
@@ -277,9 +277,9 @@ function SpecsSection() {
server.
</li>
<li>
Now, the server holds{" "}
<span className="text-primary/50 font-bold">the envelope</span>,{" "}
<span className="text-primary/50 font-bold">the seal</span> and{" "}
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">
another locked box
</span>
@@ -288,7 +288,7 @@ function SpecsSection() {
</ul>
But you&mdash;
<span className="italic">only you</span>&mdash;hold the very thing
that opens that box,{" "}
that opens that box,&nbsp;
<span className="font-mono text-accent">your password</span>.
</div>
<div className="text-xs md:text-lg text-right w-full flex items-center justify-end gap-4 leading-relaxed text-neutral-content/80">
@@ -296,7 +296,7 @@ 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.{" "}
noise and ain't no way they crackin' it.&nbsp;
<a
href="https://xkcd.com/538/"
target="_blank"
@@ -333,9 +333,9 @@ function SpecsSection() {
</Modal>
<p className="text-sm md:text-lg">
Of course, this level of{" "}
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>{" "}
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">
@@ -357,16 +357,16 @@ function OSSSection() {
}
>
<Logo type={"inline"} />
is{" "}
is&nbsp;
<span className="line-through decoration-6 text-neutral-content/50 decoration-error">
&nbsp;private
<span className="absolute -translate-y-2 -translate-x-42 md:-translate-x-72 font-hand text-xs md:text-xl opacity-70 rotate-8 tracking-normal inline-flex items-center not-italic w-48 md:w-100 flex-wrap">
only for
<span className="text-primary">&nbsp;your letters&nbsp;</span>{" "}
<span className="text-primary">&nbsp;your letters&nbsp;</span>&nbsp;
<SmileyIcon weight="duotone" className="text-primary" />
<ArrowArcLeftIcon className="text-accent inline rotate-45 -translate-y" />
</span>
</span>{" "}
</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">
@@ -378,8 +378,8 @@ function OSSSection() {
don't have to take my word at it.
</p>
<p className="text-sm md:text-lg">
You can also{" "}
<span className="uppercase font-mono text-primary">Self-host</span>{" "}
You can also&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">
@@ -408,7 +408,7 @@ function OSSSection() {
</a>
.
<p className="text-xs md:text-base opacity-70">
Found something to report or request?{" "}
Found something to report or request?&nbsp;
<a
href="https://git.ramvignesh.dev/me/pi-ku/issues"
target="_blank"
@@ -449,16 +449,16 @@ function OSSSection() {
rel="noopener noreferrer"
>
DaisyUI
</a>{" "}
·{" "}
</a>&nbsp;
·&nbsp;
<a
href="http://fabricjs.com"
target="_blank"
rel="noopener noreferrer"
>
Fabric.js
</a>{" "}
·{" "}
</a>&nbsp;
·&nbsp;
<a
href="https://phosphoricons.com"
target="_blank"
@@ -533,7 +533,7 @@ function StorySection() {
postscript; a note written after the letter is signed.
<br />
<blockquote className="text-primary/50 italic mt-2 ml-2 border-l-primary/20 leading-none border-l">
"the most honest thing was always in the{" "}
"the most honest thing was always in the&nbsp;
<span className="font-ink">பி. கு.</span>"
</blockquote>
</li>
@@ -559,7 +559,7 @@ function StorySection() {
<Logo type={"inline"} /> is an abbreviated transliteration of the
<span className="font-ink text-accent"> ி </span>
<span className="italic text-xs md:text-base">(Tamil) </span>word
for{" "}
for&nbsp;
<button
type="button"
className={
@@ -583,7 +583,7 @@ function StorySection() {
cript
</span>
.
</button>{" "}
</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>
@@ -594,7 +594,7 @@ function StorySection() {
<br />
It sits in drafts , in half-written notes, in the pause before we
change the subject. <br />
Those words{" "}
Those words&nbsp;
<button
type="button"
className={
@@ -602,8 +602,8 @@ function StorySection() {
}
>
don't just disappear. They
</button>{" "}
stay{" "}
</button>&nbsp;
stay&nbsp;
<span className={"text-primary font-hand font-extrabold"}>
unsaid
</span>
@@ -640,9 +640,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>{" "}
</span>&nbsp;
&mdash;fragile, yet never breaks.
</p>
@@ -681,7 +681,7 @@ 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} />{" "}
<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">
@@ -712,7 +712,7 @@ function ArchetypesSection() {
weight="duotone"
className="text-accent"
size={32}
/>{" "}
/>&nbsp;
To someone who's still here.
</summary>
<div className="collapse-content text-sm md:text-lg flex flex-col gap-4">
@@ -742,7 +742,7 @@ function ArchetypesSection() {
weight="duotone"
className="text-accent"
size={14}
/>{" "}
/>&nbsp;
<PersonArmsSpreadIcon
weight="duotone"
className="text-accent"
@@ -775,7 +775,7 @@ 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} />{" "}
<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">
@@ -864,14 +864,14 @@ function AttributionSection() {
<p>
<Logo type={"inline"} /> took a while to exist.
<br />
This started as a{" "}
This started as a&nbsp;
<a
href="https://cs50.harvard.edu/web/"
target="_blank"
rel="noopener noreferrer"
>
CS50W
</a>{" "}
</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
@@ -885,19 +885,19 @@ function AttributionSection() {
Of course, frustrations, id-exisi crises, crept in from time to
time. But <Logo type="inline" /> helped me re-kindle the love for
the odd hours spent obsessing over the tiniest UX decisions and
endlessly polishing the UI{" "}
endlessly polishing the UI&nbsp;
<span className="font-hand">
(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"} />{" "}
. 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>
The "why" behind all of this didn't just appear out of nowhere. For
a while, I kept coming back to{" "}
a while, I kept coming back to&nbsp;
<span
role="tooltip"
className="cursor-default ul-wavy text-accent"
@@ -918,27 +918,27 @@ function AttributionSection() {
onMouseLeave={() => setHover((h) => ({ ...h, visible: false }))}
>
Saajan
</span>{" "}
from{" "}
</span>&nbsp;
from&nbsp;
<a
href="https://www.themoviedb.org/movie/191714-the-lunchbox"
target="_blank"
rel="noopener noreferrer"
>
The Lunchbox
</a>{" "}
&mdash;brought to life with such subtle brilliance by{" "}
</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>{" "}
</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{" "}
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>
@@ -947,10 +947,10 @@ function AttributionSection() {
that a lot.
</p>
<p>
There's a lot that goes{" "}
There's a lot that goes&nbsp;
<span className={"text-primary font-hand text-lg md:text-xl"}>
unsaid
</span>{" "}
</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
@@ -973,7 +973,7 @@ function AttributionSection() {
</p>
<p className="text-xs md:text-sm opacity-75 font-mono">
P.S. And just so we're clear&mdash;I wrote every word of this
myself&mdash;as I continue to back{" "}
myself&mdash;as I continue to back&nbsp;
<a
href="https://em-dash-appreciation.org/"
target="_blank"
@@ -981,7 +981,7 @@ function AttributionSection() {
>
Em DASH
</a>
. Why should AI get to have all the fun with 'em em dashes?{" "}
. Why should AI get to have all the fun with 'em em dashes?&nbsp;
<span className="font-hand">(get it?)</span>
</p>
</div>
@@ -990,10 +990,10 @@ 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.
<span className="block mt-2 text-sm not-italic text-base-200/70 w-full text-right">
~ Saajan Fernandes,{" "}
~ Saajan Fernandes,&nbsp;
<span className="italic underline decoration-dotted">
The Lunchbox
</span>
+2 -2
View File
@@ -58,7 +58,7 @@ export default function Drawer() {
Personal Archive
</div>
<div className="mt-6 font-sans text-sm text-base-content flex items-center justify-center gap-2 opacity-60 hover:opacity-100 transition-opacity">
Welcome Back{" "}
Welcome Back&nbsp;
<span className="font-semibold text-primary">{user.full_name}</span>
<button
type="button"
@@ -180,7 +180,7 @@ export default function Drawer() {
weight="duotone"
className="text-primary/30 transition-all duration-300 group-hover:text-primary"
/>
Write something{" "}
Write something&nbsp;
<span className="relative inline-flex">
<span className="transition-opacity duration-500 opacity-80 group-hover:opacity-0">
. . . . . .
+8 -8
View File
@@ -149,7 +149,7 @@ export default function Home() {
}}
className="absolute text-4xl md:text-6xl text-center px-10 leading-tight"
>
pen down your unsaid words into{" "}
pen down your unsaid words into&nbsp;
<span className="font-display text-primary font-extralight">
letters
</span>
@@ -171,11 +171,11 @@ export default function Home() {
}}
className="absolute text-4xl md:text-6xl text-center px-10 leading-tight"
>
seal it{" "}
seal it&nbsp;
<span className="text-success font-mono tracking-tighter font-extrabold">
secure
</span>{" "}
and{" "}
</span>&nbsp;
and&nbsp;
<span className="text-info font-mono tracking-tighter italic">
private
</span>
@@ -197,7 +197,7 @@ export default function Home() {
}}
className="absolute text-4xl md:text-6xl text-center px-10 leading-tight"
>
send it to{" "}
send it to&nbsp;
<motion.span
className="font-display text-accent"
style={{
@@ -225,8 +225,8 @@ export default function Home() {
),
}}
>
{" "}
or{" "}
&nbsp;
or&nbsp;
</motion.span>
<span className="font-display text-success">
yourself in the future
@@ -250,7 +250,7 @@ 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>{" "}
and even <span className="font-display text-error">burn it</span>&nbsp;
to release the burden.
</motion.h2>
{/* Outro */}
+1 -1
View File
@@ -132,7 +132,7 @@ 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" />?{" "}
New to <Logo type="inline" />?&nbsp;
<button
type="button"
name="register"
+3 -3
View File
@@ -143,8 +143,8 @@ export default function Register() {
<InfoIcon size={20} weight="duotone" className="mt-0.5 shrink-0" />
<p className="text-sm font-semibold">
Choose a password you won't forget. <br />
Just like life,{" "}
<span className="underline decoration-2">there is no reset</span>{" "}
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.
</p>
</div>
@@ -166,7 +166,7 @@ export default function Register() {
</div>
<div className="divider text-neutral my-0">or</div>
<div className="text-center text-sm font-medium text-neutral">
Been here before?{" "}
Been here before?&nbsp;
<button
type="button"
name="register"
+1 -1
View File
@@ -23,7 +23,7 @@ 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} />{" "}
You're one train away from starting your <Logo scale={0.8} />&nbsp;
journey.
</p>
</div>