/* Slow Weekend — Saved + the post-outing reflection loop.
   Saved outings live in sw_saved; reflections (how it actually felt) in
   sw_reflections. Reflecting closes the loop: a gentle "we went → how did it
   feel?" that, over time, teaches the picks what leaves your family lighter. */

const SW_FEELINGS = [
  { key: "lighter", label: "We left lighter", accent: "#7E9078" },
  { key: "good",    label: "Good, easy",      accent: "#A6884F" },
  { key: "much",    label: "A bit much",      accent: "#B98A6A" },
  { key: "no",      label: "Not our pace",    accent: "#9A8FA8" },
];

function ReflectPanel({ existing, onSave, onCancel }) {
  const [feeling, setFeeling] = React.useState(existing ? existing.feeling : null);
  const [again, setAgain] = React.useState(existing ? existing.again : null);
  const [note, setNote] = React.useState(existing ? existing.note || "" : "");

  return (
    <div className="sw-stepin" style={{ background: "rgba(126,144,120,0.07)", border: "1px solid rgba(126,144,120,0.18)", borderRadius: 14, padding: "20px 22px", marginTop: 16 }}>
      <p style={{ font: "500 15px 'Source Serif 4', serif", color: "#2F2F2F", margin: "0 0 12px" }}>How did it feel?</p>
      <div style={{ display: "flex", flexWrap: "wrap", gap: 8, marginBottom: 18 }}>
        {SW_FEELINGS.map((f) => {
          const on = feeling === f.key;
          return (
            <button key={f.key} onClick={() => setFeeling(f.key)} style={{
              border: on ? `1px solid ${f.accent}` : "1px solid rgba(47,47,47,0.16)",
              background: on ? `${f.accent}22` : "rgba(255,255,255,0.6)",
              color: on ? "#2F2F2F" : "rgba(47,47,47,0.6)", cursor: "pointer",
              borderRadius: 999, padding: "8px 15px", font: "inherit", fontSize: 13.5, fontWeight: on ? 600 : 500, transition: "all 0.3s ease",
            }}>{f.label}</button>
          );
        })}
      </div>

      <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 18, flexWrap: "wrap" }}>
        <span style={{ fontSize: 14, color: "rgba(47,47,47,0.62)" }}>Would you go again?</span>
        <div style={{ display: "inline-flex", background: "#fff", borderRadius: 999, padding: 3, border: "1px solid rgba(47,47,47,0.1)" }}>
          {[["Yes", true], ["No", false]].map(([l, v]) => (
            <button key={l} onClick={() => setAgain(v)} style={{
              border: "none", cursor: "pointer", borderRadius: 999, padding: "6px 16px", font: "inherit", fontSize: 13.5,
              background: again === v ? "#2F2F2F" : "transparent", color: again === v ? "#F7F5F2" : "rgba(47,47,47,0.55)", transition: "all 0.3s ease",
            }}>{l}</button>
          ))}
        </div>
      </div>

      <input value={note} onChange={(e) => setNote(e.target.value)} placeholder="A note for next time (optional)" style={{
        width: "100%", border: "1px solid rgba(47,47,47,0.14)", borderRadius: 10, padding: "11px 14px",
        font: "inherit", fontSize: 14, color: "#2F2F2F", background: "#fff", outline: "none", boxSizing: "border-box",
      }} />

      <div style={{ display: "flex", gap: 12, marginTop: 16 }}>
        <button onClick={() => feeling && onSave({ feeling, again, note, date: Date.now() })} disabled={!feeling} style={{
          ...swPrimaryBtn, padding: "10px 22px", fontSize: 14, opacity: feeling ? 1 : 0.4, boxShadow: "none",
        }}>Save reflection</button>
        <button onClick={onCancel} style={swGhostLink}>Cancel</button>
      </div>
    </div>
  );
}

