Skip to content
Draft
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified bun.lockb
Binary file not shown.
592 changes: 587 additions & 5 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
"format": "prettier --write ."
},
"devDependencies": {
"@fluent/bundle": "^0.19.1",
"@fluent/langneg": "^0.7.0",
"@nubolab-ffwd/svelte-fluent": "^1.0.4",
"@sveltejs/adapter-auto": "^3.3.1",
"@sveltejs/adapter-static": "^3.0.6",
"@sveltejs/kit": "^2.8.5",
Expand All @@ -34,6 +37,7 @@
"type": "module",
"dependencies": {
"@fontsource-variable/hanken-grotesk": "^5.1.1",
"@tailwindcss/vite": "^4.0.1"
"@tailwindcss/vite": "^4.0.1",
"jsdom": "26"
}
}
8 changes: 7 additions & 1 deletion src/app.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
import '@nubolab-ffwd/svelte-fluent/types';
import { SvelteFluent } from '@nubolab-ffwd/svelte-fluent';

declare global {
namespace App {
// interface Error {}
// interface Locals {}
interface Locals {
locale: string;
fluent: SvelteFluent;
}
// interface PageData {}
// interface PageState {}
// interface Platform {}
Expand Down
14 changes: 11 additions & 3 deletions src/hooks.server.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
import { generateBundles, negotiateLocale } from '$lib/fluent';
import type { Handle } from '@sveltejs/kit';
import { createSvelteFluent } from '@nubolab-ffwd/svelte-fluent';
import { sequence } from '@sveltejs/kit/hooks';
import { type Handle } from '@sveltejs/kit';

const fluentHandler: Handle = async ({ event, resolve }) => {
event.locals.locale = negotiateLocale(event);
event.locals.fluent = createSvelteFluent(generateBundles(event.locals.locale));

return resolve(event);
};

const preloadFonts: Handle = async ({ event, resolve }) => {
const response = await resolve(event, {
preload: ({ type }) => type === 'font',
});

return response;
};

export const handle: Handle = sequence(preloadFonts);
export const handle: Handle = sequence(fluentHandler, preloadFonts);
11 changes: 6 additions & 5 deletions src/lib/components/common/DualHeader.svelte
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
<script lang="ts">
import { Localized } from '@nubolab-ffwd/svelte-fluent';
import type { Snippet } from 'svelte';

type DualHeader = {
title: string;
id: string;
subtitle: Snippet;
};

let { title, subtitle }: DualHeader = $props();

const id = $derived(title.toLowerCase().replace(/\s/g, '-'));
let { id, subtitle }: DualHeader = $props();
</script>

<hgroup class="relative mx-auto text-center md:max-w-2xl mt-12 mb-16 md:mb-24 scroll-mt-24">
<h2 {id} class="text-[2.5rem] leading-[135%] tracking-tight font-semibold capitalize">{title}</h2>
<h2 {id} class="text-[2.5rem] leading-[135%] tracking-tight font-semibold">
<Localized {id} />
</h2>
<div class="text-xl text-subtle leading-[135%] mt-3 font-medium">
{@render subtitle()}
</div>
Expand Down
7 changes: 4 additions & 3 deletions src/lib/components/common/LinkCard.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script lang="ts">
import { base } from '$app/paths';
import { Localized } from '@nubolab-ffwd/svelte-fluent';

type LinkCard = {
title: string;
Expand All @@ -15,15 +16,15 @@
class="group flex flex-col justify-between px-9 py-6 hover:bg-subtle-surface rounded-lg border border-subtle/12"
>
<div class="flex items-start justify-between mb-5">
<h3 class="flex flex-row items-center text-2xl capitalize font-medium">
{title}&nbsp;&nbsp;&nbsp;<img
<h3 class="flex flex-row items-center text-2xl font-medium">
<Localized id={title} />&nbsp;&nbsp;&nbsp;<img
src="{base}/icons/link-arrow.svg"
alt="outlink"
class="size-6"
/>
</h3>
</div>
<p class="text-subtle leading-snug tracking-wide">
{description}
<Localized id={description} />
</p>
</a>
17 changes: 9 additions & 8 deletions src/lib/components/core/Navigation.svelte
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
<script lang="ts">
import { base } from '$app/paths';
import { Localized } from '@nubolab-ffwd/svelte-fluent';

type MenuOption = {
href: string;
text: string;
};

const options: MenuOption[] = [
{ text: 'Docs', href: 'https://docs.ankiweb.net/' },
{ text: 'Forums', href: 'https://forums.ankiweb.net/' },
{ text: 'AnkiWeb', href: 'https://ankiweb.net/' },
{ text: 'Add-Ons', href: 'https://ankiweb.net/shared/addons' },
{ text: 'Shared Decks', href: 'https://ankiweb.net/shared/decks' },
{ text: 'docs-menu', href: 'https://docs.ankiweb.net/' },
{ text: 'forums-menu', href: 'https://forums.ankiweb.net/' },
{ text: 'ankiweb-menu', href: 'https://ankiweb.net/' },
{ text: 'add-ons-menu', href: 'https://ankiweb.net/shared/addons' },
{ text: 'shared-decks-menu', href: 'https://ankiweb.net/shared/decks' },
];

let scrollY = $state(0);
Expand Down Expand Up @@ -50,7 +51,7 @@
class="px-3 select-none transition-all duration-150 ease-out flex items-center text-foreground h-full hover:shadow-[inset_0_-2px_var(--color-primary)]"
{href}
>
{text}
<Localized id={text} />
</a>
{/each}
<a
Expand All @@ -69,7 +70,7 @@
href="#downloads"
class="rounded-[2rem] px-4 py-1.5 font-semibold tracking-tight transition-all duration-100 ease-out bg-gradient-to-r from-primary-darker to-primary text-background hover:opacity-80"
>
Download Anki
<Localized id="download-anki" />
</a>
</div>
<div class="flex items-center gap-2.5 min-[832px]:hidden">
Expand Down Expand Up @@ -142,7 +143,7 @@
onclick={closeMenu}
class="text-center mt-auto rounded hover:opacity-80 bg-gradient-to-r from-primary-darker to-primary text-background py-4 text-lg flex items-center justify-center font-semibold leading-none cursor-pointer transition-all duration-300 ease-out"
>
Download Anki
<Localized id="download-anki" />
</a>
</nav>
</div>
Expand Down
30 changes: 15 additions & 15 deletions src/lib/components/sections/Advantages.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script lang="ts">
import DualHeader from '$lib/components/common/DualHeader.svelte';
import { Localized } from '@nubolab-ffwd/svelte-fluent';

interface Advantage {
id: string;
Expand All @@ -14,9 +15,8 @@
const advantages: Advantage[] = [
{
id: 'synchronization',
title: 'Synchronization',
description:
'The free AnkiWeb synchronization service lets you sync your cards across devices.',
title: 'synchronization',
description: 'synchronization-description',
icon: {
viewBox: '0 0 24 24',
paths: [
Expand All @@ -26,8 +26,8 @@
},
{
id: 'media-support',
title: 'Media Support',
description: 'Audio, images, videos, and scientific markup can be used in your flashcards.',
title: 'media-support',
description: 'media-support-description',
icon: {
viewBox: '0 0 24 24',
paths: [
Expand All @@ -37,8 +37,8 @@
},
{
id: 'customization',
title: 'Customization',
description: 'Easily change your flashcard layouts and the timing of their reviews.',
title: 'customization',
description: 'customization-description',
icon: {
viewBox: '0 0 24 24',
paths: [
Expand All @@ -51,8 +51,8 @@
},
{
id: 'optimization',
title: 'Optimization',
description: 'Anki can handle decks of 100,000+ cards with no problems.',
title: 'optimization',
description: 'optimization-description',
icon: {
viewBox: '0 0 24 24',
paths: [
Expand All @@ -62,8 +62,8 @@
},
{
id: 'add-ons',
title: 'Add-ons',
description: 'Install add-ons to extend Anki with new features and functionality.',
title: 'add-ons',
description: 'add-ons-description',
icon: {
viewBox: '0 0 24 24',
paths: [
Expand Down Expand Up @@ -93,16 +93,16 @@
/>
{/each}
</svg>
<h3 class="text-lg md:text-xl font-medium capitalize">{title}</h3>
<h3 class="text-lg md:text-xl font-medium capitalize"><Localized id={title} /></h3>
</div>
<p class="text-subtle leading-snug md:text-lg tracking-wide">{description}</p>
<p class="text-subtle leading-snug md:text-lg tracking-wide"><Localized id={description} /></p>
</div>
{/snippet}

<section class="relative z-1 mx-auto w-[min(100%,986px)] pt-12">
<DualHeader title="advantages">
<DualHeader id="advantages">
{#snippet subtitle()}
<p>Here are a few reasons why users love Anki.</p>
<p><Localized id="here-are-a-few-reasons-why-users-love-anki" /></p>
{/snippet}
</DualHeader>
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6 md:gap-8">
Expand Down
16 changes: 7 additions & 9 deletions src/lib/components/sections/BasicConcepts.svelte
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
<script>
import { base } from '$app/paths';
import DualHeader from '$lib/components/common/DualHeader.svelte';
import { Localized } from '@nubolab-ffwd/svelte-fluent';
</script>

<section class="relative z-1 mx-auto w-[min(100%,986px)] pt-12">
<DualHeader title="basic concepts">
<DualHeader id="basic-concepts">
{#snippet subtitle()}
<p>Anki supports complex workflows, but getting started is easy.</p>
<p><Localized id="anki-supports-complex-workflows-but-getting-started-is-easy" /></p>
{/snippet}
</DualHeader>
<div class="flex flex-col items-center gap-6 md:gap-20 md:flex-row">
Expand All @@ -21,10 +22,9 @@
class="aspect-5/3 grow md:max-w-[35%] hidden dark:inline"
/>
<div class="w-full flex flex-col gap-2 mt-6 md:mt-0">
<h3 class="text-2xl font-medium capitalize">Decks</h3>
<h3 class="text-2xl font-medium capitalize"><Localized id="decks" /></h3>
<p class="text-lg text-subtle tracking-wide leading-snug">
Decks are groups of flashcards that allow you to study specific parts of your collection
instead of everything all at once. Create a new deck and add some flashcards to get started.
<Localized id="decks-description" />
</p>
</div>
</div>
Expand All @@ -40,11 +40,9 @@
class="aspect-5/3 grow md:max-w-[35%] hidden dark:inline"
/>
<div class="w-full flex flex-col gap-2 mt-6 md:mt-0">
<h3 class="text-2xl font-medium capitalize">Reviews</h3>
<h3 class="text-2xl font-medium capitalize"><Localized id="reviews" /></h3>
<p class="text-lg text-subtle tracking-wide leading-snug">
When you're ready, start reviewing your flashcards. Rate your recall with the most suitable
option and Anki will schedule the next review for when you're most likely to forget the
information.
<Localized id="reviews-description" />
</p>
</div>
</div>
Expand Down
23 changes: 11 additions & 12 deletions src/lib/components/sections/Contributing.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script lang="ts">
import DualHeader from '$lib/components/common/DualHeader.svelte';
import LinkCard from '$lib/components/common/LinkCard.svelte';
import { Localized } from '@nubolab-ffwd/svelte-fluent';

type ContributingLinkCard = {
title: string;
Expand All @@ -10,32 +11,30 @@

const contributingCards: ContributingLinkCard[] = [
{
title: 'open source',
description:
'If you know how to code you could help maintain Anki or create new add-ons/features.',
title: 'open-source',
description: 'open-source-description',
href: 'https://github.com/ankitects/anki/blob/main/docs/contributing.md',
},
{
title: 'share decks',
description:
"Sharing your deck can make it easier for others to start learning what you're studying.",
title: 'share-decks',
description: 'share-decks-description',
href: 'https://docs.ankiweb.net/contrib#sharing-decks-publicly',
},
{
title: 'translate anki',
description:
'Help with the efforts to translate Anki so it can become more accessible to everyone.',
title: 'translate-anki',
description: 'translate-anki-description',
href: 'https://translating.ankiweb.net/intro.html',
},
];
</script>

<section class="relative z-1 mx-auto w-[min(100%,986px)] pt-12">
<DualHeader title="contributing">
<DualHeader id="contributing">
{#snippet subtitle()}
<p>
Anki is a community project where anyone can make contributions to help improve everyone's
experience.
<Localized
id="anki-is-a-community-project-where-anyone-can-make-contributions-to-help-improve-everyone-experience"
/>
</p>
{/snippet}
</DualHeader>
Expand Down
Loading