// ─────────────────────────────────────────────────────────────
// Forests v2 · brainstorm board.
//
// Lays out every section as a DesignCanvas, with phone frames for
// each variant and trade-off notes alongside. Sections:
//   0 · Premise   — what we're solving, why the v1 doesn't scale.
//   A · Landing   — discovery & search variants.
//   B · Create    — plant a new forest.
//   C · Join      — open / moderated / referral.
//   D · Folk + DM — the profile-with-letters integration.
//   E · Leaves    — viral feed.
//   F · Motion    — the animation kit applied consistently.
//   Z · If I had to pick — composition recommendation.
// ─────────────────────────────────────────────────────────────


const PHONE_W = 390;
const PHONE_H = 760;


// ─── Small shared note card ───
function Note({ title, accent = '#76AB78', children, width = 320, height = PHONE_H }) {
  return (
    <div style={{
      width, height, boxSizing: 'border-box',
      padding: '22px 24px',
      background: '#0B1306', border: '0.5px solid #2D3A22', borderRadius: 14,
      color: '#F2EDE4', display: 'flex', flexDirection: 'column',
      font: '400 13px/1.55 var(--font-sans)',
    }}>
      <div style={{ font: '500 10.5px var(--font-sans)', color: accent,
                    letterSpacing: '0.14em', textTransform: 'uppercase', marginBottom: 10 }}>
        {title}
      </div>
      <div style={{ flex: 1, color: '#C9D2BB', overflowY: 'auto' }} className="phone-scroll">{children}</div>
    </div>
  );
}


function TradeOff({ pros = [], cons = [] }) {
  return (
    <div style={{ display: 'flex', gap: 16, marginTop: 'auto', paddingTop: 14,
                  borderTop: '0.5px solid #1F2B16' }}>
      <div style={{ flex: 1 }}>
        <div style={{ font: '500 10px var(--font-sans)', color: '#76AB78',
                      letterSpacing: '0.10em', textTransform: 'uppercase', marginBottom: 4 }}>
          + Bets on
        </div>
        <ul style={{ margin: 0, padding: '0 0 0 14px',
                     font: '400 12px/1.5 var(--font-sans)', color: '#C9D2BB' }}>
          {pros.map((p, i) => <li key={i}>{p}</li>)}
        </ul>
      </div>
      <div style={{ flex: 1 }}>
        <div style={{ font: '500 10px var(--font-sans)', color: '#D6BFA8',
                      letterSpacing: '0.10em', textTransform: 'uppercase', marginBottom: 4 }}>
          − Risks
        </div>
        <ul style={{ margin: 0, padding: '0 0 0 14px',
                     font: '400 12px/1.5 var(--font-sans)', color: '#A39B89' }}>
          {cons.map((c, i) => <li key={i}>{c}</li>)}
        </ul>
      </div>
    </div>
  );
}