function SavedCard({ pick, onOpen, onRemove, onLog }) {
  const accent = CAT_ACCENT[pick.category];
  return (
    <div className="sw-saved-card" style={{ background: "#FFFFFF", borderRadius: 18, border: "1px solid rgba(47,47,47,0.06)", boxShadow: "0 14px 40px -30px rgba(47,47,47,0.28)", overflow: "hidden" }}>
      <TextureBlock tones={pick.tones} seed={1} className="sw-saved-tex" />
      <div style={{ padding: "22px 26px 24px" }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 14 }}>
          <div onClick={() => onOpen(pick.id)} style={{ cursor: "pointer", minWidth: 0 }}>
            <div style={{ whiteSpace: "nowrap" }}><CategoryTag pick={pick} accent={accent} /></div>
            <h3 style={{ font: "500 22px/1.2 'Source Serif 4', serif", color: "#2F2F2F", margin: "11px 0 9px", letterSpacing: "-0.01em" }}>{pick.title}</h3>
            <CardMeta pick={pick} accent={accent} compact />
          </div>
          <button onClick={() => onRemove(pick.id)} title="Remove from saved" style={{
            border: "none", background: "none", cursor: "pointer", font: "inherit", fontSize: 13, color: "rgba(47,47,47,0.4)", whiteSpace: "nowrap", padding: 4,
          }}>Remove</button>
        </div>
        <div style={{ marginTop: 18, paddingTop: 16, borderTop: "1px solid rgba(47,47,47,0.07)" }}>
          <button onClick={() => onLog(pick.id)} style={{
            border: "1px solid rgba(126,144,120,0.32)", background: "transparent", cursor: "pointer", borderRadius: 999,
            padding: "9px 18px", font: "inherit", fontSize: 14, fontWeight: 500, color: "#5d6b58",
          }}>We went →</button>
        </div>
      </div>
    </div>
  );
}

// One row of "Your week": a day and its standing events, sorted by start time.
function WeekDayRow({ entry, onOpen, onRemove, flat }) {
  const timeOf = (o) => { const w = o.when || ""; const i = w.indexOf("·"); return (i >= 0 ? w.slice(i + 1) : w).trim(); };
  // Flat rows sit inside the single "Your week" card (matching the empty
  // template); the standalone style is kept for any other caller.
  const wrap = flat
    ? { display: "flex", gap: 16, alignItems: "flex-start", padding: "13px 2px", borderTop: "1px solid rgba(47,47,47,0.07)" }
    : { display: "flex", gap: 16, alignItems: "flex-start", background: "#FFFFFF", border: "1px solid rgba(47,47,47,0.06)", borderRadius: 16, padding: "14px 18px", boxShadow: "0 12px 34px -28px rgba(47,47,47,0.28)" };
  return (
    <div style={wrap}>
      <div style={{ width: 92, flexShrink: 0, fontSize: 13, fontWeight: 600, letterSpacing: "0.03em", color: "#6f5f93", paddingTop: 2 }}>{entry.label}</div>
      <div style={{ display: "flex", flexDirection: "column", gap: 11, flex: 1, minWidth: 0 }}>
        {entry.items.map((o) => (
          <div key={o.id} style={{ display: "flex", alignItems: "center", gap: 11 }}>
            <span style={{ width: 8, height: 8, borderRadius: "50%", background: CAT_ACCENT[o.category], flexShrink: 0 }} />
            <button onClick={() => onOpen(o.id)} style={{ flex: 1, minWidth: 0, textAlign: "left", border: "none", background: "none", cursor: "pointer", font: "inherit", fontSize: 14.5, color: "#2F2F2F", padding: 0, lineHeight: 1.4 }}>
              <span style={{ fontWeight: 600 }}>{timeOf(o)}</span> {o.title}
              <span style={{ color: "rgba(47,47,47,0.45)" }}> · {o.city}</span>
            </button>
            <button onClick={() => onRemove(o.id)} title="Remove from your week" style={{ border: "none", background: "none", cursor: "pointer", font: "inherit", fontSize: 12.5, color: "rgba(47,47,47,0.38)", whiteSpace: "nowrap", padding: 4, flexShrink: 0 }}>Remove</button>
          </div>
        ))}
      </div>
    </div>
  );
}

