import { useEffect, useMemo, useState, type CSSProperties, type Dispatch, type SetStateAction } from "react";
import HexLattice, { type HexNode } from "./HexLattice";
import ResonanceIndicators, { type ResonanceSignal } from "./ResonanceIndicators";

type CartCategoryKey = "food" | "activities" | "habitat";
type CurrentWarmth = "hot" | "warm" | "cool";
type InvestigationMode = "quick" | "breakdown" | "profile";

export interface OnboardingJourneySummary {
  name: string;
  claims: string[];
  cart: Record<CartCategoryKey, { name: string; note?: string }[]>;
}

export interface OnboardingJourneyProps {
  initialName?: string;
  onComplete?: (summary: OnboardingJourneySummary) => void;
}

const STEP_TITLES = [
  "Name + claim your hex",
  "Plant your Inner Circle",
  "First cart — Food",
  "First cart — Activities",
  "First cart — Habitat",
  "Your constellation begins",
  "First return — The Current",
];

const STEP_GUIDES = [
  {
    outcome: "Establish ownership",
    next: "Enter your name to fix the center hex.",
  },
  {
    outcome: "Plant the Inner Circle",
    next: "Claim the six people who anchor your world, or skip for now.",
  },
  {
    outcome: "Seed food identity",
    next: "Add at least one food item to continue.",
  },
  {
    outcome: "Seed activity identity",
    next: "Add at least one activity item to continue.",
  },
  {
    outcome: "Seed habitat identity",
    next: "Add at least one habitat item to continue.",
  },
  {
    outcome: "Close the planting phase",
    next: "You need 9 planted seeds before the cascade can begin.",
  },
  {
    outcome: "Open the live atmosphere",
    next: "Check back in an hour to see who has entered your field.",
  },
] as const;

const CLAIM_SUGGESTIONS = ["Avery", "Mina", "Theo", "Sam", "Casey", "Jordan", "Riley", "Noa"];

const CATEGORY_META: Record<
  CartCategoryKey,
  {
    label: string;
    prompt: string;
    examples: string[];
    accent: string;
    signal: ResonanceSignal["key"];
  }
> = {
  food: {
    label: "Food",
    prompt: "Tell us how you eat.",
    examples: ["Ramen Bar X", "Farmers market on Saturdays", "My own cooking"],
    accent: "#d4a574",
    signal: "hearts",
  },
  activities: {
    label: "Activities",
    prompt: "Tell us how you spend your time.",
    examples: ["Rock climbing on weekends", "Jazz vinyl listening", "Language learning apps"],
    accent: "#8ab6d6",
    signal: "stars",
  },
  habitat: {
    label: "Habitat",
    prompt: "Tell us about your space.",
    examples: ["My plants (14 and counting)", "Minimalist kitchen", "Bookshelf I actually use"],
    accent: "#9ac18a",
    signal: "moons",
  },
};

const CURRENT_SAMPLE = [
  {
    id: "mira",
    name: "Mira",
    warmth: "hot" as CurrentWarmth,
    floatLevel: "Cloud Walking" as const,
    resonanceScore: 88,
    primarySignal: "hearts" as const,
    featuredItems: ["Ramen Bar X", "Bike rides after sunset", "Ceramic mugs"],
    cartSummary: {
      food: ["Ramen Bar X", "Sour cherries", "Sunday pastries"],
      activities: ["Bike rides after sunset", "Late-night walks", "Film scores on vinyl"],
      habitat: ["Plants near every window", "Soft lighting", "A well-used kitchen"],
    },
    daysInCurrent: 11,
    heartsAvailable: 4,
    patterns: [
      { key: "hearts" as const, label: "Direct overlap", detail: "You both have Ramen Bar X and the same evening ritual.", active: true },
      { key: "hourglasses" as const, label: "Values alignment", detail: "Your patterns over the last 90 days moved together.", active: true },
      { key: "balloons" as const, label: "Presence + growth", detail: "Both of you have shown up consistently without drop-off.", active: true },
      { key: "stars" as const, label: "Category congruence", detail: "Your food and activity categories are both adventurous.", active: true },
    ],
  },
  {
    id: "sol",
    name: "Sol",
    warmth: "warm" as CurrentWarmth,
    floatLevel: "Airy" as const,
    resonanceScore: 69,
    primarySignal: "stars" as const,
    featuredItems: ["Jazz vinyl listening", "Indie film nights", "Espresso at 4pm"],
    cartSummary: {
      food: ["Espresso at 4pm", "Farmers market tomatoes", "Lemon tart"],
      activities: ["Jazz vinyl listening", "Indie film nights", "Sketchbook walks"],
      habitat: ["Record shelves", "Open windows", "One perfect lamp"],
    },
    daysInCurrent: 8,
    heartsAvailable: 2,
    patterns: [
      { key: "stars" as const, label: "Category congruence", detail: "Creative-night rituals and local food routines line up.", active: true },
      { key: "moons" as const, label: "Complementary rhythm", detail: "Your carts fill each other’s dinner-party gap.", active: true },
      { key: "balloons" as const, label: "Presence + growth", detail: "A steady daily pulse keeps the resonance warm.", active: true },
      { key: "hearts" as const, label: "Direct overlap", detail: "A few exact items match, but not enough for the strongest tier.", active: false },
    ],
  },
  {
    id: "nadia",
    name: "Nadia",
    warmth: "cool" as CurrentWarmth,
    floatLevel: "Drifting" as const,
    resonanceScore: 36,
    primarySignal: "moons" as const,
    featuredItems: ["My own cooking", "Secondhand sofa", "Sunday hikes"],
    cartSummary: {
      food: ["My own cooking", "Soup in winter", "Good tomatoes"],
      activities: ["Sunday hikes", "Slow mornings", "Library trips"],
      habitat: ["Secondhand sofa", "Plants in the kitchen", "Warm blankets"],
    },
    daysInCurrent: 4,
    heartsAvailable: 1,
    patterns: [
      { key: "moons" as const, label: "Complementary rhythm", detail: "Your cart fills the post-hike meal gap beautifully.", active: true },
      { key: "stars" as const, label: "Category congruence", detail: "You both have a grounded homebody orientation.", active: true },
      { key: "hourglasses" as const, label: "Values alignment", detail: "There are hints of the same values, but the signal is still thin.", active: false },
    ],
  },
  {
    id: "iris",
    name: "Iris",
    warmth: "warm" as CurrentWarmth,
    floatLevel: "Rising" as const,
    resonanceScore: 74,
    primarySignal: "hourglasses" as const,
    featuredItems: ["Farmers market on Saturdays", "Language learning apps", "Composting"],
    cartSummary: {
      food: ["Farmers market on Saturdays", "Meal prep Sundays", "Natural wine"],
      activities: ["Language learning apps", "Volunteering", "Long bike rides"],
      habitat: ["Composting", "Books everywhere", "Secondhand furniture"],
    },
    daysInCurrent: 17,
    heartsAvailable: 3,
    patterns: [
      { key: "hourglasses" as const, label: "Values alignment", detail: "The last 90 days show the same worldview and cadence.", active: true },
      { key: "stars" as const, label: "Category congruence", detail: "Your habits and activity categories point in the same direction.", active: true },
      { key: "balloons" as const, label: "Presence + growth", detail: "You both keep returning without needing a reminder.", active: true },
    ],
  },
  {
    id: "jun",
    name: "Jun",
    warmth: "hot" as CurrentWarmth,
    floatLevel: "Cloud Walking" as const,
    resonanceScore: 92,
    primarySignal: "balloons" as const,
    featuredItems: ["Hiking with my dog", "Gallery openings", "Meal-prepped weekdays"],
    cartSummary: {
      food: ["Meal-prepped weekdays", "Picnic lunches", "Coffee before dawn"],
      activities: ["Hiking with my dog", "Gallery openings", "Climbing gym sessions"],
      habitat: ["A dog bed by the window", "Gear hooks by the door", "Weekend laundry stacks"],
    },
    daysInCurrent: 12,
    heartsAvailable: 5,
    patterns: [
      { key: "balloons" as const, label: "Presence + growth", detail: "This is a sustained daily pulse. The current has teeth.", active: true },
      { key: "hearts" as const, label: "Direct overlap", detail: "There are multiple exact item matches.", active: true },
      { key: "moons" as const, label: "Complementary rhythm", detail: "Your carts complete each other’s adventure arc.", active: true },
      { key: "hourglasses" as const, label: "Values alignment", detail: "The pattern has held long enough to become worldview.", active: true },
    ],
  },
  {
    id: "wren",
    name: "Wren",
    warmth: "cool" as CurrentWarmth,
    floatLevel: "Drifting" as const,
    resonanceScore: 28,
    primarySignal: "stars" as const,
    featuredItems: ["Bookshelf I actually use", "Train rides", "Climbing chalk"],
    cartSummary: {
      food: ["Late breakfast", "Seltzer after work", "Trail mix"],
      activities: ["Train rides", "Climbing chalk", "Weekend errands"],
      habitat: ["Bookshelf I actually use", "Small apartment plants", "Lamp in every room"],
    },
    daysInCurrent: 2,
    heartsAvailable: 0,
    patterns: [
      { key: "stars" as const, label: "Category congruence", detail: "A few category-level signals are aligning, but it is still early.", active: true },
      { key: "balloons" as const, label: "Presence + growth", detail: "The signal is still forming and needs more showing up.", active: false },
      { key: "hearts" as const, label: "Direct overlap", detail: "No exact overlaps yet.", active: false },
    ],
  },
];