function App() {
  return (
    <DesignCanvas>
      {/* ───── 0 · Premise ───── */}
      <DCSection
        id="premise"
        title="Forests v2 · the scaling reckoning"
        subtitle="The v1 Forests screen does five jobs in one column. At thousands of public forests, plus a DM inbox crammed into the top, it breaks down. This board is five questions and the answers it tries."
      >
        <DCArtboard id="premise-current" label="v1 today — the screenshot you sent" width={PHONE_W} height={PHONE_H}>
          <Phone><LegacyForestsScreen/></Phone>
        </DCArtboard>

        <DCArtboard id="premise-jobs" label="Five jobs in one column" width={440} height={PHONE_H}>
          <Note title="What the screen tries to do" accent="#F4DCA0">
            <p style={{ marginTop: 0 }}>The v1 Forests screen carries:</p>
            <ol style={{ paddingLeft: 18, margin: '6px 0 14px' }}>
              <li style={{ marginBottom: 6 }}>
                <b>Your personal forests</b> — including <i>direct messages</i>,
                which masquerade as 2-member "forests" at the top. This
                conflates DM and group.
              </li>
              <li style={{ marginBottom: 6 }}>
                <b>Your public forests</b> — the ones you've already joined.
              </li>
              <li style={{ marginBottom: 6 }}>
                <b>Discover</b> — a peek at four public forests, with two
                different join-modes (Request / Join) stacked inline.
              </li>
              <li style={{ marginBottom: 6 }}>
                <b>Search</b> — there's no surface for it. Tens of thousands
                of forests, no way to find them.
              </li>
              <li>
                <b>Create / join with code</b> — buried as a footer link.
              </li>
            </ol>
            <p style={{ margin: '0 0 10px' }}>
              At brand-promise scale (~12k public forests, 10s of letters in
              your inbox), each of these gets buried in the next. The list
              becomes a wall and you stop scanning.
            </p>
            <div style={{ padding: 12, background: '#111D0A',
                          border: '0.5px solid #1F2B16', borderRadius: 10,
                          font: 'italic 400 12px/1.55 var(--font-serif)', color: '#A8C5A0' }}>
              The screenshot's marina_k row is a <b>letter</b>, not a forest.
              That's the central reorganization: move DMs to Folk where they
              belong, and let Forests be about forests.
            </div>
            <div style={{ marginTop: 18 }}>
              <div style={{ font: '500 10.5px var(--font-sans)', color: '#76AB78',
                            letterSpacing: '0.14em', textTransform: 'uppercase', marginBottom: 6 }}>
                Five questions this board answers
              </div>
              <ul style={{ paddingLeft: 18, margin: 0,
                            font: '400 13px/1.55 var(--font-sans)', color: '#C9D2BB' }}>
                <li>A · How do you find a forest among 12k? <i>(Landing)</i></li>
                <li>B · How do you plant a new one? <i>(Create)</i></li>
                <li>C · What does joining feel like, three ways? <i>(Join)</i></li>
                <li>D · Where do DMs live so they stop crowding Forests? <i>(Folk)</i></li>
                <li>E · How does virality work in tree-structured posts? <i>(Leaves)</i></li>
              </ul>
            </div>
          </Note>
        </DCArtboard>
      </DCSection>


      {/* ───── A · Landing ───── */}
      <DCSection
        id="landing"
        title="A · Forests landing — discovery + search at scale"
        subtitle="Three info-architectures for the new Forests tab. All three preserve the v1 row's information density; they trade in how 'discover' competes with 'yours'."
      >
        <DCArtboard id="a1" label="A1 · Tabbed (Yours / Discover / Search)" width={PHONE_W} height={PHONE_H}>
          <Phone><LandingA1_Tabbed/></Phone>
        </DCArtboard>
        <DCArtboard id="a1-note" label="A1 · trade-offs" width={300} height={PHONE_H}>
          <Note title="A1 · Tabbed" accent="#76AB78">
            <p style={{ marginTop: 0 }}>
              Three modes, three states. Yours is small and stable; Discover is
              filterable by topic; Search is a real surface, not an icon.
            </p>
            <p>
              Cleanest visually — but tab-switching makes you forget what was
              one screen ago. Tax on cross-mode comparison.
            </p>
            <TradeOff
              pros={[
                'Search is finally first-class',
                'Discover gets room to filter & paginate',
                'Yours never feels lost under thousands of forests',
              ]}
              cons={[
                'Tab interaction is a learned gesture',
                'Hard to scan Yours + Discover together',
                'Three tabs feels heavy if Yours stays at 2 forests',
              ]}
            />
          </Note>
        </DCArtboard>

        <DCArtboard id="a2" label="A2 · Continuous w/ sticky chips" width={PHONE_W} height={PHONE_H}>
          <Phone><LandingA2_Continuous/></Phone>
        </DCArtboard>
        <DCArtboard id="a2-note" label="A2 · trade-offs" width={300} height={PHONE_H}>
          <Note title="A2 · Continuous" accent="#A8C5A0">
            <p style={{ marginTop: 0 }}>
              Single scroll. Yours sits at the top compact (max 3); Discover
              owns the rest, with sticky filter chips that pin to the
              top as you scroll. Closest to the v1 — the smallest jump.
            </p>
            <p>
              Search lives in the top input only; tap-to-focus pushes Yours
              off the screen.
            </p>
            <TradeOff
              pros={[
                'Lowest disruption from v1 layout',
                'Yours + Discover read as one place',
                'Filter chips scale to 8+ facets without UI redesign',
              ]}
              cons={[
                'Yours can get visually swamped at 5+ forests',
                'Sticky-chips can feel busy in motion',
                'Search-focus animation needs care',
              ]}
            />
          </Note>
        </DCArtboard>

        <DCArtboard id="a3" label="A3 · Compass · map-first discover" width={PHONE_W} height={PHONE_H}>
          <Phone><LandingA3_Compass/></Phone>
        </DCArtboard>
        <DCArtboard id="a3-note" label="A3 · trade-offs" width={300} height={PHONE_H}>
          <Note title="A3 · Compass" accent="#D4960C">
            <p style={{ marginTop: 0 }}>
              Discover is anchored geographically. The compass card shows
              forests <i>around you right now</i> as glowing nodes; the
              list below sorts walking-distance first, then by interest.
            </p>
            <p>
              Most aligned with the brand promise ("conversations where you
              stand") — but only works if you've shipped a location backend.
              Has fallback to interest-based for desktop / online.
            </p>
            <TradeOff
              pros={[
                'Reinforces the spatial brand promise',
                'Solves the cold-start: nearby = relevant',
                'A signature view nobody else has',
              ]}
              cons={[
                'Requires location consent up-front',
                'Sparse rural / suburban experience',
                'Map is the heaviest piece of UI in the app',
              ]}
            />
          </Note>
        </DCArtboard>

        <DCArtboard id="a-search-idle" label="A · Search — idle (just opened)" width={PHONE_W} height={PHONE_H}>
          <Phone><ForestSearchScreen autoFocus={false}/></Phone>
        </DCArtboard>

        <DCArtboard id="a-search-typing" label="A · Search — typing 'cycling'" width={PHONE_W} height={PHONE_H}>
          <Phone><ForestSearchScreen initialQuery="cycling" autoFocus={false}/></Phone>
        </DCArtboard>

        <DCArtboard id="a-search-leaf" label="A · Search — body match (leaves)" width={PHONE_W} height={PHONE_H}>
          <Phone><ForestSearchScreen initialQuery="moral" autoFocus={false}/></Phone>
        </DCArtboard>

        <DCArtboard id="a-search-empty" label="A · Search — no match (plant fallback)" width={PHONE_W} height={PHONE_H}>
          <Phone><ForestSearchScreen initialQuery="kombucha" autoFocus={false}/></Phone>
        </DCArtboard>

        <DCArtboard id="a-search-note" label="A · Search — design notes" width={300} height={PHONE_H}>
          <Note title="Search · how it feels" accent="#76AB78">
            <p style={{ marginTop: 0 }}>
              Mirrors the Folk-tab search in vocabulary and bucket shape:
            </p>
            <ul style={{ paddingLeft: 18, margin: '8px 0 14px' }}>
              <li style={{ marginBottom: 6 }}>
                <b>In your forests</b> — solid bg, "Member" capsule. Private
                forests keep the bark-stripe.
              </li>
              <li style={{ marginBottom: 6 }}>
                <b>Discoverable</b> — dashed border (the same "haven't met
                yet" signal the Folk search uses for forest-folk), inline
                Join / Request button.
              </li>
              <li style={{ marginBottom: 6 }}>
                <b>Across the canopy</b> — muted glyph, "No overlap" label,
                blurb omitted per privacy.
              </li>
              <li style={{ marginBottom: 6 }}>
                <b>Matching leaves</b> — quoted branch text with forest +
                handle + sunlight count. Highlights the match in sunlight.
              </li>
              <li>
                <b>Plant a forest called "…"</b> — the equivalent of folk's
                <i>Trade handles in person</i> tile. Always at the bottom;
                a stable destination when search comes up dry.
              </li>
            </ul>
            <p style={{ margin: '14px 0 0' }}>
              <b>Idle state</b>: recent queries + "trending in your area"
              forests. Never an empty void.
            </p>
            <p style={{ margin: '8px 0 0', font: 'italic 400 12.5px/1.55 var(--font-serif)', color: '#A8C5A0' }}>
              Highlighting uses Sunlight at 18% alpha — the same accent used
              for "new activity." It reads as "this is the bit you cared
              about" without being a hammer.
            </p>
          </Note>
        </DCArtboard>
      </DCSection>


      {/* ───── B · Create ───── */}
      <DCSection
        id="create"
        title="B · Plant a forest"
        subtitle="Two takes. The shorter one ships first; the wizard frames the act as choosing what kind of place you're making, not what fields to fill in."
      >
        <DCArtboard id="b1" label="B1 · Inline (one screen)" width={PHONE_W} height={PHONE_H}>
          <Phone><CreateB1_Inline/></Phone>
        </DCArtboard>
        <DCArtboard id="b1-note" label="B1 · trade-offs" width={280} height={PHONE_H}>
          <Note title="B1 · Inline" accent="#76AB78">
            <p style={{ marginTop: 0 }}>
              Everything on one screen. Living preview at the top updates
              as you type. Plant or cancel.
            </p>
            <p>
              The fastest path. Privileges experienced users; doesn't help a
              first-time creator decide what kind of forest to make.
            </p>
            <TradeOff
              pros={[
                'Fastest. No screen transitions.',
                'Living preview teaches the model',
                'Single source of truth for all settings',
              ]}
              cons={[
                'Daunting for first-timers',
                'No "vibe" framing — fields all weigh the same',
                'Hidden until you find Create',
              ]}
            />
          </Note>
        </DCArtboard>

        <DCArtboard id="b2" label="B2 · Vibe-first wizard" width={PHONE_W} height={PHONE_H}>
          <Phone><CreateB2_Wizard/></Phone>
        </DCArtboard>
        <DCArtboard id="b2-note" label="B2 · trade-offs" width={280} height={PHONE_H}>
          <Note title="B2 · Vibe-first" accent="#F4DCA0">
            <p style={{ marginTop: 0 }}>
              Step 1 picks a <b>vibe</b> (Study Hall, Plaza, Salon, Campfire),
              which carries opinionated defaults for join-mode, moderation,
              and copy. Step 2 names it. Step 3 watches the glyph draw
              itself in.
            </p>
            <p>
              Onboards better at the cost of a longer flow. The vibe metaphor
              is also a content-shaping nudge — a Salon won't accept a
              Plaza's volume of strangers by default.
            </p>
            <TradeOff
              pros={[
                'Teaches the product by analogy',
                'Sensible-defaults reduce decision fatigue',
                'Confirmation beat is a moment of delight',
              ]}
              cons={[
                'Adds a screen tax for power users',
                'Vibe taxonomy is debatable — only four?',
                'Behavioral defaults are invisible to most users',
              ]}
            />
          </Note>
        </DCArtboard>
      </DCSection>


      {/* ───── C · Join ───── */}
      <DCSection
        id="join"
        title="C · Join a forest, three ways"
        subtitle="Open · Moderated · Referral. Each shares the same Forest preview hero — what a stranger sees before deciding. The flows diverge in what 'commit' means."
      >
        <DCArtboard id="c1" label="C1 · Open join · single tap" width={PHONE_W} height={PHONE_H}>
          <Phone><JoinC1_Open/></Phone>
        </DCArtboard>

        <DCArtboard id="c2-user" label="C2 · Moderated · with a note" width={PHONE_W} height={PHONE_H}>
          <Phone><JoinC2_Moderated/></Phone>
        </DCArtboard>

        <DCArtboard id="c2-entry" label="C2 · How a moderator gets here" width={440} height={760}>
          <JoinC2_EntryPoints/>
        </DCArtboard>

        <DCArtboard id="c2-mod" label="C2 · Moderator side" width={PHONE_W} height={PHONE_H}>
          <Phone><JoinC2_ModeratorView/></Phone>
        </DCArtboard>

        <DCArtboard id="c3" label="C3 · Referral · the four-mark" width={PHONE_W} height={PHONE_H}>
          <Phone><JoinC3_Referral/></Phone>
        </DCArtboard>

        <DCArtboard id="c-note" label="C · notes" width={320} height={PHONE_H}>
          <Note title="C · Three flows, one preview" accent="#A8C5A0">
            <p style={{ marginTop: 0 }}>
              Every flow opens with the same <b>Forest preview hero</b>:
              glyph, name, blurb, live counter, members strip with mutual
              folk surfaced. Then it diverges:
            </p>
            <ul style={{ paddingLeft: 18, margin: '8px 0 14px' }}>
              <li style={{ marginBottom: 6 }}>
                <b>Open</b> — one tap. The "you're in" beat is the only
                animation that gets to be loud (sunlight ripple + a folded
                check). It runs ~700ms then dims.
              </li>
              <li style={{ marginBottom: 6 }}>
                <b>Moderated</b> — two-tap, with optional note. Pending state
                is a dashed-canopy card that lives in your Sunlight tab
                until a decision arrives. <i>Decline is silent</i> — no
                rejection notification, just absence.
              </li>
              <li>
                <b>Referral</b> — pre-revealing the four-mark builds delight
                before commitment. The forest "reveals" only when the code
                is valid.
              </li>
            </ul>
            <p style={{ margin: '14px 0 8px' }}>
              <b>Across all three:</b> arrived members start as Stranger.
              The "Who's in" strip uses your folk's avatars first; strangers
              fall to "+ 1.8k strangers." That alone may answer the
              "should I join" question.
            </p>
            <p style={{ margin: 0, font: 'italic 400 12.5px/1.55 var(--font-serif)', color: '#A8C5A0' }}>
              The moderator-side view is non-optional; without showing it,
              we can't actually evaluate the request-to-join experience.
            </p>
          </Note>
        </DCArtboard>
      </DCSection>


      {/* ───── D · Folk + DMs ───── */}
      <DCSection
        id="folk"
        title="D · Folk + letters — where DMs live now"
        subtitle="Three integrations of DMs into the Folk tab. All three remove the personal-forest list from Forests entirely, and surface 'Letters' alongside the existing identity / ladder UI."
      >
        <DCArtboard id="d1" label="D1 · Inline accordion" width={PHONE_W} height={PHONE_H}>
          <Phone><FolkD1_Accordion/></Phone>
        </DCArtboard>
        <DCArtboard id="d1-note" label="D1 · trade-offs" width={280} height={PHONE_H}>
          <Note title="D1 · Accordion" accent="#76AB78">
            <p style={{ marginTop: 0 }}>
              Tap a Folk row → grows down to show the last two messages, a
              quick-reply, and three profile tiles. No modal. No screen
              change. Folk list never loses scroll position.
            </p>
            <TradeOff
              pros={[
                'Calmest. Zero context switches.',
                'Lets you triage 10 letters w/o leaving the list',
                'Profile + DM live as one entity, not two',
              ]}
              cons={[
                "Long threads don't fit — needs an 'open full' link",
                'Replies inline can feel cramped on mobile',
                'Multiple-folk-open complicates layout',
              ]}
            />
          </Note>
        </DCArtboard>

        <DCArtboard id="d2" label="D2 · Stacked sheet (current model, evolved)" width={PHONE_W} height={PHONE_H}>
          <Phone><FolkD2_StackedSheet/></Phone>
        </DCArtboard>
        <DCArtboard id="d2-note" label="D2 · trade-offs" width={280} height={PHONE_H}>
          <Note title="D2 · Stacked sheet" accent="#F4DCA0">
            <p style={{ marginTop: 0 }}>
              The existing ConnectSheet evolves — now tabs between
              <b>Letters</b> and <b>Profile</b>. Letters is the default
              when there are unread; profile lives one tap away.
            </p>
            <p>
              Closest to the v1 mental model. Easiest engineering. Less
              novel, but the most reliable port for an existing user base.
            </p>
            <TradeOff
              pros={[
                'Familiar; lowest disruption to current users',
                'Long threads work well in full-bleed sheet',
                'Tab toggle is a single instance, easy to A/B',
              ]}
              cons={[
                'Two screens to triage many letters',
                'Backdrop dims the Folk list — break in flow',
                'Mode-switching cost between Letters / Profile',
              ]}
            />
          </Note>
        </DCArtboard>

        <DCArtboard id="d3" label="D3 · Swipe-peek" width={PHONE_W} height={PHONE_H}>
          <Phone><FolkD3_SwipePeek/></Phone>
        </DCArtboard>
        <DCArtboard id="d3-note" label="D3 · trade-offs" width={280} height={PHONE_H}>
          <Note title="D3 · Swipe-peek" accent="#A8C5A0">
            <p style={{ marginTop: 0 }}>
              Leftward swipe reveals the last letter behind the row, in
              place. Tap-to-open still works; swipe is a power-user shortcut.
            </p>
            <p>
              The most delightful. Hidden discoverability is the trade.
            </p>
            <TradeOff
              pros={[
                'Truly delightful gesture',
                'Discoverable via a one-time hint card',
                'Composes with D1 or D2 as a power-user layer',
              ]}
              cons={[
                'Mobile-only; desktop needs a different affordance',
                'Discoverability tax for new users',
                'Accidental peeks during scroll',
              ]}
            />
          </Note>
        </DCArtboard>
      </DCSection>


      {/* ───── E · Viral leaves ───── */}
      <DCSection
        id="leaves"
        title="E · Viral leaves — reddit, but tree-shaped"
        subtitle="A separate Forests view ('leaves' toggle in the header, or a dedicated bottom-nav slot in some variants). Surfaces deep replies catching disproportionate sunlight — without losing the forest → tree → branch context."
      >
        <DCArtboard id="e1" label="E1 · Velocity feed (full cards)" width={PHONE_W} height={PHONE_H}>
          <Phone><ViralE1_VelocityFeed/></Phone>
        </DCArtboard>
        <DCArtboard id="e1-note" label="E1 · trade-offs" width={280} height={PHONE_H}>
          <Note title="E1 · Velocity feed" accent="#F4DCA0">
            <p style={{ marginTop: 0 }}>
              Each card shows the root tease above (italicized, indented)
              and the branch itself below (bold, normal column). A spur
              curve connects them — this is where the dense DM-tree
              vocabulary is finally allowed to fire, because each card
              is bounded.
            </p>
            <p>
              "Pull sunlight" is the native upvote — a soft sun pulse, not
              an arrow. Velocity (+38/h) lives in a sun-pill, top-right.
            </p>
            <TradeOff
              pros={[
                'Context never collapses; root is always visible',
                'Sunlight ripple is a unique brand-native vote',
                'Card model handles long branches without truncation',
              ]}
              cons={[
                'Heavy scrolling — 6 cards take a phone-height each',
                'Velocity needs explanation to first-timers',
                'No quick way to skip a whole forest of bad takes',
              ]}
            />
          </Note>
        </DCArtboard>

        <DCArtboard id="e2" label="E2 · Compact rows (hn-style)" width={PHONE_W} height={PHONE_H}>
          <Phone><ViralE2_Compact/></Phone>
        </DCArtboard>
        <DCArtboard id="e2-note" label="E2 · trade-offs" width={280} height={PHONE_H}>
          <Note title="E2 · Compact rows" accent="#76AB78">
            <p style={{ marginTop: 0 }}>
              Numbered list, HN-style. Each row carries the branch in
              full, metadata below; tap reveals the root tease + actions
              inline (open the tree, branch from here, hide).
            </p>
            <TradeOff
              pros={[
                'Dense — 6+ leaves per screen',
                'Numbers make scanning faster',
                'Inline reveal preserves list position',
              ]}
              cons={[
                'Strips away forest-glyph identity',
                'Hard to feel the brand voice at compact density',
                'Vote pull-ins lose their visual punch',
              ]}
            />
          </Note>
        </DCArtboard>

        <DCArtboard id="e3" label="E3 · Galaxy view" width={PHONE_W} height={PHONE_H}>
          <Phone><ViralE3_Galaxy/></Phone>
        </DCArtboard>
        <DCArtboard id="e3-note" label="E3 · trade-offs" width={280} height={PHONE_H}>
          <Note title="E3 · Galaxy" accent="#D4960C">
            <p style={{ marginTop: 0 }}>
              Leaves drawn as glowing nodes orbiting their forest's ring.
              Size = sunlight; brightness pulse = velocity; tap a node →
              the velocity card materializes below. Visual mode for "what's
              the forest feeling right now" without parsing a feed.
            </p>
            <TradeOff
              pros={[
                'Signature view; nobody has this',
                'Activity reads visually before linguistically',
                'Reinforces the brand mark (concentric rings)',
              ]}
              cons={[
                'Layout is gestural — hard to "find" something specific',
                'Loses chronology entirely',
                'Best as a secondary mode, not default',
              ]}
            />
          </Note>
        </DCArtboard>
      </DCSection>


      {/* ───── F · Motion ───── */}
      <DCSection
        id="motion"
        title="F · The motion kit"
        subtitle="Reusable animation primitives that thread through every variant. Built once, applied everywhere."
      >
        <DCArtboard id="f-kit" label="Motion kit" width={760} height={520}>
          <MotionKit/>
        </DCArtboard>
      </DCSection>


      {/* ───── Z · Recommendation ───── */}
      <DCSection
        id="recommend"
        title="Z · If I had to compose"
        subtitle="A composition, not a winner. The brainstorms aren't mutually exclusive."
      >
        <DCArtboard id="rec" label="Recommendation" width={440} height={580}>
          <Note title="My pick" accent="#D4960C" height={580}>
            <ol style={{ paddingLeft: 18, margin: 0 }}>
              <li style={{ marginBottom: 10 }}>
                Ship <b>A2 · Continuous</b> as the new Forests landing —
                lowest disruption, plus a real search input. Hold A3
                Compass behind a "your area" toggle for the next phase
                once we have a location backend.
              </li>
              <li style={{ marginBottom: 10 }}>
                Ship <b>B2 · Vibe wizard</b> for first-time creators; expose
                B1 inline as "advanced" from the wizard's step-3.
              </li>
              <li style={{ marginBottom: 10 }}>
                Ship <b>C1, C2 user, C2 moderator, C3</b> as a complete set.
                These aren't variants; they're four flows the product needs.
              </li>
              <li style={{ marginBottom: 10 }}>
                For Folk + DMs: ship <b>D1 · Accordion</b> as the default.
                Add <b>D3 · Swipe-peek</b> as a power-user gesture once D1
                is stable. Phase out the ConnectSheet (D2) — it served us
                in v1 but the modal model fights the inline brand promise.
              </li>
              <li style={{ marginBottom: 10 }}>
                For leaves: ship <b>E1 · Velocity feed</b> as the default
                reachable from a "leaves" toggle in the Forests header.
                <b> E3 · Galaxy</b> is the second view mode. <b>E2</b> is
                a power-user density preference.
              </li>
              <li>
                Wire the <b>motion kit (F)</b> through everything. The
                animations are not decoration; they are the brand's
                way of saying "this place is alive."
              </li>
            </ol>
            <div style={{ marginTop: 18, padding: 12, background: '#111D0A',
                          border: '0.5px solid #1F2B16', borderRadius: 10,
                          font: 'italic 400 12px/1.55 var(--font-serif)', color: '#A8C5A0' }}>
              Open questions for you: (a) does location consent ship with
              the next release, or is the Compass on hold? (b) is the
              moderator dashboard part of mobile, or do we kick it to
              web-only? (c) for viral leaves, do we want a dedicated
              bottom-nav slot, or is "leaves toggle inside Forests" enough?
            </div>
          </Note>
        </DCArtboard>
      </DCSection>
    </DesignCanvas>
  );
}


// ─── Legacy screen — a faithful render of the v1 screenshot ───
function LegacyForestsScreen() {
  return (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column', minHeight: 0, background: '#0B1306' }}>
      <div style={{ padding: '14px 18px 6px' }}>
        <div style={{ font: '500 10px var(--font-sans)', color: '#8A9678',
                      letterSpacing: '0.10em', textTransform: 'uppercase' }}>YOUR FORESTS</div>
        <div style={{ font: '500 26px var(--font-mono)', color: '#F2EDE4',
                      letterSpacing: '-0.01em', marginTop: 2 }}>2 spaces growing</div>
      </div>

      <PhoneBody style={{ padding: '6px 14px 90px' }}>
        <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between',
                      margin: '12px 4px 6px' }}>
          <span style={{ font: '500 10.5px var(--font-sans)', color: '#76AB78',
                         letterSpacing: '0.12em', textTransform: 'uppercase' }}>Personal</span>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            <span style={{ font: '500 10px var(--font-sans)', color: '#D6BFA8',
                           padding: '2px 8px', background: '#2A1F12',
                           border: '0.5px solid #5F3D22', borderRadius: 999,
                           display: 'inline-flex', alignItems: 'center', gap: 5 }}>
              <span style={{ width: 5, height: 5, borderRadius: '50%', background: '#7A4F2D' }}/>
              private
            </span>
            <span style={{ font: '500 13px var(--font-sans)', color: '#76AB78' }}>+ New</span>
          </div>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12,
                      padding: '12px 12px',
                      background: '#111D0A', border: '0.5px solid #1F2B16',
                      borderLeft: '2px solid #7A4F2D',
                      borderRadius: 12 }}>
          <Avatar handle="marina" size={36} accent="#7A4F2D"/>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
              <span style={{ font: '500 15px var(--font-sans)', color: '#F2EDE4' }}>marina_k</span>
              <span style={{ font: '500 10px var(--font-sans)', color: '#586552',
                             padding: '1px 7px', background: 'transparent',
                             border: '0.5px solid #2D3A22', borderRadius: 999 }}>dm</span>
              <span style={{ flex: 1 }}/>
              <span style={{ font: '400 11.5px var(--font-mono)', color: '#586552' }}>14h</span>
            </div>
            <div style={{ font: '400 12.5px var(--font-sans)', color: '#8A9678', marginTop: 4 }}>
              marina_k: Maecenas tempus, tellus eget con…
            </div>
          </div>
          <span style={{
            font: '500 11px var(--font-mono)', color: '#0B1306',
            background: '#D4960C', borderRadius: 999, padding: '1px 7px',
            alignSelf: 'flex-start', marginTop: 4,
          }}>519</span>
        </div>

        <div style={{ font: '500 10.5px var(--font-sans)', color: '#76AB78',
                      letterSpacing: '0.12em', textTransform: 'uppercase',
                      margin: '18px 4px 6px' }}>Public</div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12,
                      padding: '12px 12px',
                      background: '#111D0A', border: '0.5px solid #1F2B16', borderRadius: 12 }}>
          <ForestGlyph size={32} alive={false}/>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ font: '500 15px var(--font-sans)', color: '#F2EDE4' }}>Philosophy</div>
            <div style={{ font: '400 12px var(--font-sans)', color: '#8A9678', marginTop: 3 }}>
              8 members · Thinking out loud about ideas, ethics, …
            </div>
          </div>
          <KindChip kind="public"/>
        </div>

        <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between',
                      margin: '18px 4px 6px' }}>
          <span style={{ font: '500 10.5px var(--font-sans)', color: '#76AB78',
                         letterSpacing: '0.12em', textTransform: 'uppercase' }}>Discover</span>
          <span style={{ font: '500 12px var(--font-sans)', color: '#76AB78' }}>See all</span>
        </div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
          {[
            { name: 'Software & Web', members: 3, blurb: 'Verified developers and…', cta: 'Request' },
            { name: 'Indie Film', members: 2, blurb: 'Referral required.', cta: 'Request' },
            { name: 'Long-distance Cycling', members: 2, blurb: 'Open to anyone with two w…', cta: 'Join' },
            { name: 'Slow Cooking', members: 2, blurb: 'Recipes, kitchens, weekend…', cta: 'Join' },
          ].map(f => (
            <div key={f.name} style={{ display: 'flex', alignItems: 'center', gap: 12,
                                       padding: '12px 12px',
                                       background: '#111D0A', border: '0.5px solid #1F2B16', borderRadius: 12 }}>
              <ForestGlyph size={32} alive={false}/>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ font: '500 15px var(--font-sans)', color: '#F2EDE4' }}>{f.name}</div>
                <div style={{ font: '400 12px var(--font-sans)', color: '#8A9678', marginTop: 3 }}>
                  {f.members} members · {f.blurb}
                </div>
              </div>
              {f.cta === 'Join'
                ? <Btn kind="primary" size="sm">{f.cta}</Btn>
                : <Btn kind="secondary" size="sm">{f.cta}</Btn>}
            </div>
          ))}
        </div>
        <div style={{
          marginTop: 14, padding: '12px 14px', background: 'transparent',
          border: '0.5px dashed #2D3A22', borderRadius: 12,
          font: 'italic 400 12.5px var(--font-serif)', color: '#8A9678', textAlign: 'left',
        }}>
          + Have a referral code?
        </div>
      </PhoneBody>

      <BottomNavFolk active="forests" hasNewSunlight={false}/>
    </div>
  );
}


