infinite-agents-public/src_infinite/ui_hybrid_17.html

1201 lines
50 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Handcrafted Paper Content Card System</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Kalam:wght@300;400;700&family=Indie+Flower&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Kalam', cursive;
background: linear-gradient(135deg, #f5f1e8 0%, #e8ddc7 100%);
color: #2c1810;
min-height: 100vh;
position: relative;
overflow-x: hidden;
}
/* Paper texture background */
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image:
repeating-linear-gradient(45deg, transparent, transparent 10px, rgba(139, 69, 19, 0.02) 10px, rgba(139, 69, 19, 0.02) 20px),
repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(160, 82, 45, 0.02) 10px, rgba(160, 82, 45, 0.02) 20px);
pointer-events: none;
z-index: 1;
}
main {
position: relative;
z-index: 2;
padding: 2rem;
max-width: 1400px;
margin: 0 auto;
}
h1 {
text-align: center;
font-size: 3rem;
color: #5c3317;
margin-bottom: 3rem;
text-shadow: 2px 2px 4px rgba(92, 51, 23, 0.1);
position: relative;
display: inline-block;
width: 100%;
}
h1::after {
content: '';
position: absolute;
bottom: -10px;
left: 50%;
transform: translateX(-50%);
width: 200px;
height: 3px;
background: linear-gradient(90deg, transparent, #8b4513, transparent);
border-radius: 50%;
}
/* Paper card grid container */
.hybrid-component {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
gap: 2.5rem;
padding: 1rem;
}
/* Individual paper content card */
.paper-card {
position: relative;
background: #fdfbf7;
padding: 2rem;
border-radius: 8px;
transform: rotate(-0.5deg);
transition: all 0.3s ease;
cursor: pointer;
/* Paper shadow layers */
box-shadow:
0 1px 1px rgba(0,0,0,0.15),
0 2px 2px rgba(0,0,0,0.12),
0 4px 4px rgba(0,0,0,0.10),
0 8px 8px rgba(0,0,0,0.08),
0 16px 16px rgba(0,0,0,0.06);
}
.paper-card:nth-child(even) {
transform: rotate(0.5deg);
}
.paper-card:nth-child(3n) {
transform: rotate(-0.3deg);
}
.paper-card:hover {
transform: rotate(0deg) scale(1.03);
box-shadow:
0 2px 2px rgba(0,0,0,0.18),
0 4px 4px rgba(0,0,0,0.15),
0 8px 8px rgba(0,0,0,0.13),
0 16px 16px rgba(0,0,0,0.11),
0 32px 32px rgba(0,0,0,0.09);
z-index: 10;
}
/* Torn paper edges */
.paper-card::before,
.paper-card::after {
content: '';
position: absolute;
background: #fdfbf7;
z-index: -1;
}
.paper-card::before {
top: -2px;
left: -2px;
right: -2px;
height: 10px;
background: linear-gradient(to right,
transparent 0%, #fdfbf7 5%, #fdfbf7 10%, transparent 12%,
transparent 12%, #fdfbf7 15%, #fdfbf7 20%, transparent 22%,
transparent 22%, #fdfbf7 25%, #fdfbf7 30%, transparent 32%,
transparent 32%, #fdfbf7 35%, #fdfbf7 40%, transparent 42%,
transparent 42%, #fdfbf7 45%, #fdfbf7 50%, transparent 52%,
transparent 52%, #fdfbf7 55%, #fdfbf7 60%, transparent 62%,
transparent 62%, #fdfbf7 65%, #fdfbf7 70%, transparent 72%,
transparent 72%, #fdfbf7 75%, #fdfbf7 80%, transparent 82%,
transparent 82%, #fdfbf7 85%, #fdfbf7 90%, transparent 92%,
transparent 92%, #fdfbf7 95%, #fdfbf7 100%
);
clip-path: polygon(
0% 0%, 3% 40%, 6% 20%, 9% 60%, 12% 30%, 15% 70%, 18% 40%,
21% 80%, 24% 50%, 27% 90%, 30% 60%, 33% 100%, 36% 70%,
39% 100%, 42% 80%, 45% 100%, 48% 90%, 51% 100%, 54% 95%,
57% 100%, 60% 98%, 63% 100%, 66% 96%, 69% 100%, 72% 94%,
75% 100%, 78% 92%, 81% 100%, 84% 88%, 87% 100%, 90% 85%,
93% 100%, 96% 80%, 100% 100%, 100% 0%
);
}
.paper-card::after {
bottom: -2px;
left: -2px;
right: -2px;
height: 10px;
background: #fdfbf7;
clip-path: polygon(
0% 100%, 3% 60%, 6% 80%, 9% 40%, 12% 70%, 15% 30%, 18% 60%,
21% 20%, 24% 50%, 27% 10%, 30% 40%, 33% 0%, 36% 30%,
39% 0%, 42% 20%, 45% 0%, 48% 10%, 51% 0%, 54% 5%,
57% 0%, 60% 2%, 63% 0%, 66% 4%, 69% 0%, 72% 6%,
75% 0%, 78% 8%, 81% 0%, 84% 12%, 87% 0%, 90% 15%,
93% 0%, 96% 20%, 100% 0%, 100% 100%
);
}
/* Card header with metadata */
.card-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 1.5rem;
position: relative;
}
.card-title {
font-size: 1.8rem;
color: #5c3317;
font-weight: 700;
line-height: 1.2;
max-width: 70%;
}
.card-metadata {
font-size: 0.9rem;
color: #8b6239;
text-align: right;
font-family: 'Indie Flower', cursive;
}
.card-date {
margin-bottom: 0.2rem;
}
.card-category {
padding: 0.2rem 0.8rem;
background: rgba(139, 69, 19, 0.1);
border-radius: 15px;
display: inline-block;
font-size: 0.8rem;
}
/* Content preview area */
.card-preview {
margin-bottom: 1.5rem;
position: relative;
}
.preview-image {
width: 100%;
height: 200px;
object-fit: cover;
border-radius: 5px;
filter: sepia(0.1) saturate(0.9);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
margin-bottom: 1rem;
}
.preview-text {
color: #4a3426;
line-height: 1.8;
font-size: 1.1rem;
position: relative;
}
.preview-text::first-letter {
font-size: 3rem;
float: left;
line-height: 1;
margin-right: 0.1em;
font-weight: 700;
color: #8b4513;
}
/* Action buttons with paper feel */
.card-actions {
display: flex;
gap: 0.8rem;
margin-bottom: 1.5rem;
flex-wrap: wrap;
}
.paper-button {
padding: 0.6rem 1.2rem;
background: linear-gradient(135deg, #f9f7f3 0%, #f0e8d8 100%);
border: 2px solid #d4a574;
border-radius: 25px;
color: #5c3317;
font-family: 'Kalam', cursive;
font-weight: 400;
cursor: pointer;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
font-size: 0.9rem;
}
.paper-button::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(139, 69, 19, 0.1), transparent);
transition: left 0.5s ease;
}
.paper-button:hover::before {
left: 100%;
}
.paper-button:hover {
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(139, 69, 19, 0.2);
background: linear-gradient(135deg, #faf8f4 0%, #f3ead9 100%);
}
.paper-button:active {
transform: translateY(0);
box-shadow: 0 2px 4px rgba(139, 69, 19, 0.2);
}
.paper-button.primary {
background: linear-gradient(135deg, #d4a574 0%, #c19660 100%);
color: #fff;
border-color: #b8935a;
}
/* Favorite button with heart */
.favorite-button {
background: none;
border: none;
font-size: 1.5rem;
cursor: pointer;
color: #d4a574;
transition: all 0.3s ease;
padding: 0.5rem;
}
.favorite-button:hover {
transform: scale(1.2);
color: #e74c3c;
}
.favorite-button.active {
color: #e74c3c;
animation: heartbeat 0.6s ease-in-out;
}
@keyframes heartbeat {
0% { transform: scale(1); }
50% { transform: scale(1.3); }
100% { transform: scale(1); }
}
/* Share menu */
.share-menu {
position: absolute;
bottom: 100%;
right: 0;
background: #fdfbf7;
border: 2px solid #d4a574;
border-radius: 10px;
padding: 0.5rem;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
display: none;
min-width: 150px;
z-index: 20;
}
.share-menu.active {
display: block;
animation: paperUnfold 0.3s ease-out;
}
@keyframes paperUnfold {
from {
opacity: 0;
transform: translateY(10px) scale(0.9);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
.share-option {
padding: 0.5rem;
cursor: pointer;
transition: background 0.2s ease;
border-radius: 5px;
font-size: 0.9rem;
}
.share-option:hover {
background: rgba(212, 165, 116, 0.2);
}
/* Tags section */
.card-tags {
display: flex;
gap: 0.5rem;
flex-wrap: wrap;
margin-bottom: 1rem;
}
.tag {
padding: 0.3rem 0.8rem;
background: rgba(139, 69, 19, 0.08);
border: 1px dashed #d4a574;
border-radius: 20px;
font-size: 0.85rem;
color: #6b4423;
transition: all 0.2s ease;
cursor: pointer;
}
.tag:hover {
background: rgba(139, 69, 19, 0.15);
transform: translateY(-1px);
}
/* Modal overlay */
.modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(44, 24, 16, 0.8);
display: none;
justify-content: center;
align-items: center;
z-index: 100;
backdrop-filter: blur(5px);
}
.modal-overlay.active {
display: flex;
}
/* Expanded modal content */
.modal-content {
background: #fdfbf7;
max-width: 800px;
width: 90%;
max-height: 90vh;
overflow-y: auto;
padding: 3rem;
border-radius: 15px;
position: relative;
box-shadow:
0 4px 6px rgba(0,0,0,0.1),
0 8px 12px rgba(0,0,0,0.08),
0 16px 24px rgba(0,0,0,0.06),
0 32px 48px rgba(0,0,0,0.04);
animation: modalSlideIn 0.3s ease-out;
}
@keyframes modalSlideIn {
from {
opacity: 0;
transform: translateY(30px) scale(0.9);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
.modal-close {
position: absolute;
top: 1rem;
right: 1rem;
background: none;
border: none;
font-size: 2rem;
color: #8b4513;
cursor: pointer;
transition: transform 0.3s ease;
}
.modal-close:hover {
transform: rotate(90deg);
}
.modal-header {
margin-bottom: 2rem;
}
.modal-title {
font-size: 2.5rem;
color: #5c3317;
margin-bottom: 0.5rem;
}
.modal-meta {
color: #8b6239;
font-family: 'Indie Flower', cursive;
}
.modal-image {
width: 100%;
height: 400px;
object-fit: cover;
border-radius: 10px;
margin-bottom: 2rem;
filter: sepia(0.05) saturate(0.95);
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
}
.modal-content-text {
color: #4a3426;
line-height: 1.8;
font-size: 1.2rem;
margin-bottom: 2rem;
}
.modal-content-text p {
margin-bottom: 1.5rem;
}
.modal-content-text p:first-child::first-letter {
font-size: 4rem;
float: left;
line-height: 1;
margin-right: 0.1em;
font-weight: 700;
color: #8b4513;
}
/* Paper clip decoration */
.paper-clip {
position: absolute;
top: -10px;
right: 30px;
width: 40px;
height: 80px;
background: linear-gradient(to right, #c0c0c0 45%, #808080 50%, #c0c0c0 55%);
border-radius: 50px;
transform: rotate(45deg);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
z-index: 5;
}
/* Coffee stain effect */
.coffee-stain {
position: absolute;
width: 80px;
height: 80px;
background: radial-gradient(ellipse at center,
rgba(139, 69, 19, 0.1) 0%,
rgba(139, 69, 19, 0.05) 40%,
transparent 70%);
border-radius: 50%;
transform: rotate(15deg);
z-index: 1;
}
.coffee-stain.top-left {
top: 20px;
left: 20px;
}
.coffee-stain.bottom-right {
bottom: 30px;
right: 40px;
width: 60px;
height: 60px;
}
/* Loading animation */
.loading-text {
font-family: 'Indie Flower', cursive;
color: #8b4513;
font-size: 1.2rem;
text-align: center;
animation: scribble 1s ease-in-out infinite;
}
@keyframes scribble {
0%, 100% { transform: translateX(0); }
25% { transform: translateX(-2px) rotate(-1deg); }
75% { transform: translateX(2px) rotate(1deg); }
}
/* Responsive design */
@media (max-width: 768px) {
.hybrid-component {
grid-template-columns: 1fr;
gap: 2rem;
}
.modal-content {
padding: 2rem;
}
.modal-title {
font-size: 2rem;
}
}
/* Accessibility */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
:focus-visible {
outline: 3px dashed #8b4513;
outline-offset: 3px;
}
</style>
</head>
<body>
<main>
<h1>Handcrafted Paper Archive</h1>
<div class="hybrid-component">
<!-- Paper Content Card 1 -->
<article class="paper-card" role="article" tabindex="0" data-id="1">
<div class="paper-clip"></div>
<div class="coffee-stain top-left"></div>
<header class="card-header">
<h2 class="card-title">The Art of Traditional Bookbinding</h2>
<div class="card-metadata">
<div class="card-date">March 15, 2025</div>
<span class="card-category">Craftsmanship</span>
</div>
</header>
<div class="card-preview">
<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 200'%3E%3Crect fill='%23f5e6d3' width='400' height='200'/%3E%3Ctext x='50%25' y='50%25' text-anchor='middle' dominant-baseline='middle' font-family='serif' font-size='20' fill='%238b4513'%3EHandmade Books%3C/text%3E%3C/svg%3E" alt="Traditional bookbinding tools" class="preview-image">
<p class="preview-text">
In the quiet corners of artisan workshops, the ancient craft of bookbinding continues to thrive. Each fold, each stitch tells a story of patience and precision...
</p>
</div>
<div class="card-tags">
<span class="tag">Traditional Crafts</span>
<span class="tag">Handmade</span>
<span class="tag">Heritage</span>
</div>
<div class="card-actions">
<button class="paper-button primary expand-btn" aria-label="Read full article">
Read More
</button>
<button class="paper-button share-btn" aria-label="Share article">
Share
</button>
<button class="favorite-button" aria-label="Add to favorites" aria-pressed="false">
</button>
<div class="share-menu" role="menu">
<div class="share-option" role="menuitem">Copy Link</div>
<div class="share-option" role="menuitem">Email</div>
<div class="share-option" role="menuitem">Print</div>
</div>
</div>
</article>
<!-- Paper Content Card 2 -->
<article class="paper-card" role="article" tabindex="0" data-id="2">
<div class="coffee-stain bottom-right"></div>
<header class="card-header">
<h2 class="card-title">Letters from a Distant Land</h2>
<div class="card-metadata">
<div class="card-date">February 28, 2025</div>
<span class="card-category">Travel Journal</span>
</div>
</header>
<div class="card-preview">
<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 200'%3E%3Crect fill='%23e8ddc7' width='400' height='200'/%3E%3Ctext x='50%25' y='50%25' text-anchor='middle' dominant-baseline='middle' font-family='serif' font-size='20' fill='%235c3317'%3EOld Map & Compass%3C/text%3E%3C/svg%3E" alt="Vintage map and compass" class="preview-image">
<p class="preview-text">
Dear reader, as I pen these words from a small café overlooking the Mediterranean, the scent of lavender drifts through the open window, mingling with fresh espresso...
</p>
</div>
<div class="card-tags">
<span class="tag">Travel</span>
<span class="tag">Letters</span>
<span class="tag">Mediterranean</span>
</div>
<div class="card-actions">
<button class="paper-button primary expand-btn" aria-label="Read full article">
Read More
</button>
<button class="paper-button share-btn" aria-label="Share article">
Share
</button>
<button class="favorite-button active" aria-label="Remove from favorites" aria-pressed="true">
</button>
<div class="share-menu" role="menu">
<div class="share-option" role="menuitem">Copy Link</div>
<div class="share-option" role="menuitem">Email</div>
<div class="share-option" role="menuitem">Print</div>
</div>
</div>
</article>
<!-- Paper Content Card 3 -->
<article class="paper-card" role="article" tabindex="0" data-id="3">
<div class="paper-clip"></div>
<header class="card-header">
<h2 class="card-title">Grandmother's Recipe Collection</h2>
<div class="card-metadata">
<div class="card-date">January 10, 2025</div>
<span class="card-category">Family Heritage</span>
</div>
</header>
<div class="card-preview">
<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 200'%3E%3Crect fill='%23f0e8d8' width='400' height='200'/%3E%3Ctext x='50%25' y='50%25' text-anchor='middle' dominant-baseline='middle' font-family='serif' font-size='20' fill='%236b4423'%3EHandwritten Recipes%3C/text%3E%3C/svg%3E" alt="Handwritten recipe cards" class="preview-image">
<p class="preview-text">
Among the yellowed pages and faded ink, generations of culinary wisdom await discovery. Each recipe card bears the gentle marks of flour-dusted fingers...
</p>
</div>
<div class="card-tags">
<span class="tag">Recipes</span>
<span class="tag">Family</span>
<span class="tag">Tradition</span>
<span class="tag">Cooking</span>
</div>
<div class="card-actions">
<button class="paper-button primary expand-btn" aria-label="Read full article">
Read More
</button>
<button class="paper-button share-btn" aria-label="Share article">
Share
</button>
<button class="favorite-button" aria-label="Add to favorites" aria-pressed="false">
</button>
<div class="share-menu" role="menu">
<div class="share-option" role="menuitem">Copy Link</div>
<div class="share-option" role="menuitem">Email</div>
<div class="share-option" role="menuitem">Print</div>
</div>
</div>
</article>
<!-- Paper Content Card 4 -->
<article class="paper-card" role="article" tabindex="0" data-id="4">
<div class="coffee-stain top-left"></div>
<div class="coffee-stain bottom-right"></div>
<header class="card-header">
<h2 class="card-title">Field Notes: Urban Sketching</h2>
<div class="card-metadata">
<div class="card-date">March 5, 2025</div>
<span class="card-category">Art Journal</span>
</div>
</header>
<div class="card-preview">
<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 200'%3E%3Crect fill='%23faf8f4' width='400' height='200'/%3E%3Ctext x='50%25' y='50%25' text-anchor='middle' dominant-baseline='middle' font-family='serif' font-size='20' fill='%238b6239'%3ESketch of City Streets%3C/text%3E%3C/svg%3E" alt="Urban sketches" class="preview-image">
<p class="preview-text">
With pencil in hand and sketchbook at ready, the city reveals its hidden poetry. Every corner holds a story, every shadow a secret waiting to be captured...
</p>
</div>
<div class="card-tags">
<span class="tag">Art</span>
<span class="tag">Sketching</span>
<span class="tag">Urban</span>
</div>
<div class="card-actions">
<button class="paper-button primary expand-btn" aria-label="Read full article">
Read More
</button>
<button class="paper-button share-btn" aria-label="Share article">
Share
</button>
<button class="favorite-button" aria-label="Add to favorites" aria-pressed="false">
</button>
<div class="share-menu" role="menu">
<div class="share-option" role="menuitem">Copy Link</div>
<div class="share-option" role="menuitem">Email</div>
<div class="share-option" role="menuitem">Print</div>
</div>
</div>
</article>
<!-- Paper Content Card 5 -->
<article class="paper-card" role="article" tabindex="0" data-id="5">
<div class="paper-clip"></div>
<header class="card-header">
<h2 class="card-title">The Botanist's Diary</h2>
<div class="card-metadata">
<div class="card-date">March 20, 2025</div>
<span class="card-category">Nature Study</span>
</div>
</header>
<div class="card-preview">
<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 200'%3E%3Crect fill='%23f3ead9' width='400' height='200'/%3E%3Ctext x='50%25' y='50%25' text-anchor='middle' dominant-baseline='middle' font-family='serif' font-size='20' fill='%234a3426'%3EPressed Flowers%3C/text%3E%3C/svg%3E" alt="Pressed flowers and botanical notes" class="preview-image">
<p class="preview-text">
Spring has arrived in earnest, bringing with it a symphony of blooms. Today I discovered a rare species of wildflower hidden among the moss-covered stones...
</p>
</div>
<div class="card-tags">
<span class="tag">Botany</span>
<span class="tag">Nature</span>
<span class="tag">Science</span>
<span class="tag">Journal</span>
</div>
<div class="card-actions">
<button class="paper-button primary expand-btn" aria-label="Read full article">
Read More
</button>
<button class="paper-button share-btn" aria-label="Share article">
Share
</button>
<button class="favorite-button active" aria-label="Remove from favorites" aria-pressed="true">
</button>
<div class="share-menu" role="menu">
<div class="share-option" role="menuitem">Copy Link</div>
<div class="share-option" role="menuitem">Email</div>
<div class="share-option" role="menuitem">Print</div>
</div>
</div>
</article>
<!-- Paper Content Card 6 -->
<article class="paper-card" role="article" tabindex="0" data-id="6">
<div class="coffee-stain bottom-right"></div>
<header class="card-header">
<h2 class="card-title">Poet's Corner: Evening Verses</h2>
<div class="card-metadata">
<div class="card-date">February 14, 2025</div>
<span class="card-category">Poetry</span>
</div>
</header>
<div class="card-preview">
<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 200'%3E%3Crect fill='%23e8ddc7' width='400' height='200'/%3E%3Ctext x='50%25' y='50%25' text-anchor='middle' dominant-baseline='middle' font-family='serif' font-size='20' fill='%235c3317'%3EQuill and Inkwell%3C/text%3E%3C/svg%3E" alt="Quill pen and poetry" class="preview-image">
<p class="preview-text">
When twilight paints the sky in shades of rose and gold, the muse awakens. These verses, born of quiet contemplation, speak of love, loss, and the eternal dance...
</p>
</div>
<div class="card-tags">
<span class="tag">Poetry</span>
<span class="tag">Literature</span>
<span class="tag">Creative Writing</span>
</div>
<div class="card-actions">
<button class="paper-button primary expand-btn" aria-label="Read full article">
Read More
</button>
<button class="paper-button share-btn" aria-label="Share article">
Share
</button>
<button class="favorite-button" aria-label="Add to favorites" aria-pressed="false">
</button>
<div class="share-menu" role="menu">
<div class="share-option" role="menuitem">Copy Link</div>
<div class="share-option" role="menuitem">Email</div>
<div class="share-option" role="menuitem">Print</div>
</div>
</div>
</article>
</div>
</main>
<!-- Modal Overlay -->
<div class="modal-overlay" id="modalOverlay">
<div class="modal-content" role="dialog" aria-modal="true">
<button class="modal-close" aria-label="Close modal">&times;</button>
<div id="modalContentArea">
<!-- Dynamic content will be loaded here -->
</div>
</div>
</div>
<script>
// Handcrafted Paper Content Card System Controller
class PaperContentSystem {
constructor() {
this.cards = document.querySelectorAll('.paper-card');
this.modalOverlay = document.getElementById('modalOverlay');
this.modalContentArea = document.getElementById('modalContentArea');
this.activeShareMenu = null;
// Extended content for modal view
this.fullContent = {
1: {
title: "The Art of Traditional Bookbinding",
date: "March 15, 2025",
category: "Craftsmanship",
image: "Traditional bookbinding tools",
content: `
<p>In the quiet corners of artisan workshops, the ancient craft of bookbinding continues to thrive. Each fold, each stitch tells a story of patience and precision passed down through generations of craftspeople.</p>
<p>The process begins with carefully selected papers, each sheet examined for grain direction and quality. The bone folder, worn smooth by countless projects, becomes an extension of the binder's hand as pages are folded into signatures.</p>
<p>Thread, waxed and strong, weaves through the spine in patterns unchanged for centuries. The satisfying rhythm of needle through paper creates a meditation of craft, where time seems to slow and the modern world fades away.</p>
<p>In this digital age, the handmade book stands as a testament to the enduring power of tactile beauty. Each volume is unique, bearing the subtle marks of its maker a thumbprint in the paste, a slightly irregular stitch that speaks of human touch.</p>
`
},
2: {
title: "Letters from a Distant Land",
date: "February 28, 2025",
category: "Travel Journal",
image: "Vintage map and compass",
content: `
<p>Dear reader, as I pen these words from a small café overlooking the Mediterranean, the scent of lavender drifts through the open window, mingling with fresh espresso and the salt-tinged breeze from the harbor below.</p>
<p>This morning, I wandered through cobblestone streets older than memory, where each weathered door holds secrets and every balcony overflows with geraniums. The locals greet the day with unhurried grace, their conversations a melodic dance I'm only beginning to understand.</p>
<p>Yesterday, I discovered a forgotten garden behind the cathedral, where orange trees heavy with fruit provide shade for stone benches worn smooth by centuries of contemplation. There, I met an elderly woman feeding breadcrumbs to sparrows, who shared stories of the town in broken English mixed with expressive gestures.</p>
<p>Each sunset here paints the sky in impossible shades of coral and gold, reminding me why we travel not just to see new places, but to see ourselves anew in their reflection.</p>
`
},
3: {
title: "Grandmother's Recipe Collection",
date: "January 10, 2025",
category: "Family Heritage",
image: "Handwritten recipe cards",
content: `
<p>Among the yellowed pages and faded ink, generations of culinary wisdom await discovery. Each recipe card bears the gentle marks of flour-dusted fingers and the occasional splash of vanilla extract, evidence of countless family gatherings.</p>
<p>"A pinch of this, a dash of that," the cards read in grandmother's careful script. Measurements given in teacups and soup spoons, temperatures described as "hot as a summer day" or "warm as fresh milk." These recipes speak a language of intuition and experience.</p>
<p>Here, her famous apple pie recipe includes a note: "Roll the dough with love, not force. It knows when you're in a hurry." Below, in different ink, my mother has added: "She always sang while making this."</p>
<p>These cards are more than instructions; they're a family memoir written in cinnamon and sugar, preserving not just flavors but the warmth of kitchens past, where love was the most important ingredient.</p>
`
},
4: {
title: "Field Notes: Urban Sketching",
date: "March 5, 2025",
category: "Art Journal",
image: "Urban sketches",
content: `
<p>With pencil in hand and sketchbook at ready, the city reveals its hidden poetry. Every corner holds a story, every shadow a secret waiting to be captured in graphite and wash.</p>
<p>Today's subject: the corner café where businesspeople and artists collide over morning coffee. Quick gestural lines capture the barista's practiced movements, while careful shading brings depth to the steam rising from espresso machines.</p>
<p>A homeless man's weathered face tells decades of stories in every line. I sketch quickly, respectfully, trying to capture dignity rather than circumstance. He notices and nods a moment of connection across the divide.</p>
<p>Urban sketching teaches patience and observation. It's not about creating perfect drawings but about truly seeing the way light falls on wet pavement, how crowds move like water, the unexpected beauty in ordinary moments.</p>
`
},
5: {
title: "The Botanist's Diary",
date: "March 20, 2025",
category: "Nature Study",
image: "Pressed flowers and botanical notes",
content: `
<p>Spring has arrived in earnest, bringing with it a symphony of blooms. Today I discovered a rare species of wildflower hidden among the moss-covered stones near the old mill stream.</p>
<p>Specimen #47: Viola sororia, the common blue violet, though there's nothing common about the way morning dew transforms its petals into tiny prisms. Pressed between these pages, it will lose its dimension but retain its essence a bookmark in time.</p>
<p>The art of botanical preservation requires patience. Each specimen must be arranged just so, capturing not just its structure but its gesture the way it reached for light, how its leaves unfurled in their particular dance.</p>
<p>These pages become a dialogue between science and art, where Latin names share space with pressed petals and personal observations. Each entry is both data and poetry, fact and feeling intertwined like vine and trellis.</p>
`
},
6: {
title: "Poet's Corner: Evening Verses",
date: "February 14, 2025",
category: "Poetry",
image: "Quill pen and poetry",
content: `
<p>When twilight paints the sky in shades of rose and gold, the muse awakens. These verses, born of quiet contemplation, speak of love, loss, and the eternal dance between light and shadow.</p>
<p><em>Evening Sonnet:</em><br>
The day retreats on silent, gilded wings,<br>
While shadows lengthen on the garden wall.<br>
The nightingale prepares the songs she sings,<br>
As one by one the evening stars enthrall.</p>
<p><em>Haiku Collection:</em><br>
Old paper yellows—<br>
Yet words remain forever<br>
Young upon the page.</p>
<p>Poetry is the art of distillation, reducing experience to its essence. In these evening hours, when the world softens and blurs, truth emerges in metaphor and rhythm, saying what prose cannot.</p>
`
}
};
this.init();
}
init() {
this.bindEvents();
this.animateCards();
}
bindEvents() {
// Card interactions
this.cards.forEach(card => {
const expandBtn = card.querySelector('.expand-btn');
const shareBtn = card.querySelector('.share-btn');
const favoriteBtn = card.querySelector('.favorite-button');
const shareMenu = card.querySelector('.share-menu');
const tags = card.querySelectorAll('.tag');
// Expand to modal
expandBtn.addEventListener('click', (e) => {
e.stopPropagation();
this.openModal(card.dataset.id);
});
// Card click to expand
card.addEventListener('click', () => {
this.openModal(card.dataset.id);
});
// Share functionality
shareBtn.addEventListener('click', (e) => {
e.stopPropagation();
this.toggleShareMenu(shareMenu);
});
// Favorite toggle
favoriteBtn.addEventListener('click', (e) => {
e.stopPropagation();
this.toggleFavorite(favoriteBtn);
});
// Share menu options
shareMenu.querySelectorAll('.share-option').forEach(option => {
option.addEventListener('click', (e) => {
e.stopPropagation();
this.handleShare(option.textContent, card);
});
});
// Tag interactions
tags.forEach(tag => {
tag.addEventListener('click', (e) => {
e.stopPropagation();
this.filterByTag(tag.textContent);
});
});
// Keyboard navigation
card.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
this.openModal(card.dataset.id);
}
});
});
// Modal interactions
this.modalOverlay.addEventListener('click', (e) => {
if (e.target === this.modalOverlay) {
this.closeModal();
}
});
// Close modal button
document.querySelector('.modal-close').addEventListener('click', () => {
this.closeModal();
});
// Close share menus on outside click
document.addEventListener('click', () => {
if (this.activeShareMenu) {
this.activeShareMenu.classList.remove('active');
this.activeShareMenu = null;
}
});
// Keyboard shortcuts
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && this.modalOverlay.classList.contains('active')) {
this.closeModal();
}
});
}
openModal(cardId) {
const content = this.fullContent[cardId];
if (!content) return;
this.modalContentArea.innerHTML = `
<header class="modal-header">
<h2 class="modal-title">${content.title}</h2>
<div class="modal-meta">
<span>${content.date}</span> • <span>${content.category}</span>
</div>
</header>
<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 800 400'%3E%3Crect fill='%23f5e6d3' width='800' height='400'/%3E%3Ctext x='50%25' y='50%25' text-anchor='middle' dominant-baseline='middle' font-family='serif' font-size='30' fill='%238b4513'%3E${content.image}%3C/text%3E%3C/svg%3E" alt="${content.image}" class="modal-image">
<div class="modal-content-text">
${content.content}
</div>
`;
this.modalOverlay.classList.add('active');
document.body.style.overflow = 'hidden';
// Focus management
this.modalOverlay.querySelector('.modal-close').focus();
}
closeModal() {
this.modalOverlay.classList.remove('active');
document.body.style.overflow = '';
// Return focus to the card that opened the modal
const activeCard = document.querySelector('.paper-card:focus');
if (activeCard) {
activeCard.focus();
}
}
toggleShareMenu(menu) {
if (this.activeShareMenu && this.activeShareMenu !== menu) {
this.activeShareMenu.classList.remove('active');
}
menu.classList.toggle('active');
this.activeShareMenu = menu.classList.contains('active') ? menu : null;
}
toggleFavorite(button) {
const isActive = button.classList.contains('active');
button.classList.toggle('active');
button.setAttribute('aria-pressed', !isActive);
// Add animation feedback
button.style.animation = 'none';
setTimeout(() => {
button.style.animation = '';
}, 10);
}
handleShare(action, card) {
const title = card.querySelector('.card-title').textContent;
const url = window.location.href + '#' + card.dataset.id;
switch(action) {
case 'Copy Link':
navigator.clipboard.writeText(url).then(() => {
this.showToast('Link copied to clipboard!');
});
break;
case 'Email':
window.location.href = `mailto:?subject=${encodeURIComponent(title)}&body=${encodeURIComponent('Check out this article: ' + url)}`;
break;
case 'Print':
window.print();
break;
}
// Close share menu
if (this.activeShareMenu) {
this.activeShareMenu.classList.remove('active');
this.activeShareMenu = null;
}
}
filterByTag(tag) {
this.showToast(`Filtering by: ${tag}`);
// In a real implementation, this would filter the displayed cards
}
showToast(message) {
const toast = document.createElement('div');
toast.className = 'toast';
toast.textContent = message;
toast.style.cssText = `
position: fixed;
bottom: 2rem;
left: 50%;
transform: translateX(-50%);
background: #5c3317;
color: #fdfbf7;
padding: 1rem 2rem;
border-radius: 25px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
font-family: 'Kalam', cursive;
animation: toastSlide 0.3s ease-out;
z-index: 200;
`;
document.body.appendChild(toast);
setTimeout(() => {
toast.style.animation = 'toastSlide 0.3s ease-out reverse';
setTimeout(() => {
document.body.removeChild(toast);
}, 300);
}, 2000);
}
animateCards() {
// Add subtle animations to cards on load
this.cards.forEach((card, index) => {
card.style.opacity = '0';
card.style.transform = 'translateY(20px) rotate(-1deg)';
setTimeout(() => {
card.style.transition = 'opacity 0.5s ease-out, transform 0.5s ease-out';
card.style.opacity = '1';
card.style.transform = card.style.transform.replace('translateY(20px)', 'translateY(0)');
}, index * 100);
});
}
}
// Initialize the system
document.addEventListener('DOMContentLoaded', () => {
new PaperContentSystem();
});
// Add toast animation
const style = document.createElement('style');
style.textContent = `
@keyframes toastSlide {
from {
opacity: 0;
transform: translateX(-50%) translateY(20px);
}
to {
opacity: 1;
transform: translateX(-50%) translateY(0);
}
}
`;
document.head.appendChild(style);
</script>
</body>
</html>