const { useState } = React;

// ── PALETTE ──────────────────────────────────────────────────────────────────
// Color palette. Every grey/accent value was picked to hit WCAG 2.1 AA
// contrast (4.5:1 for body text, 3:1 for large/bold) against the
// surfaces it lands on. Verified by `npm run a11y`. Do NOT lighten
// without re-running the scan — this palette was tuned against the
// full axe-core report.
const C = {
  bg: "#f4f4f5",
  surface: "#ffffff",
  surfaceAlt: "#fafafa",
  dark: "#042f2e",
  mid: "#0f766e",
  muted: "#5b5b63", // 7:1 on white (was #71717a / 4.48:1 — just failed AA)
  faint: "#6b6b75", // 5.2:1 on white (was #a1a1aa / 2.63:1 — failed hard)
  border: "#e4e4e7",
  tealFaint: "#f0fdfa",
  tealLight: "#5eead4",
  amber: "#facc15",
  // Dark amber for use on light surfaces — #facc15 on white is 1.5:1
  // (fails AA). This passes at 5.3:1. Keep amber for dark surfaces.
  amberDark: "#a16207",
  purple: "#4f46e5",
  red: "#dc2626",
  // Red on dark teal #042f2e had 2.99:1. Use redLight for any text that
  // lands on dark backgrounds.
  redLight: "#fca5a5", // 5.5:1 on #042f2e
  tealBright: "#2dd4bf",
  royal: "#4f5bd8", // 5:1 on white (was #818cf8 / 2.98:1). Indigo-600-ish.
  // Legacy light-royal kept for gradient borders where contrast doesn't matter
  royalLight: "#818cf8",
};

// Grid palette — every category has a truly distinct hue, no duplicates
const GC = {
  school: "#34d399", // emerald-400  — school + HW + school screens (school years)
  teenJob: "#86efac", // green-300    — teen part-time job (school years only; fades into Work at 18)
  work: "#60a5fa", // blue-400     — future work (age 18 → 65)
  sleep: "#818cf8", // indigo-400   — sleep
  // Daily tasks — soft blue tones, distinct from indigo sleep + emerald school + warm screens
  hygiene: "#60a5fa", // blue-400     — hygiene / personal care
  chores: "#3b82f6", // blue-500     — chores / household
  eating: "#93c5fd", // blue-300     — eating / meals
  commute: "#2563eb", // blue-600     — driving / commute
  other: "#1d4ed8", // blue-700     — caregiving / other obligations
  freeTime: "rgba(255,255,255,0.18)", // free time — neutral/toggle-off
  scrFree: "#f97316", // orange-500   — screens in free time (toggle ON)
  activities: "#fde047", // yellow-300   — chosen activities (ideal chart) — distinct from school/work greens
  scrChosen: "#f43f5e", // rose-500     — chosen screen time (ideal chart) — distinct from sleep indigo
};

const STEPS = [
  "About You",
  "Invest Your Time",
  "Your Day With Screens",
  "Design Your Screen Time",
  "The Reveal",
  "Protected Brain Time",
  "Your Possibilities",
  "Your Plan",
  "The Bigger Picture",
];
// Named step indices — use these instead of magic numbers so navigation
// stays self-documenting and grep-friendly. Order must match STEPS above.
const STEP = {
  ABOUT: 0,
  INVEST: 1,
  DAY: 2,
  DESIGN: 3,
  REVEAL: 4,
  PBT: 5,
  POSSIBILITIES: 6,
  PLAN: 7,
  BIGGER: 8,
};
const LAST_STEP = STEPS.length - 1; // 8

// ── Domain constants ─────────────────────────────────────────────────────
// Single source of truth for every number the methodology page references.
// If you change one of these, update the corresponding methodology card too
// (see the "How This Works" section around line ~4400). Anchoring them here
// keeps the code and the published math from drifting apart.
const D = {
  // Life expectancy used for lifetime projections — CDC NCHS 2022 estimate.
  LIFE_EXPECTANCY_YRS: 78,
  // Average daily phone pickups — Reviews.org 2023–2026 benchmark. Anchors
  // the pickup slider's baseline and the pkpScale clamp.
  AVG_DAILY_PICKUPS: 185,
  // Reduction target shown on the Reveal as a "what if" scenario — roughly
  // one pickup per waking hour.
  REDUCED_PKP_TARGET: 25,
  // pkpScale clamp bounds. The scale factor is pickups/AVG_DAILY_PICKUPS
  // clamped to this range so extreme inputs (0 or 1000) don't produce
  // absurd filler estimates.
  PKP_SCALE_MIN: 0.5,
  PKP_SCALE_MAX: 1.8,
  // controllableH threshold below which a user is classified as a "light
  // user" and sees the affirming Pathway A framing on the Reveal. Design
  // choice for framing, NOT a clinical cutoff.
  LIGHT_USER_THRESHOLD_H: 2.5,
  // Fallback screen budget used when a user never built a plan in Step 4.
  // Prevents the Plan page from showing "0h screens" — a degenerate number
  // that would make the reclaimed-years math look absurd.
  FALLBACK_SCREEN_BUDGET_H: 1,
  // Gloria Mark's focus-recovery threshold (UC Irvine). A protected-brain
  // block shorter than this doesn't register as genuine recovery time.
  FOCUS_RECOVERY_MIN: 23,
  // Seniors-bracket default used to blend retirement-phase screen hours in
  // computeGridSegs. Reflects the empirical convergence of retirees toward
  // the population average regardless of pre-retirement habits.
  SENIORS_RETIRE_SCREEN_H: 5.5,
  // Weekend screen time default offset from weekday — used both by the
  // auto-suggest on Step 3 and the adjFutureScrYrs clamp on the Possibilities
  // math. Derived from Common Sense Media 2021: teens average ~2h more on
  // weekends than weekdays.
  WEEKEND_DELTA_H: 2,
};

const TIMELINE = [
  {
    t: "0–5 min",
    c: "#94a3b8",
    l: "Screen residue",
    d: "Brain still replaying the last scroll. Attention is still elsewhere.",
    dng: false,
  },
  {
    t: "5–15 min",
    c: "#64748b",
    l: "Still recovering",
    d: "Stimulation fades but focus isn't restored. Most people reach for their phone right here.",
    dng: false,
  },
  {
    t: "3–5 min",
    c: "#facc15",
    l: "Urge peaks",
    d: "The trained craving peaks. It feels urgent but it passes fast. Say: \"That's the pull. It'll pass.\" Research suggests naming emotions engages the prefrontal cortex and reduces their intensity (Lieberman et al., 2007).",
    dng: true,
  },
  {
    t: "10–15 min",
    c: "#0f766e",
    l: "Craving subsides",
    d: "The urge fades if you don't feed it. Each time you ride it out, the next one arrives later and weaker.",
    dng: false,
  },
  {
    t: "15–23 min",
    c: "#0d9488",
    l: "Focus recovers",
    d: "Gloria Mark's 23-minute threshold — this is where genuine focus recovery begins. Your brain starts to settle into its own rhythm.",
    dng: false,
  },
  {
    t: "23+ min",
    c: "#0d9488",
    l: "DMN activating",
    d: "Default mode network engages — the brain system responsible for self-reflection, memory consolidation, and creative insight. It activates during wakeful rest, not during screen use (Raichle, 2001; Immordino-Yang et al., 2012).",
    dng: false,
  },
  {
    t: "45+ min",
    c: "#042f2e",
    l: "Deep rest",
    d: "Extended periods of quiet produce boredom — which research links to creativity and self-directed thought (Eastwood et al., 2012; Mann & Cadman, 2014). This is where original thinking happens.",
    dng: false,
  },
];

const SCREEN_TYPES = [
  {
    k: "streaming",
    label: "Streaming / Movies / TV",
    sub: "Netflix, YouTube videos, shows",
    col: "#4f46e5",
  },
  { k: "gaming", label: "Gaming", sub: "Console, PC, mobile games", col: "#7c3aed" },
  { k: "social", label: "Social Media", sub: "Scrolling, posting, stories", col: "#b45309" },
  {
    k: "calls",
    label: "Video Calls (friends/family)",
    sub: "FaceTime, Zoom with people you care about",
    col: "#0369a1",
  },
  {
    k: "learning",
    label: "Learning / YouTube",
    sub: "Educational content, how-to videos, courses",
    col: "#0d9488",
  },
  {
    k: "creative",
    label: "Creative Screen Time",
    sub: "Editing, design, coding, music production",
    col: "#be185d",
  },
  { k: "news", label: "News", sub: "Reading/watching news intentionally", col: "#475569" },
];

// One merged interests list — filtered by age at render time
const INTERESTS_ALL = {
  physical: {
    label: "Physical",
    col: "#0d9488",
    items: [
      "Walking",
      "Running",
      "Hiking",
      "Yoga",
      "Swimming",
      "Gym / Weights",
      "Dance",
      "Team Sports",
      "Martial Arts",
      "Skateboarding",
      "Rock Climbing",
      "Bike Riding",
      "Gymnastics",
      "Pickup Sports",
      "Stretching",
    ],
  },
  creative: {
    label: "Creative",
    col: "#7c3aed",
    items: [
      "Art / Drawing",
      "Music (playing)",
      "Crafting / DIY",
      "Writing",
      "Writing / Stories",
      "Photography",
      "Cooking / Baking",
      "Cooking from scratch",
      "Building / LEGO",
      "Film / Video",
      "Home repair / Building",
    ],
  },
  social: {
    label: "Social & Family",
    col: "#0369a1",
    items: [
      "Friends (in person)",
      "Phone calls (not screen)",
      "Family time",
      "Time with my kids",
      "Date night / Partner time",
      "Hosting / Entertaining",
      "Volunteering",
      "Community events / groups",
      "School events",
      "Board game nights",
      "Writing letters",
      "Live events (theater, concerts, sports)",
    ],
  },
  mind: {
    label: "Mind & Learning",
    col: "#b45309",
    items: [
      "Reading",
      "Journaling",
      "Puzzles / Chess",
      "Learn a new language",
      "Language learning",
      "Meditation",
      "Financial planning",
      "Learning a practical skill",
    ],
  },
  spiritual: {
    label: "Spiritual & Faith",
    col: "#6d28d9",
    items: ["Prayer / Worship", "Religious community", "Spiritual practice", "Quiet reflection"],
  },
  community: {
    label: "Community & Civic",
    col: "#059669",
    items: [
      "Mentoring / Coaching",
      "Neighborhood involvement",
      "Mutual aid / Helping neighbors",
      "Activism / Advocacy",
      "Cultural events",
      "Heritage activities",
    ],
  },
  nature: {
    label: "Nature & Rest",
    col: "#166534",
    items: [
      "Outdoors / Nature",
      "Gardening",
      "Caring for pets",
      "Beach / Lake",
      "Camping",
      "Sitting quietly / People-watching",
      "Napping / Intentional rest",
      "Library time",
      "Park time",
    ],
  },
};
// Items hidden by age — keeps one list, filters at render
function getInterestsForAge(age) {
  const hide = new Set();
  if (age < 13) {
    hide.add("Gym / Weights");
    hide.add("Yoga");
    hide.add("Photography");
    hide.add("Meditation");
    hide.add("Language learning");
    hide.add("Time with my kids");
    hide.add("Date night / Partner time");
    hide.add("Community events / groups");
    hide.add("Financial planning");
    hide.add("Mentoring / Coaching");
    hide.add("Activism / Advocacy");
    hide.add("Home repair / Building");
    hide.add("Cooking from scratch");
    hide.add("Phone calls (not screen)");
    hide.add("Hosting / Entertaining");
    hide.add("Writing letters");
    hide.add("Learning a practical skill");
    hide.add("Napping / Intentional rest");
    hide.add("Neighborhood involvement");
    hide.add("Mutual aid / Helping neighbors");
    hide.add("Live events (theater, concerts, sports)");
  }
  if (age >= 13) {
    hide.add("Building / LEGO");
    hide.add("Gymnastics");
    hide.add("Writing / Stories");
  }
  if (age >= 18) {
    hide.add("School events");
    hide.add("Learn a new language");
  }
  if (age < 18) {
    hide.add("Date night / Partner time");
  }
  if (age < 18) {
    hide.add("Time with my kids");
    hide.add("Language learning");
    hide.add("Financial planning");
    hide.add("Home repair / Building");
  }
  if (age >= 25) {
    hide.add("Building / LEGO");
    hide.add("Gymnastics");
    hide.add("Writing / Stories");
  }
  const result = {};
  for (const [cat, { label, col, items }] of Object.entries(INTERESTS_ALL)) {
    const filtered = items.filter((i) => !hide.has(i));
    if (filtered.length > 0) result[cat] = { label, col, items: filtered };
  }
  return result;
}
const INTERESTS = INTERESTS_ALL; // used for key lookups / INTEREST_COL init

// AGE_BRACKETS — 6 brackets with default obligation + screen values
const AGE_BRACKETS = [
  {
    min: 5,
    max: 10,
    label: "Kids (5–10)",
    sleep: 10,
    school: 6.5,
    hw: 0.5,
    hygiene: 0.5,
    chores: 0.5,
    meals: 0.75,
    commute: 0.25,
    sS: 1.5,
    sH: 3,
    fd: 8,
  },
  {
    min: 11,
    max: 13,
    label: "Tweens (11–13)",
    sleep: 9.5,
    school: 6.5,
    hw: 1,
    hygiene: 0.5,
    chores: 0.75,
    meals: 1,
    commute: 0.5,
    sS: 2,
    sH: 5,
    fd: 9,
  },
  {
    min: 14,
    max: 17,
    label: "Teens (14–17)",
    sleep: 8.5,
    school: 7,
    hw: 1.5,
    hygiene: 0.5,
    chores: 0.75,
    meals: 1,
    commute: 0.5,
    sS: 3,
    sH: 7,
    fd: 11,
  },
  {
    min: 18,
    max: 22,
    label: "Young adults (18–22)",
    sleep: 7.5,
    school: 8,
    hw: 0,
    hygiene: 0.5,
    chores: 0.75,
    meals: 1,
    commute: 0.75,
    sS: 2,
    sH: 5,
    fd: 14,
  },
  {
    min: 23,
    max: 64,
    label: "Adults (23–64)",
    sleep: 7.5,
    school: 8,
    hw: 0,
    hygiene: 0.5,
    chores: 1,
    meals: 1.25,
    commute: 0.75,
    sS: 2,
    sH: 4,
    fd: 18,
  },
  {
    min: 65,
    max: 99,
    label: "Seniors (65+)",
    sleep: 7.5,
    school: 0,
    hw: 0,
    hygiene: 0.75,
    chores: 0.75,
    meals: 1,
    commute: 0.25,
    sS: 0.5,
    sH: 5,
    fd: 25,
  },
];

// DAY_WALKTHROUGH — 7 quick-tap questions walking through a typical day
// Each captures invisible filler screen time and audio-occupied time
// DAY_WALKTHROUGH — behavior-first labels, no visible time estimates
// screenMin values are base estimates, scaled by pickups at render time
const DAY_WALKTHROUGH = [
  {
    id: "morning",
    q: "What does your morning phone check look like?",
    minAge: 5,
    options: [
      { label: "I check my phone right away", screenMin: 25, audioMin: 0, weight: 1.0 },
      { label: "Quick scroll", screenMin: 8, audioMin: 0, weight: 0.5 },
      { label: "I don't check until I need it", screenMin: 0, audioMin: 0, weight: 0 },
    ],
  },
  {
    id: "gettingReady",
    q: "While getting ready?",
    minAge: 5,
    options: [
      { label: "Music or podcast playing", screenMin: 0, audioMin: 15, weight: 0 },
      { label: "Checking notifications and scrolling", screenMin: 10, audioMin: 0, weight: 0.6 },
      { label: "Both — audio plus phone", screenMin: 8, audioMin: 15, weight: 0.5 },
      { label: "No screens or audio", screenMin: 0, audioMin: 0, weight: 0 },
    ],
  },
  {
    id: "commute",
    q: "During your commute?",
    minAge: 10,
    options: [
      { label: "Scrolling or watching videos", screenMin: 20, audioMin: 0, weight: 0.8 },
      { label: "Podcast or music only", screenMin: 2, audioMin: 20, weight: 0.1 },
      { label: "Navigation only", screenMin: 5, audioMin: 0, weight: 0.2 },
      { label: "No screens", screenMin: 0, audioMin: 0, weight: 0 },
    ],
  },
  {
    id: "workChecks",
    q: "Personal phone during school/work?",
    minAge: 14,
    options: [
      {
        label: "Always nearby, checking as things come in",
        screenMin: 40,
        audioMin: 0,
        weight: 1.0,
      },
      { label: "Hourly check-ins", screenMin: 18, audioMin: 0, weight: 0.6 },
      { label: "A few times a day", screenMin: 8, audioMin: 0, weight: 0.3 },
      { label: "Phone stays away", screenMin: 2, audioMin: 0, weight: 0 },
    ],
  },
  {
    id: "meals",
    q: "Screens during meals?",
    minAge: 5,
    options: [
      { label: "Phone out, scrolling or checking", screenMin: 18, audioMin: 0, weight: 0.7 },
      { label: "TV on in the background", screenMin: 22, audioMin: 0, weight: 0.6 },
      { label: "Both — phone and TV", screenMin: 28, audioMin: 0, weight: 1.0 },
      { label: "No screens during meals", screenMin: 0, audioMin: 0, weight: 0 },
    ],
  },
  {
    id: "afterWork",
    q: "Right after school/work?",
    minAge: 10,
    options: [
      { label: "TV or streaming goes on", screenMin: 40, audioMin: 0, weight: 0.7 },
      { label: "Scrolling and decompressing", screenMin: 30, audioMin: 0, weight: 0.6 },
      { label: "Both — TV plus phone", screenMin: 55, audioMin: 0, weight: 1.0 },
      { label: "Not screens", screenMin: 0, audioMin: 0, weight: 0 },
    ],
  },
  {
    id: "bedtime",
    q: "Phone before bed?",
    minAge: 5,
    options: [
      { label: "Phone until I fall asleep", screenMin: 30, audioMin: 0, weight: 1.0 },
      { label: "Some scrolling, then I put it away", screenMin: 20, audioMin: 0, weight: 0.6 },
      { label: "Quick check only", screenMin: 5, audioMin: 0, weight: 0.2 },
      { label: "No phone in bed", screenMin: 0, audioMin: 0, weight: 0 },
    ],
  },
];

const ACTIVITY_FREQ = {
  journaling: 7,
  meditation: 7,
  caring_for_pets: 7,
  running: 5,
  reading: 5,
  walking: 5,
  yoga: 4,
  language_learning: 4,
  gym___weights: 3,
  dance: 3,
  cooking___baking: 3,
  art___drawing: 3,
  music__playing_: 3,
  writing: 3,
  outdoors___nature: 3,
  gardening: 3,
  family_time: 3,
  swimming: 3,
  team_sports: 3,
  hiking: 2,
  martial_arts: 2,
  rock_climbing: 2,
  skateboarding: 2,
  photography: 2,
  crafting___diy: 2,
  film___video: 2,
  bike_riding: 3,
  friends__in_person_: 2,
  community_groups: 2,
  puzzles___chess: 2,
  volunteering: 1,
  community_events: 1,
  board_game_nights: 1,
  beach___lake: 1,
  camping: 1,
  writing___stories: 3,
  building___lego: 2,
  gymnastics: 3,
  school_events: 1,
  learn_a_new_language: 4,
  time_with_my_kids: 3,
  date_night___partner_time: 1,
  // New items from inclusivity audit
  pickup_sports: 3,
  stretching: 5,
  cooking_from_scratch: 4,
  home_repair___building: 2,
  phone_calls__not_screen_: 3,
  playing_with_my_kids: 5,
  quality_time_with_people_i_choose: 3,
  hosting___entertaining: 1,
  writing_letters: 2,
  financial_planning: 1,
  learning_a_practical_skill: 2,
  prayer___worship: 7,
  religious_community: 2,
  spiritual_practice: 5,
  quiet_reflection: 5,
  mentoring___coaching: 2,
  neighborhood_involvement: 2,
  mutual_aid___helping_neighbors: 2,
  activism___advocacy: 1,
  cultural_events: 1,
  heritage_activities: 2,
  community_garden: 3,
  sitting_quietly___people_watching: 5,
  napping___intentional_rest: 5,
  library_time: 2,
  park_time: 4,
  live_events__theater__concerts__sports_: 1,
};

// Average session duration in hours per activity — includes prep + travel time
const ACTIVITY_HOURS = {
  walking: 0.75,
  running: 0.75,
  yoga: 1.25,
  meditation: 0.25,
  journaling: 0.25,
  gym___weights: 1.5,
  swimming: 1.5,
  dance: 1.75,
  martial_arts: 2.0,
  rock_climbing: 3.0,
  skateboarding: 1.5,
  bike_riding: 1.5,
  hiking: 3.0,
  team_sports: 2.0,
  gymnastics: 2.0,
  art___drawing: 1.5,
  music__playing_: 1.0,
  crafting___diy: 2.0,
  writing: 1.0,
  writing___stories: 1.0,
  photography: 1.5,
  cooking___baking: 1.5,
  film___video: 2.0,
  building___lego: 1.5,
  friends__in_person_: 2.5,
  family_time: 1.5,
  time_with_my_kids: 2.0,
  date_night___partner_time: 3.0,
  volunteering: 2.5,
  community_events: 2.0,
  community_groups: 2.0,
  board_game_nights: 2.5,
  school_events: 2.0,
  reading: 1.0,
  puzzles___chess: 1.0,
  language_learning: 0.5,
  learn_a_new_language: 0.5,
  outdoors___nature: 2.0,
  gardening: 1.5,
  caring_for_pets: 0.75,
  beach___lake: 3.0,
  camping: 4.0,
  // New items from inclusivity audit
  pickup_sports: 1.5,
  stretching: 0.25,
  cooking_from_scratch: 1.5,
  home_repair___building: 2.0,
  phone_calls__not_screen_: 0.5,
  playing_with_my_kids: 1.5,
  quality_time_with_people_i_choose: 2.0,
  hosting___entertaining: 3.0,
  writing_letters: 0.5,
  financial_planning: 0.5,
  learning_a_practical_skill: 1.0,
  prayer___worship: 0.5,
  religious_community: 2.0,
  spiritual_practice: 0.5,
  quiet_reflection: 0.25,
  mentoring___coaching: 1.5,
  neighborhood_involvement: 1.5,
  mutual_aid___helping_neighbors: 1.5,
  activism___advocacy: 2.0,
  cultural_events: 2.5,
  heritage_activities: 1.5,
  community_garden: 1.5,
  sitting_quietly___people_watching: 0.5,
  napping___intentional_rest: 0.5,
  library_time: 1.5,
  park_time: 1.0,
  live_events__theater__concerts__sports_: 3.0,
};

const DAYS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];

const INTEREST_COL = {};
Object.entries(INTERESTS_ALL).forEach(([, { col, items }]) =>
  items.forEach((item) => {
    INTEREST_COL[item.toLowerCase().replace(/[^a-z]/g, "_")] = col;
  })
);

// ── UTILS ────────────────────────────────────────────────────────────────────
const fmt = (h) => {
  if (h == null || isNaN(h) || !isFinite(h) || h <= 0) return "0h";
  if (h < 1) return Math.round(h * 60) + "m";
  if (h % 1 === 0) return h + "h";
  return h.toFixed(1) + "h";
};

function buildWeekSchedule(selectedInterests) {
  const allItems = Object.values(INTERESTS_ALL).flatMap((g) => g.items);
  const keyToLabel = {};
  allItems.forEach((item) => {
    keyToLabel[item.toLowerCase().replace(/[^a-z]/g, "_")] = item;
  });
  const MAX_PER_DAY = 4;
  const sched = {};
  DAYS.forEach((d) => {
    sched[d] = [];
  });
  const sorted = [...selectedInterests].sort(
    (a, b) => (ACTIVITY_FREQ[b] || 2) - (ACTIVITY_FREQ[a] || 2)
  );
  sorted.forEach((k) => {
    const freq = ACTIVITY_FREQ[k] || 2;
    const label = keyToLabel[k] || k.replace(/_/g, " ");
    const col = INTEREST_COL[k] || C.mid;
    let targetDays;
    if (k === "camping") targetDays = ["Sat"];
    else if (k === "beach___lake") targetDays = ["Sat", "Sun"];
    else if (k === "caring_for_pets" || k === "journaling" || k === "meditation") targetDays = DAYS;
    else {
      const sd = [...DAYS].sort((a, b) => sched[a].length - sched[b].length);
      targetDays = sd.slice(0, Math.min(freq, 7));
    }
    targetDays.forEach((d) => {
      if (sched[d].length < MAX_PER_DAY && !sched[d].find((x) => x.k === k))
        sched[d].push({ k, label, col });
    });
  });
  return sched;
}

// ── LIFE GRID (Dino-style) ────────────────────────────────────────────────────
// Segments: array of {c, months}
// Grid: 36 cols × rows, each dot = 1 month, future only
function LifeGrid({ segments, totalMonths, label }) {
  const { useState: useS, useRef } = React;
  const [tip, setTip] = useS(null); // {x, y, text}
  const svgRef = useRef(null);
  const COLS = 36,
    DS = 5,
    DR = 1.6;
  const numRows = Math.ceil(totalMonths / COLS);
  const dots = [];
  let cursor = 0;
  segments.forEach((seg) => {
    const count = Math.min(Math.round(seg.months), totalMonths - cursor);
    const yrs = (seg.months / 12).toFixed(1);
    const tipText = seg.l ? `${seg.l} · ${yrs} yrs` : "";
    for (let i = 0; i < count; i++) dots.push({ c: seg.c, tip: tipText });
    cursor += count;
  });
  while (dots.length < totalMonths) dots.push({ c: "empty", tip: "" });
  const circles = [];
  for (let i = 0; i < totalMonths; i++) {
    const col = i % COLS,
      row = Math.floor(i / COLS);
    const cx = (col * DS + DS / 2).toFixed(1),
      cy = (row * DS + DS / 2).toFixed(1);
    const { c } = dots[i];
    if (c === "empty")
      circles.push(
        <circle
          key={i}
          cx={cx}
          cy={cy}
          r={DR}
          fill="none"
          stroke="rgba(255,255,255,0.15)"
          strokeWidth="0.8"
        />
      );
    else circles.push(<circle key={i} cx={cx} cy={cy} r={DR} fill={c} />);
  }

  function handleMouseMove(e) {
    const svg = svgRef.current;
    if (!svg) return;
    const rect = svg.getBoundingClientRect();
    const vbW = COLS * DS,
      vbH = numRows * DS;
    const scaleX = rect.width / vbW;
    const scaleY = rect.height / vbH;
    const svgX = (e.clientX - rect.left) / scaleX;
    const svgY = (e.clientY - rect.top) / scaleY;
    const col = Math.floor(svgX / DS);
    const row = Math.floor(svgY / DS);
    const idx = row * COLS + col;
    if (col >= 0 && col < COLS && idx >= 0 && idx < dots.length && dots[idx].tip) {
      setTip({ x: e.clientX, y: e.clientY, text: dots[idx].tip });
    } else {
      setTip(null);
    }
  }

  return (
    <div style={{ position: "relative" }}>
      {label && (
        <div
          style={{
            fontSize: 10,
            color: "rgba(255,255,255,0.7)",
            marginBottom: 5,
            letterSpacing: "0.06em",
            textTransform: "uppercase",
          }}
        >
          {label}
        </div>
      )}
      <svg
        ref={svgRef}
        viewBox={`0 0 ${(COLS * DS).toFixed(0)} ${(numRows * DS).toFixed(0)}`}
        style={{ width: "100%", display: "block", cursor: "default" }}
        onMouseMove={handleMouseMove}
        onMouseLeave={() => setTip(null)}
      >
        {circles}
      </svg>
      {tip && (
        <div
          style={{
            position: "fixed",
            left: tip.x + 14,
            top: tip.y - 10,
            background: "rgba(15,15,20,0.95)",
            color: "white",
            fontSize: 12,
            fontWeight: 600,
            padding: "5px 10px",
            borderRadius: 7,
            pointerEvents: "none",
            zIndex: 9999,
            border: "1px solid rgba(255,255,255,0.15)",
            whiteSpace: "nowrap",
            boxShadow: "0 4px 12px rgba(0,0,0,0.4)",
          }}
        >
          {tip.text}
        </div>
      )}
    </div>
  );
}

function GridLegend({ items }) {
  return (
    <div style={{ display: "flex", flexWrap: "wrap", gap: "8px 18px", marginTop: 12 }}>
      {items.map((g, i) => (
        <div key={i} style={{ display: "flex", alignItems: "center", gap: 7 }}>
          {g.empty ? (
            <div
              style={{
                width: 13,
                height: 13,
                borderRadius: 3,
                border: "1px solid rgba(255,255,255,0.3)",
                flexShrink: 0,
              }}
            />
          ) : (
            <div
              style={{ width: 13, height: 13, borderRadius: 3, background: g.c, flexShrink: 0 }}
            />
          )}
          <span style={{ fontSize: 12, color: "rgba(255,255,255,0.65)", fontWeight: 500 }}>
            {g.l}
          </span>
        </div>
      ))}
    </div>
  );
}

// LIFE_PHASES — blended population-average daily hours by life stage.
// Used only for the lifetime grid projection; today's Step 1 values power the daily reveal.
// Source: BLS American Time Use Survey, CDC NCHS, NSF Sleep Foundation.
const LIFE_PHASES = [
  { from: 5, to: 13, sleep: 10.0, chores: 0.25, meals: 0.75, commute: 0.25, caregiving: 0.0 },
  { from: 13, to: 18, sleep: 8.5, chores: 0.5, meals: 1.0, commute: 0.5, caregiving: 0.0 },
  { from: 18, to: 65, sleep: 7.5, chores: 1.0, meals: 1.25, commute: 0.9, caregiving: 0.9 },
  { from: 65, to: 99, sleep: 7.5, chores: 0.75, meals: 1.0, commute: 0.25, caregiving: 0.5 },
];

function lifetimeAvg(age, yearsRem, key) {
  let weightedSum = 0,
    totalYears = 0;
  let curAge = age,
    rem = yearsRem;
  for (const p of LIFE_PHASES) {
    if (curAge >= p.to || rem <= 0) continue;
    const start = Math.max(p.from, curAge);
    const end = Math.min(p.to, curAge + rem);
    const yrs = end - start;
    if (yrs > 0) {
      weightedSum += p[key] * yrs;
      totalYears += yrs;
      rem -= yrs;
      curAge = end;
    }
  }
  return totalYears > 0 ? weightedSum / totalYears : 0;
}

// LabeledLifeGrid — Dino Ambrosi-inspired grid with category labels at section starts
// 1 row = 2 years (24 months) for more vertical space and clearer labels
function LabeledLifeGrid({ segments, totalMonths, revealScreens = true, showPacman = false }) {
  const { useState: useS, useRef } = React;
  const [tip, setTip] = useS(null);
  const svgRef = useRef(null);
  const COLS = 24,
    DS = 5.5,
    DR = 2.0;
  const numRows = Math.ceil(totalMonths / COLS);

  const dots = [];
  const sectionStarts = [];
  let cursor = 0;
  segments.forEach((seg) => {
    const startIdx = cursor;
    const count = Math.min(Math.round(seg.months), totalMonths - cursor);
    const yrs = (seg.months / 12).toFixed(1);
    const tipText = seg.l ? `${seg.l} · ${yrs} yrs` : "";
    if (count > 0) {
      sectionStarts.push({
        row: Math.floor(startIdx / COLS),
        label: seg.l,
        months: Math.round(seg.months),
        color: seg.c,
        startIdx,
      });
    }
    for (let i = 0; i < count; i++) dots.push({ c: seg.c, tip: tipText });
    cursor += count;
  });
  while (dots.length < totalMonths) dots.push({ c: "empty", tip: "" });

  const circles = [];
  let screenDotCount = 0;
  let firstScreenPos = null;
  let lastScreenPos = null;
  const screenPositions = []; // all screen dot positions for pac-man path
  for (let i = 0; i < totalMonths; i++) {
    const col = i % COLS,
      row = Math.floor(i / COLS);
    const cx = (col * DS + DS / 2).toFixed(1),
      cy = (row * DS + DS / 2).toFixed(1);
    const { c } = dots[i];
    if (c === "empty")
      circles.push(
        <circle key={i} cx={cx} cy={cy} r={DR} fill="none" stroke="#e4e4e7" strokeWidth="0.8" />
      );
    else {
      let fillC = c.includes("rgba(255,255,255") ? "#e4e4e7" : c;
      const isScreen = fillC === "#f97316"; // GC.scrFree
      if (isScreen) {
        screenDotCount++;
        const pos = { cx: parseFloat(cx), cy: parseFloat(cy), row, col };
        screenPositions.push(pos);
        if (!firstScreenPos) firstScreenPos = pos;
        lastScreenPos = pos;
        if (!revealScreens) fillC = "#e4e4e7"; // hide as faint free-time dot
      }
      circles.push(
        <circle
          key={i}
          cx={cx}
          cy={cy}
          r={DR}
          fill={fillC}
          style={
            isScreen && revealScreens
              ? { animation: `dotEat 0.4s ease-out ${screenDotCount * 35}ms both` }
              : undefined
          }
        />
      );
    }
  }
  const totalScreenDots = screenDotCount;
  // Pac-man travel: build row-by-row waypoints from screen dot positions
  // Group screen dots by row, traverse left-to-right per row
  const screenRows = {};
  screenPositions.forEach((p) => {
    if (!screenRows[p.row]) screenRows[p.row] = [];
    screenRows[p.row].push(p);
  });
  const pacWaypoints = [];
  Object.keys(screenRows)
    .sort((a, b) => a - b)
    .forEach((r) => {
      const rowDots = screenRows[r].sort((a, b) => a.col - b.col);
      // Always left to right — pac-man eats across each row
      pacWaypoints.push({ cx: rowDots[0].cx, cy: rowDots[0].cy }); // row start
      pacWaypoints.push({ cx: rowDots[rowDots.length - 1].cx, cy: rowDots[rowDots.length - 1].cy }); // row end
    });
  const pacAnimDuration = totalScreenDots * 35 + 1200; // ms, matches dot stagger — slow deliberate pace

  const vbW = COLS * DS;
  const vbH = numRows * DS;

  function handleMouseMove(e) {
    const svg = svgRef.current;
    if (!svg) return;
    const rect = svg.getBoundingClientRect();
    const scaleX = rect.width / vbW;
    const scaleY = rect.height / vbH;
    const svgX = (e.clientX - rect.left) / scaleX;
    const svgY = (e.clientY - rect.top) / scaleY;
    const col = Math.floor(svgX / DS);
    const row = Math.floor(svgY / DS);
    const idx = row * COLS + col;
    if (col >= 0 && col < COLS && idx >= 0 && idx < dots.length && dots[idx].tip) {
      setTip({ x: e.clientX, y: e.clientY, text: dots[idx].tip });
    } else {
      setTip(null);
    }
  }

  // Labels positioned outside SVG viewBox using overflow:visible
  const labelW = 0;
  const labelL = 0;
  const totalVbW = vbW;

  return (
    <div
      style={{
        position: "relative",
        background: "white",
        borderRadius: 10,
        padding: "12px 12px 12px 16px",
      }}
    >
      <svg
        ref={svgRef}
        viewBox={`-2 0 ${(totalVbW + 42).toFixed(0)} ${vbH.toFixed(0)}`}
        style={{ width: "100%", display: "block", cursor: "default", overflow: "visible" }}
        onMouseMove={handleMouseMove}
        onMouseLeave={() => setTip(null)}
      >
        {circles}
        {/* Pac-man inside SVG — follows screen dot rows */}
        {showPacman &&
          pacWaypoints.length >= 2 &&
          (() => {
            // Build SVG animate values from waypoints
            const xVals = pacWaypoints.map((w) => w.cx).join(";");
            const yVals = pacWaypoints.map((w) => w.cy).join(";");
            // Even time distribution per waypoint
            const n = pacWaypoints.length;
            const times = pacWaypoints.map((_, i) => (i / (n - 1)).toFixed(3)).join(";");
            const dur = (pacAnimDuration / 1000).toFixed(1) + "s";
            const lastWp = pacWaypoints[pacWaypoints.length - 1];
            const pacR = DS * 1.2; // bigger than dots
            return (
              <g style={{ filter: "drop-shadow(0 0 3px rgba(250,204,21,0.8))" }}>
                <g>
                  <animateTransform
                    attributeName="transform"
                    type="translate"
                    values={pacWaypoints.map((w) => `${w.cx} ${w.cy}`).join(";")}
                    keyTimes={times}
                    dur={dur}
                    fill="freeze"
                    repeatCount="1"
                  />
                  {/* Body */}
                  <circle cx="0" cy="0" r={pacR} fill="#facc15" />
                  {/* Eye */}
                  <circle cx={pacR * 0.25} cy={-pacR * 0.4} r={pacR * 0.18} fill="#042f2e" />
                  {/* Mouth — chomping */}
                  <path fill="white">
                    <animate
                      attributeName="d"
                      values={`M0 0 L${pacR * 1.1} ${-pacR * 0.65} L${pacR * 1.1} ${pacR * 0.65} Z;M0 0 L${pacR * 1.1} ${-pacR * 0.15} L${pacR * 1.1} ${pacR * 0.15} Z;M0 0 L${pacR * 1.1} ${-pacR * 0.65} L${pacR * 1.1} ${pacR * 0.65} Z`}
                      dur="0.4s"
                      repeatCount="indefinite"
                    />
                  </path>
                </g>
              </g>
            );
          })()}
        {/* Section labels — all on the right, clean order */}
        {(() => {
          const visible = sectionStarts.filter((s) => s.months > 6);
          const dotsRight = vbW;
          const minGap = 8;

          // Group categories
          const dailyTaskLabels = ["Eating", "Hygiene", "Chores", "Travel time", "Caregiving"];
          const workLabels = [
            "Work",
            "School + Work",
            "School + Homework",
            "Work (off-screen)",
            "Work (on a device)",
          ];
          const screenLabels = ["Personal screens"];
          const freeLabels = ["Free time", "Open free time"];

          // Aggregate daily tasks
          const dailyTasks = visible.filter((s) => dailyTaskLabels.includes(s.label));
          const dailyTaskMonths = dailyTasks.reduce((sum, s) => sum + s.months, 0);
          const dailyTaskStartRow =
            dailyTasks.length > 0 ? Math.min(...dailyTasks.map((s) => s.row)) : 0;

          // Aggregate work — match by label OR by school/work green colors
          const workSegs = visible.filter(
            (s) => workLabels.includes(s.label) || s.color === GC.school || s.color === "#059669"
          );
          const workTotalMonths = workSegs.reduce((sum, s) => sum + s.months, 0);
          const workStartRow = workSegs.length > 0 ? Math.min(...workSegs.map((s) => s.row)) : 0;
          const workLabel =
            workSegs.length > 0
              ? workSegs[0].label
                  .replace(" (off-screen)", "")
                  .replace(" (on a device)", "")
                  .replace(" (past)", "")
              : "Work";

          // Build ordered label list: Sleep → Work → Daily Tasks → Screens → Free time
          const allLabels = [];
          // Sleep
          const sleepSeg = visible.find((s) => s.label === "Sleep");
          if (sleepSeg)
            allLabels.push({
              row: sleepSeg.row,
              label: "Sleep",
              months: sleepSeg.months,
              color: sleepSeg.color,
            });
          // Work/School
          if (workTotalMonths > 6)
            allLabels.push({
              row: workStartRow,
              label: workLabel,
              months: workTotalMonths,
              color: workSegs[0].color,
            });
          // Daily tasks (combined, amber color)
          if (dailyTaskMonths > 6)
            allLabels.push({
              row: dailyTaskStartRow,
              label: "Daily tasks",
              months: dailyTaskMonths,
              color: "#3b82f6",
            });
          // Screens (only if revealed) — use sectionStarts not visible, so small segments aren't missed
          const scrSeg = sectionStarts.find((s) => screenLabels.includes(s.label));
          if (scrSeg && revealScreens && scrSeg.months > 0)
            allLabels.push({
              row: scrSeg.row,
              label: "Personal screens",
              months: scrSeg.months,
              color: scrSeg.color,
            });
          // Free time — always show; before reveal = "Free time" (includes screens); after reveal = "Open free time" (what remains)
          const freeSeg = sectionStarts.find((s) => freeLabels.includes(s.label));
          const freeMonths = freeSeg ? freeSeg.months : 0;
          if (revealScreens) {
            // After reveal: show "Open free time" only if there is any
            if (freeMonths > 0)
              allLabels.push({
                row: freeSeg.row,
                label: "Open free time",
                months: freeMonths,
                color: "#a1a1aa",
              });
          } else {
            // Before reveal: show "Free time" combining screens + open time (all gray dots)
            const combinedFree = freeMonths + (scrSeg ? scrSeg.months : 0);
            const freeRow = freeSeg ? freeSeg.row : scrSeg ? scrSeg.row : 0;
            if (combinedFree > 0)
              allLabels.push({
                row: freeRow,
                label: "Free time",
                months: combinedFree,
                color: "#a1a1aa",
              });
          }
          // Activities (ideal chart)
          const actSeg = visible.find(
            (s) => s.label === "Activities" || s.label === "Activities & interests"
          );
          if (actSeg)
            allLabels.push({
              row: actSeg.row,
              label: actSeg.label,
              months: actSeg.months,
              color: actSeg.color,
            });
          // Chosen screens (ideal chart)
          const chosenSeg = visible.find((s) => s.label === "Chosen screens");
          if (chosenSeg)
            allLabels.push({
              row: chosenSeg.row,
              label: chosenSeg.label,
              months: chosenSeg.months,
              color: chosenSeg.color,
            });

          // Sort by row position, then place with collision avoidance
          allLabels.sort((a, b) => a.row - b.row);
          const placed = [];
          return allLabels.map((s, i) => {
            let y = s.row * DS + DS * 0.7;
            if (placed.length > 0) {
              const lastY = placed[placed.length - 1];
              if (y < lastY + minGap) y = lastY + minGap;
            }
            placed.push(y);
            const labelColor = s.color?.includes?.("rgba") ? "#a1a1aa" : s.color || "#64748b";
            const dotY = s.row * DS + DS * 0.7;
            const x = dotsRight + 4;
            return (
              <g key={"lbl" + i}>
                <line
                  x1={dotsRight + 1}
                  y1={dotY - 0.5}
                  x2={dotsRight + 3}
                  y2={y - 0.5}
                  stroke={labelColor}
                  strokeWidth="0.4"
                  opacity="0.4"
                />
                <text
                  x={x}
                  y={y}
                  fill={labelColor}
                  fontSize="3.2"
                  fontWeight="700"
                  fontFamily="Inter,sans-serif"
                  textAnchor="start"
                >
                  {s.label}
                </text>
                <text
                  x={x}
                  y={y + 3.3}
                  fill="#a1a1aa"
                  fontSize="2.4"
                  fontFamily="Inter,sans-serif"
                  textAnchor="start"
                >
                  ({(s.months / 12).toFixed(1)} yrs)
                </text>
              </g>
            );
          });
        })()}
      </svg>
      {tip && (
        <div
          style={{
            position: "fixed",
            left: tip.x + 14,
            top: tip.y - 10,
            background: "#042f2e",
            color: "white",
            fontSize: 12,
            fontWeight: 600,
            padding: "5px 10px",
            borderRadius: 7,
            pointerEvents: "none",
            zIndex: 9999,
            border: "1px solid rgba(255,255,255,0.15)",
            whiteSpace: "nowrap",
            boxShadow: "0 4px 12px rgba(0,0,0,0.3)",
          }}
        >
          {tip.text}
        </div>
      )}
    </div>
  );
}

// PRE_SMARTPHONE_BASELINE — estimated daily screen hours by age before personal devices
// Source: Nielsen, Common Sense Media historical data, Kaiser Family Foundation
const PRE_SMARTPHONE_BASELINE = [
  { from: 2, to: 5, h: 2.0 }, // TV only
  { from: 5, to: 8, h: 2.5 }, // TV + some computer
  { from: 8, to: 13, h: 3.5 }, // TV + computer + early gaming
  { from: 13, to: 18, h: 4.5 }, // TV + computer + gaming + early social
  { from: 18, to: 99, h: 5.0 }, // TV + computer + work screens
];

// Compute years already spent on screens from age 2 to current age
// Three eras: pre-internet baseline → desktop internet → smartphone ramp to current total
// currentTotalSH = all screens today (personal + work/school devices)
// smartphoneAge=0 means single-era model (smartphone = first device, for younger users)
function computeLifetimeScreenYears(currentAge, firstOnlineAge, currentTotalSH, smartphoneAge) {
  const spAge = smartphoneAge > 0 ? smartphoneAge : firstOnlineAge;
  let totalHours = 0;
  for (let a = 2; a < currentAge; a++) {
    let dailyH;
    const bracket = PRE_SMARTPHONE_BASELINE.find((b) => a >= b.from && a < b.to);
    const baseline = bracket ? bracket.h : 2.0;
    if (a < firstOnlineAge) {
      // Era 1: Pre-internet — TV only (no personal computing)
      dailyH = baseline;
    } else if (a < spAge) {
      // Era 2: Desktop internet — modest bump for AOL, email, early web
      // Caps at +1.5h (not 2h) — pre-smartphone screen time was lower than we remember
      const desktopBump = Math.min(1.5, (a - firstOnlineAge) * 0.2);
      dailyH = baseline + desktopBump;
    } else {
      // Era 3: Smartphone — piecewise ramp, accelerating in last 5-7 years
      // Uses currentTotalSH (personal + work screens) as the ramp target
      const desktopLevel = baseline + Math.min(1.5, (spAge - firstOnlineAge) * 0.2);
      const yearsWithPhone = a - spAge;
      const totalPhoneYears = Math.max(1, currentAge - spAge);
      // Piecewise ramp: early years slow (~40% of target), last 5-7 years accelerate
      const accelYears = Math.min(7, totalPhoneYears * 0.5);
      const accelStart = totalPhoneYears - accelYears;
      let t;
      if (yearsWithPhone <= accelStart) {
        t = accelStart > 0 ? 0.4 * (yearsWithPhone / accelStart) : 0;
      } else {
        const accelProgress = (yearsWithPhone - accelStart) / Math.max(1, accelYears);
        t = 0.4 + 0.6 * (accelProgress * accelProgress);
      }
      dailyH = desktopLevel + (currentTotalSH - desktopLevel) * t;
    }
    totalHours += Math.max(0, dailyH) * 365;
  }
  return totalHours / 8760;
}

// computeGridSegs — builds lifetime dot grid segments
// Order: school → work → sleep → hygiene → chores → eating → commute → other → FREE TIME
// FREE TIME is last and visually largest — it is the hero of both charts.
// Chart 1: FREE TIME shows as one neutral block (toggle OFF) or splits into screens+open (toggle ON)
// Chart 2: FREE TIME splits into activities (green) + chosen screens (violet) + open
function computeGridSegs(params) {
  const _segs = [];
  const {
    age,
    sleep,
    schoolH,
    hygiene,
    chores,
    meals,
    commute,
    otherH,
    sH,
    actH,
    idealScr,
    yearsRem,
    isIdeal,
    showScreens,
    isKids,
    teenJobH = 0,
    collegeBonusYrs = 0,
    retireScrH = 0,
    deviceH = 0,
  } = params;

  // Blended lifetime averages — use user's ACTUAL values for working years,
  // then population averages for retirement. This ensures the grid matches
  // daily reality during the current life phase.
  const workPhaseYrs = Math.max(0, Math.min(65 - age, yearsRem));
  const retirePhaseYrs = Math.max(0, yearsRem - workPhaseYrs);
  const blend = (userVal, retireVal) =>
    yearsRem > 0 ? (workPhaseYrs * userVal + retirePhaseYrs * retireVal) / yearsRem : userVal;
  // Retirement-phase values from LIFE_PHASES
  const lSleep = blend(sleep, 7.5);
  const lChores = blend(chores, 0.75);
  const lMeals = blend(meals, 1.0);
  const lCommute = blend(commute, 0.25);
  // Caregiving: use population average (user's value is temporary, handled in daily calc only)
  const lCaregiv = lifetimeAvg(age, yearsRem, "caregiving");

  const totalM = yearsRem * 12;
  const schoolEndAge = 18 + collegeBonusYrs;
  const schoolYrs = Math.max(0, Math.min(schoolEndAge - age, yearsRem));
  const workYrs = Math.max(0, Math.min(Math.max(0, 65 - (age + schoolYrs)), yearsRem - schoolYrs));

  const push = (c, months, l) => {
    if (months > 0.5) _segs.push({ c, months, l });
  };

  // ── Fixed obligations — order matches Dino: Sleep → School+Work → smaller obligations ──
  // 1. Sleep — phase-based average (10h kids → 8.5h teen → 7.5h adult) — largest block, top
  push(GC.sleep, (lSleep / 24) * totalM, "Sleep");
  // 2. School + Work — split into on-device and off-device
  const schoolMonths = schoolYrs > 0 ? ((schoolH + teenJobH) / 24) * schoolYrs * 12 : 0;
  const workMonths = workYrs > 0 ? (8 / 24) * workYrs * 12 : 0;
  const swTotal = schoolMonths + workMonths;
  const workLabel =
    age >= 22
      ? "Work"
      : schoolYrs > 0 && workYrs > 0
        ? "School + Work"
        : schoolYrs > 0
          ? "School + Homework"
          : "Work";
  if (swTotal > 0.5 && deviceH > 0) {
    // Split: device portion (darker) + non-device portion (lighter)
    const totalWorkH = schoolYrs > 0 ? schoolH + teenJobH : 8;
    const devicePct = Math.min(1, deviceH / totalWorkH);
    const deviceMonths = swTotal * devicePct;
    const offDeviceMonths = swTotal * (1 - devicePct);
    if (offDeviceMonths > 0.5) push(GC.school, offDeviceMonths, workLabel + " (off-screen)");
    if (deviceMonths > 0.5) push("#059669", deviceMonths, workLabel + " (on a device)");
  } else if (swTotal > 0.5) {
    push(GC.school, swTotal, workLabel);
  }
  // 4. Eating — phase-based average (0.75h kids → 1.25h adult with cooking)
  push(GC.eating, (lMeals / 24) * totalM, "Eating");
  // 5. Hygiene — user-entered; stable enough across life stages
  push(GC.hygiene, (hygiene / 24) * totalM, "Hygiene");
  // 6. Driving / Commute — phase-based average
  push(GC.commute, (lCommute / 24) * totalM, "Travel time");
  // 7. Chores — phase-based average (0.25h kids → 1h adult)
  push(GC.chores, (lChores / 24) * totalM, "Chores");
  // 8. Caregiving — phase-based population average (~0.9h/day adult, ~0.5h senior)
  if (lCaregiv > 0) push(GC.other, (lCaregiv / 24) * totalM, "Caregiving");
  // 9. Activities (stated intention from Step 2)
  if (otherH > 0) push(GC.activities, (otherH / 24) * totalM, "Activities");

  // ── FREE TIME = everything remaining ──────────────────────────────────────
  const spokenFor = _segs.reduce((a, s) => a + s.months, 0);
  const freeM = Math.max(0, totalM - spokenFor);

  if (isIdeal) {
    // Chart 2: split free time into activities + chosen screens + open
    // Blend ideal screen time with Seniors bracket for retirement phase.
    // computeGridSegs receives this as a numeric literal because it is a
    // top-level function outside the Defrag component closure; keeping a
    // local constant here keeps the number traceable.
    const retireIdealScr = 5.5; // = D.SENIORS_RETIRE_SCREEN_H at top of file
    const retireYrsIdeal = Math.max(0, yearsRem - workPhaseYrs);
    const blendedIdealScr =
      yearsRem > 0
        ? (workPhaseYrs * idealScr + retireYrsIdeal * retireIdealScr) / yearsRem
        : idealScr;
    const actM = Math.min((actH / 24) * totalM, freeM);
    const scrM = Math.min((blendedIdealScr / 24) * totalM, Math.max(0, freeM - actM));
    const opM = Math.max(0, freeM - actM - scrM);
    if (actM > 0.5) push(GC.activities, actM, "Activities & interests");
    if (scrM > 0.5) push(GC.scrChosen, scrM, "Chosen screens");
    if (opM > 0.5) push(GC.freeTime, opM, "Open free time");
  } else {
    // Chart 1: free time as one block, toggle lights up screen portion orange
    // Blend screen hours: working years use weekday avg, retirement uses weekend-level (screens fill unstructured time)
    const effSH = sH;
    const rScrH = retireScrH > 0 ? retireScrH : effSH; // retirement screens default to current if not provided
    const retireYrs = Math.max(0, yearsRem - workPhaseYrs);
    const blendedScrH =
      yearsRem > 0 ? (workPhaseYrs * effSH + retireYrs * rScrH) / yearsRem : effSH;
    const scrM = Math.min((blendedScrH / 24) * totalM, freeM);
    const opM = Math.max(0, freeM - scrM);
    if (showScreens) {
      if (scrM > 0.5) push(GC.scrFree, scrM, "Personal screens");
      if (opM > 0.5) push(GC.freeTime, opM, "Open free time");
    } else {
      // Toggle OFF: all free time is one big neutral "Free Time" block
      push(GC.freeTime, freeM, "Free time");
    }
  }
  return _segs;
}

// computeFullLifeGridSegs — builds birth-to-78 dot grid for adults
// Past life: estimated from age-appropriate averages
// Future life: current projection from computeGridSegs
function computeFullLifeGridSegs(params) {
  const {
    age,
    sleep,
    schoolH,
    hygiene,
    chores,
    meals,
    commute,
    sH,
    actH,
    idealScr,
    yearsRem,
    isIdeal,
    showScreens,
    isKids,
    teenJobH = 0,
    collegeBonusYrs = 0,
    fd,
    smartphoneAge,
    currentSH,
  } = params;
  const totalLifeMonths = 78 * 12;
  const pastMonths = age * 12;
  const futureMonths = Math.max(0, totalLifeMonths - pastMonths);
  const _segs = [];
  const push = (c, months, l) => {
    if (months > 0.5) _segs.push({ c, months, l });
  };

  // ── PAST LIFE (birth to current age) ──────────────────────────
  // Simplified: sleep + school/work + screens + free time
  let pastSleep = 0,
    pastSchool = 0,
    pastWork = 0,
    pastScreens = 0,
    pastFree = 0;
  for (let a = 0; a < age; a++) {
    const sleepH = a < 2 ? 14 : a < 5 ? 11 : a < 13 ? 10 : a < 18 ? 8.5 : 7.5;
    const schoolW = a >= 5 && a < 18 ? 7 : a >= 18 && a < 22 ? 6 : 0;
    const workW = a >= 18 ? (a < 22 ? 2 : a < 65 ? 8 : 0) : 0;
    // Screen estimate per year
    let scrH = 0;
    if (a >= 2) {
      const bracket = PRE_SMARTPHONE_BASELINE.find((b) => a >= b.from && a < b.to);
      const baseline = bracket ? bracket.h : 2.0;
      const spAge = smartphoneAge > 0 ? smartphoneAge : fd;
      if (a < fd) {
        scrH = baseline;
      } else if (a < spAge) {
        scrH = baseline + Math.min(1.5, (a - fd) * 0.2);
      } else {
        const desktopLevel = baseline + Math.min(1.5, (spAge - fd) * 0.2);
        const yearsWithPhone = a - spAge;
        const totalPhoneYears = Math.max(1, age - spAge);
        const accelYrs = Math.min(7, totalPhoneYears * 0.5);
        const accelSt = totalPhoneYears - accelYrs;
        let t;
        if (yearsWithPhone <= accelSt) {
          t = accelSt > 0 ? 0.4 * (yearsWithPhone / accelSt) : 0;
        } else {
          const p = (yearsWithPhone - accelSt) / Math.max(1, accelYrs);
          t = 0.4 + 0.6 * (p * p);
        }
        scrH = desktopLevel + (currentSH - desktopLevel) * t;
      }
    }
    const otherH = Math.max(0, 24 - sleepH - schoolW - workW - Math.max(0, scrH));
    pastSleep += sleepH * (12 / 24);
    pastSchool += schoolW * (12 / 24);
    pastWork += workW * (12 / 24);
    pastScreens += Math.max(0, scrH) * (12 / 24);
    pastFree += otherH * (12 / 24);
  }

  push(GC.sleep, pastSleep, "Sleep (past)");
  push(GC.school, pastSchool + pastWork, "School + Work (past)");
  push(GC.scrFree, pastScreens, "Screens (past)");
  push("#d4d4d8", pastFree, "Other time (past)");

  // ── FUTURE LIFE (current age to 78) — reuse computeGridSegs output ────
  const futureSegs = computeGridSegs({
    age,
    sleep,
    schoolH,
    hygiene,
    chores,
    meals,
    commute,
    otherH: actH,
    sH,
    actH: 0,
    idealScr,
    yearsRem,
    isIdeal,
    showScreens,
    isKids,
    teenJobH,
    collegeBonusYrs,
  });
  futureSegs.forEach((s) => push(s.c, s.months, s.l));

  return { segs: _segs, pastMonths, totalLifeMonths };
}

// FullLifeGrid — renders birth to 78 with a gap between past and future
// White background variant for better category readability
function FullLifeGrid({ segments, totalMonths, pastMonths, age }) {
  const { useState: useS, useRef } = React;
  const [tip, setTip] = useS(null);
  const svgRef = useRef(null);
  const COLS = 36,
    DS = 5.5,
    DR = 2.0;
  const GAP_ROWS = 1.8; // visual gap between past and future sections

  // Build dot data
  const dots = [];
  let cursor = 0;
  segments.forEach((seg) => {
    const count = Math.min(Math.round(seg.months), totalMonths - cursor);
    const yrs = (seg.months / 12).toFixed(1);
    const tipText = seg.l ? `${seg.l} · ${yrs} yrs` : "";
    for (let i = 0; i < count; i++) dots.push({ c: seg.c, tip: tipText });
    cursor += count;
  });
  while (dots.length < totalMonths) dots.push({ c: "empty", tip: "" });

  // Split into past and future dots
  const pastDots = dots.slice(0, pastMonths);
  const futureDots = dots.slice(pastMonths);

  // Layout: past rows, then gap, then future rows
  const pastRows = Math.ceil(pastMonths / COLS);
  const futureRows = Math.ceil(futureDots.length / COLS);
  const totalRows = pastRows + GAP_ROWS + futureRows;
  const futureYOffset = (pastRows + GAP_ROWS) * DS;

  const circles = [];
  // Past dots
  for (let i = 0; i < pastDots.length; i++) {
    const col = i % COLS,
      row = Math.floor(i / COLS);
    const cx = (col * DS + DS / 2).toFixed(1),
      cy = (row * DS + DS / 2).toFixed(1);
    const { c } = pastDots[i];
    if (c === "empty")
      circles.push(
        <circle
          key={"p" + i}
          cx={cx}
          cy={cy}
          r={DR}
          fill="none"
          stroke="#e4e4e7"
          strokeWidth="0.8"
        />
      );
    else {
      const fillC = c.includes("rgba(255,255,255") ? "#e4e4e7" : c;
      circles.push(<circle key={"p" + i} cx={cx} cy={cy} r={DR} fill={fillC} />);
    }
  }
  // Future dots — offset by gap
  for (let i = 0; i < futureDots.length; i++) {
    const col = i % COLS,
      row = Math.floor(i / COLS);
    const cx = (col * DS + DS / 2).toFixed(1),
      cy = (futureYOffset + row * DS + DS / 2).toFixed(1);
    const { c } = futureDots[i];
    if (c === "empty")
      circles.push(
        <circle
          key={"f" + i}
          cx={cx}
          cy={cy}
          r={DR}
          fill="none"
          stroke="#e4e4e7"
          strokeWidth="0.8"
        />
      );
    else {
      const fillC = c.includes("rgba(255,255,255") ? "#e4e4e7" : c;
      circles.push(<circle key={"f" + i} cx={cx} cy={cy} r={DR} fill={fillC} />);
    }
  }

  // Divider line position
  const divY = (pastRows * DS + (GAP_ROWS * DS) / 2).toFixed(1);
  const vbW = COLS * DS;
  const vbH = totalRows * DS;

  function handleMouseMove(e) {
    const svg = svgRef.current;
    if (!svg) return;
    const rect = svg.getBoundingClientRect();
    const scaleX = rect.width / vbW;
    const scaleY = rect.height / vbH;
    const svgX = (e.clientX - rect.left) / scaleX;
    const svgY = (e.clientY - rect.top) / scaleY;
    const col = Math.floor(svgX / DS);
    // Determine if hovering past or future
    const rowInSvg = svgY / DS;
    let idx = -1;
    if (rowInSvg < pastRows) {
      const row = Math.floor(rowInSvg);
      idx = row * COLS + col;
      if (idx >= 0 && idx < pastDots.length && col < COLS && pastDots[idx].tip) {
        setTip({ x: e.clientX, y: e.clientY, text: pastDots[idx].tip });
        return;
      }
    } else if (rowInSvg > pastRows + GAP_ROWS) {
      const futureRow = Math.floor(rowInSvg - pastRows - GAP_ROWS);
      idx = futureRow * COLS + col;
      if (idx >= 0 && idx < futureDots.length && col < COLS && futureDots[idx].tip) {
        setTip({ x: e.clientX, y: e.clientY, text: futureDots[idx].tip });
        return;
      }
    }
    setTip(null);
  }

  return (
    <div
      style={{ position: "relative", background: "white", borderRadius: 10, padding: "12px 8px" }}
    >
      <svg
        ref={svgRef}
        viewBox={`0 0 ${vbW.toFixed(0)} ${vbH.toFixed(0)}`}
        style={{ width: "100%", display: "block", cursor: "default" }}
        onMouseMove={handleMouseMove}
        onMouseLeave={() => setTip(null)}
      >
        {circles}
        {/* Divider line between past and future */}
        <line
          x1="0"
          y1={divY}
          x2={vbW}
          y2={divY}
          stroke="#d4d4d8"
          strokeWidth="0.5"
          strokeDasharray="2,2"
        />
        {/* Past / Future labels in the gap */}
        <text
          x="3"
          y={parseFloat(divY) - 2}
          fill="#a1a1aa"
          fontSize="3.5"
          fontWeight="600"
          fontFamily="Inter,sans-serif"
        >
          PAST ({age} yrs)
        </text>
        <text
          x="3"
          y={parseFloat(divY) + 4.5}
          fill="#71717a"
          fontSize="3.5"
          fontWeight="600"
          fontFamily="Inter,sans-serif"
        >
          FUTURE ({78 - age} yrs)
        </text>
      </svg>
      {tip && (
        <div
          style={{
            position: "fixed",
            left: tip.x + 14,
            top: tip.y - 10,
            background: "#18181b",
            color: "white",
            fontSize: 12,
            fontWeight: 600,
            padding: "5px 10px",
            borderRadius: 7,
            pointerEvents: "none",
            zIndex: 9999,
            border: "1px solid rgba(255,255,255,0.15)",
            whiteSpace: "nowrap",
            boxShadow: "0 4px 12px rgba(0,0,0,0.3)",
          }}
        >
          {tip.text}
        </div>
      )}
    </div>
  );
}

function PieChart({ segs, size = 120, total = 24, fmtVal = fmt }) {
  const { useState: useS, useRef } = React;
  const [tip, setTip] = useS(null);
  const svgRef = useRef(null);
  const cx = size / 2,
    cy = size / 2,
    r = size / 2 - 5;

  // Build segments with their start/end angles for hit-testing
  let angle = -Math.PI / 2;
  const slices = segs
    .filter((s) => s.h > 0.05)
    .map((s, i) => {
      const sw = (s.h / total) * 2 * Math.PI;
      const startA = angle,
        endA = angle + sw;
      const x1 = cx + r * Math.cos(startA),
        y1 = cy + r * Math.sin(startA);
      const x2 = cx + r * Math.cos(endA),
        y2 = cy + r * Math.sin(endA);
      const la = sw > Math.PI ? 1 : 0;
      const d = `M${cx} ${cy} L${x1.toFixed(1)} ${y1.toFixed(1)} A${r} ${r} 0 ${la} 1 ${x2.toFixed(1)} ${y2.toFixed(1)} Z`;
      angle = endA;
      return { d, c: s.c, startA, endA, label: s.l, val: s.h };
    });

  function handleMouseMove(e) {
    const svg = svgRef.current;
    if (!svg) return;
    const rect = svg.getBoundingClientRect();
    // Map screen coords to viewBox coords
    const scaleX = size / rect.width;
    const scaleY = size / rect.height;
    const vx = (e.clientX - rect.left) * scaleX;
    const vy = (e.clientY - rect.top) * scaleY;
    const dx = vx - cx,
      dy = vy - cy;
    // Outside the circle → clear
    if (Math.sqrt(dx * dx + dy * dy) > r) {
      setTip(null);
      return;
    }
    // Angle from center, normalized to [-π/2, 3π/2) range matching our start angle
    let a = Math.atan2(dy, dx);
    if (a < -Math.PI / 2) a += 2 * Math.PI;
    const hit = slices.find((s) => a >= s.startA && a < s.endA);
    if (hit) setTip({ x: e.clientX, y: e.clientY, label: hit.label, val: hit.val });
    else setTip(null);
  }

  return (
    <div style={{ position: "relative", width: "100%", maxWidth: 320, margin: "0 auto" }}>
      <svg
        ref={svgRef}
        viewBox={`0 0 ${size} ${size}`}
        style={{ width: "100%", height: "auto", display: "block", cursor: "default" }}
        onMouseMove={handleMouseMove}
        onMouseLeave={() => setTip(null)}
      >
        {slices.map((s, i) => (
          <path key={i} d={s.d} fill={s.c} stroke="white" strokeWidth="1.5" />
        ))}
      </svg>
      {tip && (
        <div
          style={{
            position: "fixed",
            left: tip.x + 14,
            top: tip.y - 10,
            background: "rgba(15,15,20,0.95)",
            color: "white",
            fontSize: 12,
            fontWeight: 600,
            padding: "5px 10px",
            borderRadius: 7,
            pointerEvents: "none",
            zIndex: 9999,
            border: "1px solid rgba(255,255,255,0.15)",
            whiteSpace: "nowrap",
            boxShadow: "0 4px 12px rgba(0,0,0,0.4)",
          }}
        >
          {tip.label} · {fmtVal(tip.val)}
        </div>
      )}
    </div>
  );
}

function Legend({ segs, dark, fmtVal = fmt }) {
  const tc = dark ? "rgba(255,255,255,0.9)" : C.dark,
    sc = dark ? "rgba(255,255,255,0.5)" : C.muted;
  return (
    <div>
      {segs
        .filter((s) => s.h > 0.05)
        .map((s, i) => (
          <div key={i} style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 6 }}>
            <div
              style={{ width: 12, height: 12, borderRadius: 3, background: s.c, flexShrink: 0 }}
            />
            <span style={{ fontSize: 13, color: tc, fontWeight: 500 }}>
              {s.l} <span style={{ color: sc, fontWeight: 400 }}>{fmtVal(s.h)}</span>
            </span>
          </div>
        ))}
    </div>
  );
}

function Stepper({ label, dot, value, onInc, onDec, children }) {
  return (
    <div
      style={{
        display: "flex",
        justifyContent: "space-between",
        alignItems: "center",
        padding: "12px 16px",
        background: C.surface,
        borderRadius: 12,
        marginBottom: 8,
        border: `1px solid ${C.border}`,
      }}
    >
      <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
        {dot && (
          <div
            style={{ width: 9, height: 9, borderRadius: "50%", background: dot, flexShrink: 0 }}
          />
        )}
        <span style={{ fontSize: 14, color: C.dark, fontWeight: 500 }}>{label}</span>
      </div>
      <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
        <button onClick={onDec} style={bSm}>
          −
        </button>
        <span
          style={{
            fontFamily: "'SF Mono',monospace",
            fontWeight: 600,
            color: C.mid,
            minWidth: 52,
            textAlign: "center",
            fontSize: 14,
          }}
        >
          {children || fmt(value)}
        </span>
        <button onClick={onInc} style={bSm}>
          +
        </button>
      </div>
    </div>
  );
}

// 24-Hour Clock — extracted from IIFE to avoid hooks-in-IIFE violation
function ClockChart({
  meals,
  hygiene,
  commute,
  chores,
  caregiving,
  age,
  sleep,
  schoolPieH,
  workPieH,
  sH,
  freeTimePieH,
  oblig,
}) {
  const [clockProgress, setClockProgress] = React.useState(0);
  React.useEffect(() => {
    const cycleDur = 6000,
      pauseDur = 5000,
      totalDur = cycleDur + pauseDur;
    const start = Date.now();
    let raf;
    const tick = () => {
      const elapsed = (Date.now() - start) % totalDur;
      const p = elapsed < cycleDur ? Math.min(1, elapsed / cycleDur) : 1;
      setClockProgress(p);
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, []);
  const dailyTasksH = meals + hygiene + commute + chores + (age >= 18 ? caregiving : 0);
  const totalUsed = sleep + (schoolPieH + workPieH) + dailyTasksH + sH;
  const overflows = totalUsed > 24;
  const overBy = Math.max(0, totalUsed - 24);
  const clockSegs = [
    { l: "Sleep", h: sleep, c: GC.sleep },
    { l: age >= 18 ? "Work" : "School", h: schoolPieH + workPieH, c: GC.school },
    { l: "Daily tasks", h: dailyTasksH, c: "#64748b" },
    ...(overflows
      ? [
          { l: "Screens", h: Math.max(0, sH - overBy), c: GC.scrFree },
          { l: "Screens (overflow)", h: overBy, c: "#c2410c" },
        ]
      : [
          { l: "Screens", h: sH, c: GC.scrFree },
          ...(freeTimePieH - sH > 0.1
            ? [{ l: "Free time", h: Math.max(0, freeTimePieH - sH), c: C.tealBright }]
            : []),
        ]),
  ].filter((s) => s.h > 0.05);
  const freeLeft = Math.max(0, freeTimePieH - sH);
  const size = 300,
    cx = size / 2,
    cy = size / 2,
    r = size / 2 - 50;
  let angle = -Math.PI / 2;
  const arcs = clockSegs.map((s) => {
    const sw = (s.h / 24) * 2 * Math.PI;
    const startA = angle;
    angle += sw;
    const cumH = clockSegs.slice(0, clockSegs.indexOf(s) + 1).reduce((a, x) => a + x.h, 0);
    return { ...s, startA, endA: angle, sweep: sw, fillEnd: cumH / totalUsed };
  });
  const visibleAngle = -Math.PI / 2 + clockProgress * 2 * Math.PI * (totalUsed / 24);
  const currentSegIdx = arcs.findIndex((a) => clockProgress < a.fillEnd);
  const currentSeg = currentSegIdx >= 0 ? arcs[currentSegIdx] : arcs[arcs.length - 1];
  const labelAngle = Math.min(visibleAngle, currentSeg ? currentSeg.endA : visibleAngle);
  const labelR = r + 18;
  const labelX = cx + labelR * Math.cos(labelAngle);
  const labelY = cy + labelR * Math.sin(labelAngle);
  const labelAnchor = labelX > cx ? "start" : "end";
  return (
    <div
      style={{
        background: C.surface,
        borderRadius: 14,
        padding: "24px 18px",
        marginBottom: 10,
        border: `1px solid ${C.border}`,
        textAlign: "center",
      }}
    >
      <div style={{ ...sr, fontSize: 18, fontWeight: 700, color: C.dark, marginBottom: 4 }}>
        Your 24 hours
      </div>
      <div style={{ fontSize: 13, color: C.muted, marginBottom: 16 }}>
        {overflows
          ? "Your day exceeds 24 hours. Screens are eating into your daily tasks."
          : "Watch your day fill up — and see what's actually left."}
      </div>
      <svg
        viewBox={`0 0 ${size} ${size}`}
        style={{
          width: "100%",
          maxWidth: 300,
          display: "block",
          margin: "0 auto",
          overflow: "visible",
        }}
      >
        <circle cx={cx} cy={cy} r={r} fill="none" stroke="#e4e4e7" strokeWidth="1" />
        {arcs.map((s, i) => {
          if (s.startA > visibleAngle) return null;
          const eEnd = Math.min(s.endA, visibleAngle);
          const eSw = eEnd - s.startA;
          if (eSw <= 0) return null;
          const x1 = cx + r * Math.cos(s.startA),
            y1 = cy + r * Math.sin(s.startA);
          const x2 = cx + r * Math.cos(eEnd),
            y2 = cy + r * Math.sin(eEnd);
          const la = eSw > Math.PI ? 1 : 0;
          return (
            <path
              key={i}
              d={`M${cx} ${cy} L${x1.toFixed(1)} ${y1.toFixed(1)} A${r} ${r} 0 ${la} 1 ${x2.toFixed(1)} ${y2.toFixed(1)} Z`}
              fill={s.c}
              stroke="white"
              strokeWidth="1.5"
            />
          );
        })}
        {currentSeg && clockProgress > 0.01 && clockProgress < 0.99 && (
          <g>
            <line
              x1={cx + r * Math.cos(labelAngle)}
              y1={cy + r * Math.sin(labelAngle)}
              x2={labelX.toFixed(1)}
              y2={labelY.toFixed(1)}
              stroke={currentSeg.c}
              strokeWidth="0.8"
              opacity="0.6"
            />
            <text
              x={labelX.toFixed(1)}
              y={labelY.toFixed(1)}
              fill={currentSeg.c}
              fontSize="10"
              fontWeight="700"
              fontFamily="Inter,sans-serif"
              textAnchor={labelAnchor}
              dominantBaseline="middle"
            >
              {currentSeg.l} {fmt(currentSeg.h)}
            </text>
          </g>
        )}
        {overflows && clockProgress > 0.95 && (
          <text
            x={cx}
            y={cy}
            fill="#dc2626"
            fontSize="10"
            fontWeight="700"
            fontFamily="Inter,sans-serif"
            textAnchor="middle"
            dominantBaseline="middle"
          >
            Over 24h
          </text>
        )}
      </svg>
      <div
        style={{
          marginTop: 12,
          background: freeLeft > 0.5 ? C.tealFaint : overflows ? "#fef2f2" : "#fef2f2",
          borderRadius: 10,
          padding: "12px 14px",
          border: `1px solid ${freeLeft > 0.5 ? C.tealLight + "40" : "#fecaca"}`,
        }}
      >
        <div
          style={{
            ...sr,
            fontSize: 24,
            fontWeight: 700,
            color: freeLeft > 0.5 ? C.mid : "#991b1b",
          }}
        >
          {overflows ? `${fmt(totalUsed - 24)} over` : freeLeft > 0.1 ? fmt(freeLeft) : "0h"}
        </div>
        <div
          style={{
            fontSize: 13,
            fontWeight: 500,
            color: freeLeft > 0.5 ? C.mid : "#991b1b",
            marginTop: 2,
          }}
        >
          {overflows
            ? `Your day is ${Math.round(overBy * 60)} minutes over. Screens are eating into your daily tasks.`
            : freeLeft > 0.5
              ? "of genuinely free time left"
              : "Almost no free time left in your day."}
        </div>
      </div>
    </div>
  );
}

// Strategies accordion — extracted from IIFE to avoid hooks-in-IIFE violation
function StrategiesAccordion({ age = 18, isParent = false } = {}) {
  const [openStrat, setOpenStrat] = React.useState(null);
  const baseStrats = [
    {
      id: "S1",
      t: "Delay screens after waking, no devices 1 hour before bed",
      b: "Blue light suppresses melatonin (Harvard Health). Neuroscientist Andrew Huberman recommends 60–90 min of screen-free morning to avoid early dopamine peaks that may reduce motivation for harder tasks later. Evening screens disrupt sleep onset.",
      src: "Harvard Health · Huberman Lab Podcast · AAP media-free bedtime guideline",
    },
    {
      id: "S2",
      t: "Don't charge or sleep with devices in the bedroom",
      b: "Bedroom screens are associated with later bedtimes, less sleep, and higher BMI in children. This applies to every age — including yours.",
      src: "AAP Family Media Plan · Guerrero et al., Pediatric Research 2024",
    },
    {
      id: "S3",
      t: "No devices at meals",
      b: "Family mealtime screen use directly predicts adolescent problematic phone use. Meals are the single highest-leverage screen-free zone you can create.",
      src: "Guerrero et al., Pediatric Research 2024",
    },
    {
      id: "S4",
      t: "Turn on grayscale mode",
      b: "Research shows grayscale reduces screen time by 22–50 minutes/day by removing the color reward that makes apps visually compelling. Lowest effort, highest impact.",
      src: "Dekker & Baumgartner 2024 · Social Science Journal 2020",
    },
    {
      id: "S5",
      t: "Replace, don't just remove",
      b: "Your brain reaches for a device when there's a void. Book by the couch. Instrument in the corner. Shoes by the door. Having a specific alternative ready prevents the default scroll.",
      src: "Gloria Mark, Attention Span (2023)",
    },
    {
      id: "S6",
      t: "Use friction, not willpower",
      b: "Move apps off the home screen. Use app timers. Log out of social media after each session. Every added step reduces usage. Willpower depletes; friction is structural.",
      src: "Behavioral science / nudge theory",
    },
    {
      id: "S7",
      t: "One device at a time",
      b: "No phone while watching TV. Attention-switching costs compound — each switch costs 23+ minutes of recovery. Single-tasking with media is dramatically less consuming than stacking.",
      src: "Gloria Mark, UC Irvine",
    },
    {
      id: "S8",
      t: "Schedule screen time like an appointment",
      b: "'I watch Netflix 8–9pm' is intentional. 'I'll watch whatever's on when I sit down' is default. Treat media as a planned activity, not a gap-filler.",
      src: "AAP Family Media Plan",
    },
    {
      id: "S9",
      t: "Reclaim phone-free transitions",
      b: "Walking to the car, waiting in line, the elevator ride. These micro-moments are where filler screen time accumulates. Reclaiming them restores protected brain time.",
      src: "Linda Stone, Continuous Partial Attention",
    },
    {
      id: "S10",
      t: "Name it out loud",
      b: "'I'm about to scroll' or 'That's the craving.' Research shows naming emotions engages the prefrontal cortex and reduces automatic responding. Works for parents modeling for kids too.",
      src: "Lieberman et al., Psychological Science 2007 · Urge surfing (Marlatt, U of Washington)",
    },
  ];
  // Reorder by profile — lead with the strategies most relevant to this user
  let priority = [];
  if (isParent) priority = ["S10", "S3", "S2"];
  else if (age < 14) priority = ["S5", "S7", "S3"];
  else if (age < 18) priority = ["S4", "S6", "S1"];
  else priority = ["S8", "S9", "S1"];
  const ordered = [
    ...priority.map((id) => baseStrats.find((s) => s.id === id)).filter(Boolean),
    ...baseStrats.filter((s) => !priority.includes(s.id)),
  ];
  // Renumber for display
  const strats = ordered.map((s, i) => ({ ...s, n: String(i + 1).padStart(2, "0") }));
  return (
    <>
      {strats.map((a) => (
        <div
          key={a.n}
          style={{
            borderRadius: 10,
            marginBottom: 4,
            border: `1px solid ${C.border}`,
            overflow: "hidden",
          }}
        >
          <button
            onClick={() => setOpenStrat(openStrat === a.n ? null : a.n)}
            style={{
              width: "100%",
              display: "flex",
              gap: 12,
              padding: "11px 14px",
              background: openStrat === a.n ? C.tealFaint : C.surface,
              border: "none",
              cursor: "pointer",
              textAlign: "left",
              alignItems: "center",
            }}
          >
            <span
              style={{
                fontFamily: "'SF Mono',Menlo,monospace",
                fontWeight: 700,
                fontSize: 14,
                color: C.mid,
                opacity: 0.4,
                flexShrink: 0,
                minWidth: 22,
              }}
            >
              {a.n}
            </span>
            <span
              style={{
                ...sr,
                fontSize: 13,
                fontWeight: 700,
                color: C.dark,
                flex: 1,
                lineHeight: 1.3,
              }}
            >
              {a.t}
            </span>
            <span
              style={{
                fontSize: 14,
                color: C.faint,
                flexShrink: 0,
                transition: "transform 0.15s",
                transform: openStrat === a.n ? "rotate(180deg)" : "rotate(0deg)",
              }}
            >
              ▾
            </span>
          </button>
          {openStrat === a.n && (
            <div style={{ padding: "6px 14px 12px 48px" }}>
              <div style={{ fontSize: 13, color: C.muted, lineHeight: 1.6, marginBottom: 3 }}>
                {a.b}
              </div>
              <div style={{ fontSize: 11, color: C.faint, fontStyle: "italic" }}>{a.src}</div>
            </div>
          )}
        </div>
      ))}
    </>
  );
}

// Counterweights accordion — extracted from IIFE to avoid hooks-in-IIFE violation
function CounterweightsAccordion() {
  const [openCW, setOpenCW] = React.useState(null);
  const cws = [
    {
      title: "Play & Nature",
      body: "Unstructured play and time in nature build planning, creativity, and emotional regulation. Play strengthens the same executive-function skills that screens quietly replace.",
      src: "Whitebread et al., Cambridge · Peter Gray, Boston College",
      action: "Free play outdoors. No rules. No screens. No adult agenda.",
    },
    {
      title: "Deep Reading",
      body: "Sustained reading strengthens neural circuits for comprehension, empathy, and focus — all weakened by short-form digital consumption.",
      src: "Maryanne Wolf, UCLA",
      action: "Read long. Discuss deeply. Protect the brain's ability to sustain attention.",
    },
    {
      title: "Write It, Don't Type It",
      body: "EEG research shows handwriting produces widespread brain connectivity patterns in regions associated with memory and learning that typing does not activate.",
      src: "Van der Meer & Van der Weel, Frontiers in Psychology 2024 · Mueller & Oppenheimer, Psychological Science 2014",
      action:
        "Journal, take notes, or write letters by hand. The slower pace strengthens reflection and retention.",
    },
    {
      title: "Strategy & Logic Games",
      body: "Games that require planning, patience, and flexible thinking directly counteract the instant-feedback habits of persuasive design.",
      src: "Cognitive development research",
      action:
        "Chess, Catan, Sudoku, D&D — the goal isn't just to win, it's to learn to wait, think ahead, and adjust.",
    },
    {
      title: "Discussion with Depth",
      body: "Family discussions cultivate algorithmic skepticism, curiosity, and perspective-taking. Talk through ideas, not just about them.",
      src: "Critical thinking & media literacy research",
      action:
        "Debate respectfully at dinner. Explore a news article together. Teach kids to think critically instead of consuming passively.",
    },
    {
      title: "Cognitive Endurance",
      body: "Effortful learning enhances long-term retention. If it feels hard, the brain is growing.",
      src: "Robert Bjork, 'desirable difficulties' research",
      action:
        "Complex puzzles, mental math, crosswords, musical practice, journaling — embrace the productive struggle.",
    },
    {
      title: "Practice Boredom",
      body: "Periods without stimulation enable daydreaming, creativity, and self-directed thought. Boredom trains the brain to generate, not just consume.",
      src: "Eastwood et al. · Mann & Cadman",
      action:
        "Car rides without screens. Waiting without phones. Quiet creative time. Create the space and trust what emerges.",
    },
    {
      title: "Model It",
      body: "Americans check their phones an average of 144–186 times per day (Reviews.org, 2023–2026). Your habits are the most powerful curriculum your children will ever encounter.",
      src: "Reviews.org 2026 · Guerrero et al., Pediatric Research 2024",
      action:
        "Share your own struggles. Show kids it's possible to resist the pull. Keep phones out of bedrooms and create phone-free hours.",
    },
  ];
  return (
    <>
      <div style={{ marginTop: 18, marginBottom: 10 }}>
        <div style={{ fontSize: 13, color: C.muted, lineHeight: 1.6, marginBottom: 12 }}>
          Screens don't just take time — they replace the cognitive skills that make you creative
          and resilient. These activities rebuild what screens erode.
        </div>
      </div>
      {cws.map((cw) => (
        <div
          key={cw.title}
          style={{
            borderRadius: 10,
            marginBottom: 4,
            border: `1px solid ${C.border}`,
            overflow: "hidden",
          }}
        >
          <button
            onClick={() => setOpenCW(openCW === cw.title ? null : cw.title)}
            style={{
              width: "100%",
              display: "flex",
              gap: 10,
              padding: "11px 14px",
              background: openCW === cw.title ? C.tealFaint : C.surface,
              border: "none",
              cursor: "pointer",
              textAlign: "left",
              alignItems: "center",
            }}
          >
            <div
              style={{ width: 8, height: 8, borderRadius: "50%", background: C.mid, flexShrink: 0 }}
            />
            <span
              style={{
                ...sr,
                fontSize: 13,
                fontWeight: 700,
                color: C.dark,
                flex: 1,
                lineHeight: 1.3,
              }}
            >
              {cw.title}
            </span>
            <span
              style={{
                fontSize: 14,
                color: C.faint,
                flexShrink: 0,
                transition: "transform 0.15s",
                transform: openCW === cw.title ? "rotate(180deg)" : "rotate(0deg)",
              }}
            >
              ▾
            </span>
          </button>
          {openCW === cw.title && (
            <div style={{ padding: "6px 14px 12px 32px" }}>
              <div style={{ fontSize: 13, color: C.muted, lineHeight: 1.6, marginBottom: 6 }}>
                {cw.body}
              </div>
              <div
                style={{
                  fontSize: 13,
                  color: C.dark,
                  lineHeight: 1.6,
                  fontWeight: 500,
                  background: C.tealFaint,
                  borderRadius: 8,
                  padding: "8px 12px",
                  border: `1px solid ${C.tealLight}40`,
                  marginBottom: 4,
                }}
              >
                {cw.action}
              </div>
              <div style={{ fontSize: 11, color: C.faint, fontStyle: "italic" }}>{cw.src}</div>
            </div>
          )}
        </div>
      ))}
    </>
  );
}

// Smooth slider — uses local state during drag, commits to parent on release
function SmoothSlider({ min, max, step, value, onChange, style: s, ariaLabel, ariaValueText }) {
  const ref = React.useRef(null);
  const labelRef = React.useRef(null);
  const dragging = React.useRef(false);
  const cbRef = React.useRef(onChange);
  cbRef.current = onChange;

  React.useEffect(() => {
    if (!dragging.current && ref.current) ref.current.value = value;
  }, [value]);

  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;
    // Show a floating label during drag so user sees the value without React re-render
    const onStart = () => {
      dragging.current = true;
      if (!labelRef.current) {
        const lbl = document.createElement("div");
        lbl.style.cssText =
          "position:fixed;background:#042f2e;color:white;padding:4px 10px;border-radius:8px;font-size:14px;font-weight:700;pointer-events:none;z-index:9999;transform:translateX(-50%);font-family:Inter,sans-serif;";
        document.body.appendChild(lbl);
        labelRef.current = lbl;
      }
    };
    const onMove = () => {
      if (!dragging.current) return;
      // Do NOT call cbRef/setState here — it triggers React re-render and kills drag smoothness
      // The floating label shows the live value; state updates on mouseup/touchend only
      if (labelRef.current) {
        const rect = el.getBoundingClientRect();
        const pct = (parseFloat(el.value) - min) / (max - min);
        labelRef.current.textContent = el.value;
        labelRef.current.style.left = rect.left + pct * rect.width + "px";
        labelRef.current.style.top = rect.top - 32 + "px";
        labelRef.current.style.display = "block";
      }
    };
    const onEnd = () => {
      dragging.current = false;
      cbRef.current(parseFloat(el.value));
      if (labelRef.current) {
        labelRef.current.style.display = "none";
      }
    };
    el.addEventListener("mousedown", onStart);
    el.addEventListener("touchstart", onStart, { passive: true });
    el.addEventListener("input", onMove);
    el.addEventListener("mouseup", onEnd);
    el.addEventListener("touchend", onEnd);
    // Also handle mouse leaving the slider while dragging
    el.addEventListener("mouseleave", () => {
      if (dragging.current) onEnd();
    });
    return () => {
      el.removeEventListener("mousedown", onStart);
      el.removeEventListener("touchstart", onStart);
      el.removeEventListener("input", onMove);
      el.removeEventListener("mouseup", onEnd);
      el.removeEventListener("touchend", onEnd);
      if (labelRef.current) {
        document.body.removeChild(labelRef.current);
        labelRef.current = null;
      }
    };
  }, []);

  return (
    <input
      ref={ref}
      type="range"
      min={min}
      max={max}
      step={step}
      defaultValue={value}
      style={s}
      aria-label={ariaLabel}
      aria-valuetext={ariaValueText}
    />
  );
}

// ── SHARED STYLES ─────────────────────────────────────────────────────────────
const sr = { fontFamily: "'Libre Baskerville',Georgia,serif" };
const bSm = {
  width: 44,
  height: 44,
  borderRadius: 10,
  border: `1px solid ${C.border}`,
  background: C.surface,
  fontSize: 20,
  cursor: "pointer",
  color: C.mid,
  display: "flex",
  alignItems: "center",
  justifyContent: "center",
  lineHeight: 1,
  flexShrink: 0,
};
const bPrimary = {
  border: "none",
  borderRadius: 10,
  padding: "11px 24px",
  background: C.mid,
  color: "white",
  fontSize: 14,
  fontWeight: 600,
  cursor: "pointer",
};
const bOutline = {
  border: `1.5px solid ${C.border}`,
  borderRadius: 10,
  padding: "11px 24px",
  background: "transparent",
  color: C.mid,
  fontSize: 14,
  fontWeight: 600,
  cursor: "pointer",
};
const card = {
  background: C.surface,
  border: `1px solid ${C.border}`,
  borderRadius: 14,
  padding: 18,
  marginBottom: 10,
};
const dCard = (bg = "#042f2e") => ({
  background: bg,
  borderRadius: 14,
  padding: 18,
  marginBottom: 10,
  color: "white",
});
const lbl12 = {
  fontSize: 12,
  fontWeight: 700,
  color: C.muted,
  textTransform: "uppercase",
  letterSpacing: "0.08em",
  marginBottom: 6,
  display: "block",
};
const sl = { width: "100%", accentColor: C.mid, margin: "7px 0 3px" };

// ShowMath — calculator icon that reveals the formula on tap
function ShowMath({ lines, dark }) {
  const [open, setOpen] = React.useState(false);
  const iconColor = dark ? "rgba(255,255,255,0.3)" : C.faint;
  const popBg = dark ? "rgba(0,0,0,0.92)" : "white";
  const popBorder = dark ? "1px solid rgba(255,255,255,0.15)" : `1px solid ${C.border}`;
  const textColor = dark ? "rgba(255,255,255,0.85)" : C.dark;
  const mutedColor = dark ? "rgba(255,255,255,0.5)" : C.muted;
  return (
    <div style={{ position: "absolute", top: 8, right: 8, zIndex: 5 }}>
      <button
        onClick={(e) => {
          e.stopPropagation();
          setOpen((v) => !v);
        }}
        style={{
          background: dark ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.05)",
          border: dark ? "1px solid rgba(255,255,255,0.2)" : `1px solid ${C.border}`,
          cursor: "pointer",
          padding: "4px 8px",
          borderRadius: 6,
          display: "flex",
          alignItems: "center",
          gap: 4,
          fontSize: 10,
          fontWeight: 600,
          color: dark ? "rgba(255,255,255,0.7)" : C.muted,
        }}
        title="How we calculated this"
      >
        <span style={{ fontSize: 13 }}>🧮</span>
        <span>Math</span>
      </button>
      {open && (
        <div
          style={{
            position: "absolute",
            top: 28,
            right: 0,
            width: 280,
            background: popBg,
            borderRadius: 10,
            padding: "12px 14px",
            boxShadow: "0 8px 24px rgba(0,0,0,0.2)",
            border: popBorder,
            zIndex: 100,
          }}
        >
          <div
            style={{
              fontSize: 10,
              fontWeight: 700,
              letterSpacing: "0.08em",
              textTransform: "uppercase",
              color: mutedColor,
              marginBottom: 8,
            }}
          >
            How we calculated this
          </div>
          <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
            {lines.map((l, i) => (
              <div
                key={i}
                style={{
                  fontSize: 11,
                  lineHeight: 1.5,
                  color:
                    l.startsWith("=") || l.startsWith("→") ? (dark ? "#2dd4bf" : C.mid) : textColor,
                  fontWeight: l.startsWith("=") || l.startsWith("→") ? 700 : 400,
                  fontFamily:
                    l.includes("=") || l.includes("×") || l.includes("+") || l.includes("−")
                      ? "'SF Mono',Menlo,monospace"
                      : "inherit",
                }}
              >
                {l}
              </div>
            ))}
          </div>
          <button
            onClick={() => setOpen(false)}
            style={{
              marginTop: 8,
              fontSize: 10,
              color: mutedColor,
              background: "none",
              border: "none",
              cursor: "pointer",
              textDecoration: "underline",
            }}
          >
            Close
          </button>
        </div>
      )}
    </div>
  );
}

// ── SCREEN TIME FINDER MODAL ──────────────────────────────────────────────────
function ScreenTimeFinder({ onClose }) {
  const [tab, setTab] = useState("ios");
  return (
    <div
      style={{
        position: "fixed",
        inset: 0,
        background: "rgba(0,0,0,0.5)",
        zIndex: 1000,
        display: "flex",
        alignItems: "flex-end",
        justifyContent: "center",
      }}
      onClick={onClose}
    >
      <div
        style={{
          background: C.surface,
          borderRadius: "20px 20px 0 0",
          padding: 24,
          width: "100%",
          maxWidth: 480,
          maxHeight: "75vh",
          overflowY: "auto",
        }}
        onClick={(e) => e.stopPropagation()}
      >
        <div
          style={{
            display: "flex",
            justifyContent: "space-between",
            alignItems: "center",
            marginBottom: 16,
          }}
        >
          <div style={{ ...sr, fontSize: 16, fontWeight: 700, color: C.dark }}>
            How to find your screen time
          </div>
          <button
            onClick={onClose}
            style={{
              background: "none",
              border: "none",
              fontSize: 22,
              color: C.faint,
              cursor: "pointer",
              padding: "0 4px",
            }}
          >
            ✕
          </button>
        </div>
        <div style={{ display: "flex", gap: 4, marginBottom: 18 }}>
          {[
            ["ios", "📱 iPhone"],
            ["android", "🤖 Android"],
          ].map(([t, l]) => (
            <button
              key={t}
              onClick={() => setTab(t)}
              style={{
                flex: 1,
                padding: "8px 0",
                borderRadius: 9,
                border: `1px solid ${tab === t ? C.mid : C.border}`,
                background: tab === t ? C.mid : "transparent",
                color: tab === t ? "white" : C.dark,
                fontSize: 13,
                fontWeight: 600,
                cursor: "pointer",
              }}
            >
              {l}
            </button>
          ))}
        </div>
        {tab === "ios" ? (
          <div>
            <div style={{ ...sr, fontSize: 14, fontWeight: 700, color: C.mid, marginBottom: 12 }}>
              iPhone — Screen Time
            </div>
            {[
              ["Settings", "Open the Settings app (gear icon)"],
              ["Screen Time", "Scroll down and tap Screen Time"],
              ["See All Activity", "Tap 'See All Activity' under your usage chart"],
              ["Switch to Week", "Tap 'Week' at the top to see your weekly average"],
              [
                "Total = your number",
                "The total at the top is your daily average. Use that number here.",
              ],
            ].map(([h, b], i) => (
              <div key={i} style={{ display: "flex", gap: 12, marginBottom: 12 }}>
                <div
                  style={{
                    width: 24,
                    height: 24,
                    borderRadius: "50%",
                    background: C.mid,
                    color: "white",
                    fontSize: 12,
                    fontWeight: 700,
                    display: "flex",
                    alignItems: "center",
                    justifyContent: "center",
                    flexShrink: 0,
                  }}
                >
                  {i + 1}
                </div>
                <div>
                  <div style={{ fontSize: 13, fontWeight: 700, color: C.dark }}>{h}</div>
                  <div style={{ fontSize: 12, color: C.muted, lineHeight: 1.5 }}>{b}</div>
                </div>
              </div>
            ))}
            <div
              style={{
                background: C.tealFaint,
                borderRadius: 9,
                padding: "10px 13px",
                fontSize: 12,
                color: C.dark,
                lineHeight: 1.6,
                border: `1px solid ${C.tealLight}40`,
              }}
            >
              <strong>Tip:</strong> "School" or "Productivity & Finance" categories often hide real
              usage. Look at the total number, not just social apps.
            </div>
            <div
              style={{
                marginTop: 14,
                ...sr,
                fontSize: 13,
                fontWeight: 700,
                color: C.mid,
                marginBottom: 10,
              }}
            >
              iPhone — Pickups
            </div>
            <div style={{ fontSize: 13, color: C.muted, lineHeight: 1.65 }}>
              Still in Screen Time → See All Activity. Scroll down to <strong>Pickups</strong>.
              That's how many times you lifted your phone today. Use the weekly average.
            </div>
          </div>
        ) : (
          <div>
            <div style={{ ...sr, fontSize: 14, fontWeight: 700, color: C.mid, marginBottom: 12 }}>
              Android — Digital Wellbeing
            </div>
            {[
              ["Settings", "Open Settings"],
              ["Digital Wellbeing & Parental Controls", "Scroll down and tap this option"],
              ["Your Usage", "The dashboard shows today's screen time and app breakdown"],
              ["Tap Dashboard", "For a full breakdown by app. Use the daily total."],
              [
                "Pickups",
                "Look for 'Times opened' or install the Digital Wellbeing widget on your home screen",
              ],
            ].map(([h, b], i) => (
              <div key={i} style={{ display: "flex", gap: 12, marginBottom: 12 }}>
                <div
                  style={{
                    width: 24,
                    height: 24,
                    borderRadius: "50%",
                    background: C.mid,
                    color: "white",
                    fontSize: 12,
                    fontWeight: 700,
                    display: "flex",
                    alignItems: "center",
                    justifyContent: "center",
                    flexShrink: 0,
                  }}
                >
                  {i + 1}
                </div>
                <div>
                  <div style={{ fontSize: 13, fontWeight: 700, color: C.dark }}>{h}</div>
                  <div style={{ fontSize: 12, color: C.muted, lineHeight: 1.5 }}>{b}</div>
                </div>
              </div>
            ))}
            <div
              style={{
                background: C.tealFaint,
                borderRadius: 9,
                padding: "10px 13px",
                fontSize: 12,
                color: C.dark,
                lineHeight: 1.6,
                border: `1px solid ${C.tealLight}40`,
              }}
            >
              <strong>Note:</strong> Samsung devices may show "Screen time" in the Battery section
              instead. The location varies slightly by Android version.
            </div>
          </div>
        )}
        <button onClick={onClose} style={{ ...bPrimary, width: "100%", marginTop: 18 }}>
          Got it — close
        </button>
      </div>
    </div>
  );
}

// ── COMPREHENSIVE WEEK PLAN (rendered on the Plan step — Step 8 of 9) ────────
function WeekPlan({
  sleep,
  schoolH,
  sS,
  hygiene,
  chores,
  meals,
  commute,
  actH,
  interests,
  screenChecked,
  screenSessions,
  freeTime,
  totalIdeal,
  age,
}) {
  const sched = buildWeekSchedule(interests);
  const obligH = hygiene + chores + meals + commute; // caregiving passed via prop below
  const sessionDailyAvg = (k) => {
    const s = screenSessions[k];
    return s ? (s.freq * s.mins) / 7 / 60 : 0;
  };
  const unclaimedH = Math.max(0, freeTime - actH - totalIdeal);

  const nonNeg = [
    { l: "Sleep", h: sleep, c: GC.sleep },
    { l: age >= 18 ? "Work" : "School + Homework", h: schoolH, c: GC.school },
    { l: "School/work screens (required)", h: sS, c: "#facc15" },
    { l: "Hygiene", h: hygiene, c: GC.hygiene },
    { l: "Meals", h: meals, c: GC.eating },
    { l: "Chores", h: chores, c: GC.chores },
    { l: "Driving / Commute", h: commute, c: GC.commute },
  ].filter((x) => x.h > 0);

  return (
    <div>
      {/* Non-negotiables */}
      <div style={card}>
        <div style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.dark, marginBottom: 12 }}>
          Your daily non-negotiables
        </div>
        {nonNeg.map((n, i) => (
          <div
            key={i}
            style={{
              display: "flex",
              justifyContent: "space-between",
              alignItems: "center",
              padding: "7px 0",
              borderBottom: `1px solid ${C.border}`,
            }}
          >
            <div style={{ display: "flex", alignItems: "center", gap: 9 }}>
              <div
                style={{ width: 9, height: 9, borderRadius: 2, background: n.c, flexShrink: 0 }}
              />
              <span style={{ fontSize: 13, color: C.dark }}>{n.l}</span>
            </div>
            <span style={{ fontSize: 13, fontWeight: 600, color: C.muted }}>{fmt(n.h)}</span>
          </div>
        ))}
      </div>

      {/* Free time balance */}
      <div style={card}>
        <div style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.dark, marginBottom: 12 }}>
          How you want to use your free time
        </div>
        <div
          style={{
            display: "flex",
            justifyContent: "space-between",
            padding: "8px 0",
            borderBottom: `1px solid ${C.border}`,
          }}
        >
          <span style={{ fontSize: 13, color: C.dark }}>Total free time</span>
          <span style={{ fontSize: 13, fontWeight: 700, color: C.mid }}>{fmt(freeTime)}/day</span>
        </div>
        <div
          style={{
            display: "flex",
            justifyContent: "space-between",
            padding: "8px 0",
            borderBottom: `1px solid ${C.border}`,
          }}
        >
          <span style={{ fontSize: 13, color: C.dark }}>Activities & interests</span>
          <span style={{ fontSize: 13, fontWeight: 600, color: "#166534" }}>−{fmt(actH)}</span>
        </div>
        <div
          style={{
            display: "flex",
            justifyContent: "space-between",
            padding: "8px 0",
            borderBottom: `1px solid ${C.border}`,
          }}
        >
          <span style={{ fontSize: 13, color: C.dark }}>Chosen screen time</span>
          <span style={{ fontSize: 13, fontWeight: 600, color: C.purple }}>−{fmt(totalIdeal)}</span>
        </div>
        {unclaimedH > 0.1 ? (
          <div
            style={{
              display: "flex",
              justifyContent: "space-between",
              padding: "10px 12px",
              marginTop: 6,
              background: "#fef9c3",
              borderRadius: 9,
              border: "1px solid #5eead4",
            }}
          >
            <div>
              <div style={{ fontSize: 13, fontWeight: 700, color: "#0f766e" }}>
                ⏳ Unclaimed Free Time
              </div>
              <div style={{ fontSize: 11, color: "#0f766e", marginTop: 2, lineHeight: 1.5 }}>
                You haven't told us what you want to do with this yet. That's fine — rest is real.
                But screens will fill it if you don't decide first.
              </div>
            </div>
            <span
              style={{
                ...sr,
                fontSize: 22,
                fontWeight: 700,
                color: C.mid,
                flexShrink: 0,
                marginLeft: 12,
              }}
            >
              {fmt(unclaimedH)}
            </span>
          </div>
        ) : (
          <div
            style={{
              display: "flex",
              justifyContent: "space-between",
              padding: "10px 12px",
              marginTop: 6,
              background: C.tealFaint,
              borderRadius: 9,
              border: `1px solid ${C.tealLight}40`,
            }}
          >
            <span style={{ fontSize: 13, color: C.mid, fontWeight: 600 }}>
              ✓ All free time accounted for
            </span>
          </div>
        )}
      </div>

      {/* Screen budget breakdown */}
      {screenChecked.length > 0 && (
        <div style={card}>
          <div style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.dark, marginBottom: 12 }}>
            Your chosen screen time breakdown
          </div>
          {SCREEN_TYPES.filter((si) => screenChecked.includes(si.k)).map((si) => {
            const d = sessionDailyAvg(si.k),
              s = screenSessions[si.k];
            return (
              <div
                key={si.k}
                style={{
                  display: "flex",
                  justifyContent: "space-between",
                  alignItems: "center",
                  padding: "7px 0",
                  borderBottom: `1px solid ${C.border}`,
                }}
              >
                <div style={{ display: "flex", alignItems: "center", gap: 9 }}>
                  <div
                    style={{
                      width: 9,
                      height: 9,
                      borderRadius: 2,
                      background: si.col,
                      flexShrink: 0,
                    }}
                  />
                  <div>
                    <div style={{ fontSize: 13, color: C.dark }}>{si.label}</div>
                    <div style={{ fontSize: 11, color: C.faint }}>
                      {s.freq === 7 ? "daily" : `${s.freq}×/wk`} ·{" "}
                      {s.mins < 60 ? s.mins + "m" : s.mins / 60 + "h"} sessions
                    </div>
                  </div>
                </div>
                <span style={{ fontSize: 13, fontWeight: 600, color: si.col }}>{fmt(d)}/day</span>
              </div>
            );
          })}
          <div
            style={{
              display: "flex",
              justifyContent: "space-between",
              padding: "10px 0 0",
              marginTop: 2,
            }}
          >
            <span style={{ fontSize: 13, fontWeight: 700, color: C.dark }}>Total</span>
            <span style={{ fontSize: 14, fontWeight: 700, color: C.purple }}>
              {fmt(totalIdeal)}/day
            </span>
          </div>
        </div>
      )}

      {/* Week schedule — mobile-first vertical layout */}
      <div style={card}>
        <div style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.dark, marginBottom: 4 }}>
          Your balanced week
        </div>
        <div style={{ fontSize: 13, color: C.muted, marginBottom: 14, lineHeight: 1.55 }}>
          Each day shows your non-negotiables, chosen activities, and screen time. Variety across
          the week matters more than a single daily number.
        </div>

        {DAYS.map((day) => {
          // Activities scheduled this day
          const dayActs = sched[day] || [];
          // Screen types that occur this day (distribute by freq across week)
          const dayScreens = SCREEN_TYPES.filter(
            (si) =>
              screenChecked.includes(si.k) &&
              screenSessions[si.k] &&
              (() => {
                const freq = screenSessions[si.k].freq;
                const dayIdx = DAYS.indexOf(day);
                // Distribute: daily=every day, 6x=M-Sa, 5x=M-F, 4x=M-Th, 3x=M/W/F, 2x=Tu/Th, 1x=Wed
                if (freq === 7) return true;
                if (freq === 6) return dayIdx < 6;
                if (freq === 5) return dayIdx < 5;
                if (freq === 4) return dayIdx < 4;
                if (freq === 3) return [0, 2, 4].includes(dayIdx);
                if (freq === 2) return [1, 3].includes(dayIdx);
                if (freq === 1) return dayIdx === 2;
                return false;
              })()
          );

          // Time blocks: non-negotiables as a compact bar, then activities, then screens
          const isWeekend = day === "Sat" || day === "Sun";
          const blocks = [
            // Fixed obligations — school/work + commute zero on weekends
            {
              label: age >= 18 ? "Work" : "School",
              h: isWeekend ? 0 : schoolH,
              c: GC.school,
              fixed: true,
            },
            { label: "Sleep", h: sleep, c: GC.sleep, fixed: true },
            { label: "Hygiene", h: hygiene, c: GC.hygiene, fixed: true },
            { label: "Meals", h: meals, c: GC.eating, fixed: true },
            { label: "Chores", h: chores, c: GC.chores, fixed: true },
            {
              label: "Commute",
              h: isWeekend ? 0 : commute,
              c: GC.commute,
              fixed: true,
              show: !isWeekend && commute > 0,
            },
          ].filter((b) => b.h > 0 && b.show !== false);

          const total = 24;

          return (
            <div
              key={day}
              style={{
                marginBottom: 10,
                borderRadius: 11,
                border: `1px solid ${C.border}`,
                overflow: "hidden",
              }}
            >
              {/* Day header */}
              <div
                style={{
                  background: C.dark,
                  padding: "7px 12px",
                  display: "flex",
                  justifyContent: "space-between",
                  alignItems: "center",
                }}
              >
                <span
                  style={{ fontSize: 13, fontWeight: 700, color: "white", letterSpacing: "0.04em" }}
                >
                  {day === "Sat" || day === "Sun" ? day + " — Weekend" : day}
                </span>
                <span style={{ fontSize: 11, color: "rgba(255,255,255,0.7)" }}>
                  {dayActs.length > 0 || dayScreens.length > 0
                    ? `${dayActs.length} activit${dayActs.length === 1 ? "y" : "ies"}${dayScreens.length > 0 ? " · screens" : ""}`
                    : "rest day"}
                </span>
              </div>

              {/* Proportional time bar */}
              <div style={{ height: 10, display: "flex", overflow: "hidden" }}>
                {blocks.map((b, i) => (
                  <div key={i} style={{ flex: b.h / total, background: b.c, minWidth: 0 }} />
                ))}
                {dayActs.map((a, i) => (
                  <div
                    key={"a" + i}
                    style={{
                      flex: actH / Math.max(dayActs.length, 1) / total,
                      background: a.col,
                      minWidth: 0,
                      opacity: 0.85,
                    }}
                  />
                ))}
                {dayScreens.map((s, i) => (
                  <div
                    key={"s" + i}
                    style={{
                      flex: sessionDailyAvg(s.k) / total,
                      background: GC.scrChosen,
                      minWidth: 0,
                      opacity: 0.9,
                    }}
                  />
                ))}
                <div style={{ flex: 1, background: C.surfaceAlt, minWidth: 0 }} />
              </div>

              {/* Content rows */}
              <div style={{ padding: "10px 12px", background: C.surface }}>
                {/* Non-negotiables — compact */}
                <div
                  style={{
                    display: "flex",
                    flexWrap: "wrap",
                    gap: 4,
                    marginBottom: dayActs.length > 0 || dayScreens.length > 0 ? 8 : 0,
                  }}
                >
                  {blocks.map((b, i) => (
                    <div
                      key={i}
                      style={{
                        display: "inline-flex",
                        alignItems: "center",
                        gap: 4,
                        padding: "3px 8px",
                        borderRadius: 20,
                        background: `${b.c}18`,
                        border: `1px solid ${b.c}40`,
                      }}
                    >
                      <div
                        style={{
                          width: 6,
                          height: 6,
                          borderRadius: "50%",
                          background: b.c,
                          flexShrink: 0,
                        }}
                      />
                      <span style={{ fontSize: 11, color: C.dark, fontWeight: 500 }}>
                        {b.label} <span style={{ color: C.muted }}>{fmt(b.h)}</span>
                      </span>
                    </div>
                  ))}
                </div>

                {/* Activities this day */}
                {dayActs.length > 0 && (
                  <div
                    style={{
                      display: "flex",
                      flexWrap: "wrap",
                      gap: 4,
                      marginBottom: dayScreens.length > 0 ? 6 : 0,
                    }}
                  >
                    {dayActs.map((a, i) => (
                      <div
                        key={i}
                        style={{
                          display: "inline-flex",
                          alignItems: "center",
                          gap: 4,
                          padding: "3px 8px",
                          borderRadius: 20,
                          background: a.col,
                          border: `1px solid ${a.col}`,
                        }}
                      >
                        <span style={{ fontSize: 11, color: "white", fontWeight: 600 }}>
                          {a.label}
                        </span>
                      </div>
                    ))}
                  </div>
                )}

                {/* Screen time this day */}
                {dayScreens.length > 0 && (
                  <div style={{ display: "flex", flexWrap: "wrap", gap: 4 }}>
                    {dayScreens.map((s, i) => (
                      <div
                        key={i}
                        style={{
                          display: "inline-flex",
                          alignItems: "center",
                          gap: 4,
                          padding: "3px 8px",
                          borderRadius: 20,
                          background: `${GC.scrChosen}22`,
                          border: `1px solid ${GC.scrChosen}60`,
                        }}
                      >
                        <span style={{ fontSize: 11, color: C.dark, fontWeight: 500 }}>
                          {s.label.split(" / ")[0]}{" "}
                          <span style={{ color: C.muted }}>{fmt(sessionDailyAvg(s.k))}</span>
                        </span>
                      </div>
                    ))}
                  </div>
                )}

                {dayActs.length === 0 && dayScreens.length === 0 && (
                  <div style={{ fontSize: 12, color: C.faint, fontStyle: "italic" }}>
                    Free time — rest, unstructured time, or whatever the day brings.
                  </div>
                )}
              </div>
            </div>
          );
        })}

        {/* Research note */}
        <div
          style={{
            marginTop: 4,
            padding: "10px 12px",
            background: C.tealFaint,
            borderRadius: 9,
            borderLeft: `3px solid ${C.mid}`,
            fontSize: 12,
            color: C.dark,
            lineHeight: 1.65,
          }}
        >
          <strong style={{ color: C.mid }}>Research note:</strong> Singh et al. (
          <em>JAMA Pediatrics</em>, 2026 — 100,991 adolescents) found moderate social media users
          had the best wellbeing outcomes. Variety across the week and intentional use matter more
          than hitting a single daily number. WHO &amp; CDC recommend 60 min of movement daily for
          youth.
        </div>
      </div>
    </div>
  );
}

// ── APP ───────────────────────────────────────────────────────────────────────
const pulseStyle = document.createElement("style");
pulseStyle.textContent = `
  @keyframes defragPulse{0%,100%{box-shadow:0 0 0 0 rgba(249,115,22,0.9)}60%{box-shadow:0 0 0 10px rgba(249,115,22,0)}}

  @keyframes dotEat{0%{fill:#e4e4e7}30%{fill:#fdba74}100%{fill:#f97316}}
  /* pacTravel removed — pac-man now uses SVG animateTransform inside LabeledLifeGrid */
  input[type=range]{height:8px;cursor:pointer}
  input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:28px;height:28px;border-radius:50%;background:#0d9488;border:2px solid white;box-shadow:0 1px 4px rgba(0,0,0,0.25);cursor:grab}
  input[type=range]::-webkit-slider-thumb:active{cursor:grabbing;transform:scale(1.1)}
  input[type=range]::-moz-range-thumb{width:28px;height:28px;border-radius:50%;background:#0d9488;border:2px solid white;box-shadow:0 1px 4px rgba(0,0,0,0.25);cursor:grab}
  input[type=range]::-moz-range-thumb:active{cursor:grabbing;transform:scale(1.1)}
`;
if (!document.head.querySelector("#defrag-pulse")) {
  pulseStyle.id = "defrag-pulse";
  document.head.appendChild(pulseStyle);
}

function Defrag() {
  const [step, setStep] = useState(0);
  const [showFinder, setShowFinder] = useState(false);
  const [showScreensGrid, setShowScreensGrid] = useState(false);
  const [showMediaBalance, setShowMediaBalance] = useState(false);
  const [showOpening, setShowOpening] = useState(true);
  const [showAbout, setShowAbout] = useState(false);
  const [showResearch, setShowResearch] = useState(false);
  const [returningUser, setReturningUser] = useState(false);
  // Email capture state
  const [emailVal, setEmailVal] = useState("");
  const [emailNewsletter, setEmailNewsletter] = useState(true);
  const [emailSent, setEmailSent] = useState(false);
  const [emailError, setEmailError] = useState("");
  const [uGoal, setUGoal] = useState(60);
  const [uFreq, setUFreq] = useState(2);

  // Step 1 — About You
  const [age, setAge] = useState(15);
  const [isParent, setIsParent] = useState(false);
  const [fd, setFd] = useState(11); // first regular internet/online age
  const [smartphoneAge, setSmartphoneAge] = useState(0); // age when smartphone became daily constant (0 = same as fd)
  const [occupationType, setOccupationType] = useState("school"); // "school"|"work" — for ages 18-22
  const [schoolDeviceH, setSchoolDeviceH] = useState(3); // hours of school/work on a device — matches teen (14-17) bracket default since age starts at 15
  const [hwDeviceH, setHwDeviceH] = useState(0.75); // hours of homework on a device (under 18 only)
  const [sleep, setSleep] = useState(8.5);
  const [school, setSchool] = useState(7);
  const [hw, setHw] = useState(1.5);
  const [asc, setAsc] = useState(0);
  const [hygiene, setHygiene] = useState(0.5);
  const [chores, setChores] = useState(0.75);
  const [meals, setMeals] = useState(1);
  const [commute, setCommute] = useState(0.5);
  const [caregiving, setCaregiving] = useState(0);
  const [collegeType, setCollegeType] = useState("none");
  const [teenHasJob, setTeenHasJob] = useState(false);
  const [teenJobDays, setTeenJobDays] = useState(3);
  const [teenJobShiftH, setTeenJobShiftH] = useState(3);
  // Organized activities (kids/teen only)
  const [currActH, setCurrActH] = useState(0);

  // Step 3 — Invest Your Time
  const [interests, setInterests] = useState([]);
  const [deviceInterests, setDeviceInterests] = useState([]);
  const [actH, setActH] = useState(2);
  const [screenChecked, setScreenChecked] = useState([]);
  const [screenSessions, setScreenSessions] = useState({
    streaming: { freq: 4, mins: 60 },
    gaming: { freq: 2, mins: 90 },
    social: { freq: 7, mins: 30 },
    calls: { freq: 2, mins: 30 },
    learning: { freq: 3, mins: 20 },
    creative: { freq: 2, mins: 45 },
    news: { freq: 3, mins: 10 },
  });

  // Step 2 — Your Day With Screens
  const [sS, setSS] = useState(3); // school screens
  const [sH, setSH] = useState(7); // home screens
  const [wkSH, setWkSH] = useState(9); // total weekend screen hours (not a delta)
  // Track whether user has manually touched weekend slider — ref avoids re-render cycles
  const wkSHTouchedRef = React.useRef(false);
  // Auto-suggest wkSH = sH + WEEKEND_DELTA_H when user hasn't manually adjusted it
  React.useEffect(() => {
    if (!wkSHTouchedRef.current) {
      const suggested = Math.min(16, Math.max(0, sH + D.WEEKEND_DELTA_H));
      setWkSH(suggested);
    }
  }, [sH]);
  const wkX = Math.max(0, wkSH - sH); // derived delta for backward compat
  const [pkp, setPkp] = useState(D.AVG_DAILY_PICKUPS);
  const [mt, setMt] = useState(false);
  const [scrOverlap, setScrOverlap] = useState(false);
  const [dayAnswers, setDayAnswers] = useState({}); // day walkthrough answers (legacy, kept for compatibility)
  const [dayOverrides, setDayOverrides] = useState({}); // per-question minute overrides
  // Phone-checking during obligations — checkboxes in Step 1
  const [phoneChecks, setPhoneChecks] = useState([]); // array of keys: "meals","commute","gettingReady","caregiving","bedtime"
  // Custom interest state — hoisted from IIFE to avoid Rules of Hooks violation
  const [otherOpen, setOtherOpen] = useState({});
  const [otherVal, setOtherVal] = useState({});
  const [expandedCat, setExpandedCat] = useState(null); // accordion — which interest category is expanded
  const [customLabels, setCustomLabels] = useState({}); // replaces window.__defragCustomLabels
  // Default to true: the opening card discloses "anonymous data helps research"
  // so the baseline expectation is opt-in. A visible opt-out lives on Step 1.
  // The payload sent never includes PII — only age bracket, obligation hours,
  // and aggregate screen stats. Users who disable this see no data leave the device.
  const [researchOptIn, setResearchOptIn] = useState(true);
  const [researchSent, setResearchSent] = useState(false);
  const [autoCollectSent, setAutoCollectSent] = useState(false);
  const [pacActive, setPacActive] = useState(false);
  const [adjPickups, setAdjPickups] = useState(D.AVG_DAILY_PICKUPS); // adjusted pickups from Possibilities page
  const [eliminatedFiller, setEliminatedFiller] = useState([]); // filler contexts user commits to eliminating
  const [pbtOpen, setPbtOpen] = useState(false); // protected brain time expandable
  const [adjScrH, setAdjScrH] = useState(null); // adjusted personal screen hours from Possibilities (null = use totalIdeal)
  // Sync defaults when user changes inputs
  React.useEffect(() => {
    setAdjPickups(pkp);
  }, [pkp]);
  // effectiveAdjScrH moved below totalIdeal — see line after totalIdeal

  // ── localStorage persistence ──────────────────────────────────────────────
  // Saves the user's answers so they can close the tab and come back. Opt-in
  // by design: the opening card's "I've done this before →" link restores.
  // Bump STORAGE_KEY version if the persist schema changes — old data is dropped.
  const STORAGE_KEY = "defrag:v1";
  // Saved sessions expire after this many days. Prevents a user from seeing
  // their answers from a year ago when they circle back — screen habits,
  // obligations, and the tool itself all drift over that timescale.
  const SAVE_TTL_DAYS = 90;
  const restoredRef = React.useRef(false);
  const lastSavedRef = React.useRef("");
  // Single source of truth for what gets saved. Add new fields here.
  // `__savedAt` is added at write time so we can check TTL on restore.
  const buildSnapshot = () => ({
    __savedAt: Date.now(),
    __version: 1,
    age,
    isParent,
    fd,
    smartphoneAge,
    occupationType,
    schoolDeviceH,
    hwDeviceH,
    sleep,
    school,
    hw,
    asc,
    hygiene,
    chores,
    meals,
    commute,
    caregiving,
    collegeType,
    teenHasJob,
    teenJobDays,
    teenJobShiftH,
    currActH,
    interests,
    deviceInterests,
    actH,
    screenChecked,
    screenSessions,
    sS,
    sH,
    wkSH,
    pkp,
    mt,
    scrOverlap,
    phoneChecks,
    otherOpen,
    otherVal,
    customLabels,
    researchOptIn,
    adjPickups,
    eliminatedFiller,
    adjScrH,
  });
  // True if `s` is a snapshot older than the TTL — we treat it as expired.
  const isSnapshotExpired = (s) => {
    if (!s || typeof s.__savedAt !== "number") return false; // old saves without timestamp pass
    const ageMs = Date.now() - s.__savedAt;
    return ageMs > SAVE_TTL_DAYS * 24 * 60 * 60 * 1000;
  };
  // Apply a saved snapshot — each field guarded so partial/old saves still work.
  const applySnapshot = (s) => {
    if (!s || typeof s !== "object") return;
    const set = (v, fn) => {
      if (v !== undefined) fn(v);
    };
    set(s.age, setAge);
    set(s.isParent, setIsParent);
    set(s.fd, setFd);
    set(s.smartphoneAge, setSmartphoneAge);
    set(s.occupationType, setOccupationType);
    set(s.schoolDeviceH, setSchoolDeviceH);
    set(s.hwDeviceH, setHwDeviceH);
    set(s.sleep, setSleep);
    set(s.school, setSchool);
    set(s.hw, setHw);
    set(s.asc, setAsc);
    set(s.hygiene, setHygiene);
    set(s.chores, setChores);
    set(s.meals, setMeals);
    set(s.commute, setCommute);
    set(s.caregiving, setCaregiving);
    set(s.collegeType, setCollegeType);
    set(s.teenHasJob, setTeenHasJob);
    set(s.teenJobDays, setTeenJobDays);
    set(s.teenJobShiftH, setTeenJobShiftH);
    set(s.currActH, setCurrActH);
    set(s.interests, setInterests);
    set(s.deviceInterests, setDeviceInterests);
    set(s.actH, setActH);
    set(s.screenChecked, setScreenChecked);
    set(s.screenSessions, setScreenSessions);
    set(s.sS, setSS);
    set(s.sH, setSH);
    set(s.wkSH, setWkSH);
    set(s.pkp, setPkp);
    set(s.mt, setMt);
    set(s.scrOverlap, setScrOverlap);
    set(s.phoneChecks, setPhoneChecks);
    set(s.otherOpen, setOtherOpen);
    set(s.otherVal, setOtherVal);
    set(s.customLabels, setCustomLabels);
    set(s.researchOptIn, setResearchOptIn);
    set(s.adjPickups, setAdjPickups);
    set(s.eliminatedFiller, setEliminatedFiller);
    set(s.adjScrH, setAdjScrH);
    // If restoring a saved session, the weekend slider was already touched
    // (otherwise wkSH wouldn't be saved as a deliberate value).
    if (s.wkSH !== undefined) wkSHTouchedRef.current = true;
  };
  // Check for existing save on mount — BUT do not activate saving yet.
  // The restoredRef gates the save effect. It only flips true once the user
  // commits to a session (starts fresh OR restores), not on every mount.
  // This prevents the opening card's default state from clobbering real saves.
  // If an existing save is older than SAVE_TTL_DAYS we quietly wipe it so the
  // user doesn't see a Welcome back card for stale data.
  const [hasSavedSession, setHasSavedSession] = useState(false);
  React.useEffect(() => {
    try {
      const raw = localStorage.getItem(STORAGE_KEY);
      if (!raw) return;
      const parsed = JSON.parse(raw);
      if (isSnapshotExpired(parsed)) {
        localStorage.removeItem(STORAGE_KEY);
        return;
      }
      setHasSavedSession(true);
    } catch {}
  }, []);
  // Save on every state change, debounced to avoid thrashing during drags.
  React.useEffect(() => {
    if (!restoredRef.current) return;
    const timer = setTimeout(() => {
      try {
        const payload = JSON.stringify(buildSnapshot());
        if (payload === lastSavedRef.current) return;
        lastSavedRef.current = payload;
        localStorage.setItem(STORAGE_KEY, payload);
      } catch {
        /* localStorage disabled or full — fail silently */
      }
    }, 400);
    return () => clearTimeout(timer);
  }); // no deps = runs every render, debounced save is the throttle
  // Explicit restore — called from the "Restore my answers" button
  const restoreSavedSession = () => {
    try {
      const raw = localStorage.getItem(STORAGE_KEY);
      if (!raw) return false;
      const parsed = JSON.parse(raw);
      if (isSnapshotExpired(parsed)) {
        localStorage.removeItem(STORAGE_KEY);
        setHasSavedSession(false);
        return false;
      }
      applySnapshot(parsed);
      lastSavedRef.current = raw; // prevent immediate re-save of same payload
      restoredRef.current = true; // now start tracking changes
      return true;
    } catch {
      return false;
    }
  };
  // Explicit clear — called from "Start over" or "Start fresh" buttons.
  // Also called implicitly when a user begins a brand-new session over a stale save.
  const clearSavedSession = () => {
    try {
      localStorage.removeItem(STORAGE_KEY);
    } catch {}
    lastSavedRef.current = "";
    setHasSavedSession(false);
  };
  // Call this when the user begins a fresh session (clicks "Do the math" or "Start fresh").
  // Wipes any previous save and starts tracking new state.
  const beginFreshSession = () => {
    clearSavedSession();
    restoredRef.current = true;
  };

  const scrollToTop = () => {
    window.scrollTo({ top: 0, behavior: "instant" });
    document.documentElement.scrollTop = 0;
    document.body.scrollTop = 0;
  };

  // Only reset defaults when the user crosses into a different age bracket
  const getBracket = (a) => AGE_BRACKETS.find((b) => a >= b.min && a <= b.max) || AGE_BRACKETS[4];
  // Pass prevAge explicitly so rapid clicks don't read a stale closure age.
  function applyAgeBracket(newAge, prevAge = age) {
    const oldBracket = getBracket(prevAge);
    const newBracket = getBracket(newAge);
    // Only reset obligation defaults when crossing a bracket boundary
    if (oldBracket !== newBracket) {
      setSleep(newBracket.sleep);
      setSchool(newBracket.school);
      setHw(newBracket.hw);
      setHygiene(newBracket.hygiene);
      setChores(newBracket.chores);
      setMeals(newBracket.meals);
      setCommute(newBracket.commute);
      setSS(newBracket.sS);
      setSH(newBracket.sH);
      setFd(Math.min(newBracket.fd, Math.max(5, newAge - 1)));
      setSchoolDeviceH(newAge < 18 ? newBracket.sS : 2);
      // For adults 30+: estimate smartphone age based on iPhone launch (2007)
      if (newAge >= 30) {
        const iphoneYear = 2007;
        const birthYear = 2026 - newAge;
        const estSmartphoneAge = Math.max(newBracket.fd, iphoneYear - birthYear);
        setSmartphoneAge(Math.min(estSmartphoneAge, newAge - 1));
      } else {
        setSmartphoneAge(0); // under 30: smartphone = first device, no separate input needed
      }
      setCollegeType("none");
    }
    // These conditional resets still need to fire on every change at the boundary
    if (newAge >= 18) {
      setHw(0);
      setAsc(0);
      setTeenHasJob(false);
    }
    if (newAge < 13) {
      setTeenHasJob(false);
    }
    if (newAge >= 18 && newAge <= 22) setOccupationType("school");
    if (newAge >= 65) {
      setSchool(0);
      setCommute(0.25);
    }
    setCaregiving(newAge >= 25 && newAge < 65 ? 0.5 : 0);
  }

  const collegeBonusYrs =
    collegeType === "grad"
      ? 6
      : collegeType === "4year"
        ? 4
        : collegeType === "2year"
          ? 2
          : collegeType === "trade"
            ? 1.5
            : 0;
  const schoolH = school + (age < 18 ? hw : asc);
  const teenJobDailyH =
    age >= 13 && age < 18 && teenHasJob ? +((teenJobDays * teenJobShiftH) / 7).toFixed(2) : 0;
  // Weekday obligations (school/work + commute + hw apply M-F only)
  const weekdayOblig =
    sleep +
    schoolH +
    hygiene +
    chores +
    meals +
    commute +
    (age >= 18 ? caregiving : 0) +
    teenJobDailyH;
  // Weekend obligations (no school/work, commute, hw, teen job)
  const weekendOblig = sleep + hygiene + chores + meals + (age >= 18 ? caregiving : 0);
  const oblig = weekdayOblig; // weekday for daily display
  const freeTime = Math.max(0, 24 - oblig);
  const weekendFreeTime = Math.max(0, 24 - weekendOblig);
  // Weekly average free time — used for lifetime projections + balance tracker
  const avgFreeTime = (5 * freeTime + 2 * weekendFreeTime) / 7;
  // Weekly average screen hours (weekday sH + weekend wkSH)
  const avgSH = (5 * sH + 2 * wkSH) / 7;
  const sessionDailyAvg = (k) => {
    const s = screenSessions[k];
    return s ? (s.freq * s.mins) / 7 / 60 : 0;
  };
  const totalIdeal = screenChecked.reduce((a, k) => a + sessionDailyAvg(k), 0);
  // effectiveAdjScrH: starts at totalIdeal (from Invest Your Time), user can drag lower on Possibilities for additional savings
  // Floor at 1h when user hasn't built a screen budget (prevents "your plan is 0h screens")
  const effectiveAdjScrH =
    adjScrH !== null ? adjScrH : Math.max(totalIdeal, D.FALLBACK_SCREEN_BUDGET_H);
  // True when the user never built a screen budget in Step 4 AND the Possibilities
  // slider was never touched — we're silently showing the fallback. Used to warn
  // the user on downstream pages that their plan is a placeholder.
  const usingFallbackBudget = adjScrH === null && totalIdeal < D.FALLBACK_SCREEN_BUDGET_H;
  const totalScr = sS + sH;
  const yearsRem = Math.max(1, D.LIFE_EXPECTANCY_YRS - age);
  const toYrs = (h) => ((h * 365 * yearsRem) / 8760).toFixed(1);
  // rY: years reclaimed = free-time screens vs chosen — sS excluded since it can't be changed
  const rY = Math.max(0, parseFloat(toYrs(sH)) - parseFloat(toYrs(totalIdeal))).toFixed(1);
  const yw = Math.max(0, age - fd);
  const yg = ((totalScr * 365 * yw) / 8760).toFixed(1);
  const freePct = freeTime > 0 ? Math.round((sH / freeTime) * 100) : 0;
  const idealPct = freeTime > 0 ? Math.round((totalIdeal / freeTime) * 100) : 0;
  const actPct = Math.max(0, 100 - idealPct);
  const balGood = idealPct <= 25;
  const obligH = hygiene + chores + meals + commute + (age >= 18 ? caregiving : 0);
  const totalM = yearsRem * 12;
  const unclaimedH = Math.max(0, freeTime - actH - totalIdeal);

  // ── Protected brain time + screen intensity ─────────────────────────────────
  // Filler screen time — calculated from phone-checking checkboxes + pickup count
  // Each checked context adds estimated minutes, scaled by pickup intensity
  const pkpScale = Math.max(D.PKP_SCALE_MIN, Math.min(D.PKP_SCALE_MAX, pkp / D.AVG_DAILY_PICKUPS));
  const FILLER_ESTIMATES = {
    morning: 20, // morning phone check
    gettingReady: 10, // checking while getting ready
    commute: 20, // scrolling during commute
    work: 30, // personal phone checks at work/school
    afterSchool: 20, // phone during after-school activities
    meals: 18, // phone during meals
    caregiving: 15, // phone during caregiving
    bedtime: 25, // phone before bed
  };
  const fillerMinutes = phoneChecks.reduce(
    (sum, k) => sum + Math.round((FILLER_ESTIMATES[k] || 15) * pkpScale),
    0
  );
  // Audio minutes — would need a separate question to capture accurately
  // Phone checks don't tell us about audio (podcasts/music), so we don't assume
  const audioMinutes = 0;
  const wakingMinutes = (24 - sleep) * 60;
  // Protected brain time = waking minutes minus brain-occupying activities:
  // work/school (all hours, not just device), commute, all screens (required + filler + intentional), audio
  // Meals, chores, hygiene — your mind can wander during those, so NOT subtracted
  // Caregiving IS subtracted — you're managing someone else's needs, not thinking your own thoughts
  const caregivingMin = (age >= 18 ? caregiving : 0) * 60;
  const protectedMinutes = Math.max(
    0,
    wakingMinutes -
      schoolH * 60 -
      commute * 60 -
      caregivingMin -
      teenJobDailyH * 60 -
      fillerMinutes -
      sH * 60 -
      audioMinutes
  );

  // Effective protected brain time — only counts if it could form 23+ minute blocks
  // Estimate: protected time is scattered across meals, hygiene, chores, and transition gaps
  // Model each as a block and count only blocks >= FOCUS_RECOVERY_MIN (Gloria Mark)
  const protectedBlocks = [
    { name: "Meals", min: meals * 60 }, // eating without screens
    { name: "Hygiene", min: hygiene * 60 }, // shower, getting ready
    { name: "Chores", min: chores * 60 }, // dishes, laundry, tidying
  ].filter((b) => b.min > 0);
  // Subtract filler proportionally from these blocks (filler eats into meal time, getting-ready time, etc.)
  const fillerPerBlock = protectedBlocks.length > 0 ? fillerMinutes / protectedBlocks.length : 0;
  const effectiveBlocks = protectedBlocks.map((b) => ({
    ...b,
    net: Math.max(0, b.min - fillerPerBlock),
  }));
  const effectiveProtectedMinutes = effectiveBlocks.reduce(
    (sum, b) => sum + (b.net >= D.FOCUS_RECOVERY_MIN ? b.net : 0),
    0
  );

  // ── Possibilities page: 3 levers recalculate everything ──────────────────
  // adjPickups (slider) scales remaining filler; eliminatedFiller removes contexts; adjScrH lowers intentional
  // Pickup ratio: linear scale from current pickups. No floor clamp — 10 pickups = ~5% of baseline.
  const adjPkpRatio = pkp > 0 ? Math.min(1, adjPickups / pkp) : 1;
  // Lever 1: filler after removing protected windows
  // Lever 2: remaining filler scaled by adjusted pickup ratio (continuous, not rounded per-context)
  const adjFillerBase = phoneChecks
    .filter((k) => !eliminatedFiller.includes(k))
    .reduce((sum, k) => sum + (FILLER_ESTIMATES[k] || 15), 0);
  const adjFillerMinutes = Math.round(adjFillerBase * pkpScale * adjPkpRatio);
  // Lever 3: effectiveAdjScrH = adjusted intentional screen time
  const improvedProtectedMinutes = Math.round(
    Math.max(
      0,
      wakingMinutes -
        schoolH * 60 -
        commute * 60 -
        caregivingMin -
        teenJobDailyH * 60 -
        adjFillerMinutes -
        effectiveAdjScrH * 60 -
        audioMinutes
    )
  );
  const protectedGainFromPlan = improvedProtectedMinutes - protectedMinutes;
  // Reclaimed from each lever separately (for display)
  const fillerSavedMin = Math.max(0, fillerMinutes - adjFillerMinutes);
  const bonusYrsFromFiller = (fillerSavedMin / 60 / 24) * yearsRem;
  // Base reclaimed years from Invest Your Time ideal vs reality.
  // Uses max(totalIdeal, effectiveAdjScrH) as the floor so that if a user
  // drags effectiveAdjScrH ABOVE totalIdeal in Possibilities (loosening
  // their own budget), we don't over-claim savings. Pair with additionalFromScreen
  // below so the two terms telescope cleanly to (sH - effectiveAdjScrH) in both
  // directions.
  const committedScr = Math.max(totalIdeal, effectiveAdjScrH);
  const baseReclaimedYrs = Math.max(0, ((sH - committedScr) / 24) * yearsRem);
  // Additional from Possibilities levers (on top of base) — only positive when
  // user went BELOW their stated budget.
  const additionalFromScreen = Math.max(0, ((totalIdeal - effectiveAdjScrH) / 24) * yearsRem);
  const totalReclaimedYrsGlobal = baseReclaimedYrs + additionalFromScreen + bonusYrsFromFiller;
  // requiredDeviceH needed here for adjFutureScrYrs (also used later for statScrH)
  const requiredDeviceH = schoolDeviceH + (age < 18 ? hwDeviceH : 0);
  // Future screen years if user follows through
  // Weekend screen estimate caps at user's weekday plan + WEEKEND_DELTA_H,
  // matching the Step 3 auto-suggest so the projection isn't inflated by a
  // pre-plan weekend value the user already reduced elsewhere.
  const adjFutureScrYrs = (
    ((requiredDeviceH +
      (5 * effectiveAdjScrH + 2 * Math.min(effectiveAdjScrH + D.WEEKEND_DELTA_H, wkSH)) / 7) /
      24) *
    yearsRem
  ).toFixed(1);

  // Controllable screen time = filler + intentional personal (NOT required school/work)
  const controllableH = fillerMinutes / 60 + sH;
  const isLightUser = controllableH < D.LIGHT_USER_THRESHOLD_H;
  // Controllable as % of free time
  const controllableScrPct =
    avgFreeTime > 0 ? Math.min(100, Math.round((controllableH / avgFreeTime) * 100)) : 0;

  // ── Counterfactual: what if this light user drifted to the next bracket's average? ──
  // kids→tweens (5h), tweens→teens (7h), teens→national teen avg (8h), adults→national avg (5h)
  const cfScrH = age < 11 ? 5 : age < 14 ? 7 : age < 18 ? 8 : 5;
  const cfLabel =
    age < 11
      ? "the tween average"
      : age < 14
        ? "the teen average"
        : age < 18
          ? "the national teen average"
          : "the national average";
  const cfProtectedMinutes = Math.max(
    0,
    wakingMinutes -
      schoolH * 60 -
      commute * 60 -
      caregivingMin -
      teenJobDailyH * 60 -
      fillerMinutes -
      cfScrH * 60 -
      audioMinutes
  );
  const protectedMinutesLost = Math.max(0, protectedMinutes - cfProtectedMinutes);
  const cfControllablePct =
    avgFreeTime > 0
      ? Math.min(100, Math.round(((fillerMinutes / 60 + cfScrH) / avgFreeTime) * 100))
      : 0;
  const cfScreenYears = ((cfScrH / 24) * yearsRem).toFixed(1);

  // ── Pickup reduction scenario (used in Reveal at fixed 25 pkp) ────────────────
  const reducedPkp = D.REDUCED_PKP_TARGET;
  const reducedPkpScale = Math.max(
    D.PKP_SCALE_MIN,
    Math.min(D.PKP_SCALE_MAX, reducedPkp / D.AVG_DAILY_PICKUPS)
  );
  const reducedFillerMinutes = phoneChecks.reduce(
    (sum, k) => sum + Math.round((FILLER_ESTIMATES[k] || 15) * reducedPkpScale),
    0
  );
  const reducedProtectedMinutes = Math.max(
    0,
    wakingMinutes -
      schoolH * 60 -
      commute * 60 -
      caregivingMin -
      teenJobDailyH * 60 -
      reducedFillerMinutes -
      sH * 60 -
      audioMinutes
  );
  const protectedGain = reducedProtectedMinutes - protectedMinutes;
  // Pickup savings for Possibilities lever display (isolate pickup effect from filler window effect)
  const fillerAfterElimOnly = Math.round(adjFillerBase * pkpScale); // filler with windows removed but pickups unchanged
  const pkpSavedMin = Math.max(0, fillerAfterElimOnly - adjFillerMinutes); // savings from pickup reduction alone
  const bonusYrsFromPickups = (pkpSavedMin / 60 / 24) * yearsRem;

  // Suggested activity hours — based on selected interests, frequency & session data
  // Suggested daily activity hours — models realistic scheduling:
  // Each activity gets its freq × hours spread across the week, but total daily
  // slots are capped at what a person can realistically fit (1-3 activities/day).
  // This prevents 10 selected interests from summing to 8h/day.
  const suggestedActH = parseFloat(
    (() => {
      if (interests.length === 0) return 0;
      // Build weekly schedule: how many total activity-hours per week
      const weeklyTotal = interests.reduce((sum, k) => {
        return sum + (ACTIVITY_FREQ[k] || 2) * (ACTIVITY_HOURS[k] || 1);
      }, 0);
      const rawDaily = weeklyTotal / 7;
      // Cap: realistic daily ceiling is ~2-3 activities averaging ~1h each
      // Scale down when selections pile up beyond what fits in a day
      const maxRealisticDaily = Math.min(3.5, avgFreeTime * 0.5); // no more than half of free time
      return Math.min(rawDaily, maxRealisticDaily);
    })().toFixed(2)
  );
  // Auto-apply suggestion when interests change; cap at available free time
  React.useEffect(() => {
    setActH(parseFloat(Math.min(avgFreeTime, suggestedActH).toFixed(2)));
  }, [interests.join(",")]);

  // ── Shared derived values for charts ────────────────────────────────────────
  const avgLifeSH = avgSH;
  // effSH (weekday) — used for daily pie; matches user's actual input
  const effSH = sH;
  // effSHLifetime — weekly average, used for lifetime grid + reveal stats
  const effSHLifetime = avgLifeSH;
  // totalScrH / statScrH — use weekly average for lifetime accuracy
  // totalScrH: required screens (school/work devices + homework devices for students) + personal
  // (requiredDeviceH defined earlier near adjFutureScrYrs)
  const totalScrH = requiredDeviceH + avgLifeSH;
  const statScrH = totalScrH;

  // ── Total lifetime screen years (past + future) for adults ──────────────────
  // Pass total screen hours (personal + work/school devices) as the ramp target
  const pastScreenYears = computeLifetimeScreenYears(age, fd, statScrH, smartphoneAge);
  const futureScreenYears = parseFloat(((statScrH / 24) * yearsRem).toFixed(1)) || 0;
  const totalLifetimeScreenYears = (pastScreenYears + futureScreenYears).toFixed(1);

  // "School + Jobs" label for kids/teens; work label for adults
  const schoolLabel = age >= 18 ? "Work" : "School + Homework";
  // schoolPieH: school hours only (sS is DURING school, not additive to the day)
  const schoolPieH = age < 18 ? schoolH : 0;
  const workPieH = age >= 18 ? school : 0;
  const obligPieH =
    sleep +
    schoolPieH +
    workPieH +
    hygiene +
    chores +
    meals +
    commute +
    (age >= 18 ? caregiving : 0) +
    teenJobDailyH;
  const freeTimePieH = Math.max(0, 24 - obligPieH);
  // Stats — calendar years (intuitive) + waking % (intensity)
  const wakingHrs = Math.max(1, 24 - sleep);
  const calendarScrYears = ((statScrH / 24) * yearsRem).toFixed(1); // "22 years" — all screens (weekly avg)
  const personalScrYears = ((avgLifeSH / 24) * yearsRem).toFixed(1); // "18 years" — personal screens (weekly avg)
  const wakingPct = ((statScrH / wakingHrs) * 100).toFixed(0); // "58% of every waking hour"
  const wakingScreenYears = ((statScrH / wakingHrs) * yearsRem).toFixed(1); // kept for transition screens
  // Free-time screen intensity: uses weekly average for both sides (screens + free time)
  const freeTimeLifeYrs = (avgFreeTime / 24) * yearsRem;
  const scrFreeTimeYrs = (effSHLifetime / 24) * yearsRem;
  const freePctOfFreeLifeRaw =
    freeTimeLifeYrs > 0 ? Math.round((scrFreeTimeYrs / freeTimeLifeYrs) * 100) : 0;
  const freePctOfFreeLife = Math.min(100, freePctOfFreeLifeRaw);
  const scrExceedsFreeTime = freePctOfFreeLifeRaw > 100;

  // ── Pie chart segs — same category order as grid ─────────────────────────
  // Chart 1 (reality): free time splits visibly into personal screens + open time
  const rScrPieH = Math.min(effSH, freeTimePieH); // screens inside free time
  const rOpenPieH = Math.max(0, freeTimePieH - rScrPieH); // remaining open time
  const rSegs = [
    { l: "Sleep", h: sleep, c: GC.sleep, show: true },
    { l: schoolLabel, h: schoolPieH, c: GC.school, show: schoolPieH > 0 },
    { l: "Part-time job", h: teenJobDailyH, c: GC.teenJob, show: teenJobDailyH > 0 },
    { l: "Work", h: workPieH, c: GC.work, show: workPieH > 0 },
    { l: "Eating", h: meals, c: GC.eating, show: meals > 0 },
    { l: "Hygiene", h: hygiene, c: GC.hygiene, show: hygiene > 0 },
    { l: "Travel time", h: commute, c: GC.commute, show: commute > 0 },
    { l: "Chores", h: chores, c: GC.chores, show: chores > 0 },
    {
      l: "Caregiving",
      h: age >= 18 ? caregiving : 0,
      c: GC.other,
      show: (age >= 18 ? caregiving : 0) > 0,
    },
    {
      l: age < 13 ? "Projected screens (national avg)" : "Personal screens",
      h: rScrPieH,
      c: GC.scrFree,
      show: rScrPieH > 0,
    },
    { l: "Open free time", h: rOpenPieH, c: GC.freeTime, show: rOpenPieH > 0.05 },
  ]
    .filter((s) => s.show && s.h > 0.05)
    .map((s) => ({ l: s.l, h: s.h, c: s.c }));

  // Chart 2 (ideal): free time splits into activities + chosen screens + open
  const iFreeActH = Math.min(actH, freeTimePieH);
  const iFreeScrH = Math.min(totalIdeal, Math.max(0, freeTimePieH - iFreeActH));
  const iFreeOpenH = Math.max(0, freeTimePieH - iFreeActH - iFreeScrH);
  const iSegs = [
    { l: "Sleep", h: sleep, c: GC.sleep, show: true },
    { l: schoolLabel, h: schoolPieH, c: GC.school, show: schoolPieH > 0 },
    { l: "Part-time job", h: teenJobDailyH, c: GC.teenJob, show: teenJobDailyH > 0 },
    { l: "Work", h: workPieH, c: GC.work, show: workPieH > 0 },
    { l: "Eating", h: meals, c: GC.eating, show: meals > 0 },
    { l: "Hygiene", h: hygiene, c: GC.hygiene, show: hygiene > 0 },
    { l: "Travel time", h: commute, c: GC.commute, show: commute > 0 },
    { l: "Chores", h: chores, c: GC.chores, show: chores > 0 },
    {
      l: "Caregiving",
      h: age >= 18 ? caregiving : 0,
      c: GC.other,
      show: (age >= 18 ? caregiving : 0) > 0,
    },
    { l: "Activities & interests", h: iFreeActH, c: GC.activities, show: iFreeActH > 0 },
    { l: "Chosen screen time", h: iFreeScrH, c: GC.scrChosen, show: iFreeScrH > 0 },
    { l: "Open free time", h: iFreeOpenH, c: GC.freeTime, show: iFreeOpenH > 0.05 },
  ]
    .filter((s) => s.show && s.h > 0.05)
    .map((s) => ({ l: s.l, h: s.h, c: s.c }));

  // ── Lifetime grid segs ────────────────────────────────────────────────────
  // Grid uses actH (stated intention) — the honest lifetime projection.
  // Each grid is a computeGridSegs call; memoized with explicit deps so
  // slider drags on unrelated fields don't recompute every grid on every
  // render. See docblock on computeGridSegs for the blending rules.
  const gridScrH = avgLifeSH + fillerMinutes / 60;
  // Retirement screen estimate: weekend screens + filler (retirement ≈ unstructured time ≈ weekends)
  const retireScrH = wkSH + fillerMinutes / 60;
  // Shared obligation inputs used by every grid — one tuple, many memos
  // Reality grid: NO activities — just obligations + screens (personal + filler) + free time.
  // Each grid memo lists its full dep tuple inline so eslint-plugin-react-hooks
  // can statically verify the dependencies. The shared obligation inputs
  // (age/sleep/schoolH/hygiene/chores/meals/commute/yearsRem/teenJobDailyH/collegeBonusYrs)
  // are repeated in each call — verbose but lint-clean.
  // Grid with screens always visible — used by LabeledLifeGrid in Reveal (reality = no activities)
  const rGridSegsScreensOn = React.useMemo(
    () =>
      computeGridSegs({
        age,
        sleep,
        schoolH,
        hygiene,
        chores,
        meals,
        commute,
        otherH: 0,
        sH: gridScrH,
        actH: 0,
        idealScr: totalIdeal,
        yearsRem,
        isIdeal: false,
        showScreens: true,
        isKids: age < 13,
        teenJobH: teenJobDailyH,
        collegeBonusYrs,
        retireScrH,
        deviceH: requiredDeviceH,
      }),
    [
      age,
      sleep,
      schoolH,
      hygiene,
      chores,
      meals,
      commute,
      yearsRem,
      teenJobDailyH,
      collegeBonusYrs,
      gridScrH,
      totalIdeal,
      retireScrH,
      requiredDeviceH,
    ]
  );
  // Defragged grid — user's chosen screen budget rendered as the "after" state.
  // Hoisted to App level so both Possibilities (Step 7) and Plan (Step 8) can render it.
  const defragGridSegs = React.useMemo(
    () =>
      computeGridSegs({
        age,
        sleep,
        schoolH,
        hygiene,
        chores,
        meals,
        commute,
        otherH: actH,
        sH: avgLifeSH,
        actH: 0,
        idealScr: effectiveAdjScrH,
        yearsRem,
        isIdeal: true,
        showScreens: false,
        isKids: false,
        teenJobH: teenJobDailyH,
        collegeBonusYrs,
        deviceH: requiredDeviceH,
      }),
    [
      age,
      sleep,
      schoolH,
      hygiene,
      chores,
      meals,
      commute,
      yearsRem,
      teenJobDailyH,
      collegeBonusYrs,
      actH,
      avgLifeSH,
      effectiveAdjScrH,
      requiredDeviceH,
    ]
  );

  // NOTE: an earlier version computed rGridSegs, iGridSegs, fullLifeData,
  // ftRealitySegs, ftIdealSegs, and lifetimePieGridSegs. ESLint proved they
  // were all unused — the only lifetime grid actually rendered is
  // rGridSegsScreensOn (on the Reveal page) and defragGridSegs (on the
  // Possibilities and Plan pages). Removing them saved ~5-6 computeGridSegs
  // calls per render and several hundred lines of dead code.

  // ── Legend arrays (Chart 1 / Chart 2) ────────────────────────────────────
  const LEGEND_BASE = [
    { c: GC.school, l: age >= 22 ? "Work" : "School + Work" },
    { c: GC.sleep, l: "Sleep" },
    { c: GC.hygiene, l: "Hygiene" },
    { c: GC.chores, l: "Chores" },
    { c: GC.eating, l: "Eating" },
    { c: GC.commute, l: "Travel time" },
    { c: GC.other, l: "Other obligations" },
  ];
  const realityLegend = [
    ...LEGEND_BASE,
    { c: GC.scrFree, l: age < 13 ? "Projected screens (national avg)" : "Personal screens" },
    { empty: true, l: "Open free time" },
  ];
  const idealLegendSplit = [
    ...LEGEND_BASE,
    { c: GC.activities, l: "Activities & interests" },
    { c: GC.scrChosen, l: "Chosen screen time" },
    { empty: true, l: "Open free time" },
  ];
  const idealLegendFree = [...LEGEND_BASE, { empty: true, l: "Free Time" }];
  const idealLegend = showMediaBalance ? idealLegendSplit : idealLegendFree;

  // ── STEP 1 — About You ─────────────────────────────────────────────────────
  const Step1 = () => {
    const bracket = AGE_BRACKETS.find((b) => age >= b.min && age <= b.max) || AGE_BRACKETS[4];
    const rows = [
      { l: "Sleep", dot: GC.sleep, v: sleep, set: setSleep, mn: age < 13 ? 8 : 4, mx: 13 },
      {
        l: age >= 18 ? "Work Hours" : "School Hours",
        dot: GC.school,
        v: school,
        set: setSchool,
        mn: 0,
        mx: 14,
      },
      age < 18 ? { l: "Homework", dot: C.amber, v: hw, set: setHw, mn: 0, mx: 5 } : null,
      age >= 18
        ? { l: "School (if applicable)", dot: GC.school, v: asc, set: setAsc, mn: 0, mx: 6 }
        : null,
      { l: "Hygiene", dot: GC.hygiene, v: hygiene, set: setHygiene, mn: 0.25, mx: 2 },
      { l: "Chores", dot: GC.chores, v: chores, set: setChores, mn: 0, mx: 4 },
      { l: "Meals", dot: C.amber, v: meals, set: setMeals, mn: 0.25, mx: 3 },
      {
        l: age >= 18 ? "Commute / Transit" : "Travel time",
        dot: GC.commute,
        v: commute,
        set: setCommute,
        mn: 0,
        mx: 3,
      },
      age >= 18
        ? {
            l: "Caregiving / Active parenting",
            dot: GC.other,
            v: caregiving,
            set: setCaregiving,
            mn: 0,
            mx: 6,
          }
        : null,
    ].filter(Boolean);
    // teenJobRow handled separately below obligations (checkbox + conditional steppers)
    return (
      <div>
        <div style={{ marginBottom: 16 }}>
          <div
            style={{
              fontSize: 11,
              fontWeight: 700,
              letterSpacing: "0.12em",
              textTransform: "uppercase",
              color: C.royal,
              marginBottom: 4,
            }}
          >
            Step 1 of 9
          </div>
          <h2
            style={{
              ...sr,
              color: C.dark,
              fontSize: 22,
              marginBottom: 4,
              fontWeight: 700,
              lineHeight: 1.2,
            }}
          >
            About You
          </h2>
          <div style={{ fontSize: 14, color: C.muted, lineHeight: 1.5 }}>
            Tell us about yourself so we can map your day accurately.
          </div>
        </div>

        {/* Age slider */}
        <div style={card}>
          <div
            style={{
              display: "flex",
              justifyContent: "space-between",
              alignItems: "center",
              flexWrap: "wrap",
              gap: 12,
              marginBottom: 10,
            }}
          >
            <div>
              <div style={{ ...sr, fontSize: 15, color: C.dark, fontWeight: 700, marginBottom: 2 }}>
                {isParent ? "Child's age" : "How old are you?"}
              </div>
              <div style={{ fontSize: 13, color: C.muted }}>
                US life expectancy: 78 years (CDC NCHS 2022)
              </div>
            </div>
            <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
              <button
                onClick={() =>
                  setAge((prev) => {
                    const next = Math.max(5, prev - 1);
                    applyAgeBracket(next, prev);
                    return next;
                  })
                }
                style={bSm}
              >
                −
              </button>
              <span
                style={{
                  fontFamily: "'SF Mono',Menlo,monospace",
                  fontWeight: 700,
                  color: C.mid,
                  fontSize: 20,
                  minWidth: 36,
                  textAlign: "center",
                }}
              >
                {age}
              </span>
              <button
                onClick={() =>
                  setAge((prev) => {
                    const next = Math.min(77, prev + 1);
                    applyAgeBracket(next, prev);
                    return next;
                  })
                }
                style={bSm}
              >
                +
              </button>
            </div>
          </div>
          <SmoothSlider
            min={5}
            max={77}
            step={1}
            value={age}
            onChange={(a) => {
              setAge(a);
              applyAgeBracket(a);
            }}
            style={{ ...sl, marginBottom: 6 }}
            ariaLabel={isParent ? "Child's age in years" : "Your age in years"}
            ariaValueText={`${age} years old, ${bracket.label}`}
          />
          <div
            style={{
              display: "flex",
              justifyContent: "space-between",
              fontSize: 11,
              color: C.faint,
            }}
          >
            <span>5</span>
            <span>{bracket.label}</span>
            <span>77</span>
          </div>
          <div
            style={{
              background: C.surfaceAlt,
              borderRadius: 8,
              height: 10,
              overflow: "hidden",
              display: "flex",
              border: `1px solid ${C.border}`,
              marginTop: 8,
              marginBottom: 4,
            }}
          >
            <div style={{ width: `${((age / 78) * 100).toFixed(0)}%`, background: "#a1a1aa" }} />
            <div style={{ flex: 1, background: C.mid, opacity: 0.35 }} />
          </div>
          <div
            style={{
              display: "flex",
              justifyContent: "space-between",
              fontSize: 12,
              color: C.faint,
            }}
          >
            <span>born</span>
            <span>now ({age})</span>
            <span>78</span>
          </div>
        </div>

        {/* Parent toggle */}
        <div
          onClick={() => setIsParent((v) => !v)}
          style={{
            display: "flex",
            alignItems: "center",
            gap: 10,
            padding: "11px 16px",
            background: isParent ? C.tealFaint : C.surface,
            borderRadius: 12,
            border: `1px solid ${isParent ? C.mid : C.border}`,
            cursor: "pointer",
            marginBottom: 10,
            userSelect: "none",
          }}
        >
          <div
            style={{
              width: 16,
              height: 16,
              borderRadius: 4,
              border: `2px solid ${isParent ? C.mid : C.faint}`,
              background: isParent ? C.mid : "transparent",
              flexShrink: 0,
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
            }}
          >
            {isParent && (
              <span style={{ color: "white", fontSize: 10, fontWeight: 700, lineHeight: 1 }}>
                ✓
              </span>
            )}
          </div>
          <span style={{ fontSize: 14, color: C.dark, fontWeight: 500 }}>
            I'm filling this out for my child
          </span>
        </div>
        {isParent && (
          <div
            style={{
              background: "#f0fdfa",
              borderRadius: 10,
              padding: "10px 14px",
              marginBottom: 10,
              borderLeft: `3px solid ${C.amber}`,
              fontSize: 14,
              color: "#0f766e",
              lineHeight: 1.6,
            }}
          >
            For parents and kids to do together — as a conversation, not a rule.
          </div>
        )}

        {/* Screen history — two inputs for 30+, one for younger */}
        {age >= 30 ? (
          <>
            <div style={card}>
              <div style={{ ...sr, fontSize: 14, color: C.dark, fontWeight: 700, marginBottom: 4 }}>
                When did you first go online regularly?
              </div>
              <div style={{ fontSize: 12, color: C.muted, marginBottom: 10 }}>
                AOL, dial-up, desktop internet — when screens became part of your daily life.
              </div>
              <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 6 }}>
                <button onClick={() => setFd((v) => Math.max(5, v - 1))} style={bSm}>
                  −
                </button>
                <span
                  style={{
                    fontFamily: "'SF Mono',Menlo,monospace",
                    fontWeight: 700,
                    color: C.amberDark,
                    fontSize: 16,
                    minWidth: 60,
                    textAlign: "center",
                  }}
                >
                  age {fd}
                </span>
                <button
                  onClick={() =>
                    setFd((v) => Math.min(smartphoneAge > 0 ? smartphoneAge : age - 1, v + 1))
                  }
                  style={bSm}
                >
                  +
                </button>
              </div>
            </div>
            <div style={card}>
              <div style={{ ...sr, fontSize: 14, color: C.dark, fontWeight: 700, marginBottom: 4 }}>
                When did you get a smartphone?
              </div>
              <div style={{ fontSize: 12, color: C.muted, marginBottom: 10 }}>
                The moment screens became constant — in your pocket, always on, always connected.
              </div>
              <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 6 }}>
                <button onClick={() => setSmartphoneAge((v) => Math.max(fd, v - 1))} style={bSm}>
                  −
                </button>
                <span
                  style={{
                    fontFamily: "'SF Mono',Menlo,monospace",
                    fontWeight: 700,
                    color: C.amberDark,
                    fontSize: 16,
                    minWidth: 60,
                    textAlign: "center",
                  }}
                >
                  age {smartphoneAge}
                </span>
                <button
                  onClick={() => setSmartphoneAge((v) => Math.min(age - 1, v + 1))}
                  style={bSm}
                >
                  +
                </button>
              </div>
              <div style={{ fontSize: 12, color: C.muted }}>
                {Math.max(0, age - fd)} years of screens total: {Math.max(0, smartphoneAge - fd)}{" "}
                years desktop era + {Math.max(0, age - smartphoneAge)} years smartphone era.
              </div>
            </div>
          </>
        ) : (
          <div style={card}>
            <div style={{ ...sr, fontSize: 14, color: C.dark, fontWeight: 700, marginBottom: 4 }}>
              {age < 13
                ? "When did screens become a regular part of your day?"
                : "When did you get your first smartphone?"}
            </div>
            <div style={{ fontSize: 12, color: C.muted, marginBottom: 10 }}>
              {age < 13
                ? "Tablets, TV shows, YouTube, gaming — when did regular screen use start?"
                : "The moment screens became constant — in your pocket, always on."}
            </div>
            <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 6 }}>
              <button onClick={() => setFd((v) => Math.max(2, v - 1))} style={bSm}>
                −
              </button>
              <span
                style={{
                  fontFamily: "'SF Mono',Menlo,monospace",
                  fontWeight: 700,
                  color: C.amberDark,
                  fontSize: 16,
                  minWidth: 60,
                  textAlign: "center",
                }}
              >
                age {fd}
              </span>
              <button onClick={() => setFd((v) => Math.min(age - 1, v + 1))} style={bSm}>
                +
              </button>
            </div>
            <div style={{ fontSize: 12, color: C.muted }}>
              {age < 13
                ? `${Math.max(0, age - fd)} ${Math.max(0, age - fd) === 1 ? "year" : "years"} of regular screen use. We'll project what's ahead.`
                : `${Math.max(0, age - fd)} ${Math.max(0, age - fd) === 1 ? "year" : "years"} of screen use so far. Full picture in your Reveal.`}
            </div>
          </div>
        )}

        {/* For ages 18-22: school or working? */}
        {age >= 18 && age <= 22 && (
          <div style={card}>
            <div style={{ ...sr, fontSize: 14, color: C.dark, fontWeight: 700, marginBottom: 8 }}>
              Primarily in school or working?
            </div>
            <div style={{ display: "flex", gap: 6 }}>
              {[
                ["school", "In school"],
                ["work", "Working"],
              ].map(([val, label]) => (
                <button
                  key={val}
                  onClick={() => {
                    setOccupationType(val);
                    if (val === "work") {
                      setSchool(8);
                      setHw(0);
                    } else {
                      setSchool(6);
                      setHw(1.5);
                    }
                  }}
                  style={{
                    flex: 1,
                    padding: "10px 14px",
                    borderRadius: 10,
                    border: `1.5px solid ${occupationType === val ? C.mid : C.border}`,
                    background: occupationType === val ? `${C.mid}12` : C.surface,
                    cursor: "pointer",
                    fontSize: 14,
                    fontWeight: 600,
                    color: occupationType === val ? C.mid : C.dark,
                  }}
                >
                  {label}
                </button>
              ))}
            </div>
          </div>
        )}

        {/* Obligation sliders */}
        <div style={{ marginTop: 6 }}>
          <div style={{ ...sr, fontSize: 16, fontWeight: 700, color: C.dark, marginBottom: 6 }}>
            Your daily obligations
          </div>
          <div
            style={{
              background: C.tealFaint,
              borderRadius: 10,
              padding: "10px 14px",
              marginBottom: 14,
              borderLeft: `3px solid ${C.mid}`,
              fontSize: 14,
              color: C.dark,
              lineHeight: 1.6,
            }}
          >
            These are the hours you don't control. Be honest — don't round down.
          </div>
          {rows.map((r, i) => (
            <div key={i}>
              <Stepper
                label={r.l}
                dot={r.dot}
                value={r.v}
                onInc={() => r.set((v) => Math.min(r.mx, +(v + 0.25).toFixed(2)))}
                onDec={() => r.set((v) => Math.max(r.mn, +(v - 0.25).toFixed(2)))}
              />
              {r.l === "Work Hours" && age >= 18 && (
                <div
                  style={{
                    fontSize: 12,
                    color: C.muted,
                    background: C.surfaceAlt,
                    borderRadius: 8,
                    padding: "8px 12px",
                    marginTop: -4,
                    marginBottom: 8,
                    lineHeight: 1.6,
                    borderLeft: `3px solid ${C.mid}`,
                  }}
                >
                  Full-time parent or caregiver at home? That counts here. If managing a household
                  is your primary role, put those hours here — your brain is on someone else's clock
                  the entire time.
                </div>
              )}
              {r.l === "Caregiving / Active parenting" && (
                <div
                  style={{
                    fontSize: 12,
                    color: C.muted,
                    background: C.surfaceAlt,
                    borderRadius: 8,
                    padding: "8px 12px",
                    marginTop: -4,
                    marginBottom: 8,
                    lineHeight: 1.6,
                    borderLeft: `3px solid ${C.amber}`,
                  }}
                >
                  How many hours before or after work are you actively managing kids or dependents?
                  Drop-offs, pickups, bedtime routines, homework help, meal prep — the time where
                  you're "on duty" even though you're not at your job. Fun time together goes in{" "}
                  <strong style={{ color: C.dark }}>Invest Your Time</strong>.
                </div>
              )}
            </div>
          ))}

          {/* Teen part-time job — ages 13-17, inside obligations */}
          {age >= 13 && age < 18 && (
            <div style={{ marginTop: 6 }}>
              <div
                onClick={() => setTeenHasJob((v) => !v)}
                style={{
                  display: "flex",
                  alignItems: "center",
                  gap: 10,
                  padding: "11px 16px",
                  background: teenHasJob ? C.tealFaint : C.surface,
                  borderRadius: 12,
                  border: `1px solid ${teenHasJob ? C.mid : C.border}`,
                  cursor: "pointer",
                  marginBottom: teenHasJob ? 6 : 0,
                  userSelect: "none",
                }}
              >
                <div
                  style={{
                    width: 16,
                    height: 16,
                    borderRadius: 4,
                    border: `2px solid ${teenHasJob ? C.mid : C.faint}`,
                    background: teenHasJob ? C.mid : "transparent",
                    flexShrink: 0,
                    display: "flex",
                    alignItems: "center",
                    justifyContent: "center",
                  }}
                >
                  {teenHasJob && (
                    <span style={{ color: "white", fontSize: 10, fontWeight: 700, lineHeight: 1 }}>
                      ✓
                    </span>
                  )}
                </div>
                <span style={{ fontSize: 14, color: C.dark, fontWeight: 500 }}>
                  I have a part-time job
                </span>
              </div>
              {teenHasJob && (
                <>
                  <Stepper
                    label="Days per week"
                    dot={GC.teenJob}
                    value={teenJobDays}
                    onInc={() => setTeenJobDays((v) => Math.min(6, v + 1))}
                    onDec={() => setTeenJobDays((v) => Math.max(1, v - 1))}
                  >
                    {teenJobDays} day{teenJobDays !== 1 ? "s" : ""}/wk
                  </Stepper>
                  <Stepper
                    label="Hours per shift"
                    dot={GC.teenJob}
                    value={teenJobShiftH}
                    onInc={() => setTeenJobShiftH((v) => Math.min(8, +(v + 0.5).toFixed(1)))}
                    onDec={() => setTeenJobShiftH((v) => Math.max(1, +(v - 0.5).toFixed(1)))}
                  >
                    {teenJobShiftH}h/shift
                  </Stepper>
                  <div
                    style={{
                      fontSize: 12,
                      color: C.mid,
                      fontWeight: 600,
                      marginTop: -4,
                      marginBottom: 4,
                      paddingLeft: 19,
                    }}
                  >
                    ≈ {fmt(teenJobDailyH)}/day average ({teenJobDays * teenJobShiftH}h across the
                    week)
                  </div>
                </>
              )}
            </div>
          )}
        </div>

        {/* School device hours */}
        {school > 0 && (
          <div style={card}>
            <div
              style={{
                display: "flex",
                justifyContent: "space-between",
                alignItems: "baseline",
                marginBottom: 6,
              }}
            >
              <div>
                <div style={{ ...sr, fontSize: 14, color: C.dark, fontWeight: 700 }}>
                  Of those {age >= 18 ? "work" : "school"} hours, how many <em>require</em> a
                  device?
                </div>
                <div style={{ fontSize: 12, color: C.muted, marginTop: 2, lineHeight: 1.55 }}>
                  {age >= 18
                    ? "Only count device use that your job actually requires — email, spreadsheets, video calls, job-specific tools. Scrolling social media or browsing during work doesn't count here — that's personal screen time."
                    : "Chromebooks, laptops, tablets — required device use during school."}
                </div>
              </div>
              <span
                style={{
                  ...sr,
                  fontSize: 20,
                  color: C.mid,
                  fontWeight: 700,
                  flexShrink: 0,
                  marginLeft: 12,
                }}
              >
                {fmt(schoolDeviceH)}
              </span>
            </div>
            <SmoothSlider
              min={0}
              max={Math.min(school, 10)}
              step={0.25}
              value={schoolDeviceH}
              onChange={(v) => setSchoolDeviceH(v)}
              style={sl}
              ariaLabel={
                age >= 18 ? "Work hours on a device per day" : "School hours on a device per day"
              }
              ariaValueText={`${fmt(schoolDeviceH)} per day`}
            />
          </div>
        )}

        {/* Homework device hours — under 18 with homework */}
        {age < 18 && hw > 0 && (
          <div style={card}>
            <div
              style={{
                display: "flex",
                justifyContent: "space-between",
                alignItems: "baseline",
                marginBottom: 6,
              }}
            >
              <div>
                <div style={{ ...sr, fontSize: 14, color: C.dark, fontWeight: 700 }}>
                  How much homework is done on a screen?
                </div>
                <div style={{ fontSize: 12, color: C.muted, marginTop: 2 }}>
                  Google Docs, research, online assignments — required device use for homework.
                </div>
              </div>
              <span
                style={{
                  ...sr,
                  fontSize: 20,
                  color: C.mid,
                  fontWeight: 700,
                  flexShrink: 0,
                  marginLeft: 12,
                }}
              >
                {fmt(hwDeviceH)}
              </span>
            </div>
            <SmoothSlider
              min={0}
              max={Math.min(hw, 4)}
              step={0.25}
              value={hwDeviceH}
              onChange={(v) => setHwDeviceH(v)}
              style={sl}
              ariaLabel="Homework hours on a device per day"
              ariaValueText={`${fmt(hwDeviceH)} per day`}
            />
          </div>
        )}

        {/* College/education path — two choices, higher ed expands */}
        <div style={{ marginBottom: 8 }}>
          <div
            style={{
              fontSize: 12,
              fontWeight: 700,
              letterSpacing: "0.08em",
              textTransform: "uppercase",
              color: C.muted,
              marginBottom: 6,
            }}
          >
            {age >= 22 ? "Education after high school" : "After high school, I plan to…"}
          </div>
          <div style={{ display: "flex", gap: 6, marginBottom: collegeType !== "none" ? 6 : 0 }}>
            <button
              onClick={() => setCollegeType("none")}
              style={{
                flex: 1,
                padding: "12px 14px",
                borderRadius: 10,
                border: `1.5px solid ${collegeType === "none" ? C.mid : C.border}`,
                background: collegeType === "none" ? `${C.mid}12` : C.surface,
                cursor: "pointer",
                textAlign: "center",
              }}
            >
              <div
                style={{
                  fontSize: 13,
                  fontWeight: 600,
                  color: collegeType === "none" ? C.mid : C.dark,
                }}
              >
                {age >= 22 ? "Went straight to work" : "Enter the workforce"}
              </div>
            </button>
            <button
              onClick={() => {
                if (collegeType === "none") setCollegeType("4year");
              }}
              style={{
                flex: 1,
                padding: "12px 14px",
                borderRadius: 10,
                border: `1.5px solid ${collegeType !== "none" ? C.mid : C.border}`,
                background: collegeType !== "none" ? `${C.mid}12` : C.surface,
                cursor: "pointer",
                textAlign: "center",
              }}
            >
              <div
                style={{
                  fontSize: 13,
                  fontWeight: 600,
                  color: collegeType !== "none" ? C.mid : C.dark,
                }}
              >
                {age >= 22 ? "Continued education" : "Continue with higher ed"}
              </div>
            </button>
          </div>
          {collegeType !== "none" && (
            <div
              style={{
                background: C.surfaceAlt,
                borderRadius: 10,
                padding: "10px 12px",
                border: `1px solid ${C.border}`,
              }}
            >
              <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
                {[
                  ["2year", "2-year or community college", "School extends to age 20"],
                  ["trade", "Trade or vocational program", "School extends to age 19.5"],
                  ["4year", "4-year university", "School extends to age 22"],
                  ["grad", "Graduate or professional degree", "School extends to age 24"],
                ].map(([val, label, note]) => (
                  <button
                    key={val}
                    onClick={() => setCollegeType(val)}
                    style={{
                      display: "flex",
                      alignItems: "center",
                      gap: 10,
                      padding: "8px 12px",
                      borderRadius: 8,
                      border: `1.5px solid ${collegeType === val ? C.mid : C.border}`,
                      background: collegeType === val ? C.tealFaint : C.surface,
                      cursor: "pointer",
                      textAlign: "left",
                      width: "100%",
                    }}
                  >
                    <div
                      style={{
                        width: 12,
                        height: 12,
                        borderRadius: "50%",
                        border: `2px solid ${collegeType === val ? C.mid : C.faint}`,
                        background: collegeType === val ? C.mid : "transparent",
                        flexShrink: 0,
                      }}
                    />
                    <div style={{ flex: 1 }}>
                      <span
                        style={{
                          fontSize: 13,
                          fontWeight: 600,
                          color: collegeType === val ? C.mid : C.dark,
                        }}
                      >
                        {label}
                      </span>
                      <span style={{ fontSize: 11, color: C.muted, marginLeft: 6 }}>{note}</span>
                    </div>
                  </button>
                ))}
              </div>
            </div>
          )}
          {collegeBonusYrs > 0 && (
            <div
              style={{
                background: C.tealFaint,
                borderRadius: 8,
                padding: "8px 12px",
                marginTop: 6,
                fontSize: 12,
                color: C.dark,
                lineHeight: 1.6,
                borderLeft: `3px solid ${C.mid}`,
              }}
            >
              {age >= 22 ? (
                <>
                  Your school phase extended to <strong>age {18 + collegeBonusYrs}</strong> — work
                  years start after that in the lifetime projection.
                </>
              ) : (
                <>
                  This extends your school phase by <strong>{collegeBonusYrs} years</strong> — work
                  begins at <strong>age {18 + collegeBonusYrs}</strong> in the lifetime projection.
                </>
              )}
            </div>
          )}
        </div>

        {/* Teen part-time job moved to daily obligations section */}

        {/* How this shifts over time — callout for under 18 */}
        {age < 18 && (
          <div
            style={{
              background: "#f0fdfa",
              borderRadius: 9,
              padding: "9px 13px",
              marginBottom: 8,
              borderLeft: `3px solid ${C.mid}`,
              fontSize: 13,
              color: C.dark,
              lineHeight: 1.6,
            }}
          >
            <strong>How this shifts over time —</strong> Sleep drops ~30m as you get older. School
            becomes work. Chores grow. Travel increases. All of this is factored into the lifetime
            projection.
          </div>
        )}

        {/* ── Pickups ── */}
        <div style={card}>
          <div
            style={{
              display: "flex",
              justifyContent: "space-between",
              alignItems: "flex-start",
              gap: 10,
              marginBottom: 8,
            }}
          >
            <div>
              <div style={{ ...sr, fontSize: 15, color: C.dark, fontWeight: 700, marginBottom: 3 }}>
                How many times do you pick up your phone per day?
              </div>
            </div>
            <span
              style={{
                ...sr,
                fontSize: 22,
                fontWeight: 700,
                color: pkp > D.AVG_DAILY_PICKUPS ? C.red : C.mid,
                flexShrink: 0,
              }}
            >
              {pkp}×
            </span>
          </div>
          <SmoothSlider
            min={0}
            max={500}
            step={5}
            value={pkp}
            onChange={(v) => setPkp(Math.round(v))}
            style={sl}
            ariaLabel="Daily phone pickups"
            ariaValueText={`${pkp} pickups per day, national average is ${D.AVG_DAILY_PICKUPS}`}
          />
          <div
            style={{
              display: "flex",
              justifyContent: "space-between",
              fontSize: 11,
              color: C.faint,
              marginTop: 4,
            }}
          >
            <span>0</span>
            <span>Avg: {D.AVG_DAILY_PICKUPS}×</span>
            <span>500</span>
          </div>
          <div style={{ display: "flex", justifyContent: "flex-end", marginTop: 6 }}>
            <button
              onClick={() => setShowFinder(true)}
              style={{
                background: C.tealFaint,
                border: `1px solid ${C.tealLight}`,
                borderRadius: 8,
                padding: "4px 10px",
                fontSize: 11,
                color: C.mid,
                cursor: "pointer",
                fontWeight: 600,
              }}
            >
              How to find this
            </button>
          </div>
        </div>

        {/* ── Phone during obligations ── */}
        <div style={card}>
          <div style={{ ...sr, fontSize: 15, color: C.dark, fontWeight: 700, marginBottom: 4 }}>
            Where does your phone show up?
          </div>
          <div style={{ fontSize: 13, color: C.muted, lineHeight: 1.55, marginBottom: 12 }}>
            Check any that sound like you. This captures the screen time that never feels like
            "screen time."
          </div>
          {[
            {
              k: "morning",
              label: "First thing in the morning",
              desc: "Checking before you get out of bed",
            },
            {
              k: "gettingReady",
              label: "While getting ready",
              desc: "Scrolling while getting dressed, eating breakfast",
            },
            ...(commute > 0
              ? [
                  {
                    k: "commute",
                    label: "During commute / transit",
                    desc: "Podcasts, music, scrolling, browsing while traveling",
                  },
                ]
              : []),
            {
              k: "work",
              label: age >= 18 ? "At work" : "At school",
              desc: "Checking notifications, texts, scrolling between tasks",
            },
            ...(age < 18
              ? [
                  {
                    k: "afterSchool",
                    label: "During after-school activities",
                    desc: "Checking phone at practice, rehearsal, games, or between activities",
                  },
                ]
              : []),
            {
              k: "meals",
              label: "During meals",
              desc: "Phone out while eating — checking, scrolling",
            },
            ...(age >= 18 && caregiving > 0
              ? [
                  {
                    k: "caregiving",
                    label: "During caregiving",
                    desc: "Phone out while watching kids, during routines",
                  },
                ]
              : []),
            {
              k: "bedtime",
              label: "In bed before sleep",
              desc: "Phone until you fall asleep or as a wind-down habit",
            },
          ].map(({ k, label, desc }) => {
            const on = phoneChecks.includes(k);
            return (
              <button
                key={k}
                type="button"
                role="checkbox"
                aria-checked={on}
                aria-label={`${label}. ${desc}`}
                onClick={() =>
                  setPhoneChecks((prev) => (on ? prev.filter((x) => x !== k) : [...prev, k]))
                }
                style={{
                  display: "flex",
                  width: "100%",
                  textAlign: "left",
                  gap: 12,
                  padding: "10px 12px",
                  borderRadius: 10,
                  marginBottom: 5,
                  cursor: "pointer",
                  background: on ? "#f0fdfa" : C.surfaceAlt,
                  border: `1px solid ${on ? "#5eead4" : C.border}`,
                  transition: "all 0.15s",
                  fontFamily: "inherit",
                }}
              >
                <div
                  style={{
                    width: 18,
                    height: 18,
                    borderRadius: 5,
                    border: `2px solid ${on ? C.amber : C.border}`,
                    background: on ? C.amber : "transparent",
                    display: "flex",
                    alignItems: "center",
                    justifyContent: "center",
                    flexShrink: 0,
                    marginTop: 2,
                  }}
                  aria-hidden="true"
                >
                  {on && (
                    <span style={{ color: "white", fontSize: 11, lineHeight: 1, fontWeight: 700 }}>
                      ✓
                    </span>
                  )}
                </div>
                <div>
                  <div style={{ fontSize: 13, fontWeight: on ? 700 : 500, color: C.dark }}>
                    {label}
                  </div>
                  <div style={{ fontSize: 11, color: C.muted, lineHeight: 1.4, marginTop: 1 }}>
                    {desc}
                  </div>
                </div>
              </button>
            );
          })}
          {phoneChecks.length > 0 && (
            <div
              style={{
                background: "#f0fdfa",
                borderRadius: 8,
                padding: "8px 12px",
                marginTop: 6,
                border: "1px solid #5eead4",
                display: "flex",
                justifyContent: "space-between",
                alignItems: "center",
              }}
            >
              <span style={{ fontSize: 12, color: "#0f766e" }}>Estimated filler screen time</span>
              <span style={{ ...sr, fontSize: 18, fontWeight: 700, color: C.amber }}>
                {fillerMinutes}m/day
              </span>
            </div>
          )}
        </div>

        {/* Summary — absorbs transition 1 content */}
        <div style={{ ...dCard(), borderLeft: "4px solid #2dd4bf", padding: "24px 22px" }}>
          <div
            style={{
              display: "flex",
              justifyContent: "space-between",
              alignItems: "center",
              flexWrap: "wrap",
              gap: 12,
              marginBottom: 16,
            }}
          >
            <div>
              <div style={{ ...lbl12, color: "rgba(255,255,255,0.7)" }}>Hours spoken for</div>
              <div style={{ ...sr, fontSize: 34, fontWeight: 700, color: "white" }}>
                {fmt(oblig)}
              </div>
            </div>
            <div style={{ textAlign: "right" }}>
              <div style={{ ...lbl12, color: "rgba(255,255,255,0.7)" }}>Your free time</div>
              <div
                style={{
                  ...sr,
                  fontSize: 34,
                  fontWeight: 700,
                  color: freeTime < 0 ? "#facc15" : "#2dd4bf",
                }}
              >
                {freeTime < 0 ? "Over 24h!" : fmt(freeTime)}
              </div>
            </div>
          </div>
          <div style={{ ...sr, fontSize: 17, color: "white", fontWeight: 700, marginBottom: 8 }}>
            That's all the time that's actually yours.
          </div>
          <p
            style={{
              fontSize: 14,
              color: "rgba(255,255,255,0.65)",
              lineHeight: 1.7,
              marginBottom: 0,
            }}
          >
            Out of 24 hours,{" "}
            <strong style={{ color: "white" }}>{(24 - freeTime).toFixed(1)}h</strong> are already
            spoken for. That leaves{" "}
            <strong style={{ color: "#2dd4bf" }}>{freeTime.toFixed(1)} hours</strong>. Every choice
            you make about this time is a real choice.
          </p>
          {age < 18 && (
            <p
              style={{
                fontSize: 12,
                color: "rgba(255,255,255,0.7)",
                lineHeight: 1.6,
                marginTop: 10,
                marginBottom: 0,
                fontStyle: "italic",
              }}
            >
              If organized activities fill your week right now — sports, clubs, lessons — your
              actual days feel tighter. This number is your horizon: where you're headed as your
              schedule opens up.
            </p>
          )}
        </div>

        {/* ── Research opt-out (privacy transparency) ── */}
        <div
          onClick={() => setResearchOptIn((v) => !v)}
          style={{
            display: "flex",
            alignItems: "flex-start",
            gap: 10,
            padding: "12px 14px",
            background: C.surfaceAlt,
            borderRadius: 10,
            border: `1px solid ${C.border}`,
            cursor: "pointer",
            userSelect: "none",
            marginTop: 10,
          }}
        >
          <div
            style={{
              width: 18,
              height: 18,
              borderRadius: 4,
              border: `2px solid ${researchOptIn ? C.mid : C.faint}`,
              background: researchOptIn ? C.mid : "transparent",
              flexShrink: 0,
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
              marginTop: 1,
            }}
          >
            {researchOptIn && (
              <span style={{ color: "white", fontSize: 11, fontWeight: 700, lineHeight: 1 }}>
                ✓
              </span>
            )}
          </div>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 13, fontWeight: 600, color: C.dark, marginBottom: 2 }}>
              Share anonymous stats to help research
            </div>
            <div style={{ fontSize: 11, color: C.muted, lineHeight: 1.55 }}>
              We send aggregate numbers (age bracket, obligation hours, screen stats) — never your
              name, email, or anything that identifies you. Uncheck to keep everything local.
            </div>
          </div>
        </div>
      </div>
    );
  };

  // ── Invest Your Time (Step 3) ──────────────────────────────────────────────
  const InvestYourTime = () => {
    const FREQ_OPTS = [1, 2, 3, 4, 5, 6, 7];
    const MINS_OPTS = [10, 15, 20, 30, 45, 60, 90, 120, 180, 240];
    const usedH = actH + totalIdeal;
    const unclaimed = Math.max(0, freeTime - usedH);
    return (
      <div>
        <div style={{ marginBottom: 16 }}>
          <div
            style={{
              fontSize: 11,
              fontWeight: 700,
              letterSpacing: "0.12em",
              textTransform: "uppercase",
              color: C.royal,
              marginBottom: 4,
            }}
          >
            Step 2 of 9
          </div>
          <h2
            style={{
              ...sr,
              color: C.dark,
              fontSize: 22,
              marginBottom: 4,
              fontWeight: 700,
              lineHeight: 1.2,
            }}
          >
            Invest Your Time
          </h2>
          <div style={{ fontSize: 14, color: C.muted, lineHeight: 1.5 }}>
            Choose what should have a place in your life — before screens enter the picture.
          </div>
        </div>
        {/* Outer tinted container — gives white cards inside visual pop */}
        <div
          style={{
            background: "#e8eaee",
            borderRadius: 16,
            padding: "16px 14px",
            border: `1px solid ${C.border}`,
          }}
        >
          <div
            style={{
              ...dCard(),
              display: "flex",
              justifyContent: "space-between",
              alignItems: "center",
              marginBottom: 14,
              flexWrap: "wrap",
              gap: 10,
            }}
          >
            <div>
              <div style={{ ...lbl12, color: "rgba(255,255,255,0.7)" }}>Your weekday free time</div>
              <div style={{ ...sr, fontSize: 28, fontWeight: 700, color: "#2dd4bf" }}>
                {fmt(freeTime)}
                <span style={{ fontSize: 14, color: "rgba(255,255,255,0.8)", marginLeft: 6 }}>per day</span>
              </div>
            </div>
            <div
              style={{
                fontSize: 13,
                color: "rgba(255,255,255,0.75)",
                maxWidth: 220,
                lineHeight: 1.5,
              }}
            >
              Plan your activities around a typical weekday. We'll scale your weekends
              automatically.
            </div>
          </div>

          {/* ══════ PART 1: REAL-WORLD ACTIVITIES ══════ */}
          <div
            style={{
              background: C.surface,
              border: `1px solid ${C.border}`,
              borderRadius: 14,
              padding: 18,
              marginBottom: 0,
            }}
          >
            {/* INTERESTS */}
            <div
              style={{
                background: C.dark,
                borderRadius: 14,
                padding: "24px 22px",
                marginBottom: 14,
              }}
            >
              <div
                style={{
                  ...sr,
                  fontSize: "clamp(22px,5vw,28px)",
                  fontWeight: 700,
                  color: "white",
                  marginBottom: 10,
                  lineHeight: 1.2,
                }}
              >
                {age < 13
                  ? "Dream big. What would your ideal week look like?"
                  : age < 18
                    ? "Design your ideal week. What makes it into the picture?"
                    : "Design your ideal week from scratch."}
              </div>
              <div style={{ fontSize: 15, color: "rgba(255,255,255,0.85)", lineHeight: 1.7 }}>
                {age < 13 ? (
                  <>
                    Forget your current schedule for a minute. If you could fill your free time with
                    anything — sports, creative stuff, time with people, being outside — what would
                    you pick? Tap everything that interests you. You won't do all of these every
                    day, but this is your wish list.
                  </>
                ) : age < 18 ? (
                  <>
                    This is your wish list — not your calendar. Tap everything you'd want in your
                    ideal week if time and scheduling weren't an issue. You won't do all of these
                    every day. We'll figure out realistic daily time in a moment.
                  </>
                ) : (
                  <>
                    Tap everything you'd want in your ideal week — hobbies, people, movement, rest,
                    learning. Go big. This isn't your schedule, it's your wish list. We'll work out
                    daily time next.
                  </>
                )}
              </div>
              {isParent && age < 13 && (
                <div
                  style={{
                    marginTop: 10,
                    fontSize: 13,
                    color: "rgba(255,255,255,0.75)",
                    lineHeight: 1.6,
                  }}
                >
                  Parents: this is a great conversation to have together. What does your child love
                  that deserves protected time?
                </div>
              )}
            </div>
            <div style={{ fontSize: 12, color: C.muted, marginBottom: 10, lineHeight: 1.55 }}>
              Tap the 📱 icon next to any activity that uses a device — we'll count it as purposeful
              screen time, not passive scrolling.
            </div>

            {/* ── Current organized activities (kids/teens get this, adults optional) ── */}
            {age < 22 && (
              <div
                style={{
                  marginBottom: 10,
                  borderRadius: 12,
                  border: `1px solid ${C.amber}40`,
                  overflow: "hidden",
                }}
              >
                <button
                  onClick={() => setExpandedCat(expandedCat === "organized" ? null : "organized")}
                  style={{
                    width: "100%",
                    display: "flex",
                    alignItems: "center",
                    gap: 10,
                    padding: "12px 14px",
                    background: expandedCat === "organized" ? `${C.amber}08` : C.surface,
                    border: "none",
                    cursor: "pointer",
                    textAlign: "left",
                  }}
                >
                  <span
                    style={{
                      width: 10,
                      height: 10,
                      borderRadius: "50%",
                      background: C.amber,
                      flexShrink: 0,
                    }}
                  />
                  <span style={{ flex: 1, fontSize: 14, fontWeight: 600, color: C.dark }}>
                    Current Organized Activities
                  </span>
                  <span style={{ fontSize: 12, color: C.faint }}>
                    {age < 18 ? "Sports teams, lessons, clubs" : "Leagues, classes, memberships"}
                  </span>
                  <span
                    style={{
                      fontSize: 16,
                      color: C.faint,
                      transition: "transform 0.15s",
                      transform: expandedCat === "organized" ? "rotate(180deg)" : "rotate(0deg)",
                    }}
                  >
                    ▾
                  </span>
                </button>
                {expandedCat === "organized" && (
                  <div style={{ padding: "10px 14px 14px" }}>
                    <div
                      style={{ fontSize: 13, color: C.muted, lineHeight: 1.6, marginBottom: 10 }}
                    >
                      {age < 18
                        ? "These are the activities someone else schedules for you — team practices, music lessons, tutoring, church groups. They matter now, but they'll change as you grow. We capture them here so your time picture is complete."
                        : "Recurring commitments with a set schedule — gym memberships, sports leagues, classes. These are already spoken for in your week."}
                    </div>
                    <div style={{ display: "flex", flexWrap: "wrap", gap: 5 }}>
                      {(age < 18
                        ? [
                            "Soccer / Football",
                            "Basketball",
                            "Baseball / Softball",
                            "Swim Team",
                            "Track / Cross Country",
                            "Dance Class",
                            "Gymnastics Class",
                            "Music Lessons",
                            "Theater / Drama",
                            "Martial Arts Class",
                            "Tutoring",
                            "Church / Youth Group",
                            "Scouts",
                            "Coding / Robotics Club",
                          ]
                        : [
                            "Gym Membership",
                            "Sports League",
                            "Fitness Classes",
                            "Music Lessons",
                            "Art Classes",
                            "Dance Classes",
                            "Religious Community",
                          ]
                      ).map((item) => {
                        const k = "org_" + item.toLowerCase().replace(/[^a-z]/g, "_");
                        const on = interests.includes(k);
                        return (
                          <button
                            key={k}
                            onClick={() =>
                              setInterests((prev) =>
                                on ? prev.filter((x) => x !== k) : [...prev, k]
                              )
                            }
                            style={{
                              padding: "6px 12px",
                              borderRadius: 20,
                              border: `1px solid ${on ? C.amber : C.border}`,
                              background: on ? C.amber : "transparent",
                              color: on ? "white" : C.dark,
                              fontSize: 13,
                              cursor: "pointer",
                              fontWeight: on ? 600 : 400,
                            }}
                          >
                            {item}
                          </button>
                        );
                      })}
                      {/* + Other write-in */}
                      {otherOpen["organized"] ? (
                        <div
                          style={{
                            display: "inline-flex",
                            alignItems: "center",
                            gap: 5,
                            borderRadius: 20,
                            border: `1px solid ${C.amber}`,
                            padding: "3px 6px 3px 12px",
                            background: "white",
                          }}
                        >
                          <input
                            autoFocus
                            placeholder="Add activity…"
                            value={otherVal["organized"] || ""}
                            onChange={(e) =>
                              setOtherVal((v) => ({ ...v, organized: e.target.value }))
                            }
                            onKeyDown={(e) => {
                              if (e.key === "Enter") {
                                const val = (otherVal["organized"] || "").trim();
                                if (val) {
                                  const k =
                                    "org_custom_" +
                                    val
                                      .toLowerCase()
                                      .replace(/\s+/g, "_")
                                      .replace(/[^a-z0-9_]/g, "");
                                  setInterests((prev) => (prev.includes(k) ? prev : [...prev, k]));
                                  setCustomLabels((prev) => ({ ...prev, [k]: val }));
                                  setOtherVal((v) => ({ ...v, organized: "" }));
                                  setOtherOpen((v) => ({ ...v, organized: false }));
                                }
                              }
                              if (e.key === "Escape")
                                setOtherOpen((v) => ({ ...v, organized: false }));
                            }}
                            style={{
                              border: "none",
                              outline: "none",
                              fontSize: 13,
                              color: C.dark,
                              background: "transparent",
                              width: 140,
                              padding: 0,
                            }}
                          />
                          <button
                            onClick={() => {
                              const val = (otherVal["organized"] || "").trim();
                              if (val) {
                                const k =
                                  "org_custom_" +
                                  val
                                    .toLowerCase()
                                    .replace(/\s+/g, "_")
                                    .replace(/[^a-z0-9_]/g, "");
                                setInterests((prev) => (prev.includes(k) ? prev : [...prev, k]));
                                setCustomLabels((prev) => ({ ...prev, [k]: val }));
                                setOtherVal((v) => ({ ...v, organized: "" }));
                                setOtherOpen((v) => ({ ...v, organized: false }));
                              }
                            }}
                            style={{
                              background: C.amber,
                              border: "none",
                              borderRadius: 14,
                              padding: "3px 10px",
                              fontSize: 12,
                              color: "white",
                              fontWeight: 700,
                              cursor: "pointer",
                            }}
                          >
                            Add
                          </button>
                          <button
                            onClick={() => setOtherOpen((v) => ({ ...v, organized: false }))}
                            style={{
                              background: "none",
                              border: "none",
                              fontSize: 13,
                              color: C.faint,
                              cursor: "pointer",
                              padding: "0 4px",
                            }}
                          >
                            ✕
                          </button>
                        </div>
                      ) : (
                        <button
                          onClick={() => setOtherOpen((v) => ({ ...v, organized: true }))}
                          style={{
                            padding: "6px 12px",
                            borderRadius: 20,
                            border: `1px dashed ${C.border}`,
                            background: "transparent",
                            color: C.muted,
                            fontSize: 12,
                            cursor: "pointer",
                          }}
                        >
                          + Other…
                        </button>
                      )}
                      {/* Show custom organized items */}
                      {interests
                        .filter((k) => k.startsWith("org_custom_"))
                        .map((k) => {
                          const label =
                            customLabels[k] || k.replace("org_custom_", "").replace(/_/g, " ");
                          return (
                            <div
                              key={k}
                              style={{
                                display: "inline-flex",
                                alignItems: "center",
                                borderRadius: 20,
                                border: `1px solid ${C.amber}`,
                                background: C.amber,
                                overflow: "hidden",
                              }}
                            >
                              <span
                                style={{
                                  padding: "6px 12px",
                                  color: "white",
                                  fontSize: 13,
                                  fontWeight: 600,
                                }}
                              >
                                {label}
                              </span>
                              <button
                                onClick={() => setInterests((prev) => prev.filter((x) => x !== k))}
                                style={{
                                  padding: "5px 9px 5px 4px",
                                  background: "transparent",
                                  border: "none",
                                  cursor: "pointer",
                                  fontSize: 11,
                                  color: "rgba(255,255,255,0.7)",
                                  borderLeft: "1px solid rgba(255,255,255,0.3)",
                                }}
                              >
                                ✕
                              </button>
                            </div>
                          );
                        })}
                    </div>
                  </div>
                )}
              </div>
            )}

            {/* Accordion interests UI — collapsed by default, expand one at a time */}
            {(() => {
              const modeInterests = getInterestsForAge(age);
              const addCustom = (cat, col) => {
                const val = (otherVal[cat] || "").trim();
                if (!val) return;
                const k =
                  "custom_" +
                  cat +
                  "_" +
                  val
                    .toLowerCase()
                    .replace(/\s+/g, "_")
                    .replace(/[^a-z0-9_]/g, "");
                setInterests((prev) => (prev.includes(k) ? prev : [...prev, k]));
                setCustomLabels((prev) => ({ ...prev, [k]: val }));
                setOtherVal((v) => ({ ...v, [cat]: "" }));
                setOtherOpen((v) => ({ ...v, [cat]: false }));
              };
              // Helper: get selected items for a category (including custom)
              const getSelectedForCat = (cat, items) => {
                const selected = items.filter((item) =>
                  interests.includes(item.toLowerCase().replace(/[^a-z]/g, "_"))
                );
                const custom = interests
                  .filter((k) => k.startsWith("custom_" + cat + "_"))
                  .map(
                    (k) =>
                      customLabels[k] || k.replace("custom_" + cat + "_", "").replace(/_/g, " ")
                  );
                return [...selected, ...custom];
              };
              return Object.entries(modeInterests).map(([cat, { label, col, items }]) => {
                const isOpen = expandedCat === cat;
                const selectedItems = getSelectedForCat(cat, items);
                const selectedCount = selectedItems.length;
                return (
                  <div
                    key={cat}
                    style={{
                      marginBottom: 6,
                      borderRadius: 12,
                      border: `1px solid ${isOpen ? col : C.border}`,
                      overflow: "hidden",
                      transition: "all 0.15s",
                    }}
                  >
                    {/* Accordion header — always visible */}
                    <button
                      onClick={() => setExpandedCat(isOpen ? null : cat)}
                      style={{
                        width: "100%",
                        display: "flex",
                        alignItems: "center",
                        gap: 10,
                        padding: "12px 14px",
                        background: isOpen ? `${col}08` : C.surface,
                        border: "none",
                        cursor: "pointer",
                        textAlign: "left",
                      }}
                    >
                      <span
                        style={{
                          width: 10,
                          height: 10,
                          borderRadius: "50%",
                          background: col,
                          flexShrink: 0,
                        }}
                      />
                      <span style={{ flex: 1, fontSize: 14, fontWeight: 600, color: C.dark }}>
                        {label}
                      </span>
                      {selectedCount > 0 && !isOpen && (
                        <span
                          style={{
                            fontSize: 12,
                            color: col,
                            fontWeight: 700,
                            background: `${col}15`,
                            borderRadius: 12,
                            padding: "2px 8px",
                          }}
                        >
                          {selectedCount}
                        </span>
                      )}
                      <span
                        style={{
                          fontSize: 16,
                          color: C.faint,
                          transition: "transform 0.15s",
                          transform: isOpen ? "rotate(180deg)" : "rotate(0deg)",
                        }}
                      >
                        ▾
                      </span>
                    </button>

                    {/* Selected chips — visible when collapsed and items are selected */}
                    {!isOpen && selectedCount > 0 && (
                      <div
                        style={{
                          display: "flex",
                          flexWrap: "wrap",
                          gap: 4,
                          padding: "0 14px 10px",
                        }}
                      >
                        {selectedItems.map((item, idx) => (
                          <span
                            key={idx}
                            style={{
                              padding: "3px 10px",
                              borderRadius: 16,
                              background: col,
                              color: "white",
                              fontSize: 11,
                              fontWeight: 600,
                            }}
                          >
                            {item}
                          </span>
                        ))}
                      </div>
                    )}

                    {/* Expanded content — items grid */}
                    {isOpen && (
                      <div style={{ padding: "6px 14px 14px" }}>
                        <div
                          style={{
                            display: "flex",
                            flexWrap: "wrap",
                            gap: 5,
                            alignItems: "center",
                          }}
                        >
                          {items.map((item) => {
                            const k = item.toLowerCase().replace(/[^a-z]/g, "_");
                            const on = interests.includes(k),
                              hasDev = deviceInterests.includes(k);
                            return (
                              <div
                                key={k}
                                style={{
                                  display: "inline-flex",
                                  alignItems: "stretch",
                                  borderRadius: 20,
                                  border: `1px solid ${on ? col : C.border}`,
                                  background: on ? col : "transparent",
                                  overflow: "hidden",
                                }}
                              >
                                <button
                                  onClick={() =>
                                    setInterests((prev) =>
                                      on ? prev.filter((x) => x !== k) : [...prev, k]
                                    )
                                  }
                                  style={{
                                    padding: "6px 12px",
                                    background: "transparent",
                                    border: "none",
                                    color: on ? "white" : C.dark,
                                    fontSize: 13,
                                    cursor: "pointer",
                                    lineHeight: 1.4,
                                    fontWeight: on ? 600 : 400,
                                  }}
                                >
                                  {item}
                                </button>
                                {on && (
                                  <button
                                    onClick={() =>
                                      setDeviceInterests((prev) =>
                                        hasDev ? prev.filter((x) => x !== k) : [...prev, k]
                                      )
                                    }
                                    title="Uses a device?"
                                    style={{
                                      padding: "5px 9px 5px 6px",
                                      background: "transparent",
                                      border: "none",
                                      cursor: "pointer",
                                      fontSize: 13,
                                      lineHeight: 1,
                                      borderLeft: `1px solid ${hasDev ? "rgba(255,255,255,0.4)" : "rgba(255,255,255,0.2)"}`,
                                      opacity: hasDev ? 1 : 0.5,
                                    }}
                                  >
                                    📱
                                  </button>
                                )}
                              </div>
                            );
                          })}
                          {/* Custom items */}
                          {interests
                            .filter((k) => k.startsWith("custom_" + cat + "_"))
                            .map((k) => {
                              const displayLabel =
                                customLabels[k] ||
                                k.replace("custom_" + cat + "_", "").replace(/_/g, " ");
                              const hasDev = deviceInterests.includes(k);
                              return (
                                <div
                                  key={k}
                                  style={{
                                    display: "inline-flex",
                                    alignItems: "stretch",
                                    borderRadius: 20,
                                    border: `1px solid ${col}`,
                                    background: col,
                                    overflow: "hidden",
                                  }}
                                >
                                  <span
                                    style={{
                                      padding: "6px 12px",
                                      color: "white",
                                      fontSize: 13,
                                      lineHeight: 1.4,
                                      fontWeight: 600,
                                    }}
                                  >
                                    {displayLabel}
                                  </span>
                                  <button
                                    onClick={() => {
                                      setInterests((prev) => prev.filter((x) => x !== k));
                                      setDeviceInterests((prev) => prev.filter((x) => x !== k));
                                    }}
                                    style={{
                                      padding: "5px 9px 5px 4px",
                                      background: "transparent",
                                      border: "none",
                                      cursor: "pointer",
                                      fontSize: 11,
                                      color: "rgba(255,255,255,0.7)",
                                      lineHeight: 1,
                                      borderLeft: "1px solid rgba(255,255,255,0.3)",
                                    }}
                                  >
                                    ✕
                                  </button>
                                  <button
                                    onClick={() =>
                                      setDeviceInterests((prev) =>
                                        hasDev ? prev.filter((x) => x !== k) : [...prev, k]
                                      )
                                    }
                                    title="Uses a device?"
                                    style={{
                                      padding: "5px 9px 5px 6px",
                                      background: "transparent",
                                      border: "none",
                                      cursor: "pointer",
                                      fontSize: 13,
                                      lineHeight: 1,
                                      borderLeft: "1px solid rgba(255,255,255,0.2)",
                                      opacity: hasDev ? 1 : 0.5,
                                    }}
                                  >
                                    📱
                                  </button>
                                </div>
                              );
                            })}
                          {/* + Other */}
                          {otherOpen[cat] ? (
                            <div
                              style={{
                                display: "inline-flex",
                                alignItems: "center",
                                gap: 5,
                                borderRadius: 20,
                                border: `1px solid ${col}`,
                                padding: "3px 6px 3px 12px",
                                background: "white",
                              }}
                            >
                              <input
                                autoFocus
                                placeholder={`Add ${label.toLowerCase()} activity…`}
                                value={otherVal[cat] || ""}
                                onChange={(e) =>
                                  setOtherVal((v) => ({ ...v, [cat]: e.target.value }))
                                }
                                onKeyDown={(e) => {
                                  if (e.key === "Enter") addCustom(cat, col);
                                  if (e.key === "Escape")
                                    setOtherOpen((v) => ({ ...v, [cat]: false }));
                                }}
                                style={{
                                  border: "none",
                                  outline: "none",
                                  fontSize: 13,
                                  color: C.dark,
                                  background: "transparent",
                                  width: 160,
                                  padding: 0,
                                }}
                              />
                              <button
                                onClick={() => addCustom(cat, col)}
                                style={{
                                  background: col,
                                  border: "none",
                                  borderRadius: 14,
                                  padding: "3px 10px",
                                  fontSize: 12,
                                  color: "white",
                                  fontWeight: 700,
                                  cursor: "pointer",
                                }}
                              >
                                Add
                              </button>
                              <button
                                onClick={() => setOtherOpen((v) => ({ ...v, [cat]: false }))}
                                style={{
                                  background: "none",
                                  border: "none",
                                  fontSize: 13,
                                  color: C.faint,
                                  cursor: "pointer",
                                  padding: "0 4px",
                                }}
                              >
                                ✕
                              </button>
                            </div>
                          ) : (
                            <button
                              onClick={() => setOtherOpen((v) => ({ ...v, [cat]: true }))}
                              style={{
                                padding: "6px 12px",
                                borderRadius: 20,
                                border: `1px dashed ${C.border}`,
                                background: "transparent",
                                color: C.muted,
                                fontSize: 12,
                                cursor: "pointer",
                              }}
                            >
                              + Other…
                            </button>
                          )}
                        </div>
                      </div>
                    )}
                  </div>
                );
              });
            })()}

            {/* Daily average — bold CTA */}
            <div style={card}>
              {interests.length > 0 ? (
                <div
                  style={{
                    background: C.dark,
                    borderRadius: 10,
                    padding: "14px 16px",
                    marginBottom: 14,
                  }}
                >
                  <div
                    style={{
                      ...sr,
                      fontSize: 15,
                      fontWeight: 700,
                      color: "white",
                      marginBottom: 6,
                      lineHeight: 1.3,
                    }}
                  >
                    To bring these activities into your life:
                  </div>
                  <div style={{ fontSize: 14, color: "rgba(255,255,255,0.85)", lineHeight: 1.65 }}>
                    Investing about{" "}
                    <strong style={{ color: C.tealBright }}>{suggestedActH}h/day</strong> (including
                    prep &amp; travel) would make it possible. That's a weekly average — you won't
                    do everything every day. Adjust the slider below for what you want to commit.
                  </div>
                </div>
              ) : (
                <div>
                  <div
                    style={{ ...sr, fontSize: 15, color: C.dark, fontWeight: 700, marginBottom: 4 }}
                  >
                    How much daily time do you want for real-world activities?
                  </div>
                  <div style={{ fontSize: 13, color: C.muted, marginBottom: 8, lineHeight: 1.55 }}>
                    Select some activities above first, or set your own number below.
                  </div>
                </div>
              )}
              <div
                style={{
                  display: "flex",
                  justifyContent: "space-between",
                  alignItems: "baseline",
                  marginBottom: 6,
                }}
              >
                <span style={{ fontSize: 14, color: C.muted }}>Daily time for activities</span>
                <span style={{ ...sr, fontSize: 30, color: C.mid, fontWeight: 700 }}>{actH}h</span>
              </div>
              <SmoothSlider
                min={0}
                max={8}
                step={0.25}
                value={actH}
                onChange={(v) => setActH(v)}
                style={{ ...sl, marginBottom: 3 }}
                ariaLabel="Hours per day for activities and interests"
                ariaValueText={`${fmt(actH)} per day`}
              />
              <div
                style={{
                  display: "flex",
                  justifyContent: "space-between",
                  fontSize: 11,
                  color: C.faint,
                }}
              >
                <span>0h</span>
                <span>2h</span>
                <span>4h</span>
                <span>6h</span>
                <span>8h</span>
              </div>
              {interests.length > 0 && Math.abs(suggestedActH - actH) >= 0.25 && (
                <button
                  onClick={() =>
                    setActH(parseFloat(Math.min(avgFreeTime, suggestedActH).toFixed(2)))
                  }
                  style={{
                    marginTop: 8,
                    background: C.mid,
                    border: "none",
                    borderRadius: 8,
                    padding: "8px 16px",
                    fontSize: 13,
                    color: "white",
                    cursor: "pointer",
                    fontWeight: 600,
                    width: "100%",
                  }}
                >
                  Reset to suggested {suggestedActH}h/day
                </button>
              )}
              {deviceInterests.some((k) => interests.includes(k)) && (
                <div
                  style={{
                    marginTop: 10,
                    fontSize: 12,
                    color: C.muted,
                    background: C.tealFaint,
                    borderRadius: 8,
                    padding: "8px 12px",
                  }}
                >
                  Device-flagged activities appear as{" "}
                  <strong style={{ color: C.mid }}>purposeful screen time</strong> in your Reveal —
                  not double-counted against your screen budget.
                </div>
              )}
            </div>

            {/* ── Hours claimed / hours left divider ── */}
            {actH > 0 && (
              <div
                style={{
                  background: C.dark,
                  borderRadius: 12,
                  padding: "16px 18px",
                  marginBottom: 10,
                  marginTop: 6,
                }}
              >
                <div
                  style={{
                    display: "flex",
                    justifyContent: "space-between",
                    alignItems: "center",
                    marginBottom: 10,
                  }}
                >
                  <div>
                    <div
                      style={{
                        fontSize: 11,
                        fontWeight: 700,
                        letterSpacing: "0.1em",
                        textTransform: "uppercase",
                        color: "rgba(255,255,255,0.7)",
                      }}
                    >
                      Claimed for real life
                    </div>
                    <div style={{ ...sr, fontSize: 28, fontWeight: 700, color: "#2dd4bf" }}>
                      {fmt(actH)}
                    </div>
                  </div>
                  <div style={{ width: 1, height: 40, background: "rgba(255,255,255,0.15)" }} />
                  <div style={{ textAlign: "right" }}>
                    <div
                      style={{
                        fontSize: 11,
                        fontWeight: 700,
                        letterSpacing: "0.1em",
                        textTransform: "uppercase",
                        color: "rgba(255,255,255,0.7)",
                      }}
                    >
                      Hours left
                    </div>
                    <div
                      style={{
                        ...sr,
                        fontSize: 28,
                        fontWeight: 700,
                        color:
                          Math.max(0, freeTime - actH) < 1 ? "#facc15" : "rgba(255,255,255,0.7)",
                      }}
                    >
                      {fmt(Math.max(0, freeTime - actH))}
                    </div>
                  </div>
                </div>
                <div
                  style={{
                    background: "rgba(255,255,255,0.08)",
                    borderRadius: 6,
                    height: 8,
                    overflow: "hidden",
                  }}
                >
                  <div
                    style={{
                      width: `${Math.min(100, (actH / Math.max(freeTime, 0.1)) * 100)}%`,
                      height: "100%",
                      background: "#2dd4bf",
                      borderRadius: 6,
                    }}
                  />
                </div>
                <div
                  style={{
                    fontSize: 12,
                    color: "rgba(255,255,255,0.7)",
                    marginTop: 8,
                    lineHeight: 1.55,
                  }}
                >
                  You've claimed <strong style={{ color: "#2dd4bf" }}>{fmt(actH)}</strong> for
                  activities. You have{" "}
                  <strong style={{ color: "rgba(255,255,255,0.7)" }}>
                    {fmt(Math.max(0, freeTime - actH))}
                  </strong>{" "}
                  of free time left — how much goes to screens?
                </div>
              </div>
            )}
          </div>
          {/* end Part 1 white card */}

          {/* ══════ VISUAL BREAK ══════ */}
          <div style={{ margin: "28px 0 20px", textAlign: "center" }}>
            <div style={{ display: "flex", alignItems: "center", gap: 14, marginBottom: 12 }}>
              <div style={{ flex: 1, height: 2, background: C.border }} />
              <div
                style={{
                  width: 8,
                  height: 8,
                  borderRadius: "50%",
                  background: C.mid,
                  flexShrink: 0,
                }}
              />
              <div style={{ flex: 1, height: 2, background: C.border }} />
            </div>
            <div
              style={{
                fontSize: 12,
                fontWeight: 700,
                letterSpacing: "0.12em",
                textTransform: "uppercase",
                color: C.mid,
              }}
            >
              Now for screens
            </div>
          </div>

          {/* ══════ PART 2: SCREEN TIME ══════ */}
          <div
            style={{
              background: C.surface,
              border: `1px solid ${C.border}`,
              borderRadius: 14,
              padding: 18,
              marginBottom: 10,
            }}
          >
            <div
              style={{
                background: C.dark,
                borderRadius: 14,
                padding: "24px 22px",
                marginBottom: 16,
              }}
            >
              <div
                style={{
                  ...sr,
                  fontSize: "clamp(22px,5vw,28px)",
                  fontWeight: 700,
                  color: "white",
                  marginBottom: 10,
                  lineHeight: 1.2,
                }}
              >
                Now design your ideal screen time.
              </div>
              <div
                style={{
                  background: "rgba(255,255,255,0.08)",
                  borderRadius: 10,
                  padding: "12px 14px",
                  marginBottom: 12,
                  display: "flex",
                  justifyContent: "space-between",
                  alignItems: "center",
                }}
              >
                <span style={{ fontSize: 14, color: "rgba(255,255,255,0.85)" }}>
                  Based on your obligations and activities, you have
                </span>
                <span style={{ ...sr, fontSize: 24, fontWeight: 700, color: C.tealBright }}>
                  {fmt(Math.max(0, freeTime - actH))}
                </span>
              </div>
              <div
                style={{
                  fontSize: 12,
                  color: "rgba(255,255,255,0.7)",
                  marginBottom: 10,
                  textAlign: "center",
                }}
              >
                left in your day. How much of that goes to screens — on purpose?
              </div>
              <div style={{ fontSize: 15, color: "rgba(255,255,255,0.85)", lineHeight: 1.75 }}>
                If you could start over — no habits, no defaults — how would you actually want to
                spend your screen time? Be honest. Some screen time is genuinely good. This isn't
                about restriction, it's about intention.
              </div>
            </div>
            <div style={{ ...sr, fontSize: 16, fontWeight: 700, color: C.dark, marginBottom: 6 }}>
              Which types of screen time should have a place in your week?
            </div>
            <div style={{ fontSize: 13, color: C.muted, marginBottom: 14, lineHeight: 1.6 }}>
              Tap a row to select it, then set how often and for how long. Only include what
              genuinely matters to you.
            </div>

            {/* Card-row selector — each type is a full-width tappable row */}
            <div style={{ display: "flex", flexDirection: "column", gap: 6, marginBottom: 8 }}>
              {SCREEN_TYPES.filter((si) => !(age < 13 && si.k === "news")).map((si) => {
                const on = screenChecked.includes(si.k);
                const sess = screenSessions[si.k];
                const dailyAvg = (sess.freq * sess.mins) / 7 / 60;
                return (
                  <div
                    key={si.k}
                    style={{
                      borderRadius: 12,
                      overflow: "hidden",
                      border: `1.5px solid ${on ? si.col : C.border}`,
                      transition: "all 0.15s",
                    }}
                  >
                    {/* ── Row header — always visible, always tappable ── */}
                    <button
                      onClick={() =>
                        setScreenChecked((prev) =>
                          on ? prev.filter((x) => x !== si.k) : [...prev, si.k]
                        )
                      }
                      style={{
                        width: "100%",
                        display: "flex",
                        alignItems: "center",
                        gap: 12,
                        padding: "12px 14px",
                        background: on ? si.col + "18" : "white",
                        border: "none",
                        cursor: "pointer",
                        textAlign: "left",
                      }}
                    >
                      {/* Color swatch / checkbox */}
                      <div
                        style={{
                          width: 22,
                          height: 22,
                          borderRadius: 6,
                          border: `2px solid ${on ? si.col : C.border}`,
                          background: on ? si.col : "transparent",
                          display: "flex",
                          alignItems: "center",
                          justifyContent: "center",
                          flexShrink: 0,
                          transition: "all 0.15s",
                        }}
                      >
                        {on && (
                          <span style={{ color: "white", fontSize: 14, lineHeight: 1 }}>✓</span>
                        )}
                      </div>
                      {/* Label */}
                      <div style={{ flex: 1, minWidth: 0 }}>
                        <div
                          style={{
                            fontSize: 14,
                            fontWeight: on ? 700 : 500,
                            color: on ? si.col : C.dark,
                            lineHeight: 1.3,
                          }}
                        >
                          {si.label}
                        </div>
                        <div
                          style={{
                            fontSize: 11,
                            color: C.faint,
                            marginTop: 1,
                            fontStyle: "italic",
                          }}
                        >
                          {si.sub}
                        </div>
                      </div>
                      {/* Daily avg if selected, or "tap to add" cue if not */}
                      {on ? (
                        <div style={{ textAlign: "right", flexShrink: 0 }}>
                          <div style={{ ...sr, fontSize: 18, fontWeight: 700, color: si.col }}>
                            {fmt(dailyAvg)}
                          </div>
                          <div style={{ fontSize: 10, color: C.faint }}>per day</div>
                        </div>
                      ) : (
                        <div
                          style={{
                            fontSize: 12,
                            color: C.faint,
                            flexShrink: 0,
                            display: "flex",
                            alignItems: "center",
                            gap: 4,
                          }}
                        >
                          <span>Tap to add</span>
                          <span style={{ fontSize: 16, lineHeight: 1 }}>＋</span>
                        </div>
                      )}
                    </button>

                    {/* ── Expanded controls — only when selected ── */}
                    {on && (
                      <div
                        style={{
                          background: "white",
                          padding: "14px 14px 14px",
                          borderTop: `1px solid ${si.col}33`,
                        }}
                      >
                        <div style={{ marginBottom: 12 }}>
                          <div
                            style={{
                              fontSize: 12,
                              fontWeight: 600,
                              color: C.muted,
                              marginBottom: 7,
                            }}
                          >
                            How often in an ideal week?
                          </div>
                          <div style={{ display: "flex", gap: 4 }}>
                            {FREQ_OPTS.map((n) => (
                              <button
                                key={n}
                                onClick={() =>
                                  setScreenSessions((prev) => ({
                                    ...prev,
                                    [si.k]: { ...prev[si.k], freq: n },
                                  }))
                                }
                                style={{
                                  flex: 1,
                                  padding: "8px 2px",
                                  borderRadius: 8,
                                  border: `1px solid ${sess.freq === n ? si.col : C.border}`,
                                  background: sess.freq === n ? si.col : "transparent",
                                  color: sess.freq === n ? "white" : C.dark,
                                  fontSize: 11,
                                  fontWeight: 600,
                                  cursor: "pointer",
                                }}
                              >
                                {n === 7 ? "daily" : n + "×"}
                              </button>
                            ))}
                          </div>
                        </div>
                        <div>
                          <div
                            style={{
                              fontSize: 12,
                              fontWeight: 600,
                              color: C.muted,
                              marginBottom: 7,
                            }}
                          >
                            Ideal session length?
                          </div>
                          <div style={{ display: "flex", flexWrap: "wrap", gap: 4 }}>
                            {MINS_OPTS.map((m) => {
                              const lbl =
                                m < 60 ? m + "m" : (m / 60) % 1 === 0 ? m / 60 + "h" : "1.5h";
                              return (
                                <button
                                  key={m}
                                  onClick={() =>
                                    setScreenSessions((prev) => ({
                                      ...prev,
                                      [si.k]: { ...prev[si.k], mins: m },
                                    }))
                                  }
                                  style={{
                                    padding: "5px 9px",
                                    borderRadius: 8,
                                    border: `1px solid ${sess.mins === m ? si.col : C.border}`,
                                    background: sess.mins === m ? si.col : "transparent",
                                    color: sess.mins === m ? "white" : C.dark,
                                    fontSize: 12,
                                    fontWeight: 600,
                                    cursor: "pointer",
                                  }}
                                >
                                  {lbl}
                                </button>
                              );
                            })}
                          </div>
                        </div>
                      </div>
                    )}
                  </div>
                );
              })}
            </div>
            {screenChecked.length > 0 && (
              <div
                style={{
                  background: C.surfaceAlt,
                  borderRadius: 10,
                  padding: "14px 16px",
                  display: "flex",
                  justifyContent: "space-between",
                  alignItems: "center",
                  border: `1px solid ${C.border}`,
                  marginTop: 4,
                }}
              >
                <div>
                  <div style={{ fontSize: 14, color: C.dark, fontWeight: 600 }}>
                    Your ideal daily screen time
                  </div>
                  <div style={{ fontSize: 12, color: C.muted, marginTop: 2 }}>
                    This is what you'd <em>want</em> — averaged across a week
                  </div>
                </div>
                <span style={{ ...sr, fontSize: 30, color: C.amber, fontWeight: 700 }}>
                  {fmt(totalIdeal)}
                </span>
              </div>
            )}

            {/* Free time tracker — three states: over-allocated / fully invested / unclaimed */}
            {(actH > 0 || totalIdeal > 0) &&
              (() => {
                const overAllocated = usedH > freeTime + 0.1;
                const fullyInvested = !overAllocated && unclaimed <= 0.25;
                const overBy = usedH - freeTime;
                return (
                  <div
                    style={{
                      marginTop: 14,
                      borderRadius: 12,
                      overflow: "hidden",
                      border: `1px solid ${overAllocated ? "rgba(220,38,38,0.4)" : fullyInvested ? C.tealLight : "#5eead4"}`,
                    }}
                  >
                    <div
                      style={{
                        background: overAllocated
                          ? "rgba(254,242,242,1)"
                          : fullyInvested
                            ? C.tealFaint
                            : "#f0fdfa",
                        padding: "12px 16px",
                      }}
                    >
                      {/* Header row */}
                      <div
                        style={{
                          display: "flex",
                          justifyContent: "space-between",
                          alignItems: "center",
                          marginBottom: 8,
                        }}
                      >
                        <div
                          style={{
                            fontSize: 13,
                            fontWeight: 700,
                            color: overAllocated ? "#dc2626" : fullyInvested ? C.mid : "#0f766e",
                          }}
                        >
                          {overAllocated ? "🚨 Over budget" : ""}
                          {fullyInvested ? "✓ Free time fully invested" : ""}
                          {!overAllocated && !fullyInvested ? "⏳ Unclaimed Free Time" : ""}
                        </div>
                        <div style={{ display: "flex", alignItems: "baseline", gap: 4 }}>
                          <span
                            style={{ fontSize: 11, color: overAllocated ? "#dc2626" : C.muted }}
                          >
                            free time
                          </span>
                          <span
                            style={{
                              ...sr,
                              fontSize: 20,
                              fontWeight: 700,
                              color: overAllocated ? "#dc2626" : fullyInvested ? C.mid : C.mid,
                            }}
                          >
                            {fmt(freeTime)}
                          </span>
                        </div>
                      </div>

                      {/* Mini breakdown bars */}
                      <div
                        style={{
                          display: "grid",
                          gridTemplateColumns: "1fr 1fr " + (overAllocated ? "1fr" : "1fr"),
                          gap: 6,
                          marginBottom: 8,
                        }}
                      >
                        {[
                          { l: "Activities", v: actH, c: GC.activities },
                          { l: "Screen time", v: totalIdeal, c: GC.scrChosen },
                          overAllocated
                            ? { l: "Over by", v: overBy, c: "#dc2626" }
                            : {
                                l: fullyInvested ? "Balanced" : "Unclaimed",
                                v: fullyInvested ? 0 : unclaimed,
                                c: fullyInvested ? C.mid : "#f59e0b",
                              },
                        ].map((x, i) => (
                          <div
                            key={i}
                            style={{
                              background: "rgba(255,255,255,0.65)",
                              borderRadius: 8,
                              padding: "8px 6px",
                              textAlign: "center",
                            }}
                          >
                            <div
                              style={{
                                width: 8,
                                height: 8,
                                borderRadius: 2,
                                background: x.c,
                                margin: "0 auto 4px",
                              }}
                            />
                            <div style={{ ...sr, fontSize: 16, fontWeight: 700, color: x.c }}>
                              {x.v > 0 ? fmt(x.v) : "—"}
                            </div>
                            <div style={{ fontSize: 10, color: C.muted }}>{x.l}</div>
                          </div>
                        ))}
                      </div>

                      {/* State-specific message */}
                      {overAllocated && (
                        <div style={{ fontSize: 12, color: "#dc2626", lineHeight: 1.65 }}>
                          You've planned <strong>{fmt(overBy)} more</strong> than your free time
                          allows. No worries — this is exactly the kind of thing defrag. is here to
                          help you see. Try reducing your activity time or screen time above, or go
                          back to Step 1 and check your non-negotiables.
                          <div
                            style={{
                              marginTop: 6,
                              fontSize: 11,
                              color: "#dc2626",
                              fontStyle: "italic",
                            }}
                          >
                            Tip: even small adjustments add up fast. Dropping one screen session or
                            trimming 30 minutes of activity time may be all it takes.
                          </div>
                        </div>
                      )}
                      {fullyInvested && (
                        <div style={{ fontSize: 12, color: C.mid, lineHeight: 1.65 }}>
                          Every hour of free time is spoken for. Your plan is intentional — that's
                          the point.
                        </div>
                      )}
                      {!overAllocated && !fullyInvested && (
                        <div style={{ fontSize: 12, color: "#0f766e", lineHeight: 1.65 }}>
                          You have <strong>{fmt(unclaimed)}</strong> of free time that isn't
                          accounted for yet.
                          {age < 13 ? (
                            <div style={{ marginTop: 6, color: "#0f766e", lineHeight: 1.65 }}>
                              That's okay — unstructured time, play, and boredom are genuinely
                              valuable. But if you want to be intentional, consider: is there an
                              activity worth protecting here? Or should some of it become part of
                              your chosen screen time?
                            </div>
                          ) : (
                            <div style={{ marginTop: 6, color: "#0f766e", lineHeight: 1.65 }}>
                              Unstructured time has real value — rest, spontaneity, and boredom all
                              belong in a life. But screens are engineered to fill unprotected gaps
                              automatically. Consider: is there an activity worth adding above, or
                              intentional screen time worth naming here?
                            </div>
                          )}
                          <div style={{ marginTop: 8, display: "flex", gap: 6, flexWrap: "wrap" }}>
                            <button
                              onClick={() =>
                                document
                                  .querySelector('[data-section="activities"]')
                                  ?.scrollIntoView({ behavior: "smooth" })
                              }
                              style={{
                                fontSize: 11,
                                padding: "5px 12px",
                                borderRadius: 20,
                                border: `1px solid ${C.mid}`,
                                background: "transparent",
                                color: "#0f766e",
                                cursor: "pointer",
                                fontWeight: 600,
                              }}
                            >
                              Add an activity ↑
                            </button>
                            <div
                              style={{
                                fontSize: 11,
                                padding: "5px 10px",
                                borderRadius: 20,
                                background: "rgba(255,255,255,0.5)",
                                color: "#0f766e",
                              }}
                            >
                              {fmt(unclaimed)} of open time
                            </div>
                          </div>
                        </div>
                      )}
                    </div>
                  </div>
                );
              })()}

            {/* Music note */}
            <div
              style={{
                marginTop: 14,
                background: C.surfaceAlt,
                borderRadius: 10,
                padding: "12px 14px",
                border: `1px solid ${C.border}`,
              }}
            >
              <div style={{ fontSize: 13, fontWeight: 600, color: C.dark, marginBottom: 4 }}>
                🎵 Music &amp; Podcasts — a note
              </div>
              <div style={{ fontSize: 12, color: C.muted, lineHeight: 1.65 }}>
                Audio-only listening overlaps so often with other activities — running, cooking,
                commuting — that we don't count it as screen time here. The 📱 flag on your
                activities captures when a device is present.
              </div>
            </div>
          </div>
          {/* end Part 2 white card */}

          {/* Engagement hook */}
          <div style={{ ...dCard(), textAlign: "center", padding: "20px 22px", marginTop: 8 }}>
            <div
              style={{ ...sr, fontSize: 17, color: "#2dd4bf", fontWeight: 700, marginBottom: 6 }}
            >
              You've designed your ideal. Now let's see where screens actually show up.
            </div>
            <div style={{ fontSize: 13, color: "rgba(255,255,255,0.75)", lineHeight: 1.6 }}>
              The next step is the honest part — your real day with screens.
            </div>
          </div>
        </div>
        {/* end outer tinted container */}
      </div>
    );
  };

  // ── Your Day With Screens (Step 3) ─────────────────────────────────────────
  const DayWithScreens = () => {
    return (
      <div>
        <div style={{ marginBottom: 16 }}>
          <div
            style={{
              fontSize: 11,
              fontWeight: 700,
              letterSpacing: "0.12em",
              textTransform: "uppercase",
              color: C.royal,
              marginBottom: 4,
            }}
          >
            Step 3 of 9
          </div>
          <h2
            style={{
              ...sr,
              color: C.dark,
              fontSize: 22,
              marginBottom: 4,
              fontWeight: 700,
              lineHeight: 1.2,
            }}
          >
            Your Real Screen Time
          </h2>
          <div style={{ fontSize: 15, color: C.dark, lineHeight: 1.6 }}>
            No judgment — just an honest look at how much of your day actually goes to screens right
            now. Not what you wish it was. What it is.
          </div>
        </div>

        {/* ── Weekday Screen Time ── */}
        <div style={{ ...dCard(), padding: 20 }}>
          <div style={{ ...lbl12, color: "rgba(255,255,255,0.7)", marginBottom: 4 }}>
            Weekday personal screen time
          </div>
          <div
            style={{
              fontSize: 13,
              color: "rgba(255,255,255,0.75)",
              marginBottom: 8,
              lineHeight: 1.5,
            }}
          >
            How much time do you deliberately spend on{" "}
            <strong style={{ color: "white" }}>personal</strong> screens on a typical weekday?
            Streaming, gaming, scrolling, calls.
          </div>
          <div
            style={{
              fontSize: 12,
              color: "rgba(255,255,255,0.85)",
              marginBottom: 14,
              lineHeight: 1.55,
              background: "rgba(255,255,255,0.08)",
              borderRadius: 8,
              padding: "10px 12px",
            }}
          >
            <div style={{ marginBottom: 6 }}>
              You already told us you're on a device for{" "}
              <strong style={{ color: C.tealBright }}>{fmt(requiredDeviceH)}</strong> of{" "}
              {age >= 18 ? "work" : "school"}
              {age < 18 && hwDeviceH > 0 ? " and homework" : ""} per day.
            </div>
            <div>
              This is the time on devices <strong style={{ color: "white" }}>beyond</strong> those
              hours — personal streaming, social media, gaming, browsing, and calls.
            </div>
          </div>
          <div
            style={{
              display: "flex",
              justifyContent: "space-between",
              alignItems: "baseline",
              marginBottom: 3,
            }}
          >
            <span style={{ fontSize: 13, color: "rgba(255,255,255,0.65)" }}>
              At home (all personal devices + TV)
            </span>
            <span style={{ ...sr, fontSize: 20, color: "#facc15", fontWeight: 700 }}>
              {fmt(sH)}
            </span>
          </div>
          <SmoothSlider
            min={0}
            max={14}
            step={0.25}
            value={sH}
            onChange={(v) => setSH(v)}
            style={{ ...sl, accentColor: "#facc15" }}
            ariaLabel="Weekday personal screen hours"
            ariaValueText={`${fmt(sH)} per weekday`}
          />
          <div style={{ display: "flex", justifyContent: "flex-end", marginTop: 6 }}>
            <button
              onClick={() => setShowFinder(true)}
              style={{
                background: "rgba(13,148,136,0.25)",
                border: "1px solid rgba(13,148,136,0.85)",
                borderRadius: 8,
                padding: "5px 12px",
                fontSize: 11,
                color: "#2dd4bf",
                cursor: "pointer",
                fontWeight: 600,
              }}
            >
              How to find this
            </button>
          </div>
        </div>

        {/* ── Weekend Screen Time — total hours, not a delta ── */}
        <div
          style={{ ...dCard("#042f2e"), padding: 20, border: "1px solid rgba(251,191,36,0.15)" }}
        >
          <div
            style={{
              ...sr,
              fontSize: 17,
              color: "white",
              fontWeight: 700,
              marginBottom: 10,
              lineHeight: 1.3,
            }}
          >
            Now think about a normal Saturday.
          </div>
          <div
            style={{
              background: "rgba(251,191,36,0.1)",
              borderRadius: 10,
              padding: "14px 16px",
              marginBottom: 14,
              border: "1px solid rgba(251,191,36,0.2)",
            }}
          >
            <div
              style={{
                display: "flex",
                justifyContent: "space-between",
                alignItems: "center",
                marginBottom: 6,
              }}
            >
              <span style={{ fontSize: 13, color: "rgba(255,255,255,0.75)" }}>
                Weekend free time (after sleep, meals, hygiene, chores)
              </span>
              <span style={{ ...sr, fontSize: 24, fontWeight: 700, color: "#facc15" }}>
                {fmt(weekendFreeTime)}
              </span>
            </div>
            <div style={{ fontSize: 13, color: "rgba(255,255,255,0.8)", lineHeight: 1.65 }}>
              Not the camping trip or the birthday party — just a regular weekend day. No{" "}
              {age >= 18 ? "work" : "school"}, no commute. You have{" "}
              <strong style={{ color: "#facc15" }}>{fmt(weekendFreeTime)}</strong> of free time. How
              do you honestly fill it? Morning scrolling, streaming, gaming, idle phone time — all
              of it.
            </div>
          </div>
          <div
            style={{
              display: "flex",
              justifyContent: "space-between",
              alignItems: "baseline",
              marginBottom: 3,
            }}
          >
            <span style={{ fontSize: 13, color: "rgba(255,255,255,0.65)" }}>
              Total screen time on Sat/Sun
              {!wkSHTouchedRef.current && (
                <span
                  style={{
                    fontSize: 11,
                    fontStyle: "italic",
                    color: "rgba(251,191,36,0.9)",
                    marginLeft: 6,
                  }}
                >
                  (drag to adjust)
                </span>
              )}
            </span>
            <span style={{ ...sr, fontSize: 24, color: "#facc15", fontWeight: 700 }}>
              {fmt(wkSH)}
            </span>
          </div>
          <SmoothSlider
            min={0}
            max={16}
            step={0.25}
            value={wkSH}
            onChange={(v) => {
              wkSHTouchedRef.current = true;
              setWkSH(v);
            }}
            style={{ ...sl, accentColor: "#facc15" }}
            ariaLabel="Weekend personal screen hours"
            ariaValueText={`${fmt(wkSH)} per weekend day`}
          />
          <div
            style={{
              display: "flex",
              justifyContent: "space-between",
              fontSize: 11,
              color: "rgba(255,255,255,0.65)",
              marginTop: 4,
            }}
          >
            <span>0h</span>
            <span>{fmt(weekendFreeTime / 2)}</span>
            <span>{fmt(weekendFreeTime)}</span>
          </div>
          {wkSH > sH + 0.5 && (
            <div
              style={{
                marginTop: 10,
                background: "rgba(255,255,255,0.06)",
                borderRadius: 8,
                padding: "10px 12px",
                display: "flex",
                justifyContent: "space-between",
                alignItems: "center",
              }}
            >
              <span style={{ fontSize: 12, color: "rgba(255,255,255,0.75)" }}>
                That's <strong style={{ color: "#facc15" }}>+{fmt(wkSH - sH)}</strong> more than
                weekdays
              </span>
              <span style={{ fontSize: 12, color: "rgba(255,255,255,0.7)" }}>
                Weekday: {fmt(sH)}
              </span>
            </div>
          )}
          <div
            style={{
              fontSize: 12,
              color: "rgba(255,255,255,0.7)",
              marginTop: 10,
              lineHeight: 1.6,
              fontStyle: "italic",
            }}
          >
            We'll average your weekday and weekend numbers for the lifetime projection:{" "}
            <strong style={{ color: "rgba(255,255,255,0.75)" }}>{fmt(avgSH)}/day</strong>
          </div>
        </div>

        {/* Personal screens during work/school — two selectable cards */}
        <div style={{ marginBottom: 8 }}>
          <div style={{ ...sr, fontSize: 14, color: C.dark, fontWeight: 700, marginBottom: 8 }}>
            Do you use screens during {age >= 18 ? "work" : "school"} for personal stuff?
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }}>
            <button
              onClick={() => setScrOverlap(false)}
              style={{
                padding: "14px 12px",
                borderRadius: 10,
                textAlign: "center",
                cursor: "pointer",
                border: `2px solid ${!scrOverlap ? C.mid : C.border}`,
                background: !scrOverlap ? `${C.mid}12` : C.surface,
              }}
            >
              <div
                style={{
                  fontSize: 14,
                  fontWeight: 700,
                  color: !scrOverlap ? C.mid : C.dark,
                  marginBottom: 3,
                }}
              >
                Not really
              </div>
              <div style={{ fontSize: 11, color: C.muted, lineHeight: 1.4 }}>
                Phone stays in pocket during {age >= 18 ? "work" : "class"}
              </div>
            </button>
            <button
              onClick={() => setScrOverlap(true)}
              style={{
                padding: "14px 12px",
                borderRadius: 10,
                textAlign: "center",
                cursor: "pointer",
                border: `2px solid ${scrOverlap ? C.amber : C.border}`,
                background: scrOverlap ? "#f0fdfa" : C.surface,
              }}
            >
              <div
                style={{
                  fontSize: 14,
                  fontWeight: 700,
                  color: scrOverlap ? C.amber : C.dark,
                  marginBottom: 3,
                }}
              >
                Yes, some overlap
              </div>
              <div style={{ fontSize: 11, color: C.muted, lineHeight: 1.4 }}>
                Checking notifications, scrolling between tasks
              </div>
            </button>
          </div>
        </div>

        {/* Simultaneous screens — two selectable cards */}
        <div style={{ marginBottom: 8 }}>
          <div style={{ ...sr, fontSize: 14, color: C.dark, fontWeight: 700, marginBottom: 8 }}>
            Do you use screens simultaneously?
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }}>
            <button
              onClick={() => setMt(false)}
              style={{
                padding: "14px 12px",
                borderRadius: 10,
                textAlign: "center",
                cursor: "pointer",
                border: `2px solid ${!mt ? C.mid : C.border}`,
                background: !mt ? `${C.mid}12` : C.surface,
              }}
            >
              <div
                style={{
                  fontSize: 14,
                  fontWeight: 700,
                  color: !mt ? C.mid : C.dark,
                  marginBottom: 3,
                }}
              >
                One at a time
              </div>
              <div style={{ fontSize: 11, color: C.muted, lineHeight: 1.4 }}>
                I focus on one screen
              </div>
            </button>
            <button
              onClick={() => setMt(true)}
              style={{
                padding: "14px 12px",
                borderRadius: 10,
                textAlign: "center",
                cursor: "pointer",
                border: `2px solid ${mt ? C.purple : C.border}`,
                background: mt ? "rgba(124,58,237,0.08)" : C.surface,
              }}
            >
              <div
                style={{
                  fontSize: 14,
                  fontWeight: 700,
                  color: mt ? C.purple : C.dark,
                  marginBottom: 3,
                }}
              >
                Yes, I stack
              </div>
              <div style={{ fontSize: 11, color: C.muted, lineHeight: 1.4 }}>
                Phone + TV, scrolling while watching
              </div>
            </button>
          </div>
        </div>

        {/* ── Compact inline summary — bright colors ── */}
        <div
          style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 6, marginBottom: 8 }}
        >
          <div
            style={{
              background: "#042f2e",
              borderRadius: 10,
              padding: "12px 8px",
              textAlign: "center",
            }}
          >
            <div style={{ ...sr, fontSize: 20, fontWeight: 700, color: "#34d399" }}>
              {fmt(requiredDeviceH)}
            </div>
            <div
              style={{
                fontSize: 10,
                fontWeight: 700,
                color: "rgba(52,211,153,0.9)",
                marginTop: 2,
                textTransform: "uppercase",
                letterSpacing: "0.08em",
              }}
            >
              Required
            </div>
          </div>
          <div
            style={{
              background: "#042f2e",
              borderRadius: 10,
              padding: "12px 8px",
              textAlign: "center",
            }}
          >
            <div style={{ ...sr, fontSize: 20, fontWeight: 700, color: "#facc15" }}>
              {fillerMinutes}m
            </div>
            <div
              style={{
                fontSize: 10,
                fontWeight: 700,
                color: "rgba(251,191,36,0.7)",
                marginTop: 2,
                textTransform: "uppercase",
                letterSpacing: "0.08em",
              }}
            >
              Filler
            </div>
          </div>
          <div
            style={{
              background: "#042f2e",
              borderRadius: 10,
              padding: "12px 8px",
              textAlign: "center",
            }}
          >
            <div style={{ ...sr, fontSize: 20, fontWeight: 700, color: "#f97316" }}>{fmt(sH)}</div>
            <div
              style={{
                fontSize: 10,
                fontWeight: 700,
                color: "#fdba74",
                marginTop: 2,
                textTransform: "uppercase",
                letterSpacing: "0.08em",
              }}
            >
              Personal
            </div>
          </div>
        </div>

        {/* ── Engagement hook ── */}
        <div
          style={{
            background: C.dark,
            borderRadius: 12,
            padding: "18px 20px",
            textAlign: "center",
          }}
        >
          <div style={{ ...sr, fontSize: 17, color: "#2dd4bf", fontWeight: 700, marginBottom: 6 }}>
            That's everything. Ready to see your number?
          </div>
          <div style={{ fontSize: 13, color: "rgba(255,255,255,0.75)", lineHeight: 1.6 }}>
            The Reveal shows what all of this means — across your day, your free time, and your
            lifetime.
          </div>
        </div>
      </div>
    );
  };

  // ── STEP 5 of 9: THE REVEAL ──────────────────────────────────────────────
  const RevealStep = () => {
    // Auto-send aggregate anonymous stats when Reveal first renders.
    // Gated on researchOptIn — the user can disable this on Step 1.
    // Payload contains NO PII: age bracket, obligation hours, screen stats only.
    React.useEffect(() => {
      if (autoCollectSent) return;
      if (!researchOptIn) return;
      setAutoCollectSent(true);
      setResearchSent(true);
      const payload = {
        ts: new Date().toISOString(),
        ageBracket: getBracket(age).label,
        obligH: parseFloat(oblig.toFixed(1)),
        freeTimeH: parseFloat(freeTime.toFixed(1)),
        avgFreeTimeH: parseFloat(avgFreeTime.toFixed(1)),
        schoolDeviceH,
        fillerMin: fillerMinutes,
        audioMin: audioMinutes,
        intentionalScrH: sH,
        weekendExtraH: wkX,
        controllableH: parseFloat(controllableH.toFixed(1)),
        protectedMin: protectedMinutes,
        isLightUser,
        totalIdealH: parseFloat(totalIdeal.toFixed(2)),
        actH: parseFloat(actH.toFixed(2)),
        interestCount: interests.length,
        screenTypeCount: screenChecked.length,
        pickups: pkp,
        calendarScrYears,
        isParent,
        pathway: isLightUser ? "A" : "B",
      };
      fetch(
        "https://script.google.com/macros/s/AKfycbyHAQ5Nc-FnK9swxdNz8CdFcY6xv6biCLaXN7IDubNzTNrSrT2oRn2foFWhXPz0xBpJ_w/exec",
        {
          method: "POST",
          headers: { "Content-Type": "text/plain;charset=utf-8" },
          body: JSON.stringify(payload),
        }
      ).catch(() => {});
    }, []);

    // Hero stat: adults see total lifetime (past+future), kids see remaining only
    const heroScreenYears = age >= 22 ? totalLifetimeScreenYears : calendarScrYears;
    const heroSubtext =
      age >= 22
        ? `across your whole life — ${pastScreenYears.toFixed(1)} already spent + ${futureScreenYears.toFixed(1)} ahead`
        : `out of your next ${yearsRem} years of life`;

    return (
      <div>
        <div style={{ marginBottom: 16 }}>
          <div
            style={{
              fontSize: 11,
              fontWeight: 700,
              letterSpacing: "0.12em",
              textTransform: "uppercase",
              color: C.royal,
              marginBottom: 4,
            }}
          >
            Step 5 of 9
          </div>
          <h2
            style={{
              ...sr,
              color: C.dark,
              fontSize: 22,
              marginBottom: 4,
              fontWeight: 700,
              lineHeight: 1.2,
            }}
          >
            The Reveal
          </h2>
          <div style={{ fontSize: 14, color: C.muted, lineHeight: 1.5 }}>
            This is your life at your current pace — and what it looks like when you choose
            differently.
          </div>
        </div>

        {/* ── BEAT 1: Hero Stats — Big Numbers First ──────────────────────── */}
        {age < 13 && (
          <div
            style={{
              background: isLightUser ? "rgba(45,212,191,0.1)" : "rgba(249,115,22,0.15)",
              borderRadius: 9,
              padding: "10px 13px",
              marginBottom: 10,
              border: isLightUser
                ? "0.5px solid rgba(45,212,191,0.3)"
                : "0.5px solid rgba(249,115,22,0.3)",
            }}
          >
            <div style={{ fontSize: 12, color: C.muted, lineHeight: 1.6 }}>
              {isLightUser ? (
                <>
                  <strong style={{ color: C.mid }}>Your numbers below are real</strong> — based on
                  what you told us. We also show the national trajectory so you can see what you're
                  protecting.
                </>
              ) : (
                <>
                  <strong style={{ color: C.amber }}>
                    For kids, we project the national trajectory.
                  </strong>{" "}
                  Screen use typically accelerates through adolescence — the national average for
                  teens reaches 8+ hours/day.
                </>
              )}
            </div>
          </div>
        )}

        {/* Gut punch: lifetime screen years — total for adults, remaining for kids */}
        <div
          style={{
            background: C.dark,
            borderRadius: 16,
            padding: "32px 24px",
            marginBottom: 10,
            textAlign: "center",
            position: "relative",
          }}
        >
          <ShowMath
            dark
            lines={[
              `Total daily screens = ${age >= 18 ? "work" : "school"} devices (${fmt(requiredDeviceH)}) + personal avg (${fmt(avgLifeSH)})`,
              `= ${fmt(requiredDeviceH + avgLifeSH)}/day (weekly avg incl. weekends)`,
              age >= 22
                ? `Past: ${pastScreenYears.toFixed(1)} yrs (computed from age ${fd} to ${age})`
                : "",
              `Future: (${fmt(requiredDeviceH + avgLifeSH)} ÷ 24) × ${yearsRem} yrs = ${calendarScrYears} yrs`,
              age >= 22
                ? `→ Total: ${pastScreenYears.toFixed(1)} + ${calendarScrYears} = ${totalLifetimeScreenYears} years`
                : `→ ${calendarScrYears} years on screens`,
            ].filter(Boolean)}
          />
          <div
            style={{
              fontSize: 11,
              fontWeight: 700,
              letterSpacing: "0.14em",
              textTransform: "uppercase",
              color: "rgba(255,255,255,0.75)",
              marginBottom: 12,
            }}
          >
            {age >= 22 ? "Your lifetime on screens" : "At your current pace"}
          </div>
          <div
            style={{
              ...sr,
              fontSize: "clamp(56px,14vw,88px)",
              fontWeight: 700,
              color: "#facc15",
              lineHeight: 0.9,
            }}
          >
            {heroScreenYears}
          </div>
          <div
            style={{
              ...sr,
              fontSize: "clamp(20px,5vw,28px)",
              fontWeight: 700,
              color: "white",
              marginTop: 8,
            }}
          >
            years on screens
          </div>
          <div style={{ fontSize: 14, color: "rgba(255,255,255,0.7)", marginTop: 12 }}>
            {heroSubtext}
          </div>
          <div style={{ fontSize: 12, color: "rgba(255,255,255,0.6)", marginTop: 8 }}>
            All screens — {age >= 18 ? "work" : "school"} devices + personal use combined
          </div>
        </div>

        {/* Three stat cards row */}
        <div
          style={{
            display: "grid",
            gridTemplateColumns: "1fr 1fr 1fr",
            gap: 8,
            marginBottom: 10,
            position: "relative",
          }}
        >
          <ShowMath
            dark
            lines={[
              `Waking hours: 24 − ${fmt(sleep)} sleep = ${fmt(24 - sleep)}h (${wakingMinutes}m)`,
              `All screens: ${fmt(requiredDeviceH + avgLifeSH)}/day`,
              `→ Waking %: ${fmt(requiredDeviceH + avgLifeSH)} ÷ ${fmt(24 - sleep)} = ${wakingPct}%`,
              "",
              `Protected brain time:`,
              `${wakingMinutes}m waking − ${schoolH * 60}m ${age >= 18 ? "work" : "school"} − ${commute * 60}m commute${caregivingMin > 0 ? ` − ${caregivingMin}m caregiving` : ""} − ${fillerMinutes}m filler − ${sH * 60}m personal screens`,
              `→ = ${protectedMinutes} min/day`,
              "",
              `Free time: ${fmt(freeTime)}/day`,
              `Controllable screens: ${fillerMinutes}m filler + ${fmt(sH)} personal = ${fmt(controllableH)}`,
              `→ ${controllableScrPct}% of free time`,
            ]}
          />
          <div
            style={{
              background: C.dark,
              borderRadius: 12,
              padding: "18px 10px",
              textAlign: "center",
            }}
          >
            <div
              style={{
                ...sr,
                fontSize: "clamp(24px,6vw,36px)",
                fontWeight: 700,
                color: "#facc15",
                lineHeight: 1,
              }}
            >
              {wakingPct}%
            </div>
            <div
              style={{
                fontSize: 11,
                color: "rgba(255,255,255,0.75)",
                marginTop: 6,
                lineHeight: 1.3,
              }}
            >
              of waking hours on a screen
            </div>
          </div>
          <div
            style={{
              background: C.dark,
              borderRadius: 12,
              padding: "18px 10px",
              textAlign: "center",
            }}
          >
            <div
              style={{
                ...sr,
                fontSize: "clamp(24px,6vw,36px)",
                fontWeight: 700,
                color: protectedMinutes > 60 ? C.tealBright : "#facc15",
                lineHeight: 1,
              }}
            >
              {protectedMinutes}
              <span style={{ fontSize: "0.4em" }}>m</span>
            </div>
            <div
              style={{
                fontSize: 11,
                color: "rgba(255,255,255,0.75)",
                marginTop: 6,
                lineHeight: 1.3,
              }}
            >
              brain time that's yours
            </div>
          </div>
          <div
            style={{
              background: C.dark,
              borderRadius: 12,
              padding: "18px 10px",
              textAlign: "center",
            }}
          >
            <div
              style={{
                ...sr,
                fontSize: "clamp(24px,6vw,36px)",
                fontWeight: 700,
                color: controllableScrPct > 50 ? "#f97316" : "#facc15",
                lineHeight: 1,
              }}
            >
              {controllableScrPct}%
            </div>
            <div
              style={{
                fontSize: 11,
                color: "rgba(255,255,255,0.75)",
                marginTop: 6,
                lineHeight: 1.3,
              }}
            >
              of free time is screens
            </div>
            <div
              style={{
                fontSize: 9,
                color: "rgba(255,255,255,0.7)",
                marginTop: 4,
                fontStyle: "italic",
              }}
            >
              averaged across weekdays and weekends
            </div>
          </div>
        </div>

        {/* ── PATHWAY A: "What You're Protecting" — light users only ──── */}
        {isLightUser && (
          <div
            style={{
              background: "linear-gradient(135deg, #042f2e 0%, #053b38 100%)",
              borderRadius: 14,
              padding: "20px 18px",
              marginBottom: 10,
              border: "1px solid rgba(45,212,191,0.25)",
            }}
          >
            <div
              style={{
                fontSize: 10,
                fontWeight: 700,
                letterSpacing: "0.1em",
                textTransform: "uppercase",
                color: "rgba(45,212,191,0.85)",
                marginBottom: 10,
              }}
            >
              Your balance
            </div>
            <div
              style={{
                ...sr,
                fontSize: 18,
                fontWeight: 700,
                color: "white",
                lineHeight: 1.3,
                marginBottom: 10,
              }}
            >
              {age < 14
                ? "You're protecting something most kids don't have."
                : age < 18
                  ? "You have something most teens don't."
                  : "You have something most people don't."}
            </div>
            <div
              style={{
                fontSize: 13,
                color: "rgba(255,255,255,0.75)",
                lineHeight: 1.7,
                marginBottom: 16,
              }}
            >
              {age < 18 ? (
                <>
                  Your brain gets{" "}
                  <strong style={{ color: C.tealBright }}>{protectedMinutes} minutes</strong> per
                  day that belong entirely to you — no school, no screens, no one else's content.
                  Only <strong style={{ color: C.tealBright }}>{controllableScrPct}%</strong> of
                  your free time goes to screens. Most {age < 14 ? "kids your age" : "teens"} are
                  well over 50%.
                </>
              ) : (
                <>
                  Only <strong style={{ color: C.tealBright }}>{controllableScrPct}%</strong> of
                  your free time goes to screens, and your brain gets{" "}
                  <strong style={{ color: C.tealBright }}>{protectedMinutes} minutes</strong> per
                  day of genuine quiet. The national average for adults is 4–5 hours of personal
                  screen time. You're at {fmt(sH)}.
                </>
              )}
            </div>

            {/* Counterfactual: what drift looks like */}
            <div
              style={{
                background: "rgba(255,255,255,0.06)",
                borderRadius: 10,
                padding: "14px 14px 10px",
              }}
            >
              <div
                style={{
                  ...sr,
                  fontSize: 14,
                  fontWeight: 700,
                  color: "rgba(255,255,255,0.9)",
                  marginBottom: 10,
                }}
              >
                {age < 18 ? "What drift looks like" : "What losing this looks like"}
              </div>
              <div style={{ fontSize: 12, color: "rgba(255,255,255,0.55)", marginBottom: 10 }}>
                If personal screen time grew to {cfScrH}h/day — {cfLabel}
                {age < 14 ? " as you enter the next phase" : ""}:
              </div>
              <div
                style={{
                  display: "grid",
                  gridTemplateColumns: "1fr 1fr",
                  gap: 8,
                  marginBottom: 10,
                }}
              >
                {/* Protected brain time comparison */}
                <div
                  style={{
                    background: "rgba(45,212,191,0.1)",
                    borderRadius: 8,
                    padding: "10px 12px",
                    textAlign: "center",
                  }}
                >
                  <div style={{ fontSize: 10, color: "rgba(255,255,255,0.75)", marginBottom: 4 }}>
                    Now
                  </div>
                  <div style={{ ...sr, fontSize: 22, fontWeight: 700, color: C.tealBright }}>
                    {protectedMinutes}
                    <span style={{ fontSize: 11 }}>m</span>
                  </div>
                  <div style={{ fontSize: 10, color: "rgba(255,255,255,0.75)", marginTop: 2 }}>
                    brain time
                  </div>
                </div>
                <div
                  style={{
                    background: "rgba(217,119,6,0.1)",
                    borderRadius: 8,
                    padding: "10px 12px",
                    textAlign: "center",
                  }}
                >
                  <div style={{ fontSize: 10, color: "rgba(255,255,255,0.75)", marginBottom: 4 }}>
                    If drifted
                  </div>
                  <div style={{ ...sr, fontSize: 22, fontWeight: 700, color: "#facc15" }}>
                    {cfProtectedMinutes}
                    <span style={{ fontSize: 11 }}>m</span>
                  </div>
                  <div style={{ fontSize: 10, color: "rgba(255,255,255,0.75)", marginTop: 2 }}>
                    brain time
                  </div>
                </div>
              </div>
              <div
                style={{
                  display: "grid",
                  gridTemplateColumns: "1fr 1fr",
                  gap: 8,
                  marginBottom: 10,
                }}
              >
                <div
                  style={{
                    background: "rgba(45,212,191,0.1)",
                    borderRadius: 8,
                    padding: "8px 12px",
                    textAlign: "center",
                  }}
                >
                  <div style={{ ...sr, fontSize: 18, fontWeight: 700, color: C.tealBright }}>
                    {controllableScrPct}%
                  </div>
                  <div style={{ fontSize: 10, color: "rgba(255,255,255,0.75)" }}>
                    free time → screens
                  </div>
                </div>
                <div
                  style={{
                    background: "rgba(217,119,6,0.1)",
                    borderRadius: 8,
                    padding: "8px 12px",
                    textAlign: "center",
                  }}
                >
                  <div style={{ ...sr, fontSize: 18, fontWeight: 700, color: "#facc15" }}>
                    {cfControllablePct}%
                  </div>
                  <div style={{ fontSize: 10, color: "rgba(255,255,255,0.75)" }}>
                    free time → screens
                  </div>
                </div>
              </div>
              {protectedMinutesLost > 0 && (
                <div
                  style={{ fontSize: 12, color: "#facc15", fontWeight: 600, textAlign: "center" }}
                >
                  That's {protectedMinutesLost} minutes of brain time lost — every single day.
                </div>
              )}
            </div>

            {age < 14 && (
              <div
                style={{
                  fontSize: 12,
                  color: "rgba(255,255,255,0.6)",
                  lineHeight: 1.6,
                  marginTop: 12,
                  fontStyle: "italic",
                }}
              >
                The window to build these habits is now — before organized activities fall away and
                before the phone arrives with more persuasive design.
              </div>
            )}
            {age >= 14 && age < 18 && (
              <div
                style={{
                  fontSize: 12,
                  color: "rgba(255,255,255,0.6)",
                  lineHeight: 1.6,
                  marginTop: 12,
                  fontStyle: "italic",
                }}
              >
                Most teens drift toward the average gradually. The fact that you haven't is worth
                protecting.
              </div>
            )}
          </div>
        )}

        {/* ── BEAT 3: Whole-Life Bubble Chart ────────────────────────────── */}
        <div
          style={{
            background: C.surface,
            borderRadius: 14,
            padding: 18,
            marginBottom: 10,
            border: `1px solid ${C.border}`,
          }}
        >
          <div style={{ borderRadius: 12, padding: "8px 0" }}>
            <div
              style={{
                fontSize: 12,
                color: C.muted,
                marginBottom: 12,
                fontWeight: 600,
                padding: "0 8px",
              }}
            >
              Your next {yearsRem} years · each dot = 1 month · each row = 2 years
            </div>
            <div style={{ position: "relative" }}>
              <LabeledLifeGrid
                segments={rGridSegsScreensOn}
                totalMonths={totalM}
                revealScreens={showScreensGrid}
                showPacman={pacActive}
              />
              {!showScreensGrid && (
                <div
                  style={{
                    position: "absolute",
                    bottom: 16,
                    left: "50%",
                    transform: "translateX(-50%)",
                    zIndex: 10,
                  }}
                >
                  <button
                    onClick={() => {
                      setShowScreensGrid(true);
                      setPacActive(true);
                    }}
                    style={{
                      background: C.dark,
                      color: "white",
                      borderRadius: 24,
                      padding: "10px 20px",
                      fontSize: 13,
                      fontWeight: 700,
                      cursor: "pointer",
                      border: "2px solid " + GC.scrFree,
                      boxShadow: "0 4px 16px rgba(0,0,0,0.2)",
                      animation: "defragPulse 2s ease-in-out infinite",
                      display: "flex",
                      alignItems: "center",
                      gap: 8,
                    }}
                  >
                    <svg viewBox="0 0 20 20" style={{ width: 18, height: 18, flexShrink: 0 }}>
                      <path d="M10 0 A10 10 0 1 1 10 20 A10 10 0 1 1 10 0 Z" fill={GC.scrFree} />
                      <path d="M10 10 L20 4 L20 16 Z" fill="white" />
                    </svg>
                    Tap to reveal screens in your free time
                  </button>
                </div>
              )}
            </div>
            {showScreensGrid && (
              <div
                style={{
                  padding: "8px 10px",
                  marginTop: 6,
                  background: C.surfaceAlt,
                  borderRadius: 8,
                  border: `1px solid ${C.border}`,
                }}
              >
                <div style={{ display: "flex", flexWrap: "wrap", gap: 8, marginBottom: 4 }}>
                  {[
                    { c: GC.sleep, l: "Sleep" },
                    { c: GC.school, l: age >= 18 ? "Work" : "School" },
                    { c: "#3b82f6", l: "Daily tasks" },
                    { c: GC.scrFree, l: "Personal screens" },
                    { c: "#e4e4e7", l: "Open free time" },
                  ].map((x) => (
                    <div
                      key={x.l}
                      style={{
                        display: "flex",
                        alignItems: "center",
                        gap: 4,
                        fontSize: 11,
                        color: C.muted,
                      }}
                    >
                      <div
                        style={{
                          width: 8,
                          height: 8,
                          borderRadius: 2,
                          background: x.c,
                          flexShrink: 0,
                        }}
                      />
                      {x.l}
                    </div>
                  ))}
                </div>
                <div
                  style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}
                >
                  <div style={{ fontSize: 12, color: C.muted }}>
                    Orange dots are screens eating into your free time.
                  </div>
                  <button
                    onClick={() => setShowScreensGrid(false)}
                    style={{
                      fontSize: 11,
                      color: C.muted,
                      background: "transparent",
                      border: `1px solid ${C.border}`,
                      borderRadius: 16,
                      padding: "3px 12px",
                      cursor: "pointer",
                      fontWeight: 500,
                      flexShrink: 0,
                      marginLeft: 8,
                    }}
                  >
                    Hide
                  </button>
                </div>
              </div>
            )}
            <div
              style={{
                fontSize: 11,
                color: C.faint,
                lineHeight: 1.6,
                marginTop: 8,
                padding: "0 8px",
                fontStyle: "italic",
              }}
            >
              Lifetime obligations use US population averages that shift across life stages. Your
              life will differ — the direction matters more than the exact number.
            </div>
            <div
              style={{
                fontSize: 10,
                color: C.faint,
                padding: "4px 8px 0",
                textAlign: "right",
              }}
            >
              Visualization inspired by{" "}
              <a
                href="https://www.youtube.com/watch?v=4TMPXK9tw5U"
                target="_blank"
                rel="noreferrer"
                style={{ color: C.faint, textDecoration: "underline" }}
              >
                Dino Ambrosi
              </a>
            </div>
          </div>

          {/* Free time reality — show here only if NOT exceeding 24h */}
          {!scrExceedsFreeTime && (
            <div style={{ marginTop: 14 }}>
              <div
                style={{
                  background: C.dark,
                  borderRadius: 10,
                  padding: "14px 16px",
                  position: "relative",
                }}
              >
                <ShowMath
                  dark
                  lines={[
                    `Daily obligations: ${fmt(oblig)}`,
                    `Free time: 24 − ${fmt(oblig)} = ${fmt(freeTime)}/day`,
                    `Personal screens (weekly avg): ${fmt(avgLifeSH)}/day`,
                    `Free time over lifetime: (${fmt(freeTime)} ÷ 24) × ${yearsRem} = ${freeTimeLifeYrs.toFixed(1)} yrs`,
                    `Screens in free time: (${fmt(avgLifeSH)} ÷ 24) × ${yearsRem} = ${personalScrYears} yrs`,
                    `→ ${freePctOfFreeLife}% of lifetime free time → screens`,
                  ]}
                />
                <div
                  style={{
                    fontSize: 10,
                    fontWeight: 700,
                    letterSpacing: "0.1em",
                    textTransform: "uppercase",
                    color: "rgba(255,255,255,0.6)",
                    marginBottom: 6,
                  }}
                >
                  Your free time — the part you control
                </div>
                <div
                  style={{
                    ...sr,
                    fontSize: 28,
                    color: C.royal,
                    fontWeight: 700,
                    lineHeight: 1.1,
                    marginBottom: 4,
                  }}
                >
                  {freePctOfFreeLife}% of your free time → screens.
                </div>
                <div style={{ fontSize: 13, color: "rgba(255,255,255,0.8)", lineHeight: 1.6 }}>
                  Of your next {freeTimeLifeYrs.toFixed(1)} years of free time, personal screens
                  claim <strong style={{ color: C.royal }}>{personalScrYears} years</strong> at your
                  current pace
                  {age < 13
                    ? " — matching the national trajectory for kids heading into adolescence"
                    : ""}
                  .
                </div>
              </div>
            </div>
          )}

          {age < 18 && (
            <div
              style={{
                background: C.tealFaint,
                borderRadius: 8,
                padding: "10px 13px",
                marginTop: 10,
                border: `1px solid ${C.tealLight}40`,
              }}
            >
              <div style={{ fontSize: 13, color: C.dark, lineHeight: 1.6 }}>
                Of your <strong style={{ color: C.mid }}>{fmt(freeTime)}/day</strong> of free time,
                screens currently take <strong style={{ color: C.mid }}>{freePct}%</strong> — the
                estimated national teen average is 93% (Dino Ambrosi; defrag. calculation based on
                8h avg screens vs ~8.6h avg free time).
              </div>
            </div>
          )}
        </div>

        {/* Protected Brain Time detail is now on its own dedicated step (Step 6) */}
        {/* Quick teaser stat for the Reveal — links to the full PBT step */}
        <button
          onClick={() => {
            setStep(STEP.PBT);
            scrollToTop();
          }}
          aria-label={`Learn about Protected Brain Time — you currently have ${protectedMinutes} minutes per day`}
          style={{
            display: "block",
            width: "100%",
            background: C.dark,
            borderRadius: 14,
            padding: "16px 18px",
            marginBottom: 10,
            textAlign: "center",
            cursor: "pointer",
            border: "none",
            color: "inherit",
            fontFamily: "inherit",
          }}
        >
          <div
            style={{
              fontSize: 10,
              fontWeight: 700,
              letterSpacing: "0.1em",
              textTransform: "uppercase",
              color: "rgba(255,255,255,0.75)",
              marginBottom: 6,
            }}
          >
            Protected Brain Time
          </div>
          <div
            style={{
              ...sr,
              fontSize: 36,
              fontWeight: 700,
              color:
                protectedMinutes > 60 ? C.tealBright : protectedMinutes > 0 ? "#facc15" : C.redLight,
              lineHeight: 1,
            }}
          >
            {protectedMinutes}
            <span style={{ fontSize: "0.3em", color: "rgba(255,255,255,0.6)", marginLeft: 4 }}>
              min/day
            </span>
          </div>
          <div style={{ fontSize: 12, color: "rgba(255,255,255,0.6)", marginTop: 6 }}>
            Tap to learn what this means →
          </div>
        </button>

        {/* ── 24-Hour Clock — continuously cycling ──── */}
        <ClockChart
          meals={meals}
          hygiene={hygiene}
          commute={commute}
          chores={chores}
          caregiving={caregiving}
          age={age}
          sleep={sleep}
          schoolPieH={schoolPieH}
          workPieH={workPieH}
          sH={sH}
          freeTimePieH={freeTimePieH}
          oblig={oblig}
        />

        {/* Free time reality — show here ONLY when exceeding 24h (flows after the clock) */}
        {scrExceedsFreeTime && (
          <div
            style={{
              background: C.dark,
              borderRadius: 14,
              padding: "16px 18px",
              marginBottom: 10,
              position: "relative",
            }}
          >
            <ShowMath
              dark
              lines={[
                `Obligations: ${fmt(oblig)} (sleep ${fmt(sleep)} + ${age >= 18 ? "work" : "school"} ${fmt(schoolH)} + meals ${fmt(meals)} + hygiene ${fmt(hygiene)} + commute ${fmt(commute)}${caregiving > 0 ? " + caregiving " + fmt(caregiving) : ""})`,
                `Personal screens: ${fmt(sH)}`,
                `Total: ${fmt(oblig)} + ${fmt(sH)} = ${fmt(oblig + sH)}`,
                `→ Over by: ${fmt(oblig + sH)} − 24 = ${fmt(oblig + sH - 24)} (${Math.round((oblig + sH - 24) * 60)} minutes)`,
              ]}
            />
            <div
              style={{
                fontSize: 10,
                fontWeight: 700,
                letterSpacing: "0.1em",
                textTransform: "uppercase",
                color: "rgba(255,255,255,0.6)",
                marginBottom: 6,
              }}
            >
              Your free time — the part you control
            </div>
            <div
              style={{
                ...sr,
                fontSize: 20,
                color: C.redLight,
                fontWeight: 700,
                lineHeight: 1.2,
                marginBottom: 8,
              }}
            >
              Your day doesn't fit.
            </div>
            <div style={{ fontSize: 14, color: "rgba(255,255,255,0.85)", lineHeight: 1.65 }}>
              In a 24-hour day, your obligations (sleep, {age >= 18 ? "work" : "school"}, meals,
              hygiene, commute{caregiving > 0 ? ", caregiving" : ""}) take{" "}
              <strong style={{ color: "white" }}>{fmt(oblig)}</strong>. Your personal screen time is{" "}
              <strong style={{ color: "#facc15" }}>{fmt(sH)}</strong>. That's{" "}
              <strong style={{ color: C.redLight }}>{fmt(oblig + sH)}</strong> —{" "}
              <strong style={{ color: C.redLight }}>
                {Math.round((oblig + sH - 24) * 60)} minutes over
              </strong>
              . Something is being displaced.
            </div>
          </div>
        )}

        {/* ── Closing: transition to Protected Brain Time ── */}
        <div
          style={{
            background: "linear-gradient(135deg, #042f2e 0%, #1e1b4b 100%)",
            borderRadius: 16,
            padding: "36px 24px",
            marginBottom: 10,
            textAlign: "center",
            border: "1px solid rgba(129,140,248,0.2)",
          }}
        >
          <div
            style={{
              ...sr,
              fontSize: "clamp(20px,5vw,28px)",
              fontWeight: 700,
              color: "white",
              marginBottom: 8,
              lineHeight: 1.3,
            }}
          >
            That's your screen reality.
          </div>
          <div
            style={{
              fontSize: 15,
              color: "rgba(255,255,255,0.75)",
              lineHeight: 1.6,
              marginBottom: 16,
            }}
          >
            But there's a number that matters more than any of these — and no app tracks it.
          </div>
          <button
            onClick={() => {
              setStep(STEP.PBT);
              scrollToTop();
            }}
            style={{
              background: C.royal,
              color: "white",
              border: "none",
              borderRadius: 24,
              padding: "12px 28px",
              fontSize: 15,
              fontWeight: 700,
              cursor: "pointer",
              boxShadow: "0 4px 16px rgba(129,140,248,0.3)",
            }}
          >
            Discover Protected Brain Time →
          </button>
        </div>
      </div>
    );
  };

  // ── STEP 7 of 9: YOUR POSSIBILITIES ──────────────────────────────────────
  const PossibilitiesStep = () => {
    const heroScreenYears = age >= 22 ? totalLifetimeScreenYears : calendarScrYears;
    // Use App-level adjusted values
    const totalReclaimedYrs = (totalReclaimedYrsGlobal || 0).toFixed(1);
    const bonusYrs = (bonusYrsFromFiller || 0).toFixed(1);
    const fillerSaved = fillerSavedMin || 0;

    return (
      <div>
        {/* ── Step header — light, optimistic ── */}
        <div style={{ marginBottom: 16 }}>
          <div
            style={{
              fontSize: 11,
              fontWeight: 700,
              letterSpacing: "0.12em",
              textTransform: "uppercase",
              color: C.royal,
              marginBottom: 4,
            }}
          >
            Step 7 of 9
          </div>
          <h2
            style={{
              ...sr,
              color: C.dark,
              fontSize: "clamp(22px,5vw,28px)",
              marginBottom: 6,
              fontWeight: 700,
              lineHeight: 1.2,
            }}
          >
            Your Possibilities
          </h2>
        </div>

        {/* ── Fallback budget banner — user skipped Step 4 ── */}
        {usingFallbackBudget && (
          <div
            style={{
              background: "#fefce8",
              borderRadius: 10,
              padding: "12px 14px",
              marginBottom: 12,
              border: "1px solid #fde047",
              display: "flex",
              gap: 10,
              alignItems: "flex-start",
            }}
          >
            <div style={{ fontSize: 18, lineHeight: 1, flexShrink: 0 }}>⚠️</div>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 13, fontWeight: 700, color: "#713f12", marginBottom: 3 }}>
                These numbers use a 1h/day placeholder
              </div>
              <div style={{ fontSize: 12, color: "#854d0e", lineHeight: 1.55, marginBottom: 6 }}>
                You didn't pick any screen activities in Step 4 — go back to choose what's worth
                keeping, and these possibilities will reflect your real plan.
              </div>
              <button
                onClick={() => {
                  setStep(STEP.DESIGN);
                  scrollToTop();
                }}
                style={{
                  background: "#854d0e",
                  color: "white",
                  border: "none",
                  borderRadius: 6,
                  padding: "5px 12px",
                  fontSize: 11,
                  fontWeight: 700,
                  cursor: "pointer",
                }}
              >
                ← Go to Step 4
              </button>
            </div>
          </div>
        )}

        {/* ── Hero: Reclaimed years — light teal gradient ── */}
        <div
          style={{
            background: "linear-gradient(135deg, #f0fdfa 0%, #ccfbf1 100%)",
            borderRadius: 16,
            padding: "36px 24px",
            marginBottom: 12,
            textAlign: "center",
            position: "relative",
            overflow: "hidden",
            border: `1px solid ${C.tealLight}40`,
          }}
        >
          <div
            style={{
              position: "absolute",
              top: -40,
              right: -40,
              width: 180,
              height: 180,
              borderRadius: "50%",
              background: "rgba(15,118,110,0.06)",
            }}
          />
          <div
            style={{
              position: "absolute",
              bottom: -30,
              left: -30,
              width: 120,
              height: 120,
              borderRadius: "50%",
              background: "rgba(15,118,110,0.04)",
            }}
          />
          <div style={{ position: "relative", zIndex: 1 }}>
            <div
              style={{
                fontSize: 11,
                fontWeight: 700,
                letterSpacing: "0.14em",
                textTransform: "uppercase",
                color: C.mid,
                marginBottom: 16,
              }}
            >
              Now imagine something different
            </div>
            <div
              style={{
                ...sr,
                fontSize: "clamp(56px,14vw,84px)",
                fontWeight: 700,
                color: C.mid,
                lineHeight: 0.9,
              }}
            >
              +{totalReclaimedYrs}
            </div>
            <div
              style={{
                ...sr,
                fontSize: "clamp(18px,4vw,24px)",
                fontWeight: 700,
                color: C.dark,
                marginTop: 10,
              }}
            >
              years you can reclaim
            </div>
            <div
              style={{
                fontSize: 13,
                color: C.muted,
                marginTop: 12,
                lineHeight: 1.6,
                maxWidth: 420,
                margin: "12px auto 0",
              }}
            >
              based on how you <strong style={{ color: C.mid }}>want</strong> to invest your time.
            </div>
            <div
              style={{
                fontSize: 13,
                color: C.muted,
                marginTop: 10,
                lineHeight: 1.6,
                maxWidth: 420,
                margin: "0 auto",
              }}
            >
              Right now you're tracking{" "}
              <strong style={{ color: C.dark }}>{calendarScrYears} years</strong> on screens over
              your whole lifetime.
              {baseReclaimedYrs > 0.05 ? (
                <>
                  {" "}
                  Just by following your Invest Your Time screen budget of{" "}
                  <strong style={{ color: C.mid }}>{fmt(totalIdeal)}/day</strong> (down from your
                  current <strong style={{ color: C.dark }}>{fmt(sH)}</strong> average on screens),
                  you'd save{" "}
                  <strong style={{ color: C.mid }}>{baseReclaimedYrs.toFixed(1)} years</strong>.
                </>
              ) : (
                ""
              )}
            </div>
          </div>
        </div>

        {/* ── CONTROL PANEL — cockpit layout ── */}
        <div
          style={{ background: C.dark, borderRadius: 16, padding: "16px 14px", marginBottom: 12 }}
        >
          {/* Header row: title + live years counter */}
          <div
            style={{
              display: "flex",
              justifyContent: "space-between",
              alignItems: "center",
              marginBottom: 14,
            }}
          >
            <div>
              <div style={{ ...sr, fontSize: 16, fontWeight: 700, color: "white" }}>
                Your control panel
              </div>
              <div
                style={{
                  fontSize: 12,
                  color: "rgba(255,255,255,0.6)",
                  lineHeight: 1.4,
                  marginTop: 3,
                }}
              >
                You've seen the reality. Now play with the math — and see what changes when{" "}
                <em>you</em> decide how your time is spent.
              </div>
            </div>
            <div
              style={{
                background: "rgba(45,212,191,0.1)",
                borderRadius: 10,
                padding: "8px 14px",
                textAlign: "center",
                border: "1px solid rgba(45,212,191,0.2)",
              }}
            >
              <div
                style={{ ...sr, fontSize: 24, fontWeight: 700, color: C.tealBright, lineHeight: 1 }}
              >
                +{totalReclaimedYrs}
              </div>
              <div
                style={{
                  fontSize: 9,
                  color: "rgba(255,255,255,0.75)",
                  textTransform: "uppercase",
                  letterSpacing: "0.08em",
                  marginTop: 2,
                }}
              >
                years reclaimed
              </div>
            </div>
          </div>

          {/* Two sliders side by side */}
          <div
            style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8, marginBottom: 10 }}
          >
            {/* Dial 1: Pickups */}
            <div
              style={{
                background: "rgba(255,255,255,0.06)",
                borderRadius: 10,
                padding: "12px 10px",
              }}
            >
              <div
                style={{
                  fontSize: 10,
                  fontWeight: 700,
                  color: "rgba(255,255,255,0.75)",
                  textTransform: "uppercase",
                  letterSpacing: "0.06em",
                  marginBottom: 2,
                }}
              >
                Phone pickups
              </div>
              <div
                style={{
                  fontSize: 10,
                  color: "rgba(255,255,255,0.7)",
                  lineHeight: 1.3,
                  marginBottom: 6,
                }}
              >
                Checking during other activities — the constant connectivity habit
              </div>
              <div
                style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline" }}
              >
                <span
                  style={{
                    ...sr,
                    fontSize: 28,
                    fontWeight: 700,
                    color: adjPickups < pkp ? C.tealBright : "rgba(255,255,255,0.6)",
                    lineHeight: 1,
                  }}
                >
                  {adjPickups}
                  <span style={{ fontSize: 11, color: "rgba(255,255,255,0.75)" }}>/day</span>
                </span>
                <span style={{ fontSize: 10, color: "rgba(255,255,255,0.7)" }}>was {pkp}</span>
              </div>
              <SmoothSlider
                min={10}
                max={pkp}
                step={5}
                value={adjPickups}
                onChange={(v) => setAdjPickups(v)}
                style={{ width: "100%", accentColor: C.tealBright, margin: "4px 0 0" }}
                ariaLabel="Target daily phone pickups"
                ariaValueText={`${adjPickups} pickups per day`}
              />
              {adjPickups < pkp && pkpSavedMin > 0 && (
                <div
                  style={{
                    fontSize: 11,
                    color: C.tealBright,
                    fontWeight: 600,
                    textAlign: "center",
                    marginTop: 4,
                  }}
                >
                  +{pkpSavedMin}m/day → +{bonusYrsFromPickups.toFixed(1)}y
                </div>
              )}
            </div>
            {/* Dial 2: Screen time */}
            <div
              style={{
                background: "rgba(255,255,255,0.06)",
                borderRadius: 10,
                padding: "12px 10px",
              }}
            >
              <div
                style={{
                  fontSize: 10,
                  fontWeight: 700,
                  color: "rgba(255,255,255,0.75)",
                  textTransform: "uppercase",
                  letterSpacing: "0.06em",
                  marginBottom: 2,
                }}
              >
                Screen goal
              </div>
              <div
                style={{
                  fontSize: 10,
                  color: "rgba(255,255,255,0.7)",
                  lineHeight: 1.3,
                  marginBottom: 6,
                }}
              >
                Intentional screen time outside of {age >= 18 ? "work" : "school"} — streaming,
                social, gaming
              </div>
              <div
                style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline" }}
              >
                <span
                  style={{
                    ...sr,
                    fontSize: 28,
                    fontWeight: 700,
                    color:
                      effectiveAdjScrH < totalIdeal
                        ? C.tealBright
                        : effectiveAdjScrH < sH
                          ? "white"
                          : "rgba(255,255,255,0.6)",
                    lineHeight: 1,
                  }}
                >
                  {fmt(effectiveAdjScrH)}
                </span>
                <span style={{ fontSize: 10, color: "rgba(255,255,255,0.7)" }}>was {fmt(sH)}</span>
              </div>
              <SmoothSlider
                min={0}
                max={sH}
                step={0.25}
                value={effectiveAdjScrH}
                onChange={(v) => setAdjScrH(v)}
                style={{ width: "100%", accentColor: C.tealBright, margin: "4px 0 0" }}
                ariaLabel="Target daily screen budget"
                ariaValueText={`${fmt(effectiveAdjScrH)} per day`}
              />
              <div
                style={{
                  display: "flex",
                  justifyContent: "space-between",
                  fontSize: 9,
                  color: "rgba(255,255,255,0.7)",
                  marginTop: 2,
                }}
              >
                <span>0h</span>
                <span style={{ color: "rgba(45,212,191,0.85)" }}>budget {fmt(totalIdeal)}</span>
                <span>{fmt(sH)}</span>
              </div>
              {effectiveAdjScrH < totalIdeal && (
                <div
                  style={{
                    fontSize: 11,
                    color: C.tealBright,
                    fontWeight: 600,
                    textAlign: "center",
                    marginTop: 4,
                  }}
                >
                  +{additionalFromScreen.toFixed(1)}y beyond budget
                </div>
              )}
            </div>
          </div>

          {/* Filler windows — all categories shown, Step 3 selections start checked */}
          {(() => {
            const allFillerKeys =
              age < 18
                ? ["morning", "gettingReady", "commute", "work", "afterSchool", "meals", "bedtime"]
                : ["morning", "gettingReady", "commute", "work", "meals", "caregiving", "bedtime"];
            const shortLabels = {
              morning: "Morning",
              gettingReady: "Getting ready",
              commute: "Commute",
              work: age >= 18 ? "At work" : "At school",
              afterSchool: "After school",
              meals: "Meals",
              caregiving: "Caregiving",
              bedtime: "Bedtime",
            };
            // Checked = filler is active (costs time). Unchecked = protected (saves time).
            // A context is "checked" if it's in phoneChecks AND not in eliminatedFiller.
            const activeCount = allFillerKeys.filter(
              (k) => phoneChecks.includes(k) && !eliminatedFiller.includes(k)
            ).length;
            return (
              <div
                style={{
                  background: "rgba(255,255,255,0.06)",
                  borderRadius: 10,
                  padding: "10px 10px",
                  marginTop: 2,
                }}
              >
                <div
                  style={{
                    display: "flex",
                    justifyContent: "space-between",
                    alignItems: "flex-start",
                    marginBottom: 6,
                  }}
                >
                  <div>
                    <div
                      style={{
                        fontSize: 10,
                        fontWeight: 700,
                        color: "rgba(255,255,255,0.75)",
                        textTransform: "uppercase",
                        letterSpacing: "0.06em",
                      }}
                    >
                      Filler windows
                    </div>
                    <div
                      style={{
                        fontSize: 10,
                        color: "rgba(255,255,255,0.7)",
                        lineHeight: 1.3,
                        marginTop: 1,
                      }}
                    >
                      Protect your brain's downtime — uncheck to reclaim
                    </div>
                  </div>
                  {fillerSavedMin > 0 && (
                    <span
                      style={{
                        fontSize: 12,
                        fontWeight: 700,
                        color: C.tealBright,
                        flexShrink: 0,
                        marginLeft: 8,
                      }}
                    >
                      +{fillerSavedMin}m
                    </span>
                  )}
                </div>
                <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 4 }}>
                  {allFillerKeys.map((k) => {
                    const mins = Math.round((FILLER_ESTIMATES[k] || 15) * pkpScale * adjPkpRatio);
                    const inPhoneChecks = phoneChecks.includes(k);
                    const inEliminated = eliminatedFiller.includes(k);
                    // "checked" = in phoneChecks and NOT eliminated
                    const checked = inPhoneChecks && !inEliminated;
                    return (
                      <div
                        key={k}
                        onClick={() => {
                          if (!inPhoneChecks) {
                            // Not selected in Step 3 — add to phoneChecks (turns it on)
                            setPhoneChecks((prev) => [...prev, k]);
                            // Remove from eliminated in case it was there
                            setEliminatedFiller((prev) => prev.filter((x) => x !== k));
                          } else if (checked) {
                            // Currently on — turn off by adding to eliminated
                            setEliminatedFiller((prev) => [...prev, k]);
                          } else {
                            // Currently off (eliminated) — turn back on
                            setEliminatedFiller((prev) => prev.filter((x) => x !== k));
                          }
                        }}
                        style={{
                          display: "flex",
                          alignItems: "center",
                          gap: 6,
                          padding: "7px 8px",
                          borderRadius: 6,
                          cursor: "pointer",
                          background: checked ? "rgba(45,212,191,0.1)" : "rgba(255,255,255,0.02)",
                          border: `1px solid ${checked ? "rgba(45,212,191,0.25)" : "rgba(255,255,255,0.06)"}`,
                          transition: "all 0.15s",
                        }}
                      >
                        <div
                          style={{
                            width: 18,
                            height: 18,
                            borderRadius: 4,
                            border: `2px solid ${checked ? C.tealBright : "rgba(255,255,255,0.2)"}`,
                            background: checked ? C.tealBright : "transparent",
                            display: "flex",
                            alignItems: "center",
                            justifyContent: "center",
                            flexShrink: 0,
                            transition: "all 0.15s",
                          }}
                        >
                          {checked && (
                            <span style={{ color: C.dark, fontSize: 11, fontWeight: 700 }}>✓</span>
                          )}
                        </div>
                        <div style={{ flex: 1, minWidth: 0 }}>
                          <div
                            style={{
                              fontSize: 12,
                              color: checked ? "white" : "rgba(255,255,255,0.75)",
                              fontWeight: 600,
                              lineHeight: 1.2,
                            }}
                          >
                            {shortLabels[k] || k}
                          </div>
                        </div>
                        <span
                          style={{
                            fontSize: 10,
                            fontWeight: 700,
                            color: checked
                              ? "rgba(255,255,255,0.4)"
                              : inPhoneChecks
                                ? C.tealBright
                                : "rgba(255,255,255,0.15)",
                            flexShrink: 0,
                          }}
                        >
                          {checked ? `${mins}m` : inPhoneChecks ? `+${mins}m` : "—"}
                        </span>
                      </div>
                    );
                  })}
                </div>
              </div>
            );
          })()}
        </div>

        {/* ── Combined savings summary — light teal ── */}
        {totalReclaimedYrsGlobal > 0.1 && (
          <div
            style={{
              background: "linear-gradient(135deg, #f0fdfa 0%, #ccfbf1 100%)",
              borderRadius: 14,
              padding: "18px 18px",
              marginBottom: 12,
              textAlign: "center",
              border: `1px solid ${C.tealLight}40`,
            }}
          >
            <div
              style={{
                fontSize: 11,
                fontWeight: 700,
                letterSpacing: "0.1em",
                textTransform: "uppercase",
                color: C.mid,
                marginBottom: 8,
              }}
            >
              Your total reclaimed time
            </div>
            <div
              style={{
                ...sr,
                fontSize: "clamp(36px,10vw,56px)",
                fontWeight: 700,
                color: C.mid,
                lineHeight: 1,
              }}
            >
              +{totalReclaimedYrs}
              <span style={{ fontSize: "0.4em", color: C.muted, marginLeft: 4 }}>years</span>
            </div>
            <div
              style={{
                display: "flex",
                flexDirection: "column",
                gap: 4,
                fontSize: 13,
                color: C.muted,
                lineHeight: 1.5,
                marginTop: 14,
                textAlign: "left",
                maxWidth: 380,
                margin: "14px auto 0",
              }}
            >
              {baseReclaimedYrs > 0.05 && (
                <div>
                  • <strong style={{ color: C.mid }}>+{baseReclaimedYrs.toFixed(1)}y</strong> from
                  your screen budget ({fmt(sH)} → {fmt(totalIdeal)})
                </div>
              )}
              {eliminatedFiller.length > 0 && fillerSavedMin > 0 && (
                <div>
                  • <strong style={{ color: C.mid }}>+{bonusYrsFromFiller.toFixed(1)}y</strong> from
                  protecting {eliminatedFiller.length} filler window
                  {eliminatedFiller.length > 1 ? "s" : ""}
                </div>
              )}
              {adjPickups < pkp && pkpSavedMin > 0 && (
                <div>
                  • <strong style={{ color: C.mid }}>+{bonusYrsFromPickups.toFixed(1)}y</strong>{" "}
                  from reducing pickups ({pkp} → {adjPickups})
                </div>
              )}
              {additionalFromScreen > 0.05 && (
                <div>
                  • <strong style={{ color: C.mid }}>+{additionalFromScreen.toFixed(1)}y</strong>{" "}
                  from going below budget ({fmt(totalIdeal)} → {fmt(effectiveAdjScrH)})
                </div>
              )}
            </div>
          </div>
        )}

        {/* ── Protected Brain Time improvement ── */}
        <div
          style={{ background: C.dark, borderRadius: 14, padding: "20px 18px", marginBottom: 10 }}
        >
          <div style={{ ...sr, fontSize: 15, fontWeight: 700, color: "white", marginBottom: 10 }}>
            Your protected brain time — before and after
          </div>
          <div
            style={{
              display: "grid",
              gridTemplateColumns: "1fr auto 1fr",
              gap: 10,
              alignItems: "center",
              marginBottom: 12,
            }}
          >
            <div style={{ textAlign: "center" }}>
              <div
                style={{
                  fontSize: 11,
                  color: "rgba(255,255,255,0.6)",
                  marginBottom: 4,
                  textTransform: "uppercase",
                  letterSpacing: "0.06em",
                }}
              >
                Now
              </div>
              <div
                style={{
                  ...sr,
                  fontSize: 28,
                  fontWeight: 700,
                  color: protectedMinutes > 60 ? "rgba(255,255,255,0.7)" : "#facc15",
                }}
              >
                {protectedMinutes}m
              </div>
            </div>
            <div style={{ fontSize: 22, color: "rgba(255,255,255,0.7)" }}>→</div>
            <div style={{ textAlign: "center" }}>
              <div
                style={{
                  fontSize: 11,
                  color: "rgba(255,255,255,0.6)",
                  marginBottom: 4,
                  textTransform: "uppercase",
                  letterSpacing: "0.06em",
                }}
              >
                With your plan
              </div>
              <div style={{ ...sr, fontSize: 28, fontWeight: 700, color: C.tealBright }}>
                {improvedProtectedMinutes}m
              </div>
            </div>
          </div>
          {protectedGainFromPlan > 0 && (
            <div
              style={{
                background: "rgba(45,212,191,0.1)",
                borderRadius: 8,
                padding: "10px 14px",
                border: "1px solid rgba(45,212,191,0.2)",
                textAlign: "center",
              }}
            >
              <span style={{ ...sr, fontSize: 18, fontWeight: 700, color: C.tealBright }}>
                +{protectedGainFromPlan}m
              </span>
              <span style={{ fontSize: 13, color: "rgba(255,255,255,0.75)", marginLeft: 8 }}>
                more minutes for your brain every day
              </span>
            </div>
          )}
          <div
            style={{
              fontSize: 12,
              color: "rgba(255,255,255,0.6)",
              marginTop: 10,
              lineHeight: 1.55,
            }}
          >
            This comes from shifting personal screens from {fmt(sH)} to {fmt(effectiveAdjScrH)}
            {fillerSaved > 0 ? ` and eliminating ${fillerSaved}m of daily filler habits` : ""}.
            Remember: this only counts if you protect at least one unbroken 23-minute block.
          </div>
        </div>

        {/* ── What could you do with X years? — personalized equivalents ── */}
        {parseFloat(totalReclaimedYrs) > 0.5 && (
          <div
            style={{
              background: C.surface,
              borderRadius: 14,
              padding: "20px 18px",
              marginBottom: 10,
              border: `1px solid ${C.border}`,
            }}
          >
            <div style={{ ...sr, fontSize: 17, fontWeight: 700, color: C.dark, marginBottom: 4 }}>
              What could you do with {totalReclaimedYrs} years?
            </div>
            <div style={{ fontSize: 13, color: C.muted, marginBottom: 14, lineHeight: 1.55 }}>
              That's{" "}
              <strong style={{ color: C.mid }}>
                {Math.round(parseFloat(totalReclaimedYrs) * 365)} days
              </strong>{" "}
              — or{" "}
              <strong style={{ color: C.mid }}>
                {Math.round(parseFloat(totalReclaimedYrs) * 8760)} hours
              </strong>{" "}
              of reclaimed time.
            </div>
            <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
              {(() => {
                const hrs = parseFloat(totalReclaimedYrs) * 8760;
                // Generic equivalents everyone gets
                const equivs = [
                  {
                    icon: "📚",
                    text: `Read ${Math.round(hrs / 6)} books`,
                    sub: "at ~6 hours per book",
                  },
                  {
                    icon: "🌍",
                    text: `Learn ${Math.max(1, Math.round(hrs / 2000))} new language${Math.round(hrs / 2000) > 1 ? "s" : ""}`,
                    sub: "~2,000 hours to fluency (FSI estimate)",
                  },
                  {
                    icon: "🎸",
                    text: `Become an advanced musician`,
                    sub: `${Math.round(hrs).toLocaleString()} hours of practice`,
                  },
                  {
                    icon: "🏃",
                    text: `Run ${Math.round(hrs * 5).toLocaleString()} miles`,
                    sub: "at a comfortable 12-min mile pace",
                  },
                  {
                    icon: "💬",
                    text: `${Math.round(hrs).toLocaleString()} hours of real conversation`,
                    sub: "with people you actually choose",
                  },
                ];
                // Personalized based on selected interests
                const interestEquivs = [];
                const iKeys = interests.map((k) => k.toLowerCase());
                if (
                  iKeys.some((k) => k.includes("hik") || k.includes("nature") || k.includes("camp"))
                )
                  interestEquivs.push({
                    icon: "🥾",
                    text: `Hike every national park trail — twice`,
                    sub: `${Math.round(hrs / 3).toLocaleString()} hours on the trail`,
                  });
                if (
                  iKeys.some(
                    (k) =>
                      k.includes("art") ||
                      k.includes("draw") ||
                      k.includes("creative") ||
                      k.includes("craft")
                  )
                )
                  interestEquivs.push({
                    icon: "🎨",
                    text: `Create ${Math.round(hrs / 4).toLocaleString()} finished artworks`,
                    sub: "at ~4 hours per piece",
                  });
                if (iKeys.some((k) => k.includes("cook") || k.includes("bak")))
                  interestEquivs.push({
                    icon: "👨‍🍳",
                    text: `Master ${Math.round(hrs / 3)} new recipes`,
                    sub: "or become a genuinely great cook",
                  });
                if (
                  iKeys.some(
                    (k) => k.includes("music") || k.includes("guitar") || k.includes("piano")
                  )
                )
                  interestEquivs.push({
                    icon: "🎵",
                    text: `Go from beginner to advanced musician`,
                    sub: `${Math.round(hrs).toLocaleString()} hours — well past the 10,000 hour mark`,
                  });
                if (
                  iKeys.some(
                    (k) =>
                      k.includes("swim") ||
                      k.includes("run") ||
                      k.includes("gym") ||
                      k.includes("sport") ||
                      k.includes("yoga")
                  )
                )
                  interestEquivs.push({
                    icon: "💪",
                    text: `${Math.round(hrs / 1.5).toLocaleString()} workouts`,
                    sub: "enough to transform your body several times over",
                  });
                if (
                  iKeys.some((k) => k.includes("kid") || k.includes("family") || k.includes("play"))
                )
                  interestEquivs.push({
                    icon: "👨‍👩‍👧",
                    text: `${Math.round(hrs).toLocaleString()} more hours with your family`,
                    sub: "the kind of time you can't get back",
                  });
                // Show personalized first, then fill with generics
                const shown = [...interestEquivs.slice(0, 3), ...equivs].slice(0, 4);
                return shown.map((e, i) => (
                  <div
                    key={i}
                    style={{
                      display: "flex",
                      gap: 12,
                      padding: "10px 12px",
                      background: C.surfaceAlt,
                      borderRadius: 10,
                      border: `1px solid ${C.border}`,
                      alignItems: "flex-start",
                    }}
                  >
                    <span style={{ fontSize: 20, flexShrink: 0, lineHeight: 1.2 }}>{e.icon}</span>
                    <div>
                      <div style={{ fontSize: 14, fontWeight: 600, color: C.dark }}>{e.text}</div>
                      <div style={{ fontSize: 12, color: C.muted, marginTop: 1 }}>{e.sub}</div>
                    </div>
                  </div>
                ));
              })()}
            </div>
          </div>
        )}

        {/* "Now multiply that" moved to dedicated Step 9: The Bigger Picture */}

        {/* ── Balance card + media balance ────────────────────── */}
        <div
          style={{
            ...dCard(balGood ? "#053b38" : "#042f2e"),
            border: `1px solid ${balGood ? "rgba(74,222,128,0.2)" : "rgba(251,191,36,0.2)"}`,
          }}
        >
          <div style={{ ...sr, fontSize: 15, fontWeight: 700, marginBottom: 3, color: "white" }}>
            {balGood ? "Your Media Balance — healthy" : "Your Media Balance"}
          </div>
          <div
            style={{
              fontSize: 12,
              color: "rgba(255,255,255,0.7)",
              marginBottom: 12,
              fontStyle: "italic",
            }}
          >
            Of your {fmt(freeTime)} free time/day — not counting required screens
          </div>
          <div style={{ display: "flex", gap: 8, marginBottom: 12 }}>
            {[
              { v: actPct, l: "Activities", c: "#4ade80" },
              { v: idealPct, l: "Screen budget", c: balGood ? "#4ade80" : "#facc15" },
            ].map((x, i) => (
              <div
                key={i}
                style={{
                  flex: 1,
                  background: "rgba(255,255,255,0.07)",
                  borderRadius: 9,
                  padding: "13px 8px",
                  textAlign: "center",
                }}
              >
                <div style={{ ...sr, fontSize: 28, fontWeight: 700, color: x.c }}>{x.v}%</div>
                <div style={{ fontSize: 11, color: "rgba(255,255,255,0.7)", marginTop: 3 }}>
                  {x.l}
                </div>
              </div>
            ))}
          </div>
          <div style={{ fontSize: 13, color: "rgba(255,255,255,0.75)", lineHeight: 1.65 }}>
            {balGood
              ? `${actPct}% activities and ${idealPct}% screens — a healthy ratio.`
              : `${idealPct}% of your free time on screens. Research on adolescent social media use (Singh et al., JAMA Pediatrics 2026 — 100,991 adolescents) found that moderate users consistently showed better wellbeing outcomes than both heavy users and non-users — across happiness, optimism, emotional regulation, and focus. Balance is the goal. Your chosen amount is a real step toward it.`}
          </div>
        </div>

        {mt && (
          <div
            style={{
              background: "rgba(124,58,237,0.08)",
              border: `1px solid rgba(124,58,237,0.3)`,
              borderRadius: 12,
              padding: "13px 16px",
              marginBottom: 10,
            }}
          >
            <div style={{ ...sr, color: C.purple, fontSize: 14, fontWeight: 700, marginBottom: 5 }}>
              Heads up — your numbers are probably higher
            </div>
            <div style={{ fontSize: 13, color: C.dark, lineHeight: 1.65 }}>
              You use two screens simultaneously. These hours capture time — not the full cognitive
              cost of constant attention switching.
            </div>
          </div>
        )}

        {scrOverlap && (
          <div
            style={{
              background: "#faf5ff",
              borderRadius: 8,
              padding: "9px 13px",
              marginBottom: 10,
              fontSize: 12,
              color: "#6b21a8",
              border: "1px solid #d8b4fe",
            }}
          >
            ⚠️ You flagged personal use on {age >= 18 ? "work" : "school"} devices — your actual
            screen time may be higher than shown.
          </div>
        )}

        {/* ── Defragged life preview — what you're building toward as you adjust the sliders ── */}
        <div
          style={{
            background: "linear-gradient(135deg, #042f2e 0%, #053b38 100%)",
            borderRadius: 14,
            padding: "18px 16px",
            marginTop: 14,
            marginBottom: 10,
            border: "1px solid rgba(45,212,191,0.2)",
          }}
        >
          <div
            style={{
              fontSize: 11,
              fontWeight: 700,
              letterSpacing: "0.1em",
              textTransform: "uppercase",
              color: "rgba(45,212,191,0.7)",
              marginBottom: 6,
            }}
          >
            Preview
          </div>
          <div
            style={{
              ...sr,
              fontSize: 17,
              fontWeight: 700,
              color: "white",
              lineHeight: 1.3,
              marginBottom: 4,
            }}
          >
            Your defragged life
          </div>
          <div
            style={{
              fontSize: 12,
              color: "rgba(255,255,255,0.7)",
              lineHeight: 1.55,
              marginBottom: 12,
            }}
          >
            This is what your next {yearsRem} years look like with the choices above. Adjust the
            levers — watch the picture change.
          </div>
          <LabeledLifeGrid segments={defragGridSegs} totalMonths={totalM} revealScreens={true} />
        </div>

        <div style={{ display: "flex", gap: 10, flexWrap: "wrap", marginTop: 14 }}>
          <button
            onClick={() => {
              setStep(STEP.PBT);
              scrollToTop();
            }}
            style={{ ...bOutline, flex: 1 }}
          >
            ← Back to Protected Brain Time
          </button>
          <button
            onClick={() => {
              setStep(STEP.PLAN);
              scrollToTop();
            }}
            style={{ ...bPrimary, flex: 1 }}
          >
            Your Plan →
          </button>
        </div>
      </div>
    );
  };

  // ── STEP 8 of 9: YOUR PLAN ───────────────────────────────────────────────
  const PlanStep = () => {
    const recl = Math.max(0, sH - totalIdeal);
    const yw2 = Math.max(0, age - fd);
    const yg2 = (((sS + sH) * 365 * yw2) / 8760).toFixed(1);
    const [planOpen, setPlanOpen] = React.useState(null); // which plan section is expanded
    const [planAccord, setPlanAccord] = React.useState(null); // which summary accordion is open
    const [shareCopied, setShareCopied] = React.useState(false); // share button flash state
    // Build the share string once — used by both the Share button and any
    // future native-share integration. Keep it short enough to fit in an
    // SMS/tweet without truncation.
    const buildShareText = () => {
      const yrs = (totalReclaimedYrsGlobal || 0).toFixed(1);
      const bracket = getBracket(age).label;
      return `I just defragged my life. ${yrs} years of my future time are mine to keep — not spent watching someone else's feed.\n\n${bracket} · ${fmt(effectiveAdjScrH)}/day screen budget · ${improvedProtectedMinutes} min/day protected brain time\n\nFind your number: https://prompt-ed.org/defrag`;
    };
    const shareMyNumber = async () => {
      const text = buildShareText();
      // Prefer native share on mobile (iOS/Android); fall back to clipboard.
      try {
        if (navigator.share) {
          await navigator.share({ title: "My defrag. number", text });
          return;
        }
      } catch {
        // User cancelled or share failed — fall through to clipboard
      }
      try {
        await navigator.clipboard.writeText(text);
        setShareCopied(true);
        setTimeout(() => setShareCopied(false), 2400);
      } catch {
        // Last-resort fallback: select-and-copy via a hidden textarea
        try {
          const ta = document.createElement("textarea");
          ta.value = text;
          ta.setAttribute("readonly", "");
          ta.style.position = "absolute";
          ta.style.left = "-9999px";
          document.body.appendChild(ta);
          ta.select();
          document.execCommand("copy");
          document.body.removeChild(ta);
          setShareCopied(true);
          setTimeout(() => setShareCopied(false), 2400);
        } catch {}
      }
    };
    const PlanSection = ({ id, title, children }) => (
      <div
        style={{
          borderRadius: 10,
          marginBottom: 6,
          border: `1px solid ${C.border}`,
          overflow: "hidden",
        }}
      >
        <button
          onClick={() => setPlanOpen(planOpen === id ? null : id)}
          style={{
            width: "100%",
            display: "flex",
            justifyContent: "space-between",
            alignItems: "center",
            padding: "12px 14px",
            background: planOpen === id ? C.tealFaint : C.surface,
            border: "none",
            cursor: "pointer",
            textAlign: "left",
          }}
        >
          <span style={{ ...sr, fontSize: 14, fontWeight: 700, color: C.dark }}>{title}</span>
          <span
            style={{
              fontSize: 14,
              color: C.faint,
              transition: "transform 0.15s",
              transform: planOpen === id ? "rotate(180deg)" : "rotate(0deg)",
            }}
          >
            ▾
          </span>
        </button>
        {planOpen === id && <div style={{ padding: "6px 14px 14px" }}>{children}</div>}
      </div>
    );
    // defragGridSegs now hoisted to App level — accessible here via closure
    // Stats for recap
    const totalScrYrsFuture = (
      ((requiredDeviceH +
        (5 * effectiveAdjScrH + 2 * Math.min(effectiveAdjScrH + D.WEEKEND_DELTA_H, wkSH)) / 7) /
        24) *
      yearsRem
    ).toFixed(1);
    const intentionalScrYrs = ((effectiveAdjScrH / 24) * yearsRem).toFixed(1);
    const actYrs = ((actH / 24) * yearsRem).toFixed(1);
    const actToScrRatio = effectiveAdjScrH > 0 ? (actH / effectiveAdjScrH).toFixed(1) : "∞";
    const downloadPlan = () => {
      const now = new Date().toLocaleDateString();
      const html = `<!DOCTYPE html><html><head><meta charset="UTF-8"><title>My defrag. Plan</title><style>
body{font-family:Georgia,serif;max-width:680px;margin:40px auto;padding:0 20px;color:#042f2e;line-height:1.6;}
h1{font-size:32px;margin-bottom:4px;}.sub{color:#71717a;font-style:italic;margin-bottom:24px;}
.card{background:#fafafa;border:1px solid #e4e4e7;border-radius:12px;padding:18px;margin-bottom:14px;}
.stat{display:flex;justify-content:space-between;padding:6px 0;border-bottom:1px solid #e4e4e7;}
.stat:last-child{border-bottom:none;}.label{color:#71717a;}.value{font-weight:700;color:#0f766e;}
.big{font-size:36px;font-weight:700;color:#0f766e;text-align:center;margin:10px 0;}
.foot{text-align:center;color:#a1a1aa;font-size:12px;margin-top:30px;}
</style></head><body>
<h1>My defrag. Plan</h1><div class="sub">Generated ${now} · prompt-ed.org/defrag</div>
<div class="card"><div class="stat"><span class="label">Age</span><span class="value">${age}</span></div>
<div class="stat"><span class="label">Daily sleep</span><span class="value">${fmt(sleep)}</span></div>
<div class="stat"><span class="label">${age >= 18 ? "Work" : "School"} + commute</span><span class="value">${fmt(schoolH + commute)}</span></div>
<div class="stat"><span class="label">Daily free time</span><span class="value">${fmt(freeTime)}</span></div></div>
<div class="card"><div class="label" style="text-align:center;text-transform:uppercase;font-size:11px;letter-spacing:0.1em;">Years reclaimed</div>
<div class="big">+${(totalReclaimedYrsGlobal || 0).toFixed(1)}</div>
<div class="stat"><span class="label">Current personal screens</span><span class="value">${fmt(sH)}/day</span></div>
<div class="stat"><span class="label">Your screen budget</span><span class="value">${fmt(effectiveAdjScrH)}/day</span></div>
<div class="stat"><span class="label">Phone pickups (current → plan)</span><span class="value">${pkp} → ${adjPickups}/day</span></div>
<div class="stat"><span class="label">Protected brain time</span><span class="value">${protectedMinutes} → ${improvedProtectedMinutes} min/day</span></div></div>
<div class="card"><div style="font-weight:700;margin-bottom:8px;">Activities you want in your life:</div>
<div>${interests.length > 0 ? interests.join(" · ") : "(none selected)"}</div></div>
<div class="foot">The future belongs to the curious. · prompt-ed.org</div>
</body></html>`;
      const blob = new Blob([html], { type: "text/html" });
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = "my-defrag-plan.html";
      a.click();
      URL.revokeObjectURL(url);
    };
    return (
      <div>
        {/* ── Step header — dark branded with royal accent ── */}
        <div
          style={{
            background: "linear-gradient(135deg, #042f2e 0%, #1e1b4b 100%)",
            borderRadius: 16,
            padding: "28px 22px 20px",
            marginBottom: 12,
            border: "1px solid rgba(129,140,248,0.2)",
          }}
        >
          <div
            style={{
              fontSize: 11,
              fontWeight: 700,
              letterSpacing: "0.12em",
              textTransform: "uppercase",
              color: C.royal,
              marginBottom: 6,
            }}
          >
            Step 8 of 9
          </div>
          <h2
            style={{
              ...sr,
              color: "white",
              fontSize: "clamp(22px,5vw,28px)",
              marginBottom: 6,
              fontWeight: 700,
              lineHeight: 1.2,
            }}
          >
            Your Plan
          </h2>
          <div
            style={{
              fontSize: 14,
              color: "rgba(255,255,255,0.7)",
              lineHeight: 1.5,
              marginBottom: 14,
            }}
          >
            Here's what your defragged life looks like — the choices you've made, the math behind
            them, and how to protect it all.
          </div>
          <div style={{ display: "flex", gap: 8, flexWrap: "wrap", alignItems: "center" }}>
            <button
              onClick={downloadPlan}
              style={{
                background: C.royal,
                color: "white",
                border: "none",
                borderRadius: 20,
                padding: "10px 18px",
                fontSize: 13,
                fontWeight: 700,
                cursor: "pointer",
                boxShadow: "0 2px 8px rgba(129,140,248,0.3)",
              }}
            >
              ↓ Download Your Plan
            </button>
            <button
              onClick={shareMyNumber}
              aria-live="polite"
              style={{
                background: shareCopied ? C.tealBright : "transparent",
                color: shareCopied ? C.dark : "white",
                border: `1px solid ${shareCopied ? C.tealBright : "rgba(45,212,191,0.5)"}`,
                borderRadius: 20,
                padding: "10px 16px",
                fontSize: 13,
                fontWeight: 700,
                cursor: "pointer",
                transition: "all 0.15s",
              }}
            >
              {shareCopied ? "✓ Copied" : "Share my number"}
            </button>
            <button
              onClick={() => {
                if (confirm("Clear your saved answers and start over? This can't be undone.")) {
                  clearSavedSession();
                  window.location.reload();
                }
              }}
              style={{
                background: "transparent",
                color: "rgba(255,255,255,0.6)",
                border: "1px solid rgba(255,255,255,0.2)",
                borderRadius: 20,
                padding: "10px 16px",
                fontSize: 12,
                fontWeight: 500,
                cursor: "pointer",
              }}
            >
              Start over
            </button>
          </div>
        </div>

        {/* ── Fallback budget banner — user skipped Step 4 ── */}
        {usingFallbackBudget && (
          <div
            style={{
              background: "#fefce8",
              borderRadius: 10,
              padding: "12px 14px",
              marginBottom: 12,
              border: "1px solid #fde047",
              display: "flex",
              gap: 10,
              alignItems: "flex-start",
            }}
          >
            <div style={{ fontSize: 18, lineHeight: 1, flexShrink: 0 }}>⚠️</div>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 13, fontWeight: 700, color: "#713f12", marginBottom: 3 }}>
                Your plan uses a 1h/day placeholder
              </div>
              <div style={{ fontSize: 12, color: "#854d0e", lineHeight: 1.55, marginBottom: 6 }}>
                You didn't build a screen budget in Step 4 (Design Your Screen Time), so we're
                showing 1h/day as a stand-in. Go back to pick the screen activities that are worth
                it to you — your plan will update.
              </div>
              <button
                onClick={() => {
                  setStep(STEP.DESIGN);
                  scrollToTop();
                }}
                style={{
                  background: "#854d0e",
                  color: "white",
                  border: "none",
                  borderRadius: 6,
                  padding: "5px 12px",
                  fontSize: 11,
                  fontWeight: 700,
                  cursor: "pointer",
                }}
              >
                ← Go to Step 4
              </button>
            </div>
          </div>
        )}

        {/* ── YOUR IDEAL DAY SUMMARY ── */}
        <div
          style={{
            background: C.surface,
            borderRadius: 14,
            padding: "18px 18px",
            marginBottom: 12,
            border: `1px solid ${C.border}`,
          }}
        >
          <div style={{ ...sr, fontSize: 16, fontWeight: 700, color: C.dark, marginBottom: 12 }}>
            Your ideal day
          </div>

          {/* Activities accordion */}
          <div
            style={{
              borderRadius: 10,
              marginBottom: 6,
              border: `1px solid ${C.border}`,
              overflow: "hidden",
            }}
          >
            <button
              onClick={() => setPlanAccord(planAccord === "act" ? null : "act")}
              style={{
                width: "100%",
                display: "flex",
                justifyContent: "space-between",
                alignItems: "center",
                padding: "12px 14px",
                background: planAccord === "act" ? C.tealFaint : C.surfaceAlt,
                border: "none",
                cursor: "pointer",
                textAlign: "left",
              }}
            >
              <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                <div
                  style={{
                    width: 10,
                    height: 10,
                    borderRadius: 2,
                    background: GC.activities,
                    flexShrink: 0,
                  }}
                />
                <span style={{ fontSize: 14, fontWeight: 700, color: C.dark }}>
                  Real-life activities
                </span>
              </div>
              <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                <span style={{ ...sr, fontSize: 18, fontWeight: 700, color: C.mid }}>
                  {fmt(actH)}
                </span>
                <span
                  style={{
                    fontSize: 13,
                    color: C.faint,
                    transition: "transform 0.15s",
                    transform: planAccord === "act" ? "rotate(180deg)" : "rotate(0deg)",
                  }}
                >
                  ▾
                </span>
              </div>
            </button>
            {planAccord === "act" && (
              <div style={{ padding: "8px 14px 12px" }}>
                <div style={{ display: "flex", flexWrap: "wrap", gap: 5 }}>
                  {interests.map((k) => {
                    const label =
                      customLabels[k] ||
                      k.replace(/^(custom_|org_custom_|org_)[a-z]*_?/, "").replace(/_/g, " ");
                    return (
                      <span
                        key={k}
                        style={{
                          padding: "4px 10px",
                          borderRadius: 16,
                          background: C.tealFaint,
                          border: `1px solid ${C.tealLight}40`,
                          fontSize: 12,
                          color: C.dark,
                          fontWeight: 500,
                        }}
                      >
                        {label}
                      </span>
                    );
                  })}
                </div>
                <div style={{ fontSize: 12, color: C.muted, marginTop: 8 }}>
                  {Math.round(actH * 365)} hours/year · {actYrs} years over your lifetime
                </div>
              </div>
            )}
          </div>

          {/* Intentional screen time accordion */}
          <div
            style={{
              borderRadius: 10,
              marginBottom: 6,
              border: `1px solid ${C.border}`,
              overflow: "hidden",
            }}
          >
            <button
              onClick={() => setPlanAccord(planAccord === "scr" ? null : "scr")}
              style={{
                width: "100%",
                display: "flex",
                justifyContent: "space-between",
                alignItems: "center",
                padding: "12px 14px",
                background: planAccord === "scr" ? C.tealFaint : C.surfaceAlt,
                border: "none",
                cursor: "pointer",
                textAlign: "left",
              }}
            >
              <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                <div
                  style={{
                    width: 10,
                    height: 10,
                    borderRadius: 2,
                    background: GC.scrChosen,
                    flexShrink: 0,
                  }}
                />
                <span style={{ fontSize: 14, fontWeight: 700, color: C.dark }}>
                  Intentional screen time
                </span>
              </div>
              <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                <span style={{ ...sr, fontSize: 18, fontWeight: 700, color: C.purple }}>
                  {fmt(effectiveAdjScrH)}
                </span>
                <span
                  style={{
                    fontSize: 13,
                    color: C.faint,
                    transition: "transform 0.15s",
                    transform: planAccord === "scr" ? "rotate(180deg)" : "rotate(0deg)",
                  }}
                >
                  ▾
                </span>
              </div>
            </button>
            {planAccord === "scr" && (
              <div style={{ padding: "8px 14px 12px" }}>
                <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
                  {SCREEN_TYPES.filter((si) => screenChecked.includes(si.k)).map((si) => {
                    const d = sessionDailyAvg(si.k);
                    return d > 0 ? (
                      <div
                        key={si.k}
                        style={{
                          display: "flex",
                          justifyContent: "space-between",
                          fontSize: 12,
                          color: C.dark,
                          padding: "4px 8px",
                          background: C.surfaceAlt,
                          borderRadius: 4,
                        }}
                      >
                        <span>{si.label.split(" / ")[0]}</span>
                        <strong>{fmt(d)}</strong>
                      </div>
                    ) : null;
                  })}
                </div>
                <div style={{ fontSize: 12, color: C.muted, marginTop: 8 }}>
                  {effectiveAdjScrH < totalIdeal ? (
                    <>
                      Adjusted from {fmt(totalIdeal)} budget to {fmt(effectiveAdjScrH)} on Your
                      Possibilities page.
                    </>
                  ) : (
                    <>Based on your Invest Your Time screen budget.</>
                  )}
                </div>
              </div>
            )}
          </div>

          {/* Daily tasks */}
          <div
            style={{
              display: "flex",
              justifyContent: "space-between",
              alignItems: "center",
              padding: "12px 14px",
              background: C.surfaceAlt,
              borderRadius: 10,
              marginBottom: 6,
            }}
          >
            <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
              <div
                style={{
                  width: 10,
                  height: 10,
                  borderRadius: 2,
                  background: "#a78bfa",
                  flexShrink: 0,
                }}
              />
              <span style={{ fontSize: 14, fontWeight: 700, color: C.dark }}>Daily tasks</span>
            </div>
            <span style={{ ...sr, fontSize: 18, fontWeight: 700, color: C.dark }}>
              {fmt(hygiene + chores + meals + commute + (age >= 18 ? caregiving : 0))}
            </span>
          </div>

          {/* ── Goals from Possibilities ── */}
          <div
            style={{
              ...sr,
              fontSize: 13,
              fontWeight: 700,
              color: C.muted,
              marginTop: 14,
              marginBottom: 8,
              textTransform: "uppercase",
              letterSpacing: "0.06em",
            }}
          >
            Your Possibilities commitments
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 6 }}>
            <div
              style={{
                background: C.surfaceAlt,
                borderRadius: 10,
                padding: "10px 10px",
                textAlign: "center",
              }}
            >
              <div style={{ fontSize: 11, color: C.muted, marginBottom: 3 }}>Pickups</div>
              <div
                style={{
                  ...sr,
                  fontSize: 20,
                  fontWeight: 700,
                  color: adjPickups < pkp ? C.mid : C.dark,
                }}
              >
                {adjPickups}
                <span style={{ fontSize: 11, color: C.faint }}>/day</span>
              </div>
              {adjPickups < pkp && (
                <div style={{ fontSize: 10, color: C.mid, marginTop: 2 }}>was {pkp}</div>
              )}
            </div>
            <div
              style={{
                background: C.surfaceAlt,
                borderRadius: 10,
                padding: "10px 10px",
                textAlign: "center",
              }}
            >
              <div style={{ fontSize: 11, color: C.muted, marginBottom: 3 }}>Personal screens</div>
              <div
                style={{
                  ...sr,
                  fontSize: 20,
                  fontWeight: 700,
                  color: effectiveAdjScrH < sH ? C.mid : C.dark,
                }}
              >
                {fmt(effectiveAdjScrH)}
              </div>
              {effectiveAdjScrH < sH && (
                <div style={{ fontSize: 10, color: C.mid, marginTop: 2 }}>was {fmt(sH)}</div>
              )}
            </div>
            <div
              style={{
                background: C.surfaceAlt,
                borderRadius: 10,
                padding: "10px 10px",
                textAlign: "center",
              }}
            >
              <div style={{ fontSize: 11, color: C.muted, marginBottom: 3 }}>Filler eliminated</div>
              <div
                style={{
                  ...sr,
                  fontSize: 20,
                  fontWeight: 700,
                  color: fillerSavedMin > 0 ? C.mid : C.dark,
                }}
              >
                {fillerSavedMin > 0 ? `−${fillerSavedMin}m` : "—"}
              </div>
              {eliminatedFiller.length > 0 && (
                <div style={{ fontSize: 10, color: C.mid, marginTop: 2 }}>
                  {eliminatedFiller.length} window{eliminatedFiller.length > 1 ? "s" : ""}
                </div>
              )}
            </div>
          </div>
        </div>

        {/* ── WHAT THIS MEANS — 4 key stats ── */}
        <div
          style={{ background: C.dark, borderRadius: 14, padding: "20px 18px", marginBottom: 12 }}
        >
          <div style={{ ...sr, fontSize: 16, fontWeight: 700, color: "white", marginBottom: 14 }}>
            What this adds up to
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }}>
            <div
              style={{
                background: "rgba(255,255,255,0.06)",
                borderRadius: 10,
                padding: "14px 12px",
              }}
            >
              <div style={{ fontSize: 11, color: "rgba(255,255,255,0.75)", marginBottom: 4 }}>
                All screens, next {yearsRem} years
              </div>
              <div style={{ ...sr, fontSize: 24, fontWeight: 700, color: "#facc15" }}>
                {totalScrYrsFuture}
                <span style={{ fontSize: 12, color: "rgba(255,255,255,0.75)", marginLeft: 3 }}>
                  years
                </span>
              </div>
              <div style={{ fontSize: 11, color: "rgba(255,255,255,0.75)", marginTop: 3 }}>
                {age >= 18 ? "work" : "school"} + personal combined
              </div>
            </div>
            <div
              style={{
                background: "rgba(255,255,255,0.06)",
                borderRadius: 10,
                padding: "14px 12px",
              }}
            >
              <div style={{ fontSize: 11, color: "rgba(255,255,255,0.75)", marginBottom: 4 }}>
                Intentional screens only
              </div>
              <div style={{ ...sr, fontSize: 24, fontWeight: 700, color: C.tealBright }}>
                {intentionalScrYrs}
                <span style={{ fontSize: 12, color: "rgba(255,255,255,0.75)", marginLeft: 3 }}>
                  years
                </span>
              </div>
              <div style={{ fontSize: 11, color: "rgba(255,255,255,0.75)", marginTop: 3 }}>
                chosen, not default
              </div>
            </div>
            <div
              style={{
                background: "rgba(255,255,255,0.06)",
                borderRadius: 10,
                padding: "14px 12px",
              }}
            >
              <div style={{ fontSize: 11, color: "rgba(255,255,255,0.75)", marginBottom: 4 }}>
                Activities vs Screens
              </div>
              <div style={{ ...sr, fontSize: 24, fontWeight: 700, color: "#4ade80" }}>
                {actToScrRatio}
                <span style={{ fontSize: 12, color: "rgba(255,255,255,0.75)", marginLeft: 3 }}>
                  : 1
                </span>
              </div>
              <div style={{ fontSize: 11, color: "rgba(255,255,255,0.75)", marginTop: 3 }}>
                {fmt(actH)} activities · {fmt(effectiveAdjScrH)} screens
              </div>
            </div>
            <div
              style={{
                background: "rgba(45,212,191,0.1)",
                borderRadius: 10,
                padding: "14px 12px",
                border: "1px solid rgba(45,212,191,0.2)",
              }}
            >
              <div style={{ fontSize: 11, color: C.tealBright, marginBottom: 4 }}>
                Protected brain time
              </div>
              <div style={{ ...sr, fontSize: 24, fontWeight: 700, color: C.tealBright }}>
                {improvedProtectedMinutes}
                <span style={{ fontSize: 12, color: "rgba(255,255,255,0.75)", marginLeft: 3 }}>
                  min/day
                </span>
              </div>
              {protectedGainFromPlan > 0 && (
                <div style={{ fontSize: 11, color: C.tealBright, marginTop: 3 }}>
                  +{protectedGainFromPlan}m from your plan
                </div>
              )}
            </div>
          </div>
        </div>

        {/* ── DEFRAGGED LIFE BUBBLE CHART ── */}
        <div
          style={{
            background: C.surface,
            borderRadius: 14,
            padding: "16px 14px",
            marginBottom: 12,
            border: `1px solid ${C.border}`,
          }}
        >
          <div style={{ ...sr, fontSize: 16, fontWeight: 700, color: C.dark, marginBottom: 4 }}>
            Your defragged life
          </div>
          <div style={{ fontSize: 12, color: C.muted, marginBottom: 10 }}>
            Your next {yearsRem} years with your plan — activities, intentional screens, and open
            free time all visible.
          </div>
          <LabeledLifeGrid segments={defragGridSegs} totalMonths={totalM} revealScreens={true} />
          <div style={{ display: "flex", flexWrap: "wrap", gap: 6, marginTop: 10 }}>
            {[
              { c: GC.sleep, l: "Sleep" },
              { c: GC.school, l: age >= 18 ? "Work" : "School" },
              { c: "#3b82f6", l: "Daily tasks" },
              { c: GC.activities, l: "Activities" },
              { c: GC.scrChosen, l: "Intentional screens" },
              { c: GC.freeTime, l: "Open free time" },
            ].map((x) => (
              <div
                key={x.l}
                style={{
                  display: "flex",
                  alignItems: "center",
                  gap: 4,
                  fontSize: 11,
                  color: C.muted,
                }}
              >
                <div
                  style={{ width: 8, height: 8, borderRadius: 2, background: x.c, flexShrink: 0 }}
                />
                {x.l}
              </div>
            ))}
          </div>
        </div>

        {/* JAMA study — why balance matters */}
        <div
          style={{
            background: C.tealFaint,
            borderRadius: 12,
            padding: "14px 16px",
            border: `1px solid ${C.tealLight}40`,
            marginBottom: 10,
          }}
        >
          <div style={{ ...sr, fontSize: 14, fontWeight: 700, color: C.dark, marginBottom: 6 }}>
            The research says balance — not elimination
          </div>
          <div style={{ fontSize: 13, color: C.dark, lineHeight: 1.65 }}>
            The largest study on adolescent screen time and wellbeing (Singh et al., JAMA Pediatrics
            2026 — 100,991 students) found a U-shaped pattern:{" "}
            <strong style={{ color: C.mid }}>
              moderate screen users consistently showed better outcomes
            </strong>{" "}
            than both heavy users AND non-users — across happiness, optimism, emotional regulation,
            and focus. The goal isn't zero screens. It's intentional screens.
          </div>
        </div>

        {/* Parent section removed — merged into Action Plan accordion below */}

        {/* Filler screen time findings — from day walkthrough */}
        {(() => {
          const fillerMin = fillerMinutes;
          const audioMin = audioMinutes;
          const totalHiddenMin = fillerMin;
          return fillerMin > 0 || pkp > 100 ? (
            <div style={{ ...card, borderLeft: `3px solid ${C.mid}` }}>
              <div style={{ ...sr, fontSize: 14, color: C.dark, fontWeight: 700, marginBottom: 4 }}>
                Your invisible screen time
              </div>
              <div style={{ fontSize: 13, color: C.muted, lineHeight: 1.65, marginBottom: 10 }}>
                Your Screen Time report only captures intentional sessions. Based on your day
                walkthrough, here's what it misses:
              </div>
              <div style={{ display: "flex", flexDirection: "column", gap: 7 }}>
                {fillerMin > 0 && (
                  <div
                    style={{
                      display: "flex",
                      justifyContent: "space-between",
                      alignItems: "center",
                      background: "#f0fdfa",
                      borderRadius: 8,
                      padding: "9px 13px",
                    }}
                  >
                    <div>
                      <div style={{ fontSize: 13, fontWeight: 700, color: C.dark }}>
                        Filler screen time
                      </div>
                      <div style={{ fontSize: 11, color: C.muted }}>
                        Morning checks, meal scrolling, bedtime browsing
                      </div>
                    </div>
                    <div
                      style={{
                        fontSize: 15,
                        fontWeight: 700,
                        color: C.amber,
                        flexShrink: 0,
                        marginLeft: 10,
                      }}
                    >
                      ~{fillerMin} min/day
                    </div>
                  </div>
                )}
                <div
                  style={{
                    display: "flex",
                    justifyContent: "space-between",
                    alignItems: "center",
                    background: C.dark,
                    borderRadius: 8,
                    padding: "9px 13px",
                  }}
                >
                  <div style={{ fontSize: 13, fontWeight: 700, color: "white" }}>
                    Estimated total invisible time
                  </div>
                  <div
                    style={{
                      fontSize: 17,
                      fontWeight: 700,
                      color: "#facc15",
                      flexShrink: 0,
                      marginLeft: 10,
                    }}
                  >
                    ~{totalHiddenMin} min/day
                  </div>
                </div>
              </div>
              {audioMin > 0 && (
                <div style={{ fontSize: 12, color: C.muted, marginTop: 8, lineHeight: 1.55 }}>
                  Plus <strong>{audioMin} min/day</strong> of audio-occupied time (podcasts, music
                  during routines) — not screen time, but your brain is processing someone else's
                  content.
                </div>
              )}
              <div
                style={{
                  fontSize: 11,
                  color: C.muted,
                  lineHeight: 1.55,
                  marginTop: 6,
                  fontStyle: "italic",
                }}
              >
                These are estimates based on your day walkthrough answers, not precise measurements.
                Your actual invisible exposure may vary.
              </div>
            </div>
          ) : null;
        })()}

        {/* Honest truth — always visible */}
        <div
          style={{ background: C.dark, borderRadius: 12, padding: "14px 16px", marginBottom: 10 }}
        >
          <div style={{ fontSize: 14, color: "rgba(255,255,255,0.85)", lineHeight: 1.65 }}>
            <strong style={{ color: "white" }}>Knowing your number isn't enough.</strong> Platforms
            are engineered by behavioral scientists.{" "}
            <strong style={{ color: C.tealBright }}>Willpower alone won't work.</strong> The goal is
            designing your environment so the default becomes what you actually want.
          </div>
        </div>

        {/* ── Your Plan — action sections as expandable cards ── */}
        <div style={{ ...sr, fontSize: 16, fontWeight: 700, color: C.dark, marginBottom: 10 }}>
          Take action
        </div>

        <PlanSection id="strategies" title="10 Strategies That Actually Work">
          <StrategiesAccordion age={age} isParent={isParent} />
        </PlanSection>

        <PlanSection id="counterweights" title="Build What Screens Replace">
          <CounterweightsAccordion />
          {/* Parent-specific tips inside counterweights */}
          {age >= 18 && caregiving > 0 && (
            <div
              style={{ marginTop: 10, background: C.dark, borderRadius: 10, padding: "14px 16px" }}
            >
              <div
                style={{ ...sr, fontSize: 14, fontWeight: 700, color: "white", marginBottom: 8 }}
              >
                For parents: your habits are their curriculum
              </div>
              <div
                style={{
                  fontSize: 12,
                  color: "rgba(255,255,255,0.8)",
                  lineHeight: 1.6,
                  marginBottom: 8,
                }}
              >
                Research shows parental screen use is one of the strongest predictors of children's
                screen behavior (Guerrero et al., Pediatric Research 2024, University of Wollongong
                2025).
              </div>
              <div style={{ display: "flex", flexDirection: "column", gap: 5 }}>
                {[
                  "Phone-free meals — highest impact change for family screen culture",
                  "Charge ALL devices outside bedrooms — yours included",
                  "Name your screen use out loud — modeling intention vs. habit",
                  "Don't use screens to calm emotions — teach alternatives (AAP)",
                  "Co-view and discuss media together",
                  "One device-free family activity per week",
                  "Create a Family Media Plan together (AAP tool)",
                ].map((t, i) => (
                  <div key={i} style={{ display: "flex", gap: 7, alignItems: "flex-start" }}>
                    <div
                      style={{
                        width: 5,
                        height: 5,
                        borderRadius: "50%",
                        background: C.tealBright,
                        flexShrink: 0,
                        marginTop: 6,
                      }}
                    />
                    <span style={{ fontSize: 12, color: "rgba(255,255,255,0.8)", lineHeight: 1.5 }}>
                      {t}
                    </span>
                  </div>
                ))}
              </div>
            </div>
          )}
        </PlanSection>

        <PlanSection id="unplugging" title="The Science of Unplugging">
          <div style={dCard("#042f2e")}>
            <div style={{ ...sr, fontSize: 14, fontWeight: 700, marginBottom: 7, color: "white" }}>
              The 23-Minute Threshold
            </div>
            <p
              style={{
                fontSize: 13,
                color: "rgba(255,255,255,0.8)",
                lineHeight: 1.7,
                marginBottom: 5,
              }}
            >
              Dr. Gloria Mark (UC Irvine) found it takes{" "}
              <strong style={{ color: "#2dd4bf" }}>23 minutes and 15 seconds</strong> to fully
              return to a task after a digital interruption. Platforms are designed around variable
              reward schedules (B.F. Skinner; applied to tech design by Nir Eyal, <em>Hooked</em>,
              2014) — the same mechanism that makes intermittent reinforcement so hard to resist.
            </p>
            <p
              style={{
                fontSize: 12,
                color: "rgba(255,255,255,0.7)",
                fontStyle: "italic",
                lineHeight: 1.55,
                margin: 0,
              }}
            >
              Minutes 0–20: fighting the residue and the pull. Minutes 20–23: recovery. Minutes 23+:
              where something actually happens.
            </p>
          </div>
          <div style={dCard("#042f2e")}>
            <div style={{ ...sr, fontSize: 14, fontWeight: 700, marginBottom: 7, color: "white" }}>
              The 15–20 Minute Dopamine Pull
            </div>
            <p
              style={{
                fontSize: 13,
                color: "rgba(255,255,255,0.8)",
                lineHeight: 1.7,
                marginBottom: 8,
              }}
            >
              Around minute 15–20 of unplugging, your brain sends a strong signal to reach for your
              device. This isn't boredom — it's a trained craving. It peaks and passes in 3–5
              minutes if you don't feed it.
            </p>
            <div
              style={{
                background: "rgba(255,255,255,0.07)",
                borderRadius: 8,
                padding: "9px 12px",
                fontSize: 12,
                color: "rgba(255,255,255,0.75)",
                lineHeight: 1.6,
              }}
            >
              <strong>Strategy:</strong> When the urge arrives, say:{" "}
              <em>"That's the dopamine pull. It'll pass."</em> Research suggests naming emotions
              engages the prefrontal cortex and reduces their intensity (Lieberman et al.,
              Psychological Science, 2007).
            </div>
          </div>

          {/* ── THE UNPLUG CHALLENGE — urge surfing ── */}
          <div
            style={{ background: C.dark, borderRadius: 14, padding: "20px 20px", marginBottom: 10 }}
          >
            <div style={{ ...sr, fontSize: 17, fontWeight: 700, color: "white", marginBottom: 10 }}>
              The Unplug Challenge
            </div>
            <div
              style={{
                fontSize: 14,
                color: "rgba(255,255,255,0.85)",
                lineHeight: 1.7,
                marginBottom: 14,
              }}
            >
              When you put your phone down, the urge to check it typically peaks within{" "}
              <strong style={{ color: "#facc15" }}>a few minutes</strong>. It feels intense — but it
              passes. Research on smartphone withdrawal (Aarestad et al., 2023, SAGE Open) found
              withdrawal symptoms are strongest at the beginning and fluctuate with context. The key
              insight from urge surfing research: if you ride it out without acting, the craving
              subsides. Every time you resist, the next urge comes later and weaker.
            </div>
            <div
              style={{
                background: "rgba(255,255,255,0.06)",
                borderRadius: 10,
                padding: "14px 16px",
                marginBottom: 14,
              }}
            >
              <div style={{ fontSize: 13, fontWeight: 700, color: "white", marginBottom: 8 }}>
                Try this today — build up over time:
              </div>
              <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
                {[
                  {
                    time: "5 min",
                    desc: "Put your phone in another room. The craving will peak around 3–5 minutes. Name it: 'That's the pull.' It passes in minutes, not hours.",
                    c: C.tealBright,
                  },
                  {
                    time: "15 min",
                    desc: "The urge has faded. You've ridden out the hardest part. Most people never make it here — their hand moves before they decide.",
                    c: C.tealBright,
                  },
                  {
                    time: "23 min",
                    desc: "The Gloria Mark threshold — genuine focus recovery begins. Your default mode network starts to activate.",
                    c: "#facc15",
                  },
                  {
                    time: "45–60 min",
                    desc: "Deep reset territory. Boredom arrives — and with it, creativity, self-reflection, and original thought.",
                    c: "#facc15",
                  },
                ].map(({ time, desc, c }) => (
                  <div key={time} style={{ display: "flex", gap: 10, alignItems: "flex-start" }}>
                    <div
                      style={{
                        ...sr,
                        fontSize: 14,
                        fontWeight: 700,
                        color: c,
                        minWidth: 52,
                        flexShrink: 0,
                      }}
                    >
                      {time}
                    </div>
                    <div
                      style={{ fontSize: 13, color: "rgba(255,255,255,0.75)", lineHeight: 1.55 }}
                    >
                      {desc}
                    </div>
                  </div>
                ))}
              </div>
            </div>
            <div
              style={{
                fontSize: 13,
                color: "rgba(255,255,255,0.65)",
                lineHeight: 1.6,
                fontStyle: "italic",
              }}
            >
              This is called{" "}
              <strong style={{ color: "white", fontStyle: "normal" }}>urge surfing</strong> —
              observing the craving without acting on it. Research from the University of Washington
              shows that urges, left unacted on, always peak and subside. The more you practice, the
              weaker and less frequent they become.
            </div>
          </div>

          <div style={card}>
            <div style={{ ...sr, fontSize: 14, color: C.dark, fontWeight: 700, marginBottom: 12 }}>
              What actually happens when you unplug
            </div>
            {TIMELINE.map((t, i) => (
              <div
                key={i}
                style={{
                  display: "flex",
                  gap: 9,
                  marginBottom: 9,
                  alignItems: "flex-start",
                  ...(t.dng
                    ? {
                        background: "rgba(159,18,57,0.04)",
                        borderRadius: 8,
                        padding: "6px 6px 6px 0",
                      }
                    : {}),
                }}
              >
                <div
                  style={{
                    background: t.c,
                    color: "white",
                    borderRadius: 5,
                    padding: "3px 7px",
                    fontSize: 10,
                    fontWeight: 700,
                    minWidth: 64,
                    textAlign: "center",
                    flexShrink: 0,
                    lineHeight: 1.5,
                  }}
                >
                  {t.t}
                </div>
                <div>
                  <div style={{ fontWeight: 700, fontSize: 13, color: t.dng ? "#dc2626" : C.dark }}>
                    {t.l}
                  </div>
                  <div style={{ fontSize: 12, color: C.muted, lineHeight: 1.55 }}>{t.d}</div>
                </div>
              </div>
            ))}
          </div>

          <div style={card}>
            <div style={{ ...sr, fontSize: 15, color: C.dark, fontWeight: 700, marginBottom: 10 }}>
              Your three layers of intentional time
            </div>
            <div style={{ fontSize: 13, color: C.muted, lineHeight: 1.65, marginBottom: 14 }}>
              Protecting time isn't just about unplugging — it's about building a day where screens
              fill what's left, not what comes first. Here's what you've designed:
            </div>

            {/* Three layers visual */}
            <div style={{ display: "flex", flexDirection: "column", gap: 8, marginBottom: 14 }}>
              <div
                style={{
                  background: C.tealFaint,
                  borderRadius: 10,
                  padding: "12px 14px",
                  border: `1px solid ${C.tealLight}40`,
                  display: "flex",
                  justifyContent: "space-between",
                  alignItems: "center",
                }}
              >
                <div>
                  <div style={{ fontSize: 13, fontWeight: 700, color: C.dark }}>
                    Layer 1: Real-world activities
                  </div>
                  <div style={{ fontSize: 12, color: C.muted }}>
                    The things you chose to invest in
                  </div>
                </div>
                <div style={{ ...sr, fontSize: 20, fontWeight: 700, color: C.mid }}>
                  {fmt(actH)}
                </div>
              </div>
              <div
                style={{
                  background: C.surfaceAlt,
                  borderRadius: 10,
                  padding: "12px 14px",
                  border: `1px solid ${C.border}`,
                  display: "flex",
                  justifyContent: "space-between",
                  alignItems: "center",
                }}
              >
                <div>
                  <div style={{ fontSize: 13, fontWeight: 700, color: C.dark }}>
                    Layer 2: Intentional screen time
                  </div>
                  <div style={{ fontSize: 12, color: C.muted }}>
                    The screen time you actually want
                  </div>
                </div>
                <div style={{ ...sr, fontSize: 20, fontWeight: 700, color: "#facc15" }}>
                  {fmt(totalIdeal)}
                </div>
              </div>
              <div
                style={{
                  background: C.dark,
                  borderRadius: 10,
                  padding: "12px 14px",
                  display: "flex",
                  justifyContent: "space-between",
                  alignItems: "center",
                }}
              >
                <div>
                  <div style={{ fontSize: 13, fontWeight: 700, color: "white" }}>
                    Layer 3: Protected brain time
                  </div>
                  <div style={{ fontSize: 12, color: "rgba(255,255,255,0.7)" }}>
                    Time where no one else's content enters your brain
                  </div>
                </div>
                <div style={{ ...sr, fontSize: 20, fontWeight: 700, color: C.tealBright }}>
                  {improvedProtectedMinutes}m
                </div>
              </div>
            </div>

            <div
              style={{
                background: C.surfaceAlt,
                borderRadius: 8,
                padding: "10px 12px",
                border: `1px solid ${C.border}`,
                fontSize: 13,
                color: C.dark,
                lineHeight: 1.6,
              }}
            >
              <strong style={{ color: C.mid }}>Layer 3 is the one most people skip.</strong> Protect
              at least one unbroken{" "}
              {age < 13 ? "1–2 hour" : age < 18 ? "45–60 minute" : "30–45 minute"} block per day —
              no screens, no audio, no one else's agenda. The urge to check your phone peaks in 3–5
              minutes and passes within 10–15. Ride it out once, and it gets easier every time.
            </div>
          </div>

          <div
            style={{
              background: C.tealFaint,
              borderRadius: 12,
              padding: "16px 18px",
              marginBottom: 18,
              border: `1px solid ${C.tealLight}40`,
            }}
          >
            <p
              style={{
                ...sr,
                fontStyle: "italic",
                color: C.mid,
                fontSize: 14,
                lineHeight: 1.7,
                marginBottom: 6,
              }}
            >
              "Technology doesn't steal time. It occupies the time we haven't yet decided to
              protect. You just made that decision."
            </p>
            <div style={{ fontSize: 13, color: C.muted }}>
              — Rebecca Guglielmo · <strong style={{ color: C.mid }}>defrag.</strong> ·
              prompt-ed.org
            </div>
          </div>

          {/* ── Email capture ── */}
          <div style={{ ...card, border: `1.5px solid ${C.mid}40` }}>
            <div style={{ ...sr, fontSize: 16, color: C.dark, fontWeight: 700, marginBottom: 4 }}>
              Get your report by email
            </div>
            <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.55, marginBottom: 14 }}>
              We'll send you a summary of your plan — your free time, your chosen balance, and your
              reclaimed years. No account required.
            </p>
            {emailSent ? (
              <div
                style={{
                  background: C.tealFaint,
                  border: `1px solid ${C.tealLight}60`,
                  borderRadius: 10,
                  padding: "14px 16px",
                  textAlign: "center",
                }}
              >
                <div
                  style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.mid, marginBottom: 4 }}
                >
                  ✓ Report on its way
                </div>
                <div style={{ fontSize: 13, color: C.muted }}>
                  Check your inbox — and come back monthly. The algorithm never stops.
                </div>
              </div>
            ) : (
              <div>
                <input
                  type="email"
                  placeholder="your@email.com"
                  value={emailVal}
                  onChange={(e) => {
                    setEmailVal(e.target.value);
                    setEmailError("");
                  }}
                  style={{
                    width: "100%",
                    padding: "11px 14px",
                    borderRadius: 10,
                    border: `1.5px solid ${emailError ? C.red : C.border}`,
                    fontSize: 14,
                    color: C.dark,
                    background: C.surfaceAlt,
                    outline: "none",
                    marginBottom: 8,
                    boxSizing: "border-box",
                  }}
                />
                {emailError && (
                  <div style={{ fontSize: 12, color: C.red, marginBottom: 8 }}>{emailError}</div>
                )}
                <div
                  style={{
                    display: "flex",
                    alignItems: "center",
                    gap: 9,
                    marginBottom: 14,
                    cursor: "pointer",
                  }}
                  onClick={() => setEmailNewsletter((v) => !v)}
                >
                  <div
                    style={{
                      width: 18,
                      height: 18,
                      borderRadius: 5,
                      border: `2px solid ${emailNewsletter ? C.mid : C.border}`,
                      background: emailNewsletter ? C.mid : "transparent",
                      display: "flex",
                      alignItems: "center",
                      justifyContent: "center",
                      flexShrink: 0,
                      transition: "all 0.15s",
                    }}
                  >
                    {emailNewsletter && (
                      <span style={{ color: "white", fontSize: 12, lineHeight: 1 }}>✓</span>
                    )}
                  </div>
                  <span style={{ fontSize: 13, color: C.muted, lineHeight: 1.45 }}>
                    Also subscribe to the{" "}
                    <strong style={{ color: C.dark }}>defrag. newsletter</strong> — monthly insights
                    on screen time, attention, and reclaiming your inner world.
                  </span>
                </div>
                <button
                  onClick={() => {
                    const v = emailVal.trim();
                    if (!v || !v.includes("@") || !v.includes(".")) {
                      setEmailError("Please enter a valid email address.");
                      return;
                    }
                    setEmailSent(true);
                  }}
                  style={{ ...bPrimary, width: "100%", padding: "13px 18px", fontSize: 14 }}
                >
                  Email my report →
                </button>
                <div style={{ fontSize: 11, color: C.faint, marginTop: 9, textAlign: "center" }}>
                  Your email is never shared or sold. Unsubscribe anytime.
                </div>
              </div>
            )}
          </div>
        </PlanSection>

        {/* Trajectory card — under 18 */}
        {age < 18 &&
          (() => {
            // Current pace: calendar years on screens at current sH
            const currScrH = effSH;
            const currYrs = ((currScrH / 24) * yearsRem).toFixed(1);
            const currWakPct = Math.round((currScrH / wakingHrs) * 100);
            // National teen trajectory at 18: 8h/day personal + ~3h school screens
            const natScrH = 8;
            const natYrs = ((natScrH / 24) * yearsRem).toFixed(1);
            const natWakPct = Math.round((natScrH / wakingHrs) * 100);
            // Intentional path: totalIdeal (chosen screen time from Step 2)
            const intScrH = Math.max(totalIdeal, 0.5);
            const intYrs = ((intScrH / 24) * yearsRem).toFixed(1);
            const intWakPct = Math.round((intScrH / wakingHrs) * 100);
            const alreadyHigh = currScrH >= natScrH * 0.8;

            return (
              <div
                style={{
                  ...dCard("#042f2e"),
                  border: "1px solid rgba(99,102,241,0.3)",
                  marginBottom: 10,
                }}
              >
                <div style={{ ...lbl12, color: "rgba(255,255,255,0.7)" }}>The fork in the road</div>
                <div
                  style={{ ...sr, fontSize: 16, fontWeight: 700, color: "white", marginBottom: 8 }}
                >
                  {isLightUser
                    ? "What you're protecting — and what drift would cost."
                    : "Three paths. Same starting point. Very different lives."}
                </div>
                <p
                  style={{
                    fontSize: 13,
                    color: "rgba(255,255,255,0.65)",
                    lineHeight: 1.7,
                    marginBottom: 16,
                  }}
                >
                  {isLightUser && age < 13
                    ? "You're ahead of the curve. But screen use almost always increases through adolescence — as organized activities fall away and free time opens up. Here's what staying intentional looks like compared to drifting toward the average."
                    : isLightUser && age < 18
                      ? "Your screen time is lower than most people your age. That's not an accident — it's the result of choices being made now. Here's what protecting that balance means over time."
                      : age < 13
                        ? "Screen use almost always increases through adolescence — just as organized activities fall away and free time opens up. Here's what the data says, and what a different choice looks like."
                        : "The transition out of organized activities is when free time opens up most — and when screen time tends to accelerate most. What fills that space is the whole question. Here's what three different answers look like."}
                </p>

                {/* Three path rows */}
                {[
                  {
                    label: "At your current pace",
                    scrH: currScrH,
                    yrs: currYrs,
                    pct: currWakPct,
                    c: "#facc15",
                    note: `${currScrH.toFixed(1)}h/day personal screens · your numbers from Step 3`,
                    barW: Math.min(100, Math.round((currScrH / 12) * 100)),
                  },
                  ...(!alreadyHigh
                    ? [
                        {
                          label: age < 18 ? "National average at 16–18" : "National average",
                          scrH: natScrH,
                          yrs: natYrs,
                          pct: natWakPct,
                          c: "#f87171",
                          note:
                            age < 18
                              ? "8h/day personal screens — where most teens land"
                              : `${natScrH.toFixed(1)}h/day personal screens — the national average for adults`,
                          barW: Math.min(100, Math.round((natScrH / 12) * 100)),
                        },
                      ]
                    : []),
                  {
                    label: "The intentional path",
                    scrH: intScrH,
                    yrs: intYrs,
                    pct: intWakPct,
                    c: "#34d399",
                    note: `${intScrH.toFixed(1)}h/day personal screens · your intentional choice from Step 2`,
                    barW: Math.min(100, Math.round((intScrH / 12) * 100)),
                  },
                ].map(({ label, scrH, yrs, pct, c, note, barW }) => (
                  <div key={label} style={{ marginBottom: 14 }}>
                    <div
                      style={{
                        display: "flex",
                        justifyContent: "space-between",
                        alignItems: "baseline",
                        marginBottom: 4,
                      }}
                    >
                      <span style={{ fontSize: 13, fontWeight: 700, color: c }}>{label}</span>
                      <span
                        style={{
                          fontSize: 12,
                          color: "rgba(255,255,255,0.75)",
                          fontFamily: "'SF Mono',Menlo,monospace",
                        }}
                      >
                        {yrs} yrs · {pct}% waking
                      </span>
                    </div>
                    {/* Progress bar */}
                    <div
                      style={{
                        height: 8,
                        borderRadius: 4,
                        background: "rgba(255,255,255,0.08)",
                        overflow: "hidden",
                        marginBottom: 4,
                      }}
                    >
                      <div
                        style={{
                          height: "100%",
                          width: `${barW}%`,
                          borderRadius: 4,
                          background: c,
                          opacity: 0.85,
                        }}
                      />
                    </div>
                    <div style={{ fontSize: 11, color: "rgba(255,255,255,0.7)", lineHeight: 1.5 }}>
                      {note}
                    </div>
                  </div>
                ))}

                {/* Gap callout */}
                {parseFloat(natYrs) > parseFloat(intYrs) && age < 13 && !alreadyHigh && (
                  <div
                    style={{
                      background: "rgba(52,211,153,0.1)",
                      borderRadius: 9,
                      padding: "10px 13px",
                      border: "0.5px solid rgba(52,211,153,0.25)",
                      marginTop: 4,
                    }}
                  >
                    <div
                      style={{ fontSize: 13, color: "#34d399", fontWeight: 700, marginBottom: 3 }}
                    >
                      The gap between path 2 and path 3:{" "}
                      {(parseFloat(natYrs) - parseFloat(intYrs)).toFixed(1)} years.
                    </div>
                    <div
                      style={{ fontSize: 12, color: "rgba(255,255,255,0.75)", lineHeight: 1.65 }}
                    >
                      That's the difference between following the national average and choosing
                      differently. The window to build those habits is now — before the phone
                      arrives with fewer guardrails and more persuasive design.
                    </div>
                  </div>
                )}

                <div
                  style={{
                    marginTop: 12,
                    fontSize: 11,
                    color: "rgba(255,255,255,0.7)",
                    fontStyle: "italic",
                    lineHeight: 1.55,
                  }}
                >
                  Calendar years based on {yearsRem} years remaining. National average from Common
                  Sense Media and Pew Research. These are projections, not predictions — the point
                  is the direction, not the exact number.
                </div>
              </div>
            );
          })()}

        {/* Kids — invisible displacement + before the phone cards */}
        {age < 13 && (
          <>
            {/* Card 1 — invisible displacement */}
            <div
              style={{
                ...dCard("#1e1b4b"),
                border: "1px solid rgba(129,140,248,0.25)",
                marginBottom: 10,
              }}
            >
              <div style={{ ...lbl12, color: "rgba(255,255,255,0.7)" }}>
                What the data can't capture
              </div>
              <div
                style={{ ...sr, fontSize: 16, fontWeight: 700, color: "white", marginBottom: 8 }}
              >
                The invisible displacement.
              </div>
              <p
                style={{
                  fontSize: 13,
                  color: "rgba(255,255,255,0.75)",
                  lineHeight: 1.7,
                  marginBottom: 10,
                }}
              >
                When screen time displaces sleep, eating, and hygiene — we can measure that. It
                shows up in the pie chart. But there's a displacement that doesn't appear anywhere
                in this tool, because it has no hours to subtract.
              </p>
              <p
                style={{
                  fontSize: 13,
                  color: "rgba(255,255,255,0.75)",
                  lineHeight: 1.7,
                  marginBottom: 10,
                }}
              >
                Unstructured play. Boredom. Imaginative time. The moments when a child has nothing
                to do and has to figure out what to do with that. This is where creativity develops.
                Where emotional regulation is practiced. Where identity begins to form — quietly,
                without an audience, without a screen.
              </p>
              <p
                style={{
                  fontSize: 13,
                  color: "rgba(255,255,255,0.75)",
                  lineHeight: 1.7,
                  marginBottom: 0,
                }}
              >
                Research on the default mode network — the brain system responsible for creativity,
                self-reflection, and memory consolidation — shows it activates during genuine rest
                and mind-wandering. It doesn't activate during passive screen consumption. Those
                hours aren't just occupied. They displace the developmental work that can only
                happen in the gaps.
              </p>
            </div>

            {/* Card 2 — before the phone */}
            <div style={{ ...dCard(C.dark), border: `1px solid ${C.mid}40`, marginBottom: 10 }}>
              <div style={{ ...lbl12, color: "rgba(255,255,255,0.7)" }}>A note for parents</div>
              <div
                style={{ ...sr, fontSize: 16, fontWeight: 700, color: "white", marginBottom: 8 }}
              >
                The phone isn't the beginning. It's the reveal.
              </div>
              <p
                style={{
                  fontSize: 13,
                  color: "rgba(255,255,255,0.75)",
                  lineHeight: 1.7,
                  marginBottom: 10,
                }}
              >
                Most conversations about kids and phones are framed around a threshold — at what
                age, under what conditions. But by the time a child gets a phone, their relationship
                with screens is already years in the making.
              </p>
              <p
                style={{
                  fontSize: 13,
                  color: "rgba(255,255,255,0.75)",
                  lineHeight: 1.7,
                  marginBottom: 10,
                }}
              >
                The iPad at four. The gaming console at seven. The YouTube rabbit holes at nine.
                Each of those moments was either building habits of self-regulation and intentional
                use — or it wasn't. The phone doesn't create the problem. It reveals it, at higher
                stakes, with far more persuasive technology and far less parental visibility.
              </p>
              <p
                style={{
                  fontSize: 13,
                  color: "rgba(255,255,255,0.75)",
                  lineHeight: 1.7,
                  marginBottom: 12,
                }}
              >
                The most important question isn't when to give your child a phone. It's what you're
                modeling right now — and what habits are forming on the devices they already have.
              </p>
              <div
                style={{
                  background: "rgba(255,255,255,0.06)",
                  borderRadius: 9,
                  padding: "12px 14px",
                  borderLeft: `3px solid ${C.mid}`,
                }}
              >
                <div style={{ fontSize: 13, color: "rgba(255,255,255,0.6)", lineHeight: 1.65 }}>
                  If a child grows up with limits that are inconsistent, negotiated away, or quietly
                  ignored — they're learning that screens are something you resist, not something
                  you choose. That's a much harder habit to change when they get a phone and gain
                  access to content designed by behavioral scientists to be as compelling as
                  possible.
                </div>
              </div>
            </div>
          </>
        )}

        <div
          style={{
            background: C.tealFaint,
            border: `1px solid ${C.tealLight}40`,
            borderRadius: 10,
            padding: "14px 16px",
          }}
        >
          <div style={{ ...sr, fontSize: 14, color: C.dark, fontWeight: 700, marginBottom: 3 }}>
            defrag. is in early access.
          </div>
          <div style={{ fontSize: 13, color: C.muted, lineHeight: 1.55, marginBottom: 10 }}>
            Come back as your life changes — monthly is a good rhythm.
          </div>
          <div style={{ display: "flex", gap: 7, flexWrap: "wrap" }}>
            <button
              style={{
                fontSize: 12,
                background: C.surface,
                border: `1px solid ${C.border}`,
                color: C.dark,
                borderRadius: 8,
                padding: "7px 15px",
                cursor: "pointer",
              }}
            >
              Report a bug
            </button>
            <button
              style={{
                fontSize: 12,
                background: C.surface,
                border: `1px solid ${C.border}`,
                color: C.dark,
                borderRadius: 8,
                padding: "7px 15px",
                cursor: "pointer",
              }}
            >
              Share a suggestion
            </button>
          </div>
        </div>
      </div>
    );
  };

  // ── STEP 4: DESIGN YOUR SCREEN TIME ─────────────────────────────────────
  const DesignScreenTime = () => {
    const remainingFree = Math.max(0, freeTime - actH);
    return (
      <div>
        <div
          style={{
            fontSize: 11,
            fontWeight: 700,
            letterSpacing: "0.12em",
            textTransform: "uppercase",
            color: C.royal,
            marginBottom: 4,
          }}
        >
          Step 4 of 9
        </div>
        <h2
          style={{
            ...sr,
            color: C.dark,
            fontSize: 22,
            marginBottom: 4,
            fontWeight: 700,
            lineHeight: 1.2,
          }}
        >
          Design Your Screen Time
        </h2>
        <div style={{ fontSize: 14, color: C.muted, lineHeight: 1.5, marginBottom: 16 }}>
          You told us what you want your life to contain. Now — how much screen time fits?
        </div>

        <div
          style={{ background: C.dark, borderRadius: 14, padding: "24px 22px", marginBottom: 16 }}
        >
          <div
            style={{
              ...sr,
              fontSize: "clamp(20px,5vw,26px)",
              fontWeight: 700,
              color: "white",
              marginBottom: 10,
              lineHeight: 1.2,
            }}
          >
            Your remaining free time
          </div>
          <div
            style={{
              background: "rgba(255,255,255,0.08)",
              borderRadius: 10,
              padding: "12px 14px",
              marginBottom: 12,
              display: "flex",
              justifyContent: "space-between",
              alignItems: "center",
            }}
          >
            <span style={{ fontSize: 14, color: "rgba(255,255,255,0.85)" }}>
              After obligations and activities
            </span>
            <span style={{ ...sr, fontSize: 24, fontWeight: 700, color: C.tealBright }}>
              {fmt(remainingFree)}
            </span>
          </div>
          <div style={{ fontSize: 13, color: "rgba(255,255,255,0.75)", lineHeight: 1.7 }}>
            If you could start over — no habits, no defaults — how would you actually want to spend
            your screen time? Be honest. Some screen time is genuinely good. This isn't about
            restriction — it's about intention.
          </div>
        </div>

        <div
          style={{
            background: C.surface,
            border: `1px solid ${C.border}`,
            borderRadius: 14,
            padding: 18,
            marginBottom: 10,
          }}
        >
          <div style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.dark, marginBottom: 4 }}>
            What screen time do you actually want?
          </div>
          <div style={{ fontSize: 12, color: C.muted, marginBottom: 12, lineHeight: 1.5 }}>
            Tap any that deserve a real place in your day. Skip anything that's just default
            scrolling.
          </div>
          {SCREEN_TYPES.filter((si) => !(age < 13 && si.k === "news")).map((si) => {
            const on = screenChecked.includes(si.k);
            return (
              <button
                key={si.k}
                type="button"
                role="checkbox"
                aria-checked={on}
                aria-label={`${si.label}. ${si.sub}`}
                onClick={() =>
                  setScreenChecked(
                    on ? screenChecked.filter((x) => x !== si.k) : [...screenChecked, si.k]
                  )
                }
                style={{
                  display: "flex",
                  width: "100%",
                  textAlign: "left",
                  gap: 12,
                  padding: "10px 12px",
                  borderRadius: 10,
                  marginBottom: 5,
                  cursor: "pointer",
                  background: on ? "#f0fdfa" : C.surfaceAlt,
                  border: `1px solid ${on ? C.tealLight : C.border}`,
                  transition: "all 0.15s",
                  fontFamily: "inherit",
                }}
              >
                <div
                  style={{
                    width: 18,
                    height: 18,
                    borderRadius: 5,
                    border: `2px solid ${on ? si.col : C.border}`,
                    background: on ? si.col : "transparent",
                    display: "flex",
                    alignItems: "center",
                    justifyContent: "center",
                    flexShrink: 0,
                    marginTop: 2,
                  }}
                  aria-hidden="true"
                >
                  {on && (
                    <span style={{ color: "white", fontSize: 11, lineHeight: 1, fontWeight: 700 }}>
                      ✓
                    </span>
                  )}
                </div>
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 13, fontWeight: on ? 700 : 500, color: C.dark }}>
                    {si.label}
                  </div>
                  <div style={{ fontSize: 11, color: C.muted, lineHeight: 1.4, marginTop: 1 }}>
                    {si.sub}
                  </div>
                </div>
                {on && screenSessions[si.k] && (
                  <div
                    style={{
                      fontSize: 11,
                      color: C.mid,
                      fontWeight: 600,
                      flexShrink: 0,
                      alignSelf: "center",
                    }}
                  >
                    {fmt(sessionDailyAvg(si.k))}
                  </div>
                )}
              </button>
            );
          })}

          {screenChecked.length > 0 && (
            <div
              style={{
                background: C.tealFaint,
                borderRadius: 10,
                padding: "12px 14px",
                marginTop: 10,
                border: `1px solid ${C.tealLight}40`,
              }}
            >
              <div
                style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}
              >
                <span style={{ fontSize: 13, fontWeight: 600, color: C.dark }}>
                  Your ideal screen budget
                </span>
                <span style={{ ...sr, fontSize: 20, fontWeight: 700, color: C.mid }}>
                  {fmt(Math.max(totalIdeal, D.FALLBACK_SCREEN_BUDGET_H))}
                </span>
              </div>
              <div style={{ fontSize: 11, color: C.muted, marginTop: 4 }}>
                of your {fmt(remainingFree)} remaining free time
              </div>
            </div>
          )}

          {screenChecked.length === 0 && (
            <div
              style={{
                background: C.tealFaint,
                borderRadius: 10,
                padding: "12px 14px",
                marginTop: 10,
                border: `1px solid ${C.tealLight}40`,
              }}
            >
              <div style={{ fontSize: 13, color: C.dark, lineHeight: 1.6 }}>
                <strong style={{ color: C.mid }}>No screen categories selected?</strong> That's fine
                — we'll use a 1-hour baseline. You can always adjust on the Possibilities page.
              </div>
            </div>
          )}
        </div>

        <div style={{ ...dCard(), textAlign: "center", padding: "20px 22px", marginTop: 8 }}>
          <div style={{ ...sr, fontSize: 17, color: "#2dd4bf", fontWeight: 700, marginBottom: 6 }}>
            Screen budget set. Now let's see your reality.
          </div>
          <div style={{ fontSize: 13, color: "rgba(255,255,255,0.75)", lineHeight: 1.6 }}>
            The next step shows what all of this means — across your day, your free time, and your
            lifetime.
          </div>
        </div>
      </div>
    );
  };

  // ── STEP 6: PROTECTED BRAIN TIME ───────────────────────────────────────────
  const ProtectedBrainTimeStep = () => {
    return (
      <div>
        <div
          style={{
            fontSize: 11,
            fontWeight: 700,
            letterSpacing: "0.12em",
            textTransform: "uppercase",
            color: C.royal,
            marginBottom: 4,
          }}
        >
          Step 6 of 9
        </div>
        <h2
          style={{
            ...sr,
            color: C.dark,
            fontSize: 22,
            marginBottom: 4,
            fontWeight: 700,
            lineHeight: 1.2,
          }}
        >
          Protected Brain Time
        </h2>
        <div style={{ fontSize: 14, color: C.muted, lineHeight: 1.5, marginBottom: 16 }}>
          A new way to measure what matters most.
        </div>

        {/* The pitch — what is PBT? */}
        <div
          style={{
            background: "linear-gradient(135deg, #042f2e 0%, #1e1b4b 100%)",
            borderRadius: 16,
            padding: "28px 22px",
            marginBottom: 14,
            border: "1px solid rgba(129,140,248,0.2)",
          }}
        >
          <div
            style={{
              ...sr,
              fontSize: "clamp(18px,4.5vw,24px)",
              fontWeight: 700,
              color: "white",
              lineHeight: 1.3,
              marginBottom: 14,
            }}
          >
            Every app tracks how long you <em style={{ color: "#facc15" }}>use</em> your phone.
            <br />
            No one measures when your brain is <em style={{ color: C.tealBright }}>free</em>.
          </div>
          <div
            style={{
              fontSize: 14,
              color: "rgba(255,255,255,0.8)",
              lineHeight: 1.75,
              marginBottom: 16,
            }}
          >
            Protected brain time is the number of waking minutes per day where your brain is not
            processing someone else's content. No screens. No audio. No one else's agenda. Just your
            own thoughts.
          </div>
          <div
            style={{
              fontSize: 14,
              color: "rgba(255,255,255,0.8)",
              lineHeight: 1.75,
              marginBottom: 16,
            }}
          >
            This is when creativity happens. When your mind wanders and connects ideas. When you
            process emotions, form identity, and do the thinking that no algorithm can do for you.
            Neuroscientists call it the{" "}
            <strong style={{ color: "white" }}>default mode network</strong> — and it only activates
            during genuine rest, not passive scrolling.
          </div>
          <div
            style={{
              background: "rgba(255,255,255,0.06)",
              borderRadius: 12,
              padding: "16px 16px",
              border: "1px solid rgba(255,255,255,0.08)",
            }}
          >
            <div
              style={{
                fontSize: 12,
                fontWeight: 600,
                color: "rgba(255,255,255,0.75)",
                textTransform: "uppercase",
                letterSpacing: "0.1em",
                marginBottom: 8,
              }}
            >
              The 23-minute threshold
            </div>
            <div style={{ fontSize: 13, color: "rgba(255,255,255,0.8)", lineHeight: 1.7 }}>
              Dr. Gloria Mark (UC Irvine) found it takes{" "}
              <strong style={{ color: C.tealBright }}>23 minutes</strong> to fully refocus after a
              single digital interruption. If your protected time is scattered in 5-minute gaps
              between phone checks, it's functionally zero — your brain never reaches the deep
              processing state where original thought happens.
            </div>
          </div>
        </div>

        {/* The hero number */}
        <div
          style={{
            background: C.dark,
            borderRadius: 14,
            padding: "28px 22px",
            marginBottom: 14,
            textAlign: "center",
          }}
        >
          <div
            style={{
              fontSize: 10,
              fontWeight: 700,
              letterSpacing: "0.1em",
              textTransform: "uppercase",
              color: "rgba(255,255,255,0.75)",
              marginBottom: 10,
            }}
          >
            Your protected brain time
          </div>
          <div
            style={{
              ...sr,
              fontSize: "clamp(56px,14vw,80px)",
              fontWeight: 700,
              color:
                protectedMinutes > 60 ? C.tealBright : protectedMinutes > 0 ? "#facc15" : C.redLight,
              lineHeight: 0.9,
            }}
          >
            {protectedMinutes}
            <span style={{ fontSize: "0.25em", color: "rgba(255,255,255,0.6)", marginLeft: 6 }}>
              min/day
            </span>
          </div>
          <div
            style={{
              ...sr,
              fontSize: 16,
              color: "white",
              fontWeight: 700,
              marginTop: 12,
              lineHeight: 1.3,
            }}
          >
            {protectedMinutes > 120
              ? "Your brain has real room to breathe."
              : protectedMinutes > 60
                ? "Time your brain is fully yours — but fragile."
                : protectedMinutes > 0
                  ? "That's almost nothing."
                  : "Your brain has no time that belongs to you."}
          </div>
          <div style={{ fontSize: 13, color: "rgba(255,255,255,0.65)", marginTop: 8 }}>
            No {age >= 18 ? "work" : "school"}. No screens. No one else's content. Just your own
            thoughts.
          </div>
        </div>

        {/* How we calculated it */}
        <div
          style={{
            background: C.surface,
            borderRadius: 14,
            padding: 18,
            marginBottom: 14,
            border: `1px solid ${C.border}`,
          }}
        >
          <div style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.dark, marginBottom: 10 }}>
            How we calculated this
          </div>
          <div style={{ display: "flex", flexDirection: "column", gap: 4, marginBottom: 10 }}>
            {[
              { l: `Waking hours (24 − ${fmt(sleep)})`, v: Math.round(wakingMinutes) + "m" },
              { l: age >= 18 ? "Work" : "School", v: fmt(schoolH) },
              { l: "Commute", v: fmt(commute) },
              ...(caregivingMin > 0 ? [{ l: "Caregiving", v: fmt(caregiving) }] : []),
              ...(teenJobDailyH > 0 ? [{ l: "Part-time job", v: fmt(teenJobDailyH) }] : []),
              { l: "Filler screen time", v: fillerMinutes + "m" },
              { l: "Personal screens", v: fmt(sH) },
              ...(audioMinutes > 0 ? [{ l: "Audio (podcasts/music)", v: audioMinutes + "m" }] : []),
            ].map(({ l, v }, i) => (
              <div
                key={l}
                style={{
                  display: "flex",
                  justifyContent: "space-between",
                  fontSize: 12,
                  color: C.dark,
                  padding: "4px 8px",
                  background: C.surfaceAlt,
                  borderRadius: 4,
                }}
              >
                <span>{l}</span>
                <span style={{ fontWeight: 700 }}>{i === 0 ? v : `−${v}`}</span>
              </div>
            ))}
            <div
              style={{
                display: "flex",
                justifyContent: "space-between",
                fontSize: 13,
                fontWeight: 700,
                color: C.mid,
                padding: "6px 8px",
                background: C.tealFaint,
                borderRadius: 4,
                border: `1px solid ${C.tealLight}40`,
              }}
            >
              <span>Protected brain time</span>
              <span>= {protectedMinutes}m</span>
            </div>
          </div>
          <div style={{ fontSize: 12, color: C.faint, lineHeight: 1.6, fontStyle: "italic" }}>
            Meals, chores, and hygiene aren't subtracted — your mind can wander during those.{" "}
            {age >= 18 ? "Work" : "School"} IS subtracted because even without a screen, you're
            solving someone else's problems.
          </div>
        </div>

        {/* The Great Divide — pre-2007 comparison */}
        <div
          style={{
            background: C.surface,
            borderRadius: 14,
            padding: 18,
            marginBottom: 14,
            border: `1px solid ${C.border}`,
          }}
        >
          <div style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.dark, marginBottom: 4 }}>
            The Great Divide — Before 2007
          </div>
          <div style={{ fontSize: 12, color: C.muted, marginBottom: 10, lineHeight: 1.5 }}>
            Before the iPhone, the average person had 6+ hours of unoccupied waking time per day. No
            smartphone. No notifications. No infinite scroll. Here's you today.
          </div>
          <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
            <div>
              <div
                style={{
                  display: "flex",
                  justifyContent: "space-between",
                  fontSize: 11,
                  color: C.muted,
                  marginBottom: 3,
                }}
              >
                <span>Pre-2007 (defrag. estimate)</span>
                <span>~360+ min</span>
              </div>
              <div
                style={{
                  background: C.surfaceAlt,
                  borderRadius: 5,
                  height: 28,
                  overflow: "hidden",
                }}
              >
                <div
                  style={{
                    width: "86%",
                    height: "100%",
                    background: "linear-gradient(90deg, #0f766e, #2dd4bf)",
                    borderRadius: 5,
                    display: "flex",
                    alignItems: "center",
                    paddingLeft: 10,
                  }}
                >
                  <span style={{ fontSize: 11, fontWeight: 700, color: "white" }}>
                    6+ hours free
                  </span>
                </div>
              </div>
            </div>
            <div>
              <div
                style={{
                  display: "flex",
                  justifyContent: "space-between",
                  fontSize: 11,
                  color: C.muted,
                  marginBottom: 3,
                }}
              >
                <span>You today</span>
                <span>{protectedMinutes} min</span>
              </div>
              <div
                style={{
                  background: C.surfaceAlt,
                  borderRadius: 5,
                  height: 28,
                  overflow: "hidden",
                }}
              >
                <div
                  style={{
                    width: `${Math.min(86, (protectedMinutes / 420) * 100)}%`,
                    height: "100%",
                    background:
                      protectedMinutes < 120
                        ? "linear-gradient(90deg, #b45309, #facc15)"
                        : "linear-gradient(90deg, #0f766e, #2dd4bf)",
                    borderRadius: 5,
                    display: "flex",
                    alignItems: "center",
                    paddingLeft: 10,
                    minWidth: protectedMinutes > 0 ? 30 : 0,
                  }}
                >
                  <span style={{ fontSize: 11, fontWeight: 700, color: "white" }}>
                    {protectedMinutes > 0 ? `${protectedMinutes}m` : ""}
                  </span>
                </div>
              </div>
            </div>
          </div>
          <div
            style={{
              ...sr,
              fontSize: 14,
              fontWeight: 700,
              color: C.dark,
              marginTop: 14,
              textAlign: "center",
              fontStyle: "italic",
              lineHeight: 1.5,
            }}
          >
            "What brilliant things would come from your brain, if it only had the time to think of
            it."
          </div>
        </div>

        {/* Transition to Possibilities */}
        <div
          style={{
            ...dCard("linear-gradient(135deg, #042f2e 0%, #053b38 100%)"),
            textAlign: "center",
            padding: "24px 22px",
            border: "1px solid rgba(153,246,228,0.15)",
          }}
        >
          <div style={{ ...sr, fontSize: 18, fontWeight: 700, color: "white", marginBottom: 8 }}>
            Now — what if you could get some of that back?
          </div>
          <div
            style={{
              fontSize: 14,
              color: "rgba(255,255,255,0.75)",
              lineHeight: 1.6,
              marginBottom: 14,
            }}
          >
            The next step lets you play with the math. Adjust your screen time, reduce phone
            pickups, and watch your protected brain time grow.
          </div>
          <button
            onClick={() => {
              setStep(STEP.POSSIBILITIES);
              scrollToTop();
            }}
            style={{
              background: C.tealBright,
              color: C.dark,
              border: "none",
              borderRadius: 24,
              padding: "12px 28px",
              fontSize: 15,
              fontWeight: 700,
              cursor: "pointer",
              boxShadow: "0 4px 16px rgba(45,212,191,0.3)",
            }}
          >
            See Your Possibilities →
          </button>
        </div>
      </div>
    );
  };

  // ── STEP 9: THE BIGGER PICTURE ─────────────────────────────────────────────
  const BiggerPicture = () => {
    const perPersonDailyH = Math.max(0, sH * 0.5); // if average person cut screens in half
    const perPersonAnnualH = Math.round(perPersonDailyH * 365);
    const fmtBig = (n) => {
      if (n >= 1e9) return (n / 1e9).toFixed(1) + " billion";
      if (n >= 1e6) return (n / 1e6).toFixed(1) + " million";
      if (n >= 1e3) return Math.round(n).toLocaleString();
      return n.toString();
    };
    const levels = [
      { label: "You", count: 1, icon: "🧍" },
      { label: "Your family", count: 4, icon: "👨‍👩‍👧‍👦" },
      { label: "A classroom", count: 30, icon: "📚" },
      { label: "A school", count: 500, icon: "🏫" },
      { label: "A university", count: 30000, icon: "🎓" },
      { label: "A city", count: 100000, icon: "🏙️" },
      { label: "The U.S.", count: 330000000, icon: "🇺🇸" },
      { label: "The world", count: 8000000000, icon: "🌍" },
    ];
    return (
      <div>
        <div
          style={{
            fontSize: 11,
            fontWeight: 700,
            letterSpacing: "0.12em",
            textTransform: "uppercase",
            color: C.royal,
            marginBottom: 4,
          }}
        >
          Step 9 of 9
        </div>
        <h2
          style={{
            ...sr,
            color: C.dark,
            fontSize: 22,
            marginBottom: 4,
            fontWeight: 700,
            lineHeight: 1.2,
          }}
        >
          The Bigger Picture
        </h2>
        <div style={{ fontSize: 14, color: C.muted, lineHeight: 1.5, marginBottom: 16 }}>
          What if the average person cut their screen time in half — just for one year?
        </div>

        <div
          style={{
            background: "linear-gradient(135deg, #042f2e 0%, #1e1b4b 100%)",
            borderRadius: 16,
            padding: "24px 18px",
            marginBottom: 14,
            border: "1px solid rgba(129,140,248,0.2)",
          }}
        >
          <div style={{ ...sr, fontSize: 16, fontWeight: 700, color: "white", marginBottom: 6 }}>
            The math starts with one person.
          </div>
          <div
            style={{
              fontSize: 13,
              color: "rgba(255,255,255,0.75)",
              lineHeight: 1.7,
              marginBottom: 16,
            }}
          >
            The average person spends {fmt(sH)} on personal screens daily. Cutting that in half
            saves <strong style={{ color: C.tealBright }}>{fmt(perPersonDailyH)}/day</strong> —
            that's{" "}
            <strong style={{ color: C.tealBright }}>
              {perPersonAnnualH.toLocaleString()} hours
            </strong>{" "}
            per year. Now multiply that.
          </div>

          <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
            {levels.map((lvl, i) => {
              const totalHrs = perPersonAnnualH * lvl.count;
              const totalYrs = totalHrs / 8760;
              const display =
                totalYrs >= 1
                  ? fmtBig(Math.round(totalYrs)) + " years"
                  : fmtBig(totalHrs) + " hours";
              const barPct = Math.min(
                100,
                Math.max(
                  8,
                  (Math.log10(Math.max(1, totalHrs)) / Math.log10(8e9 * perPersonAnnualH)) * 100
                )
              );
              return (
                <div
                  key={lvl.label}
                  style={{
                    background: "rgba(255,255,255,0.04)",
                    borderRadius: 10,
                    padding: "10px 14px",
                    border: "1px solid rgba(255,255,255,0.06)",
                  }}
                >
                  <div
                    style={{
                      display: "flex",
                      justifyContent: "space-between",
                      alignItems: "center",
                      marginBottom: 6,
                    }}
                  >
                    <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                      <span style={{ fontSize: 18 }}>{lvl.icon}</span>
                      <div>
                        <div style={{ fontSize: 13, fontWeight: 700, color: "white" }}>
                          {lvl.label}
                        </div>
                        <div style={{ fontSize: 10, color: "rgba(255,255,255,0.75)" }}>
                          {lvl.count > 1 ? lvl.count.toLocaleString() + " people" : ""}
                        </div>
                      </div>
                    </div>
                    <div
                      style={{
                        ...sr,
                        fontSize: i < 3 ? 18 : i < 6 ? 20 : 24,
                        fontWeight: 700,
                        color: i < 3 ? C.tealBright : i < 6 ? "#facc15" : "#f97316",
                        textAlign: "right",
                      }}
                    >
                      {display}
                    </div>
                  </div>
                  <div
                    style={{
                      background: "rgba(255,255,255,0.08)",
                      borderRadius: 4,
                      height: 4,
                      overflow: "hidden",
                    }}
                  >
                    <div
                      style={{
                        width: `${barPct}%`,
                        height: "100%",
                        background: i < 3 ? C.tealBright : i < 6 ? "#facc15" : "#f97316",
                        borderRadius: 4,
                        transition: "width 0.3s",
                      }}
                    />
                  </div>
                </div>
              );
            })}
          </div>
        </div>

        <div
          style={{
            background: C.surface,
            borderRadius: 16,
            padding: "28px 22px",
            textAlign: "center",
            border: `1px solid ${C.border}`,
          }}
        >
          <div
            style={{
              ...sr,
              fontSize: "clamp(20px,5vw,28px)",
              fontWeight: 700,
              color: C.dark,
              lineHeight: 1.3,
              marginBottom: 12,
            }}
          >
            {fmtBig(Math.round((perPersonAnnualH * 8e9) / 8760))} years of human potential.
          </div>
          <div style={{ fontSize: 15, color: C.muted, lineHeight: 1.7, marginBottom: 16 }}>
            Reading, creating, connecting, thinking — recovered from the scroll. Invested instead
            into intentional use, combining the power of technology with human ideas.
          </div>
          <div style={{ ...sr, fontSize: 16, fontWeight: 700, color: C.mid, fontStyle: "italic" }}>
            The future belongs to the curious.
          </div>
        </div>
      </div>
    );
  };

  // ── SHELL ─────────────────────────────────────────────────────────────────
  return (
    <main
      style={{
        background: C.bg,
        minHeight: "100vh",
        fontFamily: "'Inter','DM Sans',system-ui,sans-serif",
        paddingBottom: 48,
        fontSize: 15,
        lineHeight: 1.5,
      }}
    >
      {/* Visually hidden h1 — gives the page a document outline without
          disrupting the brand-forward visual layout. Screen readers
          announce this as the page title; sighted users see the
          existing 'defrag.' wordmark in the nav bar. */}
      <h1
        style={{
          position: "absolute",
          width: 1,
          height: 1,
          padding: 0,
          margin: -1,
          overflow: "hidden",
          clip: "rect(0,0,0,0)",
          whiteSpace: "nowrap",
          border: 0,
        }}
      >
        defrag. — a screen time and life-balance calculator
      </h1>
      {showFinder && <ScreenTimeFinder onClose={() => setShowFinder(false)} />}

      {/* Sticky nav + step bar — sits below the Prompt-Ed site nav (58px) */}
      <div style={{ position: "sticky", top: 58, zIndex: 90 }}>
        <div
          style={{
            background: C.dark,
            padding: "14px 18px",
            display: "flex",
            justifyContent: "space-between",
            alignItems: "center",
          }}
        >
          <div
            onClick={() => {
              setShowAbout(false);
              setShowResearch(false);
              setShowOpening(true);
              scrollToTop();
            }}
            style={{ cursor: "pointer" }}
          >
            <span
              style={{ ...sr, color: "white", fontSize: 22, display: "block", lineHeight: 1.1 }}
            >
              defrag<span style={{ color: "#2dd4bf" }}>.</span>
            </span>
          </div>
          <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
            {showAbout || showResearch ? (
              <button
                onClick={() => {
                  setShowAbout(false);
                  setShowResearch(false);
                }}
                style={{
                  background: "transparent",
                  border: `1px solid rgba(255,255,255,0.25)`,
                  color: "rgba(255,255,255,0.75)",
                  borderRadius: 20,
                  padding: "4px 13px",
                  fontSize: 12,
                  cursor: "pointer",
                  fontWeight: 500,
                }}
              >
                ← Back
              </button>
            ) : (
              <>
                <button
                  onClick={() => {
                    setShowAbout(true);
                    setShowResearch(false);
                    setShowOpening(false);
                    scrollToTop();
                  }}
                  style={{
                    background: "transparent",
                    border: `1px solid rgba(255,255,255,0.25)`,
                    color: "rgba(255,255,255,0.75)",
                    borderRadius: 20,
                    padding: "4px 13px",
                    fontSize: 12,
                    cursor: "pointer",
                    fontWeight: 500,
                  }}
                >
                  About
                </button>
                <button
                  onClick={() => {
                    setShowResearch(true);
                    setShowAbout(false);
                    setShowOpening(false);
                    scrollToTop();
                  }}
                  style={{
                    background: "transparent",
                    border: `1px solid rgba(255,255,255,0.25)`,
                    color: "rgba(255,255,255,0.75)",
                    borderRadius: 20,
                    padding: "4px 13px",
                    fontSize: 12,
                    cursor: "pointer",
                    fontWeight: 500,
                  }}
                >
                  Methodology
                </button>
              </>
            )}
            {(showOpening || showAbout || showResearch) && (
              <button
                onClick={() => {
                  setShowOpening(false);
                  setShowAbout(false);
                  setShowResearch(false);
                  scrollToTop();
                }}
                style={{
                  background: "transparent",
                  border: "1.5px solid #facc15",
                  color: "#facc15",
                  borderRadius: 20,
                  padding: "5px 14px",
                  fontSize: 12,
                  cursor: "pointer",
                  fontWeight: 700,
                  letterSpacing: "0.02em",
                }}
              >
                Find Your Number →
              </button>
            )}
          </div>
        </div>
        {!showOpening && !showAbout && !showResearch && (
          <div
            style={{
              display: "flex",
              gap: 4,
              flexWrap: "wrap",
              padding: "8px 14px",
              background: C.bg,
              borderBottom: `1px solid ${C.border}`,
            }}
          >
            {STEPS.map((s, i) => (
              <button
                key={i}
                onClick={() => {
                  if (i <= step || returningUser) {
                    setStep(i);
                    scrollToTop();
                  }
                }}
                style={{
                  borderRadius: 20,
                  padding: "4px 10px",
                  fontSize: 11,
                  border: `1px solid ${i <= step || returningUser ? C.mid : C.border}`,
                  cursor: i <= step || returningUser ? "pointer" : "default",
                  background: i === step ? C.mid : "transparent",
                  // Use explicit grey for future/disabled pills instead of
                  // opacity: 0.5 — opacity multiplies both the text and
                  // border against the background and lands at ~1.5:1
                  // contrast, well below AA. Explicit C.muted hits 7:1.
                  color: i === step ? "white" : i < step || returningUser ? C.mid : C.muted,
                  fontWeight: i === step ? 600 : 400,
                }}
              >
                {i < step ? "✓ " : ""}
                {s}
              </button>
            ))}
          </div>
        )}
      </div>
      <div style={{ padding: "0 14px" }}>
        <div
          style={{
            background: C.surface,
            border: `1px solid ${C.border}`,
            borderRadius: 16,
            padding: 22,
            marginBottom: 12,
            boxShadow: "0 2px 12px rgba(0,0,0,0.06)",
          }}
        >
          {/* ── RESEARCH & SOURCES PAGE ── */}
          {showResearch ? (
            <div>
              <div style={{ ...sr, fontSize: 22, fontWeight: 700, color: C.dark, marginBottom: 4 }}>
                How This Works
              </div>
              <div style={{ fontSize: 13, color: C.muted, marginBottom: 18, fontStyle: "italic" }}>
                Every calculation explained, every source cited — for educators, researchers, and
                the PhD-curious.
              </div>

              {/* 9-Step Flow Overview */}
              <div style={{ ...card, marginBottom: 14 }}>
                <div
                  style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.dark, marginBottom: 8 }}
                >
                  The 9-Step Flow
                </div>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: "0 0 10px" }}>
                  defrag. walks users through nine sequential steps. The order is deliberate — each
                  step builds the context needed for the next. No step is skippable, but every value
                  can be adjusted at any time.
                </p>
                <ol
                  style={{
                    fontSize: 13,
                    color: C.muted,
                    lineHeight: 1.75,
                    margin: "0 0 8px 0",
                    paddingLeft: 20,
                  }}
                >
                  <li>
                    <strong style={{ color: C.dark }}>About You</strong> — age, first device age,
                    smartphone age (adults), parent toggle, daily obligations (sleep, school/work,
                    hygiene, chores, meals, commute).
                  </li>
                  <li>
                    <strong style={{ color: C.dark }}>Invest Your Time</strong> — what the user
                    wants to spend time on (organized activities, interests, protected screen
                    sessions as a budget).
                  </li>
                  <li>
                    <strong style={{ color: C.dark }}>Your Day With Screens</strong> — weekday
                    personal screen hours, weekend screen hours, phone habit checkboxes that feed
                    the filler model, daily pickup count.
                  </li>
                  <li>
                    <strong style={{ color: C.dark }}>Design Your Screen Time</strong> — choose
                    which categories of personal screens count toward the intentional budget
                    (social, streaming, gaming, etc.) and assign frequency/duration per session.
                  </li>
                  <li>
                    <strong style={{ color: C.dark }}>The Reveal</strong> — lifetime dot grid,
                    waking percentage, protected brain time hero stat, pac-man animation revealing
                    screen dots, free-time percentage, 24-hour clock.
                  </li>
                  <li>
                    <strong style={{ color: C.dark }}>Protected Brain Time</strong> — dedicated
                    pitch for the PBT concept, adaptive text by threshold, Great Divide comparison
                    bars.
                  </li>
                  <li>
                    <strong style={{ color: C.dark }}>Your Possibilities</strong> — three levers
                    (pickups, screen goal, filler contexts) in a cockpit panel; live reclaimed-years
                    counter.
                  </li>
                  <li>
                    <strong style={{ color: C.dark }}>Your Plan</strong> — ideal day summary,
                    defragged bubble chart, "What this adds up to" stats, strategies +
                    counterweights accordions, downloadable HTML plan.
                  </li>
                  <li>
                    <strong style={{ color: C.dark }}>The Bigger Picture</strong> — meta scaling:
                    one person → family → classroom → school → university → city → US → world.
                    Closes with "The future belongs to the curious."
                  </li>
                </ol>
                <div
                  style={{
                    background: C.tealFaint,
                    borderRadius: 8,
                    padding: "9px 12px",
                    marginTop: 8,
                    fontSize: 12,
                    color: C.dark,
                    lineHeight: 1.6,
                    borderLeft: `3px solid ${C.mid}`,
                  }}
                >
                  <strong>Design note:</strong> Steps 5 and 6 were separated in the April 2026
                  redesign to give Protected Brain Time the space it needed. Previously it was a
                  section inside The Reveal — now it's its own moment. Step 4 ("Design Your Screen
                  Time") was similarly pulled out so the screen budget feels like a chosen design,
                  not a hidden sub-form.
                </div>
              </div>

              {/* Default values — 6 age brackets */}
              <div style={{ ...card, marginBottom: 14 }}>
                <div
                  style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.dark, marginBottom: 10 }}
                >
                  Default Values by Age Bracket
                </div>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.6, margin: "0 0 12px" }}>
                  defrag. uses six age brackets to pre-fill obligation and screen time defaults.
                  When you move the age slider, all values update automatically. You can adjust any
                  slider to match your reality — the defaults anchor the conversation in real data.
                </p>
                <div style={{ overflowX: "auto" }}>
                  <table
                    style={{
                      width: "100%",
                      borderCollapse: "collapse",
                      fontSize: 11,
                      minWidth: 520,
                    }}
                  >
                    <thead>
                      <tr style={{ borderBottom: `2px solid ${C.border}` }}>
                        {["", "5–10", "11–13", "14–17", "18–22", "23–64", "65+"].map((h) => (
                          <th
                            key={h}
                            style={{
                              padding: "6px 6px",
                              textAlign: "left",
                              color: C.dark,
                              fontWeight: 700,
                              fontSize: 11,
                              whiteSpace: "nowrap",
                            }}
                          >
                            {h}
                          </th>
                        ))}
                      </tr>
                    </thead>
                    <tbody>
                      {[
                        ["Sleep", "10h", "9.5h", "8.5h", "7.5h", "7.5h", "7.5h"],
                        ["School / Work", "6.5h", "6.5h", "7h", "8h", "8h", "0h"],
                        ["Homework", "0.5h", "1h", "1.5h", "—", "—", "—"],
                        ["Hygiene", "0.5h", "0.5h", "0.5h", "0.5h", "0.5h", "0.75h"],
                        ["Chores", "0.5h", "0.75h", "0.75h", "0.75h", "1h", "0.75h"],
                        ["Meals", "0.75h", "1h", "1h", "1h", "1.25h", "1h"],
                        ["Commute", "0.25h", "0.5h", "0.5h", "0.75h", "0.75h", "0.25h"],
                        ["School screens", "1.5h", "2h", "3h", "2h", "2h", "0.5h"],
                        ["Personal screens", "3h", "5h", "7h", "5h", "4h", "5h"],
                        ["First device age", "8", "9", "11", "14", "18", "25"],
                      ].map(([label, ...vals], i) => (
                        <tr
                          key={label}
                          style={{
                            borderBottom: `1px solid ${C.border}`,
                            background: i % 2 === 0 ? C.surfaceAlt : "transparent",
                          }}
                        >
                          <td
                            style={{
                              padding: "5px 6px",
                              fontWeight: 600,
                              color: C.dark,
                              fontSize: 11,
                              whiteSpace: "nowrap",
                            }}
                          >
                            {label}
                          </td>
                          {vals.map((v, j) => (
                            <td
                              key={j}
                              style={{ padding: "5px 6px", color: C.muted, fontSize: 11 }}
                            >
                              {v}
                            </td>
                          ))}
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
                <div
                  style={{
                    background: C.tealFaint,
                    borderRadius: 8,
                    padding: "9px 12px",
                    marginTop: 12,
                    fontSize: 12,
                    color: C.dark,
                    lineHeight: 1.6,
                    borderLeft: `3px solid ${C.mid}`,
                  }}
                >
                  <strong>Sources:</strong> Sleep — CDC/AAP guidelines &amp; NHANES data. School
                  hours — NCES average instructional day. Work hours — BLS American Time Use Survey
                  (ATUS) 2023. Screen time — Common Sense Media <em>The Common Sense Census</em>{" "}
                  2021; <em>Constant Companion</em> 2023. Meals, chores, commute — BLS ATUS 2023.
                  Caregiving (ages 25–64, 0.5h default) — BLS ATUS 2023.
                </div>
              </div>

              {/* Intentional budget floor + retirement blend */}
              <div style={{ ...card, marginBottom: 14 }}>
                <div
                  style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.dark, marginBottom: 8 }}
                >
                  Intentional Budget Floor &amp; Retirement Blend
                </div>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: "0 0 10px" }}>
                  <strong style={{ color: C.dark }}>1-hour floor on totalIdeal.</strong> If a user
                  hasn't built an intentional screen budget in Step 4 (Design Your Screen Time),{" "}
                  <code
                    style={{
                      background: C.surfaceAlt,
                      padding: "1px 5px",
                      borderRadius: 4,
                      fontSize: 12,
                    }}
                  >
                    effectiveAdjScrH
                  </code>{" "}
                  falls back to{" "}
                  <code
                    style={{
                      background: C.surfaceAlt,
                      padding: "1px 5px",
                      borderRadius: 4,
                      fontSize: 12,
                    }}
                  >
                    max(totalIdeal, 1)
                  </code>
                  . This prevents the Plan page from reporting "0h screens" — a number that's almost
                  never realistic and would make the reclaimed-years math look absurd.
                </p>
                <div
                  style={{
                    background: C.dark,
                    borderRadius: 8,
                    padding: "10px 14px",
                    marginBottom: 10,
                    fontFamily: "'SF Mono',monospace",
                    fontSize: 12,
                    color: "#2dd4bf",
                    lineHeight: 1.8,
                  }}
                >
                  effectiveAdjScrH = adjScrH !== null
                  <br />
                  {"    "}? adjScrH
                  <br />
                  {"    "}: max(totalIdeal, 1)
                </div>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: "0 0 10px" }}>
                  <strong style={{ color: C.dark }}>Seniors retirement blend.</strong> For users
                  under 65 whose lifetime grid extends past 65, retirement-phase segments blend the
                  user's intentional screen budget with the Seniors bracket default (5.5h/day). This
                  reflects the empirical reality that retirees' screen time converges toward the
                  population average regardless of pre-retirement habits — the workplace discipline
                  that kept screens in check disappears.
                </p>
                <p
                  style={{
                    fontSize: 12,
                    color: C.muted,
                    lineHeight: 1.7,
                    margin: 0,
                    fontStyle: "italic",
                  }}
                >
                  Both choices are design decisions, not empirical constants. The 1h floor is a
                  guardrail against degenerate outputs; the retirement blend keeps the lifetime
                  projection honest for users who might otherwise assume their current screen habits
                  will hold across a 40-year horizon.
                </p>
              </div>

              {/* Day walkthrough & filler */}
              <div style={{ ...card, marginBottom: 14 }}>
                <div
                  style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.dark, marginBottom: 8 }}
                >
                  Filler Screen Time Model
                </div>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: "0 0 10px" }}>
                  Step 3 ("Your Day With Screens") asks "Where does your phone show up?" — a set of
                  checkboxes for contexts where phone use happens during other activities (morning,
                  getting ready, commute, at school/work, after school, meals, caregiving, bedtime).
                  Each checked context adds a{" "}
                  <strong style={{ color: C.dark }}>base minute estimate</strong>, scaled by pickup
                  intensity.
                </p>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: "0 0 10px" }}>
                  This captures <strong style={{ color: C.dark }}>filler screen time</strong> — the
                  phone checks during meals, the scrolling before bed, the morning scroll that never
                  feels like "screen time." These minutes are controllable but rarely counted.
                  Age-appropriate categories are shown (e.g., "After school" for under-18,
                  "Caregiving" for adults 25+).
                </p>
                <div
                  style={{
                    background: C.dark,
                    borderRadius: 8,
                    padding: "10px 14px",
                    marginBottom: 8,
                    fontFamily: "'SF Mono',monospace",
                    fontSize: 12,
                    color: "#2dd4bf",
                    lineHeight: 1.8,
                  }}
                >
                  pkpScale = max(0.5, min(1.8, pickups / 185))
                  <br />
                  fillerMinutes = sum of (FILLER_ESTIMATES[context] × pkpScale)
                  <br />
                  {"    "}for each checked context
                </div>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: "0 0 8px" }}>
                  defrag. uses a <strong style={{ color: C.dark }}>three-layer screen model</strong>
                  : Required (school/work device hours) | Filler (phone habit checkboxes, scaled by
                  pickups) | Intentional (chosen personal screens). Controllable = Filler +
                  Intentional — the number that matters for the Reveal. On the Possibilities page,
                  users can uncheck filler contexts to "protect" those windows, and adjust the
                  pickup slider to see how reducing phone checks reduces filler time.
                </p>
              </div>

              {/* Weekend math */}
              <div style={{ ...card, marginBottom: 14 }}>
                <div
                  style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.dark, marginBottom: 8 }}
                >
                  Weekend Math
                </div>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: "0 0 10px" }}>
                  Weekdays and weekends have different obligation profiles. School/work, homework,
                  commute, and teen jobs apply Monday–Friday only. defrag. computes separate free
                  time values and averages them for lifetime projections.
                </p>
                <div
                  style={{
                    background: C.dark,
                    borderRadius: 8,
                    padding: "10px 14px",
                    marginBottom: 8,
                    fontFamily: "'SF Mono',monospace",
                    fontSize: 12,
                    color: "#2dd4bf",
                    lineHeight: 1.8,
                  }}
                >
                  weekdayOblig = sleep + schoolH + hygiene + chores + meals
                  <br />
                  {"    "}+ commute + caregiving + teenJobDailyH
                  <br />
                  weekendOblig = sleep + hygiene + chores + meals + caregiving
                  <br />
                  avgFreeTime = (5 x weekdayFree + 2 x weekendFree) / 7<br />
                  avgSH = (5 x weekdaySH + 2 x weekendSH) / 7
                </div>
                <p style={{ fontSize: 12, color: C.muted, lineHeight: 1.7, margin: 0 }}>
                  Pie charts and the 24-hour clock use weekday values. Lifetime projections, the
                  life grid, and free-time screen intensity all use weekly averages (avgSH,
                  avgFreeTime) so weekday and weekend patterns are both reflected. The WeekPlan in
                  Step 8 ("Your Plan") zeroes school/work and commute on Saturday and Sunday.
                </p>
              </div>

              {/* Protected brain time */}
              <div style={{ ...card, marginBottom: 14 }}>
                <div
                  style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.dark, marginBottom: 8 }}
                >
                  Protected Brain Time
                </div>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: "0 0 10px" }}>
                  The hero stat of The Reveal. Protected brain time is the number of waking minutes
                  per day where your brain is not processing someone else's content — no screens, no
                  audio, no external input. This is when original thought, daydreaming, and
                  self-reflection happen.
                </p>
                <div
                  style={{
                    background: C.dark,
                    borderRadius: 8,
                    padding: "10px 14px",
                    marginBottom: 8,
                    fontFamily: "'SF Mono',monospace",
                    fontSize: 12,
                    color: "#2dd4bf",
                    lineHeight: 1.8,
                  }}
                >
                  wakingMinutes = (24 - sleep) x 60
                  <br />
                  protectedMinutes = max(0, wakingMinutes - schoolH×60
                  <br />
                  {"    "}- commute×60 - caregivingMin - teenJobDailyH×60
                  <br />
                  {"    "}- fillerMinutes - sH×60 - audioMinutes)
                </div>
                <div
                  style={{
                    background: C.tealFaint,
                    borderRadius: 8,
                    padding: "9px 12px",
                    fontSize: 12,
                    color: C.dark,
                    lineHeight: 1.6,
                    borderLeft: `3px solid ${C.mid}`,
                  }}
                >
                  <strong>Inspired by:</strong> Gloria Mark's research on attention fragmentation (
                  <em>Attention Span</em>, 2023) and Linda Stone's concept of continuous partial
                  attention. The default mode network requires genuine rest to activate — it does
                  not engage during passive screen consumption.
                </div>
              </div>

              {/* Pickup reduction scenario */}
              <div style={{ ...card, marginBottom: 14 }}>
                <div
                  style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.dark, marginBottom: 8 }}
                >
                  Pickup Reduction Scenario
                </div>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: "0 0 10px" }}>
                  The Reveal shows what reducing phone pickups to 25/day would do to protected brain
                  time. This recalculates filler screen time using the same formula but with a
                  reduced pickup scale factor.
                </p>
                <div
                  style={{
                    background: C.dark,
                    borderRadius: 8,
                    padding: "10px 14px",
                    marginBottom: 8,
                    fontFamily: "'SF Mono',monospace",
                    fontSize: 12,
                    color: "#2dd4bf",
                    lineHeight: 1.8,
                  }}
                >
                  reducedPkpScale = max(0.5, min(1.8, 25 / 185))
                  <br />
                  reducedFiller = same sum, scaled by reducedPkpScale
                  <br />
                  reducedProtected = max(0, wakingMin - schoolH×60 - commute×60
                  <br />
                  {"    "}- caregivingMin - teenJobDailyH×60
                  <br />
                  {"    "}- reducedFiller - sH×60 - audioMin)
                  <br />
                  protectedGain = reducedProtected - protectedMinutes
                </div>
                <p style={{ fontSize: 12, color: C.muted, lineHeight: 1.7, margin: 0 }}>
                  25 pickups/day is chosen as a realistic reduction target — roughly one per waking
                  hour. Average is 185×/day (Reviews.org 2026). Each pickup averages ~30 seconds of
                  screen exposure (Oulasvirta et al., 2012). The pickup-to-filler scaling model
                  (pkpScale = pickups / 185, clamped 0.5–1.8) is a defrag. model, not empirically
                  validated — it provides a directional estimate, not a precise measurement.
                </p>
              </div>

              {/* Full-life bubble chart */}
              <div style={{ ...card, marginBottom: 14 }}>
                <div
                  style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.dark, marginBottom: 8 }}
                >
                  Full-Life Bubble Chart (Adults 22+)
                </div>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: "0 0 10px" }}>
                  Adults see a birth-to-78 dot grid showing their entire life — past and future.
                  Past segments are estimated using age-appropriate sleep, school, work, and screen
                  time averages. Future segments use the existing computeGridSegs projection. A "you
                  are here" marker shows the user's current position in life.
                </p>
                <p style={{ fontSize: 12, color: C.muted, lineHeight: 1.7, margin: 0 }}>
                  Kids and teens (under 22) see the original remaining-life-only grid with the "tap
                  to reveal screen time" toggle, since their past is minimal relative to what's
                  ahead.
                </p>
              </div>

              {/* Screen intensity branching */}
              <div style={{ ...card, marginBottom: 14 }}>
                <div
                  style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.dark, marginBottom: 8 }}
                >
                  Screen Intensity Branching
                </div>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: "0 0 10px" }}>
                  The Reveal branches into two pathways based on controllable screen time — filler +
                  intentional, not required school/work.
                </p>
                <div
                  style={{
                    background: C.dark,
                    borderRadius: 8,
                    padding: "10px 14px",
                    marginBottom: 8,
                    fontFamily: "'SF Mono',monospace",
                    fontSize: 12,
                    color: "#2dd4bf",
                    lineHeight: 1.8,
                  }}
                >
                  controllableH = (fillerMinutes / 60) + sH
                  <br />
                  isLightUser = controllableH {"<"} 2.5
                </div>
                <p style={{ fontSize: 12, color: C.muted, lineHeight: 1.7, margin: 0 }}>
                  <strong style={{ color: C.dark }}>Pathway A ({"<"} 2.5h):</strong> "You're
                  protecting something rare" — affirming framing. The Reveal shows a celebration
                  card with the user's real stats highlighted in teal, plus a{" "}
                  <strong style={{ color: C.dark }}>counterfactual panel</strong> comparing current
                  protected brain time and free-time screen percentage against what would happen if
                  screen time drifted to the next age bracket's national average (kids→5h,
                  tweens→7h, teens→8h, adults→5h). Protected Brain Time text adds age-specific
                  affirmation. The trajectory card in Possibilities reframes from "three paths" to
                  "what you're protecting — and what drift would cost."
                  <br />
                  <strong style={{ color: C.dark }}>Pathway B (≥ 2.5h):</strong> "Here's the gap" —
                  gap-focused framing + filler vs intentional breakdown.
                  <br />
                  The 2.5h threshold is a design choice for framing, not a clinical cutoff.
                </p>
              </div>

              {/* Whole-life screen history */}
              <div style={{ ...card, marginBottom: 14 }}>
                <div
                  style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.dark, marginBottom: 8 }}
                >
                  Whole-Life Screen History
                </div>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: "0 0 10px" }}>
                  defrag. estimates total screen time from age 2 to the user's current age using a
                  three-era model. The ramp target is{" "}
                  <strong style={{ color: C.dark }}>total daily screen hours</strong> (personal +
                  work/school devices) — not just personal use.
                </p>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: "0 0 10px" }}>
                  <strong style={{ color: C.dark }}>Era 1 (Pre-internet):</strong> TV-only baseline
                  by age. <strong style={{ color: C.dark }}>Era 2 (Desktop internet):</strong>{" "}
                  Baseline + gradual bump (max +1.5h, growing at 0.2h/year) for AOL, email, early
                  web. <strong style={{ color: C.dark }}>Era 3 (Smartphone):</strong> Logarithmic
                  ramp from desktop level to current total screen hours.
                </p>
                <div
                  style={{
                    background: C.surfaceAlt,
                    borderRadius: 9,
                    padding: "11px 14px",
                    marginBottom: 10,
                    border: `1px solid ${C.border}`,
                  }}
                >
                  <div style={{ fontWeight: 700, color: C.dark, fontSize: 12, marginBottom: 6 }}>
                    Pre-Smartphone Baselines (daily screen hours)
                  </div>
                  <div style={{ display: "grid", gridTemplateColumns: "repeat(5,1fr)", gap: 4 }}>
                    {[
                      ["2–5", "2.0h"],
                      ["5–8", "2.5h"],
                      ["8–13", "3.5h"],
                      ["13–18", "4.5h"],
                      ["18+", "5.0h"],
                    ].map(([ages, h]) => (
                      <div
                        key={ages}
                        style={{
                          textAlign: "center",
                          background: "white",
                          borderRadius: 6,
                          padding: "6px 4px",
                          border: `1px solid ${C.border}`,
                        }}
                      >
                        <div style={{ fontSize: 10, color: C.faint }}>{ages}</div>
                        <div style={{ fontSize: 12, fontWeight: 700, color: C.dark }}>{h}</div>
                      </div>
                    ))}
                  </div>
                  <div style={{ fontSize: 11, color: C.faint, marginTop: 6, fontStyle: "italic" }}>
                    Sources: Nielsen, Common Sense Media historical data, Kaiser Family Foundation
                  </div>
                </div>
                <div
                  style={{
                    background: C.dark,
                    borderRadius: 8,
                    padding: "10px 14px",
                    marginBottom: 8,
                    fontFamily: "'SF Mono',monospace",
                    fontSize: 12,
                    color: "#2dd4bf",
                    lineHeight: 1.8,
                  }}
                >
                  Era 2: dailyH = baseline + min(1.5, yearsOnline × 0.2)
                  <br />
                  Era 3: piecewise ramp — early years reach ~40% of target,
                  <br />
                  {"      "}last 5-7 years accelerate quadratically to current level
                  <br />
                  {"      "}dailyH = desktopLevel + (totalScrH - desktopLevel) × t
                </div>
                <div
                  style={{
                    background: C.surfaceAlt,
                    borderRadius: 9,
                    padding: "11px 14px",
                    marginBottom: 8,
                    border: `1px solid ${C.border}`,
                  }}
                >
                  <div style={{ fontWeight: 700, color: C.dark, fontSize: 12, marginBottom: 6 }}>
                    Lifetime Screen Years by Age Group (modeled ranges)
                  </div>
                  <table style={{ width: "100%", borderCollapse: "collapse", fontSize: 11 }}>
                    <thead>
                      <tr style={{ borderBottom: `2px solid ${C.border}` }}>
                        {["Age Group", "Low Use", "Moderate", "High Use"].map((h) => (
                          <th
                            key={h}
                            style={{
                              padding: "5px 6px",
                              textAlign: "left",
                              fontWeight: 700,
                              color: C.dark,
                            }}
                          >
                            {h}
                          </th>
                        ))}
                      </tr>
                    </thead>
                    <tbody>
                      {[
                        ["Kids (10)", "9 yrs", "15 yrs", "22 yrs"],
                        ["Teens (15)", "17 yrs", "30 yrs", "44 yrs"],
                        ["Young adults (22)", "9 yrs", "15 yrs", "22 yrs"],
                        ["Adults (30)", "7 yrs", "12 yrs", "18 yrs"],
                        ["Adults (43)", "4 yrs", "6 yrs", "9 yrs"],
                      ].map(([label, ...vals], i) => (
                        <tr key={label} style={{ borderBottom: `1px solid ${C.border}` }}>
                          <td style={{ padding: "4px 6px", fontWeight: 600, color: C.dark }}>
                            {label}
                          </td>
                          {vals.map((v, j) => (
                            <td key={j} style={{ padding: "4px 6px", color: C.muted }}>
                              {v}
                            </td>
                          ))}
                        </tr>
                      ))}
                    </tbody>
                  </table>
                  <div style={{ fontSize: 10, color: C.faint, marginTop: 4, fontStyle: "italic" }}>
                    Ranges include personal + school/work device hours. Low/Med/High correspond to
                    roughly 30%, 100%, and 180% of bracket defaults. All use actual reported screen
                    time — no artificial floors.
                  </div>
                </div>
              </div>

              {/* Screen time data */}
              <div style={{ ...card, marginBottom: 14 }}>
                <div
                  style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.dark, marginBottom: 8 }}
                >
                  Screen Time Averages: What the Data Says
                </div>
                <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
                  {[
                    {
                      stat: "4h 44m/day",
                      pop: "Kids (8–12)",
                      src: "Common Sense Media Census 2021",
                      note: "Entertainment screen time only — does not include school/required device use. Most recent tween/teen Census.",
                    },
                    {
                      stat: "8h 39m/day",
                      pop: "Teens (13–18)",
                      src: "Common Sense Media Census 2021",
                      note: "Entertainment screen time. A separate 2023 smartphone-tracking study ('Constant Companion') found teens check phones 100+ times/day.",
                    },
                    {
                      stat: "6h 37m/day",
                      pop: "Adults (18+)",
                      src: "Nielsen Total Audience Report / eMarketer 2023",
                      note: "Includes TV, smartphone, computer, tablet. Varies significantly by employment status.",
                    },
                    {
                      stat: "93%",
                      pop: "Teen free time",
                      src: "Dino Ambrosi; defrag. calculation",
                      note: "Based on ~8h average screen use (Common Sense Census 2021) against ~8.6h average teen free time (24h − sleep − school − obligations). First popularized by Dino Ambrosi's TEDx talk.",
                    },
                    {
                      stat: "~26 years",
                      pop: "Lifetime (80-yr life)",
                      src: "defrag. projection at 8h/day",
                      note: "Calendar years: (8h ÷ 24h) × 80 years ≈ 26.7 years. Waking-hour percentage is higher (~48%).",
                    },
                  ].map((r) => (
                    <div
                      key={r.stat}
                      style={{
                        background: C.surfaceAlt,
                        borderRadius: 9,
                        padding: "10px 12px",
                        border: `1px solid ${C.border}`,
                      }}
                    >
                      <div
                        style={{
                          display: "flex",
                          gap: 12,
                          alignItems: "baseline",
                          marginBottom: 3,
                        }}
                      >
                        <span style={{ ...sr, fontSize: 18, fontWeight: 700, color: C.mid }}>
                          {r.stat}
                        </span>
                        <span style={{ fontSize: 12, fontWeight: 700, color: C.dark }}>
                          {r.pop}
                        </span>
                      </div>
                      <div style={{ fontSize: 11, color: C.muted, marginBottom: 3 }}>{r.note}</div>
                      <div style={{ fontSize: 11, color: C.faint, fontStyle: "italic" }}>
                        {r.src}
                      </div>
                    </div>
                  ))}
                </div>
              </div>

              {/* Total lifetime screen years */}
              <div style={{ ...card, marginBottom: 14 }}>
                <div
                  style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.dark, marginBottom: 8 }}
                >
                  Total Lifetime Screen Years (Adults)
                </div>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: "0 0 10px" }}>
                  For users age 22+, the hero stat shows total lifetime screen years: past screen
                  time (computed from age 2 to current age using the whole-life screen history
                  model) plus future projected screen time. Kids and teens see only remaining years,
                  since their past screen time is relatively small.
                </p>
                <div
                  style={{
                    background: C.dark,
                    borderRadius: 8,
                    padding: "10px 14px",
                    marginBottom: 8,
                    fontFamily: "'SF Mono',monospace",
                    fontSize: 12,
                    color: "#2dd4bf",
                    lineHeight: 1.8,
                  }}
                >
                  pastScreenYears = computeLifetimeScreenYears(age, fd, totalScrH, smartphoneAge)
                  <br />
                  futureScreenYears = (statScrH / 24) × yearsRem
                  <br />
                  totalLifetimeScreenYears = pastScreenYears + futureScreenYears
                </div>
              </div>

              {/* Lifetime projection methodology */}
              <div style={{ ...card, marginBottom: 14 }}>
                <div
                  style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.dark, marginBottom: 8 }}
                >
                  Lifetime Projection Methodology
                </div>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: "0 0 10px" }}>
                  The lifetime dot grid represents{" "}
                  <strong style={{ color: C.dark }}>remaining months of life</strong> from the
                  user's current age to age 78 (CDC NCHS 2022 estimate of 77.5 years). Each dot = 1
                  month, 1 row = ~1 year (14 columns). Dots are colored by category using
                  phase-weighted averages across four life stages. For adults 22+, a full-life grid
                  (birth to 78) is shown with a "you are here" marker.
                </p>
                <div
                  style={{
                    background: C.surfaceAlt,
                    borderRadius: 9,
                    padding: "11px 14px",
                    marginBottom: 10,
                    border: `1px solid ${C.border}`,
                  }}
                >
                  <div style={{ fontWeight: 700, color: C.dark, fontSize: 13, marginBottom: 6 }}>
                    Life Phases Used for Projection
                  </div>
                  <table style={{ width: "100%", borderCollapse: "collapse", fontSize: 12 }}>
                    <thead>
                      <tr style={{ borderBottom: `1px solid ${C.border}` }}>
                        {["Phase", "Ages", "Sleep", "Chores", "Meals", "Commute", "Caregiving"].map(
                          (h) => (
                            <th
                              key={h}
                              style={{
                                padding: "5px 8px",
                                textAlign: "left",
                                color: C.dark,
                                fontWeight: 700,
                                fontSize: 11,
                              }}
                            >
                              {h}
                            </th>
                          )
                        )}
                      </tr>
                    </thead>
                    <tbody>
                      {[
                        ["Childhood", "5–13", "10.0h", "0.25h", "0.75h", "0.25h", "—"],
                        ["Adolescence", "13–18", "8.5h", "0.5h", "1.0h", "0.5h", "—"],
                        ["Working adult", "18–65", "7.5h", "1.0h", "1.25h", "0.9h", "0.9h"],
                        ["Retirement", "65–79", "7.5h", "0.75h", "1.0h", "0.25h", "0.5h"],
                      ].map(([phase, ...vals], i) => (
                        <tr
                          key={phase}
                          style={{
                            borderBottom: `1px solid ${C.border}`,
                            background: i % 2 === 0 ? "transparent" : C.tealFaint,
                          }}
                        >
                          <td
                            style={{
                              padding: "5px 8px",
                              fontWeight: 600,
                              color: C.dark,
                              fontSize: 11,
                            }}
                          >
                            {phase}
                          </td>
                          {vals.map((v, j) => (
                            <td
                              key={j}
                              style={{ padding: "5px 8px", color: C.muted, fontSize: 11 }}
                            >
                              {v}
                            </td>
                          ))}
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: "0 0 8px" }}>
                  For each category, the lifetime average is computed as a weighted mean across
                  phases:
                </p>
                <div
                  style={{
                    background: C.dark,
                    borderRadius: 8,
                    padding: "10px 14px",
                    marginBottom: 8,
                    fontFamily: "'SF Mono',monospace",
                    fontSize: 12,
                    color: "#2dd4bf",
                    lineHeight: 1.8,
                  }}
                >
                  lifetimeAvg = Σ(phase_value × years_in_phase) ÷ total_remaining_years
                </div>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: "0 0 8px" }}>
                  School years run from current age to 18 (extended by college: +2 for community,
                  +1.5 for trade, +4 for university). Work years run from school end to 65. Screen
                  time uses the <strong style={{ color: C.dark }}>weekly average (avgSH)</strong>,
                  which accounts for weekend extra hours. defrag. does not assume behavior change in
                  the baseline projection.
                </p>
                <div
                  style={{
                    background: C.tealFaint,
                    borderRadius: 8,
                    padding: "9px 12px",
                    fontSize: 12,
                    color: C.dark,
                    lineHeight: 1.6,
                    borderLeft: `3px solid ${C.mid}`,
                  }}
                >
                  <strong>Source:</strong> BLS American Time Use Survey 2023 · CDC NCHS Life Tables
                  2023 · NSF Sleep Foundation age recommendations
                </div>
              </div>

              {/* Key studies */}
              <div style={{ ...card, marginBottom: 14 }}>
                <div
                  style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.dark, marginBottom: 10 }}
                >
                  Key Research
                </div>
                <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
                  {[
                    {
                      citation:
                        "Singh, B., Zhou, M., Curtis, R., Maher, C. & Dumuid, D. (2026). Social Media Use and Well-Being Across Adolescent Development. JAMA Pediatrics. Published online January 12, 2026.",
                      title:
                        "Social media use and wellbeing in adolescents: A longitudinal study of 100,991 students",
                      summary:
                        "The largest longitudinal study of its kind, tracking Australian adolescents across grades 4–12 over three years. Found a U-shaped association: moderate social media use was associated with the best wellbeing outcomes across happiness, optimism, life satisfaction, and cognitive engagement. Both heavy use and complete abstention were associated with poorer wellbeing. Effects varied by age and sex — heavy use most harmful for girls in middle adolescence; no use associated with isolation risk for boys from grade 9 onward. Important caveat: the study population is Australian; U.S. social media usage patterns, school structures, and cultural contexts differ. Findings are directional and conceptually relevant, but not directly transferable as U.S. population data.",
                      relevance:
                        "Informs defrag.'s non-zero screen time framing — the goal is calibration, not elimination.",
                    },
                    {
                      citation:
                        "Mark, G., Gudith, D., &amp; Klocke, U. (2008). The cost of interrupted work: more speed and stress. Proceedings of the ACM CHI Conference. AND: Mark, G. (2023). Attention Span. Harper Collins.",
                      title: "Attention recovery after digital interruption",
                      summary:
                        "The 23-minute-15-second recovery time comes from Mark et al.'s 2008 CHI conference paper measuring task resumption after interruption in office workers — a peer-reviewed finding. The claim that average continuous attention on a screen has dropped from 2.5 minutes (2004) to 47 seconds (2023) appears in Mark's 2023 popular press book Attention Span and is based on her lab's ongoing observation data; it has not been published as a standalone peer-reviewed result. These two findings should be treated as distinct: the 23-minute figure is well-sourced; the 47-second figure is from a book and warrants separate citation if used in academic contexts.",
                      relevance:
                        "Powers the recovery timeline, the 23-minute mark, and the protected brain time rationale.",
                    },
                    {
                      citation: "Stone, L. (2009). Continuous Partial Attention. lindastone.net.",
                      title: "Continuous partial attention as a modern attention mode",
                      summary:
                        "Linda Stone coined 'continuous partial attention' to describe keeping tabs on everything while never giving full attention to anything. Unlike multitasking (motivated by productivity), CPA is motivated by not wanting to miss anything. This concept directly informed defrag.'s filler screen time model — the phone checks during meals, commute scrolling, and bedtime browsing that fragment attention continuously.",
                      relevance:
                        "Conceptual foundation for the day walkthrough and filler screen time layer.",
                    },
                    {
                      citation: "Oulasvirta, A. et al. (2012). Personal and Ubiquitous Computing.",
                      title: "Habits make smartphone use more pervasive",
                      summary:
                        "Found that the average smartphone check lasts approximately 30 seconds — too brief to register as a 'session' in screen time reports. Users check habitually, not intentionally. This duration estimate is used by defrag. to compute ambient pickup exposure.",
                      relevance:
                        "Source for the pickup ambient exposure estimate in Steps 3 and 7.",
                    },
                    {
                      citation:
                        "Przybylski, A.K. &amp; Weinstein, N. (2017). Psychological Science.",
                      title: "A large-scale test of the Goldilocks hypothesis",
                      summary:
                        "Study of 120,115 UK adolescents found a non-linear relationship between digital screen time and wellbeing — small amounts were not harmful and may be beneficial; harms emerged at higher doses. No single threshold fits all ages, contexts, or device types. Critiqued for relying on self-report but influential in shifting the field away from binary restriction models.",
                      relevance:
                        "Supports defrag.'s dose-framing and the insight that the question is 'how much' not 'whether'.",
                    },
                    {
                      citation:
                        "Common Sense Media (2023). The Common Sense Census: Media Use by Tweens and Teens.",
                      title: "National U.S. survey, n=1,623 youth ages 8–18",
                      summary:
                        "Kids ages 8–12 average 4 hours 44 minutes of entertainment screen time daily (up from 4h 44m in 2021, nearly double the 2015 figure). Teens ages 13–18 average 8 hours 39 minutes — up from 7h 22m in 2021. Social media, online video, and gaming account for the majority of time. Low-income youth show higher rates across all platforms.",
                      relevance:
                        "Primary source for the screen time defaults and the opening stat trio (7–8h average, 93% of free time).",
                    },
                    {
                      citation:
                        "Ambrosi, D. Visual essay / infographic (widely circulated c. 2019–2021; exact original publication date unverified).",
                      title: "Lifetime screen time as a dot grid visualization",
                      summary:
                        "Ambrosi's widely circulated visual essay represented a human lifetime as a grid of months, shading the portion consumed by screens. The visual had significant behavioral impact because it made an abstract number concrete and spatial. Note: this work is a visual essay, not a peer-reviewed study. defrag.'s lifetime grid is directly inspired by this format, extended with interactive user data, category breakdown, and an ideal-scenario comparison.",
                      relevance:
                        "Direct inspiration for The Reveal (Step 4) lifetime dot grid format.",
                    },
                    {
                      citation: "Note: Source pending verification.",
                      title: "Interactive modeling and durable behavior change",
                      summary:
                        "The design principle behind defrag.'s goal-first structure draws on documented research showing that interactive, self-directed exploration produces more durable behavior change than passive information delivery. The specific academic source for the ASU water conservation model referenced in earlier versions has not been independently verified and has been removed pending confirmation. The underlying principle is supported by self-determination theory (Deci &amp; Ryan, 1985) and well-established in behavior change literature.",
                      relevance:
                        "Design rationale for the values-first, goal-led structure. A specific peer-reviewed citation for the interactive modeling claim will be added once verified.",
                    },
                  ].map((r) => (
                    <div
                      key={r.citation}
                      style={{ borderBottom: `1px solid ${C.border}`, paddingBottom: 12 }}
                    >
                      <div
                        style={{ fontSize: 12, fontWeight: 700, color: C.dark, marginBottom: 2 }}
                      >
                        {r.title}
                      </div>
                      <div
                        style={{ fontSize: 11, color: C.mid, fontStyle: "italic", marginBottom: 5 }}
                      >
                        {r.citation}
                      </div>
                      <p
                        style={{
                          fontSize: 12,
                          color: C.muted,
                          lineHeight: 1.65,
                          margin: "0 0 5px",
                        }}
                      >
                        {r.summary}
                      </p>
                      <div
                        style={{
                          fontSize: 11,
                          color: C.dark,
                          background: C.tealFaint,
                          borderRadius: 6,
                          padding: "4px 9px",
                          display: "inline-block",
                        }}
                      >
                        <strong>Why it's here:</strong> {r.relevance}
                      </div>
                    </div>
                  ))}
                </div>
              </div>

              {/* Design rationale */}
              <div style={{ ...card, marginBottom: 14 }}>
                <div
                  style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.dark, marginBottom: 8 }}
                >
                  Design Rationale: Why Values-First Works
                </div>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: "0 0 10px" }}>
                  Most screen time interventions start with a number — "no more than 2 hours" — and
                  work backward. The research suggests this approach has low durability. Externally
                  imposed limits trigger reactance (Brehm, 1966), are abandoned once removed, and
                  don't build the internal reasoning that drives lasting change.
                </p>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: "0 0 10px" }}>
                  defrag. inverts this. Users start by mapping what they actually want their time to
                  contain — sleep, obligations, interests, relationships. The screen time question
                  comes <em>after</em> the rest of the day is filled in. The number the user arrives
                  at is self-derived, grounded in their own stated values. This aligns with
                  self-determination theory (Deci &amp; Ryan, 1985), which identifies autonomy,
                  competence, and relatedness as the core drivers of intrinsic motivation and
                  durable behavior change.
                </p>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: "0 0 10px" }}>
                  The tool also avoids pathologizing. It does not call any amount of screen time
                  "addictive" or label users as having a problem. The framing is economic: time is a
                  finite resource, allocation is a choice, and the question is whether the current
                  allocation matches stated priorities. This approach is consistent with media
                  balance frameworks (Common Sense Media, American Academy of Pediatrics Family
                  Media Plan).
                </p>
                <div
                  style={{
                    background: C.surfaceAlt,
                    borderRadius: 8,
                    padding: "10px 12px",
                    fontSize: 12,
                    color: C.muted,
                    lineHeight: 1.65,
                    borderLeft: `3px solid ${C.amber}`,
                  }}
                >
                  <strong style={{ color: C.dark }}>A note on measurement:</strong> defrag. uses
                  self-reported screen time, which research consistently shows is underestimated by
                  30–50% (Sewall et al., 2020; Ellis et al., 2019). Step 2 prompts users to check
                  their device's screen time report. The day walkthrough captures filler time that
                  self-reports typically miss.
                </div>
              </div>

              {/* Limitations */}
              <div style={{ ...card, marginBottom: 14 }}>
                <div
                  style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.dark, marginBottom: 8 }}
                >
                  Limitations &amp; Caveats
                </div>
                <ul
                  style={{
                    fontSize: 13,
                    color: C.muted,
                    lineHeight: 1.9,
                    margin: 0,
                    paddingLeft: 18,
                  }}
                >
                  <li>
                    All defaults are population averages. Individual variation is high — defaults
                    are starting points, not prescriptions.
                  </li>
                  <li>
                    Screen time is not monolithic. Educational, creative, and social screen use have
                    different wellbeing profiles than passive consumption. defrag. distinguishes
                    required vs. personal screens but does not subdivide personal screen quality.
                  </li>
                  <li>
                    Lifetime projections assume current behavior continues unchanged — a deliberate
                    choice to make the status quo legible, not a prediction.
                  </li>
                  <li>
                    Life expectancy anchor (78, CDC NCHS 2022) uses U.S. national average. It varies
                    significantly by race, income, sex, and geography — masking a ~10-year gap
                    between income quintiles.
                  </li>
                  <li>
                    Day walkthrough filler estimates are based on option ranges (e.g., "5–10
                    minutes" mapped to 8m), not precise measurements. Actual filler time may be
                    higher or lower.
                  </li>
                  <li>
                    Protected brain time assumes audio-occupied time (podcasts, music during
                    routines) is not "protected" — some users may reasonably disagree.
                  </li>
                  <li>
                    The 2.5h screen intensity threshold is a design choice for framing, not a
                    clinical cutoff.
                  </li>
                  <li>
                    Whole-life screen history uses estimated baselines and a logarithmic ramp model
                    — directional, not precise.
                  </li>
                </ul>
              </div>

              <div style={{ display: "flex", gap: 10, flexWrap: "wrap" }}>
                <a
                  href="https://prompt-ed.org"
                  target="_blank"
                  rel="noreferrer"
                  style={{
                    flex: 1,
                    minWidth: 140,
                    ...bPrimary,
                    textAlign: "center",
                    textDecoration: "none",
                    display: "block",
                    padding: "11px 16px",
                  }}
                >
                  prompt-ed.org
                </a>
                <button
                  onClick={() => setShowResearch(false)}
                  style={{ flex: 1, minWidth: 140, ...bOutline }}
                >
                  ← Back to defrag.
                </button>
              </div>
            </div>
          ) : /* ── ABOUT PAGE ── */
          showAbout ? (
            <div>
              <div style={{ ...sr, fontSize: 22, fontWeight: 700, color: C.dark, marginBottom: 4 }}>
                About defrag.
              </div>
              <div style={{ fontSize: 13, color: C.muted, marginBottom: 18, fontStyle: "italic" }}>
                A tool from{" "}
                <a
                  href="https://prompt-ed.org"
                  target="_blank"
                  rel="noreferrer"
                  style={{ color: C.mid, fontWeight: 600, textDecoration: "none" }}
                >
                  prompt-ed.org
                </a>{" "}
                · Created by Rebecca Guglielmo
              </div>

              <div
                style={{
                  background: C.tealFaint,
                  border: `1px solid ${C.tealLight}50`,
                  borderRadius: 12,
                  padding: "16px 18px",
                  marginBottom: 16,
                }}
              >
                <div
                  style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.dark, marginBottom: 8 }}
                >
                  It started with a conversation with my daughter.
                </div>
                <p style={{ fontSize: 13, color: C.dark, lineHeight: 1.7, margin: "0 0 10px" }}>
                  She's a teenager. Smart, curious, connected. One evening I asked her how much time
                  she thought she'd spent on her phone that day. She guessed about two hours. Her
                  screen time report said six and a half.
                </p>
                <p style={{ fontSize: 13, color: C.dark, lineHeight: 1.7, margin: "0 0 10px" }}>
                  That gap — between what we think we're doing and what we're actually doing —
                  stopped me. But what happened next mattered more.
                </p>
                <p style={{ fontSize: 13, color: C.dark, lineHeight: 1.7, margin: "0 0 10px" }}>
                  I pulled out a blank piece of paper. We sat down together and I walked her through
                  the math. Her sleep. School. Homework. The things she actually wanted to do —
                  basketball, reading, time with friends. One by one, we filled in what mattered.
                  Then we looked at what was left.
                </p>
                <p style={{ fontSize: 13, color: C.dark, lineHeight: 1.7, margin: "0 0 10px" }}>
                  On her own, without me telling her a number, she landed on about one to two hours
                  of screens a day. Her answer. Her reasoning. Her choice.
                </p>
                <p style={{ fontSize: 13, color: C.dark, lineHeight: 1.7, margin: 0 }}>
                  That piece of paper became the first draft of this project. defrag. is the tool I
                  wished I'd had — and the conversation I think every family deserves to have.
                </p>
              </div>

              <div style={{ ...card, marginBottom: 14 }}>
                <div
                  style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.dark, marginBottom: 8 }}
                >
                  Why "defrag."?
                </div>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: "0 0 8px" }}>
                  When a hard drive gets fragmented, storage is scattered everywhere — the system
                  slows, space disappears, nothing runs cleanly. Defragmenting reorganizes it. You
                  get back capacity you didn't know you'd lost.
                </p>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: 0 }}>
                  That's what this tool is for. Not restriction. Reorganization. Reclaiming the
                  cognitive space that screens have quietly occupied — so there's room again for the
                  things that actually build a life.
                </p>
              </div>

              <div style={{ ...card, marginBottom: 14 }}>
                <div
                  style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.dark, marginBottom: 8 }}
                >
                  The core idea
                </div>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: "0 0 8px" }}>
                  Most screen time conversations start with the screen. defrag. starts somewhere
                  else: with your ideal day. What you actually want to do with your time. What
                  matters to you.
                </p>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: "0 0 8px" }}>
                  Once you've mapped that — your sleep, your commitments, your interests, your
                  chosen balance — the screen time picture becomes clear on its own. Not as a
                  verdict. As information.
                </p>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: 0 }}>
                  <strong style={{ color: C.dark }}>
                    AI is not the enemy. Cognitive displacement is.
                  </strong>{" "}
                  The answer isn't restriction — it's capacity-building. That's the lens this tool
                  is built on.
                </p>
              </div>

              <div style={{ ...card, marginBottom: 14 }}>
                <div
                  style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.dark, marginBottom: 8 }}
                >
                  Why this works: the insight behind the design
                </div>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: "0 0 10px" }}>
                  Researchers studying behavior change have found something counterintuitive:
                  telling people data isn't enough. Charts, statistics, and expert recommendations
                  rarely move behavior in lasting ways. What works is letting people see it,
                  manipulate it, and arrive at their own conclusions.
                </p>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: "0 0 10px" }}>
                  Researchers at Arizona State University were working on water conservation. They
                  built an interactive model — a system of dials representing agriculture, pools,
                  landscaping, residential and commercial use. Instead of telling people what to do,
                  they let them explore the numbers themselves. Turning the dials. Watching the
                  consequences. People who engaged with the model made more meaningful and lasting
                  changes than those who simply received information.
                </p>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: 0 }}>
                  That insight is the foundation of defrag. Instead of telling you how much screen
                  time is too much, the tool lets you build your own ideal day first — your sleep,
                  your values, your interests — and then see the gap yourself. The number you arrive
                  at is yours. That's what makes it stick.
                </p>
              </div>

              <div style={{ ...card, marginBottom: 14 }}>
                <div
                  style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.dark, marginBottom: 8 }}
                >
                  The research behind it
                </div>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: "0 0 8px" }}>
                  defrag. is grounded in the Singh et al. <em>JAMA Pediatrics</em> 2026 study — the
                  largest longitudinal study of its kind, following 100,991 Australian adolescents
                  across grades 4–12 over three years. The study found a U-shaped association
                  between after-school social media use and wellbeing: moderate use was associated
                  with the best outcomes across happiness, optimism, life satisfaction, emotional
                  regulation, and cognitive engagement. Both the highest use and complete non-use
                  were associated with poorer wellbeing, with effects varying significantly by age
                  and sex. For girls, high use was most harmful in middle adolescence (grades 7–9).
                  For boys, no use became increasingly associated with poor wellbeing from grade 9
                  onward — suggesting that social isolation, not just heavy use, is a risk.
                </p>
                <div
                  style={{
                    background: C.surfaceAlt,
                    borderRadius: 8,
                    padding: "10px 12px",
                    fontSize: 12,
                    color: C.muted,
                    lineHeight: 1.6,
                    borderLeft: `3px solid ${C.mid}`,
                  }}
                >
                  Additional anchors: WHO/CDC physical activity guidelines · Dr. Gloria Mark (UC
                  Irvine) on attention recovery · CDC NCHS 2024 life expectancy data · Pew Research
                  technoference data
                </div>
              </div>

              <div style={{ ...card, marginBottom: 14 }}>
                <div
                  style={{ ...sr, fontSize: 15, fontWeight: 700, color: C.dark, marginBottom: 8 }}
                >
                  About the creator
                </div>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: "0 0 10px" }}>
                  Rebecca Guglielmo is a digital literacy advocate, researcher, author, and speaker
                  focused on the intersection of adolescence, technology, and learning. A Common
                  Sense Educator with more than a decade of experience working with students,
                  families, and schools, she has developed AI policy, guidelines, and digital
                  citizenship programming designed to protect deep learning while preparing students
                  to use digital media and artificial intelligence with intention.
                </p>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: "0 0 10px" }}>
                  She is the author of <em>Half Life Gone</em> — a book about how a quarter century
                  of screens, algorithms, and AI has displaced the cognitive space humans need to
                  think, create, remember, and become themselves.
                </p>
                <p style={{ fontSize: 13, color: C.muted, lineHeight: 1.7, margin: 0 }}>
                  defrag. is part of <strong style={{ color: C.dark }}>Prompt-Ed</strong> — a
                  professional development and digital literacy resource suite for educators and
                  families.
                </p>
              </div>

              <div
                style={{
                  background: C.dark,
                  borderRadius: 12,
                  padding: "16px 18px",
                  marginBottom: 14,
                  border: `1px solid ${C.mid}30`,
                }}
              >
                <div
                  style={{ ...sr, fontSize: 14, fontWeight: 700, color: C.mid, marginBottom: 6 }}
                >
                  Want to go deeper with students?
                </div>
                <p
                  style={{
                    fontSize: 13,
                    color: "rgba(255,255,255,0.75)",
                    lineHeight: 1.7,
                    margin: "0 0 12px",
                  }}
                >
                  The Ethical Tech Lab is a student-facing program that takes these ideas further —
                  an Ethics Bowl-style tournament where students analyze real digital dilemmas,
                  debate policy, and develop their own positions on technology, AI, and the future.
                  Built for grades 5–8, it turns passive screen time awareness into active critical
                  thinking.
                </p>
                <div style={{ fontSize: 12, color: "rgba(255,255,255,0.7)", fontStyle: "italic" }}>
                  Ask us about bringing the Ethical Tech Lab & Tournament to your school. →
                  rebecca@prompt-ed.org
                </div>
              </div>

              <div
                style={{
                  background: C.dark,
                  borderRadius: 12,
                  padding: "16px 18px",
                  marginBottom: 14,
                }}
              >
                <p
                  style={{
                    ...sr,
                    fontStyle: "italic",
                    color: "rgba(255,255,255,0.85)",
                    fontSize: 14,
                    lineHeight: 1.7,
                    margin: "0 0 8px",
                  }}
                >
                  "Technology doesn't steal time. It occupies the time we haven't yet decided to
                  protect."
                </p>
                <div style={{ fontSize: 12, color: "rgba(255,255,255,0.7)" }}>
                  — Rebecca Guglielmo · defrag. · prompt-ed.org
                </div>
              </div>

              <div style={{ display: "flex", gap: 10, flexWrap: "wrap" }}>
                <a
                  href="https://prompt-ed.org"
                  target="_blank"
                  rel="noreferrer"
                  style={{
                    flex: 1,
                    minWidth: 140,
                    ...bPrimary,
                    textAlign: "center",
                    textDecoration: "none",
                    display: "block",
                    padding: "11px 16px",
                  }}
                >
                  prompt-ed.org
                </a>
                <button
                  onClick={() => {
                    setShowAbout(false);
                    setShowResearch(false);
                  }}
                  style={{ flex: 1, minWidth: 140, ...bOutline }}
                >
                  ← Back to defrag.
                </button>
              </div>
            </div>
          ) : /* ── OPENING CARD ── */
          showOpening ? (
            <div style={{ padding: "4px 0 4px" }}>
              {/* ── THE NAME + PITCH — combined ── */}
              <div style={{ padding: "8px 6px 14px" }}>
                <div style={{ fontSize: 15, color: C.dark, lineHeight: 1.7 }}>
                  <strong>de·frag</strong> — to recover what was always yours, but scattered across
                  someone else's feed. Like defragmenting a hard drive — your time got broken into a
                  million tiny pieces by apps fighting for your attention. This puts it back
                  together. A free 5-minute calculator that maps where your time actually goes —
                  sleep, obligations, screens, everything — then shows you what you'd get back if
                  you designed your day on purpose. Just the math, and a plan that's yours.
                </div>
              </div>

              {/* ── THE HOOK — giant stat, full-bleed dark ── */}
              <div
                style={{
                  background: "#042f2e",
                  borderRadius: 16,
                  padding: "40px 24px 36px",
                  marginBottom: 10,
                  textAlign: "center",
                  position: "relative",
                  overflow: "hidden",
                }}
              >
                <div
                  style={{
                    ...sr,
                    fontSize: "clamp(72px,20vw,110px)",
                    fontWeight: 700,
                    color: "#2dd4bf",
                    lineHeight: 0.85,
                  }}
                >
                  26
                </div>
                <div
                  style={{
                    ...sr,
                    fontSize: "clamp(28px,7vw,40px)",
                    fontWeight: 700,
                    color: "white",
                    marginTop: 4,
                  }}
                >
                  years on screens.
                </div>
                <div style={{ marginTop: 20, padding: "0 8px" }}>
                  <div style={{ fontSize: 16, color: "rgba(255,255,255,0.7)", lineHeight: 1.7 }}>
                    That's the average.
                  </div>
                  <div
                    style={{
                      ...sr,
                      fontSize: "clamp(20px,5vw,26px)",
                      fontWeight: 700,
                      color: "white",
                      lineHeight: 1.3,
                      marginTop: 6,
                    }}
                  >
                    One-third of your waking life.
                  </div>
                  <div
                    style={{
                      ...sr,
                      fontSize: "clamp(20px,5vw,26px)",
                      fontWeight: 700,
                      color: "#facc15",
                      lineHeight: 1.3,
                    }}
                  >
                    Watching someone else's.
                  </div>
                </div>
                <div
                  style={{
                    fontSize: 14,
                    color: "rgba(255,255,255,0.75)",
                    marginTop: 14,
                    letterSpacing: "0.01em",
                  }}
                >
                  And that's just entertainment screens — not counting school or work.
                </div>
                <div
                  style={{ ...sr, fontSize: 17, fontWeight: 700, color: "white", marginTop: 16 }}
                >
                  How much of your life is actually yours?
                </div>
              </div>

              {/* ── THE GUT CHECK — three full-width stat cards ── */}
              <div style={{ display: "flex", flexDirection: "column", gap: 8, marginBottom: 14 }}>
                <div
                  style={{
                    background: "#042f2e",
                    borderRadius: 12,
                    padding: "20px 22px",
                    display: "flex",
                    alignItems: "center",
                    justifyContent: "space-between",
                    gap: 16,
                  }}
                >
                  <div
                    style={{
                      ...sr,
                      fontSize: "clamp(32px,9vw,48px)",
                      fontWeight: 700,
                      color: "#facc15",
                      lineHeight: 1,
                      flexShrink: 0,
                    }}
                  >
                    7–8h
                  </div>
                  <div
                    style={{
                      fontSize: 14,
                      color: "rgba(255,255,255,0.8)",
                      lineHeight: 1.5,
                      textAlign: "right",
                    }}
                  >
                    is the average time spent on screens beyond the school day. That's a full-time
                    job — for someone else's content.
                  </div>
                </div>
                <div
                  style={{
                    background: "#042f2e",
                    borderRadius: 12,
                    padding: "20px 22px",
                    display: "flex",
                    alignItems: "center",
                    justifyContent: "space-between",
                    gap: 16,
                  }}
                >
                  <div
                    style={{
                      ...sr,
                      fontSize: "clamp(32px,9vw,48px)",
                      fontWeight: 700,
                      color: "#818cf8",
                      lineHeight: 1,
                      flexShrink: 0,
                    }}
                  >
                    93%
                  </div>
                  <div
                    style={{
                      fontSize: 14,
                      color: "rgba(255,255,255,0.8)",
                      lineHeight: 1.5,
                      textAlign: "right",
                    }}
                  >
                    of a teenager's free time is gone to screens — before they choose what they
                    really want.
                  </div>
                </div>
                <div
                  style={{
                    background: "#042f2e",
                    borderRadius: 12,
                    padding: "20px 22px",
                    display: "flex",
                    alignItems: "center",
                    justifyContent: "space-between",
                    gap: 16,
                  }}
                >
                  <div
                    style={{
                      ...sr,
                      fontSize: "clamp(32px,9vw,48px)",
                      fontWeight: 700,
                      color: "#2dd4bf",
                      lineHeight: 1,
                      flexShrink: 0,
                    }}
                  >
                    5 min
                  </div>
                  <div
                    style={{
                      fontSize: 14,
                      color: "rgba(255,255,255,0.8)",
                      lineHeight: 1.5,
                      textAlign: "right",
                    }}
                  >
                    to see the years you will lose — or gain.
                  </div>
                </div>
              </div>

              {/* ── CTA ── */}
              <button
                onClick={() => {
                  beginFreshSession();
                  setShowOpening(false);
                  scrollToTop();
                }}
                style={{
                  width: "100%",
                  padding: "18px 18px",
                  fontSize: 17,
                  fontWeight: 700,
                  letterSpacing: "0.01em",
                  background: "#0f766e",
                  color: "white",
                  border: "none",
                  borderRadius: 12,
                  cursor: "pointer",
                  boxShadow: "0 6px 24px rgba(15,118,110,0.35)",
                  marginBottom: 8,
                }}
              >
                Do the math and find my number →
              </button>
              <div style={{ fontSize: 11, color: C.faint, lineHeight: 1.5, textAlign: "center" }}>
                5 minutes · anonymous data helps research · nothing sold, ever
              </div>
              {hasSavedSession ? (
                <div
                  style={{
                    textAlign: "center",
                    marginTop: 10,
                    background: C.tealFaint,
                    borderRadius: 10,
                    padding: "10px 14px",
                    border: `1px solid ${C.tealLight}40`,
                  }}
                >
                  <div style={{ fontSize: 12, color: C.mid, fontWeight: 700, marginBottom: 4 }}>
                    Welcome back
                  </div>
                  <div style={{ fontSize: 11, color: C.dark, lineHeight: 1.55, marginBottom: 8 }}>
                    We saved your last session on this device. Pick up where you left off?
                  </div>
                  <div
                    style={{ display: "flex", gap: 8, justifyContent: "center", flexWrap: "wrap" }}
                  >
                    <button
                      onClick={() => {
                        if (restoreSavedSession()) {
                          setReturningUser(true);
                          setShowOpening(false);
                          scrollToTop();
                        }
                      }}
                      style={{
                        background: C.mid,
                        color: "white",
                        border: "none",
                        borderRadius: 8,
                        padding: "6px 14px",
                        fontSize: 12,
                        fontWeight: 700,
                        cursor: "pointer",
                      }}
                    >
                      Restore my answers
                    </button>
                    <button
                      onClick={() => {
                        beginFreshSession();
                        setShowOpening(false);
                        scrollToTop();
                      }}
                      style={{
                        background: "transparent",
                        color: C.muted,
                        border: `1px solid ${C.border}`,
                        borderRadius: 8,
                        padding: "6px 14px",
                        fontSize: 12,
                        cursor: "pointer",
                      }}
                    >
                      Start fresh
                    </button>
                  </div>
                </div>
              ) : (
                <div style={{ textAlign: "center", marginTop: 6 }}>
                  <span
                    onClick={() => {
                      beginFreshSession();
                      setReturningUser(true);
                      setShowOpening(false);
                      scrollToTop();
                    }}
                    style={{
                      fontSize: 11,
                      color: C.faint,
                      cursor: "pointer",
                      textDecoration: "underline",
                      textUnderlineOffset: 2,
                    }}
                  >
                    I've done this before →
                  </span>
                </div>
              )}
            </div>
          ) : (
            /* ── STEPS ── */
            <>
              {/* Top nav — quick advance */}
              {step < LAST_STEP && (
                <div
                  style={{
                    display: "flex",
                    justifyContent: "space-between",
                    alignItems: "center",
                    marginBottom: 14,
                  }}
                >
                  {step > STEP.ABOUT ? (
                    <button
                      onClick={() => {
                        setStep((s) => s - 1);
                        scrollToTop();
                      }}
                      style={{ ...bOutline, fontSize: 12, padding: "5px 14px" }}
                    >
                      ← Back
                    </button>
                  ) : (
                    <div />
                  )}
                  <button
                    onClick={() => {
                      setStep((s) => s + 1);
                      scrollToTop();
                    }}
                    style={{ ...bPrimary, fontSize: 12, padding: "5px 14px" }}
                  >
                    {
                      [
                        "Invest Your Time →",
                        "Your Day With Screens →",
                        "Design Your Screen Time →",
                        "The Reveal →",
                        "Protected Brain Time →",
                        "Your Possibilities →",
                        "Your Plan →",
                        "The Bigger Picture →",
                      ][step]
                    }
                  </button>
                </div>
              )}
              {step === STEP.ABOUT && <Step1 />}
              {step === STEP.INVEST && <InvestYourTime />}
              {step === STEP.DAY && <DayWithScreens />}
              {step === STEP.DESIGN && <DesignScreenTime />}
              {step === STEP.REVEAL && <RevealStep />}
              {step === STEP.PBT && <ProtectedBrainTimeStep />}
              {step === STEP.POSSIBILITIES && <PossibilitiesStep />}
              {step === STEP.PLAN && <PlanStep />}
              {step === STEP.BIGGER && <BiggerPicture />}
            </>
          )}
        </div>
        {!showAbout && !showOpening && (
          <div style={{ display: "flex", justifyContent: "space-between", gap: 10 }}>
            {step > STEP.ABOUT ? (
              <button
                onClick={() => {
                  setStep((s) => s - 1);
                  scrollToTop();
                }}
                style={bOutline}
              >
                ← Back
              </button>
            ) : (
              <div />
            )}
            {step < LAST_STEP && (
              <button
                onClick={() => {
                  setStep((s) => s + 1);
                  scrollToTop();
                }}
                style={{ ...bPrimary, boxShadow: "0 4px 14px rgba(13,148,136,0.3)" }}
              >
                {
                  [
                    "Invest Your Time →",
                    "Your Day With Screens →",
                    "Design Your Screen Time →",
                    "The Reveal →",
                    "Protected Brain Time →",
                    "Your Possibilities →",
                    "Your Plan →",
                    "The Bigger Picture →",
                  ][step]
                }
              </button>
            )}
          </div>
        )}
        <div
          style={{
            textAlign: "center",
            marginTop: 20,
            fontSize: 11,
            color: C.faint,
            lineHeight: 2,
          }}
        >
          <a
            href="https://prompt-ed.org"
            target="_blank"
            rel="noreferrer"
            style={{ color: C.mid, fontWeight: 700, textDecoration: "none", fontSize: 12 }}
          >
            ← prompt-ed.org
          </a>
          <span style={{ margin: "0 8px", color: C.border }}>·</span>
          <strong style={{ color: C.mid }}>defrag.</strong> · Recalibrate. · The future belongs to
          the curious.
        </div>
        <div
          style={{
            background: C.tealFaint,
            borderRadius: 10,
            padding: "10px 16px",
            marginTop: 14,
            display: "flex",
            alignItems: "center",
            justifyContent: "space-between",
            gap: 10,
            flexWrap: "wrap",
            border: `1px solid ${C.tealLight}`,
          }}
        >
          <div style={{ fontSize: 12, color: C.mid, fontWeight: 500 }}>
            Early access — found a bug or have a suggestion?
          </div>
          <button
            style={{
              fontSize: 12,
              background: C.mid,
              color: "white",
              border: "none",
              borderRadius: 6,
              padding: "5px 12px",
              cursor: "pointer",
              fontWeight: 600,
              flexShrink: 0,
            }}
          >
            Share feedback
          </button>
        </div>
        {/* Age group selector removed — single age-driven flow */}
      </div>
    </main>
  );
}

// ── Error boundary — catches render errors so users see a helpful message
// instead of a blank white screen. Preserves their saved data and offers
// recovery options.
class DefragErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { err: null };
  }
  static getDerivedStateFromError(err) {
    return { err };
  }
  componentDidCatch(err, info) {
    try {
      console.error("defrag. crashed:", err, info);
    } catch {}
    // Crash telemetry — send a minimal anonymous report to the same Google
    // Apps Script endpoint the auto-collect uses. Honors the research opt-out
    // (stored in the user's saved session if it exists). Fails silently —
    // we never want the reporting path to cause a second crash on top of
    // the first one.
    try {
      let optedIn = true;
      try {
        const raw = localStorage.getItem("defrag:v1");
        if (raw) {
          const parsed = JSON.parse(raw);
          if (parsed && parsed.researchOptIn === false) optedIn = false;
        }
      } catch {}
      if (!optedIn) return;
      const payload = {
        type: "crash",
        ts: new Date().toISOString(),
        msg: (err && err.message) || String(err),
        // First 6 lines of stack is usually enough to identify the culprit
        // without shipping a massive blob.
        stack: err && err.stack ? String(err.stack).split("\n").slice(0, 6).join("\n") : null,
        componentStack:
          info && info.componentStack
            ? String(info.componentStack).split("\n").slice(0, 6).join("\n")
            : null,
        ua: typeof navigator !== "undefined" ? navigator.userAgent : null,
        viewport:
          typeof window !== "undefined" ? `${window.innerWidth}x${window.innerHeight}` : null,
      };
      fetch(
        "https://script.google.com/macros/s/AKfycbyHAQ5Nc-FnK9swxdNz8CdFcY6xv6biCLaXN7IDubNzTNrSrT2oRn2foFWhXPz0xBpJ_w/exec",
        {
          method: "POST",
          headers: { "Content-Type": "text/plain;charset=utf-8" },
          body: JSON.stringify(payload),
        }
      ).catch(() => {});
    } catch {}
  }
  render() {
    if (!this.state.err) return this.props.children;
    const msg = (this.state.err && this.state.err.message) || String(this.state.err);
    let savedRaw = "";
    try {
      savedRaw = localStorage.getItem("defrag:v1") || "";
    } catch {}
    const hasSave = savedRaw.length > 0;
    return React.createElement(
      "div",
      {
        style: {
          maxWidth: 560,
          margin: "40px auto",
          padding: "32px 24px",
          fontFamily: "Inter,-apple-system,sans-serif",
          color: "#042f2e",
          background: "#f0fdfa",
          borderRadius: 16,
          border: "1px solid #5eead4",
          lineHeight: 1.6,
        },
      },
      React.createElement(
        "div",
        {
          style: {
            fontSize: 11,
            fontWeight: 700,
            letterSpacing: "0.12em",
            textTransform: "uppercase",
            color: "#dc2626",
            marginBottom: 8,
          },
        },
        "Something broke"
      ),
      React.createElement(
        "h1",
        {
          style: {
            fontFamily: "'Libre Baskerville',Georgia,serif",
            fontSize: 24,
            fontWeight: 700,
            margin: "0 0 10px",
            lineHeight: 1.2,
          },
        },
        "defrag. hit an unexpected error."
      ),
      React.createElement(
        "p",
        { style: { fontSize: 14, margin: "0 0 16px" } },
        "Your answers are saved on this device. You can reload to try again, or start over if the error keeps happening."
      ),
      React.createElement(
        "div",
        {
          style: {
            background: "rgba(4,47,46,0.05)",
            borderRadius: 8,
            padding: "10px 14px",
            fontFamily: "'SF Mono',Menlo,monospace",
            fontSize: 11,
            color: "#0f766e",
            marginBottom: 16,
            overflow: "auto",
            maxHeight: 120,
          },
        },
        msg
      ),
      React.createElement(
        "div",
        { style: { display: "flex", gap: 10, flexWrap: "wrap" } },
        React.createElement(
          "button",
          {
            onClick: () => window.location.reload(),
            style: {
              background: "#0f766e",
              color: "white",
              border: "none",
              borderRadius: 8,
              padding: "10px 18px",
              fontSize: 13,
              fontWeight: 700,
              cursor: "pointer",
            },
          },
          "Reload and try again"
        ),
        hasSave &&
          React.createElement(
            "button",
            {
              onClick: () => {
                if (confirm("Clear your saved answers and start over? This can't be undone.")) {
                  try {
                    localStorage.removeItem("defrag:v1");
                  } catch {}
                  window.location.reload();
                }
              },
              style: {
                background: "transparent",
                color: "#0f766e",
                border: "1px solid #5eead4",
                borderRadius: 8,
                padding: "10px 18px",
                fontSize: 13,
                cursor: "pointer",
              },
            },
            "Start over"
          ),
        React.createElement(
          "a",
          {
            href: "https://prompt-ed.org",
            style: {
              background: "transparent",
              color: "#0f766e",
              border: "1px solid #5eead4",
              borderRadius: 8,
              padding: "10px 18px",
              fontSize: 13,
              cursor: "pointer",
              textDecoration: "none",
              display: "inline-block",
            },
          },
          "← Back to Prompt-Ed"
        )
      ),
      React.createElement(
        "div",
        { style: { fontSize: 11, color: "#64748b", marginTop: 16, fontStyle: "italic" } },
        "If this keeps happening, please share feedback so we can fix it."
      )
    );
  }
}

// ── Global accessibility styles ─────────────────────────────────────────
// Injected once on mount so keyboard users see focus rings on buttons,
// sliders, and checkboxes. Uses :focus-visible so mouse clicks don't
// flash the ring. Safe to inject unconditionally — no-ops if already
// present when the script re-runs in dev.
(function injectA11yStyles() {
  try {
    if (document.getElementById("defrag-a11y-style")) return;
    const s = document.createElement("style");
    s.id = "defrag-a11y-style";
    s.textContent = `
      button:focus-visible,
      [role="checkbox"]:focus-visible,
      a:focus-visible {
        outline: 2px solid #2dd4bf;
        outline-offset: 2px;
        border-radius: 4px;
      }
      input[type="range"]:focus-visible {
        outline: 2px solid #2dd4bf;
        outline-offset: 4px;
        border-radius: 4px;
      }
      /* Hide focus ring for mouse users — :focus-visible handles this on
         modern browsers, but this belt-and-suspenders rule prevents the
         default blue ring from showing on click. */
      button:focus:not(:focus-visible) { outline: none; }
    `;
    document.head.appendChild(s);
  } catch {}
})();

ReactDOM.createRoot(document.getElementById("root")).render(
  React.createElement(DefragErrorBoundary, null, React.createElement(Defrag))
);
