-
- Teach Cyber Today...
- Secure Tomorrow
-
-
- CLARK is the largest platform that provides FREE cybersecurity curriculum. It is home to high-value, high-impact
- cyber curriculum created by top educators and reviewed for relevance and quality. Whether you’re looking to teach something new tomorrow,
- align with curriculum guidelines and standards, or refine your current course, CLARK has free resources ready for you to use!
-
-
BROWSE {{ numReleasedObjects | number }}+ LEARNING OBJECTS
-
BROWSE {{ resourceCount | number }}+ RESOURCES
+
+
+
+
+ Free Cybersecurity Education
+
-
-
VIDEO
+
+
+ Teach Cyber Today...
+ Secure Tomorrow
+
+
+
+ CLARK is the largest platform that provides
+ FREE cybersecurity curriculum. Discover high-value,
+ educator-created content that's been rigorously reviewed for quality and
+ relevance.
+
+
+
+
+
{{ numReleasedObjects | number }}+
+
Learning Objects
+
+
+
{{ resourceCount | number }}+
+
External Resources
+
+
+
+
+
+
+ BROWSE CURRICULUM
+
+
+
+ EXPLORE RESOURCES
+
+
+
+
+
+
+ Educator Reviewed
+
+
+
+ Industry Standards
+
+
+
+ Always Updated
+
+
+
+
+
+
+
+
+
+
+ Security
+
+
+
+ Education
+
+
+
+ Resources
+
+
+
+ Community
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/app/cube/home/splash/splash.component.scss b/src/app/cube/home/splash/splash.component.scss
index 0ea9a4fe5..1c24fcd0b 100644
--- a/src/app/cube/home/splash/splash.component.scss
+++ b/src/app/cube/home/splash/splash.component.scss
@@ -1,118 +1,515 @@
@import '_vars.scss';
+@keyframes float-up-down-1 {
+ 0%, 100% {
+ transform: translateY(0px);
+ }
+ 50% {
+ transform: translateY(-20px);
+ }
+}
+
+@keyframes float-up-down-2 {
+ 0%, 100% {
+ transform: translateY(0px);
+ }
+ 50% {
+ transform: translateY(-25px);
+ }
+}
+
+@keyframes float-up-down-3 {
+ 0%, 100% {
+ transform: translateY(0px);
+ }
+ 50% {
+ transform: translateY(-18px);
+ }
+}
+
+@keyframes float-up-down-4 {
+ 0%, 100% {
+ transform: translateY(0px);
+ }
+ 50% {
+ transform: translateY(-22px);
+ }
+}
+
.wrapper {
display: flex;
flex-direction: row;
- padding: 85px;
- background: linear-gradient(0deg, $primary-white 0%, rgba(255, 255, 255, 0) 100%);
+ min-height: calc(100vh - 120px);
+ padding: 60px 80px;
+ background: linear-gradient(135deg, #f8f9fb 0%, #ffffff 100%);
border: 1px solid $secondary-white;
border-top: none;
-
- //remove after 5th birthday
- padding-top: 135px;
- //remove after 5th birthday
+ gap: 60px;
.first {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+
+ .badge-container {
+ margin-bottom: 24px;
+
+ .blue-badge {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ background: rgba(59, 130, 246, 0.15);
+ color: $homepage-light-blue;
+ padding: 8px 16px;
+ border-radius: 20px;
+ font-size: 13px;
+ font-weight: 600;
+ letter-spacing: 0.5px;
+
+ i {
+ font-size: 14px;
+ line-height: 1;
+ }
+ }
+ }
+
h1 {
- font-size: 40px;
- margin-top: 0;
+ font-size: 48px;
+ font-weight: 700;
+ line-height: 1.2;
+ margin: 16px 0 24px 0;
+ color: #1a1a1a;
+
+ .highlight {
+ color: $homepage-light-blue;
+ }
}
p {
- width: 80%;
font-size: 16px;
+ line-height: 1.6;
color: $homepage-text;
+ margin: 0 0 40px 0;
+ max-width: 90%;
}
- button {
- padding: 16px 27px;
- margin-top: 40px;
- background-color: $homepage-light-blue;
- color: white;
- border: none;
- border-radius: 4px;
- cursor: pointer;
- box-shadow: 0px 6px 12px -6px $homepage-light-blue;
+ .stats-container {
+ display: flex;
+ gap: 50px;
+ margin: 40px 0;
+
+ .stat-item {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+
+ .stat-number {
+ font-size: 32px;
+ font-weight: 700;
+ color: $homepage-light-blue;
+ line-height: 1;
+ margin-bottom: 8px;
+ }
+
+ .stat-label {
+ font-size: 14px;
+ font-weight: 500;
+ color: $homepage-text;
+ }
+ }
}
- .card {
- margin: 20px 0 0 15px;
- background-color: $card-primary;
- }
+ .buttons-container {
+ display: flex;
+ gap: 16px;
+ margin: 40px 0;
+ flex-wrap: wrap;
+
+ button {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ padding: 14px 28px;
+ border: none;
+ border-radius: 6px;
+ cursor: pointer;
+ font-weight: 600;
+ font-size: 15px;
+ transition: all 0.3s ease;
+ letter-spacing: 0.5px;
+
+ i {
+ font-size: 16px;
+ line-height: 1;
+ flex-shrink: 0;
+ }
+
+ &.primary-btn {
+ background-color: $homepage-light-blue;
+ color: white;
+ box-shadow: 0px 8px 16px rgba(59, 130, 246, 0.3);
+
+ i {
+ color: white;
+ }
+
+ &:hover {
+ transform: translateY(-2px);
+ box-shadow: 0px 12px 24px rgba(59, 130, 246, 0.4);
+ }
+ }
+
+ &.secondary-btn {
+ background-color: #f0f0f0;
+ color: #1a1a1a;
+ border: 1px solid #e0e0e0;
- button:hover {
- opacity: 80%;
+ i {
+ color: #1a1a1a;
+ }
+
+ &:hover {
+ background-color: #e8e8e8;
+ transform: translateY(-2px);
+ }
+ }
+ }
}
- button:active {
- opacity: 100%;
+ .badges-container {
+ display: flex;
+ gap: 32px;
+ margin-top: 32px;
+ flex-wrap: wrap;
+
+ .trust-badge {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ font-size: 13px;
+ font-weight: 600;
+ color: #666666;
+
+ i {
+ font-size: 14px;
+ color: #999999;
+ line-height: 1;
+ }
+ }
}
}
.second {
+ flex: 1;
display: flex;
align-items: center;
- iframe {
- width: 560px;
- height: 315px;
- box-shadow: 0px 10px 20px -10px rgba(0, 0, 0, 0.5);
- border-radius: 6px;
+ justify-content: center;
+ position: relative;
+
+ .icons-container {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ min-height: 400px;
+
+ .icons-2x2-grid {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 24px;
+ width: 280px;
+
+ .icon-grid-item {
+ width: 130px;
+ height: 130px;
+ border-radius: 12px;
+ background: rgba(255, 255, 255, 0.9);
+ border: 1px solid #e8e8e8;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ gap: 12px;
+ box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.08);
+ transition: all 0.3s ease;
+ cursor: pointer;
+ position: relative;
+ padding: 16px;
+
+ i {
+ font-size: 40px;
+ color: $homepage-light-blue;
+ line-height: 1;
+ }
+
+ .icon-label {
+ font-size: 12px;
+ font-weight: 600;
+ color: #333333;
+ white-space: nowrap;
+ }
+
+ &:hover {
+ box-shadow: 0px 8px 24px rgba(0, 0, 0, 0.12);
+ transform: translateY(-4px);
+ background: white;
+ }
+ }
+ }
+
+ .floating-icon {
+ position: absolute;
+ width: 80px;
+ height: 80px;
+ border-radius: 50%;
+ background: #f5f5f5;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.08);
+ border: 1px solid #e8e8e8;
+
+ i {
+ font-size: 36px;
+ color: #b0b0b0;
+ line-height: 1;
+ }
+
+ &.floating-1 {
+ top: 10%;
+ left: 15%;
+ animation: float-up-down-1 4s ease-in-out infinite;
+ }
+
+ &.floating-2 {
+ top: 70%;
+ left: 8%;
+ animation: float-up-down-2 5s ease-in-out infinite;
+ }
+
+ &.floating-3 {
+ top: 20%;
+ right: 10%;
+ animation: float-up-down-3 4.5s ease-in-out infinite;
+ }
+ }
}
}
}
-
-@media screen and (max-width: 1150px) {
+@media screen and (max-width: 1200px) {
.wrapper {
- display: flex;
flex-direction: column;
- align-items: center;
- justify-content: center;
- text-align: center;
+ padding: 40px;
+ min-height: auto;
+ gap: 40px;
.first {
- display: flex;
- flex-direction: column;
- align-items: center;
- margin-bottom: 30px;
+ h1 {
+ font-size: 36px;
+ }
+
+ p {
+ max-width: 100%;
+ }
+
+ .stats-container {
+ gap: 30px;
+ }
+
+ .buttons-container {
+ justify-content: flex-start;
+
+ button {
+ width: auto;
+ }
+ }
}
.second {
- iframe {
- width: 500px;
- height: 280px;
- margin-top: 80px;
+ .icons-container {
+ min-height: 350px;
+
+ .icons-2x2-grid {
+ width: 240px;
+ gap: 20px;
+
+ .icon-grid-item {
+ width: 110px;
+ height: 110px;
+
+ i {
+ font-size: 35px;
+ }
+
+ .icon-label {
+ font-size: 11px;
+ }
+ }
+ }
+
+ .floating-icon {
+ width: 70px;
+ height: 70px;
+
+ i {
+ font-size: 30px;
+ }
+ }
}
}
}
}
-@media (max-width: 600px) {
+@media (max-width: 768px) {
.wrapper {
+ padding: 30px 20px;
+
+ .first {
+ h1 {
+ font-size: 28px;
+ }
+
+ p {
+ font-size: 15px;
+ }
+
+ .stats-container {
+ flex-direction: column;
+ gap: 24px;
+ }
+
+ .buttons-container {
+ flex-direction: column;
+
+ button {
+ width: 100%;
+ }
+ }
+
+ .badges-container {
+ flex-direction: column;
+ gap: 16px;
+ }
+ }
+
.second {
- iframe {
- width: 325px;
- height: 180px;
+ .icons-container {
+ min-height: 300px;
+
+ .icons-2x2-grid {
+ width: 200px;
+ gap: 16px;
+
+ .icon-grid-item {
+ width: 90px;
+ height: 90px;
+
+ i {
+ font-size: 32px;
+ }
+
+ .icon-label {
+ font-size: 10px;
+ }
+ }
+ }
+
+ .floating-icon {
+ width: 60px;
+ height: 60px;
+
+ i {
+ font-size: 26px;
+ }
+ }
}
}
}
}
-@media (max-width: 320px) {
+@media (max-width: 480px) {
.wrapper {
+ padding: 20px;
+
.first {
h1 {
- font-size: 30px;
+ font-size: 22px;
}
- button {
- padding: 10px;
+
+ p {
+ font-size: 14px;
+ }
+
+ .stats-container {
+ gap: 20px;
+
+ .stat-item {
+ .stat-number {
+ font-size: 24px;
+ }
+
+ .stat-label {
+ font-size: 12px;
+ }
+ }
+ }
+
+ .buttons-container {
+ button {
+ padding: 12px 24px;
+ font-size: 14px;
+
+ i {
+ font-size: 14px;
+ }
+ }
+ }
+
+ .badges-container {
+ .trust-badge {
+ font-size: 12px;
+
+ i {
+ font-size: 12px;
+ }
+ }
}
}
+
.second {
- iframe {
- width: 250px;
- height: 140px;
+ .icons-container {
+ .icons-2x2-grid {
+ width: 160px;
+ gap: 12px;
+
+ .icon-grid-item {
+ width: 70px;
+ height: 70px;
+
+ i {
+ font-size: 24px;
+ }
+
+ .icon-label {
+ font-size: 9px;
+ }
+ }
+ }
+
+ .floating-icon {
+ width: 50px;
+ height: 50px;
+
+ i {
+ font-size: 22px;
+ }
+ }
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/app/cube/home/splash/splash.component.ts b/src/app/cube/home/splash/splash.component.ts
index 985493b9c..757d995c1 100644
--- a/src/app/cube/home/splash/splash.component.ts
+++ b/src/app/cube/home/splash/splash.component.ts
@@ -1,7 +1,8 @@
import { Component, OnInit } from '@angular/core';
-import { GoogleTagService } from '../google-tag.service';
-import { UtilityService } from '../../../core/utility-module/utility.service';
+import { Router } from '@angular/router';
import { SearchService } from '../../../core/learning-object-module/search/search.service';
+import { UtilityService } from '../../../core/utility-module/utility.service';
+import { GoogleTagService } from '../google-tag.service';
@Component({
selector: 'clark-splash',
@@ -12,13 +13,14 @@ export class SplashComponent implements OnInit {
numReleasedObjects = 0; // default number of released objects before the service provides a new number
resourceCount = 0; // default number of resources before the service provides a new number
constructor(
+ public router: Router,
public googleTagService: GoogleTagService,
public utilityService: UtilityService,
public learningObjectService: SearchService
- ) { }
+ ) { }
async ngOnInit(): Promise
{
- this.learningObjectService.getLearningObjects({'status': ['released']}).then(stats => {
+ this.learningObjectService.getLearningObjects({ 'status': ['released'] }).then(stats => {
this.numReleasedObjects = Math.floor(stats.total / 10) * 10;
});
await this.utilityService.getAllResources().then((res: any) => {
diff --git a/src/app/onion/learning-object-builder/components/builder-navbar/builder-navbar.component.ts b/src/app/onion/learning-object-builder/components/builder-navbar/builder-navbar.component.ts
index 31f42129f..5ee46554c 100644
--- a/src/app/onion/learning-object-builder/components/builder-navbar/builder-navbar.component.ts
+++ b/src/app/onion/learning-object-builder/components/builder-navbar/builder-navbar.component.ts
@@ -1,16 +1,15 @@
-import { Component, OnDestroy, Input } from '@angular/core';
-import { BuilderStore } from '../../builder-store.service';
-import { AuthService } from 'app/core/auth-module/auth.service';
-import { LearningObjectValidator } from '../../validators/learning-object.validator';
-import { filter, takeUntil } from 'rxjs/operators';
-import { Subject } from 'rxjs';
-import { Router, ActivatedRoute } from '@angular/router';
-import { ToastrOvenService } from 'app/shared/modules/toaster/notification.service';
-import { CollectionService, Collection } from 'app/core/collection-module/collections.service';
+import { Component, Input, OnDestroy } from '@angular/core';
+import { ActivatedRoute, Router } from '@angular/router';
import { LearningObject } from '@entity';
+import { AuthService } from 'app/core/auth-module/auth.service';
+import { Collection, CollectionService } from 'app/core/collection-module/collections.service';
import { BundlingService } from 'app/core/learning-object-module/bundling/bundling.service';
import { FileService } from 'app/core/learning-object-module/file/file.service';
-import { LearningObjectStatus } from '@env/environment';
+import { ToastrOvenService } from 'app/shared/modules/toaster/notification.service';
+import { Subject } from 'rxjs';
+import { filter, takeUntil } from 'rxjs/operators';
+import { BuilderStore } from '../../builder-store.service';
+import { LearningObjectValidator } from '../../validators/learning-object.validator';
@Component({
selector: 'onion-builder-navbar',
diff --git a/src/environments/environment.ts b/src/environments/environment.ts
index a4839b6a0..d7a3e35d1 100644
--- a/src/environments/environment.ts
+++ b/src/environments/environment.ts
@@ -1,7 +1,3 @@
-// The file contents for the current environment will overwrite these during build.
-// The build system defaults to the dev environment which uses `environment.ts`, but if you do
-// `ng build --env=prod` then `environment.prod.ts` will be used instead.
-// The list of which env maps to which file can be found in `.angular-cli.json`.
export const environment = {
production: false,
environment: 'development',
@@ -16,11 +12,3 @@ export const environment = {
downtimeUrl: '',
publicKey: 'cxtp_pbDbZsDUdNr5Wu3GWX6emisZyfKkV9',
};
-
-export enum LearningObjectStatus {
- PUBLISHED = 'published',
- UNDER_REVIEW = 'review',
- WAITING = 'waiting',
- DENIED = 'denied',
- UNPUBLISHED = 'unpublished'
-}