/* Plannen — klikbaar prototype (state-machine router, reuse polish shared components)
   Doel: validatie van interactie-flows en coverage van features V4.
   Gebouwd: 18 apr 2026, Robin + Claude.

   Routes (in-memory state):
   - /                      → Home (Stapel) — DEFAULT
   - /add-deadline          → Deadline toevoegen stap 1: form
   - /add-deadline/split    → Deadline toevoegen stap 2: block-split
   - /add-deadline/place    → Deadline toevoegen stap 3: drag blocks to days
   - /deadline/:id          → Deadline-drawer
   - /focus                 → Focus-mode takeover
   - /week                  → Week-view (7-dagen)
   - /week/:day             → Dag-detail-drawer met quick-add
   - /herplan               → Herplan-flow (Free/Premium)
   - /settings              → Instellingen
   - /settings/tijd/:day    → Tijdvenster inline-edit
*/

const { useState, useEffect, useMemo, useRef } = React;

/* ═══════════════════════════════════════════════════════════════════
   MOCK DATA
   ═══════════════════════════════════════════════════════════════════ */

// Deadline-types en hun metadata
// - toets/so: test-events (met voorbereidings-ladder, urgentie hoog)
// - inlever: iets wat af moet (essay, verslag)
// - maakwerk: huiswerk-opgaves (maak-/oefenwerk, niet voor toets)
// - leerwerk: leer-huiswerk (woordjes, begrippen, zonder toets)
const DEADLINE_TYPES = {
  toets:    { label: 'Toets',    short: 'TOETS', icon: 'flag',        defaultHours: 3 },
  so:       { label: 'SO',       short: 'SO',    icon: 'flag',        defaultHours: 1 },
  inlever:  { label: 'Inleveren',short: 'INLEV', icon: 'upload',      defaultHours: 4 },
  maakwerk: { label: 'Maakwerk', short: 'MAAK',  icon: 'pencil',      defaultHours: 1 },
  leerwerk: { label: 'Leerwerk', short: 'LEER',  icon: 'book-open',   defaultHours: 1.5 },
};

// "Grote" types = op de toetsen-strip zichtbaar (test-events); maak/leer zijn kleiner huiswerk.
const BIG_DEADLINE_TYPES = ['toets', 'so', 'inlever'];

const INITIAL_DEADLINES = [
  // idealProgressPercent = waar je NU moet staan op schema; progressPercent = waar je WERKELIJK staat
  // unscheduled = nog geen blokken ingepland (bijv via quick-add of Magister-import)
  // dueDate kan null zijn ("anonieme" toets — datum nog onbekend)
  { id: 'd5', subject: 'frans', type: 'so', title: 'Frans SO — werkwoorden H6', dueDate: '2026-04-23', estimatedHours: 1, progressPercent: 40, idealProgressPercent: 60 },
  // Maakwerk + leerwerk voorbeelden
  { id: 'd6', subject: 'wiskunde', type: 'maakwerk', title: 'Opgaves 1–12 H7', dueDate: '2026-04-23', estimatedHours: 1, progressPercent: 20, idealProgressPercent: 50 },
  { id: 'd7', subject: 'duits', type: 'leerwerk', title: 'Wortschatz H5 uit het hoofd', dueDate: '2026-04-24', estimatedHours: 1.5, progressPercent: 0, idealProgressPercent: 30 },
  { id: 'd1', subject: 'biologie', type: 'toets', title: 'Bio-toets H4 — celbiologie', dueDate: '2026-04-25', estimatedHours: 3, progressPercent: 55, idealProgressPercent: 70, linkedQuizId: 'q1', linkedChapterId: 'c1' },
  { id: 'd2', subject: 'wiskunde', type: 'so', title: 'Wisk SO — statistiek H7', dueDate: '2026-04-28', estimatedHours: 2, progressPercent: 30, idealProgressPercent: 35 },
  { id: 'd3', subject: 'engels', type: 'inlever', title: 'Essay — "my hero"', dueDate: '2026-05-02', estimatedHours: 4, progressPercent: 15, idealProgressPercent: 15 },
  { id: 'd4', subject: 'scheikunde', type: 'toets', title: 'Samenvatting H4', dueDate: '2026-04-29', estimatedHours: 2, progressPercent: 45, idealProgressPercent: 30 },
  // Ongeplande deadlines (te plannen bak)
  { id: 'u1', subject: 'geschiedenis', type: 'toets', title: 'Ges toets — interbellum', dueDate: '2026-05-08', unscheduled: true, source: 'manual' },
  { id: 'u2', subject: 'aardrijkskunde', type: 'inlever', title: 'Werkstuk klimaatzones', dueDate: '2026-05-15', unscheduled: true, source: 'magister' },
  { id: 'u3', subject: 'natuurkunde', type: 'toets', title: 'Natk toets — krachten', dueDate: null, unscheduled: true, source: 'manual', noDate: true }, // anonieme toets
];

// Mock: 12 items die net via Magister-koppeling binnenkwamen
const MAGISTER_IMPORT_DEADLINES = [
  { id: 'm1', subject: 'wiskunde', type: 'toets', title: 'Wisk SO H7 — statistiek', dueDate: '2026-04-28', unscheduled: true, source: 'magister' },
  { id: 'm2', subject: 'biologie', type: 'toets', title: 'Bio H4 — celbiologie', dueDate: '2026-04-25', unscheduled: true, source: 'magister' },
  { id: 'm3', subject: 'engels', type: 'inlever', title: 'Essay "my hero"', dueDate: '2026-05-02', unscheduled: true, source: 'magister' },
  { id: 'm4', subject: 'frans', type: 'so', title: 'Frans SO werkwoorden H6', dueDate: '2026-04-23', unscheduled: true, source: 'magister' },
  { id: 'm5', subject: 'geschiedenis', type: 'toets', title: 'Ges interbellum', dueDate: '2026-05-08', unscheduled: true, source: 'magister' },
  { id: 'm6', subject: 'scheikunde', type: 'toets', title: 'Sk samenvatting H4', dueDate: '2026-04-29', unscheduled: true, source: 'magister' },
  { id: 'm7', subject: 'aardrijkskunde', type: 'inlever', title: 'Werkstuk klimaatzones', dueDate: '2026-05-15', unscheduled: true, source: 'magister' },
  { id: 'm8', subject: 'natuurkunde', type: 'toets', title: 'Natk krachten H6', dueDate: '2026-05-12', unscheduled: true, source: 'magister' },
  { id: 'm9', subject: 'nederlands', type: 'inlever', title: 'Boekverslag', dueDate: '2026-05-19', unscheduled: true, source: 'magister' },
  { id: 'm10', subject: 'duits', type: 'so', title: 'Duits SO Wortschatz', dueDate: '2026-04-30', unscheduled: true, source: 'magister' },
  { id: 'm11', subject: 'economie', type: 'toets', title: 'Eco micro-economie', dueDate: '2026-05-06', unscheduled: true, source: 'magister' },
  { id: 'm12', subject: 'informatica', type: 'inlever', title: 'Info practicum Python', dueDate: '2026-05-22', unscheduled: true, source: 'magister' },
];

// Toets-ladder steps per deadline — welke stappen naar de toets
const DEADLINE_LADDER = {
  d1: [
    { label: 'Hoofdstuk lezen', type: 'lezen', done: true },
    { label: 'Samenvatting maken', type: 'schrijven', done: true },
    { label: 'Flashcards ronde 1', type: 'oefenen', done: false, isNow: true, progress: 55 },
    { label: 'Oefenopgaves', type: 'oefenen', done: false, progress: 0 },
    { label: 'Flashcards ronde 2 + herhalen', type: 'oefenen', done: false, progress: 0 },
  ],
  d2: [
    { label: 'Theorie H7 lezen', type: 'lezen', done: true },
    { label: 'Oefenopgaves set A', type: 'oefenen', done: false, isNow: true, progress: 30 },
    { label: 'Proeftoets', type: 'oefenen', done: false, progress: 0 },
  ],
  d3: [
    { label: 'Onderwerp kiezen', type: 'schrijven', done: true },
    { label: 'Outline schrijven', type: 'schrijven', done: false, isNow: true, progress: 60 },
    { label: 'Eerste versie', type: 'schrijven', done: false, progress: 0 },
    { label: 'Revisie', type: 'schrijven', done: false, progress: 0 },
  ],
  d4: [
    { label: 'H4 doorlezen', type: 'lezen', done: true },
    { label: 'Samenvatting schrijven', type: 'schrijven', done: false, isNow: true, progress: 45 },
    { label: 'Overhoren', type: 'overhoren', done: false, progress: 0 },
  ],
  d5: [
    { label: 'Woordenschat H6 leren', type: 'overhoren', done: false, isNow: true, progress: 40 },
    { label: 'Oefenvragen werkwoorden', type: 'oefenen', done: false, progress: 0 },
  ],
  d6: [
    { label: 'Opgaves 1–6 maken', type: 'oefenen', done: false, isNow: true, progress: 20 },
    { label: 'Opgaves 7–12 maken', type: 'oefenen', done: false, progress: 0 },
  ],
  d7: [
    { label: 'Eerste ronde lezen', type: 'lezen', done: false, isNow: true, progress: 0 },
    { label: 'Overhoren', type: 'overhoren', done: false, progress: 0 },
  ],
};

// Progress-status functie: bepaalt kleur o.b.v. actual vs ideal progress
function progressStatus(actual, ideal) {
  if (actual >= ideal + 5) return 'ahead';   // groen — voor op schema
  if (actual >= ideal - 10) return 'onTrack'; // cyan — op schema
  if (actual >= ideal - 20) return 'behind';  // amber — licht achter
  return 'risk';                              // rood — risico
}

function progressColor(t, status) {
  return status === 'ahead' ? t.green
       : status === 'onTrack' ? t.primary
       : status === 'behind' ? t.warn
       : t.red;
}

function progressLabel(status) {
  return status === 'ahead' ? 'Voor op schema'
       : status === 'onTrack' ? 'Op schema'
       : status === 'behind' ? 'Licht achter'
       : 'Risico — inhalen';
}

const INITIAL_TASKS_TODAY = [
  { id: 't1', subject: 'biologie', type: 'lezen', title: 'Celbiologie §4.2 lezen', mins: 25, scheduledTime: '15:30–15:55', deadlineId: 'd1', done: false, isNow: true },
  { id: 't2', subject: 'wiskunde', type: 'oefenen', title: 'Statistiek — 3 oefenopgaves', mins: 20, scheduledTime: '16:00–16:20', deadlineId: 'd2', done: false },
  { id: 't3', subject: 'engels', type: 'schrijven', title: 'Essay-paragraaf 2 schrijven', mins: 15, scheduledTime: '19:30–19:45', deadlineId: 'd3', done: false },
  // Losse taak — niet aan een deadline gekoppeld (eigen idee om alvast iets te oefenen)
  { id: 't6', subject: 'natuurkunde', type: 'lezen', title: 'Even §3 doorlezen', mins: 15, scheduledTime: '20:00–20:15', deadlineId: null, standalone: true, done: false },
];

const INITIAL_TASKS_TOMORROW = [
  { id: 't4', subject: 'scheikunde', type: 'lezen', title: '§ 4.2 samenvatting lezen', mins: 20, deadlineId: 'd4', done: false },
  { id: 't5', subject: 'frans', type: 'overhoren', title: 'Woordenschat H6 overhoren', mins: 15, deadlineId: 'd5', done: false },
];

// Schoolvakanties per regio (Nederland kent Noord / Midden / Zuid voor grootste vakanties)
// Bron: rijksoverheid.nl — hier gemockt met realistische periodes.
const VACATIONS_BY_REGION = {
  noord: [
    { id: 'v1', name: 'Voorjaarsvakantie', start: '2026-02-14', end: '2026-02-22' },
    { id: 'v2', name: 'Meivakantie', start: '2026-05-05', end: '2026-05-11' },
    { id: 'v3', name: 'Zomervakantie', start: '2026-07-11', end: '2026-08-23' },
    { id: 'v4', name: 'Herfstvakantie', start: '2026-10-10', end: '2026-10-18' },
    { id: 'v5', name: 'Kerstvakantie', start: '2026-12-19', end: '2027-01-03' },
  ],
  midden: [
    { id: 'v1', name: 'Voorjaarsvakantie', start: '2026-02-21', end: '2026-03-01' },
    { id: 'v2', name: 'Meivakantie', start: '2026-05-05', end: '2026-05-11' },
    { id: 'v3', name: 'Zomervakantie', start: '2026-07-18', end: '2026-08-30' },
    { id: 'v4', name: 'Herfstvakantie', start: '2026-10-17', end: '2026-10-25' },
    { id: 'v5', name: 'Kerstvakantie', start: '2026-12-19', end: '2027-01-03' },
  ],
  zuid: [
    { id: 'v1', name: 'Voorjaarsvakantie', start: '2026-02-14', end: '2026-02-22' },
    { id: 'v2', name: 'Meivakantie', start: '2026-05-05', end: '2026-05-11' },
    { id: 'v3', name: 'Zomervakantie', start: '2026-07-04', end: '2026-08-16' },
    { id: 'v4', name: 'Herfstvakantie', start: '2026-10-24', end: '2026-11-01' },
    { id: 'v5', name: 'Kerstvakantie', start: '2026-12-19', end: '2027-01-03' },
  ],
};

// Check of een iso-datum in een vakantie valt — returns vakantie-object of null.
function vacationForDate(isoDate, vacations) {
  if (!isoDate || !vacations) return null;
  return vacations.find(v => isoDate >= v.start && isoDate <= v.end) || null;
}

// Mock day-labels — prototype-kalender wijkt af van echte 2026-kalender (mock "vandaag" = di 22 apr)
const MOCK_DAY_LABELS = {
  '2026-04-20': { day: 'ZO', date: 20 }, // vorige zondag (buiten zicht)
  '2026-04-21': { day: 'MA', date: 21 },
  '2026-04-22': { day: 'DI', date: 22 },
  '2026-04-23': { day: 'WO', date: 23 },
  '2026-04-24': { day: 'DO', date: 24 },
  '2026-04-25': { day: 'VR', date: 25 },
  '2026-04-26': { day: 'ZA', date: 26 },
  '2026-04-27': { day: 'ZO', date: 27 },
  '2026-04-28': { day: 'MA', date: 28 },
  '2026-04-29': { day: 'DI', date: 29 },
  '2026-04-30': { day: 'WO', date: 30 },
  '2026-05-01': { day: 'DO', date: 1 },
  '2026-05-02': { day: 'VR', date: 2 },
  // Toetsweek (10–17 juni) — mock-labels matching de prototype-kalender
  '2026-06-10': { day: 'MA', date: 10 },
  '2026-06-11': { day: 'DI', date: 11 },
  '2026-06-12': { day: 'WO', date: 12 },
  '2026-06-13': { day: 'DO', date: 13 },
  '2026-06-14': { day: 'VR', date: 14 },
  '2026-06-15': { day: 'ZA', date: 15 },
  '2026-06-16': { day: 'ZO', date: 16 },
  '2026-06-17': { day: 'MA', date: 17 },
};

function mockDayLabel(isoDate) {
  if (MOCK_DAY_LABELS[isoDate]) return MOCK_DAY_LABELS[isoDate];
  // Fallback: echte JS-datum (kan afwijken van prototype-kalender)
  const d = new Date(isoDate);
  return { day: ['ZO','MA','DI','WO','DO','VR','ZA'][d.getDay()], date: d.getDate() };
}

// Mock items-per-dag voor aangrenzende weken (voor prev/next navigatie in mini-strip)
const MOCK_WEEK_ITEMS = {
  // Week 16 (14-20 april) — rustige week voor de toets-drukte
  '2026-04-14': [{ subject: 'biologie', short: 'Biol' }, { subject: 'wiskunde', short: 'Wisk' }],
  '2026-04-15': [{ subject: 'engels', short: 'Enge' }],
  '2026-04-16': [{ subject: 'scheikunde', short: 'Sche' }, { subject: 'frans', short: 'Fran' }],
  '2026-04-17': [{ subject: 'biologie', short: 'Biol' }],
  '2026-04-18': [{ subject: 'wiskunde', short: 'Wisk' }],
  '2026-04-19': [],
  '2026-04-20': [],
  // Week 18 (28 april – 4 mei) — Wisk SO + essay
  '2026-04-28': [{ subject: 'wiskunde', short: 'Wisk' }, { subject: 'engels', short: 'Enge' }],
  '2026-04-29': [{ subject: 'scheikunde', short: 'Sche' }, { subject: 'biologie', short: 'Biol' }],
  '2026-04-30': [{ subject: 'engels', short: 'Enge' }],
  '2026-05-01': [{ subject: 'engels', short: 'Enge', count: 2 }],
  '2026-05-02': [],
  '2026-05-03': [],
  '2026-05-04': [],
  // Week 19 (5-11 mei) — meivakantie
  '2026-05-05': [], '2026-05-06': [], '2026-05-07': [], '2026-05-08': [],
  '2026-05-09': [], '2026-05-10': [], '2026-05-11': [],
};

const INITIAL_WEEK = [
  { label: 'MA', date: 21, isoDate: '2026-04-21', items: [{ subject: 'biologie', short: 'Biol' }, { subject: 'wiskunde', short: 'Wisk' }], status: 'past' },
  { label: 'DI', date: 22, isoDate: '2026-04-22', items: [{ subject: 'biologie', short: 'Biol' }, { subject: 'wiskunde', short: 'Wisk' }, { subject: 'engels', short: 'Enge' }], isToday: true },
  { label: 'WO', date: 23, isoDate: '2026-04-23', items: [{ subject: 'scheikunde', short: 'Sche' }, { subject: 'frans', short: 'Fran' }] },
  { label: 'DO', date: 24, isoDate: '2026-04-24', items: [{ subject: 'biologie', short: 'Biol', count: 2 }] },
  { label: 'VR', date: 25, isoDate: '2026-04-25', items: [], deadline: { type: 'toets', subject: 'biologie', title: 'Bio H4' } },
  { label: 'ZA', date: 26, isoDate: '2026-04-26', items: [], isWeekend: true },
  { label: 'ZO', date: 27, isoDate: '2026-04-27', items: [{ subject: 'wiskunde', short: 'Wisk' }], isWeekend: true },
];

/* Study settings per dag-van-de-week — meerdere tijdvensters per dag mogelijk */
const INITIAL_STUDY_BLOCKS = {
  ma: { available: true, ranges: [{ start: '15:30', end: '17:30' }] },
  di: { available: true, ranges: [{ start: '08:00', end: '09:00' }, { start: '15:30', end: '18:00' }] }, // ochtend + middag voorbeeld
  wo: { available: false, ranges: [] },  // sport, geen tijd
  do: { available: true, ranges: [{ start: '15:30', end: '18:00' }] },
  vr: { available: false, ranges: [] },  // vrijdagavond uit
  za: { available: true, ranges: [{ start: '10:00', end: '12:00' }] },
  zo: { available: true, ranges: [{ start: '10:00', end: '12:00' }, { start: '19:00', end: '20:30' }] },
};

// Helper: duur van 1 range in minuten — ondersteunt over-middernacht (end < start)
function rangeMinutes(r) {
  const s = timeToMin(r.start);
  const e = timeToMin(r.end);
  if (e >= s) return e - s;
  return (1440 - s) + e; // wrap via middernacht
}

// Helper: totaal aantal minuten op een dag (som van alle ranges, midnight-aware)
function rangesTotalMinutes(ranges) {
  return (ranges || []).reduce((sum, r) => sum + rangeMinutes(r), 0);
}

// Helper: eerste range van een dag (voor backwards-compat waar alleen een start-tijd gevraagd wordt)
function firstRange(block) {
  return block && block.ranges && block.ranges[0];
}

const INITIAL_MISSED_TASKS = [
  { id: 'm1', subject: 'biologie', title: 'H4 lezen §4.1', missedDate: 'ma 21', mins: 30 },
  { id: 'm2', subject: 'scheikunde', title: 'Samenvatting H4', missedDate: 'di 22', mins: 45 },
];

const SUBJECT_SHORT = {
  wiskunde: 'Wisk', biologie: 'Biol', scheikunde: 'Sche', natuurkunde: 'Nat',
  geschiedenis: 'Gesc', aardrijkskunde: 'Aard', economie: 'Econ', informatica: 'Info',
  engels: 'Enge', nederlands: 'Nede', frans: 'Fran', duits: 'Duit', maatschappijleer: 'Maat',
};

/* ═══════════════════════════════════════════════════════════════════
   STATE MANAGEMENT (simple centralized store)
   ═══════════════════════════════════════════════════════════════════ */

// Override polish PulseMascot — fallback map naar bestaande assets (celebrating/happy/idle/thinking)
// zodat moods als 'encouraging'/'zen'/'sleeping'/'focused' niet 404'en
const MOOD_MAP = {
  encouraging: 'happy',
  'encouraging-warm': 'happy',
  zen: 'idle',
  sleeping: 'idle',
  focused: 'thinking',
  proud: 'celebrating',
  curious: 'thinking',
  amazed: 'celebrating',
  confused: 'thinking',
  excited: 'celebrating',
  cheerful: 'happy',
  sad: 'idle', // verboden in UI, fallback naar idle voor safety
};
// eslint-disable-next-line
window.PulseMascot = function PulseMascotSafe({ size = 36, mood = 'idle', style }) {
  const safeMood = ['idle', 'happy', 'celebrating', 'thinking'].includes(mood) ? mood : (MOOD_MAP[mood] || 'idle');
  const src = `polish/assets/pulse-${safeMood}.svg`;
  const width = Math.round(size * (200 / 280));
  return React.createElement('img', {
    src, alt: '', width, height: size,
    style: { display: 'block', flexShrink: 0, ...(style || {}) }
  });
};
// Re-alias so our local code uses the override
const PulseMascot = window.PulseMascot;

function usePrototypeStore() {
  const [route, setRoute] = useState({ path: '/', params: {} });
  const [plan, setPlan] = useState('free');        // 'free' | 'premium'
  const [theme, setTheme] = useState('dark');      // 'dark' | 'light'
  const [deadlines, setDeadlines] = useState(INITIAL_DEADLINES);
  const [tasksToday, setTasksToday] = useState(INITIAL_TASKS_TODAY);
  const [tasksTomorrow, setTasksTomorrow] = useState(INITIAL_TASKS_TOMORROW);
  const [week, setWeek] = useState(INITIAL_WEEK);
  const [studyBlocks, setStudyBlocks] = useState(INITIAL_STUDY_BLOCKS);
  const [missedTasks, setMissedTasks] = useState(INITIAL_MISSED_TASKS);
  const [zinModus, setZinModus] = useState(false); // "geen zin"-modus
  const [rustModus, setRustModus] = useState(false); // Rust-modus: neutrale kleuren, minder accent
  // Vakanties: regio-gebaseerde import + handmatige additions/edits
  const [schoolRegion, setSchoolRegion] = useState('noord'); // 'noord' | 'midden' | 'zuid'
  const [vacations, setVacations] = useState(VACATIONS_BY_REGION.noord);
  // Stiltetijden: periodes waarin geen reminders komen en Pulse niet plant (school, bedtime, eigen)
  const [quietBlocks, setQuietBlocks] = useState({
    ma: { available: true, ranges: [{ start: '08:30', end: '15:30', label: 'school' }, { start: '22:00', end: '07:00', label: 'bedtijd' }] },
    di: { available: true, ranges: [{ start: '08:30', end: '15:30', label: 'school' }, { start: '22:00', end: '07:00', label: 'bedtijd' }] },
    wo: { available: true, ranges: [{ start: '08:30', end: '12:30', label: 'school' }, { start: '22:00', end: '07:00', label: 'bedtijd' }] },
    do: { available: true, ranges: [{ start: '08:30', end: '15:30', label: 'school' }, { start: '22:00', end: '07:00', label: 'bedtijd' }] },
    vr: { available: true, ranges: [{ start: '08:30', end: '15:30', label: 'school' }, { start: '23:00', end: '08:00', label: 'bedtijd' }] },
    za: { available: true, ranges: [{ start: '23:00', end: '09:00', label: 'bedtijd' }] },
    zo: { available: true, ranges: [{ start: '22:00', end: '08:00', label: 'bedtijd' }] },
  });
  // Scenario-state voor het testen van alternatieve home-varianten
  const [scenario, setScenario] = useState('normaal'); // 'normaal' | 'nieuw' | 'vakantie' | 'allesklaar' | 'comeback' | 'burnout' | 'magister_import' | loading/error

  // Draft state voor Add-deadline flow
  const [deadlineDraft, setDeadlineDraft] = useState(null);

  useEffect(() => {
    document.body.className = theme === 'dark' ? 'is-dark' : 'is-light';
    document.documentElement.className = theme === 'dark' ? 'is-dark' : 'is-light';
  }, [theme]);

  const navigate = (path, params = {}) => {
    setRoute({ path, params });
    window.scrollTo(0, 0);
  };
  const goBack = () => navigate('/');

  return {
    route, navigate, goBack,
    plan, setPlan,
    theme, setTheme,
    deadlines, setDeadlines,
    tasksToday, setTasksToday,
    tasksTomorrow, setTasksTomorrow,
    week, setWeek,
    studyBlocks, setStudyBlocks,
    missedTasks, setMissedTasks,
    zinModus, setZinModus,
    rustModus, setRustModus,
    scenario, setScenario,
    schoolRegion, setSchoolRegion,
    vacations, setVacations,
    quietBlocks, setQuietBlocks,
    deadlineDraft, setDeadlineDraft,
  };
}

/* ═══════════════════════════════════════════════════════════════════
   PROTO-HEADER (plan-toggle + theme-toggle + route + back)
   ═══════════════════════════════════════════════════════════════════ */

function ProtoHeader({ store }) {
  const { route, navigate, plan, setPlan, theme, setTheme, scenario, setScenario } = store;
  const isHome = route.path === '/';
  return (
    <div className="proto-header">
      <span className="brand">🔬 Plannen — prototype</span>
      <span className="route">{route.path}{route.params.id ? `/${route.params.id}` : ''}</span>
      {!isHome && (
        <button className="back-btn" onClick={() => navigate('/')}>
          ← Home
        </button>
      )}
      <span className="divider" />
      {/* Scenario-dropdown — om Home in alternatieve states te zien */}
      <label style={{
        display: 'inline-flex', alignItems: 'center', gap: 6,
        fontSize: 10, fontWeight: 800, color: '#94A3B8',
        letterSpacing: 0.5, textTransform: 'uppercase',
      }}>
        Scenario
        <select
          value={scenario}
          onChange={(e) => setScenario(e.target.value)}
          style={{
            padding: '4px 8px', borderRadius: 6,
            background: '#1E293B', color: '#F1F5F9',
            border: '1px solid #334155',
            fontSize: 11, fontWeight: 700, cursor: 'pointer',
            textTransform: 'none', letterSpacing: 0,
          }}
        >
          <option value="normaal">Normaal</option>
          <option value="nieuw">Nieuwe gebruiker (leeg)</option>
          <option value="vakantie">Vakantie</option>
          <option value="allesklaar">Alles klaar</option>
          <option value="comeback">Comeback (4 dagen weg)</option>
          <option value="burnout">Pulse observeert</option>
          <option value="magister_import">Magister-import (12 ongepland)</option>
          <option value="loading">Loading</option>
          <option value="error_no_internet">Error — geen internet</option>
          <option value="error_save_fail">Error — save faalt</option>
        </select>
      </label>
      <button
        onClick={() => navigate('/settings')}
        style={{
          padding: '4px 10px', border: '1px solid #334155',
          background: 'transparent', color: '#F1F5F9', borderRadius: 6,
          fontSize: 11, fontWeight: 700, cursor: 'pointer',
        }}
      >⚙ Instellingen</button>
      <div className="plan-toggle">
        <button className={plan === 'free' ? 'active free' : ''} onClick={() => setPlan('free')}>Free</button>
        <button className={plan === 'premium' ? 'active' : ''} onClick={() => setPlan('premium')}>Premium</button>
      </div>
      <button
        onClick={() => store.setRustModus(!store.rustModus)}
        title="Rust-modus: minder kleuren, rustigere weergave"
        style={{
          padding: '4px 10px',
          border: `1px solid ${store.rustModus ? '#7C3AED' : '#334155'}`,
          background: store.rustModus ? 'rgba(124, 58, 237, 0.18)' : 'transparent',
          color: '#F1F5F9', borderRadius: 6,
          fontSize: 11, fontWeight: 700, cursor: 'pointer',
        }}
      >
        🌿 Rust
      </button>
      <button
        onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
        style={{
          padding: '4px 10px', border: '1px solid #334155',
          background: 'transparent', color: '#F1F5F9', borderRadius: 6,
          fontSize: 11, fontWeight: 700, cursor: 'pointer',
        }}
      >
        {theme === 'dark' ? '☀ Light' : '☾ Dark'}
      </button>
    </div>
  );
}

/* ═══════════════════════════════════════════════════════════════════
   UTILITIES
   ═══════════════════════════════════════════════════════════════════ */

function daysUntil(isoDate) {
  const target = new Date(isoDate);
  const today = new Date('2026-04-22'); // mock "vandaag"
  const diff = Math.round((target - today) / 86400000);
  return diff;
}

function t(theme) { return theme === 'dark' ? TK_DARK : TK_LIGHT; }

/* ═══════════════════════════════════════════════════════════════════
   RUST-MODUS — neutrale vak-kleuren voor rustige weergave
   Globaal via Context, per component lookup via subjectColor() helper
   ═══════════════════════════════════════════════════════════════════ */

const RustModusContext = React.createContext(false);
function useRustModus() { return React.useContext(RustModusContext); }

// Geef vak-kleur terug, of neutral grey als rust-modus aan staat
function subjectColor(subject, rm, tk) {
  if (rm) return tk.fgMute;
  return SUBJECTS[subject] || tk.fgMute;
}
// Alias helper voor tint-backgrounds
function subjectTint(subject, rm, tk, opacity = 0.14) {
  const c = rm ? tk.fgMute : (SUBJECTS[subject] || tk.fgMute);
  return hexToRgba(c, opacity);
}

/* ═══════════════════════════════════════════════════════════════════
   SCREEN: HOME (Stapel)
   ═══════════════════════════════════════════════════════════════════ */

function ScreenHome({ store }) {
  const tk = t(store.theme);
  const sc = store.scenario;

  // Loading + error scenario's renderen direct een alternatieve view
  if (sc === 'loading') return <HomeLoadingSkeleton tk={tk} store={store} />;
  if (sc === 'error_no_internet') return <HomeErrorBanner tk={tk} store={store} kind="no_internet" />;
  if (sc === 'error_save_fail') return <HomeErrorBanner tk={tk} store={store} kind="save_fail" />;

  const topbarSubtitle = sc === 'vakantie' ? 'Meivakantie · rustige week · zo 27 apr'
    : sc === 'allesklaar' ? 'Dinsdag 22 april · alles van vandaag is klaar'
    : sc === 'comeback' ? 'Dinsdag 22 april · welkom terug na 4 dagen'
    : sc === 'burnout' ? 'Dinsdag 22 april · Pulse heeft iets gezien'
    : sc === 'magister_import' ? 'Dinsdag 22 april · 12 nieuwe items uit Magister'
    : sc === 'nieuw' ? 'Dinsdag 22 april · welkom — nog geen planning'
    : 'Dinsdag 22 april · 14:03';

  return (
    <div style={{ background: tk.bgApp, minHeight: 'calc(100vh - 44px)' }}>
      <div style={{
        display: 'flex', maxWidth: 1440, margin: '0 auto',
        minHeight: 'calc(100vh - 44px)',
      }}>
        <Sidebar t={tk} active="plannen" />
        <div style={{ flex: 1, display: 'flex', flexDirection: 'column', minWidth: 0 }}>
          <Topbar t={tk} title="Plannen" subtitle={topbarSubtitle} />

          {/* Scenario-specific content */}
          {sc === 'vakantie' && <HomeScenarioVakantie tk={tk} store={store} />}
          {sc === 'allesklaar' && <HomeScenarioAllesKlaar tk={tk} store={store} />}
          {sc === 'comeback' && <HomeScenarioComeback tk={tk} store={store} />}
          {sc === 'burnout' && <HomeScenarioBurnout tk={tk} store={store} />}
          {sc === 'magister_import' && <HomeScenarioMagisterImport tk={tk} store={store} />}
          {sc === 'nieuw' && <HomeScenarioNieuw tk={tk} store={store} />}
          {sc === 'normaal' && <StapelContent store={store} />}
        </div>
      </div>
    </div>
  );
}

/* ═══════════════════════════════════════════════════════════════════
   TOETSEN — shared data + strip + preview + toggle
   ═══════════════════════════════════════════════════════════════════ */

// Toetsweek-deadlines — zelfde shape als INITIAL_DEADLINES + mock-specifieke extras (daysAway, timeLabel, current)
// Dit maakt dat DeadlineCardPrototype identiek werkt in normaal én toetsweek.
const TOETSWEEK_DEADLINES = [
  { id: 'b1', subject: 'biologie', type: 'toets', title: 'Bio H4-5 — celbiologie', dueDate: '2026-06-11', timeLabel: '09:00', progressPercent: 65, idealProgressPercent: 75, daysAway: 1, current: true, hint: 'Samenvatting + begrippen vanavond' },
  { id: 'b2', subject: 'frans', type: 'so', title: 'Frans SO — H6', dueDate: '2026-06-12', timeLabel: '09:00', progressPercent: 20, idealProgressPercent: 45, daysAway: 2 },
  { id: 'b3', subject: 'wiskunde', type: 'toets', title: 'Wisk toets H7', dueDate: '2026-06-12', timeLabel: '13:30', progressPercent: 30, idealProgressPercent: 45, daysAway: 2 },
  { id: 'b4', subject: 'geschiedenis', type: 'toets', title: 'Ges toets — interbellum', dueDate: '2026-06-13', timeLabel: '10:00', progressPercent: 15, idealProgressPercent: 35, daysAway: 3 },
  { id: 'b5', subject: 'engels', type: 'inlever', title: 'En essay — inleveren', dueDate: '2026-06-14', timeLabel: 'INL', progressPercent: 55, idealProgressPercent: 50, daysAway: 4 },
  { id: 'b6', subject: 'scheikunde', type: 'toets', title: 'Sk toets — zuren/basen', dueDate: '2026-06-14', timeLabel: '11:00', progressPercent: 10, idealProgressPercent: 25, daysAway: 4 },
  { id: 'b7', subject: 'nederlands', type: 'inlever', title: 'Ned verslag — inleveren', dueDate: '2026-06-17', timeLabel: '23:59', progressPercent: 40, idealProgressPercent: 20, daysAway: 7 },
];

// Unified checklist-lookup: DEADLINE_LADDER (d1-d5) + TOETSWEEK_CHECKLIST (b1-b7)
function getDeadlineChecklist(id) {
  return DEADLINE_LADDER[id] || TOETSWEEK_CHECKLIST[id] || [];
}

// Alle deadlines die op deze isoDate vallen (week-view gebruikt dit ipv hardcoded d.deadline)
function deadlinesOnDate(deadlines, isoDate) {
  return (deadlines || []).filter(d => d.dueDate === isoDate);
}

// Helper: resolve daysAway (override beats computed)
function resolveDaysAway(deadline) {
  return deadline.daysAway != null ? deadline.daysAway : daysUntil(deadline.dueDate);
}

// Zet deadlines om naar toets-strip items (shared: normale deadlines én toetsweek)
// Filtert: alleen "grote" deadline-types (toets/so/inlever); maakwerk/leerwerk zijn regulier huiswerk.
// Filtert ook ongeplande/dateloze deadlines uit (die staan in de Te-plannen bak).
function deriveToetsenFromDeadlines(deadlines) {
  return deadlines
    .filter(d => BIG_DEADLINE_TYPES.includes(d.type) && d.dueDate && !d.unscheduled)
    .slice()
    .sort((a, b) => a.dueDate.localeCompare(b.dueDate))
    .map((d, idx) => {
      const { day, date } = mockDayLabel(d.dueDate);
      const days = resolveDaysAway(d);
      const time = d.timeLabel || (d.type === 'inlever' ? 'INL' : '—');
      return {
        id: d.id,
        subject: d.subject,
        title: d.title.split(' — ')[0],
        day, date, time,
        daysAway: days,
        current: d.current != null ? d.current : idx === 0,
        inlever: d.type === 'inlever',
        hint: d.hint,
      };
    });
}

// Preview-card in Vandaag/Morgen kolom — visueel apart van TaskCard
function ToetsPreviewCard({ t, toets, variant, onClick }) {
  const rm = useRustModus();
  const sc = subjectColor(toets.subject, rm, t);
  const days = toets.daysAway;
  const badge = days === 0 ? 'VANDAAG' : days === 1 ? 'MORGEN' : `OVER ${days}D`;
  return (
    <button onClick={onClick} style={{
      width: '100%', textAlign: 'left', cursor: onClick ? 'pointer' : 'default',
      padding: '12px 14px 12px 14px', borderRadius: 12,
      background: `linear-gradient(135deg, ${hexToRgba(sc, 0.14)}, ${hexToRgba(sc, 0.05)})`,
      border: `1.5px solid ${hexToRgba(sc, 0.35)}`,
      borderLeft: `5px solid ${sc}`,
      boxShadow: `0 2px 14px ${hexToRgba(sc, 0.12)}`,
      display: 'flex', alignItems: 'center', gap: 10,
      marginBottom: 10,
    }}>
      <div style={{
        width: 34, height: 34, borderRadius: 8,
        background: hexToRgba(sc, 0.18), flexShrink: 0,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
      }}>
        <PI name="flag" size={16} color={sc} />
      </div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{
          fontSize: 9.5, fontWeight: 800, color: sc, letterSpacing: 0.6,
          textTransform: 'uppercase', display: 'flex', alignItems: 'center', gap: 6,
        }}>
          <span>{toets.inlever ? 'Inleveren' : 'Toets'} · {toets.time || toets.day}</span>
          <span style={{
            padding: '1px 6px', borderRadius: 3,
            background: sc, color: '#FFFFFF',
            fontSize: 8.5, fontWeight: 800, letterSpacing: 0.4,
          }}>{badge}</span>
        </div>
        <div style={{ fontSize: 13, fontWeight: 800, color: t.fg, marginTop: 2, lineHeight: 1.3 }}>
          {toets.title}
        </div>
        {toets.hint && (
          <div style={{ fontSize: 11, color: t.fgDim, fontWeight: 500, marginTop: 2 }}>
            {toets.hint}
          </div>
        )}
      </div>
      <PI name="chevron-right" size={14} color={t.fgMute} />
    </button>
  );
}

/* TopStripToggle verwijderd — week-strip is nu de enige view */

function StapelContent({ store, toetsweek, magisterImport, allesKlaar, comeback, nieuw, deadlinesOverride, tasksTodayOverride, tasksTomorrowOverride }) {
  const tk = t(store.theme);
  const { week, missedTasks, zinModus, navigate, setZinModus } = store;
  const deadlines = deadlinesOverride || store.deadlines;
  const tasksToday = tasksTodayOverride || store.tasksToday;
  const tasksTomorrow = tasksTomorrowOverride || store.tasksTomorrow;
  // readOnly alleen wanneer expliciet — niet automatisch bij override.
  // Bij AllesKlaar wil student nog kunnen uncheck'en (niet informatie kwijt).
  const readOnly = false;

  // Preview-cards (toets vandaag/morgen) — afgeleid uit deadlines
  const toetsenList = deriveToetsenFromDeadlines(deadlines);
  // Vandaag-preview: alleen als er écht vandaag een toets is (daysAway === 0)
  const toetsVandaag = toetsenList.find(x => (x.daysAway ?? 999) === 0) || null;
  // Morgen-preview: daysAway === 1
  const toetsMorgen = toetsenList.find(x => (x.daysAway ?? 999) === 1) || null;

  // Collapsible kolommen — content klapt omhoog weg, titel+count blijft staan
  const [collapsed, setCollapsed] = useState({ deadlines: false, morgen: false });
  function toggleCol(key) {
    setCollapsed({ ...collapsed, [key]: !collapsed[key] });
  }

  return (
    <main style={{ flex: 1, padding: '20px 28px 40px', display: 'flex', flexDirection: 'column', gap: 16 }}>
      {/* Welkom terug — Comeback banner (prominent boven de 3 blokken) */}
      {comeback && (
        <ComebackBanner tk={tk} store={store} missedCount={(store.missedTasks || []).length} />
      )}

      {/* Alles klaar — Pulse celebration banner */}
      {allesKlaar && (
        <AllesKlaarBanner tk={tk} navigate={navigate} />
      )}

      {/* Nieuwe gebruiker — welkom + aan de slag banner */}
      {nieuw && (
        <NieuwGebruikerBanner tk={tk} navigate={navigate} />
      )}

      {/* Magister-import banner */}
      {magisterImport && (
        <div style={{
          padding: '12px 16px', borderRadius: 10,
          background: hexToRgba(tk.purple, 0.08),
          border: `1.5px solid ${hexToRgba(tk.purple, 0.28)}`,
          display: 'flex', alignItems: 'center', gap: 10,
        }}>
          <div style={{
            width: 32, height: 32, borderRadius: 8,
            background: hexToRgba(tk.purple, 0.16),
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}>
            <PI name="download" size={16} color={tk.purple} />
          </div>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 10, fontWeight: 800, color: tk.purple, letterSpacing: 0.5, textTransform: 'uppercase' }}>
              Magister-koppeling · 12 nieuwe items
            </div>
            <div style={{ fontSize: 12, fontWeight: 700, color: tk.fg, marginTop: 1 }}>
              Alle huiswerk is ingelezen — staat in <b>Te plannen</b>. Plan in 1-voor-1 of laat Pulse de week vullen.
            </div>
          </div>
          <button style={{
            padding: '5px 10px', borderRadius: 6,
            background: 'transparent', border: `1px solid ${tk.border}`,
            color: tk.fgDim, fontSize: 10.5, fontWeight: 700, cursor: 'pointer',
          }}>Negeren</button>
        </div>
      )}

      {/* Toetsweek banner */}
      {toetsweek && (
        <div style={{
          padding: '12px 16px', borderRadius: 10,
          background: `linear-gradient(135deg, ${hexToRgba(tk.warn, 0.1)}, ${hexToRgba(tk.red, 0.04)})`,
          border: `1.5px solid ${hexToRgba(tk.warn, 0.28)}`,
          display: 'flex', alignItems: 'center', gap: 10,
        }}>
          <div style={{
            width: 32, height: 32, borderRadius: 8,
            background: hexToRgba(tk.warn, 0.14),
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}>
            <PI name="flame" size={16} color={tk.warn} />
          </div>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 10, fontWeight: 800, color: tk.warn, letterSpacing: 0.5, textTransform: 'uppercase' }}>
              Toetsweek · dag 1 van 7
            </div>
            <div style={{ fontSize: 12, fontWeight: 700, color: tk.fg, marginTop: 1 }}>
              Missies gepauzeerd · Pulse is stiller
            </div>
          </div>
          <button style={{
            padding: '5px 10px', borderRadius: 6,
            background: 'transparent', border: `1px solid ${tk.border}`,
            color: tk.fgDim, fontSize: 10.5, fontWeight: 700, cursor: 'pointer',
          }}>Wat verandert er?</button>
        </div>
      )}

      {/* Week-strip */}
      <WeekStripRich
        t={tk}
        week={week}
        deadlines={deadlines}
        vacations={store.vacations}
        onDayClick={(day) => navigate('/week', { day: day.isoDate })}
        onWeekClick={() => navigate('/week')}
        onStudyTimeClick={() => navigate('/settings', { tab: 'plannen' })}
        onAddTask={readOnly ? undefined : () => navigate('/add-task', { when: 'today' })}
      />

      {/* 3 kolommen */}
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1.3fr 1fr', gap: 16 }}>
        {/* Deadlines — titel blijft, content klapt omhoog */}
        <section style={{ minWidth: 0 }}>
          <DeadlinesColumn
            tk={tk}
            deadlines={deadlines}
            toetsweek={toetsweek}
            navigate={navigate}
            collapsed={collapsed.deadlines}
            onToggleCollapse={() => toggleCol('deadlines')}
          />
        </section>

        {/* Vandaag — niet meer collapsible (is de focus) */}
        <section style={{ minWidth: 0 }}>
          <div style={{ display: 'flex', alignItems: 'baseline', gap: 6 }}>
            <ColumnHeader t={tk} title="Vandaag" subtitle={`${tasksToday.filter(x => !x.done).length} taken`} accent />
            <span style={{ flex: 1 }} />
            {!readOnly && !toetsweek && (
              <button
                onClick={() => navigate('/add-task', { when: 'today' })}
                title="Nieuwe taak voor vandaag"
                style={{
                  padding: '4px 10px', marginTop: 4,
                  border: `1px solid ${tk.border}`, background: 'transparent',
                  borderRadius: 6, color: tk.fgDim, cursor: 'pointer',
                  fontSize: 11, fontWeight: 700,
                  display: 'inline-flex', alignItems: 'center', gap: 4,
                }}
              >
                <PI name="plus" size={11} color={tk.fgMute} /> Taak
              </button>
            )}
          </div>

          {/* Herstel-bak (niet in toetsweek) */}
          {!toetsweek && missedTasks.length > 0 && !zinModus && (
            <HerstelBakPrototype t={tk} missed={missedTasks} onHerplan={() => navigate('/herplan')} />
          )}

          {zinModus && !toetsweek ? (
            <ZachteModus t={tk} tasks={tasksToday} onExit={() => setZinModus(false)} store={store} />
          ) : (
            <>
              {/* Toets-preview-card bovenin als er een toets <= 3 dagen is */}
              {toetsVandaag && (
                <ToetsPreviewCard
                  t={tk}
                  toets={toetsVandaag}
                  variant="vandaag"
                  onClick={() => navigate(`/deadline/${toetsVandaag.id}`, { id: toetsVandaag.id })}
                />
              )}

              {/* Pulse-card — alleen als er iets te zeggen is (niet bij leeg-state of alles-klaar) */}
              {tasksToday.length > 0 && (
                <PulseCard
                  t={tk}
                  label="Pulse · goedemiddag"
                  title={toetsweek ? 'Morgen: Bio-toets. Vanavond bereiden.' : 'Rustige middag vandaag.'}
                  body={
                    toetsweek
                      ? <>3 taken · ±60 min · vóór 22:00 klaar.</>
                      : <>Drie taken, ruim binnen je studie-venster. Bio is de eerste — dichtstbijzijnde toets.</>
                  }
                />
              )}
              {/* Taken */}
              <div style={{ marginTop: 14, display: 'flex', flexDirection: 'column', gap: 8 }}>
                {tasksToday.map((task, i) => (
                  <TaskCardPrototype
                    key={task.id}
                    t={tk}
                    task={task}
                    deadlines={deadlines}
                    onStart={() => store.navigate('/focus', { id: task.id })}
                    onOpenDeadline={(d) => navigate(`/deadline/${d.id}`, { id: d.id })}
                    onToggleDone={readOnly ? undefined : () => {
                      store.setTasksToday(tasksToday.map(x => x.id === task.id ? { ...x, done: !x.done } : x));
                    }}
                    canMoveUp={!readOnly && i > 0}
                    canMoveDown={!readOnly && i < tasksToday.length - 1}
                    onMoveUp={readOnly ? undefined : () => store.setTasksToday(reorderTaskList(tasksToday, task.id, -1))}
                    onMoveDown={readOnly ? undefined : () => store.setTasksToday(reorderTaskList(tasksToday, task.id, 1))}
                    onLinkToDeadline={readOnly ? undefined : () => navigate('/link-task', { taskId: task.id })}
                  />
                ))}
                {/* Empty-state als geen taken (en allesklaar gebruikt dit om celebration-CTA te tonen) */}
                {tasksToday.length === 0 && (
                  <EmptyColumnCard
                    tk={tk}
                    icon={allesKlaar ? 'check-circle-2' : 'sun'}
                    accent={allesKlaar ? tk.green : tk.primary}
                    title={allesKlaar ? 'Alles van vandaag is klaar' : 'Hier zie je je dag'}
                    body={allesKlaar
                      ? 'Nice. Geen druk — of pak iets vooruit als je zin hebt.'
                      : 'Wat ga je vandaag doen? Blokken uit je deadlines landen hier vanzelf, of voeg zelf snel een taak toe.'}
                    cta={allesKlaar ? 'Bio-blok pakken (vrijblijvend)' : '+ Nieuwe taak'}
                    onCta={() => navigate('/add-task', { when: 'today' })}
                    secondary={allesKlaar ? undefined : '+ Nieuwe deadline'}
                    onSecondary={allesKlaar ? undefined : () => navigate('/add-deadline')}
                  />
                )}
              </div>
              {/* Pulse-tip onder de taken — alleen als er taken zijn om over te tippen */}
              {tasksToday.length > 0 && (
                <div style={{
                  marginTop: 14, padding: '12px 14px', borderRadius: 10,
                  background: hexToRgba(tk.purple, 0.08),
                  border: `1px solid ${hexToRgba(tk.purple, 0.22)}`,
                  display: 'flex', alignItems: 'center', gap: 10,
                }}>
                  <PulseMascot size={26} mood="thinking" />
                  <div style={{ flex: 1 }}>
                    <div style={{
                      fontSize: 9.5, fontWeight: 800, color: tk.purple,
                      letterSpacing: 0.5, textTransform: 'uppercase',
                    }}>Pulse-tip</div>
                    <div style={{ fontSize: 11.5, color: tk.fg, fontWeight: 600, lineHeight: 1.4, marginTop: 1 }}>
                      {toetsweek
                        ? 'Eerst begrippen overhoren, dan oefenvragen. Beter 20 min goed dan 60 min moe.'
                        : 'Bio staat dichtst bij — begin daar. Wiskunde kan ook na je pauze, is minder verwarrend als je nu fris bent.'}
                    </div>
                  </div>
                  <button style={{
                    padding: '4px 8px', borderRadius: 6,
                    background: 'transparent', border: 0, color: tk.fgMute,
                    cursor: 'pointer', fontSize: 14, lineHeight: 1,
                  }}>×</button>
                </div>
              )}

              {/* Geen zin — niet in toetsweek én alleen als er taken zijn */}
              {!toetsweek && tasksToday.length > 0 && (
                <button
                  onClick={() => setZinModus(true)}
                  style={{
                    marginTop: 10, padding: '8px 12px', borderRadius: 8,
                    background: 'transparent', border: `1px dashed ${tk.border}`,
                    color: tk.fgMute, fontSize: 12, fontWeight: 600, cursor: 'pointer',
                    textAlign: 'center',
                  }}
                >
                  Vandaag heb ik geen zin →
                </button>
              )}
            </>
          )}
        </section>

        {/* Morgen — titel blijft, content klapt omhoog */}
        <section style={{ minWidth: 0 }}>
          <div style={{ display: 'flex', alignItems: 'baseline', gap: 6 }}>
            <button
              onClick={() => toggleCol('morgen')}
              title={collapsed.morgen ? 'Uitklappen' : 'Inklappen'}
              style={{
                width: 22, height: 22, padding: 0, marginTop: 4,
                border: `1px solid ${tk.border}`, background: 'transparent',
                borderRadius: 5, color: tk.fgMute, cursor: 'pointer',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                flexShrink: 0,
              }}
            >
              <PI name={collapsed.morgen ? 'chevron-down' : 'chevron-up'} size={12} color={tk.fgMute} />
            </button>
            <ColumnHeader t={tk} title="Morgen" subtitle={toetsweek ? 'Bio-toets 09:00' : 'wo 23 apr · 2 taken'} />
            <span style={{ flex: 1 }} />
            {!readOnly && !toetsweek && !collapsed.morgen && (
              <button
                onClick={() => navigate('/add-task', { when: 'tomorrow' })}
                title="Nieuwe taak voor morgen"
                style={{
                  padding: '4px 10px', marginTop: 4,
                  border: `1px solid ${tk.border}`, background: 'transparent',
                  borderRadius: 6, color: tk.fgDim, cursor: 'pointer',
                  fontSize: 11, fontWeight: 700,
                  display: 'inline-flex', alignItems: 'center', gap: 4,
                }}
              >
                <PI name="plus" size={11} color={tk.fgMute} /> Taak
              </button>
            )}
          </div>
          {!collapsed.morgen && (
            <div style={{ marginTop: 12, display: 'flex', flexDirection: 'column', gap: 8 }}>
              {toetsMorgen && (
                <ToetsPreviewCard
                  t={tk}
                  toets={toetsMorgen}
                  variant="morgen"
                  onClick={() => navigate(`/deadline/${toetsMorgen.id}`, { id: toetsMorgen.id })}
                />
              )}
              {tasksTomorrow.map((task, i) => (
                <TaskCardPrototype key={task.id} t={tk} task={task} compact
                  deadlines={deadlines}
                  onStart={() => store.navigate('/focus', { id: task.id })}
                  onOpenDeadline={(d) => navigate(`/deadline/${d.id}`, { id: d.id })}
                />
              ))}
              {tasksTomorrow.length === 0 && !toetsMorgen && (
                <EmptyColumnCard
                  tk={tk}
                  icon="sunrise"
                  accent={tk.fgMute}
                  title="Vooruitblik op morgen"
                  body={allesKlaar
                    ? 'Morgen heb je nog een schone lei. Of pak een blok vooruit.'
                    : 'Vanzelf gevuld zodra je deadlines plant. Niet urgent? Sla het over.'}
                  cta="+ Taak voor morgen"
                  onCta={() => navigate('/add-task', { when: 'tomorrow' })}
                />
              )}
            </div>
          )}
        </section>
      </div>
    </main>
  );
}

/* CollapsedColumnStrip verwijderd — nieuwe collapse is hoogte-based (titel blijft, content hides) */

/* ═══════════════════════════════════════════════════════════════════
   COMPONENT: DeadlinesColumn — Te-plannen bak + ingeplande deadlines + Quick-add
   ═══════════════════════════════════════════════════════════════════ */

function DeadlinesColumn({ tk, deadlines, toetsweek, navigate, collapsed, onToggleCollapse }) {
  const [bakOpen, setBakOpen] = useState(false); // default ingeklapt zodat deadlines zichtbaar blijven
  const [quickAddOpen, setQuickAddOpen] = useState(false);
  const [addMenuOpen, setAddMenuOpen] = useState(false);

  const unscheduled = deadlines.filter(d => d.unscheduled);
  const scheduled = deadlines.filter(d => !d.unscheduled);

  return (
    <>
      <div style={{ display: 'flex', alignItems: 'baseline', gap: 6, marginBottom: 4 }}>
        {onToggleCollapse && (
          <button
            onClick={onToggleCollapse}
            title={collapsed ? 'Uitklappen' : 'Inklappen'}
            style={{
              width: 22, height: 22, padding: 0, marginTop: 4,
              border: `1px solid ${tk.border}`, background: 'transparent',
              borderRadius: 5, color: tk.fgMute, cursor: 'pointer',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              flexShrink: 0,
            }}
          >
            <PI name={collapsed ? 'chevron-down' : 'chevron-up'} size={12} color={tk.fgMute} />
          </button>
        )}
        <ColumnHeader
          t={tk}
          title="Deadlines"
          subtitle={toetsweek ? `${scheduled.length} deze week` : `${scheduled.length} ingepland`}
        />
        <span style={{ flex: 1 }} />
        {!toetsweek && !collapsed && (
          <div style={{ position: 'relative' }}>
            <button
              onClick={() => setAddMenuOpen(!addMenuOpen)}
              title="Nieuwe deadline"
              style={{
                padding: '4px 10px', marginTop: 4,
                border: `1px solid ${tk.border}`, background: 'transparent',
                borderRadius: 6, color: tk.fgDim, cursor: 'pointer',
                fontSize: 11, fontWeight: 700,
                display: 'inline-flex', alignItems: 'center', gap: 4,
              }}
            >
              <PI name="plus" size={11} color={tk.fgMute} /> Deadline
            </button>
            {addMenuOpen && (
              <>
                <div onClick={() => setAddMenuOpen(false)} style={{ position: 'fixed', inset: 0, zIndex: 50 }} />
                <div style={{
                  position: 'absolute', top: '100%', right: 0, marginTop: 4,
                  zIndex: 51, minWidth: 240,
                  background: tk.card, border: `1px solid ${tk.border}`,
                  borderRadius: 8, padding: 4,
                  boxShadow: tk.shadowElev,
                }}>
                  <button
                    onClick={() => { setAddMenuOpen(false); navigate('/add-deadline'); }}
                    style={addDeadlineMenuBtn(tk)}
                    onMouseEnter={(e) => e.currentTarget.style.background = tk.cardSunken}
                    onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
                  >
                    <div style={{
                      width: 30, height: 30, borderRadius: 7,
                      background: hexToRgba(tk.primary, 0.14),
                      display: 'flex', alignItems: 'center', justifyContent: 'center',
                      flexShrink: 0,
                    }}>
                      <PI name="calendar-plus" size={15} color={tk.primary} />
                    </div>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ fontSize: 12.5, fontWeight: 800, color: tk.fg }}>Toevoegen en inplannen</div>
                      <div style={{ fontSize: 10.5, color: tk.fgMute, fontWeight: 600, marginTop: 1 }}>
                        Volledige wizard · blokken + planning
                      </div>
                    </div>
                  </button>
                  <button
                    onClick={() => { setAddMenuOpen(false); setQuickAddOpen(true); }}
                    style={addDeadlineMenuBtn(tk)}
                    onMouseEnter={(e) => e.currentTarget.style.background = tk.cardSunken}
                    onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
                  >
                    <div style={{
                      width: 30, height: 30, borderRadius: 7,
                      background: hexToRgba(tk.warn, 0.14),
                      display: 'flex', alignItems: 'center', justifyContent: 'center',
                      flexShrink: 0,
                    }}>
                      <PI name="zap" size={15} color={tk.warn} />
                    </div>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ fontSize: 12.5, fontWeight: 800, color: tk.fg }}>Alleen toevoegen</div>
                      <div style={{ fontSize: 10.5, color: tk.fgMute, fontWeight: 600, marginTop: 1 }}>
                        Quick · komt in Te-plannen bak
                      </div>
                    </div>
                  </button>
                </div>
              </>
            )}
          </div>
        )}
      </div>

      {/* Body — alleen tonen als niet ingeklapt */}
      {!collapsed && (
        <>
        {/* origineel body-blok start */}

      {/* Te-plannen bak — alleen tonen als er ongeplande items zijn */}
      {!toetsweek && unscheduled.length > 0 && (
        <TePlannenBak
          tk={tk}
          items={unscheduled}
          open={bakOpen}
          onToggle={() => setBakOpen(!bakOpen)}
          onPlanIn={(d) => navigate(`/add-deadline?planFor=${d.id}`, { planFor: d.id })}
          onClickItem={(d) => navigate(`/deadline/${d.id}`, { id: d.id })}
          onHide={(d) => {
            // Verberg: markeer als unscheduled=false + hidden (filteren we niet af in dit prototype,
            // maar we nemen hem uit de deadlines-lijst zodat hij weg is uit UI)
            alert(`"${d.title}" verborgen. Verschijnt weer als Magister hem nog eens stuurt — tenzij je 'm dan weer verbergt.`);
          }}
          onDelete={(d) => {
            if (confirm(`"${d.title}" definitief verwijderen?`)) {
              // In echte app: DELETE call. Hier: alert.
              alert(`"${d.title}" verwijderd.`);
            }
          }}
        />
      )}

      <div style={{ display: 'flex', flexDirection: 'column', gap: 10, marginTop: 12 }}>
        {scheduled.map(d => (
          <DeadlineCardPrototype
            key={d.id}
            t={tk}
            deadline={d}
            onClick={() => navigate(`/deadline/${d.id}`, { id: d.id })}
          />
        ))}
        {scheduled.length === 0 && unscheduled.length === 0 && !toetsweek && (
          <EmptyColumnCard
            tk={tk}
            icon="flag"
            accent={tk.primary}
            title="Hier komen je deadlines"
            body="Toetsen, SO's en inlever-werk. Pulse verdeelt ze in blokken over je studie-tijd. Koppel Magister om ze automatisch op te halen."
            cta="+ Eerste deadline"
            onCta={() => navigate('/add-deadline')}
            secondary="Magister koppelen"
            onSecondary={() => navigate('/settings', { tab: 'koppelingen' })}
          />
        )}
      </div>

      {quickAddOpen && (
        <QuickAddDeadlineModal
          tk={tk}
          onClose={() => setQuickAddOpen(false)}
          onSave={(draft) => {
            // Mock: voeg toe aan store als unscheduled
            // (in echte app: API call)
            setQuickAddOpen(false);
            console.log('Quick-add:', draft);
          }}
        />
      )}
      {/* origineel body-blok einde */}
      </>
      )}
    </>
  );
}

/* ═══════════════════════════════════════════════════════════════════
   COMPONENT: TePlannenBak — Inbox met ongeplande deadlines
   ═══════════════════════════════════════════════════════════════════ */

function TePlannenBak({ tk, items, open, onToggle, onPlanIn, onClickItem, onHide, onDelete, premium }) {
  const fromMagister = items.filter(d => d.source === 'magister').length;
  const INITIAL_VISIBLE = 5;
  const [visibleCount, setVisibleCount] = useState(INITIAL_VISIBLE);
  const visibleItems = items.slice(0, visibleCount);
  const hiddenCount = Math.max(0, items.length - visibleCount);
  return (
    <div style={{
      marginTop: 12,
      borderRadius: 10,
      background: hexToRgba(tk.warn, 0.06),
      border: `1.5px solid ${hexToRgba(tk.warn, 0.28)}`,
      overflow: 'hidden',
    }}>
      <button
        onClick={onToggle}
        style={{
          width: '100%', padding: '10px 12px',
          background: 'transparent', border: 0, cursor: 'pointer',
          display: 'flex', alignItems: 'center', gap: 8, textAlign: 'left',
        }}
      >
        <div style={{
          width: 28, height: 28, borderRadius: 7,
          background: hexToRgba(tk.warn, 0.18),
          display: 'flex', alignItems: 'center', justifyContent: 'center',
        }}>
          <PI name="inbox" size={14} color={tk.warn} />
        </div>
        <div style={{ flex: 1 }}>
          <div style={{
            fontSize: 9.5, fontWeight: 800, color: tk.warn,
            letterSpacing: 0.5, textTransform: 'uppercase',
          }}>Te plannen · {items.length}</div>
          <div style={{ fontSize: 11, color: tk.fgDim, fontWeight: 600, marginTop: 1 }}>
            {fromMagister > 0 ? `${fromMagister} uit Magister · ` : ''}
            {items.length === 1 ? 'kies wanneer je gaat leren' : 'kies wanneer je gaat leren'}
          </div>
        </div>
        <PI name={open ? 'chevron-up' : 'chevron-down'} size={14} color={tk.fgMute} />
      </button>

      {open && (
        <div style={{
          padding: '0 10px 10px',
          display: 'flex', flexDirection: 'column', gap: 8,
        }}>
          {visibleItems.map(d => (
            <UnscheduledDeadlineCard
              key={d.id}
              t={tk}
              deadline={d}
              onClick={() => onClickItem && onClickItem(d)}
              onPlanIn={onPlanIn}
              onHide={onHide}
              onDelete={onDelete}
            />
          ))}

          {/* Laad-meer / Toon-minder */}
          {hiddenCount > 0 && (
            <button
              onClick={() => setVisibleCount(visibleCount + 5)}
              style={{
                padding: '8px 10px', borderRadius: 7,
                background: 'transparent', border: `1px dashed ${tk.border}`,
                color: tk.fgDim, fontSize: 11.5, fontWeight: 700, cursor: 'pointer',
                display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 5,
              }}
            >
              <PI name="chevron-down" size={12} color={tk.fgMute} />
              Toon nog {Math.min(5, hiddenCount)} ({hiddenCount} verborgen)
            </button>
          )}
          {visibleCount > INITIAL_VISIBLE && hiddenCount === 0 && (
            <button
              onClick={() => setVisibleCount(INITIAL_VISIBLE)}
              style={{
                padding: '6px 10px', borderRadius: 7,
                background: 'transparent', border: 0,
                color: tk.fgMute, fontSize: 10.5, fontWeight: 700, cursor: 'pointer',
                display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 4,
              }}
            >
              <PI name="chevron-up" size={11} color={tk.fgMute} />
              Toon minder
            </button>
          )}

          {/* Premium: batch-plan knop (Pulse plant alles in) */}
          {items.length >= 2 && (
            <div style={{
              marginTop: 4, padding: '10px 12px', borderRadius: 8,
              background: hexToRgba(tk.purple, 0.08),
              border: `1px solid ${hexToRgba(tk.purple, 0.22)}`,
              display: 'flex', alignItems: 'center', gap: 8,
            }}>
              <PulseMascot size={26} mood="thinking" />
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 11.5, fontWeight: 800, color: tk.fg }}>
                  Pulse plant alles in één keer in
                </div>
                <div style={{ fontSize: 10.5, color: tk.fgDim, fontWeight: 600, marginTop: 1 }}>
                  Voorstel met blokken per deadline · accepteren of aanpassen
                </div>
              </div>
              <button style={{
                padding: '6px 10px', borderRadius: 7,
                background: tk.purple, color: '#FFFFFF', border: 0,
                fontSize: 11, fontWeight: 800, cursor: 'pointer',
                display: 'inline-flex', alignItems: 'center', gap: 4,
              }}>
                <PI name="sparkles" size={11} color="#FFFFFF" />
                Batch-plan
              </button>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

/* ═══════════════════════════════════════════════════════════════════
   COMPONENT: QuickAddDeadlineModal — snelle 4-veld modal
   ═══════════════════════════════════════════════════════════════════ */

function QuickAddDeadlineModal({ tk, onClose, onSave }) {
  const [subject, setSubject] = useState('biologie');
  const [type, setType] = useState('toets');
  const [title, setTitle] = useState('');
  const [dueDate, setDueDate] = useState('');
  const [dateUnknown, setDateUnknown] = useState(false);

  return (
    <div
      onClick={onClose}
      style={{
        position: 'fixed', inset: 0, zIndex: 200,
        background: 'rgba(0, 0, 0, 0.55)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        padding: 20,
      }}
    >
      <div
        onClick={(e) => e.stopPropagation()}
        style={{
          background: tk.card, borderRadius: 14,
          border: `1px solid ${tk.border}`,
          width: '100%', maxWidth: 460,
          padding: '20px 24px 22px',
          boxShadow: tk.shadowElev,
        }}
      >
        <div style={{
          display: 'flex', alignItems: 'center', gap: 8, marginBottom: 14,
        }}>
          <div style={{
            width: 32, height: 32, borderRadius: 8,
            background: hexToRgba(tk.warn, 0.14),
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}>
            <PI name="zap" size={16} color={tk.warn} />
          </div>
          <div style={{ flex: 1 }}>
            <h3 style={{
              fontFamily: 'Fredoka One', fontSize: 18, color: tk.fg,
              margin: 0, lineHeight: 1.1,
            }}>Quick-add deadline</h3>
            <div style={{ fontSize: 11.5, color: tk.fgMute, fontWeight: 600, marginTop: 2 }}>
              Voer snel iets in — plannen kan later
            </div>
          </div>
          <button onClick={onClose} style={{
            width: 28, height: 28, padding: 0, border: 0,
            background: 'transparent', color: tk.fgMute,
            cursor: 'pointer', fontSize: 18,
          }}>×</button>
        </div>

        {/* Vak + type-grid */}
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8, marginBottom: 10 }}>
          <label style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
            <span style={{ fontSize: 10, fontWeight: 800, color: tk.fgMute, letterSpacing: 0.5, textTransform: 'uppercase' }}>Vak</span>
            <select
              value={subject}
              onChange={(e) => setSubject(e.target.value)}
              style={{
                padding: '8px 10px', borderRadius: 7,
                border: `1px solid ${tk.border}`, background: tk.cardSunken,
                color: tk.fg, fontSize: 13, fontWeight: 600, fontFamily: 'inherit',
                cursor: 'pointer',
              }}
            >
              {Object.keys(SUBJECTS).map(s => (
                <option key={s} value={s}>{s.charAt(0).toUpperCase() + s.slice(1)}</option>
              ))}
            </select>
          </label>
          <label style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
            <span style={{ fontSize: 10, fontWeight: 800, color: tk.fgMute, letterSpacing: 0.5, textTransform: 'uppercase' }}>Type</span>
            <select
              value={type}
              onChange={(e) => setType(e.target.value)}
              style={{
                padding: '8px 10px', borderRadius: 7,
                border: `1px solid ${tk.border}`, background: tk.cardSunken,
                color: tk.fg, fontSize: 13, fontWeight: 600, fontFamily: 'inherit',
                cursor: 'pointer',
              }}
            >
              <optgroup label="Toetsen">
                <option value="toets">Toets</option>
                <option value="so">SO</option>
              </optgroup>
              <optgroup label="Werk & huiswerk">
                <option value="inlever">Inleveren</option>
                <option value="maakwerk">Maakwerk</option>
                <option value="leerwerk">Leerwerk</option>
              </optgroup>
            </select>
          </label>
        </div>

        {/* Title */}
        <label style={{ display: 'flex', flexDirection: 'column', gap: 4, marginBottom: 10 }}>
          <span style={{ fontSize: 10, fontWeight: 800, color: tk.fgMute, letterSpacing: 0.5, textTransform: 'uppercase' }}>Titel</span>
          <input
            type="text"
            value={title}
            onChange={(e) => setTitle(e.target.value)}
            placeholder="Bijv. Bio H4 — celbiologie"
            autoFocus
            style={{
              padding: '8px 10px', borderRadius: 7,
              border: `1px solid ${tk.border}`, background: tk.cardSunken,
              color: tk.fg, fontSize: 13, fontWeight: 600, fontFamily: 'inherit',
              outline: 'none',
            }}
          />
        </label>

        {/* Datum + onbekend-checkbox */}
        <label style={{ display: 'flex', flexDirection: 'column', gap: 4, marginBottom: 6 }}>
          <span style={{ fontSize: 10, fontWeight: 800, color: tk.fgMute, letterSpacing: 0.5, textTransform: 'uppercase' }}>Datum</span>
          <input
            type="date"
            value={dueDate}
            onChange={(e) => setDueDate(e.target.value)}
            disabled={dateUnknown}
            style={{
              padding: '8px 10px', borderRadius: 7,
              border: `1px solid ${tk.border}`, background: tk.cardSunken,
              color: tk.fg, fontSize: 13, fontWeight: 600, fontFamily: 'inherit',
              opacity: dateUnknown ? 0.5 : 1,
              outline: 'none',
            }}
          />
        </label>
        <label style={{
          display: 'inline-flex', alignItems: 'center', gap: 6,
          fontSize: 12, color: tk.fgDim, fontWeight: 600, cursor: 'pointer',
          marginBottom: 16,
        }}>
          <input
            type="checkbox"
            checked={dateUnknown}
            onChange={(e) => setDateUnknown(e.target.checked)}
            style={{ accentColor: tk.primary }}
          />
          Datum nog onbekend
        </label>

        <div style={{
          padding: '10px 12px', borderRadius: 8,
          background: hexToRgba(tk.warn, 0.06),
          border: `1px dashed ${hexToRgba(tk.warn, 0.3)}`,
          fontSize: 11.5, color: tk.fgDim, fontWeight: 600, lineHeight: 1.5,
          marginBottom: 14,
        }}>
          <PI name="info" size={11} color={tk.warn} style={{ marginRight: 4, verticalAlign: 'middle' }} />
          Quick-add zet de deadline in <b style={{ color: tk.fg }}>Te plannen</b>. Je hoeft nu geen blokken te kiezen — dat doe je later via "Plan in".
        </div>

        <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
          <button
            onClick={onClose}
            style={{
              padding: '8px 14px', borderRadius: 8,
              background: 'transparent', border: `1px solid ${tk.border}`,
              color: tk.fgDim, fontSize: 12, fontWeight: 700, cursor: 'pointer',
            }}
          >Annuleer</button>
          <button
            onClick={() => onSave({ subject, type, title, dueDate: dateUnknown ? null : dueDate, noDate: dateUnknown, unscheduled: true, source: 'manual' })}
            disabled={!title || (!dueDate && !dateUnknown)}
            style={{
              padding: '8px 14px', borderRadius: 8,
              background: (!title || (!dueDate && !dateUnknown)) ? hexToRgba(tk.primary, 0.4) : tk.primary,
              color: '#FFFFFF', border: 0,
              fontSize: 12, fontWeight: 800, cursor: (!title || (!dueDate && !dateUnknown)) ? 'not-allowed' : 'pointer',
              display: 'inline-flex', alignItems: 'center', gap: 4,
            }}
          >
            <PI name="check" size={12} color="#FFFFFF" />
            Opslaan in Te-plannen
          </button>
        </div>
      </div>
    </div>
  );
}

/* ═══════════════════════════════════════════════════════════════════
   SCENARIO VARIANTEN — Home in alternatieve states
   (Vakantie / Alles klaar / Comeback / Pulse observeert / Magister-import)
   ═══════════════════════════════════════════════════════════════════ */

function HomeScenarioVakantie({ tk, store }) {
  return (
    <main style={{ flex: 1, padding: '24px 28px', display: 'flex', justifyContent: 'center' }}>
      <div style={{
        maxWidth: 520, padding: '20px 24px 22px', borderRadius: 14,
        background: tk.card, border: `1px solid ${tk.border}`,
        boxShadow: tk.shadowCard,
        display: 'flex', gap: 16, alignItems: 'flex-start',
      }}>
        <PulseMascot size={44} mood="sleeping" />
        <div style={{ flex: 1 }}>
          <div style={{
            fontSize: 10, fontWeight: 800, color: tk.warn,
            letterSpacing: 0.5, textTransform: 'uppercase', marginBottom: 3,
          }}>☀ Meivakantie</div>
          <h2 style={{
            fontFamily: 'Fredoka One', fontSize: 20, color: tk.fg,
            margin: '0 0 6px', letterSpacing: '-0.01em',
          }}>Geen school deze week</h2>
          <p style={{ fontSize: 12.5, color: tk.fgDim, fontWeight: 500, lineHeight: 1.5, margin: '0 0 12px' }}>
            Pulse neemt even pauze — eerste toets na vakantie is op <b style={{ color: tk.fg }}>ma 29 april</b>.
            Geen streak-druk.
          </p>
          <div style={{ display: 'flex', gap: 6 }}>
            <button style={{
              padding: '8px 14px', borderRadius: 8,
              background: tk.primary, color: '#FFFFFF', border: 0,
              fontSize: 11.5, fontWeight: 800, cursor: 'pointer',
              display: 'inline-flex', alignItems: 'center', gap: 5,
            }}>
              <PI name="book-open" size={12} /> Oefenen voor de lol
            </button>
            <button style={{
              padding: '8px 12px', borderRadius: 8,
              background: 'transparent', border: `1px solid ${tk.border}`,
              color: tk.fgDim, fontSize: 11, fontWeight: 700, cursor: 'pointer',
            }}>
              Volgende week →
            </button>
          </div>
        </div>
      </div>
    </main>
  );
}

/* ═══════════════════════════════════════════════════════════════════
   EMPTY-STATE + SCENARIO BANNERS
   Gedeeld door AllesKlaar, Comeback en algemene lege kolommen
   ═══════════════════════════════════════════════════════════════════ */

function EmptyColumnCard({ tk, icon, accent, title, body, cta, onCta, secondary, onSecondary }) {
  return (
    <div style={{
      padding: '20px 16px',
      borderRadius: 12,
      background: hexToRgba(accent, 0.06),
      border: `1.5px dashed ${hexToRgba(accent, 0.3)}`,
      textAlign: 'center',
      minHeight: 240,
      display: 'flex', flexDirection: 'column', alignItems: 'center',
    }}>
      <div style={{
        width: 36, height: 36, borderRadius: 10,
        background: hexToRgba(accent, 0.12),
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        marginBottom: 10,
      }}>
        <PI name={icon} size={18} color={accent} />
      </div>
      <div style={{ fontSize: 13, fontWeight: 800, color: tk.fg, lineHeight: 1.3 }}>
        {title}
      </div>
      {body && (
        <div style={{ fontSize: 11.5, color: tk.fgDim, fontWeight: 500, marginTop: 5, lineHeight: 1.5 }}>
          {body}
        </div>
      )}
      <span style={{ flex: 1 }} />
      <div style={{ display: 'flex', gap: 6, marginTop: 12, justifyContent: 'center', flexWrap: 'wrap' }}>
        {cta && (
          <button onClick={onCta} style={{
            padding: '8px 12px', borderRadius: 7,
            background: accent, color: '#FFFFFF', border: 0,
            fontSize: 11.5, fontWeight: 800, cursor: 'pointer',
            display: 'inline-flex', alignItems: 'center', gap: 5,
          }}>{cta}</button>
        )}
        {secondary && (
          <button onClick={onSecondary} style={{
            padding: '8px 12px', borderRadius: 7,
            background: 'transparent', border: `1px solid ${tk.border}`,
            color: tk.fgDim, fontSize: 11.5, fontWeight: 700, cursor: 'pointer',
          }}>{secondary}</button>
        )}
      </div>
    </div>
  );
}

function AllesKlaarBanner({ tk, navigate }) {
  return (
    <div style={{
      padding: '16px 20px', borderRadius: 12,
      background: `linear-gradient(135deg, ${hexToRgba(tk.green, 0.14)}, ${hexToRgba(tk.green, 0.04)})`,
      border: `1.5px solid ${hexToRgba(tk.green, 0.35)}`,
      display: 'flex', alignItems: 'center', gap: 12,
    }}>
      <PulseMascot size={40} mood="celebrating" />
      <div style={{ flex: 1 }}>
        <div style={{
          fontSize: 10, fontWeight: 800, color: tk.green,
          letterSpacing: 0.5, textTransform: 'uppercase', marginBottom: 3,
        }}>✓ Vandaag klaar</div>
        <div style={{ fontFamily: 'Fredoka One', fontSize: 20, color: tk.fg, letterSpacing: '-0.01em', lineHeight: 1.2 }}>
          Lekker bezig.
        </div>
        <div style={{ fontSize: 12, color: tk.fgDim, fontWeight: 500, marginTop: 3, lineHeight: 1.5 }}>
          Alles van vandaag is af · dichtstbijzijnde toets is over <b style={{ color: tk.fg }}>8 dagen</b>. Geen druk.
        </div>
      </div>
      <div style={{ display: 'flex', gap: 6 }}>
        <button
          onClick={() => navigate('/add-task', { when: 'today' })}
          style={{
            padding: '8px 12px', borderRadius: 7,
            background: 'transparent', border: `1px solid ${tk.border}`,
            color: tk.fgDim, fontSize: 11.5, fontWeight: 800, cursor: 'pointer',
            display: 'inline-flex', alignItems: 'center', gap: 4,
          }}
        >
          <PI name="plus" size={11} />
          Extra taak
        </button>
        <button
          onClick={() => navigate('/add-deadline')}
          style={{
            padding: '8px 14px', borderRadius: 7,
            background: tk.primary, color: '#FFFFFF', border: 0,
            fontSize: 11.5, fontWeight: 800, cursor: 'pointer',
            display: 'inline-flex', alignItems: 'center', gap: 4,
          }}
        >
          <PI name="plus" size={11} color="#FFFFFF" />
          Nieuwe deadline
        </button>
      </div>
    </div>
  );
}

function NieuwGebruikerBanner({ tk, navigate }) {
  return (
    <div style={{
      padding: '18px 22px', borderRadius: 12,
      background: `linear-gradient(135deg, ${hexToRgba(tk.primary, 0.12)}, ${hexToRgba(tk.purple, 0.06)})`,
      border: `1.5px solid ${hexToRgba(tk.primary, 0.32)}`,
      display: 'flex', alignItems: 'center', gap: 14,
      position: 'relative', overflow: 'hidden',
    }}>
      <div style={{
        position: 'absolute', top: 0, left: 0, right: 0, height: 3,
        background: `linear-gradient(90deg, ${tk.primary}, ${tk.purple})`,
      }} />
      <PulseMascot size={46} mood="happy" />
      <div style={{ flex: 1 }}>
        <div style={{
          fontSize: 10, fontWeight: 800, color: tk.primary,
          letterSpacing: 0.5, textTransform: 'uppercase', marginBottom: 3,
        }}>👋 Welkom bij Plannen</div>
        <div style={{ fontFamily: 'Fredoka One', fontSize: 22, color: tk.fg, letterSpacing: '-0.01em', lineHeight: 1.2 }}>
          Laten we beginnen.
        </div>
        <div style={{ fontSize: 12.5, color: tk.fgDim, fontWeight: 500, marginTop: 4, lineHeight: 1.5 }}>
          Start met een <b style={{ color: tk.fg }}>deadline</b> (toets, SO, inleveren) of koppel <b style={{ color: tk.fg }}>Magister</b> om al je huiswerk automatisch in te laden. Kleine taken voor vandaag voeg je los toe.
        </div>
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
        <button
          onClick={() => navigate('/add-deadline')}
          style={{
            padding: '9px 14px', borderRadius: 8,
            background: tk.primary, color: '#FFFFFF', border: 0,
            fontSize: 12, fontWeight: 800, cursor: 'pointer',
            display: 'inline-flex', alignItems: 'center', gap: 5,
            whiteSpace: 'nowrap',
          }}
        >
          <PI name="plus" size={12} color="#FFFFFF" />
          Eerste deadline
        </button>
        <button
          onClick={() => navigate('/settings', { tab: 'koppelingen' })}
          style={{
            padding: '8px 14px', borderRadius: 8,
            background: 'transparent', border: `1px solid ${tk.border}`,
            color: tk.fgDim, fontSize: 11.5, fontWeight: 700, cursor: 'pointer',
            display: 'inline-flex', alignItems: 'center', gap: 5,
            whiteSpace: 'nowrap',
          }}
        >
          <PI name="download" size={11} color={tk.fgMute} />
          Magister koppelen
        </button>
      </div>
    </div>
  );
}

function ComebackBanner({ tk, store, missedCount }) {
  const [decision, setDecision] = useState(null);
  const isPremium = store.plan === 'premium';
  return (
    <div style={{
      padding: '16px 20px', borderRadius: 12,
      background: `linear-gradient(135deg, ${hexToRgba(tk.purple, 0.12)}, ${hexToRgba(tk.primary, 0.06)})`,
      border: `1.5px solid ${hexToRgba(tk.purple, 0.32)}`,
      display: 'flex', alignItems: 'flex-start', gap: 14,
      position: 'relative', overflow: 'hidden',
    }}>
      <div style={{
        position: 'absolute', top: 0, left: 0, right: 0, height: 3,
        background: `linear-gradient(90deg, ${tk.purple}, ${tk.primary})`,
      }} />
      <PulseMascot size={40} mood="encouraging" />
      <div style={{ flex: 1 }}>
        <div style={{
          fontSize: 10, fontWeight: 800, color: tk.purple,
          letterSpacing: 0.5, textTransform: 'uppercase', marginBottom: 3,
        }}>Welkom terug</div>
        <div style={{ fontFamily: 'Fredoka One', fontSize: 20, color: tk.fg, letterSpacing: '-0.01em', lineHeight: 1.2 }}>
          Je was een paar dagen weg.
        </div>
        <div style={{ fontSize: 12.5, color: tk.fgDim, fontWeight: 500, lineHeight: 1.55, marginTop: 3 }}>
          Er stonden <b style={{ color: tk.fg }}>{missedCount} taken</b> in die periode. Hieronder in de <b>Herstel-bak</b> per taak kiezen, of:
        </div>
        {!decision ? (
          <div style={{ display: 'flex', gap: 6, marginTop: 10, flexWrap: 'wrap' }}>
            <button
              onClick={() => setDecision(isPremium ? 'pulse' : 'herplan-free')}
              style={{
                padding: '8px 12px', borderRadius: 7,
                background: tk.purple, color: '#FFFFFF', border: 0,
                fontSize: 11.5, fontWeight: 800, cursor: 'pointer',
                display: 'inline-flex', alignItems: 'center', gap: 5,
              }}
            >
              {isPremium
                ? <><PI name="sparkles" size={12} color="#FFFFFF" /> Pulse plant alles opnieuw</>
                : <><PI name="calendar-plus" size={12} color="#FFFFFF" /> Herplannen naar deze week</>}
            </button>
            <button
              onClick={() => setDecision('bekijk')}
              style={{
                padding: '8px 12px', borderRadius: 7,
                background: 'transparent', border: `1px solid ${tk.border}`,
                color: tk.fgDim, fontSize: 11.5, fontWeight: 700, cursor: 'pointer',
              }}
            >Per stuk beslissen in Herstel-bak</button>
            <button
              onClick={() => setDecision('weg')}
              style={{
                padding: '8px 12px', borderRadius: 7,
                background: 'transparent', border: `1px solid ${tk.border}`,
                color: tk.fgMute, fontSize: 11.5, fontWeight: 700, cursor: 'pointer',
              }}
            >Alles weggooien</button>
          </div>
        ) : (
          <div style={{
            marginTop: 10, padding: '8px 12px', borderRadius: 8,
            background: hexToRgba(tk.green, 0.10),
            border: `1px solid ${hexToRgba(tk.green, 0.22)}`,
            display: 'flex', alignItems: 'center', gap: 8,
            fontSize: 11.5, color: tk.fg, fontWeight: 600,
          }}>
            <PI name="check-circle-2" size={14} color={tk.green} />
            <span style={{ flex: 1 }}>
              {decision === 'pulse' && 'Pulse verdeelt ze over deze week — opent de herplan-coach…'}
              {decision === 'herplan-free' && 'Sleep ze zelf naar een dag — opent herplan-flow…'}
              {decision === 'bekijk' && 'Bekijk per taak hieronder in de Herstel-bak.'}
              {decision === 'weg' && 'Taken weggedaan — je begint fris.'}
            </span>
            <button onClick={() => setDecision(null)} style={{
              padding: '3px 8px', borderRadius: 5,
              background: 'transparent', border: `1px solid ${tk.border}`,
              color: tk.fgDim, fontSize: 10.5, fontWeight: 700, cursor: 'pointer',
            }}>Terug</button>
          </div>
        )}
      </div>
    </div>
  );
}

function HomeScenarioAllesKlaar({ tk, store }) {
  // Taken blijven zichtbaar als DONE — geen informatie-verlies. Student kan
  // uncheck'en om iets opnieuw te doen. Lokale state (niet mutate store).
  const [localTasks, setLocalTasks] = useState(() =>
    store.tasksToday.map(t => ({ ...t, done: true, isNow: false }))
  );
  const localStore = {
    ...store,
    tasksToday: localTasks,
    setTasksToday: setLocalTasks,
  };
  return (
    <StapelContent
      store={localStore}
      allesKlaar
    />
  );
}

function HomeScenarioNieuw({ tk, store }) {
  // Nieuwe gebruiker / schoon account — alles leeg, alle empty-states + CTAs zichtbaar.
  // Week-strip behoudt dagen (voor datum/today-markering) maar zonder items of deadlines.
  const emptyWeek = store.week.map(d => ({
    label: d.label,
    date: d.date,
    isoDate: d.isoDate,
    items: [],
    isToday: d.isToday,
    isWeekend: d.isWeekend,
    status: d.status,
  }));
  return (
    <StapelContent
      store={{ ...store, week: emptyWeek, missedTasks: [] }}
      nieuw
      deadlinesOverride={[]}
      tasksTodayOverride={[]}
      tasksTomorrowOverride={[]}
    />
  );
}

function HomeScenarioComeback({ tk, store }) {
  // Gebruik Stapel-shell met een prominente welkom-terug banner bovenaan
  // + uitgebreide herstel-bak met meer items (de gemiste dagen)
  const extendedMissed = [
    ...store.missedTasks,
    { id: 'm3', subject: 'frans', title: 'Woordenschat H6 overhoren', missedDate: 'wo 16', mins: 20 },
    { id: 'm4', subject: 'engels', title: 'Essay-paragraaf 1', missedDate: 'do 17', mins: 30 },
    { id: 'm5', subject: 'biologie', title: 'H4 oefenvragen', missedDate: 'do 17', mins: 25 },
    { id: 'm6', subject: 'wiskunde', title: 'Statistiek oefenen', missedDate: 'vr 18', mins: 20 },
    { id: 'm7', subject: 'scheikunde', title: 'H4 flashcards', missedDate: 'vr 18', mins: 15 },
    { id: 'm8', subject: 'engels', title: 'Essay-paragraaf 2', missedDate: 'za 19', mins: 30 },
    { id: 'm9', subject: 'biologie', title: 'Celbiologie §4.2 lezen', missedDate: 'zo 20', mins: 25 },
    { id: 'm10', subject: 'wiskunde', title: 'Oefenopgaves set B', missedDate: 'ma 21', mins: 20 },
    { id: 'm11', subject: 'frans', title: 'Werkwoorden herhalen', missedDate: 'ma 21', mins: 15 },
  ];
  return (
    <StapelContent
      store={{ ...store, missedTasks: extendedMissed }}
      comeback
    />
  );
}

function HomeScenarioBurnout({ tk, store }) {
  return (
    <main style={{ flex: 1, padding: '32px 28px', display: 'flex', flexDirection: 'column', gap: 16 }}>
      {/* Observatie-card bovenaan — Pulse signaleert laat doorwerken */}
      <div style={{
        padding: '16px 20px', borderRadius: 12,
        background: hexToRgba(tk.warn, 0.08),
        border: `1px solid ${hexToRgba(tk.warn, 0.3)}`,
        display: 'flex', alignItems: 'flex-start', gap: 12,
      }}>
        <PulseMascot size={36} mood="focused" />
        <div style={{ flex: 1 }}>
          <div style={{
            fontSize: 10, fontWeight: 800, color: tk.warn,
            letterSpacing: 0.5, textTransform: 'uppercase', marginBottom: 3,
          }}>Pulse · observatie</div>
          <div style={{ fontSize: 14, fontWeight: 800, color: tk.fg, lineHeight: 1.35 }}>
            Je hebt vijf avonden op rij na tienen doorgewerkt.
          </div>
          <div style={{ fontSize: 12.5, color: tk.fgDim, fontWeight: 500, lineHeight: 1.5, marginTop: 4 }}>
            Zal ik morgen halveren? Ik schuif dan <b style={{ color: tk.fg }}>Scheikunde-samenvatting</b> naar woensdag.
          </div>
          <div style={{ display: 'flex', gap: 6, marginTop: 10 }}>
            <button style={{
              padding: '7px 14px', borderRadius: 7,
              background: tk.primary, color: '#FFFFFF', border: 0,
              fontSize: 11.5, fontWeight: 800, cursor: 'pointer',
            }}>Ja, halveer morgen</button>
            <button style={{
              padding: '7px 14px', borderRadius: 7,
              background: 'transparent', border: `1px solid ${tk.border}`,
              color: tk.fgDim, fontSize: 11, fontWeight: 700, cursor: 'pointer',
            }}>Nee, het gaat wel</button>
            <button style={{
              padding: '7px 10px', borderRadius: 7,
              background: 'transparent', border: `1px solid ${tk.border}`,
              color: tk.fgMute, fontSize: 11, fontWeight: 700, cursor: 'pointer',
            }}>Later</button>
          </div>
        </div>
      </div>

      {/* Stapel normaal */}
      <StapelContent store={store} />
    </main>
  );
}

// Mock checklist per toets — simpele stappen (versimpelde ladder)
const TOETSWEEK_CHECKLIST = {
  b1: [
    { label: 'Hoofdstuk 4 lezen', done: true },
    { label: 'Hoofdstuk 5 lezen', done: true },
    { label: 'Samenvatting maken', done: true },
    { label: 'Begrippen oefenen', done: false, isNow: true },
    { label: 'Oefenopgaves', done: false },
  ],
  b2: [
    { label: 'Woordenschat H6 leren', done: false, isNow: true },
    { label: 'Oefenvragen', done: false },
  ],
  b3: [
    { label: 'Theorie H7 lezen', done: true },
    { label: 'Oefenopgaves set A', done: false, isNow: true },
    { label: 'Proeftoets maken', done: false },
  ],
  b4: [
    { label: 'Hoofdstuk interbellum lezen', done: false, isNow: true },
    { label: 'Tijdlijn maken', done: false },
    { label: 'Begrippen oefenen', done: false },
  ],
  b5: [
    { label: 'Onderwerp kiezen', done: true },
    { label: 'Outline schrijven', done: false, isNow: true },
    { label: 'Eerste versie', done: false },
    { label: 'Revisie', done: false },
  ],
  b6: [
    { label: 'Zuren en basen theorie', done: false, isNow: true },
    { label: 'Oefenvragen', done: false },
  ],
  b7: [
    { label: 'Boek lezen', done: true },
    { label: 'Hoofdstuk-analyses', done: false, isNow: true },
    { label: 'Verslag schrijven', done: false },
    { label: 'Revisie', done: false },
  ],
};

function ToetsweekDeadlineCard({ tk, t }) {
  const [expanded, setExpanded] = useState(t.current); // current toets default uitgeklapt
  const [checklist, setChecklist] = useState(TOETSWEEK_CHECKLIST[t.id] || []);
  const doneCount = checklist.filter(c => c.done).length;
  const totalCount = checklist.length;
  const percent = totalCount > 0 ? Math.round((doneCount / totalCount) * 100) : 0;

  function toggleStep(idx) {
    setChecklist(checklist.map((c, i) => i === idx ? { ...c, done: !c.done } : c));
  }

  return (
    <div style={{
      borderRadius: 10,
      background: tk.card,
      border: t.current ? `1.5px solid ${SUBJECTS[t.subject]}` : `1px solid ${tk.border}`,
      overflow: 'hidden',
    }}>
      {/* Clickable header */}
      <button onClick={() => setExpanded(!expanded)} style={{
        width: '100%', padding: '10px 12px',
        border: 0, background: 'transparent', cursor: 'pointer',
        display: 'flex', alignItems: 'center', gap: 8, textAlign: 'left',
      }}>
        <PI name={SUBJECT_ICON_NAME(t.subject)} size={14} color={SUBJECTS[t.subject]} />
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 12, fontWeight: 800, color: tk.fg }}>{t.title}</div>
          <div style={{ fontSize: 10, color: tk.fgMute, fontWeight: 700 }}>
            {t.day} · {t.time}
            {totalCount > 0 && (
              <span style={{ color: tk.fgDim }}> · {doneCount}/{totalCount} stappen</span>
            )}
          </div>
        </div>
        {t.current && !expanded && (
          <span style={{
            fontSize: 9, fontWeight: 800, color: tk.red,
            padding: '2px 6px', borderRadius: 3,
            background: hexToRgba(tk.red, 0.14),
            letterSpacing: 0.4, textTransform: 'uppercase',
          }}>morgen</span>
        )}
        <PI name={expanded ? 'chevron-up' : 'chevron-down'} size={14} color={tk.fgMute} />
      </button>

      {/* Mini progress bar altijd zichtbaar */}
      {totalCount > 0 && (
        <div style={{
          height: 3, background: tk.cardSunken, overflow: 'hidden',
        }}>
          <div style={{
            width: `${percent}%`, height: '100%',
            background: SUBJECTS[t.subject],
            transition: 'width 0.3s',
          }} />
        </div>
      )}

      {/* Expanded checklist */}
      {expanded && (
        <div style={{
          padding: '10px 12px', borderTop: `1px solid ${tk.border}`,
          background: tk.cardSunken,
          display: 'flex', flexDirection: 'column', gap: 4,
        }}>
          {checklist.map((step, i) => (
            <button
              key={i}
              onClick={() => toggleStep(i)}
              style={{
                display: 'flex', alignItems: 'center', gap: 8,
                padding: '6px 8px', borderRadius: 6,
                background: step.isNow && !step.done ? hexToRgba(SUBJECTS[t.subject], 0.08) : 'transparent',
                border: 0, cursor: 'pointer', textAlign: 'left',
              }}
              onMouseEnter={(e) => e.currentTarget.style.background = hexToRgba(tk.fgFaint, 0.06)}
              onMouseLeave={(e) => e.currentTarget.style.background = step.isNow && !step.done ? hexToRgba(SUBJECTS[t.subject], 0.08) : 'transparent'}
            >
              {/* Checkbox visueel */}
              <div style={{
                width: 16, height: 16, borderRadius: 4,
                background: step.done ? SUBJECTS[t.subject] : 'transparent',
                border: step.done ? `2px solid ${SUBJECTS[t.subject]}` : `1.5px solid ${tk.border}`,
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                flexShrink: 0,
              }}>
                {step.done && <PI name="check" size={10} color="#FFFFFF" />}
              </div>
              <span style={{
                flex: 1, fontSize: 11.5, fontWeight: 600,
                color: step.done ? tk.fgMute : tk.fg,
                textDecoration: step.done ? 'line-through' : 'none',
              }}>
                {step.label}
              </span>
              {step.isNow && !step.done && (
                <span style={{
                  fontSize: 8.5, fontWeight: 800, color: SUBJECTS[t.subject],
                  padding: '1px 5px', borderRadius: 3,
                  background: hexToRgba(SUBJECTS[t.subject], 0.15),
                  letterSpacing: 0.3, textTransform: 'uppercase',
                }}>Nu</span>
              )}
            </button>
          ))}
          {/* Toevoegen */}
          <button style={{
            padding: '5px 8px', borderRadius: 5,
            background: 'transparent', border: `1px dashed ${tk.border}`,
            color: tk.fgMute, fontSize: 10.5, fontWeight: 700, cursor: 'pointer',
            marginTop: 4, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 4,
          }}>
            <PI name="plus" size={11} /> Stap toevoegen
          </button>
        </div>
      )}
    </div>
  );
}

function HomeScenarioMagisterImport({ tk, store }) {
  // Magister-koppeling heeft net 12 nieuwe items binnengehaald.
  // Combineer normale (ingeplande) deadlines met magister-import als ongepland.
  const combinedDeadlines = [...store.deadlines.filter(d => !d.unscheduled), ...MAGISTER_IMPORT_DEADLINES];
  return (
    <StapelContent
      store={{ ...store, deadlines: combinedDeadlines }}
      magisterImport
    />
  );
}

/* ═══════════════════════════════════════════════════════════════════
   LOADING + ERROR STATES
   ═══════════════════════════════════════════════════════════════════ */

function HomeLoadingSkeleton({ tk, store }) {
  return (
    <div style={{ background: tk.bgApp, minHeight: 'calc(100vh - 44px)' }}>
      <div style={{ display: 'flex', maxWidth: 1440, margin: '0 auto' }}>
        <Sidebar t={tk} active="plannen" />
        <div style={{ flex: 1, padding: '20px 28px' }}>
          {/* Topbar skeleton */}
          <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 18 }}>
            <SkelBar tk={tk} w={100} h={28} />
            <SkelBar tk={tk} w={180} h={16} />
            <span style={{ flex: 1 }} />
            <SkelBar tk={tk} w={60} h={28} radius={999} />
            <SkelBar tk={tk} w={50} h={28} radius={999} />
            <SkelBar tk={tk} w={28} h={28} radius={999} />
          </div>

          {/* Week-strip skeleton */}
          <div style={{
            background: tk.card, border: `1px solid ${tk.border}`,
            borderRadius: 14, padding: 14, marginBottom: 20,
          }}>
            <SkelBar tk={tk} w={140} h={20} style={{ marginBottom: 10 }} />
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 8 }}>
              {[0, 1, 2, 3, 4, 5, 6].map(i => (
                <SkelBar key={i} tk={tk} w="100%" h={100} radius={10} />
              ))}
            </div>
          </div>

          {/* 3 kolommen skeleton */}
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1.3fr 1fr', gap: 16 }}>
            {[0, 1, 2].map(c => (
              <div key={c} style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
                <SkelBar tk={tk} w={100} h={24} />
                {[0, 1, 2].map(i => (
                  <SkelBar key={i} tk={tk} w="100%" h={80} radius={10} />
                ))}
              </div>
            ))}
          </div>

          {/* Subtle Pulse in hoek */}
          <div style={{
            position: 'fixed', bottom: 20, right: 20,
            display: 'flex', alignItems: 'center', gap: 8,
            padding: '8px 14px', borderRadius: 999,
            background: tk.card, border: `1px solid ${tk.border}`,
            boxShadow: tk.shadowCard,
          }}>
            <PulseMascot size={24} mood="thinking" />
            <span style={{ fontSize: 11, color: tk.fgDim, fontWeight: 700 }}>Je planning wordt geladen…</span>
          </div>
        </div>
      </div>
    </div>
  );
}

function SkelBar({ tk, w, h, radius = 6, style = {} }) {
  return (
    <div style={{
      width: w, height: h, borderRadius: radius,
      background: `linear-gradient(90deg, ${tk.cardSunken}, ${tk.border}, ${tk.cardSunken})`,
      backgroundSize: '200% 100%',
      animation: 'skel-pulse 1.4s ease-in-out infinite',
      ...style,
    }} />
  );
}

// Inject keyframes one-time
if (typeof document !== 'undefined' && !document.getElementById('skel-keyframes')) {
  const style = document.createElement('style');
  style.id = 'skel-keyframes';
  style.textContent = `@keyframes skel-pulse { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }`;
  document.head.appendChild(style);
}

function HomeErrorBanner({ tk, store, kind }) {
  const [dismissed, setDismissed] = useState(false);

  const content = kind === 'no_internet' ? {
    icon: 'wifi-off',
    title: 'Geen internet',
    body: 'Ik toon je laatste cache van 14:03. Zodra je weer online bent, sync ik alles automatisch.',
    color: tk.warn,
  } : {
    icon: 'alert-triangle',
    title: 'Opslaan mislukt',
    body: 'Pulse kon deze wijziging niet opslaan. Ik probeer het automatisch opnieuw over 5 sec · je planning blijft zoals je hem had.',
    color: tk.red,
  };

  return (
    <div style={{ background: tk.bgApp, minHeight: 'calc(100vh - 44px)' }}>
      <div style={{ display: 'flex', maxWidth: 1440, margin: '0 auto' }}>
        <Sidebar t={tk} active="plannen" />
        <div style={{ flex: 1, display: 'flex', flexDirection: 'column', minWidth: 0 }}>
          <Topbar t={tk} title="Plannen" subtitle="Dinsdag 22 april · 14:03" />

          {/* Error banner sticky bovenaan */}
          {!dismissed && (
            <div style={{
              margin: '0 28px', marginTop: 16,
              padding: '12px 16px', borderRadius: 10,
              background: hexToRgba(content.color, 0.10),
              border: `1px solid ${hexToRgba(content.color, 0.3)}`,
              display: 'flex', alignItems: 'center', gap: 12,
            }}>
              <div style={{
                width: 32, height: 32, borderRadius: 7,
                background: hexToRgba(content.color, 0.14),
                display: 'flex', alignItems: 'center', justifyContent: 'center',
              }}>
                <PI name={content.icon} size={16} color={content.color} />
              </div>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 12.5, fontWeight: 800, color: content.color }}>{content.title}</div>
                <div style={{ fontSize: 11.5, color: tk.fgDim, fontWeight: 600, marginTop: 1 }}>{content.body}</div>
              </div>
              {kind === 'save_fail' && (
                <button style={{
                  padding: '6px 12px', borderRadius: 7,
                  background: content.color, color: '#FFFFFF', border: 0,
                  fontSize: 11, fontWeight: 800, cursor: 'pointer',
                }}>
                  <PI name="rotate-ccw" size={11} /> Opnieuw
                </button>
              )}
              <button onClick={() => setDismissed(true)} style={{
                padding: 4, background: 'transparent', border: 0,
                color: tk.fgMute, cursor: 'pointer',
              }}>
                <PI name="x" size={14} />
              </button>
            </div>
          )}

          {/* Normale Stapel daaronder (gedimd bij error) */}
          <div style={{ opacity: kind === 'save_fail' ? 0.85 : 1 }}>
            <StapelContent store={store} />
          </div>
        </div>
      </div>
    </div>
  );
}

/* ═══════════════════════════════════════════════════════════════════
   COMPONENT: Week-strip enriched (icon + vak-afkorting)
   ═══════════════════════════════════════════════════════════════════ */

function WeekStripRich({ t, week, deadlines, vacations, onDayClick, onWeekClick, onStudyTimeClick, onAddTask }) {
  // Week-offset voor prev/next navigatie
  const [weekOffset, setWeekOffset] = React.useState(0);
  const weekNr = 17 + weekOffset;

  // Genereer week-data per offset. Offset 0 = de 'week' prop (met isToday-flag).
  // Overige weken: dagen gegenereerd uit isoDate + gemockte items per dag.
  const displayedWeek = React.useMemo(() => {
    if (weekOffset === 0) return week;
    // Week 17 maandag = 2026-04-21
    const baseMonday = new Date('2026-04-21');
    baseMonday.setDate(baseMonday.getDate() + weekOffset * 7);
    const days = [];
    for (let i = 0; i < 7; i++) {
      const d = new Date(baseMonday);
      d.setDate(baseMonday.getDate() + i);
      const iso = d.toISOString().slice(0, 10);
      const lbl = mockDayLabel(iso);
      days.push({
        label: lbl.day, date: lbl.date, isoDate: iso,
        isToday: false,
        isWeekend: i >= 5,
        items: MOCK_WEEK_ITEMS[iso] || [],
      });
    }
    return days;
  }, [weekOffset, week]);

  // Datum-range uit displayedWeek (eerste t/m laatste dag)
  const firstDay = displayedWeek[0];
  const lastDay = displayedWeek[displayedWeek.length - 1];
  const firstD = new Date(firstDay.isoDate);
  const lastD = new Date(lastDay.isoDate);
  const nlMonth = (d) => d.toLocaleDateString('nl-NL', { month: 'short' }).replace('.', '');
  const sameMonth = firstD.getMonth() === lastD.getMonth();
  const dateRange = sameMonth
    ? `${firstDay.date}–${lastDay.date} ${nlMonth(firstD)}`
    : `${firstDay.date} ${nlMonth(firstD)} – ${lastDay.date} ${nlMonth(lastD)}`;

  // Samenvatting: aantal toetsen/SO/inlever op deze week (uit deadlines)
  const weekDeadlines = (deadlines || []).filter(d =>
    d.dueDate && d.dueDate >= firstDay.isoDate && d.dueDate <= lastDay.isoDate && BIG_DEADLINE_TYPES.includes(d.type) && !d.unscheduled
  );
  const toetsCount = weekDeadlines.filter(d => d.type === 'toets' || d.type === 'so').length;
  const inleverCount = weekDeadlines.filter(d => d.type === 'inlever').length;
  // Noem de eerste deadline bij naam (bv "Bio-toets vrijdag")
  let summary = '';
  if (weekDeadlines.length > 0) {
    const first = weekDeadlines[0];
    const dayLbl = mockDayLabel(first.dueDate).day.toLowerCase();
    const dayNames = { ma: 'maandag', di: 'dinsdag', wo: 'woensdag', do: 'donderdag', vr: 'vrijdag', za: 'zaterdag', zo: 'zondag' };
    const titleShort = first.title.split(' — ')[0].replace(/ H\d+.*/, '');
    summary = `${titleShort} ${dayNames[dayLbl] || dayLbl}`;
    if (weekDeadlines.length > 1) summary += ` · +${weekDeadlines.length - 1} meer`;
  } else {
    summary = weekOffset === 2 ? 'meivakantie' : 'geen deadlines';
  }
  return (
    <section style={{
      background: t.card, border: `1px solid ${t.border}`,
      borderRadius: 14, padding: '14px 18px 16px',
      boxShadow: t.shadowCard,
    }}>
      <header style={{ display: 'flex', alignItems: 'center', marginBottom: 10, gap: 8 }}>
        {/* Week-titel + prev/next direct ernaast */}
        <h3 style={{
          fontFamily: 'Fredoka One', fontSize: 18, fontWeight: 400,
          color: t.fg, margin: 0, letterSpacing: '-0.01em', cursor: 'pointer',
        }} onClick={onWeekClick}>Week {weekNr}</h3>
        <div style={{ display: 'inline-flex', gap: 2 }}>
          <button
            onClick={() => setWeekOffset(weekOffset - 1)}
            title="Vorige week"
            style={weekNavBtnStyle(t)}
          >
            <PI name="chevron-left" size={13} color={t.fgMute} />
          </button>
          <button
            onClick={() => setWeekOffset(weekOffset + 1)}
            title="Volgende week"
            style={weekNavBtnStyle(t)}
          >
            <PI name="chevron-right" size={13} color={t.fgMute} />
          </button>
        </div>
        {/* Datum-range + samenvatting */}
        <span style={{ fontSize: 12, color: t.fgMute, fontWeight: 600 }}>
          · {dateRange}
        </span>
        <span style={{
          fontSize: 11.5, color: t.fgDim, fontWeight: 600,
          padding: '2px 8px', borderRadius: 4,
          background: hexToRgba(t.fgFaint, 0.08),
          border: `1px solid ${t.border}`,
        }}>
          {summary}
        </span>
        {weekOffset !== 0 && (
          <button
            onClick={() => setWeekOffset(0)}
            title="Terug naar deze week"
            style={{
              padding: '3px 10px', borderRadius: 6,
              border: `1px solid ${t.primary}`, background: hexToRgba(t.primary, 0.08),
              color: t.primary, fontSize: 10.5, fontWeight: 800, cursor: 'pointer',
            }}
          >Deze week</button>
        )}
        <span style={{ flex: 1 }} />
        {onAddTask && (
          <button
            onClick={onAddTask}
            title="Nieuwe losse taak"
            style={{
              padding: '4px 10px', borderRadius: 6,
              border: `1px solid ${t.border}`, background: 'transparent',
              color: t.fgDim, fontSize: 11, fontWeight: 700, cursor: 'pointer',
              display: 'inline-flex', alignItems: 'center', gap: 4,
            }}
          >
            <PI name="plus" size={11} color={t.fgMute} />
            Taak
          </button>
        )}
        {onStudyTimeClick && (
          <button
            onClick={onStudyTimeClick}
            title="Pas je studie-tijden per dag aan"
            style={{
              padding: '4px 10px', borderRadius: 6,
              border: `1px solid ${t.border}`, background: 'transparent',
              color: t.fgDim, fontSize: 11, fontWeight: 700, cursor: 'pointer',
              display: 'inline-flex', alignItems: 'center', gap: 4,
            }}
          >
            <PI name="clock" size={11} color={t.fgMute} />
            Studie-tijd
          </button>
        )}
        <button
          onClick={onWeekClick}
          style={{
            padding: '4px 10px', borderRadius: 6,
            border: `1px solid ${t.border}`, background: 'transparent',
            color: t.fgDim, fontSize: 11, fontWeight: 700, cursor: 'pointer',
          }}
        >Hele week →</button>
      </header>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, minmax(0, 1fr))', gap: 8 }}>
        {displayedWeek.map(d => (
          <WeekCellRich
            key={d.isoDate || d.date} t={t} d={d}
            dayDeadlines={deadlinesOnDate(deadlines, d.isoDate)}
            vacation={vacationForDate(d.isoDate, vacations)}
            onClick={() => onDayClick(d)}
          />
        ))}
      </div>
    </section>
  );
}

function WeekCellRich({ t, d, dayDeadlines, vacation, onClick }) {
  const rm = useRustModus();
  const isToday = d.isToday;
  const isWeekend = d.isWeekend;
  const isPast = d.status === 'past';
  // Backward-compat: fallback naar d.deadline als er geen deadlines-array is doorgegeven
  const deadlinesHere = dayDeadlines && dayDeadlines.length
    ? dayDeadlines
    : (d.deadline ? [{ subject: d.deadline.subject, type: d.deadline.type, title: d.deadline.title }] : []);
  const primary = deadlinesHere[0];
  const primaryColor = primary ? subjectColor(primary.subject, rm, t) : null;
  return (
    <button
      onClick={onClick}
      style={{
        // Neutrale achtergrond — de deadline-pill doet het werk (meerdere toetsen op 1 dag = geen kleurconflict)
        background: isWeekend ? t.cardSunken : t.cardAlt,
        border: isToday ? `2px solid ${t.primary}` : `1px solid ${t.border}`,
        borderRadius: 10, padding: '10px 8px 8px',
        cursor: 'pointer', textAlign: 'left',
        minHeight: 100,
        minWidth: 0,
        display: 'flex', flexDirection: 'column', gap: 6,
        opacity: isPast ? 0.5 : 1,
        boxShadow: isToday
          ? `0 0 0 3px ${hexToRgba(t.primary, 0.2)}, 0 0 20px ${hexToRgba(t.primary, 0.15)}`
          : 'none',
        overflow: 'hidden',
      }}
    >
      {/* Header */}
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
        <span style={{
          fontSize: 10, fontWeight: 800, letterSpacing: 0.6,
          color: isToday ? t.primary : t.fgMute, textTransform: 'uppercase',
        }}>{d.label}{isToday ? ' · Vandaag' : ''}</span>
        <span style={{
          fontFamily: 'Fredoka One', fontSize: 16, color: isToday ? t.primary : t.fg,
        }}>{d.date}</span>
      </div>

      {/* Vakantie / vrije dag — all-day strip bovenin, gevolgd door HR-break */}
      {vacation && (
        <>
          <div style={{
            padding: '3px 6px', borderRadius: 4,
            background: hexToRgba(t.warn, 0.14),
            border: `1px solid ${hexToRgba(t.warn, 0.3)}`,
            display: 'flex', alignItems: 'center', gap: 4,
            minWidth: 0,
          }}>
            <PI name="sun" size={9} color={t.warn} />
            <span style={{
              fontSize: 9, fontWeight: 800, color: t.warn,
              letterSpacing: 0.3, textTransform: 'uppercase',
              overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
            }}>{vacation.name}</span>
          </div>
          <div style={{ height: 1, background: t.border, margin: '2px 0' }} />
        </>
      )}

      {/* Deadlines — zachte tint + vak-gekleurde border + kleine gevulde type-pill */}
      {deadlinesHere.map((x, i) => {
        const sc = subjectColor(x.subject, rm, t);
        const meta = DEADLINE_TYPES[x.type] || { short: String(x.type || '').toUpperCase(), icon: 'flag' };
        return (
          <div key={i} style={{
            padding: '4px 6px', borderRadius: 5,
            background: hexToRgba(sc, 0.12),
            border: `1.5px solid ${sc}`,
            display: 'flex', flexDirection: 'column', gap: 2,
            minWidth: 0,
          }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 4, minWidth: 0 }}>
              <span style={{
                padding: '0 4px', borderRadius: 2,
                background: sc, color: '#FFFFFF',
                fontSize: 8, fontWeight: 800, letterSpacing: 0.4, lineHeight: 1.4,
                flexShrink: 0,
              }}>{meta.short}</span>
              <PI name={meta.icon} size={9} color={sc} />
            </div>
            <span style={{
              fontSize: 9.5, fontWeight: 800, color: t.fg,
              // 2 regels max + ellipsis zodat lange titels niet de kolom oprekken
              display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical',
              overflow: 'hidden', textOverflow: 'ellipsis',
              lineHeight: 1.25, wordBreak: 'break-word',
            }}>{(x.title || '').split(' — ')[0]}</span>
          </div>
        );
      })}

      {/* Items (vak-icon + afkorting) */}
      {d.items.length === 0 && deadlinesHere.length === 0 ? (
        <span style={{ fontSize: 10, color: t.fgFaint, fontStyle: 'italic', fontWeight: 500 }}>
          {isWeekend ? '— weekend —' : '— leeg —'}
        </span>
      ) : (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 3, minWidth: 0 }}>
          {d.items.slice(0, 3).map((item, i) => {
            const ic = subjectColor(item.subject, rm, t);
            return (
              <div key={i} style={{
                display: 'flex', alignItems: 'center', gap: 4,
                padding: '2px 5px', borderRadius: 4,
                background: hexToRgba(ic, 0.10),
                border: `1px solid ${hexToRgba(ic, 0.18)}`,
                minWidth: 0,
              }}>
                <PI name={SUBJECT_ICON_NAME(item.subject)} size={10} color={ic} />
                <span style={{
                  fontSize: 10, fontWeight: 700, color: ic,
                  overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
                }}>
                  {item.short}{item.count > 1 ? ` ×${item.count}` : ''}
                </span>
              </div>
            );
          })}
          {d.items.length > 3 && (
            <span style={{ fontSize: 9, color: t.fgMute, fontWeight: 600, paddingLeft: 5 }}>
              +{d.items.length - 3} meer
            </span>
          )}
        </div>
      )}
    </button>
  );
}

function SUBJECT_ICON_NAME(subject) {
  const map = {
    wiskunde: 'calculator', biologie: 'leaf', scheikunde: 'flask-conical',
    natuurkunde: 'zap', geschiedenis: 'landmark', aardrijkskunde: 'map',
    economie: 'trending-up', informatica: 'terminal', engels: 'book',
    nederlands: 'book-open-text', frans: 'languages', duits: 'languages',
    maatschappijleer: 'users',
  };
  return map[subject] || 'circle';
}

/* ═══════════════════════════════════════════════════════════════════
   COMPONENT: DeadlineCard (eenvoudige versie voor prototype)
   ═══════════════════════════════════════════════════════════════════ */

function DeadlineCardPrototype({ t, deadline, onClick, onPlanIn }) {
  const rm = useRustModus();
  const [expanded, setExpanded] = useState(false);
  const [checklist, setChecklist] = useState(
    getDeadlineChecklist(deadline.id).map(s => ({
      label: s.label, done: s.done, isNow: s.isNow,
    }))
  );

  // Ongeplande deadline → aparte rendering (dashed border, geen progress, "Plan in")
  if (deadline.unscheduled) {
    return <UnscheduledDeadlineCard t={t} deadline={deadline} onClick={onClick} onPlanIn={onPlanIn} />;
  }

  const days = resolveDaysAway(deadline);
  const urgency = days <= 3 ? 'urgent' : days <= 7 ? 'soon' : 'later';
  const urgencyColor = urgency === 'urgent' ? t.red : urgency === 'soon' ? t.warn : t.fgMute;

  const status = progressStatus(deadline.progressPercent, deadline.idealProgressPercent);
  const barColor = progressColor(t, status);
  const showIdealMarker = status === 'behind' || status === 'risk';
  const sc = subjectColor(deadline.subject, rm, t);

  const doneCount = checklist.filter(c => c.done).length;
  const totalCount = checklist.length;

  function toggleStep(idx, e) {
    e.stopPropagation();
    setChecklist(checklist.map((c, i) => i === idx ? { ...c, done: !c.done } : c));
  }

  return (
    <div style={{
      borderRadius: 12,
      background: t.card, border: `1px solid ${t.border}`,
      transition: 'box-shadow 0.15s',
      overflow: 'hidden',
    }}
      onMouseEnter={(e) => e.currentTarget.style.boxShadow = t.shadowElev}
      onMouseLeave={(e) => e.currentTarget.style.boxShadow = 'none'}
    >
      {/* Header — klikbaar, opent drawer */}
      <div style={{
        padding: '12px 14px 10px',
        display: 'flex', flexDirection: 'column', gap: 8,
        cursor: 'pointer',
      }} onClick={onClick}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <SubjectChip t={t} subject={deadline.subject} size="sm" />
          {/* Status-indicator icoon naast vak-badge */}
          {status === 'ahead' && (
            <span title="Voor op schema" style={statusIconStyle(t.green)}>
              <PI name="trending-up" size={12} color={t.green} />
            </span>
          )}
          {status === 'behind' && (
            <span title="Licht achter" style={statusIconStyle(t.warn)}>
              <PI name="alert-circle" size={12} color={t.warn} />
            </span>
          )}
          {status === 'risk' && (
            <span title="Risico — inhalen" style={statusIconStyle(t.red)}>
              <PI name="alert-triangle" size={12} color={t.red} />
            </span>
          )}
          <span style={{ flex: 1 }} />
          <span style={{
            fontSize: 10, fontWeight: 800, color: urgencyColor,
            padding: '2px 8px', borderRadius: 4,
            background: hexToRgba(urgencyColor, 0.12),
          }}>
            {days === 0 ? 'VANDAAG' : days === 1 ? 'MORGEN' : `OVER ${days}D`}
          </span>
          {/* Expand-toggle — klapt details (progress + checklist) uit */}
          <button
            onClick={(e) => { e.stopPropagation(); setExpanded(!expanded); }}
            title={expanded ? 'Details verbergen' : 'Details tonen'}
            style={{
              width: 22, height: 22, padding: 0,
              background: 'transparent', border: `1px solid ${t.border}`,
              borderRadius: 5, color: t.fgMute, cursor: 'pointer',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              flexShrink: 0,
            }}
          >
            <PI name={expanded ? 'chevron-up' : 'chevron-down'} size={12} color={t.fgMute} />
          </button>
        </div>
        <div style={{ fontSize: 13, fontWeight: 700, color: t.fg, lineHeight: 1.4 }}>
          {deadline.title}
        </div>
      </div>

      {/* Expanded body: progress-bar + status-label + checklist */}
      {expanded && (
        <div style={{
          padding: '10px 14px 12px',
          background: t.cardSunken, borderTop: `1px solid ${t.border}`,
          display: 'flex', flexDirection: 'column', gap: 10,
        }}>
          {/* Progress-bar + % */}
          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            <div style={{
              flex: 1, height: 5, borderRadius: 3,
              background: t.card, overflow: 'hidden',
              position: 'relative',
            }}>
              <div style={{
                width: `${deadline.progressPercent}%`, height: '100%',
                background: barColor, borderRadius: 3,
                transition: 'width 0.4s',
              }} />
              {showIdealMarker && (
                <div style={{
                  position: 'absolute', top: -2, bottom: -2,
                  left: `${deadline.idealProgressPercent}%`,
                  width: 2, background: t.fgDim, borderRadius: 1,
                }} title={`Op schema: ${deadline.idealProgressPercent}%`} />
              )}
            </div>
            <span style={{ fontSize: 10, fontWeight: 800, color: barColor }}>
              {deadline.progressPercent}%
            </span>
          </div>
          {status !== 'onTrack' && (
            <div style={{
              fontSize: 10.5, fontWeight: 700, color: barColor,
              display: 'inline-flex', alignItems: 'center', gap: 4,
            }}>
              {status === 'ahead' && <><PI name="trending-up" size={10} color={barColor} /> {progressLabel(status)}</>}
              {status === 'behind' && <><PI name="alert-circle" size={10} color={barColor} /> {progressLabel(status)} · {deadline.idealProgressPercent - deadline.progressPercent}% te weinig</>}
              {status === 'risk' && <><PI name="alert-triangle" size={10} color={barColor} /> {progressLabel(status)}</>}
            </div>
          )}

          {/* Checklist (stappen) */}
          {totalCount > 0 && (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
              <div style={{
                fontSize: 9.5, fontWeight: 800, color: t.fgMute,
                letterSpacing: 0.5, textTransform: 'uppercase', marginBottom: 2,
              }}>Stappen · {doneCount}/{totalCount} klaar</div>
              {checklist.map((step, i) => (
                <button
                  key={i}
                  onClick={(e) => toggleStep(i, e)}
                  style={{
                    display: 'flex', alignItems: 'center', gap: 7,
                    padding: '5px 6px', borderRadius: 5,
                    background: step.isNow && !step.done ? hexToRgba(sc, 0.08) : 'transparent',
                    border: 0, cursor: 'pointer', textAlign: 'left',
                  }}
                >
                  <div style={{
                    width: 14, height: 14, borderRadius: 3,
                    background: step.done ? sc : 'transparent',
                    border: step.done ? `2px solid ${sc}` : `1.5px solid ${t.border}`,
                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                    flexShrink: 0,
                  }}>
                    {step.done && <PI name="check" size={9} color="#FFFFFF" />}
                  </div>
                  <span style={{
                    flex: 1, fontSize: 11, fontWeight: 600,
                    color: step.done ? t.fgMute : t.fg,
                    textDecoration: step.done ? 'line-through' : 'none',
                  }}>
                    {step.label}
                  </span>
                  {step.isNow && !step.done && (
                    <span style={{
                      fontSize: 8.5, fontWeight: 800, color: sc,
                      padding: '1px 5px', borderRadius: 3,
                      background: hexToRgba(sc, 0.14),
                      letterSpacing: 0.3, textTransform: 'uppercase',
                    }}>Nu</span>
                  )}
                </button>
              ))}
              <button style={{
                padding: '4px 6px', borderRadius: 4,
                background: 'transparent', border: `1px dashed ${t.border}`,
                color: t.fgMute, fontSize: 10, fontWeight: 700, cursor: 'pointer',
                marginTop: 3, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 3,
              }}>
                <PI name="plus" size={10} /> Stap toevoegen
              </button>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

function statusIconStyle(color) {
  return {
    width: 18, height: 18, borderRadius: 9,
    background: hexToRgba(color, 0.14),
    display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
    flexShrink: 0,
  };
}

function weekNavBtnStyle(t) {
  return {
    width: 24, height: 24, padding: 0,
    border: `1px solid ${t.border}`, background: 'transparent',
    borderRadius: 5, color: t.fgDim, cursor: 'pointer',
    display: 'flex', alignItems: 'center', justifyContent: 'center',
  };
}

function addDeadlineMenuBtn(tk) {
  return {
    width: '100%', padding: '8px 10px', borderRadius: 6,
    background: 'transparent', border: 0, textAlign: 'left',
    cursor: 'pointer',
    display: 'flex', alignItems: 'center', gap: 10,
    transition: 'background 0.1s',
  };
}

/* ═══════════════════════════════════════════════════════════════════
   COMPONENT: UnscheduledDeadlineCard — voor deadlines zonder ingeplande blokken
   (quick-add of Magister-import). Visueel apart: dashed border, geen progress.
   ═══════════════════════════════════════════════════════════════════ */

function UnscheduledDeadlineCard({ t, deadline, onClick, onPlanIn, onHide, onDelete }) {
  const rm = useRustModus();
  const sc = subjectColor(deadline.subject, rm, t);
  const days = deadline.dueDate ? resolveDaysAway(deadline) : null;
  const [menuOpen, setMenuOpen] = useState(false);
  const dateLabel = days == null
    ? '⏳ Datum onbekend'
    : days === 0 ? 'VANDAAG'
    : days === 1 ? 'MORGEN'
    : `OVER ${days}D`;
  return (
    <div style={{
      borderRadius: 12,
      background: t.cardSunken,
      border: `1.5px dashed ${hexToRgba(sc, 0.55)}`,
      padding: '10px 12px',
      display: 'flex', flexDirection: 'column', gap: 8,
      cursor: 'pointer',
      transition: 'background 0.15s',
      position: 'relative',
    }}
      onClick={onClick}
      onMouseEnter={(e) => e.currentTarget.style.background = hexToRgba(sc, 0.06)}
      onMouseLeave={(e) => e.currentTarget.style.background = t.cardSunken}
    >
      <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
        <SubjectChip t={t} subject={deadline.subject} size="sm" />
        <span style={{ flex: 1 }} />
        <span style={{
          fontSize: 9, fontWeight: 800, color: t.fgMute,
          letterSpacing: 0.5, textTransform: 'uppercase',
          padding: '2px 7px', borderRadius: 4,
          background: hexToRgba(t.fgFaint, 0.12),
          display: 'inline-flex', alignItems: 'center', gap: 3,
        }}>
          {deadline.source === 'magister' && <PI name="download" size={9} color={t.fgMute} />}
          Te plannen
        </span>
        {(onHide || onDelete) && (
          <button
            onClick={(e) => { e.stopPropagation(); setMenuOpen(!menuOpen); }}
            title="Acties"
            style={{
              width: 22, height: 22, padding: 0,
              border: `1px solid ${t.border}`, background: 'transparent',
              borderRadius: 5, color: t.fgDim, cursor: 'pointer',
              fontSize: 13, lineHeight: 1,
              display: 'flex', alignItems: 'center', justifyContent: 'center',
            }}
          >⋯</button>
        )}
      </div>
      <div style={{ fontSize: 13, fontWeight: 700, color: t.fg, lineHeight: 1.4 }}>
        {deadline.title}
      </div>
      <div style={{
        fontSize: 10.5, fontWeight: 700, color: days != null && days <= 3 ? t.red : t.fgDim,
        display: 'inline-flex', alignItems: 'center', gap: 4,
      }}>
        <PI name={days == null ? 'help-circle' : 'calendar'} size={11} color={days != null && days <= 3 ? t.red : t.fgMute} />
        {dateLabel}
        {deadline.source === 'magister' && (
          <span style={{
            marginLeft: 6, fontSize: 9, color: t.fgMute, fontWeight: 700,
          }}>· uit Magister</span>
        )}
      </div>
      <button
        onClick={(e) => { e.stopPropagation(); if (onPlanIn) onPlanIn(deadline); }}
        style={{
          marginTop: 2, padding: '7px 10px', borderRadius: 7,
          background: sc, color: '#FFFFFF', border: 0,
          fontSize: 11.5, fontWeight: 800, cursor: 'pointer',
          display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 5,
          boxShadow: `0 2px 6px ${hexToRgba(sc, 0.3)}`,
        }}
      >
        <PI name="calendar-plus" size={12} color="#FFFFFF" />
        Plan in
      </button>

      {menuOpen && (
        <>
          <div onClick={(e) => { e.stopPropagation(); setMenuOpen(false); }} style={{ position: 'fixed', inset: 0, zIndex: 50 }} />
          <div style={{
            position: 'absolute', top: 36, right: 10,
            zIndex: 51, minWidth: 240,
            background: t.card, border: `1px solid ${t.border}`,
            borderRadius: 8, padding: 4,
            boxShadow: t.shadowElev,
          }}
            onClick={(e) => e.stopPropagation()}
          >
            {onHide && (
              <button
                onClick={(e) => { e.stopPropagation(); setMenuOpen(false); onHide(deadline); }}
                style={unscheduledMenuBtn(t, t.fg)}
                onMouseEnter={(e) => e.currentTarget.style.background = t.cardSunken}
                onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
              >
                <PI name="eye-off" size={12} color={t.fgDim} />
                <div>
                  <div style={{ fontSize: 12, fontWeight: 700, color: t.fg }}>Verbergen</div>
                  <div style={{ fontSize: 10, fontWeight: 500, color: t.fgMute, marginTop: 1 }}>
                    Foutje van docent · niet meer nodig
                  </div>
                </div>
              </button>
            )}
            {onDelete && (
              <button
                onClick={(e) => { e.stopPropagation(); setMenuOpen(false); onDelete(deadline); }}
                style={unscheduledMenuBtn(t, t.red)}
                onMouseEnter={(e) => e.currentTarget.style.background = hexToRgba(t.red, 0.06)}
                onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
              >
                <PI name="trash-2" size={12} color={t.red} />
                <div>
                  <div style={{ fontSize: 12, fontWeight: 700, color: t.red }}>Verwijderen</div>
                  <div style={{ fontSize: 10, fontWeight: 500, color: t.fgMute, marginTop: 1 }}>
                    Definitief weg (bij Magister-sync weer terug)
                  </div>
                </div>
              </button>
            )}
          </div>
        </>
      )}
    </div>
  );
}

function unscheduledMenuBtn(t, color) {
  return {
    width: '100%', padding: '8px 10px', borderRadius: 5,
    background: 'transparent', border: 0, textAlign: 'left',
    cursor: 'pointer',
    display: 'flex', alignItems: 'flex-start', gap: 8,
  };
}

/* ═══════════════════════════════════════════════════════════════════
   COMPONENT: TaskCard (prototype versie)
   ═══════════════════════════════════════════════════════════════════ */

function TaskCardPrototype({ t, task, deadlines, onToggleDone, onStart, compact, canMoveUp, canMoveDown, onMoveUp, onMoveDown, onLinkToDeadline, onOpenDeadline }) {
  const rm = useRustModus();
  const isNow = task.isNow && !task.done;
  const showReorder = (canMoveUp || canMoveDown) && !task.done;
  const isStandalone = !!task.standalone || task.deadlineId == null;
  const [menuOpen, setMenuOpen] = useState(false);
  const linkedDeadline = !isStandalone && deadlines
    ? deadlines.find(d => d.id === task.deadlineId)
    : null;
  const deadlineDays = linkedDeadline && linkedDeadline.dueDate ? resolveDaysAway(linkedDeadline) : null;
  return (
    <div style={{
      padding: compact ? '10px 12px' : '12px 14px',
      borderRadius: 10, background: t.card,
      // Losse taak (geen deadline) → dashed border ipv solid; lichter visueel gewicht
      border: isNow
        ? `2px solid ${t.primary}`
        : isStandalone
          ? `1px dashed ${hexToRgba(t.fgFaint, 0.7)}`
          : `1px solid ${t.border}`,
      boxShadow: isNow ? `0 0 16px ${hexToRgba(t.primary, 0.15)}` : 'none',
      opacity: task.done ? 0.5 : 1,
      display: 'flex', alignItems: 'center', gap: 10,
      position: 'relative',
    }}>
      <input
        type="checkbox"
        checked={task.done}
        onChange={(e) => { e.stopPropagation(); onToggleDone && onToggleDone(); }}
        style={{ width: 16, height: 16, cursor: 'pointer', accentColor: t.primary }}
      />
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 2 }}>
          <SubjectChip t={t} subject={task.subject} size="sm" />
          <TaskTypeLabel t={t}>{task.type}</TaskTypeLabel>
          {isStandalone && (
            <span style={{
              display: 'inline-flex', alignItems: 'center', gap: 3,
              fontSize: 9, fontWeight: 800, color: t.fgMute,
              padding: '1px 5px', borderRadius: 3,
              background: hexToRgba(t.fgFaint, 0.10),
              letterSpacing: 0.4, textTransform: 'uppercase',
            }} title="Losse taak — niet gekoppeld aan een deadline">
              📌 Los
            </span>
          )}
        </div>
        <div style={{
          fontSize: compact ? 12 : 13, fontWeight: 700, color: t.fg,
          textDecoration: task.done ? 'line-through' : 'none',
        }}>{task.title}</div>
        {/* Deadline-link: toont voor welke toets/inlever je dit doet */}
        {linkedDeadline && (
          <button
            onClick={(e) => { e.stopPropagation(); onOpenDeadline && onOpenDeadline(linkedDeadline); }}
            style={{
              marginTop: 3, padding: 0, border: 0, background: 'transparent',
              cursor: onOpenDeadline ? 'pointer' : 'default', textAlign: 'left',
              display: 'inline-flex', alignItems: 'center', gap: 4,
              fontSize: 10, color: t.fgDim, fontWeight: 600,
            }}
            title={onOpenDeadline ? 'Open deadline' : undefined}
          >
            <PI name="link" size={10} color={t.fgMute} />
            <span>voor</span>
            <span style={{ color: subjectColor(linkedDeadline.subject, rm, t), fontWeight: 800 }}>
              {linkedDeadline.title.split(' — ')[0]}
            </span>
            {deadlineDays != null && (
              <span style={{
                fontSize: 9, fontWeight: 800,
                color: deadlineDays <= 3 ? t.red : deadlineDays <= 7 ? t.warn : t.fgMute,
                padding: '1px 5px', borderRadius: 3,
                background: hexToRgba(deadlineDays <= 3 ? t.red : deadlineDays <= 7 ? t.warn : t.fgFaint, 0.14),
              }}>
                {deadlineDays === 0 ? 'VANDAAG' : deadlineDays === 1 ? 'MORGEN' : `${deadlineDays}D`}
              </span>
            )}
          </button>
        )}
        {!compact && (
          <div style={{ fontSize: 10.5, color: t.fgMute, fontWeight: 600, marginTop: 2 }}>
            {task.scheduledTime || `${task.mins} min`}
          </div>
        )}
      </div>
      {/* Drie-puntjes menu — alleen tonen als losse taak (om te koppelen) */}
      {isStandalone && onLinkToDeadline && !task.done && (
        <button
          onClick={(e) => { e.stopPropagation(); setMenuOpen(!menuOpen); }}
          style={{
            width: 22, height: 22, padding: 0,
            background: 'transparent', border: `1px solid ${t.border}`,
            borderRadius: 5, color: t.fgDim,
            cursor: 'pointer', fontSize: 13, lineHeight: 1,
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}
          title="Acties"
        >⋯</button>
      )}
      {menuOpen && (
        <>
          <div
            onClick={() => setMenuOpen(false)}
            style={{ position: 'fixed', inset: 0, zIndex: 50 }}
          />
          <div style={{
            position: 'absolute', top: '100%', right: 8, marginTop: 4,
            zIndex: 51, minWidth: 200,
            background: t.card, border: `1px solid ${t.border}`,
            borderRadius: 8, padding: 4,
            boxShadow: t.shadowElev,
          }}>
            <button
              onClick={(e) => { e.stopPropagation(); setMenuOpen(false); onLinkToDeadline && onLinkToDeadline(task); }}
              style={{
                width: '100%', padding: '7px 10px', borderRadius: 5,
                background: 'transparent', border: 0, textAlign: 'left',
                fontSize: 12, fontWeight: 700, color: t.fg, cursor: 'pointer',
                display: 'flex', alignItems: 'center', gap: 6,
              }}
              onMouseEnter={(e) => e.currentTarget.style.background = t.cardSunken}
              onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
            >
              <PI name="link" size={12} color={t.fgDim} />
              Koppel aan deadline
            </button>
          </div>
        </>
      )}
      {/* Reorder-knoppen verwijderd in Vandaag/Morgen — volgorde kan je in week-view wijzigen */}
      {/* Start-knop: altijd beschikbaar (volgorde wordt niet afgedwongen).
         isNow = primary-kleur + duur zichtbaar; andere taken = ghost icon-only. */}
      {onStart && !task.done && (
        isNow ? (
          <button
            onClick={(e) => { e.stopPropagation(); onStart(); }}
            style={{
              padding: '6px 12px', borderRadius: 8,
              background: t.primary, color: '#FFFFFF',
              border: 0, fontSize: 11, fontWeight: 800,
              cursor: 'pointer', display: 'inline-flex', alignItems: 'center', gap: 4,
            }}
          >
            <PI name="play" size={12} color="#FFFFFF" /> Start · {task.mins}m
          </button>
        ) : (
          <button
            onClick={(e) => { e.stopPropagation(); onStart(); }}
            title={`Start · ${task.mins}m`}
            style={{
              width: 30, height: 30, padding: 0,
              borderRadius: 7,
              background: 'transparent',
              border: `1px solid ${t.border}`,
              color: t.primary, cursor: 'pointer',
              display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
              transition: 'background 0.15s, border-color 0.15s',
            }}
            onMouseEnter={(e) => {
              e.currentTarget.style.background = hexToRgba(t.primary, 0.1);
              e.currentTarget.style.borderColor = t.primary;
            }}
            onMouseLeave={(e) => {
              e.currentTarget.style.background = 'transparent';
              e.currentTarget.style.borderColor = t.border;
            }}
          >
            <PI name="play" size={13} color={t.primary} />
          </button>
        )
      )}
    </div>
  );
}

// Reorder helper voor task-lists in store
function reorderTaskList(list, taskId, direction) {
  const idx = list.findIndex(t => t.id === taskId);
  if (idx < 0) return list;
  const target = idx + direction;
  if (target < 0 || target >= list.length) return list;
  const next = [...list];
  [next[idx], next[target]] = [next[target], next[idx]];
  return next;
}

/* ═══════════════════════════════════════════════════════════════════
   COMPONENT: Herstel-bak (prototype)
   ═══════════════════════════════════════════════════════════════════ */

function HerstelBakPrototype({ t, missed, onHerplan, onItemAction }) {
  // Per-item state voor menu
  const [openMenuId, setOpenMenuId] = useState(null);
  // Mock-state per item (alleen visueel in prototype)
  const [handled, setHandled] = useState({}); // { [id]: 'gedaan' | 'weggooien' }

  function handleItem(id, action) {
    setHandled({ ...handled, [id]: action });
    setOpenMenuId(null);
    if (onItemAction) onItemAction(id, action);
  }

  const remaining = missed.filter(m => !handled[m.id]);

  return (
    <div style={{
      background: t.herstelBg, border: `1px solid ${t.herstelBorder}`,
      borderRadius: 10, padding: '10px 12px', marginBottom: 14,
    }}>
      <div style={{
        display: 'flex', alignItems: 'center', gap: 6, marginBottom: 6,
      }}>
        <PI name="rotate-ccw" size={12} color={t.herstelTitle} />
        <span style={{
          fontSize: 9.5, fontWeight: 800, letterSpacing: 0.6,
          color: t.herstelTitle, textTransform: 'uppercase',
        }}>Herstel-bak · {remaining.length} {remaining.length === 1 ? 'taak' : 'taken'} gemist</span>
      </div>
      <div style={{ fontSize: 12, color: t.herstelFg, fontWeight: 600, lineHeight: 1.45, marginBottom: 8 }}>
        {remaining.length === 0
          ? 'Alles afgehandeld. Mooi.'
          : `${remaining.length} ${remaining.length === 1 ? 'taak' : 'taken'} van de vorige dagen nog niet gedaan.`}
      </div>

      {/* Per-item rijen met menu */}
      <div style={{ display: 'flex', flexDirection: 'column', gap: 6, marginBottom: 10 }}>
        {missed.map(m => {
          const state = handled[m.id];
          const isHandled = !!state;
          return (
            <div key={m.id} style={{
              padding: '6px 8px', borderRadius: 6,
              background: isHandled ? hexToRgba(t.fgFaint, 0.06) : 'transparent',
              border: `1px solid ${isHandled ? t.border : 'transparent'}`,
              display: 'flex', alignItems: 'center', gap: 8,
              opacity: isHandled ? 0.55 : 1,
              position: 'relative',
            }}>
              <SubjectChip t={t} subject={m.subject} size="sm" />
              <span style={{
                flex: 1, fontSize: 11.5, color: t.herstelFg, fontWeight: 600,
                textDecoration: state === 'gedaan' ? 'line-through' : 'none',
                minWidth: 0, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
              }}>{m.title}</span>
              <span style={{ fontSize: 10, color: t.herstelFg, fontWeight: 600, opacity: 0.7, whiteSpace: 'nowrap' }}>
                {m.missedDate}
              </span>
              {isHandled ? (
                <span style={{
                  fontSize: 9, fontWeight: 800, letterSpacing: 0.4, textTransform: 'uppercase',
                  padding: '2px 6px', borderRadius: 3,
                  color: state === 'gedaan' ? t.green : t.fgMute,
                  background: state === 'gedaan' ? hexToRgba(t.green, 0.14) : hexToRgba(t.fgFaint, 0.12),
                }}>{state === 'gedaan' ? '✓ gedaan' : '✕ weg'}</span>
              ) : (
                <button
                  onClick={(e) => { e.stopPropagation(); setOpenMenuId(openMenuId === m.id ? null : m.id); }}
                  style={{
                    width: 22, height: 22, padding: 0,
                    border: `1px solid ${t.border}`, background: 'transparent',
                    borderRadius: 5, color: t.fgDim, cursor: 'pointer',
                    fontSize: 13, lineHeight: 1,
                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                  }} title="Acties"
                >⋯</button>
              )}

              {openMenuId === m.id && (
                <>
                  <div onClick={() => setOpenMenuId(null)} style={{ position: 'fixed', inset: 0, zIndex: 50 }} />
                  <div style={{
                    position: 'absolute', top: '100%', right: 4, marginTop: 4,
                    zIndex: 51, minWidth: 180,
                    background: t.card, border: `1px solid ${t.border}`,
                    borderRadius: 8, padding: 4, boxShadow: t.shadowElev,
                  }}>
                    <HerstelActionButton t={t} icon="calendar-plus" label="Herplannen" color={t.red}
                      onClick={() => handleItem(m.id, 'herplan')} />
                    <HerstelActionButton t={t} icon="check" label="Al gedaan" color={t.green}
                      onClick={() => handleItem(m.id, 'gedaan')} />
                    <HerstelActionButton t={t} icon="trash-2" label="Weggooien" color={t.fgMute}
                      onClick={() => handleItem(m.id, 'weggooien')} />
                  </div>
                </>
              )}
            </div>
          );
        })}
      </div>

      {/* Batch-herplan actie — alleen als er nog items over zijn */}
      {remaining.length > 1 && (
        <button
          onClick={onHerplan}
          style={{
            width: '100%', padding: '8px 12px', borderRadius: 8,
            background: t.red, color: '#FFFFFF', border: 0,
            fontSize: 12, fontWeight: 800, cursor: 'pointer',
            display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 5,
          }}
        >
          <PI name="calendar-plus" size={12} color="#FFFFFF" />
          Alle {remaining.length} herplannen →
        </button>
      )}
    </div>
  );
}

function HerstelActionButton({ t, icon, label, color, onClick }) {
  return (
    <button
      onClick={(e) => { e.stopPropagation(); onClick(); }}
      style={{
        width: '100%', padding: '7px 10px', borderRadius: 5,
        background: 'transparent', border: 0, textAlign: 'left',
        fontSize: 12, fontWeight: 700, color: t.fg, cursor: 'pointer',
        display: 'flex', alignItems: 'center', gap: 7,
      }}
      onMouseEnter={(e) => e.currentTarget.style.background = t.cardSunken}
      onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
    >
      <PI name={icon} size={12} color={color} />
      {label}
    </button>
  );
}

/* ═══════════════════════════════════════════════════════════════════
   COMPONENT: Zachte modus ("geen zin")
   ═══════════════════════════════════════════════════════════════════ */

function ZachteModus({ t, tasks, onExit, store }) {
  // Enkel de "kleinste" taak overhouden (eerste), rest wordt voorgesteld om te herplannen
  const kleinsteTaak = tasks[0];
  const teHerplannen = tasks.slice(1).filter(x => !x.done);

  return (
    <div style={{
      padding: '20px 20px 18px', borderRadius: 14,
      background: t.card, border: `1.5px solid ${hexToRgba(t.purple, 0.3)}`,
      position: 'relative', overflow: 'hidden',
    }}>
      {/* Gradient accent top */}
      <div style={{
        position: 'absolute', top: 0, left: 0, right: 0, height: 3,
        background: `linear-gradient(90deg, ${t.purple}, ${t.primary})`,
      }} />

      {/* Pulse-card */}
      <div style={{ display: 'flex', alignItems: 'flex-start', gap: 12, marginBottom: 14 }}>
        <PulseMascot size={42} mood="encouraging" />
        <div style={{ flex: 1 }}>
          <div style={{
            fontSize: 10, fontWeight: 800, color: t.purple,
            letterSpacing: 0.5, textTransform: 'uppercase', marginBottom: 3,
          }}>Zachte dagmodus</div>
          <div style={{ fontFamily: 'Fredoka One', fontSize: 18, color: t.fg, lineHeight: 1.2, marginBottom: 4 }}>
            Oké. Laten we de dag kleiner maken.
          </div>
          <div style={{ fontSize: 12, color: t.fgDim, fontWeight: 500, lineHeight: 1.55 }}>
            Ik laat alleen de kleinste taak staan ({kleinsteTaak?.mins || 0} min).
            {teHerplannen.length > 0 ? ` De andere ${teHerplannen.length} kunnen we verplaatsen naar een dag die beter voelt.` : ''}
          </div>
        </div>
      </div>

      {/* Kleinste taak */}
      {kleinsteTaak && (
        <>
          <div style={{
            fontSize: 10, fontWeight: 800, color: t.fgMute,
            letterSpacing: 0.5, textTransform: 'uppercase', marginBottom: 6,
          }}>Vandaag — één ding</div>
          <div style={{
            padding: '10px 12px', borderRadius: 10,
            background: hexToRgba(SUBJECTS[kleinsteTaak.subject], 0.10),
            border: `1px solid ${hexToRgba(SUBJECTS[kleinsteTaak.subject], 0.25)}`,
            display: 'flex', alignItems: 'center', gap: 8,
            marginBottom: 14,
          }}>
            <SubjectChip t={t} subject={kleinsteTaak.subject} size="sm" />
            <span style={{ fontSize: 12.5, fontWeight: 700, color: t.fg, flex: 1 }}>
              {kleinsteTaak.title}
            </span>
            <span style={{ fontSize: 11, color: t.fgMute, fontWeight: 700 }}>
              {kleinsteTaak.mins} min · vrijblijvend
            </span>
          </div>
        </>
      )}

      {/* Te herplannen */}
      {teHerplannen.length > 0 && (
        <>
          <div style={{
            fontSize: 10, fontWeight: 800, color: t.fgMute,
            letterSpacing: 0.5, textTransform: 'uppercase', marginBottom: 6,
            display: 'flex', alignItems: 'center', gap: 6,
          }}>
            <PI name="arrow-right-circle" size={12} color={t.fgMute} />
            Verplaats naar andere dag
          </div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 5, marginBottom: 14 }}>
            {teHerplannen.map(task => (
              <div key={task.id} style={{
                padding: '8px 10px', borderRadius: 8,
                background: t.cardSunken, border: `1px solid ${t.border}`,
                display: 'flex', alignItems: 'center', gap: 8,
                opacity: 0.75,
              }}>
                <SubjectChip t={t} subject={task.subject} size="sm" />
                <span style={{ fontSize: 11.5, fontWeight: 600, color: t.fg, flex: 1 }}>{task.title}</span>
                <span style={{ fontSize: 10, color: t.fgMute, fontWeight: 700 }}>{task.mins}m</span>
              </div>
            ))}
          </div>

          {/* Herplan-opties */}
          <div style={{ display: 'flex', gap: 6, marginBottom: 10 }}>
            <button
              onClick={() => store && store.navigate('/herplan')}
              style={{
                flex: 1, padding: '10px', borderRadius: 9,
                background: store && store.plan === 'premium' ? t.purple : t.primary,
                color: '#FFFFFF', border: 0,
                fontSize: 12, fontWeight: 800, cursor: 'pointer',
                display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 4,
              }}>
              {store && store.plan === 'premium' ? (
                <><PI name="sparkles" size={12} /> Laat Pulse herplannen</>
              ) : (
                <><PI name="move-vertical" size={12} /> Zelf herplannen</>
              )}
            </button>
            <button style={{
              padding: '10px 14px', borderRadius: 9,
              background: 'transparent', border: `1px solid ${t.border}`,
              color: t.fgDim, fontSize: 11.5, fontWeight: 700, cursor: 'pointer',
            }}>
              Schuif door naar morgen
            </button>
          </div>
        </>
      )}

      {/* Voet */}
      <div style={{
        paddingTop: 12, borderTop: `1px solid ${t.border}`,
        display: 'flex', alignItems: 'center', gap: 8,
      }}>
        <div style={{ fontSize: 10.5, color: t.fgMute, fontWeight: 600, flex: 1 }}>
          Geen streak-druk · morgen is morgen
        </div>
        <button onClick={onExit} style={{
          padding: '6px 12px', borderRadius: 7,
          background: 'transparent', border: `1px solid ${t.border}`,
          color: t.fgDim, fontSize: 11, fontWeight: 700, cursor: 'pointer',
        }}>
          Terug naar normale Stapel
        </button>
      </div>
    </div>
  );
}

/* ═══════════════════════════════════════════════════════════════════
   SCREEN: EDIT DEADLINE (A4 + overflow menu + verwijder-flow)
   ═══════════════════════════════════════════════════════════════════ */

function ScreenEditDeadline({ store }) {
  const tk = t(store.theme);
  const deadline = store.deadlines.find(d => d.id === store.route.params.id);
  const [title, setTitle] = useState(deadline?.title || '');
  const [dueDate, setDueDate] = useState(deadline?.dueDate || '');
  const [type, setType] = useState(deadline?.type || 'toets');
  const [hours, setHours] = useState(deadline?.estimatedHours || 2);
  const [overflowOpen, setOverflowOpen] = useState(false);
  const [confirmDelete, setConfirmDelete] = useState(false);

  if (!deadline) {
    return <ScreenPlaceholder store={store} title="Deadline niet gevonden"
      description="Deze deadline bestaat niet meer." />;
  }

  const typeOptions = Object.keys(DEADLINE_TYPES).map(k => ({
    v: k, label: DEADLINE_TYPES[k].label, icon: DEADLINE_TYPES[k].icon,
  }));

  function save() {
    store.setDeadlines(store.deadlines.map(d =>
      d.id === deadline.id ? { ...d, title, dueDate, type, estimatedHours: hours } : d
    ));
    store.navigate(`/deadline/${deadline.id}`, { id: deadline.id });
  }

  function remove() {
    store.setDeadlines(store.deadlines.filter(d => d.id !== deadline.id));
    store.navigate('/');
  }

  const daysText = daysUntil(dueDate);
  const linkedMoments = 2; // mock

  return (
    <div style={{ background: tk.bgApp, minHeight: 'calc(100vh - 44px)', padding: '40px 20px' }}>
      <div style={{
        maxWidth: 640, margin: '0 auto',
        background: tk.card, border: `1px solid ${tk.border}`,
        borderRadius: 16, padding: '28px 32px', boxShadow: tk.shadowElev,
      }}>
        {/* Header with overflow menu */}
        <div style={{ display: 'flex', alignItems: 'center', marginBottom: 20 }}>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 10, fontWeight: 800, color: tk.primary, letterSpacing: 0.5, textTransform: 'uppercase', marginBottom: 2 }}>
              Deadline bewerken
            </div>
            <h2 style={{ fontFamily: 'Fredoka One', fontSize: 22, color: tk.fg, margin: 0, letterSpacing: '-0.01em' }}>
              <SubjectChip t={tk} subject={deadline.subject} size="sm" /> {deadline.title}
            </h2>
            <div style={{ fontSize: 11.5, color: tk.fgDim, fontWeight: 600, marginTop: 4 }}>
              Wijzig velden — gekoppelde studie-momenten worden herberekend bij opslaan.
            </div>
          </div>
          <div style={{ position: 'relative' }}>
            <button onClick={() => setOverflowOpen(!overflowOpen)} style={{
              width: 34, height: 34, borderRadius: 8,
              border: `1px solid ${tk.border}`, background: 'transparent',
              color: tk.fgDim, cursor: 'pointer',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              fontSize: 18, fontWeight: 800, lineHeight: 1,
            }}>⋯</button>
            {overflowOpen && (
              <div style={{
                position: 'absolute', top: 40, right: 0, width: 220,
                background: tk.card, border: `1px solid ${tk.border}`,
                borderRadius: 10, padding: 4, zIndex: 10,
                boxShadow: tk.shadowElev,
              }}>
                <OverflowItem tk={tk} icon="copy" label="Dupliceer" onClick={() => setOverflowOpen(false)} />
                <OverflowItem tk={tk} icon="bell" label="Herinnering instellen" onClick={() => setOverflowOpen(false)} />
                <OverflowItem tk={tk} icon="share-2" label="Deel met ouder/klas" onClick={() => setOverflowOpen(false)} />
                <div style={{ height: 1, background: tk.border, margin: '4px 0' }} />
                <OverflowItem tk={tk} icon="trash-2" label="Verwijderen" color={tk.red}
                  onClick={() => { setOverflowOpen(false); setConfirmDelete(true); }} />
              </div>
            )}
          </div>
        </div>

        {/* Form (simplified — subject is vast bij edit) */}
        <Field label="Titel" tk={tk} required>
          <input type="text" value={title} onChange={(e) => setTitle(e.target.value)} style={inputStyle(tk)} />
        </Field>

        <Field label="Type" tk={tk}>
          <div style={{ display: 'flex', gap: 6 }}>
            {typeOptions.map(to => (
              <button key={to.v} onClick={() => setType(to.v)} style={{
                flex: 1, padding: '10px 6px', borderRadius: 8,
                background: type === to.v ? hexToRgba(tk.primary, 0.10) : tk.cardSunken,
                border: type === to.v ? `1.5px solid ${tk.primary}` : `1px solid ${tk.border}`,
                color: type === to.v ? tk.primary : tk.fgDim,
                fontSize: 11, fontWeight: 800, cursor: 'pointer',
                display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4,
              }}>
                <PI name={to.icon} size={15} color={type === to.v ? tk.primary : tk.fgMute} />
                {to.label}
              </button>
            ))}
          </div>
        </Field>

        <Field label="Datum" tk={tk} required>
          <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
            <input type="date" value={dueDate} onChange={(e) => setDueDate(e.target.value)}
              style={{ ...inputStyle(tk), flex: 1 }} />
            <span style={{
              fontSize: 11, fontWeight: 800,
              color: daysText <= 3 ? tk.red : tk.primary,
              padding: '4px 10px', borderRadius: 6,
              background: hexToRgba(daysText <= 3 ? tk.red : tk.primary, 0.12),
            }}>
              {daysText === 0 ? 'Vandaag' : daysText === 1 ? 'Morgen' : `Over ${daysText}d`}
            </span>
          </div>
        </Field>

        <Field label="Geschatte studietijd" tk={tk}>
          <div style={{ display: 'flex', gap: 6 }}>
            {[1, 2, 3, 4, 5, 6, 8].map(h => (
              <button key={h} onClick={() => setHours(h)} style={{
                padding: '8px 12px', borderRadius: 8,
                background: hours === h ? hexToRgba(tk.primary, 0.10) : tk.cardSunken,
                border: hours === h ? `1px solid ${tk.primary}` : `1px solid ${tk.border}`,
                color: hours === h ? tk.primary : tk.fgDim,
                fontSize: 12, fontWeight: 800, cursor: 'pointer',
              }}>{h}u</button>
            ))}
          </div>
        </Field>

        {/* Footer */}
        <div style={{ display: 'flex', gap: 8, marginTop: 20, alignItems: 'center' }}>
          <button onClick={() => store.navigate(`/deadline/${deadline.id}`, { id: deadline.id })} style={btnSecondary(tk)}>
            Annuleer
          </button>
          <span style={{
            fontSize: 11, color: tk.fgMute, fontWeight: 600, marginLeft: 8,
            display: 'inline-flex', alignItems: 'center', gap: 4,
          }}>
            <PI name="link" size={11} />
            {linkedMoments} momenten gekoppeld
          </span>
          <span style={{ flex: 1 }} />
          <button onClick={save} style={btnPrimary(tk)}>
            <PI name="check" size={13} /> Bewaar wijzigingen
          </button>
        </div>
      </div>

      {/* Verwijder-bevestiging (modal) */}
      {confirmDelete && (
        <div style={{
          position: 'fixed', top: 44, left: 0, right: 0, bottom: 0,
          background: 'rgba(0,0,0,0.5)', zIndex: 100,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
        }} onClick={() => setConfirmDelete(false)}>
          <div onClick={(e) => e.stopPropagation()} style={{
            width: 400, background: tk.card,
            border: `1px solid ${tk.border}`, borderRadius: 14,
            padding: 24, boxShadow: tk.shadowElev,
          }}>
            <div style={{
              width: 44, height: 44, borderRadius: 10,
              background: hexToRgba(tk.red, 0.14),
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              marginBottom: 14,
            }}>
              <PI name="trash-2" size={20} color={tk.red} />
            </div>
            <h3 style={{
              fontFamily: 'Fredoka One', fontSize: 18, color: tk.fg,
              margin: '0 0 6px',
            }}>Deadline verwijderen?</h3>
            <p style={{ fontSize: 13, color: tk.fgDim, fontWeight: 500, lineHeight: 1.5, margin: '0 0 16px' }}>
              <b style={{ color: tk.fg }}>{deadline.title}</b> wordt weggehaald, plus <b style={{ color: tk.fg }}>{linkedMoments} gekoppelde studie-momenten</b>.
            </p>
            <div style={{
              padding: '10px 12px', borderRadius: 8,
              background: tk.cardSunken, border: `1px solid ${tk.border}`,
              fontSize: 11, color: tk.fgMute, fontWeight: 600, marginBottom: 16,
              display: 'flex', alignItems: 'center', gap: 6,
            }}>
              <PI name="info" size={12} color={tk.fgMute} />
              Je library-quiz en leer-hoofdstuk blijven bestaan.
            </div>
            <div style={{ display: 'flex', gap: 8 }}>
              <button onClick={() => setConfirmDelete(false)} style={{
                flex: 1, padding: '10px', borderRadius: 9,
                background: 'transparent', border: `1px solid ${tk.border}`,
                color: tk.fg, fontSize: 12, fontWeight: 700, cursor: 'pointer',
              }}>Behouden</button>
              <button onClick={remove} style={{
                flex: 1, padding: '10px', borderRadius: 9,
                background: tk.red, color: '#FFFFFF', border: 0,
                fontSize: 12, fontWeight: 800, cursor: 'pointer',
                display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 4,
              }}>
                <PI name="trash-2" size={12} /> Verwijder
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

function OverflowItem({ tk, icon, label, onClick, color }) {
  return (
    <button onClick={onClick} style={{
      width: '100%', padding: '9px 10px', borderRadius: 7,
      background: 'transparent', border: 0, cursor: 'pointer',
      display: 'flex', alignItems: 'center', gap: 8,
      fontSize: 12, fontWeight: 700, color: color || tk.fg,
      textAlign: 'left',
    }}
      onMouseEnter={(e) => e.currentTarget.style.background = tk.cardSunken}
      onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
    >
      <PI name={icon} size={14} color={color || tk.fgDim} />
      {label}
    </button>
  );
}

/* ═══════════════════════════════════════════════════════════════════
   SCREEN: ADD DEADLINE — 3-step wizard
   ═══════════════════════════════════════════════════════════════════ */

function ScreenAddDeadline({ store }) {
  const tk = t(store.theme);
  const step = store.route.path === '/add-deadline' ? 1
    : store.route.path === '/add-deadline/split' ? 2
    : store.route.path === '/add-deadline/place' ? 3
    : 1;

  // Stap 3 (week-calendar) heeft meer ruimte nodig dan stap 1/2 (form-fields)
  const wideStep = step === 3;

  return (
    <div style={{
      background: tk.bgApp, minHeight: 'calc(100vh - 44px)',
      padding: '40px 20px',
    }}>
      <div style={{
        maxWidth: wideStep ? 1200 : 760, margin: '0 auto',
        background: tk.card, border: `1px solid ${tk.border}`,
        borderRadius: 16, padding: '28px 32px',
        boxShadow: tk.shadowElev,
        transition: 'max-width 0.25s',
      }}>
        {/* Stepper */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 24 }}>
          {[1, 2, 3].map(i => (
            <React.Fragment key={i}>
              <div style={{
                width: 28, height: 28, borderRadius: 14,
                background: i <= step ? tk.primary : tk.cardSunken,
                border: `1px solid ${i === step ? tk.primary : tk.border}`,
                color: i <= step ? '#FFFFFF' : tk.fgMute,
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                fontSize: 11, fontWeight: 800,
              }}>{i < step ? '✓' : i}</div>
              {i < 3 && <div style={{ flex: 1, height: 1.5, background: i < step ? tk.primary : tk.border }} />}
            </React.Fragment>
          ))}
          <span style={{ marginLeft: 12, fontSize: 11, color: tk.fgMute, fontWeight: 700 }}>
            Stap {step} van 3
          </span>
        </div>

        {step === 1 && <AddDeadlineForm store={store} />}
        {step === 2 && <AddDeadlineBlockSplit store={store} />}
        {step === 3 && <AddDeadlinePlaceBlocks store={store} />}
      </div>
    </div>
  );
}

function AddDeadlineForm({ store }) {
  const tk = t(store.theme);
  // Pre-fill als we vanaf een ongeplande deadline komen (Plan in) — dan is params.planFor de deadline-id
  const planForId = store.route.params.planFor;
  const planForDeadline = planForId ? (store.deadlines || []).find(d => d.id === planForId) : null;

  const [subject, setSubject] = useState(planForDeadline?.subject || 'biologie');
  const [title, setTitle] = useState(planForDeadline?.title || '');
  const [dueDate, setDueDate] = useState(planForDeadline?.dueDate || '2026-05-02');
  const [type, setType] = useState(planForDeadline?.type || 'toets');
  const [hours, setHours] = useState(
    planForDeadline?.estimatedHours
      || (DEADLINE_TYPES[planForDeadline?.type]?.defaultHours)
      || 3
  );

  const commonSubjects = ['biologie', 'wiskunde', 'scheikunde', 'engels', 'nederlands', 'geschiedenis', 'frans'];
  const typeOptions = Object.keys(DEADLINE_TYPES).map(k => ({
    v: k, label: DEADLINE_TYPES[k].label, icon: DEADLINE_TYPES[k].icon,
  }));
  const [moreOptionsOpen, setMoreOptionsOpen] = useState(false);
  const [linkedQuiz, setLinkedQuiz] = useState(null);
  const [linkedChapter, setLinkedChapter] = useState(null);
  const [hasNote, setHasNote] = useState(false);

  const daysText = daysUntil(dueDate);
  const canContinue = title.trim().length > 0;

  return (
    <div>
      <h2 style={{
        fontFamily: 'Fredoka One', fontSize: 24, color: tk.fg,
        margin: '0 0 6px', letterSpacing: '-0.01em',
      }}>{planForDeadline ? 'Deadline inplannen' : 'Nieuwe deadline'}</h2>
      <p style={{ fontSize: 13, color: tk.fgDim, fontWeight: 500, margin: '0 0 24px' }}>
        {planForDeadline
          ? <>We hebben de basis al ingevuld — controleer en ga door naar <b style={{ color: tk.fg }}>blokken kiezen</b>.</>
          : 'Pulse stelt studie-momenten voor zodra je opslaat.'}
      </p>

      {planForDeadline && (
        <div style={{
          padding: '10px 12px', borderRadius: 8,
          background: hexToRgba(SUBJECTS[planForDeadline.subject], 0.08),
          border: `1px solid ${hexToRgba(SUBJECTS[planForDeadline.subject], 0.25)}`,
          marginBottom: 18,
          display: 'flex', alignItems: 'center', gap: 8,
          fontSize: 11.5, color: tk.fgDim, fontWeight: 600, lineHeight: 1.5,
        }}>
          <PI name="inbox" size={13} color={SUBJECTS[planForDeadline.subject]} />
          <span>
            Vanuit <b style={{ color: tk.fg }}>Te plannen</b>
            {planForDeadline.source === 'magister' && ' · geïmporteerd uit Magister'}
            {' · pas gerust aan voor je verder gaat.'}
          </span>
        </div>
      )}

      {/* Vak */}
      <Field label="Vak" tk={tk}>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
          {commonSubjects.map(s => (
            <button key={s} onClick={() => setSubject(s)} style={{
              padding: '6px 12px', borderRadius: 20,
              background: subject === s ? hexToRgba(SUBJECTS[s], 0.16) : tk.cardSunken,
              border: subject === s ? `1px solid ${hexToRgba(SUBJECTS[s], 0.4)}` : `1px solid ${tk.border}`,
              color: subject === s ? SUBJECTS[s] : tk.fgDim,
              fontSize: 11, fontWeight: 800, cursor: 'pointer',
              display: 'inline-flex', alignItems: 'center', gap: 4,
            }}>
              <PI name={SUBJECT_ICON_NAME(s)} size={12} color={subject === s ? SUBJECTS[s] : tk.fgMute} />
              {s.charAt(0).toUpperCase() + s.slice(1)}
            </button>
          ))}
        </div>
      </Field>

      {/* Titel */}
      <Field label="Titel" tk={tk} required>
        <input
          type="text" value={title} onChange={(e) => setTitle(e.target.value)}
          placeholder="bijv. H4 — celbiologie"
          style={inputStyle(tk)}
        />
      </Field>

      {/* Type — met iconen */}
      <Field label="Type" tk={tk}>
        <div style={{ display: 'flex', gap: 6 }}>
          {typeOptions.map(to => (
            <button key={to.v} onClick={() => setType(to.v)} style={{
              flex: 1, padding: '10px 6px', borderRadius: 8,
              background: type === to.v ? hexToRgba(tk.primary, 0.10) : tk.cardSunken,
              border: type === to.v ? `1.5px solid ${tk.primary}` : `1px solid ${tk.border}`,
              color: type === to.v ? tk.primary : tk.fgDim,
              fontSize: 11, fontWeight: 800, cursor: 'pointer',
              display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4,
            }}>
              <PI name={to.icon} size={16} color={type === to.v ? tk.primary : tk.fgMute} />
              {to.label}
            </button>
          ))}
        </div>
      </Field>

      {/* Datum */}
      <Field label="Datum" tk={tk} required>
        <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
          <input
            type="date" value={dueDate} onChange={(e) => setDueDate(e.target.value)}
            style={{ ...inputStyle(tk), flex: 1 }}
          />
          <span style={{
            fontSize: 11, fontWeight: 800, color: daysText <= 3 ? tk.red : tk.primary,
            padding: '4px 10px', borderRadius: 6,
            background: hexToRgba(daysText <= 3 ? tk.red : tk.primary, 0.10),
          }}>
            {daysText === 0 ? 'Vandaag' : daysText === 1 ? 'Morgen' : `Over ${daysText}d`}
          </span>
        </div>
      </Field>

      {/* Geschatte studietijd */}
      <Field label="Geschatte studietijd" tk={tk}>
        <div style={{ display: 'flex', gap: 6 }}>
          {[1, 2, 3, 4, 5, 6, 8].map(h => (
            <button key={h} onClick={() => setHours(h)} style={{
              padding: '8px 12px', borderRadius: 8,
              background: hours === h ? hexToRgba(tk.primary, 0.10) : tk.cardSunken,
              border: hours === h ? `1px solid ${tk.primary}` : `1px solid ${tk.border}`,
              color: hours === h ? tk.primary : tk.fgDim,
              fontSize: 12, fontWeight: 800, cursor: 'pointer',
            }}>{h}u</button>
          ))}
        </div>
        <div style={{ fontSize: 11, color: tk.fgMute, fontWeight: 600, marginTop: 6 }}>
          Standaard voor {type}: {type === 'toets' ? '3' : type === 'so' ? '1' : type === 'werkstuk' ? '6' : '2'}u · kan je in volgende stap opknippen in blokken
        </div>
      </Field>

      {/* Meer opties — collapsible */}
      <div style={{
        marginBottom: 14, borderRadius: 10,
        border: `1px solid ${tk.border}`,
        overflow: 'hidden',
      }}>
        <button onClick={() => setMoreOptionsOpen(!moreOptionsOpen)} style={{
          width: '100%', padding: '10px 12px',
          background: moreOptionsOpen ? tk.cardSunken : 'transparent',
          border: 0, cursor: 'pointer',
          display: 'flex', alignItems: 'center', gap: 8, textAlign: 'left',
        }}>
          <PI name="link-2" size={14} color={tk.primary} />
          <span style={{ flex: 1, fontSize: 12, fontWeight: 800, color: tk.fg }}>Meer opties</span>
          <span style={{ fontSize: 11, color: tk.fgMute, fontWeight: 600 }}>
            koppel quiz · kennisbank · notitie
          </span>
          <PI name={moreOptionsOpen ? 'chevron-up' : 'chevron-down'} size={14} color={tk.fgMute} />
        </button>
        {moreOptionsOpen && (
          <div style={{ padding: '12px', display: 'flex', flexDirection: 'column', gap: 6, borderTop: `1px solid ${tk.border}` }}>
            <CoupleRow tk={tk} icon="zap" iconColor={tk.primary}
              label="Koppel aan quiz"
              sub={linkedQuiz || 'zoek in Snapsnel-library — bv. "Bio H4 flashcards · 42 kaarten"'}
              value={linkedQuiz}
              onClick={() => setLinkedQuiz(linkedQuiz ? null : 'Bio H4 — 42 flashcards (uit library)')}
              checked={!!linkedQuiz}
            />
            <CoupleRow tk={tk} icon="book-open" iconColor={tk.purple}
              label="Koppel aan kennisbank-hoofdstuk"
              sub={linkedChapter || 'bv. "H4 Celbiologie · 14 bladzijden"'}
              value={linkedChapter}
              onClick={() => setLinkedChapter(linkedChapter ? null : 'H4 Celbiologie · 14 bladzijden')}
              checked={!!linkedChapter}
            />
            <CoupleRow tk={tk} icon="sticky-note" iconColor={tk.warn}
              label="Notitie toevoegen"
              sub={hasNote ? 'aantekeningen gemaakt' : 'korte aantekening voor jezelf'}
              onClick={() => setHasNote(!hasNote)}
              checked={hasNote}
            />
          </div>
        )}
      </div>

      {/* Actions */}
      <div style={{ display: 'flex', gap: 8, marginTop: 20 }}>
        <button onClick={() => store.navigate('/')} style={btnSecondary(tk)}>Annuleer</button>
        <span style={{ flex: 1 }} />
        <button
          onClick={() => {
            if (!canContinue) return;
            store.setDeadlineDraft({
              subject, title, dueDate, type, estimatedHours: hours,
              linkedQuiz, linkedChapter, hasNote,
            });
            store.navigate('/add-deadline/split');
          }}
          disabled={!canContinue}
          style={{ ...btnPrimary(tk), opacity: canContinue ? 1 : 0.5 }}
        >
          Volgende → blokken
        </button>
      </div>
    </div>
  );
}

function CoupleRow({ tk, icon, iconColor, label, sub, onClick, checked }) {
  return (
    <button onClick={onClick} style={{
      padding: '10px 12px', borderRadius: 8,
      background: checked ? hexToRgba(iconColor, 0.08) : 'transparent',
      border: checked ? `1px solid ${hexToRgba(iconColor, 0.3)}` : `1px solid ${tk.border}`,
      cursor: 'pointer', textAlign: 'left',
      display: 'flex', alignItems: 'center', gap: 10,
    }}>
      <div style={{
        width: 28, height: 28, borderRadius: 6,
        background: hexToRgba(iconColor, 0.12),
        display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
      }}>
        <PI name={icon} size={14} color={iconColor} />
      </div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 12, fontWeight: 700, color: tk.fg }}>{label}</div>
        <div style={{ fontSize: 10.5, color: tk.fgMute, fontWeight: 600, marginTop: 1 }}>{sub}</div>
      </div>
      {checked ? (
        <PI name="check-circle-2" size={16} color={iconColor} />
      ) : (
        <PI name="plus" size={14} color={tk.fgMute} />
      )}
    </button>
  );
}

// Mock AI-voorstellen voor stappenplan per type/vak
// In echte app: LLM call met context (titel, vak, gekoppeld materiaal, aantal paragrafen)
function suggestBlockNames({ subject, type, numBlocks, title, context }) {
  const paragraphs = context?.paragraphs || 0;
  const workStyle = context?.workStyle || 'mixed'; // 'reading' | 'practice' | 'mixed'
  const hasMaterial = context?.hasMaterial || false;

  // Als er paragrafen-aantal en leeswerk is, splitst Pulse lees-werk op per paragraaf
  if (paragraphs > 0 && (workStyle === 'reading' || workStyle === 'mixed')) {
    const base = [];
    // Verdeel paragrafen over eerste ~60% van de blokken
    const readBlocks = Math.min(paragraphs, Math.ceil(numBlocks * 0.6));
    for (let i = 0; i < readBlocks; i++) {
      const chunk = Math.max(1, Math.ceil(paragraphs / readBlocks));
      const from = i * chunk + 1;
      const to = Math.min(paragraphs, from + chunk - 1);
      base.push(from === to ? `§${from} lezen` : `§${from}–${to} lezen`);
    }
    // Rest vullen met oefenwerk
    if (workStyle !== 'reading') {
      const rest = numBlocks - base.length;
      const practice = ['Samenvatting maken', 'Begrippen overhoren', 'Oefenvragen set A', 'Oefenvragen set B', 'Proeftoets', 'Laatste herhaling'];
      for (let i = 0; i < rest; i++) base.push(practice[i] || `Extra oefenen`);
    } else {
      // Reading-only: vul eventueel rest met samenvatten/overhoren
      while (base.length < numBlocks) base.push('Samenvatten + overhoren');
    }
    return base.slice(0, numBlocks);
  }

  // Fallback: generieke templates per type
  const perType = {
    toets: [
      'Hoofdstuk lezen', 'Samenvatting maken', 'Begrippen overhoren',
      'Oefenvragen set A', 'Oefenvragen set B', 'Proeftoets', 'Laatste herhaling',
    ],
    so: [
      'Korte theorie doorlezen', 'Oefenvragen maken', 'Overhoren',
    ],
    inlever: [
      'Onderwerp/structuur kiezen', 'Outline schrijven', 'Eerste versie',
      'Tweede versie', 'Revisie + inleveren',
    ],
    maakwerk: [
      'Opgaves eerste helft', 'Opgaves tweede helft', 'Controleren',
    ],
    leerwerk: [
      'Eerste ronde lezen', 'Overhoren', 'Extra rondje voor zekerheid',
    ],
  };
  let pool = perType[type] || perType.toets;
  // Als er gekoppeld materiaal is en practice-heavy: pas het eerste blok aan
  if (hasMaterial && workStyle === 'practice') {
    pool = ['Oefenvragen uit gekoppeld materiaal', ...pool.slice(1)];
  }
  return Array.from({ length: numBlocks }, (_, i) => pool[i] || `Extra blok ${i + 1}`);
}

// Dialog waarin Pulse context vraagt voordat hij blokken genereert.
function PulseContextDialog({ tk, draft, numBlocks, onClose, onGenerate }) {
  const [paragraphs, setParagraphs] = useState(0);
  const [workStyle, setWorkStyle] = useState('mixed');
  const hasQuiz = !!draft.linkedQuizId;
  const hasChapter = !!draft.linkedChapterId;
  const hasMaterial = hasQuiz || hasChapter;

  function run() {
    const names = suggestBlockNames({
      subject: draft.subject, type: draft.type, numBlocks, title: draft.title,
      context: { paragraphs, workStyle, hasMaterial },
    });
    onGenerate(names);
  }

  return (
    <div
      onClick={onClose}
      style={{
        position: 'fixed', inset: 0, zIndex: 200,
        background: 'rgba(0, 0, 0, 0.55)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        padding: 20,
      }}
    >
      <div
        onClick={(e) => e.stopPropagation()}
        style={{
          background: tk.card, borderRadius: 14,
          border: `1.5px solid ${hexToRgba(tk.purple, 0.3)}`,
          width: '100%', maxWidth: 520,
          padding: '24px 28px 22px',
          boxShadow: `0 14px 36px ${hexToRgba(tk.purple, 0.2)}`,
        }}
      >
        {/* Header */}
        <div style={{ display: 'flex', alignItems: 'flex-start', gap: 12, marginBottom: 16 }}>
          <PulseMascot size={40} mood="thinking" />
          <div style={{ flex: 1 }}>
            <div style={{
              fontSize: 10, fontWeight: 800, color: tk.purple,
              letterSpacing: 0.5, textTransform: 'uppercase', marginBottom: 2,
            }}>Pulse · stappenplan voorstellen</div>
            <h3 style={{
              fontFamily: 'Fredoka One', fontSize: 18, color: tk.fg,
              margin: 0, lineHeight: 1.2,
            }}>Ik splits {numBlocks} blokken op — wat heb je?</h3>
            <p style={{ fontSize: 12.5, color: tk.fgDim, fontWeight: 500, margin: '4px 0 0', lineHeight: 1.5 }}>
              Hoe meer ik weet over je stof, hoe beter het voorstel. Alles overslaan mag — dan pak ik generieke stappen.
            </p>
          </div>
          <button onClick={onClose} style={{
            width: 28, height: 28, padding: 0, border: 0,
            background: 'transparent', color: tk.fgMute,
            cursor: 'pointer', fontSize: 18,
          }}>×</button>
        </div>

        {/* Gekoppeld materiaal banner */}
        {hasMaterial ? (
          <div style={{
            padding: '10px 12px', borderRadius: 8,
            background: hexToRgba(tk.green, 0.08),
            border: `1px solid ${hexToRgba(tk.green, 0.25)}`,
            marginBottom: 14,
            display: 'flex', alignItems: 'center', gap: 8,
          }}>
            <PI name="link" size={14} color={tk.green} />
            <div style={{ fontSize: 12, color: tk.fg, fontWeight: 600, lineHeight: 1.5 }}>
              <b>Gekoppeld materiaal gevonden.</b>
              <div style={{ fontSize: 11, color: tk.fgDim, fontWeight: 500, marginTop: 2 }}>
                {hasQuiz && <span>🎯 Quiz · </span>}
                {hasChapter && <span>📖 Hoofdstuk uit kennisbank · </span>}
                Ik kan daaruit begrippen en oefenvragen halen.
              </div>
            </div>
          </div>
        ) : (
          <div style={{
            padding: '10px 12px', borderRadius: 8,
            background: tk.cardSunken, border: `1px dashed ${tk.border}`,
            marginBottom: 14,
            display: 'flex', alignItems: 'center', gap: 8,
            fontSize: 11.5, color: tk.fgDim, fontWeight: 600, lineHeight: 1.5,
          }}>
            <PI name="info" size={12} color={tk.fgMute} />
            <span>
              <b style={{ color: tk.fg }}>Geen gekoppeld materiaal.</b> Tip: koppel een quiz of hoofdstuk aan de deadline voor nog specifiekere stappen.
            </span>
          </div>
        )}

        {/* Aantal paragrafen/hoofdstukken */}
        <div style={{ marginBottom: 14 }}>
          <div style={formLabelStyle(tk)}>Hoeveel paragrafen / hoofdstukken?</div>
          <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
            {[0, 2, 3, 4, 5, 6, 8].map(n => (
              <button key={n} onClick={() => setParagraphs(n)} style={{
                padding: '8px 14px', borderRadius: 7,
                background: paragraphs === n ? hexToRgba(tk.purple, 0.14) : tk.cardSunken,
                border: paragraphs === n ? `1.5px solid ${tk.purple}` : `1px solid ${tk.border}`,
                color: paragraphs === n ? tk.purple : tk.fgDim,
                fontSize: 12, fontWeight: 800, cursor: 'pointer',
              }}>{n === 0 ? 'Weet niet / n.v.t.' : n}</button>
            ))}
          </div>
        </div>

        {/* Work-style */}
        <div style={{ marginBottom: 18 }}>
          <div style={formLabelStyle(tk)}>Wat voor stof is het vooral?</div>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 6 }}>
            {[
              { v: 'reading', label: 'Lezen', sub: 'boek, H, lezen heavy', icon: 'book-open' },
              { v: 'mixed', label: 'Gemengd', sub: 'lezen + oefenen', icon: 'layers' },
              { v: 'practice', label: 'Oefenen', sub: 'opgaves, toepassen', icon: 'target' },
            ].map(opt => (
              <button key={opt.v} onClick={() => setWorkStyle(opt.v)} style={{
                padding: '10px 8px', borderRadius: 8,
                background: workStyle === opt.v ? hexToRgba(tk.purple, 0.14) : tk.cardSunken,
                border: workStyle === opt.v ? `1.5px solid ${tk.purple}` : `1px solid ${tk.border}`,
                cursor: 'pointer', textAlign: 'left',
                display: 'flex', flexDirection: 'column', gap: 3,
              }}>
                <PI name={opt.icon} size={14} color={workStyle === opt.v ? tk.purple : tk.fgMute} />
                <div style={{ fontSize: 12, fontWeight: 800, color: workStyle === opt.v ? tk.purple : tk.fg }}>
                  {opt.label}
                </div>
                <div style={{ fontSize: 10, color: tk.fgMute, fontWeight: 600 }}>{opt.sub}</div>
              </button>
            ))}
          </div>
        </div>

        {/* Actions */}
        <div style={{ display: 'flex', gap: 8 }}>
          <button onClick={onClose} style={{
            padding: '9px 14px', borderRadius: 8,
            background: 'transparent', border: `1px solid ${tk.border}`,
            color: tk.fgDim, fontSize: 12, fontWeight: 800, cursor: 'pointer',
          }}>Annuleer</button>
          <button
            onClick={() => { const names = suggestBlockNames({
              subject: draft.subject, type: draft.type, numBlocks, title: draft.title,
              context: null, // skip context: generic fallback
            }); onGenerate(names); }}
            style={{
              padding: '9px 14px', borderRadius: 8,
              background: 'transparent', border: `1px solid ${tk.border}`,
              color: tk.fgDim, fontSize: 12, fontWeight: 700, cursor: 'pointer',
            }}
          >Sla over · generiek</button>
          <span style={{ flex: 1 }} />
          <button onClick={run} style={{
            padding: '9px 16px', borderRadius: 8,
            background: tk.purple, color: '#FFFFFF', border: 0,
            fontSize: 12, fontWeight: 800, cursor: 'pointer',
            display: 'inline-flex', alignItems: 'center', gap: 5,
          }}>
            <PI name="sparkles" size={12} color="#FFFFFF" />
            Genereer stappen
          </button>
        </div>
      </div>
    </div>
  );
}

function AddDeadlineBlockSplit({ store }) {
  const tk = t(store.theme);
  const draft = store.deadlineDraft;
  const [blockMinutes, setBlockMinutes] = useState(draft?.blockMinutes || 30);
  const [blockNames, setBlockNames] = useState(draft?.blockNames || []);
  const [contextDialogOpen, setContextDialogOpen] = useState(false);

  if (!draft) { store.navigate('/add-deadline'); return null; }

  const totalMinutes = draft.estimatedHours * 60;
  const numBlocks = Math.round(totalMinutes / blockMinutes);
  const presets = [20, 25, 30, 45, 60];

  // Als aantal blokken verandert, trim/pad de namen-array
  useEffect(() => {
    if (blockNames.length !== numBlocks) {
      const next = Array.from({ length: numBlocks }, (_, i) => blockNames[i] || '');
      setBlockNames(next);
    }
  }, [numBlocks]);

  function updateName(idx, v) {
    setBlockNames(blockNames.map((n, i) => i === idx ? v : n));
  }
  function openPulseContext() {
    setContextDialogOpen(true);
  }
  function clearAll() {
    setBlockNames(Array.from({ length: numBlocks }, () => ''));
  }

  const isPremium = store.plan === 'premium';
  const filledCount = blockNames.filter(n => n && n.trim()).length;

  return (
    <div>
      <h2 style={{
        fontFamily: 'Fredoka One', fontSize: 22, color: tk.fg,
        margin: '0 0 6px', letterSpacing: '-0.01em',
      }}>In welke blokken opknippen?</h2>
      <p style={{ fontSize: 13, color: tk.fgDim, fontWeight: 500, margin: '0 0 20px' }}>
        Je hebt <b style={{ color: tk.fg }}>{draft.estimatedHours} uur</b> ingeschat. Kies blok-duur en schrijf per blok op wat je gaat doen.
      </p>

      {/* Block duration */}
      <Field label="Blok-duur" tk={tk}>
        <div style={{ display: 'flex', gap: 6 }}>
          {presets.map(p => (
            <button key={p} onClick={() => setBlockMinutes(p)} style={{
              flex: 1, padding: '10px 8px', borderRadius: 10,
              background: blockMinutes === p ? hexToRgba(tk.primary, 0.12) : tk.cardSunken,
              border: blockMinutes === p ? `2px solid ${tk.primary}` : `1px solid ${tk.border}`,
              color: blockMinutes === p ? tk.primary : tk.fgDim,
              fontSize: 13, fontWeight: 800, cursor: 'pointer',
            }}>{p} min</button>
          ))}
        </div>
        <div style={{ fontSize: 11, color: tk.fgMute, fontWeight: 600, marginTop: 6 }}>
          Tip: de meeste leerlingen vinden 25-30 minuten fijn (Pomodoro-ritme).
        </div>
      </Field>

      {/* Blok-namen (stappenplan) */}
      <div style={{
        marginTop: 16, padding: 16, borderRadius: 12,
        background: tk.cardSunken, border: `1px solid ${tk.border}`,
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
          <div style={{ fontSize: 11, fontWeight: 800, color: tk.fgMute, letterSpacing: 0.5, textTransform: 'uppercase' }}>
            Stappenplan · {numBlocks} {numBlocks === 1 ? 'blok' : 'blokken'} van {blockMinutes} min
          </div>
          <span style={{ fontSize: 10, color: tk.fgMute, fontWeight: 600 }}>
            · {filledCount}/{numBlocks} ingevuld
          </span>
          <span style={{ flex: 1 }} />
          {/* Premium: Pulse vult in / Free: leeg */}
          {isPremium ? (
            <button
              onClick={openPulseContext}
              style={{
                padding: '5px 10px', borderRadius: 6,
                background: hexToRgba(tk.purple, 0.14),
                border: `1px solid ${hexToRgba(tk.purple, 0.32)}`,
                color: tk.purple, fontSize: 10.5, fontWeight: 800, cursor: 'pointer',
                display: 'inline-flex', alignItems: 'center', gap: 4,
              }}
            >
              <PI name="sparkles" size={11} color={tk.purple} />
              Pulse vult in
            </button>
          ) : (
            <span style={{
              fontSize: 9.5, fontWeight: 800, color: tk.fgMute,
              padding: '3px 8px', borderRadius: 4,
              background: hexToRgba(tk.fgFaint, 0.08),
              border: `1px solid ${tk.border}`,
              letterSpacing: 0.4, textTransform: 'uppercase',
              display: 'inline-flex', alignItems: 'center', gap: 3,
            }} title="Premium: laat Pulse stappen voorstellen">
              <PI name="lock" size={10} color={tk.fgMute} />
              Pulse-voorstel
            </span>
          )}
          {filledCount > 0 && (
            <button onClick={clearAll} title="Alle blokken leegmaken" style={{
              padding: '5px 8px', borderRadius: 6,
              background: 'transparent', border: `1px solid ${tk.border}`,
              color: tk.fgMute, fontSize: 10.5, fontWeight: 700, cursor: 'pointer',
            }}>×</button>
          )}
        </div>
        <p style={{ fontSize: 11.5, color: tk.fgDim, fontWeight: 500, margin: '0 0 12px', lineHeight: 1.5 }}>
          Wat ga je in elk blok doen? Deze stappen verschijnen in de toets-ladder.
          {!isPremium && ' Schrijf zelf op — of upgrade naar Premium voor Pulse-voorstellen per vak/type.'}
        </p>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
          {Array.from({ length: numBlocks }).map((_, i) => (
            <div key={i} style={{
              display: 'flex', alignItems: 'center', gap: 8,
              padding: '4px 4px 4px 10px', borderRadius: 7,
              background: tk.card, border: `1px solid ${tk.border}`,
            }}>
              <span style={{
                fontSize: 10, fontWeight: 800, color: SUBJECTS[draft.subject],
                padding: '2px 6px', borderRadius: 4,
                background: hexToRgba(SUBJECTS[draft.subject], 0.14),
                letterSpacing: 0.4, textTransform: 'uppercase',
                display: 'inline-flex', alignItems: 'center', gap: 3,
                flexShrink: 0,
              }}>
                <PI name={SUBJECT_ICON_NAME(draft.subject)} size={10} color={SUBJECTS[draft.subject]} />
                Blok {i + 1}
              </span>
              <input
                type="text"
                value={blockNames[i] || ''}
                onChange={(e) => updateName(i, e.target.value)}
                placeholder={isPremium ? 'Pulse kan dit invullen' : `Wat ga je doen in dit blok van ${blockMinutes}m?`}
                style={{
                  flex: 1, padding: '6px 8px', borderRadius: 5,
                  background: 'transparent', border: 0,
                  color: tk.fg, fontSize: 12.5, fontWeight: 600, fontFamily: 'inherit',
                  outline: 'none',
                }}
              />
              <span style={{ fontSize: 10, color: tk.fgMute, fontWeight: 700, flexShrink: 0, marginRight: 8 }}>
                {blockMinutes}m
              </span>
            </div>
          ))}
        </div>
      </div>

      {/* Pulse hint */}
      <div style={{
        marginTop: 14, display: 'flex', gap: 10, padding: '10px 14px',
        background: hexToRgba(tk.purple, 0.08), border: `1px solid ${hexToRgba(tk.purple, 0.2)}`,
        borderRadius: 10,
      }}>
        <PulseMascot size={28} mood="thinking" />
        <div style={{ fontSize: 12, color: tk.fg, fontWeight: 600, lineHeight: 1.5 }}>
          {isPremium ? (
            <>In stap 3 stel ik voor hoe deze {numBlocks} blokken over de komende {daysUntil(draft.dueDate)} dagen te verdelen. Je kan mijn voorstel aanpassen.</>
          ) : (
            <>In stap 3 sleep je elk blok naar een dag die past. Ik laat alleen dagen zien waar studie-tijd is.</>
          )}
        </div>
      </div>

      {/* Actions */}
      <div style={{ display: 'flex', gap: 8, marginTop: 24, alignItems: 'center' }}>
        <button onClick={() => store.navigate('/add-deadline')} style={btnSecondary(tk)}>← Vorige</button>
        <span style={{ flex: 1 }} />
        {filledCount < numBlocks && (
          <span style={{ fontSize: 11.5, color: tk.fgMute, fontWeight: 600, marginRight: 8 }}>
            {numBlocks - filledCount} blok{numBlocks - filledCount !== 1 ? 'ken' : ''} zonder titel — komt als "Blok N" in de ladder
          </span>
        )}
        <button
          onClick={() => {
            store.setDeadlineDraft({ ...draft, blockMinutes, numBlocks, blockNames });
            store.navigate('/add-deadline/place');
          }}
          style={btnPrimary(tk)}
        >
          Volgende → plannen
        </button>
      </div>

      {contextDialogOpen && (
        <PulseContextDialog
          tk={tk}
          draft={draft}
          numBlocks={numBlocks}
          onClose={() => setContextDialogOpen(false)}
          onGenerate={(names) => { setBlockNames(names); setContextDialogOpen(false); }}
        />
      )}
    </div>
  );
}

function AddDeadlinePlaceBlocks({ store }) {
  const tk = t(store.theme);
  const draft = store.deadlineDraft;
  const [weekOffset, setWeekOffset] = useState(0);

  if (!draft) { store.navigate('/add-deadline'); return null; }

  // Initialize placements: Premium krijgt auto-voorstel, Free begint leeg
  const [placements, setPlacements] = useState(() => {
    if (store.plan === 'premium') {
      // AI suggests: spread evenly over beschikbare dagen binnen range
      const today = new Date('2026-04-22');
      const daysToDeadline = daysUntil(draft.dueDate);
      const availableIsos = [];
      for (let i = 0; i <= daysToDeadline; i++) {
        const d = new Date(today); d.setDate(today.getDate() + i);
        const key = ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'][d.getDay()];
        const block = store.studyBlocks[key];
        if (block && block.available && block.ranges && block.ranges.length > 0) {
          availableIsos.push(d.toISOString().slice(0, 10));
        }
      }
      const suggestions = [];
      for (let i = 0; i < draft.numBlocks; i++) {
        const idx = Math.min(Math.floor(i * availableIsos.length / draft.numBlocks), availableIsos.length - 1);
        suggestions.push({ blockIdx: i, isoDate: availableIsos[idx] || null });
      }
      return suggestions;
    } else {
      return Array.from({ length: draft.numBlocks }, (_, i) => ({ blockIdx: i, isoDate: null }));
    }
  });

  const [dragging, setDragging] = useState(null);
  const unplaced = placements.filter(p => p.isoDate === null);
  const placedCount = placements.filter(p => p.isoDate !== null).length;
  const allPlaced = placedCount === draft.numBlocks;

  return (
    <div>
      <h2 style={{
        fontFamily: 'Fredoka One', fontSize: 22, color: tk.fg,
        margin: '0 0 6px', letterSpacing: '-0.01em',
      }}>
        {store.plan === 'premium'
          ? `Voorstel: ${draft.numBlocks} blokken verdeeld`
          : `Sleep ${draft.numBlocks} blokken naar een dag`}
      </h2>
      <p style={{ fontSize: 13, color: tk.fgDim, fontWeight: 500, margin: '0 0 20px' }}>
        {store.plan === 'premium'
          ? 'Ik heb ze evenredig over je studie-dagen verdeeld. Sleep om te ruilen, of navigeer naar een andere week.'
          : `Deadline ${new Date(draft.dueDate).toLocaleDateString('nl-NL', { weekday: 'long', day: 'numeric', month: 'long' })}. Sleep blokken naar een dag — navigeer naar andere weken met ← →`}
      </p>

      {/* Unplaced block pool */}
      <div style={{
        padding: '12px 14px', borderRadius: 10,
        background: tk.card, border: `1.5px dashed ${hexToRgba(tk.primary, 0.35)}`,
        marginBottom: 14,
      }}>
        <div style={{
          fontSize: 10, fontWeight: 800, color: tk.primary,
          letterSpacing: 0.5, textTransform: 'uppercase', marginBottom: 8,
        }}>
          Nog te plannen · {unplaced.length} blok{unplaced.length !== 1 ? 'ken' : ''}
        </div>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, minHeight: 30 }}>
          {unplaced.length === 0 ? (
            <span style={{ fontSize: 12, color: tk.green, fontWeight: 700 }}>
              ✓ Alle blokken zijn geplaatst — kijk of het klopt en bevestig onderaan
            </span>
          ) : (
            unplaced.map(p => (
              <BlockChip key={p.blockIdx} t={tk} draft={draft} idx={p.blockIdx}
                draggable
                onDragStart={() => setDragging(p.blockIdx)}
              />
            ))
          )}
        </div>
      </div>

      {/* Week-kalender drop target */}
      <BlockWeekCalendar
        t={tk}
        draft={draft}
        weekOffset={weekOffset}
        setWeekOffset={setWeekOffset}
        placements={placements}
        setPlacements={setPlacements}
        dragging={dragging}
        setDragging={setDragging}
        studyBlocks={store.studyBlocks}
        vacations={store.vacations}
      />

      {/* Actions */}
      <div style={{ display: 'flex', gap: 8, marginTop: 20, alignItems: 'center' }}>
        <button onClick={() => store.navigate('/add-deadline/split')} style={btnSecondary(tk)}>← Blokken</button>
        <span style={{ flex: 1 }} />
        {!allPlaced && (
          <span style={{ fontSize: 11, color: tk.fgMute, fontWeight: 600, marginRight: 8 }}>
            Nog {draft.numBlocks - placedCount} blok{draft.numBlocks - placedCount !== 1 ? 'ken' : ''} te plaatsen
          </span>
        )}
        <button
          onClick={() => {
            store.setDeadlines([...store.deadlines, {
              id: `d${Date.now()}`,
              subject: draft.subject, type: draft.type, title: draft.title,
              dueDate: draft.dueDate, estimatedHours: draft.estimatedHours,
              progressPercent: 0, idealProgressPercent: 0,
              linkedQuizId: draft.linkedQuiz ? 'q-new' : undefined,
              linkedChapterId: draft.linkedChapter ? 'c-new' : undefined,
            }]);
            store.setDeadlineDraft(null);
            store.navigate('/');
          }}
          disabled={!allPlaced}
          style={{ ...btnPrimary(tk), opacity: allPlaced ? 1 : 0.5 }}
        >
          {allPlaced ? '✓ Opslaan' : 'Plaats eerst alle blokken'}
        </button>
      </div>
    </div>
  );
}

// Week-kalender voor het plaatsen van blokken bij deadline-toevoegen
function BlockWeekCalendar({ t, draft, weekOffset, setWeekOffset, placements, setPlacements, dragging, setDragging, studyBlocks, vacations }) {
  const [visibleDays, setVisibleDays] = useState(7); // 3 | 5 | 7
  const today = new Date('2026-04-22');
  const weekStart = new Date(today);
  const dayOfWeek = (today.getDay() + 6) % 7;
  // weekOffset blijft de "positie" (aantal stappen vanaf maandag van deze week).
  // In 7-modus = weken, in 3/5-modus = stappen van visibleDays dagen.
  const offsetDays = visibleDays === 7 ? weekOffset * 7 : weekOffset * visibleDays;
  weekStart.setDate(today.getDate() - dayOfWeek + offsetDays);
  const days = [];
  const todayIso = today.toISOString().slice(0, 10);
  for (let i = 0; i < visibleDays; i++) {
    const d = new Date(weekStart); d.setDate(weekStart.getDate() + i);
    const iso = d.toISOString().slice(0, 10);
    const dow = (d.getDay() + 6) % 7; // 0=ma .. 6=zo
    const key = ['ma', 'di', 'wo', 'do', 'vr', 'za', 'zo'][dow];
    const label = ['MA', 'DI', 'WO', 'DO', 'VR', 'ZA', 'ZO'][dow];
    const isWeekend = dow >= 5;
    const isToday = iso === todayIso;
    const isDeadline = iso === draft.dueDate;
    const isPastDeadline = iso > draft.dueDate;
    const isPast = iso < todayIso;
    const vacation = vacationForDate(iso, vacations);
    days.push({ iso, key, label, date: d.getDate(), month: d.toLocaleDateString('nl-NL', { month: 'short' }), isToday, isWeekend, isDeadline, isPastDeadline, isPast, vacation });
  }
  const weekNumber = getWeekNumber(weekStart);
  const sc = SUBJECTS[draft.subject];
  const rangeLabel = visibleDays === 7
    ? `Week ${weekNumber}`
    : `${days[0].date} ${days[0].month} – ${days[visibleDays - 1].date} ${days[visibleDays - 1].month}`;
  const relLabel = (() => {
    if (visibleDays !== 7) return weekOffset === 0 ? '· vanaf deze week' : '';
    return weekOffset === 0 ? '· deze week'
      : weekOffset === 1 ? '· volgende week'
      : weekOffset > 0 ? `· +${weekOffset} weken` : `· ${weekOffset} weken`;
  })();

  return (
    <section style={{
      background: t.card, border: `1px solid ${t.border}`,
      borderRadius: 12, padding: 14,
    }}>
      {/* Week-nav + zoom-toggle */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 12, flexWrap: 'wrap' }}>
        <button onClick={() => setWeekOffset(weekOffset - 1)} style={{
          padding: '5px 10px', borderRadius: 7,
          background: 'transparent', border: `1px solid ${t.border}`,
          color: t.fgDim, fontSize: 11, fontWeight: 700, cursor: 'pointer',
          display: 'inline-flex', alignItems: 'center', gap: 4,
        }}>
          <PI name="chevron-left" size={12} /> {visibleDays === 7 ? `wk ${weekNumber - 1}` : 'vorige'}
        </button>
        <div style={{ fontFamily: 'Fredoka One', fontSize: 16, color: t.fg }}>{rangeLabel}</div>
        {relLabel && <span style={{ fontSize: 11, color: t.fgMute, fontWeight: 600 }}>{relLabel}</span>}
        <span style={{ flex: 1 }} />
        {/* Zoom-toggle: toon 3 / 5 / 7 dagen */}
        <div style={{
          display: 'inline-flex', gap: 2,
          background: t.cardSunken, border: `1px solid ${t.border}`,
          borderRadius: 7, padding: 2,
        }}>
          {[3, 5, 7].map(n => (
            <button key={n}
              onClick={() => { setVisibleDays(n); setWeekOffset(0); }}
              title={n === 7 ? 'Week' : `${n} dagen`}
              style={{
                padding: '3px 10px', borderRadius: 5,
                background: visibleDays === n ? t.card : 'transparent',
                border: 0, color: visibleDays === n ? t.fg : t.fgMute,
                fontSize: 11, fontWeight: 800, cursor: 'pointer',
              }}>{n}d</button>
          ))}
        </div>
        <button onClick={() => setWeekOffset(weekOffset + 1)} style={{
          padding: '5px 10px', borderRadius: 7,
          background: 'transparent', border: `1px solid ${t.border}`,
          color: t.fgDim, fontSize: 11, fontWeight: 700, cursor: 'pointer',
          display: 'inline-flex', alignItems: 'center', gap: 4,
        }}>
          {visibleDays === 7 ? `wk ${weekNumber + 1}` : 'volgende'} <PI name="chevron-right" size={12} />
        </button>
      </div>

      {/* N dag-cards */}
      <div style={{ display: 'grid', gridTemplateColumns: `repeat(${visibleDays}, 1fr)`, gap: 8 }}>
        {days.map(d => {
          const existing = weekOffset === 0 ? (WEEK_BLOCKS[d.iso] || []) : [];
          const droppedHere = placements.filter(p => p.isoDate === d.iso);
          const studyBlock = studyBlocks[d.key];
          const isAvailable = studyBlock && studyBlock.available && !d.isPastDeadline && !d.isPast && !d.vacation;
          const canDrop = isAvailable && !d.isDeadline;

          return (
            <div key={d.iso}
              onDragOver={(e) => { if (canDrop) e.preventDefault(); }}
              onDrop={() => {
                if (dragging === null || !canDrop) return;
                setPlacements(placements.map(p =>
                  p.blockIdx === dragging ? { ...p, isoDate: d.iso } : p
                ));
                setDragging(null);
              }}
              style={{
                background: d.isDeadline ? hexToRgba(sc, 0.08)
                  : d.vacation ? hexToRgba(t.warn, 0.08)
                  : d.isToday ? hexToRgba(t.primary, 0.05)
                  : d.isPast ? hexToRgba(t.fgFaint, 0.04)
                  : d.isPastDeadline ? hexToRgba(t.fgFaint, 0.04)
                  : d.isWeekend ? hexToRgba(t.fgFaint, 0.03)
                  : t.cardSunken,
                border: d.isDeadline ? `2px solid ${sc}`
                  : d.isToday ? `2px solid ${t.primary}`
                  : `1px solid ${t.border}`,
                borderRadius: 10, minHeight: 180,
                padding: '8px 8px 6px', display: 'flex', flexDirection: 'column', gap: 5,
                opacity: d.isPast || d.isPastDeadline ? 0.35 : !isAvailable ? 0.55 : 1,
                position: 'relative',
              }}>
              {/* Header */}
              <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between' }}>
                <div style={{
                  fontSize: 9.5, fontWeight: 800, letterSpacing: 0.5,
                  color: d.isDeadline ? sc : d.isToday ? t.primary : t.fgMute, textTransform: 'uppercase',
                }}>
                  {d.label}{d.isToday ? ' · NU' : ''}
                </div>
                <div style={{
                  fontFamily: 'Fredoka One', fontSize: 16, lineHeight: 1,
                  color: d.isDeadline ? sc : d.isToday ? t.primary : t.fg,
                }}>{d.date}</div>
              </div>

              {/* Deadline marker */}
              {d.isDeadline && (
                <div style={{
                  padding: '4px 6px', borderRadius: 5,
                  background: hexToRgba(sc, 0.18),
                  fontSize: 9, fontWeight: 800, color: sc,
                  letterSpacing: 0.4, textTransform: 'uppercase',
                  display: 'flex', alignItems: 'center', gap: 3,
                }}>
                  <PI name="flag" size={10} color={sc} />
                  {draft.type}
                </div>
              )}

              {/* Study-venster */}
              {isAvailable && !d.isDeadline && studyBlock.ranges ? (
                <div style={{ fontSize: 9, color: t.fgMute, fontWeight: 700, lineHeight: 1.3 }}>
                  {studyBlock.ranges.map((r, ri) => (
                    <div key={ri}>{r.start}–{r.end}</div>
                  ))}
                </div>
              ) : !d.isDeadline && (
                <div style={{ fontSize: 9, color: d.vacation ? t.warn : t.fgFaint, fontWeight: 700, fontStyle: 'italic' }}>
                  {d.vacation ? `☀ ${d.vacation.name.split(' ')[0].toLowerCase()}` : d.isPast ? 'verleden' : d.isPastDeadline ? 'na deadline' : d.isWeekend ? 'weekend' : 'niet beschikbaar'}
                </div>
              )}

              {/* Existing blocks (huidige week) */}
              {existing.slice(0, 2).map((b, i) => (
                <div key={`ex-${i}`} style={{
                  padding: '2px 5px', borderRadius: 3,
                  background: hexToRgba(SUBJECTS[b.subject], 0.08),
                  borderLeft: `2px solid ${SUBJECTS[b.subject]}`,
                  fontSize: 9, lineHeight: 1.3,
                  color: t.fgDim, fontWeight: 700,
                  opacity: 0.55, fontStyle: 'italic',
                }} title={b.title}>
                  {b.title.length > 15 ? b.title.slice(0, 15) + '…' : b.title}
                </div>
              ))}
              {existing.length > 2 && (
                <div style={{ fontSize: 8, color: t.fgFaint, fontWeight: 600 }}>+{existing.length - 2} meer</div>
              )}

              {/* Dropped blocks met volgorde-knoppen */}
              {droppedHere.map((p, localIdx) => (
                <div key={p.blockIdx}
                  draggable
                  onDragStart={() => setDragging(p.blockIdx)}
                  style={{
                    padding: '4px 5px', borderRadius: 5,
                    background: hexToRgba(sc, 0.2),
                    border: `1.5px solid ${sc}`,
                    fontSize: 9.5, fontWeight: 800,
                    color: sc,
                    display: 'flex', alignItems: 'center', gap: 2,
                    cursor: 'grab',
                  }}>
                  <PI name={SUBJECT_ICON_NAME(draft.subject)} size={9} color={sc} />
                  <span style={{ flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}
                    title={draft.blockNames && draft.blockNames[p.blockIdx] ? `${draft.blockNames[p.blockIdx]} · ${draft.blockMinutes}m` : undefined}>
                    {draft.blockNames && draft.blockNames[p.blockIdx]
                      ? draft.blockNames[p.blockIdx]
                      : `Blok ${p.blockIdx + 1}`} · {draft.blockMinutes}m
                  </span>
                  {/* Up/down arrows alleen als meer dan 1 in deze dag */}
                  {droppedHere.length > 1 && (
                    <>
                      <button
                        disabled={localIdx === 0}
                        onClick={(e) => {
                          e.stopPropagation();
                          reorderInDay(placements, setPlacements, p.blockIdx, -1, 'blockIdx', 'isoDate', d.iso);
                        }}
                        style={{
                          border: 0, background: 'transparent',
                          color: localIdx === 0 ? t.fgFaint : sc,
                          cursor: localIdx === 0 ? 'default' : 'pointer',
                          fontSize: 9, padding: 0, width: 14, height: 14,
                          display: 'flex', alignItems: 'center', justifyContent: 'center',
                        }} title="Omhoog">↑</button>
                      <button
                        disabled={localIdx === droppedHere.length - 1}
                        onClick={(e) => {
                          e.stopPropagation();
                          reorderInDay(placements, setPlacements, p.blockIdx, 1, 'blockIdx', 'isoDate', d.iso);
                        }}
                        style={{
                          border: 0, background: 'transparent',
                          color: localIdx === droppedHere.length - 1 ? t.fgFaint : sc,
                          cursor: localIdx === droppedHere.length - 1 ? 'default' : 'pointer',
                          fontSize: 9, padding: 0, width: 14, height: 14,
                          display: 'flex', alignItems: 'center', justifyContent: 'center',
                        }} title="Omlaag">↓</button>
                    </>
                  )}
                  <button onClick={(e) => {
                    e.stopPropagation();
                    setPlacements(placements.map(pp =>
                      pp.blockIdx === p.blockIdx ? { ...pp, isoDate: null } : pp
                    ));
                  }} style={{
                    border: 0, background: 'transparent',
                    color: sc, cursor: 'pointer', fontSize: 11, padding: 0, lineHeight: 1, marginLeft: 2,
                  }}>×</button>
                </div>
              ))}

              {/* Drop hint */}
              {dragging !== null && canDrop && droppedHere.length === 0 && (
                <div style={{
                  marginTop: 'auto', padding: '6px', borderRadius: 5,
                  border: `1.5px dashed ${hexToRgba(sc, 0.4)}`,
                  fontSize: 9, color: sc, fontWeight: 700, textAlign: 'center',
                  background: hexToRgba(sc, 0.06),
                }}>drop hier</div>
              )}
            </div>
          );
        })}
      </div>
    </section>
  );
}

function BlockChip({ t, draft, idx, draggable, onDragStart, onRemove }) {
  return (
    <div
      draggable={draggable}
      onDragStart={onDragStart}
      style={{
        padding: '6px 10px', borderRadius: 8,
        background: hexToRgba(SUBJECTS[draft.subject], 0.15),
        border: `1px solid ${hexToRgba(SUBJECTS[draft.subject], 0.35)}`,
        color: SUBJECTS[draft.subject], fontSize: 11, fontWeight: 800,
        display: 'inline-flex', alignItems: 'center', gap: 5,
        cursor: draggable ? 'grab' : 'default',
      }}
    >
      <PI name={SUBJECT_ICON_NAME(draft.subject)} size={11} color={SUBJECTS[draft.subject]} />
      <span title={draft.blockNames && draft.blockNames[idx] ? draft.blockNames[idx] : `Blok ${idx + 1}`}>
        {draft.blockNames && draft.blockNames[idx]
          ? (draft.blockNames[idx].length > 18 ? draft.blockNames[idx].slice(0, 18) + '…' : draft.blockNames[idx])
          : `Blok ${idx + 1}`} · {draft.blockMinutes}m
      </span>
      {onRemove && (
        <button onClick={onRemove} style={{
          marginLeft: 2, padding: 0, width: 14, height: 14,
          borderRadius: 7, background: 'transparent', border: 0,
          color: SUBJECTS[draft.subject], cursor: 'pointer',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
        }}>×</button>
      )}
    </div>
  );
}

function calcFreeMinutes(start, end) {
  const [sh, sm] = start.split(':').map(Number);
  const [eh, em] = end.split(':').map(Number);
  return (eh * 60 + em) - (sh * 60 + sm);
}

/* ═══════════════════════════════════════════════════════════════════
   HELPERS — form fields, buttons
   ═══════════════════════════════════════════════════════════════════ */

function Field({ label, tk, required, children }) {
  return (
    <div style={{ marginBottom: 14 }}>
      <label style={{
        display: 'block', marginBottom: 6,
        fontSize: 11, fontWeight: 800, color: tk.fgMute,
        letterSpacing: 0.5, textTransform: 'uppercase',
      }}>
        {label}{required && <span style={{ color: tk.red, marginLeft: 2 }}>*</span>}
      </label>
      {children}
    </div>
  );
}

function inputStyle(tk) {
  return {
    width: '100%', padding: '10px 12px', borderRadius: 8,
    background: tk.input, border: `1px solid ${tk.border}`,
    color: tk.fg, fontSize: 13, fontWeight: 600,
    fontFamily: 'Nunito, sans-serif',
    outline: 'none',
  };
}

function btnPrimary(tk) {
  return {
    padding: '10px 18px', borderRadius: 9,
    background: tk.primary, color: '#FFFFFF', border: 0,
    fontSize: 13, fontWeight: 800, cursor: 'pointer',
    letterSpacing: 0.2,
  };
}

function btnSecondary(tk) {
  return {
    padding: '10px 16px', borderRadius: 9,
    background: 'transparent', color: tk.fgDim,
    border: `1px solid ${tk.border}`,
    fontSize: 12, fontWeight: 700, cursor: 'pointer',
  };
}

/* ═══════════════════════════════════════════════════════════════════
   PLACEHOLDER SCREENS (to be fleshed out in next iterations)
   ═══════════════════════════════════════════════════════════════════ */

function ScreenPlaceholder({ store, title, description, nextFeatures }) {
  const tk = t(store.theme);
  return (
    <div style={{
      background: tk.bgApp, minHeight: 'calc(100vh - 44px)',
      padding: '40px 20px', display: 'flex', alignItems: 'center', justifyContent: 'center',
    }}>
      <div style={{
        maxWidth: 600, padding: 32,
        background: tk.card, border: `1px solid ${tk.border}`,
        borderRadius: 16, boxShadow: tk.shadowElev,
        textAlign: 'center',
      }}>
        <div style={{ marginBottom: 16 }}>
          <PulseMascot size={48} mood="thinking" />
        </div>
        <h2 style={{
          fontFamily: 'Fredoka One', fontSize: 24, color: tk.fg,
          margin: '0 0 8px',
        }}>{title}</h2>
        <p style={{ fontSize: 13, color: tk.fgDim, fontWeight: 500, margin: '0 0 20px', lineHeight: 1.5 }}>
          {description}
        </p>
        {nextFeatures && (
          <div style={{
            padding: 14, borderRadius: 10,
            background: tk.cardSunken, border: `1px solid ${tk.border}`,
            textAlign: 'left',
          }}>
            <div style={{
              fontSize: 10, fontWeight: 800, color: tk.fgMute,
              letterSpacing: 0.5, textTransform: 'uppercase', marginBottom: 8,
            }}>Volgende iteratie</div>
            <ul style={{ margin: 0, padding: '0 0 0 16px', fontSize: 12, color: tk.fg, lineHeight: 1.6 }}>
              {nextFeatures.map((f, i) => <li key={i}>{f}</li>)}
            </ul>
          </div>
        )}
        <button onClick={() => store.navigate('/')} style={{ ...btnPrimary(tk), marginTop: 20 }}>
          ← Terug naar Stapel
        </button>
      </div>
    </div>
  );
}

/* ═══════════════════════════════════════════════════════════════════
   SCREEN: DEADLINE-DRAWER (Stapel dimmed + 480px side-sheet rechts)
   ═══════════════════════════════════════════════════════════════════ */

function ScreenDeadlineDrawer({ store }) {
  const tk = t(store.theme);
  const deadline = store.deadlines.find(d => d.id === store.route.params.id);

  if (!deadline) {
    return (
      <ScreenPlaceholder store={store}
        title="Deadline niet gevonden"
        description="Deze deadline bestaat niet meer. Misschien net verwijderd?"
      />
    );
  }

  const days = daysUntil(deadline.dueDate);
  const sc = SUBJECTS[deadline.subject];

  // Tijdsanalyse — duidelijke semantiek:
  // - totaalNodig: totale studietijd volgens inschatting (bv. 180 min voor 3u-deadline)
  // - gedaan: hoeveel je al hebt gestudeerd voor deze toets
  // - ingepland: hoeveel er al in de agenda staat (nog te doen)
  // - nogTePlannen: wat er nog niet ingepland is
  // - vrijInVenster: totale vrije studietijd binnen je studie-vensters tot deadline
  const totaalNodig = deadline.estimatedHours * 60;
  const gedaan = Math.round(totaalNodig * deadline.progressPercent / 100);
  const nogTeDoen = totaalNodig - gedaan;
  const ingepland = Math.round(nogTeDoen * 0.7); // mock: 70% van het resterende is al gepland
  const nogTePlannen = nogTeDoen - ingepland;
  const vrijInVenster = 240; // mock: 4u vrije tijd in studie-vensters tot deadline
  const opSchema = nogTePlannen <= vrijInVenster - ingepland;

  return (
    <div style={{ position: 'relative' }}>
      {/* Stapel behind — dimmed */}
      <div style={{ filter: 'brightness(0.55) blur(0.5px)', pointerEvents: 'none' }}>
        <ScreenHome store={store} />
      </div>
      {/* Scrim */}
      <div
        onClick={() => store.navigate('/')}
        style={{
          position: 'fixed', top: 44, left: 0, right: 480, bottom: 0,
          background: tk.mode === 'dark' ? 'rgba(0,0,0,0.4)' : 'rgba(15,23,42,0.25)',
          cursor: 'pointer', zIndex: 50,
        }}
      />
      {/* Drawer */}
      <aside style={{
        position: 'fixed', top: 44, right: 0, bottom: 0, width: 480,
        background: tk.card, borderLeft: `1px solid ${tk.border}`,
        boxShadow: tk.mode === 'dark' ? '-20px 0 50px rgba(0,0,0,0.5)' : '-20px 0 50px rgba(15,23,42,0.15)',
        display: 'flex', flexDirection: 'column', zIndex: 60,
      }}>
        {/* Header */}
        <header style={{
          padding: '18px 24px', borderBottom: `1px solid ${tk.border}`,
          display: 'flex', alignItems: 'flex-start', gap: 12,
        }}>
          <div style={{ flex: 1 }}>
            <SubjectChip t={tk} subject={deadline.subject} size="md" />
            <h2 style={{
              fontFamily: 'Fredoka One', fontSize: 20, color: tk.fg,
              margin: '10px 0 4px', letterSpacing: '-0.01em',
            }}>{deadline.title}</h2>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 6 }}>
              <PI name="calendar" size={13} color={tk.fgMute} />
              <span style={{ fontSize: 12, color: tk.fgDim, fontWeight: 600 }}>
                {new Date(deadline.dueDate).toLocaleDateString('nl-NL', { weekday: 'long', day: 'numeric', month: 'long' })}
              </span>
              <span style={{
                fontSize: 11, fontWeight: 800,
                padding: '2px 8px', borderRadius: 4,
                background: hexToRgba(days <= 3 ? tk.red : tk.primary, 0.12),
                color: days <= 3 ? tk.red : tk.primary,
              }}>
                {days === 0 ? 'VANDAAG' : days === 1 ? 'MORGEN' : `OVER ${days} DAGEN`}
              </span>
            </div>
          </div>
          <div style={{ display: 'flex', gap: 6 }}>
            <button
              onClick={() => store.navigate(`/deadline/${deadline.id}/edit`, { id: deadline.id })}
              style={{
                padding: '0 10px', height: 32, borderRadius: 8,
                border: `1px solid ${tk.border}`, background: 'transparent',
                color: tk.fgDim, cursor: 'pointer',
                display: 'inline-flex', alignItems: 'center', gap: 4,
                fontSize: 11, fontWeight: 700,
              }}>
              <PI name="pencil" size={13} /> Bewerken
            </button>
            <button onClick={() => store.navigate('/')} style={{
              width: 32, height: 32, borderRadius: 8,
              border: `1px solid ${tk.border}`, background: 'transparent',
              color: tk.fgDim, cursor: 'pointer',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
            }}>
              <PI name="x" size={16} />
            </button>
          </div>
        </header>

        {/* Body */}
        <div style={{ flex: 1, overflow: 'auto', padding: '20px 24px' }}>
          {/* Tijdsanalyse — stacked-bar + duidelijke copy */}
          <section style={{ marginBottom: 24 }}>
            <div style={{
              fontSize: 10, fontWeight: 800, color: tk.fgMute,
              letterSpacing: 0.6, textTransform: 'uppercase', marginBottom: 10,
              display: 'flex', alignItems: 'center', gap: 8,
            }}>
              Voortgang
              <span style={{ color: tk.fgDim, fontWeight: 600, textTransform: 'none', letterSpacing: 0 }}>
                · {gedaan + ingepland} van {totaalNodig} min
              </span>
            </div>

            {/* Stacked bar */}
            <div style={{
              height: 10, borderRadius: 5,
              background: tk.cardSunken, border: `1px solid ${tk.border}`,
              overflow: 'hidden', position: 'relative', display: 'flex',
            }}>
              <div style={{
                width: `${(gedaan / totaalNodig) * 100}%`,
                background: tk.green, height: '100%',
              }} />
              <div style={{
                width: `${(ingepland / totaalNodig) * 100}%`,
                background: tk.primary, height: '100%',
                opacity: 0.75,
              }} />
              <div style={{
                width: `${(nogTePlannen / totaalNodig) * 100}%`,
                background: `repeating-linear-gradient(45deg, ${hexToRgba(tk.warn, 0.3)}, ${hexToRgba(tk.warn, 0.3)} 3px, ${hexToRgba(tk.warn, 0.15)} 3px, ${hexToRgba(tk.warn, 0.15)} 6px)`,
                height: '100%',
              }} />
            </div>

            {/* Legend */}
            <div style={{ display: 'flex', gap: 14, marginTop: 8, flexWrap: 'wrap' }}>
              <LegendDot color={tk.green} label="Gedaan" value={`${gedaan}m`} />
              <LegendDot color={tk.primary} label="Ingepland" value={`${ingepland}m`} />
              {nogTePlannen > 0 && (
                <LegendDot color={tk.warn} label="Nog plannen" value={`${nogTePlannen}m`} dashed />
              )}
            </div>

            {/* Status-bericht */}
            <div style={{
              marginTop: 10, padding: '10px 12px', borderRadius: 8,
              background: opSchema ? hexToRgba(tk.green, 0.10) : hexToRgba(tk.warn, 0.10),
              border: `1px solid ${opSchema ? hexToRgba(tk.green, 0.2) : hexToRgba(tk.warn, 0.25)}`,
              fontSize: 12, color: tk.fg, fontWeight: 600, lineHeight: 1.5,
            }}>
              {nogTePlannen === 0 ? (
                <><b>Alles staat al gepland.</b> Volg gewoon je schema — haalbaar binnen je vrije tijd.</>
              ) : opSchema ? (
                <><b>Je ligt op schema.</b> Nog {nogTePlannen} min in te plannen. Je hebt tot zaterdag nog {vrijInVenster - ingepland} min vrij — past ruim.</>
              ) : (
                <><b>Er is krap ruimte.</b> Nog {nogTePlannen} min te plannen in {vrijInVenster - ingepland} min vrije tijd. Overweeg de toets te halveren of Pulse te laten herplannen.</>
              )}
            </div>
          </section>

          {/* Toets-ladder */}
          <DeadlineLadderCollapsible t={tk} deadline={deadline} />

          {/* Gekoppelde content */}
          <section style={{ marginBottom: 24 }}>
            <div style={{
              fontSize: 10, fontWeight: 800, color: tk.fgMute,
              letterSpacing: 0.6, textTransform: 'uppercase', marginBottom: 10,
            }}>Gekoppeld</div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
              {deadline.linkedQuizId && (
                <LinkRow t={tk} icon="zap" iconBg={hexToRgba(tk.primary, 0.15)} iconColor={tk.primary}
                  title={`Quiz · H${deadline.type === 'toets' ? '4' : '7'} ${deadline.subject}`}
                  subtitle="20 vragen · ~15 min" badge="70% gehad" badgeColor={tk.green} />
              )}
              {deadline.linkedChapterId && (
                <LinkRow t={tk} icon="book-open" iconBg={hexToRgba(tk.purple, 0.15)} iconColor={tk.purple}
                  title={`Hoofdstuk · H4 ${deadline.subject}`}
                  subtitle="kennisbank · 14 bladzijden" />
              )}
              <LinkRow t={tk} icon="file-text" iconBg={hexToRgba(tk.warn, 0.15)} iconColor={tk.warn}
                title="Oefenopgaves · set B"
                subtitle="8 opgaves · met uitwerkingen" />
              <LinkRow t={tk} icon="sticky-note" iconBg={hexToRgba(tk.fgFaint, 0.15)} iconColor={tk.fgDim}
                title="Notities" subtitle="nog geen notities · + toevoegen" />
            </div>
          </section>

          {/* Acties */}
          <section>
            <div style={{
              fontSize: 10, fontWeight: 800, color: tk.fgMute,
              letterSpacing: 0.6, textTransform: 'uppercase', marginBottom: 10,
            }}>Acties</div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
              <SecondaryAction t={tk} icon="sparkles" title="Laat Pulse herplannen"
                subtitle={store.plan === 'premium' ? 'verdeel over beschikbare dagen' : 'upgrade naar Premium'}
                premium={store.plan === 'free'}
                onClick={() => store.navigate('/herplan')} />
              <SecondaryAction t={tk} icon="bell" title="Herinnering zetten"
                subtitle="1 dag van te voren · ochtend" />
              <SecondaryAction t={tk} icon="move-vertical" title="Handmatig herplannen"
                subtitle="sleep studie-momenten naar andere dag"
                onClick={() => store.navigate('/herplan')} />
              <SecondaryAction t={tk} icon="pencil" title="Bewerken"
                subtitle="titel, datum of studie-tijd aanpassen" />
            </div>
          </section>
        </div>

        {/* Footer */}
        <footer style={{
          padding: '14px 24px', borderTop: `1px solid ${tk.border}`,
          display: 'flex', gap: 8,
        }}>
          <button style={{
            padding: '10px 12px', borderRadius: 9,
            background: 'transparent', border: `1px solid ${tk.border}`,
            color: tk.fgDim, fontSize: 12, fontWeight: 700, cursor: 'pointer',
          }}>⋯</button>
          <button style={{
            flex: 1, padding: '10px 16px', borderRadius: 9,
            background: tk.primary, color: '#FFFFFF', border: 0,
            fontSize: 13, fontWeight: 800, cursor: 'pointer',
            display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 6,
          }}>
            <PI name="play" size={14} /> Start quiz · H{deadline.type === 'toets' ? '4' : '7'}
          </button>
        </footer>
      </aside>
    </div>
  );
}

function LegendDot({ color, label, value, dashed }) {
  return (
    <div style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontSize: 11, fontWeight: 600 }}>
      <span style={{
        width: 10, height: 10, borderRadius: 2,
        background: dashed
          ? `repeating-linear-gradient(45deg, ${hexToRgba(color, 0.3)}, ${hexToRgba(color, 0.3)} 2px, ${hexToRgba(color, 0.15)} 2px, ${hexToRgba(color, 0.15)} 4px)`
          : color,
      }} />
      <span style={{ color: color, fontWeight: 800 }}>{label}</span>
      <span style={{ color: 'currentColor', opacity: 0.7 }}>{value}</span>
    </div>
  );
}

/* ═══════════════════════════════════════════════════════════════════
   DEADLINE LADDER (collapsible in drawer — zie polish frame 08)
   ═══════════════════════════════════════════════════════════════════ */

function DeadlineLadderCollapsible({ t, deadline, store }) {
  const [expanded, setExpanded] = useState(false);
  const [editMode, setEditMode] = useState(false);
  const [steps, setSteps] = useState(() => (getDeadlineChecklist(deadline.id) || []).map(s => ({ ...s })));

  if (!steps || steps.length === 0) return null;

  const doneCount = steps.filter(s => s.done).length;
  const currentIdx = steps.findIndex(s => s.isNow);
  const overallProgress = Math.round((doneCount / steps.length) * 100 + (currentIdx >= 0 ? (steps[currentIdx].progress || 0) / steps.length : 0));

  function updateStepLabel(idx, label) {
    setSteps(steps.map((s, i) => i === idx ? { ...s, label } : s));
  }
  function toggleStepDone(idx) {
    setSteps(steps.map((s, i) => i === idx ? { ...s, done: !s.done } : s));
  }
  function removeStep(idx) {
    setSteps(steps.filter((_, i) => i !== idx));
  }
  function addStep() {
    setSteps([...steps, { label: '', done: false, type: 'oefenen' }]);
  }
  function moveStep(idx, dir) {
    const newIdx = idx + dir;
    if (newIdx < 0 || newIdx >= steps.length) return;
    const copy = [...steps];
    [copy[idx], copy[newIdx]] = [copy[newIdx], copy[idx]];
    setSteps(copy);
  }

  return (
    <section style={{ marginBottom: 20 }}>
      <button onClick={() => setExpanded(!expanded)} style={{
        width: '100%', padding: '10px 12px', borderRadius: 10,
        background: expanded ? t.cardSunken : t.card,
        border: `1px solid ${t.border}`,
        cursor: 'pointer', textAlign: 'left',
        display: 'flex', alignItems: 'center', gap: 10,
        transition: 'background 0.15s',
      }}>
        <div style={{
          width: 32, height: 32, borderRadius: 7,
          background: hexToRgba(SUBJECTS[deadline.subject], 0.14),
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          flexShrink: 0,
        }}>
          <PI name="list-checks" size={16} color={SUBJECTS[deadline.subject]} />
        </div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 12.5, fontWeight: 700, color: t.fg }}>
            Stappenplan
          </div>
          <div style={{ fontSize: 11, color: t.fgMute, fontWeight: 600, marginTop: 1 }}>
            {doneCount} van {steps.length} stappen · {overallProgress}% klaar
          </div>
        </div>
        {/* Mini progress visual */}
        <div style={{ display: 'flex', gap: 3, marginRight: 4 }}>
          {steps.map((s, i) => (
            <div key={i} style={{
              width: 8, height: 8, borderRadius: 4,
              background: s.done ? t.green : s.isNow ? t.primary : t.border,
              boxShadow: s.isNow ? `0 0 6px ${hexToRgba(t.primary, 0.5)}` : 'none',
            }} />
          ))}
        </div>
        <PI name={expanded ? 'chevron-up' : 'chevron-down'} size={16} color={t.fgMute} />
      </button>

      {/* Expanded ladder */}
      {expanded && (
        <div style={{
          marginTop: 10, padding: '14px 16px',
          background: t.cardSunken, border: `1px solid ${t.border}`,
          borderRadius: 10,
        }}>
          {/* Edit-toggle header */}
          <div style={{ display: 'flex', alignItems: 'center', marginBottom: 10, gap: 8 }}>
            <div style={{
              fontSize: 10, fontWeight: 800, color: t.fgMute,
              letterSpacing: 0.5, textTransform: 'uppercase',
            }}>
              {editMode ? 'Aanpassen · sleep volgorde, typ namen' : 'Stappen naar de deadline'}
            </div>
            <span style={{ flex: 1 }} />
            {editMode ? (
              <button onClick={() => setEditMode(false)} style={{
                padding: '4px 10px', borderRadius: 6,
                background: t.primary, color: '#FFFFFF', border: 0,
                fontSize: 11, fontWeight: 800, cursor: 'pointer',
                display: 'inline-flex', alignItems: 'center', gap: 4,
              }}>
                <PI name="check" size={11} color="#FFFFFF" /> Klaar
              </button>
            ) : (
              <button onClick={() => setEditMode(true)} style={{
                padding: '4px 10px', borderRadius: 6,
                background: 'transparent', border: `1px solid ${t.border}`,
                color: t.fgDim, fontSize: 11, fontWeight: 700, cursor: 'pointer',
                display: 'inline-flex', alignItems: 'center', gap: 4,
              }}>
                <PI name="edit-2" size={11} color={t.fgMute} /> Aanpassen
              </button>
            )}
          </div>

          {editMode ? (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
              {steps.map((s, i) => (
                <div key={i} style={{
                  display: 'flex', alignItems: 'center', gap: 6,
                  padding: '6px 6px 6px 10px', borderRadius: 7,
                  background: t.card, border: `1px solid ${t.border}`,
                }}>
                  <span style={{
                    fontSize: 10, fontWeight: 800, color: SUBJECTS[deadline.subject],
                    padding: '2px 5px', borderRadius: 4,
                    background: hexToRgba(SUBJECTS[deadline.subject], 0.14),
                    flexShrink: 0,
                  }}>{i + 1}</span>
                  <input
                    type="text"
                    value={s.label}
                    onChange={(e) => updateStepLabel(i, e.target.value)}
                    placeholder={`Wat doe je in stap ${i + 1}?`}
                    style={{
                      flex: 1, padding: '5px 6px', borderRadius: 4,
                      background: 'transparent', border: 0,
                      color: t.fg, fontSize: 12.5, fontWeight: 600, fontFamily: 'inherit',
                      outline: 'none',
                    }}
                  />
                  {/* Reorder */}
                  <button
                    disabled={i === 0}
                    onClick={() => moveStep(i, -1)}
                    style={ladderIconBtn(t, i === 0 ? t.fgFaint : t.fgDim)}
                    title="Omhoog"
                  >↑</button>
                  <button
                    disabled={i === steps.length - 1}
                    onClick={() => moveStep(i, 1)}
                    style={ladderIconBtn(t, i === steps.length - 1 ? t.fgFaint : t.fgDim)}
                    title="Omlaag"
                  >↓</button>
                  <button onClick={() => removeStep(i)} style={ladderIconBtn(t, t.red)} title="Verwijder">×</button>
                </div>
              ))}
              <button onClick={addStep} style={{
                padding: '7px 10px', borderRadius: 6,
                background: 'transparent', border: `1px dashed ${t.border}`,
                color: t.fgDim, fontSize: 11.5, fontWeight: 700, cursor: 'pointer',
                display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 5,
              }}>
                <PI name="plus" size={11} /> Stap toevoegen
              </button>
            </div>
          ) : (
            <>
              {steps.map((s, i) => (
                <LadderStep key={i} t={t} step={s} idx={i} isLast={i === steps.length - 1}
                  subject={deadline.subject} onToggle={() => toggleStepDone(i)} />
              ))}
              {/* Final step: de toets zelf */}
              <LadderStep t={t} step={{ label: deadline.title, type: deadline.type, done: false, isFinal: true, dueDate: deadline.dueDate }}
                idx={steps.length} isLast subject={deadline.subject} />
            </>
          )}
        </div>
      )}
    </section>
  );
}

function ladderIconBtn(t, color) {
  return {
    width: 22, height: 22, padding: 0,
    background: 'transparent', border: `1px solid ${t.border}`,
    borderRadius: 4, color,
    fontSize: 11, lineHeight: 1,
    cursor: 'pointer',
    display: 'flex', alignItems: 'center', justifyContent: 'center',
    flexShrink: 0,
  };
}

function LadderStep({ t, step, idx, isLast, subject }) {
  const color = step.done ? t.green : step.isNow ? t.primary : step.isFinal ? t.red : t.fgMute;
  return (
    <div style={{ display: 'flex', gap: 10, alignItems: 'flex-start', position: 'relative' }}>
      {/* Timeline line + dot */}
      <div style={{ position: 'relative', display: 'flex', flexDirection: 'column', alignItems: 'center', paddingTop: 2 }}>
        <div style={{
          width: 20, height: 20, borderRadius: 10,
          background: step.done ? t.green : step.isFinal ? 'transparent' : step.isNow ? t.primary : t.cardSunken,
          border: step.isFinal ? `2px dashed ${t.red}` : step.done ? '0' : step.isNow ? `2px solid ${t.primary}` : `1.5px solid ${t.border}`,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          color: step.done ? '#FFFFFF' : step.isFinal ? t.red : step.isNow ? '#FFFFFF' : t.fgMute,
          fontSize: 10, fontWeight: 800,
          boxShadow: step.isNow ? `0 0 8px ${hexToRgba(t.primary, 0.4)}` : 'none',
          flexShrink: 0,
        }}>
          {step.done ? <PI name="check" size={12} color="#FFFFFF" /> : step.isFinal ? <PI name="flag" size={10} color={t.red} /> : (idx + 1)}
        </div>
        {!isLast && (
          <div style={{
            width: 2, flex: 1, minHeight: 20,
            background: step.done ? t.green : t.border,
          }} />
        )}
      </div>

      {/* Step content */}
      <div style={{ flex: 1, paddingBottom: isLast ? 0 : 14 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 2 }}>
          <span style={{
            fontSize: 9.5, fontWeight: 800, color: color,
            letterSpacing: 0.4, textTransform: 'uppercase',
          }}>
            {step.done ? 'Klaar' : step.isNow ? 'Bezig' : step.isFinal ? 'Deadline' : 'Nog niet'}
          </span>
          {step.type && !step.isFinal && (
            <span style={{
              fontSize: 9, fontWeight: 700, color: t.fgMute,
              padding: '1px 5px', borderRadius: 3, background: hexToRgba(t.fgFaint, 0.1),
              letterSpacing: 0.3, textTransform: 'uppercase',
            }}>{step.type}</span>
          )}
        </div>
        <div style={{
          fontSize: 12.5, fontWeight: step.isNow || step.isFinal ? 800 : 600,
          color: step.done ? t.fgDim : t.fg, lineHeight: 1.35,
          textDecoration: step.done ? 'line-through' : 'none',
        }}>
          {step.label}
        </div>
        {step.isFinal && step.dueDate && (
          <div style={{
            display: 'inline-block', marginTop: 3,
            padding: '2px 8px', borderRadius: 4,
            background: hexToRgba(t.red, 0.12), color: t.red,
            fontSize: 10, fontWeight: 800,
          }}>
            {new Date(step.dueDate).toLocaleDateString('nl-NL', { weekday: 'short', day: 'numeric', month: 'short' })}
          </div>
        )}
        {step.isNow && typeof step.progress === 'number' && (
          <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginTop: 4 }}>
            <div style={{
              flex: 1, height: 3, borderRadius: 2,
              background: t.border, overflow: 'hidden',
            }}>
              <div style={{
                width: `${step.progress}%`, height: '100%', background: t.primary,
              }} />
            </div>
            <span style={{ fontSize: 9.5, fontWeight: 700, color: t.fgDim }}>{step.progress}%</span>
          </div>
        )}
      </div>
    </div>
  );
}

function LinkRow({ t, icon, iconBg, iconColor, title, subtitle, badge, badgeColor }) {
  return (
    <button style={{
      padding: '10px 12px', borderRadius: 10,
      background: t.cardSunken, border: `1px solid ${t.border}`,
      display: 'flex', alignItems: 'center', gap: 10,
      cursor: 'pointer', textAlign: 'left',
    }}>
      <div style={{
        width: 32, height: 32, borderRadius: 7, background: iconBg,
        display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
      }}>
        <PI name={icon} size={16} color={iconColor} />
      </div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 12.5, fontWeight: 700, color: t.fg }}>{title}</div>
        <div style={{ fontSize: 11, color: t.fgMute, fontWeight: 600, marginTop: 1 }}>{subtitle}</div>
      </div>
      {badge && (
        <span style={{
          fontSize: 10, fontWeight: 800, color: badgeColor,
          padding: '3px 8px', borderRadius: 4,
          background: hexToRgba(badgeColor, 0.15),
        }}>{badge}</span>
      )}
      <PI name="chevron-right" size={14} color={t.fgMute} />
    </button>
  );
}

function SecondaryAction({ t, icon, title, subtitle, premium, onClick }) {
  return (
    <button onClick={onClick} style={{
      padding: '10px 12px', borderRadius: 10,
      background: 'transparent', border: `1px solid ${t.border}`,
      display: 'flex', alignItems: 'center', gap: 10,
      cursor: onClick ? 'pointer' : 'default', textAlign: 'left',
    }}>
      <PI name={icon} size={16} color={t.fgDim} />
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{
          fontSize: 12.5, fontWeight: 700, color: t.fg,
          display: 'flex', alignItems: 'center', gap: 6,
        }}>
          {title}
          {premium && (
            <span style={{
              fontSize: 9, fontWeight: 800, color: t.purple,
              padding: '2px 6px', borderRadius: 3,
              background: hexToRgba(t.purple, 0.14),
              letterSpacing: 0.3, textTransform: 'uppercase',
            }}>⭐ Premium</span>
          )}
        </div>
        <div style={{ fontSize: 11, color: t.fgMute, fontWeight: 600, marginTop: 1 }}>{subtitle}</div>
      </div>
      <PI name="chevron-right" size={14} color={t.fgMute} />
    </button>
  );
}

/* ═══════════════════════════════════════════════════════════════════
   SCREEN: WEEK-VIEW — 7-dagen kalender met tijd-gutter
   ═══════════════════════════════════════════════════════════════════ */

const WEEK_BLOCKS = {
  // Per dag: taak-blokken met start-tijd + duur
  '2026-04-21': [
    { start: '15:30', end: '16:00', subject: 'biologie', title: '§4.1 inleiding', type: 'lezen', done: true },
    { start: '16:00', end: '16:20', subject: 'wiskunde', title: 'Oefening 2.1', type: 'oefenen', done: true },
  ],
  '2026-04-22': [
    { start: '15:30', end: '15:55', subject: 'biologie', title: '§4.2 celbiologie', type: 'lezen', isNow: true },
    { start: '16:00', end: '16:20', subject: 'wiskunde', title: '3 oefenopgaves', type: 'oefenen' },
    { start: '19:30', end: '19:45', subject: 'engels', title: 'Essay-paragraaf 2', type: 'schrijven' },
  ],
  '2026-04-23': [
    { start: '16:00', end: '16:20', subject: 'scheikunde', title: '§ 4.2 samenvatting', type: 'lezen' },
    { start: '16:30', end: '16:45', subject: 'frans', title: 'H6 overhoren', type: 'overhoren' },
  ],
  '2026-04-24': [
    { start: '15:30', end: '16:00', subject: 'biologie', title: 'H4 flashcards ronde 1', type: 'oefenen' },
    { start: '16:30', end: '17:00', subject: 'biologie', title: 'H4 flashcards ronde 2', type: 'oefenen' },
  ],
  '2026-04-25': [],
  '2026-04-26': [],
  '2026-04-27': [
    { start: '10:00', end: '10:30', subject: 'wiskunde', title: 'Statistiek H7 eindtoets', type: 'oefenen' },
  ],
};

function ScreenWeekView({ store }) {
  const tk = t(store.theme);
  const [selectedDay, setSelectedDay] = useState(null);
  const [weekBlocks, setWeekBlocks] = useState(WEEK_BLOCKS);
  const [view, setView] = useState('week'); // 'week' | 'maand'
  const [weekOffset, setWeekOffset] = useState(0);

  // Genereer week-data per offset. Offset 0 = store.week (met isToday-flag).
  const displayedWeek = React.useMemo(() => {
    if (weekOffset === 0) return store.week;
    const baseMonday = new Date('2026-04-21');
    baseMonday.setDate(baseMonday.getDate() + weekOffset * 7);
    const days = [];
    for (let i = 0; i < 7; i++) {
      const d = new Date(baseMonday);
      d.setDate(baseMonday.getDate() + i);
      const iso = d.toISOString().slice(0, 10);
      const lbl = mockDayLabel(iso);
      days.push({
        label: lbl.day, date: lbl.date, isoDate: iso,
        isToday: false,
        isWeekend: i >= 5,
        items: MOCK_WEEK_ITEMS[iso] || [],
      });
    }
    return days;
  }, [weekOffset, store.week]);

  const weekNumber = 17 + weekOffset;
  const firstDay = displayedWeek[0];
  const lastDay = displayedWeek[displayedWeek.length - 1];
  const firstD = new Date(firstDay.isoDate);
  const lastD = new Date(lastDay.isoDate);
  const nlMonth = (d) => d.toLocaleDateString('nl-NL', { month: 'short' }).replace('.', '');
  const sameMonth = firstD.getMonth() === lastD.getMonth();
  const dateRange = sameMonth
    ? `${firstDay.date}–${lastDay.date} ${nlMonth(firstD)}`
    : `${firstDay.date} ${nlMonth(firstD)} – ${lastDay.date} ${nlMonth(lastD)}`;
  // Samenvatting voor subtitle
  const weekDeadlines = (store.deadlines || []).filter(d =>
    d.dueDate && d.dueDate >= firstDay.isoDate && d.dueDate <= lastDay.isoDate && BIG_DEADLINE_TYPES.includes(d.type) && !d.unscheduled
  );
  let weekSummary = '';
  if (weekDeadlines.length > 0) {
    const first = weekDeadlines[0];
    const dayLbl = mockDayLabel(first.dueDate).day.toLowerCase();
    const dayNames = { ma: 'maandag', di: 'dinsdag', wo: 'woensdag', do: 'donderdag', vr: 'vrijdag', za: 'zaterdag', zo: 'zondag' };
    const titleShort = first.title.split(' — ')[0].replace(/ H\d+.*/, '');
    weekSummary = `${titleShort} ${dayNames[dayLbl] || dayLbl}`;
    if (weekDeadlines.length > 1) weekSummary += ` · +${weekDeadlines.length - 1} meer`;
  } else {
    // Check meivakantie
    const anyVacDay = displayedWeek.find(d => vacationForDate(d.isoDate, store.vacations));
    weekSummary = anyVacDay ? vacationForDate(anyVacDay.isoDate, store.vacations).name.toLowerCase() : 'geen deadlines';
  }

  // Reorder block within a day
  function reorderBlock(isoDate, idx, direction) {
    const list = weekBlocks[isoDate] ? [...weekBlocks[isoDate]] : [];
    const target = idx + direction;
    if (target < 0 || target >= list.length) return;
    [list[idx], list[target]] = [list[target], list[idx]];
    setWeekBlocks({ ...weekBlocks, [isoDate]: list });
  }

  // Time-gutter 14:00-21:30 (30-min resolution = 16 rows)
  const hours = [];
  for (let h = 14; h <= 21; h++) hours.push(`${String(h).padStart(2, '0')}:00`);

  return (
    <div style={{
      background: tk.bgApp, minHeight: 'calc(100vh - 44px)',
      display: 'flex', maxWidth: 1440, margin: '0 auto',
    }}>
      <Sidebar t={tk} active="plannen" />
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', minWidth: 0 }}>
        <Topbar t={tk} title={`Plannen · Week ${weekNumber}`}
          subtitle={`${dateRange} · ${weekSummary} · studie-vensters zichtbaar`} />

        <div style={{
          padding: '16px 28px 8px', display: 'flex', alignItems: 'center', gap: 12,
        }}>
          <button onClick={() => store.navigate('/')} style={{
            padding: '6px 10px', borderRadius: 7,
            background: 'transparent', border: `1px solid ${tk.border}`,
            color: tk.fgDim, fontSize: 11, fontWeight: 700, cursor: 'pointer',
          }}>← Vandaag</button>

          {/* View toggle */}
          <div style={{
            display: 'inline-flex', gap: 2,
            background: tk.cardSunken, border: `1px solid ${tk.border}`,
            borderRadius: 8, padding: 2,
          }}>
            {[
              { v: 'week', label: 'Week' },
              { v: 'maand', label: 'Maand' },
            ].map(opt => (
              <button key={opt.v}
                onClick={() => setView(opt.v)}
                style={{
                  padding: '5px 12px', borderRadius: 6,
                  background: view === opt.v ? tk.card : 'transparent',
                  border: 0, color: view === opt.v ? tk.fg : tk.fgMute,
                  fontSize: 11, fontWeight: 800, cursor: 'pointer',
                }}>{opt.label}</button>
            ))}
          </div>
          <span style={{ fontSize: 10, color: tk.fgMute, fontWeight: 600, marginLeft: 8 }}>
            {view === 'week' && '7 dagen naast elkaar'}
            {view === 'maand' && 'Alleen deadlines + intensiteit per dag'}
          </span>

          <span style={{ flex: 1 }} />

          <button
            onClick={() => store.navigate('/add-task', { when: 'today' })}
            style={{
              padding: '6px 10px', borderRadius: 7,
              background: 'transparent', border: `1px solid ${tk.border}`,
              color: tk.fgDim, fontSize: 11, fontWeight: 700, cursor: 'pointer',
              display: 'inline-flex', alignItems: 'center', gap: 4, marginRight: 6,
            }}
            title="Nieuwe losse taak"
          >
            <PI name="plus" size={11} color={tk.fgMute} />
            Taak
          </button>
          <button
            onClick={() => store.navigate('/settings', { tab: 'plannen' })}
            style={{
              padding: '6px 10px', borderRadius: 7,
              background: 'transparent', border: `1px solid ${tk.border}`,
              color: tk.fgDim, fontSize: 11, fontWeight: 700, cursor: 'pointer',
              display: 'inline-flex', alignItems: 'center', gap: 4, marginRight: 6,
            }}
            title="Stel je studietijd per dag in"
          >
            <PI name="clock" size={11} color={tk.fgMute} />
            Studie-tijd
          </button>
          {weekOffset !== 0 && (
            <button
              onClick={() => setWeekOffset(0)}
              title="Terug naar deze week"
              style={{
                padding: '6px 10px', borderRadius: 7,
                border: `1px solid ${tk.primary}`, background: hexToRgba(tk.primary, 0.08),
                color: tk.primary, fontSize: 11, fontWeight: 800, cursor: 'pointer',
              }}
            >Deze week</button>
          )}
          <button
            onClick={() => setWeekOffset(weekOffset - 1)}
            title="Vorige week"
            style={{
              padding: '6px 10px', borderRadius: 7,
              background: 'transparent', border: `1px solid ${tk.border}`,
              color: tk.fgDim, fontSize: 11, fontWeight: 700, cursor: 'pointer',
              display: 'inline-flex', alignItems: 'center', gap: 4,
            }}
          >
            <PI name="chevron-left" size={12} /> wk {weekNumber - 1}
          </button>
          <button
            onClick={() => setWeekOffset(weekOffset + 1)}
            title="Volgende week"
            style={{
              padding: '6px 10px', borderRadius: 7,
              background: 'transparent', border: `1px solid ${tk.border}`,
              color: tk.fgDim, fontSize: 11, fontWeight: 700, cursor: 'pointer',
              display: 'inline-flex', alignItems: 'center', gap: 4,
            }}
          >
            wk {weekNumber + 1} <PI name="chevron-right" size={12} />
          </button>
        </div>

        <div style={{ padding: '0 28px 40px', flex: 1 }}>
          {view === 'week' && (
            <WeekGrid t={tk} week={displayedWeek} deadlines={store.deadlines} vacations={store.vacations} onDayClick={setSelectedDay} weekBlocks={weekBlocks} reorderBlock={reorderBlock} />
          )}
          {view === 'maand' && <MaandBlik tk={tk} store={store} />}
        </div>
      </div>

      {/* Dag-detail drawer */}
      {selectedDay && (
        <DayDetailDrawer t={tk} day={selectedDay} store={store} onClose={() => setSelectedDay(null)} />
      )}
    </div>
  );
}

function WeekGrid({ t, week, deadlines, vacations, hours, onDayClick, weekBlocks, reorderBlock }) {
  // F1-style: card-per-dag, taken gestapeld met tijd per card (geen tijd-gutter).
  // Gives each task ruimte om titel + duur + subject-info leesbaar te tonen.

  const upcomingToets = [
    { subject: 'biologie', title: 'Bio H4', days: 3 },
    { subject: 'wiskunde', title: 'Wisk SO', days: 6 },
    { subject: 'engels', title: 'Essay', days: 10 },
    { subject: 'geschiedenis', title: 'Ges H3', days: 14 },
  ];

  return (
    <>
      <section style={{
        background: t.card, border: `1px solid ${t.border}`,
        borderRadius: 14, padding: 14,
        boxShadow: t.shadowCard,
      }}>
        <div style={{
          display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 10,
        }}>
          {week.map(d => (
            <WeekDayColumn key={d.date} t={t} d={d} onClick={() => onDayClick(d)}
              dayDeadlines={deadlinesOnDate(deadlines, d.isoDate)}
              vacation={vacationForDate(d.isoDate, vacations)}
              weekBlocks={weekBlocks} reorderBlock={reorderBlock} />
          ))}
        </div>
      </section>

      {/* Onder de grid: Komende toetsen + Vandaag-samenvatting */}
      <div style={{
        display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12, marginTop: 16,
      }}>
        {/* Komende toetsen — title bovenaan, toetsen eronder, icoon links gecentreerd */}
        <section style={{
          background: t.card, border: `1px solid ${t.border}`,
          borderRadius: 12, padding: '12px 14px',
          display: 'flex', alignItems: 'center', gap: 12,
        }}>
          <div style={{
            width: 34, height: 34, borderRadius: 8,
            background: hexToRgba(t.warn, 0.14),
            border: `1px solid ${hexToRgba(t.warn, 0.25)}`,
            display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
          }}>
            <PI name="flag" size={15} color={t.warn} />
          </div>
          <div style={{ flex: 1, display: 'flex', flexDirection: 'column', gap: 6, minWidth: 0 }}>
            <div style={{
              fontSize: 9.5, fontWeight: 800, color: t.fgMute,
              letterSpacing: 0.5, textTransform: 'uppercase',
            }}>
              Komende toetsen
            </div>
            <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
              {upcomingToets.map((tt, i) => {
                const urg = tt.days <= 3 ? t.red : tt.days <= 7 ? t.warn : t.fgMute;
                return (
                  <div key={i} style={{
                    padding: '4px 3px 4px 9px', borderRadius: 999,
                    background: hexToRgba(SUBJECTS[tt.subject], 0.10),
                    border: `1px solid ${hexToRgba(SUBJECTS[tt.subject], 0.22)}`,
                    display: 'inline-flex', alignItems: 'center', gap: 6,
                  }}>
                    <PI name={SUBJECT_ICON_NAME(tt.subject)} size={12} color={SUBJECTS[tt.subject]} />
                    <span style={{
                      fontSize: 12, fontWeight: 800,
                      color: SUBJECTS[tt.subject],
                    }}>{tt.title}</span>
                    <span style={{
                      fontSize: 10, fontWeight: 800, color: urg,
                      background: hexToRgba(urg, 0.14),
                      padding: '2px 7px', borderRadius: 999,
                    }}>{tt.days}d</span>
                  </div>
                );
              })}
            </div>
          </div>
        </section>

        {/* Vandaag samenvatting */}
        <section style={{
          background: hexToRgba(t.primary, 0.08),
          border: `1px solid ${hexToRgba(t.primary, 0.22)}`,
          borderRadius: 12, padding: '12px 14px',
          display: 'flex', alignItems: 'center', gap: 10,
        }}>
          <PulseMascot size={30} mood="thinking" />
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 13, fontWeight: 800, color: t.fg }}>
              Vandaag 3 taken · ±50 min
            </div>
            <div style={{ fontSize: 11, color: t.fgDim, fontWeight: 600 }}>
              Rustige dag. Morgen pik je je eerste Bio-blok op.
            </div>
          </div>
          <button style={{
            padding: '8px 14px', borderRadius: 8,
            background: t.primary, color: '#FFFFFF', border: 0,
            fontSize: 12, fontWeight: 800, cursor: 'pointer',
            display: 'inline-flex', alignItems: 'center', gap: 4,
          }}>
            <PI name="play" size={12} /> Start
          </button>
        </section>
      </div>
    </>
  );
}

function WeekDayColumn({ t, d, onClick, dayDeadlines, vacation, weekBlocks, reorderBlock }) {
  const blocks = (weekBlocks || WEEK_BLOCKS)[d.isoDate] || [];
  const isToday = d.isToday;
  const isWeekend = d.isWeekend;
  // Nieuwe bron: dayDeadlines (derived from store.deadlines). Fallback naar d.deadline (oud).
  const deadlinesHere = (dayDeadlines && dayDeadlines.length)
    ? dayDeadlines
    : (d.deadline ? [{ subject: d.deadline.subject, type: d.deadline.type, title: d.deadline.title, timeLabel: '10:00' }] : []);
  const primary = deadlinesHere[0];
  const primaryColor = primary ? SUBJECTS[primary.subject] : null;
  const hasDeadline = deadlinesHere.length > 0;
  const totalMins = blocks.reduce((sum, b) => {
    const [sh, sm] = b.start.split(':').map(Number);
    const [eh, em] = b.end.split(':').map(Number);
    return sum + ((eh * 60 + em) - (sh * 60 + sm));
  }, 0);

  return (
    <button
      onClick={onClick}
      style={{
        // Kolom-achtergrond blijft neutraal — de toets-badge zelf is duidelijk onderscheid
        background: isToday ? hexToRgba(t.primary, 0.05) : t.cardSunken,
        border: isToday ? `2px solid ${t.primary}` : `1px solid ${t.border}`,
        borderRadius: 10,
        display: 'flex', flexDirection: 'column',
        minHeight: 400,
        boxShadow: isToday ? `0 0 0 3px ${hexToRgba(t.primary, 0.15)}` : 'none',
        overflow: 'hidden',
        padding: 0, margin: 0,
        cursor: 'pointer', textAlign: 'left',
        transition: 'transform 0.1s, box-shadow 0.2s',
        position: 'relative',
      }}
      onMouseEnter={(e) => {
        if (!isToday) e.currentTarget.style.boxShadow = t.shadowElev;
      }}
      onMouseLeave={(e) => {
        if (!isToday) e.currentTarget.style.boxShadow = 'none';
      }}
    >
      {/* Header */}
      <div
        style={{
          padding: '10px 12px 8px',
          display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between',
          gap: 8,
          opacity: isWeekend ? 0.7 : 1,
        }}
      >
        <div>
          <div style={{
            fontSize: 10, fontWeight: 800, color: isToday ? t.primary : t.fgMute,
            letterSpacing: 0.5, textTransform: 'uppercase',
          }}>{d.label}{isToday ? ' · NU' : ''}</div>
        </div>
        <div style={{
          fontFamily: 'Fredoka One', fontSize: 20,
          color: isToday ? t.primary : t.fg, lineHeight: 1,
        }}>{d.date}</div>
      </div>

      {/* Body — taken */}
      <div style={{
        flex: 1, padding: '2px 8px 8px',
        display: 'flex', flexDirection: 'column', gap: 4,
      }}>
        {/* Vakantie / vrije dag — all-day event-banner + HR-break */}
        {vacation && (
          <>
            <div style={{
              padding: '6px 8px', borderRadius: 7,
              background: hexToRgba(t.warn, 0.12),
              border: `1px solid ${hexToRgba(t.warn, 0.3)}`,
              display: 'flex', alignItems: 'center', gap: 6,
            }}>
              <PI name="sun" size={12} color={t.warn} />
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{
                  fontSize: 9, fontWeight: 800, color: t.warn,
                  letterSpacing: 0.5, textTransform: 'uppercase',
                }}>Heel de dag</div>
                <div style={{
                  fontSize: 11, fontWeight: 800, color: t.fg, lineHeight: 1.25,
                  overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
                }}>{vacation.name}</div>
              </div>
            </div>
            <div style={{ height: 1, background: t.border, margin: '4px 0' }} />
          </>
        )}

        {/* Deadline-kaarten: zachte tint + full border + kleine gevulde type-pill + leesbare titel */}
        {deadlinesHere.map((x, i) => {
          const sc = SUBJECTS[x.subject];
          const meta = DEADLINE_TYPES[x.type] || { short: String(x.type || '').toUpperCase(), icon: 'flag' };
          return (
            <div key={i} style={{
              padding: '7px 8px 8px', borderRadius: 7,
              background: hexToRgba(sc, 0.10),
              border: `1.5px solid ${sc}`,
              display: 'flex', flexDirection: 'column', gap: 4,
              marginBottom: 2,
            }}>
              {/* Top row: type-pill + icon + optional time */}
              <div style={{ display: 'flex', alignItems: 'center', gap: 5 }}>
                <span style={{
                  padding: '1px 5px', borderRadius: 3,
                  background: sc, color: '#FFFFFF',
                  fontSize: 8.5, fontWeight: 800, letterSpacing: 0.5,
                  lineHeight: 1.3,
                }}>{meta.short}</span>
                <PI name={meta.icon} size={10} color={sc} />
                {x.timeLabel && (
                  <span style={{ fontSize: 9, fontWeight: 700, color: t.fgMute, marginLeft: 'auto' }}>
                    {x.timeLabel}
                  </span>
                )}
              </div>
              {/* Title in foreground — leesbaar */}
              <div style={{
                fontSize: 11.5, fontWeight: 800, color: t.fg, lineHeight: 1.25,
              }}>{(x.title || '').split(' — ')[0]}</div>
            </div>
          );
        })}

        {/* Taken als cards — met reorder-knoppen bij ≥2 taken */}
        {blocks.map((b, i) => (
          <div key={i} style={{
            padding: '6px 8px', borderRadius: 6,
            background: b.done ? hexToRgba(t.fgFaint, 0.08) : hexToRgba(SUBJECTS[b.subject], 0.10),
            borderLeft: `3px solid ${b.done ? t.fgFaint : SUBJECTS[b.subject]}`,
            boxShadow: b.isNow ? `0 0 0 2px ${hexToRgba(t.primary, 0.3)}` : 'none',
            opacity: b.done ? 0.6 : 1,
            cursor: 'pointer', position: 'relative',
          }}>
            <div style={{
              display: 'flex', alignItems: 'center', gap: 4, marginBottom: 1,
            }}>
              <PI name={SUBJECT_ICON_NAME(b.subject)} size={9}
                color={b.done ? t.fgMute : SUBJECTS[b.subject]} />
              <span style={{
                fontSize: 9, fontWeight: 800,
                color: b.done ? t.fgMute : SUBJECTS[b.subject],
                letterSpacing: 0.3, textTransform: 'uppercase',
              }}>{SUBJECT_SHORT[b.subject]}</span>
              <span style={{ flex: 1 }} />
              <span style={{ fontSize: 9, fontWeight: 700, color: t.fgMute }}>
                {getTaskDuration(b)}
              </span>
            </div>
            <div style={{
              fontSize: 11, fontWeight: 700, color: t.fg, lineHeight: 1.25,
              textDecoration: b.done ? 'line-through' : 'none',
              display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical', overflow: 'hidden',
            }}>{b.title}</div>
            <div style={{
              fontSize: 9, fontWeight: 700, color: t.fgMute,
              marginTop: 2, display: 'flex', alignItems: 'center', gap: 4,
            }}>
              <span>{b.start}</span>
              {/* Reorder knoppen — alleen bij meerdere blokken + reorderBlock beschikbaar */}
              {blocks.length > 1 && reorderBlock && (
                <>
                  <span style={{ flex: 1 }} />
                  <button
                    disabled={i === 0}
                    onClick={(e) => {
                      e.stopPropagation();
                      reorderBlock(d.isoDate, i, -1);
                    }}
                    style={{
                      border: 0, background: 'transparent',
                      color: i === 0 ? t.fgFaint : SUBJECTS[b.subject],
                      cursor: i === 0 ? 'default' : 'pointer',
                      fontSize: 11, padding: 0, width: 16, height: 16,
                      display: 'flex', alignItems: 'center', justifyContent: 'center',
                      borderRadius: 3,
                    }} title="Eerder op de dag">↑</button>
                  <button
                    disabled={i === blocks.length - 1}
                    onClick={(e) => {
                      e.stopPropagation();
                      reorderBlock(d.isoDate, i, 1);
                    }}
                    style={{
                      border: 0, background: 'transparent',
                      color: i === blocks.length - 1 ? t.fgFaint : SUBJECTS[b.subject],
                      cursor: i === blocks.length - 1 ? 'default' : 'pointer',
                      fontSize: 11, padding: 0, width: 16, height: 16,
                      display: 'flex', alignItems: 'center', justifyContent: 'center',
                      borderRadius: 3,
                    }} title="Later op de dag">↓</button>
                </>
              )}
            </div>
          </div>
        ))}

        {/* Empty state */}
        {blocks.length === 0 && !hasDeadline && (
          <div style={{
            flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center',
            fontSize: 10, color: t.fgFaint, fontStyle: 'italic', fontWeight: 500,
            padding: '16px 0',
          }}>
            {isWeekend ? '— weekend —' : '— leeg —'}
          </div>
        )}
      </div>

      {/* Footer — totaal */}
      <div style={{
        padding: '6px 10px', borderTop: `1px solid ${t.border}`,
        background: hexToRgba(t.fgFaint, 0.04),
        display: 'flex', alignItems: 'center', gap: 4,
        fontSize: 10, fontWeight: 700, color: totalMins > 0 ? t.primary : t.fgMute,
      }}>
        <PI name="clock" size={10} color={totalMins > 0 ? t.primary : t.fgMute} />
        {totalMins > 0 ? `${totalMins}m` : '—'}
      </div>
    </button>
  );
}

function getTaskDuration(b) {
  const [sh, sm] = b.start.split(':').map(Number);
  const [eh, em] = b.end.split(':').map(Number);
  return `${(eh * 60 + em) - (sh * 60 + sm)}m`;
}

/* ═══════════════════════════════════════════════════════════════════
   MAAND-BLIK — vooruitblik-tool (F-mini uit polish)
   Geen volledige kalender, wel deadlines + intensiteit per dag
   ═══════════════════════════════════════════════════════════════════ */

function MaandBlik({ tk, store }) {
  // Mock data voor 4 weken (wk 17 - wk 20)
  // Per dag: intensity (0-3) + optional deadline
  const monthData = [
    // Week 17 (huidige)
    { week: 17, label: 'nu', days: [
      { d: 21, intensity: 2 }, { d: 22, intensity: 2, isToday: true }, { d: 23, intensity: 1 },
      { d: 24, intensity: 2 }, { d: 25, intensity: 3, deadline: { subject: 'biologie', title: 'Bio H4' } },
      { d: 26, intensity: 0, weekend: true }, { d: 27, intensity: 1, weekend: true },
    ]},
    // Week 18
    { week: 18, label: '', days: [
      { d: 28, intensity: 2 }, { d: 29, intensity: 2, deadline: { subject: 'wiskunde', title: 'Wisk SO' } },
      { d: 30, intensity: 1 }, { d: 1, intensity: 2, month: 'mei' },
      { d: 2, intensity: 3, deadline: { subject: 'engels', title: 'En essay', inlever: true }, month: 'mei' },
      { d: 3, intensity: 0, weekend: true, month: 'mei' }, { d: 4, intensity: 0, weekend: true, month: 'mei' },
    ]},
    // Week 19 — meivakantie
    { week: 19, label: 'meivakantie', days: [
      { d: 5, intensity: 0, vakantie: true, month: 'mei' }, { d: 6, intensity: 0, vakantie: true, month: 'mei' },
      { d: 7, intensity: 0, vakantie: true, month: 'mei' }, { d: 8, intensity: 0, vakantie: true, month: 'mei' },
      { d: 9, intensity: 0, vakantie: true, month: 'mei' },
      { d: 10, intensity: 0, weekend: true, vakantie: true, month: 'mei' }, { d: 11, intensity: 0, weekend: true, vakantie: true, month: 'mei' },
    ]},
    // Week 20
    { week: 20, label: '', days: [
      { d: 12, intensity: 2, month: 'mei' }, { d: 13, intensity: 2, month: 'mei' },
      { d: 14, intensity: 3, deadline: { subject: 'nederlands', title: 'Ned verslag', inlever: true }, month: 'mei' },
      { d: 15, intensity: 2, month: 'mei' }, { d: 16, intensity: 2, deadline: { subject: 'scheikunde', title: 'Sk toets' }, month: 'mei' },
      { d: 17, intensity: 1, weekend: true, month: 'mei' }, { d: 18, intensity: 0, weekend: true, month: 'mei' },
    ]},
  ];

  return (
    <>
      {/* Context-banner */}
      <div style={{
        padding: '12px 16px', borderRadius: 10,
        background: hexToRgba(tk.primary, 0.06),
        border: `1px solid ${hexToRgba(tk.primary, 0.2)}`,
        marginBottom: 16, display: 'flex', alignItems: 'center', gap: 10,
      }}>
        <PulseMascot size={28} mood="thinking" />
        <div style={{ fontSize: 12, color: tk.fg, fontWeight: 600, lineHeight: 1.5 }}>
          <b>Maand-blik</b> is een vooruitblik-tool — niet je hoofdplanner. Het toont alleen deadlines en drukte per dag.
        </div>
      </div>

      {/* Maand-grid */}
      <section style={{
        background: tk.card, border: `1px solid ${tk.border}`,
        borderRadius: 12, padding: 16,
      }}>
        <div style={{ display: 'flex', alignItems: 'baseline', gap: 10, marginBottom: 12 }}>
          <h3 style={{ fontFamily: 'Fredoka One', fontSize: 20, color: tk.fg, margin: 0 }}>April · vooruitblik</h3>
          <span style={{ fontSize: 12, color: tk.fgMute, fontWeight: 600 }}>4 weken</span>
          <span style={{ flex: 1 }} />
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 12 }}>
            <LegendChip tk={tk} color={tk.primary} label="druk" />
            <LegendChip tk={tk} color={tk.warn} label="deadline" />
            <LegendChip tk={tk} color={tk.fgFaint} label="vakantie" />
          </span>
        </div>

        {/* Day-labels */}
        <div style={{
          display: 'grid', gridTemplateColumns: '60px repeat(7, 1fr)',
          fontSize: 10, fontWeight: 800, color: tk.fgMute,
          letterSpacing: 0.6, textTransform: 'uppercase',
          marginBottom: 8, paddingLeft: 4,
        }}>
          <span></span>
          {['MA', 'DI', 'WO', 'DO', 'VR', 'ZA', 'ZO'].map(d => (
            <span key={d} style={{ textAlign: 'center' }}>{d}</span>
          ))}
        </div>

        {/* Weeks */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
          {monthData.map(w => (
            <div key={w.week} style={{
              display: 'grid', gridTemplateColumns: '60px repeat(7, 1fr)', gap: 4, alignItems: 'stretch',
            }}>
              <div style={{
                display: 'flex', flexDirection: 'column', justifyContent: 'center',
                paddingRight: 8,
                fontSize: 10, color: tk.fgMute, fontWeight: 700, lineHeight: 1.3,
              }}>
                <div>Wk {w.week}</div>
                {w.label && (
                  <div style={{
                    fontSize: 9, fontWeight: 800,
                    color: w.label === 'nu' ? tk.primary : w.label.includes('vakantie') ? tk.warn : tk.fgMute,
                    letterSpacing: 0.4, textTransform: 'uppercase', marginTop: 1,
                  }}>{w.label}</div>
                )}
              </div>
              {w.days.map((d, i) => <MaandDay key={i} tk={tk} day={d} />)}
            </div>
          ))}
        </div>

        {/* Vakantie-voet */}
        <div style={{
          marginTop: 14, padding: '10px 12px', borderRadius: 8,
          background: hexToRgba(tk.warn, 0.08),
          border: `1px solid ${hexToRgba(tk.warn, 0.2)}`,
          display: 'flex', alignItems: 'center', gap: 8,
        }}>
          <PI name="sun" size={14} color={tk.warn} />
          <span style={{ fontSize: 11.5, color: tk.fg, fontWeight: 600 }}>
            <b>5-11 mei</b> — meivakantie. Pulse plant geen nieuwe taken tenzij je een toets erna hebt.
          </span>
        </div>
      </section>
    </>
  );
}

function MaandDay({ tk, day }) {
  const sc = day.deadline ? SUBJECTS[day.deadline.subject] : null;
  // Neutrale achtergrond — de gevulde toets-pill geeft het onderscheid.
  const bg = day.vakantie ? hexToRgba(tk.warn, 0.06)
    : day.weekend ? hexToRgba(tk.fgFaint, 0.04)
    : day.intensity === 3 ? hexToRgba(tk.primary, 0.25)
    : day.intensity === 2 ? hexToRgba(tk.primary, 0.12)
    : day.intensity === 1 ? hexToRgba(tk.primary, 0.05)
    : tk.cardSunken;
  const border = day.isToday ? `2px solid ${tk.primary}` : `1px solid ${tk.border}`;
  return (
    <div style={{
      background: bg, border, borderRadius: 6,
      padding: '6px 6px 5px', minHeight: 54,
      opacity: day.vakantie ? 0.7 : 1,
      display: 'flex', flexDirection: 'column', justifyContent: 'space-between',
    }}>
      <div style={{
        fontSize: 11, fontWeight: 800,
        color: day.isToday ? tk.primary : tk.fg,
      }}>
        {day.d}{day.month === 'mei' && ' mei'}
      </div>
      {day.deadline && (
        <div style={{
          fontSize: 9, fontWeight: 800, color: tk.fg,
          background: hexToRgba(sc, 0.12),
          border: `1.5px solid ${sc}`,
          padding: '2px 5px', borderRadius: 4,
          letterSpacing: 0.2, lineHeight: 1.2,
          display: 'inline-flex', alignItems: 'center', gap: 3,
          alignSelf: 'flex-start', maxWidth: '100%',
        }}>
          <PI name={day.deadline.inlever ? "upload" : "flag"} size={9} color={sc} />
          <span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
            {day.deadline.title}
          </span>
        </div>
      )}
      {day.vakantie && !day.deadline && (
        <div style={{ fontSize: 9, color: tk.warn, fontWeight: 700, fontStyle: 'italic' }}>vak.</div>
      )}
    </div>
  );
}

function LegendChip({ tk, color, label }) {
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4, fontSize: 10.5, color: tk.fgMute, fontWeight: 700 }}>
      <span style={{ width: 10, height: 10, borderRadius: 3, background: hexToRgba(color, 0.3), border: `1px solid ${hexToRgba(color, 0.5)}` }} />
      {label}
    </span>
  );
}

function store_getStudyBlockForDay(d) {
  const key = d.label.toLowerCase();
  const blocks = INITIAL_STUDY_BLOCKS;
  const block = blocks[key];
  return block && block.available ? block : null;
}

/* Dag-detail drawer (opened when clicking day-header in week-view) */
function DayDetailDrawer({ t, day, store, onClose }) {
  const blocks = WEEK_BLOCKS[day.isoDate] || [];
  const totalMins = blocks.reduce((sum, b) => {
    const [sh, sm] = b.start.split(':').map(Number);
    const [eh, em] = b.end.split(':').map(Number);
    return sum + ((eh * 60 + em) - (sh * 60 + sm));
  }, 0);
  // Deadlines uit store op deze dag — consistent met Vandaag/Week-view
  const dayDeadlines = deadlinesOnDate(store.deadlines, day.isoDate);

  return (
    <>
      <div onClick={onClose} style={{
        position: 'fixed', top: 44, left: 0, right: 420, bottom: 0,
        background: 'rgba(0,0,0,0.3)', zIndex: 40, cursor: 'pointer',
      }} />
      <aside style={{
        position: 'fixed', top: 44, right: 0, bottom: 0, width: 420,
        background: t.card, borderLeft: `1px solid ${t.border}`,
        boxShadow: t.shadowElev, zIndex: 50,
        display: 'flex', flexDirection: 'column',
      }}>
        <header style={{
          padding: '18px 24px', borderBottom: `1px solid ${t.border}`,
          display: 'flex', alignItems: 'flex-start', gap: 12,
        }}>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 10, fontWeight: 800, color: t.primary, letterSpacing: 0.5, textTransform: 'uppercase', marginBottom: 4 }}>
              {day.label}{day.isToday ? ' · vandaag' : ''}
            </div>
            <h2 style={{
              fontFamily: 'Fredoka One', fontSize: 22, color: t.fg,
              margin: '0 0 4px', letterSpacing: '-0.01em',
            }}>{day.date} april</h2>
            <div style={{ fontSize: 12, color: t.fgDim, fontWeight: 600 }}>
              {blocks.length} taken · {Math.floor(totalMins / 60) > 0 ? `${Math.floor(totalMins / 60)}u ` : ''}{totalMins % 60}m totaal
            </div>
          </div>
          <button onClick={onClose} style={{
            width: 32, height: 32, borderRadius: 8,
            border: `1px solid ${t.border}`, background: 'transparent',
            color: t.fgDim, cursor: 'pointer',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}>
            <PI name="x" size={16} />
          </button>
        </header>

        <div style={{ flex: 1, overflow: 'auto', padding: '20px 24px' }}>
          {/* Deadline-flag(s) — uit store.deadlines ipv hardcoded day.deadline */}
          {dayDeadlines.length > 0 && (
            <div style={{ marginBottom: 20, display: 'flex', flexDirection: 'column', gap: 8 }}>
              {dayDeadlines.map(d => {
                const sc = SUBJECTS[d.subject];
                const meta = DEADLINE_TYPES[d.type] || { label: d.type, short: d.type.toUpperCase(), icon: 'flag' };
                return (
                  <button key={d.id}
                    onClick={() => { onClose(); store.navigate(`/deadline/${d.id}`, { id: d.id }); }}
                    style={{
                      padding: '12px 14px', borderRadius: 12,
                      background: hexToRgba(sc, 0.08),
                      border: `1.5px solid ${hexToRgba(sc, 0.4)}`,
                      textAlign: 'left', cursor: 'pointer',
                      display: 'flex', alignItems: 'center', gap: 10,
                    }}
                  >
                    <div style={{
                      width: 34, height: 34, borderRadius: 8,
                      background: hexToRgba(sc, 0.18),
                      display: 'flex', alignItems: 'center', justifyContent: 'center',
                      flexShrink: 0,
                    }}>
                      <PI name={meta.icon} size={16} color={sc} />
                    </div>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{
                        fontSize: 10, fontWeight: 800, color: sc,
                        letterSpacing: 0.5, textTransform: 'uppercase',
                        display: 'inline-flex', alignItems: 'center', gap: 5,
                      }}>
                        <span style={{
                          padding: '1px 5px', borderRadius: 3,
                          background: sc, color: '#FFFFFF',
                          fontSize: 8.5, fontWeight: 800, letterSpacing: 0.5,
                        }}>{meta.short}</span>
                        <span>Deadline op deze dag</span>
                      </div>
                      <div style={{ fontSize: 13.5, fontWeight: 800, color: t.fg, marginTop: 3 }}>
                        {d.title}
                      </div>
                      {d.timeLabel && (
                        <div style={{ fontSize: 11, color: t.fgDim, marginTop: 1, fontWeight: 600 }}>
                          {d.timeLabel}
                        </div>
                      )}
                    </div>
                    <PI name="chevron-right" size={14} color={t.fgMute} />
                  </button>
                );
              })}
            </div>
          )}

          {/* Bestaande taken */}
          <div style={{
            fontSize: 10, fontWeight: 800, color: t.fgMute,
            letterSpacing: 0.6, textTransform: 'uppercase', marginBottom: 10,
          }}>Geplande taken</div>

          {blocks.length === 0 ? (
            <div style={{
              padding: '24px', borderRadius: 10,
              background: t.cardSunken, border: `1.5px dashed ${t.border}`,
              textAlign: 'center',
            }}>
              <div style={{ fontSize: 13, color: t.fgDim, fontWeight: 600, marginBottom: 4 }}>
                Nog geen taken gepland
              </div>
              <div style={{ fontSize: 11, color: t.fgMute, fontWeight: 500 }}>
                {day.isWeekend ? 'Weekend — vrij' : 'Studie-venster beschikbaar'}
              </div>
            </div>
          ) : (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
              {blocks.map((b, i) => (
                <div key={i} style={{
                  padding: '10px 12px', borderRadius: 10,
                  background: hexToRgba(SUBJECTS[b.subject], 0.08),
                  borderLeft: `3px solid ${SUBJECTS[b.subject]}`,
                  display: 'flex', alignItems: 'center', gap: 10,
                  opacity: b.done ? 0.5 : 1,
                }}>
                  <div>
                    <div style={{
                      fontSize: 10, fontWeight: 800, color: SUBJECTS[b.subject],
                      marginBottom: 2, display: 'flex', alignItems: 'center', gap: 4,
                    }}>
                      <PI name={SUBJECT_ICON_NAME(b.subject)} size={11} color={SUBJECTS[b.subject]} />
                      {SUBJECT_SHORT[b.subject]}
                    </div>
                    <div style={{ fontSize: 12, fontWeight: 700, color: t.fg, textDecoration: b.done ? 'line-through' : 'none' }}>
                      {b.title}
                    </div>
                  </div>
                  <span style={{ flex: 1 }} />
                  <span style={{ fontSize: 10.5, color: t.fgMute, fontWeight: 700 }}>{b.start}</span>
                </div>
              ))}
            </div>
          )}

          {/* Quick-add */}
          <div style={{ marginTop: 20 }}>
            <button
              onClick={() => { onClose(); store.navigate('/add-task', { when: 'custom', date: day.isoDate }); }}
              style={{
                width: '100%', padding: '12px', borderRadius: 10,
                background: 'transparent', border: `1.5px dashed ${t.primary}`,
                color: t.primary, fontSize: 12, fontWeight: 800, cursor: 'pointer',
                display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 6,
              }}
            >
              <PI name="plus" size={14} /> Taak toevoegen op deze dag
            </button>
            <div style={{ fontSize: 11, color: t.fgMute, fontWeight: 500, marginTop: 6, textAlign: 'center' }}>
              Handmatige taak · vak + titel + duur
            </div>
          </div>
        </div>

        {/* Footer */}
        <footer style={{
          padding: '12px 24px', borderTop: `1px solid ${t.border}`,
          display: 'flex', gap: 6,
        }}>
          <button style={{
            flex: 1, padding: '9px', borderRadius: 8,
            background: 'transparent', border: `1px solid ${t.border}`,
            color: t.fgDim, fontSize: 11.5, fontWeight: 700, cursor: 'pointer',
          }}>Markeer niet-beschikbaar</button>
          <button style={{
            flex: 1, padding: '9px', borderRadius: 8,
            background: hexToRgba(t.purple, 0.1), border: `1px solid ${hexToRgba(t.purple, 0.3)}`,
            color: t.purple, fontSize: 11.5, fontWeight: 800, cursor: 'pointer',
            display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 4,
          }}>
            <PI name="shuffle" size={11} /> Herplan deze dag
          </button>
        </footer>
      </aside>
    </>
  );
}

/* ═══════════════════════════════════════════════════════════════════
   SCREEN: FOCUS-MODE TAKEOVER
   ═══════════════════════════════════════════════════════════════════ */

function ScreenFocusMode({ store }) {
  const tk = t(store.theme);
  const task = store.tasksToday.find(x => x.id === store.route.params.id) || store.tasksToday[0];
  const [elapsed, setElapsed] = useState(0); // seconds
  const [paused, setPaused] = useState(false);
  const totalMinutes = task?.mins || 25;

  useEffect(() => {
    if (paused) return;
    const i = setInterval(() => setElapsed(e => e + 1), 1000);
    return () => clearInterval(i);
  }, [paused]);

  if (!task) { store.navigate('/'); return null; }

  const totalSec = totalMinutes * 60;
  const remainingSec = Math.max(0, totalSec - elapsed);
  const mins = Math.floor(remainingSec / 60);
  const secs = remainingSec % 60;
  const percent = Math.min(100, (elapsed / totalSec) * 100);

  return (
    <div style={{
      background: tk.bgApp, minHeight: 'calc(100vh - 44px)',
      display: 'flex', flexDirection: 'column',
    }}>
      {/* Mini-topbar */}
      <header style={{
        padding: '14px 28px', borderBottom: `1px solid ${tk.border}`,
        display: 'flex', alignItems: 'center', gap: 14,
        background: tk.card,
      }}>
        <span style={{
          padding: '4px 10px', borderRadius: 999,
          background: hexToRgba(tk.primary, 0.14),
          color: tk.primary, fontSize: 10, fontWeight: 800,
          letterSpacing: 0.5, textTransform: 'uppercase',
          display: 'inline-flex', alignItems: 'center', gap: 4,
        }}>
          <PI name="headphones" size={11} color={tk.primary} /> Focus actief
        </span>
        <span style={{ fontSize: 12, color: tk.fgDim, fontWeight: 600 }}>
          Dinsdag 22 april · {new Date().toLocaleTimeString('nl-NL', { hour: '2-digit', minute: '2-digit' })}
        </span>
        <span style={{ flex: 1 }} />
        <button
          onClick={() => store.navigate('/')}
          style={{
            padding: '6px 12px', borderRadius: 8,
            background: 'transparent', border: `1px solid ${tk.border}`,
            color: tk.fgDim, fontSize: 11, fontWeight: 700, cursor: 'pointer',
            display: 'inline-flex', alignItems: 'center', gap: 4,
          }}
        >
          <PI name="x" size={12} /> Stop focus
        </button>
      </header>

      {/* Body — 2 kolommen: task + timer */}
      <div style={{
        flex: 1, display: 'grid', gridTemplateColumns: '1fr 340px',
        gap: 20, padding: '40px 40px',
        maxWidth: 1200, margin: '0 auto', width: '100%',
      }}>
        {/* Links: grote task card */}
        <div style={{
          background: tk.card, border: `1px solid ${tk.border}`,
          borderRadius: 16, padding: '28px 32px',
          display: 'flex', flexDirection: 'column', gap: 14,
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
            <SubjectChip t={tk} subject={task.subject} size="md" />
            <TaskTypeLabel t={tk}>{task.type}</TaskTypeLabel>
            <span style={{ flex: 1 }} />
            <span style={{ fontSize: 10, fontWeight: 700, color: tk.fgMute }}>
              Taak 1 van {store.tasksToday.length} · vandaag
            </span>
          </div>

          <div style={{
            fontSize: 11, fontWeight: 800, color: tk.primary,
            letterSpacing: 0.5, textTransform: 'uppercase',
          }}>NU · studie-moment</div>

          <h1 style={{
            fontFamily: 'Fredoka One', fontSize: 32, color: tk.fg,
            margin: 0, letterSpacing: '-0.015em', lineHeight: 1.15,
          }}>{task.title}</h1>

          <p style={{
            fontSize: 13, color: tk.fgDim, fontWeight: 500, lineHeight: 1.55,
            margin: '4px 0 0',
          }}>
            Gekoppeld aan <b style={{ color: tk.fg }}>{task.deadlineId ? 'Bio-toets H4' : 'losse studietaak'}</b>.
            Concentreer je op de mitose-fasen (profase → telofase).
          </p>

          {/* Progress */}
          <div style={{
            marginTop: 8, padding: '12px 14px', borderRadius: 10,
            background: tk.cardSunken, border: `1px solid ${tk.border}`,
            display: 'flex', alignItems: 'center', gap: 12,
          }}>
            <div style={{
              width: 36, height: 36, borderRadius: 7,
              background: hexToRgba(SUBJECTS[task.subject], 0.14),
              display: 'flex', alignItems: 'center', justifyContent: 'center',
            }}>
              <PI name="book-open" size={18} color={SUBJECTS[task.subject]} />
            </div>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 12, fontWeight: 700, color: tk.fg }}>Leesvoortgang</div>
              <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginTop: 6 }}>
                <div style={{
                  flex: 1, height: 6, borderRadius: 3,
                  background: tk.border, overflow: 'hidden',
                }}>
                  <div style={{
                    width: '38%', height: '100%', background: tk.green, borderRadius: 3,
                  }} />
                </div>
                <span style={{ fontSize: 11, fontWeight: 700, color: tk.fgDim }}>bladzijde 3 van 8</span>
              </div>
            </div>
          </div>

          {/* Actions */}
          <div style={{ display: 'flex', gap: 8, marginTop: 4 }}>
            <button style={{
              padding: '11px 16px', borderRadius: 10,
              background: tk.primary, color: '#FFFFFF', border: 0,
              fontSize: 13, fontWeight: 800, cursor: 'pointer',
              display: 'inline-flex', alignItems: 'center', gap: 6,
            }}>
              <PI name="book-open" size={14} /> Open hoofdstuk
            </button>
            <button style={{
              padding: '11px 16px', borderRadius: 10,
              background: 'transparent', border: `1px solid ${tk.border}`,
              color: tk.fgDim, fontSize: 12, fontWeight: 700, cursor: 'pointer',
              display: 'inline-flex', alignItems: 'center', gap: 4,
            }}>
              <PI name="pencil" size={12} /> Notities
            </button>
            <span style={{ flex: 1 }} />
            <button
              onClick={() => {
                store.setTasksToday(store.tasksToday.map(x =>
                  x.id === task.id ? { ...x, done: true, isNow: false } : x
                ));
                store.navigate('/');
              }}
              style={{
                padding: '11px 18px', borderRadius: 10,
                background: tk.green, color: '#FFFFFF', border: 0,
                fontSize: 13, fontWeight: 800, cursor: 'pointer',
                display: 'inline-flex', alignItems: 'center', gap: 6,
              }}
            >
              <PI name="check" size={14} /> Klaar · volgende
            </button>
          </div>
        </div>

        {/* Rechts: timer + daarna */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
          {/* Timer */}
          <div style={{
            background: tk.card, border: `1px solid ${tk.border}`,
            borderRadius: 14, padding: '24px',
            display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 14,
          }}>
            <div style={{ fontSize: 10, fontWeight: 800, color: tk.fgMute, letterSpacing: 0.6, textTransform: 'uppercase' }}>
              Timer
            </div>
            <TimerRing t={tk} percent={percent} remaining={`${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}`} total={totalMinutes} />
            <div style={{ display: 'flex', gap: 6, width: '100%' }}>
              <button
                onClick={() => setPaused(!paused)}
                style={{
                  flex: 1, padding: '10px', borderRadius: 9,
                  background: paused ? tk.primary : 'transparent',
                  border: paused ? '0' : `1px solid ${tk.border}`,
                  color: paused ? '#FFFFFF' : tk.fgDim,
                  fontSize: 12, fontWeight: 800, cursor: 'pointer',
                  display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 4,
                }}
              >
                <PI name={paused ? 'play' : 'pause'} size={12} /> {paused ? 'Verder' : 'Pauze'}
              </button>
              <button
                onClick={() => setElapsed(0)}
                style={{
                  padding: '10px 12px', borderRadius: 9,
                  background: 'transparent', border: `1px solid ${tk.border}`,
                  color: tk.fgDim, fontSize: 11, fontWeight: 700, cursor: 'pointer',
                }}
              ><PI name="rotate-ccw" size={12} /></button>
            </div>
          </div>

          {/* Daarna */}
          {store.tasksToday[1] && !store.tasksToday[1].done && (
            <div style={{
              background: tk.cardSunken, border: `1px solid ${tk.border}`,
              borderRadius: 10, padding: '10px 12px',
              opacity: 0.7,
            }}>
              <div style={{ fontSize: 9.5, fontWeight: 800, color: tk.fgMute, letterSpacing: 0.6, textTransform: 'uppercase', marginBottom: 4 }}>
                Daarna · {store.tasksToday[1].mins} min
              </div>
              <div style={{ fontSize: 12, fontWeight: 700, color: tk.fg, lineHeight: 1.35 }}>
                {store.tasksToday[1].title}
              </div>
            </div>
          )}

          {/* Pulse stil */}
          <div style={{
            marginTop: 'auto',
            background: hexToRgba(tk.purple, 0.08),
            border: `1px solid ${hexToRgba(tk.purple, 0.2)}`,
            borderRadius: 10, padding: '10px 12px',
            display: 'flex', alignItems: 'center', gap: 8,
          }}>
            <PulseMascot size={26} mood="idle" />
            <div>
              <div style={{ fontSize: 11, fontWeight: 700, color: tk.fg }}>Ik ben er als je me nodig hebt</div>
              <div style={{ fontSize: 10, color: tk.fgMute, fontWeight: 600 }}>Tik mij voor hulp · anders stil</div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

function TimerRing({ t, percent, remaining, total }) {
  const size = 160; const stroke = 8; const r = (size - stroke) / 2;
  const circ = 2 * Math.PI * r;
  const off = circ - (percent / 100) * circ;
  return (
    <div style={{ position: 'relative', width: size, height: size }}>
      <svg width={size} height={size}>
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={t.border} strokeWidth={stroke} />
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={t.primary} strokeWidth={stroke}
          strokeLinecap="round" strokeDasharray={circ} strokeDashoffset={off}
          transform={`rotate(-90 ${size/2} ${size/2})`}
          style={{ transition: 'stroke-dashoffset 0.5s linear' }}
        />
      </svg>
      <div style={{
        position: 'absolute', top: 0, left: 0, right: 0, bottom: 0,
        display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
      }}>
        <div style={{
          fontFamily: 'Fredoka One', fontSize: 28, color: t.fg,
          letterSpacing: '-0.01em',
        }}>{remaining}</div>
        <div style={{ fontSize: 10, fontWeight: 700, color: t.fgMute, marginTop: 2 }}>
          van {total} min
        </div>
      </div>
    </div>
  );
}

/* ═══════════════════════════════════════════════════════════════════
   SCREEN: HERPLAN — Free (drag) OR Premium (voorstel)
   ═══════════════════════════════════════════════════════════════════ */

function ScreenHerplan({ store }) {
  const tk = t(store.theme);
  if (store.plan === 'free') return <HerplanFree store={store} tk={tk} />;
  return <HerplanPremium store={store} tk={tk} />;
}

function HerplanFree({ store, tk }) {
  const { missedTasks } = store;
  // placements: { taskId, isoDate | null }
  const [placements, setPlacements] = useState(
    missedTasks.map(m => ({ taskId: m.id, isoDate: null }))
  );
  const [dragging, setDragging] = useState(null);
  const [weekOffset, setWeekOffset] = useState(0);

  const unassigned = placements.filter(p => p.isoDate === null);
  const allPlaced = unassigned.length === 0;

  return (
    <div style={{ background: tk.bgApp, minHeight: 'calc(100vh - 44px)', padding: '30px 24px' }}>
      <div style={{ maxWidth: 1280, margin: '0 auto' }}>
        {/* Header */}
        <div style={{ display: 'flex', alignItems: 'flex-start', gap: 12, marginBottom: 16 }}>
          <div style={{
            width: 44, height: 44, borderRadius: 10,
            background: hexToRgba(tk.red, 0.12),
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}>
            <PI name="rotate-ccw" size={20} color={tk.red} />
          </div>
          <div style={{ flex: 1 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
              <PlanBadge t={tk} plan="free" />
              <h2 style={{ fontFamily: 'Fredoka One', fontSize: 22, color: tk.fg, margin: 0 }}>Sleep zelf</h2>
            </div>
            <p style={{ fontSize: 13, color: tk.fgDim, margin: 0, fontWeight: 500 }}>
              Hier zijn de {missedTasks.length} taken die je miste. Sleep ze naar een dag die past — navigeer naar andere weken met ← →.
            </p>
          </div>
          <button onClick={() => store.navigate('/')} style={{
            padding: '6px 10px', borderRadius: 7,
            background: 'transparent', border: `1px solid ${tk.border}`,
            color: tk.fgDim, fontSize: 11, fontWeight: 700, cursor: 'pointer',
          }}>Annuleer</button>
        </div>

        {/* Missed tasks drag-source */}
        <div style={{
          padding: '12px 14px', borderRadius: 10,
          background: tk.card, border: `1.5px dashed ${hexToRgba(tk.red, 0.4)}`,
          marginBottom: 14,
        }}>
          <div style={{ fontSize: 10, fontWeight: 800, color: tk.red, letterSpacing: 0.5, textTransform: 'uppercase', marginBottom: 8 }}>
            Nog te plannen · {unassigned.length} taken
          </div>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, minHeight: 30 }}>
            {unassigned.length === 0 ? (
              <span style={{ fontSize: 12, color: tk.green, fontWeight: 700 }}>
                ✓ Alle taken geplaatst — bevestig onderaan
              </span>
            ) : (
              unassigned.map(p => {
                const task = missedTasks.find(m => m.id === p.taskId);
                return (
                  <DraggableTaskChip key={p.taskId} t={tk} task={task}
                    onDragStart={() => setDragging(p.taskId)} />
                );
              })
            )}
          </div>
        </div>

        {/* Week-kalender met drop-targets */}
        <WeekDropCalendar t={tk} weekOffset={weekOffset} setWeekOffset={setWeekOffset}
          placements={placements} setPlacements={setPlacements}
          missedTasks={missedTasks} dragging={dragging} setDragging={setDragging} />

        {/* Footer */}
        <div style={{ display: 'flex', gap: 8, marginTop: 16, alignItems: 'center' }}>
          <span style={{ fontSize: 11, color: tk.fgMute, fontWeight: 600 }}>
            Sleep een taak naar een dag · klik × op een blok om terug te zetten
          </span>
          <span style={{ flex: 1 }} />
          <button
            onClick={() => { store.setMissedTasks([]); store.navigate('/'); }}
            disabled={!allPlaced}
            style={{
              padding: '10px 18px', borderRadius: 9,
              background: tk.primary, color: '#FFFFFF', border: 0,
              fontSize: 13, fontWeight: 800, cursor: allPlaced ? 'pointer' : 'not-allowed',
              opacity: allPlaced ? 1 : 0.5,
            }}
          >
            {allPlaced ? '✓ Bevestig planning' : `Nog ${unassigned.length} te plaatsen`}
          </button>
        </div>
      </div>
    </div>
  );
}

function DraggableTaskChip({ t, task, onDragStart, isOnCalendar, onRemove }) {
  return (
    <div
      draggable
      onDragStart={onDragStart}
      style={{
        padding: '5px 8px 5px 6px', borderRadius: 7,
        background: hexToRgba(SUBJECTS[task.subject], 0.14),
        border: `1px solid ${hexToRgba(SUBJECTS[task.subject], 0.35)}`,
        display: 'inline-flex', alignItems: 'center', gap: 4,
        cursor: 'grab',
      }}>
      <PI name="grip-vertical" size={10} color={SUBJECTS[task.subject]} />
      <PI name={SUBJECT_ICON_NAME(task.subject)} size={11} color={SUBJECTS[task.subject]} />
      <span style={{ fontSize: 11, fontWeight: 800, color: SUBJECTS[task.subject] }}>
        {task.title}
      </span>
      <span style={{ fontSize: 9, fontWeight: 700, color: t.fgMute }}>{task.mins}m</span>
      {onRemove && (
        <button onClick={(e) => { e.stopPropagation(); onRemove(); }} style={{
          marginLeft: 1, border: 0, background: 'transparent',
          color: SUBJECTS[task.subject], cursor: 'pointer', fontSize: 12, padding: 0, lineHeight: 1,
        }}>×</button>
      )}
    </div>
  );
}

// Week-kalender drop-target — toont huidige week met bestaande taken + drop-zones per dag
function WeekDropCalendar({ t, weekOffset, setWeekOffset, placements, setPlacements, missedTasks, dragging, setDragging }) {
  // Generate week-days based on offset (0 = deze week)
  const today = new Date('2026-04-22');
  const weekStart = new Date(today);
  const dayOfWeek = (today.getDay() + 6) % 7; // monday = 0
  weekStart.setDate(today.getDate() - dayOfWeek + weekOffset * 7);
  const days = [];
  for (let i = 0; i < 7; i++) {
    const d = new Date(weekStart); d.setDate(weekStart.getDate() + i);
    const iso = d.toISOString().slice(0, 10);
    const key = ['ma', 'di', 'wo', 'do', 'vr', 'za', 'zo'][i];
    const label = ['MA', 'DI', 'WO', 'DO', 'VR', 'ZA', 'ZO'][i];
    const isWeekend = i >= 5;
    const isToday = iso === today.toISOString().slice(0, 10);
    days.push({ iso, key, label, date: d.getDate(), month: d.toLocaleDateString('nl-NL', { month: 'short' }), isToday, isWeekend });
  }

  const weekNumber = getWeekNumber(weekStart);

  return (
    <section style={{
      background: t.card, border: `1px solid ${t.border}`,
      borderRadius: 12, padding: 14,
    }}>
      {/* Week-header met nav */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 12 }}>
        <button onClick={() => setWeekOffset(weekOffset - 1)} style={{
          padding: '5px 10px', borderRadius: 7,
          background: 'transparent', border: `1px solid ${t.border}`,
          color: t.fgDim, fontSize: 11, fontWeight: 700, cursor: 'pointer',
          display: 'inline-flex', alignItems: 'center', gap: 4,
        }}>
          <PI name="chevron-left" size={12} /> wk {weekNumber - 1}
        </button>
        <div style={{ fontFamily: 'Fredoka One', fontSize: 16, color: t.fg }}>
          Week {weekNumber}
        </div>
        <span style={{ fontSize: 11, color: t.fgMute, fontWeight: 600 }}>
          {weekOffset === 0 ? '· deze week' : weekOffset === 1 ? '· volgende week' : weekOffset > 0 ? `· +${weekOffset} weken` : `· ${weekOffset} weken`}
        </span>
        <span style={{ flex: 1 }} />
        <button onClick={() => setWeekOffset(weekOffset + 1)} style={{
          padding: '5px 10px', borderRadius: 7,
          background: 'transparent', border: `1px solid ${t.border}`,
          color: t.fgDim, fontSize: 11, fontWeight: 700, cursor: 'pointer',
          display: 'inline-flex', alignItems: 'center', gap: 4,
        }}>
          wk {weekNumber + 1} <PI name="chevron-right" size={12} />
        </button>
      </div>

      {/* 7 day-cards as drop-targets */}
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 8 }}>
        {days.map(d => {
          const existingBlocks = weekOffset === 0 ? (WEEK_BLOCKS[d.iso] || []) : [];
          const droppedHere = placements.filter(p => p.isoDate === d.iso);
          const studyBlock = INITIAL_STUDY_BLOCKS[d.key];
          const isAvailable = studyBlock && studyBlock.available;

          return (
            <div key={d.iso}
              onDragOver={(e) => { if (isAvailable) e.preventDefault(); }}
              onDrop={() => {
                if (dragging === null || !isAvailable) return;
                setPlacements(placements.map(p =>
                  p.taskId === dragging ? { ...p, isoDate: d.iso } : p
                ));
                setDragging(null);
              }}
              style={{
                background: d.isToday ? hexToRgba(t.primary, 0.05) : d.isWeekend ? hexToRgba(t.fgFaint, 0.03) : t.cardSunken,
                border: d.isToday ? `2px solid ${t.primary}` : `1px solid ${t.border}`,
                borderRadius: 10, minHeight: 180,
                padding: '8px 8px 6px', display: 'flex', flexDirection: 'column', gap: 5,
                opacity: !isAvailable ? 0.5 : 1,
                position: 'relative',
                transition: 'background 0.15s',
              }}>
              {/* Header */}
              <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between' }}>
                <div style={{ fontSize: 9.5, fontWeight: 800, letterSpacing: 0.5, color: d.isToday ? t.primary : t.fgMute, textTransform: 'uppercase' }}>
                  {d.label}{d.isToday ? ' · NU' : ''}
                </div>
                <div style={{ fontFamily: 'Fredoka One', fontSize: 16, color: d.isToday ? t.primary : t.fg, lineHeight: 1 }}>
                  {d.date}
                </div>
              </div>

              {/* Study-venster(s) */}
              {isAvailable && studyBlock.ranges ? (
                <div style={{ fontSize: 9, color: t.fgMute, fontWeight: 700, lineHeight: 1.3 }}>
                  {studyBlock.ranges.map((r, ri) => (
                    <div key={ri}>{r.start}–{r.end}</div>
                  ))}
                </div>
              ) : (
                <div style={{ fontSize: 9, color: t.fgFaint, fontWeight: 600, fontStyle: 'italic' }}>
                  {d.isWeekend ? 'weekend' : 'niet beschikbaar'}
                </div>
              )}

              {/* Existing blocks (current week) */}
              {existingBlocks.map((b, i) => (
                <div key={`existing-${i}`} style={{
                  padding: '3px 6px', borderRadius: 4,
                  background: hexToRgba(SUBJECTS[b.subject], 0.08),
                  borderLeft: `2px solid ${SUBJECTS[b.subject]}`,
                  fontSize: 9.5, lineHeight: 1.3,
                  color: t.fg, fontWeight: 700,
                  opacity: b.done ? 0.4 : 0.75,
                  textDecoration: b.done ? 'line-through' : 'none',
                }}>
                  {b.title.length > 20 ? b.title.slice(0, 20) + '…' : b.title}
                </div>
              ))}

              {/* Dropped-here tasks met volgorde-knoppen */}
              {droppedHere.map((p, localIdx) => {
                const task = missedTasks.find(m => m.id === p.taskId);
                const sc = SUBJECTS[task.subject];
                return (
                  <div key={p.taskId}
                    draggable
                    onDragStart={() => setDragging(p.taskId)}
                    style={{
                      padding: '4px 5px', borderRadius: 5,
                      background: hexToRgba(sc, 0.18),
                      border: `1px dashed ${hexToRgba(sc, 0.5)}`,
                      fontSize: 9.5, fontWeight: 800,
                      color: sc,
                      display: 'flex', alignItems: 'center', gap: 2,
                      cursor: 'grab',
                    }}>
                    <PI name="plus" size={9} color={sc} />
                    <span style={{ flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                      {task.title} · {task.mins}m
                    </span>
                    {droppedHere.length > 1 && (
                      <>
                        <button
                          disabled={localIdx === 0}
                          onClick={(e) => {
                            e.stopPropagation();
                            reorderInDay(placements, setPlacements, p.taskId, -1, 'taskId', 'isoDate', d.iso);
                          }}
                          style={{
                            border: 0, background: 'transparent',
                            color: localIdx === 0 ? t.fgFaint : sc,
                            cursor: localIdx === 0 ? 'default' : 'pointer',
                            fontSize: 9, padding: 0, width: 14, height: 14,
                            display: 'flex', alignItems: 'center', justifyContent: 'center',
                          }} title="Omhoog">↑</button>
                        <button
                          disabled={localIdx === droppedHere.length - 1}
                          onClick={(e) => {
                            e.stopPropagation();
                            reorderInDay(placements, setPlacements, p.taskId, 1, 'taskId', 'isoDate', d.iso);
                          }}
                          style={{
                            border: 0, background: 'transparent',
                            color: localIdx === droppedHere.length - 1 ? t.fgFaint : sc,
                            cursor: localIdx === droppedHere.length - 1 ? 'default' : 'pointer',
                            fontSize: 9, padding: 0, width: 14, height: 14,
                            display: 'flex', alignItems: 'center', justifyContent: 'center',
                          }} title="Omlaag">↓</button>
                      </>
                    )}
                    <button onClick={(e) => {
                      e.stopPropagation();
                      setPlacements(placements.map(pp =>
                        pp.taskId === p.taskId ? { ...pp, isoDate: null } : pp
                      ));
                    }} style={{
                      border: 0, background: 'transparent',
                      color: sc, cursor: 'pointer', fontSize: 11,
                      padding: 0, lineHeight: 1, marginLeft: 2,
                    }}>×</button>
                  </div>
                );
              })}

              {/* Drop hint */}
              {dragging !== null && isAvailable && droppedHere.length === 0 && (
                <div style={{
                  marginTop: 'auto',
                  padding: '6px', borderRadius: 5,
                  border: `1.5px dashed ${hexToRgba(t.primary, 0.4)}`,
                  fontSize: 9, color: t.primary, fontWeight: 700, textAlign: 'center',
                  background: hexToRgba(t.primary, 0.06),
                }}>drop hier</div>
              )}
            </div>
          );
        })}
      </div>
    </section>
  );
}

// Herschik een item binnen een dag: vind items met zelfde dag-key, wissel met buur (direction = -1 = up, 1 = down)
function reorderInDay(placements, setPlacements, itemKey, direction, idKey, dayKey, dayValue) {
  // Find the item's position in the full placements array
  const globalIdx = placements.findIndex(p => p[idKey] === itemKey);
  if (globalIdx < 0) return;
  // Find items with same dayValue
  const sameDayIndices = placements
    .map((p, i) => ({ p, i }))
    .filter(x => x.p[dayKey] === dayValue)
    .map(x => x.i);
  const localIdx = sameDayIndices.indexOf(globalIdx);
  const targetLocalIdx = localIdx + direction;
  if (targetLocalIdx < 0 || targetLocalIdx >= sameDayIndices.length) return;
  const targetGlobalIdx = sameDayIndices[targetLocalIdx];
  // Swap in the full array
  const newArr = [...placements];
  [newArr[globalIdx], newArr[targetGlobalIdx]] = [newArr[targetGlobalIdx], newArr[globalIdx]];
  setPlacements(newArr);
}

function getWeekNumber(date) {
  const d = new Date(date);
  d.setHours(0, 0, 0, 0);
  d.setDate(d.getDate() + 3 - (d.getDay() + 6) % 7);
  const week1 = new Date(d.getFullYear(), 0, 4);
  return 1 + Math.round(((d - week1) / 86400000 - 3 + (week1.getDay() + 6) % 7) / 7);
}

function HerplanPremium({ store, tk }) {
  const { missedTasks, studyBlocks } = store;
  // Proposals: één per gemiste taak, met Pulse's voorgestelde dag + reden
  const defaultProposals = [
    missedTasks[0] && { task: missedTasks[0], to: '2026-04-21', reason: 'maandag is je eerste rustige middag' },
    missedTasks[1] && { task: missedTasks[1], to: '2026-04-22', reason: 'past tussen Wiskunde en eten — korter blok' },
  ].filter(Boolean);
  const [proposals, setProposals] = useState(defaultProposals);
  const [accepted, setAccepted] = useState({}); // { [taskId]: true }
  const [dragging, setDragging] = useState(null); // task-id
  const [weekOffset, setWeekOffset] = useState(0);

  function moveToDay(taskId, iso) {
    setProposals(proposals.map(p =>
      p.task.id === taskId ? { ...p, to: iso, tweaked: true } : p
    ));
  }
  function toggleAccept(taskId) {
    setAccepted({ ...accepted, [taskId]: !accepted[taskId] });
  }
  function acceptAll() {
    const next = {};
    proposals.forEach(p => next[p.task.id] = true);
    setAccepted(next);
  }

  // Week-setup
  const today = new Date('2026-04-22');
  const weekStart = new Date(today);
  const dayOfWeek = (today.getDay() + 6) % 7;
  weekStart.setDate(today.getDate() - dayOfWeek + weekOffset * 7);
  const days = [];
  for (let i = 0; i < 7; i++) {
    const d = new Date(weekStart); d.setDate(weekStart.getDate() + i);
    const iso = d.toISOString().slice(0, 10);
    const key = ['ma', 'di', 'wo', 'do', 'vr', 'za', 'zo'][i];
    const label = ['MA', 'DI', 'WO', 'DO', 'VR', 'ZA', 'ZO'][i];
    const isWeekend = i >= 5;
    const isToday = iso === '2026-04-22';
    const isPast = iso < '2026-04-22';
    days.push({ iso, key, label, date: d.getDate(), isToday, isWeekend, isPast });
  }

  const allAccepted = proposals.length > 0 && proposals.every(p => accepted[p.task.id]);

  return (
    <div style={{ background: tk.bgApp, minHeight: 'calc(100vh - 44px)', padding: '40px 20px' }}>
      <div style={{
        maxWidth: 1200, margin: '0 auto',
        background: tk.card,
        border: `1.5px solid ${hexToRgba(tk.purple, 0.32)}`,
        borderRadius: 16, padding: 0,
        boxShadow: `0 14px 36px ${hexToRgba(tk.purple, 0.18)}`,
        position: 'relative', overflow: 'hidden',
      }}>
        {/* Top gradient-accent */}
        <div style={{
          position: 'absolute', top: 0, left: 0, right: 0, height: 3,
          background: `linear-gradient(90deg, ${tk.purple}, ${tk.primary})`,
        }} />

        <div style={{ padding: '24px 28px' }}>
          {/* Header */}
          <div style={{ display: 'flex', alignItems: 'flex-start', gap: 12, marginBottom: 18 }}>
            <PulseMascot size={44} mood="thinking" />
            <div style={{ flex: 1 }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
                <PlanBadge t={tk} plan="premium" />
                <h2 style={{ fontFamily: 'Fredoka One', fontSize: 22, color: tk.fg, margin: 0 }}>
                  Week opnieuw gepland
                </h2>
              </div>
              <p style={{ fontSize: 13, color: tk.fgDim, margin: 0, fontWeight: 500 }}>
                Ik heb {proposals.length} {proposals.length === 1 ? 'taak' : 'taken'} ingepland. Sleep naar een andere dag als je wil, of accepteer direct.
                {' '}<b style={{ color: tk.fg }}>Je Bio-toets haal je nog.</b>
              </p>
            </div>
            <button onClick={() => store.navigate('/')} style={{
              padding: '6px 10px', borderRadius: 7,
              background: 'transparent', border: `1px solid ${tk.border}`,
              color: tk.fgDim, fontSize: 11, fontWeight: 700, cursor: 'pointer',
            }}>Annuleer</button>
          </div>

          {/* Week calendar */}
          <section style={{
            background: tk.cardSunken, border: `1px solid ${tk.border}`,
            borderRadius: 12, padding: 12, marginBottom: 16,
          }}>
            {/* Week-nav */}
            <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 10 }}>
              <button onClick={() => setWeekOffset(weekOffset - 1)} style={{
                padding: '5px 10px', borderRadius: 7,
                background: 'transparent', border: `1px solid ${tk.border}`,
                color: tk.fgDim, fontSize: 11, fontWeight: 700, cursor: 'pointer',
                display: 'inline-flex', alignItems: 'center', gap: 4,
              }}>
                <PI name="chevron-left" size={12} /> vorige
              </button>
              <div style={{ fontFamily: 'Fredoka One', fontSize: 16, color: tk.fg }}>
                {weekOffset === 0 ? 'Deze week' : weekOffset === 1 ? 'Volgende week' : `${weekOffset > 0 ? '+' : ''}${weekOffset} weken`}
              </div>
              <span style={{ fontSize: 11, color: tk.fgMute, fontWeight: 600 }}>
                · {days[0].date} – {days[6].date} {days[0].iso.slice(5, 7) === days[6].iso.slice(5, 7) ? '' : ''}
              </span>
              <span style={{ flex: 1 }} />
              <button onClick={() => setWeekOffset(weekOffset + 1)} style={{
                padding: '5px 10px', borderRadius: 7,
                background: 'transparent', border: `1px solid ${tk.border}`,
                color: tk.fgDim, fontSize: 11, fontWeight: 700, cursor: 'pointer',
                display: 'inline-flex', alignItems: 'center', gap: 4,
              }}>
                volgende <PI name="chevron-right" size={12} />
              </button>
            </div>

            {/* 7-day grid */}
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 6 }}>
              {days.map(d => {
                const existing = weekOffset === 0 ? (WEEK_BLOCKS[d.iso] || []) : [];
                const proposalsHere = proposals.filter(p => p.to === d.iso);
                const studyBlock = studyBlocks[d.key];
                const isAvailable = studyBlock && studyBlock.available && !d.isPast;
                const canDrop = isAvailable;
                return (
                  <div key={d.iso}
                    onDragOver={(e) => { if (canDrop) e.preventDefault(); }}
                    onDrop={() => { if (dragging && canDrop) { moveToDay(dragging, d.iso); setDragging(null); } }}
                    style={{
                      background: d.isToday ? hexToRgba(tk.primary, 0.05)
                        : d.isPast ? hexToRgba(tk.fgFaint, 0.03)
                        : d.isWeekend ? hexToRgba(tk.fgFaint, 0.03)
                        : tk.card,
                      border: d.isToday ? `2px solid ${tk.primary}` : `1px solid ${tk.border}`,
                      borderRadius: 8, minHeight: 190, padding: '8px 7px 6px',
                      display: 'flex', flexDirection: 'column', gap: 4,
                      opacity: d.isPast ? 0.35 : !isAvailable ? 0.55 : 1,
                    }}>
                    {/* Header */}
                    <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between' }}>
                      <div style={{
                        fontSize: 9.5, fontWeight: 800, letterSpacing: 0.5,
                        color: d.isToday ? tk.primary : tk.fgMute, textTransform: 'uppercase',
                      }}>{d.label}{d.isToday ? ' · NU' : ''}</div>
                      <div style={{
                        fontFamily: 'Fredoka One', fontSize: 16, lineHeight: 1,
                        color: d.isToday ? tk.primary : tk.fg,
                      }}>{d.date}</div>
                    </div>

                    {/* Studie-venster hint */}
                    {isAvailable && studyBlock.ranges ? (
                      <div style={{ fontSize: 9, color: tk.fgMute, fontWeight: 700, lineHeight: 1.3 }}>
                        {studyBlock.ranges.map((r, ri) => (
                          <div key={ri}>{r.start}–{r.end}</div>
                        ))}
                      </div>
                    ) : (
                      <div style={{ fontSize: 9, color: tk.fgFaint, fontWeight: 600, fontStyle: 'italic' }}>
                        {d.isPast ? 'verleden' : d.isWeekend ? 'weekend' : 'niet beschikbaar'}
                      </div>
                    )}

                    {/* Bestaande blokken (dimmed) */}
                    {existing.slice(0, 2).map((b, i) => (
                      <div key={`ex-${i}`} style={{
                        padding: '2px 5px', borderRadius: 3,
                        background: hexToRgba(SUBJECTS[b.subject], 0.08),
                        borderLeft: `2px solid ${SUBJECTS[b.subject]}`,
                        fontSize: 9, lineHeight: 1.3,
                        color: tk.fgDim, fontWeight: 700,
                        opacity: 0.55, fontStyle: 'italic',
                      }} title={b.title}>
                        {b.title.length > 13 ? b.title.slice(0, 13) + '…' : b.title}
                      </div>
                    ))}
                    {existing.length > 2 && (
                      <div style={{ fontSize: 8, color: tk.fgFaint, fontWeight: 600 }}>+{existing.length - 2} meer</div>
                    )}

                    {/* Pulse-voorstel blokken (draggable) */}
                    {proposalsHere.map(p => {
                      const sc = SUBJECTS[p.task.subject];
                      const isAccepted = accepted[p.task.id];
                      return (
                        <div key={p.task.id}
                          draggable
                          onDragStart={() => setDragging(p.task.id)}
                          onDragEnd={() => setDragging(null)}
                          style={{
                            padding: '5px 6px', borderRadius: 5,
                            background: isAccepted ? sc : hexToRgba(sc, 0.15),
                            border: isAccepted ? `1.5px solid ${sc}` : `1.5px dashed ${sc}`,
                            fontSize: 10, fontWeight: 800,
                            color: isAccepted ? '#FFFFFF' : sc,
                            display: 'flex', flexDirection: 'column', gap: 2,
                            cursor: 'grab', marginTop: 2,
                            boxShadow: p.tweaked ? `0 0 0 2px ${hexToRgba(tk.warn, 0.3)}` : 'none',
                          }}
                          title={p.reason}
                        >
                          <div style={{ display: 'flex', alignItems: 'center', gap: 3 }}>
                            {!isAccepted && <PI name="sparkles" size={9} color={sc} />}
                            {isAccepted && <PI name="check" size={9} color="#FFFFFF" />}
                            <span style={{ flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                              {(p.task.title || '').split(' ').slice(0, 3).join(' ')}
                            </span>
                            <button
                              onClick={(e) => { e.stopPropagation(); toggleAccept(p.task.id); }}
                              title={isAccepted ? 'Ongedaan maken' : 'Accepteren'}
                              style={{
                                border: 0, background: 'transparent',
                                color: isAccepted ? '#FFFFFF' : sc,
                                cursor: 'pointer', fontSize: 10, padding: 0, width: 12, height: 12,
                                display: 'flex', alignItems: 'center', justifyContent: 'center',
                              }}
                            >{isAccepted ? '↺' : '✓'}</button>
                          </div>
                          <div style={{ fontSize: 8, fontWeight: 700, opacity: 0.85 }}>
                            {p.task.mins}m
                          </div>
                          {p.tweaked && (
                            <div style={{
                              fontSize: 7.5, fontWeight: 800, color: tk.warn,
                              textTransform: 'uppercase', letterSpacing: 0.3,
                            }}>jij verplaatst</div>
                          )}
                        </div>
                      );
                    })}

                    {dragging && canDrop && (
                      <div style={{
                        marginTop: 'auto', padding: '5px', borderRadius: 4,
                        border: `1.5px dashed ${hexToRgba(tk.primary, 0.4)}`,
                        fontSize: 9, color: tk.primary, fontWeight: 700, textAlign: 'center',
                        background: hexToRgba(tk.primary, 0.06),
                      }}>drop</div>
                    )}
                  </div>
                );
              })}
            </div>

            {/* Legend */}
            <div style={{
              display: 'flex', gap: 14, marginTop: 10, paddingTop: 10,
              borderTop: `1px solid ${tk.border}`,
              fontSize: 10, color: tk.fgMute, fontWeight: 700,
            }}>
              <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}>
                <PI name="sparkles" size={10} color={tk.purple} /> Pulse-voorstel
              </span>
              <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}>
                <span style={{ width: 10, height: 10, borderRadius: 2, background: hexToRgba(tk.fgFaint, 0.5) }} /> Al ingepland
              </span>
              <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}>
                <PI name="check" size={10} color={tk.green} /> Geaccepteerd
              </span>
              <span style={{ flex: 1 }} />
              <span>Sleep om te verplaatsen · klik ✓ om te accepteren</span>
            </div>
          </section>

          {/* Redenen per voorstel (inline list) */}
          {proposals.length > 0 && (
            <section style={{ marginBottom: 16 }}>
              <div style={{ fontSize: 10, fontWeight: 800, color: tk.fgMute, letterSpacing: 0.5, textTransform: 'uppercase', marginBottom: 6 }}>
                Waarom deze dagen?
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                {proposals.map(p => {
                  const sc = SUBJECTS[p.task.subject];
                  const dayLabel = mockDayLabel(p.to);
                  return (
                    <div key={p.task.id} style={{
                      padding: '8px 10px', borderRadius: 7,
                      background: tk.cardSunken, border: `1px solid ${tk.border}`,
                      display: 'flex', alignItems: 'center', gap: 8,
                      fontSize: 11.5, color: tk.fgDim, fontWeight: 600,
                    }}>
                      <SubjectChip t={tk} subject={p.task.subject} size="sm" />
                      <span style={{ color: tk.fg, fontWeight: 700 }}>{p.task.title}</span>
                      <span>→ <b style={{ color: sc }}>{dayLabel.day.toLowerCase()} {dayLabel.date}</b></span>
                      <span style={{ flex: 1 }} />
                      <span style={{ fontStyle: 'italic', color: tk.purpleFg }}>{p.reason}</span>
                    </div>
                  );
                })}
              </div>
            </section>
          )}

          {/* Impact tiles */}
          <div style={{
            display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 8, marginBottom: 20,
          }}>
            <ImpactTile t={tk} label="Maandag" value="+1 taak" note="past nog" />
            <ImpactTile t={tk} label="Dinsdag" value="+1 taak" note="nog 30m vrij" />
            <ImpactTile t={tk} label="Bio-toets" value="op tijd" note="over 3 dagen" tone="green" />
          </div>

          {/* Actions */}
          <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
            <button
              onClick={acceptAll}
              disabled={allAccepted}
              style={{
                padding: '10px 14px', borderRadius: 9,
                background: allAccepted ? hexToRgba(tk.green, 0.14) : 'transparent',
                border: `1px solid ${allAccepted ? tk.green : tk.border}`,
                color: allAccepted ? tk.green : tk.fgDim,
                fontSize: 12, fontWeight: 800, cursor: allAccepted ? 'default' : 'pointer',
                display: 'inline-flex', alignItems: 'center', gap: 4,
              }}>
              <PI name="check-check" size={12} color={allAccepted ? tk.green : tk.fgMute} />
              {allAccepted ? `Alle ${proposals.length} geaccepteerd` : 'Accepteer alle voorstellen'}
            </button>
            <span style={{
              fontSize: 11, color: tk.fgMute, fontWeight: 600,
            }}>
              {Object.keys(accepted).filter(k => accepted[k]).length}/{proposals.length} geaccepteerd
            </span>
            <span style={{ flex: 1 }} />
            <button
              onClick={() => { store.setMissedTasks([]); store.navigate('/'); }}
              style={{
                padding: '10px 18px', borderRadius: 9,
                background: tk.purple, color: '#FFFFFF', border: 0,
                fontSize: 13, fontWeight: 800, cursor: 'pointer',
                display: 'inline-flex', alignItems: 'center', gap: 6,
              }}
            >
              <PI name="check" size={14} /> Bevestig planning
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}

function ImpactTile({ t, label, value, note, tone }) {
  const color = tone === 'green' ? t.green : t.fg;
  return (
    <div style={{
      padding: '10px 12px', borderRadius: 8,
      background: tone === 'green' ? hexToRgba(t.green, 0.08) : t.cardSunken,
      border: `1px solid ${tone === 'green' ? hexToRgba(t.green, 0.22) : t.border}`,
    }}>
      <div style={{ fontSize: 9.5, fontWeight: 800, color: t.fgMute, letterSpacing: 0.5, textTransform: 'uppercase', marginBottom: 4 }}>
        {label}
      </div>
      <div style={{ fontFamily: 'Fredoka One', fontSize: 18, color, lineHeight: 1 }}>{value}</div>
      <div style={{ fontSize: 10, color: t.fgMute, fontWeight: 600, marginTop: 2 }}>{note}</div>
    </div>
  );
}

/* ═══════════════════════════════════════════════════════════════════
   SCREEN: SETTINGS (simple + tijdvenster inline-edit)
   ═══════════════════════════════════════════════════════════════════ */

const SETTINGS_TABS = [
  { key: 'profiel', label: 'Profiel', icon: 'user' },
  { key: 'vakken', label: 'Mijn vakken & niveau', icon: 'book-open-text' },
  { key: 'plannen', label: 'Plannen', icon: 'calendar' },
  { key: 'notificaties', label: 'Notificaties', icon: 'bell' },
  { key: 'koppelingen', label: 'Koppelingen', icon: 'link' },
  { key: 'privacy', label: 'Privacy', icon: 'shield' },
  { key: 'abonnement', label: 'Abonnement', icon: 'sparkles' },
];

function ScreenSettings({ store }) {
  const tk = t(store.theme);
  const isEditingDay = store.route.path.startsWith('/settings/tijd/');
  const isEditingQuiet = store.route.path.startsWith('/settings/stilte/');
  const editDay = store.route.params.day;

  if (isEditingDay) return <TijdvensterEdit store={store} tk={tk} dayKey={editDay} />;
  if (isEditingQuiet) return <StiltetijdEdit store={store} tk={tk} dayKey={editDay} />;

  // Default tab = plannen (omdat we vanuit plannen komen)
  // Lees tab uit route-params of default
  const currentTab = store.route.params.tab || 'plannen';

  return (
    <div style={{ background: tk.bgApp, minHeight: 'calc(100vh - 44px)' }}>
      <div style={{
        display: 'flex', maxWidth: 1440, margin: '0 auto',
      }}>
        <Sidebar t={tk} active="plannen" />
        <div style={{ flex: 1, display: 'flex', flexDirection: 'column', minWidth: 0 }}>
          <Topbar t={tk} title="Instellingen" subtitle={
            currentTab === 'plannen' ? 'Pas Plannen aan op jouw week'
            : currentTab === 'vakken' ? 'Beheer de vakken die je volgt en je niveau'
            : currentTab === 'notificaties' ? 'Wanneer wil je reminders ontvangen?'
            : currentTab === 'koppelingen' ? 'Magister, Itslearning, Google Classroom'
            : currentTab === 'profiel' ? 'Naam, avatar, voorkeuren'
            : currentTab === 'privacy' ? 'Wat ziet wie?'
            : 'Huidig plan en Premium-features'
          } />

          {/* Tabs-navigatie */}
          <div style={{
            padding: '0 28px', borderBottom: `1px solid ${tk.border}`,
            display: 'flex', gap: 2, overflowX: 'auto',
            background: tk.bgApp,
          }}>
            {SETTINGS_TABS.map(tab => (
              <button
                key={tab.key}
                onClick={() => store.navigate('/settings', { tab: tab.key })}
                style={{
                  padding: '12px 16px', border: 0, background: 'transparent',
                  borderBottom: currentTab === tab.key ? `2px solid ${tk.primary}` : '2px solid transparent',
                  marginBottom: -1,
                  color: currentTab === tab.key ? tk.primary : tk.fgDim,
                  fontSize: 12, fontWeight: 800, cursor: 'pointer',
                  display: 'inline-flex', alignItems: 'center', gap: 6,
                  whiteSpace: 'nowrap',
                }}
              >
                <PI name={tab.icon} size={13} color={currentTab === tab.key ? tk.primary : tk.fgMute} />
                {tab.label}
              </button>
            ))}
          </div>

          {/* Tab content */}
          <div style={{ padding: '24px 28px 40px' }}>
            {currentTab === 'plannen' && <SettingsTabPlannen store={store} tk={tk} />}
            {currentTab === 'vakken' && <SettingsTabVakken store={store} tk={tk} />}
            {currentTab === 'notificaties' && <SettingsTabNotificaties store={store} tk={tk} />}
            {currentTab === 'koppelingen' && <SettingsTabKoppelingen store={store} tk={tk} />}
            {currentTab === 'profiel' && <SettingsTabPlaceholder tk={tk} title="Profiel" sub="Naam, avatar, account-instellingen — komt later" icon="user" />}
            {currentTab === 'privacy' && <SettingsTabPlaceholder tk={tk} title="Privacy" sub="Wat delen met ouders/docenten, data-export, account verwijderen — komt later" icon="shield" />}
            {currentTab === 'abonnement' && <SettingsTabAbonnement store={store} tk={tk} />}
          </div>
        </div>
      </div>
    </div>
  );
}

/* ─── Tab: Plannen (studie-tijd + focus-mode + plannen-specifieke notificaties) ─── */
function VacationsSection({ store, tk }) {
  const { schoolRegion, setSchoolRegion, vacations, setVacations } = store;
  const [editingId, setEditingId] = useState(null);
  const [adding, setAdding] = useState(false);
  const [draft, setDraft] = useState({ name: '', start: '', end: '' });

  function regionChange(region) {
    setSchoolRegion(region);
    setVacations(VACATIONS_BY_REGION[region]);
  }

  function updateVacation(id, patch) {
    setVacations(vacations.map(v => v.id === id ? { ...v, ...patch } : v));
  }
  function removeVacation(id) {
    setVacations(vacations.filter(v => v.id !== id));
  }
  function saveNew() {
    if (!draft.name || !draft.start || !draft.end) return;
    setVacations([...vacations, { ...draft, id: 'vc' + Date.now(), source: 'manual' }]);
    setDraft({ name: '', start: '', end: '' });
    setAdding(false);
  }

  const sorted = [...vacations].sort((a, b) => a.start.localeCompare(b.start));

  return (
    <section style={{
      background: tk.card, border: `1px solid ${tk.border}`,
      borderRadius: 14, padding: 20, gridColumn: '1 / -1',
    }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
        <PI name="sun" size={16} color={tk.warn} />
        <h3 style={{ margin: 0, fontSize: 15, fontWeight: 800, color: tk.fg }}>Vakanties / Vrije dagen</h3>
      </div>
      <p style={{ fontSize: 12, color: tk.fgDim, fontWeight: 500, margin: '0 0 14px' }}>
        Op vakantiedagen en vrije dagen plant Pulse geen nieuwe taken. Je kan dagen toevoegen of aanpassen — bijvoorbeeld als je school andere data heeft, een studiedag hebt, of een weekend weg bent.
      </p>

      {/* Regio-picker */}
      <div style={{
        display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap',
        padding: '10px 12px', borderRadius: 10,
        background: tk.cardSunken, border: `1px solid ${tk.border}`,
        marginBottom: 14,
      }}>
        <span style={{
          fontSize: 10, fontWeight: 800, color: tk.fgMute,
          letterSpacing: 0.5, textTransform: 'uppercase',
          display: 'inline-flex', alignItems: 'center', gap: 4,
        }}>
          <PI name="map-pin" size={11} color={tk.fgMute} />
          Jouw schoolregio:
        </span>
        {[
          { v: 'noord', label: 'Noord' },
          { v: 'midden', label: 'Midden' },
          { v: 'zuid', label: 'Zuid' },
        ].map(r => (
          <button
            key={r.v}
            onClick={() => regionChange(r.v)}
            style={{
              padding: '5px 12px', borderRadius: 6,
              background: schoolRegion === r.v ? hexToRgba(tk.primary, 0.14) : 'transparent',
              border: schoolRegion === r.v ? `1.5px solid ${tk.primary}` : `1px solid ${tk.border}`,
              color: schoolRegion === r.v ? tk.primary : tk.fgDim,
              fontSize: 11.5, fontWeight: 800, cursor: 'pointer',
            }}
          >{r.label}</button>
        ))}
        <span style={{ flex: 1 }} />
        <span style={{ fontSize: 11, color: tk.fgMute, fontWeight: 600 }}>
          bron: rijksoverheid.nl · handmatige aanpassingen blijven behouden
        </span>
      </div>

      {/* Vakantie-lijst */}
      <div style={{ display: 'flex', flexDirection: 'column', gap: 6, marginBottom: 10 }}>
        {sorted.map(v => {
          const isEditing = editingId === v.id;
          const days = Math.round((new Date(v.end) - new Date(v.start)) / 86400000) + 1;
          return (
            <div key={v.id} style={{
              padding: '10px 12px', borderRadius: 8,
              background: tk.cardSunken, border: `1px solid ${tk.border}`,
              display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap',
            }}>
              <div style={{
                width: 28, height: 28, borderRadius: 7,
                background: hexToRgba(tk.warn, 0.14),
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                flexShrink: 0,
              }}>
                <PI name="sun" size={13} color={tk.warn} />
              </div>
              {isEditing ? (
                <>
                  <input
                    type="text"
                    value={v.name}
                    onChange={(e) => updateVacation(v.id, { name: e.target.value })}
                    style={vacInputStyle(tk,180)}
                  />
                  <input
                    type="date"
                    value={v.start}
                    onChange={(e) => updateVacation(v.id, { start: e.target.value })}
                    style={vacInputStyle(tk,140)}
                  />
                  <span style={{ color: tk.fgMute, fontWeight: 700 }}>→</span>
                  <input
                    type="date"
                    value={v.end}
                    onChange={(e) => updateVacation(v.id, { end: e.target.value })}
                    style={vacInputStyle(tk,140)}
                  />
                  <span style={{ flex: 1 }} />
                  <button onClick={() => setEditingId(null)} style={{
                    padding: '6px 10px', borderRadius: 6,
                    background: tk.primary, color: '#FFFFFF', border: 0,
                    fontSize: 11, fontWeight: 800, cursor: 'pointer',
                  }}>✓ Klaar</button>
                </>
              ) : (
                <>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 13, fontWeight: 800, color: tk.fg }}>{v.name}</div>
                    <div style={{ fontSize: 11, color: tk.fgDim, fontWeight: 600, marginTop: 1 }}>
                      {formatNlDate(v.start)} t/m {formatNlDate(v.end)} · {days} {days === 1 ? 'dag' : 'dagen'}
                      {v.source === 'manual' && (
                        <span style={{
                          marginLeft: 8, fontSize: 9, fontWeight: 800,
                          color: tk.purple, padding: '1px 5px', borderRadius: 3,
                          background: hexToRgba(tk.purple, 0.14),
                          letterSpacing: 0.4, textTransform: 'uppercase',
                        }}>handmatig</span>
                      )}
                    </div>
                  </div>
                  <button
                    onClick={() => setEditingId(v.id)}
                    style={{
                      padding: '5px 10px', borderRadius: 6,
                      background: 'transparent', border: `1px solid ${tk.border}`,
                      color: tk.fgDim, fontSize: 11, fontWeight: 700, cursor: 'pointer',
                    }}
                  >Aanpassen</button>
                  <button
                    onClick={() => removeVacation(v.id)}
                    title="Verwijderen"
                    style={{
                      padding: '5px 8px', borderRadius: 6,
                      background: 'transparent', border: `1px solid ${tk.border}`,
                      color: tk.red, fontSize: 11, fontWeight: 700, cursor: 'pointer',
                    }}
                  >×</button>
                </>
              )}
            </div>
          );
        })}
      </div>

      {/* Nieuwe vakantie toevoegen */}
      {adding ? (
        <div style={{
          padding: '10px 12px', borderRadius: 8,
          background: hexToRgba(tk.primary, 0.06),
          border: `1.5px dashed ${hexToRgba(tk.primary, 0.3)}`,
          display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap',
        }}>
          <input
            type="text"
            placeholder="Bijv. weekend weg · studiedag · skivakantie"
            value={draft.name}
            onChange={(e) => setDraft({ ...draft, name: e.target.value })}
            style={vacInputStyle(tk,200)}
            autoFocus
          />
          <input
            type="date"
            value={draft.start}
            onChange={(e) => setDraft({ ...draft, start: e.target.value })}
            style={vacInputStyle(tk,140)}
          />
          <span style={{ color: tk.fgMute, fontWeight: 700 }}>→</span>
          <input
            type="date"
            value={draft.end}
            onChange={(e) => setDraft({ ...draft, end: e.target.value })}
            style={vacInputStyle(tk,140)}
          />
          <span style={{ flex: 1 }} />
          <button onClick={() => { setAdding(false); setDraft({ name: '', start: '', end: '' }); }} style={{
            padding: '6px 10px', borderRadius: 6,
            background: 'transparent', border: `1px solid ${tk.border}`,
            color: tk.fgDim, fontSize: 11, fontWeight: 700, cursor: 'pointer',
          }}>Annuleer</button>
          <button onClick={saveNew} style={{
            padding: '6px 10px', borderRadius: 6,
            background: tk.primary, color: '#FFFFFF', border: 0,
            fontSize: 11, fontWeight: 800, cursor: 'pointer',
          }}>✓ Toevoegen</button>
        </div>
      ) : (
        <button
          onClick={() => setAdding(true)}
          style={{
            padding: '9px 12px', borderRadius: 8,
            border: `1.5px dashed ${tk.border}`, background: 'transparent',
            color: tk.fgDim, fontSize: 12, fontWeight: 700, cursor: 'pointer',
            display: 'inline-flex', alignItems: 'center', gap: 5,
          }}
        >
          <PI name="plus" size={12} /> Vakantie / Vrije dag toevoegen (weekend weg, studiereis, studiedag…)
        </button>
      )}
    </section>
  );
}

function vacInputStyle(tk, width) {
  return {
    padding: '7px 10px', borderRadius: 6,
    border: `1px solid ${tk.border}`, background: tk.card,
    color: tk.fg, fontSize: 12, fontWeight: 600, fontFamily: 'inherit',
    outline: 'none', width: width || 'auto',
  };
}

function formatNlDate(iso) {
  if (!iso) return '';
  const d = new Date(iso);
  return d.toLocaleDateString('nl-NL', { day: 'numeric', month: 'short' });
}

function SettingsTabPlannen({ store, tk }) {
  const dayOrder = ['ma', 'di', 'wo', 'do', 'vr', 'za', 'zo'];
  const [typeHours, setTypeHours] = useState(() => {
    const init = {};
    Object.keys(DEADLINE_TYPES).forEach(k => { init[k] = DEADLINE_TYPES[k].defaultHours; });
    return init;
  });
  return (
    <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>
      {/* Studie-tijd per dag */}
      <section style={{
        background: tk.card, border: `1px solid ${tk.border}`,
        borderRadius: 14, padding: 20, gridColumn: '1 / -1',
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
          <PI name="clock" size={16} color={tk.primary} />
          <h3 style={{ margin: 0, fontSize: 15, fontWeight: 800, color: tk.fg }}>Studie-tijd per weekdag</h3>
        </div>
        <p style={{ fontSize: 12, color: tk.fgDim, fontWeight: 500, margin: '0 0 16px' }}>
          Wanneer kan je studeren? Pulse plant taken binnen deze vensters. Tik een dag om aan te passen.
        </p>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 6 }}>
          {dayOrder.map(key => {
            const block = store.studyBlocks[key];
            const isActive = block.available;
            return (
              <button
                key={key}
                onClick={() => store.navigate(`/settings/tijd/${key}`, { day: key })}
                style={{
                  padding: '10px 6px', borderRadius: 8,
                  background: isActive ? hexToRgba(tk.primary, 0.08) : tk.cardSunken,
                  border: isActive ? `1.5px solid ${hexToRgba(tk.primary, 0.3)}` : `1px solid ${tk.border}`,
                  cursor: 'pointer', textAlign: 'center',
                }}
              >
                <div style={{
                  fontSize: 10, fontWeight: 800, color: tk.fgMute,
                  letterSpacing: 0.5, textTransform: 'uppercase', marginBottom: 4,
                }}>{key}</div>
                {isActive && block.ranges && block.ranges.length > 0 ? (
                  <>
                    {block.ranges.map((r, ri) => (
                      <div key={ri} style={{
                        fontSize: 10.5, fontWeight: 800, color: tk.fg, lineHeight: 1.25,
                      }}>{r.start}–{r.end}</div>
                    ))}
                    <div style={{ fontSize: 9, color: tk.primary, fontWeight: 700, marginTop: 2 }}>
                      {calcDuration('00:00', minToTime(rangesTotalMinutes(block.ranges)))}
                    </div>
                  </>
                ) : (
                  <div style={{ fontSize: 10, color: tk.fgMute, fontStyle: 'italic', fontWeight: 600 }}>vrij</div>
                )}
              </button>
            );
          })}
        </div>
      </section>

      {/* Vakanties */}
      <VacationsSection store={store} tk={tk} />

      {/* Standaard studietijd per type */}
      <section style={{
        background: tk.card, border: `1px solid ${tk.border}`,
        borderRadius: 14, padding: 20, gridColumn: '1 / -1',
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
          <PI name="sliders" size={16} color={tk.primary} />
          <h3 style={{ margin: 0, fontSize: 15, fontWeight: 800, color: tk.fg }}>
            Standaard studietijd per type deadline
          </h3>
        </div>
        <p style={{ fontSize: 12, color: tk.fgDim, fontWeight: 500, margin: '0 0 16px' }}>
          Als je een deadline aanmaakt pakt Pulse deze waarde als voorstel. Je kan hem altijd per deadline aanpassen.
        </p>
        <div style={{
          display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(180px, 1fr))', gap: 10,
        }}>
          {Object.keys(DEADLINE_TYPES).map(key => {
            const meta = DEADLINE_TYPES[key];
            return (
              <div key={key} style={{
                padding: '12px', borderRadius: 8,
                background: tk.cardSunken, border: `1px solid ${tk.border}`,
                display: 'flex', flexDirection: 'column', gap: 8,
                minWidth: 0,
              }}>
                {/* Titel-rij */}
                <div style={{ display: 'flex', alignItems: 'center', gap: 8, minWidth: 0 }}>
                  <div style={{
                    width: 28, height: 28, borderRadius: 7,
                    background: hexToRgba(tk.primary, 0.10),
                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                    flexShrink: 0,
                  }}>
                    <PI name={meta.icon} size={13} color={tk.primary} />
                  </div>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{
                      fontSize: 12.5, fontWeight: 800, color: tk.fg,
                      overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
                    }}>{meta.label}</div>
                    <div style={{ fontSize: 10, color: tk.fgMute, fontWeight: 600 }}>
                      voorstel-duur
                    </div>
                  </div>
                </div>
                {/* Stepper-rij — full width onder de titel */}
                <div style={{
                  display: 'flex', alignItems: 'center', gap: 6,
                  background: tk.card, border: `1px solid ${tk.border}`, borderRadius: 7,
                  padding: 2,
                }}>
                  <button
                    onClick={() => setTypeHours({ ...typeHours, [key]: Math.max(0.25, +(typeHours[key] - 0.25).toFixed(2)) })}
                    style={{
                      width: 26, height: 26, padding: 0, flexShrink: 0,
                      background: 'transparent', border: 0,
                      color: tk.fgDim, fontSize: 15, fontWeight: 700, cursor: 'pointer',
                      display: 'flex', alignItems: 'center', justifyContent: 'center',
                    }}
                  >−</button>
                  <span style={{
                    flex: 1, textAlign: 'center',
                    fontSize: 13, fontWeight: 800, color: tk.fg,
                  }}>{formatHours(typeHours[key])}</span>
                  <button
                    onClick={() => setTypeHours({ ...typeHours, [key]: +(typeHours[key] + 0.25).toFixed(2) })}
                    style={{
                      width: 26, height: 26, padding: 0, flexShrink: 0,
                      background: 'transparent', border: 0,
                      color: tk.fgDim, fontSize: 15, fontWeight: 700, cursor: 'pointer',
                      display: 'flex', alignItems: 'center', justifyContent: 'center',
                    }}
                  >+</button>
                </div>
              </div>
            );
          })}
        </div>
      </section>

      {/* Focus-mode */}
      <section style={{
        background: tk.card, border: `1px solid ${tk.border}`,
        borderRadius: 14, padding: 20,
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
          <PI name="headphones" size={16} color={tk.primary} />
          <h3 style={{ margin: 0, fontSize: 15, fontWeight: 800, color: tk.fg }}>Focus-mode</h3>
        </div>
        <p style={{ fontSize: 12, color: tk.fgDim, fontWeight: 500, margin: '0 0 16px' }}>
          Standaard-instellingen voor focus-sessies.
        </p>
        <div style={{ marginBottom: 10 }}>
          <Field label="Default timer-duur" tk={tk}>
            <div style={{ display: 'flex', gap: 6 }}>
              {[0, 25, 50].map(n => (
                <button key={n} style={{
                  flex: 1, padding: '10px', borderRadius: 8,
                  background: n === 25 ? hexToRgba(tk.primary, 0.10) : tk.cardSunken,
                  border: n === 25 ? `1.5px solid ${tk.primary}` : `1px solid ${tk.border}`,
                  color: n === 25 ? tk.primary : tk.fgDim,
                  fontSize: 12, fontWeight: 800, cursor: 'pointer',
                }}>{n === 0 ? 'Geen' : `${n}m`}</button>
              ))}
            </div>
          </Field>
        </div>
        <SettingToggle t={tk} label="Auto-start bij focus" sub="Timer begint direct als je 'Focus' klikt" on={true} />
        <SettingToggle t={tk} label="Pauze na 45 min" sub="Pulse voegt automatisch een 10-min pauze in" on={true} />
      </section>

      {/* Plannen-specifieke reminders */}
      <section style={{
        background: tk.card, border: `1px solid ${tk.border}`,
        borderRadius: 14, padding: 20,
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 16 }}>
          <PI name="bell" size={16} color={tk.primary} />
          <h3 style={{ margin: 0, fontSize: 15, fontWeight: 800, color: tk.fg }}>Plannen-reminders</h3>
        </div>
        <SettingToggle t={tk} label="Dag-voor-deadline" sub="Herinnering de avond voor een toets" on={true} />
        <SettingToggle t={tk} label="Gemiste taak" sub="Als je een gepland studie-moment niet hebt gedaan" on={true} />
        <SettingToggle t={tk} label="Studie-start" sub="15 min voor een gepland studie-moment begint" on={false} />
        <div style={{ marginTop: 8, fontSize: 10.5, color: tk.fgMute, fontWeight: 500 }}>
          Globale reminders (ochtend, avond, stille momenten) vind je in de tab <b>Notificaties</b>.
        </div>
      </section>

      {/* Slimme herinneringen — Premium-gated */}
      <section style={{
        background: tk.card, border: `1px solid ${tk.border}`,
        borderRadius: 14, padding: 20, position: 'relative',
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
          <PI name="sparkles" size={16} color={tk.purple} />
          <h3 style={{ margin: 0, fontSize: 15, fontWeight: 800, color: tk.fg }}>Slimme herinneringen</h3>
          <span style={{
            fontSize: 9, fontWeight: 800, color: tk.purple,
            padding: '2px 7px', borderRadius: 4,
            background: hexToRgba(tk.purple, 0.14),
            letterSpacing: 0.4, textTransform: 'uppercase',
          }}>Premium</span>
        </div>
        <p style={{ fontSize: 12, color: tk.fgDim, fontWeight: 500, margin: '0 0 14px' }}>
          Pulse let op patronen en stuurt bij als het nodig is.
        </p>

        {/* Settings met premium-lock overlay als free */}
        <div style={{ position: 'relative' }}>
          <div style={{ opacity: store.plan === 'free' ? 0.45 : 1, pointerEvents: store.plan === 'free' ? 'none' : 'auto' }}>
            <SettingToggle t={tk} label="Herplan-suggestie" sub="Als Pulse een betere verdeling ziet" on={false} />
            <SettingToggle t={tk} label="Pulse observeert" sub="Signaal bij 3+ avonden laat werken — Pulse biedt dan rust aan" on={true} />
            <SettingToggle t={tk} label="Achterstand-seintje" sub="Als je onder schema komt" on={true} />
            <SettingToggle t={tk} label="Comeback-coach" sub="Als je paar dagen niet geopend hebt" on={true} />
          </div>
          {store.plan === 'free' && (
            <div style={{
              position: 'absolute', top: 0, left: 0, right: 0, bottom: 0,
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              background: `linear-gradient(180deg, transparent, ${hexToRgba(tk.purple, 0.1)})`,
              borderRadius: 10,
            }}>
              <button style={{
                padding: '8px 14px', borderRadius: 8,
                background: tk.purple, color: '#FFFFFF', border: 0,
                fontSize: 12, fontWeight: 800, cursor: 'pointer',
                boxShadow: `0 4px 16px ${hexToRgba(tk.purple, 0.3)}`,
              }}>Upgrade naar Premium →</button>
            </div>
          )}
        </div>
      </section>

      {/* Pulse-toon */}
      <section style={{
        background: tk.card, border: `1px solid ${tk.border}`,
        borderRadius: 14, padding: 20, gridColumn: '1 / -1',
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
          <PulseMascot size={22} mood="idle" />
          <h3 style={{ margin: 0, fontSize: 15, fontWeight: 800, color: tk.fg }}>Pulse-toon</h3>
        </div>
        <p style={{ fontSize: 12, color: tk.fgDim, fontWeight: 500, margin: '0 0 14px' }}>
          Hoe wil je dat Pulse's tekst-meldingen en tips aanvoelen?
        </p>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 10 }}>
          <PulseStemOption tk={tk} selected={true}
            title="Rustig" sub="Feitelijk · kort · zonder druk"
            example="Drie taken vandaag. Eerste: Bio H4 om 15:30." />
          <PulseStemOption tk={tk}
            title="Warm" sub="Iets menselijker · persoonlijk"
            example="Goedemiddag Sanne. Rustige dag — Bio is het eerste." />
          <PulseStemOption tk={tk}
            title="Minimaal" sub="Alleen als het echt nodig is"
            example="Bio H4 — 15:30" />
        </div>
      </section>
    </div>
  );
}

function PulseStemOption({ tk, selected, title, sub, example }) {
  return (
    <div style={{
      padding: 14, borderRadius: 10,
      background: selected ? hexToRgba(tk.primary, 0.08) : tk.cardSunken,
      border: selected ? `1.5px solid ${tk.primary}` : `1px solid ${tk.border}`,
      cursor: 'pointer',
    }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 2 }}>
        <div style={{
          width: 16, height: 16, borderRadius: 8,
          border: `2px solid ${selected ? tk.primary : tk.border}`,
          background: selected ? tk.primary : 'transparent',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          flexShrink: 0,
        }}>
          {selected && <div style={{ width: 6, height: 6, borderRadius: 3, background: '#FFFFFF' }} />}
        </div>
        <span style={{ fontSize: 13, fontWeight: 800, color: tk.fg }}>{title}</span>
      </div>
      <div style={{ fontSize: 11, color: tk.fgMute, fontWeight: 600, marginBottom: 8 }}>{sub}</div>
      <div style={{
        padding: '8px 10px', borderRadius: 7,
        background: tk.card, border: `1px solid ${tk.border}`,
        fontSize: 11, color: tk.fgDim, fontStyle: 'italic', fontWeight: 500, lineHeight: 1.45,
      }}>
        "{example}"
      </div>
    </div>
  );
}

/* ─── Tab: Mijn vakken & niveau ─── */
function SettingsTabVakken({ store, tk }) {
  const [vakken, setVakken] = useState([
    { key: 'biologie', niveau: 'HAVO 4', paused: false },
    { key: 'wiskunde', niveau: 'HAVO 4 A', paused: false },
    { key: 'scheikunde', niveau: 'HAVO 4', paused: false },
    { key: 'engels', niveau: 'HAVO 4', paused: false },
    { key: 'nederlands', niveau: 'HAVO 4', paused: false },
    { key: 'geschiedenis', niveau: 'HAVO 4', paused: false },
    { key: 'frans', niveau: 'HAVO 4', paused: false },
    { key: 'aardrijkskunde', niveau: 'HAVO 4', paused: true },
  ]);

  function togglePause(i) {
    setVakken(vakken.map((v, idx) => idx === i ? { ...v, paused: !v.paused } : v));
  }

  const activeCount = vakken.filter(v => !v.paused).length;

  return (
    <div style={{ maxWidth: 820 }}>
      {/* Niveau + Leerjaar gesplitst */}
      <section style={{
        background: tk.card, border: `1px solid ${tk.border}`,
        borderRadius: 14, padding: 20, marginBottom: 16,
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
          <PI name="graduation-cap" size={16} color={tk.primary} />
          <h3 style={{ margin: 0, fontSize: 15, fontWeight: 800, color: tk.fg }}>School-niveau &amp; leerjaar</h3>
        </div>
        <p style={{ fontSize: 12, color: tk.fgDim, fontWeight: 500, margin: '0 0 14px' }}>
          Bepaalt welke termen (SO / toets / proefwerk) en welke stof je ziet.
        </p>

        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
          {/* Niveau */}
          <Field label="Niveau" tk={tk}>
            <div style={{ display: 'flex', gap: 6 }}>
              {['VMBO', 'HAVO', 'VWO', 'Gymnasium'].map(n => (
                <button key={n} style={{
                  flex: 1, padding: '8px', borderRadius: 7,
                  background: n === 'HAVO' ? hexToRgba(tk.primary, 0.12) : tk.cardSunken,
                  border: n === 'HAVO' ? `1.5px solid ${tk.primary}` : `1px solid ${tk.border}`,
                  color: n === 'HAVO' ? tk.primary : tk.fgDim,
                  fontSize: 12, fontWeight: 800, cursor: 'pointer',
                }}>{n}</button>
              ))}
            </div>
          </Field>

          {/* Leerjaar */}
          <Field label="Leerjaar" tk={tk}>
            <div style={{ display: 'flex', gap: 4 }}>
              {[1, 2, 3, 4, 5, 6].map(j => (
                <button key={j} style={{
                  flex: 1, padding: '8px', borderRadius: 7,
                  background: j === 4 ? hexToRgba(tk.primary, 0.12) : tk.cardSunken,
                  border: j === 4 ? `1.5px solid ${tk.primary}` : `1px solid ${tk.border}`,
                  color: j === 4 ? tk.primary : tk.fgDim,
                  fontSize: 12, fontWeight: 800, cursor: 'pointer',
                }}>{j}</button>
              ))}
            </div>
            <div style={{ fontSize: 10.5, color: tk.fgMute, fontWeight: 600, marginTop: 6 }}>
              HAVO heeft 5 leerjaren · VWO 6 · VMBO 4
            </div>
          </Field>
        </div>
      </section>

      {/* Vakken-lijst */}
      <section style={{
        background: tk.card, border: `1px solid ${tk.border}`,
        borderRadius: 14, padding: 20,
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
          <PI name="book-open-text" size={16} color={tk.primary} />
          <h3 style={{ margin: 0, fontSize: 15, fontWeight: 800, color: tk.fg }}>Mijn vakken</h3>
          <span style={{ flex: 1 }} />
          <span style={{ fontSize: 11, color: tk.fgMute, fontWeight: 700 }}>
            {activeCount} actief · {vakken.length - activeCount} gepauzeerd
          </span>
        </div>
        <p style={{ fontSize: 12, color: tk.fgDim, fontWeight: 500, margin: '0 0 14px', lineHeight: 1.55 }}>
          Vakken die je dit schooljaar volgt. <b style={{ color: tk.fg }}>Pauzeer</b> een vak als je het een periode niet hebt (bv. blok-systeem waarbij je het ene blok wel en het andere niet een vak volgt). Gepauzeerde vakken:
          {' '}
          <span style={{ color: tk.fgMute }}>
            geen taken plannen · niet in je standaard filters bij Quizzen &amp; Leren · kan je zichtbaar maken via "alle vakken".
          </span>
        </p>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
          {vakken.map((v, i) => (
            <div key={v.key} style={{
              padding: '10px 12px', borderRadius: 10,
              background: v.paused ? tk.cardSunken : 'transparent',
              border: `1px solid ${tk.border}`,
              display: 'flex', alignItems: 'center', gap: 10,
              opacity: v.paused ? 0.6 : 1,
            }}>
              <SubjectChip t={tk} subject={v.key} size="sm" />
              <span style={{ fontSize: 12, color: tk.fgMute, fontWeight: 700 }}>· {v.niveau}</span>
              <span style={{ flex: 1 }} />
              {v.paused && (
                <span style={{
                  fontSize: 10, fontWeight: 800, color: tk.fgMute,
                  padding: '2px 8px', borderRadius: 4,
                  background: tk.cardSunken, border: `1px solid ${tk.border}`,
                  letterSpacing: 0.4, textTransform: 'uppercase',
                }}>Gepauzeerd</span>
              )}
              <button style={{
                padding: '4px 10px', borderRadius: 6,
                background: 'transparent', border: `1px solid ${tk.border}`,
                color: tk.fgDim, fontSize: 11, fontWeight: 700, cursor: 'pointer',
              }}>Niveau wijzigen</button>
              <button onClick={() => togglePause(i)} style={{
                padding: '4px 10px', borderRadius: 6,
                background: v.paused ? hexToRgba(tk.primary, 0.1) : 'transparent',
                border: `1px solid ${v.paused ? tk.primary : tk.border}`,
                color: v.paused ? tk.primary : tk.fgDim,
                fontSize: 11, fontWeight: 700, cursor: 'pointer',
              }}>{v.paused ? 'Hervatten' : 'Pauzeren'}</button>
            </div>
          ))}
        </div>
        <button style={{
          marginTop: 10, width: '100%', padding: '10px', borderRadius: 10,
          background: 'transparent', border: `1.5px dashed ${tk.border}`,
          color: tk.fgDim, fontSize: 12, fontWeight: 700, cursor: 'pointer',
          display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 6,
        }}>
          <PI name="plus" size={14} /> Vak toevoegen
        </button>
      </section>
    </div>
  );
}

/* ─── Tab: Notificaties (globaal) ─── */
function SettingsTabNotificaties({ store, tk }) {
  return (
    <div style={{ maxWidth: 820, display: 'flex', flexDirection: 'column', gap: 16 }}>
      <section style={{
        background: tk.card, border: `1px solid ${tk.border}`,
        borderRadius: 14, padding: 20,
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 16 }}>
          <PI name="sun" size={16} color={tk.primary} />
          <h3 style={{ margin: 0, fontSize: 15, fontWeight: 800, color: tk.fg }}>Dagelijkse reminders</h3>
        </div>
        <SettingToggle t={tk} label="Ochtend-reminder" sub="Korte blik op wat er vandaag staat · 07:45" on={true} />
        <SettingToggle t={tk} label="Middag-check" sub="Tussenstand van je taken · 13:00" on={false} />
        <SettingToggle t={tk} label="Avond-wrap-up" sub="Hoe ging je dag · 21:00" on={false} />
      </section>

      {/* Stiltetijden — 7-dag picker (zelfde UX als studietijd, paarse accent) */}
      <section style={{
        background: tk.card, border: `1px solid ${tk.border}`,
        borderRadius: 14, padding: 20,
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
          <PI name="moon" size={16} color={tk.purple} />
          <h3 style={{ margin: 0, fontSize: 15, fontWeight: 800, color: tk.fg }}>Stiltetijden</h3>
        </div>
        <p style={{ fontSize: 12, color: tk.fgDim, fontWeight: 500, margin: '0 0 16px' }}>
          Geen meldingen in deze periodes. Tik op een dag om één of meer tijdsslots in te stellen — typisch schooluren en bedtijd.
        </p>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 6 }}>
          {['ma', 'di', 'wo', 'do', 'vr', 'za', 'zo'].map(key => {
            const block = store.quietBlocks[key];
            const ranges = block?.ranges || [];
            return (
              <button
                key={key}
                onClick={() => store.navigate(`/settings/stilte/${key}`, { day: key })}
                style={{
                  padding: '10px 6px', borderRadius: 8,
                  background: ranges.length ? hexToRgba(tk.purple, 0.06) : tk.cardSunken,
                  border: ranges.length ? `1.5px solid ${hexToRgba(tk.purple, 0.30)}` : `1px solid ${tk.border}`,
                  cursor: 'pointer', textAlign: 'center',
                }}
              >
                <div style={{
                  fontSize: 10, fontWeight: 800, color: tk.fgMute,
                  letterSpacing: 0.5, textTransform: 'uppercase', marginBottom: 4,
                }}>{key}</div>
                {ranges.length > 0 ? (
                  ranges.map((r, ri) => (
                    <div key={ri} style={{
                      fontSize: 10, fontWeight: 700, color: tk.fg, lineHeight: 1.3,
                    }}>
                      <div>{r.start}–{r.end}</div>
                      {r.label && (
                        <div style={{ fontSize: 8.5, color: tk.purple, fontWeight: 800, letterSpacing: 0.3, textTransform: 'uppercase' }}>
                          {r.label}
                        </div>
                      )}
                    </div>
                  ))
                ) : (
                  <div style={{ fontSize: 10, color: tk.fgMute, fontStyle: 'italic', fontWeight: 600 }}>altijd aan</div>
                )}
              </button>
            );
          })}
        </div>
        <div style={{
          marginTop: 12, padding: '8px 10px', borderRadius: 7,
          background: hexToRgba(tk.purple, 0.06),
          border: `1px dashed ${hexToRgba(tk.purple, 0.22)}`,
          fontSize: 11, color: tk.fgDim, fontWeight: 600, lineHeight: 1.5,
          display: 'flex', alignItems: 'center', gap: 6,
        }}>
          <PI name="info" size={11} color={tk.purple} />
          <span>
            Stiltetijden gelden voor <b style={{ color: tk.fg }}>alle notificaties</b> — ook kritieke reminders worden uitgesteld tot de stilte voorbij is.
          </span>
        </div>
      </section>

      <section style={{
        background: tk.card, border: `1px solid ${tk.border}`,
        borderRadius: 14, padding: 20,
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 16 }}>
          <PI name="bell-ring" size={16} color={tk.primary} />
          <h3 style={{ margin: 0, fontSize: 15, fontWeight: 800, color: tk.fg }}>Wat wil je NIET missen</h3>
        </div>
        <SettingToggle t={tk} label="Nieuwe trofee" sub="Als je iets nieuws hebt ontgrendeld" on={true} />
        <SettingToggle t={tk} label="Streak in gevaar" sub="21:00 als je nog niks hebt gedaan" on={false} />
        <SettingToggle t={tk} label="Pulse check-in" sub="Als je een paar dagen niet bent gekomen" on={true} />
      </section>
    </div>
  );
}

/* ─── Tab: Abonnement ─── */
function SettingsTabAbonnement({ store, tk }) {
  return (
    <div style={{ maxWidth: 820 }}>
      <section style={{
        background: store.plan === 'premium'
          ? `linear-gradient(135deg, ${hexToRgba(tk.purple, 0.12)}, ${hexToRgba(tk.primary, 0.08)})`
          : tk.card,
        border: `1.5px solid ${store.plan === 'premium' ? hexToRgba(tk.purple, 0.3) : tk.border}`,
        borderRadius: 14, padding: 24,
      }}>
        <div style={{
          fontSize: 11, fontWeight: 800, color: store.plan === 'premium' ? tk.purple : tk.fgMute,
          letterSpacing: 0.5, textTransform: 'uppercase', marginBottom: 4,
        }}>
          Jouw plan
        </div>
        <div style={{ fontFamily: 'Fredoka One', fontSize: 32, color: tk.fg, lineHeight: 1 }}>
          {store.plan === 'premium' ? 'Premium' : 'Free'}
        </div>
        <div style={{ fontSize: 13, color: tk.fgDim, fontWeight: 500, marginTop: 10, lineHeight: 1.6 }}>
          {store.plan === 'premium'
            ? 'Je hebt toegang tot Pulse AI-planning, Herplannen Coach, en het volledige Weekoverzicht.'
            : 'Upgrade voor Pulse AI-planning, Herplannen Coach met rationale, en navigeerbaar weekoverzicht.'}
        </div>
        {store.plan === 'free' ? (
          <button style={{
            marginTop: 16, padding: '11px 20px', borderRadius: 9,
            background: tk.purple, color: '#FFFFFF', border: 0,
            fontSize: 13, fontWeight: 800, cursor: 'pointer',
          }}>Upgrade naar Premium →</button>
        ) : (
          <button style={{
            marginTop: 16, padding: '10px 18px', borderRadius: 9,
            background: 'transparent', border: `1px solid ${tk.border}`,
            color: tk.fgDim, fontSize: 12, fontWeight: 700, cursor: 'pointer',
          }}>Abonnement beheren</button>
        )}
      </section>
    </div>
  );
}

/* ─── Tab: Koppelingen (Magister, Itslearning, Google Classroom) ─── */
function SettingsTabKoppelingen({ store, tk }) {
  const [magisterConnected, setMagisterConnected] = useState(true);
  const [magisterAutoImport, setMagisterAutoImport] = useState(true);
  const [magisterAutoPlan, setMagisterAutoPlan] = useState(false);

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 24, maxWidth: 760 }}>
      {/* Intro */}
      <section style={{
        padding: '14px 16px', borderRadius: 10,
        background: hexToRgba(tk.purple, 0.06),
        border: `1px solid ${hexToRgba(tk.purple, 0.2)}`,
        display: 'flex', alignItems: 'center', gap: 10,
      }}>
        <PulseMascot size={28} mood="thinking" />
        <div style={{ fontSize: 12.5, color: tk.fg, fontWeight: 600, lineHeight: 1.5 }}>
          Koppel je schoolsysteem zodat huiswerk + toetsen automatisch in je <b>Te plannen</b> bak komen — geen handmatig overtypen meer.
        </div>
      </section>

      {/* Magister */}
      <section style={{
        background: tk.card, border: `1px solid ${tk.border}`,
        borderRadius: 14, padding: '18px 20px',
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 14 }}>
          <div style={{
            width: 44, height: 44, borderRadius: 10,
            background: '#1E40AF', // Magister-blauw
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            color: '#FFFFFF', fontFamily: 'Fredoka One', fontSize: 20,
          }}>M</div>
          <div style={{ flex: 1 }}>
            <h3 style={{ fontFamily: 'Fredoka One', fontSize: 18, color: tk.fg, margin: 0 }}>Magister</h3>
            <div style={{ fontSize: 12, color: tk.fgDim, fontWeight: 600, marginTop: 2 }}>
              Importeer huiswerk, toetsen en cijfers
            </div>
          </div>
          {magisterConnected ? (
            <span style={{
              display: 'inline-flex', alignItems: 'center', gap: 5,
              padding: '4px 10px', borderRadius: 999,
              background: hexToRgba(tk.green, 0.14),
              border: `1px solid ${hexToRgba(tk.green, 0.3)}`,
              color: tk.green, fontSize: 10.5, fontWeight: 800,
              letterSpacing: 0.5, textTransform: 'uppercase',
            }}>
              <PI name="check-circle" size={11} color={tk.green} />
              Verbonden
            </span>
          ) : (
            <button
              onClick={() => setMagisterConnected(true)}
              style={{
                padding: '8px 14px', borderRadius: 8,
                background: tk.primary, color: '#FFFFFF', border: 0,
                fontSize: 12, fontWeight: 800, cursor: 'pointer',
              }}
            >Verbinden</button>
          )}
        </div>

        {magisterConnected && (
          <>
            <div style={{
              padding: '10px 12px', borderRadius: 8,
              background: tk.cardSunken, border: `1px solid ${tk.border}`,
              fontSize: 11.5, color: tk.fgDim, fontWeight: 600,
              marginBottom: 14, display: 'flex', alignItems: 'center', gap: 8,
            }}>
              <PI name="user" size={12} color={tk.fgMute} />
              Verbonden als <b style={{ color: tk.fg }}>Sanne de Vries</b> · 4 HAVO · School: <b style={{ color: tk.fg }}>OSG West-Friesland</b>
              <span style={{ flex: 1 }} />
              <span style={{ fontSize: 10.5, color: tk.fgMute }}>Laatste sync: 2 min geleden</span>
            </div>

            {/* Toggles */}
            <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
              <ToggleRow
                tk={tk}
                title="Auto-import huiswerk"
                desc="Nieuwe items uit Magister komen automatisch in 'Te plannen'"
                value={magisterAutoImport}
                onChange={setMagisterAutoImport}
              />
              <ToggleRow
                tk={tk}
                title="Auto-plan met Pulse"
                desc="Nieuwe Magister-items meteen door Pulse laten inplannen (Premium)"
                value={magisterAutoPlan}
                onChange={setMagisterAutoPlan}
                premium
              />
            </div>

            <div style={{
              marginTop: 14, padding: '10px 12px', borderRadius: 8,
              background: hexToRgba(tk.warn, 0.08),
              border: `1px solid ${hexToRgba(tk.warn, 0.22)}`,
              fontSize: 11.5, color: tk.fgDim, fontWeight: 600, lineHeight: 1.5,
            }}>
              <PI name="info" size={12} color={tk.warn} style={{ marginRight: 5, verticalAlign: 'middle' }} />
              Tip: probeer het scenario <b style={{ color: tk.fg }}>Magister-import (12 ongepland)</b> bovenaan om te zien hoe een eerste-keer-import er uitziet.
            </div>

            <div style={{ marginTop: 14, display: 'flex', gap: 8 }}>
              <button style={{
                padding: '7px 12px', borderRadius: 7,
                background: 'transparent', border: `1px solid ${tk.border}`,
                color: tk.fgDim, fontSize: 11.5, fontWeight: 700, cursor: 'pointer',
                display: 'inline-flex', alignItems: 'center', gap: 5,
              }}>
                <PI name="refresh-cw" size={11} /> Nu syncen
              </button>
              <button
                onClick={() => setMagisterConnected(false)}
                style={{
                  padding: '7px 12px', borderRadius: 7,
                  background: 'transparent', border: `1px solid ${tk.border}`,
                  color: tk.red, fontSize: 11.5, fontWeight: 700, cursor: 'pointer',
                }}
              >Verbinding verbreken</button>
            </div>
          </>
        )}
      </section>

      {/* Other systems — placeholders */}
      <section style={{
        background: tk.card, border: `1px solid ${tk.border}`,
        borderRadius: 14, padding: '18px 20px',
      }}>
        <h3 style={{ fontFamily: 'Fredoka One', fontSize: 16, color: tk.fg, margin: '0 0 12px' }}>
          Andere systemen
        </h3>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
          <SystemRow tk={tk} name="Itslearning" sub="Coming soon" disabled />
          <SystemRow tk={tk} name="Google Classroom" sub="Coming soon" disabled />
          <SystemRow tk={tk} name="Somtoday" sub="Coming soon" disabled />
        </div>
      </section>
    </div>
  );
}

function ToggleRow({ tk, title, desc, value, onChange, premium }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 10,
      padding: '10px 12px', borderRadius: 8,
      background: tk.cardSunken, border: `1px solid ${tk.border}`,
    }}>
      <div style={{ flex: 1 }}>
        <div style={{
          fontSize: 12.5, fontWeight: 800, color: tk.fg,
          display: 'flex', alignItems: 'center', gap: 6,
        }}>
          {title}
          {premium && (
            <span style={{
              fontSize: 8.5, fontWeight: 800, color: tk.purple,
              padding: '1px 5px', borderRadius: 3,
              background: hexToRgba(tk.purple, 0.14),
              border: `1px solid ${hexToRgba(tk.purple, 0.3)}`,
              letterSpacing: 0.4, textTransform: 'uppercase',
            }}>Premium</span>
          )}
        </div>
        <div style={{ fontSize: 11, color: tk.fgDim, fontWeight: 600, marginTop: 2 }}>{desc}</div>
      </div>
      <button
        onClick={() => onChange(!value)}
        style={{
          width: 38, height: 22, borderRadius: 999,
          background: value ? tk.primary : hexToRgba(tk.fgFaint, 0.3),
          border: 0, padding: 2, cursor: 'pointer',
          display: 'flex', alignItems: 'center',
          transition: 'background 0.15s',
        }}
      >
        <div style={{
          width: 18, height: 18, borderRadius: '50%',
          background: '#FFFFFF',
          marginLeft: value ? 16 : 0,
          transition: 'margin-left 0.15s',
        }} />
      </button>
    </div>
  );
}

function SystemRow({ tk, name, sub, disabled }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 10,
      padding: '10px 12px', borderRadius: 8,
      background: tk.cardSunken, border: `1px solid ${tk.border}`,
      opacity: disabled ? 0.6 : 1,
    }}>
      <div style={{
        width: 32, height: 32, borderRadius: 8,
        background: hexToRgba(tk.fgFaint, 0.12),
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        color: tk.fgMute, fontFamily: 'Fredoka One', fontSize: 14,
      }}>{name[0]}</div>
      <div style={{ flex: 1 }}>
        <div style={{ fontSize: 12.5, fontWeight: 800, color: tk.fg }}>{name}</div>
        <div style={{ fontSize: 11, color: tk.fgMute, fontWeight: 600 }}>{sub}</div>
      </div>
      <button
        disabled={disabled}
        style={{
          padding: '6px 10px', borderRadius: 6,
          background: 'transparent', border: `1px solid ${tk.border}`,
          color: tk.fgMute, fontSize: 11, fontWeight: 700,
          cursor: disabled ? 'not-allowed' : 'pointer',
        }}
      >Verbinden</button>
    </div>
  );
}

/* ─── Placeholder voor tabs die later uitgewerkt worden ─── */
function SettingsTabPlaceholder({ tk, title, sub, icon }) {
  return (
    <div style={{
      padding: '60px 40px', background: tk.card, border: `1px solid ${tk.border}`,
      borderRadius: 14, textAlign: 'center', maxWidth: 560, margin: '0 auto',
    }}>
      <div style={{
        width: 56, height: 56, borderRadius: 14, margin: '0 auto 14px',
        background: tk.cardSunken, border: `1px solid ${tk.border}`,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
      }}>
        <PI name={icon} size={22} color={tk.fgDim} />
      </div>
      <h3 style={{ fontFamily: 'Fredoka One', fontSize: 20, color: tk.fg, margin: '0 0 6px' }}>{title}</h3>
      <p style={{ fontSize: 13, color: tk.fgDim, fontWeight: 500, margin: 0, lineHeight: 1.5 }}>{sub}</p>
    </div>
  );
}

function SettingToggle({ t, label, sub, on }) {
  const [enabled, setEnabled] = useState(on);
  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 10,
      padding: '10px 0', borderBottom: `1px solid ${t.border}`,
    }}>
      <div style={{ flex: 1 }}>
        <div style={{ fontSize: 13, fontWeight: 700, color: t.fg }}>{label}</div>
        <div style={{ fontSize: 11, color: t.fgMute, fontWeight: 500, marginTop: 1 }}>{sub}</div>
      </div>
      <button onClick={() => setEnabled(!enabled)} style={{
        width: 40, height: 22, borderRadius: 11,
        background: enabled ? t.primary : t.border,
        border: 0, cursor: 'pointer', position: 'relative',
        transition: 'background 0.2s',
      }}>
        <span style={{
          position: 'absolute', top: 2, left: enabled ? 20 : 2,
          width: 18, height: 18, borderRadius: 9,
          background: '#FFFFFF', transition: 'left 0.2s',
        }} />
      </button>
    </div>
  );
}

/* ═══════════════════════════════════════════════════════════════════
   STILTETIJD EDIT — zelfde UX als TijdvensterEdit maar in paars
   Voor Notificaties → Stiltetijden
   ═══════════════════════════════════════════════════════════════════ */

function StiltetijdEdit({ store, tk, dayKey }) {
  const currentBlock = store.quietBlocks[dayKey] || { available: true, ranges: [] };
  const [available, setAvailable] = useState(true); // altijd beschikbaar voor stilte ('altijd aan' = geen ranges = leeg)
  const [ranges, setRanges] = useState(
    currentBlock.ranges && currentBlock.ranges.length > 0
      ? currentBlock.ranges
      : [{ start: '22:00', end: '07:00', label: 'bedtijd' }]
  );
  const dayName = { ma: 'Maandag', di: 'Dinsdag', wo: 'Woensdag', do: 'Donderdag', vr: 'Vrijdag', za: 'Zaterdag', zo: 'Zondag' }[dayKey];

  function updateRange(idx, start, end) {
    setRanges(ranges.map((r, i) => i === idx ? { ...r, start, end } : r));
  }
  function updateLabel(idx, label) {
    setRanges(ranges.map((r, i) => i === idx ? { ...r, label } : r));
  }
  function addRange() {
    const hasEarly = ranges.some(r => timeToMin(r.start) < 12 * 60);
    const hasEvening = ranges.some(r => timeToMin(r.start) >= 18 * 60);
    let newRange;
    if (!hasEarly) newRange = { start: '08:30', end: '15:30', label: 'school' };
    else if (!hasEvening) newRange = { start: '22:00', end: '07:00', label: 'bedtijd' };
    else newRange = { start: '13:00', end: '14:00', label: '' };
    setRanges([...ranges, newRange]);
  }
  function removeRange(idx) {
    if (ranges.length === 1) return;
    setRanges(ranges.filter((_, i) => i !== idx));
  }
  function save() {
    store.setQuietBlocks({
      ...store.quietBlocks,
      [dayKey]: ranges.length > 0 ? { available: true, ranges } : { available: true, ranges: [] },
    });
    store.navigate('/settings', { tab: 'notificaties' });
  }

  const totalMinutes = rangesTotalMinutes(ranges);

  return (
    <div style={{ background: tk.bgApp, minHeight: 'calc(100vh - 44px)', padding: '40px 20px' }}>
      <div style={{
        maxWidth: 640, margin: '0 auto',
        background: tk.card, border: `1px solid ${tk.border}`,
        borderRadius: 16, padding: '28px 32px', boxShadow: tk.shadowElev,
      }}>
        {/* Header */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 4 }}>
          <button onClick={() => store.navigate('/settings', { tab: 'notificaties' })} style={{
            padding: 4, border: 0, background: 'transparent',
            color: tk.fgDim, cursor: 'pointer',
          }}>
            <PI name="chevron-left" size={18} />
          </button>
          <div style={{ fontSize: 10, fontWeight: 800, color: tk.purple, letterSpacing: 0.5, textTransform: 'uppercase' }}>
            Notificaties · Stiltetijd
          </div>
        </div>
        <h2 style={{
          fontFamily: 'Fredoka One', fontSize: 26, color: tk.fg,
          margin: '0 0 6px', letterSpacing: '-0.01em',
        }}>{dayName}</h2>
        <p style={{ fontSize: 13, color: tk.fgDim, margin: '0 0 20px', fontWeight: 500 }}>
          In deze periodes krijg je geen meldingen. Typisch: schooluren + bedtijd.
        </p>

        {/* Totaal-indicator */}
        <div style={{
          display: 'flex', alignItems: 'baseline', gap: 6, marginBottom: 12,
          fontSize: 11, fontWeight: 700, color: tk.fgDim,
        }}>
          <PI name="moon" size={12} color={tk.purple} />
          Totaal stilte deze dag:
          <span style={{ color: tk.purple, fontWeight: 800 }}>{calcDuration('00:00', minToTime(totalMinutes))}</span>
          <span style={{ color: tk.fgMute }}>· {ranges.length} periode{ranges.length !== 1 ? 's' : ''}</span>
        </div>

        {/* Ranges — zelfde RangeEditor als studietijd, maar met label-input + paars accent */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: 12, marginBottom: 14 }}>
          {ranges.map((r, i) => (
            <RangeEditor
              key={i}
              tk={tk}
              range={r}
              idx={i}
              canDelete={ranges.length > 1}
              onChange={(s, e) => updateRange(i, s, e)}
              onRemove={() => removeRange(i)}
              otherRanges={ranges.filter((_, j) => j !== i)}
              accent={tk.purple}
              labelLabel="bv. school, bedtijd, training"
              onLabelChange={(v) => updateLabel(i, v)}
              allowMidnightWrap
            />
          ))}
        </div>

        {/* Voeg periode toe */}
        <button onClick={addRange} style={{
          width: '100%', padding: '10px 12px', borderRadius: 9,
          background: 'transparent', border: `1.5px dashed ${tk.border}`,
          color: tk.fgDim, fontSize: 12, fontWeight: 700, cursor: 'pointer',
          display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 6,
          marginBottom: 16,
        }}
          onMouseEnter={(e) => {
            e.currentTarget.style.borderColor = tk.purple;
            e.currentTarget.style.color = tk.purple;
          }}
          onMouseLeave={(e) => {
            e.currentTarget.style.borderColor = tk.border;
            e.currentTarget.style.color = tk.fgDim;
          }}
        >
          <PI name="plus" size={14} /> Voeg periode toe
        </button>

        {/* Presets */}
        <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', marginBottom: 10, alignItems: 'center' }}>
          <span style={{ fontSize: 10, fontWeight: 800, color: tk.fgMute, letterSpacing: 0.4, textTransform: 'uppercase' }}>Snel:</span>
          {[
            { label: 'School + bedtijd', ranges: [
              { start: '08:30', end: '15:30', label: 'school' },
              { start: '22:00', end: '07:00', label: 'bedtijd' },
            ]},
            { label: 'Alleen bedtijd', ranges: [{ start: '22:00', end: '07:00', label: 'bedtijd' }] },
            { label: 'Uitslapen', ranges: [{ start: '23:00', end: '09:00', label: 'bedtijd' }] },
          ].map(p => (
            <button key={p.label} onClick={() => setRanges(p.ranges)} style={{
              padding: '6px 12px', borderRadius: 7,
              background: tk.cardSunken, border: `1px solid ${tk.border}`,
              color: tk.fgDim, fontSize: 11, fontWeight: 800, cursor: 'pointer',
            }}>{p.label}</button>
          ))}
        </div>

        {/* Kopieer van dag */}
        <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', marginBottom: 16, alignItems: 'center' }}>
          <span style={{
            fontSize: 10, fontWeight: 800, color: tk.fgMute,
            letterSpacing: 0.4, textTransform: 'uppercase',
            display: 'inline-flex', alignItems: 'center', gap: 4,
          }}>
            <PI name="copy" size={11} color={tk.fgMute} />
            Kopieer van:
          </span>
          {['ma', 'di', 'wo', 'do', 'vr', 'za', 'zo']
            .filter(d => d !== dayKey)
            .map(d => {
              const other = store.quietBlocks[d];
              const hasRanges = other && other.ranges && other.ranges.length > 0;
              return (
                <button
                  key={d}
                  disabled={!hasRanges}
                  onClick={() => { if (hasRanges) setRanges(other.ranges.map(r => ({ ...r }))); }}
                  title={hasRanges
                    ? other.ranges.map(r => `${r.start}–${r.end}${r.label ? ' ' + r.label : ''}`).join(' + ')
                    : 'Geen stiltetijd op deze dag'
                  }
                  style={{
                    padding: '6px 10px', borderRadius: 7,
                    background: hasRanges ? tk.cardSunken : 'transparent',
                    border: `1px dashed ${tk.border}`,
                    color: hasRanges ? tk.fgDim : tk.fgFaint,
                    fontSize: 11, fontWeight: 800,
                    cursor: hasRanges ? 'pointer' : 'not-allowed',
                    textTransform: 'capitalize',
                  }}
                >{d}</button>
              );
            })
          }
        </div>

        {/* Info-banner */}
        <div style={{
          padding: '10px 14px', borderRadius: 10,
          background: hexToRgba(tk.purple, 0.08),
          border: `1px solid ${hexToRgba(tk.purple, 0.2)}`,
          display: 'flex', alignItems: 'center', gap: 10,
          marginBottom: 16,
        }}>
          <PulseMascot size={26} mood="thinking" />
          <div style={{ fontSize: 12, color: tk.fg, fontWeight: 600, lineHeight: 1.5 }}>
            Stiltetijden gelden voor <b>alle</b> notificaties — ook kritieke reminders worden uitgesteld tot de stilte voorbij is.
          </div>
        </div>

        {/* Actions */}
        <div style={{ display: 'flex', gap: 8 }}>
          <button onClick={() => store.navigate('/settings', { tab: 'notificaties' })} style={btnSecondary(tk)}>Annuleer</button>
          <span style={{ flex: 1 }} />
          <button onClick={save} style={{
            ...btnPrimary(tk),
            background: tk.purple,
          }}>✓ Opslaan</button>
        </div>
      </div>
    </div>
  );
}

function TijdvensterEdit({ store, tk, dayKey }) {
  const currentBlock = store.studyBlocks[dayKey];
  const [available, setAvailable] = useState(currentBlock.available);
  const [ranges, setRanges] = useState(
    currentBlock.ranges && currentBlock.ranges.length > 0
      ? currentBlock.ranges
      : [{ start: '15:30', end: '17:30' }]
  );

  const dayName = { ma: 'Maandag', di: 'Dinsdag', wo: 'Woensdag', do: 'Donderdag', vr: 'Vrijdag', za: 'Zaterdag', zo: 'Zondag' }[dayKey];

  function updateRange(idx, start, end) {
    setRanges(ranges.map((r, i) => i === idx ? { start, end } : r));
  }

  function addRange() {
    // Voeg een logische nieuwe range toe (ofwel vroege ochtend als nog niet aanwezig, of avond)
    const hasEarly = ranges.some(r => timeToMin(r.start) < 12 * 60);
    const hasEvening = ranges.some(r => timeToMin(r.start) >= 18 * 60);
    let newRange;
    if (!hasEarly) newRange = { start: '08:00', end: '09:00' };
    else if (!hasEvening) newRange = { start: '19:00', end: '20:30' };
    else newRange = { start: '13:00', end: '14:00' };
    setRanges([...ranges, newRange]);
  }

  function removeRange(idx) {
    if (ranges.length === 1) return; // Minstens 1 range houden, beschikbaarheid uit als geen gewenst
    setRanges(ranges.filter((_, i) => i !== idx));
  }

  function save() {
    store.setStudyBlocks({
      ...store.studyBlocks,
      [dayKey]: available ? { available: true, ranges } : { available: false, ranges: [] },
    });
    store.navigate('/settings');
  }

  const totalMinutes = available ? rangesTotalMinutes(ranges) : 0;

  return (
    <div style={{ background: tk.bgApp, minHeight: 'calc(100vh - 44px)', padding: '40px 20px' }}>
      <div style={{
        maxWidth: 640, margin: '0 auto',
        background: tk.card, border: `1px solid ${tk.border}`,
        borderRadius: 16, padding: '28px 32px', boxShadow: tk.shadowElev,
      }}>
        {/* Header */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 4 }}>
          <button onClick={() => store.navigate('/settings')} style={{
            padding: 4, border: 0, background: 'transparent',
            color: tk.fgDim, cursor: 'pointer',
          }}>
            <PI name="chevron-left" size={18} />
          </button>
          <div style={{ fontSize: 10, fontWeight: 800, color: tk.primary, letterSpacing: 0.5, textTransform: 'uppercase' }}>
            Instellingen · Studie-tijd
          </div>
        </div>
        <h2 style={{
          fontFamily: 'Fredoka One', fontSize: 26, color: tk.fg,
          margin: '0 0 6px', letterSpacing: '-0.01em',
        }}>{dayName}</h2>
        <p style={{ fontSize: 13, color: tk.fgDim, margin: '0 0 20px', fontWeight: 500 }}>
          Stel het tijdvenster in waarop je op deze dag wilt studeren.
        </p>

        {/* Beschikbaar-toggle */}
        <div style={{
          display: 'flex', alignItems: 'center', gap: 10,
          padding: '12px 14px', borderRadius: 10,
          background: available ? hexToRgba(tk.primary, 0.06) : tk.cardSunken,
          border: `1px solid ${available ? hexToRgba(tk.primary, 0.2) : tk.border}`,
          marginBottom: 16,
        }}>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 13, fontWeight: 700, color: tk.fg }}>Beschikbaar op {dayName.toLowerCase()}</div>
            <div style={{ fontSize: 11, color: tk.fgMute, fontWeight: 500, marginTop: 1 }}>
              {available ? 'Pulse plant taken binnen onderstaand tijdvenster' : 'Geen taken op deze dag'}
            </div>
          </div>
          <button onClick={() => setAvailable(!available)} style={{
            width: 44, height: 24, borderRadius: 12,
            background: available ? tk.primary : tk.border,
            border: 0, cursor: 'pointer', position: 'relative',
          }}>
            <span style={{
              position: 'absolute', top: 2, left: available ? 22 : 2,
              width: 20, height: 20, borderRadius: 10,
              background: '#FFFFFF', transition: 'left 0.2s',
            }} />
          </button>
        </div>

        {available && (
          <>
            {/* Totaal-indicator */}
            <div style={{
              display: 'flex', alignItems: 'baseline', gap: 6, marginBottom: 12,
              fontSize: 11, fontWeight: 700, color: tk.fgDim,
            }}>
              <PI name="clock" size={12} color={tk.fgMute} />
              Totaal studietijd deze dag:
              <span style={{ color: tk.primary, fontWeight: 800 }}>{calcDuration('00:00', minToTime(totalMinutes))}</span>
              <span style={{ color: tk.fgMute }}>· {ranges.length} venster{ranges.length !== 1 ? 's' : ''}</span>
            </div>

            {/* Ranges */}
            <div style={{ display: 'flex', flexDirection: 'column', gap: 12, marginBottom: 14 }}>
              {ranges.map((r, i) => (
                <RangeEditor
                  key={i}
                  tk={tk}
                  range={r}
                  idx={i}
                  canDelete={ranges.length > 1}
                  onChange={(s, e) => updateRange(i, s, e)}
                  onRemove={() => removeRange(i)}
                  otherRanges={ranges.filter((_, j) => j !== i)}
                />
              ))}
            </div>

            {/* Voeg tijdvenster toe */}
            <button onClick={addRange} style={{
              width: '100%', padding: '10px 12px', borderRadius: 9,
              background: 'transparent', border: `1.5px dashed ${tk.border}`,
              color: tk.fgDim, fontSize: 12, fontWeight: 700, cursor: 'pointer',
              display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 6,
              marginBottom: 16,
            }}
              onMouseEnter={(e) => {
                e.currentTarget.style.borderColor = tk.primary;
                e.currentTarget.style.color = tk.primary;
              }}
              onMouseLeave={(e) => {
                e.currentTarget.style.borderColor = tk.border;
                e.currentTarget.style.color = tk.fgDim;
              }}
            >
              <PI name="plus" size={14} /> Voeg tijdvenster toe
            </button>

            {/* Quick-presets — snelle opties */}
            <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', marginBottom: 10, alignItems: 'center' }}>
              <span style={{ fontSize: 10, fontWeight: 800, color: tk.fgMute, letterSpacing: 0.4, textTransform: 'uppercase' }}>Snel:</span>
              {[
                { label: 'Na school', ranges: [{ start: '15:30', end: '17:30' }] },
                { label: 'Ochtend', ranges: [{ start: '10:00', end: '12:00' }] },
                { label: 'Ochtend + middag', ranges: [{ start: '08:00', end: '09:00' }, { start: '15:30', end: '17:30' }] },
                { label: 'Dubbele sessie', ranges: [{ start: '15:30', end: '17:00' }, { start: '19:00', end: '20:30' }] },
              ].map(p => (
                <button key={p.label} onClick={() => setRanges(p.ranges)} style={{
                  padding: '6px 12px', borderRadius: 7,
                  background: tk.cardSunken, border: `1px solid ${tk.border}`,
                  color: tk.fgDim, fontSize: 11, fontWeight: 800, cursor: 'pointer',
                }}>{p.label}</button>
              ))}
            </div>

            {/* Kopieer van dag */}
            <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', marginBottom: 16, alignItems: 'center' }}>
              <span style={{
                fontSize: 10, fontWeight: 800, color: tk.fgMute,
                letterSpacing: 0.4, textTransform: 'uppercase',
                display: 'inline-flex', alignItems: 'center', gap: 4,
              }}>
                <PI name="copy" size={11} color={tk.fgMute} />
                Kopieer van:
              </span>
              {['ma', 'di', 'wo', 'do', 'vr', 'za', 'zo']
                .filter(d => d !== dayKey)
                .map(d => {
                  const other = store.studyBlocks[d];
                  const hasRanges = other && other.available && other.ranges && other.ranges.length > 0;
                  return (
                    <button
                      key={d}
                      disabled={!hasRanges}
                      onClick={() => {
                        if (!hasRanges) return;
                        setAvailable(true);
                        setRanges(other.ranges.map(r => ({ ...r })));
                      }}
                      title={hasRanges
                        ? other.ranges.map(r => `${r.start}–${r.end}`).join(' + ')
                        : 'Geen tijd ingesteld op deze dag'
                      }
                      style={{
                        padding: '6px 10px', borderRadius: 7,
                        background: hasRanges ? tk.cardSunken : 'transparent',
                        border: `1px dashed ${tk.border}`,
                        color: hasRanges ? tk.fgDim : tk.fgFaint,
                        fontSize: 11, fontWeight: 800,
                        cursor: hasRanges ? 'pointer' : 'not-allowed',
                        textTransform: 'capitalize',
                      }}
                    >{d}</button>
                  );
                })
              }
            </div>

            {/* Auto-pauze toggle */}
            <div style={{
              padding: '10px 14px', borderRadius: 10,
              background: hexToRgba(tk.purple, 0.08),
              border: `1px solid ${hexToRgba(tk.purple, 0.2)}`,
              display: 'flex', alignItems: 'center', gap: 10,
              marginBottom: 16,
            }}>
              <PulseMascot size={26} mood="thinking" />
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 12, color: tk.fg, fontWeight: 700 }}>
                  Pulse voegt automatisch een pauze van 10 min in na 45 min.
                </div>
                <div style={{ fontSize: 10.5, color: tk.fgMute, fontWeight: 600, marginTop: 1 }}>
                  kan je per studietaak uitschakelen
                </div>
              </div>
              <div style={{
                width: 40, height: 22, borderRadius: 11,
                background: tk.primary, position: 'relative',
              }}>
                <span style={{
                  position: 'absolute', top: 2, left: 20,
                  width: 18, height: 18, borderRadius: 9, background: '#FFFFFF',
                }} />
              </div>
            </div>
          </>
        )}

        {/* Actions */}
        <div style={{ display: 'flex', gap: 8 }}>
          <button onClick={() => store.navigate('/settings')} style={btnSecondary(tk)}>Annuleer</button>
          <span style={{ flex: 1 }} />
          <button onClick={save} style={btnPrimary(tk)}>✓ Opslaan</button>
        </div>
      </div>
    </div>
  );
}

/* ═══════════════════════════════════════════════════════════════════
   TIMELINE SLIDER (E2-patroon uit edge-flows) — twee draggable handles
   ═══════════════════════════════════════════════════════════════════ */

function TimelineSlider({ tk, start, end, onChange, otherRanges = [], accent, allowMidnightWrap }) {
  const accentColor = accent || tk.primary;
  // 0:00-24:00 visualized as 0-100%; step = 15 min
  const startMin = timeToMin(start);
  const endMin = timeToMin(end);
  const [dragging, setDragging] = useState(null); // 'start' | 'end' | null
  const trackRef = useRef(null);

  function minFromEvent(e) {
    if (!trackRef.current) return null;
    const rect = trackRef.current.getBoundingClientRect();
    const x = Math.max(0, Math.min(rect.width, e.clientX - rect.left));
    const pct = x / rect.width;
    let min = Math.round(pct * 24 * 60 / 15) * 15;
    return Math.max(0, Math.min(1440, min));
  }

  function onMouseMove(e) {
    if (!dragging) return;
    const min = minFromEvent(e);
    if (min === null) return;
    if (dragging === 'start') {
      // Sta alles toe behalve exact gelijk aan end (0-duur)
      if (allowMidnightWrap) {
        if (min !== endMin) onChange(minToTime(min), end);
      } else {
        if (min < endMin - 15) onChange(minToTime(min), end);
      }
    } else {
      if (allowMidnightWrap) {
        if (min !== startMin) onChange(start, minToTime(min));
      } else {
        if (min > startMin + 15) onChange(start, minToTime(min));
      }
    }
  }

  useEffect(() => {
    if (!dragging) return;
    function up() { setDragging(null); }
    window.addEventListener('mousemove', onMouseMove);
    window.addEventListener('mouseup', up);
    return () => {
      window.removeEventListener('mousemove', onMouseMove);
      window.removeEventListener('mouseup', up);
    };
  }, [dragging, startMin, endMin]);

  const startPct = (startMin / 1440) * 100;
  const endPct = (endMin / 1440) * 100;
  // Wrap-check: als end < start en allowMidnightWrap → 2-segment render
  const wraps = allowMidnightWrap && endMin < startMin;

  // Hour markers
  const hourMarkers = [0, 6, 12, 18, 24];

  return (
    <div style={{ padding: '0 10px' }}>
      {/* Slider track */}
      <div ref={trackRef} style={{
        position: 'relative', height: 48,
        userSelect: 'none',
      }}>
        {/* Background track (full 24h) */}
        <div style={{
          position: 'absolute', top: 20, left: 0, right: 0, height: 8,
          background: tk.card, borderRadius: 4,
          border: `1px solid ${tk.border}`,
        }} />

        {/* Other ranges gedimd op dezelfde tijdlijn (ook wrap-aware) */}
        {otherRanges.map((r, i) => {
          const oStartPct = (timeToMin(r.start) / 1440) * 100;
          const oEndPct = (timeToMin(r.end) / 1440) * 100;
          const oWraps = allowMidnightWrap && timeToMin(r.end) < timeToMin(r.start);
          if (oWraps) {
            return (
              <React.Fragment key={i}>
                <div style={{
                  position: 'absolute', top: 20, height: 8, borderRadius: 4,
                  left: 0, width: `${oEndPct}%`,
                  background: hexToRgba(accentColor, 0.2),
                  border: `1px dashed ${hexToRgba(accentColor, 0.4)}`,
                  zIndex: 1,
                }} title={`Ander venster: ${r.start}-${r.end}`} />
                <div style={{
                  position: 'absolute', top: 20, height: 8, borderRadius: 4,
                  left: `${oStartPct}%`, right: 0,
                  background: hexToRgba(accentColor, 0.2),
                  border: `1px dashed ${hexToRgba(accentColor, 0.4)}`,
                  zIndex: 1,
                }} title={`Ander venster: ${r.start}-${r.end}`} />
              </React.Fragment>
            );
          }
          return (
            <div key={i} style={{
              position: 'absolute', top: 20, height: 8, borderRadius: 4,
              left: `${oStartPct}%`, width: `${Math.max(0, oEndPct - oStartPct)}%`,
              background: hexToRgba(accentColor, 0.2),
              border: `1px dashed ${hexToRgba(accentColor, 0.4)}`,
              zIndex: 1,
            }} title={`Ander venster: ${r.start}-${r.end}`} />
          );
        })}

        {/* Selected range — wrap-aware (2 segmenten als over middernacht) */}
        {wraps ? (
          <>
            {/* Segment 1: van start tot 24:00 */}
            <div style={{
              position: 'absolute', top: 20, height: 8, borderRadius: '4px 0 0 4px',
              left: `${startPct}%`, right: 0,
              background: `linear-gradient(90deg, ${accentColor}, ${hexToRgba(accentColor, 0.85)})`,
              boxShadow: `0 0 12px ${hexToRgba(accentColor, 0.3)}`,
              zIndex: 2,
            }} />
            {/* Segment 2: van 00:00 tot end */}
            <div style={{
              position: 'absolute', top: 20, height: 8, borderRadius: '0 4px 4px 0',
              left: 0, width: `${endPct}%`,
              background: `linear-gradient(90deg, ${hexToRgba(accentColor, 0.85)}, ${hexToRgba(accentColor, 0.7)})`,
              boxShadow: `0 0 12px ${hexToRgba(accentColor, 0.3)}`,
              zIndex: 2,
            }} />
            {/* Midnight indicator (klein lijntje) */}
            <div style={{
              position: 'absolute', top: 16, height: 16, width: 2,
              background: accentColor, opacity: 0.5,
              left: 0, zIndex: 2,
            }} title="middernacht" />
            <div style={{
              position: 'absolute', top: 16, height: 16, width: 2,
              background: accentColor, opacity: 0.5,
              right: 0, zIndex: 2,
            }} title="middernacht" />
          </>
        ) : (
          <div style={{
            position: 'absolute', top: 20, height: 8, borderRadius: 4,
            left: `${startPct}%`, width: `${Math.max(0, endPct - startPct)}%`,
            background: `linear-gradient(90deg, ${accentColor}, ${hexToRgba(accentColor, 0.7)})`,
            boxShadow: `0 0 12px ${hexToRgba(accentColor, 0.3)}`,
          }} />
        )}

        {/* Start handle */}
        <div
          onMouseDown={() => setDragging('start')}
          style={{
            position: 'absolute', top: 12, left: `${startPct}%`,
            transform: 'translateX(-50%)',
            width: 24, height: 24, borderRadius: 12,
            background: '#FFFFFF', border: `3px solid ${accentColor}`,
            cursor: dragging === 'start' ? 'grabbing' : 'grab',
            boxShadow: `0 2px 8px ${hexToRgba(accentColor, 0.3)}`,
            zIndex: 3,
          }}
        />
        {/* End handle */}
        <div
          onMouseDown={() => setDragging('end')}
          style={{
            position: 'absolute', top: 12, left: `${endPct}%`,
            transform: 'translateX(-50%)',
            width: 24, height: 24, borderRadius: 12,
            background: '#FFFFFF', border: `3px solid ${accentColor}`,
            cursor: dragging === 'end' ? 'grabbing' : 'grab',
            boxShadow: `0 2px 8px ${hexToRgba(accentColor, 0.3)}`,
            zIndex: 3,
          }}
        />
      </div>

      {/* Hour labels + optional wrap-hint */}
      <div style={{
        display: 'flex', justifyContent: 'space-between',
        fontSize: 10, fontWeight: 700, color: tk.fgMute,
      }}>
        {hourMarkers.map(h => (
          <span key={h}>{String(h).padStart(2, '0')}:00</span>
        ))}
      </div>
      {wraps && (
        <div style={{
          fontSize: 10, fontWeight: 700, color: accentColor,
          marginTop: 4, display: 'inline-flex', alignItems: 'center', gap: 3,
        }}>
          <PI name="moon" size={10} color={accentColor} />
          Loopt door tot de volgende ochtend
        </div>
      )}
    </div>
  );
}

function RangeEditor({ tk, range, idx, canDelete, onChange, onRemove, otherRanges, accent, labelLabel, onLabelChange, allowMidnightWrap }) {
  const color = accent || tk.primary;
  return (
    <div style={{
      padding: '14px', borderRadius: 10,
      background: tk.cardSunken, border: `1px solid ${tk.border}`,
    }}>
      {/* Header */}
      <div style={{
        display: 'flex', alignItems: 'center', gap: 10, marginBottom: 10,
      }}>
        <span style={{
          padding: '2px 8px', borderRadius: 4,
          background: hexToRgba(color, 0.14),
          color, fontSize: 10, fontWeight: 800,
          letterSpacing: 0.5, textTransform: 'uppercase',
        }}>Venster {idx + 1}</span>
        <span style={{ fontSize: 10, color: tk.fgMute, fontWeight: 700 }}>
          {calcDuration(range.start, range.end)}
        </span>
        {onLabelChange && (
          <input
            type="text"
            value={range.label || ''}
            onChange={(e) => onLabelChange(e.target.value)}
            placeholder={labelLabel || 'Naam (optioneel)'}
            style={{
              padding: '4px 8px', borderRadius: 5,
              background: tk.card, border: `1px solid ${tk.border}`,
              color: tk.fg, fontSize: 11, fontWeight: 700, fontFamily: 'inherit',
              outline: 'none', maxWidth: 180,
            }}
          />
        )}
        <span style={{ flex: 1 }} />
        {canDelete && (
          <button onClick={onRemove} style={{
            padding: '3px 8px', borderRadius: 6,
            background: 'transparent', border: `1px solid ${tk.border}`,
            color: tk.red, fontSize: 11, fontWeight: 700, cursor: 'pointer',
            display: 'inline-flex', alignItems: 'center', gap: 3,
          }}
            onMouseEnter={(e) => e.currentTarget.style.background = hexToRgba(tk.red, 0.1)}
            onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
          >
            <PI name="trash-2" size={11} color={tk.red} /> Verwijder
          </button>
        )}
      </div>

      {/* VAN-TOT display */}
      <div style={{
        display: 'flex', alignItems: 'baseline', gap: 8, marginBottom: 8,
      }}>
        <span style={{
          fontSize: 10, fontWeight: 800, color: tk.fgMute,
          letterSpacing: 0.5, textTransform: 'uppercase',
        }}>Van</span>
        <span style={{ fontFamily: 'Fredoka One', fontSize: 22, color, letterSpacing: '-0.01em' }}>{range.start}</span>
        <span style={{ fontSize: 10, fontWeight: 800, color: tk.fgMute, letterSpacing: 0.5, textTransform: 'uppercase', marginLeft: 14 }}>Tot</span>
        <span style={{ fontFamily: 'Fredoka One', fontSize: 22, color, letterSpacing: '-0.01em' }}>{range.end}</span>
      </div>
      <TimelineSlider tk={tk} start={range.start} end={range.end} onChange={onChange} otherRanges={otherRanges} accent={color} allowMidnightWrap={allowMidnightWrap} />
    </div>
  );
}

function timeToMin(t) {
  const [h, m] = t.split(':').map(Number);
  return h * 60 + m;
}

function formatHours(decimal) {
  const totalMin = Math.round(decimal * 60);
  const h = Math.floor(totalMin / 60);
  const m = totalMin % 60;
  if (h === 0) return `${m}m`;
  if (m === 0) return `${h}u`;
  return `${h}u ${m}m`;
}

function minToTime(min) {
  const h = Math.floor(min / 60);
  const m = min % 60;
  return `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}`;
}

function calcDuration(start, end) {
  // Midnight-aware: als end < start, wrap door middernacht heen.
  const s = timeToMin(start);
  const e = timeToMin(end);
  const total = e >= s ? (e - s) : (1440 - s + e);
  const h = Math.floor(total / 60);
  const m = total % 60;
  if (h === 0) return `${m}m`;
  if (m === 0) return `${h}u`;
  return `${h}u ${m}m`;
}

/* ═══════════════════════════════════════════════════════════════════
   ROUTER
   ═══════════════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════════
   SCREEN: Add Losse Taak — snelle taak-creatie, eventueel gekoppeld aan deadline
   ═══════════════════════════════════════════════════════════════════ */

function ScreenAddLooseTask({ store }) {
  const tk = t(store.theme);
  const params = store.route.params || {};
  // Default: target is 'today' of 'tomorrow' meegegeven via params, anders today
  const defaultWhen = params.when || 'today'; // 'today' | 'tomorrow' | 'custom'
  const defaultDate = params.date || '2026-04-22';

  const [subject, setSubject] = useState('biologie');
  const [taskType, setTaskType] = useState('lezen');
  const [title, setTitle] = useState('');
  const [mins, setMins] = useState(25);
  const [scheduledTime, setScheduledTime] = useState('');
  const [when, setWhen] = useState(defaultWhen);
  const [customDate, setCustomDate] = useState(defaultDate);
  const [deadlineId, setDeadlineId] = useState(params.deadlineId || '');

  const linkableDeadlines = (store.deadlines || []).filter(d => !d.unscheduled);

  function save() {
    const task = {
      id: 'tl' + Date.now(),
      subject, type: taskType, title, mins,
      scheduledTime: scheduledTime || undefined,
      deadlineId: deadlineId || null,
      standalone: !deadlineId,
      done: false,
    };
    if (when === 'today') {
      store.setTasksToday([...store.tasksToday, task]);
    } else if (when === 'tomorrow') {
      store.setTasksTomorrow([...store.tasksTomorrow, task]);
    }
    // In een echte app: ook week-blocks updaten. Voor prototype: terug naar vorige view.
    store.navigate('/');
  }

  const canSave = !!title && !!mins;

  return (
    <div style={{ background: tk.bgApp, minHeight: 'calc(100vh - 44px)', padding: '40px 20px' }}>
      <div style={{
        maxWidth: 560, margin: '0 auto',
        background: tk.card, border: `1px solid ${tk.border}`,
        borderRadius: 16, padding: '28px 32px',
        boxShadow: tk.shadowElev,
      }}>
        {/* Header */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 16 }}>
          <div style={{
            width: 36, height: 36, borderRadius: 9,
            background: hexToRgba(tk.primary, 0.14),
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}>
            <PI name="plus" size={18} color={tk.primary} />
          </div>
          <div style={{ flex: 1 }}>
            <h2 style={{ fontFamily: 'Fredoka One', fontSize: 22, color: tk.fg, margin: 0 }}>Nieuwe taak</h2>
            <div style={{ fontSize: 12, color: tk.fgDim, fontWeight: 600, marginTop: 2 }}>
              Losse taak — optioneel koppelen aan een deadline
            </div>
          </div>
          <button onClick={() => store.navigate('/')} style={{
            padding: '6px 10px', borderRadius: 7,
            background: 'transparent', border: `1px solid ${tk.border}`,
            color: tk.fgDim, fontSize: 11, fontWeight: 700, cursor: 'pointer',
          }}>Annuleer</button>
        </div>

        {/* Vak + type */}
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10, marginBottom: 10 }}>
          <Field label="Vak" tk={tk}>
            <select value={subject} onChange={(e) => setSubject(e.target.value)} style={formSelect(tk)}>
              {Object.keys(SUBJECTS).map(s => (
                <option key={s} value={s}>{s.charAt(0).toUpperCase() + s.slice(1)}</option>
              ))}
            </select>
          </Field>
          <Field label="Wat voor werk" tk={tk}>
            <select value={taskType} onChange={(e) => setTaskType(e.target.value)} style={formSelect(tk)}>
              <option value="lezen">Lezen</option>
              <option value="schrijven">Schrijven</option>
              <option value="oefenen">Oefenen</option>
              <option value="overhoren">Overhoren</option>
              <option value="samenvatten">Samenvatten</option>
            </select>
          </Field>
        </div>

        {/* Titel */}
        <Field label="Titel" tk={tk}>
          <input
            type="text" value={title} onChange={(e) => setTitle(e.target.value)}
            placeholder="Bijv. §4.2 celbiologie lezen"
            autoFocus style={formInput(tk)}
          />
        </Field>

        {/* Wanneer */}
        <div style={{ marginTop: 14 }}>
          <div style={formLabelStyle(tk)}>Wanneer</div>
          <div style={{ display: 'flex', gap: 6 }}>
            {[
              { v: 'today', label: 'Vandaag' },
              { v: 'tomorrow', label: 'Morgen' },
              { v: 'custom', label: 'Andere dag' },
            ].map(o => (
              <button key={o.v} onClick={() => setWhen(o.v)} style={{
                flex: 1, padding: '9px 8px', borderRadius: 8,
                background: when === o.v ? hexToRgba(tk.primary, 0.12) : tk.cardSunken,
                border: when === o.v ? `1.5px solid ${tk.primary}` : `1px solid ${tk.border}`,
                color: when === o.v ? tk.primary : tk.fgDim,
                fontSize: 12, fontWeight: 800, cursor: 'pointer',
              }}>{o.label}</button>
            ))}
          </div>
          {when === 'custom' && (
            <input
              type="date" value={customDate} onChange={(e) => setCustomDate(e.target.value)}
              style={{ ...formInput(tk), marginTop: 8 }}
            />
          )}
        </div>

        {/* Duur + starttijd */}
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10, marginTop: 14 }}>
          <Field label="Hoe lang (min)" tk={tk}>
            <div style={{ display: 'flex', gap: 4 }}>
              {[10, 15, 25, 45].map(n => (
                <button key={n} onClick={() => setMins(n)} style={{
                  flex: 1, padding: '8px 0', borderRadius: 7,
                  background: mins === n ? hexToRgba(tk.primary, 0.12) : tk.cardSunken,
                  border: mins === n ? `1.5px solid ${tk.primary}` : `1px solid ${tk.border}`,
                  color: mins === n ? tk.primary : tk.fgDim,
                  fontSize: 11, fontWeight: 800, cursor: 'pointer',
                }}>{n}m</button>
              ))}
            </div>
          </Field>
          <Field label="Starttijd (optioneel)" tk={tk}>
            <input type="time" value={scheduledTime} onChange={(e) => setScheduledTime(e.target.value)} style={formInput(tk)} />
          </Field>
        </div>

        {/* Deadline koppelen */}
        <div style={{ marginTop: 14 }}>
          <div style={{ ...formLabelStyle(tk), display: 'flex', alignItems: 'center', gap: 6 }}>
            <PI name="link" size={11} color={tk.fgMute} />
            Aan deadline koppelen (optioneel)
          </div>
          <select value={deadlineId} onChange={(e) => setDeadlineId(e.target.value)} style={formSelect(tk)}>
            <option value="">— Losse taak · niet gekoppeld —</option>
            {linkableDeadlines.map(d => (
              <option key={d.id} value={d.id}>
                {d.subject.charAt(0).toUpperCase() + d.subject.slice(1)} · {d.title.split(' — ')[0]}
              </option>
            ))}
          </select>
          <div style={{ fontSize: 11, color: tk.fgMute, fontWeight: 600, marginTop: 6, lineHeight: 1.5 }}>
            {deadlineId
              ? 'Deze taak telt mee voor de voortgang van de deadline.'
              : 'Losse taak krijgt een 📌 marker en kan later alsnog gekoppeld worden.'}
          </div>
        </div>

        {/* Actions */}
        <div style={{ display: 'flex', gap: 8, marginTop: 24 }}>
          <button onClick={() => store.navigate('/')} style={btnSecondary(tk)}>Annuleer</button>
          <span style={{ flex: 1 }} />
          <button onClick={save} disabled={!canSave} style={{
            ...btnPrimary(tk),
            opacity: canSave ? 1 : 0.5, cursor: canSave ? 'pointer' : 'not-allowed',
          }}>
            <PI name="check" size={14} color="#FFFFFF" style={{ marginRight: 4, verticalAlign: 'middle' }} />
            Voeg toe
          </button>
        </div>
      </div>
    </div>
  );
}

function formSelect(tk) {
  return {
    padding: '9px 10px', borderRadius: 8,
    border: `1px solid ${tk.border}`, background: tk.cardSunken,
    color: tk.fg, fontSize: 13, fontWeight: 600, fontFamily: 'inherit',
    cursor: 'pointer', width: '100%',
  };
}
function formInput(tk) {
  return {
    padding: '9px 10px', borderRadius: 8,
    border: `1px solid ${tk.border}`, background: tk.cardSunken,
    color: tk.fg, fontSize: 13, fontWeight: 600, fontFamily: 'inherit',
    outline: 'none', width: '100%', boxSizing: 'border-box',
  };
}
function formLabelStyle(tk) {
  return {
    fontSize: 10, fontWeight: 800, color: tk.fgMute,
    letterSpacing: 0.5, textTransform: 'uppercase', marginBottom: 6,
  };
}

function App() {
  const store = usePrototypeStore();
  const { route } = store;

  // Route matching
  let Screen;
  if (route.path === '/') Screen = <ScreenHome store={store} />;
  else if (route.path.startsWith('/add-deadline')) Screen = <ScreenAddDeadline store={store} />;
  else if (route.path.endsWith('/edit')) Screen = <ScreenEditDeadline store={store} />;
  else if (route.path.startsWith('/deadline/')) Screen = <ScreenDeadlineDrawer store={store} />;
  else if (route.path === '/focus') Screen = <ScreenFocusMode store={store} />;
  else if (route.path === '/week') Screen = <ScreenWeekView store={store} />;
  else if (route.path === '/herplan') Screen = <ScreenHerplan store={store} />;
  else if (route.path === '/add-task') Screen = <ScreenAddLooseTask store={store} />;
  else if (route.path.startsWith('/settings')) Screen = <ScreenSettings store={store} />;
  else Screen = <ScreenHome store={store} />;

  return (
    <RustModusContext.Provider value={!!store.rustModus}>
      <ProtoHeader store={store} />
      {Screen}
    </RustModusContext.Provider>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
