Mercurial Hosting > linkmystyle
diff src/index.html.luan @ 0:8f4df159f06b
start public repo
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Fri, 11 Jul 2025 20:57:49 -0600 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/index.html.luan Fri Jul 11 20:57:49 2025 -0600 @@ -0,0 +1,841 @@ +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