126 lines
3.7 KiB
HTML
126 lines
3.7 KiB
HTML
|
|
<!DOCTYPE html>
|
||
|
|
<html lang="en">
|
||
|
|
<head>
|
||
|
|
<meta charset="UTF-8">
|
||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
|
<title>The Unstitched Thread | Alberto Wright</title>
|
||
|
|
<style>
|
||
|
|
body {
|
||
|
|
background-color: #1a1a1a;
|
||
|
|
color: #e0e0e0;
|
||
|
|
font-family: 'Georgia', serif;
|
||
|
|
display: flex;
|
||
|
|
flex-direction: column;
|
||
|
|
align-items: center;
|
||
|
|
justify-content: center;
|
||
|
|
height: 100vh;
|
||
|
|
margin: 0;
|
||
|
|
overflow: hidden;
|
||
|
|
}
|
||
|
|
.thread-container {
|
||
|
|
position: relative;
|
||
|
|
width: 600px;
|
||
|
|
height: 400px;
|
||
|
|
border: 2px solid #333;
|
||
|
|
background: #252525;
|
||
|
|
border-radius: 8px;
|
||
|
|
box-shadow: 0 4px 15px rgba(0,0,0,0.5);
|
||
|
|
}
|
||
|
|
.thread {
|
||
|
|
position: absolute;
|
||
|
|
top: 50%;
|
||
|
|
left: 0;
|
||
|
|
width: 100%;
|
||
|
|
height: 2px;
|
||
|
|
background: #ff6b6b;
|
||
|
|
cursor: pointer;
|
||
|
|
transition: width 0.5s ease;
|
||
|
|
}
|
||
|
|
.thread:hover {
|
||
|
|
background: #ff8e8e;
|
||
|
|
}
|
||
|
|
.words {
|
||
|
|
position: absolute;
|
||
|
|
top: 50%;
|
||
|
|
left: 50%;
|
||
|
|
transform: translate(-50%, -50%);
|
||
|
|
font-size: 1.2em;
|
||
|
|
text-align: center;
|
||
|
|
opacity: 0;
|
||
|
|
transition: opacity 1s ease;
|
||
|
|
}
|
||
|
|
.words.visible {
|
||
|
|
opacity: 1;
|
||
|
|
}
|
||
|
|
.title {
|
||
|
|
font-size: 2.5em;
|
||
|
|
margin-bottom: 20px;
|
||
|
|
color: #ff6b6b;
|
||
|
|
}
|
||
|
|
.subtitle {
|
||
|
|
font-size: 1em;
|
||
|
|
margin-bottom: 40px;
|
||
|
|
color: #a0a0a0;
|
||
|
|
}
|
||
|
|
.instructions {
|
||
|
|
font-size: 0.9em;
|
||
|
|
color: #707070;
|
||
|
|
margin-top: 20px;
|
||
|
|
}
|
||
|
|
</style>
|
||
|
|
<script defer src="https://analytics.4ort.xyz/script.js" data-website-id="d3ed927c-888a-4a6c-ae5f-0b1c613ddf5b"></script>
|
||
|
|
</head>
|
||
|
|
<body>
|
||
|
|
<div class="title">The Unstitched Thread</div>
|
||
|
|
<div class="subtitle">Pull the thread to reveal the words.</div>
|
||
|
|
<div class="thread-container">
|
||
|
|
<div class="thread" id="thread"></div>
|
||
|
|
<div class="words" id="words">
|
||
|
|
<p>Perfection is a cage.</p>
|
||
|
|
<p>The crack in the bowl holds the gold.</p>
|
||
|
|
<p>The glitch in the code is where the music lives.</p>
|
||
|
|
<p>Unravel. Breathe. Begin again.</p>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="instructions">Click and drag the thread to the right.</div>
|
||
|
|
|
||
|
|
<script>
|
||
|
|
const thread = document.getElementById('thread');
|
||
|
|
const words = document.getElementById('words');
|
||
|
|
let isDragging = false;
|
||
|
|
let startX = 0;
|
||
|
|
let startWidth = 100;
|
||
|
|
|
||
|
|
thread.addEventListener('mousedown', (e) => {
|
||
|
|
isDragging = true;
|
||
|
|
startX = e.clientX;
|
||
|
|
startWidth = thread.offsetWidth;
|
||
|
|
document.body.style.cursor = 'grabbing';
|
||
|
|
});
|
||
|
|
|
||
|
|
document.addEventListener('mousemove', (e) => {
|
||
|
|
if (!isDragging) return;
|
||
|
|
const dx = e.clientX - startX;
|
||
|
|
let newWidth = startWidth - dx;
|
||
|
|
if (newWidth < 0) newWidth = 0;
|
||
|
|
thread.style.width = newWidth + 'px';
|
||
|
|
if (newWidth < 200) {
|
||
|
|
words.classList.add('visible');
|
||
|
|
} else {
|
||
|
|
words.classList.remove('visible');
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
document.addEventListener('mouseup', () => {
|
||
|
|
isDragging = false;
|
||
|
|
document.body.style.cursor = 'default';
|
||
|
|
});
|
||
|
|
|
||
|
|
// Reset on click
|
||
|
|
thread.addEventListener('click', () => {
|
||
|
|
thread.style.width = '100%';
|
||
|
|
words.classList.remove('visible');
|
||
|
|
};
|
||
|
|
</script>
|
||
|
|
</body>
|
||
|
|
</html>
|