function clamp(value: number, min: number, max: number) {
  return Math.max(min, Math.min(max, value));
}

function makeId(prefix: string) {
  return `${prefix}-${Math.random().toString(36).slice(2, 9)}-${Date.now().toString(36)}`;
}

function normalize(value: string) {
  return value.trim().toLowerCase();
}

function isDuplicateItem(name: string, items: { name: string }[]) {
  const target = normalize(name);
  return items.some((item) => normalize(item.name) === target);
}

function shortLabel(value: string, max = 14) {
  const compact = value.trim().replace(/\s+/g, " ");
  return compact.length <= max ? compact : `${compact.slice(0, max - 1)}…`;
}

function initials(name: string) {
  return name
    .split(/\s+/)
    .filter(Boolean)
    .map((part) => part[0]?.toUpperCase())
    .slice(0, 2)
    .join("");
}

function scoreLabel(score: number) {
  if (score >= 81) return "Resonant";
  if (score >= 61) return "Blazing";
  if (score >= 41) return "Hot";
  if (score >= 21) return "Warm";
  return "Cool";
}

function formatHours(hours: number) {
  if (hours < 1) return `${Math.max(1, Math.round(hours * 60))}m`;
  if (hours < 24) return `${hours.toFixed(1)}h`;
  return `${Math.round(hours / 24)}d`;
}

function categoryCounts(cart: Record<CartCategoryKey, { name: string; note?: string }[]>) {
  return {
    food: cart.food.length,
    activities: cart.activities.length,
    habitat: cart.habitat.length,
  };
}

function signalScore(signals: ResonanceSignal[]) {
  const totalWeighted = signals.reduce((sum, signal) => {
    const weight = signal.key === "hearts" || signal.key === "hourglasses" ? 1.5 : signal.key === "moons" ? 1.2 : signal.key === "balloons" ? 0.8 : 1;
    return sum + clamp(signal.score, 0, 100) * weight;
  }, 0);

  return Math.round((totalWeighted / 6) * 100);
}

function formatUntilNextHour(now: number) {
  const minutes = 60 - (Math.floor(now / 60000) % 60);
  return `${minutes === 60 ? 0 : minutes}m`;
}

function formatClock(now: number) {
  return new Intl.DateTimeFormat("en-US", {
    hour: "numeric",
    minute: "2-digit",
    hour12: false,
    timeZone: "America/Chicago",
  }).format(now);
}

function currentWarmthMeta(warmth: CurrentWarmth) {
  if (warmth === "hot") return { label: "Hot", icon: "🔥", color: "#fb7185" };
  if (warmth === "warm") return { label: "Warm", icon: "🌡️", color: "#f59e0b" };
  return { label: "Cool", icon: "🌿", color: "#94a3b8" };
}

function stepCopy(step: number) {
  switch (step) {
    case 0:
      return "A first act, not a form. You are planting the center.";
    case 1:
      return "These six people do not change often. Choose once, then let the bond breathe.";
    case 2:
      return "The first three food items define the initial resonance field.";
    case 3:
      return "Activities describe how you move, not how you perform.";
    case 4:
      return "Habitat shows who you are when nobody is watching.";
    case 5:
      return "Nine planted seeds begin the cascade. The Current starts forming.";
    case 6:
      return "The atmosphere is live. Investigate the field gently.";
    default:
      return "";
  }
}

function StepRail({ step }: { step: number }) {
  return (
    <div style={{ display: "grid", gap: 6 }}>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(7, minmax(0, 1fr))", gap: 6 }}>
        {STEP_TITLES.map((label, index) => {
          const active = index === step;
          const complete = index < step;
          return (
            <div
              key={label}
              style={{
                borderRadius: 999,
                padding: "8px 10px",
                border: active ? "1px solid rgba(246,217,179,0.48)" : "1px solid rgba(255,255,255,0.08)",
                background: active ? "rgba(212,165,116,0.18)" : complete ? "rgba(154,193,138,0.14)" : "rgba(255,255,255,0.04)",
                color: active ? "#f6d9b3" : complete ? "#d8f0d0" : "rgba(245,236,224,0.62)",
                fontSize: 11,
                lineHeight: 1.25,
                minHeight: 42,
                display: "flex",
                alignItems: "center",
                justifyContent: "center",
                textAlign: "center",
              }}
            >
              {label}
            </div>
          );
        })}
      </div>
    </div>
  );
}

