From 6092b3f45f1c38579ec5cf4fe9431ca47de4759a Mon Sep 17 00:00:00 2001 From: me Date: Fri, 8 May 2026 10:49:55 +0530 Subject: [PATCH] refactor: migrate asset directory structure --- frontend/src/App.tsx | 2 +- frontend/{public => src/assets}/logo.svg | 0 frontend/src/assets/{ => textures}/noise.gif | Bin .../textures/random-grey-variations.png | Bin 0 -> 5814 bytes frontend/src/components/Logo.tsx | 105 +- frontend/src/components/SplashScreen.tsx | 2 +- frontend/src/components/ui/Modal.tsx | 60 +- frontend/src/pages/About.tsx | 1880 ++++++++--------- 8 files changed, 1025 insertions(+), 1024 deletions(-) rename frontend/{public => src/assets}/logo.svg (100%) rename frontend/src/assets/{ => textures}/noise.gif (100%) create mode 100644 frontend/src/assets/textures/random-grey-variations.png diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index bf5cc26..e78401f 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -31,7 +31,7 @@ export default function App() { return ( -
+
}> 0DwwITOEqmgSR&sA)a&N?Q8L>#|UDo zK|o3epkx9tumOmu0Sx>AAUl8@NI*>oAiNJCX9JMX;uHUW@!&(LRYQ2(MuALtyr>$& zzV0({Z!4EO=? zd4yEAAjgN;ZlB*qX#pexw{zakgMTSJr~m*SJcpZrRPaYCzknK;@N$A~g_jXTK|xCl zpa1|kZwUk-#tS0=PqY-Acpq;982?Xr0|3A$<8$!7CiZVWKH{pQu3{QQ5cW1DphKFn zpO_l_v2UGsnlh-|m=<#exfBaHeLzuRq}Cu)Q; z(bFgUgh*VoM)pnbcVwxeTIGrxJf+CI)MB#3Q&3NNE7(|jikr8n#+m4LyEF#R@<>d7@_#`XtRyh|8ARn4m@3l zFNEmcc!0ciJcPN1JZ!#z&V zkZXM1*EGwyHN1^?QnshrOllq@s2$7!f- zQh@5}!e(_f5dOQtKd#+|rgjgyASdQx|8pi$Sl*3%hOXf|!g$CxM5M*@5qP7&;H8Q?45ZHA=`7Q+f~SYPmmgQzK+A@aHPa*i0UYspL#<9HsftG`vS9{1+bG zS>~{Am(Z(a)VT}RDU^uC-N@OEIzkjJ^9>tjs6SP;XSp=}8cOO9ma)!|Zq;OKqF{SR zvj-bW{aI27Wptsbbu&ZNy(-%r*myVer&$S=BrM_+GW?KU9 zJTBIFQ0UphS5t}(p*L_J#d=1!%*Fxh|GomBZRy&-dC8X>&+=*E%-YFm94JYO_|Z!D z;AW3_hdD0sFu(Ls?S0>lZ0cWgi@rQ8yLT zzi@FX9z_f@js`VAC0xDDOJ7vatr8sc&P0!E#)P|vexNWVx4($I;rSi%2?h4O6wVe( zC)_nb4@~KOn-vEk1NL2yM@IL5c;=p6M%JJ>#MKuToh~^1rluMLc$Dyt0D9w>-tx=vr_fRh`bouFj9_M?@ zc^|;bZ@dBuiAtlN>#xrv#lal2nW|zqM>=(mr~|FS@5d+QqiI%_3N`G#Lt9feEB`fZ z_`R;+fF1f*#bF-T+LREqIaKg=ouBn!I3*+;!viDWN1KaRuQjU#T~sr<{1@M>qt*+B zzxs|{5L;b2$w9yb8_a+wk}v9CuNR7y`G+u!L8|LnM|}^%GF(-Ao|KmKugqf)VYJ2D zQXV8n6`V+Bm|?DijzbWCsQ15)sA!DI&{NbSNT@xOO%d0)+40DpT~flCfuky}QlI1N zHDAWhfd*Lj0uw7|fRYOJ^kBD0Do^Gb82pY?F*;G>idMe!^rsbrXUuDgZ}CwiieR~s zkfXwp!<5{taw9I$o5g3?H~k6zmLfDT<*b6d-l>);{Rjqm0wB_%sHYKBB^=U)?!3NV zwI&;QhS5`*39C=n2teJb1*rqWzhkxgSaTSQ1;TC5W(`{7Q#E*KovmdqQ7Jxl267~6 zK!w3y&y4b^njsHCgV>*goS`e2z5)oNX@uvXlIPc*=#gW|lJD+hU;ncXtO2t}(n(zU ze7i(Nwz%`UJ{Ea;QN-pb{}Tkl%YHCP<}S5I)Oa z*FWjg{ly5~KK1v}@pkbCx!u4;ae?(QM6Le+n%9^|TsHV;A}<6OQFeZ!mtY&iqhywc5e`k89Kx<#$kR;)kC1UoJZdHkVeG@mn)H z`WQnN_TxB1d#)(2*I6{KVM7+<)i>*_S(5Wm+*MuTnF4!43lo~B-MgGD#!D5=^SDPjPL==)sHP6j5t9izY34);}UyrBp2rwF()!3 zNImkoU-~NN;o@<3iZ?>i^f8!n&N}W8T^T?igKB2a6O!5g4!g286@|`a*Oy~0eC!TvFRFduC6vRn!9r zBZ6!r8{)WkFO5tDmYfDHZPgh!!mMo$L~InFt+7g~*rX|z#ui&*u*o#tTD@!&`!65j z<|s&#L_r-(45OtU+Yg4elQaVIklKAIN z1)9;R;&fHD<$Jitxqe-_C7KeNt9^aGtXWXD{OFE)g97UvcHLmn#;7LOE>iB4Ba|g4 zfu#pKYhrm^?BIQ57Ufvk%D}OG%_xDK=vV+fmx@<@uZblP-t@`2;-3Rd&Id-W9=u6= zdF6Lw%9%GHkcgqG>ia!u@U6YJtJJ~KiOFy~K5H4%7b1|% zHybOb%MIIeewtWlF}+f?QS{6jgM=4NG4^_$08En`^f`1^dFiTLiKh{wANR@VDmJ-` zK~pbKYBiE|Cl_!;-_ajK>797`Y_(^I&-wQdFRvz9ad)`2edZXTU(`Y z9o5J>I<@>~iivK2if9N=Ls$?0bC59e#qt)xL~M$Z9lACy!lrvR;#u>{_v(gPHSR$4SS0nExaGwDB;9Yp@W{G* zn+1w4J$skN%RT(u6+$Mnfj9#T%I!o8!SEng#Gjp*=H(SE)+Z}JNknQUc3z_G&9`&V z!=Mny=)aUBgE8}K5s-)@D4el80nHUBjUj7^XizJn6v?I8-Zb~WJ9Yrc4N7Di<5kK1 zic|_2)1`~<2TwesBiayd_A=w}qy9$l-JIcLgM#favJ=8*Q9b+Vz^|E-^(MvjyPl5=*Q$N_a&O&q)Nt*+12|w&dr`VN(nPWF<9LL zMN6`X|0_C4*G{3aUL#cGu)AR^efMU^9-=7Ry%g>9{%KX)#%UU+r?U#syniivhM>mG!ZqI&JBaY}|+39DfSnf7U|g57dFXhK7PO_xE>A zQSjx@`-Mhc11F)v5_&)U?uK6-ajp5#|Ua>RbnoR5VAa=*>;q z#ZaeJPNKSz)#ZvB&hK6B9|=ah|0t`6dsCT?JFV_-O^ZOjD)HuYCXWWE=55JZs(u{4 zwl`&3NESHzi>XdaKGb6%hl zrrG21->2=6+3g!{*lXENkWtqGH1MyF#`VGid)Qq8hi(x2i}w2CinxQZr~@u4?fH%f zZG(n7yQ4iQ!*&XI){BO}Z`+6QolA?uFM$-}KckanqKz8-*-?L5t`L`?viK zXF=8&OV zQQ-+Jc-omnCMqhW2?g78r_soVF84WmB|Ic*-AQ5pkY%5Ds{J_&(pcw^`m=bkjY>t- zF#MOUBr^1@f}?ke23P^CF%xO$&*4nm-uL^ZJNcW^UTQ+scTGC|s2F$kB4R5CZ0W3G z)hVj2^ok`aaiDIec=Ts<2|eR?fry3Ay7cLv;zEl13`PQ8pXL0}^>nvfIdN9LpM>ZY z+f3j)!Y;OH0!v0_*Ir}ACj_4V+dYu!y=d0g{za`NdnGMpC$3}4s;0`A!e%zRy16tuN5S|zoG<_-!sEF~eigc|j4;@q6!_f@j z>iP$|UsWD*9Qra}EK>hmVWw`Vw>zS`yH<%d$0f@m)-+r_Nq_Y&9LzOh{>z)GfW`6m z6@J|sWO4j2jU8sXgWR_qa;_5;saRb>hV9dgFC=QG(ip11YWe|B3YUes4JEyD%xRQn zsWZDt$DV73oO6M<#GvaCW%8^>ok2Nhf^>nx9?RgICu!fhxPZYQDO1`9E9OH|Bc3u_ zA4169rcKIXLlr4li9T{wnti=monbSHoIXIr?%@cz6sUiWS?G8Ijr1CrwcfRivK(gT zK^_))^TIjuHI6$Hd^oNr1KyT!mIh8Nq_|RZv~U10XyyB>|_-DVwOj=?ev!n7xUEwBEKk z?Q^-mNFcD(k2SmQ`N>ENU!_YO9sRk^FwJn&lQ$4I2l_-&R=K-rGa=K|cX*kz&U~e% zj#U_F-V8rwS78a>g#OML9jegbVb|h|(_9~F&(qA!c0x$i7w*_G?@2#hU!RMbiyEXp ztJ2=(3U>o?l4B~z?60qGGzlnOB4&C{Ct3=f;toGAfiydvC?2Smr&kR3jj46^=%pT} zaIllNNlomRE>JFG=^;Wa8s8S#f2gtwJ}#-Bu}LK<4u3bZL%Es0@8u{(C@}x#=Dvp+ zHCa=|!VPN&Ra$K5rFkvnokn$K(Z-SirnziveMz(-)V3^ecs3&V-=kx>Oa-IfmQ$2V|&Jy(S_Xy_x>C=Qyll`S_M^1>J-)GXm08G$EYGG zeYt2}yt+zYT$V7~coeaE4uT8h=#X5-ZfxzaY)i~1&XTEkPW2Pt&(b8>?&FVE*qNG3 z`I_OXv!Zv<=gzH`@jSg*2n2V__z3OghsjY8CdlJ|R1jI_UE*>h$JMn9gGb zfh2B5b);=<>+7~tc;U!wMLd{ydp`OLVnxF>a)6ZLNI$Y`@x;px(Gicr>^3O-kC!(m z+|?De&D?*VU?&69b)ol}aeVbyH&%Q!7?Tju2loz*8IhnFvT|XUqlp|UaC1DW;$iBz zzC5W>Kui~blJ1*$S@{s%%N-tSK`VRW$Gs0s-=BZGrz;$>Z^a z4qXnI`*Y`VnU9a@QQTfoSC&vi*mseBEY#f&^`oXP$R@Db&j@BN0fYzxkb_vth3y<-3}sk8w4fa+>C>B)#J2HZk+u!Cc!*4hNB6 zEP7Kmgdo{T{G2a)vO>Dlk9LjaL)AyAg93V*v)ASW`)*n9Xg6dFj^lRu-v>{h&$Uw!e6h=mjs^;pkg}Abyv-HS#`1?_wSa|nu>O1msEAwol5u*9K`}2>xi&kzA>?mG(=&jcI zwrmM-%B0arrPoP--m9uaeyBtWp!dKZ?@Xb>REefgQGH~mS)-gK_%w4FQsPsRN@VTV zCA5f#k&*Yykd)#jU1M*$X;2Y9eg>UF8BL)IIn+9-G&1XCa* zAI51Ep^>+8pP8w*pSOI`66fg|zGMMpScB|X3$d_0NcIp!BLvV0!l}HnC25UL9KNh* zN&U2q;I@ZT-|0@~U$cxoODLL=;niKalNKAndO%AI%7d%r=;cAeo7)-OZ+9@b~? zG<6EqXCn;oY;zr - pi. ku - .  - - ); - } + if (type === "inline") { + return ( + + pi. ku + .  + + ); + } - if (type === "mono") { - return ( - - pi. ku. - - ); - } + if (type === "mono") { + return ( + + pi. ku. + + ); + } - if (type === "logo") { - return ( - Pi. Ku. logo - ); - } + if (type === "logo") { + return ( + Pi. Ku. logo + ); + } - return ( -
- Pi - -  Ku - -
- ); + return ( +
+ Pi + +  Ku + +
+ ); } diff --git a/frontend/src/components/SplashScreen.tsx b/frontend/src/components/SplashScreen.tsx index 0874d18..2e9b67c 100644 --- a/frontend/src/components/SplashScreen.tsx +++ b/frontend/src/components/SplashScreen.tsx @@ -5,7 +5,7 @@ export default function SplashScreen() { return (
diff --git a/frontend/src/components/ui/Modal.tsx b/frontend/src/components/ui/Modal.tsx index 7d02a33..47b6771 100644 --- a/frontend/src/components/ui/Modal.tsx +++ b/frontend/src/components/ui/Modal.tsx @@ -2,39 +2,39 @@ import { XCircleIcon } from "@phosphor-icons/react"; import type { ReactNode } from "react"; interface ModalProps { - isOpen: boolean; - onClose?: () => void; - children: ReactNode; - "data-testid"?: string; + isOpen: boolean; + onClose?: () => void; + children: ReactNode; + "data-testid"?: string; } export function Modal({ - isOpen, - onClose, - children, - "data-testid": testId, + isOpen, + onClose, + children, + "data-testid": testId, }: ModalProps) { - if (!isOpen) return null; + if (!isOpen) return null; - return ( -
-
- {onClose && ( - - )} - {children} -
-
- ); + return ( +
+
+ {onClose && ( + + )} + {children} +
+
+ ); } diff --git a/frontend/src/pages/About.tsx b/frontend/src/pages/About.tsx index 3449f3f..684e7ac 100644 --- a/frontend/src/pages/About.tsx +++ b/frontend/src/pages/About.tsx @@ -1,25 +1,25 @@ import { - ArrowArcLeftIcon, - ArrowBendDownLeftIcon, - ArrowBendDownRightIcon, - ArrowRightIcon, - CaretUpIcon, - DetectiveIcon, - FlowerTulipIcon, - GhostIcon, - GithubLogoIcon, - InfoIcon, - LockKeyOpenIcon, - LockLaminatedIcon, - PasswordIcon, - PeaceIcon, - PersonArmsSpreadIcon, - PersonIcon, - QuotesIcon, - ScrollIcon, - SmileyIcon, - SparkleIcon, - VaultIcon, + ArrowArcLeftIcon, + ArrowBendDownLeftIcon, + ArrowBendDownRightIcon, + ArrowRightIcon, + CaretUpIcon, + DetectiveIcon, + FlowerTulipIcon, + GhostIcon, + GithubLogoIcon, + InfoIcon, + LockKeyOpenIcon, + LockLaminatedIcon, + PasswordIcon, + PeaceIcon, + PersonArmsSpreadIcon, + PersonIcon, + QuotesIcon, + ScrollIcon, + SmileyIcon, + SparkleIcon, + VaultIcon, } from "@phosphor-icons/react"; import { ReactLenis } from "lenis/react"; import { AnimatePresence, motion, useScroll, useTransform } from "motion/react"; @@ -35,982 +35,982 @@ 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%"]); + const ref = useRef(null); + const { scrollYProgress } = useScroll({ target: ref }); + const x = useTransform(scrollYProgress, [0, 1], ["0%", "-50%"]); - return ( -
-
- - {children} - -
-
- ); + return ( +
+
+ + {children} + +
+
+ ); } export default function About() { - useEffect(() => { - window.scrollTo(0, 0); - }, []); - return ( - -
- + useEffect(() => { + window.scrollTo(0, 0); + }, []); + return ( + +
+ - - - - + + + + - + - - - - + + + + - -
-
- ); + +
+
+ ); } function PrivacySection() { - return ( -
-

- The   Promise - - privacy - - -

-
-

- Your letters.{" "} - Nobody else's. -

-

- When you write or upload anything{" "} - (yes, even images) here, it gets - encrypted in your browser before anything leaves your device. What - reaches the server is something unreadable—and the server has no - way to change that, because the key never left you. -

-
-
-
-
-

- you see -

- +

+ The   Promise + + privacy + + -

- Your Password -

-

-
- B@z1ng4A +

+
+

+ Your letters.{" "} + Nobody else's.

-
-
- -
-
- -

- Your Letter -

-
-

Hello friend,

-

I've never told anyone this...

-

- 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. -

-
-
-
-
-
-
-
-

- server see -

- -

- Your Password -

-

- 9e54d05f88bdd67a675b03bf1cd0a1647e2109b5aa18185ff6a9ba4c6959a19d +

+ When you write or upload anything{" "} + (yes, even images) here, it gets + encrypted in your browser before anything leaves your device. What + reaches the server is something unreadable—and the server has no + way to change that, because the key never left you.

-
-
- -
-
- -

- Your Letter -

-
-

- 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== -

-
-
+
+
+
+
+

+ you see +

+ +

+ Your Password +

+

+
+ B@z1ng4A +

+
+
+ +
+
+ +

+ Your Letter +

+
+

Hello friend,

+

I've never told anyone this...

+

+ 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. +

+
+
+
+
+
+
+
+

+ server see +

+ +

+ Your Password +

+

+ 9e54d05f88bdd67a675b03bf1cd0a1647e2109b5aa18185ff6a9ba4c6959a19d +

+
+
+ +
+
+ +

+ Your Letter +

+
+

+ 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== +

+
+
+
+
+
+
-
-
-
-
-
- ); +
+ ); } function SpecsSection() { - const [isModalOpen, setIsModalOpen] = useState(false); + const [isModalOpen, setIsModalOpen] = useState(false); - return ( -
-

- S'more  - - Specs -

-
-

- uses{" "} - Zero Knowledge{" "} - - E - - nd— - - 2 - - — - - E - - nd - - -  E - - ncryption - - - {" "} - for your letters, with{" "} - - Envelope Encryption - {" "} - for the keys. -

-
- 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 very thing - that opens that 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 and ain't no way they crackin' it.{" "} - - (unless this happens) - -
-
- -
-
+ return ( +
+

+ S'more  + + Specs +

+
+

+ uses{" "} + Zero Knowledge{" "} + + E + + nd— + + 2 + + — + + E + + nd + + +  E + + ncryption + + + {" "} + for your letters, with{" "} + + Envelope Encryption + {" "} + for the keys. +

+
+ 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 very thing + that opens that 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 and ain't no way they crackin' it.{" "} + + (unless this happens) + +
+
+ +
+
- + - setIsModalOpen(false)}> -
- pi ku e2e diagram -
-
+ setIsModalOpen(false)}> +
+ pi ku e2e diagram +
+
-

- Of course, this level of{" "} - privacy comes with a - catch. No password reset{" "} - for you. -

-

- Your original password is never stored - on the server. So, if it's forgotten, the letters stay sealed - foreeeeveer. -

-
-
- ); +

