Files
4ev.link/index.html

89 lines
7.4 KiB
HTML

<!doctype html>
<html lang="en" class="dark">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>4ev.link — Permanent, Short & Simple URL Shortener</title>
<meta name="description" content="Create short, memorable, and permanent links for your long URLs. Fast, free, and easy to use. Perfect for sharing on social media.">
<meta name="keywords" content="url shortener, link shortener, short url, permanent links, free url shortener">
<link rel="canonical" href="https://4ev.link/">
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🔗</text></svg>">
<meta property="og:type" content="website">
<meta property="og:url" content="https://4ev.link/">
<meta property="og:title" content="4ev.link — Permanent, Short & Simple URL Shortener">
<meta property="og:description" content="Create short, memorable, and permanent links for your long URLs. Fast, free, and easy to use.">
<meta property="twitter:card" content="summary">
<meta property="twitter:title" content="4ev.link — Permanent, Short & Simple URL Shortener">
<meta property="twitter:description" content="Create short, memorable, and permanent links for your long URLs. Fast, free, and easy to use.">
<meta name="color-scheme" content="light dark">
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#000000" media="(prefers-color-scheme: dark)">
<script src="https://cdn.tailwindcss.com"></script>
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lucide@latest/dist/lucide.min.js"></script>
</head>
<body class="bg-white dark:bg-black text-gray-800 dark:text-gray-200 antialiased font-sans">
<div class="min-h-screen flex flex-col">
<header class="w-full max-w-5xl mx-auto p-4 sm:p-6">
<nav class="flex items-center justify-between">
<a href="/" class="flex items-center gap-2 font-bold text-xl hover:opacity-80 transition-opacity">
<i data-lucide="link-2" class="w-6 h-6"></i><span>4ev.link</span>
</a>
<a href="#" class="px-4 py-2 text-sm font-semibold bg-gray-100 dark:bg-gray-800 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors">Sign In</a>
</nav>
</header>
<main class="flex-grow flex flex-col items-center justify-center p-4" x-data="shortener()">
<div class="w-full max-w-2xl text-center">
<h1 class="text-4xl sm:text-5xl md:text-6xl font-extrabold tracking-tight mb-4">
Shorten URLs that <span class="bg-clip-text text-transparent bg-gradient-to-r from-blue-500 to-teal-400">last</span>.
</h1>
<p class="text-lg text-gray-600 dark:text-gray-400 max-w-xl mx-auto mb-8">Create short, memorable, and permanent links. Paste your long URL below to get started.</p>
<form class="flex flex-col sm:flex-row gap-2" @submit.prevent="submit">
<input type="text" x-model="i" @input="e='';s=''" placeholder="https://your-long-url.com/goes/here" class="flex-grow w-full px-4 py-3 bg-white dark:bg-gray-900 border border-gray-300 dark:border-gray-700 rounded-lg focus:ring-2 focus:ring-blue-500 focus:outline-none transition" autocapitalize="off" spellcheck="false" autofocus>
<button type="submit" :disabled="l" class="inline-flex items-center justify-center gap-2 px-6 py-3 font-semibold text-white bg-blue-600 rounded-lg hover:bg-blue-700 disabled:bg-blue-400 dark:disabled:bg-blue-800 disabled:cursor-wait transition-colors">
<span x-show="!l"><i data-lucide="zap" class="w-5 h-5"></i></span>
<span x-show="l"><i data-lucide="loader-2" class="w-5 h-5 animate-spin"></i></span>
<span x-text="l?'Working...':'Shorten'"></span>
</button>
</form>
<div x-show="s" x-transition class="mt-4 p-3 bg-gray-50 dark:bg-gray-900/50 border border-gray-200 dark:border-gray-800 rounded-lg flex flex-col sm:flex-row items-center gap-3">
<input x-ref="output" :value="s" type="text" readonly class="flex-grow w-full px-3 py-2 bg-transparent focus:outline-none text-center sm:text-left" @click="$refs.output.select()">
<div class="flex gap-2">
<button @click="copy" class="inline-flex items-center gap-1.5 px-4 py-2 text-sm font-semibold bg-gray-200 dark:bg-gray-800 rounded-lg hover:bg-gray-300 dark:hover:bg-gray-700 transition-colors w-28 justify-center">
<span x-show="!c"><i data-lucide="copy" class="w-4 h-4"></i></span>
<span x-show="c"><i data-lucide="check" class="w-4 h-4 text-green-500"></i></span>
<span x-text="c?'Copied!':'Copy'"></span>
</button>
<a :href="s" target="_blank" rel="noopener" class="inline-flex items-center gap-1.5 px-4 py-2 text-sm font-semibold bg-gray-200 dark:bg-gray-800 rounded-lg hover:bg-gray-300 dark:hover:bg-gray-700 transition-colors">
<i data-lucide="arrow-up-right-from-square" class="w-4 h-4"></i><span>Open</span>
</a>
</div>
</div>
<p x-show="e" x-text="e" x-transition class="mt-4 text-red-500"></p>
</div>
<section class="w-full max-w-5xl mx-auto mt-24 sm:mt-32 text-center">
<h2 class="text-3xl font-bold mb-2">Simple. Fast. Reliable.</h2>
<p class="text-gray-600 dark:text-gray-400 mb-12">All the features you need, none of the bloat.</p>
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
<div class="p-6 bg-gray-50 dark:bg-gray-900/50 rounded-lg"><i data-lucide="infinity" class="w-10 h-10 mx-auto mb-4 text-blue-500"></i><h3 class="text-xl font-semibold mb-2">Permanent Links</h3><p class="text-gray-600 dark:text-gray-400">Your links will never expire. We mean it. 4ev-link stands for 'forever'.</p></div>
<div class="p-6 bg-gray-50 dark:bg-gray-900/50 rounded-lg"><i data-lucide="bar-chart-3" class="w-10 h-10 mx-auto mb-4 text-blue-500"></i><h3 class="text-xl font-semibold mb-2">Analytics</h3><p class="text-gray-600 dark:text-gray-400">Track clicks and get insights into your audience. (Coming Soon)</p></div>
<div class="p-6 bg-gray-50 dark:bg-gray-900/50 rounded-lg"><i data-lucide="braces" class="w-10 h-10 mx-auto mb-4 text-blue-500"></i><h3 class="text-xl font-semibold mb-2">Developer API</h3><p class="text-gray-600 dark:text-gray-400">Integrate our shortener into your own application with a simple JSON API.</p></div>
</div>
</section>
</main>
<footer class="w-full max-w-5xl mx-auto p-4 sm:p-6 text-center text-sm text-gray-500">&copy; <span x-text="new Date().getFullYear()"></span> 4ev.link. All Rights Reserved.</footer>
</div>
<script>
lucide.createIcons();
document.addEventListener('alpine:init',()=>{Alpine.data('shortener',()=>({i:'',s:'',e:'',l:!1,c:!1,norm(t){try{return new URL(t).href}catch(o){try{return new URL('https://'+t).href}catch(o){return null}}},async submit(){this.e='',this.s='';const t=this.norm(this.i.trim());if(!t)return void(this.e='Please enter a valid URL.');this.l=!0;try{const o=await fetch('/api/create',{method:'POST',headers:{'Content-Type':'application/json','Accept':'application/json'},body:JSON.stringify({url:t})});if(!o.ok)throw new Error(await o.text()||o.statusText);const n=await o.json();this.s=n.shortUrl,this.i=''}catch(o){this.e=o.message||'An unknown error occurred.'}finally{this.l=!1}},copy(){this.s&&navigator.clipboard.writeText(this.s).then(()=>{this.c=!0,setTimeout(()=>this.c=!1,2e3)})}}))})
</script>
</body>
</html>