export default function OnboardingJourney({ initialName = "", onComplete }: OnboardingJourneyProps) {
  const [step, setStep] = useState(0);
  const [name, setName] = useState(initialName);
  const [claimMode, setClaimMode] = useState<"pending" | "claimed" | "skipped">("pending");
  const [claims, setClaims] = useState<Array<string | null>>([null, null, null, null, null, null]);
  const [cart, setCart] = useState<Record<CartCategoryKey, { name: string; note?: string }[]>>({
    food: [],
    activities: [],
    habitat: [],
  });
  const [drafts, setDrafts] = useState<Record<CartCategoryKey, { name: string; note: string }>>({
    food: { name: "", note: "" },
    activities: { name: "", note: "" },
    habitat: { name: "", note: "" },
  });
  const [clockNow, setClockNow] = useState(() => Date.now());
  const liveCurrent = step >= 6;

  useEffect(() => {
    const timer = setInterval(() => setClockNow(Date.now()), 60_000);
    return () => clearInterval(timer);
  }, []);

  const plantedCount = cart.food.length + cart.activities.length + cart.habitat.length;
  const claimedCount = claims.filter(Boolean).length;
  const currentClock = formatClock(clockNow);
  const nextRefresh = formatUntilNextHour(clockNow);

  const canAdvance =
    (step === 0 && name.trim().length > 0) ||
    (step === 1 && claimMode !== "pending") ||
    (step === 2 && cart.food.length >= 3) ||
    (step === 3 && cart.activities.length >= 3) ||
    (step === 4 && cart.habitat.length >= 3) ||
    (step === 5 && plantedCount >= 9) ||
    step >= 6;

  const currentSignals = useMemo<ResonanceSignal[]>(() => {
    const counts = categoryCounts(cart);
    return [
      {
        key: "hearts",
        score: clamp(counts.food * 18 + claimedCount * 6, 0, 100),
        note: `${counts.food} food seeds and ${claimedCount} claimed anchors`,
      },
      {
        key: "stars",
        score: clamp((counts.food > 0 ? 22 : 0) + (counts.activities > 0 ? 22 : 0) + (counts.habitat > 0 ? 22 : 0), 0, 100),
        note: "Category coverage across the cart",
      },
      {
        key: "moons",
        score: clamp(plantedCount >= 6 ? 58 : plantedCount * 8, 0, 100),
        note: "Whether the first nine are beginning to complement each other",
      },
      {
        key: "hourglasses",
        score: clamp(plantedCount >= 9 ? 72 : plantedCount * 7, 0, 100),
        note: "The cart's values signal is still forming",
      },
      {
        key: "balloons",
        score: clamp((liveCurrent ? 42 : 18) + plantedCount * 4, 0, 100),
        note: liveCurrent ? "The atmosphere is live" : "The Current is still forming",
      },
    ];
  }, [cart, claimedCount, liveCurrent, plantedCount]);

  const resonanceScore = signalScore(currentSignals);
  const resonanceLabel = scoreLabel(resonanceScore);
  const currentScore = Math.min(92, 28 + plantedCount * 4 + claimedCount * 5 + (liveCurrent ? 12 : 0));
  const currentGuide = STEP_GUIDES[step];

  const latticeNodes = useMemo<HexNode[]>(() => {
    const nodes: HexNode[] = [
      {
        id: "center-you",
        ring: 0,
        position: 0,
        label: name.trim() || "YOU",
        type: "you",
      },
    ];

    for (let position = 0; position < 6; position += 1) {
      const claim = claims[position];
      if (claim) {
        nodes.push({
          id: `claim-${position}`,
          ring: 1,
          position,
          label: shortLabel(claim, 12),
          type: "person",
          resonanceSignal: position % 2 === 0 ? "hearts" : "stars",
        });
      } else if (claimMode === "skipped") {
        nodes.push({
          id: `claim-${position}-dormant`,
          ring: 1,
          position,
          label: position === 0 ? "dormant" : undefined,
          type: "dim",
        });
      } else {
        nodes.push({
          id: `claim-${position}-empty`,
          ring: 1,
          position,
          type: "empty",
        });
      }
    }

    const allocations: Array<[CartCategoryKey, number, number[]]> = [
      ["food", 3, [0, 3, 6]],
      ["activities", 4, [1, 7, 13]],
      ["habitat", 5, [2, 8, 14]],
    ];

    allocations.forEach(([category, ring, positions]) => {
      cart[category].slice(0, 3).forEach((item, index) => {
        nodes.push({
          id: `${category}-${index}`,
          ring,
          position: positions[index],
          label: shortLabel(item.name, 13),
          type: "person",
          resonanceSignal: CATEGORY_META[category].signal,
        });
      });
    });

    if (step >= 6) {
      const positions = [0, 6, 12, 18, 24, 30];
      CURRENT_SAMPLE.forEach((sample, index) => {
        nodes.push({
          id: sample.id,
          ring: 6,
          position: positions[index],
          label: initials(sample.name),
          type: sample.warmth === "hot" ? "resonance-hot" : sample.warmth === "warm" ? "resonance-warm" : "resonance-cool",
          resonanceSignal: sample.primarySignal,
        });
      });
    }

    return nodes;
  }, [cart, claimMode, claims, name, step]);

  const cardStyle: CSSProperties = {
    background: "rgba(21, 22, 28, 0.92)",
    border: "1px solid rgba(255,255,255,0.08)",
    borderRadius: 22,
    boxShadow: "0 20px 50px rgba(0,0,0,0.24)",
  };

  const rootStyle: CSSProperties = {
    minHeight: "100%",
    padding: 24,
    background:
      "radial-gradient(circle at top, rgba(212,165,116,0.12), transparent 36%), radial-gradient(circle at 82% 22%, rgba(126,184,201,0.10), transparent 28%), linear-gradient(180deg, #09090d 0%, #111117 100%)",
    color: "#efe7db",
    fontFamily: "system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
  };

  const inputStyle: CSSProperties = {
    width: "100%",
    borderRadius: 14,
    border: "1px solid rgba(255,255,255,0.12)",
    background: "rgba(7, 7, 10, 0.75)",
    color: "#f7efe2",
    padding: "12px 12px",
    outline: "none",
    fontSize: 14,
  };

  const chipStyle: CSSProperties = {
    borderRadius: 999,
    border: "1px solid rgba(255,255,255,0.12)",
    background: "rgba(255,255,255,0.04)",
    color: "#f4ede2",
    padding: "7px 12px",
    fontSize: 12,
    cursor: "pointer",
  };

  const advance = () => {
    if (step === 6) {
      onComplete?.({
        name: name.trim(),
        claims: claims.filter((entry): entry is string => Boolean(entry)),
        cart,
      });
      return;
    }

    if (!canAdvance) return;
    setStep((current) => Math.min(current + 1, 6));
  };

  const back = () => setStep((current) => Math.max(0, current - 1));

  const updateClaim = (value: string) => {
    setClaims((current) => {
      const next = [...current];
      const slot = next.findIndex((entry) => !entry);
      if (slot === -1) return current;
      next[slot] = value;
      return next;
    });
    setClaimMode("claimed");
  };

  const skipClaim = () => {
    setClaimMode("skipped");
  };

  return (
    <section style={rootStyle}>
      <div style={{ maxWidth: 1280, margin: "0 auto", display: "grid", gap: 18 }}>
        <section
          style={{
            borderRadius: 28,
            border: "1px solid rgba(255,255,255,0.08)",
            background: "rgba(16, 16, 22, 0.82)",
            padding: 22,
            boxShadow: "0 20px 50px rgba(0,0,0,0.22)",
          }}
        >
          <div style={{ display: "flex", justifyContent: "space-between", gap: 16, flexWrap: "wrap", alignItems: "flex-start" }}>
            <div style={{ minWidth: 280, flex: 1 }}>
              <div style={{ fontSize: 12, textTransform: "uppercase", letterSpacing: "0.16em", color: "#a99e90" }}>Cascade / Onboarding</div>
              <h1 style={{ margin: "8px 0 8px", fontSize: 34, lineHeight: 1.05, color: "#f6d9b3" }}>{title}</h1>
              <p style={{ margin: 0, maxWidth: 820, color: "rgba(245,236,224,0.76)", lineHeight: 1.55 }}>{subtitle}</p>
            </div>

            <div style={{ minWidth: 290, maxWidth: 380, flex: 1, padding: 16, borderRadius: 18, background: "rgba(255,255,255,0.03)", border: "1px solid rgba(255,255,255,0.08)" }}>
              <div style={{ display: "flex", justifyContent: "space-between", gap: 12, alignItems: "baseline" }}>
                <div>
                  <div style={{ fontSize: 12, letterSpacing: "0.12em", textTransform: "uppercase", color: "#a99e90" }}>Planting progress</div>
                  <div style={{ fontSize: 22, fontWeight: 700 }}>{step + 1}/7 steps</div>
                </div>
                <div style={{ textAlign: "right" }}>
                  <div style={{ fontSize: 12, letterSpacing: "0.12em", textTransform: "uppercase", color: "#a99e90" }}>Seeds planted</div>
                  <div style={{ fontSize: 22, fontWeight: 700, color: "#f5d79b" }}>{plantedCount}</div>
                </div>
              </div>
              <div style={{ marginTop: 12, height: 10, borderRadius: 999, background: "rgba(255,255,255,0.07)", overflow: "hidden" }}>
                <div
                  style={{
                    width: `${((step + 1) / 7) * 100}%`,
                    height: "100%",
                    borderRadius: 999,
                    background: "linear-gradient(90deg, #d4a574 0%, #9ac18a 50%, #7eb8c9 100%)",
                    transition: "width 220ms ease",
                  }}
                />
              </div>
              <div style={{ marginTop: 10, display: "grid", gap: 8 }}>
                <div style={{ display: "flex", justifyContent: "space-between", gap: 12, fontSize: 13, color: "#c2b7a8" }}>
                  <span>Current score</span>
                  <span style={{ fontWeight: 700, color: "#f5d79b" }}>{currentScore}/100</span>
                </div>
                <div style={{ display: "flex", justifyContent: "space-between", gap: 12, fontSize: 13, color: "#c2b7a8" }}>
                  <span>Local clock</span>
                  <span style={{ fontWeight: 700 }}>{currentClock}</span>
                </div>
                <div style={{ display: "flex", justifyContent: "space-between", gap: 12, fontSize: 13, color: "#c2b7a8" }}>
                  <span>Next turn</span>
                  <span style={{ fontWeight: 700 }}>{nextRefresh}</span>
                </div>
              </div>
            </div>
          </div>
          <div style={{ marginTop: 14 }}>
            <StepRail step={step} />
          </div>
        </section>

        <div style={{ display: "grid", gridTemplateColumns: "minmax(0, 1.14fr) minmax(340px, 0.86fr)", gap: 18, alignItems: "start" }}>
          <div style={{ display: "grid", gap: 18 }}>
            <section style={{ ...cardStyle, padding: 18 }}>
              <div style={{ display: "flex", justifyContent: "space-between", gap: 12, flexWrap: "wrap", alignItems: "center", marginBottom: 14 }}>
                <div>
                  <div style={{ fontSize: 12, color: "#9ca3af", textTransform: "uppercase", letterSpacing: "0.12em" }}>{STEP_TITLES[step]}</div>
                  <h2 style={{ margin: "6px 0 0", fontSize: 22 }}>
                    {step === 0 && "You are in the center."}
                    {step === 1 && "You start with 6."}
                    {step === 2 && "Tell us how you eat."}
                    {step === 3 && "Tell us how you spend your time."}
                    {step === 4 && "Tell us about your space."}
                    {step === 5 && "You've planted 9."}
                    {step === 6 && "Your atmosphere is live."}
                  </h2>
                </div>
                <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
                  {STEP_TITLES.map((label, index) => (
                    <button
                      key={label}
                      type="button"
                      onClick={() => setStep(index)}
                      style={{
                        minWidth: 34,
                        minHeight: 34,
                        borderRadius: 999,
                        border: "1px solid rgba(255,255,255,0.12)",
                        background: index === step ? "rgba(245, 193, 108, 0.16)" : "rgba(255,255,255,0.04)",
                        color: index === step ? "#ffdca2" : "#f6e9d2",
                        cursor: "pointer",
                        fontWeight: 700,
                      }}
                      aria-label={`Go to ${label}`}
                    >
                      {index + 1}
                    </button>
                  ))}
                </div>
              </div>

              <div style={{ borderRadius: 18, overflow: "hidden", border: "1px solid rgba(255,255,255,0.08)", background: "rgba(10, 10, 14, 0.72)" }}>
                <HexLattice nodes={latticeNodes} showLabels size={step >= 5 ? "full" : "medium"} centerLabel={step === 6 ? "CURRENT" : name.trim() || "YOU"} activeNodeId={step === 6 ? "mira" : "center-you"} />
              </div>
            </section>

            {step === 0 && (
              <section style={{ ...cardStyle, padding: 18 }}>
                <div style={{ display: "grid", gap: 12 }}>
                  <div>
                    <div style={{ fontSize: 12, color: "#9ca3af", letterSpacing: "0.12em", textTransform: "uppercase" }}>Center identity</div>
                    <h3 style={{ margin: "6px 0 0", fontSize: 22 }}>{name.trim() || "Your name goes here"}</h3>
                  </div>

                  <div style={{ display: "grid", gap: 10, gridTemplateColumns: "minmax(0, 1fr) auto" }}>
                    <input value={name} onChange={(event) => setName(event.target.value)} placeholder="Enter your name" style={inputStyle} />
                    <button
                      type="button"
                      onClick={advance}
                      style={{
                        borderRadius: 14,
                        border: "none",
                        background: "linear-gradient(180deg, #d4a574, #c8915e)",
                        color: "#111117",
                        fontWeight: 700,
                        padding: "12px 16px",
                        cursor: canAdvance ? "pointer" : "not-allowed",
                        minWidth: 112,
                        opacity: canAdvance ? 1 : 0.5,
                      }}
                    >
                      Claim center
                    </button>
                  </div>

                  <div style={{ padding: 14, borderRadius: 16, background: "rgba(255,255,255,0.03)", color: "#d8d0c2", lineHeight: 1.55 }}>
                    The center hex is yours. It cannot be moved. It cannot be taken.
                  </div>
                </div>
              </section>
            )}

            {step === 1 && (
              <section style={{ ...cardStyle, padding: 18 }}>
                <div style={{ display: "flex", justifyContent: "space-between", gap: 12, flexWrap: "wrap", alignItems: "center", marginBottom: 12 }}>
                  <div>
                    <div style={{ fontSize: 12, color: "#9ca3af", textTransform: "uppercase", letterSpacing: "0.12em" }}>Inner circle</div>
                    <h3 style={{ margin: "6px 0 0", fontSize: 22 }}>Claim someone or skip for now</h3>
                  </div>
                  <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
                    <button type="button" onClick={skipClaim} style={{ ...chipStyle, color: "#f5d79b" }}>
                      Skip for now
                    </button>
                  </div>
                </div>

                <div style={{ display: "grid", gap: 10, gridTemplateColumns: "minmax(0, 1fr) auto" }}>
                  <input
                    placeholder="Search / enter a name"
                    style={inputStyle}
                    onKeyDown={(event) => {
                      if (event.key === "Enter") {
                        event.preventDefault();
                        const value = (event.currentTarget as HTMLInputElement).value.trim();
                        if (value) {
                          updateClaim(value);
                          (event.currentTarget as HTMLInputElement).value = "";
                        }
                      }
                    }}
                  />
                  <button
                    type="button"
                    onClick={() => {
                      const input = document.querySelector<HTMLInputElement>('input[placeholder="Search / enter a name"]');
                      const value = input?.value.trim() ?? "";
                      if (!value) return;
                      updateClaim(value);
                      if (input) input.value = "";
                    }}
                    style={{
                      borderRadius: 14,
                      border: "none",
                      background: "linear-gradient(180deg, #d4a574, #c8915e)",
                      color: "#111117",
                      fontWeight: 700,
                      padding: "12px 16px",
                      cursor: "pointer",
                      minWidth: 104,
                    }}
                  >
                    Claim
                  </button>
                </div>

                <div style={{ marginTop: 12, display: "flex", flexWrap: "wrap", gap: 8 }}>
                  {CLAIM_SUGGESTIONS.map((suggestion) => (
                    <button
                      key={suggestion}
                      type="button"
                      onClick={() => updateClaim(suggestion)}
                      style={chipStyle}
                    >
                      {suggestion}
                    </button>
                  ))}
                </div>

                <div style={{ display: "grid", gap: 10, marginTop: 14 }}>
                  {claims.map((claim, index) => (
                    <div key={index} style={{ borderRadius: 16, padding: 12, background: claim ? "rgba(212, 165, 116, 0.12)" : "rgba(255,255,255,0.03)", border: "1px solid rgba(255,255,255,0.08)" }}>
                      <div style={{ display: "flex", justifyContent: "space-between", gap: 12, alignItems: "center" }}>
                        <div>
                          <div style={{ fontSize: 12, color: "#9ca3af", textTransform: "uppercase", letterSpacing: "0.12em" }}>Slot {index + 1}</div>
                          <div style={{ marginTop: 4, fontWeight: 700 }}>{claim ?? "Empty"}</div>
                        </div>
                        <div style={{ color: claim ? "#f5d79b" : "#8b93a0", fontSize: 12 }}>{claim ? "Claimed" : "Waiting"}</div>
                      </div>
                    </div>
                  ))}
                </div>

                <div style={{ marginTop: 14, padding: 14, borderRadius: 16, background: "rgba(255,255,255,0.03)", color: "#d8d0c2", lineHeight: 1.55 }}>
                  Claiming is intentional, not casual. The six anchors only matter when they are chosen on purpose.
                </div>
              </section>
            )}

            {step >= 2 && step <= 4 && (
              <section style={{ ...cardStyle, padding: 18 }}>
                <CartStepEditor
                  category={(["food", "activities", "habitat"] as CartCategoryKey[])[step - 2]}
                  cart={cart}
                  drafts={drafts}
                  setDrafts={setDrafts}
                  setCart={setCart}
                  addItem={(category) => {
                    const draft = drafts[category];
                    const itemName = draft.name.trim();
                    if (!itemName || isDuplicateItem(itemName, cart[category])) return;

                    setCart((current) => ({
                      ...current,
                      [category]: [...current[category], { name: itemName, note: draft.note.trim() || undefined }],
                    }));

                    setDrafts((current) => ({
                      ...current,
                      [category]: { name: "", note: "" },
                    }));
                  }}
                />
              </section>
            )}

            {step === 5 && (
              <section style={{ ...cardStyle, padding: 18 }}>
                <div style={{ display: "flex", justifyContent: "space-between", gap: 12, flexWrap: "wrap", alignItems: "center", marginBottom: 12 }}>
                  <div>
                    <div style={{ fontSize: 12, color: "#9ca3af", textTransform: "uppercase", letterSpacing: "0.12em" }}>Constellation</div>
                    <h3 style={{ margin: "6px 0 0", fontSize: 22 }}>You've planted {plantedCount}.</h3>
                  </div>
                  <div style={{ color: "#f5d79b", fontSize: 13 }}>Center + Inner Circle + 9 seeds are in view.</div>
                </div>

                <div style={{ display: "grid", gap: 12, gridTemplateColumns: "repeat(auto-fit, minmax(160px, 1fr))" }}>
                  {Object.entries(cart).map(([category, items]) => (
                    <div key={category} style={{ borderRadius: 16, padding: 14, background: "rgba(255,255,255,0.03)", border: "1px solid rgba(255,255,255,0.08)" }}>
                      <div style={{ fontSize: 12, color: "#9ca3af", textTransform: "uppercase", letterSpacing: "0.12em" }}>{category}</div>
                      <div style={{ marginTop: 6, fontWeight: 700 }}>{items.length} planted</div>
                    </div>
                  ))}
                </div>

                <div style={{ marginTop: 14 }}>
                  <ResonanceIndicators
                    compact
                    title="Cart resonance"
                    subtitle="The first nine seeds define the initial field."
                    score={resonanceScore}
                    recentHours={24}
                    signals={currentSignals}
                    ringDistance={6}
                  />
                </div>

                <div style={{ marginTop: 14 }}>
                  <HexLattice nodes={latticeNodes} showLabels size="full" centerLabel={name.trim() || "YOU"} focusRing={1} />
                </div>
              </section>
            )}

            {step === 6 && (
              <CurrentPreview people={CURRENT_SAMPLE} />
            )}
          </div>

          <aside style={{ display: "grid", gap: 18 }}>
            <section style={{ ...cardStyle, padding: 18 }}>
              <div style={{ fontSize: 12, color: "#9ca3af", textTransform: "uppercase", letterSpacing: "0.12em" }}>Progress</div>
              <div style={{ display: "grid", gap: 10, marginTop: 12 }}>
                <StatusRow label="Name" value={name.trim() || "Unset"} />
                <StatusRow label="Inner circle" value={`${claims.filter(Boolean).length}/6`} />
                <StatusRow label="Food" value={`${cart.food.length}`} />
                <StatusRow label="Activities" value={`${cart.activities.length}`} />
                <StatusRow label="Habitat" value={`${cart.habitat.length}`} />
                <StatusRow label="The Current" value={step >= 6 ? "Live" : step >= 5 ? "Forming" : "Locked"} />
              </div>
            </section>

            <section style={{ ...cardStyle, padding: 18 }}>
              <div style={{ fontSize: 12, color: "#9ca3af", textTransform: "uppercase", letterSpacing: "0.12em" }}>What this step does</div>
              <div style={{ marginTop: 10, color: "#d8d0c2", lineHeight: 1.6 }}>
                {step === 0 && "Establishes ownership and permanence. The center is fixed."}
                {step === 1 && "Sets the tone. Claiming is intentional, not casual."}
                {step === 2 && "First identity data. Your food patterns start broadcasting once 3 seeds are planted."}
                {step === 3 && "Second identity data. Your activity patterns sharpen once 3 seeds are planted."}
                {step === 4 && "Most revealing category. Habitat completes the trifecta once 3 seeds are planted."}
                {step === 5 && "Closes the planting phase and shows the first resonance field."}
                {step === 6 && "The atmosphere is live. Warm hexes can be investigated, watched, or held in ambient awareness."}
              </div>
            </section>

            <section style={{ ...cardStyle, padding: 18 }}>
              <div style={{ fontSize: 12, color: "#9ca3af", textTransform: "uppercase", letterSpacing: "0.12em" }}>Step navigation</div>
              <div style={{ display: "grid", gap: 10, marginTop: 12 }}>
                <button
                  type="button"
                  onClick={back}
                  style={{
                    borderRadius: 14,
                    border: "1px solid rgba(255,255,255,0.12)",
                    background: "rgba(255,255,255,0.03)",
                    color: "#f7efe2",
                    fontWeight: 700,
                    padding: "12px 16px",
                    cursor: step > 0 ? "pointer" : "not-allowed",
                    opacity: step > 0 ? 1 : 0.45,
                  }}
                >
                  Back
                </button>
                <button
                  type="button"
                  onClick={advance}
                  style={{
                    borderRadius: 14,
                    border: "none",
                    background: "linear-gradient(180deg, #d4a574, #c8915e)",
                    color: "#111117",
                    fontWeight: 800,
                    padding: "12px 16px",
                    cursor: canAdvance ? "pointer" : "not-allowed",
                    opacity: canAdvance ? 1 : 0.45,
                  }}
                >
                  {step === 6 ? "Finish onboarding" : "Next"}
                </button>
              </div>
            </section>

            <section style={{ ...cardStyle, padding: 18 }}>
              <div style={{ fontSize: 12, color: "#9ca3af", textTransform: "uppercase", letterSpacing: "0.12em" }}>First return</div>
              <div style={{ marginTop: 10, color: "#d8d0c2", lineHeight: 1.6 }}>
                Step 7 opens the Current: 36 hexes, warmth only until you investigate, and a field that refreshes every hour.
              </div>
            </section>
          </aside>
        </div>
      </div>
    </section>
  );
}

