feat: enhance API and middleware functionality: add public API routes, implement program and course member checks, and improve rate limiting for invite acceptance. Update OpenAPI spec generation to focus on public API endpoints and add new middleware for automation key scopes. Include new documentation for lesson AI features and public API tests.

This commit is contained in:
Rotimi Best
2026-04-12 08:58:41 +01:00
parent 5a8f50f67b
commit d6e812d08b
573 changed files with 31964 additions and 8708 deletions
@@ -0,0 +1,117 @@
<script>
import { BlurFade } from '@cio/ui/custom/animation/blurfade';
import { BorderBeam } from '@cio/ui/custom/animation/border-beam';
const aiFeatures = [
{
icon: '⚡',
title: 'Create a full course in seconds',
description:
'Tell your agent what to build. It creates the course, writes the lessons, and adds quizzes. What used to take days now takes seconds.'
},
{
icon: '🔄',
title: 'Update content instantly',
description:
'Policies changed? Tell your agent to update the course. It rewrites the affected lessons and adjusts the quiz questions to match.'
},
{
icon: '📄',
title: 'Turn any doc into training',
description:
'Point your agent at a Notion page, Google Doc, or PDF. It reads the source and builds a structured course with assessments.'
}
];
const agents = [
{ name: 'Cursor', logo: '/cursor-logo.png' },
{ name: 'Claude Code', logo: '/claude-logo.svg' },
{ name: 'Codex', logo: '/codex-logo.png' },
{ name: 'OpenCode', logo: '/opencode-logo.svg' }
];
</script>
<section
id="ai"
class="relative overflow-hidden bg-linear-to-br from-gray-950 to-[#0f1629] px-6 py-16 text-white lg:px-12 lg:py-24"
>
<div
class="pointer-events-none absolute -top-[200px] -right-[200px] h-[600px] w-[600px] bg-[radial-gradient(circle,rgba(2,51,189,0.15)_0%,transparent_70%)]"
></div>
<div class="mx-auto max-w-[1100px]">
<div class="grid grid-cols-1 items-center gap-12 lg:grid-cols-2 lg:gap-20">
<div>
<BlurFade once>
<div class="mb-3.5 text-xs font-medium tracking-widest text-blue-400 uppercase">AI-Powered Content</div>
<h2 class="mb-4 text-[clamp(2rem,3vw,2.8rem)] leading-[1.15] font-medium tracking-tight text-white">
Let your agent do<br />the course building.
</h2>
<p class="mb-14 max-w-[520px] text-base leading-relaxed text-gray-500 lg:text-lg">
Connect your favorite coding agent to ClassroomIO via MCP. Create, update, and publish entire courses from
your terminal in seconds.
</p>
</BlurFade>
<div class="flex flex-col gap-6">
{#each aiFeatures as feature, i}
<BlurFade delay={0.15 * i} once>
<div class="flex items-start gap-4 rounded-xl border border-white/[0.08] bg-white/[0.04] p-6">
<div class="flex h-11 w-11 shrink-0 items-center justify-center rounded-lg bg-blue-700/20 text-2xl">
{feature.icon}
</div>
<div>
<h4 class="mb-1.5 text-sm font-medium text-white">{feature.title}</h4>
<p class="text-sm leading-relaxed text-gray-500">{feature.description}</p>
</div>
</div>
</BlurFade>
{/each}
</div>
</div>
<BlurFade delay={0.2} once>
<div>
<!-- Code Block -->
<div class="relative overflow-hidden rounded-2xl border border-gray-800 bg-[#0d0d0d]">
<BorderBeam size={200} duration={10} colorFrom="#0233BD" colorTo="#6b8fff" />
<div class="flex items-center gap-2 border-b border-gray-800 bg-gray-900 px-5 py-3.5">
<div class="h-2.5 w-2.5 rounded-full bg-red-400"></div>
<div class="h-2.5 w-2.5 rounded-full bg-yellow-400"></div>
<div class="h-2.5 w-2.5 rounded-full bg-green-500"></div>
<span class="ml-2 text-xs text-gray-600">mcp.json</span>
</div>
<div class="p-6 font-mono text-xs leading-loose whitespace-pre text-gray-400 lg:text-sm">
{'{'}<br />{' '}<span class="text-blue-400">"mcpServers"</span>: {'{'}<br />{' '}<span
class="text-blue-400">"classroomio"</span
>: {'{'}<br />{' '}<span class="text-blue-400">"command"</span>:
<span class="text-green-400">"npx"</span>,<br />{' '}<span class="text-blue-400">"args"</span>:
[<span class="text-green-400">"-y"</span>, <span class="text-green-400">"@classroomio/mcp"</span>],<br
/>{' '}<span class="text-blue-400">"env"</span>: {'{'}<br />{' '}<span
class="text-blue-400">"CLASSROOMIO_API_URL"</span
>: <span class="text-green-400">"https://api.classroomio.com"</span>,<br />{' '}<span
class="text-blue-400">"CLASSROOMIO_API_KEY"</span
>: <span class="text-green-400">"&lt;your-mcp-key&gt;"</span><br />{' }'}<br />{' }'}<br
/>{' }'}<br />{'}'}
</div>
</div>
<!-- Supported Agents -->
<div class="mt-6">
<div class="mb-3 text-xs tracking-wider text-gray-600 uppercase">Works with</div>
<div class="flex flex-wrap gap-3">
{#each agents as agent}
<div
class="flex items-center gap-2 rounded-full border border-white/[0.08] bg-white/[0.06] px-3.5 py-2"
>
<img src={agent.logo} alt="{agent.name} logo" class="h-5 w-5 rounded-full" />
<span class="text-xs text-gray-300">{agent.name}</span>
</div>
{/each}
</div>
</div>
</div>
</BlurFade>
</div>
</div>
</section>
@@ -0,0 +1,57 @@
<script>
const integrations = [
{
icon: '🔌',
title: 'REST API',
description:
'Full API access to every object in your LMS. Create users, enroll learners, pull completions. All programmatically, at scale.'
},
{
icon: '⚡',
title: 'Zapier Integration',
comingSoon: true,
description:
'Connect to 6,000+ apps without writing a line of code. Auto-enroll from your CRM, send Slack alerts on completion, update your spreadsheet.'
},
{
icon: '🪝',
title: 'Webhooks',
comingSoon: true,
description:
'Real-time event notifications for every action. Course enrolled, lesson completed, certificate issued. Push to any endpoint instantly.'
}
];
</script>
<section class="bg-gray-50 px-6 py-16 lg:px-12 lg:py-24">
<div class="mx-auto max-w-[1100px]">
<div class="mb-3.5 text-xs font-medium tracking-widest text-blue-700 uppercase">Automate the boring parts</div>
<h2 class="mb-4 text-[clamp(2rem,3vw,2.8rem)] leading-[1.15] font-medium tracking-tight">
Set it up once.<br />Let it run.
</h2>
<p class="mb-14 max-w-[520px] text-base leading-relaxed text-gray-500 lg:text-lg">
Connect ClassroomIO to everything you already use. New hire joins Slack? They're enrolled. Course completed? Your
HRIS knows.
</p>
<div class="grid grid-cols-1 gap-5 md:grid-cols-3">
{#each integrations as item}
<div
class="rounded-2xl border border-gray-200 bg-white p-8 transition-all duration-200 hover:border-gray-950 hover:shadow-lg hover:shadow-black/5"
>
<div class="mb-4 text-3xl">{item.icon}</div>
<h3 class="mb-2 text-base font-medium">
{item.title}
{#if item.comingSoon}
<span
class="ml-1 rounded-full bg-blue-700 px-1.5 py-0.5 align-middle text-[0.6rem] tracking-wide text-white uppercase"
>Soon</span
>
{/if}
</h3>
<p class="text-sm leading-relaxed text-gray-500">{item.description}</p>
</div>
{/each}
</div>
</div>
</section>
@@ -0,0 +1,57 @@
<script>
import { BlurFade } from '@cio/ui/custom/animation/blurfade';
import { Meteors } from '@cio/ui/custom/animation/meteors';
const steps = [
{
number: '01',
title: 'Invite your team',
description:
'Add users individually, bulk import via CSV, or connect your HRIS. Assign courses automatically based on role or department.'
},
{
number: '02',
title: 'Publish your courses',
description:
'Build courses with video, text, quizzes, and assignments. Set pass thresholds, enforce order, and control who sees what.'
},
{
number: '03',
title: 'Set certification rules',
description:
'Define expiry dates, renewal requirements, and passing scores. Issue branded certificates automatically on completion.'
}
];
</script>
<section id="features" class="bg-gray-950 px-6 py-16 text-white lg:px-12 lg:py-24">
<div class="mx-auto max-w-[1100px]">
<BlurFade once>
<div class="mb-3.5 text-xs font-medium tracking-widest text-blue-400 uppercase">Certifications & Compliance</div>
<h2 class="mb-4 text-[clamp(2rem,3vw,2.8rem)] leading-[1.15] font-medium tracking-tight text-white">
Go from zero to certified<br />in one afternoon.
</h2>
<p class="mb-14 max-w-[520px] text-base leading-relaxed text-gray-500 lg:text-lg">
Everything you need to run a serious certification program. No duct tape, no spreadsheets, no chasing people
down.
</p>
</BlurFade>
<div class="grid grid-cols-1 gap-0.5 overflow-hidden rounded-2xl border border-gray-800 bg-gray-800 md:grid-cols-3">
{#each steps as step, i}
<BlurFade delay={0.1 * i} once>
<div
class="relative overflow-hidden bg-gray-900 p-8 transition-colors duration-200 hover:bg-gray-900/80 lg:p-9"
>
<Meteors number={6} />
<div class="mb-3.5 text-[2.8rem] leading-none font-medium text-blue-700 italic">
{step.number}
</div>
<h3 class="mb-2.5 text-base font-medium text-white">{step.title}</h3>
<p class="text-sm leading-relaxed text-gray-500">{step.description}</p>
</div>
</BlurFade>
{/each}
</div>
</div>
</section>
@@ -0,0 +1,72 @@
<script>
import { BlurFade } from '@cio/ui/custom/animation/blurfade';
const deployOptions = [
{
icon: '🚂',
title: 'Railway',
description: 'One-click deploy with our Railway template. Live in under 3 minutes.',
href: 'https://railway.app'
},
{
icon: '🐳',
title: 'Docker Compose',
description: 'Standard Docker setup for any Linux server or VPS. Full control.',
href: '/github'
},
{
icon: '❄️',
title: 'Coolify',
description: 'Self-hosted Heroku alternative. Deploy ClassroomIO alongside your stack.',
href: 'https://coolify.io'
}
];
</script>
<section id="deploy" class="bg-white px-6 py-16 lg:px-12 lg:py-24">
<div class="mx-auto max-w-[1100px]">
<div class="grid grid-cols-1 items-center gap-12 lg:grid-cols-2 lg:gap-20">
<BlurFade once>
<div>
<div class="mb-3.5 text-xs font-medium tracking-widest text-blue-700 uppercase">Deploy to your servers</div>
<h2 class="mb-4 text-[clamp(2rem,3vw,2.8rem)] leading-[1.15] font-medium tracking-tight">
Your data.<br />Your servers.<br />Your call.
</h2>
<p class="mb-8 max-w-[520px] text-base leading-relaxed text-gray-500 lg:text-lg">
No SaaS lock-in. No per-seat pricing surprises. Deploy ClassroomIO wherever you run your infrastructure.
Minutes, not days.
</p>
<div class="mt-3 rounded-xl border border-gray-200 bg-gray-50 p-5">
<div class="mb-2.5 text-xs font-medium tracking-wider text-gray-500 uppercase">One-line deploy</div>
<code class="font-mono text-sm text-gray-950">docker compose up -d</code>
</div>
</div>
</BlurFade>
<div class="flex flex-col gap-4">
{#each deployOptions as option, i}
<BlurFade delay={0.1 * i} once>
<a
href={option.href}
target="_blank"
rel="noopener noreferrer"
class="flex items-center gap-5 rounded-xl border-[1.5px] border-gray-200 p-6 text-gray-950 no-underline transition-all duration-200 hover:border-blue-700 hover:bg-blue-50"
>
<div
class="flex h-11 w-11 shrink-0 items-center justify-center rounded-lg border border-gray-200 bg-gray-50 text-xl"
>
{option.icon}
</div>
<div>
<h4 class="mb-0.5 text-sm font-medium">{option.title}</h4>
<p class="text-sm text-gray-500">{option.description}</p>
</div>
<span class="ml-auto text-lg text-gray-400">→</span>
</a>
</BlurFade>
{/each}
</div>
</div>
</div>
</section>
@@ -0,0 +1,263 @@
<script>
import { BlurFade } from '@cio/ui/custom/animation/blurfade';
import { BorderBeam } from '@cio/ui/custom/animation/border-beam';
import { DotPattern } from '@cio/ui/custom/animation/dot-pattern';
const features = [
{
icon: '🏢',
title: 'Multi-tenancy',
description: 'Isolated environments for each department, team, or client organization.'
},
{
icon: '📋',
title: 'Audit Logs',
description: 'Full visibility into every action, login, and change across your platform.'
},
{
icon: '🔌',
title: 'API Access',
description: 'Programmatic control over users, courses, enrollments, and completions.'
},
{
icon: '🔐',
title: 'RBAC',
description: 'Fine-grained roles and permissions for admins, teachers, and learners.'
},
{
icon: '🔑',
title: 'SSO / OIDC',
description: 'Single sign-on with your identity provider. SAML and OIDC supported.'
},
{
icon: '🛡️',
title: 'SLA & Support',
description: 'Guaranteed uptime, priority assistance, and a dedicated point of contact.'
},
{
icon: '🎨',
title: 'White Labeling',
description: 'Fully customize the look and feel so learners only see your brand.'
}
];
const uiComponents = [
{ label: 'Button', category: 'Atom' },
{ label: 'Card', category: 'Molecule' },
{ label: 'Dialog', category: 'Molecule' },
{ label: 'Input', category: 'Atom' },
{ label: 'Badge', category: 'Atom' },
{ label: 'Table', category: 'Molecule' },
{ label: 'Tabs', category: 'Atom' },
{ label: 'Select', category: 'Atom' },
{ label: 'Sidebar', category: 'Molecule' },
{ label: 'Field', category: 'Molecule' },
{ label: 'Editor', category: 'Molecule' },
{ label: 'Accordion', category: 'Atom' }
];
</script>
<section class="relative overflow-hidden bg-gray-950 px-6 py-16 text-white lg:px-12 lg:py-24">
<DotPattern
fillColor="rgb(255 255 255 / 0.05)"
class="absolute inset-0 h-full w-full [mask-image:radial-gradient(600px_circle_at_center,white,transparent)]"
/>
<div class="relative z-10 mx-auto max-w-[1100px]">
<BlurFade once>
<div class="mb-3.5 text-xs font-medium tracking-widest text-blue-400 uppercase">Enterprise</div>
<h2 class="mb-4 text-[clamp(2rem,3vw,2.8rem)] leading-[1.15] font-medium tracking-tight text-white">
Enterprise-grade, out of the box.
</h2>
<p class="mb-6 max-w-[560px] text-base leading-relaxed text-gray-500 lg:text-lg">
Everything in the open-source core, plus the control, security, and support that compliance teams need at scale.
</p>
<button
data-cal-link="classroomio/enterprise"
data-cal-config="'layout':'month_view'"
class="mb-14 inline-flex cursor-pointer items-center gap-2 rounded-lg bg-blue-700 px-6 py-3 text-sm font-medium text-white transition-all duration-200 hover:bg-blue-800"
>
Talk to us →
</button>
</BlurFade>
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
{#each features as feature, i}
<BlurFade delay={0.08 * i} once>
<div
class="rounded-xl border border-white/[0.08] bg-white/[0.04] p-5 transition-all duration-200 hover:bg-white/[0.06]"
>
<div class="mb-3 text-2xl">{feature.icon}</div>
<h3 class="mb-1.5 text-sm font-medium text-white">{feature.title}</h3>
<p class="text-xs leading-relaxed text-gray-500">{feature.description}</p>
</div>
</BlurFade>
{/each}
</div>
<!-- Composable UI -->
<div class="mt-20">
<BlurFade delay={0.1} once>
<div class="grid grid-cols-1 items-center gap-12 lg:grid-cols-2 lg:gap-20">
<div>
<div class="mb-3.5 text-xs font-medium tracking-widest text-blue-400 uppercase">Design System</div>
<h3 class="mb-4 text-[clamp(1.5rem,2.5vw,2.2rem)] leading-[1.2] font-medium tracking-tight text-white">
Composable UI.<br />Build it your way.
</h3>
<p class="mb-6 max-w-[480px] text-base leading-relaxed text-gray-500 lg:text-lg">
A library of 50+ accessible, themeable components built on Svelte 5 and Tailwind. Atoms, molecules, and
full templates you can compose into any learning experience.
</p>
<div class="mb-8 flex flex-wrap gap-2">
<span
class="rounded-full border border-white/[0.1] bg-white/[0.05] px-3 py-1 text-xs font-medium text-gray-300"
>
shadcn-svelte
</span>
<span
class="rounded-full border border-white/[0.1] bg-white/[0.05] px-3 py-1 text-xs font-medium text-gray-300"
>
Tailwind v4
</span>
<span
class="rounded-full border border-white/[0.1] bg-white/[0.05] px-3 py-1 text-xs font-medium text-gray-300"
>
Accessible
</span>
<span
class="rounded-full border border-white/[0.1] bg-white/[0.05] px-3 py-1 text-xs font-medium text-gray-300"
>
Themeable
</span>
</div>
<a
href="https://ui.classroomio.dev"
target="_blank"
rel="noopener noreferrer"
class="inline-flex items-center gap-2 rounded-lg border border-white/[0.15] bg-white/[0.06] px-5 py-2.5 text-sm font-medium text-white no-underline transition-all duration-200 hover:border-blue-500/40 hover:bg-white/[0.1]"
>
Explore the design system
<span class="text-blue-400">→</span>
</a>
</div>
<div class="relative">
<div class="relative overflow-hidden rounded-2xl border border-white/[0.08] bg-white/[0.03] p-6">
<BorderBeam colorFrom="#3b82f6" colorTo="#0233BD" size={200} duration={8} />
<div class="mb-5 flex items-center gap-2">
<div class="h-3 w-3 rounded-full bg-white/[0.15]"></div>
<div class="h-3 w-3 rounded-full bg-white/[0.1]"></div>
<div class="h-3 w-3 rounded-full bg-white/[0.1]"></div>
<span class="ml-2 text-xs text-gray-600">@cio/ui</span>
</div>
<!-- Mini component showcase -->
<div class="space-y-4">
<!-- Row 1: Buttons -->
<div class="flex flex-wrap items-center gap-2">
<div class="rounded-md bg-blue-700 px-3 py-1.5 text-xs font-medium text-white">Primary</div>
<div class="rounded-md border border-white/[0.15] px-3 py-1.5 text-xs font-medium text-gray-300">
Outline
</div>
<div class="rounded-md bg-white/[0.08] px-3 py-1.5 text-xs font-medium text-gray-400">Ghost</div>
<div class="rounded-full bg-blue-500/15 px-2.5 py-0.5 text-[10px] font-medium text-blue-400">
Badge
</div>
</div>
<!-- Row 2: Input + Select mock -->
<div class="flex gap-2">
<div
class="flex-1 rounded-md border border-white/[0.1] bg-white/[0.04] px-3 py-2 text-xs text-gray-500"
>
Search courses...
</div>
<div
class="flex items-center gap-1 rounded-md border border-white/[0.1] bg-white/[0.04] px-3 py-2 text-xs text-gray-500"
>
Select
<svg
class="h-3 w-3 text-gray-600"
viewBox="0 0 12 12"
fill="none"
stroke="currentColor"
stroke-width="1.5"
>
<path d="M3 4.5L6 7.5L9 4.5" />
</svg>
</div>
</div>
<!-- Row 3: Card preview -->
<div class="rounded-lg border border-white/[0.08] bg-white/[0.03] p-3">
<div class="mb-2 flex items-center gap-2">
<div class="h-6 w-6 rounded-full bg-blue-700/30"></div>
<div>
<div class="text-xs font-medium text-gray-300">Card Component</div>
<div class="text-[10px] text-gray-600">Composable header, body, footer</div>
</div>
</div>
<div class="flex gap-1.5">
<div class="h-1 flex-1 rounded-full bg-blue-700/30"></div>
<div class="h-1 w-8 rounded-full bg-white/[0.06]"></div>
</div>
</div>
<!-- Row 4: Toggle + Switch + Checkbox -->
<div class="flex items-center gap-4">
<div class="flex items-center gap-1.5">
<div class="h-4 w-7 rounded-full bg-blue-700 p-0.5">
<div class="h-3 w-3 translate-x-3 rounded-full bg-white"></div>
</div>
<span class="text-[10px] text-gray-500">Switch</span>
</div>
<div class="flex items-center gap-1.5">
<div class="flex h-4 w-4 items-center justify-center rounded border border-blue-700 bg-blue-700">
<svg class="h-2.5 w-2.5 text-white" viewBox="0 0 12 12" fill="none">
<path d="M2.5 6L5 8.5L9.5 3.5" stroke="currentColor" stroke-width="1.5" />
</svg>
</div>
<span class="text-[10px] text-gray-500">Checkbox</span>
</div>
<div class="flex items-center gap-1.5">
<div class="flex h-4 w-4 items-center justify-center rounded-full border border-blue-700">
<div class="h-2 w-2 rounded-full bg-blue-700"></div>
</div>
<span class="text-[10px] text-gray-500">Radio</span>
</div>
</div>
</div>
</div>
<!-- Component tags floating below -->
<div class="mt-4 flex flex-wrap items-center gap-1.5">
{#each uiComponents as comp, i}
<BlurFade delay={0.04 * i} once>
<span
class="rounded-md border px-2 py-0.5 text-[10px] font-medium transition-colors duration-200 {comp.category ===
'Atom'
? 'border-blue-500/20 bg-blue-500/10 text-blue-400'
: 'border-purple-500/20 bg-purple-500/10 text-purple-400'}"
>
{comp.label}
</span>
</BlurFade>
{/each}
<BlurFade delay={0.04 * uiComponents.length} once>
<span
class="rounded-md border border-white/[0.08] bg-white/[0.04] px-2 py-0.5 text-[10px] font-medium text-gray-500"
>
+48 more
</span>
</BlurFade>
</div>
</div>
</div>
</BlurFade>
</div>
</div>
</section>
@@ -0,0 +1,71 @@
<script>
import { BlurFade } from '@cio/ui/custom/animation/blurfade';
const features = [
{
icon: '🎨',
title: 'Full Theming',
description:
"Match your brand exactly. Custom colors, fonts, logos, and layouts. Your learners will never know it's ClassroomIO under the hood.",
tags: ['Custom colors', 'Logo upload', 'Font control']
},
{
icon: '🌐',
title: 'Custom Domain',
description:
'Serve your LMS from learn.yourcompany.com. Full SSL, zero ClassroomIO branding. Just your platform, your way.',
tags: ['SSL included', 'White label', 'DNS setup guide']
},
{
icon: '⚙️',
title: 'Deep LMS Customization',
description:
'Modern codebase means any developer can go in and change anything. No Moodle plugin archaeology. No undocumented hacks.',
tags: ['Modern stack', 'Clean codebase', 'Extensible']
},
{
icon: '📊',
title: 'Manager Dashboards',
description:
'See exactly where your team stands. Completion rates, overdue courses, certificate expiry dates, all in one view and exportable to CSV.',
tags: ['Team views', 'CSV export', 'Audit logs']
}
];
</script>
<section class="bg-gray-50 px-6 py-16 lg:px-12 lg:py-24">
<div class="mx-auto max-w-[1100px]">
<BlurFade once>
<div class="mb-3.5 text-xs font-medium tracking-widest text-blue-700 uppercase">Make it yours</div>
<h2 class="mb-4 text-[clamp(2rem,3vw,2.8rem)] leading-[1.15] font-medium tracking-tight">
Your brand.<br />Your domain. Your rules.
</h2>
<p class="mb-14 max-w-[520px] text-base leading-relaxed text-gray-500 lg:text-lg">
ClassroomIO bends to fit your organization, not the other way around.
</p>
</BlurFade>
<div class="grid grid-cols-1 gap-6 md:grid-cols-2">
{#each features as feature, i}
<BlurFade delay={0.1 * i} once>
<div class="rounded-2xl border border-gray-200 bg-white p-8 lg:p-9">
<div class="mb-5 flex h-12 w-12 items-center justify-center rounded-xl bg-blue-50 text-2xl">
{feature.icon}
</div>
<h3 class="mb-2.5 text-xl font-medium tracking-tight">{feature.title}</h3>
<p class="mb-5 text-sm leading-relaxed text-gray-500">{feature.description}</p>
<div class="flex flex-wrap gap-2">
{#each feature.tags as tag}
<span
class="rounded-full border border-gray-200 bg-gray-50 px-2.5 py-1 text-xs font-medium text-gray-500"
>
{tag}
</span>
{/each}
</div>
</div>
</BlurFade>
{/each}
</div>
</div>
</section>
@@ -0,0 +1,24 @@
<section class="bg-gray-50 px-6 py-16 text-center lg:px-12 lg:py-24">
<h2 class="mb-4 text-[clamp(2rem,3.5vw,3rem)] font-bold tracking-tight">
Ready to replace Moodle<br />with something you'll <em class="text-blue-700 italic">actually enjoy?</em>
</h2>
<p class="mx-auto mb-9 max-w-[480px] text-base text-gray-500 lg:text-lg">
Get up and running in an afternoon. No vendor calls, no implementation fees, no surprises.
</p>
<div class="mb-9 flex flex-wrap justify-center gap-3.5">
<a
href="/signup"
class="inline-flex items-center gap-2 rounded-lg bg-gray-950 px-7 py-3.5 text-sm font-semibold text-white no-underline transition-all duration-200 hover:-translate-y-0.5 hover:bg-blue-700 lg:text-base"
>
Get Started Free →
</a>
<button
data-cal-link="classroomio/demo"
data-cal-config="'layout':'month_view'"
class="cursor-pointer rounded-lg border-[1.5px] border-gray-200 bg-transparent px-7 py-3.5 text-sm font-medium text-gray-950 transition-all duration-200 hover:border-gray-950 lg:text-base"
>
Book a Demo
</button>
</div>
<div class="text-sm text-gray-500">Open source · Self-hosted · No credit card required</div>
</section>
+7 -14
View File
@@ -11,7 +11,7 @@
<p class="mr-2 mb-5 text-sm leading-7 tracking-wide text-gray-600 lg:text-base lg:leading-7">
The Open Source Learning Management System for Companies
<br />
ClassroomIO is the easiest way to grow your teaching business.
Nail your compliance training and your certification program.
</p>
<!-- <a
href="https://www.producthunt.com/posts/classroomio?utm_source=badge-featured&utm_medium=badge&utm_souce=badge-classroomio"
@@ -50,19 +50,16 @@
<p class="mb-3 text-base leading-6 font-semibold text-gray-900 lg:mb-10 lg:text-base">Product</p>
<ul class="space-y-2 lg:space-y-4">
<li class="text-sm leading-6 tracking-wide text-gray-600 hover:text-gray-900 lg:text-base">
<a href="/#coursemanagement"> Course Management </a>
<a href="/#features"> Certifications </a>
</li>
<li class="text-sm leading-6 tracking-wide text-gray-600 hover:text-gray-900 lg:text-base">
<a href="/#customization"> Customizations </a>
<a href="/#ai"> AI Content </a>
</li>
<li class="text-sm leading-6 tracking-wide text-gray-600 hover:text-gray-900 lg:text-base">
<a href="/#collaboration"> Forum </a>
<a href="/#deploy"> Deploy </a>
</li>
<li class="text-sm leading-6 tracking-wide text-gray-600 hover:text-gray-900 lg:text-base">
<a href="/#ai"> AI Lesson Planner </a>
</li>
<li class="text-sm leading-6 tracking-wide text-gray-600 hover:text-gray-900 lg:text-base">
<a href="/#student-dashboard"> Student Dashboard </a>
<a href="/#testimonial"> Testimonials </a>
</li>
</ul>
</div>
@@ -113,17 +110,13 @@
<a href="mailto:[email protected]" target="_blank"> Support </a>
</li>
<li class="text-sm leading-6 tracking-wide text-gray-600 hover:text-gray-900 lg:text-base">
<a href="https://app.enzuzo.com/policies/privacy/958fc978-5477-11ee-a03b-7b111830c594" target="_blank">
Privacy policy
</a>
<a href="/privacy"> Privacy policy </a>
</li>
<li class="text-sm leading-6 tracking-wide text-gray-600 hover:text-gray-900 lg:text-base">
<a target="_blank" href="https://classroomio.com/docs/quickstart/signup"> Getting Started </a>
</li>
<li class="text-sm leading-6 tracking-wide text-gray-600 hover:text-gray-900 lg:text-base">
<a href="https://app.enzuzo.com/policies/tos/958fc978-5477-11ee-a03b-7b111830c594" target="_blank">
Terms of use
</a>
<a href="/tos"> Terms of use </a>
</li>
</ul>
</div>
+117 -200
View File
@@ -1,220 +1,137 @@
<script lang="ts">
import { onMount, onDestroy } from 'svelte';
import { fly } from 'svelte/transition';
import { sineInOut } from 'svelte/easing';
import { PUBLIC_ENABLE_USERS_COMPANIES } from '$env/static/public';
import { Button } from '@cio/ui/base/button';
const names = [
{ label: 'Audience', color: '#3ADFEC' },
{ label: 'Employees', color: '#BF0696' },
{ label: 'Customers', color: '#0233BD' },
{ label: 'Students', color: '#9747FF' }
];
let animate = $state(false);
let titleIndex = $state(0);
let timeout: NodeJS.Timeout;
onMount(() => {
setTimeout(() => {
animate = true;
}, 70);
timeout = setInterval(() => {
const nextIndex = titleIndex + 1;
titleIndex = names[nextIndex] ? nextIndex : 0;
}, 3000);
});
onDestroy(() => {
clearTimeout(timeout);
});
<script>
import { BlurFade } from '@cio/ui/custom/animation/blurfade';
import { BorderBeam } from '@cio/ui/custom/animation/border-beam';
import { Badge } from '@cio/ui/base/badge';
</script>
<div class="hero-bg relative h-full w-full border-b-2 bg-[#F5F8FE] pt-18 text-center">
<div class="w-full pt-24">
<div class="mb-10 ml-[5%] flex w-full items-center justify-start lg:ml-0 lg:justify-center">
<a
target="_blank"
rel="noopener noreferrer nofollow"
href="/github"
style="color: rgb(75, 85, 99);"
class="rounded-full border-2 border-[#C2D2FF] bg-[#DCE5FF] px-4 py-1 text-sm font-medium text-[#4B5563] hover:underline"
>We are <span class="ui:text-primary">100%</span> open source</a
>
</div>
<section class="px-6 pt-32 pb-16 lg:px-12 lg:pt-40 lg:pb-24">
<div class="mx-auto grid max-w-[1100px] grid-cols-1 items-center gap-12 lg:grid-cols-2 lg:gap-20">
<div>
<BlurFade delay={0} once>
<a href="/blog/learn-from-the-best" class="mb-7 inline-block">
<Badge variant="secondary" class="gap-2! px-3.5! py-1.5! text-xs! underline!">
<span class="relative flex h-2 w-2">
<span class="absolute inline-flex h-full w-full animate-ping rounded-full bg-green-400 opacity-75"></span>
<span class="relative inline-flex h-2 w-2 rounded-full bg-green-500"></span>
</span>
Introducing ClassroomIO Version 2 →
</Badge>
</a>
</BlurFade>
<div class="absolute top-[10%] left-[5%] hidden w-[90%] justify-between lg:flex">
{#if animate}
<div
class="relative rotate-12 transition-all hover:scale-110"
transition:fly={{ y: 100, delay: 0, easing: sineInOut }}
>
<BlurFade delay={0.1} once>
<h1 class="mb-6 text-[clamp(2.4rem,4vw,3.4rem)] leading-[1.12] font-medium tracking-tight text-gray-950">
Nail your compliance training and your
<em class="text-blue-700 not-italic">certification program.</em>
</h1>
</BlurFade>
<BlurFade delay={0.2} once>
<p class="mb-9 max-w-[480px] text-base leading-relaxed text-gray-500 lg:text-lg">
ClassroomIO is the open source LMS built for compliance-driven teams. Run your certification programs, track
completions, and prove training happened. No Moodle headaches.
</p>
</BlurFade>
<BlurFade delay={0.3} once>
<div class="flex flex-wrap items-center gap-3.5">
<a
href="/#collaboration"
class="rounded-[4px] border-[1.5px] border-[#3ADFEC] bg-white px-6 py-2 text-lg font-bold text-[#3ADFEC]"
>Collaboration</a
href="/signup"
class="inline-flex items-center gap-2 rounded-lg bg-gray-950 px-7 py-3.5 text-sm font-medium text-white no-underline transition-all duration-200 hover:-translate-y-0.5 hover:bg-blue-700 lg:text-base"
>
<svg
class="absolute -right-1 -bottom-2.5"
width="11"
height="11"
viewBox="0 0 11 11"
fill="none"
xmlns="http://www.w3.org/2000/svg"
Get Started Free →
</a>
<button
data-cal-link="classroomio/demo"
data-cal-config="'layout':'month_view'"
class="cursor-pointer rounded-lg border-[1.5px] border-gray-200 bg-transparent px-7 py-3.5 text-sm font-medium text-gray-950 transition-all duration-200 hover:border-gray-950 lg:text-base"
>
<rect width="10.9223" height="10.9223" fill="#3ADFEC" />
</svg>
Book a Demo
</button>
</div>
</BlurFade>
<div
class="relative -rotate-12 transition-all hover:scale-110"
transition:fly={{ x: 100, delay: 50, easing: sineInOut }}
>
<a
href="/github"
target="_blank"
class="rounded-[4px] border-[1.5px] border-[#BF0696] bg-white px-6 py-2 text-lg font-bold text-[#BF0696]"
>Open Source</a
>
<svg
class="absolute -right-1 -bottom-2.5"
width="11"
height="11"
viewBox="0 0 11 11"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect width="10.9223" height="10.9223" fill="#BF0696" />
</svg>
</div>
{/if}
</div>
<div class="w-full">
<div class="ml-6 text-left text-2xl font-semibold text-slate-900 lg:text-center lg:text-6xl">
<span>Educate Your</span>
<div class="mb-2 flex flex-wrap items-center justify-center lg:gap-3">
<span
class="relative mt-1 mb-0 inline-block h-[40px] w-full overflow-hidden md:mt-0 md:h-[50px] lg:-mb-4 lg:h-[75px] lg:w-[48%] lg:text-center"
>
{#key titleIndex}
<span
class="absolute right-[unset] left-0 w-full lg:right-0 lg:left-[unset]"
style="color: {names[titleIndex].color}"
transition:fly={{ y: 100, delay: 0, easing: sineInOut }}
>
<span class="m-auto w-full text-center">
{names[titleIndex].label}
</span>
</span>
{/key}
<BlurFade delay={0.4} once>
<div class="mt-7 flex flex-wrap items-center gap-5 text-xs text-gray-500">
<span class="flex items-center gap-1.5">
<span class="font-medium text-blue-700">✓</span> Open source
</span>
<span class="flex items-center gap-1.5">
<span class="font-medium text-blue-700">✓</span> Self-hosted
</span>
<span class="flex items-center gap-1.5">
<span class="font-medium text-blue-700">✓</span> No per-seat fees
</span>
</div>
<span>from one Platform</span>
</div>
<p class="ui:text-muted-foreground mx-auto mt-10 px-4 md:text-lg lg:mt-6 lg:w-[42%] lg:p-0">
ClassroomIO is an open source learning management system for companies. We give you a suite of tools to help you
achieve your training, onboarding and certification goals.
</p>
</BlurFade>
</div>
<div class="absolute top-[30%] left-[5%] hidden w-[90%] justify-between lg:flex">
{#if animate}
<div
class="relative -rotate-12 transition-all hover:scale-110"
transition:fly={{ x: -100, delay: 100, easing: sineInOut }}
>
<a
href="/#customization"
class="rounded-[4px] border-[1.5px] border-[#0233BD] bg-white px-6 py-2 text-lg font-bold text-[#0233BD]"
>
Customizable LMS
</a>
<svg
class="absolute -right-1 -bottom-2.5"
width="11"
height="11"
viewBox="0 0 11 11"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect width="10.9223" height="10.9223" fill="#0233BD" />
</svg>
<!-- Hero Visual -->
<BlurFade delay={0.2} once>
<div class="relative overflow-hidden rounded-2xl border border-gray-200 bg-gray-50 shadow-2xl/5">
<BorderBeam size={250} duration={12} colorFrom="#0233BD" colorTo="#6b8fff" delay={1} />
<div class="flex items-center gap-2 border-b border-gray-200 bg-white px-4 py-3.5">
<div class="h-2.5 w-2.5 rounded-full bg-red-400"></div>
<div class="h-2.5 w-2.5 rounded-full bg-yellow-400"></div>
<div class="h-2.5 w-2.5 rounded-full bg-green-500"></div>
</div>
<div
class="relative rotate-12 transition-all hover:scale-110"
transition:fly={{ y: 100, delay: 150, easing: sineInOut }}
>
<a
href="/#ai"
class="rounded-[4px] border-[1.5px] border-[#9747FF] bg-white px-6 py-2 text-lg font-bold text-[#9747FF]"
>AI Support</a
>
<div class="p-6">
<div class="mb-3.5 text-xs font-medium tracking-wider text-gray-500 uppercase">Team Progress - This Week</div>
<svg
class="absolute -right-1 -bottom-2.5"
width="11"
height="11"
viewBox="0 0 11 11"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect width="10.9223" height="10.9223" fill="#9747FF" />
</svg>
</div>
{/if}
</div>
<div class="mb-3 flex items-center gap-3.5 rounded-xl border border-gray-200 bg-white p-4">
<div class="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-blue-50 text-lg">📋</div>
<div class="min-w-0 flex-1">
<div class="mb-1 text-sm font-medium">Annual Compliance Training</div>
<div class="h-1 overflow-hidden rounded-full bg-gray-200">
<div class="h-full rounded-full bg-blue-700" style="width: 85%"></div>
</div>
</div>
<div
class="shrink-0 rounded-full bg-blue-50 px-2 py-0.5 text-[0.7rem] font-medium whitespace-nowrap text-blue-700"
>
85%
</div>
</div>
<div class="my-10 flex flex-col items-center justify-center gap-4 md:flex-row">
<Button variant="outline" href="/demo" target="_blank" rel="noopener noreferrer nofollow">Book a demo</Button>
<Button href="/signup" target="_blank" rel="noopener noreferrer nofollow">Sign Up for Free</Button>
<!-- <a
class="font-medium lg:font-semibold text-sm md:text-base w-11/12 md:w-fit border px-6 py-3 lg:px-10 lg:py-5 rounded-md"
href="/github"
target="_blank"
rel="noopener noreferrer nofollow"
>
View on Github
</a> -->
</div>
<div class="mb-3 flex items-center gap-3.5 rounded-xl border border-gray-200 bg-white p-4">
<div class="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-green-50 text-lg">🛡️</div>
<div class="min-w-0 flex-1">
<div class="mb-1 text-sm font-medium">Security & Compliance</div>
<div class="h-1 overflow-hidden rounded-full bg-gray-200">
<div class="h-full rounded-full bg-green-500" style="width: 100%"></div>
</div>
</div>
<div
class="shrink-0 rounded-full bg-green-50 px-2 py-0.5 text-[0.7rem] font-medium whitespace-nowrap text-green-600"
>
✓ Done
</div>
</div>
<!-- <div class="relative my-5 md:my-10">
<img
width="710"
height="710"
src="./cio-hero.webp"
alt="hero section with dark vs light mode"
class=""
/>
</div> -->
<div style="position: relative; padding-bottom: calc(50% + 42px);" class="mx-auto w-[85%] lg:w-[70%]">
<iframe
title="ClassroomIO Live Demo"
src="https://app.supademo.com/embed/cluw8chyy06nhq2s9m697a680"
allow="clipboard-write"
frameborder="0"
webkitallowfullscreen="true"
mozallowfullscreen="true"
allowfullscreen
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"
></iframe>
</div>
<div class="mb-3 flex items-center gap-3.5 rounded-xl border border-gray-200 bg-white p-4">
<div class="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-orange-50 text-lg">🎯</div>
<div class="min-w-0 flex-1">
<div class="mb-1 text-sm font-medium">Product Certification</div>
<div class="h-1 overflow-hidden rounded-full bg-gray-200">
<div class="h-full rounded-full bg-blue-700" style="width: 42%"></div>
</div>
</div>
<div
class="shrink-0 rounded-full bg-blue-50 px-2 py-0.5 text-[0.7rem] font-medium whitespace-nowrap text-blue-700"
>
42%
</div>
</div>
{#if PUBLIC_ENABLE_USERS_COMPANIES}
<div class="mb-[10%] px-[15%]">
<h2 class="text-base font-semibold text-gray-900 lg:text-xl">Used at</h2>
<div class="flex w-full flex-row flex-wrap items-center justify-between gap-5 py-[5%]">
<img loading="lazy" src="/hero-1.svg" alt="" class="w-[30%] lg:w-[13%]" />
<img loading="lazy" src="/hero-2.svg" alt="" class="w-[30%] lg:w-[13%]" />
<img loading="lazy" src="/hero-3.svg" alt="" class="w-[30%] lg:w-[13%]" />
<img loading="lazy" src="/hero-4.svg" alt="" class="w-[30%] lg:w-[13%]" />
<img loading="lazy" src="/hero-5.svg" alt="" class="w-[30%] lg:w-[13%]" />
<div class="mt-4 flex items-center gap-3 rounded-lg bg-blue-50 p-4">
<span class="text-xl">🏆</span>
<div>
<div class="text-sm font-medium">3 certificates issued today</div>
<div class="text-xs text-gray-500">Sarah, Marcus & Priya completed their certs</div>
</div>
</div>
</div>
</div>
{/if}
</BlurFade>
</div>
</div>
</section>
+9
View File
@@ -1,17 +1,26 @@
// UI Components - Named exports for easy importing
export { default as AiSection } from './ai-section.svelte';
export { default as AutomateSection } from './automate-section.svelte';
export { default as BlogListItem } from './blog-list-item.svelte';
export { default as CertSection } from './cert-section.svelte';
export { default as CoreFeatureSection } from './core-feature-section.svelte';
export { default as CoreFeatures } from './core-features.svelte';
export { default as CustomImg } from './custom-img.svelte';
export { default as DeploySection } from './deploy-section.svelte';
export { default as EnterpriseSection } from './enterprise-section.svelte';
export { default as Faq } from './faq.svelte';
export { default as FeaturesSection } from './features-section.svelte';
export { default as Footer } from './footer.svelte';
export { default as FooterCta } from './footer-cta.svelte';
export { default as Hero } from './hero.svelte';
export { default as LearnerSection } from './learner-section.svelte';
export { default as Modal } from './modal.svelte';
export { default as MoreFeatures } from './more-features.svelte';
export { default as Navigation } from './navigation.svelte';
export { default as NotFound } from './not-found.svelte';
export { default as PageHeader } from './page-header.svelte';
export { default as PageSignupCTA } from './page-signup-cta.svelte';
export { default as QuestionTypes } from './question-types.svelte';
export { default as SenjaEmbed } from './senja-embed.svelte';
export { default as StudentDashboard } from './student-dashboard.svelte';
export { default as Success } from './success.svelte';
@@ -0,0 +1,127 @@
<script>
import { BlurFade } from '@cio/ui/custom/animation/blurfade';
import { BorderBeam } from '@cio/ui/custom/animation/border-beam';
const learnerModes = [
{
icon: '📖',
title: 'Read it',
description: 'Standard lesson view for learners who prefer reading at their own pace.'
},
{
icon: '🎧',
title: 'Listen to it',
description:
'One click and AI reads the lesson aloud. Perfect for commuters, multitaskers, and auditory learners.',
comingSoon: true
},
{
icon: '⚡',
title: 'Get the summary',
description:
'AI condenses any lesson into 5 key bullet points. Great for reviewing before an assessment or when time is short.'
}
];
const summaryItems = [
'Data privacy governs how personal information is collected, stored, and shared',
'Consent must be obtained before collecting any personal data',
'GDPR and CCPA set the global standard for data handling obligations',
'Breaches must be reported within 72 hours under most regulations',
'Employees are the most common cause of accidental data exposure'
];
</script>
<section class="bg-white px-6 py-16 lg:px-12 lg:py-24">
<div class="mx-auto max-w-[1100px]">
<div class="grid grid-cols-1 items-center gap-12 lg:grid-cols-2 lg:gap-20">
<div>
<BlurFade once>
<div class="mb-3.5 text-xs font-medium tracking-widest text-blue-700 uppercase">
Built for learners, not just admins
</div>
<h2 class="mb-4 text-[clamp(2rem,3vw,2.8rem)] leading-[1.15] font-medium tracking-tight">
Every student learns differently.<br />We support <em class="text-blue-700 italic">all of them.</em>
</h2>
<p class="mb-10 max-w-[520px] text-base leading-relaxed text-gray-500 lg:text-lg">
Most LMS platforms are built for the person running them. We built ClassroomIO for the person going through
them. Because a certification program only works if people actually retain what they learned.
</p>
</BlurFade>
<div class="flex flex-col gap-4">
{#each learnerModes as mode, i}
<BlurFade delay={0.1 * i} once>
<div class="flex items-start gap-3.5">
<div class="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-blue-50 text-lg">
{mode.icon}
</div>
<div>
<h4 class="mb-1 text-sm font-medium">
{mode.title}
{#if mode.comingSoon}
<span
class="ml-1 rounded-full bg-blue-700 px-1.5 py-0.5 align-middle text-[0.6rem] tracking-wide text-white uppercase"
>Soon</span
>
{/if}
</h4>
<p class="text-sm leading-relaxed text-gray-500">{mode.description}</p>
</div>
</div>
</BlurFade>
{/each}
</div>
</div>
<!-- Lesson Mock UI -->
<BlurFade delay={0.2} once>
<div class="relative overflow-hidden rounded-2xl border border-gray-200 bg-gray-50 shadow-2xl/5">
<BorderBeam size={200} duration={14} colorFrom="#0233BD" colorTo="#93c5fd" />
<div class="flex items-center justify-between border-b border-gray-200 bg-white px-5 py-4">
<div class="text-sm font-medium">Data Privacy & Compliance</div>
<div class="rounded-full border border-gray-200 bg-gray-50 px-2.5 py-0.5 text-xs text-gray-500">
Lesson 3 of 8
</div>
</div>
<div class="p-6">
<div class="mb-5 text-sm leading-relaxed text-gray-500">
Data privacy refers to the proper handling, processing, and storage of personal information. Organizations
must ensure that customer data is collected with consent, stored securely, and never shared without
authorization...
</div>
<div class="mb-5 flex flex-wrap gap-2.5">
<button
class="flex items-center gap-1.5 rounded-lg border-none bg-gray-950 px-4 py-2 text-xs font-medium text-white"
>
🎧 Listen
<span
class="ml-1 rounded-full bg-blue-700 px-1.5 py-0.5 text-[0.6rem] tracking-wide text-white uppercase"
>Soon</span
>
</button>
<button
class="flex items-center gap-1.5 rounded-lg border-[1.5px] border-gray-200 bg-white px-4 py-2 text-xs font-medium text-gray-950"
>
⚡ Summarize
</button>
</div>
<div class="rounded-xl border border-gray-200 bg-white p-4">
<div class="mb-3 text-xs font-medium tracking-wider text-blue-700 uppercase">AI Summary</div>
<div class="flex flex-col gap-2.5">
{#each summaryItems as item}
<div class="flex gap-2.5 text-xs leading-relaxed">
<span class="shrink-0 font-medium text-blue-700">•</span>
<span>{item}</span>
</div>
{/each}
</div>
</div>
</div>
</div>
</BlurFade>
</div>
</div>
</section>
@@ -1,4 +1,6 @@
<script>
import { DotPattern } from '@cio/ui/custom/animation/dot-pattern';
/**
* @typedef {Object} Props
* @property {string} [className]
@@ -9,6 +11,9 @@
let { className = '', children } = $props();
</script>
<header class="hero-bg w-full border-b border-slate-100 pt-32 pb-16 lg:min-h-[20rem] {className}">
{@render children?.()}
<header class="relative w-full overflow-hidden border-b border-slate-100 pt-32 pb-16 lg:min-h-[20rem]">
<DotPattern fillColor="rgb(2 51 189 / 0.25)" class="absolute inset-0 h-full w-full" />
<div class="relative z-10 {className}">
{@render children?.()}
</div>
</header>
@@ -0,0 +1,23 @@
<section class="bg-gray-50 py-16 lg:py-24">
<div class="mx-auto mb-10 max-w-[1100px] px-6 text-center lg:mb-14 lg:px-12">
<div class="mb-3.5 text-xs font-medium tracking-widest text-blue-700 uppercase">Assessments & Exams</div>
<h2 class="mb-4 text-[clamp(2rem,3vw,2.8rem)] leading-[1.15] font-medium tracking-tight">
Exams that go beyond multiple choice.
</h2>
<p class="mx-auto max-w-[560px] text-base leading-relaxed text-gray-500 lg:text-lg">
Most LMS platforms give you multiple choice and call it a day. ClassroomIO supports the full range so your exams
actually test what matters.
</p>
</div>
<div class="flex justify-center lg:px-12">
<div data-cio-widget="question-type-picker" class="w-full max-w-[900px]"></div>
</div>
</section>
<svelte:head>
<script
type="module"
src="https://assets.cdn.clsrio.com/embeds/question-type-picker/question-type-picker.js"
></script>
</svelte:head>
@@ -1,19 +1,19 @@
<script>
import { SenjaEmbed } from '$lib/components';
import { Button } from '@cio/ui/base/button';
</script>
<section id="testimonial" class="flex flex-col items-center space-y-2 px-3 py-[5%] lg:px-0">
<h1 class="mx-auto my-0 flex flex-col items-center gap-4 text-3xl leading-normal font-normal md:text-4xl lg:text-5xl">
Hear from Happy ClassroomIO Users
</h1>
<section id="testimonial" class="bg-white px-6 py-16 lg:px-12 lg:py-24">
<div class="mx-auto max-w-[1100px] text-center">
<div class="mb-3.5 text-xs font-bold tracking-widest text-blue-700 uppercase">Testimonials</div>
<h2 class="mb-4 text-[clamp(2rem,3vw,2.8rem)] leading-[1.15] font-bold tracking-tight">
Hear from happy ClassroomIO users
</h2>
<p class="mx-auto mb-10 max-w-[520px] text-base leading-relaxed text-gray-500 lg:text-lg">
See what excites them about building and managing training programs with ClassroomIO.
</p>
<p class="ui:text-muted-foreground mx-auto px-4 text-center text-base leading-6 tracking-wide lg:w-2/4 lg:p-0">
See what excites them about building and managing bootcamps with ClassroomIO.
</p>
<Button href="/signup" target="_blank" rel="noopener noreferrer nofollow">Sign Up for Free</Button>
<div class="relative my-5 w-[85%] md:my-10 lg:w-[70%]">
<SenjaEmbed id="3e847d7a-13d3-483e-8a71-5b35273dcc6c" />
<div class="relative mx-auto w-full">
<SenjaEmbed id="3e847d7a-13d3-483e-8a71-5b35273dcc6c" />
</div>
</div>
</section>
@@ -1,4 +1,6 @@
<script>
import { DotPattern } from '@cio/ui/custom/animation/dot-pattern';
/**
* @typedef {Object} Props
* @property {string} [className]
@@ -9,6 +11,9 @@
let { className = '', children } = $props();
</script>
<header class="tools-hero-bg py-24 text-center {className} border-b border-slate-100 bg-white">
{@render children?.()}
<header class="relative py-24 text-center {className} overflow-hidden border-b border-slate-100 bg-white">
<DotPattern fillColor="rgb(2 51 189 / 0.25)" class="absolute inset-0 h-full w-full" />
<div class="relative z-10">
{@render children?.()}
</div>
</header>
@@ -6,23 +6,23 @@
const benefitDetails = [
{
icon: 'light-bulb.svg',
title: 'Increased Engagement',
description: 'Interactive courses and collaborative features keep employees motivated.'
title: 'Grow from within',
description: 'Employees who learn new skills stay longer, perform better, and take on bigger challenges.'
},
{
icon: 'learning.svg',
title: 'Streamlined Learning',
description: 'Centralized platform for all training materials and progress tracking.'
title: 'Training that sticks',
description: 'Structured courses with quizzes and certifications so your team actually retains what they learn.'
},
{
icon: 'pie-chart.svg',
title: 'Data-Driven Insights',
description: 'Gain valuable insights into employee performance and learning patterns.'
title: 'See the ROI',
description: 'Track completion rates, skill gaps, and progress across every department in real time.'
},
{
icon: 'paint-brush.svg',
title: 'Customizable Experience',
description: "Tailor the learning experience to your company's specific needs and branding."
title: 'Make it yours',
description: 'Your logo, your colors, your domain. Employees see your brand, not ours.'
}
];
@@ -30,21 +30,22 @@
{
icon: 'team-mgnt.svg',
img: 'team-mgnt2.svg',
title: 'Team management',
description: 'You can invite managers and employees to create and take trainings at scale in your organization.'
title: 'Enroll entire teams in minutes',
description:
'Invite managers and employees by department or role. Assign the right training to the right people without the back and forth.'
},
{
icon: 'colour-pallete.svg',
img: 'custom.svg',
title: 'Custom branding',
title: 'A learning platform that feels like yours',
description:
'With our customizable platform, you can set your company logo, brand color and add a custom domain to your employee LMS.'
'Set your company logo, brand colors, and custom domain. Your employees get a seamless experience that looks and feels internal.'
},
{
icon: 'cup.svg',
img: 'progress.svg',
title: 'Track employee progress',
description: 'You can track the progress of your employees and assist whoever needs help.'
title: 'Know exactly where your team stands',
description: 'See who completed what, who needs a nudge, and where the skill gaps are. All in one dashboard.'
}
];
</script>
@@ -57,19 +58,20 @@
<PageHeader
className="flex flex-col lg:items-center items-start lg:justify-center justify-start gap-y-6 lg:px-28 md:px-16 px-8"
>
<Badge class="px-4! py-2!" variant="outline">Unlock your team's potential</Badge>
<Badge class="px-4! py-2!" variant="outline">Invest in your people</Badge>
<div class="flex w-full flex-col items-start justify-start gap-y-8 lg:items-center lg:justify-center">
<div class="flex w-full max-w-7xl flex-col items-start justify-start gap-y-4 lg:items-center lg:justify-center">
<h1 class="m-0 mx-auto text-4xl text-slate-900 md:text-6xl lg:text-center">
Employee training software for
<br /><span class="relative text-blue-700">modern teams</span>
Your best investment is
<br /><span class="relative text-blue-700">your employees</span>
</h1>
<p class="text-base font-normal text-slate-700 md:text-lg lg:w-[60%] lg:text-center">
With ClassroomIO, you can keep your teams in sync with company standards as they change quickly.
Companies that invest in employee growth outperform the ones that don't. Give your team the tools to learn,
grow, and lead.
</p>
</div>
<Button href="/signup" target="_blank">Get Started for Free 🚀</Button>
<Button href="/signup" target="_blank">Start investing in your team</Button>
</div>
</PageHeader>
@@ -77,12 +79,12 @@
class="flex w-full max-w-7xl flex-col justify-center gap-x-6 gap-y-8 px-8 py-16 md:px-16 lg:flex-row lg:items-center lg:justify-between lg:px-28 lg:py-24"
>
<div class="flex w-full flex-col items-start justify-start gap-y-4 lg:w-[35%]">
<Badge variant="outline">Amazing benefits</Badge>
<Badge variant="outline">Why it matters</Badge>
<div class="flex flex-col items-start justify-start gap-y-4 md:w-full">
<h1 class="text-3xl">Unlock your team's potential</h1>
<h1 class="text-3xl">Great teams are built, not hired</h1>
<p class="text-lg leading-8 text-gray-500">
Modern teams require solutions that are easy to use and allows them move quickly.
The companies people want to work for are the ones that help them grow. Training is how you get there.
</p>
</div>
</div>
@@ -96,7 +98,7 @@
<img
class="h-[48px] w-[48px]"
src="https://assets.cdn.clsrio.com/www/employee-training/{benefits.icon}"
alt="light-bulb"
alt={benefits.title}
/>
<div class="align-start flex w-full flex-col justify-start gap-y-2">
@@ -114,15 +116,14 @@
class="flex w-full flex-col items-center justify-start gap-y-16 bg-[#F1F6FF] px-8 py-16 md:px-16 lg:px-28 lg:py-24"
>
<div class="flex w-full flex-col items-start justify-start gap-y-4 lg:items-center lg:justify-center">
<Badge class="px-4! py-2!" variant="outline">Explore our features</Badge>
<Badge class="px-4! py-2!" variant="outline">How it works</Badge>
<div
class="flex max-w-7xl flex-col items-start justify-start gap-y-4 lg:w-full lg:items-center lg:justify-center"
>
<h1 class="text-3xl">What makes us the right choice</h1>
<h1 class="text-3xl">Everything you need to grow your team</h1>
<p class="text-sm font-light text-[#334155] md:w-[80%] md:text-base lg:text-center">
Discover why we’re the perfect partner for your employee training needs. Experience innovative solutions
designed to reduce stress and enhance productivity.
From onboarding to upskilling, ClassroomIO gives you the tools to build a culture of continuous learning.
</p>
</div>
</div>
@@ -138,7 +139,7 @@
<img
class="h-[48px] w-[48px]"
src="https://assets.cdn.clsrio.com/www/employee-training/{feature.icon}"
alt="team icon"
alt={feature.title}
/>
<div class="flex flex-col items-start justify-start gap-y-4 md:w-full">
<h1 class="text-2xl">{feature.title}</h1>
@@ -155,7 +156,7 @@
<img
class="w-full lg:max-w-[380px]"
src="https://assets.cdn.clsrio.com/www/employee-training/{feature.img}"
alt="team management feature ui"
alt={feature.title}
/>
</div>
</div>
@@ -171,9 +172,10 @@
>
<div class="flex w-full flex-col items-start justify-start gap-y-4 lg:w-[40%]">
<div class="flex flex-col items-start justify-start gap-y-4 md:w-full">
<h1 class="text-2xl text-white">Did you know you can request for custom features?</h1>
<h1 class="text-2xl text-white">Need something specific for your team?</h1>
<p class="text-base leading-8 text-[#DEDEDE]">
Companies get the opportunity to request custom features from us.
We work with companies to build custom training solutions. Tell us what your team needs and we'll make it
happen.
</p>
</div>
<Button href="/demo" target="_blank" variant="outline">Talk to sales</Button>
@@ -188,9 +190,9 @@
</section>
<PageSignupCTA
header="Give your team the training they deserve"
subText="It's free to sign up and start getting value out of the product."
btnLabel="Sign me up"
header="The best time to invest in your team is now"
subText="Start for free. No credit card required."
btnLabel="Get started"
link="/signup"
demo={false}
/>
@@ -0,0 +1,29 @@
<script>
import { PageHeader } from '$lib/components';
/**
* @typedef {Object} Props
* @property {import('svelte').Snippet} [children]
*/
/** @type {Props} */
let { children } = $props();
</script>
<PageHeader className="flex flex-col items-center justify-center bg-[#F5F8FE] text-center pb-8">
<div class="mb-2 flex w-full items-center justify-center">
<span
class="rounded-full border-2 border-[#C2D2FF] bg-[#DCE5FF] px-4 py-1 text-sm font-medium text-blue-700"
style="color: rgb(75, 85, 99);"
>
Legal
</span>
</div>
<h1 class="text-4xl font-semibold text-slate-900 md:text-5xl">Privacy Policy</h1>
</PageHeader>
<section class="mx-auto w-[90%] max-w-3xl px-4 py-12 lg:w-[60%]">
<article class="prose prose-slate prose-headings:scroll-mt-24 prose-a:text-blue-700 max-w-none">
{@render children?.()}
</article>
</section>
@@ -0,0 +1,249 @@
## 1. Introduction
At ClassroomIO ("us", "we", "our" or the "Company") we value your privacy and the importance of safeguarding your data. This Privacy Policy (the "Policy") describes our privacy practices for the activities set out below. As per your rights, we inform you how we collect, store, access, and otherwise process information relating to individuals. In this Policy, personal data ("Personal Data") refers to any information that on its own, or in combination with other available information, can identify an individual.
We are committed to protecting your privacy in accordance with the highest level of privacy regulation. As such, we follow the obligations under the below regulations:
- Canada's Personal Information Protection and Electronic Documents Act (PIPEDA) and the applicable provincial legislations
- Quebec Law 25
- the EU's General Data Protection Regulation (GDPR)
- Brazil's Data Protection Legislation (LGPD)
- California's Consumer Privacy Act (CCPA) / California Privacy Rights Act (CPRA) and California Online Privacy Protection Act (CalOPPA)
- Colorado Privacy Act (CPA)
- Utah Consumer Privacy Act (UCPA)
- Connecticut Data Privacy Act (CTDPA)
- Virginia Consumer Data Protection Act (VCDPA)
- Texas Data Privacy and Security Act (TDPSA)
- Oregon Consumer Privacy Act (OCPA)
- Montana Consumer Data Privacy Act
- Delaware Personal Data Privacy Act
- Nebraska Data Privacy Law
- New Hampshire Data Privacy Act
- New Jersey Data Privacy Act
- Minnesota Consumer Data Privacy Act
- Maryland Online Consumer Protection Act
- Kentucky Consumer Data Privacy Act (KCDPA)
- Tennessee Information Protection Act (TIPA)
- The Rhode Island Data Transparency and Privacy Protection Act (RIDTPPA)
- Indiana Consumer Data Privacy Act (INCDPA)
- Iowa Consumer Data Privacy Act (ICDPA)
- South Africa's Protection of Personal Information Act (POPIA)
- Switzerland's Federal Act on Data Protection (FADP)
- Saudi Arabia's Personal Data Protection Law (PDPL)
### Scope
This policy applies to the ClassroomIO websites, domains, applications, services, and products.
This Policy does not apply to third-party applications, websites, products, services or platforms that may be accessed through (non-ClassroomIO) links that we may provide to you. These sites are owned and operated independently from us, and they have their own separate privacy and data collection practices. Any Personal Data that you provide to these websites will be governed by the third-party's own privacy policy. We cannot accept liability for the actions or policies of these independent sites, and we are not responsible for the content or privacy practices of such sites.
### Processing Activities
This Policy applies when you interact with us by doing any of the following:
- Make use of our application and services as an authorized user
- Visit any of our websites that link to this Privacy Statement
## 2. Personal Data We Collect
### What Personal Data We Collect
When you make a purchase, or attempt to make a purchase, we collect the following types of Personal Data:
This includes:
- Account Information such as your name, email address, and password
- Payment Information such as your billing address, phone number, credit card, debit card or other payment method
When you use our products and/or features, we collect the following types of Personal Data:
- Account Information such as your name, email address, and password
- Payment Information such as your billing address, phone number, credit card, debit card or other payment method
### How We Collect Your Personal Data
We collect Personal Data from the following sources:
**From you.** You may give us your Account Information, Payment Information, Financial Information, Demographic Data, Purchase Information, Content, Feedback, Product Information, by filling in forms, using our products or services, entering information online or by corresponding with us by post, phone, email or otherwise. This includes Personal Data you provide, for example, when you:
- Create an account or purchase products on our website;
- Use our products or services;
- Create content through our products or services;
- Express interest in our products or services;
- Download software and/or our mobile application;
- Subscribe to our newsletter;
- Complete a voluntary market research survey;
- Contact us with an inquiry or to report a problem (by phone, email, social media, or messaging service);
- When you log in to our website via social media;
**Automated technologies or interactions:** As you interact with our website, we may automatically collect the following types of data (all as described above): Device Data about your equipment, Usage Data about your browsing actions and patterns, and Contact Data where tasks carried out via our website remain uncompleted, such as incomplete orders or abandoned baskets. We collect this data by using cookies, server logs and other similar technologies. Please see our Cookie section (below) for further details.
**Third parties:** We may receive Personal Data about you from various third parties, including:
- Account Information and Payment Information from another individual when they purchase a gift for you on our website;
- Device and Usage Data from third parties, including analytics providers;
- Account Information and Payment Data from social media platforms when you log in to our website using such social media platforms;
- Content from communication services, including email providers and social networks, when you give us permission to access your data on such third-party services or networks;
- Account Information and Payment Data from third parties, including organizations (such as law enforcement agencies), associations and groups, who share data for the purposes of fraud prevention and detection and credit risk reduction; and
- Account Information, Payment Data, and Financial Data from providers of technical, payment and delivery services.
If you provide us, or our service providers, with any Personal Data relating to other individuals, you represent that you have the authority to do so and acknowledge that it will be used in accordance with this Policy. If you believe that your Personal Data has been provided to us improperly, or to otherwise exercise your rights relating to your Personal Data, please contact us by using the information set out in the "Contact us" section below.
### Device and Usage Data
When you visit a ClassroomIO website, we automatically collect and store information about your visit using browser cookies (files which are sent by us to your computer), or similar technology. You can instruct your browser to refuse all cookies or to indicate when a cookie is being sent. The Help Feature on most browsers will provide information on how to accept cookies, disable cookies or to notify you when receiving a new cookie. If you do not accept cookies, you may not be able to use some features of our Service and we recommend that you leave them turned on.
We also process information when you use our services and products. This information may include:
- Device IDs
- Login information
- IP Address
- Time stamps
- Authentication records
- Location information
- Time zone
### Data we collect from third parties
We may receive your Personal Data from third parties such as companies subscribing to ClassroomIO services, partners and other sources. This Personal Data is not collected by us but by a third party and is subject to the relevant third party's own separate privacy and data collection policies. We do not have any control or input on how your Personal Data is handled by third parties. As always, you have the right to review and rectify this information. If you have any questions you should first contact the relevant third party for further information about your Personal Data. Where that third party is unresponsive to your rights, you may contact the Data Protection Officer at ClassroomIO (contact details below).
Our websites and services may contain links to other websites, applications and services maintained by third parties. The information practices of such other services, or of social media networks that host our branded social media pages, are governed by third parties' privacy statements, which you should review to better understand those third parties' privacy practices.
### Purpose and Legal Basis for the Processing of Personal Data
We collect and use your Personal Data with your consent to provide, maintain, and develop our products and services and understand how to improve them.
These purposes include:
- To deliver your product or service
- To fulfill orders including electronic and non-electronic shipment
- Building a Safe and Secure Environment
- To verify or authenticate your identity; and
- Investigate and prevent security incidents such as breaches, attacks and hacks
- Providing, Developing, and Improving our Products and Services
- Deliver, maintain, debug and improve our products and services.
- Enable you to access ClassroomIO services and set up accounts.
- Provide you with technical and customer support
Where we process your Personal Data to provide a product or service, we do so because it is necessary to perform contractual obligations. All of the above processing is necessary in our legitimate interests to provide products and services and to maintain our relationship with you and to protect our business for example against fraud. Consent will be required to initiate services with you. New consent will be required if any changes are made to the type of data collected. Within our contract, if you fail to provide consent, some services may not be available to you.
### Third Party Tools
We use these third party tools and subprocessors to operate our services and store or process information where applicable:
- **Supabase** (database and authentication infrastructure for our application)
- **PostHog** (product analytics on our server and, where implemented, in our applications)
- **Umami** (privacy-focused website analytics on our marketing site)
This list may change as we update our vendors; material changes will be reflected in this Policy when practical.
### International Data Transfer and Storage
Where possible, we store and process data on servers within the general geographical region where you reside (note: this may not be within the country in which you reside). Your Personal Data may also be transferred to, and maintained on, servers residing outside of your state, province, country or other governmental jurisdiction where the data laws may differ from those in your jurisdiction. We will take appropriate steps to ensure that your Personal Data is treated securely and in accordance with this Policy as well as applicable data protection law. More information about standard contractual clauses can be found here: [https://eur-lex.europa.eu/legal-content/en/TXT/?uri=CELEX%3A32021D0914](https://eur-lex.europa.eu/legal-content/en/TXT/?uri=CELEX%3A32021D0914)
### Sharing and Disclosure
We will share your Personal Data with third parties only in the ways set out in this Policy or set out at the point when the Personal Data is collected.
### Legal Requirement
We may use or disclose your Personal Data in order to comply with a legal obligation, in connection with a request from a public or government authority, or in connection with court or tribunal proceedings, to prevent loss of life or injury, or to protect our rights or property. Where possible and practical to do so, we will tell you in advance of such disclosure.
### Service Providers and Other Third Parties
We may use a third party service provider, independent contractors, agencies, or consultants to deliver and help us improve our products and services. We may share your Personal Data with marketing agencies, database service providers, backup and disaster recovery service providers, email service providers and others but only to maintain and improve our products and services. For further information on the recipients of your Personal Data, please contact us by using the information in the "Contacting us" section below.
## 3. Cookies
### What are Cookies?
A cookie is a small file with information that your browser stores on your device. Information in this file is typically shared with the owner of the site in addition to potential partners and third parties to that business. The collection of this information may be used in the function of the site and/or to improve your experience.
### How we use cookies
To give you the best experience possible, we use the following types of cookies:
- **Preference.** We use preference cookies to help us remember the way you like to use our service.
- Some cookies are used to personalize content and present you with a tailored experience. For example, location could be used to give you services and offers in your area.
## 4. Retention & Deletion
We will only retain your Personal Data for as long as necessary for the purpose for which that data was collected and to the extent required by applicable law. When we no longer need Personal Data, we will remove it from our systems and/or take steps to anonymize it.
## 5. Merger or Acquisition
If we are involved in a merger, acquisition or asset sale, your personal information may be transferred. We will provide notice before your personal information is transferred and becomes subject to a different Privacy Policy. Under certain circumstances, we may be required to disclose your personal information if required to do so by law or in response to valid requests by public authorities (e.g. a court or a government agency).
## 6. How We Keep Your Data Safe
We have appropriate organizational safeguards and security measures in place to protect your Personal Data from being accidentally lost, used or accessed in an unauthorized way, altered or disclosed.
The communication between your browser and our website uses a secure encrypted connection wherever your Personal Data is involved.
We require any third party who is contracted to process your Personal Data on our behalf to have security measures in place to protect your data and to treat such data in accordance with the law.
In the unfortunate event of a Personal Data breach, we will notify you and any applicable regulator when we are legally required to do so.
## 7. Your Rights for Your Personal Data
Depending on your geographical location and citizenship, your rights are subject to local data privacy regulations. These rights may include:
- **Right to Access** (PIPEDA, GDPR Article 15, CCPA/CPRA, CPA, VCDPA, CTDPA, UCPA, LGPD, POPIA)
- **Right to Rectification** (PIPEDA, GDPR Article 16, CPRA, CPA, VCDPA, CTDPA, LGPD, POPIA)
- **Right to be Forgotten (right to erasure)** (GDPR Article 17, CCPA/CPRA, CPA, VCDPA, CTDPA, UCPA, LGPD, POPIA)
- **Right to Restriction of Processing** (GDPR Article 18, LGPD)
- **Right to Portability** (PIPEDA, GDPR Article 20, LGPD)
- **Right to Opt Out** (CPRA, CPA, VCDPA, CTDPA, UCPA)
- **Right to Objection** (GDPR Article 21, LGPD, POPIA)
- **Nondiscrimination and nonretaliation** (CCPA/CPRA, CPA, VCDPA, CTDPA, UCPA)
- **File an Appeal** (CPA, VCDPA, CTDPA)
- **File a Complaint** (GDPR Article 77, LGPD, POPIA)
You have the right to file an appeal based on our response to you exercising any of these rights. In the event you disagree with how we resolved the appeal, you may have the right to contact your local data protection or consumer protection authority.
If you are based in the EEA, please visit this website ([https://edpb.europa.eu/about-edpb/about-edpb/members_en](https://edpb.europa.eu/about-edpb/about-edpb/members_en)) for a list of local data protection authorities.
You have the right to learn whether we are processing your Personal Data and to request a copy of the Personal Data we are processing about you.
You have the right to have incomplete or inaccurate Personal Data that we process about you rectified.
You have the right to request that we delete Personal Data that we process about you, unless we need to retain such data in order to comply with a legal obligation or to establish, exercise or defend legal claims.
You have the right to restrict our processing of your Personal Data under certain circumstances. In this case, we will not process your Data for any purpose other than storing it.
You have the right to obtain Personal Data we hold about you, in a structured, electronic format, and to transmit such Personal Data to another data controller, where this is (a) Personal Data which you have provided to us, and (b) if we are processing that data on the basis of your consent or to perform a contract with you or the third party that subscribes to services.
You have the right to opt out of the processing of your Personal Data for purposes of: (1) Targeted advertising; (2) The sale of Personal Data; and/or (3) Profiling in furtherance of decisions that produce legal or similarly significant effects concerning you. Under CPRA, you have the right to opt out of the sharing of your Personal Data to third parties and our use and disclosure of your Sensitive Personal Data to uses necessary to provide the products and services reasonably expected by you.
Where the legal justification for our processing of your Personal Data is our legitimate interest, you have the right to object to such processing on grounds relating to your particular situation. We will abide by your request unless we have compelling legitimate grounds for processing which override your interests and rights, or if we need to continue to process the Personal Data for the establishment, exercise or defense of a legal claim.
You have the right not to be denied service or have an altered experience for exercising your rights.
If you are based in Colorado, please visit this [website](https://complaints.coag.gov/s/contact-us) to file a complaint. If you are based in Virginia, please visit this [website](https://www.oag.state.va.us/consumer-protection/index.php/file-a-complaint) to file a complaint. If you are based in Connecticut, please visit this [website](https://portal.ct.gov/AG/Common/Complaint-Form-Landing-page) to file a complaint.
### Withdrawing Consent
If you have consented to our processing of your Personal Data, you have the right to withdraw your consent at any time, free of charge, such as where you wish to opt out from marketing messages that you receive from us. If you wish to withdraw your consent, please contact us using the information found at the bottom of this page.
### How to Exercise Your Rights
You can make a request to exercise any of these rights in relation to your Personal Data by contacting our team using the contact details below.
For your own privacy and security, at our discretion, we may require you to prove your identity before providing the requested information.
## 8. Changes
We may modify this Policy at any time. If we make changes to this Policy then we will post an updated version of this Policy at this website. When using our services, you may be asked to review and accept our Privacy Policy. In this manner, we may record your acceptance and notify you of any future changes to this Policy.
## 9. Contact Us
To request a copy of your information, unsubscribe from our email list, request for your data to be deleted, or ask a question about your data privacy:
Email [[email protected]](mailto:[email protected])
Write to us at:
Data Privacy Officer of ClassroomIO
128 City Road, London, United Kingdom, EC1V 2NX
**Last updated:** April 12, 2026
@@ -1,4 +1,3 @@
import { redirect } from '@sveltejs/kit';
import { client } from '$lib/utils/posthog';
export const prerender = false;
@@ -6,8 +5,14 @@ export const prerender = false;
export const load = async ({ request }) => {
client.capture({
distinctId: request.headers.get('x-forwarded-for') || new Date().getTime().toString(),
event: 'privacy page visited'
event: 'privacy policy page visited'
});
redirect(307, 'https://app.enzuzo.com/policies/privacy/958fc978-5477-11ee-a03b-7b111830c594');
return {
pageMetaTags: {
title: 'Privacy Policy | ClassroomIO',
description:
'How ClassroomIO collects, uses, stores, and protects personal data when you use our websites and services.'
}
};
};
@@ -0,0 +1,29 @@
<script>
import { PageHeader } from '$lib/components';
/**
* @typedef {Object} Props
* @property {import('svelte').Snippet} [children]
*/
/** @type {Props} */
let { children } = $props();
</script>
<PageHeader className="flex flex-col items-center justify-center bg-[#F5F8FE] text-center pb-8">
<div class="mb-2 flex w-full items-center justify-center">
<span
class="rounded-full border-2 border-[#C2D2FF] bg-[#DCE5FF] px-4 py-1 text-sm font-medium text-blue-700"
style="color: rgb(75, 85, 99);"
>
Legal
</span>
</div>
<h1 class="text-4xl font-semibold text-slate-900 md:text-5xl">Terms of Service</h1>
</PageHeader>
<section class="mx-auto w-[90%] max-w-3xl px-4 py-12 lg:w-[60%]">
<article class="prose prose-slate prose-headings:scroll-mt-24 prose-a:text-blue-700 max-w-none">
{@render children?.()}
</article>
</section>
@@ -0,0 +1,136 @@
## Introduction
Our aim is to keep this Agreement as readable as possible, but in some cases for legal reasons, some of the language is required "legalese".
## Your Acceptance of this Agreement
These terms of service are entered into by and between You and ClassroomIO ("Company," "we," "our," or "us"). The following terms and conditions, together with any documents they expressly incorporate by reference (collectively "Terms of Service"), govern your access to and use of classroomio.com, including any content, functionality, and services offered on or through classroomio.com (the "Website").
Please read the Terms of Service carefully before you start to use the Website.
By using the Website [or by clicking to accept or agree to the Terms of Service when this option is made available to you], you accept and agree to be bound and abide by these Terms of Service and our [Privacy Policy](/privacy), incorporated herein by reference. If you do not want to agree to these Terms of Service, you must not access or use the Website.
**BY ACCESSING AND USING THIS WEBSITE, YOU:**
**ACCEPT AND AGREE TO BE BOUND AND COMPLY WITH THESE TERMS OF SERVICE; YOU REPRESENT AND WARRANT THAT YOU ARE THE LEGAL AGE OF MAJORITY UNDER APPLICABLE LAW TO FORM A BINDING CONTRACT WITH US; AND, YOU AGREE IF YOU ACCESS THE WEBSITE FROM A JURISDICTION WHERE IT IS NOT PERMITTED, YOU DO SO AT YOUR OWN RISK.**
## Updates to Terms of Service
We may revise and update these Terms of Service from time to time in our sole discretion. All changes are effective immediately when we post them and apply to all access to and use of the Website thereafter.
Continuing to use the Website following the posting of revised Terms of Service means that you accept and agree to the changes. You are expected to check this page each time you access this Website so you are aware of any changes, as they are binding on you.
## Your Responsibilities
You are required to ensure that all persons who access the Website are aware of this Agreement and comply with it. It is a condition of your use of the Website that all the information you provide on the Website is correct, current, and complete.
**YOU ARE SOLELY AND ENTIRELY RESPONSIBLE FOR YOUR USE OF THE WEBSITE AND YOUR COMPUTER, INTERNET AND DATA SECURITY.**
## Prohibited Activities
You may use the Website only for lawful purposes and in accordance with these Terms of Service. You agree not to use the Website:
- In any way that violates any applicable federal, state, local or international law or regulation (including, without limitation, any laws regarding the exports of data software to and from the U.S. or other countries).
- For the purpose of exploiting, harming, or attempting to exploit or harm minors in any way by exposing them to inappropriate content, asking for personally identifiable information or otherwise.
- To send, knowingly receive, upload, download, use, or re-use any material that does not comply with the Submission Standards set out in these Terms of Service.
- To transmit, or procure the sending of, any advertising or promotional material, including any "junk mail," "chain letter," "spam," or any other similar solicitation.
- To impersonate or attempt to impersonate the Company, a Company employee, another user, or any other persona or entity (including, without limitation, by using email addresses associated with any of the foregoing).
- To engage in any other conduct that restricts or inhibits anyone's use or enjoyment of the website, or which as determined by us, may harm the Company or users of the website, or expose them to liability.
Additionally, you agree not to:
- Use the Website in any manner that could disable, overburden, damage, or impair the site or interfere with any other party's use of the Website, including their ability to engage in real-time activities through the Website.
- Use any robot, spider, or other automatic device, process, or means to access the Website for any purpose, including monitoring or copying any of the material on the Website.
- Use any manual process to monitor or copy any of the material on the Website, or for any other purpose not expressly authorized in these Terms of Service, without our prior written consent.
- Use any device, software, or routine that interferes with the proper working of the Website.
- Introduce any viruses, Trojan horses, worms, logic bombs, or other material that is malicious or technologically harmful.
- Attempt to gain unauthorized access to, interfere with, damage, or disrupt any parts of the Website, the server on which the Website is stored, or any server, computer, or database connected to the Website.
- Attack the Website via a denial-of-service attack or a distributed denial-of-service attack.
- Otherwise attempting to interfere with the proper working of the Website.
## Intellectual Property Rights
The Website and its entire contents, features, and functionality (including but not limited to all information, software, text, displays, images, video, and audio, and the design, selection, and arrangement thereof) are owned by the Company, its licensors, or other providers of such material and are protected by United States and international copyright, trademark, patent, trade secret, and other intellectual property or proprietary rights laws.
You must not reproduce, distribute, modify, create derivative works of, publicly display, publicly perform, republish, download, store, or transmit any of the material on our Website, except as follows:
- Your computer may temporarily store copies of such material in RAM incidental to your accessing and viewing those materials.
- You may store files that are automatically cached by your Web browser for display enhancement purposes.
- You may print or download one copy of a reasonable number of pages of the Website.
- If we provide desktop, mobile or other applications for download, you may download a single copy to your computer or mobile device, provided you agree to be bound by our license terms for such applications (for example, our open source license for applicable software).
You must not:
- Modify copies of any materials from this site.
- Delete or alter any of the copyright, trademark, or other proprietary rights notices from copies of materials from this site.
If you print, copy, modify, download, or otherwise use or provide any other person with access to any part of the Website in breach of the Terms of Service, your right to use the Website will stop immediately and you must, at our option, return or destroy any copies of the materials you have made. No right, title, or interest in or to the Website or any content on the Website is transferred to you, and all rights not expressly granted are reserved by the Company. Any use of the Website not expressly permitted by these Terms of Service is a breach of these Terms of Service and may violate copyright, trademark, and other laws.
## Our Rights
We have the right, without provision of notice to:
- Take appropriate legal action, including, without limitation, referral to or cooperation with law enforcement or regulatory authorities, or notifying the harmed party of any illegal or unauthorized use of the Website; and
- Terminate or suspend your access to all or part of the Website for any or no reason, including, without limitation, any violation of these Terms of Service.
**YOU WAIVE AND HOLD HARMLESS COMPANY AND ITS PARENT, SUBSIDIARIES, AFFILIATES, AND THEIR RESPECTIVE DIRECTORS, OFFICERS, EMPLOYEES, AGENTS, SERVICE PROVIDERS, CONTRACTORS, LICENSORS, LICENSEES, SUPPLIERS, AND SUCCESSORS FROM ANY AND ALL CLAIMS RESULTING FROM ANY ACTION TAKEN BY THE COMPANY AND ANY OF THE FOREGOING PARTIES RELATING TO ANY, INVESTIGATIONS BY EITHER THE COMPANY OR BY LAW ENFORCEMENT AUTHORITIES.**
## Third-Party Links and Content
For your convenience, this Website may provide links or pointers to third-party sites or third-party content. We make no representations about any other websites or third-party content that may be accessed from this Website. If you choose to access any such sites, you do so at your own risk. We have no control over the third-party content or any such third-party sites and accept no responsibility for such sites or for any loss or damage that may arise from your use of them. You are subject to any terms and conditions of such third-party sites.
## Software
By downloading our software, you acknowledge and agree to the applicable open source or end user license terms published with that software (for example, our [LICENSE](https://github.com/classroomio/classroomio/blob/main/LICENSE) for the ClassroomIO project where applicable). Those terms will govern your use of the software.
## Payment and Fees
You may be required to purchase or pay a fee to access our services. We accept payment methods as shown on the Website at the time of purchase. However, Company does not guarantee the availability of any payment method at any moment and Company may add, remove or suspend any payment method temporarily or permanently at Company's sole discretion. You agree to provide current, complete, and accurate purchase and account information for all purchases made via the Website and to promptly update account and payment information, including email address, payment method, and payment card expiration date, in order to complete your purchases and contact you as needed. Sales tax will be added to the price of purchases as deemed required by us. We may change prices at any time. All payments shall be in the currency advertised on the website.
You agree to pay all charges or fees at the prices then in effect for your purchases, and you authorize us to charge your chosen payment provider for any such amounts upon making your purchase.
We reserve the right to correct any errors or mistakes in pricing, even if we have already requested or received payment. We also reserve the right to refuse any order placed through the Website.
## Disclaimers, Liability and Indemnification
YOU UNDERSTAND AND AGREE THAT YOUR USE OF THE WEBSITE, ITS CONTENT, AND ANY GOODS, DIGITAL PRODUCTS, SERVICES, INFORMATION OR ITEMS FOUND OR ATTAINED THROUGH THE WEBSITE IS AT YOUR OWN RISK. THE WEBSITE, ITS CONTENT, AND ANY GOODS, SERVICES, DIGITAL PRODUCTS, INFORMATION OR ITEMS FOUND OR ATTAINED THROUGH THE WEBSITE ARE PROVIDED ON AN "AS IS" AND "AS AVAILABLE" BASIS, WITHOUT ANY WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. THE FOREGOING DOES NOT AFFECT ANY WARRANTIES THAT CANNOT BE EXCLUDED OR LIMITED UNDER APPLICABLE LAW.
YOU ACKNOWLEDGE AND AGREE THAT COMPANY OR ITS RESPECTIVE DIRECTORS, OFFICERS, EMPLOYEES, AGENTS, SERVICE PROVIDERS, CONTRACTORS, LICENSORS, LICENSEES, SUPPLIERS, OR SUCCESSORS MAKE NO WARRANTY, REPRESENTATION, OR ENDORSEMENT WITH RESPECT TO THE COMPLETENESS, SECURITY, RELIABILITY, SUITABILITY, ACCURACY, CURRENCY, OR AVAILABILITY OF THE WEBSITE OR ITS CONTENTS OR THAT ANY GOODS, SERVICES, DIGITAL PRODUCTS, INFORMATION OR ITEMS FOUND OR ATTAINED THROUGH THE WEBSITE WILL BE ACCURATE, RELIABLE, ERROR-FREE, OR UNINTERRUPTED, THAT DEFECTS WILL BE CORRECTED, THAT OUR WEBSITE OR THE SERVER THAT MAKES IT AVAILABLE OR CONTENT ARE FREE OF VIRUSES OR OTHER HARMFUL COMPONENTS OR DESTRUCTIVE CODE.
### How We Limit Our Liability to You
EXCEPT WHERE SUCH EXCLUSIONS ARE PROHIBITED BY LAW, IN NO EVENT SHALL THE COMPANY NOR ITS RESPECTIVE DIRECTORS, OFFICERS, EMPLOYEES, AGENTS, SERVICE PROVIDERS, CONTRACTORS, LICENSORS, LICENSEES, SUPPLIERS, OR SUCCESSORS BE LIABLE UNDER THESE TERMS OF SERVICE TO YOU OR ANY THIRD-PARTY FOR ANY CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, SPECIAL, OR PUNITIVE DAMAGES WHATSOEVER, INCLUDING ANY DAMAGES FOR BUSINESS INTERRUPTION, LOSS OF USE, DATA, REVENUE OR PROFIT, COST OF CAPITAL, LOSS OF BUSINESS OPPORTUNITY, LOSS OF GOODWILL, WHETHER ARISING OUT OF BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE), ANY OTHER THEORY OF LIABILITY, OR OTHERWISE, REGARDLESS OF WHETHER SUCH DAMAGES WERE FORESEEABLE AND WHETHER OR NOT THE COMPANY WAS ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
### Indemnification
To the maximum extent permitted by applicable law, you agree to defend, indemnify, and hold harmless Company, its parent, subsidiaries, affiliates, and their respective directors, officers, employees, agents, service providers, contractors, licensors, suppliers, successors, and assigns from and against any claims, liabilities, damages, judgments, awards, losses, costs, expenses, or fees (including reasonable attorneys' fees) arising out of or relating to your breach of these Terms of Service or your use of the Website including, but not limited to, third-party sites and content, any use of the Website's content and services other than as expressly authorized in these Terms of Service or any use of any goods, digital products and information purchased from this Website.
## Privacy Policy
Your provision of personal information through the Website is governed by our Privacy Policy located at [/privacy](/privacy) (the "Privacy Policy").
## Governing Law
The Website and these Terms of Service will be governed by and construed in accordance with the laws of Nigeria and any applicable federal laws applicable therein, without giving effect to any choice or conflict of law provision, principle, or rule and notwithstanding your domicile, residence, or physical location. Any action or proceeding arising out of or relating to this Website and/or under these Terms of Service will be instituted in the courts of the Country of Nigeria, and each party irrevocably submits to the exclusive jurisdiction of such courts in any such action or proceeding. You waive any and all objections to the exercise of jurisdiction over you by such courts and to the venue of such courts.
The parties agree that the United Nations Convention on Contracts for the International Sale of Goods will not govern these Terms of Service or the rights and obligations of the parties under these Terms of Service.
## Severability
If any provision of these Terms of Service is illegal or unenforceable under applicable law, the remainder of the provision will be amended to achieve as closely as possible the effect of the original term and all other provisions of these Terms of Service will continue in full force and effect.
## Entire Terms of Service
These Terms of Service constitute the entire and only Terms of Service between the parties in relation to its subject matter and replaces and extinguishes all prior or simultaneous Terms of Services, undertakings, arrangements, understandings or statements of any nature made by the parties or any of them whether oral or written (and, if written, whether or not in draft form) with respect to such subject matter. Each of the parties acknowledges that they are not relying on any statements, warranties or representations given or made by any of them in relation to the subject matter of these Terms of Service, save those expressly set out in these Terms of Service, and that they shall have no rights or remedies with respect to such subject matter otherwise than under these Terms of Service save to the extent that they arise out of the fraud or fraudulent misrepresentation of another party. No variation of these Terms of Service shall be effective unless it is in writing and signed by or on behalf of Company.
## Waiver
No failure to exercise, and no delay in exercising, on the part of either party, any right or any power hereunder shall operate as a waiver thereof, nor shall any single or partial exercise of any right or power hereunder preclude further exercise of that or any other right hereunder.
## Notice
We may provide any notice to you under these Terms of Service by: (i) sending a message to the email address you provide to us and consent to us using; or (ii) by posting to the Website. Notices sent by email will be effective when we send the email and notices we provide by posting will be effective upon posting. It is your responsibility to keep your email address current.
To give us notice under these Terms of Service, you must contact us as follows: (i) by personal delivery, overnight courier or registered or certified mail to ClassroomIO, 128 City Road, London, United Kingdom, EC1V 2NX. We may update the address for notices to us by posting a notice on this Website. Notices provided by personal delivery will be effective immediately once personally received by an authorized representative of Company. Notices provided by overnight courier or registered or certified mail will be effective once received and where confirmation has been provided to evidence the receipt of the notice.
**Last updated:** April 12, 2026
@@ -1,4 +1,3 @@
import { redirect } from '@sveltejs/kit';
import { client } from '$lib/utils/posthog';
export const prerender = false;
@@ -6,8 +5,13 @@ export const prerender = false;
export const load = async ({ request }) => {
client.capture({
distinctId: request.headers.get('x-forwarded-for') || new Date().getTime().toString(),
event: 'privacy page visited'
event: 'terms of service page visited'
});
redirect(307, 'https://app.enzuzo.com/policies/tos/958fc978-5477-11ee-a03b-7b111830c594');
return {
pageMetaTags: {
title: 'Terms of Service | ClassroomIO',
description: 'Terms governing your access to and use of ClassroomIO websites, content, and services.'
}
};
};
+26 -15
View File
@@ -1,20 +1,31 @@
<script>
import { Hero, CoreFeatures, Faq, StudentDashboard, MoreFeatures, Testimonial } from '$lib/components';
import { PUBLIC_ENABLE_FAQ } from '$env/static/public';
import { onMount } from 'svelte';
onMount(() => {
console.log('Welcome to CIO');
});
import {
Hero,
CertSection,
FeaturesSection,
AiSection,
LearnerSection,
QuestionTypes,
AutomateSection,
DeploySection,
EnterpriseSection,
Testimonial,
PageSignupCTA
} from '$lib/components';
</script>
<Hero />
<CoreFeatures />
<StudentDashboard />
<AiSection />
<FeaturesSection />
<CertSection />
<LearnerSection />
<QuestionTypes />
<!-- <AutomateSection /> -->
<DeploySection />
<EnterpriseSection />
<Testimonial />
<MoreFeatures />
{#if PUBLIC_ENABLE_FAQ}
<Faq />
{/if}
<PageSignupCTA
header="Ready to replace Moodle with something you'll actually enjoy?"
subText="Get up and running in an afternoon. No vendor calls, no implementation fees, no surprises."
btnLabel="Book a Demo"
/>
+1 -1
View File
@@ -73,7 +73,7 @@
</section>
<PageSignupCTA
header="Bring your bootcamp vision online"
header="Migrate your certification program to ClassroomIO"
subText="Try before you buy. No credit card required."
btnLabel="Sign up for free"
link="/signup"
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated by Pixelmator Pro 3.6.17 -->
<svg width="1200" height="1200" viewBox="0 0 1200 1200" xmlns="http://www.w3.org/2000/svg">
<g id="g314">
<path id="path147" fill="#d97757" stroke="none" d="M 233.959793 800.214905 L 468.644287 668.536987 L 472.590637 657.100647 L 468.644287 650.738403 L 457.208069 650.738403 L 417.986633 648.322144 L 283.892639 644.69812 L 167.597321 639.865845 L 54.926208 633.825623 L 26.577238 627.785339 L 3.3e-05 592.751709 L 2.73832 575.27533 L 26.577238 559.248352 L 60.724873 562.228149 L 136.187973 567.382629 L 249.422867 575.194763 L 331.570496 580.026978 L 453.261841 592.671082 L 472.590637 592.671082 L 475.328857 584.859009 L 468.724915 580.026978 L 463.570557 575.194763 L 346.389313 495.785217 L 219.543671 411.865906 L 153.100723 363.543762 L 117.181267 339.060425 L 99.060455 316.107361 L 91.248367 266.01355 L 123.865784 230.093994 L 167.677887 233.073853 L 178.872513 236.053772 L 223.248367 270.201477 L 318.040283 343.570496 L 441.825592 434.738342 L 459.946411 449.798706 L 467.194672 444.64447 L 468.080597 441.020203 L 459.946411 427.409485 L 392.617493 305.718323 L 320.778564 181.932983 L 288.80542 130.630859 L 280.348999 99.865845 C 277.369171 87.221436 275.194641 76.590698 275.194641 63.624268 L 312.322174 13.20813 L 332.8591 6.604126 L 382.389313 13.20813 L 403.248352 31.328979 L 434.013519 101.71814 L 483.865753 212.537048 L 561.181274 363.221497 L 583.812134 407.919434 L 595.892639 449.315491 L 600.40271 461.959839 L 608.214783 461.959839 L 608.214783 454.711609 L 614.577271 369.825623 L 626.335632 265.61084 L 637.771851 131.516846 L 641.718201 93.745117 L 660.402832 48.483276 L 697.530334 24.000122 L 726.52356 37.852417 L 750.362549 72 L 747.060486 94.067139 L 732.886047 186.201416 L 705.100708 330.52356 L 686.979919 427.167847 L 697.530334 427.167847 L 709.61084 415.087341 L 758.496704 350.174561 L 840.644348 247.490051 L 876.885925 206.738342 L 919.167847 161.71814 L 946.308838 140.29541 L 997.61084 140.29541 L 1035.38269 196.429626 L 1018.469849 254.416199 L 965.637634 321.422852 L 921.825562 378.201538 L 859.006714 462.765259 L 819.785278 530.41626 L 823.409424 535.812073 L 832.75177 534.92627 L 974.657776 504.724915 L 1051.328979 490.872559 L 1142.818848 475.167786 L 1184.214844 494.496582 L 1188.724854 514.147644 L 1172.456421 554.335693 L 1074.604126 578.496765 L 959.838989 601.449829 L 788.939636 641.879272 L 786.845764 643.409485 L 789.261841 646.389343 L 866.255127 653.637634 L 899.194702 655.409424 L 979.812134 655.409424 L 1129.932861 666.604187 L 1169.154419 692.537109 L 1192.671265 724.268677 L 1188.724854 748.429688 L 1128.322144 779.194641 L 1046.818848 759.865845 L 856.590759 714.604126 L 791.355774 698.335754 L 782.335693 698.335754 L 782.335693 703.731567 L 836.69812 756.885986 L 936.322205 846.845581 L 1061.073975 962.81897 L 1067.436279 991.490112 L 1051.409424 1014.120911 L 1034.496704 1011.704712 L 924.885986 929.234924 L 882.604126 892.107544 L 786.845764 811.48999 L 780.483276 811.48999 L 780.483276 819.946289 L 802.550415 852.241699 L 919.087341 1027.409424 L 925.127625 1081.127686 L 916.671204 1098.604126 L 886.469849 1109.154419 L 853.288696 1103.114136 L 785.073914 1007.355835 L 714.684631 899.516785 L 657.906067 802.872498 L 650.979858 806.81897 L 617.476624 1167.704834 L 601.771851 1186.147705 L 565.530212 1200 L 535.328857 1177.046997 L 519.302124 1139.919556 L 535.328857 1066.550537 L 554.657776 970.792053 L 570.362488 894.68457 L 584.536926 800.134277 L 592.993347 768.724976 L 592.429626 766.630859 L 585.503479 767.516968 L 514.22821 865.369263 L 405.825531 1011.865906 L 320.053711 1103.677979 L 299.516815 1111.812256 L 263.919525 1093.369263 L 267.221497 1060.429688 L 287.114136 1031.114136 L 405.825531 880.107361 L 477.422913 786.52356 L 523.651062 732.483276 L 523.328918 724.671265 L 520.590698 724.671265 L 205.288605 929.395935 L 149.154434 936.644409 L 124.993355 914.01355 L 127.973183 876.885986 L 139.409409 864.80542 L 234.201385 799.570435 L 233.879227 799.8927 Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

+1
View File
@@ -0,0 +1 @@
<svg width='240' height='300' viewBox='0 0 240 300' fill='none' xmlns='http://www.w3.org/2000/svg'><g clip-path='url(#clip0_1401_86274)'><mask id='mask0_1401_86274' style='mask-type:luminance' maskUnits='userSpaceOnUse' x='0' y='0' width='240' height='300'><path d='M240 0H0V300H240V0Z' fill='white'/></mask><g mask='url(#mask0_1401_86274)'><path d='M180 240H60V120H180V240Z' fill='#CFCECD'/><path d='M180 60H60V240H180V60ZM240 300H0V0H240V300Z' fill='#211E1E'/></g></g><defs><clipPath id='clip0_1401_86274'><rect width='240' height='300' fill='white'/></clipPath></defs></svg>

After

Width:  |  Height:  |  Size: 577 B

+1 -1
View File
@@ -17,7 +17,7 @@ export default defineConfig({
entries: ['src/routes/**/+*.{js,ts,svelte}']
},
ssr: {
noExternal: ['bits-ui', 'svelte-toolbelt', '@lucide/svelte', 'runed']
noExternal: ['bits-ui', 'svelte-toolbelt', '@lucide/svelte', 'runed', 'svelte-motion', 'svelte-inview']
},
resolve: {
mainFields: ['browser']