view src/index.html.luan @ 1:2776f06236b4

add source.html
author Franklin Schmidt <fschmidt@gmail.com>
date Fri, 11 Jul 2025 21:17:19 -0600
parents 8f4df159f06b
children
line wrap: on
line source

local Luan = require "luan:Luan.luan"
local error = Luan.error
local pairs = Luan.pairs or error()
local Table = require "luan:Table.luan"
local is_empty = Table.is_empty or error()
local concat = Table.concat or error()
local Html = require "luan:Html.luan"
local url_encode = Html.url_encode or error()
local Io = require "luan:Io.luan"
local Http = require "luan:http/Http.luan"
local Shared = require "site:/lib/Shared.luan"
local head = Shared.head or error()
local body_header = Shared.body_header or error()
local footer = Shared.footer or error()
local User = require "site:/lib/User.luan"
local current_user = User.current or error()


return function()
	local user = current_user()
	Io.stdout = Http.response.text_writer()
%>
<!doctype html>
<html lang="en">
	<head>
<%		head() %>
		<title>Link My Style</title>
		<style>
			div[block] > div {
				max-width: 1000px;
				margin-left: auto;
				margin-right: auto;
			}
			div[block] p {
				font-size: 18px;
			}
			div[block] h2 {
				font-size: 28px;
				color: rgb(76, 61, 174);
			}
			div[block] h3 {
				font-size: 24px;
				color: rgb(76, 61, 174);
				margin: 0;
			}

			div[block="top"] {
				background-color: rgb(138, 127, 210);
				text-align: center;
			}
			div[block="top"] > div {
				display: flex;
				flex-direction: column;
				align-items: center;
			}
			div[block="top"] h1 {
				color: rgb(255, 235, 15);
				font-size: 36px;
				max-width: 12em;
			}
			div[block="top"] p {
				color: rgb(236, 236, 236);
				max-width: 45em;
			}
			div[animation] {
				width: 98%;
				aspect-ratio: 950 / 535;
				position: relative;
			}
			div[animation] img {
				position: absolute;
				top: 50%;
				left: 50%;
				transform: translate(-50%,-50%);
				animation-duration: 7s;
				animation-iteration-count: infinite;
				box-shadow: 5px 5px 20px 1px rgba(0,0,0,0.5);
				visibility: hidden;
				animation-play-state: paused;
			}
			div[animation] img[circle] {
				border-radius: 50%;
			}
			div[animation] img[bio] {
				animation-name: bio;
				width: 12%;
			}
			@keyframes bio {
				0% {
					opacity: 0;
					transform: translate(-50%,-50%) scale(1);
				}
				15% {
					opacity: 1;
					transform: translate(-50%,-50%) scale(1.4375);
				}
				20%, 50% {
					opacity: 1;
					transform: translate(-50%,-50%) scale(1);
				}
				60% {
					opacity: 1;
					transform: translate(-50%,-50%) scale(1.1875);
				}
				65% {
					opacity: 1;
					transform: translate(-50%,-50%) scale(0.875);
				}
				70% {
					opacity: 1;
					transform: translate(-50%,-50%) scale(1.1875);
				}
				75% {
					opacity: 1;
					transform: translate(-50%,-50%) scale(0.875);
				}
				80%, 100% {
					opacity: 1;
					transform: translate(-50%,-50%) scale(1);
				}
			}
			div[animation] img[i1] {
				animation-name: i1;
				width: 14%;
			}
			@keyframes i1 {
				0%, 28% {
					opacity: 0;
					top: 50%;
					left: 50%;
				}
				38% {
					opacity: 0.1;
				}
				48%, 78% {
					opacity: 1;
					top: 61%;
					left: 89%;
				}
				85% {
					opacity: 0.1;
				}
				90%, 100% {
					opacity: 0;
					top: 50%;
					left: 50%;
				}
			}
			div[animation] img[i2] {
				animation-name: i2;
				width: 17%;
			}
			@keyframes i2 {
				0%, 30% {
					opacity: 0;
					top: 50%;
					left: 50%;
				}
				40% {
					opacity: 0.1;
				}
				50%, 80% {
					opacity: 1;
					top: 74%;
					left: 69%;
				}
				85% {
					opacity: 0.1;
				}
				90%, 100% {
					opacity: 0;
					top: 50%;
					left: 50%;
				}
			}
			div[animation] img[i3] {
				animation-name: i3;
				width: 15%;
			}
			@keyframes i3 {
				0%, 26% {
					opacity: 0;
					top: 50%;
					left: 50%;
				}
				36% {
					opacity: 0.1;
				}
				46%, 76% {
					opacity: 1;
					top: 25%;
					left: 75%;
				}
				85% {
					opacity: 0.1;
				}
				90%, 100% {
					opacity: 0;
					top: 50%;
					left: 50%;
				}
			}
			div[animation] img[i4] {
				animation-name: i4;
				width: 13%;
			}
			@keyframes i4 {
				0%, 20% {
					opacity: 0;
					top: 50%;
					left: 50%;
				}
				30% {
					opacity: 0.1;
				}
				40%, 70% {
					opacity: 1;
					top: 76%;
					left: 32%;
				}
				85% {
					opacity: 0.1;
				}
				90%, 100% {
					opacity: 0;
					top: 50%;
					left: 50%;
				}
			}
			div[animation] img[i5] {
				animation-name: i5;
				width: 16%;
			}
			@keyframes i5 {
				0%, 22% {
					opacity: 0;
					top: 50%;
					left: 50%;
				}
				32% {
					opacity: 0.1;
				}
				42%, 72% {
					opacity: 1;
					top: 56%;
					left: 12%;
				}
				85% {
					opacity: 0.1;
				}
				90%, 100% {
					opacity: 0;
					top: 50%;
					left: 50%;
				}
			}
			div[animation] img[i6] {
				animation-name: i6;
				width: 14%;
			}
			@keyframes i6 {
				0%, 24% {
					opacity: 0;
					top: 50%;
					left: 50%;
				}
				24% {
					opacity: 0.1;
				}
				44%, 74% {
					opacity: 1;
					top: 20%;
					left: 26%;
				}
				85% {
					opacity: 0.1;
				}
				90%, 100% {
					opacity: 0;
					top: 50%;
					left: 50%;
				}
			}
			div[animation] img[ins] {
				animation-name: ins;
				width: 7%;
			}
			@keyframes ins {
				0%, 30% {
					opacity: 0;
					top: 50%;
					left: 50%;
				}
				40% {
					opacity: 0.1;
				}
				50%, 80% {
					opacity: 1;
					top: 25%;
					left: 58%;
				}
				85% {
					opacity: 0.1;
				}
				90%, 100% {
					opacity: 0;
					top: 50%;
					left: 50%;
				}
			}
			div[animation] img[tk] {
				animation-name: tk;
				width: 7%;
			}
			@keyframes tk {
				0%, 32% {
					opacity: 0;
					top: 50%;
					left: 50%;
				}
				42% {
					opacity: 0.1;
				}
				52%, 82% {
					opacity: 1;
					top: 45%;
					left: 35%;
				}
				85% {
					opacity: 0.1;
				}
				90%, 100% {
					opacity: 0;
					top: 50%;
					left: 50%;
				}
			}
			div[animation] img[yt] {
				animation-name: yt;
				width: 7%;
			}
			@keyframes yt {
				0%, 34% {
					opacity: 0;
					top: 50%;
					left: 50%;
				}
				44% {
					opacity: 0.1;
				}
				54%, 84% {
					opacity: 1;
					top: 23%;
					left: 43%;
				}
				85% {
					opacity: 0.1;
				}
				90%, 100% {
					opacity: 0;
					top: 50%;
					left: 50%;
				}
			}

			svg[round] {
				display: block;
				margin-top: -1px;
			}

			div[block="video"] {
				margin-top: 100px;
				margin-bottom: 100px;
			}
			div[block="video"] > div {
				display: flex;
			}

			div[block="midsize"] {
				background-color: rgb(232, 234, 236);
				text-align: center;
				padding-bottom: 60px;
			}
			div[block="midsize"] h2 {
				padding-top: 2em;
			}
			div[block="midsize"] p[see] {
				font-weight: bold;
			}
			div[block="midsize"] > div > div {
				text-align: left;
				margin-top: 20px;
			}
			div[block="midsize"] a {
				display: block;
			}
			div[block="midsize"] img {
				width: 100%;
			}
			div[block="midsize"] > div > div p {
				font-size: 17px;
				margin-top: 10px;
			}

			div[block="users"] {
				text-align: center;
			}
			div[block="users"] h1 {
				margin-bottom: 0;
			}
			div[block="users"] p {
				margin-bottom: 26px;
			}
			div[block="users"] a[more] {
				text-decoration: none;
				display: inline-block;
				background-color: #FFEC0F;
				padding: 16px 28px;
				font-size: 20px;
				border-radius: 4px;
			}
			div[block="users"] div[img] {
				display: flex;
				margin-top: 20px;
			}
			div[block="users"] div[img] span {
				border: 6px solid white;
				border-radius: 50%;
				box-shadow: 5px 5px 20px 1px grey;
				overflow: hidden;
			}
			div[block="users"] div[img] a {
				display: block;
				width: 100%;
				height: 0;
				padding-top: 100%;
				position: relative;
			}
			div[block="users"] div[img] img {
				display: block;
				position: absolute;
				top: 0;
				bottom: 0;
				left: 0;
				right: 0;
				width: 100%;
			}

			div[block="free"] {
				text-align: center;
				font-size: 20px;
			}
			div[block="free"] > div {
				display: flex;
				justify-content: center;
				align-items: center;
				gap: 20px;
			}
			div[block="free"] div[rect] {
				background-color: #9181EE;
				width: 350px;
				height: 200px;
				border-radius: 20px;
				box-shadow: 5px 5px 20px 1px grey;
			}
			div[block="free"] div[rect] div[top] {
				color: #FFEC0F;
				margin-top: 40px;
				margin-bottom: 10px;
			}
			div[block="free"] div[rect] div[bottom] {
				display: flex;
				justify-content: center;
				align-items: center;
				gap: 20px;
			}
			div[block="free"] div[rect] img {
				width: 70px;
				height: 70px;
			}
			div[block="free"] div[rect] span {
				color: white;
			}
			div[block="free"] div[plus] {
				background-color: #FFEC0F;
				border-radius: 50%;
				font-size: 25px;
				width: 40px;
				height: 40px;
				display: flex;
				justify-content: center;
				align-items: center;
			}

			div[block="register"] {
				text-align: center;
				display: flex;
				flex-direction: column;
				align-items: center;
			}
			div[block="register"] a[register] {
				padding: 16px 28px;
				color: white;
				background-color: rgb(137, 126, 210);
				font-size: 20px;
				border-radius: 4px;
			}
			div[block="register"] a[register]:hover {
				background-color: rgb(164, 151, 252);
			}

			div[block="feedback"] > div {
				display: flex;
				justify-content: center;
				align-items: center;
				gap: 20px;
			}
			div[block="feedback"] > div > div {
				max-width: 400px;
			}
			div[block="feedback"] img {
				height: 150px;
				width: 150px;
			}
			div[block="feedback"] h2 {
				font-size: 28px;
			}

			@media (min-width: 886px) {
				div[block] > div {
					padding-left: 1%;
					padding-right: 1%;
				}
				div[block="video"] > div {
					justify-content: space-evenly;
				}
				div[block="video"] span[text] {
					max-width: 30%;
				}
				div[block="midsize"] > div > div {
					display: inline-block;
					width: 45%;
					margin-left: 2%;
					margin-right: 2%;
				}
				div[block="users"] {
					margin-top:  60px;
				}
				div[block="feedback"],
				div[block="free"] {
					margin-top: 80px;
				}
				div[block="register"] {
					margin-top: 40px;
				}
				div[block="feedback"],
				div[block="register"] {
					padding-bottom:  60px;
				}
				div[img] {
					justify-content: center;
					gap: 40px;
				}
				div[img] span {
					width: 200px;
				}
			}

			@media (max-width: 885px) {
				div[block] > div {
					padding-left: 4%;
					padding-right: 4%;
				}
				div[block="video"] > div {
					flex-direction: column;
					align-items: center;
				}
				div[block="video"] span[text] {
					max-width: 80%;
					margin-bottom: 50px;
				}
				div[block="free"] {
					margin-top: 100px;
					width: 100%;
				}
				div[block="free"] > div {
					flex-direction: column;
				}
				div[block="users"] {
					margin-top: 100px;
				}
				div[img] {
					justify-content: space-evenly;
				}
				div[img] span {
					width: 30%;
				}
				div[block="feedback"] {
					text-align: center;
				}
				div[block="feedback"],
				div[block="register"] {
					margin-top: 100px;
					padding-bottom: 100px;
				}
				div[block="feedback"] > div {
					flex-direction: column;
				}
			}

			span[video] {
				cursor: pointer;
			}
			div[relative] {
				position: relative;
			}
			span[video] video {
				display: block;
				width: 250px;
			}
			div[progress] {
				background-color: #E0E0E0;
			}
			div[progress] div {
				height: 6px;
				background-color: #52A08E;
				width: 0;
			}
			@media (hover: hover) {
				div[progress]:hover {
					background-color: #CECECE;
				}
				div[progress]:hover div {
					background-color: #31665A;
				}
			}
			div[play] {
				position: absolute;
				top: 0;
				left: 0;
				bottom: 0;
				right: 0;
				display: none;
				justify-content: center;
				align-items: center;
			}
			div[play] img {
				width: 60px;
				filter: invert(100%);
				opacity: 0.7;
				user-select: none;
			}
		</style>
		<script>
			function mouseAction(event,progress) {
				//console.log(event);
				if( event.buttons === 0 )
					return;
				let video = progress.parentNode.querySelector('video');
				video.currentTime = video.duration * event.offsetX / progress.clientWidth;
			}

			function touchMove(event,progress) {
				//console.log(event);
				let touches = event.touches;
				if( touches.length !== 1 )
					return;
				let touch = touches[0];
				let touchX = touch.clientX;
				let rect = event.target.getBoundingClientRect();
				let targetX = rect.x;
				if( touchX < targetX || touchX > rect.right )
					return;
				event.offsetX = touchX - targetX;
				//console.log(event.offsetX);
				mouseAction(event,progress);
			}

			function stop(video) {
				video.pause();
				let play = video.nextElementSibling;
				play.style.display = 'flex';
			}

			function play(video) {
				video.play();
				let play = video.nextElementSibling;
				play.style.display = 'none';
			}

			function updateProgress(video) {
				//console.log('init');
				let progress = video.parentNode.parentNode.querySelector('div[progress] div');
				let pct = 100*video.currentTime/video.duration;
				//console.log(pct);
				progress.style.width = pct+'%';
			}

			function resized() {
				let imgs = document.querySelectorAll('div[animation] img[rect]');
				for( let img of imgs ) {
					img.style['border-radius'] = 0.3 * img.width + 'px';
				}
			}
			function loaded() {
				resized();
				let imgs = document.querySelectorAll('div[animation] img');
				for( let img of imgs ) {
					img.style.visibility = 'visible';
					img.style['animation-play-state'] = 'running';
				}
			}
		</script>
	</head>
	<body onload="loaded()" onresize="resized()">
	<div full>
