jinger wy
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Family Calendar</title>
  <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=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">
  <style>
    :root {
      --bg: #000;
      --panel: #09090b;
      --panel-2: #000;
      --text: #fff;
      --muted: #71717a;
      --line: rgba(255,255,255,.1);
      --line-strong: rgba(255,255,255,.35);
      --button-bg: #fff;
      --button-text: #000;
      --input-bg: #000;
      --shadow: rgba(255,255,255,.06);
      --radius-xl: 28px;
      --radius-lg: 22px;
      --radius-md: 16px;
    }

    body.light-mode {
      --bg: #f7f7f5;
      --panel: #ffffff;
      --panel-2: #f4f4f2;
      --text: #050505;
      --muted: #737373;
      --line: rgba(0,0,0,.1);
      --line-strong: rgba(0,0,0,.35);
      --button-bg: #000;
      --button-text: #fff;
      --input-bg: #fbfbfa;
      --shadow: rgba(0,0,0,.08);
    }

    * { box-sizing: border-box; }

    body {
      margin: 0;
      min-height: 100vh;
      background: var(--bg);
      color: var(--text);
      font-family: 'Poppins', system-ui, sans-serif;
      transition: background .18s ease, color .18s ease;
    }

    button, input, textarea, select { font: inherit; }
    button { cursor: pointer; }

    .font-scotch {
      font-family: 'Scotch Display', 'Playfair Display', Georgia, serif;
    }

    .app {
      width: 100%;
      max-width: 1040px;
      min-height: 100vh;
      margin: 0 auto;
      padding: 20px 16px 96px;
    }

    .panel-shell {
      display: grid;
      grid-template-columns: 1fr;
      gap: 0;
      align-items: start;
    }

    .panel[draggable="true"] {
      cursor: grab;
    }

    .panel.dragging {
      opacity: .48;
      cursor: grabbing;
    }

    .drag-handle {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      width: 34px;
      height: 34px;
      border-radius: 999px;
      border: 1px solid var(--line);
      color: var(--muted);
      background: var(--panel-2);
      flex: 0 0 auto;
    }

    body.fullscreen-panel .panel {
      display: none;
    }

    body.fullscreen-panel .panel.active-fullscreen-panel {
      display: block;
      min-height: calc(100vh - 116px);
      margin-bottom: 0;
    }

    .panel {
      background: var(--panel);
      border: 1px solid var(--line);
      border-radius: var(--radius-xl);
      padding: 18px;
      margin-bottom: 16px;
      transition: background .18s ease, border-color .18s ease;
    }

    .hero { box-shadow: 0 20px 80px var(--shadow); }

    .top-row, .section-head, .month-row, .note-title-row, .todo-row {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 12px;
    }

    .hero-actions {
      display: flex;
      gap: 8px;
      align-items: center;
    }

    .eyebrow {
      margin: 0 0 4px;
      font-size: 11px;
      letter-spacing: .28em;
      text-transform: uppercase;
      color: var(--muted);
      font-weight: 700;
    }

    h1, h2, h3, p { margin: 0; }

    h1 {
      font-size: 44px;
      line-height: .95;
      letter-spacing: -0.04em;
    }

    h2 {
      font-size: 30px;
      line-height: 1;
      letter-spacing: -0.03em;
    }

    .subtext {
      margin-top: 6px;
      font-size: 13px;
      color: var(--muted);
    }

    .icon-btn, .add-btn, .month-btn {
      border: 0;
      transition: transform .12s ease, opacity .12s ease, background .18s ease, color .18s ease;
    }

    .icon-btn:active, .add-btn:active, .month-btn:active, .person-chip:active, .day:active {
      transform: scale(.96);
    }

    .icon-btn {
      width: 44px;
      height: 44px;
      display: grid;
      place-items: center;
      border-radius: 999px;
      background: var(--button-bg);
      color: var(--button-text);
      font-size: 17px;
      flex: 0 0 auto;
    }

    .icon-btn svg {
      width: 18px;
      height: 18px;
    }

    .chips {
      display: flex;
      gap: 8px;
      overflow-x: auto;
      padding: 16px 0 2px;
      scrollbar-width: none;
    }

    .chips::-webkit-scrollbar { display: none; }

    .person-chip {
      flex: 0 0 auto;
      border-radius: 999px;
      border: 1px solid var(--line);
      background: var(--panel-2);
      color: var(--text);
      padding: 9px 15px;
      font-size: 13px;
      font-weight: 600;
      transition: background .18s ease, color .18s ease, border-color .18s ease;
    }

    .person-chip.active {
      background: var(--button-bg);
      color: var(--button-text);
      border-color: var(--button-bg);
    }

    .input-row {
      display: flex;
      gap: 8px;
      margin-top: 14px;
    }

    input, textarea, select {
      width: 100%;
      min-width: 0;
      border: 1px solid var(--line);
      background: var(--input-bg);
      color: var(--text);
      border-radius: var(--radius-md);
      padding: 13px 14px;
      outline: none;
      font-size: 14px;
      transition: background .18s ease, color .18s ease, border-color .18s ease;
    }

    textarea {
      resize: none;
      min-height: 92px;
    }

    input::placeholder, textarea::placeholder { color: var(--muted); opacity: .75; }
    input:focus, textarea:focus, select:focus { border-color: var(--line-strong); }

    .add-btn {
      border-radius: var(--radius-md);
      background: var(--button-bg);
      color: var(--button-text);
      border: 1px solid var(--button-bg);
      padding: 0 16px;
      min-height: 48px;
      font-size: 14px;
      font-weight: 700;
      white-space: nowrap;
    }

    .month-row { margin-bottom: 18px; }

    .month-btn {
      border: 1px solid var(--line);
      background: var(--panel-2);
      color: var(--text);
      padding: 9px 12px;
      border-radius: 999px;
      font-size: 13px;
    }

    .month-title { text-align: center; }
    .calendar-icon { margin-bottom: 3px; color: var(--muted); font-size: 17px; }

    .weekdays, .calendar-grid {
      display: grid;
      grid-template-columns: repeat(7, 1fr);
    }

    .weekdays {
      margin-bottom: 8px;
      text-align: center;
      font-size: 11px;
      color: var(--muted);
      font-weight: 700;
      letter-spacing: .16em;
    }

    .calendar-grid { gap: 6px; }
    .day, .blank-day { min-height: 56px; }

    .day {
      border-radius: 16px;
      border: 1px solid var(--line);
      background: var(--panel-2);
      color: var(--text);
      text-align: left;
      padding: 8px;
      transition: background .18s ease, color .18s ease, border-color .18s ease;
    }

    .day.today { border-color: var(--line-strong); }

    .day.selected {
      background: var(--button-bg);
      color: var(--button-text);
      border-color: var(--button-bg);
    }

    .day-number {
      display: block;
      font-size: 14px;
      font-weight: 700;
    }

    .dot-row {
      display: flex;
      flex-wrap: wrap;
      gap: 3px;
      margin-top: 7px;
    }

    .dot {
      width: 6px;
      height: 6px;
      border-radius: 999px;
      background: var(--text);
    }

    .day.selected .dot { background: var(--button-text); }

    .note-list {
      display: grid;
      gap: 9px;
      margin: 16px 0;
    }

    .empty {
      border: 1px dashed var(--line-strong);
      border-radius: var(--radius-lg);
      padding: 16px;
      color: var(--muted);
      font-size: 14px;
    }

    .note-card {
      border-radius: var(--radius-lg);
      border: 1px solid var(--line);
      padding: 15px;
    }

    .note-white { background: #fff; color: #000; border-color: #fff; }
    .note-gray { background: #52525b; color: #fff; border-color: #52525b; }
    .note-slate { background: #18181b; color: #fff; border-color: #3f3f46; }
    .note-outline { background: #000; color: #fff; border-color: #fff; }
    body.light-mode .note-outline { background: #fff; color: #000; border-color: #000; }

    .note-person {
      margin-bottom: 4px;
      font-size: 11px;
      letter-spacing: .14em;
      text-transform: uppercase;
      opacity: .65;
      font-weight: 700;
    }

    .note-details {
      margin-top: 5px;
      font-size: 13px;
      opacity: .78;
    }

    .delete-note, .delete-todo {
      border: 0;
      background: transparent;
      color: inherit;
      opacity: .65;
      padding: 4px;
      font-size: 16px;
    }

    .note-form {
      background: var(--panel-2);
      border: 1px solid var(--line);
      border-radius: var(--radius-lg);
      padding: 12px;
      display: grid;
      gap: 8px;
    }

    .form-grid {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 8px;
    }

    .full-btn { width: 100%; min-height: 48px; }

    .todo-input-row {
      display: flex;
      gap: 8px;
      margin: 16px 0;
    }

    .todo-list {
      display: grid;
      gap: 9px;
    }

    .todo-item {
      display: flex;
      align-items: center;
      gap: 12px;
      border: 1px solid var(--line);
      background: var(--panel-2);
      border-radius: var(--radius-lg);
      padding: 12px;
      transition: background .18s ease, border-color .18s ease;
    }

    .check-btn {
      border: 0;
      background: transparent;
      color: var(--text);
      font-size: 20px;
      width: 26px;
      height: 26px;
      padding: 0;
    }

    .todo-text {
      flex: 1;
      min-width: 0;
      font-size: 14px;
    }

    .todo-item.done .todo-text {
      color: var(--muted);
      text-decoration: line-through;
    }

    .focus-pill {
      border: 1px solid var(--line);
      border-radius: 999px;
      padding: 5px 10px;
      color: var(--muted);
      font-size: 12px;
      display: none;
    }

    body.focus-mode .calendar-section,
    body.focus-mode .notes-section { display: none; }
    body.focus-mode .focus-pill { display: inline-block; }

    .bottom-nav {
      position: fixed;
      left: 50%;
      bottom: 14px;
      transform: translateX(-50%);
      z-index: 50;
      width: min(520px, calc(100% - 24px));
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: 6px;
      padding: 8px;
      border: 1px solid var(--line);
      border-radius: 999px;
      background: color-mix(in srgb, var(--panel) 92%, transparent);
      box-shadow: 0 18px 60px var(--shadow);
      backdrop-filter: blur(18px);
    }

    .nav-btn {
      display: grid;
      place-items: center;
      gap: 2px;
      min-height: 48px;
      border: 0;
      border-radius: 999px;
      background: transparent;
      color: var(--muted);
      font-size: 10px;
      font-weight: 700;
    }

    .nav-btn svg {
      width: 17px;
      height: 17px;
    }

    .nav-btn.active {
      background: var(--button-bg);
      color: var(--button-text);
    }


    @media (min-width: 768px) {
      .app {
        padding: 32px 24px 104px;
      }

      .panel-shell {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 16px;
      }

      .panel {
        margin-bottom: 0;
      }

      .hero {
        grid-column: 1 / -1;
      }

      .calendar-section,
      .notes-section,
      .todo-section {
        min-width: 0;
      }

      body.fullscreen-panel .panel.active-fullscreen-panel {
        grid-column: 1 / -1;
      }
    }

    @media (min-width: 640px) {
      .app { padding-top: 32px; }
    }
  </style>
</head>
<body>
  <main class="app">
    <div class="panel-shell" id="panelShell">
    <section class="panel hero" data-panel="home" draggable="true">
      <div class="top-row">
        <div>
          <p class="eyebrow">Family planner</p>
          <h1 class="font-scotch">Calendar</h1>
          <p class="subtext" id="activeScheduleText">Viewing all schedules</p>
        </div>
        <div class="hero-actions">
          <span class="drag-handle" aria-label="Drag panel">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
              <path d="M8 6h.01M16 6h.01M8 12h.01M16 12h.01M8 18h.01M16 18h.01"></path>
            </svg>
          </span>
          <button class="icon-btn" id="themeToggleBtn" aria-label="Toggle theme"></button>
          <button class="icon-btn" id="toggleCalendarBtn" aria-label="Hide calendar">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
              <path d="M3 5h18"></path>
              <path d="M7 3v4"></path>
              <path d="M17 3v4"></path>
              <rect x="3" y="5" width="18" height="16" rx="2"></rect>
              <path d="M8 11h.01"></path>
              <path d="M12 11h.01"></path>
              <path d="M16 11h.01"></path>
              <path d="M8 15h.01"></path>
              <path d="M12 15h.01"></path>
            </svg>
          </button>
        </div>
      </div>
      <div class="chips" id="peopleChips"></div>
      <div class="input-row">
        <input id="personInput" type="text" placeholder="Add person or pet" />
        <button class="add-btn" id="addPersonBtn">Add</button>
      </div>
    </section>

    <section class="panel calendar-section" data-panel="calendar" draggable="true">
      <div class="month-row">
        <button class="month-btn" id="prevMonthBtn" aria-label="Previous month">
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
            <path d="M15 18l-6-6 6-6"></path>
          </svg>
        </button>
        <div class="month-title">
          <div class="calendar-icon">▦</div>
          <h2 class="font-scotch" id="monthTitle"></h2>
        </div>
        <button class="month-btn" id="nextMonthBtn" aria-label="Next month">
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
            <path d="M9 18l6-6-6-6"></path>
          </svg>
        </button>
      </div>

      <div class="weekdays">
        <div>S</div><div>M</div><div>T</div><div>W</div><div>T</div><div>F</div><div>S</div>
      </div>
      <div class="calendar-grid" id="calendarGrid"></div>
    </section>

    <section class="panel notes-section" data-panel="notes" draggable="true">
      <div>
        <h2 class="font-scotch">Notes</h2>
        <p class="subtext" id="selectedDateLabel"></p>
      </div>

      <div class="note-list" id="noteList"></div>

      <div class="note-form">
        <input id="noteTitleInput" type="text" placeholder="Note title" />
        <textarea id="noteDetailsInput" placeholder="Details"></textarea>
        <div class="form-grid">
          <select id="notePersonSelect"></select>
          <select id="noteColorSelect">
            <option value="white">White</option>
            <option value="gray">Gray</option>
            <option value="slate">Slate</option>
            <option value="outline">Outline</option>
          </select>
        </div>
        <button class="add-btn full-btn" id="addNoteBtn">+ Add note</button>
      </div>
    </section>

    <section class="panel todo-section" data-panel="todo" draggable="true">
      <div class="section-head">
        <div>
          <h2 class="font-scotch">To-do list</h2>
          <p class="subtext">Use calendar toggle to focus on tasks only.</p>
        </div>
        <span class="focus-pill">Focus mode</span>
      </div>

      <div class="todo-input-row">
        <input id="todoInput" type="text" placeholder="Add a task" />
        <button class="add-btn" id="addTodoBtn">+</button>
      </div>
      <div class="todo-list" id="todoList"></div>
    </section>
    </div>

    <nav class="bottom-nav" aria-label="Panel navigation">
      <button class="nav-btn active" data-target-panel="all" type="button">
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
          <rect x="3" y="3" width="7" height="7" rx="1"></rect>
          <rect x="14" y="3" width="7" height="7" rx="1"></rect>
          <rect x="3" y="14" width="7" height="7" rx="1"></rect>
          <rect x="14" y="14" width="7" height="7" rx="1"></rect>
        </svg>
        All
      </button>
      <button class="nav-btn" data-target-panel="calendar" type="button">
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
          <rect x="3" y="5" width="18" height="16" rx="2"></rect>
          <path d="M16 3v4M8 3v4M3 10h18"></path>
        </svg>
        Calendar
      </button>
      <button class="nav-btn" data-target-panel="notes" type="button">
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
          <path d="M4 4h16v16H4z"></path>
          <path d="M8 8h8M8 12h8M8 16h5"></path>
        </svg>
        Notes
      </button>
      <button class="nav-btn" data-target-panel="todo" type="button">
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
          <path d="M9 11l3 3L22 4"></path>
          <path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"></path>
        </svg>
        To-do
      </button>
    </nav>
  </main>

  <script>
    const state = {
      people: [
        { id: 'leia', name: 'Leia' },
        { id: 'lucas', name: 'Lucas' },
        { id: 'mom', name: 'Mom' },
        { id: 'dad', name: 'Dad' },
        { id: 'hiro', name: 'Hiro' }
      ],
      activePersonId: 'all',
      currentMonth: new Date(),
      selectedDate: toDateKey(new Date()),
      showCalendar: true,
      theme: 'light',
      notes: [
        {
          id: uid(),
          date: toDateKey(new Date()),
          personId: 'leia',
          title: 'School pickup',
          details: 'Bring extra snack and water bottle.',
          color: 'white'
        },
        {
          id: uid(),
          date: toDateKey(new Date()),
          personId: 'hiro',
          title: 'Walk Hiro',
          details: 'Evening walk after dinner.',
          color: 'outline'
        }
      ],
      todos: [
        { id: uid(), text: "Check tomorrow's schedule", done: false },
        { id: uid(), text: "Pack Leia's bag", done: true }
      ]
    };

    const peopleChips = document.getElementById('peopleChips');
    const activeScheduleText = document.getElementById('activeScheduleText');
    const personInput = document.getElementById('personInput');
    const addPersonBtn = document.getElementById('addPersonBtn');
    const toggleCalendarBtn = document.getElementById('toggleCalendarBtn');
    const themeToggleBtn = document.getElementById('themeToggleBtn');
    const prevMonthBtn = document.getElementById('prevMonthBtn');
    const nextMonthBtn = document.getElementById('nextMonthBtn');
    const monthTitle = document.getElementById('monthTitle');
    const calendarGrid = document.getElementById('calendarGrid');
    const selectedDateLabel = document.getElementById('selectedDateLabel');
    const noteList = document.getElementById('noteList');
    const noteTitleInput = document.getElementById('noteTitleInput');
    const noteDetailsInput = document.getElementById('noteDetailsInput');
    const notePersonSelect = document.getElementById('notePersonSelect');
    const noteColorSelect = document.getElementById('noteColorSelect');
    const addNoteBtn = document.getElementById('addNoteBtn');
    const todoInput = document.getElementById('todoInput');
    const addTodoBtn = document.getElementById('addTodoBtn');
    const todoList = document.getElementById('todoList');
    const panelShell = document.getElementById('panelShell');
    const navButtons = document.querySelectorAll('.nav-btn');

    const SUN_ICON = `
      <svg width="18" height="18" viewBox="0 0 24 24" fill="none"
           stroke="currentColor" stroke-width="2"
           stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
        <circle cx="12" cy="12" r="4"></circle>
        <path d="M12 2v2"></path>
        <path d="M12 20v2"></path>
        <path d="M4.93 4.93l1.41 1.41"></path>
        <path d="M17.66 17.66l1.41 1.41"></path>
        <path d="M2 12h2"></path>
        <path d="M20 12h2"></path>
        <path d="M4.93 19.07l1.41-1.41"></path>
        <path d="M17.66 6.34l1.41-1.41"></path>
      </svg>
    `;

    const MOON_ICON = `
      <svg width="18" height="18" viewBox="0 0 24 24" fill="none"
           stroke="currentColor" stroke-width="2"
           stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
        <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
      </svg>
    `;

    const CALENDAR_ICON = `
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
          <path d="M3 5h18"></path>
          <path d="M7 3v4"></path>
          <path d="M17 3v4"></path>
          <rect x="3" y="5" width="18" height="16" rx="2"></rect>
          <path d="M8 11h.01"></path>
          <path d="M12 11h.01"></path>
          <path d="M16 11h.01"></path>
          <path d="M8 15h.01"></path>
          <path d="M12 15h.01"></path>
        </svg>
      `;

    const CALENDAR_OFF_ICON = `
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
          <path d="M3 5h18"></path>
          <path d="M7 3v4"></path>
          <path d="M17 3v4"></path>
          <rect x="3" y="5" width="18" height="16" rx="2"></rect>
          <path d="M3 3l18 18"></path>
        </svg>
      `;


    addPersonBtn.addEventListener('click', addPerson);
    personInput.addEventListener('keydown', event => {
      if (event.key === 'Enter') addPerson();
    });
    toggleCalendarBtn.addEventListener('click', toggleCalendar);
    themeToggleBtn.addEventListener('click', toggleTheme);
    prevMonthBtn.addEventListener('click', () => changeMonth(-1));
    nextMonthBtn.addEventListener('click', () => changeMonth(1));
    addNoteBtn.addEventListener('click', addNote);
    addTodoBtn.addEventListener('click', addTodo);
    todoInput.addEventListener('keydown', event => {
      if (event.key === 'Enter') addTodo();
    });

    navButtons.forEach(button => {
      button.addEventListener('click', () => setActivePanel(button.dataset.targetPanel));
    });

    let draggedPanel = null;

    panelShell.addEventListener('dragstart', event => {
      const panel = event.target.closest('.panel[draggable="true"]');
      if (!panel) return;
      draggedPanel = panel;
      panel.classList.add('dragging');
      event.dataTransfer.effectAllowed = 'move';
    });

    panelShell.addEventListener('dragend', () => {
      if (draggedPanel) draggedPanel.classList.remove('dragging');
      draggedPanel = null;
    });

    panelShell.addEventListener('dragover', event => {
      event.preventDefault();
      const afterElement = getDragAfterElement(panelShell, event.clientY);
      if (!draggedPanel) return;
      if (afterElement == null) {
        panelShell.appendChild(draggedPanel);
      } else {
        panelShell.insertBefore(draggedPanel, afterElement);
      }
    });

    function setActivePanel(panelName) {
      document.body.classList.toggle('fullscreen-panel', panelName !== 'all');

      document.querySelectorAll('.panel').forEach(panel => {
        panel.classList.toggle('active-fullscreen-panel', panel.dataset.panel === panelName);
      });

      navButtons.forEach(button => {
        button.classList.toggle('active', button.dataset.targetPanel === panelName);
      });

      if (panelName !== 'all') {
        window.scrollTo({ top: 0, behavior: 'smooth' });
      }
    }

    function getDragAfterElement(container, y) {
      const draggableElements = [...container.querySelectorAll('.panel[draggable="true"]: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, element: child };
        }

        return closest;
      }, { offset: Number.NEGATIVE_INFINITY }).element;
    }

    function uid() {
      return Date.now().toString(36) + Math.random().toString(36).slice(2);
    }

    function toDateKey(date) {
      return date.toISOString().slice(0, 10);
    }

    function parseDateKey(key) {
      return new Date(key + 'T00:00:00');
    }

    function getVisibleNotes() {
      return state.notes.filter(note => state.activePersonId === 'all' || note.personId === state.activePersonId);
    }

    function getPersonName(id) {
      return state.people.find(person => person.id === id)?.name || 'Schedule';
    }

    function addPerson() {
      const name = personInput.value.trim();
      if (!name) return;
      const id = name.toLowerCase().replace(/[^a-z0-9]+/g, '-') + '-' + Date.now();
      state.people.push({ id, name });
      state.activePersonId = id;
      personInput.value = '';
      render();
    }

    function toggleCalendar() {
      state.showCalendar = !state.showCalendar;
      document.body.classList.toggle('focus-mode', !state.showCalendar);
      toggleCalendarBtn.innerHTML = state.showCalendar ? CALENDAR_ICON : CALENDAR_OFF_ICON;
      toggleCalendarBtn.setAttribute('aria-label', state.showCalendar ? 'Hide calendar' : 'Show calendar');

      if (!state.showCalendar) {
        setActivePanel('todo');
      } else {
        setActivePanel('all');
      }
    }

    function toggleTheme() {
      state.theme = state.theme === 'dark' ? 'light' : 'dark';

      document.body.classList.toggle('light-mode', state.theme === 'light');

      themeToggleBtn.innerHTML = state.theme === 'light' ? SUN_ICON : MOON_ICON;
      themeToggleBtn.setAttribute(
        'aria-label',
        state.theme === 'light' ? 'Switch to dark mode' : 'Switch to light mode'
      );
    }

    function changeMonth(direction) {
      state.currentMonth = new Date(
        state.currentMonth.getFullYear(),
        state.currentMonth.getMonth() + direction,
        1
      );
      renderCalendar();
    }

    function addNote() {
      const title = noteTitleInput.value.trim();
      const details = noteDetailsInput.value.trim();
      if (!title) return;

      state.notes.push({
        id: uid(),
        date: state.selectedDate,
        personId: notePersonSelect.value,
        title,
        details,
        color: noteColorSelect.value
      });

      noteTitleInput.value = '';
      noteDetailsInput.value = '';
      renderCalendar();
      renderNotes();
    }

    function deleteNote(id) {
      state.notes = state.notes.filter(note => note.id !== id);
      renderCalendar();
      renderNotes();
    }

    function addTodo() {
      const text = todoInput.value.trim();
      if (!text) return;
      state.todos.unshift({ id: uid(), text, done: false });
      todoInput.value = '';
      renderTodos();
    }

    function toggleTodo(id) {
      state.todos = state.todos.map(todo => todo.id === id ? { ...todo, done: !todo.done } : todo);
      renderTodos();
    }

    function deleteTodo(id) {
      state.todos = state.todos.filter(todo => todo.id !== id);
      renderTodos();
    }

    function renderPeople() {
      peopleChips.innerHTML = '';

      const allButton = document.createElement('button');
      allButton.className = 'person-chip' + (state.activePersonId === 'all' ? ' active' : '');
      allButton.textContent = 'All';
      allButton.addEventListener('click', () => {
        state.activePersonId = 'all';
        render();
      });
      peopleChips.appendChild(allButton);

      state.people.forEach(person => {
        const button = document.createElement('button');
        button.className = 'person-chip' + (state.activePersonId === person.id ? ' active' : '');
        button.textContent = person.name;
        button.addEventListener('click', () => {
          state.activePersonId = person.id;
          render();
        });
        peopleChips.appendChild(button);
      });

      activeScheduleText.textContent = state.activePersonId === 'all'
        ? 'Viewing all schedules'
        : 'Viewing ' + getPersonName(state.activePersonId) + "'s schedule";
    }

    function renderPersonSelect() {
      notePersonSelect.innerHTML = '';
      state.people.forEach(person => {
        const option = document.createElement('option');
        option.value = person.id;
        option.textContent = person.name;
        notePersonSelect.appendChild(option);
      });

      if (state.activePersonId !== 'all') {
        notePersonSelect.value = state.activePersonId;
      }
    }

    function renderCalendar() {
      const year = state.currentMonth.getFullYear();
      const month = state.currentMonth.getMonth();
      const firstDay = new Date(year, month, 1);
      const lastDay = new Date(year, month + 1, 0);
      const startOffset = firstDay.getDay();
      const visibleNotes = getVisibleNotes();
      const todayKey = toDateKey(new Date());

      monthTitle.textContent = state.currentMonth.toLocaleDateString(undefined, {
        month: 'long',
        year: 'numeric'
      });

      calendarGrid.innerHTML = '';

      for (let i = 0; i < startOffset; i++) {
        const blank = document.createElement('div');
        blank.className = 'blank-day';
        calendarGrid.appendChild(blank);
      }

      for (let day = 1; day <= lastDay.getDate(); day++) {
        const date = new Date(year, month, day);
        const dateKey = toDateKey(date);
        const dayNotes = visibleNotes.filter(note => note.date === dateKey);

        const button = document.createElement('button');
        button.className = 'day';
        if (dateKey === todayKey) button.classList.add('today');
        if (dateKey === state.selectedDate) button.classList.add('selected');

        button.innerHTML = `
          <span class="day-number">${day}</span>
          <span class="dot-row">${dayNotes.slice(0, 3).map(() => '<span class="dot"></span>').join('')}</span>
        `;

        button.addEventListener('click', () => {
          state.selectedDate = dateKey;
          renderCalendar();
          renderNotes();
        });

        calendarGrid.appendChild(button);
      }
    }

    function renderNotes() {
      const visibleNotes = getVisibleNotes().filter(note => note.date === state.selectedDate);
      selectedDateLabel.textContent = parseDateKey(state.selectedDate).toLocaleDateString(undefined, {
        weekday: 'long',
        month: 'long',
        day: 'numeric'
      });

      noteList.innerHTML = '';

      if (visibleNotes.length === 0) {
        const empty = document.createElement('div');
        empty.className = 'empty';
        empty.textContent = 'No notes for this date yet.';
        noteList.appendChild(empty);
        return;
      }

      visibleNotes.forEach(note => {
        const article = document.createElement('article');
        article.className = 'note-card note-' + note.color;
        article.innerHTML = `
          <div class="note-title-row">
            <div>
              <p class="note-person">${escapeHtml(getPersonName(note.personId))}</p>
              <h3>${escapeHtml(note.title)}</h3>
              ${note.details ? `<p class="note-details">${escapeHtml(note.details)}</p>` : ''}
            </div>
            <button class="delete-note" aria-label="Delete note">×</button>
          </div>
        `;
        article.querySelector('.delete-note').addEventListener('click', () => deleteNote(note.id));
        noteList.appendChild(article);
      });
    }

    function renderTodos() {
      todoList.innerHTML = '';

      state.todos.forEach(todo => {
        const item = document.createElement('div');
        item.className = 'todo-item' + (todo.done ? ' done' : '');
        item.innerHTML = `
          <button class="check-btn" aria-label="Toggle task">${todo.done ? '✓' : '○'}</button>
          <span class="todo-text">${escapeHtml(todo.text)}</span>
          <button class="delete-todo" aria-label="Delete task">🗑</button>
        `;
        item.querySelector('.check-btn').addEventListener('click', () => toggleTodo(todo.id));
        item.querySelector('.delete-todo').addEventListener('click', () => deleteTodo(todo.id));
        todoList.appendChild(item);
      });
    }

    function escapeHtml(value) {
      return String(value)
        .replaceAll('&', '&')
        .replaceAll('<', '<')
        .replaceAll('>', '>')
        .replaceAll('"', '"')
        .replaceAll("'", ''');
    }

    function render() {
      renderPeople();
      renderPersonSelect();
      renderCalendar();
      renderNotes();
      renderTodos();
    }

    document.body.classList.add('light-mode');
    themeToggleBtn.innerHTML = SUN_ICON;
    themeToggleBtn.setAttribute('aria-label', 'Switch to dark mode');
    toggleCalendarBtn.innerHTML = CALENDAR_ICON;
    setActivePanel('all');
    render();
  </script>
</body>
</html>