{m.profile_page_title()} {#if cropFile && browser} {#await import('$lib/components/AvatarCropModal.svelte') then { default: AvatarCropModal }} {/await} {/if}
{#if justSubscribed}

Welcome to Pro!

Your subscription is being activated. Refresh the page in a moment if the Pro badge doesn't appear yet.

{/if}

{data.user.username}

{data.user.role} {#if data.isPro} {m.profile_plan_pro()} {/if}
{#if avatarError}

{avatarError}

{:else}

{m.profile_click_to_change()}

{/if}
{#each (['profile', 'stats', 'history'] as const) as tab} {/each}
{#if activeTab === 'profile'} {#if !data.isPro}

{m.profile_subscription_heading()}

{m.profile_free_limits()}

{m.profile_plan_free()}

{m.profile_upgrade_heading()}

{m.profile_upgrade_desc()} See plans →

{#if checkoutError}

{checkoutError}

{/if}
{:else}

{m.profile_pro_active()}

{m.profile_pro_perks()}

{m.profile_manage_subscription()} →
{/if}

Preferences

{#if saveStatus === 'saving'}{m.profile_saving()}… {:else if saveStatus === 'saved'}✓ {m.profile_saved()} {:else}{m.profile_saved()}{/if}

{m.profile_theme_label()}

{#each THEMES as t, i} {#if i === 6} {/if} {/each}

{m.profile_font_family()}

{#each FONTS as f} {/each}

{m.profile_text_size()}

{#each FONT_SIZES as s} {/each}
{audioStore.speed.toFixed(1)}x
0.5x3.0x

Playback

{m.profile_auto_advance()}

Load the next chapter automatically when audio ends

Announce chapter

Read the chapter title aloud before advancing

Audio mode

{audioStore.audioMode === 'stream' ? 'Stream — starts within seconds' : 'Generate — waits for full audio'} {#if audioStore.voice.startsWith('cfai:')} (not available for CF AI){/if}

{m.profile_sessions_heading()}

{m.profile_session_unrecognised()}

{#if revokeError}
{revokeError}
{/if} {#if sessions.length === 0}

{m.profile_no_sessions()}

{:else}
    {#each sessions as session (session.id)}
  • {parseUA(session.user_agent)} {#if session.is_current} {m.profile_session_this()} {/if}
    {#if session.ip}

    {session.ip}

    {/if}

    {m.profile_session_signed_in({ date: formatDate(session.created_at) })} {#if session.last_seen && session.last_seen !== session.created_at} {m.profile_session_last_seen({ date: formatDate(session.last_seen) })} {/if}

  • {/each}
{/if}
{#if pushState !== 'unsupported'}

Push notifications

{#if pushState === 'subscribed'} You'll receive a push notification when new chapters are added to books in your library. {:else if pushState === 'denied'} Notifications are blocked by your browser. Change the permission in your browser settings. {:else} Get notified when new chapters arrive for books in your library. {/if}

{#if pushError}

{pushError}

{/if}
{#if pushState === 'subscribed'} {:else if pushState === 'denied'} Blocked {:else} {/if}
{/if}
{#if deleteConfirmOpen}

Delete account

This permanently deletes your account, reading history, settings, and all associated data. This action cannot be undone.

{#if deleteError}

{deleteError}

{/if}
{/if}
{/if} {#if activeTab === 'stats'}

Reading Overview

{#each [ { label: 'Chapters Read', value: data.stats.totalChaptersRead }, { label: 'Completed', value: data.stats.booksCompleted }, { label: 'Reading', value: data.stats.booksReading }, { label: 'Plan to Read', value: data.stats.booksPlanToRead }, ] as stat}

{stat.value}

{stat.label}

{/each}

Activity

{data.stats.streak}

day streak

{data.stats.avgRatingGiven > 0 ? data.stats.avgRatingGiven.toFixed(1) : '—'}

avg rating given

{#if data.stats.topGenres.length > 0}

Favourite Genres

{#each data.stats.topGenres as genre, i} {genre} {/each}
{/if} {#if data.stats.booksDropped > 0}

{data.stats.booksDropped} dropped book{data.stats.booksDropped !== 1 ? 's' : ''} — revisit your library

{/if}
{/if} {#if activeTab === 'history'} {/if}