// Inject keyframes once
if (!document.getElementById("db-kf")) {
  const s = document.createElement("style");
  s.id = "db-kf";
  s.textContent = `
    @keyframes db-up   { from { opacity:0; transform:translateY(24px); } to { opacity:1; transform:translateY(0); } }
    @keyframes db-in   { from { opacity:0; } to { opacity:1; } }
    @keyframes db-glow { 0%,100% { opacity:.14; } 50% { opacity:.26; } }
    .db-widget {
      transition: transform 200ms ease, box-shadow 200ms ease, border-color 200ms ease;
    }
    .db-widget:hover {
      transform: translateY(-3px);
      box-shadow: 0 12px 40px rgba(0,0,0,.3), 0 0 0 1px rgba(206,148,69,.06);
      border-color: rgba(206,148,69,.12) !important;
    }
    .db-day-row {
      transition: background 140ms ease;
    }
    .db-day-row:hover { background: rgba(255,255,255,.04) !important; }
    .db-mock-btn { transition: box-shadow 200ms, transform 150ms; }
    .db-mock-btn:hover {
      transform: translateY(-2px);
      box-shadow: 0 10px 24px rgba(84,52,22,.16) !important;
    }
    .db-chip {
      transition: border-color 140ms, color 140ms, background 140ms;
    }
    .db-chip:hover {
      border-color: rgba(206,148,69,.15) !important;
      color: #c8893d !important;
      background: rgba(206,148,69,.06) !important;
    }
    .db-gen-btn { transition: box-shadow 180ms, transform 140ms; }
    .db-gen-btn:hover {
      transform: translateY(-1px);
      box-shadow: 0 8px 18px rgba(84,52,22,.12) !important;
    }
  `;
  document.head.appendChild(s);
}

const THEMES = {
  dark: {
    bg: "#151618", surface: "rgba(255,255,255,.05)", surfaceFocus: "rgba(124,106,143,.10)",
    bgArt: "radial-gradient(circle at 15% 18%, rgba(255,255,255,.08), transparent 24%), radial-gradient(circle at 84% 14%, rgba(210,214,220,.10), transparent 22%), radial-gradient(circle at 68% 78%, rgba(168,174,184,.08), transparent 28%), linear-gradient(180deg, #1c1d21 0%, #17181b 52%, #131416 100%)",
    border: "rgba(255,255,255,.08)", borderAccent: "rgba(188,194,204,.22)",
    text1: "#f3f4f6", text2: "#b0b5be", text3: "#7d838e",
    label: "#8a919d", rowHover: "rgba(255,255,255,.04)", todayRow: "rgba(255,255,255,.05)",
    glow: "radial-gradient(ellipse, rgba(255,255,255,.08) 0%, transparent 72%)",
    gradTitle: false,
    accentText: "#d6d9df", accentBg: "rgba(255,255,255,.08)", accentBorder: "rgba(198,204,214,.18)",
    dotFuture: "rgba(255,255,255,.06)", dotFutureBorder: "rgba(255,255,255,.12)",
    connector: "rgba(255,255,255,.05)", connectorDone: "rgba(214,218,226,.24)",
    searchBg: "rgba(255,255,255,.04)", searchBorder: "rgba(255,255,255,.1)",
    searchBorderFocus: "rgba(196,201,212,.56)", searchShadowFocus: "0 0 0 4px rgba(196,201,212,.10), 0 0 24px rgba(196,201,212,.10)",
    inputBg: "rgba(255,255,255,.03)", inputColor: "#f4f4f5",
    dropdownBg: "#161618", dropdownBorder: "rgba(255,255,255,.1)",
    dropdownShadow: "0 16px 48px rgba(0,0,0,.6)", dropdownHover: "rgba(255,255,255,.05)",
    chipBorder: "rgba(255,255,255,.1)", chipBg: "rgba(255,255,255,.03)", chipColor: "#71717a",
    errorBg: "rgba(239,68,68,.08)", errorBorder: "rgba(239,68,68,.2)", errorText: "#f87171",
    emptyIconBg: "rgba(255,255,255,.04)", emptyIconBorder: "rgba(255,255,255,.08)", emptyIcon: "#3f3f46",
    progressTrack: "rgba(255,255,255,.06)", timelineBg: "rgba(255,255,255,.02)", timelineBorder: "rgba(255,255,255,.07)",
    weakBg: "rgba(255,255,255,.04)", weakBorder: "rgba(255,255,255,.08)",
    planCtaBg: "rgba(255,255,255,.06)", planCtaBorder: "rgba(198,204,214,.14)",
    selectBg: "rgba(255,255,255,.04)", selectColor: "#71717a", selectBorder: "rgba(255,255,255,.1)",
    genBtnDisabledBg: "rgba(255,255,255,.05)", genBtnDisabledColor: "#52525b",
    primaryButton: "#7c6a8f",
    primaryGlow: "0 8px 18px rgba(43,31,56,.18)",
    secondaryButton: "rgba(124,106,143,.12)",
    secondaryButtonBorder: "rgba(124,106,143,.22)",
  },
  light: {
    bg: "#f4f5f7", surface: "rgba(255,255,255,.82)", surfaceFocus: "rgba(115,97,138,.04)",
    bgArt: "radial-gradient(circle at 14% 18%, rgba(255,255,255,.92), transparent 24%), radial-gradient(circle at 86% 16%, rgba(224,227,232,.72), transparent 22%), radial-gradient(circle at 72% 82%, rgba(209,214,221,.52), transparent 26%), linear-gradient(180deg, #f6f7f8 0%, #eef1f4 52%, #e8ecef 100%)",
    border: "rgba(88,96,110,.10)", borderAccent: "rgba(154,162,176,.20)",
    text1: "#0a0a0b", text2: "#52525b", text3: "#a1a1aa",
    label: "#8d95a1", rowHover: "rgba(255,255,255,.42)", todayRow: "rgba(255,255,255,.38)",
    glow: "transparent",
    gradTitle: false,
    accentText: "#6f7785", accentBg: "rgba(255,255,255,.48)", accentBorder: "rgba(171,178,189,.20)",
    dotFuture: "rgba(0,0,0,.06)", dotFutureBorder: "rgba(0,0,0,.12)",
    connector: "rgba(0,0,0,.07)", connectorDone: "rgba(154,162,176,.22)",
    searchBg: "rgba(255,255,255,.78)", searchBorder: "rgba(88,96,110,.12)",
    searchBorderFocus: "#9aa3b1", searchShadowFocus: "0 0 0 4px rgba(154,163,177,.10)",
    inputBg: "#fff", inputColor: "#0a0a0b",
    dropdownBg: "#fff", dropdownBorder: "rgba(0,0,0,.08)",
    dropdownShadow: "0 12px 40px rgba(0,0,0,.12)", dropdownHover: "#f9f9f8",
    chipBorder: "rgba(0,0,0,.09)", chipBg: "#fff", chipColor: "#52525b",
    errorBg: "rgba(239,68,68,.05)", errorBorder: "rgba(239,68,68,.15)", errorText: "#b91c1c",
    emptyIconBg: "rgba(0,0,0,.04)", emptyIconBorder: "rgba(0,0,0,.08)", emptyIcon: "#a1a1aa",
    progressTrack: "rgba(0,0,0,.06)", timelineBg: "#fff", timelineBorder: "rgba(0,0,0,.06)",
    weakBg: "rgba(255,255,255,.42)", weakBorder: "rgba(171,178,189,.14)",
    planCtaBg: "rgba(255,255,255,.42)", planCtaBorder: "rgba(171,178,189,.14)",
    selectBg: "#fff", selectColor: "#52525b", selectBorder: "rgba(0,0,0,.09)",
    genBtnDisabledBg: "rgba(0,0,0,.05)", genBtnDisabledColor: "#a1a1aa",
    primaryButton: "#73618a",
    primaryGlow: "0 10px 20px rgba(75,55,98,.14)",
    secondaryButton: "#f6f1fb",
    secondaryButtonBorder: "rgba(115,97,138,.18)",
  },
};

