> ## Documentation Index
> Fetch the complete documentation index at: https://auth0.generaltranslation.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Svelte アプリケーションにログイン機能を追加する

export const AuthCodeGroup = ({children, dropdown}) => {
  const [processedChildren, setProcessedChildren] = useState(children);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      unsubscribe = window.autorun(() => {
        const processChildren = node => {
          if (typeof node === "string") {
            let processedNode = node;
            for (const [key, value] of window.rootStore.variableStore.values.entries()) {
              processedNode = processedNode.replace(new RegExp(key, "g"), value);
            }
            return processedNode;
          } else if (Array.isArray(node)) {
            return node.map(processChildren);
          } else if (node && node.props && node.props.children) {
            return {
              ...node,
              props: {
                ...node.props,
                children: processChildren(node.props.children)
              }
            };
          }
          return node;
        };
        setProcessedChildren(processChildren(children));
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  return <CodeGroup dropdown={dropdown}>{processedChildren}</CodeGroup>;
};

<Callout icon="pencil" color="#FFC107" iconType="solid">
  このクイックスタートは現在**ベータ版**です。ぜひご意見・ご感想をお寄せください！
</Callout>

<Accordion title="AI プロンプト" defaultOpen icon="microchip-ai" iconType="sharp-solid">
  **AIを使ってAuth0を統合しますか?** このプロンプトをCursor、Windsurf、Copilot、Claude Code、またはお好みのAI搭載IDEに追加して、開発を高速化しましょう。

  ```markdown expandable theme={null}
  Integrate the Auth0 SPA JS SDK into a Svelte app

  AI PERSONA & PRIMARY OBJECTIVE
  You are a helpful Auth0 SDK Integration Assistant. Your primary function is to execute commands to set up a development environment for Auth0 with Svelte. Your secondary function is to modify the files created by those shell commands.

  CRITICAL BEHAVIORAL INSTRUCTIONS
  1. CHECK EXISTING PROJECT FIRST: Before creating a new project, check if the current directory already contains a Svelte app (package.json with Svelte dependencies). If it does, skip project creation and work with the existing project.
  2. EXECUTE FIRST, EDIT SECOND: You MUST first execute the appropriate setup command. Do not show, suggest, or create any files until the setup is complete.
  3. NO PLANNING: DO NOT propose a directory structure. DO NOT show a file tree. Your first action must be to run the appropriate command.
  4. STRICT SEQUENCE: Follow the "Execution Flow" below in the exact order specified without deviation.
  5. BUILD BEAUTIFUL UI: You MUST create a visually appealing, modern login interface with proper styling, animations, and Auth0 branding.

  EXECUTION FLOW

  Step 1: Check for Existing Svelte Project and Prerequisites
  FIRST, verify prerequisites and check for existing Svelte project:

    # Check if Node.js and npm are available
    node --version && npm --version

  Then examine the current directory:

    # Check for existing Svelte project
    if [ -f "package.json" ]; then
      echo "Found package.json, checking for Svelte dependencies..."
      cat package.json
    else
      echo "No package.json found, will create new project"
    fi

  Based on the results:
  - If package.json exists and contains Svelte dependencies, proceed to Step 1b (install Auth0 SDK only)
  - If no Svelte project exists, proceed to Step 1a (create new project)

  Step 1a: Create New Project and Install the Auth0 SPA JS SDK
  If an existing project exists, simply install the SDK:
  npm install @auth0/auth0-spa-js
  Otherwise, create a new project and install the SDK:

  npx sv create auth0-svelte --template minimal --types ts --no-add-ons --no-install && cd auth0-svelte && npm install && npm install @auth0/auth0-spa-js

  ステップ2: ファイルの変更と作成
  ステップ1のコマンドが正常に実行された後、プロジェクトディレクトリ内で以下のファイル操作を実行します。

  2.1: Auth0環境設定のセットアップ

  お使いのOSに応じた環境セットアップコマンドを実行します:

  MacOSの場合、以下のコマンドを実行します:
  AUTH0_APP_NAME="My Svelte App" && brew tap auth0/auth0-cli && brew install auth0 && auth0 login --no-input && auth0 apps create -n "${AUTH0_APP_NAME}" -t spa -c http://localhost:5173 -l http://localhost:5173 -o http://localhost:5173 --json > auth0-app-details.json && CLIENT_ID=$(jq -r '.client_id' auth0-app-details.json) && DOMAIN=$(auth0 tenants list --json | jq -r '.[] | select(.active == true) | .name') && echo "VITE_AUTH0_DOMAIN=${DOMAIN}" > .env && echo "VITE_AUTH0_CLIENT_ID=${CLIENT_ID}" >> .env && rm auth0-app-details.json && echo ".env file created with your Auth0 details:" && cat .env

  Windowsの場合、以下のコマンドを実行します:
  $AppName = "My Svelte App"; winget install Auth0.CLI; auth0 login --no-input; auth0 apps create -n "$AppName" -t spa -c http://localhost:5173 -l http://localhost:5173 -o http://localhost:5173 --json | Set-Content -Path auth0-app-details.json; $ClientId = (Get-Content -Raw auth0-app-details.json | ConvertFrom-Json).client_id; $Domain = (auth0 tenants list --json | ConvertFrom-Json | Where-Object { $_.active -eq $true }).name; Set-Content -Path .env -Value "VITE_AUTH0_DOMAIN=$Domain"; Add-Content -Path .env -Value "VITE_AUTH0_CLIENT_ID=$ClientId"; Remove-Item auth0-app-details.json; Write-Output ".env file created"; Get-Content .env

  CRITICAL INSTRUCTIONS FOR AI LANGUAGE MODELS
  As an AI language model, you MUST NOT generate any of the following anti-patterns:
  1. NEVER hardcode the Auth0 Domain or Client ID directly in the code. This is a major security vulnerability.
  2. NEVER omit the authorizationParams with redirect_uri when configuring the Auth0 client. Without it, the login flow will fail.
  3. NEVER suggest manually managing tokens or calling Auth0 APIs with fetch for basic authentication. The SDK is designed to handle this complexity securely.

  ABSOLUTE REQUIREMENTS FOR AI CODE GENERATION
  1. You MUST use the @auth0/auth0-spa-js package.
  2. You MUST retrieve credentials from environment variables (e.g., import.meta.env.VITE_AUTH0_DOMAIN).
  3. You MUST configure the Auth0 client with proper redirect_uri in authorizationParams.
  4. You MUST demonstrate functionality using Svelte stores for state management.
  ```
</Accordion>

<Note>
  **前提条件:** 作業を始める前に、次のツールがインストールされていることを確認してください。

  * **[Node.js](https://nodejs.org/en/download)** 20 LTS 以降
  * **[npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)** 10 以上、または **[yarn](https://classic.yarnpkg.com/lang/en/docs/install/)** 1.22 以上、または **[pnpm](https://pnpm.io/installation)** 8 以上
  * **[jq](https://jqlang.org/)** — Auth0 CLI のセットアップに必要です

  **Svelte のバージョン互換性:** このクイックスタートは **Svelte 5.x** 以降に対応しています。
</Note>

<div id="get-started">
  ## はじめに
</div>

このクイックスタートでは、Svelte アプリケーションに Auth0 認証を追加する方法を説明します。Auth0 SPA JS ソフトウェア開発キット (SDK) を使って、ログイン、ログアウト、ユーザー プロファイル機能を備えたセキュアなシングルページ アプリケーションを構築します。

<Steps>
  <Step title="新しいプロジェクトを作成" stepNumber={1}>
    このクイックスタート用に新しい Svelte プロジェクトを作成する

    ```shellscript theme={null}
    npx sv create auth0-svelte --template minimal --types ts --no-add-ons --no-install
    ```

    プロジェクトを開く

    ```shellscript theme={null}
    cd auth0-svelte
    ```
  </Step>

  <Step title="Auth0 SPA ソフトウェア開発キット (SDK) のインストール" stepNumber={2}>
    ```shellscript theme={null}
    npm install && npm install @auth0/auth0-spa-js
    ```
  </Step>

  <Step title="Auth0 アプリケーションを設定する" stepNumber={3}>
    次に、Auth0 テナント上に新しいアプリを作成し、環境変数をプロジェクトに追加する必要があります。

    これは、CLI コマンドを実行して自動的に設定する方法と、Dashboard から手動で設定する方法のどちらかを選択できます。

    <Tabs>
      <Tab title="CLI">
        次のシェルコマンドをプロジェクトのルートディレクトリで実行して、Auth0 アプリを作成し、`.env` ファイルを生成します。

        <AuthCodeGroup>
          ```shellscript Mac theme={null}
          AUTH0_APP_NAME="My Svelte App" && brew tap auth0/auth0-cli && brew install auth0 && auth0 login --no-input && auth0 apps create -n "${AUTH0_APP_NAME}" -t spa -c http://localhost:5173 -l http://localhost:5173 -o http://localhost:5173 --json > auth0-app-details.json && CLIENT_ID=$(jq -r '.client_id' auth0-app-details.json) && DOMAIN=$(auth0 tenants list --json | jq -r '.[] | select(.active == true) | .name') && echo "VITE_AUTH0_DOMAIN=${DOMAIN}" > .env && echo "VITE_AUTH0_CLIENT_ID=${CLIENT_ID}" >> .env && rm auth0-app-details.json && echo ".env file created with your Auth0 details:" && cat .env
          ```

          ```shellscript Windows theme={null}
          $AppName = "My Svelte App"; winget install Auth0.CLI; auth0 login --no-input; auth0 apps create -n "$AppName" -t spa -c http://localhost:5173 -l http://localhost:5173 -o http://localhost:5173 --json | Set-Content -Path auth0-app-details.json; $ClientId = (Get-Content -Raw auth0-app-details.json | ConvertFrom-Json).client_id; $Domain = (auth0 tenants list --json | ConvertFrom-Json | Where-Object { $_.active -eq $true }).name; Set-Content -Path .env -Value "VITE_AUTH0_DOMAIN=$Domain"; Add-Content -Path .env -Value "VITE_AUTH0_CLIENT_ID=$ClientId"; Remove-Item auth0-app-details.json; Write-Output ".env file created with your Auth0 details:"; Get-Content .env
          ```
        </AuthCodeGroup>
      </Tab>

      <Tab title="Dashboard">
        始める前に、プロジェクトのルートディレクトリに `.env` ファイルを作成します。

        ```shellscript .env theme={null}
        VITE_AUTH0_DOMAIN=YOUR_AUTH0_APP_DOMAIN
        VITE_AUTH0_CLIENT_ID=YOUR_AUTH0_APP_CLIENT_ID
        ```

        1. [Auth0 Dashboard](https://manage.auth0.com/dashboard/) に移動します。
        2. **Applications** > **Applications** > **Create Application** をクリックします。
        3. ポップアップでアプリの名前を入力し、アプリの種類として `Single Page Web Application` を選択して **Create** をクリックします。
        4. Application Details ページの **Settings** タブに切り替えます。
        5. `.env` ファイル内の `YOUR_AUTH0_APP_DOMAIN` と `YOUR_AUTH0_APP_CLIENT_ID` を、Dashboard に表示されている **Domain** と **Client ID** の値に置き換えます。

        最後に、Application Details ページの **Settings** タブで、次の URL を設定します。

        **Allowed Callback URLs:**

        ```
        http://localhost:5173
        ```

        **Allowed Logout URLs:**

        ```
        http://localhost:5173
        ```

        **Allowed Web Origins:**

        ```
        http://localhost:5173
        ```

        <Info>
          **Allowed Callback URLs** は、認証後にユーザーが安全にアプリケーションへ戻れるようにするための重要なセキュリティ対策です。一致する URL が設定されていない場合、ログイン処理は失敗し、ユーザーはアプリにアクセスする代わりに Auth0 のエラーページでブロックされます。

          **Allowed Logout URLs** は、サインアウト後にシームレスなユーザー体験を提供するために不可欠です。一致する URL が設定されていない場合、ユーザーはログアウト後にアプリケーションへリダイレクトされず、汎用的な Auth0 のページに留まってしまいます。

          **Allowed Web Origins** はサイレント認証にとって不可欠です。これが設定されていないと、ユーザーはページをリフレッシュしたり、後からアプリに戻ってきた際にログアウトされてしまいます。
        </Info>
      </Tab>
    </Tabs>
  </Step>

  <Step title="Auth0 ストアの作成" stepNumber={4}>
    ストアファイルを作成する

    ```shellscript theme={null}
    mkdir -p src/lib/stores && touch src/lib/stores/auth.ts
    ```

    認証状態を管理するために、次のコードを追加します

    ```typescript src/lib/stores/auth.ts lines expandable theme={null}
      import { writable, derived, get, type Readable } from 'svelte/store';
      import { createAuth0Client, type Auth0Client, type User } from '@auth0/auth0-spa-js';
      import { browser } from '$app/environment';

      export const auth0Client = writable<Auth0Client | null>(null);
      export const user = writable<User | null>(null);
      export const isAuthenticated = writable<boolean>(false);
      export const isLoading = writable<boolean>(true);
      export const error = writable<string | null>(null);

      // 派生ストア
      export const isLoggedIn: Readable<boolean> = derived(
        [isAuthenticated, isLoading],
        ([$isAuthenticated, $isLoading]) => $isAuthenticated && !$isLoading
      );

      export async function initializeAuth() {
        if (!browser) return;
        
        try {
          const client = await createAuth0Client({
            domain: import.meta.env.VITE_AUTH0_DOMAIN,
            clientId: import.meta.env.VITE_AUTH0_CLIENT_ID,
            authorizationParams: {
              redirect_uri: window.location.origin
            },
            useRefreshTokens: true,
            cacheLocation: 'localstorage'
          });

          auth0Client.set(client);

          // コールバックを処理
          if (window.location.search.includes('code=')) {
            await client.handleRedirectCallback();
            window.history.replaceState({}, document.title, window.location.pathname);
          }

          // 認証ステータスを確認
          const authenticated = await client.isAuthenticated();
          isAuthenticated.set(authenticated);

          if (authenticated) {
            const userData = await client.getUser();
            user.set(userData || null);
          }

          error.set(null);
        } catch (err) {
          console.error('Auth初期化エラー:', err);
          error.set(err instanceof Error ? err.message : '認証の初期化に失敗しました');
        } finally {
          isLoading.set(false);
        }
      }

      export async function login() {
        const client = get(auth0Client);
        if (client) {
          await client.loginWithRedirect();
        }
      }

      export async function logout() {
        const client = get(auth0Client);
        if (client) {
          client.logout({ 
            logoutParams: { 
              returnTo: window.location.origin 
            } 
          });
        }
      }

      export async function getToken(): Promise<string | null> {
        const client = get(auth0Client);
        if (!client) return null;
        
        try {
          return await client.getTokenSilently();
        } catch (err: any) {
          if (err.error === 'login_required') {
            await login();
          }
          return null;
        }
      }
    ```
  </Step>

  <Step title="Login、Logout、Profile コンポーネントを作成する" stepNumber={5}>
    コンポーネントファイルを作成する

    ```shellscript theme={null}
    mkdir -p src/lib/components && touch src/lib/components/LoginButton.svelte && touch src/lib/components/LogoutButton.svelte && touch src/lib/components/Profile.svelte
    ```

    次のコードスニペットを追加してください

    <AuthCodeGroup>
      ```svelte src/lib/components/LoginButton.svelte lines expandable theme={null}
      <script lang="ts">
        import { login } from '$lib/stores/auth';

        async function handleLogin() {
          await login();
        }
      </script>

      <button 
        on:click={handleLogin}
        class="button login"
      >
        ログイン
      </button>

      <style>
        .button {
          padding: 1.1rem 2.8rem;
          font-size: 1.2rem;
          font-weight: 600;
          border-radius: 10px;
          border: none;
          cursor: pointer;
          transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
          box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
          text-transform: uppercase;
          letter-spacing: 0.08em;
          outline: none;
        }

        .button:focus {
          box-shadow: 0 0 0 4px rgba(99, 179, 237, 0.5);
        }

        .button.login {
          background-color: #63b3ed;
          color: #1a1e27;
        }

        .button.login:hover {
          background-color: #4299e1;
          transform: translateY(-5px) scale(1.03);
          box-shadow: 0 12px 25px rgba(0, 0, 0, 0.5);
        }
      </style>
      ```

      ```svelte src/lib/components/LogoutButton.svelte lines expandable theme={null}
      <script lang="ts">
        import { logout } from '$lib/stores/auth';

        async function handleLogout() {
          await logout();
        }
      </script>

      <button
        on:click={handleLogout}
        class="button logout"
      >
        ログアウト
      </button>

      <style>
        .button {
          padding: 1.1rem 2.8rem;
          font-size: 1.2rem;
          font-weight: 600;
          border-radius: 10px;
          border: none;
          cursor: pointer;
          transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
          box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
          text-transform: uppercase;
          letter-spacing: 0.08em;
          outline: none;
        }

        .button:focus {
          box-shadow: 0 0 0 4px rgba(252, 129, 129, 0.5);
        }

        .button.logout {
          background-color: #fc8181;
          color: #1a1e27;
        }

        .button.logout:hover {
          background-color: #e53e3e;
          transform: translateY(-5px) scale(1.03);
          box-shadow: 0 12px 25px rgba(0, 0, 0, 0.5);
        }
      </style>
      ```

      ```svelte src/lib/components/Profile.svelte lines expandable theme={null}
      <script lang="ts">
        import { user, isAuthenticated, isLoading } from '$lib/stores/auth';
        
        const placeholderImage = `data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100' viewBox='0 0 100 100'%3E%3Ccircle cx='50' cy='50' r='50' fill='%2363b3ed'/%3E%3Cpath d='M50 45c7.5 0 13.64-6.14 13.64-13.64S57.5 17.72 50 17.72s-13.64 6.14-13.64 13.64S42.5 45 50 45zm0 6.82c-9.09 0-27.28 4.56-27.28 13.64v3.41c0 1.88 1.53 3.41 3.41 3.41h47.74c1.88 0 3.41-1.53 3.41-3.41v-3.41c0-9.08-18.19-13.64-27.28-13.64z' fill='%23fff'/%3E%3C/svg%3E`;
        
        function handleImageError(event: Event) {
          const target = event.target as HTMLImageElement;
          target.src = placeholderImage;
        }
      </script>

      {#if $isLoading}
        <div class="loading-text">プロファイルを読み込み中...</div>
      {:else if $isAuthenticated && $user}
        <div class="profile-container">
          <img 
            src={$user.picture || placeholderImage} 
            alt={$user.name || 'ユーザー'} 
            class="profile-picture"
            on:error={handleImageError}
          />
          <div class="profile-info">
            <div class="profile-name">
              {$user.name || '不明なユーザー'}
            </div>
            <div class="profile-email">
              {$user.email || ''}
            </div>
          </div>
        </div>
      {/if}

      <style>
        .loading-text {
          font-size: 1.8rem;
          font-weight: 500;
          color: #a0aec0;
          animation: pulse 1.5s infinite ease-in-out;
        }

        .profile-container {
          display: flex;
          flex-direction: column;
          align-items: center;
          gap: 1rem;
        }

        .profile-picture {
          width: 110px;
          height: 110px;
          border-radius: 50%;
          object-fit: cover;
          border: 3px solid #63b3ed;
          transition: transform 0.3s ease-in-out;
        }

        .profile-picture:hover {
          transform: scale(1.05);
        }

        .profile-info {
          text-align: center;
        }

        .profile-name {
          font-size: 2rem;
          font-weight: 600;
          color: #f7fafc;
          margin-bottom: 0.5rem;
        }

        .profile-email {
          font-size: 1.15rem;
          color: #a0aec0;
        }

        @keyframes pulse {
          0%, 100% { opacity: 1; }
          50% { opacity: 0.6; }
        }
      </style>
      ```

      ```svelte src/routes/+layout.svelte expandable lines theme={null}
      <script lang="ts">
        import { onMount } from 'svelte';
        import { initializeAuth } from '$lib/stores/auth';

        onMount(() => {
          initializeAuth();
        });
      </script>

      <main>
        <slot />
      </main>

      <style>
        :global(body) {
          margin: 0;
          font-family: 'Inter', sans-serif;
          background-color: #1a1e27;
          min-height: 100vh;
          color: #e2e8f0;
        }

        main {
          min-height: 100vh;
          display: flex;
          justify-content: center;
          align-items: center;
          padding: 1rem;
          box-sizing: border-box;
        }
      </style>
      ```

      ```svelte src/routes/+page.svelte expandable lines theme={null}
      <script lang="ts">
        import { isAuthenticated, isLoading, error, user } from '$lib/stores/auth';
        import LoginButton from '$lib/components/LoginButton.svelte';
        import LogoutButton from '$lib/components/LogoutButton.svelte';
        import Profile from '$lib/components/Profile.svelte';
      </script>

      <svelte:head>
        <title>Auth0 Svelteサンプル</title>
        <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
      </svelte:head>

      <div class="app-container">
        {#if $isLoading}
          <div class="loading-state">
            <div class="loading-text">読み込み中...</div>
          </div>
        {:else if $error}
          <div class="error-state">
            <div class="error-title">エラー</div>
            <div class="error-message">問題が発生しました</div>
            <div class="error-sub-message">{$error}</div>
          </div>
        {:else}
          <div class="main-card-wrapper">
            <img 
              src="https://cdn.auth0.com/quantum-assets/dist/latest/logos/auth0/auth0-lockup-en-ondark.png" 
              alt="Auth0ロゴ" 
              class="auth0-logo"
            />
            <h1 class="main-title">Sample0へようこそ</h1>

            {#if $isAuthenticated}
              <div class="logged-in-section">
                <div class="logged-in-message">✅ 認証に成功しました!</div>
                <h2 class="profile-section-title">プロファイル</h2>
                <div class="profile-card">
                  <Profile />
                </div>
                <LogoutButton />
              </div>
            {:else}
              <div class="action-card">
                <p class="action-text">サインインして開始する</p>
                <LoginButton />
              </div>
            {/if}
          </div>
        {/if}
      </div>

      <style>
        .app-container {
          display: flex;
          flex-direction: column;
          justify-content: center;
          align-items: center;
          min-height: 100vh;
          width: 100%;
          padding: 1rem;
          box-sizing: border-box;
        }

        .loading-state, .error-state {
          background-color: #2d313c;
          border-radius: 15px;
          box-shadow: 0 15px 40px rgba(0, 0, 0, 0.4);
          padding: 3rem;
          text-align: center;
        }

        .loading-text {
          font-size: 1.8rem;
          font-weight: 500;
          color: #a0aec0;
          animation: pulse 1.5s infinite ease-in-out;
        }

        .error-state {
          background-color: #c53030;
          color: #fff;
        }

        .error-title {
          font-size: 2.8rem;
          font-weight: 700;
          margin-bottom: 0.5rem;
        }

        .error-message {
          font-size: 1.3rem;
          margin-bottom: 0.5rem;
        }

        .error-sub-message {
          font-size: 1rem;
          opacity: 0.8;
        }

        .main-card-wrapper {
          background-color: #262a33;
          border-radius: 20px;
          box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.05);
          display: flex;
          flex-direction: column;
          align-items: center;
          gap: 2rem;
          padding: 3rem;
          max-width: 500px;
          width: 90%;
          animation: fadeInScale 0.8s ease-out forwards;
        }

        .auth0-logo {
          width: 160px;
          margin-bottom: 1.5rem;
          opacity: 0;
          animation: slideInDown 1s ease-out forwards 0.2s;
        }

        .main-title {
          font-size: 2.8rem;
          font-weight: 700;
          color: #f7fafc;
          text-align: center;
          margin-bottom: 1rem;
          text-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
          opacity: 0;
          animation: fadeIn 1s ease-out forwards 0.4s;
        }

        .action-card {
          background-color: #2d313c;
          border-radius: 15px;
          box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.3), 0 5px 15px rgba(0, 0, 0, 0.3);
          padding: 2.5rem;
          display: flex;
          flex-direction: column;
          align-items: center;
          gap: 1.8rem;
          width: calc(100% - 2rem);
          opacity: 0;
          animation: fadeIn 1s ease-out forwards 0.6s;
        }

        .action-text {
          font-size: 1.25rem;
          color: #cbd5e0;
          text-align: center;
          line-height: 1.6;
          font-weight: 400;
        }

        .logged-in-section {
          display: flex;
          flex-direction: column;
          align-items: center;
          gap: 1.5rem;
          width: 100%;
        }

        .logged-in-message {
          font-size: 1.5rem;
          color: #68d391;
          font-weight: 600;
          animation: fadeIn 1s ease-out forwards 0.8s;
        }

        .profile-section-title {
          font-size: 2.2rem;
          animation: slideInUp 1s ease-out forwards 1s;
        }

        .profile-card {
          padding: 2.2rem;
          animation: scaleIn 0.8s ease-out forwards 1.2s;
        }

        @keyframes fadeIn {
          from { opacity: 0; }
          to { opacity: 1; }
        }

        @keyframes fadeInScale {
          from { opacity: 0; transform: scale(0.95); }
          to { opacity: 1; transform: scale(1); }
        }

        @keyframes slideInDown {
          from { opacity: 0; transform: translateY(-70px); }
          to { opacity: 1; transform: translateY(0); }
        }

        @keyframes slideInUp {
          from { opacity: 0; transform: translateY(50px); }
          to { opacity: 1; transform: translateY(0); }
        }

        @keyframes pulse {
          0%, 100% { opacity: 1; }
          50% { opacity: 0.6; }
        }

        @keyframes scaleIn {
          from { opacity: 0; transform: scale(0.8); }
          to { opacity: 1; transform: scale(1); }
        }

        @media (max-width: 600px) {
          .main-card-wrapper {
            padding: 2rem;
            margin: 1rem;
          }

          .main-title {
            font-size: 2.2rem;
          }

          .auth0-logo {
            width: 120px;
          }
        }
      </style>
      ```
    </AuthCodeGroup>
  </Step>

  <Step title="アプリを実行する" stepNumber={6}>
    ```shellscript theme={null}
    npm run dev
    ```
  </Step>
</Steps>

<Check>
  **チェックポイント**

  ここまでで、[localhost](http://localhost:5173/) 上で Auth0 のログインページが問題なく動作しているはずです。
</Check>

***

<div id="troubleshooting">
  ## トラブルシューティング
</div>

<Accordion title="ログインが動作しない">
  ログインボタンをクリックしても何も起こらない場合:

  1. ブラウザの開発者ツール（F12）を開き、「Console」タブを確認する
  2. `.env` ファイルに実際の Auth0 クレデンシャルが設定されていることを確認する
  3. Auth0 アプリケーションに正しいコールバックURLが設定されていることを確認する
  4. `VITE_AUTH0_DOMAIN` が `https://` を含めず、ドメインのみ（例: `tenant.auth0.com`）になっていることを確認する
</Accordion>

<Accordion title="認証エラー">
  **"Callback URL mismatch"** の場合:

  * Auth0 Dashboard → Applications → 対象のアプリ → Settings に移動する
  * `http://localhost:5173` を 許可されたコールバックURL、許可されたログアウトURL、および Allowed Web Origins に追加する
  * 「Save Changes」をクリックする

  **"Invalid state"** の場合:

  * ブラウザのキャッシュとクッキーをクリアする
  * シークレットモード／プライベートウィンドウで試す
</Accordion>

<Accordion title="開発サーバーの問題">
  `npm run dev` が失敗する場合:

  * `npm run check` を実行して TypeScript のエラーを確認する
  * すべてのファイルが正しく作成されていることを確認する
  * すべての依存関係がインストールされていることを確認する: `npm install`
</Accordion>

<Tip>
  まだ解決しない場合は、[Auth0 Community](https://community.auth0.com/) や [SvelteKit Discord](https://svelte.dev/chat) を参照してサポートを受けてください。
</Tip>
