본문 바로가기
카테고리 없음

와이어프레임 스케치 코드

by 미드나잇플라잉 2025. 4. 24.

<p data-ke-size="size16">&nbsp;</p>
<p data-ke-size="size16">&nbsp;</p>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.22.9/babel.min.js"></script>
<script src="https://cdn.tailwindcss.com"></script>
<div>
<style>
    body {
      background: linear-gradient(to bottom, #1e3a8a, #7e22ce);
      color: white;
      font-family: 'Arial', sans-serif;
      margin: 0;
      padding: 0;
      overflow-x: hidden;
    }
    .app-container {
      max-width: 400px;
      margin: 0 auto;
      min-height: 100vh;
      position: relative;
    }
    .screen {
      padding: 20px;
      display: none;
      flex-direction: column;
      justify-content: space-between;
      min-height: 100vh;
      background: rgba(0, 0, 0, 0.3);
      transition: opacity 0.5s ease-in-out;
    }
    .screen.active {
      display: flex;
      opacity: 1;
    }
    .stars {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      z-index: -1;
    }
    .star {
      position: absolute;
      background: white;
      border-radius: 50%;
      opacity: 0.7;
      animation: twinkle 2s infinite;
    }
    @keyframes twinkle {
      0%, 100% { opacity: 0.7; }
      50% { opacity: 0.3; }
    }
    .luna {
      position: fixed;
      bottom: 80px;
      right: 20px;
      width: 60px;
      height: 60px;
      background: url('https://via.placeholder.com/60?text=루나') no-repeat center;
      background-size: cover;
      cursor: pointer;
      animation: float 3s ease-in-out infinite;
      z-index: 10;
    }
    @keyframes float {
      0%, 100% { transform: translateY(0); }
      50% { transform: translateY(-10px); }
    }
    .nav-bar {
      position: fixed;
      bottom: 0;
      width: 400px;
      display: flex;
      justify-content: space-around;
      padding: 10px 0;
      background: rgba(0, 0, 0, 0.7);
      z-index: 10;
    }
    .nav-button {
      background: none;
      border: none;
      color: white;
      font-size: 14px;
      padding: 10px;
      transition: color 0.3s;
    }
    .nav-button.active {
      color: #a78bfa;
      font-weight: bold;
    }
    .button {
      background: #7c3aed;
      color: white;
      padding: 12px;
      border-radius: 8px;
      text-align: center;
      font-size: 16px;
      cursor: pointer;
      transition: background 0.3s;
    }
    .button:hover {
      background: #6d28d9;
    }
    .mbti-option {
      background: #3b82f6;
      padding: 12px;
      border-radius: 8px;
      text-align: center;
      cursor: pointer;
      transition: background 0.3s;
    }
    .mbti-option:hover {
      background: #2563eb;
    }
    .progress-bar {
      width: 100%;
      height: 8px;
      background: #4b5563;
      border-radius: 4px;
      overflow: hidden;
    }
    .progress-bar-fill {
      height: 100%;
      background: #a78bfa;
      transition: width 0.3s;
    }
    .modal {
      display: none;
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: rgba(0, 0, 0, 0.8);
      z-index: 20;
      align-items: center;
      justify-content: center;
    }
    .modal.active {
      display: flex;
    }
    .modal-content {
      background: #1e40af;
      padding: 20px;
      border-radius: 12px;
      max-width: 90%;
      text-align: center;
    }
    .apple-game {
      flex-grow: 1;
      background: rgba(0, 0, 0, 0.2);
      border-radius: 8px;
      position: relative;
      overflow: hidden;
    }
    .apple {
      position: absolute;
      width: 30px;
      height: 30px;
      background: url('https://via.placeholder.com/30?text=사과') no-repeat center;
      background-size: cover;
      cursor: pointer;
    }
    .mission-item {
      background: #1e40af;
      padding: 10px;
      border-radius: 8px;
      margin-bottom: 10px;
    }
    .mission-button {
      background: #16a34a;
      color: white;
      padding: 6px 12px;
      border-radius: 6px;
      font-size: 12px;
    }
    .avatar-container {
      flex-grow: 1;
      display: flex;
      justify-content: center;
      align-items: center;
      background: rgba(0, 0, 0, 0.2);
      border-radius: 8px;
      margin-bottom: 10px;
    }
    .avatar-figure {
      width: 100px;
      height: 150px;
      background: #6b7280;
      border-radius: 20px;
      position: relative;
    }
    .avatar-head {
      width: 50px;
      height: 50px;
      background: #d1d5db;
      border-radius: 50%;
      position: absolute;
      top: 10px;
      left: 25px;
    }
    .shop-items {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      gap: 10px;
    }
    .shop-item {
      background: #1e40af;
      padding: 10px;
      border-radius: 8px;
      text-align: center;
    }
    .community-post {
      background: #1e40af;
      padding: 10px;
      border-radius: 8px;
      margin-bottom: 10px;
    }
    .hexagon-chart {
      width: 100%;
      height: 150px;
      background: url('https://via.placeholder.com/300x150?text=헥사곤') no-repeat center;
      background-size: contain;
    }
  </style>
</div>
<div id="root">&nbsp;</div>
<script type="text/babel">
    const { useState, useEffect, useRef } = React;

    // 별 생성 컴포넌트
    const Stars = () => {
      const stars = [];
      for (let i = 0; i < 100; i++) {
        const style = {
          left: `${Math.random() * 100}%`,
          top: `${Math.random() * 100}%`,
          animationDelay: `${Math.random() * 3}s`,
          width: `${Math.random() * 3 + 1}px`,
          height: `${Math.random() * 3 + 1}px`,
        };
        stars.push(<div key={i} className="star" style={style}></div>);
      }
      return <div className="stars">{stars}</div>;
    };

    // 루나 캐릭터
    const Luna = ({ onClick }) => {
      return (
        <div className="luna" onClick={onClick} title="루나와 대화하기" role="button" aria-label="루나와 대화"></div>
      );
    };

    // 내비게이션 바
    const NavBar = ({ currentScreen, setCurrentScreen }) => {
      const navItems = [
        { id: 'home', label: '홈' },
        { id: 'missions', label: '미션' },
        { id: 'avatar', label: '아바타' },
        { id: 'shop', label: '상점' },
        { id: 'community', label: '커뮤니티' },
      ];
      return (
        <div className="nav-bar" role="navigation">
          {navItems.map((item) => (
            <button
              key={item.id}
              className={`nav-button ${currentScreen === item.id ? 'active' : ''}`}
              onClick={() => setCurrentScreen(item.id)}
              aria-label={item.label}
            >
              {item.label}
            </button>
          ))}
        </div>
      );
    };

    // 모달 컴포넌트
    const Modal = ({ isOpen, onClose, title, children }) => {
      return (
        <div className={`modal ${isOpen ? 'active' : ''}`} onClick={onClose} role="dialog" aria-modal="true">
          <div className="modal-content" onClick={(e) => e.stopPropagation()}>
            <h3 className="text-xl font-bold mb-4">{title}</h3>
            {children}
            <button className="button" onClick={onClose} aria-label="모달 닫기">닫기</button>
          </div>
        </div>
      );
    };

    // 사과 자르기 미니게임
    const AppleGame = ({ onComplete }) => {
      const [apples, setApples] = useState([]);
      const [score, setScore] = useState(0);
      const [timeLeft, setTimeLeft] = useState(15);
      const [gameStarted, setGameStarted] = useState(false);
      const [gameEnded, setGameEnded] = useState(false);
      const gameAreaRef = useRef(null);

      const startGame = () => {
        setGameStarted(true);
        setScore(0);
        setTimeLeft(15);
        setApples([]);
        setGameEnded(false);
      };

      const cutApple = (index) => {
        setApples(apples.filter((_, i) => i !== index));
        setScore(score + 1);
      };

      useEffect(() => {
        if (!gameStarted || gameEnded) return;

        const interval = setInterval(() => {
          if (gameAreaRef.current) {
            const width = gameAreaRef.current.offsetWidth - 30;
            const height = gameAreaRef.current.offsetHeight - 30;

            setApples(prev => [
              ...prev,
              {
                id: Date.now(),
                x: Math.random() * width,
                y: Math.random() * height,
              },
            ]);
          }
        }, 1000);

        const timer = setInterval(() => {
          setTimeLeft(prev => {
            if (prev <= 1) {
              clearInterval(interval);
              clearInterval(timer);
              setGameEnded(true);
              onComplete(score);
              return 0;
            }
            return prev - 1;
          });
        }, 1000);

        return () => {
          clearInterval(interval);
          clearInterval(timer);
        };
      }, [gameStarted, gameEnded, score]);

      if (!gameStarted) {
        return (
          <div className="flex flex-col items-center justify-center h-full">
            <h3 className="text-xl mb-4">민첩성 테스트: 사과 자르기</h3>
            <p className="mb-4 text-sm">화면에 나타나는 사과를 빠르게 터치하세요!</p>
            <button className="button" onClick={startGame}>시작하기</button>
          </div>
        );
      }

      if (gameEnded) {
        return (
          <div className="flex flex-col items-center justify-center h-full">
            <h3 className="text-xl mb-4">테스트 완료!</h3>
            <p className="mb-4">점수: {score} 점</p>
            <button className="button" onClick={startGame}>다시 하기</button>
          </div>
        );
      }

      return (
        <div className="flex flex-col h-full">
          <div className="flex justify-between mb-4">
            <p>점수: {score}</p>
            <p>시간: {timeLeft}초</p>
          </div>
          <div className="apple-game" ref={gameAreaRef}>
            {apples.map((apple, index) => (
              <div
                key={apple.id}
                className="apple"
                style={{ left: apple.x + 'px', top: apple.y + 'px' }}
                onClick={() => cutApple(index)}
                role="button"
                aria-label="사과 자르기"
              />
            ))}
          </div>
        </div>
      );
    };

    // 메인 앱 컴포넌트
    const App = () => {
      const [currentScreen, setCurrentScreen] = useState('welcome');
      const [mbtiQuestion, setMbtiQuestion] = useState(1);
      const [mbtiResult, setMbtiResult] = useState(null);
      const [dreamCountry, setDreamCountry] = useState(null);
      const [coins, setCoins] = useState(0);
      const [lunaModalOpen, setLunaModalOpen] = useState(false);
      const [gameResult, setGameResult] = useState(null);
      const totalMbtiQuestions = 20;

      const handleAppleGameComplete = (score) => {
        const earnedCoins = score * 5;
        setCoins(prev => prev + earnedCoins);
        setGameResult({
          score,
          coins: earnedCoins,
        });
      };

      const answerMbti = (answer) => {
        if (mbtiQuestion < totalMbtiQuestions) {
          setMbtiQuestion(mbtiQuestion + 1);
        } else {
          const results = [
            '깊은 몰입형 (Deep Diver)',
            '예민한 감각형 (Light Sensor)',
            '불규칙한 변동형 (Rhythm Seeker)',
            '안정적 규칙형 (Stable Sleeper)',
          ];
          setMbtiResult(results[Math.floor(Math.random() * results.length)]);
          setCurrentScreen('mbtiResult');
        }
      };

      const selectDreamCountry = (country) => {
        setDreamCountry(country);
        setCurrentScreen('home');
      };

      const screens = {
        welcome: (
          <div className="screen active flex flex-col items-center justify-center text-center">
            <Stars />
            <h1 className="text-3xl font-bold mb-6">허니드림</h1>
            <p className="text-lg mb-8">더 나은 수면으로 꿈의 나라를 만들어보세요!</p>
            <div className="w-48 h-48 bg-gray-700 rounded-full mb-8 flex items-center justify-center animate-pulse">
              <div className="w-40 h-40 bg-blue-900 rounded-full flex items-center justify-center">
                <div className="w-32 h-32 bg-indigo-800 rounded-full flex items-center justify-center">
                  <div className="w-24 h-24 bg-purple-800 rounded-full"></div>
                </div>
              </div>
            </div>
            <button
              className="button"
              onClick={() => setCurrentScreen('mbti')}
              aria-label="게임 시작"
            >
              시작하기
            </button>
            {/* 주석: 타겟(20~40대 직장인/학생)을 위해 간단한 CTA로 빠른 온보딩 유도, 몽환적 애니메이션으로 호기심 자극 */}
          </div>
        ),

        mbti: (
          <div className="screen active flex flex-col h-full">
            <Stars />
            <h2 className="text-2xl font-bold mb-4">수면 MBTI 테스트</h2>
            <p className="text-sm mb-2">질문 {mbtiQuestion}/{totalMbtiQuestions}</p>
            <p className="mb-6">
              {mbtiQuestion === 1 && "정해진 시간에 자고 일어나는 것이 편하다."}
              {mbtiQuestion === 2 && "수면 중에 자주 깨는 편이다."}
              {mbtiQuestion === 3 && "스트레스를 받으면 수면에 영향이 크다."}
              {mbtiQuestion > 3 && `질문 ${mbtiQuestion}`}
            </p>
            <div className="flex flex-col space-y-4 mb-6">
              <div className="mbti-option" onClick={() => answerMbti('A')} role="button" aria-label="매우 그렇다">매우 그렇다</div>
              <div className="mbti-option" onClick={() => answerMbti('B')} role="button" aria-label="약간 그렇다">약간 그렇다</div>
              <div className="mbti-option" onClick={() => answerMbti('C')} role="button" aria-label="별로 그렇지 않다">별로 그렇지 않다</div>
              <div className="mbti-option" onClick={() => answerMbti('D')} role="button" aria-label="전혀 그렇지 않다">전혀 그렇지 않다</div>
            </div>
            <div className="progress-bar">
              <div
                className="progress-bar-fill"
                style={{ width: `${(mbtiQuestion / totalMbtiQuestions) * 100}%` }}
              ></div>
            </div>
            {/* 주석: 타겟의 개인화 니즈 충족, 3~5분 내 완료 가능한 간결한 UX로 바쁜 사용자 부담 감소 */}
          </div>
        ),

        mbtiResult: (
          <div className="screen active flex flex-col h-full">
            <Stars />
            <h2 className="text-2xl font-bold mb-4">당신의 수면 유형</h2>
            <div className="bg-indigo-900 p-6 rounded-lg text-center mb-8">
              <h3 className="text-xl font-bold mb-4">{mbtiResult || "결과 계산 중"}</h3>
              <p className="mb-4">
                {mbtiResult === '깊은 몰입형 (Deep Diver)' && '한번 잠에 들면 깊게 잠드는 타입입니다. 일정한 수면 패턴을 유지하세요.'}
                {mbtiResult === '예민한 감각형 (Light Sensor)' && '환경 변화에 민감합니다. 수면 환경 최적화가 중요해요.'}
                {mbtiResult === '불규칙한 변동형 (Rhythm Seeker)' && '수면 패턴이 불규칙합니다. 규칙적인 취침 시간을 설정하세요.'}
                {mbtiResult === '안정적 규칙형 (Stable Sleeper)' && '규칙적인 수면 습관을 유지하며 수면 질을 높이세요.'}
              </p>
            </div>
            <h3 className="text-xl font-bold mb-2">꿈의 나라 선택</h3>
            <p className="text-sm mb-4">궁극적으로 도달하고 싶은 이상향을 선택하세요.</p>
            <div className="grid grid-cols-2 gap-4">
              <div className="bg-blue-900 p-4 rounded-lg text-center cursor-pointer" onClick={() => selectDreamCountry('island')}>
                <p className="font-bold mb-2">열대 휴양지</p>
                <div className="h-16 bg-blue-800 rounded flex items-center justify-center">이미지</div>
              </div>
              <div className="bg-green-900 p-4 rounded-lg text-center cursor-pointer" onClick={() => selectDreamCountry('forest')}>
                <p className="font-bold mb-2">신비한 숲</p>
                <div className="h-16 bg-green-800 rounded flex items-center justify-center">이미지</div>
              </div>
              <div className="bg-gray-800 p-4 rounded-lg text-center cursor-pointer" onClick={() => selectDreamCountry('city')}>
                <p className="font-bold mb-2">현대 도시</p>
                <div className="h-16 bg-gray-700 rounded flex items-center justify-center">이미지</div>
              </div>
              <div className="bg-indigo-900 p-4 rounded-lg text-center cursor-pointer" onClick={() => selectDreamCountry('cosmos')}>
                <p className="font-bold mb-2">우주 정거장</p>
                <div className="h-16 bg-indigo-800 rounded flex items-center justify-center">이미지</div>
              </div>
            </div>
            {/* 주석: 타겟의 장기 목표(꿈의 나라) 설정, 개인화로 몰입감 강화 */}
          </div>
        ),

        home: (
          <div className="screen active flex flex-col h-full">
            <Stars />
            <div className="flex justify-between items-center mb-4">
              <h2 className="text-2xl font-bold">허니드림</h2>
              <div className="bg-purple-900 px-3 py-1 rounded-full text-sm">
                코인: {coins}
              </div>
            </div>
            <div className="bg-indigo-900 p-4 rounded-lg mb-4">
              <h3 className="font-bold mb-2">오늘의 수면 상태</h3>
              <p className="text-sm">아직 오늘의 수면을 기록하지 않았습니다.</p>
              <button
                className="button mt-2 w-full"
                onClick={() => setCurrentScreen('sleep')}
                aria-label="취침 준비"
              >
                취침 준비
              </button>
            </div>
            <div className="bg-purple-900 p-4 rounded-lg mb-4">
              <h3 className="font-bold mb-2">능력치 현황</h3>
              <div className="hexagon-chart"></div>
            </div>
            <div className="bg-blue-900 p-4 rounded-lg">
              <h3 className="font-bold mb-2">오늘의 미션</h3>
              {['10분 햇빛 쬐기', '5분 명상'].map((mission, i) => (
                <div key={i} className="mission-item">
                  <p>{mission}</p>
                  <div className="flex justify-between items-center mt-1">
                    <span>+15 코인</span>
                    <button className="mission-button">완료하기</button>
                  </div>
                </div>
              ))}
              <button
                className="button mt-4 w-full"
                onClick={() => setCurrentScreen('missions')}
                aria-label="모든 미션 보기"
              >
                모든 미션 보기
              </button>
            </div>
            <NavBar currentScreen={currentScreen} setCurrentScreen={setCurrentScreen} />
            <Luna onClick={() => setLunaModalOpen(true)} />
            {/* 주석: 타겟의 바쁜 일정 고려, 핵심 CTA(취침, 미션) 강조로 빠른 접근 제공 */}
          </div>
        ),

        sleep: (
          <div className="screen active flex flex-col h-full">
            <Stars />
            <h2 className="text-2xl font-bold mb-4">취침 준비</h2>
            <div className="bg-indigo-900 p-4 rounded-lg mb-4">
              <h3 className="font-bold mb-2">수면 시간 설정</h3>
              <div className="grid grid-cols-2 gap-4 mb-4">
                <div>
                  <p className="text-sm mb-1">취침 시간</p>
                  <select className="w-full bg-indigo-800 p-2 rounded" aria-label="취침 시간 선택">
                    {Array.from({ length: 24 }).map((_, i) => (
                      <option key={i} value={i}>{i}:00</option>
                    ))}
                  </select>
                </div>
                <div>
                  <p className="text-sm mb-1">기상 시간</p>
                  <select className="w-full bg-indigo-800 p-2 rounded" aria-label="기상 시간 선택">
                    {Array.from({ length: 24 }).map((_, i) => (
                      <option key={i} value={i}>{i}:00</option>
                    ))}
                  </select>
                </div>
              </div>
            </div>
            <div className="bg-purple-900 p-4 rounded-lg mb-4">
              <h3 className="font-bold mb-2">수면 환경 체크리스트</h3>
              {['방을 어둡게 했나요?', '실내 온도는 적절한가요?', '전자기기를 치웠나요?'].map((item, i) => (
                <div key={i} className="flex items-center mt-2">
                  <input type="checkbox" id={`check-${i}`} className="mr-2" aria-label={item} />
                  <label htmlFor={`check-${i}`} className="text-sm">{item}</label>
                </div>
              ))}
            </div>
            <button
              className="button mb-4"
              onClick={() => setCurrentScreen('morning')}
              aria-label="취침 모드 시작"
            >
              취침 모드 시작하기
            </button>
            <button
              className="bg-gray-600 text-white px-4 py-2 rounded-lg"
              onClick={() => setCurrentScreen('home')}
              aria-label="홈으로 돌아가기"
            >
              돌아가기
            </button>
            {/* 주석: 타겟의 비웨어러블 사용자 고려, 간단한 입력으로 수면 모드 활성화 */}
          </div>
        ),

        morning: (
          <div className="screen active flex flex-col h-full">
            <Stars />
            <h2 className="text-2xl font-bold mb-4">아침 평가</h2>
            <div className="bg-indigo-900 p-4 rounded-lg mb-4">
              <h3 className="font-bold mb-2">당신의 수면은 어땠나요?</h3>
              <div className="flex justify-between my-2">
                <span>매우 나쁨</span>
                <span>매우 좋음</span>
              </div>
              <input type="range" min="1" max="10" className="w-full" aria-label="수면 품질 평가" />
              <h4 className="font-bold mt-4 mb-2">기타 체크리스트</h4>
              {['중간에 깬 적이 있나요?', '꿈을 꿨나요?', '아침에 개운한가요?'].map((item, i) => (
                <div key={i} className="flex items-center mt-2">
                  <input type="checkbox" id={`morning-check-${i}`} className="mr-2" aria-label={item} />
                  <label htmlFor={`morning-check-${i}`} className="text-sm">{item}</label>
                </div>
              ))}
            </div>
            <button
              className="button mb-4"
              onClick={() => {
                setCoins(prev => prev + 50);
                setCurrentScreen('minigame');
              }}
              aria-label="평가 완료"
            >
              평가 완료 (+50 코인)
            </button>
            <NavBar currentScreen={currentScreen} setCurrentScreen={setCurrentScreen} />
            <Luna onClick={() => setLunaModalOpen(true)} />
            {/* 주석: 타겟의 수면 이점 체감 니즈 충족, 간단한 평가로 빠른 보상 제공 */}
          </div>
        ),

        minigame: (
          <div className="screen active flex flex-col h-full">
            <Stars />
            <h2 className="text-2xl font-bold mb-4">미니게임</h2>
            <p className="mb-4 text-sm">아침 활력을 위한 미니게임을 해보세요!</p>
            <AppleGame onComplete={handleAppleGameComplete} />
            <NavBar currentScreen={currentScreen} setCurrentScreen={setCurrentScreen} />
            <Luna onClick={() => setLunaModalOpen(true)} />
            {/* 주석: 타겟의 재미 니즈 충족, 15초 내 완료 가능한 게임으로 몰입감 제공 */}
          </div>
        ),

        missions: (
          <div className="screen active flex flex-col h-full">
            <Stars />
            <h2 className="text-2xl font-bold mb-4">일일 미션</h2>
            <div className="bg-indigo-900 p-4 rounded-lg mb-4">
              <h3 className="font-bold mb-2">기본 미션</h3>
              {[
                '물 2L 마시기',
                '10분 햇빛 쬐기',
                '수면 일기 작성하기',
              ].map((mission, i) => (
                <div key={i} className="mission-item">
                  <p>{mission}</p>
                  <div className="flex justify-between items-center mt-2">
                    <span>+15 코인</span>
                    <button className="mission-button" aria-label={`${mission} 완료`}>완료하기</button>
                  </div>
                </div>
              ))}
            </div>
            <div className="bg-purple-900 p-4 rounded-lg mb-4">
              <h3 className="font-bold mb-2">특별 미션</h3>
              {[
                '3일 연속 같은 시간에 일어나기',
                '취침 전 30분 스마트폰 사용 안하기',
              ].map((mission, i) => (
                <div key={i} className="mission-item">
                  <p>{mission}</p>
                  <div className="flex justify-between items-center mt-2">
                    <span>+30 코인</span>
                    <button className="mission-button" aria-label={`${mission} 도전`}>도전하기</button>
                  </div>
                </div>
              ))}
            </div>
            <NavBar currentScreen={currentScreen} setCurrentScreen={setCurrentScreen} />
            <Luna onClick={() => setLunaModalOpen(true)} />
            {/* 주석: 타겟의 짧은 시간 투자 니즈 충족, 3~10분 미션으로 습관 개선 유도 */}
          </div>
        ),

        avatar: (
          <div className="screen active flex flex-col h-full">
            <Stars />
            <h2 className="text-2xl font-bold mb-4">나의 드림 아바타</h2>
            <div className="avatar-container">
              <div className="avatar-figure">
                <div className="avatar-head"></div>
              </div>
            </div>
            <div className="bg-indigo-900 p-4 rounded-lg mb-4">
              <h3 className="font-bold mb-2">아바타 커스터마이징</h3>
              <div className="grid grid-cols-2 gap-4">
                <div>
                  <p className="text-sm mb-1">머리 스타일</p>
                  <select className="w-full bg-indigo-800 p-2 rounded" aria-label="머리 스타일 선택">
                    <option>기본형</option>
                    <option>단발</option>
                    <option>긴 머리</option>
                  </select>
                </div>
                <div>
                  <p className="text-sm mb-1">옷 스타일</p>
                  <select className="w-full bg-indigo-800 p-2 rounded" aria-label="옷 스타일 선택">
                    <option>기본 옷</option>
                    <option>파자마</option>
                    <option>정장</option>
                  </select>
                </div>
              </div>
              <button className="button mt-4 w-full" aria-label="아바타 저장">저장하기</button>
            </div>
            <div className="bg-purple-900 p-4 rounded-lg">
              <h3 className="font-bold mb-2">드림월드 꾸미기</h3>
              <p className="text-sm mb-2">꿈의 나라: {dreamCountry || '미선택'}</p>
              <button className="button w-full" aria-label="꿈의 나라 방문">꿈의 나라 방문하기</button>
            </div>
            <NavBar currentScreen={currentScreen} setCurrentScreen={setCurrentScreen} />
            <Luna onClick={() => setLunaModalOpen(true)} />
            {/* 주석: 타겟의 창의적 표현 니즈 충족, 꿈의 나라로 장기 목표 동기 부여 */}
          </div>
        ),

        shop: (
          <div className="screen active flex flex-col h-full">
            <Stars />
            <div className="flex justify-between items-center mb-4">
              <h2 className="text-2xl font-bold">아이템 상점</h2>
              <div className="bg-purple-900 px-3 py-1 rounded-full text-sm">
                코인: {coins}
              </div>
            </div>
            <div className="shop-items">
              {[
                { name: '푹신한 베개', price: 100, desc: '수면의 질 +5%' },
                { name: '수면 안대', price: 50, desc: '깊은 수면 +10%' },
                { name: '아로마 디퓨저', price: 150, desc: '수면 환경 +15%' },
                { name: '수면 음악', price: 80, desc: '빠른 입면 +20%' },
              ].map((item, i) => (
                <div key={i} className="shop-item">
                  <div className="w-full h-24 bg-gray-800 rounded mb-2"></div>
                  <h4 className="font-bold">{item.name}</h4>
                  <p className="text-xs mb-2">{item.desc}</p>
                  <div className="flex justify-between items-center">
                    <span>{item.price} 코인</span>
                    <button className="bg-purple-700 text-white px-2 py-1 rounded text-xs" aria-label={`${item.name} 구매`}>
                      구매하기
                    </button>
                  </div>
                </div>
              ))}
            </div>
            <h3 className="font-bold mt-6 mb-2">프리미엄 아이템</h3>
            <div className="shop-items">
              {[
                { name: '꿈 분석기', price: 500, desc: '꿈 해석 기능 추가' },
                { name: '명상 가이드', price: 300, desc: '수면 명상 프로그램' },
              ].map((item, i) => (
                <div key={i} className="shop-item">
                  <div className="w-full h-24 bg-indigo-800 rounded mb-2"></div>
                  <h4 className="font-bold">{item.name}</h4>
                  <p className="text-xs mb-2">{item.desc}</p>
                  <div className="flex justify-between items-center">
                    <span>{item.price} 코인</span>
                    <button className="bg-indigo-600 text-white px-2 py-1 rounded text-xs" aria-label={`${item.name} 구매`}>
                      구매하기
                    </button>
                  </div>
                </div>
              ))}
            </div>
            <NavBar currentScreen={currentScreen} setCurrentScreen={setCurrentScreen} />
            <Luna onClick={() => setLunaModalOpen(true)} />
            {/* 주석: 타겟의 실용적 보상 니즈 충족, 코인으로 수면 관련 아이템 구매 가능 */}
          </div>
        ),

        community: (
          <div className="screen active flex flex-col h-full">
            <Stars />
            <h2 className="text-2xl font-bold mb-4">수면 커뮤니티</h2>
            <div className="bg-indigo-900 p-4 rounded-lg mb-4">
              <div className="flex justify-between items-center mb-2">
                <h3 className="font-bold">수면 팁 공유</h3>
                <button className="bg-blue-600 text-white px-2 py-1 rounded text-xs" aria-label="새 글 작성">
                  글쓰기
                </button>
              </div>
              {[
                { user: '꿀잠러', title: '카페인 줄이고 수면 개선했어요', likes: 24 },
                { user: '새벽별', title: '숙면을 위한 침실 온도 꿀팁', likes: 15 },
              ].map((post, i) => (
                <div key={i} className="community-post">
                  <h4 className="font-bold">{post.title}</h4>
                  <div className="flex justify-between items-center mt-2 text-sm">
                    <span>{post.user}</span>
                    <div className="flex items-center">
                      <span className="mr-1">좋아요 {post.likes}</span>
                      <button className="bg-purple-700 text-white px-2 py-1 rounded text-xs" aria-label="좋아요">
                        👍
                      </button>
                    </div>
                  </div>
                </div>
              ))}
            </div>
            <div className="bg-purple-900 p-4 rounded-lg">
              <h3 className="font-bold mb-2">수면 챌린지</h3>
              <p className="text-sm mb-4">친구들과 함께 건강한 수면 습관을 만들어보세요!</p>
              <div className="bg-purple-800 p-3 rounded mb-3">
                <h4 className="font-bold">7일 연속 같은 시간에 일어나기</h4>
                <div className="flex justify-between items-center mt-2">
                  <span>참여자: 126명</span>
                  <button className="bg-green-600 text-white px-2 py-1 rounded text-xs" aria-label="챌린지 참여">
                    참여하기
                  </button>
                </div>
              </div>
              <div className="bg-purple-800 p-3 rounded">
                <h4 className="font-bold">30일 취침 전 스크린 끄기</h4>
                <div className="flex justify-between items-center mt-2">
                  <span>참여자: 87명</span>
                  <button className="bg-green-600 text-white px-2 py-1 rounded text-xs" aria-label="챌린지 참여">
                    참여하기
                  </button>
                </div>
              </div>
            </div>
            <NavBar currentScreen={currentScreen} setCurrentScreen={setCurrentScreen} />
            <Luna onClick={() => setLunaModalOpen(true)} />
            {/* 주석: 타겟의 소셜 연결 니즈 충족, 커뮤니티로 소속감과 동기 부여 */}
          </div>
        ),
      };

      return (
        <div className="app-container">
          {screens[currentScreen]}
          {['home', 'missions', 'avatar', 'shop', 'community', 'morning', 'minigame'].includes(currentScreen) && (
            <Luna onClick={() => setLunaModalOpen(true)} />
          )}
          <Modal
            isOpen={lunaModalOpen}
            onClose={() => setLunaModalOpen(false)}
            title="루나와의 대화"
          >
            <div className="mb-4 p-3 bg-indigo-900 rounded-lg">
              <p>안녕하세요! 저는 당신의 수면 도우미 루나예요. 어떻게 도와드릴까요?</p>
            </div>
            <div className="flex mb-4">
              <input
                type="text"
                placeholder="루나에게 질문하기..."
                className="flex-grow p-2 rounded-l bg-gray-800 text-white"
                aria-label="루나에게 질문"
              />
              <button className="bg-purple-700 text-white px-4 py-2 rounded-r" aria-label="질문 전송">
                전송
              </button>
            </div>
            <div className="text-sm">
              <p>루나에게 수면에 관한 질문을 해보세요!</p>
              <ul className="list-disc pl-5 mt-2">
                <li>수면의 질을 높이는 방법이 궁금해요</li>
                <li>불면증에 좋은 방법이 있을까요?</li>
                <li>꿈을 더 생생하게 꾸고 싶어요</li>
              </ul>
            </div>
          </Modal>
          <Modal
            isOpen={gameResult !== null}
            onClose={() => setGameResult(null)}
            title="게임 결과"
          >
            <div className="text-center mb-4">
              <h3 className="text-xl mb-2">축하합니다!</h3>
              <p>점수: {gameResult?.score} 점</p>
              <p>획득한 코인: {gameResult?.coins} 코인</p>
            </div>
            <button
              className="button w-full"
              onClick={() => {
                setGameResult(null);
                setCurrentScreen('home');
              }}
              aria-label="홈으로 돌아가기"
            >
              홈으로 돌아가기
            </button>
          </Modal>
        </div>
      );
    };

    ReactDOM.render(<App />, document.getElementById('root'));
  </script>
<p data-ke-size="size16">&nbsp;</p>
<p data-ke-size="size16">&nbsp;</p>