<?php
require_once 'includes/config.php';
require_once 'topic-reviews.php';
require_once 'study-points.php';
requireLogin();
$uid = $_SESSION['user_id'];
ensureTopicReviewsTable($pdo);
ensureStudyPointsColumn($pdo);

// ── Anti-abuse: is this account currently locked by the system? ──────
$abuseLocked = false; $abuseLockedUntil = null;
try {
    $lockChk = $pdo->prepare("SELECT abuse_locked_until FROM users WHERE id=?");
    $lockChk->execute([$uid]);
    $lockRow = $lockChk->fetch();
    if ($lockRow && !empty($lockRow['abuse_locked_until']) && strtotime($lockRow['abuse_locked_until']) > time()) {
        $abuseLocked = true;
        $abuseLockedUntil = $lockRow['abuse_locked_until'];
    }
} catch (Exception $e) { /* abuse columns not migrated yet — see database_abuse_lock.sql */ }

// ── AJAX ──────────────────────────────────────────────────
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_SERVER['HTTP_X_REQUESTED_WITH'])) {
    $action = $_POST['action'] ?? '';

    if ($action === 'add') {
        // Blocked entirely while under a system lock
        if ($abuseLocked) {
            jsonResponse([
                'success' => false,
                'locked'  => true,
                'message' => 'Your account has been locked by the system until ' . date('M j, g:i A', strtotime($abuseLockedUntil)) . ' due to repeated unrealistic session entries. Contact an admin if you believe this is a mistake.',
                'locked_until' => $abuseLockedUntil,
            ]);
        }

        $subId = (int)($_POST['subject_id'] ?? 0);
        $date  = $_POST['date'] ?? date('Y-m-d');
        $hours = max(0, (int)($_POST['hours'] ?? 0));
        $mins  = max(0, min(59, (int)($_POST['minutes'] ?? 0)));
        $notes = sanitize($_POST['notes'] ?? '');
        $total = $hours * 60 + $mins;

        // ── Anti-abuse: unrealistic manual entry (50+ hours in one session) ──
        if ($total > 3000) {
            $aStmt = null; $aRow = null;
            try {
                $aStmt = $pdo->prepare("SELECT abuse_warned FROM users WHERE id=?");
                $aStmt->execute([$uid]);
                $aRow = $aStmt->fetch();
            } catch (Exception $e) { /* abuse columns not migrated yet */ }

            if ($aRow && !empty($aRow['abuse_warned'])) {
                // Already warned once — lock the account now for 12 hours
                $until = date('Y-m-d H:i:s', time() + 12 * 3600);
                try {
                    $pdo->prepare("UPDATE users SET abuse_locked_until=? WHERE id=?")->execute([$until, $uid]);
                } catch (Exception $e) {}
                jsonResponse([
                    'success' => false,
                    'locked'  => true,
                    'message' => 'Your account has been locked by the system for 12 hours for entering another unrealistic session (50+ hours) after being warned.',
                    'locked_until' => $until,
                ]);
            } else {
                try {
                    $pdo->prepare("UPDATE users SET abuse_warned=1 WHERE id=?")->execute([$uid]);
                } catch (Exception $e) {}
                jsonResponse([
                    'success' => false,
                    'warn'    => true,
                    'message' => "That's over 50 hours for a single study session — that isn't realistic. If you try to log another session like this, your account will be locked for 12 hours.",
                ]);
            }
        }

        if ($subId <= 0)  jsonResponse(['success'=>false,'message'=>'Please select a subject.']);
        if ($total <= 0)  jsonResponse(['success'=>false,'message'=>'Please enter a duration (at least 1 minute).']);
        if ($total > 1440) jsonResponse(['success'=>false,'message'=>'A study session cannot exceed 24 hours.']);

        $chk = $pdo->prepare("SELECT id FROM subjects WHERE id=? AND user_id=?");
        $chk->execute([$subId, $uid]);
        if (!$chk->fetch()) jsonResponse(['success'=>false,'message'=>'Invalid subject.']);

        $dateObj = DateTime::createFromFormat('Y-m-d', $date);
        if (!$dateObj) $date = date('Y-m-d');

        $pdo->prepare("INSERT INTO study_sessions (user_id,subject_id,date,duration_minutes,notes) VALUES (?,?,?,?,?)")
            ->execute([$uid, $subId, $date, $total, $notes]);

        $pdo->prepare("INSERT INTO study_streaks (user_id,date,minutes_studied) VALUES (?,?,?)
                       ON DUPLICATE KEY UPDATE minutes_studied=minutes_studied+?")
            ->execute([$uid, $date, $total, $total]);

        // ── Spaced repetition: schedule/advance a review for this topic ──
        // (skip auto-generated placeholder notes from the timer/pomodoro that aren't a real topic)
        $isPlaceholderNote = ($notes === '⏱️ Live session') || (strpos($notes, '🍅 Pomodoro session') === 0);
        if (!$isPlaceholderNote) {
            scheduleTopicReview($pdo, $uid, $subId, $notes, $date);
        }

        // ── Points: 1 point per full hour of study, awarded off the lifetime total ──
        $pointsEarned = awardStudyPoints($pdo, $uid);

        $h = floor($total/60); $m = $total%60;
        $msg = "Session logged! ({$h}h {$m}m)";
        if ($pointsEarned > 0) $msg .= " +{$pointsEarned} 🏆";
        jsonResponse(['success'=>true,'message'=>$msg,'points_earned'=>$pointsEarned]);
    }

    if ($action === 'delete') {
        $id = (int)($_POST['id'] ?? 0);
        $pdo->prepare("DELETE FROM study_sessions WHERE id=? AND user_id=?")->execute([$id, $uid]);
        jsonResponse(['success'=>true]);
    }

    // ── Spaced repetition actions ──
    if ($action === 'sr_review_done') {
        $id = (int)($_POST['id'] ?? 0);
        $ok = advanceTopicReview($pdo, $uid, $id);
        jsonResponse(['success'=>$ok, 'message'=>$ok ? 'Nice! Scheduled for your next review.' : 'Could not update review.']);
    }

    if ($action === 'sr_mastered') {
        $id = (int)($_POST['id'] ?? 0);
        $ok = markTopicMastered($pdo, $uid, $id);
        jsonResponse(['success'=>$ok, 'message'=>$ok ? 'Marked as mastered — no more reminders for this topic.' : 'Could not update review.']);
    }

    jsonResponse(['success'=>false,'message'=>'Unknown action.']);
}

// ── Page data ──────────────────────────────────────────────
$period = $_GET['period'] ?? 'week';
$dateFilter = match($period) {
    'month' => 'AND ss.date >= DATE_SUB(CURDATE(), INTERVAL 1 MONTH)',
    'year'  => 'AND ss.date >= DATE_SUB(CURDATE(), INTERVAL 1 YEAR)',
    'all'   => '',
    default => 'AND ss.date >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)',
};

$stmt = $pdo->prepare("SELECT ss.*, s.name as subject_name, s.color
    FROM study_sessions ss JOIN subjects s ON ss.subject_id=s.id
    WHERE ss.user_id=? $dateFilter ORDER BY ss.date DESC, ss.created_at DESC");
$stmt->execute([$uid]);
$sessions = $stmt->fetchAll();

$stmt2 = $pdo->prepare("SELECT * FROM subjects WHERE user_id=? ORDER BY name");
$stmt2->execute([$uid]);
$subjectsList = $stmt2->fetchAll();

$totalMins = array_sum(array_column($sessions,'duration_minutes'));
$days      = count(array_unique(array_column($sessions,'date')));
$avgMins   = $days > 0 ? round($totalMins/$days) : 0;

// ── Spaced repetition data ──
$dueReviews = getDueTopicReviews($pdo, $uid);

// ── Points data ──
$studyPoints     = getStudyPointsBalance($pdo, $uid);
$minsToNextPoint = minutesToNextStudyPoint($pdo, $uid);

require_once 'includes/header.php';
renderHeader('Study Log', 'study-log');
?>

<style>
@import url('https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800;900&family=Plus+Jakarta+Sans:wght@300;400;500;600;700&display=swap');

:root {
  --sl-df: 'Outfit', sans-serif;
  --sl-db: 'Plus Jakarta Sans', sans-serif;
  --sl-r:  16px;
  --sl-lg: 22px;
  --sl-g:  16px;
}

.slp { font-family: var(--sl-db); padding-bottom: 48px; max-width: 1280px; }

/* ── Top bar ── */
.sl-topbar {
  display:flex; align-items:center; justify-content:space-between;
  gap:12px; margin-bottom:var(--sl-g); flex-wrap:wrap;
  animation: sl-rise .4s ease both;
}
.sl-period { display:flex; background:var(--bg-secondary); border-radius:10px; padding:3px; gap:2px; }
.sl-ptb {
  padding:7px 15px; border-radius:8px; border:none; font-family:var(--sl-db);
  font-size:12px; font-weight:600; cursor:pointer; background:transparent;
  color:var(--text-muted); transition:all .16s; text-decoration:none; display:inline-block;
}
.sl-ptb.active { background:var(--bg-card); color:var(--text-primary); box-shadow:0 1px 4px rgba(0,0,0,.18); }
.sl-ptb:hover:not(.active) { color:var(--text-secondary); }

.sl-actions { display:flex; gap:8px; }
.sl-btn {
  display:inline-flex; align-items:center; gap:7px; padding:9px 18px;
  border-radius:11px; font-family:var(--sl-db); font-size:13px; font-weight:700;
  cursor:pointer; border:none; transition:all .18s; white-space:nowrap;
}
.sl-btn-primary {
  background:linear-gradient(135deg,#6366f1,#8b5cf6);
  color:#fff; box-shadow:0 4px 14px rgba(99,102,241,.3);
}
.sl-btn-primary:hover { transform:translateY(-2px); box-shadow:0 8px 22px rgba(99,102,241,.4); }
.sl-btn-secondary {
  background:var(--bg-card); border:1px solid var(--border); color:var(--text-secondary);
}
.sl-btn-secondary:hover { border-color:var(--border-light); color:var(--text-primary); background:var(--bg-card-hover); }

/* ── Stats ── */
.sl-stats { display:grid; grid-template-columns:repeat(4,1fr); gap:var(--sl-g); margin-bottom:var(--sl-g); }
@media(max-width:900px){
  .sl-stats { grid-template-columns:repeat(2,1fr); }
}

.sl-st {
  background:var(--bg-card); border:1px solid var(--border); border-radius:var(--sl-lg);
  padding:22px 22px 18px; position:relative; overflow:hidden;
  transition:transform .2s,box-shadow .2s,border-color .2s;
  animation:sl-rise .5s ease both; cursor:default;
}
.sl-st:nth-child(1){animation-delay:.08s} .sl-st:nth-child(2){animation-delay:.13s} .sl-st:nth-child(3){animation-delay:.18s} .sl-st:nth-child(4){animation-delay:.23s}
.sl-st:hover { transform:translateY(-4px); box-shadow:0 16px 40px rgba(0,0,0,.2); border-color:var(--border-light); }
.sl-st::before { content:''; position:absolute; width:120px; height:120px; border-radius:50%; top:-30px; right:-30px; pointer-events:none; }
.sl-st1::before{background:rgba(99,102,241,.16)} .sl-st2::before{background:rgba(6,182,212,.14)} .sl-st3::before{background:rgba(16,185,129,.14)} .sl-st4::before{background:rgba(245,158,11,.16)}
.sl-st::after { content:''; position:absolute; bottom:0; left:0; right:0; height:2px; opacity:0; transition:opacity .2s; }
.sl-st:hover::after{opacity:1}
.sl-st1::after{background:linear-gradient(90deg,#6366f1,#a855f7)}
.sl-st2::after{background:linear-gradient(90deg,#06b6d4,#6366f1)}
.sl-st3::after{background:linear-gradient(90deg,#10b981,#06b6d4)}
.sl-st4::after{background:linear-gradient(90deg,#f59e0b,#f97316)}

.sl-sth { display:flex; justify-content:space-between; align-items:flex-start; margin-bottom:16px; }
.sl-sti { width:42px; height:42px; border-radius:12px; display:flex; align-items:center; justify-content:center; font-size:19px; }
.sl-stv { font-family:var(--sl-df); font-size:30px; font-weight:800; color:var(--text-primary); line-height:1; letter-spacing:-.5px; }
.sl-stv .du { font-size:14px; color:var(--text-muted); font-weight:500; font-family:var(--sl-db); }
.sl-stl { font-size:12px; color:var(--text-muted); margin-top:6px; font-weight:500; }

/* ── Card ── */
.sl-card {
  background:var(--bg-card); border:1px solid var(--border); border-radius:var(--sl-lg);
  padding:22px; margin-bottom:var(--sl-g); animation:sl-rise .5s .25s ease both;
}
.sl-card-hd { display:flex; align-items:center; justify-content:space-between; margin-bottom:20px; gap:12px; flex-wrap:wrap; }
.sl-card-t { font-family:var(--sl-df); font-size:15px; font-weight:700; color:var(--text-primary); letter-spacing:-.2px; }
.sl-card-meta { font-size:12px; color:var(--text-muted); font-weight:600; }

/* ── Session rows ── */
.sl-row-hd {
  display:grid; grid-template-columns:100px 1fr 90px 1fr 44px;
  gap:8px; padding:0 4px 10px;
  border-bottom:1px solid var(--border);
  font-size:11px; font-weight:700; color:var(--text-muted);
  text-transform:uppercase; letter-spacing:.8px;
}
.sl-row {
  display:grid; grid-template-columns:100px 1fr 90px 1fr 44px;
  gap:8px; padding:11px 4px;
  border-bottom:1px solid var(--border);
  align-items:center;
  transition:background .12s, border-radius .12s, padding .12s;
}
.sl-row:last-child { border-bottom:none; }
.sl-row:hover { background:var(--bg-secondary); border-radius:12px; padding-left:12px; padding-right:12px; }

@media(max-width:680px){
  .sl-row-hd { display:none; }
  .sl-row {
    display:grid;
    grid-template-columns:1fr auto;
    grid-template-rows:auto auto auto;
    grid-template-areas:"date del" "subj del" "meta del";
    gap:3px 12px;
    background:var(--bg-secondary); border:1px solid var(--border) !important;
    border-radius:14px; padding:13px 14px !important; margin-bottom:8px;
  }
  .sl-row:last-child{ margin-bottom:0; }
  .sl-date{grid-area:date;}
  .sl-subj{grid-area:subj;}
  .sl-dur{grid-area:meta;}
  .sl-notes{display:none;}
  .sl-del{grid-area:del;display:flex;align-items:center;}
}

.sl-date { font-size:12px; color:var(--text-muted); }
.sl-date strong { font-size:13px; font-weight:600; color:var(--text-primary); display:block; }
.sl-subj { display:flex; align-items:center; gap:8px; font-size:13px; font-weight:600; color:var(--text-primary); overflow:hidden; white-space:nowrap; text-overflow:ellipsis; }
.sl-dot { width:9px; height:9px; border-radius:50%; flex-shrink:0; display:inline-block; }
.sl-dur { font-family:var(--sl-df); font-weight:700; color:var(--accent); font-size:14px; white-space:nowrap; }
.sl-notes-txt { font-size:12px; color:var(--text-muted); overflow:hidden; white-space:nowrap; text-overflow:ellipsis; }
.sl-del button {
  background:rgba(239,68,68,.1); color:#ef4444; border:none;
  border-radius:9px; padding:7px 9px; cursor:pointer; transition:all .15s; font-size:14px;
}
.sl-del button:hover { background:rgba(239,68,68,.22); transform:scale(1.08); }

/* ── Empty ── */
.sl-empty { text-align:center; padding:52px 20px; }
.sl-empty .sl-ei { font-size:48px; margin-bottom:14px; }
.sl-empty h3 { font-size:15px; font-weight:700; color:var(--text-secondary); margin-bottom:6px; }
.sl-empty p { font-size:13px; color:var(--text-muted); }

/* ── Modal ── */
.sl-modal-ov {
  position:fixed; inset:0; background:rgba(0,0,0,.6); backdrop-filter:blur(6px);
  z-index:9990; display:flex; align-items:center; justify-content:center;
  padding:16px; opacity:0; pointer-events:none; transition:opacity .2s;
}
.sl-modal-ov.active { opacity:1; pointer-events:auto; }
.sl-modal {
  background:var(--bg-card); border:1px solid rgba(99,102,241,.22);
  border-radius:24px; padding:28px; width:100%; max-width:460px;
  box-shadow:0 32px 80px rgba(0,0,0,.5);
  transform:scale(.94) translateY(14px);
  transition:transform .28s cubic-bezier(.34,1.3,.64,1);
  max-height:90vh; overflow-y:auto;
}
.sl-modal-ov.active .sl-modal { transform:scale(1) translateY(0); }

.sl-modal-hd { display:flex; align-items:center; justify-content:space-between; margin-bottom:24px; }
.sl-modal-title { font-family:var(--sl-df); font-size:17px; font-weight:800; color:var(--text-primary); display:flex; align-items:center; gap:10px; }
.sl-modal-close { background:var(--bg-secondary); border:1px solid var(--border); border-radius:9px; color:var(--text-muted); font-size:14px; padding:5px 10px; cursor:pointer; transition:all .15s; }
.sl-modal-close:hover { color:var(--text-primary); border-color:var(--border-light); }

.sl-fg { margin-bottom:16px; }
.sl-fg label { display:block; font-size:11px; font-weight:700; color:var(--text-muted); letter-spacing:.6px; text-transform:uppercase; margin-bottom:7px; }
.sl-inp {
  width:100%; background:var(--bg-secondary); border:1px solid var(--border);
  border-radius:11px; padding:11px 14px; font-family:var(--sl-db);
  font-size:13px; color:var(--text-primary); transition:border-color .15s, box-shadow .15s;
  outline:none; box-sizing:border-box;
}
.sl-inp:focus { border-color:rgba(99,102,241,.5); box-shadow:0 0 0 3px rgba(99,102,241,.08); }
.sl-fg2 { display:grid; grid-template-columns:1fr 1fr; gap:12px; }

/* Duration quick picker */
.sl-dur-picks { display:flex; gap:7px; flex-wrap:wrap; }
.sl-dpick {
  padding:6px 13px; border-radius:8px; border:1px solid var(--border);
  background:var(--bg-secondary); font-size:12px; font-weight:600;
  color:var(--text-muted); cursor:pointer; transition:all .15s;
}
.sl-dpick:hover, .sl-dpick.active {
  background:rgba(99,102,241,.12); border-color:rgba(99,102,241,.35); color:var(--accent);
}

.sl-alert { padding:10px 14px; border-radius:10px; font-size:13px; font-weight:600; margin-bottom:16px; display:none; }
.sl-alert.success { background:rgba(16,185,129,.1); border:1px solid rgba(16,185,129,.2); color:#10b981; }
.sl-alert.error   { background:rgba(239,68,68,.1);  border:1px solid rgba(239,68,68,.2);  color:#ef4444; }

.sl-save-btn {
  width:100%; background:linear-gradient(135deg,#6366f1,#8b5cf6);
  color:#fff; border:none; border-radius:12px; padding:14px;
  font-family:var(--sl-db); font-size:14px; font-weight:700;
  cursor:pointer; transition:all .18s; box-shadow:0 4px 14px rgba(99,102,241,.3);
  display:flex; align-items:center; justify-content:center; gap:8px; margin-top:4px;
}
.sl-save-btn:hover:not(:disabled) { transform:translateY(-2px); box-shadow:0 8px 24px rgba(99,102,241,.4); }
.sl-save-btn:disabled { opacity:.6; cursor:not-allowed; }

/* ── Pomodoro ── */
.pm-ring-wrap { position:relative; width:180px; height:180px; margin:0 auto 16px; }
.pm-mode-tabs { display:flex; gap:5px; background:var(--bg-secondary); border-radius:11px; padding:4px; margin-bottom:18px; }
.pm-mtb {
  flex:1; padding:8px 6px; border:none; border-radius:8px; font-family:var(--sl-db);
  font-size:12px; font-weight:600; cursor:pointer; transition:all .16s;
  background:transparent; color:var(--text-muted);
}
.pm-mtb.active { background:linear-gradient(135deg,#6366f1,#8b5cf6); color:#fff; box-shadow:0 2px 8px rgba(99,102,241,.3); }
.pm-ctrl { display:flex; gap:10px; margin-bottom:14px; }
.pm-start {
  flex:2; background:linear-gradient(135deg,#6366f1,#8b5cf6); color:#fff; border:none;
  border-radius:12px; padding:13px; font-family:var(--sl-db); font-size:14px;
  font-weight:700; cursor:pointer; transition:all .18s; box-shadow:0 4px 14px rgba(99,102,241,.3);
}
.pm-start:hover { transform:translateY(-2px); box-shadow:0 8px 22px rgba(99,102,241,.4); }
.pm-reset {
  flex:1; background:var(--bg-secondary); border:1px solid var(--border); color:var(--text-secondary);
  border-radius:12px; padding:13px; font-family:var(--sl-db); font-size:14px;
  font-weight:700; cursor:pointer; transition:all .16s;
}
.pm-reset:hover { border-color:var(--border-light); color:var(--text-primary); }
.pm-custom { border-top:1px solid var(--border); padding-top:16px; margin-top:4px; }
.pm-custom-lbl { font-size:11px; font-weight:700; color:var(--text-muted); text-transform:uppercase; letter-spacing:.6px; margin-bottom:10px; }

/* ── No subjects warning ── */
.sl-warn {
  background:rgba(245,158,11,.08); border:1px solid rgba(245,158,11,.2);
  border-radius:14px; padding:14px 18px; font-size:13px; color:#f59e0b;
  font-weight:600; margin-bottom:var(--sl-g); display:flex; align-items:center; gap:10px;
}

/* ════════════════════════════════
   CUSTOM TOAST / CONFIRM POPUP
════════════════════════════════ */
.sl-toast-ov {
  position:fixed; inset:0; z-index:99999;
  display:flex; align-items:flex-end; justify-content:center;
  padding:0 16px 32px;
  pointer-events:none; opacity:0;
  transition:opacity .22s ease;
}
.sl-toast-ov.show { opacity:1; pointer-events:auto; }

.sl-toast {
  background:var(--bg-card); border:1px solid rgba(99,102,241,.2);
  border-radius:20px; padding:20px 22px 18px;
  width:100%; max-width:400px;
  box-shadow:0 24px 60px rgba(0,0,0,.55), 0 0 0 1px rgba(255,255,255,.04);
  transform:translateY(28px) scale(.96);
  transition:transform .28s cubic-bezier(.34,1.3,.64,1);
  position:relative;
}
.sl-toast-ov.show .sl-toast { transform:translateY(0) scale(1); }

.sl-toast::before {
  content:''; position:absolute; top:0; left:20%; right:20%; height:1px;
  background:linear-gradient(90deg,transparent,rgba(99,102,241,.7),rgba(168,85,247,.6),transparent);
  border-radius:99px;
}
.sl-toast-icon { font-size:28px; margin-bottom:10px; }
.sl-toast-title { font-family:var(--sl-df); font-size:16px; font-weight:800; color:var(--text-primary); margin-bottom:5px; }
.sl-toast-msg   { font-size:13px; color:var(--text-muted); line-height:1.5; margin-bottom:18px; }
.sl-toast-btns  { display:flex; gap:8px; }
.sl-toast-btn {
  flex:1; padding:11px; border-radius:11px; font-family:var(--sl-db);
  font-size:13px; font-weight:700; cursor:pointer; border:none; transition:all .16s;
  text-align:center;
}
.sl-toast-btn.primary {
  background:linear-gradient(135deg,#6366f1,#8b5cf6); color:#fff;
  box-shadow:0 4px 12px rgba(99,102,241,.3);
}
.sl-toast-btn.primary:hover { transform:translateY(-2px); box-shadow:0 6px 18px rgba(99,102,241,.4); }
.sl-toast-btn.danger {
  background:linear-gradient(135deg,#ef4444,#dc2626); color:#fff;
  box-shadow:0 4px 12px rgba(239,68,68,.3);
}
.sl-toast-btn.danger:hover { transform:translateY(-2px); box-shadow:0 6px 18px rgba(239,68,68,.4); }
.sl-toast-btn.secondary {
  background:var(--bg-secondary); border:1px solid var(--border); color:var(--text-secondary);
}
.sl-toast-btn.secondary:hover { color:var(--text-primary); border-color:var(--border-light); }

/* Simple info toast (no buttons) */
.sl-snack-ov {
  position:fixed; bottom:28px; left:50%; transform:translateX(-50%) translateY(80px);
  z-index:99999; transition:transform .3s cubic-bezier(.34,1.3,.64,1), opacity .25s ease;
  opacity:0; pointer-events:none;
}
.sl-snack-ov.show { transform:translateX(-50%) translateY(0); opacity:1; pointer-events:auto; }
.sl-snack {
  background:#1e1e2e; border:1px solid rgba(99,102,241,.25);
  border-radius:99px; padding:10px 20px;
  font-size:13px; font-weight:700; color:var(--text-primary);
  white-space:nowrap; box-shadow:0 8px 28px rgba(0,0,0,.4);
  display:flex; align-items:center; gap:8px;
}

/* ════════════════════════════════
   LIVE SESSION TIMER CARD
════════════════════════════════ */
.ls-card {
  background:var(--bg-card); border:1px solid var(--border); border-radius:var(--sl-lg);
  padding:22px; margin-bottom:var(--sl-g); animation:sl-rise .5s .2s ease both;
  position:relative; overflow:hidden;
  transition:border-color .4s ease, box-shadow .4s ease;
}
.ls-card.active-session {
  border-color:rgba(34,197,94,.4);
  box-shadow:0 0 0 1px rgba(34,197,94,.07), 0 16px 40px rgba(0,0,0,.2);
  background:linear-gradient(160deg, var(--bg-card) 70%, rgba(34,197,94,.04) 100%);
}
.ls-card::before {
  content:''; position:absolute; inset:0; pointer-events:none;
  background:radial-gradient(ellipse at 0% 0%, rgba(99,102,241,.05) 0%, transparent 55%);
}

/* Idle */
.ls-idle { display:flex; align-items:center; justify-content:space-between; gap:16px; flex-wrap:wrap; }
.ls-idle-left { display:flex; align-items:center; gap:14px; }
.ls-idle-icon {
  width:50px; height:50px; border-radius:15px;
  background:linear-gradient(135deg,rgba(99,102,241,.15),rgba(34,197,94,.1));
  border:1px solid rgba(99,102,241,.15);
  display:flex; align-items:center; justify-content:center; font-size:23px; flex-shrink:0;
}
.ls-idle-title { font-family:var(--sl-df); font-size:15px; font-weight:700; color:var(--text-primary); }
.ls-idle-sub { font-size:12px; color:var(--text-muted); margin-top:3px; }
.ls-start-btn {
  display:inline-flex; align-items:center; gap:8px;
  padding:12px 24px; border-radius:13px;
  background:linear-gradient(135deg,#22c55e,#16a34a);
  color:#fff; border:none; font-family:var(--sl-db); font-size:14px; font-weight:700;
  cursor:pointer; transition:all .2s; box-shadow:0 4px 18px rgba(34,197,94,.38);
  white-space:nowrap; position:relative; overflow:hidden;
}
.ls-start-btn::after {
  content:''; position:absolute; inset:0;
  background:linear-gradient(105deg,transparent 30%,rgba(255,255,255,.15),transparent 70%);
  transform:skewX(-15deg) translateX(-100%); transition:transform .5s ease;
}
.ls-start-btn:hover::after { transform:skewX(-15deg) translateX(200%); }
.ls-start-btn:hover { transform:translateY(-2px); box-shadow:0 8px 26px rgba(34,197,94,.48); }

/* Running state */
.ls-running { display:none; }
.ls-running.visible { display:block; animation:sl-rise .35s ease both; }
.ls-idle.hidden { display:none; }

/* Top row */
.ls-running-top {
  display:flex; align-items:center; justify-content:space-between;
  gap:10px; margin-bottom:20px; flex-wrap:wrap;
}
.ls-live-badge {
  display:inline-flex; align-items:center; gap:6px;
  background:rgba(34,197,94,.12); border:1px solid rgba(34,197,94,.3);
  border-radius:99px; padding:5px 13px;
  font-size:11px; font-weight:800; color:#22c55e;
  text-transform:uppercase; letter-spacing:1px; flex-shrink:0;
}
.ls-live-dot {
  width:7px; height:7px; border-radius:50%; background:#22c55e;
  animation:ls-blink 1.2s ease-in-out infinite;
}
@keyframes ls-blink { 0%,100%{opacity:1;transform:scale(1)} 50%{opacity:.3;transform:scale(.6)} }

/* Subject row */
.ls-sub-row {
  display:flex; align-items:center; gap:8px;
  background:var(--bg-secondary); border:1px solid var(--border);
  border-radius:11px; padding:8px 14px; flex:1; min-width:0; max-width:240px;
  transition:border-color .2s;
}
.ls-sub-row:focus-within { border-color:rgba(99,102,241,.4); }
.ls-sub-dot { width:9px; height:9px; border-radius:50%; flex-shrink:0; background:var(--border); transition:background .2s; }
.ls-sub-select {
  flex:1; background:transparent; border:none; outline:none;
  font-family:var(--sl-db); font-size:13px; font-weight:600;
  color:var(--text-primary); min-width:0;
}

/* Ring timer */
.ls-timer-wrap { text-align:center; padding:4px 0 18px; }
.ls-timer-ring { position:relative; width:200px; height:200px; margin:0 auto 10px; }
.ls-timer-ring svg { transform:rotate(-90deg); }
.ls-timer-inner {
  position:absolute; inset:0; display:flex;
  flex-direction:column; align-items:center; justify-content:center;
}
.ls-timer-display {
  font-family:var(--sl-df); font-size:clamp(32px,8vw,46px); font-weight:900;
  letter-spacing:-3px; line-height:1; font-variant-numeric:tabular-nums;
  background:linear-gradient(135deg,#818cf8 0%,#c084fc 45%,#38bdf8 100%);
  -webkit-background-clip:text; -webkit-text-fill-color:transparent; background-clip:text;
  transition:all .3s ease;
}
.ls-timer-paused .ls-timer-display {
  background:linear-gradient(135deg,#f59e0b,#fbbf24) !important;
  -webkit-background-clip:text; -webkit-text-fill-color:transparent; background-clip:text;
}
.ls-timer-sub {
  font-size:11px; color:var(--text-muted); font-weight:600;
  margin-top:6px; letter-spacing:.5px; text-transform:uppercase;
}

/* Progress bar */
.ls-elapsed-bar { height:5px; background:var(--bg-secondary); border-radius:99px; overflow:hidden; margin-bottom:18px; }
.ls-elapsed-fill {
  height:100%; border-radius:99px;
  background:linear-gradient(90deg,#6366f1,#a855f7,#38bdf8,#22c55e);
  background-size:300% 100%; animation:ls-flow 4s linear infinite;
  transition:width .8s cubic-bezier(.4,0,.2,1); width:0%;
}
@keyframes ls-flow { 0%{background-position:0%} 100%{background-position:300%} }
.ls-elapsed-fill.paused { animation:none; opacity:.55; }

/* Controls */
.ls-controls { display:grid; grid-template-columns:1fr 2fr; gap:10px; }
@media(max-width:380px){ .ls-controls { grid-template-columns:1fr; } }
.ls-stop-btn {
  display:flex; align-items:center; justify-content:center; gap:8px;
  padding:14px; border-radius:13px;
  background:linear-gradient(135deg,#ef4444,#dc2626);
  color:#fff; border:none; font-family:var(--sl-db); font-size:14px; font-weight:700;
  cursor:pointer; transition:all .18s; box-shadow:0 4px 14px rgba(239,68,68,.3);
}
.ls-stop-btn:hover { transform:translateY(-2px); box-shadow:0 8px 22px rgba(239,68,68,.4); }
.ls-pause-btn {
  display:flex; align-items:center; justify-content:center; gap:7px;
  padding:14px; border-radius:13px; border:1px solid var(--border);
  background:var(--bg-secondary); color:var(--text-secondary);
  font-family:var(--sl-db); font-size:14px; font-weight:700;
  cursor:pointer; transition:all .18s;
}
.ls-pause-btn:hover { border-color:var(--border-light); color:var(--text-primary); }
.ls-pause-btn.paused { background:rgba(245,158,11,.1); border-color:rgba(245,158,11,.35); color:#f59e0b; }

/* Save modal */
.ls-notes-inp { resize:vertical; }

@keyframes sl-rise { from{opacity:0;transform:translateY(18px)} to{opacity:1;transform:translateY(0)} }
</style>

<div class="slp">

<?php if ($abuseLocked): ?>
<div class="sl-warn" style="background:rgba(239,68,68,.1);border-color:rgba(239,68,68,.3);color:#ef4444">
  🔒 Your account is <strong>locked by the system</strong> until <?= date('M j, g:i A', strtotime($abuseLockedUntil)) ?> due to repeated unrealistic session entries — logging is disabled until then. Contact an admin if you think this is a mistake.
</div>
<?php endif; ?>

<?php if (!$subjectsList): ?>
<div class="sl-warn">
  ⚠️ You need to <a href="<?= SITE_URL ?>/subjects" style="color:#f59e0b;text-decoration:underline">add subjects</a> before logging study sessions.
</div>
<?php endif; ?>

<!-- ── Top bar ── -->
<div class="sl-topbar">
  <div class="sl-period">
    <a href="?period=week"  class="sl-ptb <?= $period==='week' ?'active':'' ?>">Week</a>
    <a href="?period=month" class="sl-ptb <?= $period==='month'?'active':'' ?>">Month</a>
    <a href="?period=year"  class="sl-ptb <?= $period==='year' ?'active':'' ?>">Year</a>
    <a href="?period=all"   class="sl-ptb <?= $period==='all'  ?'active':'' ?>">All Time</a>
  </div>
  <div class="sl-actions">
    <button class="sl-btn sl-btn-secondary" onclick="document.getElementById('slPomModal').classList.add('active')" <?= $abuseLocked?'disabled title="Locked by system"':'' ?>>
      ⏱️ Pomodoro
    </button>
    <button class="sl-btn sl-btn-primary" onclick="document.getElementById('slAddModal').classList.add('active')" <?= $abuseLocked?'disabled title="Locked by system"':'' ?>>
      ＋ Log Session
    </button>
  </div>
</div>

<!-- ── Stats ── -->
<div class="sl-stats">
  <div class="sl-st sl-st1">
    <div class="sl-sth">
      <div class="sl-sti" style="background:rgba(99,102,241,.12)">⏱️</div>
      <span style="font-size:11px;font-weight:700;padding:3px 9px;border-radius:99px;background:rgba(6,182,212,.12);color:#06b6d4">
        <?= $period==='week'?'7 days':($period==='month'?'30 days':($period==='year'?'1 year':'All')) ?>
      </span>
    </div>
    <div class="sl-stv"><?= floor($totalMins/60) ?><span class="du">h <?= $totalMins%60 ?>m</span></div>
    <div class="sl-stl">Total Study Time</div>
  </div>
  <div class="sl-st sl-st2">
    <div class="sl-sth">
      <div class="sl-sti" style="background:rgba(6,182,212,.12)">📋</div>
      <span style="font-size:11px;font-weight:700;padding:3px 9px;border-radius:99px;background:rgba(16,185,129,.12);color:#10b981">Sessions</span>
    </div>
    <div class="sl-stv"><?= count($sessions) ?></div>
    <div class="sl-stl">Sessions Logged</div>
  </div>
  <div class="sl-st sl-st3">
    <div class="sl-sth">
      <div class="sl-sti" style="background:rgba(16,185,129,.12)">📊</div>
      <span style="font-size:11px;font-weight:700;padding:3px 9px;border-radius:99px;background:rgba(245,158,11,.12);color:#f59e0b">Daily avg</span>
    </div>
    <div class="sl-stv"><?= floor($avgMins/60) ?><span class="du">h <?= $avgMins%60 ?>m</span></div>
    <div class="sl-stl">Avg Per Study Day</div>
  </div>
  <div class="sl-st sl-st4">
    <div class="sl-sth">
      <div class="sl-sti" style="background:rgba(245,158,11,.12)">🏆</div>
      <span style="font-size:11px;font-weight:700;padding:3px 9px;border-radius:99px;background:rgba(99,102,241,.12);color:#818cf8">1h = 1pt</span>
    </div>
    <div class="sl-stv"><?= number_format($studyPoints) ?></div>
    <div class="sl-stl"><?= $minsToNextPoint > 0 ? $minsToNextPoint.'m to next point' : 'Study Points' ?></div>
  </div>
</div>

<!-- ── Spaced Repetition Tracker ── -->
<div class="sl-card" id="slSrCard">
  <div class="sl-card-hd">
    <div class="sl-card-t">🔁 Spaced Repetition</div>
    <?php if (count($dueReviews) > 0): ?>
      <span class="sl-card-meta" style="background:rgba(239,68,68,.12);color:#ef4444;padding:4px 11px;border-radius:99px;font-weight:700"><?= count($dueReviews) ?> due now</span>
    <?php else: ?>
      <span class="sl-card-meta">Every topic you log gets its own review schedule</span>
    <?php endif; ?>
  </div>

  <?php if ($dueReviews): ?>
    <div id="slSrDueList">
    <?php foreach ($dueReviews as $r):
      $daysAgo = max(0, (int)((strtotime('today') - strtotime($r['last_studied_date'])) / 86400));
    ?>
    <div class="sl-sr-row" id="slSrRow<?= $r['id'] ?>" style="background:var(--bg-secondary);border:1px solid var(--border);border-radius:14px;padding:13px 16px;margin-bottom:10px;display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap">
      <div style="min-width:0;flex:1 1 220px">
        <div style="display:flex;align-items:center;gap:8px;font-size:13px;font-weight:600;color:var(--text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap">
          <span class="sl-dot" style="background:<?= htmlspecialchars($r['subject_color']) ?>"></span>
          <?= htmlspecialchars($r['topic']) ?>
        </div>
        <div style="font-size:11px;color:var(--text-muted);margin-top:3px">
          <?= htmlspecialchars($r['subject_name']) ?> &bull; last studied <?= $daysAgo === 0 ? 'today' : $daysAgo.'d ago' ?> &bull; review #<?= (int)$r['times_reviewed'] ?>
        </div>
      </div>
      <div style="display:flex;gap:8px;flex-shrink:0">
        <button onclick="slReviewDone(<?= $r['id'] ?>)" style="padding:8px 14px;border-radius:10px;border:none;background:rgba(99,102,241,.14);color:#818cf8;font-family:var(--sl-db);font-size:12px;font-weight:700;cursor:pointer;white-space:nowrap">✅ Reviewed</button>
        <button onclick="slReviewMastered(<?= $r['id'] ?>)" style="padding:8px 14px;border-radius:10px;border:none;background:rgba(16,185,129,.14);color:#10b981;font-family:var(--sl-db);font-size:12px;font-weight:700;cursor:pointer;white-space:nowrap">🎓 Mastered</button>
      </div>
    </div>
    <?php endforeach; ?>
    </div>
  <?php else: ?>
    <div class="sl-empty" style="padding:24px 20px">
      <div class="sl-ei">🎉</div>
      <h3>Nothing due for review</h3>
      <p>Add a note on what you studied when logging a session — we'll automatically remind you when it's time to revisit it.</p>
    </div>
  <?php endif; ?>
</div>

<!-- ── Live Session Timer ── -->
<div class="ls-card" id="lsCard">

  <!-- IDLE state -->
  <div class="ls-idle" id="lsIdle">
    <div class="ls-idle-left">
      <div class="ls-idle-icon">🎯</div>
      <div>
        <div class="ls-idle-title">Live Study Session</div>
        <div class="ls-idle-sub">Start a timer — auto-saves when you stop</div>
      </div>
    </div>
    <button class="ls-start-btn" onclick="lsOpen()">
      <svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><polygon points="5,3 19,12 5,21"/></svg>
      Start Session
    </button>
  </div>

  <!-- RUNNING state -->
  <div class="ls-running" id="lsRunning">

    <!-- Top: Live badge + subject picker -->
    <div class="ls-running-top">
      <div class="ls-live-badge"><span class="ls-live-dot"></span> Live</div>
      <div class="ls-sub-row" style="max-width:240px">
        <span class="ls-sub-dot" id="lsSubDot"></span>
        <select id="ls_subject_run" class="ls-sub-select" onchange="lsSubjectChanged()">
          <option value="">— Select subject —</option>
          <?php foreach ($subjectsList as $sub): ?>
          <option value="<?= $sub['id'] ?>" data-color="<?= htmlspecialchars($sub['color']) ?>">
            <?= htmlspecialchars($sub['name']) ?>
          </option>
          <?php endforeach; ?>
        </select>
      </div>
    </div>

    <!-- SVG Ring Timer -->
    <div class="ls-timer-wrap">
      <div class="ls-timer-ring">
        <svg width="200" height="200" viewBox="0 0 200 200">
          <!-- Background ring -->
          <circle cx="100" cy="100" r="88" fill="none" stroke="var(--bg-secondary)" stroke-width="8"/>
          <!-- Progress ring (animated via JS) -->
          <circle id="lsRingProgress" cx="100" cy="100" r="88"
            fill="none" stroke="url(#ls-grad)" stroke-width="8"
            stroke-linecap="round"
            stroke-dasharray="552.9"
            stroke-dashoffset="552.9"
            style="transform:rotate(-90deg);transform-origin:center;transition:stroke-dashoffset .8s ease"/>
          <defs>
            <linearGradient id="ls-grad" x1="0%" y1="0%" x2="100%" y2="100%">
              <stop offset="0%" stop-color="#6366f1"/>
              <stop offset="50%" stop-color="#a855f7"/>
              <stop offset="100%" stop-color="#22c55e"/>
            </linearGradient>
          </defs>
        </svg>
        <div class="ls-timer-inner">
          <div class="ls-timer-display" id="lsDisplay">00:00:00</div>
          <div class="ls-timer-sub" id="lsSubLabel">Ready</div>
        </div>
      </div>
    </div>

    <!-- Elapsed bar -->
    <div class="ls-elapsed-bar">
      <div class="ls-elapsed-fill" id="lsElapsedBar"></div>
    </div>

    <!-- Controls -->
    <div class="ls-controls">
      <button class="ls-pause-btn" id="lsPauseBtn" onclick="lsTogglePause()">⏸ Pause</button>
      <button class="ls-stop-btn" onclick="lsStop()">⏹ Stop & Save</button>
    </div>
    <div style="text-align:center;margin-top:10px">
      <button onclick="lsDiscardConfirm()" style="background:none;border:none;color:var(--text-muted);font-size:12px;font-weight:600;cursor:pointer;padding:4px 8px;border-radius:6px;transition:color .15s" onmouseover="this.style.color='#ef4444'" onmouseout="this.style.color='var(--text-muted)'">
        🗑 Discard &amp; Reset
      </button>
    </div>

  </div>
</div>

<!-- ════ CUSTOM TOAST POPUP ════ -->
<div class="sl-toast-ov" id="slToastOv">
  <div class="sl-toast" id="slToast">
    <div class="sl-toast-icon" id="slToastIcon">⚠️</div>
    <div class="sl-toast-title" id="slToastTitle">Are you sure?</div>
    <div class="sl-toast-msg"   id="slToastMsg"></div>
    <div class="sl-toast-btns" id="slToastBtns"></div>
  </div>
</div>

<!-- Simple snack bar -->
<div class="sl-snack-ov" id="slSnackOv">
  <div class="sl-snack" id="slSnackMsg">✅ Done!</div>
</div>

<!-- ════ LIVE SAVE MODAL ════ -->
<div class="sl-modal-ov" id="lsSaveModal">
  <div class="sl-modal" style="max-width:400px">
    <div class="sl-modal-hd">
      <div class="sl-modal-title">💾 Save Session</div>
      <button class="sl-modal-close" onclick="lsCancelSave()">✕</button>
    </div>
    <div id="lsSaveMsg" class="sl-alert"></div>

    <div style="background:var(--bg-secondary);border-radius:14px;padding:16px;margin-bottom:18px;text-align:center">
      <div style="font-size:11px;font-weight:700;color:var(--text-muted);text-transform:uppercase;letter-spacing:.6px;margin-bottom:6px">Session Duration</div>
      <div style="font-family:var(--sl-df);font-size:36px;font-weight:900;letter-spacing:-2px;background:linear-gradient(135deg,#818cf8,#c084fc);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text" id="lsSaveDuration">0h 0m</div>
    </div>

    <div class="sl-fg">
      <label>Subject *</label>
      <select id="ls_subject_save" class="sl-inp">
        <option value="">— Select subject —</option>
        <?php foreach ($subjectsList as $sub): ?>
        <option value="<?= $sub['id'] ?>"><?= htmlspecialchars($sub['name']) ?></option>
        <?php endforeach; ?>
      </select>
    </div>

    <div class="sl-fg">
      <label>Notes <span style="text-transform:none;letter-spacing:0;font-weight:400">(optional)</span></label>
      <textarea id="ls_notes_save" class="sl-inp ls-notes-inp" rows="2" placeholder="What did you study?"></textarea>
    </div>

    <div style="display:flex;gap:10px">
      <button onclick="lsCancelSave()" style="flex:1;padding:12px;border-radius:12px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary);font-family:var(--sl-db);font-size:13px;font-weight:700;cursor:pointer">Discard</button>
      <button id="lsSaveBtn" onclick="lsConfirmSave()" class="sl-save-btn" style="flex:2;margin-top:0">Save Session</button>
    </div>
  </div>
</div>


<!-- ── Session log ── -->
<div class="sl-card">
  <div class="sl-card-hd">
    <div class="sl-card-t">📋 Study Sessions</div>
    <span class="sl-card-meta"><?= count($sessions) ?> sessions &bull; <?= floor($totalMins/60) ?>h <?= $totalMins%60 ?>m</span>
  </div>

  <?php if ($sessions): ?>
  <div class="sl-row-hd">
    <span>Date</span><span>Subject</span><span>Duration</span><span>Notes</span><span></span>
  </div>
  <?php foreach ($sessions as $s): ?>
  <div class="sl-row">
    <div class="sl-date">
      <strong><?= date('M j, Y', strtotime($s['date'])) ?></strong>
      <?= date('D', strtotime($s['date'])) ?>
    </div>
    <div class="sl-subj">
      <span class="sl-dot" style="background:<?= htmlspecialchars($s['color']) ?>"></span>
      <?= htmlspecialchars($s['subject_name']) ?>
    </div>
    <div class="sl-dur"><?= floor($s['duration_minutes']/60) ?>h <?= $s['duration_minutes']%60 ?>m</div>
    <div class="sl-notes">
      <span class="sl-notes-txt"><?= $s['notes'] ? htmlspecialchars($s['notes']) : '<span style="color:var(--text-muted)">—</span>' ?></span>
    </div>
    <div class="sl-del"><button onclick="slDelete(<?= $s['id'] ?>)" title="Delete">🗑</button></div>
  </div>
  <?php endforeach; ?>
  <?php else: ?>
  <div class="sl-empty">
    <div class="sl-ei">⏱️</div>
    <h3>No sessions in this period</h3>
    <p>Click "＋ Log Session" to start tracking</p>
  </div>
  <?php endif; ?>
</div>

</div><!-- .slp -->


<!-- ════ LOG SESSION MODAL ════ -->
<div class="sl-modal-ov" id="slAddModal">
  <div class="sl-modal">
    <div class="sl-modal-hd">
      <div class="sl-modal-title">➕ Log Study Session</div>
      <button class="sl-modal-close" onclick="document.getElementById('slAddModal').classList.remove('active')">✕</button>
    </div>
    <div id="slMsg" class="sl-alert"></div>

    <div class="sl-fg">
      <label>Subject *</label>
      <select id="ses_subject" class="sl-inp">
        <option value="">— Select subject —</option>
        <?php foreach ($subjectsList as $sub): ?>
        <option value="<?= $sub['id'] ?>"><?= htmlspecialchars($sub['name']) ?></option>
        <?php endforeach; ?>
      </select>
    </div>

    <div class="sl-fg">
      <label>Date</label>
      <input type="date" id="ses_date" class="sl-inp" value="<?= date('Y-m-d') ?>">
    </div>

    <div class="sl-fg">
      <label>Quick Duration</label>
      <div class="sl-dur-picks">
        <button class="sl-dpick" onclick="slSetDur(0,30,this)">30m</button>
        <button class="sl-dpick" onclick="slSetDur(1,0,this)">1h</button>
        <button class="sl-dpick" onclick="slSetDur(1,30,this)">1h 30m</button>
        <button class="sl-dpick" onclick="slSetDur(2,0,this)">2h</button>
        <button class="sl-dpick" onclick="slSetDur(2,30,this)">2h 30m</button>
        <button class="sl-dpick" onclick="slSetDur(3,0,this)">3h</button>
      </div>
    </div>

    <div class="sl-fg2">
      <div class="sl-fg" style="margin-bottom:0">
        <label>Hours</label>
        <input type="number" id="ses_hours" class="sl-inp" min="0" max="24" value="0">
      </div>
      <div class="sl-fg" style="margin-bottom:0">
        <label>Minutes</label>
        <input type="number" id="ses_minutes" class="sl-inp" min="0" max="59" value="30">
      </div>
    </div>
    <div style="margin-bottom:16px"></div>

    <div class="sl-fg">
      <label>Notes <span style="text-transform:none;letter-spacing:0;font-weight:400">(optional)</span></label>
      <textarea id="ses_notes" class="sl-inp" rows="2" style="resize:vertical" placeholder="What did you study?"></textarea>
    </div>

    <button id="sesSaveBtn" class="sl-save-btn" onclick="slSave()">Save Session</button>
  </div>
</div>


<!-- ════ POMODORO MODAL ════ -->
<div class="sl-modal-ov" id="slPomModal">
  <div class="sl-modal">
    <div class="sl-modal-hd">
      <div class="sl-modal-title">⏱️ Pomodoro Timer</div>
      <button class="sl-modal-close" onclick="pomClose()">✕</button>
    </div>

    <div class="pm-mode-tabs">
      <button id="pm-btn-work"  class="pm-mtb active" onclick="pomSetMode('work')">🍅 Work</button>
      <button id="pm-btn-short" class="pm-mtb"        onclick="pomSetMode('short')">☕ Short</button>
      <button id="pm-btn-long"  class="pm-mtb"        onclick="pomSetMode('long')">🌿 Long</button>
    </div>

    <div class="sl-fg">
      <label>Subject (auto-log after work)</label>
      <select id="pm-subject" class="sl-inp">
        <option value="">— Select subject —</option>
        <?php foreach ($subjectsList as $sub): ?>
        <option value="<?= $sub['id'] ?>"><?= htmlspecialchars($sub['name']) ?></option>
        <?php endforeach; ?>
      </select>
    </div>

    <div class="pm-ring-wrap">
      <svg width="180" height="180" style="transform:rotate(-90deg)">
        <circle cx="90" cy="90" r="80" fill="none" stroke="var(--bg-secondary)" stroke-width="10"/>
        <circle id="pm-ring" cx="90" cy="90" r="80" fill="none" stroke="url(#pm-grad)"
          stroke-width="10" stroke-linecap="round" stroke-dasharray="502.65" stroke-dashoffset="0"
          style="transition:stroke-dashoffset .9s linear"/>
        <defs>
          <linearGradient id="pm-grad" x1="0%" y1="0%" x2="100%" y2="0%">
            <stop offset="0%" stop-color="#6366f1"/>
            <stop offset="100%" stop-color="#a855f7"/>
          </linearGradient>
        </defs>
      </svg>
      <div style="position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center">
        <div id="pm-time" style="font-family:var(--sl-df);font-size:40px;font-weight:900;color:var(--text-primary);letter-spacing:-2px;font-variant-numeric:tabular-nums">25:00</div>
        <div id="pm-label" style="font-size:12px;color:var(--text-muted);margin-top:3px;font-weight:600">Work Session</div>
      </div>
    </div>

    <div style="display:flex;justify-content:center;gap:8px;margin-bottom:8px">
      <div id="pm-dot-1" style="width:10px;height:10px;border-radius:50%;background:var(--accent)"></div>
      <div id="pm-dot-2" style="width:10px;height:10px;border-radius:50%;background:var(--border)"></div>
      <div id="pm-dot-3" style="width:10px;height:10px;border-radius:50%;background:var(--border)"></div>
      <div id="pm-dot-4" style="width:10px;height:10px;border-radius:50%;background:var(--border)"></div>
    </div>
    <div style="text-align:center;font-size:12px;color:var(--text-muted);margin-bottom:18px">
      <span id="pm-session-count">0</span> / 4 sessions
    </div>

    <div class="pm-ctrl">
      <button id="pm-start-btn" class="pm-start" onclick="pomToggle()">▶ Start</button>
      <button class="pm-reset" onclick="pomReset()">↺ Reset</button>
    </div>

    <div id="pm-log-status" class="sl-alert"></div>

    <div class="pm-custom">
      <div class="pm-custom-lbl">⚙️ Custom Durations (minutes)</div>
      <div style="display:grid;grid-template-columns:1fr 1fr 1fr;gap:10px">
        <div>
          <label style="display:block;font-size:11px;font-weight:700;color:var(--text-muted);margin-bottom:6px">🍅 Work</label>
          <input type="number" id="pm-custom-work"  class="sl-inp" value="25" min="1" max="90" onchange="pomUpdateCustom()">
        </div>
        <div>
          <label style="display:block;font-size:11px;font-weight:700;color:var(--text-muted);margin-bottom:6px">☕ Short</label>
          <input type="number" id="pm-custom-short" class="sl-inp" value="5"  min="1" max="30" onchange="pomUpdateCustom()">
        </div>
        <div>
          <label style="display:block;font-size:11px;font-weight:700;color:var(--text-muted);margin-bottom:6px">🌿 Long</label>
          <input type="number" id="pm-custom-long"  class="sl-inp" value="15" min="1" max="60" onchange="pomUpdateCustom()">
        </div>
      </div>
    </div>
  </div>
</div>

<script>
// ══════════════════════════════════════
// CUSTOM TOAST / SNACK HELPERS
// ══════════════════════════════════════
function slToast(opts) {
  // opts: { icon, title, msg, buttons:[{label,cls,cb}] }
  document.getElementById('slToastIcon').textContent  = opts.icon  || '💬';
  document.getElementById('slToastTitle').textContent = opts.title || '';
  document.getElementById('slToastMsg').textContent   = opts.msg   || '';
  var btns = document.getElementById('slToastBtns');
  btns.innerHTML = '';
  (opts.buttons || []).forEach(function(b){
    var el = document.createElement('button');
    el.className = 'sl-toast-btn ' + (b.cls || 'secondary');
    el.textContent = b.label;
    el.onclick = function(){
      document.getElementById('slToastOv').classList.remove('show');
      if (b.cb) b.cb();
    };
    btns.appendChild(el);
  });
  document.getElementById('slToastOv').classList.add('show');
}

function slSnack(msg, duration) {
  var el = document.getElementById('slSnackMsg');
  el.textContent = msg;
  var ov = document.getElementById('slSnackOv');
  ov.classList.add('show');
  clearTimeout(ov._t);
  ov._t = setTimeout(function(){ ov.classList.remove('show'); }, duration || 2800);
}


// ══════════════════════════════════════
// LIVE SESSION TIMER
// ══════════════════════════════════════
var LS = {
  running:false, paused:false, startTime:null,
  elapsed:0, interval:null, MAX_SECS:3600,
};
var LS_CIRC = 552.9; // 2π × 88

// Restore from sessionStorage
(function(){
  try {
    var saved = sessionStorage.getItem('ls_state');
    if (!saved) return;
    var s = JSON.parse(saved);
    if (!s.running) return;
    // Validate — if saved timestamp is more than 12h ago, discard
    var now = Date.now();
    if (s.savedAt && (now - s.savedAt) > 43200000) {
      sessionStorage.removeItem('ls_state'); return;
    }
    LS.running = true;
    LS.paused  = s.paused || false;
    // Recalculate elapsed: saved elapsed + time since last save (if was running)
    LS.elapsed = s.elapsed || 0;
    if (!s.paused && s.savedAt) {
      LS.elapsed += Math.floor((now - s.savedAt) / 1000);
    }
    LS.startTime = LS.paused ? null : Date.now();
    window._lsRestoreSubject = s.subjectId || '';
  } catch(e){ sessionStorage.removeItem('ls_state'); }
})();

function lsSaveSS() {
  try {
    // Save current accumulated elapsed (exclude current running segment — recalc on restore)
    var snapElapsed = LS.elapsed;
    // If running (not paused), snapshot elapsed up to now
    if (!LS.paused && LS.startTime) {
      snapElapsed = LS.elapsed + Math.floor((Date.now() - LS.startTime) / 1000);
    }
    sessionStorage.setItem('ls_state', JSON.stringify({
      running:   LS.running,
      paused:    LS.paused,
      elapsed:   snapElapsed,
      savedAt:   Date.now(),
      subjectId: document.getElementById('ls_subject_run').value,
    }));
  } catch(e){}
}

function lsGetTotalSecs() {
  var t = LS.elapsed;
  if (LS.running && !LS.paused && LS.startTime)
    t += Math.floor((Date.now() - LS.startTime) / 1000);
  return t;
}

function lsFmt(secs) {
  var h=Math.floor(secs/3600), m=Math.floor((secs%3600)/60), s=secs%60;
  return String(h).padStart(2,'0')+':'+String(m).padStart(2,'0')+':'+String(s).padStart(2,'0');
}

function lsSubjectChanged() {
  var sel = document.getElementById('ls_subject_run');
  var opt = sel.options[sel.selectedIndex];
  var col = (opt && opt.dataset.color) ? opt.dataset.color : 'var(--border)';
  document.getElementById('lsSubDot').style.background = col;
  lsUpdateDisplay();
}

function lsUpdateDisplay() {
  var total = lsGetTotalSecs();
  document.getElementById('lsDisplay').textContent = lsFmt(total);

  // Ring progress — fills over 1 hour
  var pct    = Math.min(1, total / LS.MAX_SECS);
  var offset = LS_CIRC * (1 - pct);
  var ring   = document.getElementById('lsRingProgress');
  if (ring) ring.setAttribute('stroke-dashoffset', offset);

  // Elapsed bar
  document.getElementById('lsElapsedBar').style.width = (pct * 100) + '%';

  // Subject label
  var sel = document.getElementById('ls_subject_run');
  var opt = sel.options[sel.selectedIndex];
  document.getElementById('lsSubLabel').textContent =
    (opt && opt.value) ? opt.text : 'Select a subject ↑';
}

function lsOpen() {
  LS.running = true; LS.paused = false;
  LS.elapsed = 0; LS.startTime = Date.now();
  document.getElementById('lsIdle').classList.add('hidden');
  document.getElementById('lsRunning').classList.add('visible');
  document.getElementById('lsCard').classList.add('active-session');
  lsUpdateDisplay();
  LS.interval = setInterval(function(){ lsUpdateDisplay(); lsSaveSS(); }, 1000);
}

function lsTogglePause() {
  var btn  = document.getElementById('lsPauseBtn');
  var run  = document.getElementById('lsRunning');
  var bar  = document.getElementById('lsElapsedBar');
  if (!LS.paused) {
    LS.elapsed += Math.floor((Date.now() - LS.startTime) / 1000);
    LS.startTime = null; LS.paused = true;
    clearInterval(LS.interval); LS.interval = null;
    btn.innerHTML = '▶ Resume'; btn.classList.add('paused');
    run.classList.add('ls-timer-paused');
    bar.classList.add('paused');
  } else {
    LS.startTime = Date.now(); LS.paused = false;
    btn.innerHTML = '⏸ Pause'; btn.classList.remove('paused');
    run.classList.remove('ls-timer-paused');
    bar.classList.remove('paused');
    LS.interval = setInterval(function(){ lsUpdateDisplay(); lsSaveSS(); }, 1000);
  }
  lsUpdateDisplay(); lsSaveSS();
}

function lsStop() {
  // Accumulate elapsed
  if (!LS.paused && LS.startTime) {
    LS.elapsed += Math.floor((Date.now() - LS.startTime) / 1000);
    LS.startTime = null;
  }
  clearInterval(LS.interval); LS.interval = null;

  var totalSecs = LS.elapsed;

  if (totalSecs < 60) {
    slToast({
      icon:'⚠️', title:'Too short!',
      msg:'Your session is less than 1 minute. Do you want to discard it?',
      buttons:[
        { label:'Keep Going', cls:'primary', cb: function(){
          // Resume
          LS.startTime = Date.now(); LS.paused = false;
          document.getElementById('lsPauseBtn').innerHTML = '⏸ Pause';
          document.getElementById('lsPauseBtn').classList.remove('paused');
          LS.interval = setInterval(function(){ lsUpdateDisplay(); lsSaveSS(); }, 1000);
        }},
        { label:'Discard', cls:'danger', cb: lsReset },
      ]
    });
    return;
  }

  // Show save modal
  var h = Math.floor(totalSecs/3600), m = Math.floor((totalSecs%3600)/60);
  document.getElementById('lsSaveDuration').textContent = h+'h '+m+'m';
  var runSub = document.getElementById('ls_subject_run').value;
  if (runSub) document.getElementById('ls_subject_save').value = runSub;
  document.getElementById('lsSaveMsg').style.display = 'none';
  document.getElementById('lsSaveModal').classList.add('active');
}

function lsDiscardConfirm() {
  var total = lsGetTotalSecs();
  var h = Math.floor(total/3600), m = Math.floor((total%3600)/60), s = total%60;
  var timeStr = h>0 ? h+'h '+m+'m' : m+'m '+s+'s';
  slToast({
    icon:'🗑️', title:'Discard session?',
    msg:'This will delete your '+timeStr+' session. Cannot be undone.',
    buttons:[
      { label:'Cancel',  cls:'secondary', cb: function(){} },
      { label:'Discard', cls:'danger',    cb: function(){ lsReset(); slSnack('Session discarded'); } },
    ]
  });
}

function lsCancelSave() {
  slToast({
    icon:'🗑️', title:'Discard session?',
    msg:'Your '+ lsFmt(LS.elapsed) +' session will be lost.',
    buttons:[
      { label:'Keep It', cls:'primary', cb: function(){
        document.getElementById('lsSaveModal').classList.add('active');
      }},
      { label:'Discard', cls:'danger', cb: function(){
        document.getElementById('lsSaveModal').classList.remove('active');
        lsReset();
      }},
    ]
  });
}

async function lsConfirmSave() {
  var subId = document.getElementById('ls_subject_save').value;
  if (!subId) {
    var m = document.getElementById('lsSaveMsg');
    m.className='sl-alert error'; m.textContent='⚠️ Please select a subject.';
    m.style.display='block'; return;
  }
  var totalSecs = LS.elapsed;
  var hours = Math.floor(totalSecs/3600);
  var mins  = Math.max(1, Math.floor((totalSecs%3600)/60));

  var btn = document.getElementById('lsSaveBtn');
  btn.disabled=true; btn.textContent='⏳ Saving...';

  try {
    var fd=new FormData();
    fd.append('action','add'); fd.append('subject_id',subId);
    fd.append('date', new Date().toISOString().split('T')[0]);
    fd.append('hours',hours); fd.append('minutes',mins);
    fd.append('notes', document.getElementById('ls_notes_save').value || '⏱️ Live session');

    var res  = await fetch(location.href,{method:'POST',body:fd,headers:{'X-Requested-With':'XMLHttpRequest'}});
    var data = await res.json();

    if (data.success) {
      sessionStorage.removeItem('ls_state');
      document.getElementById('lsSaveModal').classList.remove('active');
      var pointsSuffix = data.points_earned > 0 ? ' +' + data.points_earned + ' 🏆' : '';
      slSnack('✅ Session saved! ' + hours+'h '+mins+'m' + pointsSuffix);
      setTimeout(function(){ location.reload(); }, 900);
    } else {
      var m=document.getElementById('lsSaveMsg');
      m.className='sl-alert error'; m.textContent='⚠️ '+data.message;
      m.style.display='block';
      btn.disabled=false; btn.textContent='Save Session';
    }
  } catch(e) {
    var m=document.getElementById('lsSaveMsg');
    m.className='sl-alert error'; m.textContent='⚠️ Network error.';
    m.style.display='block';
    btn.disabled=false; btn.textContent='Save Session';
  }
}

function lsReset() {
  clearInterval(LS.interval);
  LS.running=false; LS.paused=false; LS.elapsed=0; LS.startTime=null; LS.interval=null;
  document.getElementById('lsRunning').classList.remove('visible');
  document.getElementById('lsIdle').classList.remove('hidden');
  document.getElementById('lsCard').classList.remove('active-session');
  document.getElementById('lsDisplay').textContent='00:00:00';
  document.getElementById('lsElapsedBar').style.width='0%';
  var ring=document.getElementById('lsRingProgress');
  if(ring) ring.setAttribute('stroke-dashoffset', LS_CIRC);
  document.getElementById('lsPauseBtn').innerHTML='⏸ Pause';
  document.getElementById('lsPauseBtn').classList.remove('paused');
  document.getElementById('lsSubDot').style.background='var(--border)';
  document.getElementById('ls_notes_save').value='';
  sessionStorage.removeItem('ls_state');
}

// Restore if timer was running before page refresh
window.addEventListener('load', function(){
  if (!LS.running) return;
  document.getElementById('lsIdle').classList.add('hidden');
  document.getElementById('lsRunning').classList.add('visible');
  document.getElementById('lsCard').classList.add('active-session');
  if (window._lsRestoreSubject) {
    document.getElementById('ls_subject_run').value = window._lsRestoreSubject;
    lsSubjectChanged();
  }
  if (LS.paused) {
    document.getElementById('lsPauseBtn').innerHTML = '▶ Resume';
    document.getElementById('lsPauseBtn').classList.add('paused');
    document.getElementById('lsRunning').classList.add('ls-timer-paused');
    document.getElementById('lsElapsedBar').classList.add('paused');
  } else {
    LS.interval = setInterval(function(){ lsUpdateDisplay(); lsSaveSS(); }, 1000);
  }
  lsUpdateDisplay();
});

window.addEventListener('beforeunload', function(e){
  if (LS.running) { lsSaveSS(); e.preventDefault(); e.returnValue=''; }
});

// ── Quick duration picker ──────────────────────────────────────────
function slSetDur(h, m, btn) {
  document.getElementById('ses_hours').value   = h;
  document.getElementById('ses_minutes').value = m;
  document.querySelectorAll('.sl-dpick').forEach(b => b.classList.remove('active'));
  btn.classList.add('active');
}

// ── Save session ──────────────────────────────────────────────────
async function slSave() {
  var subId = document.getElementById('ses_subject').value;
  var hours = parseInt(document.getElementById('ses_hours').value)   || 0;
  var mins  = parseInt(document.getElementById('ses_minutes').value) || 0;

  if (!subId)          { slAlert('Please select a subject.', 'error'); return; }
  if (hours+mins <= 0) { slAlert('Please enter a duration.', 'error'); return; }

  var btn = document.getElementById('sesSaveBtn');
  btn.disabled = true; btn.innerHTML = '⏳ Saving...';

  try {
    var fd = new FormData();
    fd.append('action','add'); fd.append('subject_id',subId);
    fd.append('date',   document.getElementById('ses_date').value);
    fd.append('hours',  hours); fd.append('minutes', mins);
    fd.append('notes',  document.getElementById('ses_notes').value);

    var res  = await fetch(location.href, {method:'POST', body:fd, headers:{'X-Requested-With':'XMLHttpRequest'}});
    var data = await res.json();

    if (data.success) {
      slAlert(data.message, 'success');
      document.getElementById('ses_subject').value = '';
      document.getElementById('ses_hours').value   = '0';
      document.getElementById('ses_minutes').value = '30';
      document.getElementById('ses_notes').value   = '';
      document.querySelectorAll('.sl-dpick').forEach(b => b.classList.remove('active'));
      setTimeout(() => { document.getElementById('slAddModal').classList.remove('active'); location.reload(); }, 900);
    } else if (data.locked) {
      btn.disabled = false; btn.innerHTML = 'Save Session';
      document.getElementById('slAddModal').classList.remove('active');
      slToast({
        icon: '🔒', title: 'Account Locked by System',
        msg: data.message,
        buttons: [ { label: 'OK', cls: 'danger', cb: function(){ location.reload(); } } ]
      });
    } else if (data.warn) {
      btn.disabled = false; btn.innerHTML = 'Save Session';
      slToast({
        icon: '⚠️', title: 'Unrealistic Session',
        msg: data.message,
        buttons: [ { label: 'I Understand', cls: 'primary', cb: null } ]
      });
    } else {
      slAlert(data.message, 'error');
      btn.disabled = false; btn.innerHTML = 'Save Session';
    }
  } catch(e) {
    slAlert('Connection error. Please try again.', 'error');
    btn.disabled = false; btn.innerHTML = 'Save Session';
  }
}

function slAlert(msg, type) {
  var el = document.getElementById('slMsg');
  el.className = 'sl-alert ' + type;
  el.textContent = (type==='success' ? '✅ ' : '⚠️ ') + msg;
  el.style.display = 'block';
}

// ── Spaced repetition actions ──────────────────────────────────────
async function slReviewDone(id) {
  var row = document.getElementById('slSrRow'+id);
  var fd = new FormData(); fd.append('action','sr_review_done'); fd.append('id', id);
  try {
    var res  = await fetch(location.href, {method:'POST', body:fd, headers:{'X-Requested-With':'XMLHttpRequest'}});
    var data = await res.json();
    if (data.success) {
      slSnack('✅ ' + data.message);
      if (row) { row.style.transition='opacity .25s, transform .25s'; row.style.opacity='0'; row.style.transform='translateX(8px)'; }
      setTimeout(function(){ location.reload(); }, 500);
    } else {
      slSnack('⚠️ ' + (data.message || 'Something went wrong.'));
    }
  } catch(e) { slSnack('⚠️ Network error.'); }
}

async function slReviewMastered(id) {
  var row = document.getElementById('slSrRow'+id);
  var fd = new FormData(); fd.append('action','sr_mastered'); fd.append('id', id);
  try {
    var res  = await fetch(location.href, {method:'POST', body:fd, headers:{'X-Requested-With':'XMLHttpRequest'}});
    var data = await res.json();
    if (data.success) {
      slSnack('🎓 ' + data.message);
      if (row) { row.style.transition='opacity .25s, transform .25s'; row.style.opacity='0'; row.style.transform='translateX(8px)'; }
      setTimeout(function(){ location.reload(); }, 500);
    } else {
      slSnack('⚠️ ' + (data.message || 'Something went wrong.'));
    }
  } catch(e) { slSnack('⚠️ Network error.'); }
}

async function slDelete(id) {
  slToast({
    icon:'🗑️', title:'Delete session?',
    msg:'This study session will be permanently removed.',
    buttons:[
      { label:'Cancel',  cls:'secondary', cb: null },
      { label:'Delete',  cls:'danger', cb: async function(){
        var fd=new FormData(); fd.append('action','delete'); fd.append('id',id);
        var res  = await fetch(location.href,{method:'POST',body:fd,headers:{'X-Requested-With':'XMLHttpRequest'}});
        var data = await res.json();
        if(data.success){ slSnack('🗑️ Session deleted'); setTimeout(()=>location.reload(),700); }
      }},
    ]
  });
}

// Close on backdrop
['slAddModal','slPomModal'].forEach(id => {
  document.getElementById(id).addEventListener('click', function(e){
    if (e.target !== this) return;
    if (id === 'slPomModal') { pomClose(); return; }
    this.classList.remove('active');
  });
});


// ══════════════════════════════════════
// POMODORO
// ══════════════════════════════════════
var PM = {
  mode:'work', durations:{work:25*60,short:5*60,long:15*60},
  total:25*60, remaining:25*60, running:false, interval:null, sessions:0,
};
var CIRC = 502.65;
function pmEl(id){ return document.getElementById(id); }

function pomSetMode(mode) {
  if (PM.running) return;
  PM.mode = mode; PM.total = PM.durations[mode]; PM.remaining = PM.total;
  pomUpdateDisplay();
  ['work','short','long'].forEach(m => pmEl('pm-btn-'+m).classList.toggle('active', m===mode));
}

function pomUpdateCustom() {
  PM.durations.work  = Math.max(1,Math.min(90, parseInt(pmEl('pm-custom-work').value)  ||25))*60;
  PM.durations.short = Math.max(1,Math.min(30, parseInt(pmEl('pm-custom-short').value) ||5)) *60;
  PM.durations.long  = Math.max(1,Math.min(60, parseInt(pmEl('pm-custom-long').value)  ||15))*60;
  if (!PM.running){ PM.total=PM.durations[PM.mode]; PM.remaining=PM.total; pomUpdateDisplay(); }
}

function pomUpdateDisplay() {
  var m=Math.floor(PM.remaining/60), s=PM.remaining%60;
  pmEl('pm-time').textContent = String(m).padStart(2,'0')+':'+String(s).padStart(2,'0');
  pmEl('pm-label').textContent = {work:'Work Session',short:'Short Break',long:'Long Break'}[PM.mode];
  var pct = PM.total>0 ? PM.remaining/PM.total : 0;
  pmEl('pm-ring').setAttribute('stroke-dashoffset', CIRC*pct);
  for(var i=1;i<=4;i++) pmEl('pm-dot-'+i).style.background = i<=PM.sessions ? 'var(--accent)' : 'var(--border)';
  pmEl('pm-session-count').textContent = PM.sessions;
  pmEl('pm-start-btn').textContent = PM.running ? '⏸ Pause' : (PM.remaining<PM.total ? '▶ Resume' : '▶ Start');
}

function pomTick() {
  if(PM.remaining<=0){ clearInterval(PM.interval); PM.running=false; pomOnComplete(); return; }
  PM.remaining--; pomUpdateDisplay();
}

function pomOnComplete() {
  try {
    var ctx=new(window.AudioContext||window.webkitAudioContext)();
    [0,.3,.6].forEach((t,i)=>{
      var o=ctx.createOscillator(),g=ctx.createGain();
      o.connect(g); g.connect(ctx.destination);
      o.frequency.value=[523,659,784][i]; o.type='sine';
      g.gain.setValueAtTime(.3,ctx.currentTime+t);
      g.gain.exponentialRampToValueAtTime(.001,ctx.currentTime+t+.4);
      o.start(ctx.currentTime+t); o.stop(ctx.currentTime+t+.5);
    });
  } catch(e){}
  if(PM.mode==='work'){
    PM.sessions++; pomUpdateDisplay(); pomAutoLog();
    pomSetMode(PM.sessions%4===0 ? 'long' : 'short');
  } else { pomSetMode('work'); }
}

async function pomAutoLog() {
  var subId=pmEl('pm-subject').value;
  if(!subId){ pomStatus('⚠️ Select a subject to auto-log!','error'); return; }
  var mins=Math.round(PM.durations.work/60);
  try {
    var fd=new FormData();
    fd.append('action','add'); fd.append('subject_id',subId);
    fd.append('date',new Date().toISOString().split('T')[0]);
    fd.append('hours',Math.floor(mins/60)); fd.append('minutes',mins%60);
    fd.append('notes','🍅 Pomodoro session ('+mins+' min)');
    await fetch(location.href,{method:'POST',body:fd,headers:{'X-Requested-With':'XMLHttpRequest'}});
    pomStatus('✅ '+mins+' min logged!','success');
  } catch(e){ pomStatus('⚠️ Could not auto-log.','error'); }
}

function pomStatus(msg,type){
  var el=pmEl('pm-log-status');
  el.className='sl-alert '+type; el.textContent=msg; el.style.display='block';
  setTimeout(()=>el.style.display='none',4000);
}

function pomToggle(){
  if(PM.running){clearInterval(PM.interval);PM.running=false;}
  else{PM.running=true;PM.interval=setInterval(pomTick,1000);}
  pomUpdateDisplay();
}
function pomReset(){ clearInterval(PM.interval); PM.running=false; PM.remaining=PM.total; pomUpdateDisplay(); }
function pomClose(){
  if(PM.running){
    slToast({
      icon:'⏱️', title:'Timer is running', msg:'Stop and close the Pomodoro timer?',
      buttons:[
        {label:'Keep Running', cls:'secondary'},
        {label:'Stop & Close', cls:'danger', cb:function(){ pomCloseConfirmed(); }}
      ]
    });
    return;
  }
  pomCloseConfirmed();
}
function pomCloseConfirmed(){
  clearInterval(PM.interval); PM.running=false;
  if(PM.sessions>0) location.reload();
  document.getElementById('slPomModal').classList.remove('active');
}

pomUpdateDisplay();

<?php if ($abuseLocked): ?>
slToast({
  icon: '🔒', title: 'Account Locked by System',
  msg: 'Your account has been locked until <?= date('M j, g:i A', strtotime($abuseLockedUntil)) ?> due to repeated unrealistic session entries. Logging is disabled until then. Contact an admin if you think this is a mistake.',
  buttons: [ { label: 'OK', cls: 'danger', cb: null } ]
});
<?php endif; ?>
</script>

<?php require_once __DIR__ . '/includes/review-popup.php'; ?>
<?php require_once 'includes/footer.php'; renderFooter(); ?>