// ─── Motion kit display ───
function MotionKit() {
  return (
    <div style={{ width: 760, height: 520, boxSizing: 'border-box',
                  padding: 24, background: '#0B1306',
                  border: '0.5px solid #2D3A22', borderRadius: 14,
                  color: '#F2EDE4', display: 'grid',
                  gridTemplateColumns: 'repeat(3, 1fr)', gap: 14 }}>
      <MotionCell title="Leaf stagger" desc="40ms gap, scale 0.97 → 1, fade.">
        <LeafStagger staggerMs={120} style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
          {[1, 2, 3, 4].map(i => (
            <div key={i} style={{
              padding: '8px 10px', background: '#111D0A',
              border: '0.5px solid #1F2B16', borderRadius: 8,
              font: '500 11px var(--font-mono)', color: '#A8C5A0',
            }}>leaf · {i}</div>
          ))}
        </LeafStagger>
      </MotionCell>

      <MotionCell title="Breathing glyph" desc="Active forests breathe at 3.6s.">
        <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%' }}>
          <BreathingForestGlyph size={64} hot/>
        </div>
      </MotionCell>

      <MotionCell title="Sun ripple" desc="Pull sunlight = soft ripple bloom.">
        <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%' }}>
          <PersistentSunRipple/>
        </div>
      </MotionCell>

      <MotionCell title="Live counter" desc="Random walk, ±2 around baseline.">
        <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%',
                       font: '500 32px var(--font-mono)', color: '#A8C5A0' }}>
          <LiveCounter baseline={41} range={2}/>
        </div>
      </MotionCell>

      <MotionCell title="Branch draw-in" desc="Glyph rings self-assemble.">
        <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%' }}>
          <DrawInRings/>
        </div>
      </MotionCell>

      <MotionCell title="Typing dots" desc="Used for 'active now' on root cards.">
        <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%' }}>
          <TypingDots size={8}/>
        </div>
      </MotionCell>
    </div>
  );
}

