Skip to content

Commit c8112ec

Browse files
authored
Merge pull request #23 from EarthyScience/vb/dev
Polishing text and images
2 parents 0fd3099 + 2e31df1 commit c8112ec

File tree

9 files changed

+110
-58
lines changed

9 files changed

+110
-58
lines changed

public/header/minicubes_lazaro.png

29.1 MB
Loading

public/header/mpibgc_field.png

370 KB
Loading

public/header/workshop_kigali.png

305 KB
Loading

public/logo_ellis_jena.png

-33.1 KB
Loading

public/logo_esa.png

-3.95 KB
Loading

src/app/page.mdx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,18 +78,18 @@ export default function Landing() {
7878
avatarSrc="publication_preview/requenamesa_earthvision_2021.gif"
7979
/>
8080

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

89-
<CustomCard
88+
<CustomCardHorizontal
9089
title="Opportunities"
9190
description="Come work or collaborate with us!"
9291
href="/resources/opportunities"
92+
avatarSrc="header/workshop_kigali.png"
9393
/>
9494
</div>
9595
</div>

src/app/science/page.mdx

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,52 @@
1-
# Towards Earth surface forecasting
1+
import { CustomCard, CustomCardHorizontal } from '@/components/CustomCard';
2+
23

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

5-
## Early Warning
6+
# Towards Earth surface forecasting
67

7-
## Geospatial Vegetation Forecasting
8+
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.
89

9-
## Drought Impacts
10+
## What we do
11+
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.
12+
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.
13+
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.
14+
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.
1015

11-
## Heatwave Nowcasting
16+
## Vision
17+
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.
1218

13-
## Anticipatory Action
1419

15-
## Vegetation structure
20+
# Our third-party funded projects
1621

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

24+
<CustomCardHorizontal
25+
title="WeatherGenerator"
26+
description="Horizon Europe project."
27+
href="/science/weathergenerator"
28+
avatarSrc="projects/logo_weathergenerator.png"
29+
/>
1930

20-
# Our thrid-party funded projects
31+
<CustomCardHorizontal
32+
title="ELIAS"
33+
description="Horizon Europe project."
34+
href="/science/elias"
35+
avatarSrc="projects/logo_elias.png"
36+
/>
2137

22-
## [WeatherGenerator](/science/weathergenerator)
38+
<CustomCard
39+
title="DeepExtremes"
40+
description="ESA AI4Science ITT."
41+
href="/science/deepextremes"
42+
/>
2343

24-
## [ELIAS](/science/elias)
44+
<CustomCardHorizontal
45+
title="DeepCube"
46+
description="Horizon 2020 project."
47+
href="/science/deepcube"
48+
avatarSrc="projects/logo_deepcube.png"
49+
/>
2550

26-
## [DeepExtremes](/science/deepextremes)
51+
</div>
2752

28-
## [DeepCube](/science/deepcube)

src/components/CustomCard.tsx

Lines changed: 65 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,18 @@ import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
99
import { ComponentType } from "react";
1010
import { FaExternalLinkAlt } from "react-icons/fa";
1111

12+
// Add this helper function at the top
13+
const isExternalUrl = (url?: string) => {
14+
if (!url) return false;
15+
return url.startsWith('http://') || url.startsWith('https://') || url.startsWith('//');
16+
};
17+
18+
1219
type CustomCardProps = {
1320
title: string;
1421
description: string;
1522
href: string;
16-
target?: string;
23+
target?: string; // Keep this optional for manual override if needed
1724
avatarSrc?: string | null;
1825
avatarFallback?: string;
1926
showIcon?: boolean;
@@ -26,14 +33,17 @@ export const CustomCard = ({
2633
title,
2734
description,
2835
href,
29-
target = "_blank",
36+
target, // Remove default value, we'll determine it automatically
3037
avatarSrc = null,
3138
avatarFallback = "CN",
3239
showIcon = false,
3340
icon: IconComponent = Heart,
3441
iconSize = 24,
3542
className = "",
3643
}: CustomCardProps) => {
44+
const isExternal = isExternalUrl(href);
45+
const linkTarget = target || (isExternal ? "_blank" : "_self");
46+
3747
return (
3848
<Card className={`w-full max-w-sm mx-auto min-w-0 hover:shadow-md transition-shadow duration-200 ${className}`}>
3949
<CardHeader>
@@ -57,9 +67,14 @@ export const CustomCard = ({
5767
<div className="flex-1 min-w-0">
5868
<CardTitle className="text-sm sm:text-base md:text-lg leading-tight">
5969
{href ? (
60-
<a href={href} target={target} className="hover:underline inline-flex items-center gap-2">
70+
<a
71+
href={href}
72+
target={linkTarget}
73+
rel={isExternal ? "noopener noreferrer" : undefined}
74+
className="hover:underline inline-flex items-center gap-2"
75+
>
6176
{title}
62-
<FaExternalLinkAlt size={12} className="flex-shrink-0 opacity-60" />
77+
{isExternal && <FaExternalLinkAlt size={12} className="flex-shrink-0 opacity-60" />}
6378
</a>
6479
) : (
6580
title
@@ -81,48 +96,61 @@ export const CustomCardHorizontal = ({
8196
title,
8297
description,
8398
href,
84-
target = "_blank",
99+
target, // Remove default value
85100
avatarSrc = null,
86101
avatarFallback = "CN",
87102
showIcon = false,
88103
icon: IconComponent = Heart,
89104
iconSize = 24,
90105
className = "",
91106
}: CustomCardProps) => {
107+
const isExternal = isExternalUrl(href);
108+
const linkTarget = target || (isExternal ? "_blank" : "_self");
109+
92110
return (
93111
<Card className={`w-full max-w-sm mx-auto min-w-0 hover:shadow-md transition-shadow duration-200 ${className}`}>
94-
<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">
95-
{/* Image Section — responsive positioning */}
96-
<div className="flex justify-center sm:block">
97-
{avatarSrc ? (
98-
<Avatar className="h-24 w-24 rounded-md shadow-md">
99-
<AvatarImage src={avatarSrc} alt="Avatar" />
100-
<AvatarFallback>{avatarFallback}</AvatarFallback>
101-
</Avatar>
102-
) : showIcon && IconComponent ? (
103-
<div className="w-24 h-24 flex items-center justify-center rounded-md bg-gray-100 shadow-md">
104-
<IconComponent size={iconSize} className="text-gray-500" />
112+
<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">
113+
{/* Image Section — responsive positioning */}
114+
<div className="flex justify-center sm:block">
115+
{avatarSrc ? (
116+
<Avatar className="h-24 w-24 rounded-md shadow-md">
117+
<AvatarImage
118+
src={avatarSrc}
119+
alt="Avatar"
120+
className="object-contain"
121+
style={{ objectFit: 'contain' }}
122+
/>
123+
<AvatarFallback>{avatarFallback}</AvatarFallback>
124+
</Avatar>
125+
) : showIcon && IconComponent ? (
126+
<div className="w-24 h-24 flex items-center justify-center rounded-md bg-gray-100 shadow-md">
127+
<IconComponent size={iconSize} className="text-gray-500" />
128+
</div>
129+
) : null}
105130
</div>
106-
) : null}
107-
</div>
108131

109-
{/* Content Section — always left aligned */}
110-
<div className="flex-1 text-left">
111-
<CardTitle className="text-lg font-semibold">
112-
{href ? (
113-
<a href={href} target={target} className="inline-flex items-center gap-2 hover:underline">
114-
{title}
115-
<FaExternalLinkAlt size={12} className="opacity-60" />
116-
</a>
117-
) : (
118-
title
119-
)}
120-
</CardTitle>
121-
<CardDescription className="text-sm mt-1">
122-
{description}
123-
</CardDescription>
124-
</div>
125-
</div>
126-
</Card>
132+
{/* Content Section — always left aligned */}
133+
<div className="flex-1 text-left">
134+
<CardTitle className="text-lg font-semibold">
135+
{href ? (
136+
<a
137+
href={href}
138+
target={linkTarget}
139+
rel={isExternal ? "noopener noreferrer" : undefined}
140+
className="inline-flex items-center gap-2 hover:underline"
141+
>
142+
{title}
143+
{isExternal && <FaExternalLinkAlt size={12} className="opacity-60" />}
144+
</a>
145+
) : (
146+
title
147+
)}
148+
</CardTitle>
149+
<CardDescription className="text-sm mt-1">
150+
{description}
151+
</CardDescription>
152+
</div>
153+
</div>
154+
</Card>
127155
);
128-
}
156+
}

src/components/Funding.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const Logo = ({ logo }: { logo: LogoItem }) => {
1111
alt={logo.alt}
1212
width={logo.width}
1313
height={logo.height}
14-
className="h-8 w-auto"
14+
className="h-auto w-auto max-h-8 sm:max-h-12 object-contain"
1515
priority
1616
/>
1717
);
@@ -37,7 +37,7 @@ const RenderLogo = ({ logo, defaultLogoText }: {
3737

3838
if (Array.isArray(logo)) {
3939
return (
40-
<div className="flex items-center gap-2">
40+
<div className="flex flex-col sm:flex-row items-center sm:items-center gap-4 sm:gap-2">
4141
{logo.map((item, index) => (
4242
<Logo key={index} logo={item} />
4343
))}

0 commit comments

Comments
 (0)