function CartStepEditor({
  category,
  cart,
  drafts,
  setDrafts,
  addItem,
}: {
  category: CartCategoryKey;
  cart: Record<CartCategoryKey, { name: string; note?: string }[]>;
  drafts: Record<CartCategoryKey, { name: string; note: string }>;
  setDrafts: Dispatch<SetStateAction<Record<CartCategoryKey, { name: string; note: string }>>>;
  addItem: (category: CartCategoryKey) => void;
}) {
  const meta = CATEGORY_META[category];
  const items = cart[category];

  const inputStyle: CSSProperties = {
    width: "100%",
    borderRadius: 14,
    border: "1px solid rgba(255,255,255,0.12)",
    background: "rgba(7, 7, 10, 0.75)",
    color: "#f7efe2",
    padding: "12px 12px",
    outline: "none",
    fontSize: 14,
  };

  const chipStyle: CSSProperties = {
    borderRadius: 999,
    border: "1px solid rgba(255,255,255,0.12)",
    background: "rgba(255,255,255,0.04)",
    color: "#f4ede2",
    padding: "7px 12px",
    fontSize: 12,
    cursor: "pointer",
  };

  return (
    <div style={{ display: "grid", gap: 12 }}>
      <div style={{ display: "flex", justifyContent: "space-between", gap: 12, alignItems: "center", flexWrap: "wrap" }}>
        <div>
          <div style={{ fontSize: 12, color: "#9ca3af", textTransform: "uppercase", letterSpacing: "0.12em" }}>{meta.label}</div>
          <h3 style={{ margin: "6px 0 0", fontSize: 22 }}>{meta.prompt}</h3>
        </div>
        <div style={{ color: meta.accent, fontWeight: 800 }}>{items.length}/3 planted</div>
      </div>

      <div style={{ display: "grid", gap: 10, gridTemplateColumns: "minmax(0, 1fr) auto" }}>
        <input
          value={drafts[category].name}
          onChange={(event) =>
            setDrafts((current) => ({
              ...current,
              [category]: { ...current[category], name: event.target.value },
            }))
          }
          onKeyDown={(event) => {
            if (event.key === "Enter") {
              event.preventDefault();
              addItem(category);
            }
          }}
          placeholder={`Add a ${meta.label.toLowerCase()} item`}
          style={inputStyle}
        />
        <button
          type="button"
          onClick={() => addItem(category)}
          style={{
            borderRadius: 14,
            border: "none",
            background: `linear-gradient(180deg, ${meta.accent}, ${meta.accent}cc)`,
            color: "#111117",
            fontWeight: 700,
            padding: "12px 16px",
            cursor: "pointer",
            minWidth: 104,
          }}
        >
          Plant
        </button>
      </div>

      <input
        value={drafts[category].note}
        onChange={(event) =>
          setDrafts((current) => ({
            ...current,
            [category]: { ...current[category], note: event.target.value },
          }))
        }
        onKeyDown={(event) => {
          if (event.key === "Enter") {
            event.preventDefault();
            addItem(category);
          }
        }}
        placeholder="Optional note: why this matters, where it sits, how it feels"
        style={{ ...inputStyle, fontSize: 13, color: "#d8d0c2" }}
      />

      <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
        {meta.examples.map((example) => (
          <button key={example} type="button" onClick={() => setDrafts((current) => ({ ...current, [category]: { ...current[category], name: example } }))} style={chipStyle}>
            {example}
          </button>
        ))}
      </div>

      <div style={{ display: "grid", gap: 8 }}>
        {items.length === 0 ? (
          <div style={{ borderRadius: 16, border: "1px dashed rgba(255,255,255,0.12)", padding: 18, color: "#8f95a3", background: "rgba(255,255,255,0.02)" }}>
            No items yet. Add the first seed here.
          </div>
        ) : (
          items.map((item) => (
            <div key={`${category}-${item.name}-${item.note ?? ""}`} style={{ borderRadius: 16, padding: 14, background: "rgba(255,255,255,0.03)", border: "1px solid rgba(255,255,255,0.08)" }}>
              <div style={{ fontWeight: 700 }}>{item.name}</div>
              {item.note && <div style={{ color: "#afa699", marginTop: 4, fontSize: 13 }}>{item.note}</div>}
            </div>
          ))
        )}
      </div>
    </div>
  );
}