function MotionCell({ title, desc, children }) {
  return (
    <div style={{
      padding: 12, background: '#0F1A09',
      border: '0.5px solid #1F2B16', borderRadius: 12,
      display: 'flex', flexDirection: 'column', minHeight: 140,
    }}>
      <div style={{ font: '500 10.5px var(--font-sans)', color: '#76AB78',
                    letterSpacing: '0.12em', textTransform: 'uppercase' }}>{title}</div>
      <div style={{ font: 'italic 400 11.5px var(--font-serif)', color: '#8A9678', marginTop: 3 }}>
        {desc}
      </div>
      <div style={{ flex: 1, marginTop: 8 }}>{children}</div>
    </div>
  );
}

function PersistentSunRipple() {
  // Auto-loops every 2.6s
  const [n, setN] = React.useState(0);
  React.useEffect(() => { const id = setInterval(() => setN(v => v + 1), 2600); return () => clearInterval(id); }, []);
  return (
    <div style={{ position: 'relative', width: 48, height: 48 }}>
      <FLIcons.Sun size={28} color="#D4960C"/>
      <span key={n} style={{
        position: 'absolute', left: 0, top: 0, width: 48, height: 48,
        borderRadius: '50%', border: '1.5px solid #D4960C',
        animation: 'flCanopyRipple 2.5s var(--ease-organic) forwards',
      }}/>
    </div>
  );
}

