Initial React project

This commit is contained in:
Johan
2026-03-11 17:51:51 +01:00
parent 2a81092b3c
commit 39f3381467
16 changed files with 803 additions and 722 deletions

18
dist/assets/index-C7d5krmc.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

4
dist/index.html vendored
View File

@@ -7,8 +7,8 @@
<title>arbejd-react</title> <title>arbejd-react</title>
<script src="https://cdn.tailwindcss.com"></script> <script src="https://cdn.tailwindcss.com"></script>
<script src="https://code.iconify.design/iconify-icon/1.0.7/iconify-icon.min.js"></script> <script src="https://code.iconify.design/iconify-icon/1.0.7/iconify-icon.min.js"></script>
<script type="module" crossorigin src="/assets/index-DC25ZOar.js"></script> <script type="module" crossorigin src="/assets/index-C7d5krmc.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-HggOSgEE.css"> <link rel="stylesheet" crossorigin href="/assets/index-nOCYJhc8.css">
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>

File diff suppressed because one or more lines are too long

View File

@@ -15,6 +15,8 @@ import { JobordbogenPage } from './presentation/jobordbogen/pages/JobordbogenPag
import { JobordbogenEntryPage } from './presentation/jobordbogen/pages/JobordbogenEntryPage'; import { JobordbogenEntryPage } from './presentation/jobordbogen/pages/JobordbogenEntryPage';
import { StoriesPage } from './presentation/stories/pages/StoriesPage'; import { StoriesPage } from './presentation/stories/pages/StoriesPage';
import { NewsletterPage } from './presentation/newsletter/pages/NewsletterPage'; import { NewsletterPage } from './presentation/newsletter/pages/NewsletterPage';
import { ForVirksomhederPage } from './presentation/companies/pages/ForVirksomhederPage';
import { JobSearchersPage } from './presentation/jobseekers/pages/JobSearchersPage';
import { import {
SimulatorPage, SimulatorPage,
type SimulatorEvaluationSelection, type SimulatorEvaluationSelection,
@@ -35,6 +37,8 @@ function App() {
const isPricingRoute = useMemo(() => window.location.pathname === '/pricing' || window.location.pathname === '/priser', []); const isPricingRoute = useMemo(() => window.location.pathname === '/pricing' || window.location.pathname === '/priser', []);
const isStoriesRoute = useMemo(() => window.location.pathname === '/stories', []); const isStoriesRoute = useMemo(() => window.location.pathname === '/stories', []);
const isNewsletterRoute = useMemo(() => window.location.pathname === '/newsletter', []); const isNewsletterRoute = useMemo(() => window.location.pathname === '/newsletter', []);
const isCompaniesRoute = useMemo(() => window.location.pathname === '/for-virksomheder' || window.location.pathname === '/virksomheder', []);
const isJobseekersRoute = useMemo(() => window.location.pathname === '/for-jobsogere' || window.location.pathname === '/jobsearchers', []);
const isJobordbogenEntryRoute = useMemo(() => window.location.pathname.startsWith('/jobordbogen/') && window.location.pathname !== '/jobordbogen/', []); const isJobordbogenEntryRoute = useMemo(() => window.location.pathname.startsWith('/jobordbogen/') && window.location.pathname !== '/jobordbogen/', []);
const isJobordbogenRoute = useMemo(() => window.location.pathname === '/jobordbogen' || window.location.pathname === '/academy', []); const isJobordbogenRoute = useMemo(() => window.location.pathname === '/jobordbogen' || window.location.pathname === '/academy', []);
const initialAuthenticated = useMemo(() => Boolean(window.localStorage.getItem('token')), []); const initialAuthenticated = useMemo(() => Boolean(window.localStorage.getItem('token')), []);
@@ -113,6 +117,14 @@ function App() {
return <NewsletterPage />; return <NewsletterPage />;
} }
if (isCompaniesRoute) {
return <ForVirksomhederPage />;
}
if (isJobseekersRoute) {
return <JobSearchersPage />;
}
if (isJobordbogenEntryRoute) { if (isJobordbogenEntryRoute) {
return <JobordbogenEntryPage />; return <JobordbogenEntryPage />;
} }

View File

@@ -0,0 +1,252 @@
import { type CSSProperties } from 'react';
import './companies.css';
import { SiteFooter } from '../../shared/components/SiteFooter';
import { SiteNavbar } from '../../shared/components/SiteNavbar';
import screen1Image from '../../../assets/screen1.png';
import screen2Image from '../../../assets/screen2.png';
interface IconifyIconProps {
className?: string;
icon: string;
style?: CSSProperties;
}
function IconifyIcon({ className, icon, style }: IconifyIconProps) {
return <iconify-icon className={className} icon={icon} style={style} />;
}
const companyLogos = [
'https://cdn.prod.website-files.com/5d4a8e9cc03a64b5d34a42b4/6086b30019b62383f496b96e_DKM.svg',
'https://cdn.prod.website-files.com/5d4a8e9cc03a64b5d34a42b4/6086b300089747750fea09bd_find%20job%20abroad.svg',
'https://cdn.prod.website-files.com/5d4a8e9cc03a64b5d34a42b4/6086b302bd1bed78e2c84ebe_Midtfjord.svg',
'https://cdn.prod.website-files.com/5d4a8e9cc03a64b5d34a42b4/6086b302fde5303d3b057be1_JPD.svg',
'https://cdn.prod.website-files.com/5d4a8e9cc03a64b5d34a42b4/60939fdba79df07cd812c88d_gws-logo-300x137.png',
'https://cdn.prod.website-files.com/5d4a8e9cc03a64b5d34a42b4/6086b303b480060b735069de_plast-line.svg',
'https://cdn.prod.website-files.com/5d4a8e9cc03a64b5d34a42b4/6086b30482be352ae620de93_St%C3%A6rmose.svg',
'https://images.unsplash.com/photo-1486406146926-c627a92ad1ab?w=320&q=80',
'https://images.unsplash.com/photo-1454165804606-c3d57bc86b40?w=320&q=80',
'https://images.unsplash.com/photo-1460925895917-afdab827c52f?w=320&q=80',
];
const jobMatches = [
{ title: 'Tømrer', count: '72 kandidater' },
{ title: 'Pædagog', count: '359 kandidater' },
{ title: 'Chauffør', count: '438 kandidater' },
{ title: 'Tjener', count: '836 kandidater' },
{ title: 'Rengøring', count: '1471 kandidater' },
{ title: 'Sygeplejerske', count: '192 kandidater' },
];
const features = [
{ icon: 'solar:wallet-money-linear', title: 'Gratis oprettelse', text: 'Hurtig og ubegrænset gratis oprettelse af jobannoncer' },
{ icon: 'solar:bolt-linear', title: 'Effektivt', text: 'Reducer rekrutteringsudgifter med op til 90%' },
{ icon: 'solar:users-group-two-rounded-linear', title: '1-1 match', text: 'Systematiserer, sorterer og matcher op med dine krav' },
{ icon: 'solar:hand-shake-linear', title: 'Beslut med et klik', text: 'Træf beslutningerne hurtigt og effektivt' },
{ icon: 'solar:lock-keyhole-linear', title: 'Ingen begrænsninger', text: 'Direkte adgang til ansøgerne og kandidaterne' },
{ icon: 'solar:chat-line-linear', title: 'Dialog', text: 'Gå i dialog med kandidaterne med det samme' },
{ icon: 'solar:close-circle-linear', title: 'Afslå med et klik', text: 'Afslag og samtale invitationer sendes med et enkelt klik' },
{ icon: 'solar:hand-money-linear', title: 'Nem betaling', text: 'Betal kun hvis I ønsker adgang til kontaktoplysninger' },
{ icon: 'solar:graph-up-linear', title: 'Automatiseret', text: 'Spar tid - ingen manuel screeningsproces' },
];
export function ForVirksomhederPage() {
return (
<div className="companies-react-root scroll-smooth bg-[#f8fafc] relative min-h-screen text-gray-600 selection:bg-teal-100 selection:text-teal-900 overflow-x-hidden flex flex-col font-normal custom-scrollbar">
<div className="fixed top-[-15%] left-[-10%] w-[60vw] h-[60vw] rounded-full bg-gradient-to-br from-teal-400/30 to-emerald-300/10 blur-[140px] pointer-events-none z-0" />
<div className="fixed bottom-[-15%] right-[-10%] w-[70vw] h-[70vw] rounded-full bg-gradient-to-tl from-indigo-500/20 to-purple-400/10 blur-[160px] pointer-events-none z-0" />
<SiteNavbar activeTab="how" activeHowItem="companies" />
<main className="flex-1 relative z-10 pt-16">
<section className="py-20 px-6 lg:px-12 max-w-7xl mx-auto">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-10 items-center">
<div>
<h1 className="text-4xl md:text-6xl font-medium tracking-tight text-gradient-subtle mb-6">Udvælg og ansæt den rigtige medarbejder</h1>
<ul className="space-y-3 mb-8">
{[
'Gratis oprettelse af jobannoncer',
'Reducer og undgå fejl- og forgæves rekrutteringer',
'Sorterer og matcher udbuddet af ansøgere',
'Indkaldelser og afslag sendes med ét klik',
].map((item) => (
<li key={item} className="flex items-start gap-3 text-base text-gray-700">
<IconifyIcon icon="solar:check-circle-linear" className="text-xl text-teal-600 mt-0.5" style={{ strokeWidth: 1.5 }} />
<span>{item}</span>
</li>
))}
</ul>
<div className="flex flex-wrap gap-4 mb-5">
<a href="https://app.arbejd.com/welcome" className="inline-flex items-center justify-center gap-2 px-6 py-3.5 bg-gray-900 text-white rounded-2xl shadow-[0_8px_25px_rgba(17,24,39,0.22)] hover:bg-gray-800 transition-all outline-none border border-gray-800">Opret en gratis profil</a>
<a href="https://app.arbejd.com/welcome" className="inline-flex items-center justify-center gap-2 px-6 py-3.5 bg-white/70 backdrop-blur-xl text-gray-900 rounded-2xl border border-white/90 shadow-[0_8px_25px_rgba(15,23,42,0.08)] hover:bg-white transition-all outline-none">Opret Virksomhed</a>
</div>
<p className="text-sm text-gray-500 mb-4">Oprettelse kan pt. kun ske via bærbar eller desktop. Ved at tilmelde din virksomhed accepterer du samtidigt Arbejd.coms forretningsbetingelser og privatlivspolitik.</p>
<p className="text-sm text-gray-600 mb-4">Har du allerede en profil? <a href="https://app.arbejd.com/" className="text-teal-700 hover:text-teal-900">Log in her</a></p>
<div className="p-4 rounded-2xl bg-gradient-to-r from-white/70 to-white/40 border border-white/80 shadow-sm max-w-lg">
<h3 className="text-base font-medium text-gray-900 mb-1">Hjælp til oprettelse?</h3>
<p className="text-sm text-gray-600 mb-2">Vi sidder klar til at hjælpe dig telefonen og guider dig igennem oprettelsen.</p>
<a href="tel:+4542162228" className="inline-flex items-center gap-2 text-teal-700 font-medium hover:text-teal-900">
<IconifyIcon icon="solar:phone-linear" className="text-lg" style={{ strokeWidth: 1.5 }} />
Ring +45 42 16 22 28
</a>
</div>
</div>
<div className="relative">
<div className="rounded-[2.5rem] bg-gradient-to-br from-white/70 to-white/30 backdrop-blur-2xl border border-white/80 p-5 shadow-[0_12px_40px_rgba(0,0,0,0.05)]">
<img src={screen1Image} alt="A laptop showing the Arbejd.com dashboard" className="w-full rounded-2xl border border-white/70 shadow-sm" />
</div>
<div className="absolute -bottom-8 -right-4 w-[45%] rounded-[2rem] bg-gradient-to-br from-white/70 to-white/30 backdrop-blur-2xl border border-white/80 p-3 shadow-[0_12px_40px_rgba(0,0,0,0.12)]">
<img src={screen2Image} alt="An iPhone showing the Arbejd.com app" className="w-full rounded-xl border border-white/80" />
</div>
</div>
</div>
</section>
<section className="py-14 px-6 lg:px-12 max-w-7xl mx-auto border-y border-white/40 bg-gradient-to-r from-white/10 via-white/30 to-white/10 backdrop-blur-xl">
<p className="text-center text-sm font-medium text-gray-500 uppercase tracking-widest mb-8">Vi har hjulpet virksomheder over hele Danmark</p>
<div className="flex flex-wrap justify-center items-center gap-8 md:gap-12 opacity-70 grayscale hover:grayscale-0 transition-all duration-500">
{companyLogos.map((logo, index) => (
<img key={`${logo}-${index}`} src={logo} alt={`Company logo ${index + 1}`} className="h-8 md:h-10 w-auto object-contain" loading="lazy" decoding="async" referrerPolicy="no-referrer" />
))}
</div>
</section>
<section className="py-20 px-6 lg:px-12 max-w-7xl mx-auto">
<div className="text-center max-w-3xl mx-auto mb-10">
<h2 className="text-3xl md:text-4xl font-medium tracking-tight text-gradient-subtle mb-4">Vi har dygtige kandidater fra alle brancher</h2>
<p className="text-lg text-gray-600">Med over 37.000 kandidater tværs af hele landet og 22 brancheområder, er der gode muligheder for at finde din næste kollega eller medarbejder.</p>
</div>
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-4 mb-10">
{jobMatches.map((job) => (
<div key={job.title} className="rounded-2xl border border-white/80 bg-white/60 backdrop-blur-xl p-4 shadow-sm text-center">
<div className="inline-flex items-center gap-1.5 text-amber-500 text-xs mb-2">
<IconifyIcon icon="solar:star-linear" className="text-sm" style={{ strokeWidth: 1.5 }} />
<span>2/3 match</span>
</div>
<h3 className="text-base font-medium text-gray-900">{job.title}</h3>
<p className="text-xs text-gray-500 mt-1">{job.count}</p>
</div>
))}
</div>
<div className="text-center">
<a href="https://app.arbejd.com/welcome" className="inline-flex items-center justify-center gap-2 px-6 py-3.5 bg-gray-900 text-white rounded-2xl shadow-[0_8px_25px_rgba(17,24,39,0.22)] hover:bg-gray-800 transition-all outline-none border border-gray-800">Opret Dig Nu</a>
</div>
</section>
<section className="py-20 px-6 lg:px-12 max-w-7xl mx-auto border-t border-white/40">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12 items-center">
<div>
<h2 className="text-3xl md:text-4xl font-medium tracking-tight text-gradient-subtle mb-5">Der er en smartere måde at hyre </h2>
<p className="text-lg text-gray-600 mb-7">Vores intelligente platform hjælper dig med at screene og hyre kandidater hurtigere. Stop med at spilde hundredvis af timer at screene kandidater der ikke lever op til stillingens krav. Vi præsenterer dig først for dem der matcher jobbet bedst. Enkelt og tidsbesparende.</p>
<a href="https://app.arbejd.com/welcome" className="inline-flex items-center justify-center gap-2 px-6 py-3.5 bg-gray-900 text-white rounded-2xl shadow-[0_8px_25px_rgba(17,24,39,0.22)] hover:bg-gray-800 transition-all outline-none border border-gray-800">Opret Dig Nu</a>
</div>
<div className="relative rounded-[2.5rem] bg-gradient-to-br from-white/70 to-white/30 backdrop-blur-2xl border border-white/80 p-5 shadow-[0_12px_40px_rgba(0,0,0,0.05)]">
<img src={screen1Image} alt="A snapshot of the Arbejd.com dashboard showing candidates" className="w-full rounded-2xl border border-white/70" />
<div className="absolute -top-6 -right-4 w-16 h-16 rounded-2xl bg-white/80 border border-white/80 shadow-lg flex items-center justify-center animate-float-slow">
<IconifyIcon icon="solar:bell-bing-linear" className="text-3xl text-amber-500" style={{ strokeWidth: 1.5 }} />
</div>
</div>
</div>
</section>
<section className="py-20 px-6 lg:px-12 max-w-7xl mx-auto border-t border-white/40">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12 items-center">
<div className="order-2 lg:order-1">
<h2 className="text-3xl md:text-4xl font-medium tracking-tight text-gradient-subtle mb-5">Du er igang minutter</h2>
<p className="text-lg text-gray-600 mb-7">Screen tusindvis af kandidater ud fra uddannelse, kvalifikationer, afstand til jobbet og andre relevante filtre. Skip telefoninterviews og chat direkte med ansøgerne sikkert og nemt Arbejd.com.</p>
<a href="https://app.arbejd.com/welcome" className="inline-flex items-center justify-center gap-2 px-6 py-3.5 bg-gray-900 text-white rounded-2xl shadow-[0_8px_25px_rgba(17,24,39,0.22)] hover:bg-gray-800 transition-all outline-none border border-gray-800">Opret Dig Nu</a>
</div>
<div className="order-1 lg:order-2 space-y-4">
<div className="grid grid-cols-2 sm:grid-cols-3 gap-3">
{['Poul\nMaskinmester', 'Lene\nKok', 'Pernille\nAdvokat', 'Troels\nLagermedarbejder', 'Selma\nServicemedarbejder', 'Caroline\nKommunikationsmedarbejder'].map((person) => {
const [name, role] = person.split('\n');
return (
<div key={person} className="rounded-xl bg-white/70 border border-white/80 p-3 backdrop-blur-md shadow-sm">
<p className="text-sm font-medium text-gray-900">{name}</p>
<p className="text-xs text-gray-500">{role}</p>
</div>
);
})}
</div>
<div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
<div className="rounded-xl bg-white/70 border border-white/80 p-3 backdrop-blur-md shadow-sm text-xs text-gray-700">Send besked, favorit og download CV</div>
<div className="rounded-xl bg-white/70 border border-white/80 p-3 backdrop-blur-md shadow-sm text-xs text-gray-700">Kørekort & certifikater</div>
<div className="rounded-xl bg-white/70 border border-white/80 p-3 backdrop-blur-md shadow-sm text-xs text-gray-700">Sprog, kvalifikationer og erfaring</div>
</div>
</div>
</div>
</section>
<section className="py-20 px-6 lg:px-12 max-w-7xl mx-auto border-t border-white/40">
<div className="text-center mb-12">
<h2 className="text-3xl md:text-4xl font-medium tracking-tight text-gradient-subtle mb-4">Designet til din virksomhed</h2>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{features.map((feature) => (
<div key={feature.title} className="p-6 bg-gradient-to-br from-white/70 to-white/30 backdrop-blur-xl border border-white/80 rounded-3xl shadow-[0_4px_20px_rgba(0,0,0,0.02)] hover:shadow-[0_8px_30px_rgba(0,0,0,0.06)] transition-all group">
<div className="w-12 h-12 rounded-2xl bg-gradient-to-br from-teal-50 to-white border border-teal-100/50 shadow-sm flex items-center justify-center mb-4 group-hover:scale-110 transition-transform">
<IconifyIcon icon={feature.icon} className="text-2xl text-teal-600" style={{ strokeWidth: 1.5 }} />
</div>
<h3 className="text-lg font-medium text-gray-900 mb-2 tracking-tight">{feature.title}</h3>
<p className="text-base text-gray-600 font-normal leading-relaxed">{feature.text}</p>
</div>
))}
</div>
</section>
<section className="py-20 px-6 lg:px-12 max-w-7xl mx-auto border-t border-white/40">
<div className="max-w-4xl mx-auto rounded-[2.5rem] border border-white/80 bg-gradient-to-br from-white/70 to-white/30 backdrop-blur-2xl p-10 shadow-[0_12px_40px_rgba(0,0,0,0.05)] text-center">
<div className="text-sm font-medium text-teal-700 mb-3">Fra DKK 995/adgang</div>
<h2 className="text-3xl md:text-4xl font-medium tracking-tight text-gradient-subtle mb-4">Gratis og ubegrænset oprettelse</h2>
<p className="text-lg text-gray-600 mb-8">Arbejd.com er anderledes. Du får gratis adgang til vores SaaS-løsning samt ubegrænset oprettelse af annoncer. kan du finde dine kandidater hurtigt og effektivt. Du betaler først, når du vil i kontakt med ansøgerne.</p>
<a href="/pricing" className="inline-flex items-center justify-center gap-2 px-6 py-3.5 bg-gray-900 text-white rounded-2xl shadow-[0_8px_25px_rgba(17,24,39,0.22)] hover:bg-gray-800 transition-all outline-none border border-gray-800">Se Priserne</a>
</div>
</section>
<section className="py-20 px-6 lg:px-12 max-w-7xl mx-auto border-t border-white/40">
<div className="max-w-4xl mx-auto text-center mb-12">
<div className="text-xs uppercase tracking-widest text-teal-700 font-medium mb-3">For virksomheder</div>
<h2 className="text-3xl md:text-4xl font-medium tracking-tight text-gradient-subtle mb-4">Det behøver ikke være svært at finde relevante kandidater</h2>
<p className="text-lg text-gray-600">Du kan oprette mange jobopslag du ønsker og screene relevante kandidater, helt gratis. Du betaler altså først når du ønsker at tage kontakt til en jobansøger. Se vores prismodeller her.</p>
</div>
<div className="max-w-5xl mx-auto grid grid-cols-1 md:grid-cols-2 gap-6">
{[
'Når du har oprettet dig som virksomhed, kan du starte dit jobopslag ved at gå til "Annoncer" -> og trykke "Opret annonce". Du guides herefter igennem oprettelsen, og du kan til enhver tid gå til og fra din oprettelse af jobannoncen.',
'Du opretter en konto her, hvor du nemt kan udfylde information om din virksomhed. Opret herefter gratis dit jobopslag som helt automatisk matches med alle de relevante kandidater til stillingen.',
'Ja - modsat konkurrenterne betaler du hos Arbejd.com ingenting for oprettelsen af jobannoncer. Du kan oprette så mange du har lyst til uden betaling. Du betaler først når du ønsker at tage kontakt til en jobansøger. Se vores prismodeller her.',
].map((answer) => (
<div key={answer} className="rounded-2xl border border-white/80 bg-white/70 backdrop-blur-xl p-6 shadow-sm md:col-span-1">
<p className="text-base text-gray-700 leading-relaxed mb-5">{answer}</p>
<div className="text-xs text-gray-500">Senest opdateret<br />May 5, 2021</div>
</div>
))}
<div className="rounded-2xl border border-white/80 bg-white/70 backdrop-blur-xl p-6 shadow-sm flex items-center justify-center md:col-span-2">
<a href="#" className="inline-flex items-center gap-2 text-teal-700 hover:text-teal-900 font-medium">
<IconifyIcon icon="solar:alt-arrow-down-linear" className="text-lg" style={{ strokeWidth: 1.5 }} />
Se Flere Svar
</a>
</div>
</div>
</section>
<section className="pb-24 px-6 lg:px-12 max-w-7xl mx-auto">
<div className="max-w-4xl mx-auto rounded-[2.5rem] border border-white/80 bg-gradient-to-br from-white/70 to-white/30 backdrop-blur-2xl p-10 shadow-[0_12px_40px_rgba(0,0,0,0.05)] text-center">
<div className="w-12 h-12 rounded-2xl bg-white/80 border border-white/80 shadow-sm flex items-center justify-center mx-auto mb-4">
<IconifyIcon icon="solar:magnifer-linear" className="text-2xl text-teal-600" style={{ strokeWidth: 1.5 }} />
</div>
<h3 className="text-2xl md:text-3xl font-medium text-gray-900 tracking-tight mb-3">Større virksomhed eller vikar- og rekrutterings-bureau?</h3>
<p className="text-lg text-gray-600 mb-6">Kontakt os +45 42 16 22 28 for en skræddersyet løsning.</p>
<a href="tel:+4542162228" className="inline-flex items-center justify-center gap-2 px-6 py-3.5 bg-gray-900 text-white rounded-2xl shadow-[0_8px_25px_rgba(17,24,39,0.22)] hover:bg-gray-800 transition-all outline-none border border-gray-800">Ring Nu</a>
</div>
</section>
</main>
<SiteFooter />
</div>
);
}

View File

@@ -0,0 +1,24 @@
.companies-react-root {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
}
.custom-scrollbar::-webkit-scrollbar { width: 6px; }
.custom-scrollbar::-webkit-scrollbar-track { background: transparent; }
.custom-scrollbar::-webkit-scrollbar-thumb { background-color: rgba(20, 184, 166, 0.2); border-radius: 20px; }
.custom-scrollbar::-webkit-scrollbar-thumb:hover { background-color: rgba(20, 184, 166, 0.4); }
@keyframes float-slow {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-8px); }
}
.animate-float-slow { animation: float-slow 6s ease-in-out infinite; }
.text-gradient-subtle {
display: inline-block;
line-height: 1.1;
padding-bottom: 0.08em;
background: linear-gradient(135deg, #1f2937 0%, #4b5563 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}

View File

@@ -1,9 +1,9 @@
import { useEffect, useState, type CSSProperties } from 'react'; import { type CSSProperties } from 'react';
import './homepage.css'; import './homepage.css';
import { SiteFooter } from '../../shared/components/SiteFooter'; import { SiteFooter } from '../../shared/components/SiteFooter';
import { SiteNavbar } from '../../shared/components/SiteNavbar';
import screen1Image from '../../../assets/screen1.png'; import screen1Image from '../../../assets/screen1.png';
import screen2Image from '../../../assets/screen2.png'; import screen2Image from '../../../assets/screen2.png';
import appIcon from '../../../assets/appicon.png';
interface IconifyIconProps { interface IconifyIconProps {
className?: string; className?: string;
@@ -65,190 +65,13 @@ const foundJobs = [
]; ];
export function HomePage() { export function HomePage() {
const [isNavOpen, setIsNavOpen] = useState(false);
const [isTipsOpen, setIsTipsOpen] = useState(false);
const [isHowOpen, setIsHowOpen] = useState(false);
const [isMobileTipsOpen, setIsMobileTipsOpen] = useState(false);
const [isMobileHowOpen, setIsMobileHowOpen] = useState(false);
useEffect(() => {
if (!isNavOpen) {
return undefined;
}
const previousOverflow = document.body.style.overflow;
document.body.style.overflow = 'hidden';
function handleEscape(event: KeyboardEvent) {
if (event.key === 'Escape') {
setIsNavOpen(false);
}
}
window.addEventListener('keydown', handleEscape);
return () => {
document.body.style.overflow = previousOverflow;
window.removeEventListener('keydown', handleEscape);
};
}, [isNavOpen]);
useEffect(() => {
function handleResize() {
if (window.innerWidth > 990) {
setIsNavOpen(false);
setIsMobileHowOpen(false);
setIsMobileTipsOpen(false);
}
}
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
useEffect(() => {
function handleClickOutside(event: MouseEvent) {
const target = event.target as HTMLElement | null;
if (!target?.closest('.homepage-how-dropdown')) {
setIsHowOpen(false);
}
if (!target?.closest('.homepage-tips-dropdown')) {
setIsTipsOpen(false);
}
}
document.addEventListener('click', handleClickOutside);
return () => document.removeEventListener('click', handleClickOutside);
}, []);
return ( return (
<div className="homepage-react-root scroll-smooth bg-[#f8fafc] relative min-h-screen text-gray-600 selection:bg-teal-100 selection:text-teal-900 overflow-x-hidden flex flex-col font-normal custom-scrollbar"> <div className="homepage-react-root scroll-smooth bg-[#f8fafc] relative min-h-screen text-gray-600 selection:bg-teal-100 selection:text-teal-900 overflow-x-hidden flex flex-col font-normal custom-scrollbar">
<div className="fixed top-[-15%] left-[-10%] w-[60vw] h-[60vw] rounded-full bg-gradient-to-br from-teal-400/30 to-emerald-300/10 blur-[140px] pointer-events-none z-0" /> <div className="fixed top-[-15%] left-[-10%] w-[60vw] h-[60vw] rounded-full bg-gradient-to-br from-teal-400/30 to-emerald-300/10 blur-[140px] pointer-events-none z-0" />
<div className="fixed bottom-[-15%] right-[-10%] w-[70vw] h-[70vw] rounded-full bg-gradient-to-tl from-indigo-500/20 to-purple-400/10 blur-[160px] pointer-events-none z-0" /> <div className="fixed bottom-[-15%] right-[-10%] w-[70vw] h-[70vw] rounded-full bg-gradient-to-tl from-indigo-500/20 to-purple-400/10 blur-[160px] pointer-events-none z-0" />
<div className="fixed top-[20%] right-[15%] w-[40vw] h-[40vw] rounded-full bg-gradient-to-tr from-cyan-400/20 to-blue-300/10 blur-[130px] pointer-events-none z-0" /> <div className="fixed top-[20%] right-[15%] w-[40vw] h-[40vw] rounded-full bg-gradient-to-tr from-cyan-400/20 to-blue-300/10 blur-[130px] pointer-events-none z-0" />
<nav className="homepage-nav fixed top-0 inset-x-0 z-50 h-16 bg-white/20 backdrop-blur-2xl border-b border-white/50 shadow-[0_4px_30px_rgba(0,0,0,0.03)] flex items-center justify-between px-6 lg:px-12 transition-all"> <SiteNavbar />
<a href="#" className="flex items-center gap-2 group outline-none">
<img
src={appIcon}
alt="Arbejd logo"
className="w-8 h-8 rounded-lg shadow-[0_4px_15px_rgba(49,103,201,0.2)] group-hover:shadow-[0_6px_20px_rgba(49,103,201,0.3)] transition-all group-hover:scale-105 object-cover"
/>
<span className="text-xl font-normal tracking-tight text-gray-900">
ARBEJD<span className="text-base">.com</span>
</span>
</a>
<div className="homepage-nav-links">
<a href="/pricing" className="text-base font-normal text-gray-600 hover:text-gray-900 transition-colors outline-none drop-shadow-sm">Priser</a>
<div className="homepage-how-dropdown">
<button
type="button"
className="homepage-how-trigger text-base font-normal text-gray-600 hover:text-gray-900 transition-colors outline-none drop-shadow-sm"
onClick={() => {
setIsHowOpen((current) => !current);
setIsTipsOpen(false);
}}
aria-expanded={isHowOpen}
>
Sådan virker det
<IconifyIcon icon="solar:alt-arrow-down-linear" className={`text-base transition-transform ${isHowOpen ? 'rotate-180' : ''}`} style={{ strokeWidth: 1.5 }} />
</button>
<div className={isHowOpen ? 'homepage-how-menu open' : 'homepage-how-menu'}>
<a href="#" onClick={() => setIsHowOpen(false)}>For virksomheder</a>
<a href="#" onClick={() => setIsHowOpen(false)}>For jobsøgere</a>
<a href="/pricing" onClick={() => setIsHowOpen(false)}>Priser</a>
<a href="#" onClick={() => setIsHowOpen(false)}>FAQ</a>
<a href="#" onClick={() => setIsHowOpen(false)}>Nyhedsbrev</a>
</div>
</div>
<div className="homepage-tips-dropdown">
<button
type="button"
className="homepage-tips-trigger text-base font-normal text-gray-600 hover:text-gray-900 transition-colors outline-none drop-shadow-sm"
onClick={() => {
setIsTipsOpen((current) => !current);
setIsHowOpen(false);
}}
aria-expanded={isTipsOpen}
>
Tips og tricks
<IconifyIcon icon="solar:alt-arrow-down-linear" className={`text-base transition-transform ${isTipsOpen ? 'rotate-180' : ''}`} style={{ strokeWidth: 1.5 }} />
</button>
<div className={isTipsOpen ? 'homepage-tips-menu open' : 'homepage-tips-menu'}>
<a href="/stories" onClick={() => setIsTipsOpen(false)}>Stories</a>
<a href="/jobordbogen" onClick={() => setIsTipsOpen(false)}>Jobordbogen</a>
</div>
</div>
</div>
<div className="homepage-nav-actions">
<a href="https://app.arbejd.com/" className="hidden sm:block text-base font-normal text-gray-700 hover:text-gray-900 transition-colors outline-none drop-shadow-sm">Log ind</a>
<a href="https://app.arbejd.com/welcome" className="text-base font-normal text-white bg-gradient-to-r from-gray-900 to-gray-800 hover:from-gray-800 hover:to-gray-700 px-5 py-2.5 rounded-full transition-all shadow-[0_4px_15px_rgba(0,0,0,0.1)] outline-none border border-gray-700">Opret dig</a>
</div>
<button
type="button"
className="homepage-nav-hamburger"
aria-expanded={isNavOpen}
aria-label={isNavOpen ? 'Luk menu' : 'Åbn menu'}
onClick={() => {
setIsNavOpen((current) => {
const next = !current;
if (!next) {
setIsMobileHowOpen(false);
setIsMobileTipsOpen(false);
}
return next;
});
}}
>
<IconifyIcon icon={isNavOpen ? 'solar:close-circle-linear' : 'solar:hamburger-menu-linear'} className="text-xl text-gray-800" style={{ strokeWidth: 1.8 }} />
</button>
<div className={isNavOpen ? 'homepage-nav-popup open' : 'homepage-nav-popup'}>
<a href="/pricing" onClick={() => setIsNavOpen(false)}>Priser</a>
<div className="homepage-nav-popup-group">
<button
type="button"
className="homepage-nav-popup-group-trigger"
onClick={() => {
setIsMobileHowOpen((current) => !current);
setIsMobileTipsOpen(false);
}}
aria-expanded={isMobileHowOpen}
>
Sådan virker det
<IconifyIcon icon="solar:alt-arrow-down-linear" className={`text-base transition-transform ${isMobileHowOpen ? 'rotate-180' : ''}`} style={{ strokeWidth: 1.5 }} />
</button>
<div className={isMobileHowOpen ? 'homepage-nav-popup-submenu open' : 'homepage-nav-popup-submenu'}>
<a href="#" onClick={() => setIsNavOpen(false)}>For virksomheder</a>
<a href="#" onClick={() => setIsNavOpen(false)}>For jobsøgere</a>
<a href="#" onClick={() => setIsNavOpen(false)}>FAQ</a>
<a href="#" onClick={() => setIsNavOpen(false)}>Nyhedsbrev</a>
</div>
</div>
<div className="homepage-nav-popup-group">
<button
type="button"
className="homepage-nav-popup-group-trigger"
onClick={() => {
setIsMobileTipsOpen((current) => !current);
setIsMobileHowOpen(false);
}}
aria-expanded={isMobileTipsOpen}
>
Tips og tricks
<IconifyIcon icon="solar:alt-arrow-down-linear" className={`text-base transition-transform ${isMobileTipsOpen ? 'rotate-180' : ''}`} style={{ strokeWidth: 1.5 }} />
</button>
<div className={isMobileTipsOpen ? 'homepage-nav-popup-submenu open' : 'homepage-nav-popup-submenu'}>
<a href="/stories" onClick={() => setIsNavOpen(false)}>Stories</a>
<a href="/jobordbogen" onClick={() => setIsNavOpen(false)}>Jobordbogen</a>
</div>
</div>
<a href="https://app.arbejd.com/" onClick={() => setIsNavOpen(false)}>Log ind</a>
<a href="https://app.arbejd.com/welcome" className="homepage-nav-popup-cta" onClick={() => setIsNavOpen(false)}>Opret dig</a>
</div>
</nav>
<main className="flex-1 relative z-10 pt-16"> <main className="flex-1 relative z-10 pt-16">
<section className="relative pt-24 pb-32 px-6 lg:px-12 max-w-7xl mx-auto flex flex-col items-center text-center"> <section className="relative pt-24 pb-32 px-6 lg:px-12 max-w-7xl mx-auto flex flex-col items-center text-center">
@@ -260,13 +83,15 @@ export function HomePage() {
</div> </div>
<h1 className="text-5xl md:text-6xl lg:text-7xl font-medium tracking-tight text-gradient mb-8 leading-tight max-w-4xl drop-shadow-sm"> <h1 className="text-5xl md:text-6xl lg:text-7xl font-medium tracking-tight text-gradient mb-8 leading-tight max-w-4xl drop-shadow-sm">
Arbejd, Danmarks Arbejd.com
<br /> <br />
Nye Jobportal Din hurtigste vej til
<br />
dit næste job
</h1> </h1>
<p className="text-xl md:text-2xl text-gray-600 mb-10 max-w-2xl font-normal leading-relaxed drop-shadow-sm"> <p className="text-xl md:text-2xl text-gray-600 mb-10 max-w-2xl font-normal leading-relaxed drop-shadow-sm">
Opdag drømmejobbet med kraften fra AI. Vi matcher dine færdigheder med de perfekte muligheder og hjælper dig hele vejen til samtalen. CV, ansøgninger, jobmatch og interviewtræning samlet ét sted med din personlige AI-assistent.
</p> </p>
<a href="https://app.arbejd.com" className="group relative inline-flex items-center gap-3 px-8 py-4 bg-gradient-to-r from-gray-900 via-gray-800 to-gray-900 text-white rounded-full font-normal text-lg overflow-hidden shadow-[0_8px_25px_rgba(17,24,39,0.25)] hover:shadow-[0_12px_35px_rgba(17,24,39,0.35)] transition-all outline-none border border-gray-700 hover:-translate-y-0.5"> <a href="https://app.arbejd.com" className="group relative inline-flex items-center gap-3 px-8 py-4 bg-gradient-to-r from-gray-900 via-gray-800 to-gray-900 text-white rounded-full font-normal text-lg overflow-hidden shadow-[0_8px_25px_rgba(17,24,39,0.25)] hover:shadow-[0_12px_35px_rgba(17,24,39,0.35)] transition-all outline-none border border-gray-700 hover:-translate-y-0.5">

View File

@@ -1,5 +1,6 @@
import { useEffect, useMemo, useState, type CSSProperties } from 'react'; import { useMemo, type CSSProperties } from 'react';
import { SiteFooter } from '../../shared/components/SiteFooter'; import { SiteFooter } from '../../shared/components/SiteFooter';
import { SiteNavbar } from '../../shared/components/SiteNavbar';
import { dictCards, slugifyJobordbogenTitle } from './JobordbogenPage'; import { dictCards, slugifyJobordbogenTitle } from './JobordbogenPage';
import './jobordbogen.css'; import './jobordbogen.css';
@@ -13,50 +14,11 @@ function IconifyIcon({ className, icon, style }: IconifyIconProps) {
return <iconify-icon className={className} icon={icon} style={style} />; return <iconify-icon className={className} icon={icon} style={style} />;
} }
function Logo() {
return (
<svg viewBox="0 0 100 100" className="w-8 h-8 rounded-lg shadow-[0_4px_15px_rgba(49,103,201,0.2)] group-hover:shadow-[0_6px_20px_rgba(49,103,201,0.3)] transition-all group-hover:scale-105">
<defs>
<linearGradient id="jobEntryNavBg" x1="0%" y1="100%" x2="100%" y2="0%">
<stop offset="0%" stopColor="#1A9A75" />
<stop offset="100%" stopColor="#3167C9" />
</linearGradient>
<linearGradient id="jobEntryNavFg" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stopColor="#6ACEEB" />
<stop offset="100%" stopColor="#46D3B6" />
</linearGradient>
</defs>
<rect width="100" height="100" fill="url(#jobEntryNavBg)" />
<path fillRule="evenodd" clipRule="evenodd" d="M 60 15 L 72 15 L 72 85 L 60 85 L 60 72.98 A 28 28 0 1 1 60 27.02 Z M 44 34 A 16 16 0 1 0 44 66 A 16 16 0 1 0 44 34 Z" fill="url(#jobEntryNavFg)" />
</svg>
);
}
export function JobordbogenEntryPage() { export function JobordbogenEntryPage() {
const path = useMemo(() => window.location.pathname, []); const path = useMemo(() => window.location.pathname, []);
const slug = path.split('/').filter(Boolean).at(-1) ?? ''; const slug = path.split('/').filter(Boolean).at(-1) ?? '';
const currentCard = useMemo(() => dictCards.find((card) => slugifyJobordbogenTitle(card.title) === slug) ?? null, [slug]); const currentCard = useMemo(() => dictCards.find((card) => slugifyJobordbogenTitle(card.title) === slug) ?? null, [slug]);
const relatedCards = useMemo(() => dictCards.filter((card) => card.title !== currentCard?.title).slice(0, 3), [currentCard?.title]); const relatedCards = useMemo(() => dictCards.filter((card) => card.title !== currentCard?.title).slice(0, 3), [currentCard?.title]);
const [isNavOpen, setIsNavOpen] = useState(false);
const [isTipsOpen, setIsTipsOpen] = useState(false);
const [isHowOpen, setIsHowOpen] = useState(false);
useEffect(() => {
if (!isNavOpen) return undefined;
const previousOverflow = document.body.style.overflow;
document.body.style.overflow = 'hidden';
return () => {
document.body.style.overflow = previousOverflow;
};
}, [isNavOpen]);
useEffect(() => {
function handleResize() {
if (window.innerWidth > 990) setIsNavOpen(false);
}
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
if (!currentCard) { if (!currentCard) {
return ( return (
@@ -73,52 +35,7 @@ export function JobordbogenEntryPage() {
<div className="fixed bottom-[-15%] right-[-10%] w-[70vw] h-[70vw] rounded-full bg-gradient-to-tl from-indigo-500/20 to-purple-400/10 blur-[160px] pointer-events-none z-0" /> <div className="fixed bottom-[-15%] right-[-10%] w-[70vw] h-[70vw] rounded-full bg-gradient-to-tl from-indigo-500/20 to-purple-400/10 blur-[160px] pointer-events-none z-0" />
<div className="fixed top-[20%] right-[15%] w-[40vw] h-[40vw] rounded-full bg-gradient-to-tr from-cyan-400/20 to-blue-300/10 blur-[130px] pointer-events-none z-0" /> <div className="fixed top-[20%] right-[15%] w-[40vw] h-[40vw] rounded-full bg-gradient-to-tr from-cyan-400/20 to-blue-300/10 blur-[130px] pointer-events-none z-0" />
<nav className="fixed top-0 inset-x-0 z-50 h-16 bg-white/20 backdrop-blur-2xl border-b border-white/50 shadow-[0_4px_30px_rgba(0,0,0,0.03)] flex items-center justify-between px-6 lg:px-12 transition-all"> <SiteNavbar activeTab="tips" activeTipsItem="jobordbogen" />
<a href="/home" className="flex items-center gap-2 group outline-none">
<Logo />
<span className="text-xl font-normal tracking-tight text-gray-900 uppercase">ARBEJD</span>
</a>
<div className="job-nav-links">
<a href="/pricing" className="text-base font-normal text-gray-600 hover:text-gray-900 transition-colors outline-none drop-shadow-sm">Priser</a>
<div className="job-how-dropdown">
<button type="button" className="job-how-trigger text-base font-normal text-gray-600 hover:text-gray-900 transition-colors outline-none drop-shadow-sm" onClick={() => { setIsHowOpen((c) => !c); setIsTipsOpen(false); }} aria-expanded={isHowOpen}>
Sådan virker det
<IconifyIcon icon="solar:alt-arrow-down-linear" className={`text-base transition-transform ${isHowOpen ? 'rotate-180' : ''}`} style={{ strokeWidth: 1.5 }} />
</button>
<div className={isHowOpen ? 'job-how-menu open' : 'job-how-menu'}>
<a href="#" onClick={() => setIsHowOpen(false)}>For virksomheder</a>
<a href="#" onClick={() => setIsHowOpen(false)}>For jobsøgere</a>
<a href="/pricing" onClick={() => setIsHowOpen(false)}>Priser</a>
<a href="#" onClick={() => setIsHowOpen(false)}>FAQ</a>
<a href="#" onClick={() => setIsHowOpen(false)}>Nyhedsbrev</a>
</div>
</div>
<div className="job-tips-dropdown">
<button type="button" className="job-tips-trigger text-base font-normal text-gray-900 transition-colors outline-none drop-shadow-sm border-b-2 border-teal-500 pb-0.5" onClick={() => { setIsTipsOpen((c) => !c); setIsHowOpen(false); }} aria-expanded={isTipsOpen}>
Tips og tricks
<IconifyIcon icon="solar:alt-arrow-down-linear" className={`text-base transition-transform ${isTipsOpen ? 'rotate-180' : ''}`} style={{ strokeWidth: 1.5 }} />
</button>
<div className={isTipsOpen ? 'job-tips-menu open' : 'job-tips-menu'}>
<a href="/stories" onClick={() => setIsTipsOpen(false)}>Stories</a>
<a href="/jobordbogen" className="active" onClick={() => setIsTipsOpen(false)}>Jobordbogen</a>
</div>
</div>
</div>
<div className="job-nav-actions">
<a href="#" className="hidden sm:block text-base font-normal text-gray-700 hover:text-gray-900 transition-colors outline-none drop-shadow-sm">Log ind</a>
<a href="#" className="text-base font-normal text-white bg-gradient-to-r from-gray-900 to-gray-800 hover:from-gray-800 hover:to-gray-700 px-5 py-2.5 rounded-full transition-all shadow-[0_4px_15px_rgba(0,0,0,0.1)] outline-none border border-gray-700">Opret dig</a>
</div>
<button type="button" className="job-nav-hamburger" aria-expanded={isNavOpen} aria-label={isNavOpen ? 'Luk menu' : 'Åbn menu'} onClick={() => setIsNavOpen((c) => !c)}>
<IconifyIcon icon={isNavOpen ? 'solar:close-circle-linear' : 'solar:hamburger-menu-linear'} className="text-xl text-gray-800" style={{ strokeWidth: 1.8 }} />
</button>
<div className={isNavOpen ? 'job-nav-popup open' : 'job-nav-popup'}>
<a href="/pricing" onClick={() => setIsNavOpen(false)}>Priser</a>
<a href="/stories" onClick={() => setIsNavOpen(false)}>Tips og tricks: Stories</a>
<a href="/jobordbogen" onClick={() => setIsNavOpen(false)}>Tips og tricks: Jobordbogen</a>
<a href="#" onClick={() => setIsNavOpen(false)}>Log ind</a>
<a href="#" className="job-nav-popup-cta" onClick={() => setIsNavOpen(false)}>Opret dig</a>
</div>
</nav>
<main className="flex-1 relative z-10 pt-16"> <main className="flex-1 relative z-10 pt-16">
<section className="relative pt-24 pb-12 px-6 lg:px-12 max-w-7xl mx-auto flex flex-col items-center text-center"> <section className="relative pt-24 pb-12 px-6 lg:px-12 max-w-7xl mx-auto flex flex-col items-center text-center">

View File

@@ -1,6 +1,7 @@
import { useEffect, useMemo, useState, type CSSProperties } from 'react'; import { useMemo, useState, type CSSProperties } from 'react';
import './jobordbogen.css'; import './jobordbogen.css';
import { SiteFooter } from '../../shared/components/SiteFooter'; import { SiteFooter } from '../../shared/components/SiteFooter';
import { SiteNavbar } from '../../shared/components/SiteNavbar';
type ViewMode = 'dict' | 'academy'; type ViewMode = 'dict' | 'academy';
@@ -14,27 +15,6 @@ function IconifyIcon({ className, icon, style }: IconifyIconProps) {
return <iconify-icon className={className} icon={icon} style={style} />; return <iconify-icon className={className} icon={icon} style={style} />;
} }
function Logo({ nav = true }: { nav?: boolean }) {
const idPrefix = nav ? 'jobNav' : 'jobFooter';
return (
<svg viewBox="0 0 100 100" className={nav ? 'w-8 h-8 rounded-lg shadow-[0_4px_15px_rgba(49,103,201,0.2)] group-hover:shadow-[0_6px_20px_rgba(49,103,201,0.3)] transition-all group-hover:scale-105' : 'w-8 h-8 rounded-lg shadow-sm transition-transform group-hover:scale-105'}>
<defs>
<linearGradient id={`${idPrefix}Bg`} x1="0%" y1="100%" x2="100%" y2="0%">
<stop offset="0%" stopColor="#1A9A75" />
<stop offset="100%" stopColor="#3167C9" />
</linearGradient>
<linearGradient id={`${idPrefix}Fg`} x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stopColor="#6ACEEB" />
<stop offset="100%" stopColor="#46D3B6" />
</linearGradient>
</defs>
<rect width="100" height="100" fill={`url(#${idPrefix}Bg)`} />
<path fillRule="evenodd" clipRule="evenodd" d="M 60 15 L 72 15 L 72 85 L 60 85 L 60 72.98 A 28 28 0 1 1 60 27.02 Z M 44 34 A 16 16 0 1 0 44 66 A 16 16 0 1 0 44 34 Z" fill={`url(#${idPrefix}Fg)`} />
</svg>
);
}
export interface DictCard { export interface DictCard {
accent: string; accent: string;
body: string; body: string;
@@ -662,56 +642,6 @@ export function JobordbogenPage() {
const path = useMemo(() => window.location.pathname, []); const path = useMemo(() => window.location.pathname, []);
const [mode, setMode] = useState<ViewMode>(path === '/academy' ? 'academy' : 'dict'); const [mode, setMode] = useState<ViewMode>(path === '/academy' ? 'academy' : 'dict');
const [searchQuery, setSearchQuery] = useState(''); const [searchQuery, setSearchQuery] = useState('');
const [isNavOpen, setIsNavOpen] = useState(false);
const [isTipsOpen, setIsTipsOpen] = useState(false);
const [isHowOpen, setIsHowOpen] = useState(false);
useEffect(() => {
if (!isNavOpen) {
return undefined;
}
const previousOverflow = document.body.style.overflow;
document.body.style.overflow = 'hidden';
function handleEscape(event: KeyboardEvent) {
if (event.key === 'Escape') {
setIsNavOpen(false);
}
}
window.addEventListener('keydown', handleEscape);
return () => {
document.body.style.overflow = previousOverflow;
window.removeEventListener('keydown', handleEscape);
};
}, [isNavOpen]);
useEffect(() => {
function handleResize() {
if (window.innerWidth > 990) {
setIsNavOpen(false);
}
}
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
useEffect(() => {
function handleClickOutside(event: MouseEvent) {
const target = event.target as HTMLElement | null;
if (!target?.closest('.job-how-dropdown')) {
setIsHowOpen(false);
}
if (!target?.closest('.job-tips-dropdown')) {
setIsTipsOpen(false);
}
}
document.addEventListener('click', handleClickOutside);
return () => document.removeEventListener('click', handleClickOutside);
}, []);
const isDict = mode === 'dict'; const isDict = mode === 'dict';
const normalizedSearch = searchQuery.trim().toLowerCase(); const normalizedSearch = searchQuery.trim().toLowerCase();
@@ -729,76 +659,7 @@ export function JobordbogenPage() {
<div className="fixed bottom-[-15%] right-[-10%] w-[70vw] h-[70vw] rounded-full bg-gradient-to-tl from-indigo-500/20 to-purple-400/10 blur-[160px] pointer-events-none z-0" /> <div className="fixed bottom-[-15%] right-[-10%] w-[70vw] h-[70vw] rounded-full bg-gradient-to-tl from-indigo-500/20 to-purple-400/10 blur-[160px] pointer-events-none z-0" />
<div className="fixed top-[20%] right-[15%] w-[40vw] h-[40vw] rounded-full bg-gradient-to-tr from-cyan-400/20 to-blue-300/10 blur-[130px] pointer-events-none z-0" /> <div className="fixed top-[20%] right-[15%] w-[40vw] h-[40vw] rounded-full bg-gradient-to-tr from-cyan-400/20 to-blue-300/10 blur-[130px] pointer-events-none z-0" />
<nav className="fixed top-0 inset-x-0 z-50 h-16 bg-white/20 backdrop-blur-2xl border-b border-white/50 shadow-[0_4px_30px_rgba(0,0,0,0.03)] flex items-center justify-between px-6 lg:px-12 transition-all"> <SiteNavbar activeTab="tips" activeTipsItem="jobordbogen" />
<a href="/home" className="flex items-center gap-2 group outline-none">
<Logo nav />
<span className="text-xl font-normal tracking-tight text-gray-900 uppercase">ARBEJD</span>
</a>
<div className="job-nav-links">
<a href="/pricing" className="text-base font-normal text-gray-600 hover:text-gray-900 transition-colors outline-none drop-shadow-sm">Priser</a>
<div className="job-how-dropdown">
<button
type="button"
className="job-how-trigger text-base font-normal text-gray-600 hover:text-gray-900 transition-colors outline-none drop-shadow-sm"
onClick={() => {
setIsHowOpen((current) => !current);
setIsTipsOpen(false);
}}
aria-expanded={isHowOpen}
>
Sådan virker det
<IconifyIcon icon="solar:alt-arrow-down-linear" className={`text-base transition-transform ${isHowOpen ? 'rotate-180' : ''}`} style={{ strokeWidth: 1.5 }} />
</button>
<div className={isHowOpen ? 'job-how-menu open' : 'job-how-menu'}>
<a href="#" onClick={() => setIsHowOpen(false)}>For virksomheder</a>
<a href="#" onClick={() => setIsHowOpen(false)}>For jobsøgere</a>
<a href="/pricing" onClick={() => setIsHowOpen(false)}>Priser</a>
<a href="#" onClick={() => setIsHowOpen(false)}>FAQ</a>
<a href="#" onClick={() => setIsHowOpen(false)}>Nyhedsbrev</a>
</div>
</div>
<div className="job-tips-dropdown">
<button
type="button"
className="job-tips-trigger text-base font-normal text-gray-900 transition-colors outline-none drop-shadow-sm border-b-2 border-teal-500 pb-0.5"
onClick={() => {
setIsTipsOpen((current) => !current);
setIsHowOpen(false);
}}
aria-expanded={isTipsOpen}
>
Tips og tricks
<IconifyIcon icon="solar:alt-arrow-down-linear" className={`text-base transition-transform ${isTipsOpen ? 'rotate-180' : ''}`} style={{ strokeWidth: 1.5 }} />
</button>
<div className={isTipsOpen ? 'job-tips-menu open' : 'job-tips-menu'}>
<a href="/stories" onClick={() => setIsTipsOpen(false)}>Stories</a>
<a href="/jobordbogen" className="active" onClick={() => setIsTipsOpen(false)}>Jobordbogen</a>
</div>
</div>
</div>
<div className="job-nav-actions">
<a href="#" className="hidden sm:block text-base font-normal text-gray-700 hover:text-gray-900 transition-colors outline-none drop-shadow-sm">Log ind</a>
<a href="#" className="text-base font-normal text-white bg-gradient-to-r from-gray-900 to-gray-800 hover:from-gray-800 hover:to-gray-700 px-5 py-2.5 rounded-full transition-all shadow-[0_4px_15px_rgba(0,0,0,0.1)] outline-none border border-gray-700">Opret dig</a>
</div>
<button type="button" className="job-nav-hamburger" aria-expanded={isNavOpen} aria-label={isNavOpen ? 'Luk menu' : 'Åbn menu'} onClick={() => setIsNavOpen((current) => !current)}>
<IconifyIcon icon={isNavOpen ? 'solar:close-circle-linear' : 'solar:hamburger-menu-linear'} className="text-xl text-gray-800" style={{ strokeWidth: 1.8 }} />
</button>
<div className={isNavOpen ? 'job-nav-popup open' : 'job-nav-popup'}>
<a href="/pricing" onClick={() => setIsNavOpen(false)}>Priser</a>
<a href="#" onClick={() => setIsNavOpen(false)}>Sådan virker det: For virksomheder</a>
<a href="#" onClick={() => setIsNavOpen(false)}>Sådan virker det: For jobsøgere</a>
<a href="#" onClick={() => setIsNavOpen(false)}>Sådan virker det: FAQ</a>
<a href="#" onClick={() => setIsNavOpen(false)}>Sådan virker det: Nyhedsbrev</a>
<a href="/stories" onClick={() => setIsNavOpen(false)}>Tips og tricks: Stories</a>
<a href="/jobordbogen" onClick={() => setIsNavOpen(false)}>Tips og tricks: Jobordbogen</a>
<a href="#" onClick={() => setIsNavOpen(false)}>Log ind</a>
<a href="#" className="job-nav-popup-cta" onClick={() => setIsNavOpen(false)}>Opret dig</a>
</div>
</nav>
<main className="flex-1 relative z-10 pt-16"> <main className="flex-1 relative z-10 pt-16">
<section className="relative pt-24 pb-12 px-6 lg:px-12 max-w-7xl mx-auto flex flex-col items-center text-center"> <section className="relative pt-24 pb-12 px-6 lg:px-12 max-w-7xl mx-auto flex flex-col items-center text-center">

View File

@@ -0,0 +1,256 @@
import { type CSSProperties, type ReactNode } from 'react';
import './jobseekers.css';
import { SiteFooter } from '../../shared/components/SiteFooter';
import { SiteNavbar } from '../../shared/components/SiteNavbar';
import screen1Image from '../../../assets/screen1.png';
import screen2Image from '../../../assets/screen2.png';
interface IconifyIconProps {
className?: string;
icon: string;
style?: CSSProperties;
}
function IconifyIcon({ className, icon, style }: IconifyIconProps) {
return <iconify-icon className={className} icon={icon} style={style} />;
}
function PhoneMock({
image,
alt,
animatedClass,
children,
}: {
image: string;
alt: string;
animatedClass?: string;
children?: ReactNode;
}) {
return (
<div className={`relative shrink-0 w-[260px] h-[540px] rounded-[3rem] p-3 bg-gradient-to-br from-white/35 to-white/10 backdrop-blur-3xl border border-white/50 shadow-[0_20px_45px_rgba(0,0,0,0.12),inset_0_0_20px_rgba(255,255,255,0.5)] ${animatedClass ?? ''}`}>
<div className="absolute -left-[2px] top-28 w-1 h-8 bg-white/40 border border-white/50 rounded-l-md shadow-sm" />
<div className="absolute -left-[2px] top-40 w-1 h-14 bg-white/40 border border-white/50 rounded-l-md shadow-sm" />
<div className="absolute -left-[2px] top-56 w-1 h-14 bg-white/40 border border-white/50 rounded-l-md shadow-sm" />
<div className="absolute -right-[2px] top-44 w-1 h-20 bg-white/40 border border-white/50 rounded-r-md shadow-sm" />
<div className="relative w-full h-full rounded-[2.4rem] bg-white overflow-hidden border border-white/70">
<img src={image} alt={alt} className="absolute inset-0 w-full h-full object-cover" />
<div className="absolute top-2 left-1/2 -translate-x-1/2 w-[84px] h-[24px] bg-black rounded-full z-10" />
<div className="absolute bottom-1.5 left-1/2 -translate-x-1/2 w-1/3 h-[4px] bg-white/90 rounded-full z-10 shadow-sm" />
</div>
{children}
</div>
);
}
type Pill = {
icon: string;
label: string;
position: string;
tone: string;
};
type FeatureSection = {
description: string;
image: string;
pills?: Pill[];
title: string;
};
const featureSections: FeatureSection[] = [
{
title: 'Job Search',
description:
'Appen viser de stillinger, der matcher dig bedst, baseret på dit CV, dine kompetencer, ønsket geografi, arbejdstid, branche og de filtre, du selv vælger. Resultaterne bliver løbende forbedret, når du interagerer med opslag og opdaterer dine præferencer.',
image: screen1Image,
},
{
title: 'CV Management',
description:
'Tilføj erfaring, uddannelse, kvalifikationer, certifikater, sprog og kørekort i ét samlet flow. Når din profil er komplet, bliver du lettere fundet af relevante arbejdsgivere, og dine ansøgninger står stærkere i match-processen.',
image: screen2Image,
pills: [
{ icon: 'solar:case-linear', label: 'Erfaring', position: '-top-3 -left-12', tone: 'text-teal-700 bg-teal-50 border-teal-200' },
{ icon: 'solar:diploma-linear', label: 'Uddannelse', position: 'top-20 -right-14', tone: 'text-indigo-700 bg-indigo-50 border-indigo-200' },
{ icon: 'solar:star-linear', label: 'Kvalifikationer', position: 'top-48 -left-16', tone: 'text-amber-700 bg-amber-50 border-amber-200' },
{ icon: 'solar:verified-check-linear', label: 'Certifikater', position: 'bottom-32 -right-16', tone: 'text-emerald-700 bg-emerald-50 border-emerald-200' },
{ icon: 'solar:global-linear', label: 'Sprog', position: 'bottom-16 -left-12', tone: 'text-sky-700 bg-sky-50 border-sky-200' },
{ icon: 'solar:card-linear', label: 'Kørekort', position: '-bottom-3 right-0', tone: 'text-rose-700 bg-rose-50 border-rose-200' },
],
},
{
title: 'AI-agenter',
description:
'Dine AI-agenter søger hver dag efter de bedste jobmatches, sender dig relevante notifikationer og giver konkrete anbefalinger til forbedringer i dit CV. Det gør din jobsøgning mere målrettet, uden at du selv skal overvåge alle nye opslag.',
image: screen1Image,
pills: [
{ icon: 'solar:bell-bing-linear', label: 'Nyt match: Elektriker', position: '-top-4 -left-16', tone: 'text-teal-700 bg-teal-50 border-teal-200' },
{ icon: 'solar:document-add-linear', label: 'CV-tip: Tilføj certifikat', position: 'top-24 -right-24', tone: 'text-indigo-700 bg-indigo-50 border-indigo-200' },
{ icon: 'solar:briefcase-linear', label: 'Nyt match: Kok', position: 'bottom-28 -left-14', tone: 'text-amber-700 bg-amber-50 border-amber-200' },
{ icon: 'solar:pen-linear', label: 'CV-tip: Mere erfaring', position: 'bottom-10 -right-20', tone: 'text-emerald-700 bg-emerald-50 border-emerald-200' },
],
},
{
title: 'Simulator',
description:
'Simulatoren hjælper dig med at træne jobsamtaler i realistiske scenarier. Efter hver session får du en tydelig evaluering med forbedringspunkter til svar, struktur, gennemslagskraft og forberedelse til den konkrete stilling.',
image: screen2Image,
},
{
title: 'Generér jobansøgning',
description:
'Generér en målrettet ansøgning ud fra stillingsopslag, din profil og dine erfaringer. Du får et stærkt første udkast, som er let at tilpasse, så du hurtigere går fra interessant job til klar ansøgning.',
image: screen1Image,
},
{
title: 'Ansøg med ét klik',
description:
'Når din profil er sat op, kan du søge relevante stillinger med minimal friktion og følge hele processen ét sted. Du får overblik over gemte jobs, ansøgninger, svar og næste skridt direkte i appen.',
image: screen2Image,
},
];
const experienceCards = [
{
icon: 'solar:user-id-linear',
title: 'Profil & præferencer',
text: 'Vi bruger dine egne profiloplysninger, jobønsker og filtervalg for at vise dig mere relevante stillinger.',
},
{
icon: 'solar:document-text-linear',
title: 'CV-indhold',
text: 'Erfaring, uddannelse, kvalifikationer og certifikater bruges til at forbedre matching, ansøgninger og anbefalinger.',
},
{
icon: 'solar:bell-bing-linear',
title: 'Notifikationer',
text: 'Aktivitet i appen hjælper os med at sende mere præcise notifikationer om nye matches og relevante muligheder.',
},
{
icon: 'solar:chat-round-line-linear',
title: 'Samtaleforberedelse',
text: 'Simulator-feedback bruges til at foreslå konkrete forbedringer, så du står stærkere til den rigtige samtale.',
},
{
icon: 'solar:shield-check-linear',
title: 'Kontrol over dine data',
text: 'Du bestemmer, hvad du udfylder, og kan løbende opdatere din profil, så oplysningerne afspejler din situation.',
},
{
icon: 'solar:settings-linear',
title: 'En samlet oplevelse',
text: 'Alt hænger sammen: jobsøgning, CV, ansøgning, notifikationer og træning i én samlet brugeroplevelse.',
},
];
export function JobSearchersPage() {
return (
<div className="jobseekers-react-root scroll-smooth bg-[#f8fafc] relative min-h-screen text-gray-600 selection:bg-teal-100 selection:text-teal-900 overflow-x-hidden flex flex-col font-normal custom-scrollbar">
<div className="fixed top-[-15%] left-[-10%] w-[60vw] h-[60vw] rounded-full bg-gradient-to-br from-teal-400/30 to-emerald-300/10 blur-[140px] pointer-events-none z-0" />
<div className="fixed bottom-[-15%] right-[-10%] w-[70vw] h-[70vw] rounded-full bg-gradient-to-tl from-indigo-500/20 to-purple-400/10 blur-[160px] pointer-events-none z-0" />
<SiteNavbar activeTab="how" activeHowItem="jobseekers" />
<main className="flex-1 relative z-10 pt-16">
<section className="py-20 px-6 lg:px-12 max-w-7xl mx-auto">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12 items-center">
<div>
<h1 className="text-4xl md:text-6xl font-medium tracking-tight text-gradient-subtle mb-6">Hvorfor ikke lade jobbet finde dig?</h1>
<ul className="space-y-3 mb-8">
{[
'Opret en profil på under 2 minutter',
'Få hjælp hele vejen fra oprettelse til job',
'Søg blandt alle stillinger og brancher',
].map((item) => (
<li key={item} className="flex items-start gap-3 text-base text-gray-700">
<IconifyIcon icon="solar:check-circle-linear" className="text-xl text-teal-600 mt-0.5" style={{ strokeWidth: 1.5 }} />
<span>{item}</span>
</li>
))}
</ul>
<div className="flex flex-wrap gap-4 mb-4">
<a href="https://app.arbejd.com/welcome" className="inline-flex items-center justify-center gap-2 px-6 py-3.5 bg-gray-900 text-white rounded-2xl shadow-[0_8px_25px_rgba(17,24,39,0.22)] hover:bg-gray-800 transition-all outline-none border border-gray-800">Opret Dig</a>
</div>
<p className="text-sm text-gray-500 mb-3">Eller download Arbejd.com app&apos;en</p>
<div className="flex flex-col sm:flex-row gap-3">
<a href="https://apps.apple.com/dk/app/arbejd-com/id1466763785" target="_blank" rel="noopener noreferrer" className="inline-flex items-center justify-center gap-2 px-5 py-3 rounded-2xl bg-white/70 border border-white/80 shadow-sm text-gray-800">
<IconifyIcon icon="mdi:apple" className="text-xl" />
<span className="text-sm font-medium">Download from App Store</span>
</a>
<a href="https://play.google.com/store/apps/details?id=arbejd.com" target="_blank" rel="noopener noreferrer" className="inline-flex items-center justify-center gap-2 px-5 py-3 rounded-2xl bg-white/70 border border-white/80 shadow-sm text-gray-800">
<IconifyIcon icon="mdi:google-play" className="text-lg text-teal-600" />
<span className="text-sm font-medium">Download from Google Play</span>
</a>
</div>
</div>
<div className="relative flex justify-center">
<PhoneMock image={screen1Image} alt="Arbejd.com app showing a list of jobs" animatedClass="animate-float-phone" />
<div className="absolute -bottom-6 right-0 w-20 h-20 rounded-2xl bg-white/80 border border-white/80 shadow-lg flex items-center justify-center animate-float-soft">
<IconifyIcon icon="solar:case-minimalistic-linear" className="text-4xl text-teal-600" style={{ strokeWidth: 1.5 }} />
</div>
</div>
</div>
</section>
{featureSections.map((section, index) => {
const reverse = index % 2 === 1;
const phoneFloatClass = reverse ? 'animate-float-phone-alt' : 'animate-float-phone';
return (
<section key={section.title} className="py-20 px-6 lg:px-12 max-w-7xl mx-auto border-t border-white/40">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12 items-center">
<div className={reverse ? 'order-2 lg:order-2' : 'order-2 lg:order-1'}>
<div className="text-xs uppercase tracking-widest text-teal-700 font-medium mb-3">Feature {index + 1}</div>
<h2 className="text-3xl md:text-4xl font-medium tracking-tight text-gradient-subtle mb-4">{section.title}</h2>
<p className="text-lg text-gray-600">{section.description}</p>
</div>
<div className={reverse ? 'order-1 lg:order-1 flex justify-center lg:justify-start' : 'order-1 lg:order-2 flex justify-center lg:justify-end'}>
<div className="relative">
<PhoneMock image={section.image} alt={section.title} animatedClass={phoneFloatClass}>
{section.pills?.map((pill) => (
<div
key={pill.label}
className={`hidden sm:flex absolute ${pill.position} px-3 py-1.5 rounded-full border bg-white/90 backdrop-blur-md shadow-md items-center gap-1.5 text-xs font-medium ${pill.tone} animate-float-soft`}
>
<IconifyIcon icon={pill.icon} className="text-sm" style={{ strokeWidth: 1.5 }} />
<span>{pill.label}</span>
</div>
))}
</PhoneMock>
</div>
</div>
</div>
</section>
);
})}
<section className="py-20 px-6 lg:px-12 max-w-7xl mx-auto border-t border-white/40">
<div className="text-center max-w-3xl mx-auto mb-10">
<div className="text-xs uppercase tracking-widest text-teal-700 font-medium mb-3">Sådan fungerer oplevelsen</div>
<h2 className="text-3xl md:text-4xl font-medium tracking-tight text-gradient-subtle mb-4">Hele app-oplevelsen samlet ét sted</h2>
<p className="text-lg text-gray-600">
Arbejd.com kombinerer jobsøgning, profil, ansøgninger og interviewtræning i én platform. Her er, hvordan vi bruger information til at gøre oplevelsen mere relevant for dig.
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{experienceCards.map((card) => (
<div key={card.title} className="p-6 bg-gradient-to-br from-white/70 to-white/30 backdrop-blur-xl border border-white/80 rounded-3xl shadow-[0_4px_20px_rgba(0,0,0,0.02)] hover:shadow-[0_8px_30px_rgba(0,0,0,0.06)] transition-all group">
<div className="w-12 h-12 rounded-2xl bg-gradient-to-br from-teal-50 to-white border border-teal-100/50 shadow-sm flex items-center justify-center mb-4 group-hover:scale-110 transition-transform">
<IconifyIcon icon={card.icon} className="text-2xl text-teal-600" style={{ strokeWidth: 1.5 }} />
</div>
<h3 className="text-lg font-medium text-gray-900 mb-2 tracking-tight">{card.title}</h3>
<p className="text-base text-gray-600 leading-relaxed">{card.text}</p>
</div>
))}
</div>
</section>
</main>
<SiteFooter />
</div>
);
}

View File

@@ -0,0 +1,36 @@
.jobseekers-react-root {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
}
.custom-scrollbar::-webkit-scrollbar { width: 6px; }
.custom-scrollbar::-webkit-scrollbar-track { background: transparent; }
.custom-scrollbar::-webkit-scrollbar-thumb { background-color: rgba(20, 184, 166, 0.2); border-radius: 20px; }
.custom-scrollbar::-webkit-scrollbar-thumb:hover { background-color: rgba(20, 184, 166, 0.4); }
@keyframes float-phone {
0%, 100% { transform: translateY(0) rotate(-3deg); }
50% { transform: translateY(-10px) rotate(-1deg); }
}
@keyframes float-phone-alt {
0%, 100% { transform: translateY(6px) rotate(3deg); }
50% { transform: translateY(-6px) rotate(2deg); }
}
@keyframes float-soft {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-7px); }
}
.animate-float-phone { animation: float-phone 8s ease-in-out infinite; }
.animate-float-phone-alt { animation: float-phone-alt 10s ease-in-out infinite; }
.animate-float-soft { animation: float-soft 6s ease-in-out infinite; }
.text-gradient-subtle {
display: inline-block;
line-height: 1.1;
padding-bottom: 0.08em;
background: linear-gradient(135deg, #1f2937 0%, #4b5563 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}

View File

@@ -1,6 +1,7 @@
import { useEffect, useMemo, useState, type CSSProperties } from 'react'; import { useMemo, useState, type CSSProperties } from 'react';
import './pricing.css'; import './pricing.css';
import { SiteFooter } from '../../shared/components/SiteFooter'; import { SiteFooter } from '../../shared/components/SiteFooter';
import { SiteNavbar } from '../../shared/components/SiteNavbar';
type PricingAudience = 'jobseekers' | 'companies'; type PricingAudience = 'jobseekers' | 'companies';
@@ -14,32 +15,6 @@ function IconifyIcon({ className, icon, style }: IconifyIconProps) {
return <iconify-icon className={className} icon={icon} style={style} />; return <iconify-icon className={className} icon={icon} style={style} />;
} }
function Logo({ nav = true }: { nav?: boolean }) {
const idPrefix = nav ? 'nav' : 'footer';
return (
<svg viewBox="0 0 100 100" className={nav ? 'w-8 h-8 rounded-lg shadow-[0_4px_15px_rgba(49,103,201,0.2)] group-hover:shadow-[0_6px_20px_rgba(49,103,201,0.3)] transition-all group-hover:scale-105' : 'w-8 h-8 rounded-lg shadow-sm transition-transform group-hover:scale-105'}>
<defs>
<linearGradient id={`${idPrefix}LogoBg`} x1="0%" y1="100%" x2="100%" y2="0%">
<stop offset="0%" stopColor="#1A9A75" />
<stop offset="100%" stopColor="#3167C9" />
</linearGradient>
<linearGradient id={`${idPrefix}LogoFg`} x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stopColor="#6ACEEB" />
<stop offset="100%" stopColor="#46D3B6" />
</linearGradient>
</defs>
<rect width="100" height="100" fill={`url(#${idPrefix}LogoBg)`} />
<path
fillRule="evenodd"
clipRule="evenodd"
d="M 60 15 L 72 15 L 72 85 L 60 85 L 60 72.98 A 28 28 0 1 1 60 27.02 Z M 44 34 A 16 16 0 1 0 44 66 A 16 16 0 1 0 44 34 Z"
fill={`url(#${idPrefix}LogoFg)`}
/>
</svg>
);
}
interface CheckItemProps { interface CheckItemProps {
children: string; children: string;
dark?: boolean; dark?: boolean;
@@ -75,56 +50,6 @@ export function PricingPage() {
const pathname = useMemo(() => window.location.pathname, []); const pathname = useMemo(() => window.location.pathname, []);
const initialAudience: PricingAudience = pathname.includes('virksomhed') ? 'companies' : 'jobseekers'; const initialAudience: PricingAudience = pathname.includes('virksomhed') ? 'companies' : 'jobseekers';
const [audience, setAudience] = useState<PricingAudience>(initialAudience); const [audience, setAudience] = useState<PricingAudience>(initialAudience);
const [isNavOpen, setIsNavOpen] = useState(false);
const [isTipsOpen, setIsTipsOpen] = useState(false);
const [isHowOpen, setIsHowOpen] = useState(false);
useEffect(() => {
if (!isNavOpen) {
return undefined;
}
const previousOverflow = document.body.style.overflow;
document.body.style.overflow = 'hidden';
function handleEscape(event: KeyboardEvent) {
if (event.key === 'Escape') {
setIsNavOpen(false);
}
}
window.addEventListener('keydown', handleEscape);
return () => {
document.body.style.overflow = previousOverflow;
window.removeEventListener('keydown', handleEscape);
};
}, [isNavOpen]);
useEffect(() => {
function handleResize() {
if (window.innerWidth > 990) {
setIsNavOpen(false);
}
}
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
useEffect(() => {
function handleClickOutside(event: MouseEvent) {
const target = event.target as HTMLElement | null;
if (!target?.closest('.pricing-how-dropdown')) {
setIsHowOpen(false);
}
if (!target?.closest('.pricing-tips-dropdown')) {
setIsTipsOpen(false);
}
}
document.addEventListener('click', handleClickOutside);
return () => document.removeEventListener('click', handleClickOutside);
}, []);
const isJobseekers = audience === 'jobseekers'; const isJobseekers = audience === 'jobseekers';
@@ -134,82 +59,10 @@ export function PricingPage() {
<div className="fixed bottom-[-15%] right-[-10%] w-[70vw] h-[70vw] rounded-full bg-gradient-to-tl from-indigo-500/20 to-purple-400/10 blur-[160px] pointer-events-none z-0" /> <div className="fixed bottom-[-15%] right-[-10%] w-[70vw] h-[70vw] rounded-full bg-gradient-to-tl from-indigo-500/20 to-purple-400/10 blur-[160px] pointer-events-none z-0" />
<div className="fixed top-[20%] right-[15%] w-[40vw] h-[40vw] rounded-full bg-gradient-to-tr from-cyan-400/20 to-blue-300/10 blur-[130px] pointer-events-none z-0" /> <div className="fixed top-[20%] right-[15%] w-[40vw] h-[40vw] rounded-full bg-gradient-to-tr from-cyan-400/20 to-blue-300/10 blur-[130px] pointer-events-none z-0" />
<nav className="pricing-nav fixed top-0 inset-x-0 z-50 h-16 bg-white/20 backdrop-blur-2xl border-b border-white/50 shadow-[0_4px_30px_rgba(0,0,0,0.03)] flex items-center justify-between px-6 lg:px-12 transition-all"> <SiteNavbar
<a href="/home" className="flex items-center gap-2 group outline-none"> activeTab="pricing"
<Logo nav /> activeHowItem={isJobseekers ? 'jobseekers' : 'companies'}
<span className="text-xl font-normal tracking-tight text-gray-900 uppercase">ARBEJD</span> />
</a>
<div className="pricing-nav-links">
<a href="/pricing" className="text-base font-normal text-gray-900 transition-colors outline-none drop-shadow-sm border-b border-gray-900 pb-0.5">Priser</a>
<div className="pricing-how-dropdown">
<button
type="button"
className="pricing-how-trigger text-base font-normal text-gray-600 hover:text-gray-900 transition-colors outline-none drop-shadow-sm"
onClick={() => {
setIsHowOpen((current) => !current);
setIsTipsOpen(false);
}}
aria-expanded={isHowOpen}
>
Sådan virker det
<IconifyIcon icon="solar:alt-arrow-down-linear" className={`text-base transition-transform ${isHowOpen ? 'rotate-180' : ''}`} style={{ strokeWidth: 1.5 }} />
</button>
<div className={isHowOpen ? 'pricing-how-menu open' : 'pricing-how-menu'}>
<a href="#" onClick={() => setIsHowOpen(false)}>For virksomheder</a>
<a href="#" onClick={() => setIsHowOpen(false)}>For jobsøgere</a>
<a href="/pricing" onClick={() => setIsHowOpen(false)}>Priser</a>
<a href="#" onClick={() => setIsHowOpen(false)}>FAQ</a>
<a href="#" onClick={() => setIsHowOpen(false)}>Nyhedsbrev</a>
</div>
</div>
<div className="pricing-tips-dropdown">
<button
type="button"
className="pricing-tips-trigger text-base font-normal text-gray-600 hover:text-gray-900 transition-colors outline-none drop-shadow-sm"
onClick={() => {
setIsTipsOpen((current) => !current);
setIsHowOpen(false);
}}
aria-expanded={isTipsOpen}
>
Tips og tricks
<IconifyIcon icon="solar:alt-arrow-down-linear" className={`text-base transition-transform ${isTipsOpen ? 'rotate-180' : ''}`} style={{ strokeWidth: 1.5 }} />
</button>
<div className={isTipsOpen ? 'pricing-tips-menu open' : 'pricing-tips-menu'}>
<a href="/stories" onClick={() => setIsTipsOpen(false)}>Stories</a>
<a href="/jobordbogen" onClick={() => setIsTipsOpen(false)}>Jobordbogen</a>
</div>
</div>
</div>
<div className="pricing-nav-actions">
<a href="#" className="hidden sm:block text-base font-normal text-gray-700 hover:text-gray-900 transition-colors outline-none drop-shadow-sm">Log ind</a>
<a href="#" className="text-base font-normal text-white bg-gradient-to-r from-gray-900 to-gray-800 hover:from-gray-800 hover:to-gray-700 px-5 py-2.5 rounded-full transition-all shadow-[0_4px_15px_rgba(0,0,0,0.1)] outline-none border border-gray-700">Opret dig</a>
</div>
<button
type="button"
className="pricing-nav-hamburger"
aria-expanded={isNavOpen}
aria-label={isNavOpen ? 'Luk menu' : 'Åbn menu'}
onClick={() => setIsNavOpen((current) => !current)}
>
<IconifyIcon icon={isNavOpen ? 'solar:close-circle-linear' : 'solar:hamburger-menu-linear'} className="text-xl text-gray-800" style={{ strokeWidth: 1.8 }} />
</button>
<div className={isNavOpen ? 'pricing-nav-popup open' : 'pricing-nav-popup'}>
<a href="/pricing" onClick={() => setIsNavOpen(false)}>Priser</a>
<a href="#" onClick={() => setIsNavOpen(false)}>Sådan virker det: For virksomheder</a>
<a href="#" onClick={() => setIsNavOpen(false)}>Sådan virker det: For jobsøgere</a>
<a href="#" onClick={() => setIsNavOpen(false)}>Sådan virker det: FAQ</a>
<a href="#" onClick={() => setIsNavOpen(false)}>Sådan virker det: Nyhedsbrev</a>
<a href="/stories" onClick={() => setIsNavOpen(false)}>Tips og tricks: Stories</a>
<a href="/jobordbogen" onClick={() => setIsNavOpen(false)}>Tips og tricks: Jobordbogen</a>
<a href="#" onClick={() => setIsNavOpen(false)}>Log ind</a>
<a href="#" className="pricing-nav-popup-cta" onClick={() => setIsNavOpen(false)}>Opret dig</a>
</div>
</nav>
<main className="flex-1 relative z-10 pt-16"> <main className="flex-1 relative z-10 pt-16">
<section className="relative pt-24 pb-16 px-6 lg:px-12 max-w-7xl mx-auto flex flex-col items-center text-center"> <section className="relative pt-24 pb-16 px-6 lg:px-12 max-w-7xl mx-auto flex flex-col items-center text-center">

View File

@@ -0,0 +1,178 @@
import { useEffect, useState } from 'react';
import appIcon from '../../../assets/appicon.png';
type ActiveTab = 'pricing' | 'how' | 'tips' | null;
type ActiveHowItem = 'companies' | 'jobseekers' | null;
type ActiveTipsItem = 'stories' | 'jobordbogen' | null;
interface SiteNavbarProps {
activeTab?: ActiveTab;
activeHowItem?: ActiveHowItem;
activeTipsItem?: ActiveTipsItem;
}
export function SiteNavbar({
activeTab = null,
activeHowItem = null,
activeTipsItem = null,
}: SiteNavbarProps) {
const [isNavOpen, setIsNavOpen] = useState(false);
const [isHowOpen, setIsHowOpen] = useState(false);
const [isTipsOpen, setIsTipsOpen] = useState(false);
const [isMobileHowOpen, setIsMobileHowOpen] = useState(false);
const [isMobileTipsOpen, setIsMobileTipsOpen] = useState(false);
useEffect(() => {
if (!isNavOpen) return undefined;
const previousOverflow = document.body.style.overflow;
document.body.style.overflow = 'hidden';
function handleEscape(event: KeyboardEvent) {
if (event.key === 'Escape') {
setIsNavOpen(false);
}
}
window.addEventListener('keydown', handleEscape);
return () => {
document.body.style.overflow = previousOverflow;
window.removeEventListener('keydown', handleEscape);
};
}, [isNavOpen]);
useEffect(() => {
function handleResize() {
if (window.innerWidth > 990) {
setIsNavOpen(false);
setIsMobileHowOpen(false);
setIsMobileTipsOpen(false);
}
}
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
useEffect(() => {
function handleClickOutside(event: MouseEvent) {
const target = event.target as HTMLElement | null;
if (!target?.closest('.site-navbar-how')) {
setIsHowOpen(false);
}
if (!target?.closest('.site-navbar-tips')) {
setIsTipsOpen(false);
}
}
document.addEventListener('click', handleClickOutside);
return () => document.removeEventListener('click', handleClickOutside);
}, []);
const topLinkBase = 'text-base font-normal transition-colors outline-none drop-shadow-sm';
const activeTop = `${topLinkBase} text-gray-900 border-b border-gray-900 pb-0.5`;
const inactiveTop = `${topLinkBase} text-gray-600 hover:text-gray-900`;
return (
<nav className="fixed top-0 inset-x-0 z-50 h-16 bg-white/20 backdrop-blur-2xl border-b border-white/50 shadow-[0_4px_30px_rgba(0,0,0,0.03)] flex items-center justify-between px-6 lg:px-12 transition-all">
<a href="/home" className="flex items-center gap-2 group outline-none">
<img
src={appIcon}
alt="Arbejd logo"
className="w-8 h-8 rounded-lg shadow-[0_4px_15px_rgba(49,103,201,0.2)] group-hover:shadow-[0_6px_20px_rgba(49,103,201,0.3)] transition-all group-hover:scale-105 object-cover"
/>
<span className="text-xl font-normal tracking-tight text-gray-900">
ARBEJD<span className="text-base">.com</span>
</span>
</a>
<div className="hidden md:flex items-center gap-8">
<a href="/pricing" className={activeTab === 'pricing' ? activeTop : inactiveTop}>Priser</a>
<div className="site-navbar-how relative">
<button
type="button"
className={activeTab === 'how' ? activeTop : inactiveTop}
onClick={() => {
setIsHowOpen((current) => !current);
setIsTipsOpen(false);
}}
aria-expanded={isHowOpen}
>
Sådan virker det
</button>
<div className={`${isHowOpen ? 'block' : 'hidden'} absolute top-[calc(100%+0.65rem)] left-0 min-w-[220px] rounded-2xl border border-white/75 bg-gradient-to-br from-white/90 to-white/70 backdrop-blur-2xl shadow-[0_20px_45px_rgba(0,0,0,0.1)] p-2`}>
<div className={`flex items-center justify-between gap-2 px-3 py-2.5 rounded-xl text-sm cursor-default ${activeHowItem === 'companies' ? 'bg-white text-gray-900' : 'text-gray-600'}`}>
<span>For virksomheder</span>
<span className="inline-flex items-center px-1.5 py-0.5 rounded-full text-[9px] font-semibold whitespace-nowrap bg-amber-100 text-amber-700 border border-amber-200">Kommer snart</span>
</div>
<a href="/for-jobsogere" onClick={() => setIsHowOpen(false)} className={`block px-3 py-2.5 rounded-xl text-sm ${activeHowItem === 'jobseekers' ? 'bg-white text-gray-900' : 'text-gray-600 hover:bg-white/70 hover:text-gray-900'}`}>For jobsøgere</a>
</div>
</div>
<div className="site-navbar-tips relative">
<button
type="button"
className={activeTab === 'tips' ? activeTop : inactiveTop}
onClick={() => {
setIsTipsOpen((current) => !current);
setIsHowOpen(false);
}}
aria-expanded={isTipsOpen}
>
Tips og tricks
</button>
<div className={`${isTipsOpen ? 'block' : 'hidden'} absolute top-[calc(100%+0.65rem)] left-0 min-w-[190px] rounded-2xl border border-white/75 bg-gradient-to-br from-white/90 to-white/70 backdrop-blur-2xl shadow-[0_20px_45px_rgba(0,0,0,0.1)] p-2`}>
<a href="/stories" onClick={() => setIsTipsOpen(false)} className={`block px-3 py-2.5 rounded-xl text-sm ${activeTipsItem === 'stories' ? 'bg-white text-gray-900' : 'text-gray-600 hover:bg-white/70 hover:text-gray-900'}`}>Stories</a>
<a href="/jobordbogen" onClick={() => setIsTipsOpen(false)} className={`block px-3 py-2.5 rounded-xl text-sm ${activeTipsItem === 'jobordbogen' ? 'bg-white text-gray-900' : 'text-gray-600 hover:bg-white/70 hover:text-gray-900'}`}>Jobordbogen</a>
</div>
</div>
</div>
<div className="hidden md:flex items-center gap-4">
<a href="https://app.arbejd.com/" className="text-base font-normal text-gray-700 hover:text-gray-900 transition-colors outline-none drop-shadow-sm">Log ind</a>
<a href="https://app.arbejd.com/welcome" className="text-base font-normal text-white bg-gradient-to-r from-gray-900 to-gray-800 hover:from-gray-800 hover:to-gray-700 px-5 py-2.5 rounded-full transition-all shadow-[0_4px_15px_rgba(0,0,0,0.1)] outline-none border border-gray-700">Opret dig</a>
</div>
<button
type="button"
className="md:hidden w-10 h-10 rounded-full bg-white/60 border border-white/80 flex items-center justify-center"
aria-expanded={isNavOpen}
aria-label={isNavOpen ? 'Luk menu' : 'Åbn menu'}
onClick={() => setIsNavOpen((current) => !current)}
>
<iconify-icon icon={isNavOpen ? 'solar:close-circle-linear' : 'solar:hamburger-menu-linear'} className="text-xl text-gray-800" style={{ strokeWidth: 1.8 }} />
</button>
{isNavOpen ? (
<div className="md:hidden absolute top-full right-4 mt-2 w-[min(320px,calc(100vw-2rem))] rounded-2xl border border-white/80 bg-gradient-to-br from-white/92 to-white/70 backdrop-blur-2xl shadow-[0_20px_45px_rgba(0,0,0,0.1)] p-2 flex flex-col gap-1">
<a href="/pricing" className="px-3 py-2.5 rounded-xl hover:bg-white text-gray-700">Priser</a>
<button type="button" className="px-3 py-2.5 rounded-xl text-left text-gray-700 hover:bg-white flex items-center justify-between" onClick={() => { setIsMobileHowOpen((c) => !c); setIsMobileTipsOpen(false); }} aria-expanded={isMobileHowOpen}>
Sådan virker det
<iconify-icon icon="solar:alt-arrow-down-linear" className={`${isMobileHowOpen ? 'rotate-180' : ''} transition-transform`} />
</button>
{isMobileHowOpen ? (
<div className="pl-2 flex flex-col gap-1">
<div className="px-3 py-2 rounded-lg text-sm text-gray-700 flex items-center justify-between gap-2 cursor-default">
<span>For virksomheder</span>
<span className="inline-flex items-center px-1.5 py-0.5 rounded-full text-[9px] font-semibold whitespace-nowrap bg-amber-100 text-amber-700 border border-amber-200">Kommer snart</span>
</div>
<a href="/for-jobsogere" className="px-3 py-2 rounded-lg text-sm text-gray-700 hover:bg-white">For jobsøgere</a>
</div>
) : null}
<button type="button" className="px-3 py-2.5 rounded-xl text-left text-gray-700 hover:bg-white flex items-center justify-between" onClick={() => { setIsMobileTipsOpen((c) => !c); setIsMobileHowOpen(false); }} aria-expanded={isMobileTipsOpen}>
Tips og tricks
<iconify-icon icon="solar:alt-arrow-down-linear" className={`${isMobileTipsOpen ? 'rotate-180' : ''} transition-transform`} />
</button>
{isMobileTipsOpen ? (
<div className="pl-2 flex flex-col gap-1">
<a href="/stories" className="px-3 py-2 rounded-lg text-sm text-gray-700 hover:bg-white">Stories</a>
<a href="/jobordbogen" className="px-3 py-2 rounded-lg text-sm text-gray-700 hover:bg-white">Jobordbogen</a>
</div>
) : null}
<a href="https://app.arbejd.com/" className="px-3 py-2.5 rounded-xl hover:bg-white text-gray-700">Log ind</a>
<a href="https://app.arbejd.com/welcome" className="px-3 py-2.5 rounded-xl bg-gray-900 text-white">Opret dig</a>
</div>
) : null}
</nav>
);
}

View File

@@ -1,6 +1,7 @@
import { useEffect, useState, type CSSProperties } from 'react'; import { type CSSProperties } from 'react';
import './stories.css'; import './stories.css';
import { SiteFooter } from '../../shared/components/SiteFooter'; import { SiteFooter } from '../../shared/components/SiteFooter';
import { SiteNavbar } from '../../shared/components/SiteNavbar';
interface IconifyIconProps { interface IconifyIconProps {
className?: string; className?: string;
@@ -12,27 +13,6 @@ function IconifyIcon({ className, icon, style }: IconifyIconProps) {
return <iconify-icon className={className} icon={icon} style={style} />; return <iconify-icon className={className} icon={icon} style={style} />;
} }
function Logo({ nav = true }: { nav?: boolean }) {
const idPrefix = nav ? 'storiesNav' : 'storiesFooter';
return (
<svg viewBox="0 0 100 100" className={nav ? 'w-8 h-8 rounded-lg shadow-[0_4px_15px_rgba(49,103,201,0.2)] group-hover:shadow-[0_6px_20px_rgba(49,103,201,0.3)] transition-all group-hover:scale-105' : 'w-8 h-8 rounded-lg shadow-sm transition-transform group-hover:scale-105'}>
<defs>
<linearGradient id={`${idPrefix}Bg`} x1="0%" y1="100%" x2="100%" y2="0%">
<stop offset="0%" stopColor="#1A9A75" />
<stop offset="100%" stopColor="#3167C9" />
</linearGradient>
<linearGradient id={`${idPrefix}Fg`} x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stopColor="#6ACEEB" />
<stop offset="100%" stopColor="#46D3B6" />
</linearGradient>
</defs>
<rect width="100" height="100" fill={`url(#${idPrefix}Bg)`} />
<path fillRule="evenodd" clipRule="evenodd" d="M 60 15 L 72 15 L 72 85 L 60 85 L 60 72.98 A 28 28 0 1 1 60 27.02 Z M 44 34 A 16 16 0 1 0 44 66 A 16 16 0 1 0 44 34 Z" fill={`url(#${idPrefix}Fg)`} />
</svg>
);
}
const seriesCards = [ const seriesCards = [
{ image: 'https://images.unsplash.com/photo-1600880292203-757bb62b4baf?w=600&q=80', audience: 'For jobansøgere', episodes: '2 Episoder', tone: 'teal' }, { image: 'https://images.unsplash.com/photo-1600880292203-757bb62b4baf?w=600&q=80', audience: 'For jobansøgere', episodes: '2 Episoder', tone: 'teal' },
{ image: 'https://images.unsplash.com/photo-1542744173-8e7e53415bb0?w=600&q=80', audience: 'For jobansøgere', episodes: '8 Episoder', tone: 'teal' }, { image: 'https://images.unsplash.com/photo-1542744173-8e7e53415bb0?w=600&q=80', audience: 'For jobansøgere', episodes: '8 Episoder', tone: 'teal' },
@@ -45,133 +25,13 @@ const seriesCards = [
] as const; ] as const;
export function StoriesPage() { export function StoriesPage() {
const [isNavOpen, setIsNavOpen] = useState(false);
const [isTipsOpen, setIsTipsOpen] = useState(false);
const [isHowOpen, setIsHowOpen] = useState(false);
useEffect(() => {
if (!isNavOpen) {
return undefined;
}
const previousOverflow = document.body.style.overflow;
document.body.style.overflow = 'hidden';
function handleEscape(event: KeyboardEvent) {
if (event.key === 'Escape') {
setIsNavOpen(false);
}
}
window.addEventListener('keydown', handleEscape);
return () => {
document.body.style.overflow = previousOverflow;
window.removeEventListener('keydown', handleEscape);
};
}, [isNavOpen]);
useEffect(() => {
function handleResize() {
if (window.innerWidth > 990) {
setIsNavOpen(false);
}
}
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
useEffect(() => {
function handleClickOutside(event: MouseEvent) {
const target = event.target as HTMLElement | null;
if (!target?.closest('.stories-how-dropdown')) {
setIsHowOpen(false);
}
if (!target?.closest('.stories-tips-dropdown')) {
setIsTipsOpen(false);
}
}
document.addEventListener('click', handleClickOutside);
return () => document.removeEventListener('click', handleClickOutside);
}, []);
return ( return (
<div className="stories-react-root scroll-smooth bg-[#f8fafc] relative min-h-screen text-gray-600 selection:bg-teal-100 selection:text-teal-900 overflow-x-hidden flex flex-col font-normal custom-scrollbar"> <div className="stories-react-root scroll-smooth bg-[#f8fafc] relative min-h-screen text-gray-600 selection:bg-teal-100 selection:text-teal-900 overflow-x-hidden flex flex-col font-normal custom-scrollbar">
<div className="fixed top-[-15%] left-[-10%] w-[60vw] h-[60vw] rounded-full bg-gradient-to-br from-teal-400/30 to-emerald-300/10 blur-[140px] pointer-events-none z-0" /> <div className="fixed top-[-15%] left-[-10%] w-[60vw] h-[60vw] rounded-full bg-gradient-to-br from-teal-400/30 to-emerald-300/10 blur-[140px] pointer-events-none z-0" />
<div className="fixed bottom-[-15%] right-[-10%] w-[70vw] h-[70vw] rounded-full bg-gradient-to-tl from-indigo-500/20 to-purple-400/10 blur-[160px] pointer-events-none z-0" /> <div className="fixed bottom-[-15%] right-[-10%] w-[70vw] h-[70vw] rounded-full bg-gradient-to-tl from-indigo-500/20 to-purple-400/10 blur-[160px] pointer-events-none z-0" />
<div className="fixed top-[20%] right-[15%] w-[40vw] h-[40vw] rounded-full bg-gradient-to-tr from-cyan-400/20 to-blue-300/10 blur-[130px] pointer-events-none z-0" /> <div className="fixed top-[20%] right-[15%] w-[40vw] h-[40vw] rounded-full bg-gradient-to-tr from-cyan-400/20 to-blue-300/10 blur-[130px] pointer-events-none z-0" />
<nav className="stories-nav fixed top-0 inset-x-0 z-50 h-16 bg-white/20 backdrop-blur-2xl border-b border-white/50 shadow-[0_4px_30px_rgba(0,0,0,0.03)] flex items-center justify-between px-6 lg:px-12 transition-all"> <SiteNavbar activeTab="tips" activeTipsItem="stories" />
<a href="/home" className="flex items-center gap-2 group outline-none">
<Logo nav />
<span className="text-xl font-normal tracking-tight text-gray-900 uppercase">ARBEJD</span>
</a>
<div className="stories-nav-links">
<a href="/pricing" className="text-base font-normal text-gray-600 hover:text-gray-900 transition-colors outline-none drop-shadow-sm">Priser</a>
<div className="stories-how-dropdown">
<button
type="button"
className="stories-how-trigger text-base font-normal text-gray-600 hover:text-gray-900 transition-colors outline-none drop-shadow-sm"
onClick={() => {
setIsHowOpen((current) => !current);
setIsTipsOpen(false);
}}
aria-expanded={isHowOpen}
>
Sådan virker det
<IconifyIcon icon="solar:alt-arrow-down-linear" className={`text-base transition-transform ${isHowOpen ? 'rotate-180' : ''}`} style={{ strokeWidth: 1.5 }} />
</button>
<div className={isHowOpen ? 'stories-how-menu open' : 'stories-how-menu'}>
<a href="#" onClick={() => setIsHowOpen(false)}>For virksomheder</a>
<a href="#" onClick={() => setIsHowOpen(false)}>For jobsøgere</a>
<a href="/pricing" onClick={() => setIsHowOpen(false)}>Priser</a>
<a href="#" onClick={() => setIsHowOpen(false)}>FAQ</a>
<a href="#" onClick={() => setIsHowOpen(false)}>Nyhedsbrev</a>
</div>
</div>
<div className="stories-tips-dropdown">
<button
type="button"
className="stories-tips-trigger text-base font-normal text-gray-900 transition-colors outline-none drop-shadow-sm border-b-2 border-teal-500 pb-0.5"
onClick={() => {
setIsTipsOpen((current) => !current);
setIsHowOpen(false);
}}
aria-expanded={isTipsOpen}
>
Tips og tricks
<IconifyIcon icon="solar:alt-arrow-down-linear" className={`text-base transition-transform ${isTipsOpen ? 'rotate-180' : ''}`} style={{ strokeWidth: 1.5 }} />
</button>
<div className={isTipsOpen ? 'stories-tips-menu open' : 'stories-tips-menu'}>
<a href="/stories" className="active" onClick={() => setIsTipsOpen(false)}>Stories</a>
<a href="/jobordbogen" onClick={() => setIsTipsOpen(false)}>Jobordbogen</a>
</div>
</div>
</div>
<div className="stories-nav-actions">
<a href="#" className="hidden sm:block text-base font-normal text-gray-700 hover:text-gray-900 transition-colors outline-none drop-shadow-sm">Log ind</a>
<a href="#" className="text-base font-normal text-white bg-gradient-to-r from-gray-900 to-gray-800 hover:from-gray-800 hover:to-gray-700 px-5 py-2.5 rounded-full transition-all shadow-[0_4px_15px_rgba(0,0,0,0.1)] outline-none border border-gray-700">Opret dig</a>
</div>
<button type="button" className="stories-nav-hamburger" aria-expanded={isNavOpen} aria-label={isNavOpen ? 'Luk menu' : 'Åbn menu'} onClick={() => setIsNavOpen((current) => !current)}>
<IconifyIcon icon={isNavOpen ? 'solar:close-circle-linear' : 'solar:hamburger-menu-linear'} className="text-xl text-gray-800" style={{ strokeWidth: 1.8 }} />
</button>
<div className={isNavOpen ? 'stories-nav-popup open' : 'stories-nav-popup'}>
<a href="/pricing" onClick={() => setIsNavOpen(false)}>Priser</a>
<a href="#" onClick={() => setIsNavOpen(false)}>Sådan virker det: For virksomheder</a>
<a href="#" onClick={() => setIsNavOpen(false)}>Sådan virker det: For jobsøgere</a>
<a href="#" onClick={() => setIsNavOpen(false)}>Sådan virker det: FAQ</a>
<a href="#" onClick={() => setIsNavOpen(false)}>Sådan virker det: Nyhedsbrev</a>
<a href="/stories" onClick={() => setIsNavOpen(false)}>Tips og tricks: Stories</a>
<a href="/jobordbogen" onClick={() => setIsNavOpen(false)}>Tips og tricks: Jobordbogen</a>
<a href="#" onClick={() => setIsNavOpen(false)}>Log ind</a>
<a href="#" className="stories-nav-popup-cta" onClick={() => setIsNavOpen(false)}>Opret dig</a>
</div>
</nav>
<main className="flex-1 relative z-10 pt-16"> <main className="flex-1 relative z-10 pt-16">
<section className="relative pt-24 pb-20 px-6 lg:px-12 max-w-7xl mx-auto flex flex-col items-center text-center min-h-[500px]"> <section className="relative pt-24 pb-20 px-6 lg:px-12 max-w-7xl mx-auto flex flex-col items-center text-center min-h-[500px]">