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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions client/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ import ProjectManagement from './pages/ProjectManagement'
const THEME_COOKIE = 'graphyma-theme'

function readThemeCookie() {
if (typeof document === 'undefined') return 'dark'
if (typeof document === 'undefined') return 'light'

const match = document.cookie.match(new RegExp(`(?:^|; )${THEME_COOKIE}=([^;]*)`))
const value = match ? decodeURIComponent(match[1]) : ''
return value === 'light' ? 'light' : 'dark'
return value === 'dark' ? 'dark' : 'light'
}

function writeThemeCookie(theme) {
Expand Down
Binary file added client/src/assets/graphyma_logo2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 7 additions & 3 deletions client/src/components/footer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,13 @@ export default function Footer() {
<div>
<p className="footer-section-title">Services</p>
<nav className="footer-nav">
{['Remote Sensing', 'Communications', 'Trainings', 'Project Management'].map(s => (
<Link key={s} to={`/services/${s.toLowerCase().replace(' ', '-')}`} className="footer-link">
{s}
{[
{ label: 'Consultancy', to: '/services/remote-sensing' },
{ label: 'User Uptake', to: '/services/communications' },
{ label: 'Trainings', to: '/services/trainings' },
].map(({ label, to }) => (
<Link key={label} to={to} className="footer-link">
{label}
</Link>
))}
</nav>
Expand Down
3 changes: 2 additions & 1 deletion client/src/components/navbar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Link, useLocation } from 'react-router-dom'
import { motion, AnimatePresence } from 'framer-motion'
import './styles/navbar.css'
import graphymaLogo from '../assets/graphyma_logo1.png'
import graphymaLogoLight from '../assets/graphyma_logo2.png'

const NAV_LINKS = [
{ path: '/', label: 'Home' },
Expand Down Expand Up @@ -40,7 +41,7 @@ export default function Navbar({ theme = 'dark', onThemeToggle }) {
<Link to="/" className="logo-link">
<motion.div whileHover={{ scale: 1.03 }} transition={{ type: 'spring', stiffness: 400 }} className="logo-inner">
{/* Logo mark */}
<img src={graphymaLogo} alt="GRAPHYMA" className="logo-mark" />
<img src={theme === 'dark' ? graphymaLogo : graphymaLogoLight} alt="GRAPHYMA" className="logo-mark" />
<span className="brand-text">GRAPH<span className="brand-accent">YMA</span></span>
</motion.div>
</Link>
Expand Down
74 changes: 33 additions & 41 deletions client/src/index.css
Original file line number Diff line number Diff line change
@@ -1,41 +1,34 @@
/* ═══════════════════════════════════════════
GRAPHYMA — Global Styles
Aesthetic: Dark Orbital Luxury
Palette: Deep teal-black + bioluminescent mint
═══════════════════════════════════════════ */

/* Deep teal-black */
/* :root {
color-scheme: dark;
:root {
color-scheme: light;

--bg: #050c0b;
--bg-rgb: 5, 12, 11;
--bg-alt: #071412;
--bg-alt-rgb: 7, 20, 18;
--bg-card: rgba(13, 255, 196, 0.025);
--bg-card-hover: rgba(13, 255, 196, 0.05);
--surface: #0b1815;
--surface-rgb: 11, 24, 21;
--surface-2: #10211d;
--surface-2-rgb: 16, 33, 29;
--bg: #f8fafc;
--bg-rgb: 248, 250, 252;
Comment on lines +1 to +5
--bg-alt: #f1f5f9;
--bg-alt-rgb: 241, 245, 249;
--bg-card: rgba(255, 255, 255, 0.8);
--bg-card-hover: rgba(255, 255, 255, 0.95);
--surface: #ffffff;
--surface-rgb: 255, 255, 255;
--surface-2: #f4f6f8;
--surface-2-rgb: 244, 246, 248;

--accent: #2563eb;
--accent-rgb: 37, 99, 235;
--accent-2: #4f7cff;
--accent-2-rgb: 79, 124, 255;
--accent-3: #1d4ed8;
--accent-dim: rgba(16, 185, 129, 0.12);
--accent-glow: rgba(16, 185, 129, 0.18);

--accent: #0dffc4;
--accent-rgb: 13, 255, 196;
--accent-2: #00c49a;
--accent-2-rgb: 0, 196, 154;
--accent-3: #007a60;
--accent-dim: rgba(13, 255, 196, 0.1);
--accent-glow: rgba(13, 255, 196, 0.35);

--text: #ebf7f5;
--text-rgb: 235, 247, 245;
--text-2: #6bbab5;
--text-2-rgb: 107, 186, 181;
--text-3: #2e5f5c;
--text-3-rgb: 46, 95, 92;

--border: rgba(13, 255, 196, 0.08);
--border-bright: rgba(13, 255, 196, 0.28);
--text: #0f172a;
--text-rgb: 15, 23, 42;
--text-2: #475569;
--text-2-rgb: 71, 85, 105;
--text-3: #94a3b8;
--text-3-rgb: 148, 163, 184;

--border: rgba(37, 99, 235, 0.08);
--border-bright: rgba(37, 99, 235, 0.28);
--shadow-soft: 0 18px 50px rgba(0, 0, 0, 0.24);
--shadow-strong: 0 28px 80px rgba(0, 0, 0, 0.36);

Expand All @@ -50,13 +43,12 @@
--font-display: 'Syne', sans-serif;
--font-body: 'DM Sans', sans-serif;
--font-mono: 'JetBrains Mono', monospace;
} */
}

/* Floral Lavender */
:root {
:root[data-theme='dark'] {
color-scheme: dark;

--bg: #050c0b;
--bg: #050c0b;
--bg-rgb: 5, 12, 11;
--bg-alt: #071412;
--bg-alt-rgb: 7, 20, 18;
Expand All @@ -75,7 +67,7 @@
--accent-dim: rgba(181, 126, 220, 0.1);
--accent-glow: rgba(181, 126, 220, 0.35);

--text: #f3eef8;
--text: #f3eef8;
--text-rgb: 243, 238, 248;
--text-2: #b3a3c7;
--text-2-rgb: 179, 163, 199;
Expand Down
14 changes: 7 additions & 7 deletions client/src/pages/About.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ const STORY_PARAS = [
{
label: 'What We Do',
heading: 'Intelligence from orbit',
text: 'At its core, GRAPHYMA offers specialised services in satellite data analysis, digital consultancy, professional training, and project management. Its Earth Observation expertise allows the company to develop tailored solutions for environmental challenges, while its broader technological perspective supports clients in digital transformation, operational efficiency, and data-informed planning.',
text: 'GRAPHYMA offers specialised services in satellite data analysis, digital consultancy, professional training, and project management. Its Earth Observation expertise allows the company to develop tailored solutions for environmental challenges, while its broader technological perspective supports clients in digital transformation, operational efficiency, and data-informed planning.',
},
{
label: 'Our Ambition',
Expand Down Expand Up @@ -161,7 +161,7 @@ export default function About() {
transition={{ delay: 0.6, duration: 0.8 }}
className="about-hero-copy"
>
GRAPHYMA is not only a startup with technical expertise, but a growing platform for connecting Earth Observation with the challenges and opportunities of the real world.
GRAPYMA is a startup that combines technical expertise with communication and user uptake experience, merging deep science with clear and accessible communication
</motion.p>
</div>
</section>
Expand Down Expand Up @@ -235,7 +235,7 @@ export default function About() {
{/* ══════════════════════════════════════
CAPABILITIES
══════════════════════════════════════ */}
<section id="pillars" className="section about-pillars-section">
{/* <section id="pillars" className="section about-pillars-section">
<div className="glow-tl" />
<div className="container">
<div className="about-pillars-header">
Expand Down Expand Up @@ -288,7 +288,7 @@ export default function About() {
))}
</div>
</div>
</section>
</section> */}

{/* ══════════════════════════════════════
VALUES
Expand Down Expand Up @@ -364,7 +364,7 @@ export default function About() {
{/* ══════════════════════════════════════
EXPERTISE BADGES
══════════════════════════════════════ */}
<section className="about-badges-section">
{/* <section className="about-badges-section">
<div className="container">
<motion.div
initial={{ opacity: 0, y: 20 }}
Expand Down Expand Up @@ -403,7 +403,7 @@ export default function About() {
))}
</motion.div>
</div>
</section>
</section> */}

{/* ══════════════════════════════════════
CTA
Expand All @@ -422,7 +422,7 @@ export default function About() {
Ready to work with us?
</h2>
<p className="about-cta-copy">
Whether you are an institution, company, or research body — GRAPHYMA can help you unlock the value of Earth Observation.
Whether you are an institution, company, or research body, GRAPHYMA can help!
</p>
</div>
<div className="about-cta-actions">
Expand Down
2 changes: 1 addition & 1 deletion client/src/pages/Communications.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export default function Communications() {
transition={{ duration: 0.65, delay: 0.12 }}
className="comms-hero-copy"
>
We turn technical capability into measurable uptake. Our communication strategy connects EO outputs to real-world decisions, making the value obvious to every stakeholder.
We turn Earth Observation insights into business actions, making the value obvious at every level.
</motion.p>
<motion.div
initial={{ opacity: 0, y: 18 }}
Expand Down
33 changes: 11 additions & 22 deletions client/src/pages/Home.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,10 @@ const SERVICES = [
]

const STATS = [
{ target: 16, suffix: 'TB', label: 'FREE DATA every day', decimals: 0 },
{ target: 3.5, suffix: 'B', label: 'Market Today', decimals: 1 },
{ target: 11.5, suffix: 'K+', label: 'active satellites worldwide', decimals: 1 },
{ target: 60, suffix: '%', label: 'Climate Variables Convered', decimals: 0 },
{ target: 1, suffix: 'T$', label: 'USD market forcast by 2030', decimals: 0 },
{ target: 1000, suffix: '+', label: 'Earth Observation satellites are currently in operation', decimals: 0 },
{ target: 950, suffix: '+', label: 'terabits of data collected every day by EO satellites', decimals: 0 },
{ target: 60, suffix: '%', label: 'Of Essential Climate Variables can be addressed by satellite data', decimals: 0 },
{ target: 3, suffix: 'X', label: 'Growth Increase in satellite deployment since 2020', decimals: 0 },
]

const FLOAT_LABELS = [
Expand Down Expand Up @@ -312,7 +311,7 @@ export default function Home() {
{/* ══════════════════════════════════════
MARKET FACTS
══════════════════════════════════════ */}
<section className="home-facts-section">
{/* <section className="home-facts-section">
<div className="container">
<motion.span
className="section-label"
Expand Down Expand Up @@ -352,7 +351,7 @@ export default function Home() {
))}
</div>
</div>
</section>
</section> */}

{/* ══════════════════════════════════════
SERVICES
Expand All @@ -375,15 +374,6 @@ export default function Home() {
Specialised services<br />
<span className="gradient-text">built for impact</span>
</motion.h2>
<motion.p
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ delay: 0.2, duration: 0.7 }}
className="home-services-copy"
>
We provide specialised services that combine technical expertise, communication, training, and strategic support.
</motion.p>
</div>

{/* Service image cards (static visuals) */}
Expand Down Expand Up @@ -454,15 +444,14 @@ export default function Home() {
{/* Satellite dots on outer ring */}
<circle cx="230" cy="34" r="5" fill="var(--accent)" opacity="0.6" />
<circle cx="426" cy="230" r="4" fill="var(--accent)" opacity="0.45" />
<circle cx="134" cy="395" r="5" fill="var(--accent)" opacity="0.55" />
</svg>

{/* Node labels */}
{[
{ label: 'ESA', top: '47%', left: '5%' },
{ label: 'Copernicus',top: '9%', left: '62%' },
{ label: 'EUMETSAT', top: '65%', left: '77%' },
{ label: 'JRC', top: '78%', left: '20%' },
{ label: 'ECMWF', top: '78%', left: '20%' },
{ label: 'GRAPHYMA', top: '45%', left: '41%' },
].map(({ label, top, left }) => (
<div
Expand All @@ -486,14 +475,14 @@ export default function Home() {
<span className="section-label">Our Heritage</span>
<h2 className="home-heritage-title">
A legacy shaped by<br />
<span className="gradient-text">Europe's most trusted</span><br />
EO entities
<span className="gradient-text">Helping organizations unlock the power of</span><br />
Earth Observation
</h2>
<p className="home-heritage-copy">
We inherit a legacy of expertise, shaped by our team's years of collaboration with Europe's most trusted Earth Observation entities — from ESA and Copernicus to EUMETSAT and JRC.
Whether you're a startup, public institution, research organization, or enterprise, we help you navigate the Earth Observation ecosystem with confidence. Our team combines years of experience across Europe's leading EO programmes to transform complex satellite technologies into practical solutions tailored to your goals.
</p>
<p className="home-heritage-copy">
This foundation gives us a unique vantage point: we understand both the technical depth of satellite systems and the practical needs of the organisations that depend on them.
From identifying the right data and platforms to designing workflows, delivering training, and supporting implementation, we make Earth Observation accessible to organizations of every size and level of expertise.
</p>

{/* Tags */}
Expand Down
34 changes: 25 additions & 9 deletions client/src/pages/RemoteSensing.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,27 @@ const page = {
}

const CAPABILITIES = [
{ title: 'Acquisition Strategy', detail: 'Right sensors, right revisit, right data.' },
{ title: 'Pre-processing', detail: 'Radiometric, geometric, and atmospheric corrections.' },
{ title: 'Analytics & Models', detail: 'Indices, ML pipelines, and change detection.' },
{ title: 'Decision Layers', detail: 'Actionable maps and executive-ready outputs.' },
]
{
title: 'Understand Your Needs',
detail: 'Aligning Earth Observation solutions with your objectives.',
},
{
title: 'Identify the Right EO Data',
detail: 'Selecting the most suitable satellite data and platforms.',
},
{
title: 'Analyse & Interpret',
detail: 'Transforming satellite data into meaningful insights.',
},
{
title: 'Deliver Actionable Insights',
detail: 'Clear reports, dashboards, and decision-ready outputs.',
},
{
title: 'Support & Capacity Building',
detail: 'Training teams for confident Earth Observation adoption.',
},
];

function SatelliteGraphic() {
return (
Expand Down Expand Up @@ -111,7 +127,7 @@ export default function RemoteSensing() {
transition={{ duration: 0.65, delay: 0.12 }}
className="rs-hero-copy"
>
We design end-to-end remote sensing workflows that translate complex satellite data into operational decisions. From sensor selection to advanced analytics, every step is tuned for your mission and timeframe.
We design remote sensing consultancy strategies that integrate directly into our clients' workflows
</motion.p>
<motion.div
initial={{ opacity: 0, y: 18 }}
Expand Down Expand Up @@ -246,7 +262,7 @@ export default function RemoteSensing() {
transition={{ duration: 0.65, delay: 0.12 }}
className="rs-section-copy"
>
Every project is built on a proven pipeline that compresses time-to-insight while preserving data quality. We align the pipeline to your operational decisions, not the other way around.
We deliver fast, high-quality insights using a proven process. Most importantly, we adapt our workflow to fit your business decisions, not the other way around.
</motion.p>
<motion.div
initial={{ opacity: 0, y: 18 }}
Expand Down Expand Up @@ -274,11 +290,11 @@ export default function RemoteSensing() {
whileInView={{ opacity: 1, x: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.8 }}
className="rs-orbit-wrap"
className="rs-orbit-wrap rs-stage-align"
>
<div className="rs-stage-card">
<div className="rs-stage-list">
{['Ingest', 'Normalize', 'Analyze', 'Validate', 'Deploy'].map((step, i) => (
{['Understand', 'Identify', 'Analyse', 'Deliver', 'Support'].map((step, i) => (
<div key={step} className="rs-stage-row">
<div className="rs-stage-number">{String(i + 1).padStart(2, '0')}</div>
<div className="rs-stage-bar">
Expand Down
4 changes: 2 additions & 2 deletions client/src/pages/styles/Home.css
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@

.home-stats-grid {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-columns: repeat(4, 1fr);
gap: 1.5rem;
}

Expand All @@ -192,7 +192,7 @@

.home-stat-label {
font-family: var(--font-mono);
font-size: 0.65rem;
font-size: 0.70rem;
letter-spacing: 0.15em;
color: var(--text-3);
text-transform: uppercase;
Expand Down
Loading