mirror of
https://github.com/multipleof4/4ev.link.git
synced 2026-01-13 15:57:53 +00:00
Feat: New display font, heart, feature bubbles
This commit is contained in:
36
index.html
36
index.html
@@ -1,9 +1,11 @@
|
|||||||
<!doctype html><html lang="en"><head>
|
<!doctype html><html lang="en"><head>
|
||||||
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
||||||
<title>4ev.link — tiny links that last</title><meta name="description" content="Free: random short link • Paid: custom URLs (coming soon).">
|
<title>4ev.link — tiny links that last</title><meta name="description" content="Privacy-first URL shortener. Free: random slug • Paid: custom URLs (coming soon). Links are forever (or until we go bankrupt).">
|
||||||
<link rel="icon" href="data:,"><style>[x-cloak]{display:none!important}</style>
|
<link rel="icon" href="data:,"><style>[x-cloak]{display:none!important}</style>
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@600;700&display=swap" rel="stylesheet">
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
<script>tailwind.config={theme:{extend:{fontFamily:{sans:['Inter','ui-sans-serif','system-ui','-apple-system','Segoe UI','Roboto','Arial']}}}}</script>
|
<script>tailwind.config={theme:{extend:{fontFamily:{sans:['Inter','ui-sans-serif','system-ui','-apple-system','Segoe UI','Roboto','Arial'],display:['Space Grotesk','Inter','system-ui']}}}}</script>
|
||||||
<script src="//unpkg.com/alpinejs" defer></script>
|
<script src="//unpkg.com/alpinejs" defer></script>
|
||||||
<script src="https://unpkg.com/lucide@latest" defer></script>
|
<script src="https://unpkg.com/lucide@latest" defer></script>
|
||||||
</head><body class="bg-white text-gray-900 antialiased">
|
</head><body class="bg-white text-gray-900 antialiased">
|
||||||
@@ -19,11 +21,31 @@
|
|||||||
|
|
||||||
<main class="max-w-3xl mx-auto px-4 pt-16 pb-24" x-data="{t:'',o:'',e:'',l:!1,async s(){this.e='',this.o='';let u=this.t.trim();try{new URL(u)}catch(_){this.e='Enter a valid URL';return}this.l=!0;try{let r=await fetch('/',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({url:u})});if(!r.ok)throw 0;let j=await r.json();this.o=j.shortUrl;this.$nextTick(()=>lucide?.createIcons())}catch(_){this.e='Something went wrong. Try again.'}finally{this.l=!1}},async c(){try{await navigator.clipboard.writeText(this.o);let b=this.$refs.copy;b?.classList.add('text-green-600');setTimeout(()=>b?.classList.remove('text-green-600'),900)}catch(_){}}">
|
<main class="max-w-3xl mx-auto px-4 pt-16 pb-24" x-data="{t:'',o:'',e:'',l:!1,async s(){this.e='',this.o='';let u=this.t.trim();try{new URL(u)}catch(_){this.e='Enter a valid URL';return}this.l=!0;try{let r=await fetch('/',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({url:u})});if(!r.ok)throw 0;let j=await r.json();this.o=j.shortUrl;this.$nextTick(()=>lucide?.createIcons())}catch(_){this.e='Something went wrong. Try again.'}finally{this.l=!1}},async c(){try{await navigator.clipboard.writeText(this.o);let b=this.$refs.copy;b?.classList.add('text-green-600');setTimeout(()=>b?.classList.remove('text-green-600'),900)}catch(_){}}">
|
||||||
<section class="text-center">
|
<section class="text-center">
|
||||||
<h1 class="text-3xl sm:text-4xl font-semibold tracking-tight">Get ur 4ev.link <span class="text-red-500">❤</span></h1>
|
<h1 class="font-display text-3xl sm:text-4xl font-semibold tracking-tight inline-flex items-center gap-2 justify-center">
|
||||||
<p class="mt-3 text-gray-600 text-sm">
|
<span>Get ur 4ev.link</span>
|
||||||
Free: random short link • Paid: custom URLs
|
<span aria-hidden="true" class="inline-block align-[-2px]">
|
||||||
|
<svg viewBox="0 0 24 24" class="w-6 h-6 text-red-500" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M12.1 21.35c-.1.06-.22.06-.32 0C7.14 18.23 2 14.52 2 9.86 2 7.2 4.15 5 6.86 5c1.6 0 3.11.76 4.14 1.98C12.99 5.76 14.5 5 16.1 5 18.81 5 21 7.2 21 9.86c0 4.66-5.14 8.37-8.9 11.49z"/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</h1>
|
||||||
|
<p class="mt-3 text-gray-600 text-sm">Free: random short link • Paid: custom URLs
|
||||||
<span class="ml-1 inline-flex items-center gap-1 rounded border border-gray-200 px-1.5 py-0.5 text-[11px] text-gray-700">coming soon</span>
|
<span class="ml-1 inline-flex items-center gap-1 rounded border border-gray-200 px-1.5 py-0.5 text-[11px] text-gray-700">coming soon</span>
|
||||||
</p>
|
</p>
|
||||||
|
<div class="mt-4 flex flex-wrap items-center justify-center gap-2">
|
||||||
|
<span class="inline-flex items-center gap-1 rounded-full border border-gray-200 bg-white px-3 py-1 text-xs text-gray-700 shadow-sm">
|
||||||
|
<i data-lucide="shield" class="w-3.5 h-3.5"></i><span>Privacy-first</span>
|
||||||
|
</span>
|
||||||
|
<span class="inline-flex items-center gap-1 rounded-full border border-gray-200 bg-white px-3 py-1 text-xs text-gray-700 shadow-sm">
|
||||||
|
<i data-lucide="ban" class="w-3.5 h-3.5"></i><span>No pixel tracking</span>
|
||||||
|
</span>
|
||||||
|
<span class="inline-flex items-center gap-1 rounded-full border border-gray-200 bg-white px-3 py-1 text-xs text-gray-700 shadow-sm">
|
||||||
|
<i data-lucide="link-2" class="w-3.5 h-3.5"></i><span>Simple URL shortener</span>
|
||||||
|
</span>
|
||||||
|
<span class="inline-flex items-center gap-1 rounded-full border border-gray-200 bg-white px-3 py-1 text-xs text-gray-700 shadow-sm">
|
||||||
|
<i data-lucide="infinity" class="w-3.5 h-3.5"></i><span>Links are forever (or until we go bankrupt)</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="mt-8">
|
<section class="mt-8">
|
||||||
@@ -31,8 +53,8 @@
|
|||||||
<input x-model="t" type="url" inputmode="url" placeholder="https://example.com/very/long/link"
|
<input x-model="t" type="url" inputmode="url" placeholder="https://example.com/very/long/link"
|
||||||
class="w-full rounded-md border border-gray-300 bg-white px-3 py-3 text-[15px] placeholder:text-gray-400 focus:outline-none focus:ring-2 focus:ring-gray-900/10 focus:border-gray-400" required>
|
class="w-full rounded-md border border-gray-300 bg-white px-3 py-3 text-[15px] placeholder:text-gray-400 focus:outline-none focus:ring-2 focus:ring-gray-900/10 focus:border-gray-400" required>
|
||||||
<button type="submit" :disabled="l"
|
<button type="submit" :disabled="l"
|
||||||
class="shrink-0 inline-flex items-center gap-2 rounded-md bg-black text-white px-4 py-3 text-sm font-medium hover:bg-gray-900 disabled:opacity-50 disabled:cursor-not-allowed">
|
class="shrink-0 inline-flex items-center justify-center rounded-md bg-black text-white px-4 py-3 text-sm font-medium hover:bg-gray-900 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||||
<i data-lucide="link" class="w-4 h-4"></i><span x-text="l?'Shortening…':'Shorten'"></span>
|
<span x-text="l?'Shortening…':'Shorten'"></span>
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
<p x-show="e" x-text="e" class="mt-2 text-sm text-red-600" role="alert"></p>
|
<p x-show="e" x-text="e" class="mt-2 text-sm text-red-600" role="alert"></p>
|
||||||
|
|||||||
Reference in New Issue
Block a user