function CurrentPreview({ people }: { people: typeof CURRENT_SAMPLE }) {
  const [selectedId, setSelectedId] = useState(people[0]?.id ?? "");
  const [mode, setMode] = useState<InvestigationMode>("quick");
  const [watchlistIds, setWatchlistIds] = useState<string[]>([]);
  const [packageIds, setPackageIds] = useState<string[]>([]);
  const [longingIds, setLongingIds] = useState<string[]>([]);
  const [echoIds, setEchoIds] = useState<string[]>([]);
  const [now] = useState(() => Date.now());

  const selectedPerson = useMemo(
    () => people.find((person) => person.id === selectedId) ?? people[0],
    [people, selectedId],
  );

  const selectedWarmth = currentWarmthMeta(selectedPerson?.warmth ?? "cool");
  const selectedInWatchlist = Boolean(selectedPerson && watchlistIds.includes(selectedPerson.id));
  const selectedInPackage = Boolean(selectedPerson && packageIds.includes(selectedPerson.id));
  const selectedInLonging = Boolean(selectedPerson && longingIds.includes(selectedPerson.id));
  const selectedInEcho = Boolean(selectedPerson && echoIds.includes(selectedPerson.id));

  const currentNodes = useMemo<HexNode[]>(() => {
    const nodes: HexNode[] = [{ id: "center-you", ring: 0, position: 0, label: "YOU", type: "you" }];
    const positions = [0, 6, 12, 18, 24, 30];

    people.forEach((person, index) => {
      nodes.push({
        id: person.id,
        ring: 6,
        position: positions[index] ?? index,
        label: initials(person.name),
        type: person.warmth === "hot" ? "resonance-hot" : person.warmth === "warm" ? "resonance-warm" : "resonance-cool",
        resonanceSignal: person.primarySignal,
      });
    });

    return nodes;
  }, [people]);

  const signals = useMemo<ResonanceSignal[]>(() => {
    if (!selectedPerson) return [];
    return selectedPerson.patterns.map((pattern, index) => ({
      key: pattern.key,
      score: pattern.active ? Math.max(34, selectedPerson.resonanceScore - index * 8) : 18,
      note: pattern.detail,
    }));
  }, [selectedPerson]);

  const fieldScore = selectedPerson?.resonanceScore ?? 0;
  const nextRefresh = formatUntilNextHour(now);
  const totalVisible = people.length;
  const circulating = Math.max(36 - totalVisible, 0);

  const toggle = (id: string, setter: Dispatch<SetStateAction<string[]>>) => {
    setter((current) => (current.includes(id) ? current.filter((entry) => entry !== id) : [...current, id]));
  };

  const actionCard = (active: boolean, label: string, helper: string, onClick: () => void) => (
    <button
      type="button"
      onClick={onClick}
      style={{
        width: "100%",
        borderRadius: 14,
        border: active ? "1px solid rgba(245, 193, 108, 0.28)" : "1px solid rgba(255,255,255,0.12)",
        background: active ? "rgba(245, 193, 108, 0.16)" : "rgba(245, 193, 108, 0.12)",
        color: "#f7efe2",
        textAlign: "left",
        padding: 12,
        cursor: "pointer",
      }}
    >
      <div style={{ fontWeight: 700 }}>{label}</div>
      <div style={{ marginTop: 4, color: "#b6ac9d", fontSize: 12, lineHeight: 1.45 }}>{helper}</div>
    </button>
  );

  return (
    <section style={{ display: "grid", gap: 18 }}>
      <div style={{ ...{ background: "rgba(21, 22, 28, 0.92)", border: "1px solid rgba(255,255,255,0.08)", borderRadius: 22, boxShadow: "0 20px 50px rgba(0,0,0,0.24)" }, padding: 18 }}>
        <div style={{ display: "flex", justifyContent: "space-between", gap: 12, flexWrap: "wrap", alignItems: "center", marginBottom: 14 }}>
          <div>
            <div style={{ fontSize: 12, color: "#9ca3af", textTransform: "uppercase", letterSpacing: "0.12em" }}>The Current</div>
            <h3 style={{ margin: "6px 0 0", fontSize: 22 }}>Welcome back. Your atmosphere is live.</h3>
          </div>
          <div style={{ color: "#f5d79b", fontSize: 13 }}>{nextRefresh} until refresh</div>
        </div>

        <div style={{ borderRadius: 18, overflow: "hidden", border: "1px solid rgba(255,255,255,0.08)", background: "rgba(10, 10, 14, 0.72)" }}>
          <HexLattice
            nodes={currentNodes}
            showLabels
            activeNodeId={selectedPerson?.id}
            size="medium"
            centerLabel="CURRENT"
            focusRing={6}
            onNodeClick={(node) => setSelectedId(node.id)}
          />
        </div>

        <div style={{ marginTop: 14, display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(180px, 1fr))", gap: 10 }}>
          <StatTile label="Visible slots" value={`${totalVisible}/36`} detail="People currently inside the hourly field." />
          <StatTile label="Circulating" value={`${circulating}`} detail="People outside the current active surface." />
          <StatTile label="Warmth" value={scoreLabel(fieldScore)} detail="Recent resonance only; not the full score." />
        </div>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "minmax(0, 1.08fr) minmax(340px, 0.92fr)", gap: 18, alignItems: "start" }}>
        <div style={{ display: "grid", gap: 18 }}>
          <section style={{ ...{ background: "rgba(21, 22, 28, 0.92)", border: "1px solid rgba(255,255,255,0.08)", borderRadius: 22, boxShadow: "0 20px 50px rgba(0,0,0,0.24)" }, padding: 18 }}>
            <div style={{ display: "flex", justifyContent: "space-between", gap: 12, flexWrap: "wrap", alignItems: "center", marginBottom: 12 }}>
              <div>
                <div style={{ fontSize: 12, color: "#9ca3af", textTransform: "uppercase", letterSpacing: "0.12em" }}>Investigate</div>
                <h4 style={{ margin: "6px 0 0", fontSize: 22 }}>Tap 1, tap 2, tap 3.</h4>
              </div>
              <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
                <ModeButton active={mode === "quick"} onClick={() => setMode("quick")} label="Quick" />
                <ModeButton active={mode === "breakdown"} onClick={() => setMode("breakdown")} label="Breakdown" locked={selectedWarmth.label === "Cool"} />
                <ModeButton active={mode === "profile"} onClick={() => setMode("profile")} label="Profile" locked={selectedWarmth.label !== "Hot"} />
              </div>
            </div>

            <div style={{ padding: 14, borderRadius: 16, background: "rgba(255,255,255,0.03)", color: "#d8d0c2", lineHeight: 1.55, marginBottom: 14 }}>
              {mode === "quick"
                ? "Quick view shows warmth, float level, and featured items."
                : mode === "breakdown"
                  ? "Breakdown unlocks the active resonance patterns and the last 24 hours of signal."
                  : "Full profile expands the cart categories and the person's life texture."}
            </div>

            <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(150px, 1fr))", gap: 10 }}>
              {people.map((person) => {
                const meta = currentWarmthMeta(person.warmth);
                const active = selectedPerson?.id === person.id;
                return (
                  <button key={person.id} type="button" onClick={() => setSelectedId(person.id)} style={{ borderRadius: 16, padding: 12, border: active ? `1px solid ${meta.color}` : "1px solid rgba(255,255,255,0.08)", background: active ? `color-mix(in srgb, ${meta.color} 12%, rgba(255,255,255,0.03))` : "rgba(255,255,255,0.03)", color: "#efe7db", textAlign: "left", cursor: "pointer" }}>
                    <div style={{ display: "flex", justifyContent: "space-between", gap: 8, alignItems: "center" }}>
                      <div style={{ fontWeight: 700 }}>{person.name}</div>
                      <div style={{ color: meta.color, fontSize: 14 }}>{meta.icon}</div>
                    </div>
                    <div style={{ color: "#a7a1b3", fontSize: 12, marginTop: 4 }}>{person.floatLevel}</div>
                  </button>
                );
              })}
            </div>
          </section>
        </div>

        <aside style={{ display: "grid", gap: 18 }}>
          <section style={{ ...{ background: "rgba(21, 22, 28, 0.92)", border: "1px solid rgba(255,255,255,0.08)", borderRadius: 22, boxShadow: "0 20px 50px rgba(0,0,0,0.24)" }, padding: 18 }}>
            <div style={{ fontSize: 12, color: "#9ca3af", textTransform: "uppercase", letterSpacing: "0.12em" }}>Selected hex</div>
            <div style={{ marginTop: 12, display: "flex", gap: 14, alignItems: "center" }}>
              <div style={{ width: 60, height: 60, borderRadius: 18, display: "grid", placeItems: "center", background: `${selectedWarmth.color}22`, border: `1px solid ${selectedWarmth.color}55`, color: selectedWarmth.color, fontSize: 20, fontWeight: 800 }}>{initials(selectedPerson?.name ?? "")}</div>
              <div style={{ minWidth: 0 }}>
                <div style={{ fontSize: 24, fontWeight: 800, lineHeight: 1.05 }}>{selectedPerson?.name ?? "—"}</div>
                <div style={{ color: "#a6a0b1", fontSize: 13, marginTop: 4 }}>{selectedWarmth.label.toLowerCase()} ambient field</div>
              </div>
            </div>

            <div style={{ display: "grid", gap: 10, marginTop: 16 }}>
              <InfoRow label="Warmth" value={`${selectedWarmth.icon} ${selectedWarmth.label}`} tone={selectedWarmth.color} />
              <InfoRow label="Float level" value={selectedPerson?.floatLevel ?? "—"} tone="#f5d79b" />
              <InfoRow label="Resonance score" value={String(selectedPerson?.resonanceScore ?? 0)} tone="#f5c16c" />
              <InfoRow label="Hearts available" value={`${selectedPerson?.heartsAvailable ?? 0}`} tone="#fb7185" />
              <InfoRow label="Days in Current" value={selectedPerson ? formatHours(selectedPerson.daysInCurrent) : "—"} tone="#9ac18a" />
            </div>

            <div style={{ marginTop: 16, display: "grid", gap: 10 }}>
              {actionCard(selectedInWatchlist, selectedInWatchlist ? "Return to My World" : "Add to My World", "The non-committal maybe. It stays in your ambient awareness.", () => toggle(selectedPerson!.id, setWatchlistIds))}
              {actionCard(selectedInPackage, selectedInPackage ? "Care Package Sent" : "Send Care Package", `Requires 3+ Hearts. Current: ${selectedPerson?.heartsAvailable ?? 0}.`, () => toggle(selectedPerson!.id, setPackageIds))}
              {actionCard(selectedInLonging, selectedInLonging ? "Already in Longing" : "Add to Longing", `Monthly slot / warm signal. ${selectedPerson?.daysInCurrent ?? 0} days in Current.`, () => toggle(selectedPerson!.id, setLongingIds))}
              {actionCard(selectedInEcho, selectedInEcho ? "Already in Echo" : "Add to Echo", `Weekly resonance / warm+ and 7+ days. ${selectedPerson?.daysInCurrent ?? 0} days in Current.`, () => toggle(selectedPerson!.id, setEchoIds))}
            </div>
          </section>

          <section style={{ ...{ background: "rgba(21, 22, 28, 0.92)", border: "1px solid rgba(255,255,255,0.08)", borderRadius: 22, boxShadow: "0 20px 50px rgba(0,0,0,0.24)" }, padding: 18 }}>
            <ResonanceIndicators compact title="Ambient warmth" subtitle={`Recent signal from ${selectedPerson?.name ?? "the field"}.`} score={selectedPerson?.resonanceScore ?? fieldScore} recentHours={24} signals={signals} ringDistance={selectedWarmth.label === "Hot" ? 6 : selectedWarmth.label === "Warm" ? 5 : 3} />
          </section>

          <section style={{ ...{ background: "rgba(21, 22, 28, 0.92)", border: "1px solid rgba(255,255,255,0.08)", borderRadius: 22, boxShadow: "0 20px 50px rgba(0,0,0,0.24)" }, padding: 18 }}>
            <div style={{ fontSize: 12, color: "#9ca3af", textTransform: "uppercase", letterSpacing: "0.12em" }}>Selected hex details</div>
            <div style={{ marginTop: 12, display: "grid", gap: 10 }}>
              {mode === "quick" && selectedPerson && (
                <>
                  <DetailCard title="Featured items" text={selectedPerson.featuredItems.join(" · ")} />
                  <DetailCard title="Current note" text="Tap again to open the resonance breakdown. Warm and hot hexes unlock deeper visibility." />
                </>
              )}
              {mode === "breakdown" && selectedPerson && selectedWarmth.label !== "Cool" && (
                <>
                  {selectedPerson.patterns.map((pattern) => (
                    <PatternRow key={pattern.key} pattern={pattern} />
                  ))}
                  <DetailCard title="What this means" text="Hearts, Stars, Moons, Hourglasses, and Balloons are recent resonance only. They are not the full score." />
                </>
              )}
              {mode === "profile" && selectedPerson && selectedWarmth.label === "Hot" && (
                <>
                  <DetailCard title="Full profile" text={`${selectedPerson.name} has been in the Current for ${selectedPerson.daysInCurrent} days.`} />
                  {(["food", "activities", "habitat"] as const).map((category) => (
                    <div key={category} style={{ borderRadius: 16, padding: 12, background: "rgba(255,255,255,0.03)", border: "1px solid rgba(255,255,255,0.08)" }}>
                      <div style={{ fontSize: 12, color: "#9ca3af", textTransform: "uppercase", letterSpacing: "0.12em" }}>{category}</div>
                      <div style={{ display: "flex", flexWrap: "wrap", gap: 8, marginTop: 8 }}>
                        {selectedPerson.cartSummary[category].map((item) => (
                          <span key={item} style={{ borderRadius: 999, padding: "6px 10px", fontSize: 12, background: `${category === "food" ? "rgba(212,165,116,0.16)" : category === "activities" ? "rgba(138,182,214,0.16)" : "rgba(154,193,138,0.16)"}`, color: "#f7efe2", border: "1px solid rgba(255,255,255,0.08)" }}>
                            {item}
                          </span>
                        ))}
                      </div>
                    </div>
                  ))}
                </>
              )}
              <DetailCard title="Ambient awareness" text={selectedInWatchlist ? "This hex is in your ambient awareness. It stays in the Current for easy revisiting." : "Add to My World is the non-committal maybe: no move, no notify, just hold the signal."} />
            </div>
          </section>

          <section style={{ ...{ background: "rgba(21, 22, 28, 0.92)", border: "1px solid rgba(255,255,255,0.08)", borderRadius: 22, boxShadow: "0 20px 50px rgba(0,0,0,0.24)" }, padding: 18 }}>
            <div style={{ fontSize: 12, color: "#9ca3af", textTransform: "uppercase", letterSpacing: "0.12em" }}>At a glance</div>
            <div style={{ display: "grid", gap: 10, marginTop: 12 }}>
              <DetailCard title="Who enters" text="R5 drop-downs, circulation entries, and new users whose carts resonate right now." />
              <DetailCard title="Who leaves" text="People whose resonance fades below threshold, or who rotate out after 6+ hours without interaction." />
              <DetailCard title="What you see" text="Ambient warmth first. Tap deeper only when the signal justifies it." />
            </div>
          </section>
        </aside>
      </div>
    </section>
  );
}

