PageSourceSearch

https://morable.ai/assets/check-in-aDwgzWR4.js

js morable.ai collected 2026-10-05 00:48:04 UTC 27,280 bytes, 529 lines download raw bytes

1import { c as useServerFn, d as useQuery, r as reactExports, j as jsxRuntimeExports, g as analytics, u as useNavigate, e as useQueryClient, y as adaptExecutionPlan, z as trackActivity, A as useFeatureView, x as trackFunnel, B as onceEver } from "./index-DCIAVSLG.js";
2import { P as PendingDot, S as Skeleton, T as ThinkingBlock, I as InlineSpinner } from "./loading-BvAdAWUN.js";
3import { S as Shell } from "./Shell-C0EsziAS.js";
4import { W as WorkspaceActions, P as PrimaryButton, B as BackToCommandCenter, b as btnSecondary } from "./WorkspaceActions-nIPIL1-e.js";
5import { f as submitCheckIn, h as generateCheckInQuestions, i as getTodayCheckIn, a as getNextMoveRecommendation, j as listWeeklyReviews, k as generateWeeklyReview, m as evaluateAdaptation } from "./roadmap.functions-CA60ix7p.js";
6import { r as refreshEvolution } from "./evolution.functions-AbGwYalQ.js";
7import { g as getRetentionState, s as scheduleReturnReminder, u as useNextMoveCycle } from "./retention.functions-DsjFvjs3.js";
8import { g as getRouteSignalFeedback, s as submitRouteSignalFeedback } from "./feedback.functions-HRoIPlYd.js";
9import { u as useControlSurface } from "./ControlSurfaceContext-CaYhGVrQ.js";
10import "./useRouterState-BUAA-I5X.js";
11import "./createLucideIcon-DiixQpQS.js";
12const REASONS = [
13  { value: "too_generic", label: "Too generic" },
14  { value: "missed_context", label: "Missed my context" },
15  { value: "wrong_priority", label: "Wrong priority" },
16  { value: "too_long", label: "Too long" }
17];
18function RouteSignalFeedback({ routeSignalId }) {
19  const fetchStatus = useServerFn(getRouteSignalFeedback);
20  const submit = useServerFn(submitRouteSignalFeedback);
21  const { data, isLoading } = useQuery({
22    queryKey: ["routeSignalFeedback", routeSignalId],
23    queryFn: () => fetchStatus({ data: { route_signal_id: routeSignalId } }),
24    staleTime: 1e3 * 60 * 60
25  });
26  const [expanded, setExpanded] = reactExports.useState(false);
27  const [reason, setReason] = reactExports.useState(null);
28  const [comment, setComment] = reactExports.useState("");
29  const [done, setDone] = reactExports.useState(false);
30  const [busy, setBusy] = reactExports.useState(false);
31  if (isLoading) return null;
32  const alreadyVoted = !!data?.voted;
33  if (alreadyVoted || done) {
34    return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-6 border-t border-border/60 pt-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground animate-fade-in", children: "✓ Thanks for helping improve Morable." }) });
35  }
36  const submitHelpful = async () => {
37    setBusy(true);
38    try {
39      await submit({ data: { route_signal_id: routeSignalId, helpful: true } });
40      void analytics.track("route_signal_helpful", { route_signal_id: routeSignalId });
41      setDone(true);
42    } catch {
43      setDone(true);
44    } finally {
45      setBusy(false);
46    }
47  };
48  const submitNotHelpful = async () => {
49    setBusy(true);
50    try {
51      await submit({
52        data: {
53          route_signal_id: routeSignalId,
54          helpful: false,
55          reason_tag: reason ?? void 0,
56          comment: comment.trim() || void 0
57        }
58      });
59      void analytics.track("route_signal_not_helpful", {
60        route_signal_id: routeSignalId,
61        reason_tag: reason ?? null
62        // Never send the free-text comment body.
63      });
64      setDone(true);
65    } catch {
66      setDone(true);
67    } finally {
68      setBusy(false);
69    }
70  };
71  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-6 border-t border-border/60 pt-4 animate-fade-in", children: !expanded ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
72    /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs uppercase tracking-[0.2em] text-muted-foreground", children: "Was this helpful?" }),
73    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
74      /* @__PURE__ */ jsxRuntimeExports.jsx(
75        "button",
76        {
77          type: "button",
78          onClick: submitHelpful,
79          disabled: busy,
80          className: "rounded-full glass px-3.5 py-1.5 text-xs transition-colors hover:text-foreground disabled:opacity-50",
81          children: "👍 Yes"
82        }
83      ),
84      /* @__PURE__ */ jsxRuntimeExports.jsx(
85        "button",
86        {
87          type: "button",
88          onClick: () => setExpanded(true),
89          disabled: busy,
90          className: "rounded-full glass px-3.5 py-1.5 text-xs transition-colors hover:text-foreground disabled:opacity-50",
91          children: "👎 Not really"
92        }
93      )
94    ] })
95  ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "animate-fade-up", children: [
96    /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs uppercase tracking-[0.2em] text-muted-foreground", children: "What would have made this more helpful?" }),
97    /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-3 flex flex-wrap gap-2", children: REASONS.map((r) => {
98      const on = reason === r.value;
99      return /* @__PURE__ */ jsxRuntimeExports.jsx(
100        "button",
101        {
102          type: "button",
103          onClick: () => setReason(on ? null : r.value),
104          className: `rounded-full px-3 py-1.5 text-xs transition-colors ${on ? "bg-accent text-accent-foreground" : "glass text-muted-foreground hover:text-foreground"}`,
105          children: r.label
106        },
107        r.value
108      );
109    }) }),
110    /* @__PURE__ */ jsxRuntimeExports.jsx(
111      "textarea",
112      {
113        value: comment,
114        onChange: (e) => setComment(e.target.value),
115        rows: 2,
116        placeholder: "Anything you'd like Morable to understand better?",
117        className: "mt-3 w-full rounded-2xl bg-background/40 border border-border p-3 text-xs text-foreground placeholder:text-muted-foreground/70 focus:outline-none focus:ring-1 focus:ring-accent/50"
118      }
119    ),
120    /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-3 flex justify-end", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
121      "button",
122      {
123        type: "button",
124        onClick: submitNotHelpful,
125        disabled: busy,
126        className: "rounded-full bg-foreground px-4 py-2 text-xs font-medium text-background disabled:opacity-40",
127        children: busy ? "Sending…" : "Send"
128      }
129    ) })
130  ] }) });
131}
132const QUESTION_MESSAGES = ["Reading your current phase", "Looking at your last few days", "Choosing what’s worth asking today"];
133const SUBMIT_MESSAGES = ["Saving your answers", "Updating what Morable knows about you", "Checking whether anything should change"];
134function formatCompletedAt(iso) {
135  const d = new Date(iso);
136  try {
137    return d.toLocaleString(void 0, {
138      weekday: "long",
139      month: "short",
140      day: "numeric",
141      hour: "numeric",
142      minute: "2-digit"
143    });
144  } catch {
145    return d.toString();
146  }
147}
148function CompletedCheckIn({
149  view,
150  justCompleted = false,
151  onThisWeek,
152  onRoadmap
153}) {
154  const answers = view.qa.length > 0 ? view.qa : view.legacy ? [{
155    question: "What moved forward today",
156    answer: view.legacy.moved ?? "—"
157  }, {
158    question: "What slowed you down most",
159    answer: view.legacy.slowed ?? "—"
160  }, {
161    question: "What matters most right now",
162    answer: view.legacy.matters ?? "—"
163  }] : [];
164  return /* @__PURE__ */ jsxRuntimeExports.jsx(Shell, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mx-auto max-w-3xl py-10 animate-fade-up", children: [
165    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
166      /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs uppercase tracking-[0.25em] text-accent", children: "Daily check-in" }),
167      /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1.5 rounded-full border border-accent/30 bg-accent/10 px-3 py-1 text-[11px] font-medium tracking-wide text-accent", children: [
168        "Completed Today ",
169        /* @__PURE__ */ jsxRuntimeExports.jsx("span", { "aria-hidden": true, children: "✓" })
170      ] })
171    ] }),
172    /* @__PURE__ */ jsxRuntimeExports.jsx("h1", { className: "mt-3 font-display text-4xl md:text-5xl text-gradient", children: "Today's entry is logged." }),
173    /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-3 text-xs text-muted-foreground", children: [
174      "Completed ",
175      formatCompletedAt(view.checkInAt)
176    ] }),
177    justCompleted && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-6 rounded-2xl border px-5 py-4", style: {
178      borderColor: "var(--border)",
179      background: "var(--card)"
180    }, children: [
181      /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-foreground", children: "Logged. Morable will use this to sharpen your next move." }),
182      /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-[13px] text-muted-foreground", children: "Come back tomorrow to continue." })
183    ] }),
184    view.routeSignal && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-8 glass-strong rounded-3xl p-8 md:p-10", children: [
185      /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs uppercase tracking-[0.25em] text-accent", children: "Route signal" }),
186      /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-3 font-display text-2xl leading-relaxed md:text-3xl", children: view.routeSignal }),
187      view.checkInId && /* @__PURE__ */ jsxRuntimeExports.jsx(RouteSignalFeedback, { routeSignalId: view.checkInId })
188    ] }),
189    answers.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-8 space-y-4", children: [
190      /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs uppercase tracking-[0.2em] text-muted-foreground", children: "Your answers" }),
191      answers.map((qa, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "glass rounded-3xl p-6", children: [
192        /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
193          /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs uppercase tracking-[0.2em] text-muted-foreground", children: [
194            "0",
195            i + 1
196          ] }),
197          /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "h-px flex-1 bg-border" })
198        ] }),
199        /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-3 font-display text-lg leading-snug", children: qa.question }),
200        /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-3 whitespace-pre-wrap text-sm text-foreground/90", children: qa.answer || "—" })
201      ] }, i))
202    ] }),
203    view.extraNotes && /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "mt-4 glass rounded-3xl p-6", children: [
204      /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs uppercase tracking-[0.2em] text-muted-foreground", children: "Additional context" }),
205      /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-3 whitespace-pre-wrap text-sm text-foreground/90", children: view.extraNotes })
206    ] }),
207    /* @__PURE__ */ jsxRuntimeExports.jsxs(WorkspaceActions, { children: [
208      /* @__PURE__ */ jsxRuntimeExports.jsx(BackToCommandCenter, { workspace: "check_in" }),
209      /* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", onClick: onThisWeek, className: btnSecondary, children: "Open Focus" }),
210      /* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", onClick: onRoadmap, className: btnSecondary, children: "Open Roadmap" })
211    ] }),
212    /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-10 text-center text-xs uppercase tracking-[0.25em] text-muted-foreground", children: "Your next personalized check-in unlocks tomorrow." })
213  ] }) });
214}
215function CheckIn() {
216  useControlSurface("check_in");
217  const navigate = useNavigate();
218  const queryClient = useQueryClient();
219  const submit = useServerFn(submitCheckIn);
220  const fetchQs = useServerFn(generateCheckInQuestions);
221  const fetchToday = useServerFn(getTodayCheckIn);
222  const fetchNextMove = useServerFn(getNextMoveRecommendation);
223  const fetchRetention = useServerFn(getRetentionState);
224  const scheduleReminder = useServerFn(scheduleReturnReminder);
225  const listReviews = useServerFn(listWeeklyReviews);
226  const runWeeklyAnalysis = useServerFn(generateWeeklyReview);
227  const evaluateEvolution = useServerFn(refreshEvolution);
228  const runAdaptation = useServerFn(evaluateAdaptation);
229  const adaptPlan = useServerFn(adaptExecutionPlan);
230  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
231  const {
232    data: todayEntry,
233    isLoading: todayLoading,
234    refetch: refetchToday
235  } = useQuery({
236    queryKey: ["todayCheckIn", today],
237    queryFn: () => fetchToday(),
238    staleTime: 1e3 * 60 * 5
239  });
240  const alreadyDone = !!todayEntry?.doneToday;
241  const {
242    data: retention
243  } = useQuery({
244    queryKey: ["retentionState"],
245    queryFn: () => fetchRetention(),
246    staleTime: 1e3 * 60 * 2
247  });
248  const [justCompleted, setJustCompleted] = reactExports.useState(false);
249  const {
250    data: nextMoveData
251  } = useQuery({
252    queryKey: ["nextMoveRecommendation"],
253    queryFn: () => fetchNextMove(),
254    staleTime: 1e3 * 60 * 5
255  });
256  const cycleNumber = useNextMoveCycle(nextMoveData?.recommendationId, Boolean(nextMoveData?.recommendation), nextMoveData?.cycleNumber);
257  const recordedOutcome = nextMoveData?.outcome ?? null;
258  const moveDone = recordedOutcome === "completed";
259  const {
260    data: qData,
261    isLoading: qLoading
262  } = useQuery({
263    queryKey: ["checkInQuestions", today],
264    queryFn: () => fetchQs({
265      data: void 0
266    }),
267    staleTime: 1e3 * 60 * 60 * 12,
268    enabled: !todayLoading && !alreadyDone
269  });
270  const [answers, setAnswers] = reactExports.useState([]);
271  const [notes, setNotes] = reactExports.useState("");
272  const [busy, setBusy] = reactExports.useState(false);
273  const [err, setErr] = reactExports.useState(null);
274  reactExports.useEffect(() => {
275    if (qData?.questions) setAnswers(qData.questions.map(() => ""));
276  }, [qData]);
277  const startedRef = reactExports.useRef(false);
278  reactExports.useEffect(() => {
279    if (startedRef.current) return;
280    if (alreadyDone) return;
281    if (!qData?.questions?.length) return;
282    startedRef.current = true;
283    const cycleProps = {
284      question_count: qData.questions.length,
285      move_id: nextMoveData?.recommendationId ?? null,
286      cycle_number: cycleNumber
287    };
288    void analytics.track("check_in_started", cycleProps);
289    trackActivity("check_in_started", cycleProps);
290  }, [qData, alreadyDone]);
291  useFeatureView("check_ins");
292  const questions = qData?.questions ?? [];
293  const canSubmit = !busy;
294  const handle = async () => {
295    setBusy(true);
296    setErr(null);
297    try {
298      const dynamicQA = questions.map((q, i) => ({
299        question: q.question,
300        answer: (answers[i] ?? "").trim()
301      })).filter((qa) => qa.answer.length > 0);
302      const answeredCount = dynamicQA.length;
303      const res = await analytics.measure("submit_check_in", () => submit({
304        data: {
305          moved: dynamicQA[0]?.answer.slice(0, 40) || "Check-in",
306          slowed: dynamicQA[1]?.answer.slice(0, 40) || "Check-in",
307          matters: dynamicQA[2]?.answer.slice(0, 60) || "Check-in",
308          notes: notes.trim() || void 0,
309          dynamicQA: answeredCount > 0 ? dynamicQA : void 0
310        }
311      }), {
312        slowMs: 2e3
313      });
314      trackFunnel("first_check_in_completed");
315      trackActivity("check_in_completed", {
316        answered_count: answeredCount,
317        question_count: questions.length
318      });
319      void analytics.track("check_in_completed", {
320        move_id: nextMoveData?.recommendationId ?? null,
321        cycle_number: cycleNumber,
322        question_count: questions.length,
323        answered_count: answeredCount,
324        answer_depth: answeredCount === 0 ? "none" : answeredCount >= questions.length && questions.length > 0 ? "all" : "some",
325        // Execution reality is recorded on the Today's Move card; this
326        // screen only observes it for analytics joins.
327        next_move_done: moveDone,
328        execution_status: recordedOutcome || "not_observed",
329        execution_recorded: false,
330        has_execution_context: false,
331        // Structured evidence pipeline observability.
332        evidence_extracted: res?.evidence?.extracted ?? 0,
333        evidence_accepted: res?.evidence?.accepted ?? 0,
334        evidence_held: res?.evidence?.held ?? 0,
335        evidence_ingested: Boolean(res?.evidence?.ingested)
336      });
337      if (retention) {
338        const priorCount = retention.checkInCount;
339        const priorFirstAt = retention.firstCheckInAt;
340        const priorFirstDay = priorFirstAt ? priorFirstAt.slice(0, 10) : null;
341        const hasPriorSecondDay = Boolean(retention.secondCheckInAt);
342        if (priorCount === 0) {
343          void analytics.track("first_check_in_completed", {});
344          trackActivity("first_check_in_completed", {});
345          try {
346            await scheduleReminder({
347              data: {
348                kind: "first_checkin_followup",
349                inHours: 24
350              }
351            });
352          } catch {
353          }
354        } else if (!hasPriorSecondDay && priorFirstDay && priorFirstDay !== today) {
355          void analytics.track("second_checkin_completed", {
356            days_since_first: retention.daysSinceFirst
357          });
358          trackActivity("second_checkin_completed", {
359            days_since_first: retention.daysSinceFirst
360          });
361          if ((retention.daysSinceFirst ?? 99) <= 7 && onceEver("morable_retained_7d")) {
362            void analytics.track("retained_7d_after_first_checkin", {
363              days_since_first: retention.daysSinceFirst
364            });
365            trackActivity("retained_7d_after_first_checkin", {
366              days_since_first: retention.daysSinceFirst
367            });
368          }
369        }
370      }
371      setJustCompleted(true);
372      await refetchToday();
373      await queryClient.invalidateQueries({
374        queryKey: ["retentionState"]
375      });
376      void (async () => {
377        try {
378          const reviews = await listReviews();
379          const last = reviews?.[0]?.created_at;
380          if (!last || Date.now() - new Date(last).getTime() > 7 * 864e5) {
381            await runWeeklyAnalysis();
382          }
383        } catch {
384        }
385        try {
386          await evaluateEvolution();
387        } catch {
388        }
389        try {
390          const result = await runAdaptation({
391            data: {
392              trigger: "check_in"
393            }
394          });
395          void analytics.track("adaptation_evaluated", {
396            level: result.level,
397            reason_class: result.reasonClass,
398            materiality_score: result.materialityScore,
399            roadmap_outcome: result.roadmapOutcome,
400            profile_outcome: result.profileOutcome,
401            phase_outcome: result.phaseOutcome,
402            duplicate_skipped: result.duplicateSkipped,
403            failed: result.failed
404          });
405          try {
406            const patch = await adaptPlan({
407              data: {
408                trigger: "check_in"
409              }
410            });
411            void analytics.track("execution_plan_adaptation_evaluated", {
412              status: patch.status,
413              reason_class: patch.reasonClass,
414              from_version: patch.fromVersion,
415              to_version: patch.toVersion
416            });
417            if (patch.status === "patched") {
418              void analytics.track("execution_plan_patched", {
419                plan_id: patch.planId,
420                reason_class: patch.reasonClass,
421                superseded: patch.counts.superseded,
422                replaced: patch.counts.replaced,
423                appended: patch.counts.appended,
424                reordered: patch.counts.reordered
425              });
426              await queryClient.invalidateQueries({
427                queryKey: ["executionPlan"]
428              });
429            }
430          } catch {
431          }
432          if (result.roadmapOutcome === "applied" || result.profileOutcome === "applied") {
433            await queryClient.invalidateQueries();
434          } else {
435            await queryClient.invalidateQueries({
436              queryKey: ["nextMoveRecommendation"]
437            });
438          }
439        } catch {
440          await queryClient.invalidateQueries({
441            queryKey: ["nextMoveRecommendation"]
442          });
443        }
444      })();
445    } catch (e) {
446      setErr(e instanceof Error ? e.message : "Failed");
447    } finally {
448      setBusy(false);
449    }
450  };
451  if (todayLoading) {
452    return /* @__PURE__ */ jsxRuntimeExports.jsx(Shell, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { "aria-busy": true, className: "mt-10", children: [
453      /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "flex items-center gap-2 text-[13px] text-muted-foreground", children: [
454        /* @__PURE__ */ jsxRuntimeExports.jsx(PendingDot, { className: "text-accent" }),
455        "Loading today’s check-in…"
456      ] }),
457      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-6 space-y-3", children: [
458        /* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-24 w-full" }),
459        /* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-16 w-full" })
460      ] })
461    ] }) });
462  }
463  if (alreadyDone && todayEntry) {
464    return /* @__PURE__ */ jsxRuntimeExports.jsx(CompletedCheckIn, { view: {
465      checkInId: todayEntry.checkInId,
466      checkInAt: todayEntry.checkInAt ?? (/* @__PURE__ */ new Date()).toISOString(),
467      routeSignal: todayEntry.routeSignal,
468      qa: todayEntry.qa,
469      extraNotes: todayEntry.extraNotes,
470      legacy: todayEntry.legacy
471    }, justCompleted, onThisWeek: () => navigate({
472      to: "/this-week"
473    }), onRoadmap: () => navigate({
474      to: "/roadmap"
475    }) });
476  }
477  return /* @__PURE__ */ jsxRuntimeExports.jsxs(Shell, { children: [
478    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-6 animate-fade-up", children: [
479      /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs uppercase tracking-[0.25em] text-accent", children: "Daily check-in" }),
480      /* @__PURE__ */ jsxRuntimeExports.jsx("h1", { className: "mt-3 font-display text-4xl md:text-5xl text-gradient", children: "Today's move." })
481    ] }),
482    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-12 animate-fade-up", children: [
483      /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs uppercase tracking-[0.25em] text-muted-foreground", children: "Help Morable understand you better" }),
484      /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-3 max-w-2xl text-sm text-muted-foreground", children: "Optional — your answers help Morable understand what changed and adapt what comes next." })
485    ] }),
486    qLoading && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-6", children: [
487      /* @__PURE__ */ jsxRuntimeExports.jsx(ThinkingBlock, { label: "Preparing today’s questions", messages: QUESTION_MESSAGES, surface: "check_in_questions", note: "These are written from your current phase and recent progress." }),
488      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-5 space-y-3", children: [
489        /* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-16 w-full" }),
490        /* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-16 w-full" })
491      ] })
492    ] }),
493    !qLoading && questions.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-6 space-y-6", children: questions.map((q, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "glass rounded-3xl p-7 animate-fade-up", children: [
494      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
495        /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs uppercase tracking-[0.2em] text-muted-foreground", children: [
496          "0",
497          i + 1
498        ] }),
499        /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "h-px flex-1 bg-border" })
500      ] }),
501      /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-3 font-display text-xl leading-snug", children: q.question }),
502      q.placeholder && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-2 text-xs text-muted-foreground/70", children: q.placeholder }),
503      /* @__PURE__ */ jsxRuntimeExports.jsx("textarea", { value: answers[i] ?? "", onChange: (e) => setAnswers((prev) => prev.map((a, idx) => idx === i ? e.target.value : a)), placeholder: "Your answer (optional)", rows: 3, className: "mt-4 w-full rounded-2xl bg-background/40 border border-border p-4 text-sm text-foreground placeholder:text-muted-foreground/70 focus:outline-none focus:ring-1 focus:ring-accent/50" })
504    ] }, i)) }),
505    !qLoading && /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "mt-6 glass rounded-3xl p-7 animate-fade-up", children: [
506      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
507        /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs uppercase tracking-[0.2em] text-muted-foreground", children: "Optional" }),
508        /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "h-px flex-1 bg-border" })
509      ] }),
510      /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-3 font-display text-xl leading-snug", children: "Anything else Morable should know?" }),
511      /* @__PURE__ */ jsxRuntimeExports.jsx("textarea", { value: notes, onChange: (e) => setNotes(e.target.value), placeholder: "New context, opportunities, obstacles, shifts in priority.", rows: 3, className: "mt-4 w-full rounded-2xl bg-background/40 border border-border p-4 text-sm text-foreground placeholder:text-muted-foreground/70 focus:outline-none focus:ring-1 focus:ring-accent/50" })
512    ] }),
513    busy && /* @__PURE__ */ jsxRuntimeExports.jsx(ThinkingBlock, { className: "mt-6", label: "Saving your check-in", messages: SUBMIT_MESSAGES, surface: "check_in_submit", note: "Nothing is lost — your answers are already captured." }),
514    !busy && err && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-6", children: [
515      /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-destructive", children: err }),
516      /* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", onClick: handle, className: "mc-focus mt-2 text-xs text-accent hover:opacity-80", children: "Try again" })
517    ] }),
518    /* @__PURE__ */ jsxRuntimeExports.jsxs(WorkspaceActions, { children: [
519      /* @__PURE__ */ jsxRuntimeExports.jsx(PrimaryButton, { workspace: "check_in", label: "Submit today's check-in", disabled: !canSubmit, onClick: handle, children: busy ? /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-2", children: [
520        /* @__PURE__ */ jsxRuntimeExports.jsx(InlineSpinner, {}),
521        "Saving your check-in…"
522      ] }) : "Submit today's check-in" }),
523      /* @__PURE__ */ jsxRuntimeExports.jsx(BackToCommandCenter, { workspace: "check_in" })
524    ] })
525  ] });
526}
527export {
528  CheckIn as component
529};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.