const SUGGESTIONS = [
  { label: "SWE Internship",  role: "Software Engineering Intern", type: "internship" },
  { label: "SWE Full-time",   role: "Software Engineer",           type: "full-time"  },
  { label: "PM Internship",   role: "Product Management Intern",   type: "internship" },
  { label: "Data Science",    role: "Data Scientist",              type: "full-time"  },
  { label: "ML Engineer",     role: "Machine Learning Engineer",   type: "full-time"  },
  { label: "Backend Dev",     role: "Backend Engineer",            type: "full-time"  },
  { label: "Frontend Dev",    role: "Frontend Engineer",           type: "full-time"  },
  { label: "DevOps",          role: "DevOps Engineer",             type: "full-time"  },
];

const TYPE_META = {
  dsa:           { label: "DSA",        color: "#c8893d", bg: "rgba(200,137,61,.12)"  },
  technical:     { label: "Technical",  color: "#c8893d", bg: "rgba(200,137,61,.12)"  },
  system_design: { label: "Sys Design", color: "#60a5fa", bg: "rgba(96,165,250,.12)"  },
  behavioral:    { label: "Behavioral", color: "#fbbf24", bg: "rgba(251,191,36,.12)"  },
  mixed:         { label: "Mixed",      color: "#a1a1aa", bg: "rgba(161,161,170,.08)" },
};

function up(delay = 0) {
  return { animation: `db-up 480ms cubic-bezier(.22,.68,0,1.15) ${delay}ms both` };
}

function DLabel({ children }) {
  return (
    <div style={{ font: "600 12px var(--font-sans)", letterSpacing: "0.11em", textTransform: "uppercase", color: "#3f3f46", marginBottom: 12 }}>
      {children}
    </div>
  );
}

function TypePill({ type }) {
  const m = TYPE_META[type] || TYPE_META.mixed;
  return (
    <span style={{ padding: "2px 8px", borderRadius: 4, font: "600 12px var(--font-sans)", letterSpacing: "0.04em", color: m.color, background: m.bg, flexShrink: 0 }}>
      {m.label}
    </span>
  );
}

// ─── Dashboard ───────────────────────────────────────────────────────────────

// Shimmer skeleton block — gray bar with travelling highlight. Matches the
// keyframes `skeletonShimmer` defined in ui_kits/app/index.html.
function SkeletonBox({ width = "100%", height = 16, radius = 6, T }) {
  return (
    <div style={{
      width, height, borderRadius: radius,
      background: `linear-gradient(90deg, ${T.border} 0%, ${T.surface} 50%, ${T.border} 100%)`,
      backgroundSize: "200% 100%",
      animation: "skeletonShimmer 1.4s ease-in-out infinite",
    }} />
  );
}

function DashboardSkeleton({ T }) {
  const widget = (lines) => (
    <div className="db-widget" style={{
      flex: "1 1 200px", borderRadius: 16, padding: "18px 20px",
      background: T.surface, border: `1px solid ${T.border}`, minHeight: 130,
      display: "flex", flexDirection: "column", gap: 12,
    }}>
      <SkeletonBox width="40%" height={10} T={T} />
      <SkeletonBox width="65%" height={24} T={T} />
      {lines >= 3 && <SkeletonBox width="80%" height={10} T={T} />}
    </div>
  );
  return (
    <>
      <div style={{ display: "flex", flexWrap: "wrap", gap: 14, marginBottom: 40, alignItems: "stretch" }}>
        {widget(3)}
        {widget(3)}
        {widget(3)}
        {widget(2)}
      </div>
      <div style={{ borderRadius: 16, border: `1px solid ${T.border}`, background: T.surface, padding: 20, display: "flex", flexDirection: "column", gap: 14 }}>
        {[0, 1, 2, 3, 4].map(i => (
          <div key={i} style={{ display: "flex", alignItems: "center", gap: 16 }}>
            <SkeletonBox width={22} height={22} radius={999} T={T} />
            <SkeletonBox width={`${50 + (i * 6) % 25}%`} height={14} T={T} />
          </div>
        ))}
      </div>
    </>
  );
}