+ Of course, this level of{" "} + privacy comes with a + catch. No password reset{" "} + for you. +

+

+ Your original password is never stored + on the server. So, if it's forgotten, the letters stay sealed + foreeeeveer. +

+
+
+ ); } function OSSSection() { - return ( -
-

- - is{" "} - -  private - - only for -  your letters {" "} - - - - {" "} - open source ! -

-
-

- is - ...uhhh... pretty - secure. Every claim - about privacy and encryption is publicly available in the code so you - don't have to take my word at it. -

-

- You can also{" "} - Self-host{" "} - in just 4 steps. -

-
-
-            git clone https://git.ramvignesh.dev/me/pi-ku.git
-          
-
-            cd pi-ku
-          
-
-            ./scripts/setup.sh
-          
-
-            ./scripts/start.sh
-          
-
- -
- - View Source - - . -

- Found something to report or request?{" "} - +

- Please say so. - -

-

+ + is{" "} + +  private + + only for +  your letters {" "} + + + + {" "} + open source ! + +
+

+ is + ...uhhh... pretty + secure. Every claim + about privacy and encryption is publicly available in the code so you + don't have to take my word at it. +

+

+ You can also{" "} + Self-host{" "} + in just 4 steps. +

+
+
+                        git clone https://git.ramvignesh.dev/me/pi-ku.git
+                    
+
+                        cd pi-ku
+                    
+
+                        ./scripts/setup.sh
+                    
+
+                        ./scripts/start.sh
+                    
+
-
+
+ + View Source + + . +

+ Found something to report or request?{" "} + + Please say so. + +

+
-

- Built on the shoulders of open source. -

+
-

- wouldn't exist without the work of people who - chose to build in the open. -

-

a big thanks to

-

- - Web Crypto API - - : Browser-native cryptography that runs entirely on your device. The - backbone of everything secure—your letters, keys—here. -

+

+ Built on the shoulders of open source. +

-

- - DaisyUI - {" "} - ·{" "} - - Fabric.js - {" "} - ·{" "} - - Phosphor Icons - - : The brilliant work by others that let me focus on the core - experience instead of re-inventing the wheel. -

+

+ wouldn't exist without the work of people who + chose to build in the open. +

+

a big thanks to

+

+ + Web Crypto API + + : Browser-native cryptography that runs entirely on your device. The + backbone of everything secure—your letters, keys—here. +

-

- Open source is what made possible. It always - feels right to give it back the same way. -

-
-
- ); +

+ + DaisyUI + {" "} + ·{" "} + + Fabric.js + {" "} + ·{" "} + + Phosphor Icons + + : The brilliant work by others that let me focus on the core + experience instead of re-inventing the wheel. +

+ +

+ Open source is what made possible. It always + feels right to give it back the same way. +

+
+ + ); } function StorySection() { - return ( -
-

- The Story -

-
-
- -
-
- - - -
- குறிப்பு - - note. remark. - -
-
- {/* Dict Card */} -
-
-
-
-
pin·ku·rip·pu
-
-
- /noun/ tamil -
+ The Story + +
+
+ +
+
+ + + +
+ குறிப்பு + + note. remark. + +
+
+ {/* Dict Card */} +
+
+
+
+
pin·ku·rip·pu
+
+
+ /noun/ tamil +
-
    -
  1. - postscript; a note written after the letter is signed. -
    -
    - "the most honest thing was always in the{" "} - பி. கு." -
    -
  2. -
  3. the thing you almost didn't say.
  4. -
+
    +
  1. + postscript; a note written after the letter is signed. +
    +
    + "the most honest thing was always in the{" "} + பி. கு." +
    +
  2. +
  3. the thing you almost didn't say.
  4. +
+
+
+
+
+
+
+
+
+
+
+
+
+

+ is an abbreviated transliteration of the + தமிழ் + (Tamil) word + for{" "} + {" "} + —the thing you add after you've already signed your name, what + you write when you thought you were finished, but weren't. +

+

+ + 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{" "} + {" "} + stay{" "} + + unsaid + + — + a quiet weight difficult to bear. +

+

+ And that's okay... +

+

+ + + was built for putting that weight down. + +
A space for the letters you meant to send, the afterthoughts + that deserved more than silence. +

+
-
-
-
-
-
-
-
-
-
-
-

- is an abbreviated transliteration of the - தமிழ் - (Tamil) word - for{" "} - {" "} - —the thing you add after you've already signed your name, what - you write when you thought you were finished, but weren't. -

-

- - 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{" "} - {" "} - stay{" "} - - unsaid - - — - a quiet weight difficult to bear. -

-

- And that's okay... -

-

- - - was built for putting that weight down. - -
A space for the letters you meant to send, the afterthoughts - that deserved more than silence. -

-
-
-
- ); + ); } function ForWhoSection() { - return ( -
-
-

- Who is
this for? -

+ return ( +
+
+

+ Who is
this for? +

-
-

- wasn't built for one kind of person, but a - particular kind of feeling— - - {" "} - the one that lingers very quietly - {" "} - —fragile, yet never breaks. -

+
+

+ wasn't built for one kind of person, but a + particular kind of feeling— + + {" "} + the one that lingers very quietly + {" "} + —fragile, yet never breaks. +

-
- - See if any of these feel too familiar to you - -
- +
+ + See if any of these feel too familiar to you + +
+ +
+
+
-
-
-
-
-
- ); +
+
+ ); } function ArchetypesSection() { - return ( -
-

- The Archetypes -

-

of writing

-
-
-
- - {" "} - To someone you can't reach anymore. - -
-

- 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. -

-
-
- - 01 - -
+ return ( +
+

+ The Archetypes +

+

of writing

+
+
+
+ + {" "} + To someone you can't reach anymore. + +
+

+ 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. +

+
+
+ + 01 + +
-
-
- - {" "} - To someone who's still here. - -
-

- 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. -

+
+
+ + {" "} + To someone who's still here. + +
+

+ 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. +

+
+
+ + 02 + +
+
+
+ +
+ {" "} + +
+ To yourself, further along. +
+
+

+ 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. +

+
+
+ + 03 + +
+
+
+ + {" "} + For liberation. + +
+

+ 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. +

+
+
+ + 04 + +
+
-
- - 02 -
-
-
- -
- {" "} - -
- To yourself, further along. -
-
-

- 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. -

-
-
- - 03 - -
-
-
- - {" "} - For liberation. - -
-

- 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. -

-
-
- - 04 - -
- -
-
- ); + ); } function AttributionSection() { - const [hover, setHover] = useState<{ - visible: boolean; - x: number; - y: number; - }>({ visible: false, x: 0, y: 0 }); + const [hover, setHover] = useState<{ + visible: boolean; + x: number; + y: number; + }>({ visible: false, x: 0, y: 0 }); - const navigate = useNavigate(); + const navigate = useNavigate(); - return ( -
- {/* Saajan hover image */} - - {hover.visible && ( - - )} - + return ( +
+ {/* Saajan hover image */} + + {hover.visible && ( + + )} + -

- Honest Speak -

-
-
- Hi. -

Thank you so much for making it this far. Really.

-

- took a while to exist. -
- This started as a{" "} - - CS50W - {" "} - capstone—one I kept postponing until I ran out of excuses. - When I sat down to build it, it felt heavier than a typical - assignment—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 - perfect as I could get it. Something to be remembered for—a - Swan Song if you will. -

-

So, I gave it all I've got.

-

- Of course, frustrations, id-exisi crises, crept in from time to - time. But helped me re-kindle the love for - the odd hours spent obsessing over the tiniest UX decisions and - endlessly polishing the UI{" "} - - (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) - - . I know I've shared the nuts and bolts of {" "} - here—the core philosophies, how it all works—but the - heart of it is really something you have to find by exploring it - yourself. -

-

- The "why" behind all of this didn't just appear out of nowhere. For - a while, 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 - {" "} - —brought to life with such subtle brilliance by{" "} - - Irrfan Khan - {" "} - - —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{" "} - - "it is what it is" - - , but the simple act of writing—of letting the unsaid - out—offered him a brief, yet necessary ease. I think about - that a lot. -

-

- There's a lot that goes{" "} - - unsaid - {" "} - 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 digitally, yet - somehow the things that actually matter most end up staying - inside—a trapped one at that. -
- Maybe writing can/will help. Maybe putting words somewhere - deliberate makes them feel less like a weight you're carrying alone. -

-

Or maybe it won't—but it's worth a try.

-

- is for that try. I hope it helps. Really. -

-

- —Ram -

-

- P.S. And just so we're clear—I wrote every word of this - myself—as I continue to back{" "} - - Em DASH - - . Why should AI get to have all the fun with 'em em dashes?{" "} - (get it?) -

+ Honest Speak + +
+
+ Hi. +

Thank you so much for making it this far. Really.

+

+ took a while to exist. +
+ This started as a{" "} + + CS50W + {" "} + capstone—one I kept postponing until I ran out of excuses. + When I sat down to build it, it felt heavier than a typical + assignment—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 + perfect as I could get it. Something to be remembered for—a + Swan Song if you will. +

+

So, I gave it all I've got.

+

+ Of course, frustrations, id-exisi crises, crept in from time to + time. But helped me re-kindle the love for + the odd hours spent obsessing over the tiniest UX decisions and + endlessly polishing the UI{" "} + + (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) + + . I know I've shared the nuts and bolts of {" "} + here—the core philosophies, how it all works—but the + heart of it is really something you have to find by exploring it + yourself. +

+

+ The "why" behind all of this didn't just appear out of nowhere. For + a while, 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 + {" "} + —brought to life with such subtle brilliance by{" "} + + Irrfan Khan + {" "} + + —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{" "} + + "it is what it is" + + , but the simple act of writing—of letting the unsaid + out—offered him a brief, yet necessary ease. I think about + that a lot. +

+

+ There's a lot that goes{" "} + + unsaid + {" "} + 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 digitally, yet + somehow the things that actually matter most end up staying + inside—a trapped one at that. +
+ Maybe writing can/will help. Maybe putting words somewhere + deliberate makes them feel less like a weight you're carrying alone. +

+

Or maybe it won't—but it's worth a try.

+

+ is for that try. I hope it helps. Really. +

+

+ —Ram +

+

+ P.S. And just so we're clear—I wrote every word of this + myself—as I continue to back{" "} + + Em DASH + + . Why should AI get to have all the fun with 'em em dashes?{" "} + (get it?) +

+
+
+ {" "} + I think we forget things if there is nobody to tell them. + + ~ Saajan Fernandes,{" "} + + The Lunchbox + + +
+
+
+ +
-
- {" "} - I think we forget things if there is nobody to tell them. - - ~ Saajan Fernandes,{" "} - - The Lunchbox - - -
-
-
- -
-
- ); + ); }