function DrawInRings() {
  // Replay every 3s
  const [k, setK] = React.useState(0);
  React.useEffect(() => { const id = setInterval(() => setK(v => v + 1), 3000); return () => clearInterval(id); }, []);
  return (
    <svg key={k} width="90" height="90" viewBox="0 0 90 90">
      {[40, 28, 16].map((r, i) => (
        <circle key={r} cx="45" cy="45" r={r} fill="none"
          stroke="#5E8048" strokeWidth="1.4" strokeLinecap="round"
          strokeDasharray={2 * Math.PI * r}
          style={{
            strokeDashoffset: 2 * Math.PI * r,
            animation: `flBranchDraw 1.1s var(--ease-organic) ${i * 180}ms forwards`,
          }}/>
      ))}
      <circle cx="45" cy="45" r="5" fill="#D4960C"
        style={{ transformOrigin: '45px 45px',
                  animation: 'flBeadGrow 360ms var(--ease-organic) 640ms both' }}/>
    </svg>
  );
}


// ─── Embed backdrop: same gradient the brainstorm board uses, sized to
//     wrap a single Phone with a thin border of gradient visible. ───
function EmbedBackdrop({ children }) {
  return (
    <div style={{
      background: 'linear-gradient(180deg, #1A2812 0%, #0B1306 100%)',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      padding: '12px 20px', boxSizing: 'border-box',
    }}>
      {children}
    </div>
  );
}

// ─── Router: ?board=<id> renders one artboard; no param renders the full
//     DesignCanvas as the prototype was originally authored. ───
function EmbedOrApp() {
  const board = new URLSearchParams(location.search).get('board');
  switch (board) {
    case 'a1':
      return <EmbedBackdrop><Phone><LandingA1_Tabbed/></Phone></EmbedBackdrop>;
    case 'a-search-idle':
      return <EmbedBackdrop><Phone><ForestSearchScreen autoFocus={false}/></Phone></EmbedBackdrop>;
    case 'a-search-typing':
      return <EmbedBackdrop><Phone><ForestSearchScreen initialQuery="cycling" autoFocus={false}/></Phone></EmbedBackdrop>;
    case 'a-search-leaf':
      return <EmbedBackdrop><Phone><ForestSearchScreen initialQuery="moral" autoFocus={false}/></Phone></EmbedBackdrop>;
    case 'a-search-empty':
      return <EmbedBackdrop><Phone><ForestSearchScreen initialQuery="kombucha" autoFocus={false}/></Phone></EmbedBackdrop>;
    default:
      return <App/>;
  }
}

ReactDOM.createRoot(document.getElementById('root')).render(<EmbedOrApp/>);
