The source code for our eny.social landing page, which is mirrored in a different repository as part of the CI setup. eny.social
social-network eny local-first
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor(layout): pull the profiles into the center and add SMIL breathing animation

Sam Sauer 762f5553 ab6b78ee

+31 -28
+23 -5
app/components/Hero.tsx
··· 91 91 92 92 {/* Image (6 cols) — bleeds top + right, blob visible on left + bottom */} 93 93 <div className="relative lg:col-span-6 lg:overflow-visible"> 94 + {/* SVG clip-path with SMIL morph animation */} 95 + <svg className="absolute h-0 w-0" aria-hidden="true"> 96 + <defs> 97 + <clipPath id="hero-blob" clipPathUnits="objectBoundingBox"> 98 + <path d="M0.9502,0.5487 C1.0731,0.7445,0.9515,1.0075,0.7345,0.9473 C0.6670,0.9286,0.4922,0.9118,0.4336,0.9537 C0.2466,1.0875,0.0064,0.9066,0.0696,0.6794 C0.0894,0.6084,0.0786,0.5322,0.0403,0.4712 C-0.0826,0.2754,0.0950,0.0193,0.3119,0.0794 C0.3795,0.0982,0.4523,0.0850,0.5108,0.0431 C0.6977,-0.0907,0.9993,0.1093,0.9361,0.3364 C0.9163,0.4074,0.9119,0.4876,0.9502,0.5487Z"> 99 + <animate 100 + attributeName="d" 101 + dur="12s" 102 + repeatCount="indefinite" 103 + values=" 104 + M0.9502,0.5487 C1.0731,0.7445,0.9515,1.0075,0.7345,0.9473 C0.6670,0.9286,0.4922,0.9118,0.4336,0.9537 C0.2466,1.0875,0.0064,0.9066,0.0696,0.6794 C0.0894,0.6084,0.0786,0.5322,0.0403,0.4712 C-0.0826,0.2754,0.0950,0.0193,0.3119,0.0794 C0.3795,0.0982,0.4523,0.0850,0.5108,0.0431 C0.6977,-0.0907,0.9993,0.1093,0.9361,0.3364 C0.9163,0.4074,0.9119,0.4876,0.9502,0.5487Z; 105 + M0.9402,0.5587 C1.0631,0.7545,0.9615,1.0175,0.7445,0.9373 C0.6570,0.9186,0.5022,0.9218,0.4436,0.9437 C0.2566,1.0775,0.0164,0.9166,0.0596,0.6894 C0.0794,0.5984,0.0886,0.5422,0.0503,0.4612 C-0.0726,0.2854,0.1050,0.0293,0.3219,0.0694 C0.3895,0.0882,0.4423,0.0950,0.5208,0.0531 C0.7077,-0.0807,0.9893,0.1193,0.9261,0.3464 C0.9063,0.4174,0.9219,0.4776,0.9402,0.5587Z; 106 + M0.9602,0.5387 C1.0831,0.7345,0.9415,0.9975,0.7245,0.9573 C0.6770,0.9386,0.4822,0.9018,0.4236,0.9637 C0.2366,1.0975,-0.0036,0.8966,0.0796,0.6694 C0.0994,0.6184,0.0686,0.5222,0.0303,0.4812 C-0.0926,0.2654,0.0850,0.0093,0.3019,0.0894 C0.3695,0.1082,0.4623,0.0750,0.5008,0.0331 C0.6877,-0.1007,1.0093,0.0993,0.9461,0.3264 C0.9263,0.3974,0.9019,0.4976,0.9602,0.5387Z; 107 + M0.9502,0.5487 C1.0731,0.7445,0.9515,1.0075,0.7345,0.9473 C0.6670,0.9286,0.4922,0.9118,0.4336,0.9537 C0.2466,1.0875,0.0064,0.9066,0.0696,0.6794 C0.0894,0.6084,0.0786,0.5322,0.0403,0.4712 C-0.0826,0.2754,0.0950,0.0193,0.3119,0.0794 C0.3795,0.0982,0.4523,0.0850,0.5108,0.0431 C0.6977,-0.0907,0.9993,0.1093,0.9361,0.3364 C0.9163,0.4074,0.9119,0.4876,0.9502,0.5487Z 108 + " 109 + /> 110 + </path> 111 + </clipPath> 112 + </defs> 113 + </svg> 114 + 94 115 {/* Full-size blob-masked photo */} 95 116 <div 96 - className="relative w-[130%] -mr-[30%] lg:w-[170%] aspect-square lg:-mr-[70%] lg:[transform:translate(2%,-20%)] overflow-hidden" 97 - style={{ 98 - borderRadius: "60% 40% 30% 70% / 60% 30% 70% 40%", 99 - animation: "blob-breathe 12s ease-in-out infinite", 100 - }} 117 + className="relative w-[130%] -mr-[30%] lg:w-[170%] aspect-square lg:-mr-[70%] lg:[transform:translate(2%,-20%)]" 118 + style={{ clipPath: "url(#hero-blob)" }} 101 119 > 102 120 {slides.map((slide, index) => ( 103 121 <img
+8 -8
app/components/Waitlist.tsx
··· 4 4 import SectionIntroLabel from "./ui/SectionIntroLabel"; 5 5 6 6 const avatars = [ 7 - { top: "8%", left: "10%", size: 48, delay: 0, img: "https://stinkhorn.us-west.host.bsky.network/xrpc/com.atproto.sync.getBlob?did=did:plc:vmqt4a4pf5jxvtalzjz2zsqk&cid=bafkreifed32u3tuknqoywdqij24vm4jqn35pvkx3q6spmqqoxiv654wtva" }, 8 - { top: "15%", right: "12%", size: 40, delay: 1.2, img: "https://calocybe.us-west.host.bsky.network/xrpc/com.atproto.sync.getBlob?did=did:plc:xrdmnk5t6y5l2n3zq5pok4ua&cid=bafkreibddkvunzwhhtloccrzia6ugllqq7bow435sjclvhbhhkmwqu2d4a" }, 9 - { top: "60%", left: "5%", size: 36, delay: 0.8, img: "https://panus.us-west.host.bsky.network/xrpc/com.atproto.sync.getBlob?did=did:plc:35gbbt2mb36gsl62tduilory&cid=bafkreigfixmlz4ynckkwtzuvxmowbozwlokr2aapgm36ne5sse4tzhxf3u" }, 10 - { top: "70%", right: "8%", size: 44, delay: 2, img: "https://agrocybe.us-west.host.bsky.network/xrpc/com.atproto.sync.getBlob?did=did:plc:ymdvhm76z46uamksi25rffeh&cid=bafkreifp66m5ihkxuthf4vwo6b5ao3evl52fbezsvfkfucxedox3a7joli" }, 11 - { top: "35%", left: "85%", size: 32, delay: 1.5 }, 12 - { top: "80%", left: "20%", size: 38, delay: 0.4 }, 13 - { top: "25%", left: "3%", size: 42, delay: 1.8 }, 14 - { top: "50%", right: "3%", size: 34, delay: 0.6 }, 7 + { top: "8%", left: "20%", size: 48, delay: 0, img: "https://stinkhorn.us-west.host.bsky.network/xrpc/com.atproto.sync.getBlob?did=did:plc:vmqt4a4pf5jxvtalzjz2zsqk&cid=bafkreifed32u3tuknqoywdqij24vm4jqn35pvkx3q6spmqqoxiv654wtva" }, 8 + { top: "15%", right: "20%", size: 40, delay: 1.2, img: "https://calocybe.us-west.host.bsky.network/xrpc/com.atproto.sync.getBlob?did=did:plc:xrdmnk5t6y5l2n3zq5pok4ua&cid=bafkreibddkvunzwhhtloccrzia6ugllqq7bow435sjclvhbhhkmwqu2d4a" }, 9 + { top: "60%", left: "15%", size: 36, delay: 0.8, img: "https://panus.us-west.host.bsky.network/xrpc/com.atproto.sync.getBlob?did=did:plc:35gbbt2mb36gsl62tduilory&cid=bafkreigfixmlz4ynckkwtzuvxmowbozwlokr2aapgm36ne5sse4tzhxf3u" }, 10 + { top: "70%", right: "18%", size: 44, delay: 2, img: "https://agrocybe.us-west.host.bsky.network/xrpc/com.atproto.sync.getBlob?did=did:plc:ymdvhm76z46uamksi25rffeh&cid=bafkreifp66m5ihkxuthf4vwo6b5ao3evl52fbezsvfkfucxedox3a7joli" }, 11 + { top: "35%", left: "75%", size: 32, delay: 1.5 }, 12 + { top: "80%", left: "28%", size: 38, delay: 0.4 }, 13 + { top: "25%", left: "12%", size: 42, delay: 1.8 }, 14 + { top: "50%", right: "14%", size: 34, delay: 0.6 }, 15 15 ]; 16 16 17 17 const colors = [
-15
app/globals.css
··· 251 251 } 252 252 } 253 253 254 - /* Organic blob breathing for hero image */ 255 - @keyframes blob-breathe { 256 - 0%, 100% { 257 - border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%; 258 - } 259 - 25% { 260 - border-radius: 30% 60% 70% 40% / 50% 60% 30% 60%; 261 - } 262 - 50% { 263 - border-radius: 50% 60% 30% 60% / 30% 40% 70% 50%; 264 - } 265 - 75% { 266 - border-radius: 60% 30% 60% 40% / 70% 50% 40% 60%; 267 - } 268 - } 269 254 270 255 /* Horizontal scroll for value cards */ 271 256 .hide-scrollbar {