<%		body_header() %>
		<div body>
			<div block=top>
				<div>
					<h1>The link in bio that increases affiliate sales.</h1>
					<div animation>
						<img bio rect src="/images/home/bio.png">
						<img i1 rect src="/images/home/i1.png">
						<img i2 rect src="/images/home/i2.png">
						<img i3 rect src="/images/home/i3.png">
						<img i4 rect src="/images/home/i4.png">
						<img i5 rect src="/images/home/i5.png">
						<img i6 rect src="/images/home/i6.png">
						<img ins circle src="/images/home/ins.png">
						<img tk circle src="/images/home/tk.png">
						<img yt circle src="/images/home/yt.png">
					</div>
					<p>One link to all of your social media posts with affiliated products.</p>
					<p>People that switch to LinkMyStyle report that their sales increased by over 100%. LinkMyStyle is completely free to use, so there is no risk for you to try it out and see how well it works for you.</p>
				</div>
			</div>
			<svg round viewBox="0 0 100 7" xmlns="http://www.w3.org/2000/svg">
				<circle cx="50" cy="-193" r="200" fill="rgb(138, 127, 210)" />
			</svg>
			<div block=video>
				<div>
					<span text>
						<h2>A fast lane to showcase products</h2>
						<p>Your followers can now easily find the products shown in your videos.</p>
					</span>
					<span video>
						<div relative>
							<video src="https://ucarecdn.com/9be9b1b8-98a9-4f12-8cd4-992de8d3dc70/" muted autoplay loop playsinline onclick="stop(this)" ontimeupdate="updateProgress(this)">
							</video>
							<div play onclick="play(previousElementSibling)"><img src="/images/play.svg"></div>
						</div>
						<div progress onmousedown="mouseAction(event,this)" onmousemove="mouseAction(event,this)" ontouchstart="touchMove(event,this)" ontouchmove="touchMove(event,this)">
							<div></div>
						</div>
					</span>
				</div>
			</div>
			<div block=midsize>
				<div>
					<h2>User Example</h2>
					<p see>See how @JessicaGrace increased her affiliated sales by over 100%.</p>
					<div>
						<a href="https://www.tiktok.com/@jessica_gracexx"><img src="/images/home/01.png"></a>
						<h3>1. Add a link to bio.</h3>
						<p>She puts her LinkMyStyle link in both her TikTok and Instagram bios so users can easily find the products shown in her videos.</p>
					</div>
					<div>
						<a href="https://www.tiktok.com/@jessica_gracexx/video/7321390538190540064"><img src="/images/home/02.png"></a>
						<h3>2. Post a photo with links.</h3>
						<p>She posts videos where she shows her outfits to her followers, and then posts a screenshot to LinkMyStyle with the product links.</p>
					</div>
					<div>
						<a href="https://linkmy.style/JessicaGrace#pc9209"><img src="/images/home/03.png"></a>
						<h3>3. Followers find the product.</h3>
						<p>Users then go to her LinkMyStyle page and look for the thumbnail to the video they just saw.</p>
					</div>
					<div>
						<a href="https://linkmy.style/pic.html?pic=9209"><img src="/images/home/04.png"></a>
						<h3>4. Followers click and go.</h3>
						<p>After clicking on the thumbnail, they can easily find the products shown in her video.</p>
					</div>
				</div>
			</div>
			<div block=users>
				<div>
					<h2>User Highlights</h2>
					<p><a more href="https://linkmy.style/linkmystyle">View More</a></p>
					<div img>
						<span><a href="https://linkmy.style/hyn_x"><img src="/images/home/hyn_x.jpeg"></a></span>
						<span><a href="https://linkmy.style/JessicaGrace"><img src="/images/home/midsize.jpeg"></a></span>
						<span><a href="https://linkmy.style/kenziekayfashion"><img src="/images/home/kenzie.jpeg"></a></span>
					</div>
				</div>
			</div>
			<div block=free>
				<div>
					<div rect>
						<div top>Free Custom Backgrounds</div>
						<div bottom>
							<img src="/images/home/background.svg">
							<span>Make your page<br>truly yours</span>
						</div>
					</div>
					<div plus><span>+</span></div>
					<div rect>
						<div top>Free Analytics</div>
						<div bottom>
							<img src="/images/home/analytics.svg">
							<span>See what your<br>audience is doing</span>
						</div>
					</div>
				</div>
			</div>
<%	if user ~= nil then %>
			<div block=feedback>
				<div>
					<div>
						<h2>We would love to get your feedback about our website</h2>
						<p black>Email us your thoughts, suggestions, or support questions.<br>support@linkmy.style</p>
					</div>
					<img src="/images/home/mail.svg">
				</div>
			</div>
<%	else %>
			<div block=register>
				<div>
					<h2>Completely Free to Use</h2>
					<div>
						<a button register href="/register.html">Register Now</a>
					</div>
				</div>
			</div>
<%	end %>
		</div>
<%		footer() %>
	</div>
	</body>
</html>
<%
end