// The two natures of Saved, in one place so the empty-state preview and the
// populated screen can never drift apart (the bug: the populated view dropped the
// labels/containers/grid the empty template sets up). `invite` is the aspirational
// empty copy; `live` is the how-it-works copy once there's content.
const SAVED_KINDS = {
  week: {
    label: "Your week", accent: "#5d6b58",
    invite: "Save a weekly storytime or park rhythm and it settles into a standing week, right here.",
    live: "Your standing rhythm. These stay put; logging a visit just marks that you went.",
  },
  shortlist: {
    label: "Your shortlist", accent: "#9A6238",
    invite: "One-off outings you mean to do. Once you've been, mark it and it moves into Memories.",
    live: "One-off outings you mean to do. Mark one once you've been and it moves into Memories.",
  },
};

function KindLabel({ label, accent }) {
  return <span style={{ fontSize: 12, letterSpacing: "0.14em", textTransform: "uppercase", color: accent, fontWeight: 600 }}>{label}</span>;
}

// The 7-day grid from the empty-state template, now driven by real data: each day
// that holds a standing event lights up sage with its count, the rest stay faint.
function WeekStrip({ schedule }) {
  const order = [1, 2, 3, 4, 5, 6, 0];
  const initial = { 0: "S", 1: "M", 2: "T", 3: "W", 4: "T", 5: "F", 6: "S" };
  const countByDay = {};
  (schedule || []).forEach((e) => { countByDay[e.day] = e.items.length; });
  return (
    <div style={{ display: "flex", gap: 6 }}>
      {order.map((d, i) => {
        const n = countByDay[d] || 0;
        return (
          <div key={i} style={{ flex: 1, textAlign: "center" }}>
            <div style={{ fontSize: 10.5, color: "rgba(47,47,47,0.4)", marginBottom: 5 }}>{initial[d]}</div>
            <div style={{ height: 26, borderRadius: 7, display: "flex", alignItems: "center", justifyContent: "center", fontSize: 11.5, fontWeight: 600, background: n ? "rgba(126,144,120,0.22)" : "rgba(47,47,47,0.05)", color: n ? "#5d6b58" : "transparent" }}>
              {n || ""}
            </div>
          </div>
        );
      })}
    </div>
  );
}