function StatusRow({ label, value }: { label: string; value: string }) {
  return (
    <div style={{ display: "flex", justifyContent: "space-between", gap: 12, alignItems: "center", padding: "10px 12px", borderRadius: 14, background: "rgba(255,255,255,0.03)", border: "1px solid rgba(255,255,255,0.08)" }}>
      <div style={{ color: "#c8bfaf", fontSize: 14 }}>{label}</div>
      <div style={{ color: "#f5d79b", fontWeight: 700, fontSize: 14 }}>{value}</div>
    </div>
  );
}

function InfoRow({ label, value, tone }: { label: string; value: string; tone: string }) {
  return (
    <div style={{ borderRadius: 16, padding: 12, background: "rgba(255,255,255,0.03)", border: "1px solid rgba(255,255,255,0.08)", display: "flex", justifyContent: "space-between", gap: 12, alignItems: "center" }}>
      <div style={{ fontSize: 12, color: "#9ca3af", textTransform: "uppercase", letterSpacing: "0.12em" }}>{label}</div>
      <div style={{ fontWeight: 700, color: tone, textAlign: "right" }}>{value}</div>
    </div>
  );
}

function DetailCard({ title, text }: { title: string; text: string }) {
  return (
    <div style={{ borderRadius: 16, padding: 12, background: "rgba(255,255,255,0.03)", border: "1px solid rgba(255,255,255,0.08)" }}>
      <div style={{ fontSize: 12, color: "#9ca3af", textTransform: "uppercase", letterSpacing: "0.12em" }}>{title}</div>
      <div style={{ marginTop: 6, color: "#d8d0c2", fontSize: 14, lineHeight: 1.55 }}>{text}</div>
    </div>
  );
}

