Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added public/aigrader.mp4
Binary file not shown.
Binary file added public/graphics/cyber-101.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
632 changes: 632 additions & 0 deletions public/graphics/cyber-101.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/graphics/mock2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
588 changes: 588 additions & 0 deletions public/graphics/mockup.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/terminalproof.mp4
Binary file not shown.
Binary file added public/videoproof.mp4
Binary file not shown.
18 changes: 1 addition & 17 deletions src/components/Footer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,23 +48,7 @@ export function Footer() {
<path d="M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z"/>
</svg>
</Link>
<Link
href="https://twitter.com/ctfguideapp"
className="group"
aria-label="ctfguideapp on Twitter"
>

<svg
aria-hidden="true"
className="h-6 w-6 fill-white group-hover:fill-[#1da1f2]"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
>
<path d="M512 97.2c-18.8 8.3-39.1 13.9-60.2 16.4 21.6-13 38.2-33.6 46-58.1-20.2 12-42.6 20.7-66.4 25.4C416.2 62.7 390.2 48 362.2 48c-59.4 0-107.5 48-107.5 107.5 0 8.4.9 16.6 2.6 24.5-89.3-4.5-168.6-47.3-221.5-112.6-9.2 15.8-14.5 34.2-14.5 53.8 0 37.2 18.9 69.9 47.6 88.9-17.5-.5-34-5.4-48.4-13.4v1.3c0 51.9 36.8 95.3 85.7 105.2-8.9 2.4-18.3 3.7-28 3.7-6.8 0-13.4-.7-19.9-2 13.5 42.1 52.5 72.8 98.6 73.6-36 28.2-81.3 45-130.6 45-8.5 0-16.9-.5-25.2-1.5C46.2 448.5 101.2 464 160.2 464c192.3 0 297.6-159.3 297.6-297.6 0-4.5-.1-9-.3-13.4 20.5-14.8 38.2-33.3 52.3-54.4z"/>

</svg>

</Link>

<Link
href="https://github.com/ctfguide-tech"
className="group"
Expand Down
247 changes: 247 additions & 0 deletions src/components/home/SecondaryFeatures.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
'use client'

import { useId } from 'react'
import Image from 'next/image'
import { Tab } from '@headlessui/react'
import clsx from 'clsx'

import { Container } from '@/components/Container'

const features = [
{
name: 'AI Grader',
summary: 'Labs automatically graded using AI.',
description:
'We use AI to automatically grade sessions, saving you time and effort.',
image: '../../aigrader.mp4',
icon: function ReportingIcon() {
let id = useId()
return (
<>
<defs>
<linearGradient
id={id}
x1="11.5"
y1={18}
x2={36}
y2="15.5"
gradientUnits="userSpaceOnUse"
>
<stop offset=".194" stopColor="#fff" />
<stop offset={1} stopColor="#6692F1" />
</linearGradient>
</defs>
<path
d="m30 15-4 5-4-11-4 18-4-11-4 7-4-5"
stroke={`url(#${id})`}
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
/>
</>
)
},
},
{
name: 'Submission Playback',
summary:
'Review recorded student lab sessions.',
description:
'We automatically records lab sessions, so you can review them later.',
image: '../../videoproof.mp4',
icon: function InventoryIcon() {
return (
<>



<svg xmlns="http://www.w3.org/2000/svg" opacity=".5" fill="#fff"
viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
<path stroke-linecap="round" stroke-linejoin="round" d="M15.91 11.672a.375.375 0 0 1 0 .656l-5.603 3.113a.375.375 0 0 1-.557-.328V8.887c0-.286.307-.466.557-.327l5.603 3.112Z" />
</svg>

</>
)
},
},
{
name: 'Virtual Machines',
summary:
'Cloud machines streamed to the browser.',
description:
'Easily access cloud machines from your browser, no need to install anything.',
image: '../../terminalproof.mp4',
icon: function ContactsIcon() {
return (
<>



<svg xmlns="http://www.w3.org/2000/svg" opacity=".5" fill="#fff" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M21.75 17.25v-.228a4.5 4.5 0 0 0-.12-1.03l-2.268-9.64a3.375 3.375 0 0 0-3.285-2.602H7.923a3.375 3.375 0 0 0-3.285 2.602l-2.268 9.64a4.5 4.5 0 0 0-.12 1.03v.228m19.5 0a3 3 0 0 1-3 3H5.25a3 3 0 0 1-3-3m19.5 0a3 3 0 0 0-3-3H5.25a3 3 0 0 0-3 3m16.5 0h.008v.008h-.008v-.008Zm-3 0h.008v.008h-.008v-.008Z" />
</svg>



</>
)
},
},
]

function Feature({ feature, isActive, className, ...props }) {
return (
<div
className={clsx(className, !isActive && 'opacity-75 hover:opacity-100')}
{...props}
>
<div
className={clsx(
'w-9 rounded-lg',
isActive ? 'bg-blue-600' : 'bg-neutral-900',
)}
>
<svg aria-hidden="true" className="h-9 w-9" fill="none">
<feature.icon />
</svg>
</div>
<h3
className={clsx(
'mt-6 text-sm font-medium',
isActive ? 'text-blue-600' : 'text-white',
)}
>
{feature.name}
</h3>
<p className="mt-2 font-display text-xl text-white">
{feature.summary}
</p>
<p className="mt-4 text-sm text-white">{feature.description}</p>
</div>
)
}

function FeaturesMobile() {
return (
<div className="-mx-4 mt-20 flex flex-col gap-y-10 overflow-hidden px-4 sm:-mx-6 sm:px-6 lg:hidden">
{features.map((feature) => (
<div key={feature.summary}>
<Feature feature={feature} className="mx-auto max-w-2xl" isActive />



<video

className="mt-4 object-contain rounded-xl shadow-xl h-auto m-auto ring-1 ring-gray-400/10 w-full"
width={2432}
height={1442}
muted

autoSave='true'
loop
onLoadedMetadata={(e) => {
e.target.currentTime = 2; // Skip first two seconds
}}
autoPlay
>
<source src={feature.image}
type="video/mp4" >
</source>
</video>
</div>
))}
</div>
)
}

function FeaturesDesktop() {
return (
<Tab.Group as="div" className="hidden lg:mt-20 lg:block">
{({ selectedIndex }) => (
<>
<Tab.List className="grid grid-cols-3 gap-x-8">
{features.map((feature, featureIndex) => (
<Feature
key={feature.summary}
feature={{
...feature,
name: (
<Tab className="ui-not-focus-visible:outline-none focus-outline-none focus:outline-none outline-none">
<span className="absolute inset-0" />
{feature.name}
</Tab>
),
}}
isActive={featureIndex === selectedIndex}
className="relative"
/>
))}
</Tab.List>
<Tab.Panels className="relative mt-20 overflow-hidden rounded-4xl bg-neutral-800 px-14 py-16 xl:px-16">
<div className="-mx-5 flex">
{features.map((feature, featureIndex) => (
<Tab.Panel
static
key={feature.summary}
className={clsx(
'px-5 transition duration-500 ease-in-out ui-not-focus-visible:outline-none',
featureIndex !== selectedIndex && 'opacity-60',
)}
style={{ transform: `translateX(-${selectedIndex * 100}%)` }}
aria-hidden={featureIndex !== selectedIndex}
>
<div className="w-[52.75rem] overflow-hidden rounded-xl bg-neutral-900 shadow-lg shadow-slate-900/5 ring-1 ring-slate-500/10">

<video className='w-full'
muted
width={1055}
height={810}
autoSave='true'
loop
onLoadedMetadata={(e) => {
e.target.currentTime = 2; // Skip first two seconds
}}
autoPlay
>
<source src={feature.image}
type="video/mp4" >
</source>
</video>



</div>
</Tab.Panel>
))}
</div>
<div className="pointer-events-none absolute inset-0 rounded-4xl ring-1 ring-inset ring-slate-900/10" />
</Tab.Panels>
</>
)}
</Tab.Group>
)
}

export function SecondaryFeatures() {
return (
<section
id="secondary-features"
aria-label="Features for simplifying everyday business tasks"
className="pb-14 pt-20 sm:pb-20 sm:pt-32 lg:pb-32"
>
<Container>
<div className="mx-auto max-w-6xl md:text-center">
<h2 className="font-display text-3xl tracking-tight text-white sm:text-4xl">
We're the best platform for teaching cybersecurity.
</h2>

</div>
<div className='max-w-7xl mx-auto'>
<FeaturesMobile />
<FeaturesDesktop />
</div>
</Container>
</section>
)
}
Binary file added src/images/screenshots/cyber-101.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 3 additions & 2 deletions src/pages/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { FeaturesPanel } from '@/components/home/FeaturePanel';
import { Stats } from '@/components/home/Stats';
import { LearningPanel } from '@/components/home/LearningPanel';
import { Enterprise } from '@/components/home/Enterprise';

import { SecondaryFeatures } from '@/components/home/SecondaryFeatures';
export default function Home() {
return (
<>
Expand Down Expand Up @@ -39,7 +39,8 @@ export default function Home() {

<FeaturesPanel />

<LearningPanel />
<SecondaryFeatures/>

<Stats></Stats>
<Enterprise />

Expand Down