function SavedScreen({ saved, onOpen, onRemove, onLog, memories, onBrowse }) {
  const data = window.SLOW_WEEKEND_DATA;
  // Saved has two natures (PRD §4): "Your week" = saved weekly-recurring events,
  // standing (they persist across logged visits); the shortlist = one-off saves
  // that graduate to Memories once logged. SW owns the split so this view and the
  // nav badge can't disagree. Reads only the user's own saves (never seeded).
  const { week, shortlist } = SW.savedGroups(saved, memories, data.outings);
  const schedule = SW.savedWeekSchedule(week, data.outings);
  const shortPicks = shortlist.map((id) => data.outings.find((o) => o.id === id)).filter(Boolean);
  const empty = schedule.length === 0 && shortPicks.length === 0;

  React.useEffect(() => {
    try { if (window.SWA && schedule.length) SWA.track("your_week", { days: schedule.length, events: week.length }); } catch (e) {}
  }, [schedule.length, week.length]);

  return (
    <div className="sw-fade" style={{ maxWidth: 860, margin: "0 auto", padding: "30px clamp(20px,6vw,64px) 130px" }}>
      <span style={{ fontSize: 12.5, letterSpacing: "0.2em", textTransform: "uppercase", color: "rgba(47,47,47,0.4)" }}>Will-do</span>
      <h1 style={{ font: "500 clamp(28px,4vw,38px)/1.1 'Source Serif 4', serif", letterSpacing: "-0.02em", color: "#2F2F2F", margin: "8px 0 0" }}>Saved</h1>
      <p style={{ fontSize: 16, lineHeight: 1.6, color: "rgba(47,47,47,0.58)", margin: "14px 0 0", maxWidth: 560 }}>
        Everything you've saved. Standing weekly events become <strong style={{ fontWeight: 600, color: "#2F2F2F" }}>your week</strong>; one-off plans are your shortlist, and once you've been, mark it so it moves into Memories.
      </p>

      {empty ? (
        /* Aspirational empty state — preview what Saved becomes (the two natures),
           with illustrative placeholders only (never seeded outings; §4 "Saved is
           the user's own choices"). Then funnel to where saving happens. */
        <div style={{ marginTop: 40 }}>
          <div style={{ display: "grid", gap: 16, gridTemplateColumns: "repeat(auto-fit, minmax(244px, 1fr))", marginBottom: 30, opacity: 0.96 }}>
            <div style={{ border: "1px solid rgba(47,47,47,0.1)", borderRadius: 18, padding: "22px 24px", background: "#FFFFFF" }}>
              <KindLabel label={SAVED_KINDS.week.label} accent={SAVED_KINDS.week.accent} />
              <p style={{ fontSize: 14.5, lineHeight: 1.55, color: "rgba(47,47,47,0.62)", margin: "10px 0 16px" }}>{SAVED_KINDS.week.invite}</p>
              <div style={{ display: "flex", gap: 6 }}>
                {["M", "T", "W", "T", "F", "S", "S"].map((d, i) => (
                  <div key={i} style={{ flex: 1, textAlign: "center" }}>
                    <div style={{ fontSize: 10.5, color: "rgba(47,47,47,0.4)", marginBottom: 5 }}>{d}</div>
                    <div style={{ height: 26, borderRadius: 7, background: (i === 1 || i === 5) ? "rgba(126,144,120,0.22)" : "rgba(47,47,47,0.05)" }} />
                  </div>
                ))}
              </div>
            </div>
            <div style={{ border: "1px solid rgba(47,47,47,0.1)", borderRadius: 18, padding: "22px 24px", background: "#FFFFFF" }}>
              <KindLabel label={SAVED_KINDS.shortlist.label} accent={SAVED_KINDS.shortlist.accent} />
              <p style={{ fontSize: 14.5, lineHeight: 1.55, color: "rgba(47,47,47,0.62)", margin: "10px 0 16px" }}>{SAVED_KINDS.shortlist.invite}</p>
              <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
                {[0, 1].map((i) => (
                  <div key={i} style={{ display: "flex", alignItems: "center", gap: 11 }}>
                    <div style={{ width: 34, height: 34, borderRadius: 9, background: "rgba(47,47,47,0.06)", flexShrink: 0 }} />
                    <div style={{ flex: 1 }}>
                      <div style={{ height: 8, width: i ? "52%" : "72%", borderRadius: 4, background: "rgba(47,47,47,0.09)", marginBottom: 6 }} />
                      <div style={{ height: 7, width: i ? "34%" : "46%", borderRadius: 4, background: "rgba(47,47,47,0.05)" }} />
                    </div>
                  </div>
                ))}
              </div>
            </div>
          </div>
          <div style={{ textAlign: "center", padding: "6px 0" }}>
            <p style={{ font: "400 18px 'Source Serif 4', serif", color: "rgba(47,47,47,0.6)", margin: "0 0 18px" }}>Nothing saved yet. Find one you like and tap the heart, it'll gather here.</p>
            <button onClick={onBrowse} style={swPrimaryBtn}>See this week's three</button>
          </div>
        </div>
      ) : (
        <>
          {schedule.length > 0 && (
            <section style={{ marginTop: 34 }}>
              <div style={{ background: "#FFFFFF", border: "1px solid rgba(47,47,47,0.1)", borderRadius: 18, padding: "22px 24px" }}>
                <KindLabel label={SAVED_KINDS.week.label} accent={SAVED_KINDS.week.accent} />
                <p style={{ fontSize: 14.5, lineHeight: 1.55, color: "rgba(47,47,47,0.62)", margin: "10px 0 16px" }}>{SAVED_KINDS.week.live}</p>
                <WeekStrip schedule={schedule} />
                <div style={{ display: "flex", flexDirection: "column", marginTop: 14 }}>
                  {schedule.map((entry) => (
                    <WeekDayRow key={entry.day} entry={entry} onOpen={onOpen} onRemove={onRemove} flat />
                  ))}
                </div>
              </div>
            </section>
          )}

          {shortPicks.length > 0 && (
            <section style={{ marginTop: schedule.length > 0 ? 40 : 34 }}>
              <KindLabel label={SAVED_KINDS.shortlist.label} accent={SAVED_KINDS.shortlist.accent} />
              <p style={{ fontSize: 14.5, lineHeight: 1.55, color: "rgba(47,47,47,0.62)", margin: "10px 0 18px" }}>{SAVED_KINDS.shortlist.live}</p>
              <div style={{ display: "flex", flexDirection: "column", gap: 20 }}>
                {shortPicks.map((p) => (
                  <SavedCard key={p.id} pick={p} onOpen={onOpen} onRemove={onRemove} onLog={onLog} />
                ))}
              </div>
            </section>
          )}
        </>
      )}
    </div>
  );
}

