<html lang="en" style="--rem: 16;"><head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>FAE Global Summit Agenda - Dark Mode (Editable, Exportable)</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js" integrity="sha512-BNaRQnYJYiPSqHHDb58B0yaPfCu+Wgds8Gp/gU33kqBtgNS4tSPHuGibyoeqMV/TJlSKda6FXzoEyYGjTe+vXA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://unpkg.com/jspdf@2.5.1/dist/jspdf.umd.min.js" defer=""></script>
<script>
// Test log to see if libraries are potentially loaded
console.log("External libraries (Tailwind, Fonts, html2canvas, jsPDF) requested.");
// Initial checks might still run before deferred script executes
if (window.jspdf) {
console.log("Initial Check: jsPDF library seems to be loaded (window.jspdf exists).");
} else {
console.warn("Initial Check: jsPDF library (window.jspdf) not found immediately after script tag (expected if deferred).");
}
if (window.html2canvas) {
console.log("Initial Check: html2canvas library seems to be loaded.");
} else {
console.warn("Initial Check: html2canvas library not found immediately after script tag.");
}
</script>
<style>
/* Use Inter font */
body {
font-family: 'Inter', sans-serif;
background-color: #111827; /* Dark gray background (Tailwind gray-900) */
color: #d1d5db; /* Default light gray text (Tailwind gray-300) */
}
/* Style for time slots */
.time-slot {
position: relative; /* Needed for absolute positioning of delete button */
display: flex;
align-items: flex-start;
padding-top: 0.75rem;
padding-bottom: 0.75rem;
border-bottom: 1px solid #374151; /* Darker border (Tailwind gray-700) */
}
.time-slot:last-child {
/* border-bottom: none; */ /* Keep border for consistency when adding */
}
.time {
flex-shrink: 0;
width: 95px;
font-weight: 500;
color: #9ca3af; /* Lighter gray text (Tailwind gray-400) */
margin-right: 1.25rem;
padding: 0.25rem 0.1rem; /* Padding for edit focus */
cursor: text;
border-radius: 0.25rem;
}
.time:focus {
outline: 1px solid #4b5563; /* Gray-600 outline */
background-color: #374151; /* Gray-700 background */
color: #f3f4f6; /* Gray-100 text */
}
.activity {
flex-grow: 1;
color: #e5e7eb; /* Lighter text (Tailwind gray-200) */
padding: 0.25rem 0.1rem; /* Padding for edit focus */
cursor: text;
border-radius: 0.25rem;
margin-right: 20px; /* Space for delete button */
}
.activity:focus {
outline: 1px solid #4b5563; /* Gray-600 outline */
background-color: #374151; /* Gray-700 background */
color: #f9fafb; /* Gray-50 text */
}
.activity strong {
font-weight: 600;
color: #ffffff; /* White for strong elements */
}
.activity em {
color: #9ca3af; /* Lighter gray for secondary info (Tailwind gray-400) */
font-style: normal;
display: block;
font-size: 0.875rem; /* text-sm */
margin-top: 0.125rem;
}
/* Header styling */
.day-header {
background-color: #1f2937; /* Darker header (Tailwind gray-800) */
padding: 1rem 1.25rem;
font-weight: 600;
font-size: 1.125rem;
color: #ffffff; /* White header text */
border-bottom: 1px solid #374151; /* Gray-700 border */
border-top-left-radius: 0.5rem;
border-top-right-radius: 0.5rem;
}
.day-header .day-theme {
font-weight: 400;
color: #9ca3af; /* Gray-400 color */
font-size: 0.9rem;
margin-left: 0.5rem;
}
/* Card styling */
.day-card {
border: 1px solid #374151; /* Gray-700 border */
border-radius: 0.5rem;
background-color: #1f2937; /* Dark card background (Tailwind gray-800) */
overflow: hidden; /* Keep overflow hidden */
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); /* Adjusted shadow for dark */
display: flex; /* Use flexbox for card layout */
flex-direction: column; /* Stack header, content, button vertically */
}
.day-content {
padding: 0 1.25rem;
flex-grow: 1; /* Allow content to grow */
}
/* Make elements editable on focus (styles adjusted for dark mode) */
[contenteditable="true"]:focus {
outline: 1px solid #4b5563;
background-color: #374151;
color: #f9fafb; /* Ensure text is light on focus background */
}
/* Button Styles */
.export-button {
background-color: #374151; /* gray-700 */
color: #f3f4f6; /* gray-100 */
padding: 0.6rem 1.2rem;
border-radius: 0.375rem; /* rounded-md */
font-weight: 500;
margin: 0 0.5rem;
cursor: pointer;
transition: background-color 0.2s;
border: 1px solid #4b5563; /* gray-600 */
}
.export-button:hover {
background-color: #4b5563; /* gray-600 */
}
.export-button:active {
background-color: #525a67;
}
.add-item-button {
display: block; /* Make it a block element */
width: calc(100% - 2.5rem); /* Full width minus padding */
background-color: #374151; /* gray-700 */
color: #9ca3af; /* gray-400 */
padding: 0.5rem 1rem;
border-radius: 0.375rem; /* rounded-md */
font-weight: 500;
text-align: center;
cursor: pointer;
transition: background-color 0.2s, color 0.2s;
border: 1px dashed #4b5563; /* gray-600 */
margin: 1rem 1.25rem; /* Match content padding */
}
.add-item-button:hover {
background-color: #4b5563; /* gray-600 */
color: #f3f4f6; /* gray-100 */
}
.delete-item-button {
position: absolute;
right: 0.75rem; /* Adjust position */
top: 50%;
transform: translateY(-50%);
width: 18px;
height: 18px;
background-color: #4b5563; /* gray-600 */
color: #1f2937; /* gray-800 */
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
font-weight: bold;
line-height: 1;
cursor: pointer;
opacity: 0; /* Hidden by default */
transition: opacity 0.2s, background-color 0.2s;
border: 1px solid #6b7280; /* gray-500 */
}
.time-slot:hover .delete-item-button {
opacity: 1; /* Show on hover */
}
.delete-item-button:hover {
background-color: #ef4444; /* red-500 */
color: white;
border-color: #dc2626; /* red-600 */
}
/* Style for error messages */
.error-message {
color: #f87171; /* Tailwind red-400 */
font-size: 0.875rem;
margin-top: 0.5rem;
}
.status-message { /* General class for status messages */
font-size: 0.875rem;
margin-top: 0.5rem;
}
/* Drag and Drop Styles */
.time-slot.dragging {
opacity: 0.5;
background: #374151; /* Slightly different background when dragging */
}
.day-content.drag-over {
/* Add a subtle indicator that it's a drop target */
background-color: rgba(75, 85, 99, 0.3); /* gray-600 with opacity */
border: 1px dashed #6b7280; /* gray-500 */
margin: -1px; /* Adjust margin to keep layout stable */
}
.drag-placeholder {
height: 40px; /* Example height, adjust as needed */
background-color: rgba(96, 165, 250, 0.3); /* blue-400 with opacity */
border: 1px dashed #60a5fa; /* blue-400 */
margin: 0.5rem 0;
border-radius: 0.25rem;
}
</style>
<style>*, ::before, ::after{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246 / 0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246 / 0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/* ! tailwindcss v3.4.16 | MIT License | https://tailwindcss.com */*,::after,::before{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}::after,::before{--tw-content:''}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;font-family:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.mb-10{margin-bottom:2.5rem}.mb-4{margin-bottom:1rem}.mb-8{margin-bottom:2rem}.mt-10{margin-top:2.5rem}.grid{display:grid}.grid-cols-1{grid-template-columns:repeat(1, minmax(0, 1fr))}.gap-8{gap:2rem}.p-4{padding:1rem}.text-center{text-align:center}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:0.875rem;line-height:1.25rem}.font-bold{font-weight:700}.text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}@media (min-width: 768px){.md\:grid-cols-2{grid-template-columns:repeat(2, minmax(0, 1fr))}.md\:p-8{padding:2rem}.md\:text-4xl{font-size:2.25rem;line-height:2.5rem}}@media (min-width: 1024px){.lg\:grid-cols-3{grid-template-columns:repeat(3, minmax(0, 1fr))}}</style></head><body class="p-4 md:p-8" data-new-gr-c-s-check-loaded="14.1229.0" data-gr-ext-installed="" data-new-gr-c-s-loaded="14.1229.0">
<h1 class="text-3xl md:text-4xl font-bold text-center text-white mb-4">FAE Global Summit 2025</h1>
<p class="text-center text-lg text-gray-400 mb-8">June 10th - June 15th | Edinburgh, UK</p>
<div class="text-center mb-10">
<button id="export-html-btn" class="export-button">Export HTML</button>
<button id="export-pdf-btn" class="export-button">Export PDF</button>
</div>
<div id="agenda-content" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
<div class="day-card">
<div class="day-header" contenteditable="true">Tuesday, June 10th <span class="day-theme">- Arrival & Welcome</span></div>
<div class="day-content">
<div class="time-slot" draggable="true">
<div class="time" contenteditable="true">All Day</div>
<div class="activity" contenteditable="true">Arrivals & Moxy Hotel Check-in<div><span style="--tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; --tw-contain-size: ; --tw-contain-layout: ; --tw-contain-paint: ; --tw-contain-style: ; color: rgb(156, 163, 175); display: block; font-size: 0.875rem; margin-top: 0.125rem;">???</span></div></div>
<button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div>
<div class="time-slot" draggable="true">
<div class="time" contenteditable="true">15:00 - 17:00</div>
<div class="activity" contenteditable="true">Summit Welcome Refreshments<div><span style="--tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; --tw-contain-size: ; --tw-contain-layout: ; --tw-contain-paint: ; --tw-contain-style: ; color: rgb(156, 163, 175); display: block; font-size: 0.875rem; margin-top: 0.125rem;">???</span></div></div>
<button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div>
<div class="time-slot" draggable="true">
<div class="time" contenteditable="true">17:00 - 18:00</div>
<div class="activity" contenteditable="true" spellcheck="false">
<strong>Opening Welcome & Summit Kick-off</strong><em>Theme: Setting the Stage. Overview of Summit Goals & Agenda</em>
</div>
<button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div><div class="time-slot" draggable="true">
<div class="time" contenteditable="true">19:00 - 21:00</div>
<div class="activity" contenteditable="true">Welcome Reception & Dinner<div><span style="--tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; --tw-contain-size: ; --tw-contain-layout: ; --tw-contain-paint: ; --tw-contain-style: ; color: rgb(156, 163, 175); display: block; font-size: 0.875rem; margin-top: 0.125rem;">???</span></div></div>
<button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div>
</div>
<button class="add-item-button" aria-label="Add item to Tuesday">Add Item</button>
</div>
<div class="day-card">
<div class="day-header" contenteditable="true" spellcheck="true">Wednesday, June 11th <span class="day-theme">- Technical Deep Dive</span></div>
<div class="day-content">
<div class="time-slot" draggable="true">
<div class="time" contenteditable="true">09:30 - 10:00</div>
<div class="activity" contenteditable="true" spellcheck="false">Introductions Breakfast<div><span style="--tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; --tw-contain-size: ; --tw-contain-layout: ; --tw-contain-paint: ; --tw-contain-style: ; color: rgb(156, 163, 175); display: block; font-size: 0.875rem; margin-top: 0.125rem;">???</span></div></div>
<button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div>
<div class="time-slot" draggable="true"><div class="time" contenteditable="true">10:00 - 11:00</div><div class="activity" contenteditable="true">Zone monitoring</div><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div>
<div class="time-slot" draggable="true">
<div class="time" contenteditable="true">11:00 - 12:00</div>
<div class="activity" contenteditable="true" spellcheck="false"><div><font color="#ffffff"><b>Rev 7/Rev 8/DF product roadmap</b></font></div><div><span style="--tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; --tw-contain-size: ; --tw-contain-layout: ; --tw-contain-paint: ; --tw-contain-style: ; color: rgb(156, 163, 175); display: block; font-size: 0.875rem; margin-top: 0.125rem;">???</span></div></div>
<button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div><div class="time-slot" draggable="true">
<div class="time" contenteditable="true">12:00 - 13:00</div>
<div class="activity" contenteditable="true" spellcheck="false">Lunch<div><span style="--tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; --tw-contain-size: ; --tw-contain-layout: ; --tw-contain-paint: ; --tw-contain-style: ; color: rgb(156, 163, 175); display: block; font-size: 0.875rem; margin-top: 0.125rem;">???</span></div></div>
<button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div><div class="time-slot" draggable="true">
<div class="time" contenteditable="true">13:00 - 14:00</div>
<div class="activity" contenteditable="true" spellcheck="false"><font color="#ffffff"><b>SPAD tutorial 101</b></font><div><div style=""><font color="#9ca3af"><span style="font-size: 14px;">basics, how it works, histogram, etc.</span></font><b style="color: rgb(255, 255, 255);"> Tarek/Robert</b></div></div></div>
<button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div>
<div class="time-slot" draggable="true">
<div class="time" contenteditable="true">14:00 - 15:00</div>
<div class="activity" contenteditable="true" spellcheck="false"><div><font color="#ffffff"><b>SPAD tutorial 102 </b></font></div><span style="--tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; --tw-contain-size: ; --tw-contain-layout: ; --tw-contain-paint: ; --tw-contain-style: ; font-weight: bolder; color: rgb(255, 255, 255);"><font color="#9ca3af" style="--tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; --tw-contain-size: ; --tw-contain-layout: ; --tw-contain-paint: ; --tw-contain-style: ; font-weight: 400;"><span style="--tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; --tw-contain-size: ; --tw-contain-layout: ; --tw-contain-paint: ; --tw-contain-style: ; font-size: 14px;">competitive products, future developments Tarek/Robert</span></font></span></div>
<button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div><div class="time-slot" draggable="true"><div class="time" contenteditable="true">15:00 - 16:00</div><div class="activity" contenteditable="true">FUSA w/s (Eric Y)</div><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div></div>
<button class="add-item-button" aria-label="Add item to Wednesday">Add Item</button>
</div>
<div class="day-card">
<div class="day-header" contenteditable="true" spellcheck="true">Thursday, June 12th <span class="day-theme">- Emotional Intelligence & AI</span></div>
<div class="day-content">
<div class="time-slot" draggable="true">
<div class="time" contenteditable="true">08:00 - 09:30</div>
<div class="activity" contenteditable="true">Breakfast<div><span style="--tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; --tw-contain-size: ; --tw-contain-layout: ; --tw-contain-paint: ; --tw-contain-style: ; color: rgb(156, 163, 175); display: block; font-size: 0.875rem; margin-top: 0.125rem;">???</span></div></div>
<button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div>
<div class="time-slot" draggable="true">
<div class="time" contenteditable="true">09:30 - 10:15</div>
<div class="activity" contenteditable="true" spellcheck="false"><div><font color="#ffffff"><b>Cronos</b></font></div><div><span style="--tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; --tw-contain-size: ; --tw-contain-layout: ; --tw-contain-paint: ; --tw-contain-style: ; color: rgb(156, 163, 175); display: block; font-size: 0.875rem; margin-top: 0.125rem;">Design/specs/status, etc. Neil</span></div></div>
<button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div><div class="time-slot" draggable="true">
<div class="time" contenteditable="true">10:15 - 11:00</div>
<div class="activity" contenteditable="true" spellcheck="false">L4/Rev9 Teaser<div><span style="--tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; --tw-contain-size: ; --tw-contain-layout: ; --tw-contain-paint: ; --tw-contain-style: ; color: rgb(156, 163, 175); display: block; font-size: 0.875rem; margin-top: 0.125rem;">PRD, status: Neil</span></div></div>
<button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div>
<div class="time-slot" draggable="true">
<div class="time" contenteditable="true">11:00 - 12:30</div>
<div class="activity" contenteditable="true" spellcheck="false"><strong>Workshop: Advanced Demo Techniques / Value Selling for FAEs</strong><div><span style="--tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; --tw-contain-size: ; --tw-contain-layout: ; --tw-contain-paint: ; --tw-contain-style: ; color: rgb(156, 163, 175); display: block; font-size: 0.875rem; margin-top: 0.125rem;">Mayb remove</span></div></div>
<button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div><div class="time-slot" draggable="true">
<div class="time" contenteditable="true">12:30 - 13:30</div>
<div class="activity" contenteditable="true">Lunch<div><span style="--tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; --tw-contain-size: ; --tw-contain-layout: ; --tw-contain-paint: ; --tw-contain-style: ; color: rgb(156, 163, 175); display: block; font-size: 0.875rem; margin-top: 0.125rem;">???</span></div></div>
<button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div><div class="time-slot" draggable="true"><div class="time" contenteditable="true">13:30 - 14:30</div><div class="activity" contenteditable="true" spellcheck="false"><div>Examples of main use cases </div><div><font color="#9ca3af"><span style="font-size: 14px;">(robotics/autonomy/etc.) - each FAE 5 min</span></font></div></div><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div><div class="time-slot" draggable="true">
<div class="time" contenteditable="true">14:30 - 15:15</div>
<div class="activity" contenteditable="true" spellcheck="false"><div><font color="#ffffff"><b>Gemini and Blue City Demos</b></font></div><div><span style="--tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; --tw-contain-size: ; --tw-contain-layout: ; --tw-contain-paint: ; --tw-contain-style: ; color: rgb(156, 163, 175); display: block; font-size: 0.875rem; margin-top: 0.125rem;">???</span></div></div>
<button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div><div class="time-slot" draggable="true"><div class="time" contenteditable="true">15:15 - 16:15</div><div class="activity" contenteditable="true">placeholder</div><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div><div class="time-slot" draggable="true">
<div class="time" contenteditable="true">16:15 - 17:15</div>
<div class="activity" contenteditable="true" spellcheck="false"><strong>Competitive Landscape & Positioning</strong> (Marketing/Competitive Intel)<div><span style="--tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; --tw-contain-size: ; --tw-contain-layout: ; --tw-contain-paint: ; --tw-contain-style: ; color: rgb(156, 163, 175); display: block; font-size: 0.875rem; margin-top: 0.125rem;">Tom Grey: get presentation </span></div></div>
<button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div></div>
<button class="add-item-button" aria-label="Add item to Thursday">Add Item</button>
</div>
<div class="day-card">
<div class="day-header" contenteditable="true" spellcheck="true">Friday, June 13th <span class="day-theme">- Knowledge Sharing & Customer Focus</span></div>
<div class="day-content">
<div class="time-slot" draggable="true">
<div class="time" contenteditable="true">08:00 - 09:00</div>
<div class="activity" contenteditable="true">Breakfast<div><span style="--tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; --tw-contain-size: ; --tw-contain-layout: ; --tw-contain-paint: ; --tw-contain-style: ; color: rgb(156, 163, 175); display: block; font-size: 0.875rem; margin-top: 0.125rem;">???</span></div></div>
<button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div>
<div class="time-slot" draggable="true">
<div class="time" contenteditable="true">10:00 - 11:00</div>
<div class="activity" contenteditable="true" spellcheck="false"><strong>FAE Best Practices Sharing Session / Open time</strong><div><span style="--tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; --tw-contain-size: ; --tw-contain-layout: ; --tw-contain-paint: ; --tw-contain-style: ; color: rgb(156, 163, 175); display: block; font-size: 0.875rem; margin-top: 0.125rem;">???</span></div></div>
<button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div><div class="time-slot" draggable="true">
<div class="time" contenteditable="true">11:00 - 11:30</div>
<div class="activity" contenteditable="true" spellcheck="false"><font color="#ffffff"><b>AI Challenge Presentations</b></font><br><div><span style="--tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; --tw-contain-size: ; --tw-contain-layout: ; --tw-contain-paint: ; --tw-contain-style: ; color: rgb(156, 163, 175); display: block; font-size: 0.875rem; margin-top: 0.125rem;">???</span></div></div>
<button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div><div class="time-slot" draggable="true">
<div class="time" contenteditable="true">11:30 - 12:00</div>
<div class="activity" contenteditable="true" spellcheck="false"><font color="#ffffff"><b>AI Tools are the Future</b></font><br><div><span style="--tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; --tw-contain-size: ; --tw-contain-layout: ; --tw-contain-paint: ; --tw-contain-style: ; color: rgb(156, 163, 175); display: block; font-size: 0.875rem; margin-top: 0.125rem;">???</span></div></div>
<button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div>
<div class="time-slot" draggable="true">
<div class="time" contenteditable="true">12:00 - 13:00</div>
<div class="activity" contenteditable="true">Lunch<div><span style="--tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; --tw-contain-size: ; --tw-contain-layout: ; --tw-contain-paint: ; --tw-contain-style: ; color: rgb(156, 163, 175); display: block; font-size: 0.875rem; margin-top: 0.125rem;">???</span></div></div>
<button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div><div class="time-slot" draggable="true">
<div class="time" contenteditable="true">13:00 - 14:00</div>
<div class="activity" contenteditable="true" spellcheck="false"><strong>Summit Wrap-up & Key Takeaways</strong> (FAE Leadership)<div><span style="--tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; --tw-contain-size: ; --tw-contain-layout: ; --tw-contain-paint: ; --tw-contain-style: ; color: rgb(156, 163, 175); display: block; font-size: 0.875rem; margin-top: 0.125rem;">???</span></div></div>
<button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div><div class="time-slot" draggable="true">
<div class="time" contenteditable="true">14:00 - 14:30</div>
<div class="activity" contenteditable="true" spellcheck="false"><strong>Closing Remarks & Thank You</strong> (Exec Sponsor)<div><span style="--tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; --tw-contain-size: ; --tw-contain-layout: ; --tw-contain-paint: ; --tw-contain-style: ; color: rgb(156, 163, 175); display: block; font-size: 0.875rem; margin-top: 0.125rem;">???</span></div></div>
<button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div><div class="time-slot" draggable="true"><div class="time" contenteditable="true">14:30 - 15:15</div><div class="activity" contenteditable="true">Transition to Dinner</div><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div><div class="time-slot" draggable="true"><div class="time" contenteditable="true">15:15 - 16:00</div><div class="activity" contenteditable="true" spellcheck="false"><div>FAE internal sessions - ideas:</div><div> SDK w/s</div><div> Gemini/Blue city w/s</div><div> FAE blockers/challenges for customer satisfaction</div><div> Good practices</div></div><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div><div class="time-slot" draggable="true">
<div class="time" contenteditable="true">16:00 - 18:00</div>
<div class="activity" contenteditable="true" spellcheck="false">Beers/Scotch/Dinner w/ Edinburgh Team<div><span style="--tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; --tw-contain-size: ; --tw-contain-layout: ; --tw-contain-paint: ; --tw-contain-style: ; color: rgb(156, 163, 175); display: block; font-size: 0.875rem; margin-top: 0.125rem;">???</span></div></div>
<button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div>
</div>
<button class="add-item-button" aria-label="Add item to Friday">Add Item</button>
</div>
<div class="day-card">
<div class="day-header" contenteditable="true">Saturday, June 14th <span class="day-theme">- Team Building & Wrap-up</span></div>
<div class="day-content">
<div class="time-slot" draggable="true">
<div class="time" contenteditable="true">All Day</div>
<div class="activity" contenteditable="true" spellcheck="false"><strong>Team Building Activity</strong> <em>(e.g., Edinburgh-based challenge, workshop) Bike: https://www.tripadvisor.com/AttractionProductReview-g186525-d16840471-Edinburgh_Sky_to_Sea_Bike_or_E_Bike_Tour_with_Transfer_by_TBC-Edinburgh_Scotland.html</em></div>
<button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div>
</div>
<button class="add-item-button" aria-label="Add item to Saturday">Add Item</button>
</div>
<div class="day-card">
<div class="day-header" contenteditable="true">Sunday, June 15th <span class="day-theme">- Departures</span></div>
<div class="day-content">
<div class="time-slot" draggable="true">
<div class="time" contenteditable="true">Morning</div>
<div class="activity" contenteditable="true">Breakfast Available<div><span style="--tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; --tw-contain-size: ; --tw-contain-layout: ; --tw-contain-paint: ; --tw-contain-style: ; color: rgb(156, 163, 175); display: block; font-size: 0.875rem; margin-top: 0.125rem;"><br></span></div></div>
<button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div>
<div class="time-slot" draggable="true">
<div class="time" contenteditable="true">All Day</div>
<div class="activity" contenteditable="true">Check-out & Departures<div><span style="--tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; --tw-contain-size: ; --tw-contain-layout: ; --tw-contain-paint: ; --tw-contain-style: ; color: rgb(156, 163, 175); display: block; font-size: 0.875rem; margin-top: 0.125rem;"><br></span></div></div>
<button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button><button class="delete-item-button" aria-label="Delete item">×</button></div>
</div>
<button class="add-item-button" aria-label="Add item to Sunday">Add Item</button>
</div>
</div> <div id="status-notes" class="mt-10 text-center text-sm text-gray-500">
<p><strong>Note:</strong> You can click directly on the time slots and activity descriptions to edit the text.</p>
<p>(Edits are temporary. Use the export buttons to save your changes.)</p>
<p class="status-message" style="color: rgb(52, 211, 153);">Cleaned HTML export successful!</p></div>
<script>
// --- Function Definitions ---
// Helper function to display status messages
function showStatusMessage(message, isError = true) {
const statusNotes = document.getElementById('status-notes');
if (!statusNotes) {
console.error("Status notes container not found!");
return;
}
const existingMessages = statusNotes.querySelectorAll('.status-message');
existingMessages.forEach(msg => msg.remove());
const messageElement = document.createElement('p');
messageElement.textContent = message;
messageElement.classList.add('status-message');
if (isError) {
messageElement.classList.add('error-message');
} else {
messageElement.style.color = '#34d399'; // Tailwind green-400
}
statusNotes.appendChild(messageElement);
}
// --- HTML Export Function ---
function exportHtml() {
console.log("Export HTML button clicked.");
let cleanedHtml = '';
try {
// --- Clone the document element ---
const clonedDoc = document.documentElement.cloneNode(true);
console.log("Document cloned for cleaning.");
// --- Find and remove extension elements from the clone ---
const knownExtensionSelectors = [
'[data-grammarly-shadow-root]',
'grammarly-extension',
'grammarly-extension-vbars',
'grammarly-desktop-integration',
'grammarly-desktop-integration-vbars',
'grammarly-desktop-integration-vbars-v2',
'grammarly-desktop-integration-vbars-v3',
'grammarly-desktop-integration-vbars-v4',
'grammarly-desktop-integration-vbars-v5',
'grammarly-desktop-integration-vbars-v6',
// Selectors for Seamless.ai (add more specific ones if known)
'[id^="seamless-ai-"]',
'[class*="seamless-ai"]',
'.seamless-button',
'.seamless-overlay',
'seamless-flyout',
'.seamless-flyout-container',
'.seamless-flyout-content',
'.seamless-flyout-header',
'.seamless-flyout-body',
'.seamless-flyout-footer',
'.seamless-flyout-close',
'.seamless-flyout-title',
'.seamless-flyout-description',
'.seamless-flyout-link',
'.seamless-flyout-button'
// Add other known extension selectors here if needed
];
knownExtensionSelectors.forEach(selector => {
const elementsToRemove = clonedDoc.querySelectorAll(selector);
elementsToRemove.forEach(el => {
console.log("Removing extension element:", el.tagName, el.id ? `#${el.id}` : '', el.className ? `.${el.className}`: '');
el.remove();
});
});
console.log("Known extension elements removed from clone.");
// ----------------------------------------------------
// Get the outerHTML of the cleaned clone
cleanedHtml = clonedDoc.outerHTML;
if (!cleanedHtml) {
throw new Error("Failed to generate cleaned HTML.");
}
showStatusMessage("Generating cleaned HTML file...", false);
// Create the Blob from the cleaned HTML
const blob = new Blob([cleanedHtml], { type: 'text/html' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'fae_summit_agenda_cleaned.html'; // Changed filename slightly
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
console.log("Cleaned HTML export successful.");
showStatusMessage("Cleaned HTML export successful!", false);
} catch (error) {
console.error("Error exporting cleaned HTML:", error);
showStatusMessage(`Cleaned HTML export failed: ${error.message}`);
}
}
// --- PDF Export Function ---
function exportPdf() {
console.log("Export PDF button clicked.");
showStatusMessage("Exporting PDF...", false);
console.log("Checking for PDF libraries inside exportPdf function...");
if (typeof html2canvas === 'undefined') {
console.error("exportPdf: html2canvas library is not loaded.");
showStatusMessage("PDF Export Error: html2canvas library not found.");
return;
} else {
console.log("exportPdf: html2canvas found.");
}
if (typeof window.jspdf === 'undefined' || typeof window.jspdf.jsPDF === 'undefined') {
console.error("exportPdf: jsPDF library or constructor is not loaded correctly (window.jspdf or window.jspdf.jsPDF is undefined).");
if (typeof window.jspdf === 'undefined') {
showStatusMessage("PDF Export Error: Core jsPDF object (window.jspdf) not found.");
} else {
showStatusMessage("PDF Export Error: jsPDF constructor (window.jspdf.jsPDF) not found.");
}
// *** Add a check for window object properties for debugging ***
console.log("Current window properties:", Object.keys(window).sort());
return;
} else {
console.log("exportPdf: jsPDF and constructor found (window.jspdf.jsPDF).");
}
try {
const elementToCapture = document.body; // Capture the entire body
const buttons = document.querySelector('.text-center.mb-10');
const note = document.getElementById('status-notes');
// Add padding temporarily for visual spacing in the PDF
const originalBodyPadding = document.body.style.padding;
document.body.style.padding = "2rem"; // Apply padding for capture
if (!elementToCapture) {
throw new Error("Main content area not found."); // Should not happen if body exists
}
if (buttons) buttons.style.visibility = 'hidden';
if (note) note.style.visibility = 'hidden';
console.log("Starting PDF export. Capturing element:", elementToCapture);
html2canvas(elementToCapture, {
scale: 2, // Higher scale for better resolution
useCORS: true,
backgroundColor: '#111827',
logging: true,
windowWidth: document.documentElement.scrollWidth, // Try to capture full width
windowHeight: document.documentElement.scrollHeight // Try to capture full height
}).then(canvas => {
console.log("Canvas generated successfully by html2canvas.");
const imgData = canvas.toDataURL('image/png');
const pdf = new window.jspdf.jsPDF({
orientation: 'p', // Changed to portrait as body is taller
unit: 'pt',
format: 'a4'
});
console.log("jsPDF instance created.");
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = pdf.internal.pageSize.getHeight();
const canvasWidth = canvas.width;
const canvasHeight = canvas.height;
const aspectRatio = canvasWidth / canvasHeight;
let imgWidth = pdfWidth - 40; // pdf width - margins
let imgHeight = imgWidth / aspectRatio;
// If the calculated height is too tall for the page, fit to height instead
if (imgHeight > pdfHeight - 40) {
imgHeight = pdfHeight - 40; // pdf height - margins
imgWidth = imgHeight * aspectRatio;
}
const x = (pdfWidth - imgWidth) / 2; // Center horizontally
const y = 20; // Top margin
pdf.addImage(imgData, 'PNG', x, y, imgWidth, imgHeight);
pdf.save('fae_summit_agenda.pdf');
console.log("PDF saved.");
showStatusMessage("PDF export successful!", false);
// Restore styles after saving
document.body.style.padding = originalBodyPadding;
if (buttons) buttons.style.visibility = 'visible';
if (note) note.style.visibility = 'visible';
}).catch(err => {
console.error("Error during html2canvas processing:", err);
showStatusMessage(`PDF generation failed during canvas step: ${err.message || err}`);
document.body.style.padding = originalBodyPadding; // Restore padding on error
if (buttons) buttons.style.visibility = 'visible';
if (note) note.style.visibility = 'visible';
});
} catch (error) {
console.error("Error setting up PDF export:", error);
showStatusMessage(`PDF export setup failed: ${error.message}`);
const buttons = document.querySelector('.text-center.mb-10');
const note = document.getElementById('status-notes');
if (buttons) buttons.style.visibility = 'visible';
if (note) note.style.visibility = 'visible';
}
}
// --- Time Parsing/Formatting Helpers ---
// Parses "HH:MM - HH:MM" into minutes from midnight
// Returns { start: number, end: number } or null
function parseTimeRange(timeString) {
if (!timeString) return null;
const match = timeString.trim().match(/^(\d{1,2}):(\d{2})\s*-\s*(\d{1,2}):(\d{2})$/);
if (match) {
const startHour = parseInt(match[1], 10);
const startMin = parseInt(match[2], 10);
const endHour = parseInt(match[3], 10);
const endMin = parseInt(match[4], 10);
if (startHour >= 0 && startHour < 24 && startMin >= 0 && startMin < 60 &&
endHour >= 0 && endHour < 24 && endMin >= 0 && endMin < 60) {
const start = startHour * 60 + startMin;
let end = endHour * 60 + endMin;
// Handle midnight case (e.g., 23:00 - 00:30)
if (end < start) end += 24 * 60;
return { start, end };
}
}
return null;
}
// Formats minutes from midnight into "HH:MM - HH:MM"
function formatTimeRange(startMinutes, endMinutes) {
if (startMinutes == null || endMinutes == null || endMinutes < startMinutes) {
return "Invalid Time"; // Or return original if needed
}
const format = (totalMinutes) => {
const hours = Math.floor(totalMinutes / 60) % 24;
const minutes = totalMinutes % 60;
return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}`;
};
return `${format(startMinutes)} - ${format(endMinutes)}`;
}
// Calculates duration in minutes, returns null if unparseable
function calculateDuration(timeString) {
const parsed = parseTimeRange(timeString);
if (parsed) {
return parsed.end - parsed.start;
}
return null;
}
// --- Function to Add Drag Listeners (Moved to global scope) ---
let draggedItem = null; // Keep track of the dragged item globally
let placeholder = null; // Keep track of the placeholder globally
function addDragListenersToItem(item) {
item.addEventListener('dragstart', (e) => {
draggedItem = item;
setTimeout(() => item.classList.add('dragging'), 0);
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/plain', '');
// console.log('Drag Start:', draggedItem);
});
item.addEventListener('dragend', () => {
if (draggedItem) {
draggedItem.classList.remove('dragging');
// console.log('Drag End:', draggedItem);
draggedItem = null;
}
if (placeholder && placeholder.parentNode) {
placeholder.parentNode.removeChild(placeholder);
}
placeholder = null;
document.querySelectorAll('.day-content.drag-over').forEach(container => {
container.classList.remove('drag-over');
});
});
}
// Function to create placeholder (Moved to global scope)
function createPlaceholder() {
placeholder = document.createElement('div');
placeholder.classList.add('drag-placeholder');
return placeholder;
}
// Function to get drag after element (Moved to global scope)
function getDragAfterElement(container, y) {
const draggableElements = [...container.querySelectorAll('.time-slot:not(.dragging)')];
return draggableElements.reduce((closest, child) => {
const box = child.getBoundingClientRect();
const offset = y - box.top - box.height / 2;
if (offset < 0 && offset > closest.offset) {
return { offset: offset, element: child };
} else {
return closest;
}
}, { offset: Number.NEGATIVE_INFINITY }).element;
}
// --- Add/Delete Item Functionality ---
// Function to create a new, empty time slot element
function createTimeSlotElement() {
const timeSlot = document.createElement('div');
timeSlot.classList.add('time-slot');
const timeDiv = document.createElement('div');
timeDiv.classList.add('time');
timeDiv.setAttribute('contenteditable', 'true');
timeDiv.textContent = 'New Time'; // Placeholder
const activityDiv = document.createElement('div');
activityDiv.classList.add('activity');
activityDiv.setAttribute('contenteditable', 'true');
activityDiv.textContent = 'New Activity'; // Placeholder
timeSlot.appendChild(timeDiv);
timeSlot.appendChild(activityDiv);
timeSlot.setAttribute('draggable', 'true'); // Make new items draggable
// Add delete button to the new slot
addDeleteButton(timeSlot);
// Add drag listeners to the new slot
addDragListenersToItem(timeSlot);
return timeSlot;
}
// Function to add a delete button to a time slot
function addDeleteButton(timeSlotElement) {
const deleteBtn = document.createElement('button');
deleteBtn.classList.add('delete-item-button');
deleteBtn.innerHTML = '×'; // Use '×' symbol
deleteBtn.setAttribute('aria-label', 'Delete item');
// Event listener for delete is handled by delegation
timeSlotElement.appendChild(deleteBtn);
}
// Function to handle adding an item
function handleAddItem(event) {
const addButton = event.target;
// Find the '.day-content' div within the same '.day-card'
const dayCard = addButton.closest('.day-card');
if (!dayCard) return; // Should not happen
const dayContent = dayCard.querySelector('.day-content');
if (!dayContent) return; // Should not happen
// --- Calculate next time slot ---
let newStartTime = 9 * 60; // Default start: 09:00
let newEndTime = newStartTime + 60; // Default end: 10:00
const timeSlots = dayContent.querySelectorAll('.time-slot');
if (timeSlots.length > 0) {
let lastValidEndTime = null;
// Iterate backwards to find the last valid numerical time
for (let i = timeSlots.length - 1; i >= 0; i--) {
const timeElement = timeSlots[i].querySelector('.time');
if (timeElement) {
const parsed = parseTimeRange(timeElement.textContent);
if (parsed && parsed.end != null) {
lastValidEndTime = parsed.end;
break; // Found the last valid one
}
}
}
if (lastValidEndTime !== null) {
newStartTime = lastValidEndTime; // Start immediately after the last one
newEndTime = newStartTime + 60;
} else {
// No valid numerical time found, keep the default 09:00 - 10:00
console.log("No valid numerical time found in existing slots, defaulting to 09:00 - 10:00");
}
}
const formattedTime = formatTimeRange(newStartTime, newEndTime);
// --- End Calculation ---
const newItem = createTimeSlotElement();
// Set the calculated time
const newItemTimeDiv = newItem.querySelector('.time');
if (newItemTimeDiv) {
newItemTimeDiv.textContent = formattedTime;
}
// Set default activity text
const newItemActivityDiv = newItem.querySelector('.activity');
if (newItemActivityDiv) {
newItemActivityDiv.textContent = 'New Activity'; // Keep placeholder text
}
dayContent.appendChild(newItem);
// Optional: Scroll the new item into view or focus the activity field
newItem.querySelector('.activity').focus();
}
// Function to handle deleting an item (called via event delegation)
function handleDeleteItem(event) {
// Check if the clicked element is actually the delete button
if (event.target.classList.contains('delete-item-button')) {
const timeSlot = event.target.closest('.time-slot');
if (timeSlot) {
timeSlot.remove();
// Add a visual confirmation or undo option here if desired
}
}
}
// --- Add Event Listeners after DOM is loaded ---
document.addEventListener('DOMContentLoaded', (event) => {
console.log("DOM fully loaded and parsed.");
if (typeof html2canvas === 'undefined') {
console.error("DOM Ready: html2canvas library is still not loaded.");
} else {
console.log("DOM Ready: html2canvas found.");
}
if (typeof window.jspdf === 'undefined' || typeof window.jspdf.jsPDF === 'undefined') {
console.error("DOM Ready: jsPDF library or constructor is still not loaded correctly.");
if (typeof window.jspdf === 'undefined') {
console.error("DOM Ready: window.jspdf is undefined.");
} else {
console.error("DOM Ready: window.jspdf.jsPDF is undefined.");
}
} else {
console.log("DOM Ready: jsPDF and constructor found.");
}
const htmlButton = document.getElementById('export-html-btn');
const pdfButton = document.getElementById('export-pdf-btn');
if (htmlButton) {
htmlButton.addEventListener('click', exportHtml);
console.log("HTML export listener attached.");
} else {
console.error("HTML export button not found!");
showStatusMessage("Initialization Error: HTML button missing.");
}
if (pdfButton) {
pdfButton.addEventListener('click', exportPdf);
console.log("PDF export listener attached.");
} else {
console.error("PDF export button not found!");
showStatusMessage("Initialization Error: PDF button missing.");
}
// Add listeners for "Add Item" buttons
const addButtons = document.querySelectorAll('.add-item-button');
addButtons.forEach(button => {
button.addEventListener('click', handleAddItem);
});
console.log(`Attached 'click' listeners to ${addButtons.length} 'Add Item' buttons.`);
// Add delete buttons to existing items
const existingTimeSlots = document.querySelectorAll('#agenda-content .time-slot');
existingTimeSlots.forEach(slot => {
addDeleteButton(slot);
});
console.log(`Added delete buttons to ${existingTimeSlots.length} existing time slots.`);
// Add delegated event listener for delete buttons
const agendaContent = document.getElementById('agenda-content');
if (agendaContent) {
agendaContent.addEventListener('click', handleDeleteItem);
console.log("Attached delegated 'click' listener to #agenda-content for delete buttons.");
} else {
console.error("Could not find #agenda-content to attach delete listener.");
showStatusMessage("Initialization Error: Agenda container not found for delete functionality.");
}
// --- Drag and Drop Initialization (Inside DOMContentLoaded) ---
// Add draggable attribute and listeners to existing items
const initialTimeSlots = document.querySelectorAll('#agenda-content .time-slot');
initialTimeSlots.forEach(item => {
item.setAttribute('draggable', 'true');
// REMOVED inline dragstart/dragend listeners here
addDragListenersToItem(item); // Add drag listeners using the function
});
console.log(`Made ${initialTimeSlots.length} existing time slots draggable.`);
// Add listeners to potential drop containers (.day-content)
const dayContainers = document.querySelectorAll('#agenda-content .day-content');
dayContainers.forEach(container => {
container.addEventListener('dragenter', (e) => {
// Check if the drag originates from a valid draggable item
if (draggedItem) {
e.preventDefault();
container.classList.add('drag-over');
console.log('Drag Enter:', container.parentNode.querySelector('.day-header').textContent.trim());
}
});
container.addEventListener('dragover', (e) => {
if (draggedItem) {
e.preventDefault(); // Allow drop
container.classList.add('drag-over'); // Ensure class is present
// Placeholder logic
const afterElement = getDragAfterElement(container, e.clientY);
if (!placeholder) {
placeholder = createPlaceholder();
}
// Insert placeholder
if (afterElement == null) {
container.appendChild(placeholder);
} else {
container.insertBefore(placeholder, afterElement);
}
}
});
container.addEventListener('dragleave', (e) => {
// Check if the mouse is leaving the container itself, not just moving over a child element
if (draggedItem && !container.contains(e.relatedTarget)) {
container.classList.remove('drag-over');
if (placeholder && placeholder.parentNode === container) {
container.removeChild(placeholder);
placeholder = null; // Reset placeholder when leaving a container
}
console.log('Drag Leave:', container.parentNode.querySelector('.day-header').textContent.trim());
}
});
container.addEventListener('drop', (e) => {
if (draggedItem) {
e.preventDefault(); // Prevent default action (like navigating)
container.classList.remove('drag-over');
// --- Pre-insertion logic ---
const droppedTimeElement = draggedItem.querySelector('.time');
const droppedOriginalText = droppedTimeElement ? droppedTimeElement.textContent : "";
const droppedOriginalParsed = parseTimeRange(droppedOriginalText);
const droppedOriginalDuration = calculateDuration(droppedOriginalText); // Returns null if not HH:MM-HH:MM
const isDroppedTimeNumerical = droppedOriginalParsed !== null && droppedOriginalDuration !== null;
// Store original first item reference *before* inserting dragged item,
// useful for finding the *intended* first start time if needed.
// const originalFirstItem = container.querySelector('.time-slot:not(.dragging)');
// Finding the actual first item AFTER insertion seems more reliable for cascade.
// Use placeholder to determine drop position
if (placeholder && placeholder.parentNode === container) {
container.insertBefore(draggedItem, placeholder);
container.removeChild(placeholder);
} else {
const afterElement = getDragAfterElement(container, e.clientY);
if (afterElement) {
container.insertBefore(draggedItem, afterElement);
} else {
container.appendChild(draggedItem); // Append if no element after cursor
}
}
if (placeholder && placeholder.parentNode) { // Clean up if still around
placeholder.parentNode.removeChild(placeholder);
}
placeholder = null; // Reset placeholder after drop
// --- Attempt to auto-adjust time ONLY for items with numerical time ---
let initialDraggedItemEndTime = null; // Store the end time *after* this initial adjustment
if (isDroppedTimeNumerical && droppedTimeElement) {
console.log(`Adjusting time for dropped item: ${droppedOriginalText}`);
try {
let newStartTime = null;
let newEndTime = null;
// Check if it's dropped at the very top (no preceding time-slot sibling)
let isAtTop = true;
let prevEl = draggedItem.previousElementSibling;
while(prevEl) {
if (prevEl.classList.contains('time-slot')) {
isAtTop = false;
break;
}
prevEl = prevEl.previousElementSibling;
}
if (isAtTop) {
// --- Dropped at the top ---
console.log("Dropped at the top. Finding first valid numerical time below...");
let sibling = draggedItem.nextElementSibling;
let foundFirstNumericalStartTime = null;
while (sibling) {
if (sibling.classList.contains('time-slot')) {
const siblingTimeElement = sibling.querySelector('.time');
const siblingParsed = parseTimeRange(siblingTimeElement?.textContent);
if (siblingParsed && siblingParsed.start != null) {
foundFirstNumericalStartTime = siblingParsed.start;
console.log(`Using start time ${formatTimeRange(foundFirstNumericalStartTime, null).split(' - ')[0]} from first numerical item below.`);
break; // Found the first valid time
}
}
sibling = sibling.nextElementSibling;
}
if (foundFirstNumericalStartTime !== null) {
// Adopt the start time of the item it displaced
newStartTime = foundFirstNumericalStartTime;
} else {
// If no numerical time below, keep its original start time
newStartTime = droppedOriginalParsed.start;
console.log("No numerical time found below, keeping original start time.");
}
newEndTime = newStartTime + droppedOriginalDuration;
} else {
// --- Dropped somewhere else (Not at the top) ---
let prevSibling = draggedItem.previousElementSibling;
let foundPreviousNumericalEndTime = null;
// Find the first PRECEDING sibling with a valid numerical time
while(prevSibling) {
if (prevSibling.classList.contains('time-slot')) {
const prevTimeElement = prevSibling.querySelector('.time');
const prevParsed = parseTimeRange(prevTimeElement?.textContent);
if (prevParsed && prevParsed.end != null) {
foundPreviousNumericalEndTime = prevParsed.end;
console.log(`Using end time ${formatTimeRange(null, foundPreviousNumericalEndTime).split(' - ')[1]} from first valid numerical item above.`);
break; // Found the first valid time
}
}
prevSibling = prevSibling.previousElementSibling;
}
if (foundPreviousNumericalEndTime !== null) {
// Set start time based on previous item's end time
newStartTime = foundPreviousNumericalEndTime;
console.log("Calculated new start time based on valid previous item:", formatTimeRange(newStartTime, null).split(' - ')[0]);
} else {
// No numerical item above. Check BELOW.
console.log("No numerical item above. Checking below...");
let sibling = draggedItem.nextElementSibling;
let foundFirstNumericalStartTimeBelow = null;
while (sibling) {
if (sibling.classList.contains('time-slot')) {
const siblingTimeElement = sibling.querySelector('.time');
const siblingParsed = parseTimeRange(siblingTimeElement?.textContent);
if (siblingParsed && siblingParsed.start != null) {
foundFirstNumericalStartTimeBelow = siblingParsed.start;
console.log(`Using start time ${formatTimeRange(foundFirstNumericalStartTimeBelow, null).split(' - ')[0]} from first numerical item below.`);
break; // Found the first valid time
}
}
sibling = sibling.nextElementSibling;
}
if (foundFirstNumericalStartTimeBelow !== null) {
// Adopt the start time of the item below it
newStartTime = foundFirstNumericalStartTimeBelow;
console.log("Adopted start time from item below.");
} else {
// Fallback: If no numerical item above OR below, keep original start time
newStartTime = droppedOriginalParsed.start;
console.log("Could not find valid numerical time above or below, keeping original start time as fallback.");
}
}
newEndTime = newStartTime + droppedOriginalDuration;
}
// Update the dragged item's time text if a new valid time was calculated
const newFormattedTime = formatTimeRange(newStartTime, newEndTime);
console.log("Updating dropped item time to:", newFormattedTime);
droppedTimeElement.textContent = newFormattedTime;
initialDraggedItemEndTime = newEndTime; // Store for cascade
} catch (timeError) {
console.error("Error during initial time adjustment for dropped item:", timeError);
// If adjustment fails, try to get end time from original for cascade
if(droppedOriginalParsed && droppedOriginalParsed.end != null) {
initialDraggedItemEndTime = droppedOriginalParsed.end;
}
}
} else {
// Item has non-numerical time ("All Day", etc.) or time element missing
console.log(`Skipping time adjustment for non-numerical item: ${droppedOriginalText}`);
initialDraggedItemEndTime = null; // Ensure cascade doesn't use non-numerical item
}
// -------------------------------------
// --- Cascade time adjustments to subsequent items ---
let lastValidEndTime = initialDraggedItemEndTime; // Use the end time calculated above (or null)
let currentItem = draggedItem.nextElementSibling; // Start cascade from item AFTER the dropped one
while (currentItem) {
if (!currentItem.classList.contains('time-slot')) {
currentItem = currentItem.nextElementSibling; // Skip non-time-slots
continue;
}
const timeElement = currentItem.querySelector('.time');
if (!timeElement) {
console.warn("Cascade: Could not find time element in item:", currentItem.textContent.substring(0,50));
currentItem = currentItem.nextElementSibling; // Move to next
continue; // Cannot process without a time element
}
const currentParsedTime = parseTimeRange(timeElement.textContent);
const currentDuration = calculateDuration(timeElement.textContent); // Use existing duration
if (currentParsedTime === null || currentDuration === null) {
// Item has invalid time format (e.g., "All Day") or unparsable duration
console.log(`Cascade: Skipping item with non-standard time or duration: ${timeElement.textContent}`);
// Do NOT update lastValidEndTime, keep the value from the previous valid item
} else {
// Item has a valid time format, adjust it based on the last valid end time
if (lastValidEndTime !== null) {
const newStartTime = lastValidEndTime;
const newEndTime = newStartTime + currentDuration;
const newFormattedTime = formatTimeRange(newStartTime, newEndTime);
console.log(`Cascade: Updating item ${timeElement.textContent} to ${newFormattedTime}`);
timeElement.textContent = newFormattedTime;
lastValidEndTime = newEndTime; // Update for the next iteration
} else {
// If the preceding item was invalid, we can't adjust based on it.
// We *should* however update lastValidEndTime based on this *current* valid item's end time
// so subsequent items can adjust correctly relative to this one.
console.warn(`Cascade: Preceding item invalid, cannot adjust ${timeElement.textContent}. Updating lastValidEndTime based on its current end time.`);
lastValidEndTime = currentParsedTime.end;
}
}
currentItem = currentItem.nextElementSibling; // Move to the next item
}
// -------------------------------------
// Note: dragend event on the draggedItem handles removing the .dragging class
}
});
});
console.log(`Attached drag/drop listeners to ${dayContainers.length} day containers.`);
});
</script>
</body></html>