Paper effects can add a touch of elegance and realism to your digital designs. These effects mimic the texture and appearance of real paper, creating a tactile experience for users.
In this article, we will explore 10 stunning paper effect examples that can elevate your UI projects. Each example showcases unique techniques and styles to inspire your next design.
CODE1
Here's the code:
CODETEXT1
CODE2
Here's the code:
CODETEXT2
CODE3
Here's the code:
CODETEXT3
CODE4
Here's the code:
CODETEXT4
CODE5
Here's the code:
CODETEXT5
Subframe's drag-and-drop interface and intuitive, responsive canvas make it effortless to design pixel-perfect UIs, including stunning paper effects. Loved by designers and developers alike, Subframe ensures your creations are both beautiful and functional.
Start for free and bring your paper effect designs to life with Subframe today!
CODE6
Here's the code:
CODETEXT6
CODE7
Here's the code:
CODETEXT7
CODE8
Here's the code:
CODETEXT8
CODE9
Here's the code:
CODETEXT9
CODE10
Here's the code:
CODETEXT10
Ready to elevate your UI designs with stunning paper effects? Subframe's intuitive drag-and-drop interface allows you to create pixel-perfect UIs efficiently and effortlessly.
Start designing immediately and bring your creative visions to life. Start for free with Subframe today!
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> :root { --parchment-color: #f8f0e0; --shadow-color: rgba(0, 0, 0, 0.1); --ink-color: #2a1a0a; --ink-hover: #854c1d; --margin-color: #e4d5b7; --bookmark-color: #a34c4c; } * { margin: 0; padding: 0; box-sizing: border-box; } body { background-color: #302c2a; font-family: 'Libre Baskerville', 'Baskerville', Georgia, serif; display: flex; justify-content: center; align-items: center; height: 100vh; overflow: hidden; color: var(--ink-color); background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><rect width="100" height="100" fill="%23302c2a"/><path d="M0 50 L100 50 M50 0 L50 100" stroke="%23252220" stroke-width="0.5" stroke-dasharray="2,8"/></svg>'); } .digital-library { width: 680px; height: 680px; position: relative; perspective: 1500px; } .book { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transform: rotateY(0deg); transition: transform 0.8s cubic-bezier(0.4, 0, 0.2, 1); box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3); } .book:hover { transform: rotateY(5deg); } .book-cover, .book-pages { position: absolute; width: 100%; height: 100%; border-radius: 5px; overflow: hidden; } .book-cover { background: linear-gradient(45deg, #5c3a21 0%, #8b5a2b 100%); z-index: 1; display: flex; justify-content: center; align-items: center; padding: 20px; box-shadow: inset 0 0 30px rgba(0, 0, 0, 0.5); transform: translateZ(2px); backface-visibility: hidden; } .book-cover-title { color: #f8f0e0; text-align: center; font-size: 2.2rem; font-weight: 700; letter-spacing: 2px; text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); } .book-cover-subtitle { color: #e4d5b7; text-align: center; font-size: 1.2rem; margin-top: 10px; font-style: italic; } .book-spine { position: absolute; width: 30px; height: 100%; background: linear-gradient(to right, #4a2e1a, #6b4425, #4a2e1a); left: -15px; transform: rotateY(-90deg) translateZ(15px); box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.6); z-index: 0; } .book-pages { background: var(--parchment-color); z-index: 2; padding: 40px; display: flex; flex-direction: column; overflow-y: auto; scroll-behavior: smooth; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 200 200"><filter id="noise"><feTurbulence type="fractalNoise" baseFrequency="0.8" numOctaves="3" stitchTiles="stitch"/><feColorMatrix type="matrix" values="0.3 0 0 0 0 0 0.3 0 0 0 0 0 0.3 0 0 0 0 0 0.5 0"/></filter><rect width="200" height="200" filter="url(%23noise)" opacity="0.05"/></svg>'), radial-gradient(circle at center, var(--parchment-color), #e8daba); box-shadow: inset 0 0 20px var(--shadow-color), inset 0 0 3px var(--shadow-color); } .page-content { position: relative; flex: 1; } .crease-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; background-image: linear-gradient(90deg, transparent 0%, rgba(0,0,0,0.03) 50%, transparent 100%), linear-gradient(to right, transparent 0%, rgba(0,0,0,0.01) 5%, transparent 10%, rgba(0,0,0,0.01) 15%, transparent 20%, rgba(0,0,0,0.01) 25%, transparent 30%, rgba(0,0,0,0.01) 35%, transparent 40%); } .book-header { display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid rgba(0, 0, 0, 0.1); padding-bottom: 15px; margin-bottom: 20px; } .header-title { font-size: 1.6rem; font-weight: normal; letter-spacing: 1px; } .search-bar { position: relative; display: flex; align-items: center; } .search-input { background-color: rgba(255, 255, 255, 0.5); border: 1px solid rgba(0, 0, 0, 0.2); padding: 8px 12px 8px 35px; border-radius: 20px; font-family: inherit; font-size: 0.9rem; color: var(--ink-color); width: 180px; transition: all 0.3s ease; } .search-input:focus { outline: none; width: 220px; background-color: rgba(255, 255, 255, 0.7); box-shadow: 0 0 5px rgba(0, 0, 0, 0.1); } .search-icon { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); color: rgba(0, 0, 0, 0.4); font-size: 1rem; } .book-nav { display: flex; margin-bottom: 25px; } .nav-item { cursor: pointer; padding: 8px 15px; margin-right: 10px; border-radius: 3px; transition: all 0.25s ease; position: relative; font-size: 0.9rem; } .nav-item:after { content: ''; position: absolute; bottom: 0; left: 0; width: 0; height: 2px; background-color: var(--ink-hover); transition: width 0.3s ease; } .nav-item:hover:after, .nav-item.active:after { width: 100%; } .nav-item.active { font-weight: 600; } .books-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 25px; margin-bottom: 30px; } .book-item { background-color: rgba(255, 255, 255, 0.2); border-radius: 5px; padding: 15px; cursor: pointer; transition: all 0.3s ease; position: relative; overflow: hidden; box-shadow: 0 3px 8px var(--shadow-color); } .book-item:before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-image: linear-gradient(to bottom right, rgba(0,0,0,0.02), transparent); pointer-events: none; } .book-item:after { content: ''; position: absolute; bottom: 0; right: 0; width: 30px; height: 30px; background: linear-gradient(135deg, transparent 50%, rgba(0,0,0,0.05) 50%); border-radius: 0 0 5px 0; transition: all 0.3s ease; } .book-item:hover { transform: translateY(-3px); box-shadow: 0 6px 12px var(--shadow-color); } .book-item-title { font-size: 1.1rem; margin-bottom: 8px; color: var(--ink-color); font-weight: 600; } .book-item-author { font-style: italic; font-size: 0.9rem; margin-bottom: 12px; color: rgba(42, 26, 10, 0.8); } .book-item-description { font-size: 0.85rem; line-height: 1.5; margin-bottom: 15px; color: rgba(42, 26, 10, 0.9); } .book-item-meta { display: flex; justify-content: space-between; align-items: center; font-size: 0.8rem; color: rgba(42, 26, 10, 0.7); } .bookmark { position: absolute; top: -6px; right: 20px; width: 18px; height: 30px; background-color: var(--bookmark-color); border-radius: 2px 2px 8px 8px; transform: translateY(-100%); transition: transform 0.3s ease; z-index: 10; } .book-item:hover .bookmark { transform: translateY(0); } .progress-bar { width: 60px; height: 6px; background-color: rgba(0, 0, 0, 0.1); border-radius: 3px; overflow: hidden; } .progress-fill { height: 100%; background-color: var(--ink-hover); border-radius: 3px; transition: width 0.5s ease; } .book-item .ink-hover { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: transparent; pointer-events: none; z-index: 5; transition: background-color 0.3s ease; mix-blend-mode: multiply; opacity: 0; } .book-item:hover .ink-hover { background-color: rgba(0, 0, 0, 0.02); opacity: 1; } .recently-viewed { margin-top: 25px; } .section-title { font-size: 1.2rem; margin-bottom: 15px; font-weight: normal; position: relative; display: inline-block; } .section-title:after { content: ''; position: absolute; bottom: -4px; left: 0; width: 100%; height: 1px; background-color: rgba(0, 0, 0, 0.1); } .recent-books { display: flex; gap: 15px; overflow-x: auto; padding-bottom: 15px; position: relative; } .recent-book { min-width: 140px; height: 90px; background-color: rgba(255, 255, 255, 0.2); border-radius: 4px; padding: 10px; cursor: pointer; transition: all 0.3s ease; box-shadow: 0 2px 5px var(--shadow-color); position: relative; display: flex; flex-direction: column; } .recent-book:hover { transform: translateY(-2px); box-shadow: 0 4px 8px var(--shadow-color); } .recent-book-title { font-size: 0.9rem; font-weight: 600; margin-bottom: 5px; line-height: 1.3; } .recent-book-author { font-size: 0.8rem; font-style: italic; color: rgba(42, 26, 10, 0.8); } .pagination { display: flex; justify-content: center; margin-top: 20px; } .page-button { width: 35px; height: 35px; display: flex; justify-content: center; align-items: center; margin: 0 5px; border-radius: 50%; cursor: pointer; transition: all 0.3s ease; background-color: transparent; color: var(--ink-color); font-family: inherit; font-size: 0.9rem; border: 1px solid rgba(0, 0, 0, 0.1); } .page-button:hover { background-color: rgba(0, 0, 0, 0.05); } .page-button.active { background-color: var(--ink-color); color: var(--parchment-color); border-color: var(--ink-color); } /* Scroll styling */ .book-pages::-webkit-scrollbar { width: 5px; } .book-pages::-webkit-scrollbar-track { background: rgba(0, 0, 0, 0.05); border-radius: 10px; } .book-pages::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, 0.15); border-radius: 10px; } .book-pages::-webkit-scrollbar-thumb:hover { background: rgba(0, 0, 0, 0.2); } .page-turner { position: absolute; width: 50px; height: 50px; border-radius: 50%; background-color: rgba(255, 255, 255, 0.6); display: flex; justify-content: center; align-items: center; cursor: pointer; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); transition: all 0.3s ease; z-index: 10; } .page-turner:hover { background-color: rgba(255, 255, 255, 0.8); transform: scale(1.05); } .turn-left { top: 50%; left: -25px; transform: translateY(-50%); } .turn-right { top: 50%; right: -25px; transform: translateY(-50%); } .page-effect { pointer-events: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(to right, rgba(0,0,0,0.04) 0%, transparent 5%, transparent 95%, rgba(0,0,0,0.04) 100%); } .page-shadow { pointer-events: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%; box-shadow: inset 0 0 30px rgba(0, 0, 0, 0.1); border-radius: 5px; } /* Responsive adjustments */ @media (max-width: 650px) { .books-grid { grid-template-columns: 1fr; } .book-header { flex-direction: column; align-items: flex-start; gap: 15px; } .header-title { font-size: 1.3rem; } .search-input { width: 100%; } } </style> </head> <body> <div class="digital-library"> <div class="book"> <div class="book-spine"></div> <div class="book-cover"> <div> <h1 class="book-cover-title">THE ALEXANDRIA ARCHIVE</h1> <div class="book-cover-subtitle">A Digital Collection of Literary Treasures</div> </div> </div> <div class="book-pages"> <div class="page-content"> <div class="book-header"> <h2 class="header-title">The Alexandria Archive</h2> <div class="search-bar"> <span class="search-icon">⌕</span> <input type="text" class="search-input" placeholder="Search manuscripts..."> </div> </div> <div class="book-nav"> <div class="nav-item active" data-section="classics">Classics</div> <div class="nav-item" data-section="philosophy">Philosophy</div> <div class="nav-item" data-section="poetry">Poetry</div> <div class="nav-item" data-section="science">Science</div> </div> <div class="books-grid"> <div class="book-item"> <div class="bookmark"></div> <div class="ink-hover"></div> <h3 class="book-item-title">The Odyssey</h3> <div class="book-item-author">Homer, 8th Century BCE</div> <p class="book-item-description">Follow Odysseus's journey home after the Trojan War, facing mythical creatures and divine challenges across the ancient Mediterranean.</p> <div class="book-item-meta"> <span>Last read: Yesterday</span> <div class="progress-bar"> <div class="progress-fill" style="width: 75%"></div> </div> </div> </div> <div class="book-item"> <div class="bookmark"></div> <div class="ink-hover"></div> <h3 class="book-item-title">Meditations</h3> <div class="book-item-author">Marcus Aurelius, 170-180 CE</div> <p class="book-item-description">Personal writings of the Roman Emperor on Stoic philosophy, addressing rationality, virtue, and the unpredictability of nature.</p> <div class="book-item-meta"> <span>Last read: 3 days ago</span> <div class="progress-bar"> <div class="progress-fill" style="width: 40%"></div> </div> </div> </div> <div class="book-item"> <div class="bookmark"></div> <div class="ink-hover"></div> <h3 class="book-item-title">Canterbury Tales</h3> <div class="book-item-author">Geoffrey Chaucer, 1387-1400</div> <p class="book-item-description">A collection of stories told by pilgrims traveling to Canterbury, offering a vivid cross-section of 14th century English society.</p> <div class="book-item-meta"> <span>Last read: 1 week ago</span> <div class="progress-bar"> <div class="progress-fill" style="width: 15%"></div> </div> </div> </div> <div class="book-item"> <div class="bookmark"></div> <div class="ink-hover"></div> <h3 class="book-item-title">Don Quixote</h3> <div class="book-item-author">Miguel de Cervantes, 1605</div> <p class="book-item-description">Chronicles the adventures of an aging nobleman who, under the influence of chivalric romances, sets out to revive knighthood.</p> <div class="book-item-meta"> <span>Last read: 2 weeks ago</span> <div class="progress-bar"> <div class="progress-fill" style="width: 60%"></div> </div> </div> </div> </div> <div class="pagination"> <button class="page-button active">1</button> <button class="page-button">2</button> <button class="page-button">3</button> <button class="page-button">></button> </div> <div class="recently-viewed"> <h3 class="section-title">Recently Viewed Manuscripts</h3> <div class="recent-books"> <div class="recent-book"> <div class="recent-book-title">The Republic</div> <div class="recent-book-author">Plato</div> </div> <div class="recent-book"> <div class="recent-book-title">The Divine Comedy</div> <div class="recent-book-author">Dante Alighieri</div> </div> <div class="recent-book"> <div class="recent-book-title">The Prince</div> <div class="recent-book-author">Niccolò Machiavelli</div> </div> <div class="recent-book"> <div class="recent-book-title">Hamlet</div> <div class="recent-book-author">William Shakespeare</div> </div> </div> </div> </div> <div class="crease-overlay"></div> <div class="page-effect"></div> <div class="page-shadow"></div> </div> </div> <div class="page-turner turn-left">◀</div> <div class="page-turner turn-right">▶</div> </div> <script> document.addEventListener('DOMContentLoaded', () => { // Navigation functionality const navItems = document.querySelectorAll('.nav-item'); navItems.forEach(item => { item.addEventListener('click', () => { navItems.forEach(ni => ni.classList.remove('active')); item.classList.add('active'); // Add page turning animation const book = document.querySelector('.book'); book.style.transform = 'rotateY(10deg)'; setTimeout(() => { book.style.transform = 'rotateY(0deg)'; }, 600); }); }); // Pagination functionality const paginationButtons = document.querySelectorAll('.page-button'); paginationButtons.forEach(button => { button.addEventListener('click', () => { paginationButtons.forEach(btn => btn.classList.remove('active')); button.classList.add('active'); }); }); // Book item hover effect with digital ink const bookItems = document.querySelectorAll('.book-item'); bookItems.forEach(book => { book.addEventListener('mouseenter', (e) => { const inkEffect = book.querySelector('.ink-hover'); inkEffect.style.opacity = '1'; // Create dynamic ink trail book.addEventListener('mousemove', (moveEvent) => { const rect = book.getBoundingClientRect(); const x = moveEvent.clientX - rect.left; const y = moveEvent.clientY - rect.top; // Apply subtle ink effect around cursor position inkEffect.style.background = `radial-gradient(circle at ${x}px ${y}px, rgba(133, 76, 29, 0.07), transparent 60%)`; }); }); book.addEventListener('mouseleave', () => { const inkEffect = book.querySelector('.ink-hover'); inkEffect.style.opacity = '0'; }); }); // Page turning buttons const turnLeftBtn = document.querySelector('.turn-left'); const turnRightBtn = document.querySelector('.turn-right'); const book = document.querySelector('.book'); turnLeftBtn.addEventListener('click', () => { book.style.transform = 'rotateY(-5deg)'; setTimeout(() => { book.style.transform = 'rotateY(0deg)'; }, 600); }); turnRightBtn.addEventListener('click', () => { book.style.transform = 'rotateY(5deg)'; setTimeout(() => { book.style.transform = 'rotateY(0deg)'; }, 600); }); // Search input animation const searchInput = document.querySelector('.search-input'); searchInput.addEventListener('focus', () => { searchInput.style.width = '220px'; searchInput.style.backgroundColor = 'rgba(255, 255, 255, 0.7)'; }); searchInput.addEventListener('blur', () => { if (searchInput.value === '') { searchInput.style.width = '180px'; searchInput.style.backgroundColor = 'rgba(255, 255, 255, 0.5)'; } }); // Recent books hover effect const recentBooks = document.querySelectorAll('.recent-book'); recentBooks.forEach(book => { book.addEventListener('mouseenter', () => { book.style.backgroundColor = 'rgba(255, 255, 255, 0.3)'; }); book.addEventListener('mouseleave', () => { book.style.backgroundColor = 'rgba(255, 255, 255, 0.2)'; }); }); // Initialize book progress bars with animation const progressBars = document.querySelectorAll('.progress-fill'); setTimeout(() => { progressBars.forEach(bar => { const width = bar.style.width; bar.style.width = '0'; setTimeout(() => { bar.style.width = width; }, 300); }); }, 500); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> :root { --primary-color: #f8f5e6; --secondary-color: #2b2118; --accent-color: #8b5a2b; --ink-blot: #1e1e1e; --paper-shadow: rgba(0,0,0,0.2); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Times New Roman', Times, serif; } body { background-color: #f0f0f0; height: 100vh; width: 100%; overflow-x: hidden; } .container { max-width: 700px; margin: 0 auto; height: 100%; overflow: auto; padding-top: 130px; position: relative; background-image: url("data:image/svg+xml,%3Csvg width='100' height='100' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise' x='0' y='0'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeBlend mode='multiply' in='SourceGraphic'/%3E%3C/filter%3E%3Crect width='100' height='100' filter='url(%23noise)' opacity='0.1'/%3E%3C/svg%3E"); } .header { position: fixed; top: 0; width: 100%; max-width: 700px; z-index: 100; transition: transform 0.3s ease; } .header-container { background-color: var(--primary-color); padding: 15px 20px; box-shadow: 0 4px 8px var(--paper-shadow); position: relative; clip-path: polygon(0 0, 100% 0, 100% calc(100% - 5px), 95% 100%, 90% calc(100% - 3px), 85% 100%, 80% calc(100% - 4px), 75% 100%, 70% calc(100% - 2px), 65% 100%, 60% calc(100% - 3px), 55% 100%, 50% calc(100% - 5px), 45% 100%, 40% calc(100% - 3px), 35% 100%, 30% calc(100% - 4px), 25% 100%, 20% calc(100% - 2px), 15% 100%, 10% calc(100% - 3px), 5% 100%, 0 calc(100% - 5px)); } .header-texture { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-image: url("data:image/svg+xml,%3Csvg width='100' height='100' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise' x='0' y='0'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeBlend mode='multiply' in='SourceGraphic'/%3E%3C/filter%3E%3Crect width='100' height='100' filter='url(%23noise)' opacity='0.2'/%3E%3C/svg%3E"); opacity: 0.8; pointer-events: none; } .header-title { text-align: center; margin-bottom: 15px; position: relative; } .masthead { font-size: 48px; font-weight: 700; font-family: 'Times New Roman', Times, serif; color: var(--secondary-color); letter-spacing: -1px; line-height: 1; position: relative; display: inline-block; text-shadow: 2px 2px 0 rgba(0,0,0,0.1); } .masthead::before { content: ""; position: absolute; top: -2px; left: -5px; width: 15px; height: 15px; background-color: var(--ink-blot); border-radius: 50%; filter: blur(5px); opacity: 0.1; transform: rotate(-15deg); } .masthead::after { content: ""; position: absolute; bottom: 10px; right: -5px; width: 8px; height: 8px; background-color: var(--ink-blot); border-radius: 50%; filter: blur(3px); opacity: 0.1; transform: rotate(25deg); } .tagline { font-style: italic; color: var(--accent-color); font-size: 14px; letter-spacing: 1px; margin-top: -5px; } .date { font-size: 14px; color: var(--secondary-color); opacity: 0.8; font-weight: 600; position: absolute; right: 20px; top: 15px; } .nav { display: flex; justify-content: space-around; border-top: 2px solid var(--secondary-color); border-bottom: 2px solid var(--secondary-color); padding: 8px 0; position: relative; } .nav-item { color: var(--secondary-color); text-decoration: none; font-size: 16px; padding: 5px 10px; font-weight: 600; transition: all 0.3s ease; position: relative; overflow: hidden; } .nav-item::before { content: ""; position: absolute; bottom: 0; left: 0; width: 100%; height: 2px; background-color: var(--accent-color); transform: translateX(-100%); transition: transform 0.3s ease; } .nav-item:hover { color: var(--accent-color); } .nav-item:hover::before { transform: translateX(0); } .ink-blot { position: absolute; background-color: var(--ink-blot); border-radius: 50%; filter: blur(5px); opacity: 0.1; } .ink-blot-1 { top: 30%; left: 10%; width: 10px; height: 10px; transform: rotate(15deg); } .ink-blot-2 { bottom: 20%; right: 15%; width: 12px; height: 12px; transform: rotate(-25deg); } .content { padding: 20px; background-color: var(--primary-color); margin: 20px; box-shadow: 0 4px 8px var(--paper-shadow); position: relative; overflow: hidden; } .content::before { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-image: url("data:image/svg+xml,%3Csvg width='100' height='100' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise' x='0' y='0'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeBlend mode='multiply' in='SourceGraphic'/%3E%3C/filter%3E%3Crect width='100' height='100' filter='url(%23noise)' opacity='0.1'/%3E%3C/svg%3E"); opacity: 0.7; pointer-events: none; } .article-title { font-size: 24px; color: var(--secondary-color); margin-bottom: 10px; font-weight: 700; border-bottom: 1px solid var(--accent-color); padding-bottom: 5px; } .article-meta { display: flex; justify-content: space-between; color: var(--accent-color); font-style: italic; margin-bottom: 15px; font-size: 14px; } .article-content { font-size: 16px; line-height: 1.5; color: var(--secondary-color); column-count: 2; column-gap: 20px; } .article-content p { margin-bottom: 15px; } .first-letter { float: left; font-size: 60px; line-height: 40px; padding-top: 4px; padding-right: 8px; padding-left: 3px; font-weight: 700; color: var(--accent-color); } @media (max-width: 600px) { .masthead { font-size: 36px; } .nav { flex-wrap: wrap; } .nav-item { margin: 3px; font-size: 14px; } .article-content { column-count: 1; } .container { padding-top: 110px; } } .search-container { position: absolute; right: 20px; top: 50%; transform: translateY(-50%); background-color: var(--primary-color); border: 1px solid var(--secondary-color); display: flex; align-items: center; border-radius: 4px; overflow: hidden; height: 30px; width: 0; opacity: 0; transition: width 0.3s ease, opacity 0.3s ease; } .search-container.open { width: 180px; opacity: 1; } .search-input { width: 100%; height: 100%; border: none; outline: none; padding: 0 10px; background-color: transparent; font-family: 'Times New Roman', Times, serif; color: var(--secondary-color); } .search-button { background: none; border: none; color: var(--secondary-color); cursor: pointer; width: 30px; display: flex; align-items: center; justify-content: center; } .search-toggle { position: absolute; right: 20px; top: 50%; transform: translateY(-50%); background: none; border: none; color: var(--secondary-color); cursor: pointer; width: 30px; height: 30px; display: flex; align-items: center; justify-content: center; font-weight: bold; } .weather { position: absolute; left: 20px; top: 15px; color: var(--secondary-color); font-size: 14px; display: flex; align-items: center; } .weather-icon { font-weight: bold; margin-right: 5px; opacity: 0.8; } .breaking-news { position: absolute; bottom: -6px; left: 0; width: 100%; background-color: var(--accent-color); color: var(--primary-color); padding: 3px 0; text-align: center; font-size: 12px; font-weight: bold; white-space: nowrap; overflow: hidden; z-index: 5; transform: rotate(-0.5deg); } .breaking-news-content { display: inline-block; animation: scroll 30s linear infinite; } @keyframes scroll { 0% { transform: translateX(100%); } 100% { transform: translateX(-100%); } } .header-shadow { position: absolute; bottom: -15px; left: 0; width: 100%; height: 15px; background: linear-gradient(to bottom, var(--paper-shadow), transparent); z-index: -1; transform: skewX(-2deg); } .menu-toggle { display: none; background: none; border: none; cursor: pointer; padding: 5px; position: absolute; left: 15px; top: 50%; transform: translateY(-50%); } .menu-toggle span { display: block; width: 25px; height: 3px; background-color: var(--secondary-color); margin: 5px 0; transition: 0.3s; } @media (max-width: 600px) { .menu-toggle { display: block; } .nav { flex-direction: column; max-height: 0; overflow: hidden; transition: max-height 0.3s ease; } .nav.open { max-height: 300px; } .nav-item { padding: 8px 0; text-align: center; } .search-container.open { width: 120px; } .weather { display: none; } .header-title { padding: 0 40px; } } </style> </head> <body> <div class="container"> <header class="header"> <div class="header-container"> <div class="header-texture"></div> <div class="weather"> <span class="weather-icon">☀️</span> 72°F, Clear Skies </div> <div class="date">MAY 27, 2024</div> <div class="header-title"> <h1 class="masthead">The Chronicle</h1> <div class="tagline">All the news that's fit to digitize</div> </div> <button class="menu-toggle" id="menuToggle"> <span></span> <span></span> <span></span> </button> <nav class="nav" id="mainNav"> <a href="#" class="nav-item">Front Page</a> <a href="#" class="nav-item">Politics</a> <a href="#" class="nav-item">Business</a> <a href="#" class="nav-item">Technology</a> <a href="#" class="nav-item">Arts</a> <a href="#" class="nav-item">Opinion</a> </nav> <button class="search-toggle" id="searchToggle">🔍</button> <div class="search-container" id="searchContainer"> <input type="text" class="search-input" placeholder="Search articles..."> <button class="search-button">→</button> </div> <div class="ink-blot ink-blot-1"></div> <div class="ink-blot ink-blot-2"></div> <div class="breaking-news"> <div class="breaking-news-content"> BREAKING NEWS: Local library introduces innovative digital archive of historic newspapers • Markets close at record high • New exhibition celebrates history of print journalism • City council approves renovation of historic press building </div> </div> <div class="header-shadow"></div> </div> </header> <main> <article class="content"> <h2 class="article-title">Digital Newspapers Experience Renaissance in Modern Age</h2> <div class="article-meta"> <span>By Jonathan Pressman</span> <span>Print & Digital Correspondent</span> </div> <div class="article-content"> <p><span class="first-letter">T</span>he tactile feel of newsprint may be fading into memory, but the spirit of traditional journalism is finding new life online as digital newspapers embrace vintage aesthetics while utilizing cutting-edge technology. Across the industry, news organizations are reimagining their digital presence with designs that evoke the golden age of print journalism.</p> <p>"We've found that readers respond positively to familiar newspaper design elements," explains Maria Gutenberg, design director at The Metropolitan Journal. "The serif typography, column layouts, and even subtle paper textures create an immediate sense of credibility and permanence in an era of fleeting digital content."</p> <p>Industry research indicates that websites incorporating traditional newspaper design elements see longer average visit durations and higher subscription conversion rates. The blend of nostalgia with modern functionality appears to bridge the gap between generations of news consumers.</p> <p>"It's not just aesthetic appeal," notes typographer Samuel Mergenthaler. "The classic newspaper layout evolved over centuries to optimize readability and information hierarchy. Those principles remain valuable in digital environments."</p> </div> </article> <article class="content"> <h2 class="article-title">Typography Choices Signal Editorial Character</h2> <div class="article-meta"> <span>By Eleanor Linotype</span> <span>Design Editor</span> </div> <div class="article-content"> <p><span class="first-letter">A</span>s digital news portals compete for reader attention, their typographic choices have become increasingly significant branding elements. The persistence of serif typefaces in digital news environments speaks to their enduring association with journalistic authority.</p> <p>"Every font family carries cultural associations," says typography historian Richard Caslon. "The newspaper serif conveys a sense of tradition and craftsmanship that sans-serif fonts, despite their technical advantages on screens, simply cannot replicate."</p> <p>The trend extends beyond typography to interactive elements as well. Hover effects that mimic the look of highlighted text or folded paper corners create subtle but meaningful connections to the physical reading experience.</p> <p>"These design touches aren't merely decorative," explains UX researcher Beatrice Garamond. "They form part of an environmental psychology that helps readers mentally transition into a more focused, contemplative reading state—similar to what happens when we unfold a physical newspaper."</p> </div> </article> </main> </div> <script> // Date display const today = new Date(); const options = { month: 'long', day: 'numeric', year: 'numeric' }; const formattedDate = today.toLocaleDateString('en-US', options).toUpperCase(); document.querySelector('.date').textContent = formattedDate; // Header scroll effect let lastScrollTop = 0; const header = document.querySelector('.header'); window.addEventListener('scroll', () => { const st = window.pageYOffset || document.documentElement.scrollTop; if (st > lastScrollTop && st > 100) { // Scroll down header.style.transform = 'translateY(-100%)'; } else { // Scroll up header.style.transform = 'translateY(0)'; } lastScrollTop = st <= 0 ? 0 : st; }); // Search toggle const searchToggle = document.getElementById('searchToggle'); const searchContainer = document.getElementById('searchContainer'); searchToggle.addEventListener('click', () => { searchContainer.classList.toggle('open'); if (searchContainer.classList.contains('open')) { searchContainer.querySelector('.search-input').focus(); } }); // Close search when clicking outside document.addEventListener('click', (e) => { if (!searchContainer.contains(e.target) && e.target !== searchToggle) { searchContainer.classList.remove('open'); } }); // Mobile menu toggle const menuToggle = document.getElementById('menuToggle'); const mainNav = document.getElementById('mainNav'); menuToggle.addEventListener('click', () => { mainNav.classList.toggle('open'); menuToggle.classList.toggle('active'); }); // Random ink blots function createRandomInkBlots() { const headerContainer = document.querySelector('.header-container'); const contentElements = document.querySelectorAll('.content'); // Create ink blots for header for (let i = 0; i < 3; i++) { const inkBlot = document.createElement('div'); inkBlot.classList.add('ink-blot'); inkBlot.style.width = `${Math.random() * 10 + 5}px`; inkBlot.style.height = `${Math.random() * 10 + 5}px`; inkBlot.style.top = `${Math.random() * 80 + 10}%`; inkBlot.style.left = `${Math.random() * 80 + 10}%`; inkBlot.style.opacity = `${Math.random() * 0.1 + 0.05}`; inkBlot.style.transform = `rotate(${Math.random() * 360}deg)`; headerContainer.appendChild(inkBlot); } // Create ink blots for content contentElements.forEach(content => { for (let i = 0; i < 2; i++) { const inkBlot = document.createElement('div'); inkBlot.classList.add('ink-blot'); inkBlot.style.width = `${Math.random() * 8 + 5}px`; inkBlot.style.height = `${Math.random() * 8 + 5}px`; inkBlot.style.top = `${Math.random() * 80 + 10}%`; inkBlot.style.left = `${Math.random() * 80 + 10}%`; inkBlot.style.opacity = `${Math.random() * 0.1 + 0.05}`; inkBlot.style.transform = `rotate(${Math.random() * 360}deg)`; content.appendChild(inkBlot); } }); } createRandomInkBlots(); // Paper texture effect function addPaperTexture() { const contents = document.querySelectorAll('.content'); contents.forEach(content => { // Add subtle crease effect const crease = document.createElement('div'); crease.style.position = 'absolute'; crease.style.top = '0'; crease.style.bottom = '0'; crease.style.left = `${30 + Math.random() * 40}%`; crease.style.width = '1px'; crease.style.background = 'rgba(0,0,0,0.05)'; crease.style.boxShadow = '0 0 5px rgba(0,0,0,0.03)'; content.appendChild(crease); }); } addPaperTexture(); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Interactive Notebook</title> <style> :root { --paper-color: #f9f7f1; --pencil-color: #444; --highlight-color: #ffde7d; --blue-ink: #1e88e5; --red-ink: #e53935; --green-ink: #43a047; } * { box-sizing: border-box; margin: 0; padding: 0; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background: #f0f0f0; display: flex; justify-content: center; align-items: center; height: 100vh; overflow: hidden; } .container { width: 100%; max-width: 700px; height: 700px; perspective: 1500px; position: relative; } .notebook { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transform: rotateX(10deg); transition: transform 0.5s ease; } .notebook:hover { transform: rotateX(5deg); } .page { position: absolute; width: 100%; height: 100%; background: var(--paper-color); padding: 30px; border-radius: 5px; box-shadow: 0 5px 15px rgba(0,0,0,0.1); overflow: auto; transform-origin: left center; transition: transform 0.7s cubic-bezier(0.645, 0.045, 0.355, 1); display: flex; flex-direction: column; gap: 20px; opacity: 0; visibility: hidden; } .page:before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: url('data:image/svg+xml;utf8,<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg"><rect width="100%" height="100%" fill="none"/><path d="M0,20 L100,20 M0,40 L100,40 M0,60 L100,60 M0,80 L100,80" stroke="rgba(0,0,0,0.05)" stroke-width="1"/></svg>'); opacity: 0.5; pointer-events: none; z-index: -1; } .page.active { opacity: 1; visibility: visible; z-index: 5; } .page-content { display: flex; flex-direction: column; gap: 15px; } .page-title { font-size: 24px; color: var(--pencil-color); font-weight: 600; margin-bottom: 10px; border-bottom: 2px solid rgba(0,0,0,0.1); padding-bottom: 10px; display: inline-block; position: relative; } .page-title:after { content: ''; position: absolute; width: 100%; transform: scaleX(0); height: 2px; bottom: -2px; left: 0; background-color: var(--blue-ink); transform-origin: bottom right; transition: transform 0.3s ease-out; } .page-title:hover:after { transform: scaleX(1); transform-origin: bottom left; } .navigation { display: flex; justify-content: space-between; margin-top: auto; padding-top: 15px; } .page-btn { background: none; border: none; color: var(--blue-ink); font-weight: 600; cursor: pointer; padding: 8px 15px; border-radius: 20px; transition: all 0.3s ease; position: relative; overflow: hidden; } .page-btn:hover { background: rgba(30, 136, 229, 0.1); } .page-btn:after { content: ''; position: absolute; width: 100%; height: 100%; top: 0; left: -100%; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent); transition: 0.3s; } .page-btn:hover:after { left: 100%; } .page-btn:disabled { opacity: 0.5; cursor: not-allowed; } .page-indicator { display: flex; gap: 5px; justify-content: center; margin-top: 15px; } .page-dot { width: 8px; height: 8px; border-radius: 50%; background: rgba(0,0,0,0.2); transition: all 0.3s ease; } .page-dot.active { background: var(--blue-ink); transform: scale(1.2); } .drawing-area { width: 100%; height: 200px; border: 1px dashed rgba(0,0,0,0.2); position: relative; cursor: crosshair; background: rgba(255,255,255,0.5); border-radius: 4px; overflow: hidden; } .tools { display: flex; gap: 10px; margin-bottom: 10px; } .tool { padding: 5px 10px; border: none; background: rgba(0,0,0,0.05); border-radius: 3px; cursor: pointer; transition: all 0.2s ease; } .tool:hover { background: rgba(0,0,0,0.1); } .tool.active { background: var(--blue-ink); color: white; } .color-picker { display: flex; gap: 10px; } .color { width: 20px; height: 20px; border-radius: 50%; cursor: pointer; transition: transform 0.2s ease; } .color:hover { transform: scale(1.2); } .color.pencil { background: var(--pencil-color); } .color.blue { background: var(--blue-ink); } .color.red { background: var(--red-ink); } .color.green { background: var(--green-ink); } .note { background: var(--highlight-color); padding: 15px; border-radius: 5px; position: relative; font-size: 14px; line-height: 1.5; box-shadow: 3px 3px 0 rgba(0,0,0,0.1); transform: rotate(-1deg); transition: transform 0.3s ease; } .note:hover { transform: rotate(0) scale(1.02); } .note:before { content: '💡'; font-size: 16px; margin-right: 5px; } .math-problem { display: flex; flex-direction: column; gap: 10px; padding: 15px; border-radius: 5px; background: rgba(0,0,0,0.02); transition: all 0.3s ease; } .math-problem:hover { background: rgba(0,0,0,0.05); } .problem-title { font-weight: 600; color: var(--pencil-color); } .problem-eq { font-family: "Times New Roman", serif; font-size: 18px; color: var(--blue-ink); } .problem-solution { height: 0; overflow: hidden; transition: height 0.3s ease; } .problem-solution.visible { height: auto; } .show-solution { background: none; border: none; color: var(--blue-ink); text-decoration: underline; cursor: pointer; font-size: 14px; align-self: flex-start; } .vocab-term { display: flex; flex-direction: column; gap: 5px; border-left: 3px solid var(--green-ink); padding-left: 10px; margin-bottom: 10px; } .term { font-weight: 600; color: var(--green-ink); } .definition { font-size: 14px; line-height: 1.5; } .highlight { background: var(--highlight-color); padding: 0 2px; border-radius: 3px; } @media (max-width: 600px) { .container { max-width: 100%; height: 600px; } .page { padding: 20px; } .drawing-area { height: 150px; } } /* Animation for new notes appearing */ @keyframes fadeIn { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } .animate-in { animation: fadeIn 0.5s ease forwards; } /* Pencil trail effect */ .pencil-trail { position: absolute; pointer-events: none; z-index: 9999; width: 6px; height: 6px; border-radius: 50%; background: var(--pencil-color); opacity: 0; transform: translate(-50%, -50%); } @keyframes fadeOut { from { opacity: 0.6; } to { opacity: 0; width: 1px; height: 1px; } } </style> </head> <body> <div class="container"> <div class="notebook"> <div class="page active" id="page1"> <h1 class="page-title">My Learning Journal</h1> <div class="page-content"> <p>Welcome to your interactive digital notebook! This space is designed to mimic a real paper notebook while giving you all the benefits of digital learning.</p> <div class="note"> Try drawing in the area below. You can switch between different colors and clear your work at any time. </div> <div class="tools"> <div class="color-picker"> <div class="color pencil active" data-color="#444"></div> <div class="color blue" data-color="#1e88e5"></div> <div class="color red" data-color="#e53935"></div> <div class="color green" data-color="#43a047"></div> </div> <button class="tool" id="clear">Clear</button> </div> <div class="drawing-area"> <canvas id="drawing-canvas"></canvas> </div> </div> <div class="navigation"> <button class="page-btn" id="prev-btn" disabled>← Previous</button> <div class="page-indicator"> <div class="page-dot active"></div> <div class="page-dot"></div> <div class="page-dot"></div> </div> <button class="page-btn" id="next-btn">Next →</button> </div> </div> <div class="page" id="page2"> <h1 class="page-title">Math Notes</h1> <div class="page-content"> <div class="math-problem"> <p class="problem-title">Quadratic Equation Example</p> <p class="problem-eq">x² - 5x + 6 = 0</p> <button class="show-solution">Show solution</button> <div class="problem-solution"> <p>Using the quadratic formula:</p> <p class="problem-eq">x = (-b ± √(b² - 4ac)) / 2a</p> <p>Where a=1, b=-5, c=6</p> <p class="problem-eq">x = (5 ± √(25 - 24)) / 2 = (5 ± √1) / 2 = (5 ± 1) / 2</p> <p>Therefore x = 3 or x = 2</p> </div> </div> <div class="vocab-term"> <p class="term">Polynomial</p> <p class="definition">An expression consisting of variables and coefficients using only addition, subtraction, multiplication, and non-negative integer exponents.</p> </div> <div class="vocab-term"> <p class="term">Derivative</p> <p class="definition">A measure of how a function changes as its input changes. Commonly denoted as f'(x) or <span class="highlight">dy/dx</span>.</p> </div> <div class="note"> Remember: Practice makes perfect! Try working through problems step by step and show your work. </div> </div> <div class="navigation"> <button class="page-btn" id="prev-btn">← Previous</button> <div class="page-indicator"> <div class="page-dot"></div> <div class="page-dot active"></div> <div class="page-dot"></div> </div> <button class="page-btn" id="next-btn">Next →</button> </div> </div> <div class="page" id="page3"> <h1 class="page-title">Science Sketches</h1> <div class="page-content"> <p>Use this page to sketch scientific concepts, label diagrams, or create mind maps of biology processes.</p> <div class="note"> Tip: Try drawing a cell structure and labeling the organelles, or sketch the water cycle! </div> <div class="tools"> <div class="color-picker"> <div class="color pencil active" data-color="#444"></div> <div class="color blue" data-color="#1e88e5"></div> <div class="color red" data-color="#e53935"></div> <div class="color green" data-color="#43a047"></div> </div> <button class="tool" id="clear2">Clear</button> </div> <div class="drawing-area"> <canvas id="drawing-canvas2"></canvas> </div> <div class="vocab-term"> <p class="term">Mitochondria</p> <p class="definition">The powerhouse of the cell, responsible for producing ATP through cellular respiration.</p> </div> </div> <div class="navigation"> <button class="page-btn" id="prev-btn">← Previous</button> <div class="page-indicator"> <div class="page-dot"></div> <div class="page-dot"></div> <div class="page-dot active"></div> </div> <button class="page-btn" id="next-btn" disabled>Next →</button> </div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Canvas Setup setupCanvas('drawing-canvas'); setupCanvas('drawing-canvas2'); // Page Navigation const pages = document.querySelectorAll('.page'); const prevBtns = document.querySelectorAll('#prev-btn'); const nextBtns = document.querySelectorAll('#next-btn'); const dots = document.querySelectorAll('.page-dot'); let currentPage = 0; function showPage(index) { pages.forEach(page => page.classList.remove('active')); dots.forEach(dot => dot.classList.remove('active')); pages[index].classList.add('active'); dots[index].classList.add('active'); currentPage = index; // Update navigation buttons prevBtns.forEach(btn => { btn.disabled = currentPage === 0; }); nextBtns.forEach(btn => { btn.disabled = currentPage === pages.length - 1; }); } prevBtns.forEach(btn => { btn.addEventListener('click', () => { if (currentPage > 0) { showPage(currentPage - 1); } }); }); nextBtns.forEach(btn => { btn.addEventListener('click', () => { if (currentPage < pages.length - 1) { showPage(currentPage + 1); } }); }); // Show solution toggle const solutionBtn = document.querySelector('.show-solution'); const solution = document.querySelector('.problem-solution'); solutionBtn.addEventListener('click', function() { solution.classList.toggle('visible'); solutionBtn.textContent = solution.classList.contains('visible') ? 'Hide solution' : 'Show solution'; }); // Pencil trail effect document.addEventListener('mousemove', function(e) { if (e.target.closest('.drawing-area')) return; const trail = document.createElement('div'); trail.className = 'pencil-trail'; trail.style.left = e.pageX + 'px'; trail.style.top = e.pageY + 'px'; document.body.appendChild(trail); trail.style.animation = 'fadeOut 0.5s forwards'; setTimeout(() => { trail.remove(); }, 500); }); // Canvas drawing functionality function setupCanvas(canvasId) { const canvas = document.getElementById(canvasId); if (!canvas) return; const context = canvas.getContext('2d'); const drawingArea = canvas.parentElement; // Set canvas size to match parent container function resizeCanvas() { canvas.width = drawingArea.clientWidth; canvas.height = drawingArea.clientHeight; } resizeCanvas(); window.addEventListener('resize', resizeCanvas); // Drawing variables let isDrawing = false; let lastX = 0; let lastY = 0; let currentColor = '#444'; // Color picker functionality const colorPickers = document.querySelectorAll('.color'); colorPickers.forEach(color => { color.addEventListener('click', function() { // Remove active class from all colors colorPickers.forEach(c => c.classList.remove('active')); // Add active class to selected color this.classList.add('active'); // Set current color currentColor = this.dataset.color; }); }); // Clear button functionality const clearBtn = document.getElementById(canvasId === 'drawing-canvas' ? 'clear' : 'clear2'); if (clearBtn) { clearBtn.addEventListener('click', function() { context.clearRect(0, 0, canvas.width, canvas.height); }); } // Drawing event listeners canvas.addEventListener('mousedown', startDrawing); canvas.addEventListener('touchstart', startDrawingTouch); canvas.addEventListener('mousemove', draw); canvas.addEventListener('touchmove', drawTouch); canvas.addEventListener('mouseup', stopDrawing); canvas.addEventListener('mouseout', stopDrawing); canvas.addEventListener('touchend', stopDrawing); function startDrawing(e) { isDrawing = true; [lastX, lastY] = [e.offsetX, e.offsetY]; } function startDrawingTouch(e) { e.preventDefault(); isDrawing = true; const rect = canvas.getBoundingClientRect(); const touch = e.touches[0]; [lastX, lastY] = [touch.clientX - rect.left, touch.clientY - rect.top]; } function draw(e) { if (!isDrawing) return; context.lineJoin = 'round'; context.lineCap = 'round'; context.lineWidth = 2; context.strokeStyle = currentColor; context.beginPath(); context.moveTo(lastX, lastY); context.lineTo(e.offsetX, e.offsetY); context.stroke(); [lastX, lastY] = [e.offsetX, e.offsetY]; } function drawTouch(e) { if (!isDrawing) return; e.preventDefault(); const rect = canvas.getBoundingClientRect(); const touch = e.touches[0]; const offsetX = touch.clientX - rect.left; const offsetY = touch.clientY - rect.top; context.lineJoin = 'round'; context.lineCap = 'round'; context.lineWidth = 2; context.strokeStyle = currentColor; context.beginPath(); context.moveTo(lastX, lastY); context.lineTo(offsetX, offsetY); context.stroke(); [lastX, lastY] = [offsetX, offsetY]; } function stopDrawing() { isDrawing = false; } } // Page content animation const contentElements = document.querySelectorAll('.page-content > *'); contentElements.forEach((el, index) => { el.classList.add('animate-in'); el.style.animationDelay = `${index * 0.1}s`; }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Light & Shadow Photography Portfolio</title> <style> :root { --primary-color: #f8f5f0; --accent-color: #b89f7a; --text-color: #2c2c2c; --shadow-color: rgba(0,0,0,0.1); --transition-timing: cubic-bezier(0.25, 0.46, 0.45, 0.94); } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Cormorant Garamond', serif; background-color: var(--primary-color); color: var(--text-color); overflow-x: hidden; height: 100%; width: 100%; position: relative; line-height: 1.6; } .container { max-width: 700px; height: 700px; margin: 0 auto; padding: 20px; overflow: hidden; position: relative; } .portfolio-header { text-align: center; margin-bottom: 20px; position: relative; z-index: 10; } .portfolio-title { font-size: 2.5rem; font-weight: 300; letter-spacing: 2px; margin-bottom: 5px; position: relative; display: inline-block; } .portfolio-title::after { content: ''; position: absolute; bottom: -5px; left: 50%; transform: translateX(-50%); width: 80px; height: 1px; background-color: var(--accent-color); } .portfolio-subtitle { font-style: italic; font-size: 1rem; color: var(--accent-color); margin-bottom: 10px; } .gallery-container { position: relative; height: calc(100% - 120px); overflow: hidden; } .gallery { display: grid; grid-template-columns: repeat(2, 1fr); grid-auto-rows: 180px; grid-gap: 20px; height: 100%; overflow-y: auto; padding: 10px; padding-right: 20px; scrollbar-width: thin; scrollbar-color: var(--accent-color) var(--primary-color); } .gallery::-webkit-scrollbar { width: 6px; } .gallery::-webkit-scrollbar-track { background: var(--primary-color); } .gallery::-webkit-scrollbar-thumb { background-color: var(--accent-color); border-radius: 6px; } .gallery-item { position: relative; overflow: hidden; border-radius: 2px; cursor: pointer; transform: translateY(40px); opacity: 0; transition: transform 0.5s var(--transition-timing), opacity 0.5s var(--transition-timing); } .gallery-item.active { transform: translateY(0); opacity: 1; } .gallery-item:nth-child(odd) { transition-delay: 0.2s; } .gallery-item:nth-child(even) { transition-delay: 0.4s; } .gallery-item::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: white; opacity: 0; z-index: 1; transition: opacity 0.3s ease; } .gallery-item img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.8s var(--transition-timing); } .gallery-item:hover img { transform: scale(1.05); } .gallery-item::after { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; box-shadow: inset 0 0 0 1px rgba(255,255,255,0.2); pointer-events: none; z-index: 2; } /* Watercolor paper edge effect */ .paper-edge { position: absolute; pointer-events: none; z-index: 5; } .paper-edge-top { top: 0; left: 0; right: 0; height: 20px; background: linear-gradient(to bottom, var(--primary-color) 0%, transparent 100%); } .paper-edge-bottom { bottom: 0; left: 0; right: 0; height: 20px; background: linear-gradient(to top, var(--primary-color) 0%, transparent 100%); } .paper-edge-left { top: 0; left: 0; bottom: 0; width: 20px; background: linear-gradient(to right, var(--primary-color) 0%, transparent 100%); } .paper-edge-right { top: 0; right: 0; bottom: 0; width: 20px; background: linear-gradient(to left, var(--primary-color) 0%, transparent 100%); } .lightbox { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(248, 245, 240, 0.97); z-index: 100; display: flex; justify-content: center; align-items: center; opacity: 0; pointer-events: none; transition: opacity 0.5s var(--transition-timing); } .lightbox.active { opacity: 1; pointer-events: all; } .lightbox-content { position: relative; max-width: 80%; max-height: 80%; transform: scale(0.9); opacity: 0; transition: all 0.5s var(--transition-timing); } .lightbox.active .lightbox-content { transform: scale(1); opacity: 1; transition-delay: 0.2s; } .lightbox-image { max-width: 100%; max-height: 70vh; display: block; border-radius: 2px; box-shadow: 0 10px 30px rgba(0,0,0,0.1); } .lightbox-caption { position: absolute; bottom: -40px; left: 0; width: 100%; text-align: center; font-style: italic; color: var(--text-color); opacity: 0.8; } .lightbox-close { position: absolute; top: 20px; right: 20px; width: 40px; height: 40px; cursor: pointer; z-index: 110; display: flex; align-items: center; justify-content: center; opacity: 0.8; transition: opacity 0.3s ease; } .lightbox-close:hover { opacity: 1; } .lightbox-close::before, .lightbox-close::after { content: ''; position: absolute; width: 24px; height: 1px; background-color: var(--text-color); } .lightbox-close::before { transform: rotate(45deg); } .lightbox-close::after { transform: rotate(-45deg); } /* Textured paper background */ .texture { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100' viewBox='0 0 100 100'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)' opacity='0.05'/%3E%3C/svg%3E"); pointer-events: none; opacity: 0.6; z-index: 1; } .description { font-size: 0.9rem; margin-bottom: 20px; max-width: 600px; text-align: center; margin: 0 auto 20px; opacity: 0.85; transform: translateY(20px); opacity: 0; transition: all 0.5s var(--transition-timing); } .description.active { transform: translateY(0); opacity: 0.85; } /* Portrait mode layout adjustments */ @media (max-width: 500px) { .gallery { grid-template-columns: 1fr; grid-auto-rows: 200px; } .portfolio-title { font-size: 2rem; } .description { font-size: 0.8rem; } } /* Navigation arrows for lightbox */ .lightbox-nav { position: absolute; top: 50%; transform: translateY(-50%); width: 40px; height: 40px; cursor: pointer; display: flex; align-items: center; justify-content: center; z-index: 110; opacity: 0.7; transition: opacity 0.3s ease; } .lightbox-nav:hover { opacity: 1; } .lightbox-prev { left: 20px; } .lightbox-next { right: 20px; } .lightbox-nav::before, .lightbox-nav::after { content: ''; position: absolute; width: 20px; height: 1px; background-color: var(--text-color); } .lightbox-prev::before { transform: rotate(-45deg) translateY(-5px); transform-origin: left; } .lightbox-prev::after { transform: rotate(45deg) translateY(5px); transform-origin: left; } .lightbox-next::before { transform: rotate(45deg) translateY(-5px); transform-origin: right; } .lightbox-next::after { transform: rotate(-45deg) translateY(5px); transform-origin: right; } /* Custom watercolor stain decorative element */ .watercolor-stain { position: absolute; z-index: -1; width: 400px; height: 400px; background-image: radial-gradient(circle at center, rgba(184, 159, 122, 0.07) 0%, rgba(184, 159, 122, 0) 70%); mix-blend-mode: multiply; transform: translate(-50%, -50%); animation: float 15s infinite ease-in-out; } .stain1 { top: 20%; left: 20%; animation-delay: 0s; } .stain2 { top: 70%; left: 70%; width: 300px; height: 300px; animation-delay: -7s; } @keyframes float { 0%, 100% { transform: translate(-50%, -50%) rotate(0deg) scale(1); } 50% { transform: translate(-50%, -50%) rotate(5deg) scale(1.1); } } </style> </head> <body> <div class="container"> <div class="texture"></div> <div class="watercolor-stain stain1"></div> <div class="watercolor-stain stain2"></div> <header class="portfolio-header"> <h1 class="portfolio-title">LIGHT & SHADOW</h1> <p class="portfolio-subtitle">A visual narrative by Emma Whitman</p> </header> <p class="description"> Exploring the delicate relationship between natural light and organic textures. This collection captures fleeting moments where illumination transforms mundane spaces into ethereal landscapes. </p> <div class="gallery-container"> <div class="gallery"> <div class="gallery-item" data-caption="Morning Light - Window light creating geometric patterns on an antique table"> <img src="https://images.unsplash.com/photo-1501556466850-7c9fa1fccb4c?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80" alt="Window light"> </div> <div class="gallery-item" data-caption="Soft Focus - Floral elements captured with intentional shallow depth of field"> <img src="https://images.unsplash.com/photo-1494972308805-463bc619d34e?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80" alt="Floral elements"> </div> <div class="gallery-item" data-caption="Textural Study - Interplay of shadows across rough stone surfaces"> <img src="https://images.unsplash.com/photo-1500462918059-b1a0cb512f1d?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80" alt="Stone textures"> </div> <div class="gallery-item" data-caption="Negative Space - Minimalist composition highlighting form through absence"> <img src="https://images.unsplash.com/photo-1472214103451-9374bd1c798e?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80" alt="Minimalist landscape"> </div> <div class="gallery-item" data-caption="Translucent - Light filtering through botanical specimens"> <img src="https://images.unsplash.com/photo-1502082553048-f009c37129b9?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80" alt="Botanical light"> </div> <div class="gallery-item" data-caption="Dappled Light - Forest canopy creating natural light patterns"> <img src="https://images.unsplash.com/photo-1418065460487-3e41a6c84dc5?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80" alt="Forest light"> </div> <div class="gallery-item" data-caption="Gradient Study - The subtle shift of light across a neutral surface"> <img src="https://images.unsplash.com/photo-1496096265110-f83ad7f96608?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80" alt="Gradient light"> </div> <div class="gallery-item" data-caption="Reflections - Exploring symmetry through water surface distortions"> <img src="https://images.unsplash.com/photo-1462331940025-496dfbfc7564?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80" alt="Water reflections"> </div> </div> <div class="paper-edge paper-edge-top"></div> <div class="paper-edge paper-edge-bottom"></div> <div class="paper-edge paper-edge-left"></div> <div class="paper-edge paper-edge-right"></div> </div> <div class="lightbox"> <div class="lightbox-close"></div> <div class="lightbox-nav lightbox-prev"></div> <div class="lightbox-nav lightbox-next"></div> <div class="lightbox-content"> <img class="lightbox-image" src="" alt=""> <p class="lightbox-caption"></p> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Elements const galleryItems = document.querySelectorAll('.gallery-item'); const lightbox = document.querySelector('.lightbox'); const lightboxImage = document.querySelector('.lightbox-image'); const lightboxCaption = document.querySelector('.lightbox-caption'); const lightboxClose = document.querySelector('.lightbox-close'); const lightboxPrev = document.querySelector('.lightbox-prev'); const lightboxNext = document.querySelector('.lightbox-next'); const description = document.querySelector('.description'); let currentIndex = 0; // Animate elements in on load setTimeout(() => { description.classList.add('active'); galleryItems.forEach(item => { item.classList.add('active'); }); }, 100); // Open lightbox galleryItems.forEach((item, index) => { item.addEventListener('click', () => { currentIndex = index; const imgSrc = item.querySelector('img').src; const caption = item.getAttribute('data-caption'); lightboxImage.src = imgSrc; lightboxCaption.textContent = caption; lightbox.classList.add('active'); }); }); // Close lightbox lightboxClose.addEventListener('click', () => { lightbox.classList.remove('active'); }); // Close on clicking outside the image lightbox.addEventListener('click', (e) => { if (e.target === lightbox) { lightbox.classList.remove('active'); } }); // Navigate to previous image lightboxPrev.addEventListener('click', () => { currentIndex = (currentIndex - 1 + galleryItems.length) % galleryItems.length; updateLightboxContent(); }); // Navigate to next image lightboxNext.addEventListener('click', () => { currentIndex = (currentIndex + 1) % galleryItems.length; updateLightboxContent(); }); // Update lightbox content function updateLightboxContent() { const item = galleryItems[currentIndex]; const imgSrc = item.querySelector('img').src; const caption = item.getAttribute('data-caption'); // Add a fade out/in effect lightboxImage.style.opacity = 0; lightboxCaption.style.opacity = 0; setTimeout(() => { lightboxImage.src = imgSrc; lightboxCaption.textContent = caption; lightboxImage.style.opacity = 1; lightboxCaption.style.opacity = 1; }, 300); } // Keyboard navigation document.addEventListener('keydown', (e) => { if (!lightbox.classList.contains('active')) return; if (e.key === 'Escape') { lightbox.classList.remove('active'); } else if (e.key === 'ArrowLeft') { currentIndex = (currentIndex - 1 + galleryItems.length) % galleryItems.length; updateLightboxContent(); } else if (e.key === 'ArrowRight') { currentIndex = (currentIndex + 1) % galleryItems.length; updateLightboxContent(); } }); // Add subtle parallax effect on gallery items document.addEventListener('mousemove', (e) => { const mouseX = e.clientX / window.innerWidth; const mouseY = e.clientY / window.innerHeight; galleryItems.forEach(item => { const itemRect = item.getBoundingClientRect(); const itemCenterX = itemRect.left + itemRect.width / 2; const itemCenterY = itemRect.top + itemRect.height / 2; const offsetX = (mouseX - 0.5) * 10; const offsetY = (mouseY - 0.5) * 10; if (item.classList.contains('active')) { item.querySelector('img').style.transform = `scale(1.03) translate(${offsetX}px, ${offsetY}px)`; } }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Handcrafted Event Invitation</title> <style> @import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,700;1,400&family=Montserrat:wght@300;400;600&display=swap'); * { margin: 0; padding: 0; box-sizing: border-box; } :root { --primary-color: #f8f3e9; --accent-color: #e6846f; --dark-accent: #bb5a44; --text-color: #2c3e50; --shadow-color: rgba(0, 0, 0, 0.1); --paper-white: #fff9f0; } body { font-family: 'Montserrat', sans-serif; background-color: #e9e4db; display: flex; justify-content: center; align-items: center; min-height: 100vh; color: var(--text-color); overflow-x: hidden; padding: 20px; } .container { width: 100%; max-width: 650px; height: 650px; position: relative; overflow: hidden; border-radius: 2px; } .paper-container { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; perspective: 1000px; } .paper-layer { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: var(--primary-color); box-shadow: 0 8px 16px var(--shadow-color); transform: translateZ(0px) rotateX(0deg); overflow: hidden; transition: transform 0.6s ease-out; } .paper-layer::before { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-image: repeating-linear-gradient( var(--primary-color) 0px, var(--primary-color) 2px, var(--paper-white) 2.5px ); opacity: 0.3; pointer-events: none; } .paper-layer::after { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-image: url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 18c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm48 25c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm-43-7c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm63 31c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM34 90c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm56-76c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM12 86c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm28-65c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm23-11c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-6 60c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm29 22c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zM32 63c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm57-13c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-9-21c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM60 91c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM35 41c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM12 60c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2z' fill='%23e0d5c8' fill-opacity='0.1' fill-rule='evenodd'/%3E%3C/svg%3E"); opacity: 0.5; pointer-events: none; } .torn-edge { position: absolute; bottom: 0; left: 0; width: 100%; height: 40px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 40' preserveAspectRatio='none'%3E%3Cpath d='M0,0 C50,25 100,35 150,20 C200,5 250,25 300,30 C350,35 400,10 450,20 C500,30 550,5 600,10 C650,15 700,35 750,25 C800,15 850,30 900,20 C950,10 1000,30 1000,40 L1000,40 L0,40 Z' fill='%23e9e4db'/%3E%3C/svg%3E"); background-size: 100% 100%; transform: translateY(100%); transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1); } .invitation-content { padding: 50px 40px; text-align: center; height: 100%; display: flex; flex-direction: column; justify-content: space-between; position: relative; z-index: 10; } .header { margin-bottom: 20px; } h1 { font-family: 'Playfair Display', serif; font-size: 2.5rem; font-weight: 700; color: var(--accent-color); margin-bottom: 10px; font-style: italic; letter-spacing: 1px; } .subtitle { font-size: 1rem; font-weight: 300; letter-spacing: 2px; text-transform: uppercase; color: var(--text-color); opacity: 0.8; margin-bottom: 30px; } .invitation-message { font-size: 1.1rem; line-height: 1.5; margin-bottom: 30px; } .event-details { margin-bottom: 30px; } .detail-item { margin-bottom: 15px; display: flex; flex-direction: column; align-items: center; } .detail-label { font-size: 0.85rem; text-transform: uppercase; letter-spacing: 1.5px; color: var(--dark-accent); font-weight: 600; margin-bottom: 5px; } .detail-value { font-size: 1.1rem; font-weight: 400; } .slider-container { width: 100%; padding: 15px 0; display: flex; flex-direction: column; align-items: center; margin-top: 10px; } .slider-track { width: 80%; height: 4px; background-color: #e0d5c8; border-radius: 2px; position: relative; margin-bottom: 15px; } .slider-progress { position: absolute; top: 0; left: 0; height: 100%; background-color: var(--accent-color); border-radius: 2px; width: 0%; transition: width 0.3s ease; } .slider-thumb { width: 24px; height: 24px; background-color: var(--accent-color); border-radius: 50%; position: absolute; top: 50%; transform: translate(-50%, -50%); left: 0%; cursor: pointer; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); z-index: 5; transition: transform 0.1s ease, box-shadow 0.1s ease; } .slider-thumb:hover { transform: translate(-50%, -50%) scale(1.1); box-shadow: 0 3px 6px rgba(0, 0, 0, 0.25); } .slider-thumb:active { transform: translate(-50%, -50%) scale(0.95); } .slider-labels { width: 80%; display: flex; justify-content: space-between; font-size: 0.8rem; color: var(--text-color); opacity: 0.7; padding: 0 12px; } .layer-indicator { width: 80%; display: flex; justify-content: space-between; margin-bottom: 15px; } .layer-dot { width: 10px; height: 10px; border-radius: 50%; background-color: #e0d5c8; transition: background-color 0.3s ease, transform 0.3s ease; } .layer-dot.active { background-color: var(--accent-color); transform: scale(1.2); } .slider-instruction { font-size: 0.9rem; color: var(--text-color); opacity: 0.7; margin-top: 5px; font-style: italic; } .detail-layer { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: var(--primary-color); display: flex; flex-direction: column; justify-content: center; align-items: center; padding: 40px; text-align: center; transform: translateY(100%); transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1); z-index: 20; } .detail-layer::before { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-image: repeating-linear-gradient( var(--primary-color) 0px, var(--primary-color) 2px, var(--paper-white) 2.5px ); opacity: 0.3; pointer-events: none; } .detail-layer::after { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-image: url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 18c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm48 25c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm-43-7c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm63 31c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM34 90c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm56-76c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM12 86c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm28-65c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm23-11c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-6 60c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm29 22c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zM32 63c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm57-13c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-9-21c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM60 91c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM35 41c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM12 60c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2z' fill='%23e0d5c8' fill-opacity='0.1' fill-rule='evenodd'/%3E%3C/svg%3E"); opacity: 0.5; pointer-events: none; } .detail-layer-top { position: absolute; top: 0; left: 0; width: 100%; height: 40px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 40' preserveAspectRatio='none'%3E%3Cpath d='M0,40 C50,15 100,5 150,20 C200,35 250,15 300,10 C350,5 400,30 450,20 C500,10 550,35 600,30 C650,25 700,5 750,15 C800,25 850,10 900,20 C950,30 1000,10 1000,0 L1000,0 L0,0 Z' fill='%23e9e4db'/%3E%3C/svg%3E"); background-size: 100% 100%; transform: translateY(-100%); transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1); } .detail-content { position: relative; z-index: 10; width: 100%; max-width: 450px; } h2 { font-family: 'Playfair Display', serif; font-size: 2rem; color: var(--accent-color); margin-bottom: 20px; } .detail-description { font-size: 1rem; line-height: 1.6; margin-bottom: 30px; } .location-map { position: relative; width: 100%; height: 180px; margin-bottom: 25px; border-radius: 5px; overflow: hidden; border: 2px solid #e0d5c8; } .map-placeholder { width: 100%; height: 100%; display: flex; flex-direction: column; justify-content: center; align-items: center; background-color: rgba(255, 249, 240, 0.8); font-size: 0.9rem; line-height: 1.4; color: var(--text-color); padding: 15px; text-align: center; background-image: radial-gradient(circle at 20% 30%, rgba(230, 132, 111, 0.15) 15%, transparent 15%), radial-gradient(circle at 90% 85%, rgba(230, 132, 111, 0.1) 10%, transparent 10%), radial-gradient(circle at 60% 40%, rgba(230, 132, 111, 0.05) 25%, transparent 25%), radial-gradient(circle at 30% 70%, rgba(230, 132, 111, 0.1) 15%, transparent 15%); } .map-address { font-weight: 600; margin-top: 10px; } .cta-button { display: inline-block; padding: 12px 30px; background-color: var(--accent-color); color: white; font-size: 1rem; text-transform: uppercase; letter-spacing: 1.5px; border: none; border-radius: 3px; cursor: pointer; transition: all 0.3s ease; box-shadow: 0 3px 5px rgba(0, 0, 0, 0.1); font-weight: 600; margin-top: 10px; } .cta-button:hover { background-color: var(--dark-accent); transform: translateY(-2px); box-shadow: 0 5px 10px rgba(0, 0, 0, 0.15); } .cta-button:active { transform: translateY(1px); box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); } .layer-0 { z-index: 30; } .layer-1 { z-index: 20; } .layer-2 { z-index: 10; } .layer-3 { z-index: 5; } .confetti { position: absolute; width: 8px; height: 16px; background-color: var(--accent-color); opacity: 0; pointer-events: none; z-index: 100; } @media (max-width: 600px) { h1 { font-size: 2rem; } h2 { font-size: 1.7rem; } .invitation-content { padding: 40px 20px; } .slider-track, .slider-labels, .layer-indicator { width: 90%; } .detail-description { font-size: 0.9rem; } .location-map { height: 150px; } } @media (max-width: 400px) { h1 { font-size: 1.8rem; } .detail-item { margin-bottom: 10px; } } </style> </head> <body> <div class="container"> <div class="paper-container"> <div class="paper-layer layer-0"> <div class="invitation-content"> <div class="header"> <h1>Invitation</h1> <div class="subtitle">You're cordially invited</div> </div> <div class="invitation-message"> Join us for an exclusive gathering of creative minds at our annual Artisan Workshop Festival. A celebration of craft, inspiration, and community. </div> <div class="event-details"> <div class="detail-item"> <span class="detail-label">When</span> <span class="detail-value">Saturday, October 24th at 6:00 PM</span> </div> <div class="detail-item"> <span class="detail-label">Where</span> <span class="detail-value">The Craftsman's Hall, Portland</span> </div> </div> <div class="slider-container"> <div class="layer-indicator"> <div class="layer-dot active" data-layer="0"></div> <div class="layer-dot" data-layer="1"></div> <div class="layer-dot" data-layer="2"></div> <div class="layer-dot" data-layer="3"></div> </div> <div class="slider-track"> <div class="slider-progress"></div> <div class="slider-thumb" id="sliderThumb"></div> </div> <div class="slider-labels"> <span>Invitation</span> <span>Details</span> <span>Location</span> <span>RSVP</span> </div> <div class="slider-instruction">Slide to reveal more details</div> </div> </div> <div class="torn-edge"></div> </div> <div class="detail-layer layer-1"> <div class="detail-layer-top"></div> <div class="detail-content"> <h2>Event Details</h2> <div class="detail-description"> <p>The Artisan Workshop Festival brings together skilled craftspeople from across the region. Enjoy hands-on demonstrations, interactive workshops, and exclusive exhibits featuring traditional and contemporary paper crafts.</p> <p>Dress code is creative casual. Light refreshments and craft materials will be provided.</p> </div> <button class="cta-button" id="detailsBackButton">Back to Invitation</button> </div> </div> <div class="detail-layer layer-2"> <div class="detail-layer-top"></div> <div class="detail-content"> <h2>Location</h2> <div class="location-map"> <div class="map-placeholder"> <span>The Craftsman's Hall</span> <span class="map-address">1425 Artisan Avenue<br>Portland, OR 97204</span> </div> </div> <div class="detail-description"> Free parking available in the adjacent lot. Public transportation routes 12 and 19 stop directly in front of the venue. Wheelchair accessible entrance on the west side of the building. </div> <button class="cta-button" id="locationBackButton">Back to Invitation</button> </div> </div> <div class="detail-layer layer-3"> <div class="detail-layer-top"></div> <div class="detail-content"> <h2>RSVP</h2> <div class="detail-description"> <p>Please confirm your attendance by October 10th. Each guest may bring one companion. Let us know of any dietary restrictions or special accommodations needed.</p> <p>Contact: [email protected]<br>Phone: (503) 555-1234</p> </div> <button class="cta-button" id="attendButton">I'll Attend</button> <button class="cta-button" id="rsvpBackButton" style="margin-top: 15px; background-color: transparent; color: var(--accent-color); box-shadow: none;">Back to Invitation</button> </div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const sliderThumb = document.getElementById('sliderThumb'); const sliderTrack = document.querySelector('.slider-track'); const sliderProgress = document.querySelector('.slider-progress'); const layers = document.querySelectorAll('.paper-layer, .detail-layer'); const layerDots = document.querySelectorAll('.layer-dot'); const tornEdge = document.querySelector('.torn-edge'); const detailLayerTops = document.querySelectorAll('.detail-layer-top'); const backButtons = [ document.getElementById('detailsBackButton'), document.getElementById('locationBackButton'), document.getElementById('rsvpBackButton') ]; const attendButton = document.getElementById('attendButton'); let isDragging = false; let currentLayer = 0; // Initialize positions function updateLayerPositions() { layers.forEach((layer, index) => { if (index === 0) { layer.style.transform = 'translateY(0)'; } else if (index <= currentLayer) { layer.style.transform = 'translateY(0)'; } else { layer.style.transform = 'translateY(100%)'; } }); // Update torn edge position if (currentLayer === 0) { tornEdge.style.transform = 'translateY(100%)'; } else { tornEdge.style.transform = 'translateY(0)'; } // Update detail layer top edges detailLayerTops.forEach((top, index) => { const layerIndex = index + 1; if (layerIndex <= currentLayer) { top.style.transform = 'translateY(0)'; } else { top.style.transform = 'translateY(-100%)'; } }); // Update layer dots layerDots.forEach((dot, index) => { if (index === currentLayer) { dot.classList.add('active'); } else { dot.classList.remove('active'); } }); } // Set up slider interactions function setSliderPosition(position) { const percentage = Math.max(0, Math.min(100, position)); sliderThumb.style.left = `${percentage}%`; sliderProgress.style.width = `${percentage}%`; // Determine current layer based on percentage if (percentage < 25) { currentLayer = 0; } else if (percentage < 50) { currentLayer = 1; } else if (percentage < 75) { currentLayer = 2; } else { currentLayer = 3; } updateLayerPositions(); } function getPositionFromEvent(e) { const rect = sliderTrack.getBoundingClientRect(); const x = e.clientX - rect.left; return (x / rect.width) * 100; } sliderThumb.addEventListener('mousedown', function(e) { isDragging = true; e.preventDefault(); }); document.addEventListener('mousemove', function(e) { if (isDragging) { setSliderPosition(getPositionFromEvent(e)); } }); document.addEventListener('mouseup', function() { if (isDragging) { isDragging = false; snapToLayer(); } }); // Touch events sliderThumb.addEventListener('touchstart', function(e) { isDragging = true; e.preventDefault(); }); document.addEventListener('touchmove', function(e) { if (isDragging) { const touch = e.touches[0]; setSliderPosition(getPositionFromEvent(touch)); } }); document.addEventListener('touchend', function() { if (isDragging) { isDragging = false; snapToLayer(); } }); // Dot navigation layerDots.forEach((dot) => { dot.addEventListener('click', function() { currentLayer = parseInt(this.getAttribute('data-layer')); snapToLayer(); }); }); // Snap to the nearest layer function snapToLayer() { setSliderPosition(currentLayer * 33.33); } // Back buttons backButtons.forEach((button) => { button.addEventListener('click', function() { currentLayer = 0; snapToLayer(); }); }); // Attend button with confetti attendButton.addEventListener('click', function() { createConfetti(); }); function createConfetti() { const container = document.querySelector('.container'); const colors = ['#e6846f', '#f8f3e9', '#bb5a44', '#f1c0b3', '#2c3e50']; for (let i = 0; i < 100; i++) { const confetti = document.createElement('div'); confetti.className = 'confetti'; confetti.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)]; confetti.style.left = `${Math.random() * 100}%`; confetti.style.top = `${Math.random() * 20 + 40}%`; confetti.style.width = `${Math.random() * 10 + 5}px`; confetti.style.height = `${Math.random() * 10 + 10}px`; confetti.style.transform = `rotate(${Math.random() * 360}deg)`; container.appendChild(confetti); // Animate confetti setTimeout(() => { confetti.style.opacity = '1'; confetti.style.transform = `translateY(${Math.random() * 450 - 250}px) translateX(${Math.random() * 300 - 150}px) rotate(${Math.random() * 960}deg)`; confetti.style.transition = `all ${Math.random() * 2 + 1.5}s ease-out`; // Remove confetti after animation setTimeout(() => { confetti.style.opacity = '0'; setTimeout(() => { confetti.remove(); }, 1000); }, 1500); }, 10); } // Show thank you message attendButton.textContent = "Thank you!"; attendButton.disabled = true; // Reset after a few seconds setTimeout(() => { attendButton.textContent = "I'll Attend"; attendButton.disabled = false; }, 3000); } // Initialize updateLayerPositions(); }); </script> </body> </html>
<html> <head> <title>Recipe Keeper: Handwritten Recipes with Heart</title> <style> @import url('https://fonts.googleapis.com/css2?family=Caveat:wght@400;700&family=Dancing+Script:wght@400;700&family=Noto+Serif:ital,wght@0,400;0,700;1,400&display=swap'); * { margin: 0; padding: 0; box-sizing: border-box; } :root { --card-color: #f8f5e6; --ink-color: #2e3032; --accent: #926b4b; --coffee-stain: rgba(146, 107, 75, 0.15); --tomato-stain: rgba(185, 74, 72, 0.1); } body { background: #e9e2d0; font-family: 'Noto Serif', serif; height: 100vh; display: flex; align-items: center; justify-content: center; overflow: hidden; background-image: url('data:image/svg+xml;utf8,<svg width="100" height="100" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h100v100H0z" fill="%23e9e2d0"/><path d="M20 20h2v2h-2zm30 0h2v2h-2zm30 0h2v2h-2zM5 35h2v2H5zm30 0h2v2h-2zm30 0h2v2h-2zM20 50h2v2h-2zm30 0h2v2h-2zm30 0h2v2h-2zM5 65h2v2H5zm30 0h2v2h-2zm30 0h2v2h-2zM20 80h2v2h-2zm30 0h2v2h-2zm30 0h2v2h-2z" fill="%23d6ceb9"/></svg>'); } .recipe-book { width: 650px; height: 560px; position: relative; perspective: 1500px; margin: 20px auto; } .book-container { transform-style: preserve-3d; width: 100%; height: 100%; transition: transform 0.8s ease; position: relative; } .page { position: absolute; width: 100%; height: 100%; transform-style: preserve-3d; transition: transform 0.6s cubic-bezier(0.645, 0.045, 0.355, 1); transform-origin: left center; backface-visibility: hidden; cursor: pointer; border-radius: 0 10px 10px 0; overflow: hidden; box-shadow: 0 5px 25px rgba(0,0,0,0.1); } .page.front, .page.back { background: var(--card-color); padding: 30px; color: var(--ink-color); } .page.back { transform: rotateY(180deg); } .page.flipped { transform: rotateY(-180deg); } .page.turned { z-index: 10; } .recipe-title { font-family: 'Dancing Script', cursive; font-size: 2.5rem; font-weight: 700; color: var(--ink-color); margin-bottom: 15px; text-align: center; text-shadow: 1px 1px 1px rgba(0,0,0,0.1); position: relative; } .recipe-intro { font-family: 'Caveat', cursive; font-size: 1.3rem; margin-bottom: 20px; line-height: 1.4; color: var(--ink-color); position: relative; } .recipe-section { margin-bottom: 20px; position: relative; } .section-title { font-family: 'Dancing Script', cursive; font-size: 1.8rem; margin-bottom: 10px; color: var(--accent); text-decoration: underline; text-decoration-style: wavy; text-decoration-thickness: 1px; text-underline-offset: 5px; } .ingredients-list, .instructions-list { font-family: 'Caveat', cursive; font-size: 1.25rem; line-height: 1.6; margin-left: 25px; position: relative; } .ingredients-list li, .instructions-list li { margin-bottom: 8px; position: relative; } .recipes-list { list-style: none; margin-top: 20px; } .recipes-list li { font-family: 'Caveat', cursive; font-size: 1.5rem; padding: 10px; margin-bottom: 10px; border-bottom: 1px dashed var(--accent); cursor: pointer; transition: all 0.3s ease; position: relative; } .recipes-list li:hover { color: var(--accent); transform: translateX(5px); } .recipes-list li::before { content: "•"; margin-right: 10px; color: var(--accent); } .note { font-family: 'Caveat', cursive; font-size: 1.2rem; font-style: italic; color: rgba(46, 48, 50, 0.8); margin-top: 20px; padding: 10px; border-top: 1px dashed var(--accent); position: relative; } .coffee-stain { position: absolute; border-radius: 50%; opacity: 0.6; background: var(--coffee-stain); filter: blur(4px); } .tomato-stain { position: absolute; border-radius: 50%; opacity: 0.5; background: var(--tomato-stain); filter: blur(3px); } .smudge { position: absolute; background: rgba(0,0,0,0.06); border-radius: 50%; filter: blur(4px); transform: rotate(45deg); } .nav-arrows { display: flex; justify-content: space-between; position: absolute; bottom: 20px; width: 90%; left: 5%; z-index: 100; } .nav-arrow { width: 40px; height: 40px; background: rgba(146, 107, 75, 0.2); border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: all 0.3s ease; } .nav-arrow:hover { background: rgba(146, 107, 75, 0.4); transform: scale(1.1); } .nav-arrow svg { width: 20px; height: 20px; fill: var(--accent); } .page-number { font-family: 'Caveat', cursive; position: absolute; bottom: 15px; right: 30px; font-size: 1.2rem; color: rgba(46, 48, 50, 0.6); } @media (max-width: 700px) { .recipe-book { width: 95%; height: 600px; } .recipe-title { font-size: 2rem; } .recipe-intro, .ingredients-list, .instructions-list { font-size: 1.1rem; } .section-title { font-size: 1.5rem; } .page { padding: 15px; } } /* Paper texture overlay */ .page::after { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-image: url('data:image/svg+xml;utf8,<svg width="200" height="200" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg"><filter id="noise"><feTurbulence type="fractalNoise" baseFrequency="0.65" numOctaves="3" stitchTiles="stitch"/><feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0.5 0"/></filter><rect width="200" height="200" filter="url(%23noise)" opacity="0.15"/></svg>'); pointer-events: none; z-index: 1; } /* Add handwritten feel with varying ink opacity */ .handwritten { font-family: 'Caveat', cursive; letter-spacing: 0.5px; line-height: 1.5; } .ingredients-list li::first-letter, .instructions-list li::first-letter { font-weight: bold; color: rgba(46, 48, 50, 0.9); } /* Recipe book cover */ .book-cover { position: absolute; width: 100%; height: 100%; background: var(--accent); border-radius: 10px; box-shadow: 0 10px 30px rgba(0,0,0,0.2); display: flex; flex-direction: column; justify-content: center; align-items: center; color: #f8f5e6; padding: 20px; z-index: 0; transform-origin: left center; transition: transform 0.8s cubic-bezier(0.645, 0.045, 0.355, 1); } .book-cover.open { transform: rotateY(-160deg); } .cover-title { font-family: 'Dancing Script', cursive; font-size: 3rem; margin-bottom: 20px; text-align: center; } .cover-subtitle { font-family: 'Noto Serif', serif; font-style: italic; font-size: 1.2rem; text-align: center; margin-bottom: 30px; } .cover-decoration { width: 100px; height: 2px; background: #f8f5e6; margin: 15px 0; position: relative; } .cover-decoration::before, .cover-decoration::after { content: "✽"; position: absolute; top: -10px; color: #f8f5e6; font-size: 1rem; } .cover-decoration::before { left: -15px; } .cover-decoration::after { right: -15px; } /* Page flip corner animation */ .page-corner { position: absolute; bottom: 0; right: 0; width: 40px; height: 40px; background: linear-gradient(135deg, transparent 50%, rgba(0,0,0,0.05) 50%); border-radius: 0 0 0 10px; z-index: 3; cursor: pointer; } .page-corner::before { content: ""; position: absolute; top: 0; right: 0; width: 0; height: 0; border-style: solid; border-width: 0 0 40px 40px; border-color: transparent transparent var(--card-color) transparent; filter: brightness(0.95); } .page-corner:hover::before { border-color: transparent transparent var(--accent) transparent; opacity: 0.3; } /* Custom loading indicator */ .loader { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 100px; height: 100px; display: flex; justify-content: center; align-items: center; } .loader::before { content: ""; width: 60px; height: 60px; border-radius: 50%; border: 6px solid var(--card-color); border-top-color: var(--accent); animation: spin 1s infinite ease-in-out; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } /* Recipe tags */ .recipe-tag { display: inline-block; font-family: 'Caveat', cursive; background: rgba(146, 107, 75, 0.15); padding: 2px 8px; border-radius: 20px; font-size: 0.9rem; margin-right: 5px; margin-bottom: 5px; } /* Cooking time and servings indicator */ .recipe-meta { display: flex; justify-content: space-around; margin: 15px 0; font-family: 'Caveat', cursive; font-size: 1.2rem; } .meta-item { display: flex; align-items: center; } .meta-item svg { width: 20px; height: 20px; margin-right: 5px; fill: var(--accent); } </style> </head> <body> <div class="recipe-book"> <div class="book-cover"> <div class="cover-title">Grandma's Recipe Book</div> <div class="cover-decoration"></div> <div class="cover-subtitle">Family recipes, just like she made them</div> <div class="cover-decoration"></div> </div> <div class="book-container"> <div class="page front" id="page1"> <h1 class="recipe-title">My Recipe Collection</h1> <p class="recipe-intro">Welcome to my little corner of culinary treasures! These are the recipes I've collected over the years—some handed down through generations, others discovered on my own adventures. Each one tells a story of gatherings around the table and moments shared with loved ones.</p> <div class="recipe-section"> <h2 class="section-title">Recipes</h2> <ul class="recipes-list"> <li data-recipe="apple-pie">Grandma's Apple Pie</li> <li data-recipe="tomato-soup">Hearty Tomato Basil Soup</li> <li data-recipe="chocolate-cake">Double Chocolate Fudge Cake</li> <li data-recipe="lemon-chicken">Lemon & Herb Roasted Chicken</li> </ul> </div> <div class="note">Tap on any recipe to flip to its page. Or simply drag the page corner to turn!</div> <div class="coffee-stain" style="width: 80px; height: 80px; top: 70px; right: 30px; transform: rotate(15deg);"></div> <div class="smudge" style="width: 40px; height: 15px; bottom: 100px; left: 50px;"></div> <div class="page-number">1</div> <div class="page-corner"></div> </div> <div class="page back" id="page1-back"> <h1 class="recipe-title">Grandma's Apple Pie</h1> <div class="recipe-meta"> <div class="meta-item"> <svg viewBox="0 0 24 24"><path d="M12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22C6.47,22 2,17.5 2,12A10,10 0 0,1 12,2M12.5,7V12.25L17,14.92L16.25,16.15L11,13V7H12.5Z"/></svg> Prep: 30 mins </div> <div class="meta-item"> <svg viewBox="0 0 24 24"><path d="M8.1,13.34L3.91,9.16C2.35,7.59 2.35,5.06 3.91,3.5L10.93,10.5L8.1,13.34M14.88,11.53L13.41,13L20.29,19.88L18.88,21.29L12,14.41L5.12,21.29L3.71,19.88L13.47,10.12C12.76,8.59 13.26,6.44 14.85,4.85C16.76,2.93 19.5,2.57 20.96,4.03C22.43,5.5 22.07,8.24 20.15,10.15C18.56,11.74 16.41,12.24 14.88,11.53Z"/></svg> Serves: 8 </div> </div> <div class="recipe-section"> <h2 class="section-title">Ingredients</h2> <ul class="ingredients-list handwritten"> <li>2½ cups all-purpose flour</li> <li>1 tsp salt</li> <li>2 tbsp sugar</li> <li>1 cup cold butter, cubed</li> <li>¼ cup ice water</li> <li>6 cups thinly sliced Granny Smith apples</li> <li>¾ cup sugar</li> <li>2 tbsp flour</li> <li>1 tsp cinnamon</li> <li>¼ tsp nutmeg</li> <li>1 tbsp lemon juice</li> <li>1 egg, beaten (for wash)</li> </ul> </div> <div class="tomato-stain" style="width: 50px; height: 50px; bottom: 120px; left: 20px;"></div> <div class="smudge" style="width: 30px; height: 10px; top: 180px; right: 60px;"></div> <div class="page-number">2</div> <div class="page-corner"></div> </div> <div class="page front" id="page2"> <div class="recipe-section"> <h2 class="section-title">Instructions</h2> <ol class="instructions-list handwritten"> <li>Mix flour, salt, and 2 tbsp sugar. Cut in butter until crumbly. Add water 1 tbsp at a time until dough forms.</li> <li>Divide dough in half, flatten into disks. Wrap and chill for 1 hour.</li> <li>Preheat oven to 375°F. Roll one disk to fit a 9-inch pie plate.</li> <li>Mix apples, sugar, flour, spices, and lemon juice. Pour into crust.</li> <li>Roll second disk, cover pie. Crimp edges, cut slits for venting.</li> <li>Brush with beaten egg, sprinkle with sugar.</li> <li>Bake 45-50 minutes until golden and filling bubbles.</li> <li>Cool completely before serving.</li> </ol> </div> <div class="note">Grandma's secret: Add a pinch of cardamom and a splash of brandy to the filling for extra depth of flavor!</div> <div class="coffee-stain" style="width: 100px; height: 100px; top: 50px; right: 40px; transform: rotate(-10deg);"></div> <div class="smudge" style="width: 20px; height: 8px; bottom: 150px; left: 80px;"></div> <div class="page-number">3</div> <div class="page-corner"></div> </div> <div class="page back" id="page2-back"> <h1 class="recipe-title">Hearty Tomato Basil Soup</h1> <div class="recipe-meta"> <div class="meta-item"> <svg viewBox="0 0 24 24"><path d="M12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22C6.47,22 2,17.5 2,12A10,10 0 0,1 12,2M12.5,7V12.25L17,14.92L16.25,16.15L11,13V7H12.5Z"/></svg> Prep: 15 mins </div> <div class="meta-item"> <svg viewBox="0 0 24 24"><path d="M8.1,13.34L3.91,9.16C2.35,7.59 2.35,5.06 3.91,3.5L10.93,10.5L8.1,13.34M14.88,11.53L13.41,13L20.29,19.88L18.88,21.29L12,14.41L5.12,21.29L3.71,19.88L13.47,10.12C12.76,8.59 13.26,6.44 14.85,4.85C16.76,2.93 19.5,2.57 20.96,4.03C22.43,5.5 22.07,8.24 20.15,10.15C18.56,11.74 16.41,12.24 14.88,11.53Z"/></svg> Serves: 6 </div> </div> <div class="recipe-section"> <h2 class="section-title">Ingredients</h2> <ul class="ingredients-list handwritten"> <li>2 tbsp olive oil</li> <li>1 large onion, diced</li> <li>3 garlic cloves, minced</li> <li>2 carrots, diced</li> <li>2 celery stalks, diced</li> <li>2 28oz cans San Marzano tomatoes</li> <li>4 cups vegetable broth</li> <li>2 tbsp tomato paste</li> <li>1 tsp dried oregano</li> <li>1 cup fresh basil leaves, torn</li> <li>½ cup heavy cream</li> <li>Salt and pepper to taste</li> </ul> </div> <div class="tomato-stain" style="width: 70px; height: 70px; top: 200px; right: 60px;"></div> <div class="smudge" style="width: 35px; height: 12px; bottom: 100px; left: 40px;"></div> <div class="page-number">4</div> <div class="page-corner"></div> </div> <div class="page front" id="page3"> <div class="recipe-section"> <h2 class="section-title">Instructions</h2> <ol class="instructions-list handwritten"> <li>Heat olive oil in a large pot over medium heat. Add onions, cook until translucent (about 5 minutes).</li> <li>Add garlic, carrots, and celery. Cook until vegetables begin to soften, about 8 minutes.</li> <li>Add tomatoes, breaking them up with a wooden spoon. Add broth, tomato paste, and oregano.</li> <li>Bring to a boil, then reduce heat and simmer for 30 minutes.</li> <li>Add half the basil. Using an immersion blender, blend until smooth (or transfer carefully to a blender in batches).</li> <li>Return to heat, stir in cream, and warm through. Do not boil.</li> <li>Season with salt and pepper to taste.</li> <li>Serve topped with remaining fresh basil.</li> </ol> </div> <div class="note">Perfect with grilled cheese sandwiches! I like to use crusty sourdough bread and sharp cheddar.</div> <div class="coffee-stain" style="width: 60px; height: 60px; bottom: 80px; right: 30px;"></div> <div class="smudge" style="width: 25px; height: 10px; top: 150px; left: 60px;"></div> <div class="page-number">5</div> <div class="page-corner"></div> </div> <div class="page back" id="page3-back"> <h1 class="recipe-title">Double Chocolate Fudge Cake</h1> <div class="recipe-meta"> <div class="meta-item"> <svg viewBox="0 0 24 24"><path d="M12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22C6.47,22 2,17.5 2,12A10,10 0 0,1 12,2M12.5,7V12.25L17,14.92L16.25,16.15L11,13V7H12.5Z"/></svg> Prep: 25 mins </div> <div class="meta-item"> <svg viewBox="0 0 24 24"><path d="M8.1,13.34L3.91,9.16C2.35,7.59 2.35,5.06 3.91,3.5L10.93,10.5L8.1,13.34M14.88,11.53L13.41,13L20.29,19.88L18.88,21.29L12,14.41L5.12,21.29L3.71,19.88L13.47,10.12C12.76,8.59 13.26,6.44 14.85,4.85C16.76,2.93 19.5,2.57 20.96,4.03C22.43,5.5 22.07,8.24 20.15,10.15C18.56,11.74 16.41,12.24 14.88,11.53Z"/></svg> Serves: 12 </div> </div> <div class="recipe-section"> <h2 class="section-title">Ingredients</h2> <ul class="ingredients-list handwritten"> <li>2 cups all-purpose flour</li> <li>2 cups granulated sugar</li> <li>¾ cup unsweetened cocoa powder</li> <li>2 tsp baking soda</li> <li>1 tsp baking powder</li> <li>1 tsp salt</li> <li>1 cup buttermilk</li> <li>½ cup vegetable oil</li> <li>2 large eggs</li> <li>2 tsp vanilla extract</li> <li>1 cup hot coffee</li> <li>8 oz semisweet chocolate chips</li> </ul> </div> <span class="recipe-tag">Celebration</span> <span class="recipe-tag">Family Favorite</span> <div class="coffee-stain" style="width: 90px; height: 90px; top: 150px; left: 40px;"></div> <div class="smudge" style="width: 40px; height: 15px; bottom: 120px; right: 50px;"></div> <div class="page-number">6</div> <div class="page-corner"></div> </div> <div class="page front" id="page4"> <div class="recipe-section"> <h2 class="section-title">Instructions</h2> <ol class="instructions-list handwritten"> <li>Preheat oven to 350°F. Grease and flour two 9-inch round cake pans.</li> <li>In a large bowl, whisk together flour, sugar, cocoa, baking soda, baking powder, and salt.</li> <li>Add buttermilk, oil, eggs, and vanilla. Beat with mixer on medium speed for 2 minutes.</li> <li>Stir in hot coffee (batter will be thin). Fold in chocolate chips.</li> <li>Pour batter evenly into prepared pans.</li> <li>Bake 30-35 minutes until toothpick inserted in center comes out clean.</li> <li>Cool in pans for 10 minutes, then remove to wire racks to cool completely.</li> <li>Frost with your favorite chocolate frosting between layers and over top and sides.</li> </ol> </div> <div class="note">This was Johnny's birthday cake every year from age 7 to 18! The coffee really brings out the chocolate flavor, but you can't taste the coffee itself.</div> <div class="tomato-stain" style="width: 40px; height: 40px; top: 100px; right: 70px;"></div> <div class="smudge" style="width: 30px; height: 10px; bottom: 180px; left: 60px;"></div> <div class="page-number">7</div> <div class="page-corner"></div> </div> <div class="page back" id="page4-back"> <h1 class="recipe-title">Lemon & Herb Roasted Chicken</h1> <div class="recipe-meta"> <div class="meta-item"> <svg viewBox="0 0 24 24"><path d="M12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22C6.47,22 2,17.5 2,12A10,10 0 0,1 12,2M12.5,7V12.25L17,14.92L16.25,16.15L11,13V7H12.5Z"/></svg> Prep: 20 mins </div> <div class="meta-item"> <svg viewBox="0 0 24 24"><path d="M8.1,13.34L3.91,9.16C2.35,7.59 2.35,5.06 3.91,3.5L10.93,10.5L8.1,13.34M14.88,11.53L13.41,13L20.29,19.88L18.88,21.29L12,14.41L5.12,21.29L3.71,19.88L13.47,10.12C12.76,8.59 13.26,6.44 14.85,4.85C16.76,2.93 19.5,2.57 20.96,4.03C22.43,5.5 22.07,8.24 20.15,10.15C18.56,11.74 16.41,12.24 14.88,11.53Z"/></svg> Serves: 4-6 </div> </div> <div class="recipe-section"> <h2 class="section-title">Ingredients</h2> <ul class="ingredients-list handwritten"> <li>1 whole chicken (4-5 pounds)</li> <li>2 lemons</li> <li>1 head of garlic, halved crosswise</li> <li>¼ cup olive oil</li> <li>3 tbsp fresh rosemary, chopped</li> <li>2 tbsp fresh thyme leaves</li> <li>2 tbsp fresh sage, chopped</li> <li>1 tbsp kosher salt</li> <li>2 tsp black pepper</li> <li>2 tbsp unsalted butter, softened</li> <li>1 cup chicken broth</li> </ul> </div> <span class="recipe-tag">Sunday Dinner</span> <span class="recipe-tag">Comfort Food</span> <div class="coffee-stain" style="width: 70px; height: 70px; bottom: 100px; right: 60px;"></div> <div class="smudge" style="width: 25px; height: 8px; top: 140px; left: 80px;"></div> <div class="page-number">8</div> <div class="page-corner"></div> </div> <div class="page front" id="page5"> <div class="recipe-section"> <h2 class="section-title">Instructions</h2> <ol class="instructions-list handwritten"> <li>Preheat oven to 425°F.</li> <li>Pat chicken dry with paper towels. Place in a roasting pan.</li> <li>Zest one lemon into a small bowl. Quarter both lemons.</li> <li>Mix lemon zest, herbs, olive oil, salt, and pepper.</li> <li>Gently loosen skin from chicken breast and thighs. Rub half the herb mixture under the skin.</li> <li>Rub softened butter over the outside of chicken, then coat with remaining herb mixture.</li> <li>Stuff cavity with quartered lemons and garlic halves.</li> <li>Tie legs together with kitchen twine and tuck wing tips under body.</li> <li>Pour broth into pan. Roast for 1 hour and 15 minutes, or until thermometer inserted into thickest part of thigh reads 165°F.</li> <li>Let rest 15 minutes before carving.</li> </ol> </div> <div class="note">Dad always says this reminds him of Sunday dinners at Grandma's house. The drippings make amazing gravy!</div> <div class="tomato-stain" style="width: 60px; height: 60px; top: 120px; left: 50px;"></div> <div class="smudge" style="width: 20px; height: 10px; bottom: 150px; right: 40px;"></div> <div class="page-number">9</div> <div class="page-corner"></div> </div> <div class="page back" id="page5-back"> <h1 class="recipe-title">Notes & Memories</h1> <p class="recipe-intro">These recipes are more than just ingredients and instructions—they're stories of my family, celebrations, and everyday moments that made us who we are.</p> <div class="recipe-section handwritten" style="font-size: 1.25rem; line-height: 1.6;"> <p>I remember helping Grandma make her
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Digital Origami Greeting Cards</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { display: flex; justify-content: center; align-items: center; min-height: 700px; background: linear-gradient(135deg, #f6f9fc, #e9f1f7); overflow: hidden; padding: 20px; } .container { width: 100%; max-width: 650px; height: 650px; perspective: 1500px; position: relative; } .gallery { display: flex; height: 100px; position: absolute; bottom: 0; width: 100%; justify-content: center; gap: 10px; z-index: 100; } .card-thumbnail { width: 80px; height: 80px; border-radius: 5px; cursor: pointer; transition: transform 0.3s ease, box-shadow 0.3s ease; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); background-size: cover; background-position: center; overflow: hidden; position: relative; } .card-thumbnail:hover { transform: translateY(-5px); box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15); } .card-thumbnail::after { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(135deg, rgba(255,255,255,0.2), rgba(255,255,255,0)); pointer-events: none; } .envelope { position: absolute; width: 300px; height: 200px; top: 50%; left: 50%; transform-style: preserve-3d; transform: translate(-50%, -60%) rotateX(0deg); transition: transform 1s ease; } .envelope.open { transform: translate(-50%, -60%) rotateX(180deg); } .envelope-front { width: 300px; height: 200px; background: linear-gradient(135deg, #e85349, #d42c21); border-radius: 5px; position: absolute; transform-style: preserve-3d; backface-visibility: hidden; box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15); display: flex; justify-content: center; align-items: center; overflow: hidden; } .envelope-front::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: url("data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23ffffff' fill-opacity='0.1' fill-rule='evenodd'%3E%3Ccircle cx='3' cy='3' r='3'/%3E%3Ccircle cx='13' cy='13' r='3'/%3E%3C/g%3E%3C/svg%3E"); } .envelope-seal { width: 40px; height: 40px; background: #f8d568; border-radius: 50%; display: flex; justify-content: center; align-items: center; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); transform: translateZ(1px); cursor: pointer; transition: transform 0.3s ease, box-shadow 0.3s ease; } .envelope-seal:hover { transform: translateZ(5px) scale(1.1); box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3); } .envelope-seal::before { content: ''; position: absolute; width: 20px; height: 20px; background: #e85349; transform: rotate(45deg); } .envelope-back { width: 300px; height: 200px; background: linear-gradient(135deg, #f8f9fa, #e9ecef); border-radius: 5px; position: absolute; transform: rotateX(180deg); backface-visibility: hidden; box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15); display: flex; justify-content: center; align-items: center; } .card { position: absolute; width: 280px; height: 180px; background: white; border-radius: 4px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); transform-style: preserve-3d; transform-origin: center; transition: transform 1.5s cubic-bezier(0.68, -0.55, 0.27, 1.55); transform: translateZ(-10px) translateY(0px) scale(0.95); opacity: 0; overflow: hidden; } .card.active { transform: translateZ(30px) translateY(-40px); opacity: 1; } .card-inner { width: 100%; height: 100%; transform-style: preserve-3d; transition: transform 1s ease; } .card-inner.folded { transform: rotateY(0deg); } .card-inner.unfolded { transform: rotateY(180deg); } .card-front, .card-back { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; display: flex; justify-content: center; align-items: center; } .card-front { background-color: #fff; border-radius: 4px; padding: 15px; text-align: center; display: flex; flex-direction: column; justify-content: center; align-items: center; } .card-back { background-color: #fff; transform: rotateY(180deg); border-radius: 4px; padding: 15px; text-align: center; } .fold-line { position: absolute; width: 2px; height: 100%; left: 50%; background: rgba(0, 0, 0, 0.1); transform: translateX(-50%); z-index: 10; transition: opacity 0.5s ease; } .fold-line.active { opacity: 0; } .crease { position: absolute; width: 100%; height: 100%; background: linear-gradient(90deg, rgba(0, 0, 0, 0) 49.5%, rgba(0, 0, 0, 0.1) 49.5%, rgba(0, 0, 0, 0.1) 50.5%, rgba(0, 0, 0, 0) 50.5%); opacity: 0.5; pointer-events: none; transition: opacity 0.5s ease; } .crease.active { opacity: 0; } .origami-element { position: absolute; background-color: #f8f9fa; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); transform-origin: center; transition: transform 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55); } .instructions { position: absolute; top: 20px; width: 100%; text-align: center; color: #495057; font-size: 16px; font-weight: 300; letter-spacing: 0.5px; opacity: 0.9; } .message { font-size: 16px; line-height: 1.6; color: #495057; margin-top: 15px; opacity: 0; transform: translateY(20px); transition: opacity 0.6s ease, transform 0.6s ease; } .message.visible { opacity: 1; transform: translateY(0); } .sender { font-style: italic; font-size: 14px; margin-top: 10px; color: #6c757d; align-self: flex-end; opacity: 0; transform: translateY(10px); transition: opacity 0.6s ease 0.2s, transform 0.6s ease 0.2s; } .sender.visible { opacity: 1; transform: translateY(0); } .title { font-size: 20px; font-weight: bold; color: #212529; margin-bottom: 10px; opacity: 0; transform: translateY(-10px); transition: opacity 0.6s ease, transform 0.6s ease; } .title.visible { opacity: 1; transform: translateY(0); } .origami-decoration { position: absolute; width: 30px; height: 30px; background-color: #f8d568; transform: rotate(45deg); top: 15px; right: 15px; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); transition: transform 0.3s ease; } .origami-decoration:hover { transform: rotate(45deg) scale(1.1); } .card-front .origami-corner { position: absolute; width: 40px; height: 40px; top: 0; right: 0; background: linear-gradient(135deg, #f8d568 0%, #f8d568 50%, transparent 50%); transform-origin: top right; transition: transform 0.3s ease; } .card-front .origami-corner:hover { transform: scale(1.1); } .birthday-card .card-front { background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%); } .thank-you-card .card-front { background: linear-gradient(135deg, #c1dfc4 0%, #deecdd 100%); } .congratulations-card .card-front { background: linear-gradient(135deg, #ffefba 0%, #ffffff 100%); } .birthday-card .card-back { background: url("data:image/svg+xml,%3Csvg width='52' height='26' viewBox='0 0 52 26' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%239C92AC' fill-opacity='0.1'%3E%3Cpath d='M10 10c0-2.21-1.79-4-4-4-3.314 0-6-2.686-6-6h2c0 2.21 1.79 4 4 4 3.314 0 6 2.686 6 6 0 2.21 1.79 4 4 4 3.314 0 6 2.686 6 6 0 2.21 1.79 4 4 4v2c-3.314 0-6-2.686-6-6 0-2.21-1.79-4-4-4-3.314 0-6-2.686-6-6zm25.464-1.95l8.486 8.486-1.414 1.414-8.486-8.486 1.414-1.414z' /%3E%3C/g%3E%3C/g%3E%3C/svg%3E"), linear-gradient(135deg, #a8edea 0%, #fed6e3 100%); } .thank-you-card .card-back { background: url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 18c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm48 25c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm-43-7c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm63 31c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM34 90c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm56-76c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM12 86c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm28-65c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm23-11c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-6 60c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm29 22c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zM32 63c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm57-13c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-9-21c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM60 91c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM35 41c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM12 60c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2z' fill='%239C92AC' fill-opacity='0.1' fill-rule='evenodd'/%3E%3C/svg%3E"), linear-gradient(135deg, #c1dfc4 0%, #deecdd 100%); } .congratulations-card .card-back { background: url("data:image/svg+xml,%3Csvg width='80' height='80' viewBox='0 0 80 80' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23000000' fill-opacity='0.05'%3E%3Cpath d='M50 50c0-5.523 4.477-10 10-10s10 4.477 10 10-4.477 10-10 10c0 5.523-4.477 10-10 10s-10-4.477-10-10 4.477-10 10-10zM10 10c0-5.523 4.477-10 10-10s10 4.477 10 10-4.477 10-10 10c0 5.523-4.477 10-10 10S0 25.523 0 20s4.477-10 10-10zm10 8c4.418 0 8-3.582 8-8s-3.582-8-8-8-8 3.582-8 8 3.582 8 8 8zm40 40c4.418 0 8-3.582 8-8s-3.582-8-8-8-8 3.582-8 8 3.582 8 8 8z' /%3E%3C/g%3E%3C/g%3E%3C/svg%3E"), linear-gradient(135deg, #ffefba 0%, #ffffff 100%); } @keyframes fold-animation { 0% { transform: rotateY(0deg); } 100% { transform: rotateY(180deg); } } @keyframes unfold-animation { 0% { transform: rotateY(180deg); } 100% { transform: rotateY(0deg); } } @keyframes float { 0% { transform: translateY(0px); } 50% { transform: translateY(-5px); } 100% { transform: translateY(0px); } } .floating { animation: float 3s ease-in-out infinite; } @media (max-width: 700px) { .envelope, .card { transform: translate(-50%, -60%) rotateX(0deg) scale(0.9); } .instructions { font-size: 14px; } .gallery { height: 80px; } .card-thumbnail { width: 70px; height: 70px; } } @media (max-width: 500px) { .envelope, .card { transform: translate(-50%, -60%) rotateX(0deg) scale(0.8); } .card-thumbnail { width: 60px; height: 60px; } } </style> </head> <body> <div class="container"> <div class="instructions">Click the golden seal to open the envelope, then select a card below</div> <div class="envelope"> <div class="envelope-front"> <div class="envelope-seal"></div> </div> <div class="envelope-back"></div> </div> <div class="card birthday-card"> <div class="fold-line"></div> <div class="crease"></div> <div class="card-inner folded"> <div class="card-front"> <div class="origami-corner"></div> <div class="title">Happy Birthday!</div> <div class="message">Tap to unfold the card</div> </div> <div class="card-back"> <div class="title visible">Happy Birthday!</div> <div class="message visible"> May your day be as perfectly crafted as this digital origami card. Here's to another year of beautiful moments, each one folded into the fabric of your life. </div> <div class="sender visible">With love, Sarah</div> </div> </div> </div> <div class="card thank-you-card"> <div class="fold-line"></div> <div class="crease"></div> <div class="card-inner folded"> <div class="card-front"> <div class="origami-corner"></div> <div class="title">Thank You</div> <div class="message">Tap to unfold the card</div> </div> <div class="card-back"> <div class="title visible">Thank You</div> <div class="message visible"> Like the careful creases in origami, your thoughtfulness has made an impression that will last. I am deeply grateful for your kindness. </div> <div class="sender visible">Warmly, Michael</div> </div> </div> </div> <div class="card congratulations-card"> <div class="fold-line"></div> <div class="crease"></div> <div class="card-inner folded"> <div class="card-front"> <div class="origami-corner"></div> <div class="title">Congratulations!</div> <div class="message">Tap to unfold the card</div> </div> <div class="card-back"> <div class="title visible">Congratulations!</div> <div class="message visible"> Just as each fold in origami is intentional, each step in your journey has led to this moment. Cheers to your achievement and the beautiful design of your success! </div> <div class="sender visible">Cheering you on, Emma</div> </div> </div> </div> <div class="gallery"> <div class="card-thumbnail" style="background-color: #fed6e3;" data-card="birthday-card"></div> <div class="card-thumbnail" style="background-color: #c1dfc4;" data-card="thank-you-card"></div> <div class="card-thumbnail" style="background-color: #ffefba;" data-card="congratulations-card"></div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const envelope = document.querySelector('.envelope'); const envelopeSeal = document.querySelector('.envelope-seal'); const cards = document.querySelectorAll('.card'); const cardThumbnails = document.querySelectorAll('.card-thumbnail'); let currentCard = null; // Apply the floating animation to the envelope envelope.classList.add('floating'); // Add envelope opening functionality envelopeSeal.addEventListener('click', function() { envelope.classList.toggle('open'); // If opening envelope, show the first card after a delay if (envelope.classList.contains('open')) { setTimeout(() => { showCard(document.querySelector('.birthday-card')); }, 800); } else { // If closing envelope, hide any active card hideActiveCard(); } }); // Add functionality to card thumbnails cardThumbnails.forEach(thumbnail => { thumbnail.addEventListener('click', function() { if (!envelope.classList.contains('open')) { envelope.classList.add('open'); setTimeout(() => { const cardClass = this.getAttribute('data-card'); showCard(document.querySelector(`.${cardClass}`)); }, 800); } else { const cardClass = this.getAttribute('data-card'); showCard(document.querySelector(`.${cardClass}`)); } }); }); // Add functionality to cards (folding/unfolding) cards.forEach(card => { card.addEventListener('click', function() { const cardInner = this.querySelector('.card-inner'); const foldLine = this.querySelector('.fold-line'); const crease = this.querySelector('.crease'); if (cardInner.classList.contains('folded')) { // Unfold the card cardInner.classList.remove('folded'); cardInner.classList.add('unfolded'); foldLine.classList.add('active'); crease.classList.add('active'); // Show message elements with animation setTimeout(() => { const frontTitle = this.querySelector('.card-front .title'); const frontMessage = this.querySelector('.card-front .message'); frontTitle.classList.add('visible'); frontMessage.classList.add('visible'); }, 500); } else { // Fold the card cardInner.classList.remove('unfolded'); cardInner.classList.add('folded'); foldLine.classList.remove('active'); crease.classList.remove('active'); // Hide message elements const frontTitle = this.querySelector('.card-front .title'); const frontMessage = this.querySelector('.card-front .message'); frontTitle.classList.remove('visible'); frontMessage.classList.remove('visible'); } }); }); // Function to show a specific card function showCard(card) { hideActiveCard(); currentCard = card; card.classList.add('active'); // Reset card to folded state when showing a new card const cardInner = card.querySelector('.card-inner'); const foldLine = card.querySelector('.fold-line'); const crease = card.querySelector('.crease'); cardInner.classList.add('folded'); cardInner.classList.remove('unfolded'); foldLine.classList.remove('active'); crease.classList.remove('active'); // Hide front message elements const frontTitle = card.querySelector('.card-front .title'); const frontMessage = card.querySelector('.card-front .message'); frontTitle.classList.remove('visible'); frontMessage.classList.remove('visible'); } // Function to hide the currently active card function hideActiveCard() { cards.forEach(card => { card.classList.remove('active'); }); currentCard = null; } // Create origami corner fold effect const corners = document.querySelectorAll('.origami-corner'); corners.forEach(corner => { corner.addEventListener('mouseover', function() { this.style.transform = 'scale(1.2) rotate(-5deg)'; }); corner.addEventListener('mouseout', function() { this.style.transform = 'scale(1) rotate(0deg)'; }); }); // Initialize thumbnail backgrounds with proper card designs document.querySelector('[data-card="birthday-card"]').style.background = 'linear-gradient(135deg, #a8edea 0%, #fed6e3 100%)'; document.querySelector('[data-card="thank-you-card"]').style.background = 'linear-gradient(135deg, #c1dfc4 0%, #deecdd 100%)'; document.querySelector('[data-card="congratulations-card"]').style.background = 'linear-gradient(135deg, #ffefba 0%, #ffffff 100%)'; }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Papier Tactile | Premium Stationery</title> <style> :root { --primary-color: #f8f4e8; --accent-color: #c2a780; --dark-color: #3a3a3a; --light-color: #ffffff; --cotton-texture: url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 18c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm48 25c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm-43-7c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm63 31c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM34 90c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm56-76c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM12 86c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm28-65c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm23-11c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-6 60c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm29 22c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zM32 63c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm57-13c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-9-21c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM60 91c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM35 41c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM12 60c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2z' fill='%23ede8dc' fill-opacity='0.2' fill-rule='evenodd'/%3E%3C/svg%3E"); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Cormorant Garamond', serif; } @font-face { font-family: 'Cormorant Garamond'; src: url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@300;400;600&display=swap'); } body { background: var(--primary-color); color: var(--dark-color); width: 100%; height: 100vh; overflow-x: hidden; background-image: var(--cotton-texture); } .container { max-width: 700px; height: 700px; margin: 0 auto; padding: 1.5rem; overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--accent-color) var(--primary-color); } .container::-webkit-scrollbar { width: 6px; } .container::-webkit-scrollbar-track { background: var(--primary-color); } .container::-webkit-scrollbar-thumb { background-color: var(--accent-color); border-radius: 10px; } header { text-align: center; margin-bottom: 2rem; } h1 { font-weight: 600; font-size: 2.2rem; color: var(--dark-color); letter-spacing: 1px; margin-bottom: 0.5rem; } p.tagline { font-size: 1.1rem; font-weight: 300; color: var(--accent-color); letter-spacing: 1px; } .paper-showcase { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1.5rem; margin-bottom: 2rem; } .paper-card { position: relative; border-radius: 8px; overflow: hidden; height: 260px; cursor: pointer; transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); background: var(--light-color); box-shadow: 0 10px 20px rgba(0, 0, 0, 0.05); } .paper-card::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-size: cover; background-position: center; transition: transform 0.6s ease-out; z-index: 1; } .cotton-paper::before { background-image: url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 18c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm48 25c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm-43-7c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm63 31c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM34 90c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm56-76c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM12 86c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm28-65c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm23-11c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-6 60c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm29 22c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zM32 63c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm57-13c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-9-21c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM60 91c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM35 41c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM12 60c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2z' fill='%23f1f1f1' fill-opacity='0.6' fill-rule='evenodd'/%3E%3C/svg%3E"); } .linen-paper::before { background-image: url("data:image/svg+xml,%3Csvg width='40' height='40' viewBox='0 0 40 40' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23f0f0f0' fill-opacity='0.4' fill-rule='evenodd'%3E%3Cpath d='M0 40L40 0H20L0 20M40 40V20L20 40'/%3E%3C/g%3E%3C/svg%3E"); } .recycled-paper::before { background-image: url("data:image/svg+xml,%3Csvg width='52' height='26' viewBox='0 0 52 26' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23f0f0f0' fill-opacity='0.4'%3E%3Cpath d='M10 10c0-2.21-1.79-4-4-4-3.314 0-6-2.686-6-6h2c0 2.21 1.79 4 4 4 3.314 0 6 2.686 6 6 0 2.21 1.79 4 4 4 3.314 0 6 2.686 6 6 0 2.21 1.79 4 4 4v2c-3.314 0-6-2.686-6-6 0-2.21-1.79-4-4-4-3.314 0-6-2.686-6-6zm25.464-1.95l8.486 8.486-1.414 1.414-8.486-8.486 1.414-1.414z' /%3E%3C/g%3E%3C/g%3E%3C/svg%3E"); } .pearl-paper::before { background-image: url("data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23f0f0f0' fill-opacity='0.4' fill-rule='evenodd'%3E%3Ccircle cx='3' cy='3' r='3'/%3E%3Ccircle cx='13' cy='13' r='3'/%3E%3C/g%3E%3C/svg%3E"); } .paper-card:hover { transform: translateY(-10px) scale(1.02); box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1); } .paper-card:hover::before { transform: scale(1.1); } .paper-info { position: absolute; bottom: 0; left: 0; width: 100%; padding: 1.2rem; background: rgba(255, 255, 255, 0.9); backdrop-filter: blur(5px); transform: translateY(65px); transition: transform 0.4s ease; z-index: 2; } .paper-card:hover .paper-info { transform: translateY(0); } .paper-card h3 { font-size: 1.2rem; margin-bottom: 0.5rem; color: var(--dark-color); } .paper-card p { font-size: 0.9rem; line-height: 1.4; color: #666; margin-bottom: 0.8rem; opacity: 0; transform: translateY(10px); transition: all 0.3s ease 0.1s; } .paper-card:hover p { opacity: 1; transform: translateY(0); } .weight-label { display: inline-block; font-size: 0.8rem; padding: 3px 10px; border-radius: 12px; background: var(--accent-color); color: var(--light-color); margin-top: 0.5rem; } .interactive-paper { position: relative; background: var(--light-color); border-radius: 10px; padding: 2rem; margin-top: 3rem; overflow: hidden; box-shadow: 0 10px 25px rgba(0, 0, 0, 0.05); } .interactive-paper::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-image: var(--cotton-texture); opacity: 0.3; } .paper-content { position: relative; z-index: 1; } .paper-title { text-align: center; margin-bottom: 1.5rem; font-size: 1.5rem; color: var(--dark-color); } .paper-options { display: flex; justify-content: space-around; margin-bottom: 2rem; flex-wrap: wrap; gap: 1rem; } .paper-option { padding: 0.5rem 1rem; border: 1px solid #ddd; border-radius: 6px; cursor: pointer; transition: all 0.3s ease; font-size: 0.9rem; background: rgba(255, 255, 255, 0.8); } .paper-option:hover, .paper-option.active { background: var(--accent-color); color: white; transform: translateY(-3px); box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1); } .paper-preview { height: 150px; background: white; border-radius: 6px; display: flex; align-items: center; justify-content: center; overflow: hidden; position: relative; cursor: pointer; transition: all 0.3s ease; } .paper-preview.moving::after { content: ''; position: absolute; top: 50%; left: 0; width: 100%; height: 20px; background: rgba(255, 255, 255, 0.1); filter: blur(10px); transform: translateY(-50%); pointer-events: none; animation: lightSweep 2s infinite; } @keyframes lightSweep { 0% { transform: translateY(-50%) translateX(-100%); } 100% { transform: translateY(-50%) translateX(100%); } } .paper-preview-text { font-size: 1.2rem; color: #555; text-align: center; line-height: 1.5; padding: 0 2rem; user-select: none; } .paper-preview-texture { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-size: cover; opacity: 0.1; pointer-events: none; transition: opacity 0.3s ease; } .footer { text-align: center; margin-top: 3rem; padding: 1rem 0; font-size: 0.9rem; color: #888; border-top: 1px solid rgba(194, 167, 128, 0.3); } .cart-button { display: inline-block; padding: 0.8rem 2rem; background: var(--accent-color); color: white; border: none; border-radius: 6px; font-size: 1rem; cursor: pointer; transition: all 0.3s ease; margin-top: 2rem; position: relative; overflow: hidden; } .cart-button::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.2); transition: all 0.4s ease; } .cart-button:hover::before { left: 100%; } .cart-button:hover { background: #b39672; transform: translateY(-3px); box-shadow: 0 5px 15px rgba(194, 167, 128, 0.4); } .button-wrapper { text-align: center; } /* Responsive adjustments */ @media (max-width: 600px) { .paper-showcase { grid-template-columns: 1fr; } .paper-options { flex-direction: column; align-items: center; } .paper-option { width: 80%; text-align: center; margin-bottom: 0.5rem; } h1 { font-size: 1.8rem; } .paper-card { height: 230px; } } /* Animation for the cards */ @keyframes fadeInUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } .paper-card { animation: fadeInUp 0.6s ease forwards; opacity: 0; } .paper-card:nth-child(1) { animation-delay: 0.1s; } .paper-card:nth-child(2) { animation-delay: 0.2s; } .paper-card:nth-child(3) { animation-delay: 0.3s; } .paper-card:nth-child(4) { animation-delay: 0.4s; } /* Paper Fold Effect on Hover */ .paper-preview { box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); transform-style: preserve-3d; perspective: 1000px; transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); } .paper-preview:hover { box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1); transform: translateY(-5px) rotateX(5deg); } /* Simulated paper depth on corners */ .paper-preview::before { content: ''; position: absolute; top: 0; right: 0; width: 20px; height: 20px; background: linear-gradient(135deg, transparent 50%, rgba(0, 0, 0, 0.05) 50%); border-radius: 0 6px 0 0; transform: rotate(180deg); opacity: 0; transition: opacity 0.3s ease; } .paper-preview:hover::before { opacity: 1; } </style> </head> <body> <div class="container"> <header> <h1>Papier Tactile</h1> <p class="tagline">Experience premium stationery through your screen</p> </header> <section class="paper-showcase"> <div class="paper-card cotton-paper"> <div class="paper-info"> <h3>100% Cotton</h3> <p>Our archival-quality cotton paper offers a luxurious, tactile sensation with subtle texture that brings your words to life.</p> <span class="weight-label">120 GSM</span> </div> </div> <div class="paper-card linen-paper"> <div class="paper-info"> <h3>Italian Linen</h3> <p>Crafted in Florence using traditional methods, this linen paper features a distinct crosshatch texture that catches light beautifully.</p> <span class="weight-label">110 GSM</span> </div> </div> <div class="paper-card recycled-paper"> <div class="paper-info"> <h3>Artisanal Recycled</h3> <p>Eco-conscious with character, our recycled paper contains visible pulp flecks that tell the story of its past life.</p> <span class="weight-label">100 GSM</span> </div> </div> <div class="paper-card pearl-paper"> <div class="paper-info"> <h3>Japanese Pearl</h3> <p>Featuring an iridescent finish that subtly shifts as you move, this paper adds a sophisticated sheen to your correspondence.</p> <span class="weight-label">90 GSM</span> </div> </div> </section> <section class="interactive-paper"> <div class="paper-content"> <h2 class="paper-title">Feel the Difference</h2> <div class="paper-options"> <div class="paper-option active" data-texture="cotton">Cotton</div> <div class="paper-option" data-texture="linen">Linen</div> <div class="paper-option" data-texture="recycled">Recycled</div> <div class="paper-option" data-texture="pearl">Pearl</div> </div> <div class="paper-preview" id="paperPreview"> <div class="paper-preview-texture" id="paperTexture"></div> <p class="paper-preview-text">Move your cursor across to feel the texture</p> </div> <div class="button-wrapper"> <button class="cart-button">Add to Cart</button> </div> </div> </section> <footer class="footer"> <p>Each paper exhibits unique characteristics that respond to ink, pressure, and light.</p> </footer> </div> <script> document.addEventListener('DOMContentLoaded', function() { const paperOptions = document.querySelectorAll('.paper-option'); const paperPreview = document.getElementById('paperPreview'); const paperTexture = document.getElementById('paperTexture'); let currentTexture = 'cotton'; // Set initial texture setTexture('cotton'); // Texture option selection paperOptions.forEach(option => { option.addEventListener('click', function() { paperOptions.forEach(opt => opt.classList.remove('active')); this.classList.add('active'); const texture = this.getAttribute('data-texture'); setTexture(texture); currentTexture = texture; }); }); // Dynamic texture parallax effect on mouse move paperPreview.addEventListener('mousemove', function(e) { const rect = this.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; // Calculate percentage positions const xPercent = x / rect.width * 100; const yPercent = y / rect.height * 100; // Move the texture slightly with mouse paperTexture.style.transform = `translate(${(xPercent - 50) / 10}px, ${(yPercent - 50) / 10}px)`; // Add light reflection effect paperPreview.classList.add('moving'); // Enhance texture opacity on hover paperTexture.style.opacity = 0.4; }); // Reset on mouse leave paperPreview.addEventListener('mouseleave', function() { paperTexture.style.transform = 'translate(0, 0)'; paperPreview.classList.remove('moving'); paperTexture.style.opacity = 0.1; }); // Function to set texture based on selection function setTexture(textureType) { let textureUrl = ''; let backgroundSize = 'cover'; switch(textureType) { case 'cotton': textureUrl = "data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 18c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm48 25c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm-43-7c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm63 31c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM34 90c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm56-76c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM12 86c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm28-65c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm23-11c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-6 60c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm29 22c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zM32 63c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm57-13c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-9-21c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM60 91c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM35 41c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM12 60c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2z' fill='%23ede8dc' fill-opacity='0.4' fill-rule='evenodd'/%3E%3C/svg%3E"; paperPreview.style.boxShadow = "0 1px 3px rgba(0, 0, 0, 0.1)"; break; case 'linen': textureUrl = "data:image/svg+xml,%3Csvg width='40' height='40' viewBox='0 0 40 40' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23c9c9c9' fill-opacity='0.4' fill-rule='evenodd'%3E%3Cpath d='M0 40L40 0H20L0 20M40 40V20L20 40'/%3E%3C/g%3E%3C/svg%3E"; paperPreview.style.boxShadow = "0 1px 4px rgba(0, 0, 0, 0.12)"; break; case 'recycled': textureUrl = "data:image/svg+xml,%3Csvg width='52' height='26' viewBox='0 0 52 26' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23c9c9c9' fill-opacity='0.4'%3E%3Cpath d='M10 10c0-2.21-1.79-4-4-4-3.314 0-6-2.686-6-6h2c0 2.21 1.79 4 4 4 3.314 0 6 2.686 6 6 0 2.21 1.79 4 4 4 3.314 0 6 2.686 6 6 0 2.21 1.79 4 4 4v2c-3.314 0-6-2.686-6-6 0-2.21-1.79-4-4-4-3.314 0-6-2.686-6-6zm25.464-1.95l8.486 8.486-1.414 1.414-8.486-8.486 1.414-1.414z' /%3E%3C/g%3E%3C/g%3E%3C/svg%3E"; paperPreview.style.boxShadow = "0 1px 5px rgba(0, 0, 0, 0.15)"; paperPreview.style.background = "#fffdf9"; break; case 'pearl': textureUrl = "data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23d3d3d3' fill-opacity='0.4' fill-rule='evenodd'%3E%3Ccircle cx='3' cy='3' r='3'/%3E%3Ccircle cx='13' cy='13' r='3'/%3E%3C/g%3E%3C/svg%3E"; paperPreview.style.boxShadow = "0 1px 3px rgba(0, 0, 0, 0.08)"; paperPreview.style.background = "linear-gradient(135deg, #ffffff 0%, #f9f9f9 50%, #f8f8f8 100%)"; break; } paperTexture.style.backgroundImage = `url('${textureUrl}')`; paperTexture.style.backgroundSize = backgroundSize; // Add subtle transition effect paperPreview.style.opacity = 0.8; setTimeout(() => { paperPreview.style.opacity = 1; }, 100); } // Button effects const cartButton = document.querySelector('.cart-button'); cartButton.addEventListener('click', function(e) { e.preventDefault(); this.classList.add('clicked'); // Add ripple effect const ripple = document.createElement('span'); ripple.classList.add('ripple'); this.appendChild(ripple); // Notification feedback const originalText = this.textContent; this.textContent = "Added to Cart!"; setTimeout(() => { this.textContent = originalText; if (ripple) ripple.remove(); this.classList.remove('clicked'); }, 1500); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Comic Book Experience</title> <style> @import url('https://fonts.googleapis.com/css2?family=Bangers&family=Comic+Neue:wght@400;700&display=swap'); :root { --primary-color: #ff3d5a; --secondary-color: #3d66ff; --accent-color: #ffd500; --bg-color: #f4f4f4; --text-color: #222; --panel-shadow: 0 10px 20px rgba(0,0,0,0.15); --panel-border: 4px solid #000; } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Comic Neue', cursive; background-color: var(--bg-color); background-image: linear-gradient(rgba(0, 0, 0, 0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(0, 0, 0, 0.05) 1px, transparent 1px); background-size: 20px 20px; color: var(--text-color); overflow-x: hidden; height: 100vh; width: 100%; display: flex; justify-content: center; align-items: center; } .comic-container { width: 100%; max-width: 700px; height: 600px; margin: 0 auto; position: relative; overflow: hidden; background-color: #fff; box-shadow: 0 0 15px rgba(0, 0, 0, 0.2), 0 0 30px rgba(0, 0, 0, 0.1); border-radius: 8px; border: var(--panel-border); transform-style: preserve-3d; transform-origin: center center; transition: transform 0.5s ease; } .comic-container::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-image: url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 18c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm48 25c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm-43-7c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm63 31c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM34 90c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm56-76c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM12 86c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm28-65c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm23-11c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-6 60c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm29 22c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zM32 63c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm57-13c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-9-21c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM60 91c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM35 41c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM12 60c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2z' fill='%23000000' fill-opacity='0.02' fill-rule='evenodd'/%3E%3C/svg%3E"); z-index: -1; } .toolbar { position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%); display: flex; gap: 15px; z-index: 100; } .button { font-family: 'Bangers', cursive; background-color: var(--primary-color); color: white; border: 3px solid black; padding: 8px 15px; font-size: 18px; cursor: pointer; border-radius: 8px; box-shadow: 3px 3px 0 black; transition: all 0.2s ease; text-transform: uppercase; position: relative; overflow: hidden; } .button:hover { transform: translateY(-3px); box-shadow: 5px 5px 0 black; } .button:active { transform: translateY(0); box-shadow: 1px 1px 0 black; } .button::after { content: ''; position: absolute; top: -50%; left: -60%; width: 200%; height: 200%; background: linear-gradient(transparent, rgba(255, 255, 255, 0.3), transparent); transform: rotate(30deg); transition: all 0.5s ease; } .button:hover::after { left: 100%; } .button.next-btn { background-color: var(--secondary-color); } .button.prev-btn { background-color: var(--accent-color); color: black; } .page { position: absolute; width: 100%; height: 100%; display: grid; grid-template-rows: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr); gap: 20px; padding: 20px; transition: transform 0.8s ease, opacity 0.8s ease; transform-origin: center center; } .page.active { transform: translateX(0); opacity: 1; z-index: 10; } .page.prev { transform: translateX(-100%) rotate(-5deg); opacity: 0; z-index: 5; } .page.next { transform: translateX(100%) rotate(5deg); opacity: 0; z-index: 5; } .panel { background-color: white; border: var(--panel-border); box-shadow: var(--panel-shadow); border-radius: 5px; overflow: hidden; position: relative; cursor: pointer; transition: transform 0.3s ease, box-shadow 0.3s ease; display: flex; flex-direction: column; justify-content: space-between; transform-style: preserve-3d; } .panel:hover { transform: scale(1.05) rotateY(5deg); box-shadow: 0 15px 25px rgba(0,0,0,0.2); } .panel.full-width { grid-column: span 2; } .panel.full-height { grid-row: span 2; } .panel-header { background-color: var(--primary-color); color: white; font-family: 'Bangers', cursive; padding: 10px; font-size: 1.2rem; text-align: center; text-transform: uppercase; border-bottom: 3px solid black; letter-spacing: 1px; text-shadow: 2px 2px 0 black; } .panel-content { padding: 15px; flex-grow: 1; display: flex; flex-direction: column; justify-content: center; align-items: center; background-size: cover; background-position: center; position: relative; } .panel-footer { font-size: 0.9rem; padding: 5px 10px; background-color: rgba(0, 0, 0, 0.05); text-align: right; border-top: 1px dashed #ccc; } .speech-bubble { background-color: white; border: 3px solid black; border-radius: 30px; padding: 15px; position: relative; margin: 10px 0; max-width: 80%; align-self: flex-start; box-shadow: 3px 3px 0 black; font-weight: bold; } .speech-bubble::after { content: ''; position: absolute; bottom: -15px; left: 20px; width: 20px; height: 20px; background-color: white; border-right: 3px solid black; border-bottom: 3px solid black; transform: rotate(45deg); } .speech-bubble.right { align-self: flex-end; } .speech-bubble.right::after { left: auto; right: 20px; border-right: none; border-bottom: none; border-left: 3px solid black; border-top: 3px solid black; bottom: -15px; } .character { max-width: 70%; height: auto; filter: drop-shadow(3px 3px 0 rgba(0,0,0,0.3)); margin-top: auto; } .halftone { position: relative; } .halftone::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-image: radial-gradient(#000 1px, transparent 1px); background-size: 5px 5px; opacity: 0.1; pointer-events: none; z-index: 1; } .splash { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 50; opacity: 0; pointer-events: none; background-color: white; transform: scale(0); transition: all 0.5s ease; } .splash.active { opacity: 1; transform: scale(1); } .splash-svg { width: 100%; height: 100%; } .caption { font-family: 'Bangers', cursive; background-color: var(--accent-color); color: black; display: inline-block; padding: 5px 10px; transform: rotate(-2deg); margin: 10px 0; font-size: 1.2rem; border: 2px solid black; box-shadow: 3px 3px 0 black; } .sound-effect { font-family: 'Bangers', cursive; position: absolute; color: var(--primary-color); font-size: 2rem; text-shadow: 2px 2px 0 black; transform: rotate(-10deg); z-index: 10; letter-spacing: 1px; animation: pulse 1s infinite alternate; } @keyframes pulse { from { transform: rotate(-10deg) scale(1); } to { transform: rotate(-10deg) scale(1.1); } } .folded-corner { position: relative; } .folded-corner::after { content: ''; position: absolute; bottom: 0; right: 0; width: 30px; height: 30px; background: linear-gradient(135deg, transparent 50%, rgba(0,0,0,0.1) 50%); border-radius: 0 0 5px 0; } .comic-intro { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: var(--primary-color); display: flex; flex-direction: column; justify-content: center; align-items: center; z-index: 100; transition: transform 0.8s ease, opacity 0.8s ease; } .comic-intro.hidden { transform: translateY(-100%); opacity: 0; } .comic-title { font-family: 'Bangers', cursive; font-size: 3rem; color: white; text-align: center; text-shadow: 4px 4px 0 black; margin-bottom: 20px; letter-spacing: 2px; transform: rotate(-3deg); } .comic-subtitle { font-family: 'Comic Neue', cursive; font-size: 1.2rem; color: white; text-align: center; max-width: 80%; margin-bottom: 30px; } .start-button { font-family: 'Bangers', cursive; background-color: var(--accent-color); color: black; border: 4px solid black; padding: 12px 30px; font-size: 1.5rem; cursor: pointer; border-radius: 10px; box-shadow: 5px 5px 0 black; transition: all 0.2s ease; text-transform: uppercase; letter-spacing: 1px; } .start-button:hover { transform: translateY(-5px); box-shadow: 7px 7px 0 black; } .start-button:active { transform: translateY(0); box-shadow: 2px 2px 0 black; } /* Media Queries */ @media (max-width: 500px) { .comic-container { height: 550px; } .page { grid-template-rows: repeat(4, 1fr); grid-template-columns: 1fr; gap: 10px; padding: 10px; } .panel.full-width { grid-column: span 1; } .panel-header { font-size: 1rem; padding: 5px; } .speech-bubble { padding: 10px; font-size: 0.9rem; } .comic-title { font-size: 2.2rem; } .comic-subtitle { font-size: 1rem; } } </style> </head> <body> <div class="comic-container"> <!-- Splash effect for transitions --> <div class="splash"> <svg class="splash-svg" viewBox="0 0 100 100" preserveAspectRatio="none"> <path d="M50,0 L100,40 L80,100 L20,90 L0,30 Z" fill="var(--primary-color)"></path> </svg> </div> <!-- Intro Screen --> <div class="comic-intro"> <h1 class="comic-title">DIGITAL PANEL ADVENTURES</h1> <p class="comic-subtitle">Explore the fusion of classic comic art and modern digital interaction in this immersive comic experience!</p> <button class="start-button" id="start-btn">BEGIN!</button> </div> <!-- Pages --> <div class="page active"> <div class="panel halftone folded-corner"> <div class="panel-header">Welcome to the Future</div> <div class="panel-content"> <div class="speech-bubble">This is where comics and digital collide!</div> <div class="caption">The beginning of a new era</div> </div> </div> <div class="panel"> <div class="panel-header" style="background-color: var(--secondary-color);">Halftone Textures</div> <div class="panel-content halftone"> <div class="speech-bubble right">Classic printing techniques meet modern web design</div> <div class="sound-effect" style="top: 20px; right: 10px;">POP!</div> </div> </div> <div class="panel"> <div class="panel-header" style="background-color: var(--accent-color); color: black;">Bold Outlines</div> <div class="panel-content"> <div class="speech-bubble">Heavy borders create that authentic comic feel!</div> </div> <div class="panel-footer">Click to interact →</div> </div> <div class="panel halftone"> <div class="panel-header" style="background-color: #7a28cb;">Interact!</div> <div class="panel-content"> <div class="speech-bubble right">Try clicking panels and buttons!</div> <div class="sound-effect" style="bottom: 20px; left: 30px;">ZOOM!</div> </div> </div> </div> <div class="page next"> <div class="panel full-width halftone"> <div class="panel-header">Exaggerated Paper Effects</div> <div class="panel-content"> <div class="speech-bubble">Notice how the panels fold and crease like real comic pages?</div> <div class="sound-effect" style="top: 50%; left: 50%; transform: translate(-50%, -50%) rotate(-5deg);">CRINKLE!</div> </div> </div> <div class="panel full-height" style="grid-column: 1"> <div class="panel-header" style="background-color: var(--secondary-color);">Dynamic Storytelling</div> <div class="panel-content"> <div class="speech-bubble">Comics are all about sequential art...</div> <div class="speech-bubble right">...but digital adds motion and interactivity!</div> <div class="caption">A whole new dimension</div> </div> </div> <div class="panel" style="grid-column: 2; grid-row: 2"> <div class="panel-header" style="background-color: #28cb71;">Ink Splashes</div> <div class="panel-content halftone"> <div class="speech-bubble">Watch for dramatic transitions between panels!</div> </div> <div class="panel-footer">Try navigating →</div> </div> </div> <div class="page next"> <div class="panel full-height"> <div class="panel-header" style="background-color: var(--accent-color); color: black;">Bold Comic Design</div> <div class="panel-content halftone"> <div class="speech-bubble">Strong colors and heavy shadows create visual impact!</div> <div class="caption">Classic comic styling</div> <div class="sound-effect" style="bottom: 30%; right: 20%;">KAPOW!</div> </div> </div> <div class="panel" style="grid-column: 2; grid-row: 1"> <div class="panel-header" style="background-color: #cb3c28;">Speech Bubbles</div> <div class="panel-content"> <div class="speech-bubble right">Notice how they point to the speaker?</div> </div> <div class="panel-footer">A comic essential</div> </div> <div class="panel" style="grid-column: 2; grid-row: 2"> <div class="panel-header" style="background-color: var(--secondary-color);">The End?</div> <div class="panel-content"> <div class="speech-bubble">Or just the beginning of your comic journey...</div> <div class="caption">To be continued!</div> </div> </div> </div> <div class="toolbar"> <button class="button prev-btn">Previous</button> <button class="button next-btn">Next</button> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const container = document.querySelector('.comic-container'); const pages = document.querySelectorAll('.page'); const nextBtn = document.querySelector('.next-btn'); const prevBtn = document.querySelector('.prev-btn'); const splash = document.querySelector('.splash'); const startBtn = document.getElementById('start-btn'); const comicIntro = document.querySelector('.comic-intro'); const panels = document.querySelectorAll('.panel'); let currentPage = 0; // Initialize pages function updatePages() { pages.forEach((page, index) => { if (index === currentPage) { page.className = 'page active'; } else if (index < currentPage) { page.className = 'page prev'; } else { page.className = 'page next'; } }); } // Splash transition effect function showSplash() { splash.classList.add('active'); setTimeout(() => { splash.classList.remove('active'); }, 600); } // Next page nextBtn.addEventListener('click', function() { if (currentPage < pages.length - 1) { showSplash(); setTimeout(() => { currentPage++; updatePages(); container.style.transform = `rotateY(${Math.random() * 2 - 1}deg) rotateX(${Math.random() * 2 - 1}deg)`; }, 300); } }); // Previous page prevBtn.addEventListener('click', function() { if (currentPage > 0) { showSplash(); setTimeout(() => { currentPage--; updatePages(); container.style.transform = `rotateY(${Math.random() * 2 - 1}deg) rotateX(${Math.random() * 2 - 1}deg)`; }, 300); } }); // Start button startBtn.addEventListener('click', function() { comicIntro.classList.add('hidden'); }); // Panel interaction panels.forEach(panel => { panel.addEventListener('click', function() { // Random sound effects on panel click const sounds = ['BAM!', 'POW!', 'ZOOM!', 'WHAM!', 'POP!', 'CRASH!']; const randomSound = sounds[Math.floor(Math.random() * sounds.length)]; const soundEffect = document.createElement('div'); soundEffect.className = 'sound-effect'; soundEffect.style.top = `${Math.random() * 70 + 10}%`; soundEffect.style.left = `${Math.random() * 70 + 10}%`; soundEffect.textContent = randomSound; this.appendChild(soundEffect); // Apply a random transform to the panel this.style.transform = `scale(1.05) rotate(${Math.random() * 4 - 2}deg)`; // Remove the sound effect after animation setTimeout(() => { soundEffect.remove(); this.style.transform = ''; }, 1000); }); }); // Randomly apply paper folding effects function applyPaperEffects() { container.style.transform = `rotateY(${Math.random() * 2 - 1}deg) rotateX(${Math.random() * 2 - 1}deg)`; } // Apply initial paper effects applyPaperEffects(); // Mouse movement effects for 3D feel container.addEventListener('mousemove', function(e) { const xAxis = (window.innerWidth / 2 - e.pageX) / 25; const yAxis = (window.innerHeight / 2 - e.pageY) / 25; this.style.transform = `rotateY(${xAxis}deg) rotateX(${yAxis}deg)`; }); // Reset transform when mouse leaves container.addEventListener('mouseleave', function() { this.style.transform = `rotateY(0deg) rotateX(0deg)`; }); // Touch event handling for mobile let touchStartX = 0; let touchEndX = 0; container.addEventListener('touchstart', e => { touchStartX = e.changedTouches[0].screenX; }); container.addEventListener('touchend', e => { touchEndX = e.changedTouches[0].screenX; handleSwipe(); }); function handleSwipe() { const swipeThreshold = 50; if (touchEndX < touchStartX - swipeThreshold) { // Swipe left - go to next page if (currentPage < pages.length - 1) { showSplash(); setTimeout(() => { currentPage++; updatePages(); }, 300); } } if (touchEndX > touchStartX + swipeThreshold) { // Swipe right - go to previous page if (currentPage > 0) { showSplash(); setTimeout(() => { currentPage--; updatePages(); }, 300); } } } }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>EcoScribe - Sustainability Blog</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Poppins', sans-serif; } :root { --leaf-green: #4a7c59; --moss-green: #8a9a5b; --earth-brown: #9c7c38; --paper-cream: #f8f4e3; --bark-brown: #5e503f; } @font-face { font-family: 'Poppins'; src: url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap'); } body { background-color: var(--paper-cream); background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiPgogIDxmaWx0ZXIgaWQ9Im5vaXNlIiB4PSIwIiB5PSIwIj4KICAgIDxmZVR1cmJ1bGVuY2UgdHlwZT0iZnJhY3RhbE5vaXNlIiBiYXNlRnJlcXVlbmN5PSIwLjY1IiBudW1PY3RhdmVzPSIzIiBzdGl0Y2hUaWxlcz0ic3RpdGNoIiAvPgogICAgPGZlQmxlbmQgbW9kZT0ibXVsdGlwbHkiIGluPSJTb3VyY2VHcmFwaGljIiAvPgogIDwvZmlsdGVyPgogIDxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbHRlcj0idXJsKCNub2lzZSkiIG9wYWNpdHk9IjAuMDciLz4KPC9zdmc+'); position: relative; overflow-x: hidden; max-width: 700px; height: 700px; margin: 0 auto; } .fiber { position: absolute; background-color: rgba(156, 124, 56, 0.1); border-radius: 50%; transform: rotate(45deg); } header { padding: 1.5rem; position: relative; overflow: hidden; border-bottom: 2px solid rgba(74, 124, 89, 0.2); } .logo { display: flex; align-items: center; gap: 0.8rem; margin-bottom: 1rem; } .logo-icon { width: 40px; height: 40px; background-color: var(--leaf-green); border-radius: 50%; display: flex; align-items: center; justify-content: center; position: relative; overflow: hidden; } .logo-icon::before { content: ""; position: absolute; width: 24px; height: 24px; background-color: var(--paper-cream); border-radius: 50% 0 50% 50%; transform: rotate(45deg); } .logo h1 { color: var(--leaf-green); font-size: 1.8rem; font-weight: 600; letter-spacing: 0.5px; } .search { display: flex; align-items: center; background: rgba(255, 255, 255, 0.6); border: 1px solid var(--moss-green); border-radius: 25px; padding: 0.6rem 1rem; margin-bottom: 1rem; transition: all 0.3s ease; } .search:focus-within { box-shadow: 0 0 0 2px rgba(74, 124, 89, 0.3); } .search input { flex: 1; border: none; background: transparent; outline: none; font-size: 0.9rem; color: var(--bark-brown); } .search button { background: none; border: none; cursor: pointer; color: var(--leaf-green); display: flex; align-items: center; justify-content: center; } .nav-tabs { display: flex; gap: 1rem; overflow-x: auto; padding-bottom: 0.5rem; scrollbar-width: none; } .nav-tabs::-webkit-scrollbar { display: none; } .nav-tab { padding: 0.5rem 1rem; background: transparent; border: none; color: var(--bark-brown); white-space: nowrap; cursor: pointer; position: relative; font-weight: 500; transition: all 0.3s ease; } .nav-tab::after { content: ""; position: absolute; bottom: -2px; left: 50%; transform: translateX(-50%); width: 0; height: 2px; background-color: var(--leaf-green); transition: width 0.3s ease; } .nav-tab:hover::after, .nav-tab.active::after { width: 80%; } .nav-tab.active { color: var(--leaf-green); font-weight: 600; } .leaf-button { background-color: var(--leaf-green); color: white; border: none; padding: 0.7rem 1.5rem; border-radius: 25px; font-weight: 500; cursor: pointer; display: flex; align-items: center; gap: 0.5rem; position: relative; overflow: hidden; transition: all 0.3s ease; box-shadow: 0 4px 12px rgba(74, 124, 89, 0.2); } .leaf-button::before { content: ""; position: absolute; width: 20px; height: 20px; background-color: rgba(255, 255, 255, 0.1); border-radius: 50% 0 50% 50%; right: 10px; bottom: -10px; transform: rotate(45deg); transition: all 0.3s ease; } .leaf-button:hover { background-color: #3d6b4a; transform: translateY(-2px); } .leaf-button:hover::before { transform: rotate(60deg) scale(1.2); } main { padding: 1.5rem; overflow-y: auto; height: calc(100% - 180px); } .parallax-container { position: relative; overflow: hidden; border-radius: 12px; margin-bottom: 1.5rem; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); } .parallax-bg { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiPgogIDxsaW5lYXJHcmFkaWVudCBpZD0iZ3JhZCIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMTAwJSI+CiAgICA8c3RvcCBvZmZzZXQ9IjAlIiBzdHlsZT0ic3RvcC1jb2xvcjojNGE3YzU5O3N0b3Atb3BhY2l0eTowLjgiIC8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0eWxlPSJzdG9wLWNvbG9yOiM4YTlhNWI7c3RvcC1vcGFjaXR5OjAuOSIgLz4KICA8L2xpbmVhckdyYWRpZW50PgogIDxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiLz4KPC9zdmc+'); transform: translateY(0); transition: transform 0.3s ease-out; z-index: 1; } .parallax-content { position: relative; padding: 2.5rem 2rem; color: white; z-index: 2; } .parallax-title { font-size: 1.5rem; font-weight: 700; margin-bottom: 1rem; text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); } .parallax-desc { font-size: 0.95rem; margin-bottom: 1.5rem; line-height: 1.5; max-width: 90%; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); } .article-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 1.5rem; } .article-card { background: white; border-radius: 12px; overflow: hidden; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.06); transition: all 0.3s ease; position: relative; } .article-card:hover { transform: translateY(-5px); box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1); } .article-img { height: 130px; background-color: var(--moss-green); position: relative; overflow: hidden; } .article-img::after { content: ""; position: absolute; bottom: 0; left: 0; width: 100%; height: 40%; background: linear-gradient(to top, rgba(0, 0, 0, 0.6), transparent); } .article-pattern { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCI+CiAgPHBhdGggZD0iTTAgMCBMIDUgMCBMIDAgNSBaIiBmaWxsPSIjZmZmZmZmIiBmaWxsLW9wYWNpdHk9IjAuMSIvPgo8L3N2Zz4='); opacity: 0.4; } .article-badge { position: absolute; top: 10px; left: 10px; background-color: var(--leaf-green); color: white; padding: 0.3rem 0.7rem; border-radius: 20px; font-size: 0.7rem; font-weight: 500; z-index: 2; } .article-content { padding: 1rem; } .article-title { font-size: 1rem; font-weight: 600; margin-bottom: 0.5rem; color: var(--bark-brown); line-height: 1.4; } .article-meta { display: flex; align-items: center; gap: 0.5rem; color: #888; font-size: 0.8rem; } .reading-time { display: flex; align-items: center; gap: 0.2rem; } .icon { width: 16px; height: 16px; display: inline-flex; align-items: center; justify-content: center; } .newsletter { background: white; border-radius: 12px; padding: 1.5rem; margin-top: 2rem; position: relative; overflow: hidden; border: 1px solid rgba(74, 124, 89, 0.2); } .newsletter::before { content: ""; position: absolute; width: 150px; height: 150px; background-color: rgba(74, 124, 89, 0.05); border-radius: 50%; top: -50px; right: -50px; } .newsletter h3 { color: var(--leaf-green); margin-bottom: 0.8rem; font-size: 1.2rem; } .newsletter p { color: var(--bark-brown); font-size: 0.9rem; margin-bottom: 1rem; line-height: 1.5; } .newsletter-form { display: flex; gap: 0.8rem; } .newsletter-form input { flex: 1; padding: 0.8rem 1rem; border: 1px solid rgba(74, 124, 89, 0.3); border-radius: 25px; outline: none; background-color: rgba(255, 255, 255, 0.5); transition: all 0.3s ease; } .newsletter-form input:focus { border-color: var(--leaf-green); box-shadow: 0 0 0 2px rgba(74, 124, 89, 0.1); } .more-link { display: inline-flex; align-items: center; gap: 0.3rem; color: var(--leaf-green); text-decoration: none; font-weight: 500; font-size: 0.9rem; margin-top: 1.5rem; position: relative; } .more-link::after { content: ""; position: absolute; bottom: -2px; left: 0; width: 0; height: 1px; background-color: var(--leaf-green); transition: width 0.3s ease; } .more-link:hover::after { width: 100%; } @media (max-width: 600px) { header { padding: 1rem; } main { padding: 1rem; height: calc(100% - 160px); } .parallax-content { padding: 2rem 1.5rem; } .parallax-title { font-size: 1.3rem; } .article-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 1rem; } .article-img { height: 100px; } .newsletter { padding: 1.2rem; } .newsletter-form { flex-direction: column; } } .spinner { width: 24px; height: 24px; border: 3px solid rgba(255, 255, 255, 0.2); border-radius: 50%; border-top-color: white; animation: spin 1s ease infinite; display: none; } @keyframes spin { to { transform: rotate(360deg); } } .loading .spinner { display: inline-block; } .loading-text { display: inline; } .loading .loading-text { display: none; } </style> </head> <body> <header> <div class="logo"> <div class="logo-icon"></div> <h1>EcoScribe</h1> </div> <div class="search"> <input type="text" placeholder="Search sustainable living topics..."> <button> <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="11" cy="11" r="8"></circle> <line x1="21" y1="21" x2="16.65" y2="16.65"></line> </svg> </button> </div> <div class="nav-tabs"> <button class="nav-tab active">Home</button> <button class="nav-tab">Zero Waste</button> <button class="nav-tab">Ethical Fashion</button> <button class="nav-tab">Green Energy</button> <button class="nav-tab">Eco-Travel</button> </div> </header> <main> <div class="parallax-container"> <div class="parallax-bg"></div> <div class="parallax-content"> <h2 class="parallax-title">Climate Action: A Path Forward</h2> <p class="parallax-desc">Discover how small daily choices can lead to significant environmental impact. Our new series explores practical, achievable steps everyone can take.</p> <button class="leaf-button"> <span>Read the series</span> <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M5 12h14M12 5l7 7-7 7"></path> </svg> </button> </div> </div> <div class="article-grid"> <div class="article-card"> <div class="article-img"> <div class="article-pattern"></div> <div class="article-badge">Zero Waste</div> </div> <div class="article-content"> <h3 class="article-title">The Beginner's Guide to Composting in Small Spaces</h3> <div class="article-meta"> <div class="reading-time"> <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="10"></circle> <polyline points="12 6 12 12 16 14"></polyline> </svg> <span>8 min read</span> </div> </div> </div> </div> <div class="article-card"> <div class="article-img"> <div class="article-pattern"></div> <div class="article-badge">Fashion</div> </div> <div class="article-content"> <h3 class="article-title">5 Biodegradable Fabrics Reshaping Ethical Fashion</h3> <div class="article-meta"> <div class="reading-time"> <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="10"></circle> <polyline points="12 6 12 12 16 14"></polyline> </svg> <span>6 min read</span> </div> </div> </div> </div> <div class="article-card"> <div class="article-img"> <div class="article-pattern"></div> <div class="article-badge">Energy</div> </div> <div class="article-content"> <h3 class="article-title">Solar Panel Innovations: What's New in 2023</h3> <div class="article-meta"> <div class="reading-time"> <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="10"></circle> <polyline points="12 6 12 12 16 14"></polyline> </svg> <span>12 min read</span> </div> </div> </div> </div> </div> <a href="#" class="more-link"> <span>View all articles</span> <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M5 12h14M12 5l7 7-7 7"></path> </svg> </a> <div class="newsletter"> <h3>Join Our Community</h3> <p>Subscribe for bi-weekly tips on sustainable living, exclusive guides and early access to our virtual eco-events.</p> <form class="newsletter-form"> <input type="email" placeholder="Your email address" required> <button class="leaf-button" type="button"> <span class="loading-text">Subscribe</span> <span class="spinner"></span> </button> </form> </div> </main> <script> document.addEventListener('DOMContentLoaded', function() { // Create random paper fibers const body = document.body; for (let i = 0; i < 40; i++) { const fiber = document.createElement('div'); fiber.classList.add('fiber'); const size = Math.random() * 15 + 5; const posX = Math.random() * 700; const posY = Math.random() * 700; fiber.style.width = `${size}px`; fiber.style.height = `${size * 5}px`; fiber.style.left = `${posX}px`; fiber.style.top = `${posY}px`; fiber.style.opacity = Math.random() * 0.1 + 0.05; fiber.style.transform = `rotate(${Math.random() * 180}deg)`; body.appendChild(fiber); } // Parallax effect const parallaxBg = document.querySelector('.parallax-bg'); const parallaxContainer = document.querySelector('.parallax-container'); parallaxContainer.addEventListener('mousemove', function(e) { const containerRect = parallaxContainer.getBoundingClientRect(); const mouseX = e.clientX - containerRect.left; const mouseY = e.clientY - containerRect.top; const moveX = (mouseX / containerRect.width - 0.5) * 15; const moveY = (mouseY / containerRect.height - 0.5) * 15; parallaxBg.style.transform = `translate(${moveX}px, ${moveY}px)`; }); parallaxContainer.addEventListener('mouseleave', function() { parallaxBg.style.transform = 'translateY(0)'; }); // Navigation tabs const tabs = document.querySelectorAll('.nav-tab'); tabs.forEach(tab => { tab.addEventListener('click', function() { tabs.forEach(t => t.classList.remove('active')); this.classList.add('active'); }); }); // Newsletter subscription simulation const subscribeBtn = document.querySelector('.newsletter-form .leaf-button'); const emailInput = document.querySelector('.newsletter-form input'); subscribeBtn.addEventListener('click', function() { if (!emailInput.value.trim()) { emailInput.focus(); return; } this.classList.add('loading'); setTimeout(() => { this.classList.remove('loading'); emailInput.value = ''; // Show success message const form = document.querySelector('.newsletter-form'); const successMsg = document.createElement('p'); successMsg.textContent = "You're all set! Check your inbox to confirm."; successMsg.style.color = "var(--leaf-green)"; successMsg.style.marginTop = "0.5rem"; successMsg.style.fontSize = "0.9rem"; successMsg.style.fontWeight = "500"; // Add animation to success message successMsg.style.opacity = "0"; successMsg.style.transform = "translateY(10px)"; successMsg.style.transition = "all 0.3s ease"; form.appendChild(successMsg); // Trigger animation setTimeout(() => { successMsg.style.opacity = "1"; successMsg.style.transform = "translateY(0)"; }, 10); // Remove success message after 4 seconds setTimeout(() => { successMsg.style.opacity = "0"; successMsg.style.transform = "translateY(-10px)"; setTimeout(() => { form.removeChild(successMsg); }, 300); }, 4000); }, 1500); }); // Card hover animation const articleCards = document.querySelectorAll('.article-card'); articleCards.forEach(card => { card.addEventListener('mouseenter', function() { this.style.transform = 'translateY(-5px) scale(1.02)'; this.style.boxShadow = '0 10px 30px rgba(0, 0, 0, 0.12)'; }); card.addEventListener('mouseleave', function() { this.style.transform = ''; this.style.boxShadow = ''; }); }); }); </script> </body> </html>