Calendars are essential tools for organizing our daily lives, helping us keep track of appointments, deadlines, and events. In this article, we explore ten unique calendar examples that can enhance your productivity and time management.
From minimalist designs to feature-rich planners, these calendars cater to various needs and preferences. Discover the perfect calendar to streamline your schedule and boost your efficiency.
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
Designers and developers love Subframe for its drag-and-drop interface and intuitive, responsive canvas. Create pixel-perfect UI effortlessly, ensuring your calendar designs are both stunning and functional.
Join the community of satisfied users and elevate your design game. Start for free 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 design game? With Subframe, you can create pixel-perfect interfaces, including stunning calendars, in minutes. Enjoy the efficiency of a drag-and-drop editor and beautifully crafted components.
Don't wait! Start for free and begin designing immediately. Join the community of satisfied users today!
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Enterprise Meeting Calendar</title> <style> :root { --primary: #3A506B; --secondary: #5BC0BE; --accent: #0B132B; --light: #f5f5f5; --gray: #e0e0e0; --gray-dark: #718096; --shadow: 0 4px 12px rgba(0, 0, 0, 0.08); --shadow-hover: 0 8px 24px rgba(0, 0, 0, 0.12); --border-radius: 8px; --transition: all 0.3s ease; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; } body { background-color: var(--light); color: var(--accent); display: flex; flex-direction: column; height: 700px; width: 700px; overflow: hidden; } .container { display: flex; flex-direction: column; width: 100%; height: 100%; padding: 1rem; } header { display: flex; justify-content: space-between; align-items: center; padding-bottom: 1rem; border-bottom: 1px solid var(--gray); margin-bottom: 1rem; } .logo { display: flex; align-items: center; gap: 0.5rem; } .logo-icon { width: 30px; height: 30px; background-color: var(--secondary); border-radius: 50%; display: flex; align-items: center; justify-content: center; color: white; } .logo-text { font-weight: 600; font-size: 1.2rem; color: var(--primary); } .filter-section { display: flex; justify-content: space-between; margin-bottom: 1rem; } .view-toggle, .date-selector, .add-meeting { display: flex; align-items: center; gap: 0.5rem; } .view-toggle { background-color: white; border-radius: var(--border-radius); box-shadow: var(--shadow); overflow: hidden; padding: 2px; } .view-option { padding: 0.4rem 1rem; border: none; background: none; cursor: pointer; font-size: 0.85rem; font-weight: 500; color: var(--gray-dark); transition: var(--transition); } .view-option.active { background-color: var(--secondary); color: white; border-radius: 6px; } .month-year { font-weight: 600; font-size: 1.1rem; } .date-nav { display: flex; align-items: center; gap: 0.5rem; } .date-btn { width: 28px; height: 28px; border-radius: 50%; border: none; background-color: white; box-shadow: var(--shadow); cursor: pointer; display: flex; align-items: center; justify-content: center; transition: var(--transition); } .date-btn:hover { box-shadow: var(--shadow-hover); transform: translateY(-1px); } .add-meeting-btn { background-color: var(--primary); color: white; border: none; border-radius: var(--border-radius); padding: 0.5rem 1rem; display: flex; align-items: center; gap: 0.5rem; cursor: pointer; font-weight: 500; transition: var(--transition); box-shadow: var(--shadow); } .add-meeting-btn:hover { background-color: var(--accent); box-shadow: var(--shadow-hover); transform: translateY(-1px); } .calendar-container { flex-grow: 1; overflow: hidden; border-radius: var(--border-radius); box-shadow: var(--shadow); background-color: white; position: relative; } .calendar { display: grid; grid-template-columns: repeat(7, 1fr); grid-template-rows: auto; height: 100%; } .day-header { text-align: center; padding: 0.8rem; font-weight: 600; font-size: 0.8rem; color: var(--gray-dark); border-bottom: 1px solid var(--gray); } .day-cell { border-right: 1px solid var(--gray); border-bottom: 1px solid var(--gray); min-height: 100px; padding: 0.5rem; position: relative; overflow: hidden; transition: var(--transition); } .day-cell:nth-child(7n) { border-right: none; } .day-cell:hover { background-color: rgba(91, 192, 190, 0.05); } .day-number { font-size: 0.9rem; font-weight: 500; margin-bottom: 0.5rem; } .today .day-number { display: inline-block; width: 24px; height: 24px; background-color: var(--secondary); color: white; border-radius: 50%; text-align: center; line-height: 24px; } .other-month { background-color: rgba(245, 245, 245, 0.6); color: var(--gray-dark); } .meeting { padding: 0.4rem 0.6rem; border-radius: 4px; font-size: 0.75rem; margin-bottom: 0.3rem; cursor: pointer; transition: var(--transition); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; position: relative; } .meeting:hover { transform: translateY(-1px); box-shadow: var(--shadow); } .meeting.priority-high { background-color: #FFECEB; border-left: 3px solid #EF476F; } .meeting.priority-medium { background-color: #FFF7E6; border-left: 3px solid #FFD166; } .meeting.priority-low { background-color: #E6F8F5; border-left: 3px solid var(--secondary); } .conflict-indicator { position: absolute; top: 0; right: 0; width: 8px; height: 8px; background-color: #EF476F; border-radius: 50%; display: none; } .meeting.conflict .conflict-indicator { display: block; } .meeting-time { font-weight: 600; margin-right: 0.3rem; } .more-meetings { font-size: 0.75rem; color: var(--gray-dark); text-align: center; cursor: pointer; } /* Modal styles */ .modal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); display: flex; align-items: center; justify-content: center; z-index: 1000; opacity: 0; visibility: hidden; transition: all 0.3s ease; } .modal.open { opacity: 1; visibility: visible; } .modal-content { background-color: white; border-radius: var(--border-radius); width: 500px; max-width: 90%; padding: 1.5rem; box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15); transform: translateY(20px); transition: all 0.3s ease; } .modal.open .modal-content { transform: translateY(0); } .modal-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem; } .modal-title { font-size: 1.2rem; font-weight: 600; color: var(--accent); } .close-modal { background: none; border: none; cursor: pointer; font-size: 1.2rem; color: var(--gray-dark); } .modal-body { margin-bottom: 1.5rem; } .form-group { margin-bottom: 1rem; } .form-label { display: block; margin-bottom: 0.3rem; font-weight: 500; font-size: 0.9rem; } .form-input { width: 100%; padding: 0.7rem; border: 1px solid var(--gray); border-radius: var(--border-radius); font-size: 0.9rem; transition: var(--transition); } .form-input:focus { outline: none; border-color: var(--secondary); box-shadow: 0 0 0 3px rgba(91, 192, 190, 0.2); } .form-select { width: 100%; padding: 0.7rem; border: 1px solid var(--gray); border-radius: var(--border-radius); font-size: 0.9rem; background-color: white; transition: var(--transition); } .form-select:focus { outline: none; border-color: var(--secondary); box-shadow: 0 0 0 3px rgba(91, 192, 190, 0.2); } .modal-footer { display: flex; justify-content: flex-end; gap: 0.8rem; } .btn { padding: 0.7rem 1.2rem; border-radius: var(--border-radius); border: none; font-weight: 500; cursor: pointer; transition: var(--transition); } .btn-cancel { background-color: var(--gray); color: var(--accent); } .btn-cancel:hover { background-color: #d4d4d4; } .btn-primary { background-color: var(--primary); color: white; } .btn-primary:hover { background-color: var(--accent); } /* Daily view */ .daily-view { display: none; flex-direction: column; height: 100%; } .daily-view.active { display: flex; } .daily-header { padding: 1rem; text-align: center; font-weight: 600; border-bottom: 1px solid var(--gray); } .time-slots { flex-grow: 1; overflow-y: auto; padding: 0 1rem; } .time-slot { display: flex; border-bottom: 1px solid var(--gray); min-height: 60px; } .time-label { width: 60px; padding: 0.5rem; color: var(--gray-dark); font-size: 0.8rem; text-align: right; padding-right: 1rem; } .time-content { flex-grow: 1; padding: 0.5rem 0; position: relative; } /* Weekly view */ .weekly-view { display: none; flex-direction: column; height: 100%; } .weekly-view.active { display: flex; } .weekly-header { display: grid; grid-template-columns: 60px repeat(7, 1fr); border-bottom: 1px solid var(--gray); } .weekly-day { padding: 0.8rem 0; text-align: center; font-size: 0.8rem; font-weight: 600; } .weekly-day .day-name { font-weight: 400; color: var(--gray-dark); } .weekly-grid { display: grid; grid-template-columns: 60px repeat(7, 1fr); flex-grow: 1; overflow-y: auto; } .weekly-hour { border-bottom: 1px solid var(--gray); height: 60px; position: relative; } .weekly-hour-label { text-align: right; padding-right: 1rem; color: var(--gray-dark); font-size: 0.8rem; padding-top: 0.5rem; } .weekly-cell { border-left: 1px solid var(--gray); position: relative; } /* Monthly view */ .monthly-view { display: none; height: 100%; } .monthly-view.active { display: block; } /* Status notification */ .status-notification { position: fixed; bottom: 1.5rem; right: 1.5rem; background-color: var(--accent); color: white; padding: 0.8rem 1.2rem; border-radius: var(--border-radius); box-shadow: var(--shadow); display: flex; align-items: center; gap: 0.7rem; transform: translateY(100px); opacity: 0; transition: all 0.3s ease; z-index: 1001; } .status-notification.show { transform: translateY(0); opacity: 1; } .status-icon { width: 24px; height: 24px; border-radius: 50%; background-color: var(--secondary); display: flex; align-items: center; justify-content: center; } .conflict-alert { position: absolute; top: 0.7rem; right: 0.7rem; background-color: #ffe8e8; border: 1px solid #ffb8b8; border-radius: var(--border-radius); padding: 0.7rem 1rem; box-shadow: var(--shadow); display: flex; align-items: center; gap: 0.5rem; font-size: 0.85rem; color: #d63031; transform: translateY(-10px); opacity: 0; transition: all 0.3s ease; z-index: 100; pointer-events: none; } .conflict-alert.show { transform: translateY(0); opacity: 1; pointer-events: auto; } .conflict-alert-icon { font-size: 1.1rem; } .quick-actions { position: absolute; bottom: 1rem; right: 1rem; display: flex; gap: 0.5rem; } .quick-action { width: 40px; height: 40px; border-radius: 50%; background-color: white; box-shadow: var(--shadow); display: flex; align-items: center; justify-content: center; cursor: pointer; transition: var(--transition); } .quick-action:hover { transform: translateY(-2px); box-shadow: var(--shadow-hover); } @media (max-width: 700px) { .filter-section { flex-direction: column; gap: 0.8rem; align-items: flex-start; } .date-selector { width: 100%; justify-content: space-between; } .day-header { padding: 0.5rem; font-size: 0.7rem; } .day-cell { padding: 0.3rem; min-height: 80px; } .meeting { padding: 0.3rem 0.4rem; font-size: 0.7rem; } } @media (max-width: 500px) { .view-option { padding: 0.3rem 0.6rem; font-size: 0.75rem; } .month-year { font-size: 0.9rem; } .add-meeting-btn { padding: 0.4rem 0.8rem; font-size: 0.8rem; } .day-number { font-size: 0.8rem; } .meeting { font-size: 0.65rem; padding: 0.2rem 0.3rem; } .daily-view, .weekly-view { font-size: 0.8rem; } } /* Animation classes */ @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.05); } 100% { transform: scale(1); } } .pulse { animation: pulse 0.5s ease; } @keyframes slideIn { from { transform: translateY(10px); opacity: 0; } to { transform: translateY(0); opacity: 1; } } .slide-in { animation: slideIn 0.3s ease forwards; } .meeting.dragging { opacity: 0.5; border: 2px dashed var(--primary); } </style> </head> <body> <div class="container"> <header> <div class="logo"> <div class="logo-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect> <line x1="16" y1="2" x2="16" y2="6"></line> <line x1="8" y1="2" x2="8" y2="6"></line> <line x1="3" y1="10" x2="21" y2="10"></line> </svg> </div> <div class="logo-text">Syncalendar</div> </div> </header> <div class="filter-section"> <div class="view-toggle"> <button class="view-option" data-view="daily">Daily</button> <button class="view-option" data-view="weekly">Weekly</button> <button class="view-option active" data-view="monthly">Monthly</button> </div> <div class="date-selector"> <div class="month-year">October 2023</div> <div class="date-nav"> <button class="date-btn" id="prev-date"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="15 18 9 12 15 6"></polyline> </svg> </button> <button class="date-btn" id="today-date"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" 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> </button> <button class="date-btn" id="next-date"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="9 18 15 12 9 6"></polyline> </svg> </button> </div> </div> <div class="add-meeting"> <button class="add-meeting-btn" id="add-meeting"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <line x1="12" y1="5" x2="12" y2="19"></line> <line x1="5" y1="12" x2="19" y2="12"></line> </svg> New Meeting </button> </div> </div> <div class="calendar-container"> <!-- Daily View --> <div class="daily-view"> <div class="daily-header">Tuesday, October 17, 2023</div> <div class="time-slots"> <div class="time-slot"> <div class="time-label">8:00</div> <div class="time-content"></div> </div> <div class="time-slot"> <div class="time-label">9:00</div> <div class="time-content"> <div class="meeting priority-high" draggable="true"> <div class="conflict-indicator"></div> <span class="meeting-time">9:00 - 10:30</span> Q3 Strategy Review with Executive Team </div> </div> </div> <div class="time-slot"> <div class="time-label">10:00</div> <div class="time-content"></div> </div> <div class="time-slot"> <div class="time-label">11:00</div> <div class="time-content"> <div class="meeting priority-medium" draggable="true"> <span class="meeting-time">11:00 - 12:00</span> Product Development Update </div> </div> </div> <div class="time-slot"> <div class="time-label">12:00</div> <div class="time-content"> <div class="meeting priority-low" draggable="true"> <span class="meeting-time">12:00 - 1:00</span> Lunch with Marketing Team </div> </div> </div> <div class="time-slot"> <div class="time-label">13:00</div> <div class="time-content"></div> </div> <div class="time-slot"> <div class="time-label">14:00</div> <div class="time-content"> <div class="meeting priority-medium" draggable="true"> <span class="meeting-time">14:00 - 15:00</span> Client Onboarding Planning </div> </div> </div> <div class="time-slot"> <div class="time-label">15:00</div> <div class="time-content"></div> </div> <div class="time-slot"> <div class="time-label">16:00</div> <div class="time-content"> <div class="meeting priority-high conflict" draggable="true"> <div class="conflict-indicator"></div> <span class="meeting-time">16:00 - 17:30</span> Quarterly Budget Review </div> </div> </div> <div class="time-slot"> <div class="time-label">17:00</div> <div class="time-content"></div> </div> </div> </div> <!-- Weekly View --> <div class="weekly-view"> <div class="weekly-header"> <div></div> <div class="weekly-day"> <div class="day-name">Mon</div> <div>16</div> </div> <div class="weekly-day"> <div class="day-name">Tue</div> <div>17</div> </div> <div class="weekly-day"> <div class="day-name">Wed</div> <div>18</div> </div> <div class="weekly-day"> <div class="day-name">Thu</div> <div>19</div> </div> <div class="weekly-day"> <div class="day-name">Fri</div> <div>20</div> </div> <div class="weekly-day"> <div class="day-name">Sat</div> <div>21</div> </div> <div class="weekly-day"> <div class="day-name">Sun</div> <div>22</div> </div> </div> <div class="weekly-grid"> <!-- First row: 9:00 --> <div class="weekly-hour-label">9:00</div> <div class="weekly-cell"></div> <div class="weekly-cell"> <div class="meeting priority-high" draggable="true"> <div class="conflict-indicator"></div> <span class="meeting-time">9:00</span> Q3 Strategy Review </div> </div> <div class="weekly-cell"></div> <div class="weekly-cell"> <div class="meeting priority-medium" draggable="true"> <span class="meeting-time">9:30</span> Team Standup </div> </div> <div class="weekly-cell"></div> <div class="weekly-cell"></div> <div class="weekly-cell"></div> <!-- Second row: 10:00 --> <div class="weekly-hour-label">10:00</div> <div class="weekly-cell"></div> <div class="weekly-cell"></div> <div class="weekly-cell"> <div class="meeting priority-low" draggable="true"> <span class="meeting-time">10:00</span> Design Review </div> </div> <div class="weekly-cell"></div> <div class="weekly-cell"> <div class="meeting priority-medium" draggable="true"> <span class="meeting-time">10:30</span> Project Planning </div> </div> <div class="weekly-cell"></div> <div class="weekly-cell"></div> <!-- Third row: 11:00 --> <div class="weekly-hour-label">11:00</div> <div class="weekly-cell"> <div class="meeting priority-high" draggable="true"> <span class="meeting-time">11:00</span> Client Call </div> </div> <div class="weekly-cell"> <div class="meeting priority-medium" draggable="true"> <span class="meeting-time">11:00</span> Development Update </div> </div> <div class="weekly-cell"></div> <div class="weekly-cell"></div> <div class="weekly-cell"></div> <div class="weekly-cell"></div> <div class="weekly-cell"></div> <!-- Fourth row: 12:00 --> <div class="weekly-hour-label">12:00</div> <div class="weekly-cell"></div> <div class="weekly-cell"> <div class="meeting priority-low" draggable="true"> <span class="meeting-time">12:00</span> Lunch Meeting </div> </div> <div class="weekly-cell"></div> <div class="weekly-cell"></div> <div class="weekly-cell"> <div class="meeting priority-medium" draggable="true"> <span class="meeting-time">12:30</span> UX Workshop </div> </div> <div class="weekly-cell"></div> <div class="weekly-cell"></div> <!-- Fifth row: 13:00 --> <div class="weekly-hour-label">13:00</div> <div class="weekly-cell"></div> <div class="weekly-cell"></div> <div class="weekly-cell"></div> <div class="weekly-cell"></div> <div class="weekly-cell"></div> <div class="weekly-cell"></div> <div class="weekly-cell"></div> <!-- Sixth row: 14:00 --> <div class="weekly-hour-label">14:00</div> <div class="weekly-cell"> <div class="meeting priority-medium" draggable="true"> <span class="meeting-time">14:00</span> Sprint Planning </div> </div> <div class="weekly-cell"> <div class="meeting priority-medium" draggable="true"> <span class="meeting-time">14:00</span> Client Onboarding </div> </div> <div class="weekly-cell"></div> <div class="weekly-cell"> <div class="meeting priority-high" draggable="true"> <span class="meeting-time">14:30</span> Stakeholder Update </div> </div> <div class="weekly-cell"></div> <div class="weekly-cell"></div> <div class="weekly-cell"></div> <!-- Seventh row: 15:00 --> <div class="weekly-hour-label">15:00</div> <div class="weekly-cell"></div> <div class="weekly-cell"></div> <div class="weekly-cell"> <div class="meeting priority-low" draggable="true"> <span class="meeting-time">15:00</span> Training Session </div> </div> <div class="weekly-cell"></div> <div class="weekly-cell"></div> <div class="weekly-cell"></div> <div class="weekly-cell"></div> <!-- Eighth row: 16:00 --> <div class="weekly-hour-label">16:00</div> <div class="weekly-cell"> <div class="meeting priority-medium" draggable="true"> <span class="meeting-time">16:00</span> Team Feedback </div> </div> <div class="weekly-cell"> <div class="meeting priority-high conflict" draggable="true"> <div class="conflict-indicator"></div> <span class="meeting-time">16:00</span> Budget Review </div> </div> <div class="weekly-cell"></div> <div class="weekly-cell"></div> <div class="weekly-cell"> <div class="meeting priority-low" draggable="true"> <span class="meeting-time">16:30</span> Weekly Wrap-up </div> </div> <div class="weekly-cell"></div> <div class="weekly-cell"></div> </div> </div> <!-- Monthly View --> <div class="monthly-view active"> <div class="calendar"> <div class="day-header">Sunday</div> <div class="day-header">Monday</div> <div class="day-header">Tuesday</div> <div class="day-header">Wednesday</div> <div class="day-header">Thursday</div> <div class="day-header">Friday</div> <div class="day-header">Saturday</div> <!-- Week 1 --> <div class="day-cell other-month"> <div class="day-number">24</div> </div> <div class="day-cell other-month"> <div class="day-number">25</div> </div> <div class="day-cell other-month"> <div class="day-number">26</div> </div> <div class="day-cell other-month"> <div class="day-number">27</div> </div> <div class="day-cell other-month"> <div class="day-number">28</div> </div> <div class="day-cell other-month"> <div class="day-number">29</div> </div> <div class="day-cell other-month"> <div class="day-number">30</div> </div> <!-- Week 2 --> <div class="day-cell"> <div class="day-number">1</div> <div class="meeting priority-medium" draggable="true"> <span class="meeting-time">10:00</span> Department Sync </div> </div> <div class="day-cell"> <div class="day-number">2</div> <div class="meeting priority-high" draggable="true"> <span class="meeting-time">14:00</span> Project Kickoff </div> </div> <div class="day-cell"> <div class="day-number">3</div> <div class="meeting priority-low" draggable="true"> <span class="meeting-time">11:30</span> Team Building </div> </div> <div class="day-cell"> <div class="day-number">4</div> </div> <div class="day-cell"> <div class="day-number">5</div> <div class="meeting priority-medium" draggable="true"> <span class="meeting-time">9:00</span> API Integration </div> </div> <div class="day-cell"> <div class="day-number">6</div> </div> <div class="day-cell"> <div class="day-number">7</div> </div> <!-- Week 3 --> <div class="day-cell"> <div class="day-number">8</div> </div> <div class="day-cell"> <div class="day-number">9</div> <div class="meeting priority-high" draggable="true"> <span class="meeting-time">13:00</span> Investor Presentation </div> </div> <div class="day-cell"> <div class
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Academic Calendar</title> <style> :root { --primary: #5762D5; --secondary: #FF8A5B; --lecture: #AED9E0; --lab: #FFA5AB; --exam: #FFC857; --meeting: #B0D8A4; --deadline: #E5C1CD; --holiday: #E6E6FA; --light-bg: #f8f9fa; --dark-text: #2c3e50; --shadow: rgba(0, 0, 0, 0.1); --border-radius: 12px; --transition: all 0.3s ease; } * { box-sizing: border-box; margin: 0; padding: 0; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: var(--light-bg); color: var(--dark-text); height: 100%; overflow: hidden; } .container { width: 100%; max-width: 700px; height: 700px; margin: 0 auto; padding: 20px; background-color: white; box-shadow: 0 4px 20px var(--shadow); border-radius: var(--border-radius); overflow: hidden; display: flex; flex-direction: column; } .header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; position: relative; } .title { font-size: 24px; font-weight: 700; color: var(--primary); } .semester-indicator { display: flex; align-items: center; background-color: var(--light-bg); padding: 8px 16px; border-radius: 20px; box-shadow: 0 2px 8px var(--shadow); transition: var(--transition); cursor: pointer; } .semester-indicator:hover { transform: translateY(-2px); box-shadow: 0 4px 12px var(--shadow); } .semester-text { font-weight: 600; margin-right: 8px; } .semester-dropdown { position: absolute; top: 60px; right: 0; background-color: white; border-radius: var(--border-radius); box-shadow: 0 4px 12px var(--shadow); z-index: 10; overflow: hidden; opacity: 0; transform: translateY(-10px); pointer-events: none; transition: var(--transition); } .semester-dropdown.active { opacity: 1; transform: translateY(0); pointer-events: auto; } .semester-option { padding: 12px 20px; cursor: pointer; transition: var(--transition); } .semester-option:hover { background-color: var(--light-bg); } .toolbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; } .controls { display: flex; gap: 12px; } .btn { background-color: var(--primary); color: white; border: none; border-radius: 6px; padding: 8px 16px; cursor: pointer; font-weight: 500; transition: var(--transition); display: flex; align-items: center; gap: 6px; } .btn:hover { transform: translateY(-2px); box-shadow: 0 4px 8px rgba(87, 98, 213, 0.3); } .btn-today { background-color: var(--secondary); } .btn-today:hover { box-shadow: 0 4px 8px rgba(255, 138, 91, 0.3); } .month-nav { display: flex; align-items: center; gap: 16px; } .month-title { font-size: 18px; font-weight: 600; min-width: 160px; text-align: center; } .nav-btn { background: none; border: none; color: var(--primary); font-size: 18px; cursor: pointer; width: 32px; height: 32px; display: flex; align-items: center; justify-content: center; border-radius: 50%; transition: var(--transition); } .nav-btn:hover { background-color: var(--light-bg); } .legend { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; margin-bottom: 16px; } .legend-item { display: flex; align-items: center; gap: 6px; font-size: 14px; } .legend-color { width: 12px; height: 12px; border-radius: 3px; } .calendar { flex: 1; overflow: hidden; border-radius: var(--border-radius); box-shadow: 0 2px 12px var(--shadow); } .calendar-header { display: grid; grid-template-columns: repeat(7, 1fr); background-color: var(--primary); color: white; padding: 10px 0; } .weekday { text-align: center; font-weight: 500; font-size: 14px; } .calendar-days { display: grid; grid-template-columns: repeat(7, 1fr); grid-auto-rows: minmax(70px, 1fr); height: calc(100% - 36px); overflow-y: auto; } .day { border: 1px solid #eaeaea; padding: 8px; position: relative; transition: var(--transition); overflow: hidden; } .day:hover { background-color: var(--light-bg); z-index: 5; } .day-number { font-size: 14px; font-weight: 600; margin-bottom: 4px; } .current-day .day-number { background-color: var(--primary); color: white; width: 24px; height: 24px; border-radius: 50%; display: flex; align-items: center; justify-content: center; } .day.inactive { color: #bbbbbb; background-color: #f7f7f7; } .events { display: flex; flex-direction: column; gap: 4px; max-height: calc(100% - 24px); overflow: hidden; } .event { font-size: 12px; padding: 3px 6px; border-radius: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer; transition: var(--transition); } .event:hover { transform: translateY(-1px); box-shadow: 0 2px 4px var(--shadow); } .event-lecture { background-color: var(--lecture); } .event-lab { background-color: var(--lab); } .event-exam { background-color: var(--exam); } .event-meeting { background-color: var(--meeting); } .event-deadline { background-color: var(--deadline); } .event-holiday { background-color: var(--holiday); } .syllabus-modal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); display: flex; align-items: center; justify-content: center; opacity: 0; pointer-events: none; transition: var(--transition); z-index: 100; } .syllabus-modal.active { opacity: 1; pointer-events: auto; } .modal-content { background-color: white; border-radius: var(--border-radius); width: 90%; max-width: 500px; max-height: 80%; overflow-y: auto; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); transform: translateY(20px); transition: var(--transition); } .syllabus-modal.active .modal-content { transform: translateY(0); } .modal-header { display: flex; justify-content: space-between; align-items: center; padding: 16px; border-bottom: 1px solid #eaeaea; } .modal-title { font-size: 18px; font-weight: 600; color: var(--primary); } .close-modal { background: none; border: none; font-size: 24px; cursor: pointer; color: var(--dark-text); transition: var(--transition); } .close-modal:hover { color: var(--secondary); } .modal-body { padding: 16px; } .event-detail { margin-bottom: 12px; } .event-detail-label { font-weight: 600; margin-bottom: 4px; } .syllabus-section { margin-top: 16px; padding-top: 16px; border-top: 1px solid #eaeaea; } .syllabus-title { font-weight: 600; margin-bottom: 8px; color: var(--primary); } @media (max-width: 600px) { .header { flex-direction: column; align-items: flex-start; gap: 10px; } .semester-indicator { align-self: flex-end; } .toolbar { flex-direction: column; gap: 10px; } .controls { width: 100%; justify-content: space-between; } .month-nav { width: 100%; justify-content: space-between; } .weekday { font-size: 12px; } .day { padding: 4px; } .day-number { font-size: 12px; } .event { font-size: 10px; padding: 2px 4px; } } /* Animations */ @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.05); } 100% { transform: scale(1); } } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } .pulse { animation: pulse 1.5s infinite; } .fade-in { animation: fadeIn 0.5s ease-in-out; } .semester-badge { position: absolute; top: -5px; right: -5px; background-color: var(--secondary); color: white; font-size: 10px; padding: 2px 6px; border-radius: 10px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); } .syllabus-link { color: var(--primary); text-decoration: underline; cursor: pointer; } .syllabus-link:hover { color: var(--secondary); } /* Custom scrollbar */ ::-webkit-scrollbar { width: 8px; height: 8px; } ::-webkit-scrollbar-track { background: #f1f1f1; border-radius: 4px; } ::-webkit-scrollbar-thumb { background: #c5c9e0; border-radius: 4px; } ::-webkit-scrollbar-thumb:hover { background: var(--primary); } </style> </head> <body> <div class="container"> <div class="header"> <h1 class="title">Academic Calendar</h1> <div class="semester-indicator" id="semesterToggle"> <span class="semester-text" id="currentSemester">Fall 2023</span> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path d="M7.646 4.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1-.708.708L8 5.707l-5.646 5.647a.5.5 0 0 1-.708-.708l6-6z"/> </svg> <span class="semester-badge pulse">New</span> </div> <div class="semester-dropdown" id="semesterDropdown"> <div class="semester-option" data-value="Fall 2023">Fall 2023</div> <div class="semester-option" data-value="Spring 2024">Spring 2024</div> <div class="semester-option" data-value="Summer 2024">Summer 2024</div> <div class="semester-option" data-value="Fall 2024">Fall 2024</div> </div> </div> <div class="toolbar"> <div class="controls"> <button class="btn btn-today" id="todayBtn"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5zM1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4H1z"/> </svg> Today </button> <button class="btn" id="syncBtn"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path d="M11.534 7h3.932a.25.25 0 0 1 .192.41l-1.966 2.36a.25.25 0 0 1-.384 0l-1.966-2.36a.25.25 0 0 1 .192-.41zm-11 2h3.932a.25.25 0 0 0 .192-.41L2.692 6.23a.25.25 0 0 0-.384 0L.342 8.59A.25.25 0 0 0 .534 9z"/> <path fill-rule="evenodd" d="M8 3c-1.552 0-2.94.707-3.857 1.818a.5.5 0 1 1-.771-.636A6.002 6.002 0 0 1 13.917 7H12.9A5.002 5.002 0 0 0 8 3zM3.1 9a5.002 5.002 0 0 0 8.757 2.182.5.5 0 1 1 .771.636A6.002 6.002 0 0 1 2.083 9H3.1z"/> </svg> Sync </button> </div> <div class="month-nav"> <button class="nav-btn" id="prevMonth"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path fill-rule="evenodd" d="M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z"/> </svg> </button> <div class="month-title" id="currentMonth">September 2023</div> <button class="nav-btn" id="nextMonth"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z"/> </svg> </button> </div> </div> <div class="legend"> <div class="legend-item"> <div class="legend-color" style="background-color: var(--lecture);"></div> <span>Lecture</span> </div> <div class="legend-item"> <div class="legend-color" style="background-color: var(--lab);"></div> <span>Lab</span> </div> <div class="legend-item"> <div class="legend-color" style="background-color: var(--exam);"></div> <span>Exam</span> </div> <div class="legend-item"> <div class="legend-color" style="background-color: var(--meeting);"></div> <span>Meeting</span> </div> <div class="legend-item"> <div class="legend-color" style="background-color: var(--deadline);"></div> <span>Deadline</span> </div> <div class="legend-item"> <div class="legend-color" style="background-color: var(--holiday);"></div> <span>Holiday</span> </div> </div> <div class="calendar"> <div class="calendar-header"> <div class="weekday">Sun</div> <div class="weekday">Mon</div> <div class="weekday">Tue</div> <div class="weekday">Wed</div> <div class="weekday">Thu</div> <div class="weekday">Fri</div> <div class="weekday">Sat</div> </div> <div class="calendar-days" id="calendarDays"></div> </div> </div> <div class="syllabus-modal" id="syllabusModal"> <div class="modal-content"> <div class="modal-header"> <h3 class="modal-title" id="modalTitle">Event Details</h3> <button class="close-modal" id="closeModal">×</button> </div> <div class="modal-body" id="modalBody"> <!-- Dynamic content will be inserted here --> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Calendar initialization const today = new Date(); let currentMonth = today.getMonth(); let currentYear = today.getFullYear(); let selectedSemester = 'Fall 2023'; // Sample course data const courses = { 'CS101': { title: 'Introduction to Computer Science', instructor: 'Dr. Jane Foster', schedule: 'MWF 10:00-10:50 AM', location: 'Science Building, Room 301', description: 'Fundamental concepts of computing, algorithms, and programming with Python.', syllabus: 'Course covers programming fundamentals, data structures, algorithm analysis, and basic problem-solving techniques. Weekly programming assignments and a final project required.' }, 'MATH201': { title: 'Linear Algebra', instructor: 'Prof. Robert Chen', schedule: 'TTh 1:00-2:15 PM', location: 'Math Building, Room 105', description: 'Vector spaces, linear transformations, matrices, and determinants.', syllabus: 'Topics include systems of linear equations, vector spaces, linear transformations, eigenvalues, and eigenvectors. Weekly problem sets and three exams throughout the semester.' }, 'PHYS211': { title: 'Physics I: Mechanics', instructor: 'Dr. Sarah Johnson', schedule: 'MWF 2:00-2:50 PM', location: 'Physics Building, Room 201', description: 'Classical mechanics, Newton\'s laws, energy and momentum conservation.', syllabus: 'Course covers kinematics, dynamics, energy, momentum, rotational motion, and gravitation. Weekly lab sessions and problem sets required.' }, 'ENG250': { title: 'Technical Writing', instructor: 'Prof. Michael Barnes', schedule: 'TTh 9:30-10:45 AM', location: 'Liberal Arts Building, Room 120', description: 'Principles and practices of effective technical communication.', syllabus: 'Students will write technical documents including reports, proposals, instructions, and technical descriptions. Peer review sessions and portfolio development included.' }, 'BIO175': { title: 'Introduction to Biology', instructor: 'Dr. Emma Wilson', schedule: 'MWF 11:00-11:50 AM', location: 'Life Sciences Building, Room 210', description: 'Introduction to cell biology, genetics, evolution, and ecology.', syllabus: 'This course explores fundamental concepts in biology including cell structure and function, genetics, evolution, and ecology. Weekly labs and a research paper required.' } }; // Sample events data by semester const eventsData = { 'Fall 2023': [ { date: new Date(2023, 8, 5), type: 'holiday', title: 'Labor Day - No Classes' }, { date: new Date(2023, 8, 6), type: 'lecture', title: 'CS101 Lecture', course: 'CS101' }, { date: new Date(2023, 8, 6), type: 'lecture', title: 'BIO175 Lecture', course: 'BIO175' }, { date: new Date(2023, 8, 7), type: 'lecture', title: 'MATH201 Lecture', course: 'MATH201' }, { date: new Date(2023, 8, 7), type: 'lecture', title: 'ENG250 Lecture', course: 'ENG250' }, { date: new Date(2023, 8, 8), type: 'lecture', title: 'CS101 Lecture', course: 'CS101' }, { date: new Date(2023, 8, 8), type: 'lecture', title: 'PHYS211 Lecture', course: 'PHYS211' }, { date: new Date(2023, 8, 8), type: 'lab', title: 'PHYS211 Lab', course: 'PHYS211' }, { date: new Date(2023, 8, 9), type: 'lecture', title: 'MATH201 Lecture', course: 'MATH201' }, { date: new Date(2023, 8, 9), type: 'lecture', title: 'ENG250 Lecture', course: 'ENG250' }, { date: new Date(2023, 8, 10), type: 'lecture', title: 'CS101 Lecture', course: 'CS101' }, { date: new Date(2023, 8, 10), type: 'lecture', title: 'BIO175 Lecture', course: 'BIO175' }, { date: new Date(2023, 8, 10), type: 'lab', title: 'BIO175 Lab', course: 'BIO175' }, { date: new Date(2023, 8, 13), type: 'lecture', title: 'CS101 Lecture', course: 'CS101' }, { date: new Date(2023, 8, 13), type: 'lecture', title: 'BIO175 Lecture', course: 'BIO175' }, { date: new Date(2023, 8, 13), type: 'deadline', title: 'CS101 Assignment 1 Due', course: 'CS101' }, { date: new Date(2023, 8, 14), type: 'lecture', title: 'MATH201 Lecture', course: 'MATH201' }, { date: new Date(2023, 8, 14), type: 'lecture', title: 'ENG250 Lecture', course: 'ENG250' }, { date: new Date(2023, 8, 15), type: 'lecture', title: 'CS101 Lecture', course: 'CS101' }, { date: new Date(2023, 8, 15), type: 'lecture', title: 'PHYS211 Lecture', course: 'PHYS211' }, { date: new Date(2023, 8, 15), type: 'lab', title: 'PHYS211 Lab', course: 'PHYS211' }, { date: new Date(2023, 8, 16), type: 'lecture', title: 'MATH201 Lecture', course: 'MATH201' }, { date: new Date(2023, 8, 16), type: 'lecture', title: 'ENG250 Lecture', course: 'ENG250' }, { date: new Date(2023, 8, 16), type: 'meeting', title: 'Academic Advising', course: null }, { date: new Date(2023, 8, 17), type: 'lecture', title: 'CS101 Lecture', course: 'CS101' }, { date: new Date(2023, 8, 17), type: 'lecture', title: 'BIO175 Lecture', course: 'BIO175' }, { date: new Date(2023, 8, 17), type: 'lab', title: 'BIO175 Lab', course: 'BIO175' }, { date: new Date(2023, 8, 19), type: 'deadline', title: 'PHYS211 Lab Report Due', course: 'PHYS211' }, { date: new Date(2023, 8, 20), type: 'lecture', title: 'CS101 Lecture', course: 'CS101' }, { date: new Date(2023, 8, 20), type: 'lecture', title: 'BIO175 Lecture', course: 'BIO175' }, { date: new Date(2023, 8, 21), type: 'lecture', title: 'MATH201 Lecture', course: 'MATH201' }, { date: new Date(2023, 8, 21), type: 'lecture', title: 'ENG250 Lecture', course: 'ENG250' }, { date: new Date(2023, 8, 22), type: 'lecture', title: 'CS101 Lecture', course: 'CS101' }, { date: new Date(2023, 8, 22), type: 'lecture', title: 'PHYS211 Lecture', course: 'PHYS211' }, { date: new Date(2023, 8, 22), type: 'lab', title: 'PHYS211 Lab', course: 'PHYS211' }, { date: new Date(2023, 8, 23), type: 'lecture', title: 'MATH201 Lecture', course: 'MATH201' }, { date: new Date(2023, 8, 23), type: 'lecture', title: 'ENG250 Lecture', course: 'ENG250' }, { date: new Date(2023, 8, 24), type: 'lecture', title: 'CS101 Lecture', course: 'CS101' }, { date: new Date(2023, 8, 24), type: 'lecture', title: 'BIO175 Lecture', course: 'BIO175' }, { date: new Date(2023, 8, 24), type: 'lab', title: 'BIO175 Lab', course: 'BIO175' }, { date: new Date(2023, 8, 27), type: 'lecture', title: 'CS101 Lecture', course: 'CS101' }, { date: new Date(2023, 8, 27), type: 'lecture', title: 'BIO175 Lecture', course: 'BIO175' }, { date: new Date(2023, 8, 27), type: 'deadline', title: 'ENG250 Essay Draft Due', course: 'ENG250' }, { date: new Date(2023, 8, 28), type: 'lecture', title: 'MATH201 Lecture', course: 'MATH201' }, { date: new Date(2023, 8, 28), type: 'lecture', title: 'ENG250 Lecture', course: 'ENG250' }, { date: new Date(2023, 8, 28), type: 'exam', title: 'MATH201 Quiz 1', course: 'MATH201' }, { date: new Date(2023, 8, 29), type: 'lecture', title: 'CS101 Lecture', course: 'CS101' }, { date: new Date(2023, 8, 29), type: 'lecture', title: 'PHYS211 Lecture', course: 'PHYS211' }, { date: new Date(2023, 8, 29), type: 'lab', title: 'PHYS211 Lab', course: 'PHYS211' }, { date: new Date(2023, 8, 30), type: 'lecture', title: 'MATH201 Lecture', course: 'MATH201' }, { date: new Date(2023, 8, 30), type: 'lecture', title: 'ENG250 Lecture', course: 'ENG250' }, { date: new Date(2023, 9, 1), type: 'lecture', title: 'CS101 Lecture', course: 'CS101' }, { date: new Date(2023, 9, 1), type: 'lecture', title: 'BIO175 Lecture', course: 'BIO175' }, { date: new Date(2023, 9, 1), type: 'lab', title: 'BIO175 Lab', course: 'BIO175' }, { date: new Date(2023, 9, 4), type: 'lecture', title: 'CS101 Lecture', course: 'CS101' }, { date: new Date(2023, 9, 4), type: 'lecture', title: 'BIO175 Lecture', course: 'BIO175' }, { date: new Date(2023, 9, 5), type: 'lecture', title: 'MATH201 Lecture', course: 'MATH201' }, { date: new Date(2023, 9, 5), type: 'lecture', title: 'ENG250 Lecture', course: 'ENG250' }, { date: new Date(2023, 9, 5), type: 'deadline', title: 'CS101 Assignment 2 Due', course: 'CS101' }, { date: new Date(2023, 9, 6), type: 'lecture', title: 'CS101 Lecture', course: 'CS101' }, { date: new Date(2023, 9, 6), type: 'lecture', title: 'PHYS211 Lecture', course: 'PHYS211' }, { date: new Date(2023, 9, 6), type: 'lab', title: 'PHYS211 Lab', course: 'PHYS211' }, { date: new Date(2023, 9, 7), type: 'lecture', title: 'MATH201 Lecture', course: 'MATH201' }, { date: new Date(2023, 9, 7), type: 'lecture', title: 'ENG250 Lecture', course: 'ENG250' }, { date: new Date(2023, 9, 8), type: 'lecture', title: 'CS101 Lecture', course: 'CS101' }, { date: new Date(2023, 9, 8), type: 'lecture', title: 'BIO175 Lecture', course: 'BIO175' }, { date: new Date(2023, 9, 8), type: 'lab', title: 'BIO175 Lab', course: 'BIO175' }, { date: new Date(2023, 9, 9), type: 'holiday', title: 'Fall Break - No Classes' }, { date: new Date(2023, 9, 10), type: 'holiday', title: 'Fall Break - No Classes' }, { date: new Date(2023, 9, 11), type: 'lecture', title: 'CS101 Lecture', course: 'CS101' }, { date: new Date(2023, 9, 11), type: 'lecture', title: 'BIO175 Lecture', course: 'BIO175' }, { date: new Date(2023, 9, 12), type: 'lecture', title: 'MATH201 Lecture', course: 'MATH201' }, { date: new Date(2023, 9, 12), type: 'lecture', title: 'ENG250 Lecture', course: 'ENG250' }, { date: new Date(2023, 9, 13), type: 'lecture', title: 'CS101 Lecture', course: 'CS101' }, { date: new Date(2023, 9, 13), type: 'lecture', title: 'PHYS211 Lecture', course: 'PHYS211' }, { date: new Date(2023, 9, 13), type: 'lab', title: 'PHYS211 Lab', course: 'PHYS211' }, { date: new Date(2023, 9, 14), type: 'exam', title: 'BIO175 Midterm Exam', course: 'BIO175' }, { date: new Date(2023, 9, 14), type: 'lecture', title: 'MATH201 Lecture', course: 'MATH201' }, { date: new Date(2023, 9, 14), type: 'lecture', title: 'ENG250 Lecture', course: 'ENG250' }, { date: new Date(2023, 9, 15), type: 'lecture', title: 'CS101 Lecture', course: 'CS101' }, { date: new Date(2023, 9, 15), type: 'lecture', title: 'BIO175 Lecture', course: 'BIO175' }, { date: new Date(2023, 9, 15), type: 'lab', title: 'BIO175 Lab', course: 'BIO175' } ], 'Spring 2024': [ { date: new Date(2024, 0, 16), type: 'holiday', title: 'Classes Begin' }, { date: new Date(2024, 0, 17), type: 'lecture', title: 'CS102 Lecture', course: 'CS101' }, { date: new Date(2024, 0, 17), type: 'lecture', title: 'CHEM101 Lecture', course: 'BIO175' }, { date: new Date(2024, 0, 19), type: 'lecture', title: 'MATH202 Lecture', course: 'MATH201' }, { date: new Date(2024, 0, 19), type: 'meeting', title: 'Spring Planning Meeting', course: null }, { date: new Date(2024, 0, 22), type: 'deadline', title: 'Registration Deadline', course:
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background: #f8f9fa; color: #343a40; display: flex; justify-content: center; align-items: center; min-height: 100vh; overflow: hidden; perspective: 1000px; } .container { width: 700px; height: 700px; display: flex; flex-direction: column; background: #fff; border-radius: 20px; box-shadow: 0 15px 35px rgba(50, 50, 93, 0.1), 0 5px 15px rgba(0, 0, 0, 0.07); overflow: hidden; position: relative; } .background-map { position: absolute; width: 100%; height: 100%; opacity: 0.05; background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwMCIgaGVpZ2h0PSIxMDAwIiB2aWV3Qm94PSIwIDAgMTAwMCAxMDAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik01MDAsOTkwIEM3NzAuMTQyLDk5MCw5OTAsNzcwLjE0Miw5OTAsNTAwIEM5OTAsMjI5Ljg1OCw3NzAuMTQyLDEwLDUwMCwxMCBDMjI5Ljg1OCwxMCwxMCwyMjkuODU4LDEwLDUwMCBDMTAsNzcwLjE0MiwyMjkuODU4LDk5MCw1MDAsOTkwIFogTTUwMCw5NzAgQzc1OS4xOTUsOTcwLDk3MCw3NTkuMTk1LDk3MCw1MDAgQzk3MCwyNDAuODA1LDc1OS4xOTUsMzAsNTAwLDMwIEMyNDAuODA1LDMwLDMwLDI0MC44MDUsMzAsNTAwIEMzMCw3NTkuMTk1LDI0MC44MDUsOTcwLDUwMCw5NzAgWiIgZmlsbD0iIzMzNjZmZiIvPjxwYXRoIGQ9Ik02NTAsMzAwIEM2ODguNjYsMzAwLDcyMCwzMzEuMzQsNzIwLDM3MCBDNzIwLDQwOC42Niw2ODguNjYsNDQwLDY1MCw0NDAgQzYxMS4zNCw0NDAsNTgwLDQwOC42Niw1ODAsMzcwIEM1ODAsMzMxLjM0LDYxMS4zNCwzMDAsNjUwLDMwMCBaIE0zNTAsNjAwIEMzODguNjYsNjAwLDQyMCw2MzEuMzQsNDIwLDY3MCBDNDIwLDcwOC42NiwzODguNjYsNzQwLDM1MCw3NDAgQzMxMS4zNCw3NDAsMjgwLDcwOC42NiwyODAsNjcwIEMyODAsNjMxLjM0LDMxMS4zNCw2MDAsMzUwLDYwMCBaIiBmaWxsPSIjMzM2NmZmIi8+PHBhdGggZD0iTTIwMCwzMDAgTDI1MCwzMzAgTDI1MCw0MDAgTDMwMCw0NTAgTDQwMCw0NTAgTDQ1MCw0MDAgTDUwMCw0NTAgTDU1MCw0MDAgTDY1MCwzNTAgTDc1MCw0MDAgTDgwMCw0NTAgTDgwMCw1NTAgTDc1MCw2MDAgTDY1MCw2NTAgTDU1MCw2MDAgTDUwMCw2NTAgTDQ1MCw2MDAgTDQwMCw2NTAgTDMwMCw2MDAgTDI1MCw1NTAgTDIwMCw1MDAgWiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMzM2NmZmIiBzdHJva2Utd2lkdGg9IjUiLz48cGF0aCBkPSJNMjAwLDIwMCBNODAwLDgwMCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMzM2NmZmIiBzdHJva2Utd2lkdGg9IjUiLz48L3N2Zz4='); background-size: cover; pointer-events: none; z-index: 0; } .header { display: flex; justify-content: space-between; align-items: center; padding: 20px; background: linear-gradient(135deg, #3366ff, #00ccff); color: white; z-index: 1; } .logo { display: flex; align-items: center; gap: 10px; } .globe-icon { width: 40px; height: 40px; background: rgba(255, 255, 255, 0.2); border-radius: 50%; display: flex; justify-content: center; align-items: center; animation: rotate 30s linear infinite; position: relative; } .globe-icon::before { content: ''; position: absolute; width: 30px; height: 30px; border-radius: 50%; border: 2px solid white; border-top: 2px solid transparent; border-bottom: 2px solid transparent; } .globe-icon::after { content: ''; position: absolute; width: 30px; height: 30px; border-radius: 50%; border: 2px solid white; border-left: 2px solid transparent; border-right: 2px solid transparent; transform: rotate(90deg); } @keyframes rotate { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .logo h1 { font-size: 1.6rem; font-weight: 700; } .time-zone { display: flex; align-items: center; gap: 10px; background: rgba(255, 255, 255, 0.2); padding: 8px 15px; border-radius: 30px; font-size: 0.9rem; } .time-zone select { background: transparent; border: none; color: white; font-size: 0.9rem; cursor: pointer; padding-right: 10px; outline: none; } .time-zone select option { background: #3366ff; color: white; } .nav { display: flex; justify-content: space-between; align-items: center; padding: 10px 20px; background: #fff; border-bottom: 1px solid rgba(0, 0, 0, 0.05); z-index: 1; } .month-selector { display: flex; align-items: center; gap: 20px; } .month-name { font-size: 1.2rem; font-weight: 600; min-width: 120px; text-align: center; } .nav-btn { background: transparent; border: none; cursor: pointer; width: 30px; height: 30px; display: flex; justify-content: center; align-items: center; color: #3366ff; font-size: 1.2rem; border-radius: 50%; transition: all 0.2s ease; } .nav-btn:hover { background: rgba(51, 102, 255, 0.1); } .view-toggle { display: flex; gap: 10px; } .view-btn { background: #f1f3f5; border: none; padding: 5px 12px; border-radius: 5px; cursor: pointer; font-size: 0.9rem; transition: all 0.2s ease; } .view-btn.active { background: #3366ff; color: white; } .calendar { display: flex; flex-direction: column; flex: 1; overflow: hidden; position: relative; z-index: 1; } .weekdays { display: grid; grid-template-columns: repeat(7, 1fr); text-align: center; font-weight: 500; font-size: 0.9rem; color: #6c757d; padding: 10px 0; background: #f8f9fa; } .days { display: grid; grid-template-columns: repeat(7, 1fr); grid-template-rows: repeat(6, 1fr); flex: 1; gap: 1px; background: rgba(0, 0, 0, 0.03); } .day { background: white; padding: 5px; position: relative; cursor: pointer; transition: transform 0.2s ease, box-shadow 0.2s ease; overflow: hidden; display: flex; flex-direction: column; } .day:hover { transform: translateY(-2px); box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); z-index: 2; } .date-number { font-size: 0.9rem; font-weight: 500; margin-bottom: 5px; } .other-month .date-number { color: #adb5bd; } .events { display: flex; flex-direction: column; gap: 3px; overflow: hidden; flex: 1; } .event { padding: 3px 5px; border-radius: 4px; font-size: 0.7rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer; position: relative; color: white; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); animation: fadeIn 0.3s ease; } @keyframes fadeIn { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: translateY(0); } } .event-flight { background: linear-gradient(135deg, #6a11cb, #2575fc); } .event-hotel { background: linear-gradient(135deg, #ff8008, #ffc837); } .event-tour { background: linear-gradient(135deg, #0ba360, #3cba92); } .marker { position: absolute; width: 8px; height: 8px; border-radius: 50%; top: 5px; right: 5px; } .has-flight .marker { background: #2575fc; } .has-hotel .marker { background: #ffc837; } .has-tour .marker { background: #3cba92; } .today { background: rgba(51, 102, 255, 0.05); } .today .date-number { background: #3366ff; color: white; border-radius: 50%; width: 24px; height: 24px; display: flex; justify-content: center; align-items: center; } .event-details { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%) scale(0.9); width: 300px; background: white; border-radius: 15px; box-shadow: 0 15px 35px rgba(50, 50, 93, 0.2), 0 5px 15px rgba(0, 0, 0, 0.1); padding: 20px; z-index: 100; opacity: 0; visibility: hidden; transition: all 0.3s ease; overflow: hidden; } .event-details.show { opacity: 1; visibility: visible; transform: translate(-50%, -50%) scale(1); } .detail-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 15px; } .detail-date { font-size: 0.9rem; color: #6c757d; margin-bottom: 5px; } .detail-title { font-size: 1.2rem; font-weight: 600; color: #343a40; margin-bottom: 10px; } .close-details { background: transparent; border: none; cursor: pointer; font-size: 1.2rem; color: #6c757d; padding: 5px; } .detail-content { display: flex; flex-direction: column; gap: 15px; } .detail-item { display: flex; gap: 10px; align-items: flex-start; } .detail-icon { color: #3366ff; font-size: 1.1rem; margin-top: 2px; } .detail-text { flex: 1; } .detail-label { font-size: 0.8rem; color: #6c757d; margin-bottom: 3px; } .detail-value { font-size: 0.95rem; color: #343a40; } .weather { display: flex; align-items: center; justify-content: center; gap: 10px; background: #f8f9fa; padding: 10px; border-radius: 10px; margin-top: 10px; } .weather-icon { width: 40px; height: 40px; display: flex; justify-content: center; align-items: center; font-size: 1.5rem; color: #ffc837; } .weather-info { display: flex; flex-direction: column; } .weather-temp { font-size: 1.1rem; font-weight: 600; } .weather-desc { font-size: 0.8rem; color: #6c757d; } .detail-actions { display: flex; gap: 10px; margin-top: 20px; } .detail-btn { flex: 1; padding: 8px; border-radius: 5px; border: none; font-size: 0.9rem; cursor: pointer; transition: all 0.2s ease; } .btn-edit { background: #f1f3f5; color: #343a40; } .btn-edit:hover { background: #dee2e6; } .btn-view { background: #3366ff; color: white; } .btn-view:hover { background: #2952cc; } .overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); z-index: 99; opacity: 0; visibility: hidden; transition: all 0.3s ease; } .overlay.show { opacity: 1; visibility: visible; } .quick-add { position: absolute; bottom: 20px; right: 20px; width: 60px; height: 60px; border-radius: 50%; background: #3366ff; color: white; display: flex; justify-content: center; align-items: center; font-size: 1.5rem; box-shadow: 0 5px 15px rgba(51, 102, 255, 0.3); cursor: pointer; z-index: 10; transition: all 0.3s ease; } .quick-add:hover { transform: translateY(-5px); box-shadow: 0 10px 25px rgba(51, 102, 255, 0.4); } .add-event-form { position: absolute; bottom: -400px; left: 0; width: 100%; background: white; padding: 20px; border-radius: 20px 20px 0 0; box-shadow: 0 -5px 25px rgba(0, 0, 0, 0.1); z-index: 100; transition: all 0.3s ease; } .add-event-form.show { bottom: 0; } .form-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; } .form-title { font-size: 1.2rem; font-weight: 600; } .close-form { background: transparent; border: none; cursor: pointer; font-size: 1.2rem; color: #6c757d; } .form-group { margin-bottom: 15px; } .form-label { display: block; margin-bottom: 5px; font-size: 0.9rem; color: #495057; } .form-control { width: 100%; padding: 10px; border: 1px solid #dee2e6; border-radius: 5px; font-size: 0.95rem; transition: all 0.2s ease; } .form-control:focus { outline: none; border-color: #3366ff; box-shadow: 0 0 0 3px rgba(51, 102, 255, 0.1); } .form-select { width: 100%; padding: 10px; border: 1px solid #dee2e6; border-radius: 5px; font-size: 0.95rem; appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%23343a40' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 10px center; transition: all 0.2s ease; } .form-select:focus { outline: none; border-color: #3366ff; box-shadow: 0 0 0 3px rgba(51, 102, 255, 0.1); } .form-row { display: flex; gap: 15px; } .form-col { flex: 1; } .form-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px; } .form-btn { padding: 10px 20px; border-radius: 5px; border: none; font-size: 0.95rem; cursor: pointer; transition: all 0.2s ease; } .btn-cancel { background: #f1f3f5; color: #343a40; } .btn-cancel:hover { background: #dee2e6; } .btn-save { background: #3366ff; color: white; } .btn-save:hover { background: #2952cc; } .flight-path { position: absolute; width: 100%; height: 100%; pointer-events: none; z-index: 5; opacity: 0; transition: opacity 0.3s ease; } .flight-path.show { opacity: 1; } .flight-dot { position: absolute; width: 10px; height: 10px; background: #3366ff; border-radius: 50%; box-shadow: 0 0 10px rgba(51, 102, 255, 0.5); animation: flightPath 3s linear infinite; } @keyframes flightPath { 0% { transform: translate(var(--start-x), var(--start-y)) scale(0.5); opacity: 0; } 20% { opacity: 1; } 80% { opacity: 1; } 100% { transform: translate(var(--end-x), var(--end-y)) scale(0.5); opacity: 0; } } .offline-badge { position: absolute; top: 10px; right: 10px; background: rgba(255, 255, 255, 0.9); color: #495057; padding: 5px 10px; border-radius: 20px; font-size: 0.8rem; display: flex; align-items: center; gap: 5px; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); z-index: 50; opacity: 0; transform: translateY(-10px); transition: all 0.3s ease; } .offline-badge.show { opacity: 1; transform: translateY(0); } .loading-spinner { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 50px; height: 50px; border: 3px solid rgba(51, 102, 255, 0.1); border-radius: 50%; border-top: 3px solid #3366ff; animation: spin 1s linear infinite; z-index: 100; display: none; } @keyframes spin { 0% { transform: translate(-50%, -50%) rotate(0deg); } 100% { transform: translate(-50%, -50%) rotate(360deg); } } @media (max-width: 700px) { .container { width: 100%; height: 100vh; border-radius: 0; } .header { padding: 15px; } .logo h1 { font-size: 1.3rem; } .globe-icon { width: 30px; height: 30px; } .time-zone { font-size: 0.8rem; padding: 5px 10px; } .nav { padding: 8px 15px; } .month-name { font-size: 1rem; min-width: 100px; } .view-btn { font-size: 0.8rem; padding: 4px 8px; } .weekdays { font-size: 0.8rem; } .date-number { font-size: 0.8rem; } .event { font-size: 0.6rem; padding: 2px 4px; } .event-details { width: 280px; } .detail-title { font-size: 1.1rem; } .detail-value { font-size: 0.85rem; } .quick-add { width: 50px; height: 50px; font-size: 1.3rem; } } </style> </head> <body> <div class="container"> <div class="background-map"></div> <div class="header"> <div class="logo"> <div class="globe-icon"></div> <h1>TravelSync</h1> </div> <div class="time-zone"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path d="M8 3.5a.5.5 0 0 0-1 0V9a.5.5 0 0 0 .252.434l3.5 2a.5.5 0 0 0 .496-.868L8 8.71V3.5z"/> <path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm7-8A7 7 0 1 1 1 8a7 7 0 0 1 14 0z"/> </svg> <select id="timezone-selector"> <option value="local">Local Time</option> <option value="destination">Destination Time</option> <option value="UTC">UTC</option> <option value="EST">EST (UTC-5)</option> <option value="PST">PST (UTC-8)</option> <option value="JST">JST (UTC+9)</option> </select> </div> </div> <div class="nav"> <div class="month-selector"> <button class="nav-btn prev-month"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path fill-rule="evenodd" d="M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z"/> </svg> </button> <div class="month-name">September 2023</div> <button class="nav-btn next-month"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z"/> </svg> </button> </div> <div class="view-toggle"> <button class="view-btn active">Month</button> <button class="view-btn">Week</button> </div> </div> <div class="calendar"> <div class="weekdays"> <div>Sun</div> <div>Mon</div> <div>Tue</div> <div>Wed</div> <div>Thu</div> <div>Fri</div> <div>Sat</div> </div> <div class="days" id="calendar-days"></div> </div> <div class="quick-add" id="quick-add"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 16 16"> <path d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4z"/> </svg> </div> <div class="add-event-form" id="add-event-form"> <div class="form-header"> <div class="form-title">Add Travel Item</div> <button class="close-form" id="close-form"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z"/> </svg> </button> </div> <div class="form-group"> <label class="form-label">Type</label> <select class="form-select" id="event-type"> <option value="flight">Flight</option> <option value="hotel">Hotel</option> <option value="tour">Tour/Activity</option> </select> </div> <div class="form-group"> <label class="form-label">Title</label> <input type="text" class="form-control" id="event-title" placeholder="e.g., Flight to Paris"> </div> <div class="form-row"> <div class="form-col"> <div class="form-group"> <label class="form-label">Date</label> <input type="date" class="form-control" id="event-date"> </div> </div> <div class="form-col"> <div class="form-group"> <label class="form-label">Time</label> <input type="time" class="form-control" id="event-time"> </div> </div> </div> <div class="form-group" id="location-group"> <label class="form-label">Location</label> <input type="text" class="form-control" id="event-location" placeholder="e.g., Charles de Gaulle Airport"> </div> <div class="form-actions"> <button class="form-btn btn-cancel" id="cancel-add">Cancel</button> <button class="form-btn btn-save" id="save-event">Save</button> </div> </div> <div class="event-details" id="event-details"> <div class="detail-header"> <div> <div class="detail-date">September 15, 2023</div> <div class="detail-title">Flight to Paris</div> </div> <button class="close-details" id="close-details"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z"/> </svg> </button> </div> <div class="detail-content"> <div class="detail-item"> <div class="detail-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path d="M2.5 8a.5.5 0 1 0 0-1 .5.5 0 0 0 0 1zm0-2a.5.5 0 1 0 0-1 .5.5 0 0 0 0 1zm.5 4a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0zm-.5 1a.5.5 0 1 0 0 1 .5.5 0 0 0 0-1zm0-7a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0zm-.5 1a.5.5 0 1 0 0 1 .5.5 0 0 0 0-1zm.5 1a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0zM8 8a.5.5 0 1 0 0-1 .5.5 0 0 0 0 1zm3 0a.5.5 0 1 0 0-1 .5.5 0 0 0 0 1zm-3 1a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0zm3 0a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0zm-3-3a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0zm3 0a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0zm-3-3a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0zm3 0a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0zm-3 6a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0zm3 0a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0zm-3-3a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0zm3 0a.5.5 0 1 1-1 0 .5.5 0 0
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> :root { --color-forest: #2C5E1A; --color-moss: #88A61B; --color-sand: #E0D0B8; --color-bark: #78552B; --color-earth: #503B2C; --color-stone: #BCBCB8; --color-leaf: #C5E063; --color-water: #5A8C92; --color-sunset: #E07A5F; --color-berry: #A84B5E; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: var(--color-sand); color: var(--color-earth); display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; overflow-x: hidden; padding: 15px; } .calendar-container { width: 100%; max-width: 670px; height: 670px; background-color: #f4eee4; border-radius: 15px; box-shadow: 0 10px 25px rgba(80, 59, 44, 0.1); overflow: hidden; position: relative; display: flex; flex-direction: column; background-image: radial-gradient(circle at 20% 80%, rgba(197, 224, 99, 0.1) 0%, transparent 70%), radial-gradient(circle at 80% 30%, rgba(90, 140, 146, 0.1) 0%, transparent 70%); } .eco-label { position: absolute; top: 20px; right: 20px; background-color: var(--color-leaf); color: var(--color-forest); padding: 5px 10px; border-radius: 20px; font-size: 12px; font-weight: bold; display: flex; align-items: center; gap: 5px; opacity: 0.9; transform: rotate(2deg); box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); z-index: 10; } .eco-label svg { width: 14px; height: 14px; } .calendar-header { padding: 20px; display: flex; justify-content: space-between; align-items: center; } .brand { display: flex; align-items: center; gap: 10px; } .brand-logo { width: 40px; height: 40px; border-radius: 50%; background-color: var(--color-moss); display: flex; align-items: center; justify-content: center; } .brand-logo svg { width: 25px; height: 25px; fill: white; } .brand-name { font-size: 18px; font-weight: bold; letter-spacing: 0.5px; color: var(--color-forest); } .month-selector { display: flex; gap: 15px; align-items: center; } .current-month { font-size: 1.1rem; font-weight: 600; min-width: 120px; text-align: center; color: var(--color-earth); } .month-nav { background: none; border: none; cursor: pointer; color: var(--color-moss); font-size: 1.5rem; width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center; justify-content: center; transition: all 0.2s; } .month-nav:hover { background-color: var(--color-leaf); color: var(--color-forest); } .weekdays { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; padding: 0 15px; margin-bottom: 5px; } .weekday { text-align: center; font-size: 0.8rem; font-weight: 600; color: var(--color-bark); padding: 5px 0; text-transform: uppercase; letter-spacing: 1px; } .days-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 10px; padding: 0 15px; flex-grow: 1; margin-bottom: 15px; } .day { background-color: rgba(255, 255, 255, 0.5); border-radius: 10px; padding: 5px; min-height: 80px; display: flex; flex-direction: column; position: relative; transition: transform 0.2s, box-shadow 0.2s; overflow: hidden; cursor: pointer; border: 1px solid rgba(188, 188, 184, 0.2); } .day:hover { transform: translateY(-3px); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05); background-color: rgba(255, 255, 255, 0.8); } .day.inactive { opacity: 0.3; } .day.today { background-color: rgba(197, 224, 99, 0.2); border: 1px solid var(--color-leaf); } .day-number { font-size: 0.85rem; font-weight: 600; margin-bottom: 5px; } .events { display: flex; flex-direction: column; gap: 4px; font-size: 0.65rem; } .event { padding: 3px 6px; border-radius: 3px; width: 100%; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: flex; align-items: center; gap: 3px; transition: all 0.3s; } .event-icon { width: 10px; height: 10px; display: flex; align-items: center; justify-content: center; } .event.conference { background-color: rgba(90, 140, 146, 0.2); color: var(--color-water); border-left: 3px solid var(--color-water); } .event.workshop { background-color: rgba(224, 122, 95, 0.2); color: var(--color-sunset); border-left: 3px solid var(--color-sunset); } .event.meetup { background-color: rgba(168, 75, 94, 0.2); color: var(--color-berry); border-left: 3px solid var(--color-berry); } .event.sustainability { background-color: rgba(44, 94, 26, 0.1); color: var(--color-forest); border-left: 3px solid var(--color-forest); } .categories { display: flex; justify-content: center; gap: 15px; padding: 10px 20px; background-color: rgba(255, 255, 255, 0.5); margin: 0 15px 15px; border-radius: 10px; flex-wrap: wrap; } .category { display: flex; align-items: center; gap: 5px; font-size: 0.75rem; color: var(--color-earth); cursor: pointer; padding: 3px 8px; border-radius: 15px; transition: all 0.2s; } .category:hover { background-color: rgba(255, 255, 255, 0.8); } .category-dot { width: 10px; height: 10px; border-radius: 50%; } .category-dot.conference { background-color: var(--color-water); } .category-dot.workshop { background-color: var(--color-sunset); } .category-dot.meetup { background-color: var(--color-berry); } .category-dot.sustainability { background-color: var(--color-forest); } .event-popup { position: absolute; width: 300px; max-width: 90%; background-color: white; border-radius: 15px; padding: 20px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15); z-index: 100; top: 50%; left: 50%; transform: translate(-50%, -50%) scale(0.9); opacity: 0; visibility: hidden; transition: all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55); } .event-popup.show { transform: translate(-50%, -50%) scale(1); opacity: 1; visibility: visible; } .popup-header { margin-bottom: 15px; display: flex; justify-content: space-between; align-items: flex-start; } .popup-title { font-size: 1.2rem; font-weight: bold; color: var(--color-earth); margin-bottom: 5px; } .popup-date { font-size: 0.85rem; color: var(--color-bark); display: flex; align-items: center; gap: 5px; } .popup-close { background: none; border: none; cursor: pointer; color: var(--color-earth); font-size: 1.2rem; padding: 5px; } .popup-type { padding: 3px 10px; border-radius: 15px; font-size: 0.7rem; font-weight: bold; display: inline-flex; align-items: center; gap: 5px; margin-bottom: 10px; } .popup-type.conference { background-color: rgba(90, 140, 146, 0.2); color: var(--color-water); } .popup-type.workshop { background-color: rgba(224, 122, 95, 0.2); color: var(--color-sunset); } .popup-type.meetup { background-color: rgba(168, 75, 94, 0.2); color: var(--color-berry); } .popup-type.sustainability { background-color: rgba(44, 94, 26, 0.1); color: var(--color-forest); } .popup-description { font-size: 0.9rem; line-height: 1.5; color: var(--color-earth); margin-bottom: 15px; } .popup-eco-impact { background-color: rgba(197, 224, 99, 0.2); padding: 10px; border-radius: 10px; margin-bottom: 15px; } .impact-title { font-size: 0.85rem; font-weight: bold; color: var(--color-forest); margin-bottom: 5px; display: flex; align-items: center; gap: 5px; } .impact-details { font-size: 0.8rem; color: var(--color-earth); } .impact-stats { display: flex; justify-content: space-around; gap: 10px; margin-top: 10px; } .impact-stat { text-align: center; font-size: 0.75rem; } .stat-value { font-size: 1.1rem; font-weight: bold; color: var(--color-forest); margin-bottom: 2px; } .popup-buttons { display: flex; gap: 10px; } .popup-button { padding: 8px 15px; border-radius: 5px; border: none; cursor: pointer; font-size: 0.85rem; font-weight: 600; flex: 1; transition: all 0.2s; } .primary-button { background-color: var(--color-moss); color: white; } .primary-button:hover { background-color: var(--color-forest); } .secondary-button { background-color: var(--color-stone); color: var(--color-earth); } .secondary-button:hover { background-color: #a9a9a6; } .overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.5); opacity: 0; visibility: hidden; transition: all 0.3s; z-index: 99; } .overlay.show { opacity: 1; visibility: visible; } @media (max-width: 600px) { .weekday { font-size: 0.7rem; } .day { min-height: 60px; } .days-grid { gap: 5px; } .categories { gap: 8px; padding: 8px 10px; } .category { font-size: 0.7rem; padding: 2px 6px; } .brand-name { font-size: 16px; } .current-month { font-size: 1rem; min-width: 100px; } } /* Leaf animation */ .leaf { position: absolute; width: 40px; height: 40px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%232C5E1A' opacity='0.1'%3E%3Cpath d='M17,8C8,10,5.9,16.17,3.82,21.34L5.71,22l1-2.3A4.49,4.49,0,0,0,8,20C19,20,22,3,22,3,21,5,14,5.25,9,6.25S2,11.5,2,13.5a6.13,6.13,0,0,0,1.5,4,5.2,5.2,0,0,0,3.5,2c3.5.5,4.5-2,7.5-2.5s4.5,1,7.5-3'/%3E%3C/svg%3E"); background-size: contain; background-repeat: no-repeat; opacity: 0; animation: leafFall 15s linear infinite; z-index: 1; } @keyframes leafFall { 0% { transform: translateY(-50px) rotate(0deg); opacity: 0; } 10% { opacity: 0.7; } 90% { opacity: 0.7; } 100% { transform: translateY(700px) rotate(360deg); opacity: 0; } } /* Day selection animation */ .day.selected { background-color: rgba(255, 255, 255, 0.9); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); transform: scale(1.05); } .day.selected::after { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; border: 2px solid var(--color-moss); border-radius: 10px; animation: pulse 1.5s infinite; } @keyframes pulse { 0% { opacity: 1; transform: scale(1); } 50% { opacity: 0.5; transform: scale(1.05); } 100% { opacity: 1; transform: scale(1); } } /* Organic paper texture */ .calendar-container::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; 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.15' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)' opacity='0.05'/%3E%3C/svg%3E"); opacity: 0.4; pointer-events: none; } </style> </head> <body> <div class="calendar-container"> <div class="eco-label"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> <path d="M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4M15,12A3,3 0 0,1 12,15A3,3 0 0,1 9,12A3,3 0 0,1 12,9A3,3 0 0,1 15,12Z"></path> </svg> Carbon-Smart Planning </div> <div class="calendar-header"> <div class="brand"> <div class="brand-logo"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> <path d="M17,8C8,10,5.9,16.17,3.82,21.34L5.71,22L6.66,19.7C7.14,19.87,7.64,20,8,20C19,20,22,3,22,3C21,5,14,5.25,9,6.25C4,7.25,2,11.5,2,13.5C2,15.5,3.5,17.5,5,18C6.5,18.5,9,18,11,17.5C13,17,15,16.5,16.5,17.5C18,18.5,20,20,20,20Z"></path> </svg> </div> <div class="brand-name">EcoEvent Planner</div> </div> <div class="month-selector"> <button class="month-nav prev-month">❮</button> <div class="current-month">June 2023</div> <button class="month-nav next-month">❯</button> </div> </div> <div class="weekdays"> <div class="weekday">Sun</div> <div class="weekday">Mon</div> <div class="weekday">Tue</div> <div class="weekday">Wed</div> <div class="weekday">Thu</div> <div class="weekday">Fri</div> <div class="weekday">Sat</div> </div> <div class="days-grid" id="daysContainer"> <!-- Days will be added dynamically --> </div> <div class="categories"> <div class="category" data-type="conference"> <div class="category-dot conference"></div> <span>Conferences</span> </div> <div class="category" data-type="workshop"> <div class="category-dot workshop"></div> <span>Workshops</span> </div> <div class="category" data-type="meetup"> <div class="category-dot meetup"></div> <span>Meetups</span> </div> <div class="category" data-type="sustainability"> <div class="category-dot sustainability"></div> <span>Sustainability</span> </div> </div> </div> <div class="event-popup" id="eventPopup"> <div class="popup-header"> <div> <div class="popup-title">Zero Waste Workshop</div> <div class="popup-date"> <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="currentColor"> <path d="M19,19H5V8H19M16,1V3H8V1H6V3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3H18V1"></path> </svg> June 15, 2023 </div> </div> <button class="popup-close" id="closePopup">✕</button> </div> <div class="popup-type workshop"> <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="currentColor"> <path d="M12,3L1,9L12,15L21,10.09V17H23V9M5,13.18V17.18L12,21L19,17.18V13.18L12,17L5,13.18Z"></path> </svg> Workshop </div> <div class="popup-description"> Learn practical skills for reducing waste in event planning. This hands-on workshop will cover sustainable materials, digital alternatives to printed materials, and food waste reduction strategies. </div> <div class="popup-eco-impact"> <div class="impact-title"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor"> <path d="M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4M15,12A3,3 0 0,1 12,15A3,3 0 0,1 9,12A3,3 0 0,1 12,9A3,3 0 0,1 15,12Z"></path> </svg> Environmental Impact </div> <div class="impact-details"> This event uses renewable energy and offers plant-based catering with local ingredients. </div> <div class="impact-stats"> <div class="impact-stat"> <div class="stat-value">85%</div> <div>Waste Diverted</div> </div> <div class="impact-stat"> <div class="stat-value">15kg</div> <div>CO₂ Saved</div> </div> <div class="impact-stat"> <div class="stat-value">100%</div> <div>Digital Materials</div> </div> </div> </div> <div class="popup-buttons"> <button class="popup-button primary-button">Register Now</button> <button class="popup-button secondary-button">Add to Calendar</button> </div> </div> <div class="overlay" id="overlay"></div> <script> document.addEventListener('DOMContentLoaded', function() { // Floating leaves animation for (let i = 0; i < 5; i++) { setTimeout(() => { createLeaf(); }, i * 3000); } // Create calendar days generateCalendar(); // Event handlers document.getElementById('closePopup').addEventListener('click', closeEventPopup); document.getElementById('overlay').addEventListener('click', closeEventPopup); document.querySelector('.prev-month').addEventListener('click', function() { // In a real app, this would change the month animateMonthChange('prev'); }); document.querySelector('.next-month').addEventListener('click', function() { // In a real app, this would change the month animateMonthChange('next'); }); // Category filters document.querySelectorAll('.category').forEach(category => { category.addEventListener('click', function() { const type = this.dataset.type; filterEvents(type); }); }); }); function generateCalendar() { const daysContainer = document.getElementById('daysContainer'); daysContainer.innerHTML = ''; // Sample data for June 2023 const totalDays = 30; const startDay = 4; // Thursday (0-indexed) // Add empty cells for days before the 1st for (let i = 0; i < startDay; i++) { const emptyDay = document.createElement('div'); emptyDay.className = 'day inactive'; daysContainer.appendChild(emptyDay); } // Event data const events = { 5: [{ title: 'Sustainable Packaging Seminar', type: 'conference' }], 8: [{ title: 'Community Garden Volunteer Day', type: 'sustainability' }], 12: [{ title: 'Eco-friendly Vendor Meetup', type: 'meetup' }], 15: [{ title: 'Zero Waste Workshop', type: 'workshop' }], 18: [{ title: 'Renewable Energy Forum', type: 'conference' }], 22: [{ title: 'Ocean Cleanup Coordination', type: 'sustainability' }], 25: [{ title: 'Green Tech Showcase', type: 'meetup' }], 28: [{ title: 'Composting Workshop', type: 'workshop' }] }; // Create calendar days for (let day = 1; day <= totalDays; day++) { const dayElement = document.createElement('div'); dayElement.className = 'day'; if (day === 15) dayElement.classList.add('today'); const dayNumber = document.createElement('div'); dayNumber.className = 'day-number'; dayNumber.textContent = day; dayElement.appendChild(dayNumber); const eventsContainer = document.createElement('div'); eventsContainer.className = 'events'; // Add events for this day if any if (events[day]) { events[day].forEach(event => { const eventElement = document.createElement('div'); eventElement.className = `event ${event.type}`; // Add icon based on event type const iconElement = document.createElement('div'); iconElement.className = 'event-icon'; let iconSvg; switch(event.type) { case 'conference': iconSvg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M17,12V3A1,1 0 0,0 16,2H3A1,1 0 0,0 2,3V17L6,13H16A1,1 0 0,0 17,12M21,6H19V15H6V17A1,1 0 0,0 7,18H18L22,22V7A1,1 0 0,0 21,6Z" /></svg>'; break; case 'workshop': iconSvg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M12,3L1,9L12,15L21,10.09V17H23V9M5,13.18V17.18L12,21L19,17.18V13.18L12,17L5,13.18Z" /></svg>'; break; case 'meetup': iconSvg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M12,5.5A3.5,3.5 0 0,1 15.5,9A3.5,3.5 0 0,1 12,12.5A3.5,3.5 0 0,1 8.5,9A3.5,3.5 0 0,1 12,5.5M5,8C5.56,8 6.08,8.15 6.53,8.42C6.38,9.85 6.8,11.27 7.66,12.38C7.16,13.34 6.16,14 5,14A3,3 0 0,1 2,11A3,3 0 0,1 5,8M19,8A3,3 0 0,1 22,11A3,3 0 0,1 19,14C17.84,14 16.84,13.34 16.34,12.38C17.2,11.27 17.62,9.85 17.47,8.42C17.92,8.15 18.44,8 19,8M5.5,18.25C5.5,16.18 8.41,14.5 12,14.5C15.59,14.5 18.5,16.18 18.5,18.25V20H5.5V18.25M0,20V18.5C0,17.11 1.89,15.94 4.45,15.6C3.86,16.28 3.5,17.22 3.5,18.25V20H0M24,20H20.5V18.25C20.5,17.22 20.14,16.28 19.55,15.6C22.11,15.94 24,17.11 24,18.5V20Z" /></svg>'; break; case 'sustainability': iconSvg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M15.5,9.63C15.31,6.84 14.18,4.12 12.06,2C9.92,4.14 8.74,6.86 8.5,9.63C9.79,10.31 10.97,11.19 12,12.26C13.03,11.2 14.21,10.32 15.5,9.63M12,15.45C9.85,12.17 6.18,10 2,10C2,20 11.32,21.89 12,22C12.68,21.88 22,20 22,10C17.82,10 14.15,12.17 12,15.45Z" /></svg>'; break; } iconElement.innerHTML = iconSvg; eventElement.appendChild(iconElement); const eventTitle = document.createElement('span'); eventTitle.textContent = event.title; eventElement.appendChild(eventTitle); // Add event listener to show popup eventElement.addEventListener('click', function(e) { e.stopPropagation(); showEventPopup(event, day); }); eventsContainer.appendChild(eventElement); }); } dayElement.appendChild(eventsContainer); // Add click event to the day dayElement.addEventListener('click', function() { document.querySelectorAll('.day').forEach(d => d.classList.remove('selected')); this.classList.add('selected'); }); daysContainer.appendChild(dayElement); } } function showEventPopup(event, day) { const popup = document.getElementById('eventPopup'); const overlay = document.getElementById('overlay'); // Update popup content based on the event popup.querySelector('.popup-title').textContent = event.title; popup.querySelector('.popup-date').innerHTML = ` <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="currentColor"> <path d="M19,19H5V8H19M16,1V3H8V1H6V3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3H18V1"></path> </svg> June ${day}, 2023 `; const typeElement = popup.querySelector('.popup-type'); typeElement.className = `popup-type ${event.type}`; let typeText, typeIcon, description, impact; switch(event.type) { case 'conference': typeText = 'Conference'; typeIcon = '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M17,12V3A1,1 0 0,0 16,2H3A1,1 0 0,0 2,3V17L6,13H16A1,1 0 0,0 17,12M21,6H19V15H6V17A1,1 0 0,0 7,18H18L22,22V7A1,1 0 0,0 21,6Z" /></svg>'; description = 'Join leading experts for sustainable discussions. This conference includes panel discussions on reducing carbon footprints and implementing green technologies in corporate environments.'; impact = { waste: '80%', co2: '25kg', digital: '90%' }; break; case 'workshop': typeText = 'Workshop'; typeIcon = '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M12,3L1,9L12,15L21,10.09V17H23V9M5,13.18V17.18L12,21L19,17.18V13.18L12,17L5,13.18Z" /></svg>'; description = 'Learn practical skills for reducing waste in event planning. This hands-on workshop will cover sustainable materials, digital alternatives to printed materials, and food waste reduction strategies.'; impact = { waste: '85%', co2: '15kg', digital: '100%' }; break; case 'meetup': typeText = 'Meetup'; typeIcon = '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>LUXE Collection 2024</title> <style> /* Base styles & reset */ * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Helvetica Neue', Arial, sans-serif; } body { background-color: #0a0a0a; color: #f8f8f8; height: 100%; width: 100%; overflow: hidden; } /* Typography */ h1 { font-size: 2.5rem; font-weight: 200; letter-spacing: 5px; text-transform: uppercase; margin-bottom: 0.5rem; } h2 { font-size: 1.2rem; font-weight: 300; letter-spacing: 2px; color: #999; margin-bottom: 2rem; } /* Container for the calendar */ .calendar-container { max-width: 700px; height: 700px; margin: 0 auto; padding: 2rem; position: relative; overflow: hidden; display: flex; flex-direction: column; } /* Header */ .header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 2.5rem; position: relative; } .logo { font-size: 1.8rem; font-weight: 200; letter-spacing: 6px; position: relative; z-index: 2; } .logo::after { content: ''; position: absolute; width: 40px; height: 1px; background: linear-gradient(90deg, rgba(212,175,55,0.3) 0%, rgba(212,175,55,1) 100%); bottom: -5px; left: 0; } .controls { display: flex; align-items: center; } .month-display { text-transform: uppercase; letter-spacing: 2px; font-size: 1rem; margin: 0 1.5rem; min-width: 120px; text-align: center; } .nav-btn { background: none; border: none; color: #f8f8f8; font-size: 1rem; cursor: pointer; padding: 0.5rem; transition: all 0.3s ease; } .nav-btn:hover { color: #d4af37; /* Gold metallic accent */ transform: scale(1.1); } /* Grid layout for events */ .event-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.25rem; flex-grow: 1; overflow-y: auto; padding-right: 0.5rem; position: relative; } .event-grid::-webkit-scrollbar { width: 3px; } .event-grid::-webkit-scrollbar-track { background: #1a1a1a; } .event-grid::-webkit-scrollbar-thumb { background: #333; } /* Event card styling */ .event-card { background-color: #141414; border: 1px solid #1e1e1e; border-radius: 2px; padding: 1.25rem; transition: all 0.4s cubic-bezier(0.19, 1, 0.22, 1); position: relative; overflow: hidden; cursor: pointer; height: 200px; display: flex; flex-direction: column; justify-content: space-between; } .event-card::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-size: cover; background-position: center; opacity: 0; z-index: 0; transition: opacity 0.6s ease; } .event-card:hover { transform: translateY(-5px); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); } .event-card:hover::before { opacity: 0.15; } .event-card:hover .event-preview { opacity: 1; transform: translateY(0); } .event-date { font-size: 0.85rem; font-weight: 500; color: #d4af37; margin-bottom: 0.5rem; position: relative; z-index: 1; } .event-title { font-size: 1rem; font-weight: 400; letter-spacing: 1px; margin-bottom: 0.75rem; position: relative; z-index: 1; } .event-location { font-size: 0.8rem; color: #777; position: relative; z-index: 1; } .event-preview { position: absolute; bottom: 0; left: 0; width: 100%; background: linear-gradient(0deg, rgba(20,20,20,0.9) 0%, rgba(20,20,20,0.7) 70%, rgba(20,20,20,0) 100%); padding: 2rem 1.25rem 1.25rem; opacity: 0; transform: translateY(20px); transition: all 0.4s cubic-bezier(0.19, 1, 0.22, 1); z-index: 2; } .event-tag { display: inline-block; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 1px; background-color: rgba(212, 175, 55, 0.2); color: #d4af37; padding: 0.25rem 0.5rem; border-radius: 2px; margin-bottom: 0.5rem; } .event-description { font-size: 0.8rem; line-height: 1.4; margin-bottom: 0.75rem; } .view-collection { display: inline-block; font-size: 0.75rem; text-transform: uppercase; letter-spacing: 1px; color: #d4af37; text-decoration: none; position: relative; } .view-collection::after { content: ''; position: absolute; width: 100%; height: 1px; background: linear-gradient(90deg, rgba(212,175,55,0.3) 0%, rgba(212,175,55,1) 100%); bottom: -3px; left: 0; transform: scaleX(0); transform-origin: left; transition: transform 0.3s ease; } .view-collection:hover::after { transform: scaleX(1); } /* Filter controls */ .filter-container { display: flex; justify-content: flex-start; margin-bottom: 1.5rem; overflow-x: auto; padding-bottom: 0.5rem; } .filter-container::-webkit-scrollbar { height: 2px; } .filter-container::-webkit-scrollbar-track { background: #1a1a1a; } .filter-container::-webkit-scrollbar-thumb { background: #333; } .filter-btn { background: none; border: 1px solid #333; color: #999; font-size: 0.75rem; padding: 0.5rem 1rem; margin-right: 0.75rem; cursor: pointer; transition: all 0.3s ease; white-space: nowrap; letter-spacing: 1px; text-transform: uppercase; } .filter-btn.active { background-color: #d4af37; border-color: #d4af37; color: #0a0a0a; } .filter-btn:hover:not(.active) { border-color: #d4af37; color: #d4af37; } /* Event highlight animation */ @keyframes highlightPulse { 0% { box-shadow: 0 0 0 0 rgba(212, 175, 55, 0.4); } 70% { box-shadow: 0 0 0 10px rgba(212, 175, 55, 0); } 100% { box-shadow: 0 0 0 0 rgba(212, 175, 55, 0); } } .highlight { animation: highlightPulse 2s infinite; } /* Background element */ .bg-element { position: absolute; top: 0; right: 0; width: 250px; height: 250px; background: linear-gradient(135deg, rgba(212,175,55,0.05) 0%, rgba(212,175,55,0) 70%); z-index: 0; border-radius: 50%; filter: blur(40px); } /* Responsive design */ @media (max-width: 700px) { .event-grid { grid-template-columns: repeat(2, 1fr); } h1 { font-size: 2rem; } h2 { font-size: 1rem; } .header { flex-direction: column; align-items: flex-start; } .logo { margin-bottom: 1rem; } .controls { width: 100%; justify-content: space-between; } } @media (max-width: 500px) { .event-grid { grid-template-columns: 1fr; } .calendar-container { padding: 1.5rem; } } </style> </head> <body> <div class="calendar-container"> <div class="bg-element"></div> <div class="header"> <div class="logo">LUXE</div> <div class="controls"> <button class="nav-btn prev-month">←</button> <div class="month-display">OCTOBER 2024</div> <button class="nav-btn next-month">→</button> </div> </div> <h1>FALL COLLECTION</h1> <h2>DISCOVER OUR UPCOMING FASHION EVENTS</h2> <div class="filter-container"> <button class="filter-btn active" data-filter="all">All Events</button> <button class="filter-btn" data-filter="runway">Runway Shows</button> <button class="filter-btn" data-filter="preview">Collection Previews</button> <button class="filter-btn" data-filter="release">Product Releases</button> <button class="filter-btn" data-filter="exclusive">Exclusive Events</button> </div> <div class="event-grid"> <!-- Events will be dynamically generated here --> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Event data const eventData = [ { id: 1, date: 'OCT 02', title: 'NOIR AUTUMN RUNWAY', location: 'Milan Fashion Center', category: 'runway', description: 'Unveiling the avant-garde pieces from our noir-inspired autumn line with unexpected silhouettes and textural contrasts.', backgroundImage: 'https://images.unsplash.com/photo-1529139574466-a303027c1d8b?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80', highlight: true }, { id: 2, date: 'OCT 07', title: 'METALLIC CAPSULE PREVIEW', location: 'Paris Gallery', category: 'preview', description: 'An intimate first look at our metallic capsule collection with innovative fabric treatments and architectural forms.', backgroundImage: 'https://images.unsplash.com/photo-1539109136881-3be0616acf4b?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80', highlight: false }, { id: 3, date: 'OCT 12', title: 'LUXE ACCESSORIES LAUNCH', location: 'New York Flagship Store', category: 'release', description: 'The debut of our limited-edition accessories with signature hardware details and unexpected material combinations.', backgroundImage: 'https://images.unsplash.com/photo-1544816155-12df9643f363?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80', highlight: false }, { id: 4, date: 'OCT 15', title: 'DIGITAL COUTURE EXPERIENCE', location: 'Virtual Exhibition', category: 'exclusive', description: 'An immersive digital showcase presenting our artisanal techniques through cutting-edge virtual reality.', backgroundImage: 'https://images.unsplash.com/photo-1558769132-cb1aea458c5e?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80', highlight: false }, { id: 5, date: 'OCT 19', title: 'STRUCTURED MINIMALISM', location: 'Berlin Design Hub', category: 'runway', description: 'A dialogue between structure and fluidity through our architectural silhouettes and restrained palette.', backgroundImage: 'https://images.unsplash.com/photo-1509631179647-0177331693ae?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80', highlight: false }, { id: 6, date: 'OCT 23', title: 'ATELIER OPEN HOUSE', location: 'Milan Studio', category: 'exclusive', description: 'A rare opportunity to witness our artisans at work and explore the craftsmanship behind the fall collection.', backgroundImage: 'https://images.unsplash.com/photo-1531469535976-c6fc3604095f?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80', highlight: false }, { id: 7, date: 'OCT 26', title: 'MONOCHROME LOOKBOOK REVEAL', location: 'London Photography Gallery', category: 'preview', description: 'An exhibition of our monochromatic editorial featuring emerging photographers and unexpected contexts.', backgroundImage: 'https://images.unsplash.com/photo-1582783722123-17e9e99eee62?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80', highlight: false }, { id: 8, date: 'OCT 29', title: 'LIMITED EDITION RELEASE', location: 'Online Exclusive', category: 'release', description: 'The midnight drop of our most anticipated pieces from the fall collection, available for 48 hours only.', backgroundImage: 'https://images.unsplash.com/photo-1515886657613-9f3515b0c78f?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80', highlight: true }, { id: 9, date: 'OCT 31', title: 'SEASONAL TRANSITION SHOWCASE', location: 'Tokyo Concept Space', category: 'runway', description: 'The transitional pieces that bridge fall and winter, featuring innovative fabric technology and modular design.', backgroundImage: 'https://images.unsplash.com/photo-1548123378-8c10cca84ce7?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80', highlight: false } ]; // Current state let currentMonth = 9; // 0-based, 9 = October let currentYear = 2024; let currentFilter = 'all'; const monthNames = ['JANUARY', 'FEBRUARY', 'MARCH', 'APRIL', 'MAY', 'JUNE', 'JULY', 'AUGUST', 'SEPTEMBER', 'OCTOBER', 'NOVEMBER', 'DECEMBER']; // DOM references const eventGrid = document.querySelector('.event-grid'); const monthDisplay = document.querySelector('.month-display'); const prevMonthBtn = document.querySelector('.prev-month'); const nextMonthBtn = document.querySelector('.next-month'); const filterBtns = document.querySelectorAll('.filter-btn'); // Generate event cards function renderEvents() { eventGrid.innerHTML = ''; const filteredEvents = eventData.filter(event => { return currentFilter === 'all' || event.category === currentFilter; }); filteredEvents.forEach(event => { const eventCard = document.createElement('div'); eventCard.classList.add('event-card'); if (event.highlight) { eventCard.classList.add('highlight'); } eventCard.style.setProperty('--bg-image', `url(${event.backgroundImage})`); eventCard.innerHTML = ` <div> <div class="event-date">${event.date}</div> <div class="event-title">${event.title}</div> <div class="event-location">${event.location}</div> </div> <div class="event-preview"> <div class="event-tag">${getCategoryLabel(event.category)}</div> <div class="event-description">${event.description}</div> <a href="#" class="view-collection">View Details</a> </div> `; // Set the background image eventCard.style.setProperty('--bg-image', `url(${event.backgroundImage})`); eventCard.style.backgroundImage = `url(${event.backgroundImage})`; // Set the background image for the ::before pseudo-element eventCard.style.setProperty('--event-bg', event.backgroundImage); eventGrid.appendChild(eventCard); }); } // Get readable label for category function getCategoryLabel(category) { const labels = { 'runway': 'Runway', 'preview': 'Preview', 'release': 'Release', 'exclusive': 'Exclusive' }; return labels[category] || category; } // Update month display function updateMonthDisplay() { monthDisplay.textContent = `${monthNames[currentMonth]} ${currentYear}`; } // Event listeners prevMonthBtn.addEventListener('click', function() { currentMonth--; if (currentMonth < 0) { currentMonth = 11; currentYear--; } updateMonthDisplay(); renderEvents(); }); nextMonthBtn.addEventListener('click', function() { currentMonth++; if (currentMonth > 11) { currentMonth = 0; currentYear++; } updateMonthDisplay(); renderEvents(); }); filterBtns.forEach(btn => { btn.addEventListener('click', function() { filterBtns.forEach(b => b.classList.remove('active')); this.classList.add('active'); currentFilter = this.getAttribute('data-filter'); renderEvents(); }); }); // Initialize updateMonthDisplay(); renderEvents(); // Add hover effects to event cards document.addEventListener('mouseover', function(e) { if (e.target.closest('.event-card')) { const card = e.target.closest('.event-card'); const before = window.getComputedStyle(card, '::before'); card.style.setProperty('--bg-opacity', '0.15'); } }); document.addEventListener('mouseout', function(e) { if (e.target.closest('.event-card')) { const card = e.target.closest('.event-card'); card.style.setProperty('--bg-opacity', '0'); } }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>MediSchedule - Your Health Appointment Calendar</title> <style> :root { --primary: #3498db; --primary-light: #5dade2; --primary-dark: #2980b9; --secondary: #2ecc71; --secondary-light: #58d68d; --secondary-dark: #27ae60; --tertiary: #e7f5fe; --accent: #9b59b6; --accent-light: #c39bd3; --text: #333; --text-light: #666; --text-dark: #222; --background: #f9f9f9; --alert: #e74c3c; --white: #ffffff; --shadow: rgba(0, 0, 0, 0.1); --transition: all 0.3s ease; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: var(--background); color: var(--text); line-height: 1.6; width: 100%; height: 100%; overflow-x: hidden; } .container { max-width: 690px; margin: 0 auto; padding: 15px; height: 690px; display: flex; flex-direction: column; position: relative; } header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; padding-bottom: 15px; border-bottom: 1px solid rgba(0, 0, 0, 0.05); } .logo { display: flex; align-items: center; gap: 10px; } .logo-icon { width: 36px; height: 36px; background: linear-gradient(135deg, var(--primary), var(--secondary)); border-radius: 50%; display: flex; align-items: center; justify-content: center; color: white; font-size: 18px; box-shadow: 0 3px 10px var(--shadow); } .logo-text { font-weight: 600; font-size: 1.2rem; color: var(--primary-dark); } .logo-text span { color: var(--secondary); } .user-info { display: flex; align-items: center; gap: 10px; } .user-avatar { width: 36px; height: 36px; border-radius: 50%; background: var(--tertiary); display: flex; align-items: center; justify-content: center; color: var(--primary); font-weight: 500; border: 2px solid var(--primary-light); } .calendar-container { display: flex; gap: 15px; flex: 1; } .calendar { flex: 1.8; background: var(--white); border-radius: 12px; box-shadow: 0 5px 15px var(--shadow); overflow: hidden; transition: var(--transition); height: 100%; display: flex; flex-direction: column; } .calendar-header { background: linear-gradient(120deg, var(--primary), var(--primary-dark)); color: white; padding: 15px 20px; display: flex; justify-content: space-between; align-items: center; } .month-selector { display: flex; align-items: center; gap: 15px; } .month-selector h2 { font-size: 1.1rem; font-weight: 500; } .nav-btn { background: rgba(255, 255, 255, 0.2); border: none; width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; color: white; font-size: 0.8rem; transition: var(--transition); } .nav-btn:hover { background: rgba(255, 255, 255, 0.4); } .today-btn { background: rgba(255, 255, 255, 0.15); border: 1px solid rgba(255, 255, 255, 0.3); padding: 6px 12px; border-radius: 20px; color: white; font-size: 0.8rem; cursor: pointer; transition: var(--transition); } .today-btn:hover { background: rgba(255, 255, 255, 0.25); } .weekdays { display: grid; grid-template-columns: repeat(7, 1fr); text-align: center; padding: 10px 0; background: var(--tertiary); font-size: 0.8rem; color: var(--text-light); font-weight: 500; } .days { display: grid; grid-template-columns: repeat(7, 1fr); grid-template-rows: repeat(6, 1fr); flex: 1; gap: 1px; background: rgba(0, 0, 0, 0.03); border-top: 1px solid rgba(0, 0, 0, 0.05); } .day { background: var(--white); height: 100%; padding: 8px; position: relative; transition: var(--transition); cursor: pointer; display: flex; flex-direction: column; } .day:hover { background: var(--tertiary); } .day-number { font-size: 0.8rem; font-weight: 500; margin-bottom: 5px; } .other-month { color: #ccc; } .today { background: var(--tertiary); } .today .day-number { background: var(--primary); color: white; width: 22px; height: 22px; display: flex; align-items: center; justify-content: center; border-radius: 50%; } .day-events { display: flex; flex-direction: column; gap: 3px; font-size: 0.6rem; overflow: hidden; } .day-event { padding: 2px 4px; border-radius: 3px; color: white; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; opacity: 0.9; transition: var(--transition); } .day-event:hover { opacity: 1; } .day-event.checkup { background: var(--primary); } .day-event.therapy { background: var(--secondary); } .day-event.urgent { background: var(--alert); } .day-event.lab { background: var(--accent); } .event-dot { width: 6px; height: 6px; border-radius: 50%; margin-right: 3px; display: inline-block; } .appointment-panel { flex: 1; background: var(--white); border-radius: 12px; box-shadow: 0 5px 15px var(--shadow); overflow: hidden; display: flex; flex-direction: column; } .panel-header { background: linear-gradient(120deg, var(--secondary), var(--secondary-dark)); color: white; padding: 15px 20px; } .panel-title { font-size: 1rem; font-weight: 500; margin-bottom: 5px; } .panel-subtitle { font-size: 0.8rem; opacity: 0.8; } .appointment-list { flex: 1; overflow-y: auto; padding: 15px; } .appointment-list::-webkit-scrollbar { width: 6px; } .appointment-list::-webkit-scrollbar-track { background: var(--tertiary); } .appointment-list::-webkit-scrollbar-thumb { background: var(--primary-light); border-radius: 6px; } .appointment-item { background: var(--tertiary); border-radius: 8px; padding: 12px; margin-bottom: 10px; transition: var(--transition); position: relative; border-left: 4px solid var(--primary); } .appointment-item:hover { transform: translateY(-2px); box-shadow: 0 3px 10px var(--shadow); } .appointment-item.therapy { border-left-color: var(--secondary); } .appointment-item.urgent { border-left-color: var(--alert); } .appointment-item.lab { border-left-color: var(--accent); } .appointment-time { font-size: 0.75rem; color: var(--text-light); margin-bottom: 5px; display: flex; align-items: center; gap: 5px; } .appointment-time i { color: var(--primary); } .appointment-title { font-weight: 500; margin-bottom: 5px; font-size: 0.9rem; } .appointment-doctor { font-size: 0.8rem; color: var(--text-light); margin-bottom: 10px; } .appointment-actions { display: flex; gap: 8px; } .appointment-btn { padding: 6px 12px; border-radius: 6px; border: none; font-size: 0.7rem; cursor: pointer; transition: var(--transition); display: flex; align-items: center; gap: 5px; } .btn-primary { background: var(--primary); color: white; } .btn-primary:hover { background: var(--primary-dark); } .btn-outline { background: transparent; border: 1px solid var(--primary); color: var(--primary); } .btn-outline:hover { background: var(--tertiary); } .add-appointment { padding: 15px; border-top: 1px solid rgba(0, 0, 0, 0.05); } .appointment-form { display: flex; flex-direction: column; gap: 12px; } .form-group { display: flex; flex-direction: column; gap: 5px; } .form-label { font-size: 0.8rem; color: var(--text-light); } .form-input { padding: 8px 12px; border-radius: 6px; border: 1px solid rgba(0, 0, 0, 0.1); font-size: 0.9rem; transition: var(--transition); } .form-input:focus { border-color: var(--primary); outline: none; box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.2); } .form-select { padding: 8px 12px; border-radius: 6px; border: 1px solid rgba(0, 0, 0, 0.1); font-size: 0.9rem; background: white; transition: var(--transition); } .form-select:focus { border-color: var(--primary); outline: none; box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.2); } .form-row { display: flex; gap: 10px; } .form-row .form-group { flex: 1; } .full-width { width: 100%; } .notification { position: fixed; bottom: 20px; right: 20px; background: white; border-radius: 8px; padding: 15px; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); max-width: 300px; display: flex; gap: 10px; transform: translateY(100px); opacity: 0; transition: all 0.3s ease; z-index: 1000; } .notification.show { transform: translateY(0); opacity: 1; } .notification-icon { width: 28px; height: 28px; border-radius: 50%; background: var(--primary); display: flex; align-items: center; justify-content: center; color: white; } .notification-content { flex: 1; } .notification-title { font-weight: 500; margin-bottom: 3px; font-size: 0.9rem; } .notification-message { font-size: 0.8rem; color: var(--text-light); } .notification-close { width: 20px; height: 20px; border-radius: 50%; background: rgba(0, 0, 0, 0.05); display: flex; align-items: center; justify-content: center; cursor: pointer; transition: var(--transition); } .notification-close:hover { background: rgba(0, 0, 0, 0.1); } /* Animation */ @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.05); } 100% { transform: scale(1); } } .day-event.urgent { animation: pulse 1.5s infinite; } .hidden { display: none; } @media (max-width: 640px) { .calendar-container { flex-direction: column; } .days { grid-template-rows: repeat(5, 35px); } .day { padding: 2px 4px; } .day-events { display: none; } } </style> </head> <body> <div class="container"> <header> <div class="logo"> <div class="logo-icon"> <i>+</i> </div> <div class="logo-text">Medi<span>Schedule</span></div> </div> <div class="user-info"> <div class="user-avatar">JS</div> </div> </header> <div class="calendar-container"> <div class="calendar"> <div class="calendar-header"> <div class="month-selector"> <button class="nav-btn" id="prev-month"> <i><</i> </button> <h2 id="current-month">May 2024</h2> <button class="nav-btn" id="next-month"> <i>></i> </button> </div> <button class="today-btn" id="today-btn">Today</button> </div> <div class="weekdays"> <div>Sun</div> <div>Mon</div> <div>Tue</div> <div>Wed</div> <div>Thu</div> <div>Fri</div> <div>Sat</div> </div> <div class="days" id="calendar-days"></div> </div> <div class="appointment-panel"> <div class="panel-header"> <h3 class="panel-title">Your Appointments</h3> <div class="panel-subtitle" id="selected-date">Thursday, May 16, 2024</div> </div> <div class="appointment-list" id="appointment-list"> <div class="appointment-item"> <div class="appointment-time"> <i>⏰</i> 9:00 AM - 9:30 AM </div> <div class="appointment-title">Annual Physical Examination</div> <div class="appointment-doctor">Dr. Sarah Johnson</div> <div class="appointment-actions"> <button class="appointment-btn btn-primary" onclick="showNotification('Reminder sent!', 'We\'ve sent a reminder for your appointment with Dr. Johnson.')"> <i>📌</i> Remind </button> <button class="appointment-btn btn-outline" onclick="showNotification('Rescheduling options', 'Please call (555) 123-4567 to reschedule this appointment.')"> <i>🔄</i> Reschedule </button> </div> </div> <div class="appointment-item therapy"> <div class="appointment-time"> <i>⏰</i> 2:00 PM - 3:00 PM </div> <div class="appointment-title">Physical Therapy Session</div> <div class="appointment-doctor">Therapist Mike Brown</div> <div class="appointment-actions"> <button class="appointment-btn btn-primary" onclick="showNotification('Reminder sent!', 'We\'ve sent a reminder for your therapy session with Mike Brown.')"> <i>📌</i> Remind </button> <button class="appointment-btn btn-outline" onclick="showNotification('Rescheduling options', 'Please call (555) 987-6543 to reschedule this therapy session.')"> <i>🔄</i> Reschedule </button> </div> </div> </div> <div class="add-appointment"> <form class="appointment-form" id="appointment-form"> <div class="form-row"> <div class="form-group"> <label class="form-label" for="appointment-type">Appointment Type</label> <select class="form-select" id="appointment-type"> <option value="checkup">Medical Checkup</option> <option value="therapy">Therapy Session</option> <option value="lab">Lab Work</option> <option value="urgent">Urgent Care</option> </select> </div> <div class="form-group"> <label class="form-label" for="appointment-time">Time</label> <select class="form-select" id="appointment-time"> <option value="8:00">8:00 AM</option> <option value="9:00">9:00 AM</option> <option value="10:00">10:00 AM</option> <option value="11:00">11:00 AM</option> <option value="12:00">12:00 PM</option> <option value="1:00">1:00 PM</option> <option value="2:00">2:00 PM</option> <option value="3:00">3:00 PM</option> <option value="4:00">4:00 PM</option> </select> </div> </div> <div class="form-group"> <label class="form-label" for="appointment-provider">Healthcare Provider</label> <select class="form-select" id="appointment-provider"> <option value="Dr. Sarah Johnson">Dr. Sarah Johnson - General Medicine</option> <option value="Dr. Robert Chen">Dr. Robert Chen - Cardiology</option> <option value="Dr. Lisa Wong">Dr. Lisa Wong - Dermatology</option> <option value="Therapist Mike Brown">Therapist Mike Brown - Physical Therapy</option> <option value="Dr. Emily Davis">Dr. Emily Davis - Neurology</option> </select> </div> <button type="button" class="appointment-btn btn-primary full-width" id="schedule-btn"> Schedule Appointment </button> </form> </div> </div> </div> </div> <div class="notification" id="notification"> <div class="notification-icon"> <i>✓</i> </div> <div class="notification-content"> <div class="notification-title" id="notification-title">Appointment Scheduled</div> <div class="notification-message" id="notification-message">Your appointment has been successfully scheduled.</div> </div> <div class="notification-close" onclick="closeNotification()">×</div> </div> <script> // Calendar functionality const calendar = { currentDate: new Date(), selectedDate: new Date(), events: { '2024-05-16': [ { type: 'checkup', title: 'Annual Physical Examination', time: '9:00' }, { type: 'therapy', title: 'Physical Therapy Session', time: '14:00' } ], '2024-05-18': [ { type: 'lab', title: 'Blood Work', time: '10:30' } ], '2024-05-22': [ { type: 'urgent', title: 'Follow-up Consultation', time: '11:00' } ], '2024-05-25': [ { type: 'checkup', title: 'Dental Cleaning', time: '13:00' } ] }, init() { this.updateCalendar(); this.setupEventListeners(); this.updateSelectedDate(); this.updateAppointments(); }, setupEventListeners() { document.getElementById('prev-month').addEventListener('click', () => { this.currentDate.setMonth(this.currentDate.getMonth() - 1); this.updateCalendar(); }); document.getElementById('next-month').addEventListener('click', () => { this.currentDate.setMonth(this.currentDate.getMonth() + 1); this.updateCalendar(); }); document.getElementById('today-btn').addEventListener('click', () => { this.currentDate = new Date(); this.selectedDate = new Date(); this.updateCalendar(); this.updateSelectedDate(); this.updateAppointments(); }); document.getElementById('schedule-btn').addEventListener('click', this.scheduleAppointment.bind(this)); }, updateCalendar() { const daysContainer = document.getElementById('calendar-days'); daysContainer.innerHTML = ''; const year = this.currentDate.getFullYear(); const month = this.currentDate.getMonth(); // Update month and year in header document.getElementById('current-month').textContent = new Intl.DateTimeFormat('en-US', { month: 'long', year: 'numeric' }).format(this.currentDate); // First day of month const firstDay = new Date(year, month, 1); // Last day of month const lastDay = new Date(year, month + 1, 0); // First day of the calendar grid (might be from previous month) const startDay = new Date(firstDay); startDay.setDate(startDay.getDate() - startDay.getDay()); const today = new Date(); // Generate 42 days (6 weeks) for (let i = 0; i < 42; i++) { const currentDate = new Date(startDay); currentDate.setDate(startDay.getDate() + i); const isOtherMonth = currentDate.getMonth() !== month; const isToday = currentDate.toDateString() === today.toDateString(); const isSelected = currentDate.toDateString() === this.selectedDate.toDateString(); // Format date as YYYY-MM-DD for event lookup const dateKey = this.formatDateKey(currentDate); const dayEvents = this.events[dateKey] || []; const dayElement = document.createElement('div'); dayElement.className = `day${isOtherMonth ? ' other-month' : ''}${isToday ? ' today' : ''}${isSelected ? ' selected' : ''}`; dayElement.dataset.date = dateKey; // Add day number const dayNumber = document.createElement('div'); dayNumber.className = 'day-number'; dayNumber.textContent = currentDate.getDate(); dayElement.appendChild(dayNumber); // Add events if (dayEvents.length > 0) { const eventsContainer = document.createElement('div'); eventsContainer.className = 'day-events'; dayEvents.forEach(event => { const eventElement = document.createElement('div'); eventElement.className = `day-event ${event.type}`; eventElement.innerHTML = `<span class="event-dot"></span>${event.title}`; eventsContainer.appendChild(eventElement); }); dayElement.appendChild(eventsContainer); } // Add click handler to select day dayElement.addEventListener('click', () => { // Remove selected class from previously selected day const previousSelected = document.querySelector('.day.selected'); if (previousSelected) { previousSelected.classList.remove('selected'); } // Add selected class to clicked day dayElement.classList.add('selected'); // Update selected date this.selectedDate = new Date(currentDate); this.updateSelectedDate(); this.updateAppointments(); }); daysContainer.appendChild(dayElement); } }, formatDateKey(date) { return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`; }, updateSelectedDate() { document.getElementById('selected-date').textContent = new Intl.DateTimeFormat('en-US', { weekday: 'long', month: 'long', day: 'numeric', year: 'numeric' }).format(this.selectedDate); }, updateAppointments() { const appointmentList = document.getElementById('appointment-list'); appointmentList.innerHTML = ''; const dateKey = this.formatDateKey(this.selectedDate); const dayEvents = this.events[dateKey] || []; if (dayEvents.length === 0) { const noAppointments = document.createElement('div'); noAppointments.style.textAlign = 'center'; noAppointments.style.padding = '20px'; noAppointments.style.color = 'var(--text-light)'; noAppointments.innerHTML = ` <div style="font-size: 1.5rem; margin-bottom: 10px;">📅</div> <div style="font-weight: 500; margin-bottom: 5px;">No appointments scheduled</div> <div style="font-size: 0.8rem;">Use the form below to schedule a new appointment</div> `; appointmentList.appendChild(noAppointments); return; } dayEvents.forEach(event => { const timeFormat = event.time.includes(':') ? event.time : `${event.time}:00`; const hour = parseInt(timeFormat.split(':')[0]); const minute = timeFormat.split(':')[1]; const period = hour >= 12 ? 'PM' : 'AM'; const hour12 = hour > 12 ? hour - 12 : (hour === 0 ? 12 : hour); const formattedTime = `${hour12}:${minute} ${period}`; // Calculate end time (30 minutes for normal, 60 for therapy) const endHour = event.type === 'therapy' ? hour + 1 : hour; const endMinute = event.type === 'therapy' ? minute : (parseInt(minute) + 30).toString().padStart(2, '0'); const endPeriod = endHour >= 12 ? 'PM' : 'AM'; const endHour12 = endHour > 12 ? endHour - 12 : (endHour === 0 ? 12 : endHour); const formattedEndTime = `${endHour12}:${endMinute} ${endPeriod}`; const item = document.createElement('div'); item.className = `appointment-item ${event.type}`; // Use the event data to construct the appointment item let doctorName = 'Dr. Sarah Johnson'; if (event.type === 'therapy') doctorName = 'Therapist Mike Brown'; if (event.type === 'lab') doctorName = 'Lab Technician Alice Miller'; if (event.title.toLowerCase().includes('dental')) doctorName = 'Dr. Robert Chen, DDS'; item.innerHTML = ` <div class="appointment-time"> <i>⏰</i> ${formattedTime} - ${formattedEndTime} </div> <div class="appointment-title">${event.title}</div> <div class="appointment-doctor">${doctorName}</div> <div class="appointment-actions"> <button class="appointment-btn btn-primary" onclick="showNotification('Reminder sent!', 'We\\'ve sent a reminder for your ${event.title.toLowerCase()}.')"> <i>📌</i> Remind </button> <button class="appointment-btn btn-outline" onclick="showNotification('Rescheduling options', 'Please call (555) 123-4567 to reschedule this appointment.')"> <i>🔄</i> Reschedule </button> </div> `; appointmentList.appendChild(item); }); }, scheduleAppointment() { const type = document.getElementById('appointment-type').value; const time = document.getElementById('appointment-time').value; const provider = document.getElementById('appointment-provider').value; // Generate appointment title based on type let title = 'Medical Checkup'; if (type === 'therapy') title = 'Physical Therapy Session'; if (type === 'lab') title = 'Lab Tests'; if (type === 'urgent') title = 'Urgent Care Visit'; // Format date for events object const dateKey = this.formatDateKey(this.selectedDate); // Create new event const newEvent = { type: type, title: title, time: time, provider: provider }; // Add to events object if (!this.events[dateKey]) { this.events[dateKey] = []; } // Check for time conflicts const timeHour = parseInt(time.split(':')[0]); let hasConflict = false; for (const event of this.events[dateKey]) { const eventHour = parseInt(event.time.split(':')[0]); // Check if the same hour or adjacent hour for therapy (which takes longer) if (eventHour === timeHour || (event.type === 'therapy' && eventHour + 1 === timeHour) || (type === 'therapy' && eventHour === timeHour + 1)) { hasConflict = true; break; } } if (hasConflict) { showNotification('Time Conflict', 'This time slot conflicts with an existing appointment. Please select a different time.', 'warning'); return; } this.events[dateKey].push(newEvent); // Update calendar and appointments this.updateCalendar(); this.updateAppointments(); // Show confirmation notification showNotification('Appointment Scheduled', `Your ${title.toLowerCase()} has been scheduled with ${provider} on ${new Intl.DateTimeFormat('en-US', { month: 'long', day: 'numeric' }).format(this.selectedDate)} at ${time}.`); } }; // Show notification function showNotification(title, message, type = 'success') { const notification = document.getElementById('notification'); const notificationTitle = document.getElementById('notification-title'); const notificationMessage = document.getElementById('notification-message'); notificationTitle.textContent = title; notificationMessage.textContent = message; // Change icon and color based on type const notificationIcon = notification.querySelector('.notification-icon'); if (type === 'warning') { notificationIcon.style.background = 'var(--alert)'; notificationIcon.innerHTML = '<i>!</i>'; } else { notificationIcon.style.background = 'var(--primary)'; notificationIcon.innerHTML = '<i>✓</i>'; } notification.classList.add('show'); // Auto hide after 4 seconds setTimeout(closeNotification, 4000); } function closeNotification() { const notification = document.getElementById('notification'); notification.classList.remove('show'); } // Initialize calendar document.addEventListener('DOMContentLoaded', () => { calendar.init(); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Gourmet Reservations Calendar</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Playfair Display', serif; } @import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;500;700&family=Poppins:wght@300;400;500&display=swap'); :root { --primary: #873e23; --secondary: #e3c4a8; --accent: #f5b841; --dark: #2c1a12; --light: #fdf6ed; --shadow: rgba(44, 26, 18, 0.15); --available: #3a9278; --busy: #d64550; --limited: #f5b841; } body { background-color: var(--light); max-width: 700px; max-height: 700px; margin: 0 auto; overflow: hidden; } .container { width: 100%; height: 100vh; max-height: 700px; padding: 20px; display: flex; flex-direction: column; overflow: hidden; position: relative; } .bg-pattern { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-image: radial-gradient(var(--secondary) 1px, transparent 1px); background-size: 20px 20px; opacity: 0.2; z-index: -1; animation: fadeIn 1s ease-in-out; } .header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; padding-bottom: 15px; border-bottom: 2px solid var(--secondary); } .logo { display: flex; align-items: center; gap: 10px; } .logo-icon { width: 32px; height: 32px; background-color: var(--primary); border-radius: 50%; display: flex; align-items: center; justify-content: center; color: var(--light); font-size: 16px; } .logo-text { color: var(--primary); font-weight: 700; font-size: 1.2rem; line-height: 1; } .logo-text span { font-size: 0.7rem; color: var(--dark); opacity: 0.8; display: block; font-family: 'Poppins', sans-serif; font-weight: 400; } .user-info { font-family: 'Poppins', sans-serif; font-size: 0.9rem; color: var(--dark); display: flex; align-items: center; gap: 10px; } .user-icon { width: 36px; height: 36px; background-color: var(--secondary); border-radius: 50%; display: flex; align-items: center; justify-content: center; color: var(--primary); font-size: 18px; transition: all 0.3s ease; } .user-icon:hover { transform: scale(1.1); background-color: var(--primary); color: var(--light); cursor: pointer; } .main-content { display: flex; gap: 20px; height: calc(100% - 80px); } .calendar-section { flex: 1; background-color: white; border-radius: 12px; box-shadow: 0 4px 12px var(--shadow); padding: 20px; display: flex; flex-direction: column; overflow: hidden; position: relative; transition: all 0.3s ease; } .calendar-header { display: flex; justify-content: space-between; margin-bottom: 15px; } .current-month { font-weight: 700; color: var(--dark); font-size: 1.1rem; } .calendar-controls { display: flex; gap: 10px; } .calendar-btn { width: 30px; height: 30px; border-radius: 50%; border: none; background-color: var(--light); color: var(--primary); font-size: 1rem; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.2s ease; } .calendar-btn:hover { background-color: var(--primary); color: var(--light); } .weekdays { display: grid; grid-template-columns: repeat(7, 1fr); gap: 5px; margin-bottom: 10px; } .weekday { text-align: center; font-size: 0.8rem; font-weight: 500; color: var(--dark); opacity: 0.7; font-family: 'Poppins', sans-serif; } .calendar-days { display: grid; grid-template-columns: repeat(7, 1fr); gap: 5px; flex-grow: 1; } .day { aspect-ratio: 1; display: flex; align-items: center; justify-content: center; flex-direction: column; border-radius: 8px; cursor: pointer; transition: all 0.2s ease; position: relative; overflow: hidden; font-family: 'Poppins', sans-serif; } .day:not(.empty):hover { background-color: var(--secondary); transform: translateY(-2px); } .day.empty { cursor: default; } .day-number { font-size: 0.9rem; font-weight: 500; margin-bottom: 2px; } .day-status { font-size: 0.65rem; width: 70%; height: 4px; border-radius: 2px; } .available .day-status { background-color: var(--available); } .busy .day-status { background-color: var(--busy); } .limited .day-status { background-color: var(--limited); } .day.selected { background-color: var(--primary); color: white; transform: scale(1.05); box-shadow: 0 4px 8px rgba(135, 62, 35, 0.3); font-weight: 700; } .day.selected .day-status { background-color: white; opacity: 0.8; } .day.today { border: 2px solid var(--accent); } .day.past { opacity: 0.5; cursor: not-allowed; } .day.past:hover { background-color: transparent; transform: none; } .reservation-section { width: 280px; background-color: white; border-radius: 12px; box-shadow: 0 4px 12px var(--shadow); padding: 20px; display: flex; flex-direction: column; overflow: hidden; position: relative; transition: all 0.3s ease; } .reservation-header { margin-bottom: 15px; } .reservation-title { font-weight: 700; color: var(--dark); font-size: 1.1rem; margin-bottom: 5px; } .reservation-date { font-family: 'Poppins', sans-serif; font-size: 0.9rem; color: var(--primary); } .time-slots { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin-bottom: 15px; max-height: 230px; overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--secondary) var(--light); padding-right: 5px; } .time-slots::-webkit-scrollbar { width: 6px; } .time-slots::-webkit-scrollbar-track { background: var(--light); border-radius: 10px; } .time-slots::-webkit-scrollbar-thumb { background-color: var(--secondary); border-radius: 10px; } .time-slot { padding: 12px 10px; border-radius: 8px; text-align: center; cursor: pointer; transition: all 0.2s ease; font-family: 'Poppins', sans-serif; font-size: 0.9rem; position: relative; overflow: hidden; border: 1px solid var(--secondary); } .time-slot:hover { border-color: var(--primary); } .time-slot.selected { background-color: var(--primary); color: white; border-color: var(--primary); transform: scale(1.05); box-shadow: 0 2px 6px rgba(135, 62, 35, 0.3); } .time-slot.unavailable { cursor: not-allowed; opacity: 0.5; background-color: #f5f5f5; color: #999; border-color: #eee; } .time-slot.unavailable:hover { transform: none; border-color: #eee; } .party-size { margin-bottom: 15px; } .party-size-label { font-family: 'Poppins', sans-serif; font-size: 0.9rem; margin-bottom: 8px; color: var(--dark); display: block; } .party-selector { display: flex; gap: 10px; align-items: center; } .party-btn { width: 36px; height: 36px; border-radius: 50%; border: none; background-color: var(--light); color: var(--primary); font-size: 1.2rem; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.2s ease; } .party-btn:hover { background-color: var(--primary); color: var(--light); } .party-count { font-family: 'Playfair Display', serif; font-weight: 700; font-size: 1.2rem; color: var(--dark); width: 40px; text-align: center; } .special-request { margin-bottom: 20px; } .special-request-label { font-family: 'Poppins', sans-serif; font-size: 0.9rem; margin-bottom: 8px; color: var(--dark); display: block; } .special-request-input { width: 100%; padding: 10px; border-radius: 8px; border: 1px solid var(--secondary); font-family: 'Poppins', sans-serif; font-size: 0.9rem; resize: none; height: 70px; transition: all 0.2s ease; } .special-request-input:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 2px rgba(135, 62, 35, 0.1); } .button-container { margin-top: auto; } .reserve-btn { width: 100%; padding: 12px; border: none; border-radius: 8px; background-color: var(--primary); color: white; font-family: 'Poppins', sans-serif; font-weight: 500; font-size: 1rem; cursor: pointer; transition: all 0.3s ease; display: flex; align-items: center; justify-content: center; gap: 10px; position: relative; overflow: hidden; } .reserve-btn:hover { background-color: #6a2e1a; transform: translateY(-2px); box-shadow: 0 4px 12px rgba(135, 62, 35, 0.3); } .reserve-btn:active { transform: translateY(0); } .reserve-btn::after { content: ''; position: absolute; width: 30px; height: 100%; top: 0; left: -80px; background-color: rgba(255, 255, 255, 0.3); transform: skewX(-20deg); transition: all 0.5s ease; } .reserve-btn:hover::after { left: 110%; } .legend { display: flex; gap: 15px; margin-top: 10px; justify-content: center; font-family: 'Poppins', sans-serif; font-size: 0.75rem; } .legend-item { display: flex; align-items: center; gap: 5px; } .legend-color { width: 10px; height: 10px; border-radius: 50%; } .legend-available { background-color: var(--available); } .legend-busy { background-color: var(--busy); } .legend-limited { background-color: var(--limited); } .confirmation-modal { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(255, 255, 255, 0.95); display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 20px; text-align: center; z-index: 10; opacity: 0; pointer-events: none; transition: all 0.4s ease; backdrop-filter: blur(5px); } .confirmation-modal.show { opacity: 1; pointer-events: auto; } .confirmation-icon { width: 80px; height: 80px; background-color: var(--available); border-radius: 50%; display: flex; align-items: center; justify-content: center; color: white; font-size: 40px; margin-bottom: 20px; transform: scale(0); transition: transform 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275) 0.1s; } .confirmation-modal.show .confirmation-icon { transform: scale(1); } .confirmation-title { font-size: 1.6rem; font-weight: 700; color: var(--dark); margin-bottom: 10px; transform: translateY(20px); opacity: 0; transition: all 0.5s ease 0.2s; } .confirmation-modal.show .confirmation-title { transform: translateY(0); opacity: 1; } .confirmation-details { font-family: 'Poppins', sans-serif; font-size: 1rem; color: var(--dark); margin-bottom: 30px; opacity: 0; transform: translateY(20px); transition: all 0.5s ease 0.3s; line-height: 1.6; } .confirmation-modal.show .confirmation-details { transform: translateY(0); opacity: 1; } .confirmation-btn { padding: 12px 30px; border: none; border-radius: 8px; background-color: var(--primary); color: white; font-family: 'Poppins', sans-serif; font-weight: 500; font-size: 1rem; cursor: pointer; transition: all 0.3s ease; opacity: 0; transform: translateY(20px); transition: all 0.5s ease 0.4s; } .confirmation-modal.show .confirmation-btn { transform: translateY(0); opacity: 1; } .confirmation-btn:hover { background-color: #6a2e1a; transform: translateY(-2px); box-shadow: 0 4px 12px rgba(135, 62, 35, 0.3); } @keyframes fadeIn { from { opacity: 0; } to { opacity: 0.2; } } @media (max-width: 700px) { .container { padding: 15px; } .main-content { flex-direction: column; gap: 15px; overflow-y: auto; height: calc(100% - 70px); } .calendar-section { flex: none; height: 350px; } .reservation-section { width: 100%; flex: none; } .time-slots { max-height: 150px; } .day-number { font-size: 0.8rem; } } </style> </head> <body> <div class="container"> <div class="bg-pattern"></div> <div class="header"> <div class="logo"> <div class="logo-icon"> <i>G</i> </div> <div class="logo-text"> Gourmand <span>Fine Dining</span> </div> </div> <div class="user-info"> <div class="user-icon"> <i>≡</i> </div> </div> </div> <div class="main-content"> <div class="calendar-section"> <div class="calendar-header"> <div class="current-month">October 2023</div> <div class="calendar-controls"> <button class="calendar-btn prev-month">‹</button> <button class="calendar-btn next-month">›</button> </div> </div> <div class="weekdays"> <div class="weekday">S</div> <div class="weekday">M</div> <div class="weekday">T</div> <div class="weekday">W</div> <div class="weekday">T</div> <div class="weekday">F</div> <div class="weekday">S</div> </div> <div class="calendar-days"> <!-- Days will be dynamically generated here --> </div> <div class="legend"> <div class="legend-item"> <div class="legend-color legend-available"></div> <span>Available</span> </div> <div class="legend-item"> <div class="legend-color legend-busy"></div> <span>Fully Booked</span> </div> <div class="legend-item"> <div class="legend-color legend-limited"></div> <span>Limited</span> </div> </div> </div> <div class="reservation-section"> <div class="reservation-header"> <div class="reservation-title">Make a Reservation</div> <div class="reservation-date">Select a date to begin</div> </div> <div class="time-slots"> <!-- Time slots will be dynamically generated here --> </div> <div class="party-size"> <label class="party-size-label">Number of Guests</label> <div class="party-selector"> <button class="party-btn decrease-party">−</button> <span class="party-count">2</span> <button class="party-btn increase-party">+</button> </div> </div> <div class="special-request"> <label class="special-request-label">Special Requests</label> <textarea class="special-request-input" placeholder="Allergies, special occasions, seating preferences..."></textarea> </div> <div class="button-container"> <button class="reserve-btn" disabled>Complete Reservation</button> </div> </div> </div> <div class="confirmation-modal"> <div class="confirmation-icon">✓</div> <h2 class="confirmation-title">Reservation Confirmed!</h2> <div class="confirmation-details"> Your table for <span class="confirm-party-size">2</span> guests is set for <span class="confirm-date">October 15</span> at <span class="confirm-time">7:30 PM</span>.<br> We look forward to serving you at Gourmand. </div> <button class="confirmation-btn">Done</button> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Current date const currentDate = new Date(); const currentDay = currentDate.getDate(); const currentMonth = currentDate.getMonth(); const currentYear = currentDate.getFullYear(); // State variables let selectedDate = null; let selectedTimeSlot = null; let partySize = 2; let displayedMonth = currentMonth; let displayedYear = currentYear; // DOM elements const calendarDaysContainer = document.querySelector('.calendar-days'); const currentMonthElement = document.querySelector('.current-month'); const timeSlotsContainer = document.querySelector('.time-slots'); const reservationDateElement = document.querySelector('.reservation-date'); const partySizeElement = document.querySelector('.party-count'); const decreasePartyBtn = document.querySelector('.decrease-party'); const increasePartyBtn = document.querySelector('.increase-party'); const reserveBtn = document.querySelector('.reserve-btn'); const confirmModal = document.querySelector('.confirmation-modal'); const confirmPartySize = document.querySelector('.confirm-party-size'); const confirmDate = document.querySelector('.confirm-date'); const confirmTime = document.querySelector('.confirm-time'); const confirmBtn = document.querySelector('.confirmation-btn'); const prevMonthBtn = document.querySelector('.prev-month'); const nextMonthBtn = document.querySelector('.next-month'); // Generate calendar for the current month generateCalendar(displayedMonth, displayedYear); // Event listeners decreasePartyBtn.addEventListener('click', function() { if (partySize > 1) { partySize--; partySizeElement.textContent = partySize; } }); increasePartyBtn.addEventListener('click', function() { if (partySize < 12) { partySize++; partySizeElement.textContent = partySize; } }); reserveBtn.addEventListener('click', function() { if (selectedDate && selectedTimeSlot) { const options = { month: 'long', day: 'numeric' }; confirmPartySize.textContent = partySize; confirmDate.textContent = selectedDate.toLocaleDateString('en-US', options); confirmTime.textContent = selectedTimeSlot; confirmModal.classList.add('show'); } }); confirmBtn.addEventListener('click', function() { confirmModal.classList.remove('show'); // Reset the form selectedDate = null; selectedTimeSlot = null; reserveBtn.disabled = true; reservationDateElement.textContent = 'Select a date to begin'; timeSlotsContainer.innerHTML = ''; generateCalendar(displayedMonth, displayedYear); }); prevMonthBtn.addEventListener('click', function() { displayedMonth--; if (displayedMonth < 0) { displayedMonth = 11; displayedYear--; } generateCalendar(displayedMonth, displayedYear); }); nextMonthBtn.addEventListener('click', function() { displayedMonth++; if (displayedMonth > 11) { displayedMonth = 0; displayedYear++; } generateCalendar(displayedMonth, displayedYear); }); // Functions function generateCalendar(month, year) { calendarDaysContainer.innerHTML = ''; const daysInMonth = new Date(year, month + 1, 0).getDate(); const firstDay = new Date(year, month, 1).getDay(); // Update the month display const monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; currentMonthElement.textContent = `${monthNames[month]} ${year}`; // Create empty cells for days before the first day of the month for (let i = 0; i < firstDay; i++) { const emptyDay = document.createElement('div'); emptyDay.classList.add('day', 'empty'); calendarDaysContainer.appendChild(emptyDay); } // Create cells for each day in the month for (let day = 1; day <= daysInMonth; day++) { const dayCell = document.createElement('div'); dayCell.classList.add('day'); const dayNumber = document.createElement('div'); dayNumber.classList.add('day-number'); dayNumber.textContent = day; const dayStatus = document.createElement('div'); dayStatus.classList.add('day-status'); dayCell.appendChild(dayNumber); dayCell.appendChild(dayStatus); // Check if the day is today const isToday = day === currentDay && month === currentMonth && year === currentYear; // Check if the day is in the past const isPast = new Date(year, month, day) < new Date(currentYear, currentMonth, currentDay); if (isToday) { dayCell.classList.add('today'); } if (isPast) { dayCell.classList.add('past'); } else { // Randomly assign availability status to future dates for demo purposes const rand = Math.random(); if (rand < 0.2) { dayCell.classList.add('busy'); } else if (rand < 0.5) { dayCell.classList.add('limited'); } else { dayCell.classList.add('available'); } // Event listener for selecting dates dayCell.addEventListener('click', function() { if (!isPast) { // Remove selected class from all days document.querySelectorAll('.day').forEach(d => d.classList.remove('selected')); // Add selected class to this day dayCell.classList.add('selected'); // Update selected date selectedDate = new Date(year, month, day); // Update reservation date display const options = { weekday: 'long', month: 'long', day: 'numeric' }; reservationDateElement.textContent = selectedDate.toLocaleDateString('en-US', options); // Generate time slots generateTimeSlots(); } }); } calendarDaysContainer.appendChild(dayCell); } } function generateTimeSlots() { timeSlotsContainer.innerHTML = ''; selectedTimeSlot = null; reserveBtn.disabled = true; // Define time slots const timeSlots = ['5:00 PM', '5:30 PM', '6:00 PM', '6:30 PM', '7:00 PM', '7:30 PM', '8:00 PM', '8:30 PM', '9:00 PM', '9:30 PM']; timeSlots.forEach(time => { const timeSlotElement = document.createElement('div'); timeSlotElement.classList.add('time-slot'); timeSlotElement.textContent = time; // Randomly mark some time slots as unavailable for demo purposes const isUnavailable = Math.random() < 0.3; if (isUnavailable) { timeSlotElement.classList.add('unavailable'); } else { timeSlotElement.addEventListener('click', function() { // Remove selected class from all time slots document.querySelectorAll('.time-slot').forEach(t => t.classList.remove('selected')); // Add selected class to this time slot timeSlotElement.classList.add('selected'); // Update selected time slot selectedTimeSlot = time; // Enable reserve button reserveBtn.disabled = false; }); } timeSlotsContainer.appendChild(timeSlotElement); }); } }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Project Management Timeline Calendar</title> <style> :root { --primary: #4A6FA5; --secondary: #5F9EA0; --success: #4CAF50; --warning: #FFC107; --danger: #F44336; --light: #F8F9FA; --dark: #343A40; --gray: #6C757D; --planning: #8E44AD; --research: #3498DB; --development: #16A085; --testing: #F39C12; --deployment: #E74C3C; --marketing: #1ABC9C; } * { box-sizing: border-box; margin: 0; padding: 0; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: #F5F7FA; color: var(--dark); max-width: 700px; height: 700px; margin: 0 auto; overflow: hidden; display: flex; flex-direction: column; } .container { display: flex; flex-direction: column; height: 100%; overflow: hidden; padding: 1rem; background-color: white; border-radius: 10px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05); } header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem; padding-bottom: 0.75rem; border-bottom: 1px solid #eee; } .title { font-size: 1.5rem; font-weight: 600; color: var(--primary); } .controls { display: flex; align-items: center; gap: 0.5rem; } .btn { padding: 0.5rem 1rem; border: none; border-radius: 5px; background-color: var(--light); color: var(--dark); cursor: pointer; font-size: 0.9rem; transition: all 0.2s ease; display: flex; align-items: center; gap: 0.25rem; } .btn:hover { background-color: #e9ecef; } .btn-primary { background-color: var(--primary); color: white; } .btn-primary:hover { background-color: #3d5c88; } .filter-container { display: flex; gap: 0.5rem; margin-bottom: 1rem; flex-wrap: wrap; } .filter-badge { padding: 0.25rem 0.75rem; border-radius: 20px; font-size: 0.8rem; cursor: pointer; display: flex; align-items: center; gap: 0.25rem; border: 1px solid transparent; transition: all 0.2s ease-in-out; } .filter-badge.active { box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); } .filter-badge:hover { transform: translateY(-2px); } .filter-badge[data-type="planning"] { background-color: rgba(142, 68, 173, 0.1); color: var(--planning); border-color: var(--planning); } .filter-badge[data-type="research"] { background-color: rgba(52, 152, 219, 0.1); color: var(--research); border-color: var(--research); } .filter-badge[data-type="development"] { background-color: rgba(22, 160, 133, 0.1); color: var(--development); border-color: var(--development); } .filter-badge[data-type="testing"] { background-color: rgba(243, 156, 18, 0.1); color: var(--testing); border-color: var(--testing); } .filter-badge[data-type="deployment"] { background-color: rgba(231, 76, 60, 0.1); color: var(--deployment); border-color: var(--deployment); } .filter-badge[data-type="marketing"] { background-color: rgba(26, 188, 156, 0.1); color: var(--marketing); border-color: var(--marketing); } .calendar-container { flex-grow: 1; overflow-y: auto; padding-right: 0.5rem; } .calendar-header { display: flex; justify-content: space-between; margin-bottom: 0.5rem; padding-right: 0.5rem; position: sticky; top: 0; background-color: white; z-index: 10; } .month-selector { display: flex; align-items: center; gap: 0.5rem; } .month-name { font-weight: 600; min-width: 100px; text-align: center; } .month-nav { background: none; border: none; cursor: pointer; font-size: 1.2rem; color: var(--gray); transition: color 0.2s ease; width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center; justify-content: center; } .month-nav:hover { color: var(--primary); background-color: var(--light); } .timeline { width: 100%; overflow-x: hidden; } .weeks { display: flex; border-bottom: 1px solid #eee; padding-bottom: 0.5rem; } .week-name, .day-name { flex: 1; text-align: center; font-size: 0.8rem; color: var(--gray); font-weight: 500; } .days { display: flex; margin-top: 0.25rem; } .projects { margin-top: 1rem; } .project { margin-bottom: 1.5rem; overflow: hidden; border-radius: 8px; transition: all 0.3s ease; } .project:hover { box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05); } .project-header { display: flex; justify-content: space-between; align-items: center; padding: 0.75rem 1rem; background-color: var(--light); border-radius: 8px 8px 0 0; cursor: pointer; } .project-title { font-weight: 600; display: flex; align-items: center; gap: 0.5rem; } .project-status { padding: 0.15rem 0.5rem; border-radius: 10px; font-size: 0.7rem; font-weight: 500; } .status-on-track { background-color: rgba(76, 175, 80, 0.1); color: var(--success); } .status-at-risk { background-color: rgba(255, 193, 7, 0.1); color: var(--warning); } .status-delayed { background-color: rgba(244, 67, 54, 0.1); color: var(--danger); } .project-timeline { padding: 1rem; background-color: rgba(245, 247, 250, 0.5); } .milestones { position: relative; padding-left: 1.5rem; margin-top: 0.5rem; } .milestone { display: flex; margin-bottom: 1rem; position: relative; cursor: grab; transition: transform 0.2s ease; } .milestone:hover { transform: translateX(5px); } .milestone:before { content: ''; position: absolute; left: -1.5rem; top: 0.3rem; width: 12px; height: 12px; border-radius: 50%; z-index: 2; } .milestone:after { content: ''; position: absolute; left: -1.44rem; top: 0.75rem; width: 2px; height: calc(100% + 1rem); background-color: #ddd; z-index: 1; } .milestone:last-child:after { display: none; } .milestone[data-type="planning"]:before { background-color: var(--planning); box-shadow: 0 0 0 3px rgba(142, 68, 173, 0.2); } .milestone[data-type="research"]:before { background-color: var(--research); box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.2); } .milestone[data-type="development"]:before { background-color: var(--development); box-shadow: 0 0 0 3px rgba(22, 160, 133, 0.2); } .milestone[data-type="testing"]:before { background-color: var(--testing); box-shadow: 0 0 0 3px rgba(243, 156, 18, 0.2); } .milestone[data-type="deployment"]:before { background-color: var(--deployment); box-shadow: 0 0 0 3px rgba(231, 76, 60, 0.2); } .milestone[data-type="marketing"]:before { background-color: var(--marketing); box-shadow: 0 0 0 3px rgba(26, 188, 156, 0.2); } .milestone-content { flex-grow: 1; } .milestone-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 0.25rem; } .milestone-title { font-weight: 500; font-size: 0.95rem; margin-right: 0.5rem; } .milestone-date { font-size: 0.8rem; color: var(--gray); white-space: nowrap; } .milestone-description { font-size: 0.85rem; color: var(--gray); margin-bottom: 0.5rem; } .milestone-metadata { display: flex; gap: 0.75rem; font-size: 0.8rem; } .meta-item { display: flex; align-items: center; gap: 0.25rem; color: var(--dark); } .milestone-badge { padding: 0.15rem 0.4rem; border-radius: 4px; font-size: 0.75rem; font-weight: 500; } .badge-planning { background-color: rgba(142, 68, 173, 0.1); color: var(--planning); } .badge-research { background-color: rgba(52, 152, 219, 0.1); color: var(--research); } .badge-development { background-color: rgba(22, 160, 133, 0.1); color: var(--development); } .badge-testing { background-color: rgba(243, 156, 18, 0.1); color: var(--testing); } .badge-deployment { background-color: rgba(231, 76, 60, 0.1); color: var(--deployment); } .badge-marketing { background-color: rgba(26, 188, 156, 0.1); color: var(--marketing); } .progress-bar { height: 5px; background-color: #eee; border-radius: 5px; margin-top: 0.5rem; overflow: hidden; } .progress-bar-fill { height: 100%; background-color: var(--primary); border-radius: 5px; transition: width 0.3s ease; } .tooltip { position: absolute; background-color: white; border-radius: 6px; padding: 0.75rem; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); z-index: 100; max-width: 250px; display: none; animation: fadeIn 0.2s ease-in-out; border-left: 3px solid var(--primary); } @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .add-milestone { margin-top: 0.75rem; padding: 0.5rem; background-color: rgba(75, 111, 165, 0.05); border-radius: 5px; text-align: center; cursor: pointer; color: var(--primary); font-weight: 500; transition: all 0.2s ease; display: flex; align-items: center; justify-content: center; gap: 0.25rem; } .add-milestone:hover { background-color: rgba(75, 111, 165, 0.1); } #create-project-btn { position: fixed; bottom: 1.5rem; right: 1.5rem; width: 50px; height: 50px; border-radius: 50%; background-color: var(--primary); color: white; border: none; font-size: 1.5rem; cursor: pointer; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); display: flex; align-items: center; justify-content: center; transition: all 0.3s ease; z-index: 100; } #create-project-btn:hover { background-color: #3d5c88; transform: translateY(-2px); box-shadow: 0 6px 15px rgba(0, 0, 0, 0.15); } .milestone.is-dragging { opacity: 0.7; background-color: rgba(255, 255, 255, 0.8); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); border-radius: 5px; z-index: 100; } .toolbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem; } .search-bar { display: flex; align-items: center; background-color: var(--light); border-radius: 5px; padding: 0.4rem 0.75rem; width: 300px; transition: all 0.2s ease; } .search-bar:focus-within { box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); background-color: white; border: 1px solid #e0e0e0; } .search-icon { color: var(--gray); margin-right: 0.5rem; } .search-input { border: none; background: none; outline: none; flex-grow: 1; font-size: 0.9rem; } .view-options { display: flex; gap: 0.25rem; } .view-btn { padding: 0.4rem 0.6rem; border: none; background-color: var(--light); border-radius: 5px; cursor: pointer; transition: all 0.2s ease; display: flex; align-items: center; justify-content: center; } .view-btn.active { background-color: var(--primary); color: white; } .view-btn:hover:not(.active) { background-color: #e9ecef; } /* Responsive styles */ @media (max-width: 650px) { .filter-container { overflow-x: auto; padding-bottom: 0.5rem; margin-bottom: 0.5rem; scrollbar-width: none; /* Firefox */ } .filter-container::-webkit-scrollbar { display: none; /* Chrome, Safari, Edge */ } .filter-badge { white-space: nowrap; } .toolbar { flex-direction: column; align-items: flex-start; gap: 0.75rem; } .search-bar { width: 100%; } .month-name { min-width: 80px; } } </style> </head> <body> <div class="container"> <header> <div class="title">Project Timeline</div> <div class="controls"> <button class="btn" id="today-btn">Today</button> <button class="btn btn-primary"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4z"/> </svg> New Task </button> </div> </header> <div class="toolbar"> <div class="search-bar"> <span class="search-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z"/> </svg> </span> <input type="text" class="search-input" placeholder="Search tasks or milestones..."> </div> <div class="view-options"> <button class="view-btn active" data-view="timeline"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5zM2 2a1 1 0 0 0-1 1v11a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1H2z"/> <path d="M2.5 4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5H3a.5.5 0 0 1-.5-.5V4z"/> </svg> </button> <button class="view-btn" data-view="gantt"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path d="M0 0h16v16H0V0zm1 1v14h14V1H1z"/> <path d="M2 7h4v2H2V7zm0 4h4v2H2v-2zm0-8h4v2H2V3zm6 0h4v2H8V3zm6 0h-2v2h2V3zM8 7h2v2H8V7zm2 4H8v2h2v-2zm2-4h2v2h-2V7zm2 4h-2v2h2v-2z"/> </svg> </button> <button class="view-btn" data-view="kanban"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path d="M1 2.5A1.5 1.5 0 0 1 2.5 1h3A1.5 1.5 0 0 1 7 2.5v3A1.5 1.5 0 0 1 5.5 7h-3A1.5 1.5 0 0 1 1 5.5v-3zm8 0A1.5 1.5 0 0 1 10.5 1h3A1.5 1.5 0 0 1 15 2.5v3A1.5 1.5 0 0 1 13.5 7h-3A1.5 1.5 0 0 1 9 5.5v-3zm-8 8A1.5 1.5 0 0 1 2.5 9h3A1.5 1.5 0 0 1 7 10.5v3A1.5 1.5 0 0 1 5.5 15h-3A1.5 1.5 0 0 1 1 13.5v-3zm8 0A1.5 1.5 0 0 1 10.5 9h3a1.5 1.5 0 0 1 1.5 1.5v3a1.5 1.5 0 0 1-1.5 1.5h-3A1.5 1.5 0 0 1 9 13.5v-3z"/> </svg> </button> </div> </div> <div class="filter-container"> <div class="filter-badge" data-type="planning"> <span>Planning</span> </div> <div class="filter-badge" data-type="research"> <span>Research</span> </div> <div class="filter-badge" data-type="development"> <span>Development</span> </div> <div class="filter-badge" data-type="testing"> <span>Testing</span> </div> <div class="filter-badge" data-type="deployment"> <span>Deployment</span> </div> <div class="filter-badge" data-type="marketing"> <span>Marketing</span> </div> </div> <div class="calendar-container"> <div class="calendar-header"> <div class="month-selector"> <button class="month-nav prev-month"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path fill-rule="evenodd" d="M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z"/> </svg> </button> <div class="month-name">September 2023</div> <button class="month-nav next-month"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z"/> </svg> </button> </div> </div> <div class="projects"> <div class="project"> <div class="project-header"> <div class="project-title"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path d="M1 2.828c.885-.37 2.154-.769 3.388-.893 1.33-.134 2.458.063 3.112.752v9.746c-.935-.53-2.12-.603-3.213-.493-1.18.12-2.37.461-3.287.811V2.828zm7.5-.141c.654-.689 1.782-.886 3.112-.752 1.234.124 2.503.523 3.388.893v9.923c-.918-.35-2.107-.692-3.287-.81-1.094-.111-2.278-.039-3.213.492V2.687zM8 1.783C7.015.936 5.587.81 4.287.94c-1.514.153-3.042.672-3.994 1.105A.5.5 0 0 0 0 2.5v11a.5.5 0 0 0 .707.455c.882-.4 2.303-.881 3.68-1.02 1.409-.142 2.59.087 3.223.877a.5.5 0 0 0 .78 0c.633-.79 1.814-1.019 3.222-.877 1.378.139 2.8.62 3.681 1.02A.5.5 0 0 0 16 13.5v-11a.5.5 0 0 0-.293-.455c-.952-.433-2.48-.952-3.994-1.105C10.413.809 8.985.936 8 1.783z"/> </svg> Website Redesign </div> <div class="project-status status-on-track">On Track</div> </div> <div class="project-timeline"> <div class="milestones"> <div class="milestone" data-type="planning" draggable="true"> <div class="milestone-content"> <div class="milestone-header"> <div class="milestone-title">Requirements Gathering</div> <div class="milestone-date">Sep 5-10, 2023</div> </div> <div class="milestone-description">Collect stakeholder requirements and analyze user needs</div> <div class="milestone-metadata"> <div class="meta-item"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 16 16"> <path d="M8 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm2-3a2 2 0 1 1-4 0 2 2 0 0 1 4 0zm4 8c0 1-1 1-1 1H3s-1 0-1-1 1-4 6-4 6 3 6 4zm-1-.004c-.001-.246-.154-.986-.832-1.664C11.516 10.68 10.289 10 8 10c-2.29 0-3.516.68-4.168 1.332-.678.678-.83 1.418-.832 1.664h10z"/> </svg> Alex, Emma </div> <div class="meta-item"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 16 16"> <path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/> </svg> High </div> </div> <div class="progress-bar"> <div class="progress-bar-fill" style="width: 100%;"></div> </div> </div> </div> <div class="milestone" data-type="research" draggable="true"> <div class="milestone-content"> <div class="milestone-header"> <div class="milestone-title">Competitor Analysis</div> <div class="milestone-date">Sep 11-15, 2023</div> </div> <div class="milestone-description">Research competitor websites and identify market gaps</div> <div class="milestone-metadata"> <div class="meta-item"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 16 16"> <path d="M8 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm2-3a2 2 0 1 1-4 0 2 2 0 0 1 4 0zm4 8c0 1-1 1-1 1H3s-1 0-1-1 1-4 6-4 6 3 6 4zm-1-.004c-.001-.246-.154-.986-.832-1.664C11.516 10.68 10.289 10 8 10c-2.29 0-3.516.68-4.168 1.332-.678.678-.83 1.418-.832 1.664h10z"/> </svg> Mia </div> <div class="meta-item"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 16 16"> <path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/> </svg> Medium </div> </div> <div class="progress-bar"> <div class="progress-bar-fill" style="width: 75%;"></div> </div> </div> </div> <div class="milestone" data-type="development" draggable="true"> <div class="milestone-content"> <div class="milestone-header"> <div class="milestone-title">Wireframe Creation</div> <div class="milestone-date">Sep 16-20, 2023</div> </div> <div class="milestone-description">Create low-fidelity wireframes for key pages and user flows</div> <div class="milestone-metadata"> <div class="meta-item"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 16 16"> <path d="M8 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm2-3a2 2 0 1 1-4 0 2 2 0 0 1 4 0zm4 8c0 1-1 1-1 1H3s-1 0-1-1 1-4 6-4 6 3 6 4zm-1-.004c-.001-.246-.154-.986-.832-1.664C11.516 10.68 10.289 10 8 10c-2.29 0-3.516.68-4.168 1.332-.678.678-.83 1.418-.832 1.664h10z"/> </svg> Noah, Emma </div> <div class="meta-item"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 16 16"> <path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/> </svg> High </div> </div> <div class="progress-bar"> <div class="progress-bar-fill" style="width: 30%;"></div> </div> </div> </div> <div class="add-milestone"> <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" viewBox="0 0 16 16"> <path d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Social Media Post Scheduler</title> <style> :root { --primary: #5460fe; --secondary: #ff4676; --dark: #1a1b2f; --light: #f7f9ff; --success: #00c875; --warning: #ffcb47; --info: #00b2ff; --instagram: #e1306c; --twitter: #1da1f2; --facebook: #4267b2; --linkedin: #0077b5; --tiktok: #000000; --youtube: #ff0000; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; } body { background: var(--dark); color: var(--light); display: flex; justify-content: center; align-items: center; min-height: 100vh; overflow-x: hidden; width: 100%; } .scheduler-app { width: 700px; height: 700px; background: #252640; border-radius: 20px; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4); display: flex; flex-direction: column; overflow: hidden; position: relative; } .app-header { padding: 20px; display: flex; justify-content: space-between; align-items: center; background: linear-gradient(90deg, #2b2c4e, #1e1f36); border-bottom: 1px solid rgba(255, 255, 255, 0.1); } .logo { display: flex; align-items: center; gap: 10px; } .logo-icon { width: 32px; height: 32px; background: var(--primary); border-radius: 8px; display: flex; justify-content: center; align-items: center; font-weight: bold; font-size: 18px; } .logo-text { font-weight: 700; font-size: 18px; } .logo-text span { color: var(--secondary); } .tools { display: flex; gap: 12px; } .tool-btn { background: rgba(255, 255, 255, 0.1); border: none; color: var(--light); width: 36px; height: 36px; border-radius: 8px; display: flex; justify-content: center; align-items: center; cursor: pointer; transition: all 0.2s ease; } .tool-btn:hover { background: rgba(255, 255, 255, 0.2); transform: translateY(-2px); } .tool-btn.active { background: var(--primary); } .profile { width: 36px; height: 36px; border-radius: 50%; background: linear-gradient(45deg, var(--secondary), var(--primary)); display: flex; justify-content: center; align-items: center; } .tabs { display: flex; gap: 5px; padding: 10px 20px; background: #1e1f36; } .tab { padding: 10px 16px; background: transparent; border: none; color: rgba(255, 255, 255, 0.6); border-radius: 8px; cursor: pointer; font-weight: 500; transition: all 0.3s ease; } .tab:hover { color: rgba(255, 255, 255, 0.9); background: rgba(255, 255, 255, 0.05); } .tab.active { background: var(--primary); color: white; } .content { flex: 1; overflow: auto; padding: 0 20px; display: flex; flex-direction: column; } .month-selector { display: flex; justify-content: space-between; align-items: center; padding: 18px 0; position: sticky; top: 0; background: #252640; z-index: 10; } .month-nav { display: flex; align-items: center; gap: 15px; } .current-month { font-size: 20px; font-weight: 700; } .month-btn { background: rgba(255, 255, 255, 0.1); border: none; color: var(--light); width: 32px; height: 32px; border-radius: 8px; display: flex; justify-content: center; align-items: center; cursor: pointer; transition: all 0.2s ease; } .month-btn:hover { background: rgba(255, 255, 255, 0.2); } .week-days { display: grid; grid-template-columns: repeat(7, 1fr); text-align: center; font-size: 12px; font-weight: 600; text-transform: uppercase; color: rgba(255, 255, 255, 0.5); margin-bottom: 10px; } .day-item { padding: 8px 0; } .calendar { display: grid; grid-template-columns: repeat(7, 1fr); grid-gap: 8px; margin-bottom: 20px; } .date { position: relative; aspect-ratio: 1/1; border-radius: 12px; padding: 8px; background: rgba(255, 255, 255, 0.05); cursor: pointer; transition: transform 0.2s ease, background 0.2s ease; display: flex; flex-direction: column; } .date:hover { background: rgba(255, 255, 255, 0.1); transform: translateY(-2px); } .date.today { border: 2px solid var(--primary); } .date.other-month { opacity: 0.3; } .date.has-posts::after { content: ""; position: absolute; bottom: 8px; right: 8px; width: 8px; height: 8px; border-radius: 50%; background: var(--primary); } .date-num { font-size: 14px; font-weight: 600; } .post-indicators { display: flex; flex-wrap: wrap; gap: 3px; margin-top: 4px; } .post-indicator { width: 8px; height: 8px; border-radius: 50%; } .instagram { background: var(--instagram); } .twitter { background: var(--twitter); } .facebook { background: var(--facebook); } .linkedin { background: var(--linkedin); } .tiktok { background: var(--tiktok); } .youtube { background: var(--youtube); } .posts-container { display: flex; flex-direction: column; } .today-posts { margin-top: 10px; background: rgba(255, 255, 255, 0.05); border-radius: 16px; padding: 16px; margin-bottom: 20px; } .section-title { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; } .section-title h3 { font-size: 16px; font-weight: 600; } .post-card { background: rgba(255, 255, 255, 0.08); border-radius: 10px; padding: 14px; margin-bottom: 10px; display: flex; align-items: center; gap: 14px; cursor: move; transition: transform 0.2s ease, box-shadow 0.2s ease; position: relative; overflow: hidden; } .post-card::before { content: ''; position: absolute; top: 0; left: 0; width: 4px; height: 100%; } .post-card.instagram::before { background: var(--instagram); } .post-card.twitter::before { background: var(--twitter); } .post-card.facebook::before { background: var(--facebook); } .post-card.linkedin::before { background: var(--linkedin); } .post-card.tiktok::before { background: var(--tiktok); } .post-card.youtube::before { background: var(--youtube); } .post-card:hover { transform: translateY(-2px); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); } .post-card.dragging { transform: scale(1.02); box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3); z-index: 10; } .platform-icon { width: 36px; height: 36px; border-radius: 50%; display: flex; justify-content: center; align-items: center; color: white; font-size: 18px; } .instagram-icon { background: var(--instagram); } .twitter-icon { background: var(--twitter); } .facebook-icon { background: var(--facebook); } .linkedin-icon { background: var(--linkedin); } .tiktok-icon { background: var(--tiktok); } .youtube-icon { background: var(--youtube); } .post-info { flex: 1; } .post-title { font-weight: 600; font-size: 14px; } .post-content { font-size: 12px; color: rgba(255, 255, 255, 0.7); margin-top: 4px; } .post-time { font-size: 12px; color: rgba(255, 255, 255, 0.5); margin-top: 6px; } .post-actions { display: flex; gap: 8px; } .post-action { background: transparent; border: none; color: rgba(255, 255, 255, 0.5); width: 28px; height: 28px; border-radius: 6px; display: flex; justify-content: center; align-items: center; cursor: pointer; transition: all 0.2s ease; } .post-action:hover { background: rgba(255, 255, 255, 0.1); color: var(--light); } .upcoming-posts { margin-bottom: 20px; } .add-post { position: fixed; bottom: 30px; right: 30px; width: 56px; height: 56px; border-radius: 50%; background: var(--primary); color: white; border: none; display: flex; justify-content: center; align-items: center; font-size: 28px; cursor: pointer; box-shadow: 0 4px 20px rgba(84, 96, 254, 0.5); transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); z-index: 100; } .add-post:hover { transform: scale(1.1); } .post-preview { position: absolute; bottom: 80px; right: 20px; width: 300px; background: #2e2f4e; border-radius: 16px; padding: 20px; box-shadow: 0 15px 50px rgba(0, 0, 0, 0.3); pointer-events: none; opacity: 0; transform: translateY(20px); transition: opacity 0.3s ease, transform 0.3s ease; z-index: 50; } .post-preview.show { opacity: 1; transform: translateY(0); pointer-events: all; } .preview-header { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; } .preview-platform { font-weight: 600; font-size: 16px; } .preview-content { margin-bottom: 14px; } .preview-image { width: 100%; height: 150px; border-radius: 10px; background-size: cover; background-position: center; margin-bottom: 14px; } .preview-actions { display: flex; justify-content: flex-end; gap: 10px; } .preview-btn { padding: 8px 14px; border-radius: 8px; border: none; font-weight: 500; cursor: pointer; transition: all 0.2s ease; } .preview-btn.cancel { background: rgba(255, 255, 255, 0.1); color: var(--light); } .preview-btn.cancel:hover { background: rgba(255, 255, 255, 0.2); } .preview-btn.schedule { background: var(--primary); color: white; } .preview-btn.schedule:hover { background: #6570ff; } .modal-backdrop { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); display: flex; justify-content: center; align-items: center; z-index: 1000; opacity: 0; pointer-events: none; transition: opacity 0.3s ease; } .modal-backdrop.show { opacity: 1; pointer-events: all; } .modal { width: 500px; background: #2e2f4e; border-radius: 16px; padding: 24px; box-shadow: 0 20px 70px rgba(0, 0, 0, 0.4); transform: translateY(20px); transition: transform 0.3s ease; } .modal-backdrop.show .modal { transform: translateY(0); } .modal-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; } .modal-title { font-size: 20px; font-weight: 700; } .close-modal { background: transparent; border: none; color: rgba(255, 255, 255, 0.5); width: 32px; height: 32px; border-radius: 8px; display: flex; justify-content: center; align-items: center; cursor: pointer; transition: all 0.2s ease; font-size: 20px; } .close-modal:hover { background: rgba(255, 255, 255, 0.1); color: var(--light); } .form-group { margin-bottom: 20px; } .form-label { display: block; margin-bottom: 8px; font-size: 14px; font-weight: 500; color: rgba(255, 255, 255, 0.7); } .form-input, .form-select, .form-textarea { width: 100%; padding: 12px 14px; background: rgba(255, 255, 255, 0.07); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 8px; color: var(--light); font-size: 14px; transition: all 0.2s ease; } .form-input:focus, .form-select:focus, .form-textarea:focus { outline: none; border-color: var(--primary); background: rgba(255, 255, 255, 0.1); } .form-textarea { resize: vertical; min-height: 100px; } .platform-selection { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 10px; } .platform-option { flex: 0 0 calc(33.333% - 7px); background: rgba(255, 255, 255, 0.07); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 8px; padding: 10px; cursor: pointer; transition: all 0.2s ease; display: flex; align-items: center; gap: 8px; } .platform-option:hover { background: rgba(255, 255, 255, 0.1); } .platform-option.selected { background: rgba(84, 96, 254, 0.2); border-color: var(--primary); } .platform-option-icon { width: 24px; height: 24px; border-radius: 50%; display: flex; justify-content: center; align-items: center; color: white; font-size: 14px; } .platform-option-name { font-size: 14px; } .form-actions { display: flex; justify-content: flex-end; gap: 14px; } .form-button { padding: 12px 24px; border-radius: 8px; font-weight: 600; cursor: pointer; transition: all 0.2s ease; } .form-button.cancel { background: rgba(255, 255, 255, 0.1); color: var(--light); border: none; } .form-button.cancel:hover { background: rgba(255, 255, 255, 0.15); } .form-button.schedule { background: var(--primary); color: white; border: none; } .form-button.schedule:hover { background: #6570ff; } /* Animations */ @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.05); } 100% { transform: scale(1); } } .post-card { animation: fadeIn 0.3s ease forwards; animation-delay: calc(var(--i) * 0.1s); opacity: 0; } .date { animation: fadeIn 0.2s ease forwards; animation-delay: calc(var(--i) * 0.03s); opacity: 0; } .add-post { animation: pulse 2s ease-in-out infinite; } /* Loading animation */ .loading { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: #252640; display: flex; justify-content: center; align-items: center; z-index: 2000; opacity: 1; transition: opacity 0.5s ease; } .loading.hide { opacity: 0; pointer-events: none; } .spinner { width: 48px; height: 48px; border: 5px solid rgba(255, 255, 255, 0.1); border-radius: 50%; border-top-color: var(--primary); animation: spin 1s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } /* Toast Notification */ .toast { position: fixed; bottom: 30px; left: 50%; transform: translateX(-50%) translateY(100px); background: #333; color: white; padding: 12px 24px; border-radius: 8px; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); font-size: 14px; opacity: 0; transition: transform 0.3s ease, opacity 0.3s ease; z-index: 2000; } .toast.show { transform: translateX(-50%) translateY(0); opacity: 1; } .toast.success { background: var(--success); } .toast.error { background: var(--secondary); } /* For the smallest screens */ @media (max-width: 480px) { .scheduler-app { width: 100%; height: 100vh; border-radius: 0; } .date { padding: 4px; } .date-num { font-size: 12px; } .post-card { padding: 10px; } .platform-icon { width: 30px; height: 30px; font-size: 16px; } .post-title { font-size: 13px; } .post-content, .post-time { font-size: 11px; } } /* Medium screens */ @media (min-width: 481px) and (max-width: 768px) { .scheduler-app { width: 95%; height: 95vh; } } /* Responsive font sizes */ @media (max-width: 600px) { .current-month { font-size: 18px; } .section-title h3 { font-size: 14px; } } /* Rich tooltip style */ .tooltip { position: absolute; background: #3a3b56; padding: 8px 12px; border-radius: 6px; font-size: 12px; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); pointer-events: none; opacity: 0; transition: opacity 0.2s ease; z-index: 100; white-space: nowrap; } .tooltip.show { opacity: 1; } /* Custom scrollbar */ .content::-webkit-scrollbar { width: 8px; } .content::-webkit-scrollbar-track { background: rgba(255, 255, 255, 0.05); border-radius: 4px; } .content::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.15); border-radius: 4px; } .content::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.25); } </style> </head> <body> <div class="scheduler-app"> <div class="loading"> <div class="spinner"></div> </div> <div class="app-header"> <div class="logo"> <div class="logo-icon">S</div> <div class="logo-text">Social<span>Flow</span></div> </div> <div class="tools"> <button class="tool-btn active" id="calendar-btn" title="Calendar View"> <i>📅</i> </button> <button class="tool-btn" id="analytics-btn" title="Analytics"> <i>📊</i> </button> <button class="tool-btn" id="settings-btn" title="Settings"> <i>⚙️</i> </button> <div class="profile" title="Your Profile"> <i>👤</i> </div> </div> </div> <div class="tabs"> <button class="tab active">Calendar</button> <button class="tab">Schedule</button> <button class="tab">Posts</button> <button class="tab">Campaigns</button> </div> <div class="content"> <div class="month-selector"> <div class="month-nav"> <button class="month-btn" id="prev-month"> <i>◀</i> </button> <span class="current-month">August 2023</span> <button class="month-btn" id="next-month"> <i>▶</i> </button> </div> <div class="schedule-filters"> <button class="tool-btn" id="filter-btn" title="Filter Content"> <i>🔍</i> </button> </div> </div> <div class="week-days"> <div class="day-item">Sun</div> <div class="day-item">Mon</div> <div class="day-item">Tue</div> <div class="day-item">Wed</div> <div class="day-item">Thu</div> <div class="day-item">Fri</div> <div class="day-item">Sat</div> </div> <div class="calendar" id="calendar-grid"> <!-- Dates will be populated by JS --> </div> <div class="posts-container"> <div class="today-posts"> <div class="section-title"> <h3>Today's Schedule</h3> <div class="post-actions"> <button class="post-action" title="Sort Posts"> <i>↕️</i> </button> </div> </div> <div class="post-card instagram" style="--i: 1;"> <div class="platform-icon instagram-icon"> <i>📸</i> </div> <div class="post-info"> <div class="post-title">New product launch teaser</div> <div class="post-content">Get ready for our biggest product drop of the year! #ComingSoon</div> <div class="post-time">10:30 AM • Carousel Post</div> </div> <div class="post-actions"> <button class="post-action preview-post-btn" title="Preview Post"> <i>👁️</i> </button> <button class="post-action" title="Edit Post"> <i>✏️</i> </button> </div> </div> <div class="post-card twitter" style="--i: 2;"> <div class="platform-icon twitter-icon"> <i>🐦</i> </div> <div class="post-info"> <div class="post-title">Industry news commentary</div> <div class="post-content">Our take on today's major tech announcement and what it means for creators.</div> <div class="post-time">12:45 PM • Thread (3)</div> </div> <div class="post-actions"> <button class="post-action preview-post-btn" title="Preview Post"> <i>👁️</i> </button> <button class="post-action" title="Edit Post"> <i>✏️</i> </button> </div> </div> <div class="post-card linkedin" style="--i: 3;"> <div class="platform-icon linkedin-icon"> <i>💼</i> </div> <div class="post-info"> <div class="post-title">Team growth announcement</div> <div class="post-content">Excited to welcome three new specialists to our marketing department!</div> <div class="post-time">3:15 PM • Article</div> </div> <div class="post-actions"> <button class="post-action preview-post-btn" title="Preview Post"> <i>👁️</i> </button> <button class="post-action" title="Edit Post"> <i>✏️</i> </button> </div> </div> </div> <div class="upcoming-posts"> <div class="section-title"> <h3>Upcoming Posts</h3> </div> <div class="post-card facebook" style="--i: 4;"> <div class="platform-icon facebook-icon"> <i>👍</i> </div> <div class="post-info"> <div class="post-title">Community spotlight</div> <div class="post-content">Meet Sarah, a customer who used our platform to grow her business by 200%.</div> <div class="post-time">Tomorrow, 11:00 AM • Video Post</div> </div> <div class="post-actions"> <button class="post-action" title="Edit Post"> <i>✏️</i> </button> </div> </div> <div class="post-card youtube" style="--i: 5;"> <div class="platform-icon youtube-icon"> <i>▶️</i> </div> <div class="post-info"> <div class="post-title">Tutorial: Advanced editing techniques</div> <div class="post-content">Learn the pro editing workflows that will cut your production time in half.</div> <div class="post-time">Aug 25, 2:00 PM • 15-min Video</div> </div> <div class="post-actions"> <button class="post-action" title="Edit Post"> <i>✏️</i> </button> </div> </div> <div class="post-card tiktok" style="--i: 6;"> <div class="platform-icon tiktok-icon"> <i>🎵</i> </div> <div class="post-info"> <div class="post-title">Product hack viral trend</div> <div class="post-content">3 unexpected ways to use our product that will blow your mind! #lifehack</div> <div class="post-time">Aug 26, 6:30 PM • 30s Video</div> </div> <div class="post-actions"> <button class="post-action" title="Edit Post"> <i>✏️</i> </button> </div> </div> </div> </div> </div> <button class="add-post" id="add-post-btn" title="Create New Post">+</button> <div class="post-preview" id="post-preview"> <div class="preview-header"> <div class="platform-icon instagram-icon"> <i>📸</i> </div> <div class="preview-platform">Instagram Post</div> </div> <div class="preview-content"> Get ready for our biggest product drop of the year! After months of development, we're excited to share what we've been working on. Stay tuned for the full reveal next week. #ComingSoon #ProductLaunch </div> <div class="preview-image" style="background-image: url('https://via.placeholder.com/400x300/FF4676/FFFFFF?text=Product+Teaser');"></div> <div class="preview-actions"> <button class="preview-btn cancel" id="close-preview">Close</button> <button class="preview-btn schedule">Schedule</button> </div> </div> </div> <div class="modal-backdrop" id="new-post-modal"> <div class="modal"> <div class="modal-header"> <h3 class="modal-title">Create New Post</h3> <button class="close-modal" id="close-modal">×</button> </div> <div class="form-group"> <label class="form-label">Select Platforms</label> <div class="platform-selection"> <div class="platform-option" data-platform="instagram"> <div class="platform-option-icon instagram-icon"> <i>📸</i> </div> <div class="platform-option-name">Instagram</div> </div> <div class="platform-option" data-platform="twitter"> <div class="platform-option-icon twitter-icon"> <i>🐦</i> </div> <div class="platform-option-name">Twitter</div> </div> <div class="platform-option" data-platform="facebook"> <div class="platform-option-icon facebook-icon"> <i>👍</i> </div> <div class="platform-option-name">Facebook</div> </div> <div class="platform-option" data-platform="linkedin"> <div class="platform-option-icon linkedin-icon"> <i>💼</i> </div> <div class="platform-option-name">LinkedIn</div> </div> <div class="platform-option" data-platform="tiktok"> <div class="platform-option-icon tiktok-icon"> <i>🎵</i> </div> <div class="platform-option-name">TikTok</div> </div> <div class="platform-option" data-platform="youtube"> <div class="platform-option-icon youtube-icon"> <i>▶️</i> </div> <div class="platform-option-name">YouTube</div> </div> </div> </div> <div class="form-group"> <label class="form-label">Post Title</label> <input type="text" class="form-input" placeholder="Enter a title for your post"> </div> <div class="form-group"> <label class="form-label">Content</label> <textarea class="form-textarea" placeholder="Type your post content here..."></textarea> </div> <div class="form-group"> <label class="form-label">Schedule Date & Time</label> <input type="text" class="form-input" placeholder="Aug 24, 2023 • 10:30 AM"> </div> <div class="form-group"> <label class="form-label">Attachments</label> <button class="form-button cancel" style="width: 100%; margin-top: 5px;"> Upload Media </button> </div> <div class="form-actions"> <button class="form-button cancel" id="cancel-post">Cancel</button> <button class="form-button schedule" id="schedule-post">Schedule Post</button> </div> </div> </div> <div class="tooltip" id="tooltip"></div> <div class="toast" id="toast"></div> <script> document.addEventListener('DOMContentLoaded', function() { // Simulating loading time setTimeout(() => { document.querySelector('.loading').classList.add('hide'); }, 1000); // Initialize Calendar const calendarGrid = document.getElementById('calendar-grid'); const currentMonthEl = document.querySelector('.current-month'); // Current date for "today" highlighting
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Financial Deadline Calendar</title> <style> :root { --primary-dark: #1a2a3a; --primary: #2c3e50; --primary-light: #34495e; --secondary: #3498db; --secondary-light: #5dade2; --neutral-dark: #2c3e50; --neutral: #95a5a6; --neutral-light: #ecf0f1; --alert: #e74c3c; --warning: #f39c12; --success: #2ecc71; --font-primary: 'Helvetica Neue', Arial, sans-serif; --border-radius: 8px; --shadow: 0 4px 6px rgba(0, 0, 0, 0.1); --transition: all 0.3s ease; } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: var(--font-primary); background-color: var(--neutral-light); color: var(--primary-dark); height: 700px; width: 700px; max-width: 100%; margin: 0 auto; padding: 0; overflow: hidden; display: flex; flex-direction: column; } .app-container { display: flex; flex-direction: column; height: 100%; width: 100%; max-width: 700px; background: linear-gradient(135deg, #f5f7fa 0%, #eef2f7 100%); border-radius: var(--border-radius); box-shadow: var(--shadow); overflow: hidden; } .header { background: linear-gradient(to right, var(--primary-dark), var(--primary-light)); color: white; padding: 1rem; display: flex; justify-content: space-between; align-items: center; border-bottom: 3px solid var(--secondary); } .header h1 { font-size: 1.5rem; font-weight: 600; margin: 0; } .user-section { display: flex; align-items: center; gap: 10px; } .user-avatar { width: 32px; height: 32px; border-radius: 50%; background-color: var(--secondary); display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); } .lock-icon { cursor: pointer; transition: var(--transition); } .lock-icon:hover { color: var(--secondary-light); } .main-content { display: flex; flex: 1; height: calc(100% - 60px); } .sidebar { width: 200px; background-color: var(--primary); color: white; padding: 1rem; overflow-y: auto; transition: var(--transition); } .sidebar.collapsed { width: 60px; } .month-selector { margin-bottom: 1.5rem; } .month-selector h3 { margin-bottom: 0.5rem; font-size: 0.9rem; text-transform: uppercase; color: var(--neutral); } .month-selector select { width: 100%; padding: 8px; background-color: var(--primary-light); color: white; border: 1px solid var(--secondary); border-radius: var(--border-radius); cursor: pointer; } .account-section h3 { margin-bottom: 0.5rem; font-size: 0.9rem; text-transform: uppercase; color: var(--neutral); } .account-item { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; padding: 8px; border-radius: var(--border-radius); transition: var(--transition); cursor: pointer; } .account-item:hover { background-color: var(--primary-light); } .account-item.active { background-color: var(--secondary); } .account-color { width: 12px; height: 12px; border-radius: 50%; } .calendar-container { flex: 1; padding: 1rem; overflow-y: auto; display: flex; flex-direction: column; } .calendar-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem; } .current-month { font-size: 1.5rem; font-weight: 600; color: var(--primary); } .calendar-nav { display: flex; gap: 10px; } .nav-btn { background-color: var(--primary); color: white; border: none; border-radius: var(--border-radius); width: 32px; height: 32px; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: var(--transition); } .nav-btn:hover { background-color: var(--secondary); } .weekdays { display: grid; grid-template-columns: repeat(7, 1fr); text-align: center; font-weight: bold; margin-bottom: 8px; color: var(--primary); } .calendar-grid { display: grid; grid-template-columns: repeat(7, 1fr); grid-template-rows: repeat(6, 1fr); gap: 6px; flex: 1; min-height: 350px; } .day { border: 1px solid #ddd; border-radius: var(--border-radius); padding: 5px; min-height: 80px; background-color: white; transition: var(--transition); display: flex; flex-direction: column; position: relative; overflow: hidden; } .day:hover { box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); } .day.inactive { background-color: #f9f9f9; color: var(--neutral); } .day.today { border: 2px solid var(--secondary); } .day-number { font-weight: bold; margin-bottom: 4px; text-align: right; } .bill-item { font-size: 0.8rem; padding: 3px 6px; margin-bottom: 3px; border-radius: var(--border-radius); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer; transition: var(--transition); } .bill-item:hover { filter: brightness(1.1); } .bill-item.paid { text-decoration: line-through; opacity: 0.7; } .bill-item.upcoming { background-color: var(--secondary-light); color: white; } .bill-item.due-today { background-color: var(--warning); color: white; font-weight: bold; } .bill-item.overdue { background-color: var(--alert); color: white; font-weight: bold; } .add-bill { position: fixed; bottom: 2rem; right: 2rem; width: 50px; height: 50px; border-radius: 50%; background-color: var(--secondary); color: white; border: none; font-size: 1.5rem; cursor: pointer; display: flex; align-items: center; justify-content: center; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); transition: var(--transition); z-index: 100; } .add-bill:hover { background-color: var(--primary); transform: translateY(-2px); } .modal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); display: flex; align-items: center; justify-content: center; z-index: 1000; opacity: 0; visibility: hidden; transition: var(--transition); } .modal.active { opacity: 1; visibility: visible; } .modal-content { background-color: white; padding: 2rem; border-radius: var(--border-radius); width: 90%; max-width: 500px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2); transform: translateY(20px); transition: var(--transition); } .modal.active .modal-content { transform: translateY(0); } .modal-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem; } .modal-header h2 { color: var(--primary); margin: 0; font-size: 1.5rem; } .close-modal { background: none; border: none; font-size: 1.5rem; cursor: pointer; color: var(--neutral); transition: var(--transition); } .close-modal:hover { color: var(--alert); } .form-group { margin-bottom: 1rem; } .form-group label { display: block; margin-bottom: 0.5rem; font-weight: 600; color: var(--primary); } .form-group input, .form-group select { width: 100%; padding: 0.75rem; border: 1px solid #ddd; border-radius: var(--border-radius); font-size: 1rem; } .form-actions { display: flex; justify-content: flex-end; gap: 1rem; margin-top: 1.5rem; } .btn { padding: 0.75rem 1.5rem; border: none; border-radius: var(--border-radius); font-weight: 600; cursor: pointer; transition: var(--transition); } .btn-cancel { background-color: var(--neutral-light); color: var(--primary); } .btn-cancel:hover { background-color: var(--neutral); color: white; } .btn-save { background-color: var(--secondary); color: white; } .btn-save:hover { background-color: var(--primary); } .detail-modal .modal-content { position: relative; } .bill-detail-header { display: flex; align-items: center; margin-bottom: 1.5rem; padding-bottom: 1rem; border-bottom: 1px solid #eee; } .bill-status { display: inline-block; padding: 0.3rem 0.75rem; border-radius: 20px; font-size: 0.8rem; font-weight: 600; margin-left: auto; } .bill-status.paid { background-color: var(--success); color: white; } .bill-status.upcoming { background-color: var(--secondary); color: white; } .bill-status.due-today { background-color: var(--warning); color: white; } .bill-status.overdue { background-color: var(--alert); color: white; } .bill-details { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-bottom: 1.5rem; } .detail-item { margin-bottom: 0.5rem; } .detail-label { font-size: 0.8rem; color: var(--neutral); margin-bottom: 0.25rem; } .detail-value { font-weight: 600; color: var(--primary-dark); } .detail-actions { display: flex; justify-content: space-between; margin-top: 1.5rem; padding-top: 1rem; border-top: 1px solid #eee; } .toggle-container { position: relative; display: inline-block; width: 60px; height: 34px; } .toggle-container input { opacity: 0; width: 0; height: 0; } .toggle-slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; transition: .4s; border-radius: 34px; } .toggle-slider:before { position: absolute; content: ""; height: 26px; width: 26px; left: 4px; bottom: 4px; background-color: white; transition: .4s; border-radius: 50%; } input:checked + .toggle-slider { background-color: var(--success); } input:checked + .toggle-slider:before { transform: translateX(26px); } .loader { width: 100%; height: 4px; position: absolute; top: 0; left: 0; background-color: var(--neutral-light); overflow: hidden; visibility: hidden; } .loader::after { content: ''; display: block; width: 30%; height: 100%; background-color: var(--secondary); animation: loading 1.5s infinite; } @keyframes loading { 0% { transform: translateX(-100%); } 100% { transform: translateX(400%); } } .secure-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(25, 42, 66, 0.95); z-index: 2000; display: flex; flex-direction: column; align-items: center; justify-content: center; color: white; padding: 2rem; text-align: center; } .secure-overlay h2 { margin-bottom: 1rem; font-size: 1.5rem; } .secure-overlay p { margin-bottom: 2rem; font-size: 1rem; max-width: 400px; } .secure-overlay .pin-container { display: flex; gap: 10px; margin-bottom: 1.5rem; } .pin-digit { width: 40px; height: 40px; border-radius: var(--border-radius); border: 2px solid var(--secondary); background-color: var(--primary-dark); color: white; font-size: 1.2rem; text-align: center; } .pin-entry { display: flex; margin-bottom: 1.5rem; } .pin-dot { width: 15px; height: 15px; border-radius: 50%; background-color: var(--neutral); margin: 0 5px; transition: var(--transition); } .pin-dot.filled { background-color: var(--secondary); } .numpad { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; max-width: 240px; } .numpad-btn { width: 60px; height: 60px; border-radius: 50%; border: none; background-color: var(--primary); color: white; font-size: 1.2rem; cursor: pointer; transition: var(--transition); } .numpad-btn:hover { background-color: var(--secondary); } .numpad-btn.delete { background-color: var(--alert); } .secure-message { margin-top: 1rem; color: var(--alert); height: 20px; } @media (max-width: 600px) { .sidebar { width: 60px; } .sidebar.expanded { width: 200px; position: absolute; height: 100%; z-index: 50; } .calendar-grid { gap: 4px; } .day { min-height: 60px; padding: 3px; } .bill-item { font-size: 0.7rem; padding: 2px 4px; } .modal-content { padding: 1rem; } .numpad-btn { width: 50px; height: 50px; } } /* Animation & Interaction */ .pulse { animation: pulse 2s infinite; } @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(52, 152, 219, 0.4); } 70% { box-shadow: 0 0 0 10px rgba(52, 152, 219, 0); } 100% { box-shadow: 0 0 0 0 rgba(52, 152, 219, 0); } } .day-highlight { position: absolute; top: 0; left: 0; width: 100%; height: 5px; background-color: transparent; } .day[data-bill-count="1"] .day-highlight { background-color: var(--secondary-light); } .day[data-bill-count="2"] .day-highlight { background-color: var(--warning); } .day[data-bill-count="3"] .day-highlight, .day[data-bill-count="4"] .day-highlight, .day[data-bill-count="5"] .day-highlight { background-color: var(--alert); } .shimmer { position: relative; overflow: hidden; } .shimmer::after { content: ''; position: absolute; top: 0; left: -100%; width: 50%; height: 100%; background: linear-gradient( 90deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.3) 50%, rgba(255, 255, 255, 0) 100% ); animation: shimmer 2s infinite; } @keyframes shimmer { to { left: 100%; } } /* Tooltip */ [data-tooltip] { position: relative; } [data-tooltip]::after { content: attr(data-tooltip); position: absolute; bottom: 125%; left: 50%; transform: translateX(-50%); padding: 5px 10px; background-color: var(--primary-dark); color: white; border-radius: var(--border-radius); font-size: 0.8rem; white-space: nowrap; opacity: 0; visibility: hidden; transition: var(--transition); z-index: 100; } [data-tooltip]:hover::after { opacity: 1; visibility: visible; } </style> </head> <body> <div class="app-container"> <div class="header"> <h1>Financial Deadline Calendar</h1> <div class="user-section"> <div class="user-avatar">JD</div> <div class="lock-icon" id="lock-app"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect> <path d="M7 11V7a5 5 0 0 1 10 0v4"></path> </svg> </div> </div> </div> <div class="main-content"> <div class="sidebar"> <div class="month-selector"> <h3>Month</h3> <select id="month-select"> <option value="0">January</option> <option value="1">February</option> <option value="2">March</option> <option value="3">April</option> <option value="4">May</option> <option value="5">June</option> <option value="6">July</option> <option value="7">August</option> <option value="8">September</option> <option value="9">October</option> <option value="10">November</option> <option value="11">December</option> </select> </div> <div class="account-section"> <h3>Accounts</h3> <div class="account-item active"> <div class="account-color" style="background-color: #3498db;"></div> <span>Bank of America</span> </div> <div class="account-item"> <div class="account-color" style="background-color: #e74c3c;"></div> <span>Chase Credit Card</span> </div> <div class="account-item"> <div class="account-color" style="background-color: #2ecc71;"></div> <span>Mortgage</span> </div> <div class="account-item"> <div class="account-color" style="background-color: #f39c12;"></div> <span>Utilities</span> </div> <div class="account-item"> <div class="account-color" style="background-color: #9b59b6;"></div> <span>Subscriptions</span> </div> </div> </div> <div class="calendar-container"> <div class="calendar-header"> <div class="current-month">November 2023</div> <div class="calendar-nav"> <button class="nav-btn" id="prev-month"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="15 18 9 12 15 6"></polyline> </svg> </button> <button class="nav-btn" id="next-month"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="9 18 15 12 9 6"></polyline> </svg> </button> </div> </div> <div class="weekdays"> <div>Sun</div> <div>Mon</div> <div>Tue</div> <div>Wed</div> <div>Thu</div> <div>Fri</div> <div>Sat</div> </div> <div class="calendar-grid" id="calendar-grid"> <!-- Calendar will be filled by JavaScript --> </div> </div> </div> </div> <button class="add-bill pulse" id="add-bill-btn"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <line x1="12" y1="5" x2="12" y2="19"></line> <line x1="5" y1="12" x2="19" y2="12"></line> </svg> </button> <!-- Add Bill Modal --> <div class="modal" id="add-bill-modal"> <div class="modal-content"> <div class="loader" id="form-loader"></div> <div class="modal-header"> <h2>Add New Payment</h2> <button class="close-modal" id="close-add-modal">×</button> </div> <form id="add-bill-form"> <div class="form-group"> <label for="bill-name">Payment Name</label> <input type="text" id="bill-name" placeholder="e.g. Mortgage Payment" required> </div> <div class="form-group"> <label for="bill-amount">Amount</label> <input type="number" id="bill-amount" placeholder="0.00" min="0.01" step="0.01" required> </div> <div class="form-group"> <label for="bill-date">Due Date</label> <input type="date" id="bill-date" required> </div> <div class="form-group"> <label for="bill-account">Account</label> <select id="bill-account" required> <option value="bank">Bank of America</option> <option value="credit">Chase Credit Card</option> <option value="mortgage">Mortgage</option> <option value="utilities">Utilities</option> <option value="subscriptions">Subscriptions</option> </select> </div> <div class="form-group"> <label for="bill-notes">Notes (Optional)</label> <input type="text" id="bill-notes" placeholder="Additional details about this payment"> </div> <div class="form-actions"> <button type="button" class="btn btn-cancel" id="cancel-add">Cancel</button> <button type="submit" class="btn btn-save">Save Payment</button> </div> </form> </div> </div> <!-- Bill Detail Modal --> <div class="modal detail-modal" id="bill-detail-modal"> <div class="modal-content"> <div class="loader" id="detail-loader"></div> <div class="modal-header"> <h2 id="detail-title">Payment Details</h2> <button class="close-modal" id="close-detail-modal">×</button> </div> <div class="bill-detail-header"> <h3 id="detail-name">Mortgage Payment</h3> <span class="bill-status" id="detail-status">Due Today</span> </div> <div class="bill-details"> <div class="detail-item"> <div class="detail-label">Amount</div> <div class="detail-value" id="detail-amount">$1,450.00</div> </div> <div class="detail-item"> <div class="detail-label">Due Date</div> <div class="detail-value" id="detail-date">November 15, 2023</div> </div> <div class="detail-item"> <div class="detail-label">Account</div> <div class="detail-value" id="detail-account">Bank of America</div> </div> <div class="detail-item"> <div class="detail-label">Payment Status</div> <div class="detail-value" id="detail-payment-status">Not Paid</div> </div> </div> <div class="detail-item" id="notes-section"> <div class="detail-label">Notes</div> <div class="detail-value" id="detail-notes">Monthly mortgage payment including principal, interest, taxes, and insurance.</div> </div> <div class="detail-actions"> <div class="toggle-section"> <label class="toggle-container"> <input type="checkbox" id="paid-toggle"> <span class="toggle-slider"></span> </label> <span id="toggle-label">Mark as Paid</span> </div> <button class="btn btn-save" id="edit-bill">Edit Payment</button> </div> </div> </div> <!-- Security PIN Overlay --> <div class="secure-overlay" id="secure-overlay" style="display: none;"> <h2>Secure Financial Data</h2> <p>Enter your 4-digit PIN to access your financial calendar</p> <div class="pin-entry"> <div class="pin-dot" id="pin-dot-1"></div> <div class="pin-dot" id="pin-dot-2"></div> <div class="pin-dot" id="pin-dot-3"></div> <div class="pin-dot" id="pin-dot-4"></div> </div> <div class="numpad"> <button class="numpad-btn" data-value="1">1</button> <button class="numpad-btn" data-value="2">2</button> <button class="numpad-btn" data-value="3">3</button> <button class="numpad-btn" data-value="4">4</button> <button class="numpad-btn" data-value="5">5</button> <button class="numpad-btn" data-value="6">6</button> <button class="numpad-btn" data-value="7">7</button> <button class="numpad-btn" data-value="8">8</button> <button class="numpad-btn" data-value="9">9</button> <button class="numpad-btn" data-value="0">0</button> <button class="numpad-btn delete" id="pin-delete"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M21 4H8l-7 8 7 8h13a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2z"></path> <line x1="18" y1="9" x2="12" y2="15"></line> <line x1="12" y1="9" x2="18" y2="15"></line> </svg> </button> </div> <div class="secure-message" id="pin-message"></div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Sample financial data const financialData = [ { id: 1, name: "Mortgage Payment", amount: 1450.00, dueDate: "2023-11-15", account: "mortgage", accountName: "Mortgage", color: "#2ecc71", paid: false, notes: "Monthly mortgage payment including principal, interest, taxes, and insurance." }, { id: 2, name: "Credit Card Bill", amount: 385.75, dueDate: "2023-11-23", account: "credit", accountName: "Chase Credit Card", color: "#e74c3c", paid: false, notes: "Monthly credit card payment. Includes recent holiday shopping." }, { id: 3, name: "Electric Bill", amount: 87.32, dueDate: "2023-11-18", account: "utilities", accountName: "Utilities", color: "#f39c12", paid: false, notes: "Monthly electric utility bill." }, { id: 4, name: "Car Insurance", amount: 128.45, dueDate: "2023-11-05", account: "bank", accountName: "Bank of America", color: "#3498db", paid: true, notes: "Quarterly car insurance premium." }, { id: 5, name: "Internet Service", amount: 65.99, dueDate: "2023-11-10", account: "utilities", accountName: "Utilities", color: "#f39c12", paid: false, notes: "Monthly internet service bill." }, { id: 6, name: "Netflix Subscription", amount: 14.99, dueDate: "2023-11-14", account: "subscriptions", accountName: "Subscriptions", color: "#9b59b6", paid: false, notes: "Monthly streaming service subscription." }, { id: 7, name: "Phone Bill", amount: 92.50, dueDate: "2023-11-21", account: "utilities", accountName: "Utilities", color: "#f39c12", paid: false, notes: "Monthly mobile phone bill for two lines." }, { id: 8, name: "Water Bill", amount: 43.27, dueDate: "2023-11-25", account: "utilities", accountName: "Utilities", color: "#f39c12", paid: false, notes: "Bi-monthly water and sewer bill." }, { id: 9, name: "Gym Membership", amount: 29.99, dueDate: "2023-11-01", account: "subscriptions", accountName: "Subscriptions", color: "#9b59b6", paid: true, notes: "Monthly gym membership fee." }, { id: 10, name: "Student Loan", amount: 220.00, dueDate: "2023-11-12", account: "bank", accountName: "Bank of America", color: "#3498db", paid: false, notes: "Monthly student loan payment." } ]; // Set current date const currentDate = new Date(); const currentMonth = currentDate.getMonth(); const currentYear = currentDate.getFullYear(); // DOM Elements const calendarGrid = document.getElementById('calendar-grid'); const monthDisplay = document.querySelector('.current-month'); const monthSelect = document.getElementById('month-select'); const prevMonthBtn = document.getElementById('prev-month'); const nextMonthBtn = document.getElementById('next-month'); const addBillBtn = document.getElementById('add-bill-btn'); const addBillModal = document.getElementById('add-bill-modal'); const billDetailModal = document.getElementById('bill-detail-modal'); const closeAddModalBtn = document.getElementById('close-add-modal'); const closeDetailModalBtn = document.getElementById('close-detail-modal'); const cancelAddBtn = document.getElementById('cancel-add'); const addBillForm = document.getElementById('add-bill-form'); const lockAppBtn = document.getElementById('lock-app'); const secureOverlay = document.getElementById('secure-overlay'); const numpadButtons = document.querySelectorAll('.numpad-btn'); const