/* ---- Memories — "I actually went" (PRD §6 beta success signal) ---- */

function ordinalDate(d) {
  const n = d.getDate(), v = n % 100, s = ["th", "st", "nd", "rd"];
  const suf = v >= 11 && v <= 13 ? "th" : s[n % 10] || "th";
  return d.toLocaleDateString(undefined, { weekday: "long" }) + " the " + n + suf;
}

function MemoryStat({ value, label, accent }) {
  return (
    <div style={{ background: "rgba(255,255,255,0.06)", borderRadius: 14, padding: "18px 20px" }}>
      <div style={{ font: "600 30px 'Source Serif 4', serif", color: accent, lineHeight: 1 }}>{value}</div>
      <div style={{ fontSize: 13, color: "rgba(247,245,242,0.55)", marginTop: 8 }}>{label}</div>
    </div>
  );
}

function memDateLabel(d) {
  return d.toLocaleDateString(undefined, { weekday: "short", month: "short", day: "numeric" });
}

// A timeline row: open the outing, correct the visit date, remove an accidental
// entry, and reflect on how it felt (reflections live with Memories now).
function MemoryRow({ x, reflection, onOpen, onReflect, onRemove, onSetDate }) {
  const accent = CAT_ACCENT[x.o.category];
  const [editing, setEditing] = React.useState(false);
  const [dateOpen, setDateOpen] = React.useState(false);
  const feeling = reflection && SW_FEELINGS.find((f) => f.key === reflection.feeling);
  const ctrlBtn = { flexShrink: 0, padding: "0 13px", border: "none", borderLeft: "1px solid rgba(47,47,47,0.06)", background: "none", cursor: "pointer", fontSize: 12.5, fontWeight: 600, color: "rgba(47,47,47,0.5)" };
  return (
    <div>
      <div style={{ display: "flex", alignItems: "stretch", gap: 0, background: "#FFFFFF", borderRadius: 16, overflow: "hidden", border: "1px solid rgba(47,47,47,0.06)", boxShadow: "0 12px 32px -30px rgba(47,47,47,0.5)" }}>
        <button onClick={() => onOpen(x.id)} style={{ flex: 1, display: "flex", alignItems: "stretch", gap: 0, textAlign: "left", cursor: "pointer", font: "inherit", border: "none", background: "none", padding: 0, minWidth: 0 }}>
          <TextureBlock tones={x.o.tones} style={{ width: 92, flexShrink: 0, minHeight: 78 }} />
          <div style={{ padding: "15px 18px", minWidth: 0 }}>
            <h4 style={{ font: "500 18px/1.25 'Source Serif 4', serif", color: "#2F2F2F", margin: "0 0 6px", letterSpacing: "-0.01em" }}>{x.o.title}</h4>
            <div style={{ display: "flex", alignItems: "center", gap: 9, flexWrap: "wrap", fontSize: 13, color: "rgba(47,47,47,0.55)" }}>
              <span style={{ display: "inline-flex", alignItems: "center", gap: 8 }}><span style={{ width: 7, height: 7, borderRadius: "50%", background: accent }} />Visited {memDateLabel(x.d)}</span>
              {feeling && <span style={{ display: "inline-flex", alignItems: "center", gap: 6, color: feeling.accent, fontWeight: 600 }}>· {feeling.label}</span>}
            </div>
          </div>
        </button>
        <button onClick={() => setEditing((e) => !e)} title="How did it feel?" style={ctrlBtn}>{reflection ? "Edit" : "Reflect"}</button>
        <button onClick={() => setDateOpen((d) => !d)} title="Fix the date" style={ctrlBtn}>Date</button>
        <button onClick={() => onRemove(x.idx)} title="Remove this visit" style={{ ...ctrlBtn, color: "rgba(47,47,47,0.35)", fontWeight: 400, fontSize: 18, padding: "0 15px" }}>×</button>
      </div>
      {dateOpen && (
        <div className="sw-stepin" style={{ display: "flex", alignItems: "center", gap: 12, flexWrap: "wrap", padding: "12px 16px", marginTop: 6, background: "rgba(47,47,47,0.03)", borderRadius: 12 }}>
          <span style={{ fontSize: 13.5, color: "rgba(47,47,47,0.6)" }}>When did you actually go?</span>
          <input type="date" value={x.date} max={new Date().toISOString().slice(0, 10)}
            onChange={(e) => { if (e.target.value) onSetDate(x.idx, e.target.value); }}
            style={{ border: "1px solid rgba(47,47,47,0.16)", borderRadius: 10, padding: "8px 12px", font: "inherit", fontSize: 14, color: "#2F2F2F", background: "#fff" }} />
          <button onClick={() => setDateOpen(false)} style={swGhostLink}>Done</button>
        </div>
      )}
      {editing && <ReflectPanel existing={reflection} onSave={(r) => { onReflect(x.id, r); setEditing(false); }} onCancel={() => setEditing(false)} />}
    </div>
  );
}