function PatternRow({ pattern }: { pattern: (typeof CURRENT_SAMPLE)[number]["patterns"][number] }) {
  return (
    <div style={{ borderRadius: 16, padding: 12, background: pattern.active ? "rgba(245, 193, 108, 0.10)" : "rgba(255,255,255,0.03)", border: pattern.active ? "1px solid rgba(245, 193, 108, 0.22)" : "1px solid rgba(255,255,255,0.08)" }}>
      <div style={{ display: "flex", justifyContent: "space-between", gap: 10, alignItems: "center" }}>
        <div style={{ fontWeight: 700 }}>{pattern.label}</div>
        <div style={{ fontSize: 12, color: pattern.active ? "#f5c16c" : "#8b93a0" }}>{pattern.active ? "Active" : "Quiet"}</div>
      </div>
      <div style={{ marginTop: 6, color: "#b6ac9d", fontSize: 13, lineHeight: 1.45 }}>{pattern.detail}</div>
    </div>
  );
}

function ModeButton({ active, label, locked = false, onClick }: { active: boolean; label: string; locked?: boolean; onClick: () => void }) {
  return (
    <button
      type="button"
      onClick={onClick}
      disabled={locked}
      style={{
        borderRadius: 999,
        border: active ? "1px solid rgba(245, 193, 108, 0.36)" : "1px solid rgba(255,255,255,0.12)",
        background: active ? "rgba(245, 193, 108, 0.16)" : "rgba(255,255,255,0.04)",
        color: locked ? "#8b93a0" : active ? "#ffdca2" : "#efe7db",
        padding: "8px 12px",
        fontSize: 12,
        cursor: locked ? "not-allowed" : "pointer",
        opacity: locked ? 0.6 : 1,
      }}
    >
      {label}
    </button>
  );
}

function StatTile({ label, value, detail }: { label: string; value: string; detail: string }) {
  return (
    <div style={{ borderRadius: 16, padding: 14, background: "rgba(255,255,255,0.03)", border: "1px solid rgba(255,255,255,0.08)" }}>
      <div style={{ fontSize: 12, color: "#9ca3af", textTransform: "uppercase", letterSpacing: "0.12em" }}>{label}</div>
      <div style={{ marginTop: 6, fontSize: 22, fontWeight: 800, color: "#f5d79b" }}>{value}</div>
      <div style={{ marginTop: 6, color: "#b6ac9d", fontSize: 13, lineHeight: 1.45 }}>{detail}</div>
    </div>
  );
}