diff --git a/src/app/globals.css b/src/app/globals.css index 35207dc..18e435f 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -5,6 +5,13 @@ --breakpoint-xs: 26.25rem; } +/* + * Viewport-height variant: laptop screens once browser chrome is subtracted + * (1366x768 -> ~657px, 1536x864 -> ~750px, 1440x900 -> ~790px) and most phones. + * The hero uses it to fit its first screen. Combine with breakpoints: `lg:short:mt-4`. + */ +@custom-variant short (@media (max-height: 56.25rem)); + /* * Page gutter (16/24/32px) that also clears landscape notches: the viewport uses * viewport-fit=cover, so content would otherwise slide under the notch. diff --git a/src/components/ui/layout.tsx b/src/components/ui/layout.tsx index deb8e4f..b559913 100644 --- a/src/components/ui/layout.tsx +++ b/src/components/ui/layout.tsx @@ -108,14 +108,16 @@ export interface MetricTileProps { value: string detail?: string className?: string + /** Extra classes for the detail line (e.g. hiding it where vertical space is tight) */ + detailClassName?: string } -export function MetricTile({ label, value, detail, className }: MetricTileProps) { +export function MetricTile({ label, value, detail, className, detailClassName }: MetricTileProps) { return (

{label}

{value}

- {detail &&

{detail}

} + {detail &&

{detail}

}
) } diff --git a/src/features/landing/Hero.tsx b/src/features/landing/Hero.tsx index ae30e49..96f02ea 100644 --- a/src/features/landing/Hero.tsx +++ b/src/features/landing/Hero.tsx @@ -1,5 +1,6 @@ 'use client' +import { useId, useState } from 'react' import { ArrowRightIcon, Avatar, @@ -15,6 +16,7 @@ import { Surface, } from '@/components/ui' import { useTranslations, useLocale } from '@/i18n' +import { cn } from '@/lib/utils' import { SOCIAL_LINKS, getCvUrl } from '@/lib/constants' import { useEmailCopyFeedback } from '@/lib/hooks/useEmailCopyFeedback' import { FEATURED_PROJECTS } from '@/content/featuredProjects' @@ -26,6 +28,9 @@ import { FeaturedProjectCard } from './FeaturedProjectCard' type SocialKey = (typeof SOCIAL_LINKS)[number]['key'] +const METRIC_TILE_CLASS = 'lg:short:p-3' +const METRIC_DETAIL_CLASS = 'lg:short:max-xl:hidden' + function BriefcaseIcon({ className }: { className?: string }) { return ( @@ -58,6 +63,10 @@ export function Hero() { } = useFeaturedRotation(FEATURED_PROJECTS) const cvUrl = getCvUrl(locale) const { copiedEmail, copyEmail } = useEmailCopyFeedback() + // On short screens (`short`: ≤900px tall) the long bio is clamped so the whole hero fits the first screen; + // the full text stays in the DOM for screen readers and search engines. + const [isBioExpanded, setIsBioExpanded] = useState(false) + const bioId = useId() // Copy about the current role switches on its start date (see useEntryPhase) const isRoleUpcoming = useEntryPhase(CURRENT_ROLE_ID) === 'upcoming' const roleMetric = isRoleUpcoming ? 'metrics.upcoming' : 'metrics.current' @@ -68,12 +77,17 @@ export function Hero() { } return ( - +
{/* CSS entrance (.hero-enter): the first screen is visible before hydration */}
- -
+ +
XR FIELD MD-ES / 2026
@@ -85,11 +99,17 @@ export function Hero() { >
- + {/* From lg the portrait scales with the viewport height (138px at 657px tall, capped at 224px) */} +
- +

{t('name')}

{t('headline')}

-
+
{t(isRoleUpcoming ? 'availabilityLabelUpcoming' : 'availabilityLabel')} @@ -132,7 +152,7 @@ export function Hero() { {t('location')}
-
+
{t('ctaResume')} @@ -168,14 +188,34 @@ export function Hero() {
-

- {t(isRoleUpcoming ? 'aboutMeUpcoming' : 'aboutMe')} -

+
+

+ {t(isRoleUpcoming ? 'aboutMeUpcoming' : 'aboutMe')} +

+ {/* Only short screens clamp the bio, so only they need the toggle */} + +
-
- - - +
+ {/* Short lg/laptop screens: tighter tiles; below xl the narrow columns would wrap the detail onto two lines */} + + +
diff --git a/src/i18n/messages/en.json b/src/i18n/messages/en.json index 07720d6..0822cf9 100644 --- a/src/i18n/messages/en.json +++ b/src/i18n/messages/en.json @@ -31,6 +31,8 @@ "headlineSub": "Systems, Cloud, Full-Stack and XR developer tools", "aboutMe": "Telematics Engineer from URJC, graduated in January 2026, with experience in software development, systems, and data visualization. Author of Code-XR, an open-source VS Code extension published at IEEE VISSOFT 2025, focused on visual analysis of code metrics in XR environments. Currently enrolled in the Master's Degree in Telecommunications Engineering at UPM, specializing in Machine Learning and Big Data, while working as a Specialist Technician on a URJC research project on dependencies in complex collections of software modules, after an extracurricular Cloud & Systems N2 internship at SATEC. Interested in software analytics, code repositories, and applied research.", "aboutMeUpcoming": "Telematics Engineer from URJC, graduated in January 2026, with experience in software development, systems, and data visualization. Author of Code-XR, an open-source VS Code extension published at IEEE VISSOFT 2025, focused on visual analysis of code metrics in XR environments. Currently enrolled in the Master's Degree in Telecommunications Engineering at UPM, specializing in Machine Learning and Big Data. After an extracurricular Cloud & Systems N2 internship at SATEC, joining a URJC research project on dependencies in complex collections of software modules as a Specialist Technician on October 8, 2026. Interested in software analytics, code repositories, and applied research.", + "readMore": "Read more", + "readLess": "Show less", "ctaProjects": "View Projects", "ctaResume": "Download CV", "availabilityLabel": "Currently active", diff --git a/src/i18n/messages/es.json b/src/i18n/messages/es.json index ae23b07..2a0e785 100644 --- a/src/i18n/messages/es.json +++ b/src/i18n/messages/es.json @@ -31,6 +31,8 @@ "headlineSub": "Sistemas, Cloud, Full-Stack y herramientas XR", "aboutMe": "Ingeniero Telemático por la URJC, titulado en enero de 2026, con experiencia en desarrollo software, sistemas y visualización de datos. Autor de Code-XR, extensión open source para VS Code publicada en IEEE VISSOFT 2025, orientada al análisis visual de métricas de código en entornos XR. Actualmente cursando el Máster Universitario en Ingeniería de Telecomunicación en la UPM, con intensificación en Aprendizaje Automático y Big Data, compaginándolo con un puesto de Técnico Especialista en un proyecto de investigación de la URJC sobre dependencias en colecciones complejas de módulos software, tras unas prácticas extracurriculares en Cloud & Sistemas N2 de SATEC. Interesado en analítica de software, repositorios de código e investigación aplicada.", "aboutMeUpcoming": "Ingeniero Telemático por la URJC, titulado en enero de 2026, con experiencia en desarrollo software, sistemas y visualización de datos. Autor de Code-XR, extensión open source para VS Code publicada en IEEE VISSOFT 2025, orientada al análisis visual de métricas de código en entornos XR. Actualmente cursando el Máster Universitario en Ingeniería de Telecomunicación en la UPM, con intensificación en Aprendizaje Automático y Big Data. Tras unas prácticas extracurriculares en Cloud & Sistemas N2 de SATEC, se incorpora el 8 de octubre de 2026 como Técnico Especialista a un proyecto de investigación de la URJC sobre dependencias en colecciones complejas de módulos software. Interesado en analítica de software, repositorios de código e investigación aplicada.", + "readMore": "Leer más", + "readLess": "Mostrar menos", "ctaProjects": "Ver Proyectos", "ctaResume": "Descargar CV", "availabilityLabel": "Actualmente activo",