function MemoriesScreen({ memories, reflections, onOpen, onReflect, onRemove, onSetDate, onBrowse }) {
  const data = window.SLOW_WEEKEND_DATA;
  const recap = SW.memoryRecap(memories, data.outings);
  const reflect = SW.textureReflection(memories, data.outings);
  const groups = SW.memoryTimeline(memories, data.outings);

  // The reflection insight lives here now (Memories = did + reflected).
  const distinctVisited = Array.from(new Set(groups.flatMap((g) => g.items).map((x) => x.id)));
  const reflectedIds = distinctVisited.filter((id) => (reflections || {})[id]);
  const lighter = reflectedIds.filter((id) => ["lighter", "good"].includes(reflections[id].feeling));
  const insight = reflectedIds.length >= 2
    ? `Of the ${reflectedIds.length} you've reflected on, ${lighter.length} left you lighter, we'll lean toward more like those.`
    : null;

  if (!memories.length) {
    /* Aspirational empty state — preview the year-in-review the log becomes, with
       illustrative placeholders (dashes, never fabricated counts). Then funnel out. */
    return (
      <div className="sw-fade" style={{ maxWidth: 640, margin: "0 auto", padding: "56px clamp(20px,6vw,64px) 130px", textAlign: "center" }}>
        <h1 style={{ font: "500 clamp(28px,4.4vw,40px)/1.1 'Source Serif 4', serif", letterSpacing: "-0.02em", color: "#2F2F2F", margin: "0 0 14px" }}>Where you've been</h1>
        <p style={{ fontSize: 16.5, lineHeight: 1.6, color: "rgba(47,47,47,0.6)", margin: "0 0 30px" }}>
          When you go somewhere good, mark it as visited. We keep a quiet record of your slow weekends, and turn it into a year-in-review you'll actually want to look back on.
        </p>
        <div style={{ border: "1px solid rgba(47,47,47,0.1)", borderRadius: 20, padding: "26px 24px", background: "#FFFFFF", marginBottom: 30, textAlign: "left" }}>
          <span style={{ fontSize: 12, letterSpacing: "0.16em", textTransform: "uppercase", color: "rgba(47,47,47,0.42)", fontWeight: 600 }}>Your year, one day</span>
          <div style={{ display: "flex", gap: 12, margin: "16px 0 18px", flexWrap: "wrap" }}>
            {[["—", "outings"], ["—", "places"], ["—", "calm hours"]].map(([n, label], i) => (
              <div key={i} style={{ flex: "1 1 90px", background: "rgba(126,144,120,0.08)", borderRadius: 14, padding: "16px 14px", textAlign: "center" }}>
                <div style={{ font: "500 26px 'Source Serif 4', serif", color: "rgba(47,47,47,0.45)" }}>{n}</div>
                <div style={{ fontSize: 12, color: "rgba(47,47,47,0.5)", marginTop: 3 }}>{label}</div>
              </div>
            ))}
          </div>
          <p style={{ margin: 0, fontSize: 13.5, lineHeight: 1.55, color: "rgba(47,47,47,0.5)" }}>
            Log a few visits and this fills in: the places that left you lighter, your most-loved outing, and the texture of your year.
          </p>
        </div>
        <button onClick={onBrowse} style={{ border: "none", cursor: "pointer", borderRadius: 999, padding: "14px 28px", fontSize: 15, font: "inherit", fontWeight: 500, background: "#2F2F2F", color: "#F7F5F2" }}>See this week's picks →</button>
      </div>
    );
  }

  return (
    <div className="sw-fade" style={{ maxWidth: 860, margin: "0 auto", padding: "30px clamp(20px,6vw,64px) 130px" }}>
      <h1 style={{ font: "500 clamp(28px,4.4vw,42px)/1.1 'Source Serif 4', serif", letterSpacing: "-0.02em", color: "#2F2F2F", margin: 0 }}>Where you've been</h1>
      <p style={{ fontSize: 16, color: "rgba(47,47,47,0.55)", margin: "12px 0 0" }}>{recap.visits} slow weekend{recap.visits !== 1 ? "s" : ""} this year.</p>

      <div style={{ background: "#2F2F2F", borderRadius: 24, padding: "clamp(24px,4vw,36px)", color: "#F7F5F2", margin: "28px 0 44px", boxShadow: "0 30px 60px -40px rgba(47,47,47,0.7)" }}>
        <span style={{ fontSize: 12, letterSpacing: "0.18em", textTransform: "uppercase", color: "rgba(247,245,242,0.45)" }}>{recap.year} · so far</span>
        <h2 style={{ font: "500 clamp(24px,3.4vw,30px) 'Source Serif 4', serif", color: "#F7F5F2", margin: "10px 0 22px", letterSpacing: "-0.01em" }}>Your year in slow weekends</h2>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 12, marginBottom: 14 }}>
          <MemoryStat value={recap.visits} label="outings together" accent="#C2A878" />
          <MemoryStat value={recap.hours} label="calm hours" accent="#A8B5A2" />
          <MemoryStat value={recap.places} label="places" accent="#B0A6C0" />
        </div>
        {recap.byCategory.length > 0 && (
          <div style={{ background: "rgba(255,255,255,0.06)", borderRadius: 14, padding: "20px 22px" }}>
            <div style={{ fontSize: 13, color: "rgba(247,245,242,0.55)", marginBottom: 14 }}>Your weekends leaned…</div>
            <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
              {recap.byCategory.map((c) => (
                <div key={c.key}>
                  <div style={{ display: "flex", justifyContent: "space-between", fontSize: 13.5, marginBottom: 5 }}>
                    <span style={{ color: "#F7F5F2" }}>{c.key}</span><span style={{ color: "rgba(247,245,242,0.6)" }}>{c.pct}%</span>
                  </div>
                  <div style={{ height: 7, borderRadius: 999, background: "rgba(255,255,255,0.08)", overflow: "hidden" }}>
                    <div style={{ width: `${c.pct}%`, height: "100%", borderRadius: 999, background: CAT_ACCENT[c.key] || "#A8B5A2" }} />
                  </div>
                </div>
              ))}
            </div>
          </div>
        )}
        {recap.mostLoved && (
          <p style={{ font: "italic 400 16px/1.5 'Source Serif 4', serif", color: "rgba(247,245,242,0.82)", margin: "20px 2px 0" }}>
            Your most-loved: <strong style={{ color: "#F7F5F2", fontStyle: "normal", fontWeight: 600 }}>{recap.mostLoved.outing.title}</strong>, you went back {recap.mostLoved.count} times.
          </p>
        )}
      </div>

      {reflect.unlocked ? (
        <div style={{ position: "relative", overflow: "hidden", borderRadius: 24, padding: "clamp(26px,4vw,40px)", margin: "0 0 40px", background: "linear-gradient(135deg, #5d6b58, #2F2F2F)", color: "#F7F5F2", boxShadow: "0 30px 60px -40px rgba(47,47,47,0.7)" }}>
          <span style={{ fontSize: 12, letterSpacing: "0.18em", textTransform: "uppercase", color: "rgba(247,245,242,0.5)" }}>Your reflection</span>
          <h2 style={{ font: "500 clamp(26px,4vw,36px)/1.15 'Source Serif 4', serif", margin: "12px 0 10px", letterSpacing: "-0.01em" }}>{reflect.persona}</h2>
          <p style={{ fontSize: 16.5, lineHeight: 1.55, color: "rgba(247,245,242,0.82)", margin: "0 0 24px", maxWidth: 520 }}>{reflect.headline} {reflect.sought}</p>
          <div style={{ display: "flex", flexDirection: "column", gap: 11 }}>
            {reflect.byTexture.slice(0, 4).map((tx) => (
              <div key={tx.key}>
                <div style={{ display: "flex", justifyContent: "space-between", fontSize: 13.5, marginBottom: 5 }}>
                  <span style={{ color: "#F7F5F2" }}>{tx.key}</span><span style={{ color: "rgba(247,245,242,0.6)" }}>{tx.pct}%</span>
                </div>
                <div style={{ height: 7, borderRadius: 999, background: "rgba(255,255,255,0.1)", overflow: "hidden" }}>
                  <div style={{ width: `${tx.pct}%`, height: "100%", borderRadius: 999, background: "#C2A878" }} />
                </div>
              </div>
            ))}
          </div>
        </div>
      ) : (
        <div style={{ margin: "0 0 40px", background: "rgba(126,144,120,0.09)", border: "1px dashed rgba(126,144,120,0.35)", borderRadius: 18, padding: "22px 24px" }}>
          <span style={{ fontSize: 12, letterSpacing: "0.18em", textTransform: "uppercase", color: "#5d6b58", fontWeight: 600 }}>A reflection is forming</span>
          <p style={{ fontSize: 15.5, lineHeight: 1.6, color: "rgba(47,47,47,0.65)", margin: "10px 0 0", maxWidth: 540 }}>
            Once you've marked {reflect.need} outings, we'll show you the shape of your slow weekends: the kinds of outings you lean toward and what that says about your family, a little like a year-in-review. {reflect.remaining} more to go, and every visit you log brings it closer.
          </p>
        </div>
      )}

      {insight && (
        <div style={{ margin: "0 0 36px", background: "rgba(126,144,120,0.09)", border: "1px solid rgba(126,144,120,0.2)", borderRadius: 14, padding: "16px 20px", fontSize: 14.5, color: "#5d6b58", lineHeight: 1.5 }}>
          {insight}
        </div>
      )}

      {groups.map((g) => (
        <div key={g.label} style={{ marginBottom: 26 }}>
          <div style={{ fontSize: 12, letterSpacing: "0.16em", textTransform: "uppercase", color: "rgba(47,47,47,0.4)", fontWeight: 600, margin: "0 0 12px" }}>{g.label}</div>
          <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
            {g.items.map((x) => (
              <MemoryRow key={x.idx} x={x} reflection={(reflections || {})[x.id]} onOpen={onOpen} onReflect={onReflect} onRemove={onRemove} onSetDate={onSetDate} />
            ))}
          </div>
        </div>
      ))}
    </div>
  );
}

Object.assign(window, { SavedScreen, SavedCard, WeekDayRow, ReflectPanel, MemoriesScreen, MemoryRow, MemoryStat });
