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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added public/header/minicubes_lazaro.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/header/mpibgc_field.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/header/workshop_kigali.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/logo_ellis_jena.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/logo_esa.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: 5 additions & 5 deletions src/app/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -79,18 +79,18 @@ export default function Landing() {
avatarSrc="publication_preview/requenamesa_earthvision_2021.gif"
/>

<CustomCard
<CustomCardHorizontal
title="EarthNet Team"
description="Meet our team."
description="We are an interdisciplinary group interested in the applications of machine learning to Earth System Science."
href="/team"
avatarSrc="https://github.com/shadcn.png"
avatarFallback="AI"
avatarSrc="header/mpibgc_field.png"
/>

<CustomCard
<CustomCardHorizontal
title="Opportunities"
description="Come work or collaborate with us!"
href="/resources/opportunities"
avatarSrc="header/workshop_kigali.png"
/>
</div>
</div>
Expand Down
52 changes: 38 additions & 14 deletions src/app/science/page.mdx
Original file line number Diff line number Diff line change
@@ -1,28 +1,52 @@
# Towards Earth surface forecasting
import { CustomCard, CustomCardHorizontal } from '@/components/CustomCard';


## Land Surface Foundation Models
![Stylistic rendering of satellite images and a globe. (© L. Alonso/MPI-BGC)](/header/minicubes_lazaro.png)

## Early Warning
# Towards Earth surface forecasting

## Geospatial Vegetation Forecasting
The EarthNet Initiative develops machine learning models to forecast the Earth's surface dynamics. We take a data-centric stance by primarily leveraging high-resolution satellite remote sensing to forecast and monitor responses of the terrestrial biosphere to weather patterns on different time scales. Our research focuses on the dynamics of the Earth system to enable a wide range of applications around the mitigation of complex climate risks, for instance through impact-based forecasts and early warning systems for extreme weather events.

## Drought Impacts
## What we do
1. **Large-scale satellite image deep learning**: We develop datasets and train large-scale deep neural networks on satellite imagery, to enable a multitude of land surface oriented downstream applications.
2. **Climate risk mitigation**: We study our approaches in the context of extreme climate risks and their associated impacts. In particular, we assess how our AI approaches may support societal responses to changing climate risks.
3. **Tailored machine learning for geoscience**: We adapt and design tailored neural network architectures for uni- and multi-modal environmental tasks. This includes accounting for challenging scenarios like long-range interactions, ecological memory or non-IID datasets.
4. **Collaboration with stakeholders**: We engage with stakeholders from NGOs and the public sector to transfer our scientific findings and methods into tangible real-world impact.

## Heatwave Nowcasting
## Vision
We aim to address gaps in traditional approaches to modeling the land surface, by leveraging machine learning to directly work with the only globally-available observed data: satellite remote sensing. Through an interdisciplinary team with expertise in both, Geosciences and machine learning, we tackle unresolved challenges in forecasting the Earth’s surface to test our process understanding and ultimately contribute to improved climate risk mitigation.

## Anticipatory Action

## Vegetation structure
# Our third-party funded projects

## Carbon cycle monitoring
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">

<CustomCardHorizontal
title="WeatherGenerator"
description="Horizon Europe project."
href="/science/weathergenerator"
avatarSrc="projects/logo_weathergenerator.png"
/>

# Our thrid-party funded projects
<CustomCardHorizontal
title="ELIAS"
description="Horizon Europe project."
href="/science/elias"
avatarSrc="projects/logo_elias.png"
/>

## [WeatherGenerator](/science/weathergenerator)
<CustomCard
title="DeepExtremes"
description="ESA AI4Science ITT."
href="/science/deepextremes"
/>

## [ELIAS](/science/elias)
<CustomCardHorizontal
title="DeepCube"
description="Horizon 2020 project."
href="/science/deepcube"
avatarSrc="projects/logo_deepcube.png"
/>

## [DeepExtremes](/science/deepextremes)
</div>

## [DeepCube](/science/deepcube)
102 changes: 65 additions & 37 deletions src/components/CustomCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,18 @@ import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { ComponentType } from "react";
import { FaExternalLinkAlt } from "react-icons/fa";

// Add this helper function at the top
const isExternalUrl = (url?: string) => {
if (!url) return false;
return url.startsWith('http://') || url.startsWith('https://') || url.startsWith('//');
};


type CustomCardProps = {
title: string;
description: string;
href: string;
target?: string;
target?: string; // Keep this optional for manual override if needed
avatarSrc?: string | null;
avatarFallback?: string;
showIcon?: boolean;
Expand All @@ -26,14 +33,17 @@ export const CustomCard = ({
title,
description,
href,
target = "_blank",
target, // Remove default value, we'll determine it automatically
avatarSrc = null,
avatarFallback = "CN",
showIcon = false,
icon: IconComponent = Heart,
iconSize = 24,
className = "",
}: CustomCardProps) => {
const isExternal = isExternalUrl(href);
const linkTarget = target || (isExternal ? "_blank" : "_self");

return (
<Card className={`w-full max-w-sm mx-auto min-w-0 hover:shadow-md transition-shadow duration-200 ${className}`}>
<CardHeader>
Expand All @@ -57,9 +67,14 @@ export const CustomCard = ({
<div className="flex-1 min-w-0">
<CardTitle className="text-sm sm:text-base md:text-lg leading-tight">
{href ? (
<a href={href} target={target} className="hover:underline inline-flex items-center gap-2">
<a
href={href}
target={linkTarget}
rel={isExternal ? "noopener noreferrer" : undefined}
className="hover:underline inline-flex items-center gap-2"
>
{title}
<FaExternalLinkAlt size={12} className="flex-shrink-0 opacity-60" />
{isExternal && <FaExternalLinkAlt size={12} className="flex-shrink-0 opacity-60" />}
</a>
) : (
title
Expand All @@ -81,48 +96,61 @@ export const CustomCardHorizontal = ({
title,
description,
href,
target = "_blank",
target, // Remove default value
avatarSrc = null,
avatarFallback = "CN",
showIcon = false,
icon: IconComponent = Heart,
iconSize = 24,
className = "",
}: CustomCardProps) => {
const isExternal = isExternalUrl(href);
const linkTarget = target || (isExternal ? "_blank" : "_self");

return (
<Card className={`w-full max-w-sm mx-auto min-w-0 hover:shadow-md transition-shadow duration-200 ${className}`}>
<div className="flex flex-col sm:flex-row sm:items-start gap-2 sm:gap-4 px-3 -mt-4 sm:mt-0 pb-0">
{/* Image Section — responsive positioning */}
<div className="flex justify-center sm:block">
{avatarSrc ? (
<Avatar className="h-24 w-24 rounded-md shadow-md">
<AvatarImage src={avatarSrc} alt="Avatar" />
<AvatarFallback>{avatarFallback}</AvatarFallback>
</Avatar>
) : showIcon && IconComponent ? (
<div className="w-24 h-24 flex items-center justify-center rounded-md bg-gray-100 shadow-md">
<IconComponent size={iconSize} className="text-gray-500" />
<div className="flex flex-col sm:flex-row sm:items-start gap-2 sm:gap-4 px-3 -mt-4 sm:mt-0 pb-0">
{/* Image Section — responsive positioning */}
<div className="flex justify-center sm:block">
{avatarSrc ? (
<Avatar className="h-24 w-24 rounded-md shadow-md">
<AvatarImage
src={avatarSrc}
alt="Avatar"
className="object-contain"
style={{ objectFit: 'contain' }}
/>
<AvatarFallback>{avatarFallback}</AvatarFallback>
</Avatar>
) : showIcon && IconComponent ? (
<div className="w-24 h-24 flex items-center justify-center rounded-md bg-gray-100 shadow-md">
<IconComponent size={iconSize} className="text-gray-500" />
</div>
) : null}
</div>
) : null}
</div>

{/* Content Section — always left aligned */}
<div className="flex-1 text-left">
<CardTitle className="text-lg font-semibold">
{href ? (
<a href={href} target={target} className="inline-flex items-center gap-2 hover:underline">
{title}
<FaExternalLinkAlt size={12} className="opacity-60" />
</a>
) : (
title
)}
</CardTitle>
<CardDescription className="text-sm mt-1">
{description}
</CardDescription>
</div>
</div>
</Card>
{/* Content Section — always left aligned */}
<div className="flex-1 text-left">
<CardTitle className="text-lg font-semibold">
{href ? (
<a
href={href}
target={linkTarget}
rel={isExternal ? "noopener noreferrer" : undefined}
className="inline-flex items-center gap-2 hover:underline"
>
{title}
{isExternal && <FaExternalLinkAlt size={12} className="opacity-60" />}
</a>
) : (
title
)}
</CardTitle>
<CardDescription className="text-sm mt-1">
{description}
</CardDescription>
</div>
</div>
</Card>
);
}
}
4 changes: 2 additions & 2 deletions src/components/Funding.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const Logo = ({ logo }: { logo: LogoItem }) => {
alt={logo.alt}
width={logo.width}
height={logo.height}
className="h-8 w-auto"
className="h-auto w-auto max-h-8 sm:max-h-12 object-contain"
priority
/>
);
Expand All @@ -37,7 +37,7 @@ const RenderLogo = ({ logo, defaultLogoText }: {

if (Array.isArray(logo)) {
return (
<div className="flex items-center gap-2">
<div className="flex flex-col sm:flex-row items-center sm:items-center gap-4 sm:gap-2">
{logo.map((item, index) => (
<Logo key={index} logo={item} />
))}
Expand Down
Loading