function Dashboard({ user, onStartMock, onDaySelect, jobContext, onJobChange, token, plan, onPlanChange, darkMode = false, subscriptionPlan = "free", onUpgrade, streak = { current: 0, longest: 0, last: null }, sessionUsage = { used: 0, limit: 1 }, loading = false }) {
  const T = THEMES[darkMode ? "dark" : "light"];
  const hour      = new Date().getHours();
  const greeting  = hour < 12 ? "Good morning" : hour < 17 ? "Good afternoon" : "Good evening";
  const dateLabel = new Date().toLocaleDateString("en-US", { weekday: "long", month: "long", day: "numeric" });

  const [query,       setQuery]       = React.useState(jobContext?.role || "");
  const [company,     setCompany]     = React.useState(jobContext?.company || "");
  const [focused,     setFocused]     = React.useState(false);
  const [saved,       setSaved]       = React.useState(false);
  const [planLoading, setPlanLoading] = React.useState(false);
  const [planError,   setPlanError]   = React.useState("");
  const [days,        setDays]        = React.useState(14);
  const [jdEditing,   setJdEditing]   = React.useState(false);
  const [jdDraft,     setJdDraft]     = React.useState(jobContext?.jobDescription || "");
  const [jdExpanded,  setJdExpanded]  = React.useState(false);

  function saveJd() {
    onJobChange({ ...jobContext, jobDescription: jdDraft });
    setJdEditing(false);
  }

  const currentRole = jobContext?.role;

  const filteredSuggestions = query.length > 0
    ? SUGGESTIONS.filter(s =>
        s.label.toLowerCase().includes(query.toLowerCase()) ||
        s.role.toLowerCase().includes(query.toLowerCase()))
    : SUGGESTIONS;

  function apply(role) {
    onJobChange({ ...jobContext, role, company });
    setQuery(role);
    setFocused(false);
    setSaved(true);
    setTimeout(() => setSaved(false), 2000);
  }

  // Extract complete day objects from partial JSON as it streams in
  function extractStreamedDays(buf) {
    const planIdx = buf.indexOf('"plan"');
    if (planIdx === -1) return [];
    const arrStart = buf.indexOf("[", planIdx);
    if (arrStart === -1) return [];
    const days = [];
    let depth = 0, dayStart = -1;
    for (let i = arrStart; i < buf.length; i++) {
      const ch = buf[i];
      if (ch === "{") { if (depth === 0) dayStart = i; depth++; }
      else if (ch === "}") {
        depth--;
        if (depth === 0 && dayStart !== -1) {
          try { days.push(JSON.parse(buf.slice(dayStart, i + 1))); } catch {}
          dayStart = -1;
        }
      }
    }
    return days;
  }

  async function generatePlan() {
    if (!currentRole) { setPlanError("Set a target role first."); return; }
    if (!token)       { setPlanError("Sign in to generate a plan."); return; }
    setPlanLoading(true); setPlanError("");

    // Skeleton UI: render `days` placeholder rows immediately so the user
    // sees the timeline appear instantly. Real days replace placeholders
    // by index as they stream in from the server.
    const today = new Date();
    const skeletonPlan = {
      role: currentRole, company: jobContext?.company || "", days, weak_topics: [],
      plan: Array.from({ length: days }, (_, i) => {
        const d = new Date(today); d.setDate(d.getDate() + i);
        return {
          day: i + 1,
          date: d.toISOString().slice(0, 10),
          focus: "",
          type: "",
          tasks: [],
          mock: false,
          isPlaceholder: true,
        };
      }),
    };
    onPlanChange(skeletonPlan);

    try {
      const res = await fetch("https://api.usegreenroom.app/api/plan/generate", {
        method: "POST",
        headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
        body: JSON.stringify({ role: currentRole, company: jobContext?.company || "", days, job_description: jobContext?.jobDescription || "" }),
      });

      // Error responses are still JSON (403, 401) — read them normally
      if (!res.ok) {
        const data = await res.json().catch(() => ({}));
        if (res.status === 403) {
          if (data.error === "no_github") setPlanError("Connect GitHub in Settings to generate your plan.");
          else if (data.error === "github_claimed") setPlanError("This GitHub account is linked to another account.");
          // plan_limit gate disabled — re-enable: else if (data.error === "plan_limit") onUpgrade?.("pro");
        } else {
          setPlanError(data?.error || "Server error — please try again.");
        }
        setPlanLoading(false);
        return;
      }

      // Success — stream plain text, extract days as they arrive
      const reader  = res.body.getReader();
      const decoder = new TextDecoder();
      let buffer = "";
      let lastDayCount = 0;
      const partialPlan = { role: currentRole, company: jobContext?.company || "", days, plan: skeletonPlan.plan, weak_topics: [] };

      while (true) {
        const { done, value } = await reader.read();
        if (done) break;
        buffer += decoder.decode(value, { stream: true });

        // Render each newly completed day as soon as its closing } arrives.
        // Real days overlay skeleton placeholders by index, so the user sees
        // each row "fill in" rather than the timeline shrinking and growing.
        const found = extractStreamedDays(buffer);
        if (found.length > lastDayCount) {
          lastDayCount = found.length;
          const merged = skeletonPlan.plan.map((sk, i) => found[i] || sk);
          onPlanChange({ ...partialPlan, plan: merged });
        }
      }

      // Final parse — picks up weak_topics + any edge-case day that slipped through
      try {
        const t    = buffer.trim();
        const full = JSON.parse(t.slice(t.indexOf("{"), t.lastIndexOf("}") + 1));
        if (full?.plan?.length) {
          onPlanChange(full);
          window.posthog?.capture('plan_generated', {
            role: currentRole, company: jobContext?.company || "",
            days, weak_topics: full.weak_topics?.length || 0,
          });
        }
      } catch {}

      // Re-fetch after 20s to pick up enriched YouTube + resources
      let mounted = true;
      setTimeout(async () => {
        if (!mounted) return;
        try {
          const r = await fetch("https://api.usegreenroom.app/api/plan", { headers: { Authorization: `Bearer ${token}` } });
          if (r.ok && mounted) { const enriched = await r.json(); if (enriched?.plan) onPlanChange(enriched); }
        } catch {}
      }, 20000);
      return () => { mounted = false; };

    } catch {
      setPlanError("Server error — make sure the backend is running.");
    }
    setPlanLoading(false);
  }

  const todayStr      = new Date().toISOString().slice(0, 10);
  const todayEntry    = plan?.plan?.find(d => d.date === todayStr);
  const completedDays = plan?.plan?.filter(d => d.date < todayStr).length || 0;
  const progressPct   = plan ? Math.round((completedDays / plan.days) * 100) : 0;

  // ── Mock interview history (for progress dashboard) ─────────────
  // Hydrate from localStorage so the Mock-progress widget doesn't pop into
  // existence after /api/history returns and shove Today's-focus / Plan-progress
  // out of position in the flex row.
  const [mockHistory, setMockHistory] = React.useState(() => {
    try {
      const cached = JSON.parse(localStorage.getItem("gr.mockHistory") || "null");
      if (Array.isArray(cached)) return cached;
    } catch {}
    return [];
  });
  React.useEffect(() => {
    if (!token) return;
    fetch("https://api.usegreenroom.app/api/history", { headers: { Authorization: `Bearer ${token}` } })
      .then(r => r.ok ? r.json() : [])
      .then(data => {
        const arr = Array.isArray(data) ? data : [];
        setMockHistory(arr);
        try { localStorage.setItem("gr.mockHistory", JSON.stringify(arr)); } catch {}
      })
      .catch(() => {});
  }, [token]);
  const completedMocks = mockHistory.filter(m => m.score != null);
  const totalMocks     = mockHistory.length;
  const avgScore       = completedMocks.length ? (completedMocks.reduce((s, m) => s + m.score, 0) / completedMocks.length) : 0;
  const latestScore    = completedMocks[0]?.score || 0;
  const earliestScore  = completedMocks[completedMocks.length - 1]?.score || 0;
  const improvement    = latestScore && earliestScore ? latestScore - earliestScore : 0;

  // ── NO ROLE ──────────────────────────────────────────────────────────────────
  if (!currentRole) {
    return (
      <div data-screen-label="Dashboard" style={{ minHeight: "100vh", background: T.bg, backgroundImage: T.bgArt, display: "flex", flexDirection: "column", position: "relative", overflow: "hidden", transition: "background 250ms ease" }}>
        {/* Ambient glow */}
        <div style={{
          position: "fixed", top: -120, left: "50%", transform: "translateX(-50%)",
          width: 700, height: 400, borderRadius: "50%",
          background: T.glow,
          pointerEvents: "none", animation: "db-glow 5s ease-in-out infinite",
        }} />}

        <div style={{ flex: 1, display: "flex", alignItems: "center", justifyContent: "center", padding: "48px 32px", position: "relative", zIndex: 1 }}>
          <div style={{ width: "100%", maxWidth: 560 }}>

            <div style={{ textAlign: "center", marginBottom: 40, ...up(0) }}>
              <div style={{
                width: 56, height: 56, borderRadius: 16, margin: "0 auto 20px",
                background: T.accentBg, border: `1px solid ${T.accentBorder}`,
                display: "flex", alignItems: "center", justifyContent: "center",
              }}>
                <Icon name="target" size={26} color={T.accentText} />
              </div>
              <h2 style={{
                font: "400 36px/1.04 var(--font-display)", letterSpacing: "-0.02em", margin: "0 0 12px",
                ...(T.gradTitle
                  ? { background: "linear-gradient(135deg, #fff7ea 40%, #d7a35e 100%)", WebkitBackgroundClip: "text", WebkitTextFillColor: "transparent", backgroundClip: "text" }
                  : { color: T.text1 }),
              }}>What are you preparing for?</h2>
              <p style={{ font: "15px/1.6 var(--font-sans)", color: T.text2, margin: 0 }}>
                Set your target role and Ari will tailor every mock interview, question, and study plan to match.
              </p>
            </div>

            {/* Search */}
            <div style={{ position: "relative", marginBottom: 12, ...up(80), zIndex: 50 }}>
              <div style={{
                display: "flex", alignItems: "center",
                background: T.searchBg, borderRadius: 12,
                border: `1.5px solid ${focused ? T.searchBorderFocus : T.searchBorder}`,
                boxShadow: focused ? T.searchShadowFocus : "none",
                transition: "border-color 150ms, box-shadow 150ms",
              }}>
                <span style={{ paddingLeft: 18, display: "flex", flexShrink: 0 }}>
                  <Icon name="search" size={16} color={T.text3} />
                </span>
                <input
                  value={query}
                  onChange={e => { setQuery(e.target.value); setFocused(true); }}
                  onFocus={() => setFocused(true)}
                  onBlur={() => setTimeout(() => setFocused(false), 150)}
                  onKeyDown={e => e.key === "Enter" && query.trim() && apply(query.trim())}
                  placeholder="Search a role — e.g. Software Engineer, ML Engineer…"
                  style={{
                    flex: 1, height: 52, padding: "0 16px", border: "none", outline: "none",
                    font: "500 15px var(--font-sans)", color: T.inputColor, background: "transparent",
                  }}
                />
                {query && (
                  <button onClick={() => apply(query.trim())} style={{
                    height: 52, padding: "0 22px", border: "none", cursor: "pointer",
                    background: T.primaryButton,
                    color: "#fff", font: "600 14px var(--font-sans)",
                    transition: "opacity 150ms",
                  }}
                    onMouseEnter={e => e.currentTarget.style.opacity = "0.85"}
                    onMouseLeave={e => e.currentTarget.style.opacity = "1"}
                  >{saved ? "Saved ✓" : "Set role →"}</button>
                )}
              </div>

              {focused && filteredSuggestions.length > 0 && (
                <div style={{
                  position: "absolute", top: "calc(100% + 6px)", left: 0, right: 0, zIndex: 30,
                  background: T.dropdownBg, borderRadius: 12,
                  border: `1px solid ${T.dropdownBorder}`,
                  boxShadow: T.dropdownShadow,
                  // Cap the panel so it can never spill past ~6 rows of content.
                  // Without this, 15 suggestions × ~46px = 700px of dropdown
                  // visually crashes into the company input + chips below on
                  // mobile, and the typed text appears to "overlap" the rows.
                  maxHeight: 320,
                  overflowY: "auto",
                  WebkitOverflowScrolling: "touch",
                  overscrollBehavior: "contain",
                }}>
                  {filteredSuggestions.slice(0, 8).map((s, i, arr) => (
                    <button key={s.label} onMouseDown={() => apply(s.role)} style={{
                      width: "100%", padding: "11px 18px", border: "none", cursor: "pointer",
                      background: "transparent", textAlign: "left",
                      display: "flex", alignItems: "center", gap: 12,
                      borderBottom: i < arr.length - 1 ? `1px solid ${T.border}` : "none",
                      transition: "background 100ms",
                      minWidth: 0,
                    }}
                      onMouseEnter={e => e.currentTarget.style.background = T.dropdownHover}
                      onMouseLeave={e => e.currentTarget.style.background = "transparent"}
                    >
                      <span style={{
                        padding: "2px 9px", borderRadius: 5, font: "600 11px var(--font-sans)", flexShrink: 0,
                        color:       s.type === "internship" ? "#60a5fa" : T.accentText,
                        background:  s.type === "internship" ? "rgba(96,165,250,.1)" : T.accentBg,
                      }}>{s.type === "internship" ? "Intern" : "Full-time"}</span>
                      <span style={{
                        font: "500 14px var(--font-sans)", color: T.text1,
                        // Long role names ("Senior Machine Learning Engineer") would otherwise wrap
                        // and double the row height on narrow mobile widths, breaking the layout.
                        overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", minWidth: 0,
                      }}>{s.role}</span>
                    </button>
                  ))}
                </div>
              )}
            </div>

            {/* Company */}
            <input
              value={company}
              onChange={e => setCompany(e.target.value)}
              placeholder="Target company — optional, e.g. Google, Stripe…"
              style={{
                width: "100%", height: 44, padding: "0 16px", boxSizing: "border-box",
                border: `1.5px solid ${T.border}`, borderRadius: 10,
                font: "14px var(--font-sans)", color: T.inputColor, outline: "none",
                background: T.inputBg, transition: "border-color 150ms",
                ...up(120),
              }}
              onFocus={e => e.target.style.borderColor = T.searchBorderFocus}
              onBlur={e =>  e.target.style.borderColor = T.border}
            />

            {/* Quick chips */}
            <div style={{ display: "flex", flexWrap: "wrap", gap: 8, marginTop: 20, justifyContent: "center", ...up(160) }}>
              {SUGGESTIONS.map(s => (
                <button key={s.label} className="db-chip" onClick={() => { setQuery(s.role); apply(s.role); }} style={{
                  padding: "7px 16px", borderRadius: 999, cursor: "pointer",
                  font: "500 13px var(--font-sans)",
                  border: `1px solid ${T.chipBorder}`,
                  background: T.chipBg, color: T.chipColor,
                }}>{s.label}</button>
              ))}
            </div>
          </div>
        </div>
      </div>
    );
  }

  // ── HAS ROLE ─────────────────────────────────────────────────────────────────
  return (
    <div data-screen-label="Dashboard" style={{ minHeight: "100vh", background: T.bg, backgroundImage: T.bgArt, color: T.text1, position: "relative", overflow: "hidden", transition: "background 250ms ease" }}>

      {/* Ambient glow */}
      <div style={{
        position: "fixed", top: -160, left: "50%", transform: "translateX(-50%)",
        width: 900, height: 500, borderRadius: "50%",
        background: T.glow,
        pointerEvents: "none", zIndex: 0,
        animation: "db-glow 6s ease-in-out infinite",
      }} />

      <div style={{ position: "relative", zIndex: 1, maxWidth: 1080, margin: "0 auto", padding: "40px 48px 80px" }}>

        {/* ── Hero header ────────────────────────────────────────── */}
        <div style={{ marginBottom: 48 }}>
          <div style={{ font: "600 11px var(--font-sans)", letterSpacing: "0.12em", textTransform: "uppercase", color: T.label, marginBottom: 10, ...up(0) }}>
            {dateLabel}
          </div>
          <div style={{ display: "flex", alignItems: "flex-end", justifyContent: "space-between", gap: 24, flexWrap: "wrap" }}>
            <div>
              <h1 style={{
                font: "400 clamp(40px,5.5vw,72px)/.96 var(--font-display)",
                letterSpacing: "-0.02em", margin: "0 0 16px",
                color: T.text1,
                ...up(60),
              }}>
                {greeting},{" "}
                <em style={{ fontStyle: "italic", fontWeight: 400, color: "#1F7A4F" }}>{user.firstName}</em>.
              </h1>
              <div style={{ display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap", ...up(110) }}>
                <div style={{
                  display: "inline-flex", alignItems: "center", gap: 7,
                  padding: "5px 12px 5px 9px", borderRadius: 999,
                  background: T.accentBg, border: `1px solid ${T.accentBorder}`,
                }}>
                  <div style={{ width: 6, height: 6, borderRadius: 999, background: T.accentText }} />
                  <span style={{ font: "500 13px var(--font-sans)", color: T.accentText }}>
                    {currentRole}{jobContext?.company ? ` · ${jobContext.company}` : ""}
                  </span>
                </div>
                {plan && (
                  <span style={{ font: "13px var(--font-sans)", color: T.label }}>
                    Day {completedDays + 1} of {plan.days} · {progressPct}% done
                  </span>
                )}
              </div>
            </div>

            <div style={{ display: "flex", flexDirection: "column", alignItems: "flex-start", gap: 12 }}>
              <button onClick={onStartMock} className="db-mock-btn" style={{
                display: "inline-flex", alignItems: "center", gap: 10,
                height: 46, padding: "0 26px", borderRadius: 12, border: "none",
                background: T.primaryButton,
                color: "#fff", font: "600 14px var(--font-sans)", cursor: "pointer",
                boxShadow: T.primaryGlow,
                letterSpacing: "-0.01em",
                ...up(130),
              }}>
                <Icon name="video" size={15} color="#fff" />
                Start mock interview
              </button>
              {subscriptionPlan !== "free" && (() => {
                const remaining = sessionUsage.limit - sessionUsage.used;
                const pct = (sessionUsage.used / sessionUsage.limit) * 100;
                const barColor = remaining <= 5 ? "#dc2626" : remaining <= 10 ? "#d97706" : "var(--gr-green-500)";
                return (
                  <div style={{ display: "flex", flexDirection: "column", gap: 6, minWidth: 220 }}>
                    <div style={{ display: "flex", alignItems: "baseline", gap: 6 }}>
                      <span style={{ font: "700 28px var(--font-mono)", color: barColor, letterSpacing: "-0.03em", lineHeight: 1 }}>
                        {remaining}
                      </span>
                      <span style={{ font: "500 13px var(--font-sans)", color: T.label }}>
                        of {sessionUsage.limit} sessions left this month
                      </span>
                    </div>
                    <div style={{ height: 4, background: "rgba(0,0,0,.1)", borderRadius: 999, overflow: "hidden", width: "100%" }}>
                      <div style={{ height: "100%", width: `${pct}%`, background: barColor, borderRadius: 999, transition: "width 600ms ease" }} />
                    </div>
                  </div>
                );
              })()}
            </div>
          </div>

          {/* Progress bar */}
          {plan && (
            <div style={{ marginTop: 24, height: 2, background: "rgba(255,255,255,.06)", borderRadius: 999, overflow: "hidden", ...up(160) }}>
              <div style={{
                height: "100%", borderRadius: 999,
                width: `${progressPct}%`,
                background: T.primaryButton,
                boxShadow: T.primaryGlow,
                transition: "width 800ms ease",
              }} />
            </div>
          )}
        </div>

        {/* ── Initial-load skeleton — covers widget row + timeline ───────── */}
        {loading && !plan && (
          <DashboardSkeleton T={T} />
        )}

        {/* ── Widget row (real content) ─────────────────────────────────── */}
        {!(loading && !plan) && (
        <div style={{ display: "flex", flexWrap: "wrap", gap: 14, marginBottom: 40, alignItems: "stretch" }}>

          {/* Streak */}
          {streak.current > 0 && (() => {
            const today    = new Date().toISOString().slice(0, 10);
            const lastDate = streak.last;
            const isToday  = lastDate === today;
            const isAtRisk = !isToday && (() => {
              if (!lastDate) return false;
              const diff = (new Date(today) - new Date(lastDate)) / 86400000;
              return diff >= 1;
            })();
            return (
              <div className="db-widget" style={{
                flex: "1 1 200px", borderRadius: 16, padding: "18px 20px",
                background: isAtRisk
                  ? "linear-gradient(160deg, rgba(239,68,68,0.10) 0%, rgba(239,68,68,0.02) 100%)"
                  : "linear-gradient(160deg, rgba(245,158,11,0.14) 0%, rgba(245,158,11,0.03) 100%)",
                border: `1px solid ${isAtRisk ? "rgba(239,68,68,0.30)" : "rgba(245,158,11,0.30)"}`,
                ...up(180),
              }}>
                <DLabel>{isAtRisk ? "Streak at risk" : "Streak"}</DLabel>
                <div style={{ display: "flex", alignItems: "baseline", gap: 8, marginBottom: 4 }}>
                  <span style={{ font: "400 48px/1 var(--font-display)", letterSpacing: "-0.03em", color: T.text1, fontVariantNumeric: "tabular-nums" }}>🔥 {streak.current}</span>
                  <span style={{ font: "16px var(--font-sans)", color: T.text2 }}>day{streak.current === 1 ? "" : "s"}</span>
                </div>
                <div style={{ font: "13px var(--font-sans)", color: T.label }}>
                  {isAtRisk
                    ? "Do a mock today to keep your streak alive."
                    : isToday
                      ? `Best: ${streak.longest} days`
                      : `Started yesterday · Best: ${streak.longest}`}
                </div>
              </div>
            );
          })()}

          {/* Today's focus */}
          {todayEntry && (
            <div className="db-widget" style={{
              flex: "1 1 220px", borderRadius: 16, overflow: "hidden",
              border: `1px solid ${T.accentBorder}`,
              display: "flex", flexDirection: "column",
              background: `linear-gradient(160deg, ${T.accentBg} 0%, rgba(255,255,255,.02) 100%)`,
              boxShadow: darkMode ? "0 0 40px rgba(206,148,69,.06)" : "0 12px 30px rgba(183,121,57,.10)",
              ...up(200),
            }}>
              <div style={{ padding: "18px 20px", flex: 1 }}>
                <DLabel>Today's focus</DLabel>
                <div style={{ font: "400 22px/1.15 var(--font-display)", letterSpacing: "-0.015em", color: T.accentText, marginBottom: 10 }}>{todayEntry.focus}</div>
                <TypePill type={todayEntry.type} />
              </div>
              <button onClick={onStartMock} style={{
                width: "100%", padding: "12px 20px", border: "none",
                borderTop: `1px solid ${T.accentBorder}`,
                background: T.accentBg,
                color: T.accentText, font: "600 15px var(--font-sans)", cursor: "pointer",
                display: "flex", alignItems: "center", justifyContent: "center", gap: 8,
                transition: "background 150ms",
              }}
                onMouseEnter={e => e.currentTarget.style.background = darkMode ? "rgba(206,148,69,.24)" : "rgba(186,123,54,.14)"}
                onMouseLeave={e => e.currentTarget.style.background = T.accentBg}
              >
                <Icon name="video" size={13} color={T.accentText} />
                Start today's session
              </button>
            </div>
          )}

          {/* Plan progress */}
          {plan && (
            <div className="db-widget" style={{
              flex: "1 1 180px", borderRadius: 16, padding: "18px 20px",
              background: T.surface, border: `1px solid ${T.border}`,
              ...up(230),
            }}>
              <DLabel>Plan progress</DLabel>
              <div style={{ display: "flex", alignItems: "baseline", gap: 6, marginBottom: 12 }}>
                <span style={{ font: "400 48px/1 var(--font-display)", letterSpacing: "-0.03em", color: T.text1, fontVariantNumeric: "tabular-nums" }}>{completedDays}</span>
                <span style={{ font: "16px var(--font-sans)", color: T.text2 }}>of {plan.days} days</span>
                <span style={{ font: "700 15px var(--font-sans)", color: T.accentText, marginLeft: "auto" }}>{progressPct}%</span>
              </div>
              <div style={{ height: 4, background: T.progressTrack, borderRadius: 999, overflow: "hidden" }}>
                <div style={{
                  height: "100%", borderRadius: 999, width: `${progressPct}%`,
                  background: T.primaryButton,
                  transition: "width 800ms ease",
                }} />
              </div>
              <div style={{ font: "14px var(--font-sans)", color: T.label, marginTop: 8 }}>{plan.days - completedDays} days remaining</div>
            </div>
          )}

          {/* Mock interview progress */}
          {totalMocks > 0 && (
            <div className="db-widget" style={{
              flex: "1 1 240px", borderRadius: 16, padding: "18px 20px",
              background: T.surface, border: `1px solid ${T.border}`,
              ...up(245),
            }}>
              <DLabel>Mock progress</DLabel>
              <div style={{ display: "flex", alignItems: "baseline", gap: 8, marginBottom: 4 }}>
                <span style={{ font: "400 48px/1 var(--font-display)", letterSpacing: "-0.03em", color: T.text1, fontVariantNumeric: "tabular-nums" }}>{latestScore || "—"}</span>
                <span style={{ font: "16px var(--font-sans)", color: T.text2 }}>/ 10</span>
                {improvement !== 0 && completedMocks.length >= 2 && (
                  <span style={{ font: "700 13px var(--font-sans)", color: improvement > 0 ? "#15803d" : "#dc2626", marginLeft: "auto" }}>
                    {improvement > 0 ? "▲" : "▼"} {Math.abs(improvement)} since first mock
                  </span>
                )}
              </div>
              <div style={{ font: "13px var(--font-sans)", color: T.label, marginBottom: 12 }}>
                {totalMocks} mock{totalMocks === 1 ? "" : "s"} · avg {avgScore.toFixed(1)}
              </div>
              {/* Sparkline of last 10 mocks (chronological order) */}
              {completedMocks.length >= 2 && (() => {
                const last10 = completedMocks.slice(0, 10).reverse();
                const w = 220, h = 36, pad = 2;
                const xs = last10.map((_, i) => pad + (i * (w - pad * 2)) / Math.max(last10.length - 1, 1));
                const ys = last10.map(m => h - pad - ((m.score - 1) / 9) * (h - pad * 2));
                const path = xs.map((x, i) => `${i === 0 ? "M" : "L"}${x.toFixed(1)},${ys[i].toFixed(1)}`).join(" ");
                return (
                  <svg width="100%" height={h} viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none" style={{ display: "block" }}>
                    <path d={path} fill="none" stroke={T.accentText} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" />
                    {xs.map((x, i) => (
                      <circle key={i} cx={x} cy={ys[i]} r="2.5" fill={T.accentText} />
                    ))}
                  </svg>
                );
              })()}
            </div>
          )}

          {/* Weak topics */}
          {plan?.weak_topics?.length > 0 && (
            <div className="db-widget" style={{
              flex: "1 1 180px", borderRadius: 16, padding: "18px 20px",
              background: T.surface, border: `1px solid ${T.border}`,
              ...up(260),
            }}>
              <DLabel>Focus areas</DLabel>
              <div style={{ display: "flex", flexDirection: "column", gap: 7 }}>
                {plan.weak_topics.map((t, i) => (
                  <div key={i} style={{
                    display: "flex", alignItems: "center", gap: 10,
                    padding: "8px 12px", borderRadius: 8,
                    background: T.weakBg, border: `1px solid ${T.weakBorder}`,
                  }}>
                    <div style={{ width: 5, height: 5, borderRadius: 999, background: "#f59e0b", flexShrink: 0 }} />
                    <span style={{ font: "500 15px var(--font-sans)", color: T.text1 }}>{t}</span>
                  </div>
                ))}
              </div>
            </div>
          )}

          {/* LinkedIn */}
          {jobContext?.linkedinName ? (
            <div className="db-widget" style={{
              flex: "1 1 200px", borderRadius: 16, padding: "18px 20px",
              background: T.surface, border: `1px solid ${T.border}`,
              ...up(290),
            }}>
              <DLabel>LinkedIn</DLabel>
              <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                {jobContext.linkedinPicture
                  ? <img src={jobContext.linkedinPicture} width="36" height="36" style={{ borderRadius: 999, border: "1.5px solid rgba(0,119,181,.3)" }} alt="" />
                  : <div style={{ width: 36, height: 36, borderRadius: 999, background: "#0077b5", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0, color: "#fff", font: "700 15px var(--font-sans)" }}>in</div>}
                <div style={{ minWidth: 0 }}>
                  <div style={{ font: "600 15px var(--font-sans)", color: T.text1, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{jobContext.linkedinName}</div>
                  <div style={{ font: "14px var(--font-sans)", color: T.text2, marginTop: 1 }}>Used for behavioural questions</div>
                </div>
                <Icon name="check-circle-2" size={15} color={T.accentText} style={{ marginLeft: "auto", flexShrink: 0 }} />
              </div>
            </div>
          ) : (
            <div className="db-widget" style={{
              flex: "1 1 200px", borderRadius: 16, padding: "18px 20px",
              background: T.surface, border: `1px solid ${T.border}`,
              ...up(290),
            }}>
              <DLabel>LinkedIn</DLabel>
              <p style={{ font: "15px/1.6 var(--font-sans)", color: T.text2, margin: "0 0 12px" }}>
                Connect so Ari can ask questions tailored to your actual work history.
              </p>
              <a href="https://api.usegreenroom.app/auth/linkedin" style={{
                display: "flex", alignItems: "center", justifyContent: "center", gap: 7,
                height: 34, borderRadius: 8, textDecoration: "none",
                background: "#0077b5", color: "#fff", font: "500 15px var(--font-sans)",
                transition: "opacity 150ms",
              }}
                onMouseEnter={e => e.currentTarget.style.opacity = "0.8"}
                onMouseLeave={e => e.currentTarget.style.opacity = "1"}
              >
                <svg width="12" height="12" viewBox="0 0 24 24" fill="#fff"><path d="M20.45 20.45h-3.55v-5.57c0-1.33-.02-3.04-1.85-3.04-1.85 0-2.13 1.45-2.13 2.94v5.67H9.36V9h3.41v1.56h.05c.48-.9 1.64-1.85 3.37-1.85 3.6 0 4.27 2.37 4.27 5.46v6.28ZM5.34 7.43a2.06 2.06 0 1 1 0-4.12 2.06 2.06 0 0 1 0 4.12ZM7.12 20.45H3.56V9h3.56v11.45ZM22.22 0H1.77C.79 0 0 .77 0 1.72v20.56C0 23.23.79 24 1.77 24h20.45C23.21 24 24 23.23 24 22.28V1.72C24 .77 23.21 0 22.22 0Z"/></svg>
                Connect LinkedIn
              </a>
            </div>
          )}

          {/* GitHub */}
          {jobContext?.githubName ? (
            <div className="db-widget" style={{
              flex: "1 1 200px", borderRadius: 16, padding: "18px 20px",
              background: T.surface, border: `1px solid ${T.border}`,
              ...up(300),
            }}>
              <DLabel>GitHub</DLabel>
              <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                {jobContext.githubAvatar
                  ? <img src={jobContext.githubAvatar} width="36" height="36" style={{ borderRadius: 999, border: "1.5px solid rgba(255,255,255,.12)" }} alt="" />
                  : <div style={{ width: 36, height: 36, borderRadius: 999, background: "#24292e", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }}>
                      <svg width="18" height="18" viewBox="0 0 24 24" fill="#fff"><path d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z"/></svg>
                    </div>}
                <div style={{ minWidth: 0 }}>
                  <div style={{ font: "600 15px var(--font-sans)", color: T.text1, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{jobContext.githubName}</div>
                  <div style={{ font: "14px var(--font-sans)", color: T.text2, marginTop: 1 }}>@{jobContext.github} · {jobContext.githubRepos} repos</div>
                </div>
                <Icon name="check-circle-2" size={15} color={T.accentText} style={{ marginLeft: "auto", flexShrink: 0 }} />
              </div>
              {jobContext.githubLanguages?.length > 0 && (
                <div style={{ display: "flex", gap: 5, flexWrap: "wrap", marginTop: 10 }}>
                  {jobContext.githubLanguages.slice(0, 4).map(l => (
                    <span key={l} style={{ padding: "2px 8px", borderRadius: 4, font: "12px var(--font-sans)", color: T.text2, background: T.accentBg, border: `1px solid ${T.border}` }}>{l}</span>
                  ))}
                </div>
              )}
            </div>
          ) : (
            <div className="db-widget" style={{
              flex: "1 1 200px", borderRadius: 16, padding: "18px 20px",
              background: T.surface, border: `1px solid ${T.border}`,
              ...up(300),
            }}>
              <DLabel>GitHub</DLabel>
              <p style={{ font: "15px/1.6 var(--font-sans)", color: T.text2, margin: "0 0 12px" }}>
                Connect so Ari references your real projects in technical questions.
              </p>
              <a href="https://api.usegreenroom.app/auth/github" style={{
                display: "flex", alignItems: "center", justifyContent: "center", gap: 7,
                height: 34, borderRadius: 8, textDecoration: "none",
                background: "#24292e", color: "#fff", font: "500 15px var(--font-sans)",
                transition: "opacity 150ms",
              }}
                onMouseEnter={e => e.currentTarget.style.opacity = "0.8"}
                onMouseLeave={e => e.currentTarget.style.opacity = "1"}
              >
                <svg width="14" height="14" viewBox="0 0 24 24" fill="#fff"><path d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z"/></svg>
                Connect GitHub
              </a>
            </div>
          )}

          {/* No plan CTA */}
          {!plan && !planLoading && (
            <div className="db-widget" style={{
              flex: "1 1 200px", borderRadius: 16, padding: "20px",
              background: T.planCtaBg, border: `1px solid ${T.planCtaBorder}`,
              ...up(290),
            }}>
              <div style={{ font: "400 20px/1.2 var(--font-display)", letterSpacing: "-0.01em", color: T.accentText, marginBottom: 6 }}>Generate your study plan</div>
              <div style={{ font: "15px/1.55 var(--font-sans)", color: "#52525b", marginBottom: 14 }}>
                A day-by-day schedule built around your interview date and target role.
              </div>
              <button className="db-gen-btn" onClick={generatePlan} style={{
                width: "100%", height: 36, borderRadius: 8, border: "none",
                background: T.primaryButton,
                color: "#fff", font: "600 13px var(--font-sans)", cursor: "pointer",
                boxShadow: T.primaryGlow,
                letterSpacing: "-0.01em",
              }}>Create plan</button>
            </div>
          )}
        </div>
        )}

        {/* ── Job description ────────────────────────────────────── */}
        <div style={{ marginBottom: 32, ...up(315) }}>
          <div style={{
            borderRadius: 16, border: `1px solid ${T.border}`,
            background: T.surface, overflow: "hidden",
          }}>
            <div style={{
              display: "flex", alignItems: "center", justifyContent: "space-between",
              padding: "16px 20px",
              borderBottom: (jdEditing || (jobContext?.jobDescription && jdExpanded)) ? `1px solid ${T.border}` : "none",
            }}>
              <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                <Icon name="file-text" size={15} color={T.label} />
                <span style={{ font: "400 17px/1 var(--font-display)", letterSpacing: "-0.01em", color: T.text1 }}>Job description</span>
                {jobContext?.jobDescription && !jdEditing && (
                  <span style={{ font: "12px var(--font-sans)", color: T.label, background: T.accentBg, padding: "2px 7px", borderRadius: 4 }}>
                    {jobContext.jobDescription.length} chars
                  </span>
                )}
              </div>
              <div style={{ display: "flex", gap: 8 }}>
                {jdEditing ? (
                  <>
                    <button onClick={() => { setJdDraft(jobContext?.jobDescription || ""); setJdEditing(false); }} style={{
                      height: 28, padding: "0 12px", borderRadius: 6, border: `1px solid ${T.border}`,
                      background: "transparent", color: T.text2, font: "500 13px var(--font-sans)", cursor: "pointer",
                    }}>Cancel</button>
                    <button onClick={saveJd} style={{
                      height: 28, padding: "0 12px", borderRadius: 6, border: "none",
                      background: T.primaryButton, color: "#fff", font: "600 13px var(--font-sans)", cursor: "pointer",
                    }}>Save</button>
                  </>
                ) : (
                  <>
                    {jobContext?.jobDescription && (
                      <button onClick={() => setJdExpanded(x => !x)} style={{
                        height: 28, padding: "0 12px", borderRadius: 6, border: `1px solid ${T.border}`,
                        background: "transparent", color: T.text2, font: "500 13px var(--font-sans)", cursor: "pointer",
                      }}>{jdExpanded ? "Collapse" : "View"}</button>
                    )}
                    <button onClick={() => { setJdDraft(jobContext?.jobDescription || ""); setJdEditing(true); setJdExpanded(false); }} style={{
                      height: 28, padding: "0 12px", borderRadius: 6, border: `1px solid ${T.border}`,
                      background: "transparent", color: T.accentText, font: "500 13px var(--font-sans)", cursor: "pointer",
                      display: "flex", alignItems: "center", gap: 6,
                    }}>
                      <Icon name="pencil" size={12} color={T.accentText} />
                      {jobContext?.jobDescription ? "Edit" : "Add"}
                    </button>
                  </>
                )}
              </div>
            </div>

            {/* Edit mode */}
            {jdEditing && (
              <div style={{ padding: "16px 20px" }}>
                <textarea
                  autoFocus
                  value={jdDraft}
                  onChange={e => setJdDraft(e.target.value)}
                  placeholder="Paste the full job description here. Ari will use the required skills, responsibilities, and seniority level to ask questions that match exactly what this role demands."
                  style={{
                    width: "100%", minHeight: 180, padding: "12px 14px", boxSizing: "border-box",
                    border: `1.5px solid ${T.searchBorderFocus}`, borderRadius: 10,
                    font: "14px/1.6 var(--font-sans)", color: T.inputColor,
                    background: T.inputBg, resize: "vertical", outline: "none",
                  }}
                />
                <div style={{ font: "12px var(--font-sans)", color: T.label, marginTop: 6 }}>
                  {jdDraft.length} characters · Ari reads up to the first 1,200
                </div>
              </div>
            )}

            {/* View mode — collapsed */}
            {!jdEditing && jobContext?.jobDescription && !jdExpanded && (
              <div style={{ padding: "12px 20px" }}>
                <div style={{
                  font: "14px/1.6 var(--font-sans)", color: T.text2,
                  display: "-webkit-box", WebkitLineClamp: 2, WebkitBoxOrient: "vertical", overflow: "hidden",
                }}>
                  {jobContext.jobDescription}
                </div>
              </div>
            )}

            {/* View mode — expanded */}
            {!jdEditing && jobContext?.jobDescription && jdExpanded && (
              <div style={{ padding: "16px 20px", maxHeight: 260, overflowY: "auto" }}>
                <pre style={{ font: "14px/1.6 var(--font-sans)", color: T.text2, margin: 0, whiteSpace: "pre-wrap", wordBreak: "break-word" }}>
                  {jobContext.jobDescription}
                </pre>
              </div>
            )}

            {/* Empty state */}
            {!jdEditing && !jobContext?.jobDescription && (
              <div style={{ padding: "14px 20px" }}>
                <span style={{ font: "14px var(--font-sans)", color: T.label }}>
                  No job description yet — add one so Ari asks role-specific questions.
                </span>
              </div>
            )}
          </div>
        </div>

        {/* ── Study plan section ─────────────────────────────────── */}
        <div style={up(320)}>

          {/* Section header — allowed to wrap on narrow viewports so the
              days-select + Create-plan button drop below the label instead
              of overflowing the container. */}
          <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 16, flexWrap: "wrap", gap: 10 }}>
            <DLabel>Study plan</DLabel>
            <div style={{ display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" }}>
              <select value={days} onChange={e => setDays(Number(e.target.value))} style={{
                height: 30, padding: "0 10px", borderRadius: 6,
                border: `1px solid ${T.selectBorder}`,
                font: "14px var(--font-sans)", color: T.selectColor,
                background: T.selectBg, cursor: "pointer", outline: "none",
                flexShrink: 0,
              }}>
                {[7, 14, 21, 30].map(d => <option key={d} value={d}>{d} days</option>)}
              </select>
              <button onClick={generatePlan} disabled={planLoading} style={{
                height: 30, padding: "0 14px", borderRadius: 6,
                background: planLoading ? T.genBtnDisabledBg : T.secondaryButton,
                color: planLoading ? T.genBtnDisabledColor : T.accentText,
                font: "600 14px var(--font-sans)", cursor: planLoading ? "not-allowed" : "pointer",
                border: planLoading ? "none" : `1px solid ${T.secondaryButtonBorder}`,
                transition: "opacity 150ms",
                whiteSpace: "nowrap",
                flexShrink: 0,
              }}>{planLoading ? "Generating…" : plan ? "Refresh plan" : "Create plan"}</button>
            </div>
          </div>

          {planError && (
            <div style={{
              padding: "10px 14px", borderRadius: 8, marginBottom: 12,
              background: T.errorBg, border: `1px solid ${T.errorBorder}`,
              font: "13px var(--font-sans)", color: T.errorText,
            }}>{planError}</div>
          )}

          {/* Generating — only show the big spinner box if there's no plan/skeleton yet */}
          {planLoading && !plan && (
            <div style={{
              borderRadius: 16, border: `1px solid ${T.border}`,
              background: T.surface, padding: "56px 32px", textAlign: "center",
            }}>
              <div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 10 }}>
                <div style={{ display: "inline-flex", alignItems: "center", gap: 12, color: T.text2 }}>
                  <div style={{ width: 16, height: 16, borderRadius: 999, border: "2px solid rgba(206,148,69,.3)", borderTopColor: T.accentText, animation: "spin 700ms linear infinite" }} />
                  <span style={{ font: "14px var(--font-sans)" }}>Building your personalised plan…</span>
                </div>
                <span style={{ font: "13px var(--font-sans)", color: T.text3 }}>Usually 8–15 seconds</span>
              </div>
            </div>
          )}

          {/* Empty */}
          {!planLoading && !plan && (
            <div style={{
              borderRadius: 16, border: `1px solid ${T.border}`,
              background: T.surface, padding: "60px 40px", textAlign: "center",
            }}>
              <div style={{
                width: 52, height: 52, borderRadius: 14, margin: "0 auto 18px",
                background: T.emptyIconBg, border: `1px solid ${T.emptyIconBorder}`,
                display: "flex", alignItems: "center", justifyContent: "center",
              }}>
                <Icon name="calendar" size={24} color={T.emptyIcon} />
              </div>
              <div style={{ font: "400 20px/1.2 var(--font-display)", letterSpacing: "-0.01em", color: T.text1, marginBottom: 8 }}>No plan yet</div>
              <div style={{ font: "14px/1.6 var(--font-sans)", color: T.text2, maxWidth: 300, margin: "0 auto 24px" }}>
                Generate a day-by-day prep schedule tailored to your role{jobContext?.company ? ` at ${jobContext.company}` : ""}.
              </div>
              <button className="db-gen-btn" onClick={generatePlan} style={{
                height: 40, padding: "0 22px", borderRadius: 9, border: "none",
                background: T.primaryButton,
                color: "#fff", font: "600 14px var(--font-sans)", cursor: "pointer",
                boxShadow: T.primaryGlow,
                letterSpacing: "-0.01em",
              }}>Create my plan</button>
            </div>
          )}

          {/* Timeline — shown during streaming too, so skeleton rows fill in live */}
          {plan && (
            <div style={{ borderRadius: 16, border: `1px solid ${T.timelineBorder}`, background: T.timelineBg, overflow: "hidden" }}>
              {plan.plan.map((day, i) => {
                const isPast  = day.date < todayStr;
                const isToday = day.date === todayStr;
                const isLast  = i === plan.plan.length - 1;

                return (
                  <div key={day.day} style={{ display: "flex", position: "relative" }}>
                    {/* Track */}
                    <div style={{ width: 56, flexShrink: 0, display: "flex", flexDirection: "column", alignItems: "center", padding: "18px 0 0" }}>
                      <div style={{
                        width: 22, height: 22, borderRadius: 999, flexShrink: 0, zIndex: 1,
                        background: isPast || isToday ? T.accentText : T.dotFuture,
                        border: isPast || isToday ? "none" : `1.5px solid ${T.dotFutureBorder}`,
                        display: "flex", alignItems: "center", justifyContent: "center",
                        boxShadow: (isPast || isToday) ? (darkMode ? "0 0 10px rgba(206,148,69,.32)" : "0 0 10px rgba(186,123,54,.18)") : "none",
                      }}>
                        {isPast
                          ? <Icon name="check" size={11} color="#fff" />
                          : isToday
                          ? <div style={{ width: 7, height: 7, borderRadius: 999, background: "#fff" }} />
                          : <span style={{ font: "700 11px var(--font-mono)", color: T.text3 }}>{day.day}</span>}
                      </div>
                      {!isLast && (
                        <div style={{
                          width: 1, flex: 1, minHeight: 12, marginTop: 3,
                          background: isPast ? T.connectorDone : T.connector,
                        }} />
                      )}
                    </div>

                    {/* Row */}
                    <button className="db-day-row" disabled={day.isPlaceholder} onClick={() => { if (day.isPlaceholder) return; if (onDaySelect) { window.posthog?.capture('plan_day_opened', { day: day.day, focus: day.focus, type: day.type }); onDaySelect(day); } }} style={{
                      flex: 1, display: "flex", alignItems: "center", gap: 12,
                      padding: "14px 20px 14px 4px", border: "none", cursor: day.isPlaceholder ? "default" : "pointer", textAlign: "left",
                      background: isToday ? T.todayRow : "transparent",
                      borderBottom: !isLast ? `1px solid ${T.border}` : "none",
                      opacity: day.isPlaceholder ? 0.55 : 1,
                    }}>
                      <div style={{ flex: 1, minWidth: 0 }}>
                        <div style={{ display: "flex", alignItems: "center", gap: 7, marginBottom: 2 }}>
                          {day.isPlaceholder ? (
                            <span style={{
                              display: "inline-block", height: 16, width: "55%", borderRadius: 4,
                              background: `linear-gradient(90deg, ${T.border} 0%, ${T.surface} 50%, ${T.border} 100%)`,
                              backgroundSize: "200% 100%",
                              animation: "skeletonShimmer 1.4s ease-in-out infinite",
                            }} />
                          ) : (
                          <span style={{
                            font: `${isToday ? "600" : "500"} 16px var(--font-sans)`,
                            color: isPast ? T.label : T.text1,
                            textDecoration: isPast ? "line-through" : "none",
                          }}>{day.focus}</span>
                          )}
                          {isToday && (
                            <span style={{
                              font: "700 11px var(--font-sans)", letterSpacing: "0.08em",
                              color: T.accentText, background: T.accentBg,
                              padding: "2px 6px", borderRadius: 3,
                            }}>TODAY</span>
                          )}
                          {day.mock && (
                            <span style={{
                              font: "700 11px var(--font-sans)", letterSpacing: "0.08em",
                              color: "#60a5fa", background: "rgba(96,165,250,.1)",
                              padding: "2px 6px", borderRadius: 3,
                            }}>MOCK</span>
                          )}
                        </div>
                        <span style={{ font: "14px var(--font-sans)", color: T.label }}>{day.date}</span>
                      </div>
                      <TypePill type={day.type} />
                      <Icon name="chevron-right" size={13} color={T.label} />
                    </button>
                  </div>
                );
              })}
            </div>
          )}
        </div>

      </div>
    </div>
  );
}

window.Dashboard = Dashboard;
