/* --- Self-hosted fonts ---
   Previously loaded from Google Fonts (fonts.googleapis.com/fonts.gstatic.com),
   which sends every visitor's IP to Google before they've agreed to
   anything — self-hosting removes that entirely and drops one round-trip.
   Both are variable fonts, so one file each covers the whole 300-700
   weight range the site uses. */
@font-face {
    font-family: 'Outfit';
    src: url('fonts/outfit-variable.woff2') format('woff2-variations'), url('fonts/outfit-variable.woff2') format('woff2');
    font-weight: 300 700;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Plus Jakarta Sans';
    src: url('fonts/plus-jakarta-sans-variable.woff2') format('woff2-variations'), url('fonts/plus-jakarta-sans-variable.woff2') format('woff2');
    font-weight: 300 700;
    font-style: normal;
    font-display: swap;
}

/* --- Reset & Variables --- */
:root {
    --color-bg: #000000;
    --color-bg-rgb: 0, 0, 0;
    --color-surface: #0a0a0a;
    --color-surface-hover: #121212;
    --color-border: #161616;
    --color-border-hover: #333333;
    
    /* Monochrome Palette (Absolutely no vibrant colors) */
    --color-text: #ffffff;
    --color-text-muted: #888888;
    --color-text-light: #cccccc;
    --color-accent: #ffffff;
    
    --font-sans: 'Plus Jakarta Sans', sans-serif;
    --font-display: 'Outfit', sans-serif;
    
    --transition-smooth: all 0.7s cubic-bezier(0.16, 1, 0.3, 1);
    --transition-fast: all 0.35s cubic-bezier(0.16, 1, 0.3, 1);
    
    --max-width: 1040px;
    --header-height: 80px;

    /* Card-style boxes (focus cards, spec cards, modal, wind banner, demo
       screenshots) share these so the whole site softens consistently. */
    --radius-md: 14px;
    --radius-sm: 8px;
}

*, *::before, *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

html {
    scroll-behavior: smooth;
    scroll-padding-top: var(--header-height);
}

body {
    background-color: var(--color-bg);
    color: var(--color-text);
    font-family: var(--font-sans);
    line-height: 1.62;
    overflow-x: hidden;
    -webkit-font-smoothing: antialiased;
}

/* Custom Selection */
::selection {
    background-color: rgba(255, 255, 255, 0.15);
    color: var(--color-text);
}

/* Scrollbar */
::-webkit-scrollbar {
    width: 6px;
}
::-webkit-scrollbar-track {
    background: var(--color-bg);
}
::-webkit-scrollbar-thumb {
    background: #1c1c1c;
    border-radius: 0;
}
::-webkit-scrollbar-thumb:hover {
    background: #2a2a2a;
}

a {
    color: inherit;
    text-decoration: none;
}

ul {
    list-style: none;
}

img {
    max-width: 100%;
    height: auto;
    display: block;
}

button, input, textarea {
    font-family: inherit;
    background: none;
    border: none;
    outline: none;
    color: inherit;
}

/* --- Layout Utilities --- */
.container {
    width: 100%;
    max-width: var(--max-width);
    margin: 0 auto;
    padding: 0 24px;
}

.section {
    padding: 120px 0;
    position: relative;
    border-bottom: 1px solid var(--color-border);
}

/* The hero is already a full 100vh block on its own, so stacking the
   standard 120px section padding on top of that left a lot of empty black
   space before "Chi Sono" appeared. Tightened for this one transition only. */
.about-section {
    padding-top: 60px;
}

.section:last-of-type {
    border-bottom: none;
}

.section-header {
    margin-bottom: 70px;
}

.section-title {
    font-family: var(--font-display);
    font-size: 2.5rem;
    font-weight: 300;
    letter-spacing: -0.03em;
    color: var(--color-text);
    margin-bottom: 16px;
    text-transform: uppercase;
}

.section-divider {
    width: 40px;
    height: 1px;
    background: var(--color-text);
    opacity: 0.3;
}

/* --- Scroll Progress Bar --- */
/* transform: scaleX is compositor-only (no layout/paint), so this tracks
   scroll perfectly smoothly even on long, content-heavy pages. */
.scroll-progress {
    position: fixed;
    top: 0;
    left: 0;
    height: 2px;
    width: 100%;
    background: linear-gradient(90deg, rgba(255, 255, 255, 0.35), #ffffff);
    z-index: 1100;
    pointer-events: none;
    transform: scaleX(0);
    transform-origin: left;
    will-change: transform;
}

/* --- Preloader --- */
.preloader {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: var(--color-bg);
    z-index: 9999;
    display: flex;
    justify-content: center;
    align-items: center;
    transition: opacity 0.8s cubic-bezier(0.16, 1, 0.3, 1), visibility 0.8s;
}

.preloader.fade-out {
    opacity: 0;
    visibility: hidden;
}

.loader-content {
    text-align: center;
    animation: loaderIn 0.9s cubic-bezier(0.16, 1, 0.3, 1);
}

@keyframes loaderIn {
    from { opacity: 0; transform: translateY(12px); }
    to { opacity: 1; transform: translateY(0); }
}

.loader-name {
    font-family: var(--font-display);
    font-size: 1.8rem;
    font-weight: 500;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--color-text);
    margin-bottom: 6px;
}

.loader-subtitle {
    font-family: var(--font-sans);
    font-size: 0.8rem;
    font-weight: 400;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--color-text-muted);
    margin-bottom: 24px;
}

.loader-bar-container {
    width: 120px;
    height: 1px;
    background-color: rgba(255, 255, 255, 0.08);
    margin: 0 auto;
    overflow: hidden;
    position: relative;
}

.loader-bar {
    width: 0%;
    height: 100%;
    background-color: var(--color-text);
    animation: loading 1.2s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

@keyframes loading {
    0% { width: 0%; }
    100% { width: 100%; }
}

/* --- Buttons --- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 12px 32px;
    font-family: var(--font-sans);
    font-weight: 500;
    font-size: 0.9rem;
    cursor: pointer;
    border-radius: var(--radius-sm);
    transition: background-color 0.35s cubic-bezier(0.16, 1, 0.3, 1),
                color 0.35s cubic-bezier(0.16, 1, 0.3, 1),
                border-color 0.35s cubic-bezier(0.16, 1, 0.3, 1),
                box-shadow 0.35s cubic-bezier(0.16, 1, 0.3, 1),
                transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
    letter-spacing: 0.03em;
}

.btn:active {
    transform: scale(0.96) !important;
}

.btn-primary {
    background-color: var(--color-text);
    color: var(--color-bg);
    border: 1px solid var(--color-text);
}

.btn-primary:hover {
    background-color: transparent;
    color: var(--color-text);
    box-shadow: 0 10px 30px rgba(255, 255, 255, 0.1);
}

.btn-secondary {
    background-color: transparent;
    color: var(--color-text-muted);
    border: 1px solid var(--color-border);
}

.btn-secondary:hover {
    color: var(--color-text);
    border-color: var(--color-border-hover);
}

/* --- Header / Navigation --- */
.header {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: var(--header-height);
    background-color: rgba(0, 0, 0, 0.85);
    border-bottom: 1px solid var(--color-border);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    z-index: 100;
    transition: var(--transition-smooth);
}

.header.header-scrolled {
    height: 60px;
    background-color: rgba(0, 0, 0, 0.95);
    border-bottom-color: rgba(255, 255, 255, 0.04);
}

.header-container {
    display: flex;
    justify-content: space-between;
    align-items: center;
    height: 100%;
}

.logo {
    font-family: var(--font-display);
    font-size: 1.4rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    text-transform: uppercase;
    display: inline-block;
    transition: var(--transition-fast);
}

.logo:hover {
    transform: rotate(-6deg) scale(1.05);
    color: var(--color-text-muted);
}

.header-actions {
    display: flex;
    align-items: center;
    gap: 28px;
}

.lang-switch {
    display: flex;
    align-items: center;
    gap: 8px;
}

.lang-btn {
    display: inline-flex;
    padding: 2px;
    line-height: 0;
    border: 1px solid transparent;
    border-radius: 3px;
    cursor: pointer;
    opacity: 0.45;
    transition: var(--transition-fast);
}

.lang-btn svg {
    display: block;
    border-radius: 2px;
}

.lang-btn:hover {
    opacity: 0.8;
    transform: translateY(-1px);
}

.lang-btn.active {
    opacity: 1;
    border-color: rgba(255, 255, 255, 0.35);
}

.nav-toggle {
    display: none;
    cursor: pointer;
    z-index: 110;
}

.hamburger {
    display: block;
    width: 20px;
    height: 1px;
    background-color: var(--color-text);
    position: relative;
    transition: var(--transition-fast);
}

.hamburger::before, .hamburger::after {
    content: '';
    position: absolute;
    width: 100%;
    height: 100%;
    background-color: var(--color-text);
    transition: var(--transition-fast);
}

.hamburger::before { top: -5px; }
.hamburger::after { top: 5px; }

.nav-toggle.active .hamburger {
    background-color: transparent;
}
.nav-toggle.active .hamburger::before {
    transform: rotate(45deg);
    top: 0;
}
.nav-toggle.active .hamburger::after {
    transform: rotate(-45deg);
    top: 0;
}

.nav-list {
    display: flex;
    gap: 40px;
}

.nav-link {
    position: relative;
    font-family: var(--font-sans);
    font-weight: 400;
    font-size: 0.9rem;
    color: var(--color-text-muted);
    transition: var(--transition-fast);
    padding: 6px 0;
}

.nav-link::after {
    content: '';
    position: absolute;
    left: 0;
    bottom: 0;
    width: 100%;
    height: 1px;
    background-color: var(--color-text);
    transform: scaleX(0);
    transform-origin: right;
    transition: transform 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}

.nav-link:hover {
    color: var(--color-text);
}

.nav-link:hover::after,
.nav-link.active-link::after {
    transform: scaleX(1);
    transform-origin: left;
}

.nav-link.active-link {
    color: var(--color-text);
}

/* --- Hero Section --- */
.hero-section {
    min-height: 100vh;
    display: flex;
    align-items: center;
    position: relative;
    padding-top: var(--header-height);
    overflow: hidden;
}

/* A fixed-size, pre-rendered glow that we move with transform (translate3d)
   instead of recalculating a gradient's center every mousemove — the former
   repaints the whole background each frame, the latter is compositor-only
   and stays smooth no matter how fast the cursor moves. */
.hero-glow {
    position: absolute;
    top: 0;
    left: 0;
    width: 600px;
    height: 600px;
    margin-left: -300px;
    margin-top: -300px;
    z-index: 0;
    pointer-events: none;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(255, 255, 255, 0.08), transparent 65%);
    opacity: 0;
    transform: translate3d(50vw, 260px, 0);
    transition: opacity 0.4s ease;
    will-change: transform;
}

.hero-section:hover .hero-glow {
    opacity: 1;
}

/* filter: blur() visually bleeds well past the element's own box, by an
   amount that's hard to predict — so however this box was positioned
   against .hero-section's overflow:hidden, the clip line kept landing
   somewhere inside that still-bright bleed and showing a hard seam.
   A radial-gradient sidesteps the problem entirely: it reaches true,
   mathematical transparent() at 65% of the box's own radius. For that to
   actually clear the section edge, the distance from the gradient's center
   to that edge must stay above 65% of the radius — i.e. (radius - overhang)
   / radius >= 0.65, so overhang <= 0.35 * radius (kept comfortably under
   that here, 0.35 * radius). The floating animation below also drifts the
   box a little further out at its peak, which is small enough to stay
   inside that margin too. */
.hero-blob {
    position: absolute;
    z-index: 0;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(255, 255, 255, 0.16), transparent 65%);
    pointer-events: none;
    animation: blobFloat 20s ease-in-out infinite;
}

.hero-blob-1 {
    width: 460px;
    height: 460px;
    top: -55px;
    left: -55px;
}

.hero-blob-2 {
    width: 440px;
    height: 440px;
    bottom: -50px;
    right: -50px;
    animation-delay: -10s;
}

@keyframes blobFloat {
    0%, 100% { transform: translate(0, 0) scale(1); }
    /* Kept small on purpose: this drift adds directly to whichever overhang
       is already closest to the safety margin above (top for blob-1, right
       for blob-2), so a bigger drift would need an even bigger circle to
       stay safely inside it. Scale doesn't have this problem — it grows the
       radius and the transparent-stop distance by the same factor, so the
       ratio between them (and therefore the safety margin) stays constant. */
    50% { transform: translate(14px, -12px) scale(1.12); }
}

.hero-content {
    position: relative;
    z-index: 1;
    max-width: 800px;
    margin: 0 auto;
    text-align: center;
}

.hero-tagline {
    display: inline-block;
    font-size: 0.8rem;
    font-weight: 500;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--color-text-muted);
    margin-bottom: 24px;
}

.hero-title {
    font-family: var(--font-display);
    font-size: 3.8rem;
    font-weight: 300;
    line-height: 1.18;
    letter-spacing: -0.03em;
    margin-bottom: 28px;
    color: var(--color-text-muted);
}

.hero-title .text-light {
    background: linear-gradient(90deg, #ffffff 0%, #888888 45%, #ffffff 100%);
    background-size: 200% auto;
    background-clip: text;
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    color: var(--color-text);
    animation: textShine 7s linear infinite;
}

@keyframes textShine {
    to { background-position: -200% center; }
}

.hero-description {
    font-size: 1.15rem;
    color: var(--color-text-muted);
    margin-bottom: 48px;
    max-width: 600px;
    margin-left: auto;
    margin-right: auto;
    font-weight: 300;
}

.hero-cta {
    display: flex;
    gap: 16px;
    justify-content: center;
}

.scroll-down-btn {
    position: absolute;
    bottom: 50px;
    left: 50%;
    transform: translateX(-50%);
    color: var(--color-text-muted);
    display: flex;
    flex-direction: column;
    align-items: center;
    z-index: 2;
    animation: bounce 2s infinite;
    cursor: pointer;
    transition: var(--transition-fast);
}

.scroll-down-btn svg {
    width: 18px;
    height: 18px;
}

.scroll-down-btn:hover {
    color: var(--color-text);
}

@keyframes bounce {
    0%, 20%, 50%, 80%, 100% { transform: translate(-50%, 0); }
    40% { transform: translate(-50%, -6px); }
    60% { transform: translate(-50%, -3px); }
}

/* --- About Section --- */
/* Bio text is a single centered column, read top to bottom; Experience/
   Education/Languages live in their own full-width block below (see
   .experience-panel). */
.about-text {
    max-width: 720px;
    margin: 0 auto 60px;
}

.about-text h3 {
    font-family: var(--font-display);
    font-size: 1.6rem;
    font-weight: 400;
    margin-bottom: 24px;
    letter-spacing: -0.01em;
}

.about-text p {
    color: var(--color-text-muted);
    margin-bottom: 20px;
    font-weight: 300;
}

.journey-section h3 {
    font-family: var(--font-display);
    font-size: 1.6rem;
    font-weight: 400;
    margin-bottom: 24px;
    letter-spacing: -0.01em;
}

.journey-section {
    margin-top: 50px;
}

.journey-section:first-of-type {
    margin-top: 0;
}

.experience-panel {
    margin-bottom: 80px;
}

/* Collapsible Experience / Education accordions: the grid-template-rows
   0fr -> 1fr trick animates to the content's natural height with no JS
   measuring, so it stays smooth even as content, language or font-loading
   changes that height. overflow+min-height:0 on the inner wrapper is what
   lets the 0fr row actually collapse to zero instead of clamping to the
   content's min-content size. */
.journey-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    width: 100%;
    cursor: pointer;
    font-family: var(--font-display);
    font-size: 1.6rem;
    font-weight: 400;
    letter-spacing: -0.01em;
    transition: color 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}

.journey-toggle:hover {
    color: var(--color-text-muted);
}

.journey-toggle-icon {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
    color: var(--color-text-muted);
    transition: transform 0.45s cubic-bezier(0.16, 1, 0.3, 1);
}

.journey-toggle[aria-expanded="true"] .journey-toggle-icon {
    transform: rotate(180deg);
}

.journey-collapse {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows 0.55s cubic-bezier(0.16, 1, 0.3, 1);
}

.journey-collapse.open {
    grid-template-rows: 1fr;
}

.journey-collapse-inner {
    overflow: hidden;
    min-height: 0;
}

.languages-list {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 16px;
}

.lang-tag {
    font-size: 0.8rem;
    font-weight: 400;
    padding: 6px 14px;
    border: 1px solid var(--color-border);
    color: var(--color-text-light);
    transition: var(--transition-fast);
}

.lang-tag:hover {
    border-color: var(--color-border-hover);
    color: var(--color-text);
}

/* Languages, nested inside the Formazione & Certificazioni accordion */
.journey-languages {
    margin-top: 34px;
    padding-top: 26px;
    border-top: 1px solid var(--color-border);
}

.journey-languages h4 {
    font-family: var(--font-sans);
    font-size: 0.8rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--color-text-muted);
}

.journey-list {
    display: flex;
    flex-direction: column;
}

.journey-item {
    display: grid;
    grid-template-columns: 120px 1fr;
    gap: 20px;
    padding: 24px 0;
    border-bottom: 1px solid var(--color-border);
}

.journey-item:first-of-type {
    padding-top: 0;
}

.journey-item:last-of-type {
    border-bottom: none;
    padding-bottom: 0;
}

.journey-year {
    font-family: var(--font-display);
    font-size: 0.95rem;
    font-weight: 400;
    color: var(--color-text-muted);
    padding-top: 2px;
}

.journey-details h4 {
    font-family: var(--font-sans);
    font-size: 1.05rem;
    font-weight: 500;
    margin-bottom: 2px;
}

.journey-org {
    font-size: 0.85rem;
    color: var(--color-text-muted);
    margin-bottom: 8px;
}

.journey-desc {
    font-size: 0.85rem;
    color: var(--color-text-muted);
    font-weight: 300;
}

/* --- Focus Areas --- */
.focus-section {
    padding-top: 60px;
    border-top: 1px solid var(--color-border);
}

.focus-title {
    font-family: var(--font-display);
    font-size: 1.6rem;
    font-weight: 400;
    margin-bottom: 40px;
    letter-spacing: -0.01em;
}

/* Static grid: one card per area, no carousel mechanics. */
.focus-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 24px;
}

.focus-card {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: 32px 28px;
    background: var(--color-surface);
    transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1),
                border-color 0.3s ease,
                box-shadow 0.3s ease;
}

.focus-card:hover {
    transform: translateY(-4px);
    border-color: var(--color-border-hover);
    box-shadow: 0 14px 28px rgba(0, 0, 0, 0.35);
}

.focus-num {
    font-family: var(--font-display);
    font-size: 1.7rem;
    font-weight: 300;
    color: var(--color-text-muted);
    margin-bottom: 18px;
    opacity: 0.5;
}

.focus-card h4 {
    font-family: var(--font-sans);
    font-size: 1.15rem;
    font-weight: 500;
    margin-bottom: 12px;
}

.focus-card p {
    font-size: 0.9rem;
    color: var(--color-text-muted);
    font-weight: 300;
    line-height: 1.6;
}

/* --- Technical Skills --- */
.skills-section {
    padding-top: 60px;
    margin-top: 60px;
    border-top: 1px solid var(--color-border);
}

.skills-title {
    font-family: var(--font-display);
    font-size: 1.6rem;
    font-weight: 400;
    margin-bottom: 32px;
    letter-spacing: -0.01em;
}

.skills-groups {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 32px;
}

.skills-group h4 {
    font-family: var(--font-sans);
    font-size: 0.8rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--color-text-muted);
    margin-bottom: 16px;
}

.skills-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

.skills-tags span {
    font-size: 0.85rem;
    font-weight: 300;
    color: var(--color-text-light);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    padding: 6px 14px;
    transition: var(--transition-fast);
}

.skills-tags span:hover {
    color: var(--color-text);
    border-color: var(--color-border-hover);
}

/* --- Projects Section --- */
.project-filters {
    display: flex;
    justify-content: flex-start;
    gap: 16px;
    margin-bottom: 60px;
}

.filter-btn {
    padding: 6px 18px;
    font-size: 0.85rem;
    font-weight: 400;
    border: 1px solid var(--color-border);
    cursor: pointer;
    transition: var(--transition-fast);
    color: var(--color-text-muted);
}

.filter-btn:hover {
    color: var(--color-text);
    border-color: var(--color-border-hover);
}

.filter-btn.active {
    color: var(--color-bg);
    background-color: var(--color-text);
    border-color: var(--color-text);
}

.projects-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 24px;
}

.featured-project {
    max-width: 800px;
    margin: 0 auto;
    text-align: center;
}

.windrose-name {
    font-family: var(--font-display);
    font-size: 1.7rem;
    font-weight: 400;
    letter-spacing: -0.01em;
    margin-bottom: 14px;
}

.windrose-desc {
    max-width: 560px;
    margin: 0 auto 48px;
    color: var(--color-text-muted);
    font-size: 0.95rem;
    font-weight: 300;
    line-height: 1.7;
}

/* --- Rosa dei Venti (interactive project selector) ---
   Ported from rosa-dei-venti.html; scoped under .owr- to avoid collisions.
   Colors are intentionally on-brand for Ostro (blue/cyan), the one
   exception to the site's otherwise monochrome palette. */
.owr-wrapper {
    --owr-accent-a: #2b6ef5;
    --owr-accent-b: #22d3ee;
    --owr-inactive: #3a4457;
    --owr-inactive-text: #64748b;
    --owr-frame: rgba(56, 189, 248, 0.18);
    position: relative;
    width: clamp(300px, 62vw, 560px);
    aspect-ratio: 1 / 1;
    margin: 0 auto;
}

.owr-star-svg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    overflow: visible;
}

.owr-frame-ring {
    position: absolute;
    inset: 1%;
    border-radius: 50%;
    border: 1px dashed var(--owr-frame);
    pointer-events: none;
    animation: owr-spin 100s linear infinite;
}
@keyframes owr-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }

.owr-core {
    position: absolute;
    top: 50%; left: 50%;
    width: 20%;
    aspect-ratio: 1/1;
    transform: translate(-50%, -50%);
    border-radius: 50%;
    background: radial-gradient(circle at 35% 30%, #0f1a2e, #060a12 70%);
    box-shadow: 0 0 0 1px rgba(56,189,248,0.25), 0 0 30px rgba(43,110,245,0.35);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    animation: owr-pulse 4s ease-in-out infinite;
    z-index: 3;
}
/* overflow: visible because the wind-line paths sit close to the icon's
   own viewBox edges — with the default clip, the drift animation below
   sliced them off sharply at that boundary. The circular .owr-core (with
   its own overflow: hidden) is the real clip edge, and there's plenty of
   margin between the icon and that circle for the drift to bleed into. */
.owr-core svg { width: 62%; height: 62%; overflow: visible; }

/* Wind Flow icon at the core: 3 gust lines drifting left-right on a loop,
   staggered so they read as one current of wind rather than 3 things
   moving in sync. Speeds up while the compass is being aimed
   (.owr-wrapper.is-aiming, set on hover/cursor-tracking — see script.js),
   and the core's own glow (below) intensifies with it, so the whole thing
   feels like it's responding to you.
   Note: no CSS `filter` here on purpose — a drop-shadow on an SVG shape
   forces the browser to composite it in its own rectangular layer, which
   showed up as a faint square edge against the circular core. */
.owr-wind-line {
    animation: owr-wind-blow 3s ease-in-out infinite;
}
.owr-wind-line--top { animation-delay: 0s; }
.owr-wind-line--mid { animation-delay: 0.25s; animation-duration: 2.6s; }
.owr-wind-line--bottom { animation-delay: 0.5s; }

.owr-wrapper.is-aiming .owr-wind-line {
    animation-duration: 1.1s;
}
.owr-wrapper.is-aiming .owr-wind-line--mid {
    animation-duration: 0.95s;
}

.owr-wrapper.is-aiming .owr-core {
    box-shadow: 0 0 0 1px rgba(56, 189, 248, 0.55), 0 0 46px rgba(43, 110, 245, 0.65);
}

@keyframes owr-wind-blow {
    0%, 100% { transform: translateX(-0.5px); opacity: 0.55; }
    50%      { transform: translateX(0.7px); opacity: 1; }
}
@keyframes owr-pulse {
    0%, 100% { box-shadow: 0 0 0 1px rgba(56,189,248,0.25), 0 0 26px rgba(43,110,245,0.3); }
    50%      { box-shadow: 0 0 0 1px rgba(56,189,248,0.45), 0 0 42px rgba(43,110,245,0.55); }
}

.owr-needle {
    position: absolute;
    top: 50%; left: 50%;
    width: 2px;
    height: 27%;
    transform-origin: 50% 100%;
    transform: translate(-50%, -100%) rotate(0deg);
    transition: transform 0.18s ease-out;
    animation: owr-needle-idle 6s ease-in-out infinite;
    pointer-events: none;
    z-index: 2;
}
.owr-wrapper.is-aiming .owr-needle { animation: none; }
.owr-needle::after {
    content: "";
    position: absolute;
    top: 0; left: 50%;
    width: 0; height: 0;
    transform: translateX(-50%);
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
    border-bottom: 10px solid var(--owr-accent-b);
    filter: drop-shadow(0 0 4px var(--owr-accent-b));
}
@keyframes owr-needle-idle {
    0%, 100% { transform: translate(-50%, -100%) rotate(-4deg); }
    50%      { transform: translate(-50%, -100%) rotate(4deg); }
}

.owr-spike-major {
    filter: drop-shadow(0 0 6px rgba(43,110,245,0.25));
}
.owr-spike-major.owr-spike-active {
    filter: drop-shadow(0 0 12px rgba(34,211,238,0.65));
}
.owr-spike-minor { opacity: 0.5; }

/* Degree ticks + intercardinal labels: purely decorative graduation,
   filling the empty ring between the spikes and the frame like a real
   compass card. No glow/filter on purpose — that's reserved for the
   interactive elements (needle, active point, wind icon). */
.owr-tick {
    stroke: var(--owr-inactive-text);
    stroke-width: 0.6;
    opacity: 0.45;
}

.owr-intercardinal-label {
    fill: var(--owr-inactive-text);
    font-family: var(--font-sans);
    font-size: 4.2px;
    font-weight: 600;
    letter-spacing: 0.03em;
    opacity: 0.55;
}

.owr-point {
    position: absolute;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    transform: translate(-50%, -50%);
    cursor: pointer;
    background: none;
    border: none;
    padding: 6px;
    font-family: inherit;
    opacity: 0;
    animation: owr-point-in 0.6s ease forwards;
    z-index: 4;
}
.owr-point:focus-visible .owr-dot {
    outline: 2px solid var(--owr-accent-b);
    outline-offset: 3px;
}
@keyframes owr-point-in {
    from { opacity: 0; transform: translate(-50%, -50%) scale(0.4); }
    to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}

.owr-dot {
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: var(--owr-inactive);
    transition: transform 0.25s ease, box-shadow 0.25s ease, background 0.25s ease;
}
.owr-point--active .owr-dot {
    background: linear-gradient(135deg, var(--owr-accent-a), var(--owr-accent-b));
    box-shadow: 0 0 14px rgba(34, 211, 238, 0.7);
    animation: owr-dot-glow 2.4s ease-in-out infinite;
}
@keyframes owr-dot-glow {
    0%, 100% { box-shadow: 0 0 10px rgba(34, 211, 238, 0.55); }
    50%      { box-shadow: 0 0 22px rgba(34, 211, 238, 0.9); }
}
.owr-point:hover .owr-dot,
.owr-point:focus-visible .owr-dot {
    transform: scale(1.35);
}
.owr-point--inactive:hover .owr-dot {
    background: #4b5670;
}

.owr-label {
    font-size: clamp(0.78rem, 1.8vw, 1rem);
    font-weight: 600;
    color: #e2e8f0;
    letter-spacing: 0.02em;
    white-space: nowrap;
    transition: color 0.25s ease;
}
.owr-point--inactive .owr-label { color: var(--owr-inactive-text); }
.owr-point--active .owr-label { color: #7dd3fc; }
.owr-point--active:hover .owr-label,
.owr-point--active:focus-visible .owr-label { color: #fff; }

.owr-badge {
    font-size: 0.62rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    padding: 1px 7px;
    border-radius: 999px;
    color: var(--owr-inactive-text);
    border: 1px solid #2a3345;
    background: rgba(255,255,255,0.02);
}
.owr-point--active .owr-badge {
    color: #0b1220;
    background: linear-gradient(135deg, var(--owr-accent-a), var(--owr-accent-b));
    border-color: transparent;
}

.owr-beam {
    position: absolute;
    top: 50%; left: 50%;
    height: 1px;
    width: 0;
    transform-origin: 0% 50%;
    background: linear-gradient(90deg, rgba(56,189,248,0.9), rgba(56,189,248,0));
    opacity: 0;
    transition: width 0.35s ease, opacity 0.35s ease;
    pointer-events: none;
    z-index: 1;
}

.owr-tooltip {
    position: absolute;
    bottom: calc(100% + 8px);
    left: 50%;
    transform: translateX(-50%) translateY(4px);
    background: #101827;
    border: 1px solid #263248;
    color: #cbd5e1;
    font-size: 0.72rem;
    padding: 5px 9px;
    border-radius: 6px;
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s ease, transform 0.2s ease;
}
.owr-point:hover .owr-tooltip,
.owr-point:focus-visible .owr-tooltip {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}

/* Wind info banner: a floating card describing whichever wind was
   clicked; for the active one (Ostro) it also links through to the full
   project specs modal. Always centered over the compass itself — same
   spot every time regardless of which wind triggered it — rather than
   anchored next to each point, which read as jumping around unpredictably
   between clicks. */
.owr-info-banner {
    position: absolute;
    top: 50%;
    left: 50%;
    z-index: 6;
    width: min(280px, 76vw);
    padding: 20px 22px;
    text-align: left;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: 0 18px 40px rgba(0, 0, 0, 0.45);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transform: translate(-50%, -50%) scale(0.94);
    transition: opacity 0.35s cubic-bezier(0.16, 1, 0.3, 1),
                transform 0.35s cubic-bezier(0.16, 1, 0.3, 1),
                visibility 0.35s;
}

.owr-info-banner.open {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: translate(-50%, -50%) scale(1);
}

.owr-info-close {
    position: absolute;
    top: 12px;
    right: 12px;
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--color-text-muted);
    cursor: pointer;
    transition: var(--transition-fast);
}

.owr-info-close:hover {
    color: var(--color-text);
}

.owr-info-close svg {
    width: 15px;
    height: 15px;
}

.owr-info-badge {
    display: inline-block;
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    padding: 2px 9px;
    border-radius: 999px;
    color: var(--owr-inactive-text, var(--color-text-muted));
    border: 1px solid var(--color-border);
    margin-bottom: 10px;
}

.owr-info-title {
    font-family: var(--font-display);
    font-size: 1.15rem;
    font-weight: 400;
    margin-bottom: 10px;
    padding-right: 18px;
}

.owr-info-desc {
    font-size: 0.85rem;
    color: var(--color-text-muted);
    font-weight: 300;
    line-height: 1.6;
}

.owr-info-note {
    font-size: 0.75rem;
    color: var(--color-text-muted);
    font-weight: 300;
    font-style: italic;
    margin-top: 12px;
}

.owr-info-note:empty,
.owr-info-cta:empty {
    display: none;
}

.owr-info-cta {
    margin-top: 18px;
    padding: 10px 22px;
    font-size: 0.85rem;
}

@media (prefers-reduced-motion: reduce) {
    .owr-frame-ring, .owr-core, .owr-needle,
    .owr-wind-line, .owr-point--active .owr-dot {
        animation: none !important;
    }
}

.project-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    padding: 40px;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    min-height: 290px;
    cursor: pointer;
    transition: var(--transition-smooth);
    transform-style: preserve-3d;
    will-change: transform;
}

.project-card:hover {
    border-color: var(--color-border-hover);
    transform: translateY(-4px);
}

.project-card-header {
    margin-bottom: 24px;
}

.project-tag {
    font-size: 0.7rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--color-text-muted);
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    padding-bottom: 4px;
}

.project-card-body {
    margin-bottom: 30px;
}

.project-title {
    font-family: var(--font-display);
    font-size: 1.6rem;
    font-weight: 400;
    margin-bottom: 10px;
    letter-spacing: -0.01em;
}

.project-summary {
    color: var(--color-text-muted);
    font-size: 0.9rem;
    font-weight: 300;
    margin-bottom: 20px;
}

.project-meta-line {
    font-size: 0.8rem;
    color: var(--color-text-muted);
    opacity: 0.7;
    font-weight: 300;
}

.project-card-footer {
    margin-top: auto;
}

.view-details-link {
    font-size: 0.85rem;
    font-weight: 400;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--color-text-muted);
    transition: var(--transition-fast);
}

.view-details-link svg {
    width: 14px;
    height: 14px;
    transition: transform 0.3s ease;
}

.project-card:hover .view-details-link {
    color: var(--color-text);
}

.project-card:hover .view-details-link svg {
    transform: translateX(4px);
}

/* --- Contact Section --- */
/* --- Contact Section --- */
.contact-simple {
    max-width: 650px;
    margin: 0 auto;
    text-align: center;
}

.contact-lead {
    font-size: 1.2rem;
    color: var(--color-text-muted);
    margin-bottom: 40px;
    font-weight: 300;
    line-height: 1.7;
}

.contact-buttons {
    display: flex;
    gap: 16px;
    justify-content: center;
    flex-wrap: wrap;
}

/* --- Footer --- */
.footer {
    border-top: 1px solid var(--color-border);
    padding: 50px 0;
    font-size: 0.8rem;
    color: var(--color-text-muted);
}

.footer-container {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.footer-links {
    display: flex;
    gap: 24px;
}

.footer-links a {
    transition: var(--transition-fast);
}

.footer-links a:hover {
    color: var(--color-text);
}

/* --- Modal Dialog --- */
.modal {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.4s cubic-bezier(0.16, 1, 0.3, 1), visibility 0.4s;
}

.modal.open {
    opacity: 1;
    visibility: visible;
}

.modal-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.9);
}

.modal-wrapper {
    position: relative;
    z-index: 1002;
    width: 90%;
    max-width: 640px;
    transform: translateY(15px) scale(0.96);
    transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1), max-width 0.3s ease;
}

.modal.open .modal-wrapper {
    transform: translateY(0) scale(1);
}

/* On desktop the modal has room to breathe: wider, so the demo screenshots
   (full browser captures) are actually legible instead of shrunk to ~600px. */
@media (min-width: 860px) {
    .modal-wrapper { max-width: 780px; }
}
@media (min-width: 1180px) {
    .modal-wrapper { max-width: 980px; }
}
@media (min-width: 1500px) {
    .modal-wrapper { max-width: 1140px; }
}

.modal-container {
    background: #080808;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    max-height: 85vh;
    overflow-y: auto;
    position: relative;
    padding: 50px;
}

.modal-close {
    position: absolute;
    top: 24px;
    right: 24px;
    width: 32px;
    height: 32px;
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: pointer;
    color: var(--color-text-muted);
    transition: var(--transition-fast);
}

.modal-close:hover {
    color: var(--color-text);
}

.modal-close svg {
    width: 18px;
    height: 18px;
}

.modal-detail-tag {
    display: inline-block;
    font-size: 0.75rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--color-text-muted);
    margin-bottom: 12px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.15);
    padding-bottom: 4px;
}

.modal-detail-title {
    font-family: var(--font-display);
    font-size: 2.2rem;
    font-weight: 300;
    margin-bottom: 24px;
    letter-spacing: -0.02em;
}

.modal-detail-desc {
    color: var(--color-text-muted);
    margin-bottom: 36px;
    font-size: 0.95rem;
    line-height: 1.65;
    font-weight: 300;
}

.modal-meta-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 30px;
    margin-bottom: 40px;
    border-top: 1px solid var(--color-border);
    border-bottom: 1px solid var(--color-border);
    padding: 30px 0;
}

.modal-meta-item h5 {
    font-family: var(--font-sans);
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--color-text-muted);
    margin-bottom: 6px;
}

.modal-meta-item p {
    font-size: 0.9rem;
    color: var(--color-text-light);
}

.modal-tech-list {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.modal-tech-list span {
    font-size: 0.75rem;
    color: var(--color-text-light);
    border: 1px solid var(--color-border);
    padding: 2px 10px;
}

.modal-detail-tagline {
    font-family: var(--font-display);
    font-size: 1.05rem;
    font-style: italic;
    color: var(--color-text-muted);
    margin-bottom: 32px;
}

/* Ostro specs: floating flip cards, one per topic — front shows just the
   title, a click/tap/Enter flips it to reveal the paragraph on the back. */
.spec-cards {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 26px;
    margin-bottom: 40px;
    perspective: 1400px;
}

@media (max-width: 700px) {
    .spec-cards {
        grid-template-columns: 1fr;
    }
}

.spec-card {
    position: relative;
    height: 230px;
    cursor: pointer;
    outline: none;
    /* Entrance: fades/slides in on its own (staggered per-card delay set
       inline in script.js) whenever the specs view renders, so the modal
       doesn't just dump 4 flat boxes on screen at once. `backwards` holds
       the 0% keyframe (invisible) until the delay elapses. */
    animation: spec-card-in 0.55s cubic-bezier(0.16, 1, 0.3, 1) backwards;
    transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}

/* Lifts on hover/focus — on .spec-card itself, not .spec-card-inner, so it
   composes cleanly with that element's own flip rotation instead of
   fighting over the same transform. */
.spec-card:hover,
.spec-card:focus-visible {
    transform: translateY(-6px);
}

@keyframes spec-card-in {
    from { opacity: 0; transform: translateY(18px); }
    to   { opacity: 1; transform: translateY(0); }
}

.spec-card-inner {
    position: relative;
    width: 100%;
    height: 100%;
    transition: transform 0.65s cubic-bezier(0.16, 1, 0.3, 1);
    transform-style: preserve-3d;
}

.spec-card.flipped .spec-card-inner {
    transform: rotateY(180deg);
}

.spec-card-face {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    padding: 22px 22px;
    backface-visibility: hidden;
    transition: border-color 0.3s ease, box-shadow 0.3s ease;
}

.spec-card:hover .spec-card-face,
.spec-card:focus-visible .spec-card-face {
    border-color: var(--color-border-hover);
    box-shadow: 0 14px 28px rgba(0, 0, 0, 0.4);
}

.spec-card-front {
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: 10px;
}

.spec-card-num {
    font-family: var(--font-display);
    font-size: 1.3rem;
    font-weight: 300;
    color: var(--color-text-muted);
    opacity: 0.55;
}

.spec-card-front h5 {
    font-family: var(--font-sans);
    font-size: 1rem;
    font-weight: 500;
    color: var(--color-text);
    line-height: 1.4;
}

.spec-card-hint {
    font-size: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--color-text-muted);
    opacity: 0.5;
}

.spec-card-back {
    transform: rotateY(180deg);
    /* flex-start, not center: with overflow-y:auto, a centered flex child
       taller than its box overflows equally above AND below — scrollTop:0
       then lands you mid-text with the opening line already scrolled past
       and unreachable. Top-aligned content always starts, well, at the
       start. The card is now sized to fit every card's text anyway (see
       the mobile height above), so this is a safety net for edge cases
       (very long translations, larger accessibility font sizes), not the
       everyday behavior. */
    justify-content: flex-start;
    overflow-y: auto;
}

.spec-card-back p {
    font-size: 0.85rem;
    color: var(--color-text-muted);
    font-weight: 300;
    line-height: 1.55;
}

.spec-card-list {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.spec-card-list li {
    font-size: 0.8rem;
    color: var(--color-text-muted);
    font-weight: 300;
    line-height: 1.5;
}

.spec-card-list strong {
    color: var(--color-text-light);
    font-weight: 500;
}

/* Ostro demo: five plain screenshots, no captions. */
.demo-screens {
    display: flex;
    flex-direction: column;
    gap: 28px;
    margin-bottom: 40px;
}

.demo-screen-wrapper {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    padding: 10px;
    background: #050505;
    cursor: zoom-in;
    transition: border-color 0.3s ease;
}

.demo-screen-wrapper:hover,
.demo-screen-wrapper:focus-visible {
    border-color: var(--color-border-hover);
    outline: none;
}

.demo-screen-wrapper img {
    width: 100%;
    height: auto;
    display: block;
}

/* Screenshot lightbox: full-screen view of a clicked demo screenshot. */
.lightbox {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 40px;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.35s cubic-bezier(0.16, 1, 0.3, 1), visibility 0.35s;
}

.lightbox.open {
    opacity: 1;
    visibility: visible;
}

.lightbox-overlay {
    position: absolute;
    inset: 0;
    background-color: rgba(0, 0, 0, 0.95);
}

.lightbox-img {
    position: relative;
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    object-fit: contain;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    transform: scale(0.96);
    transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1);
}

.lightbox.open .lightbox-img {
    transform: scale(1);
}

.lightbox-close {
    position: fixed;
    top: 24px;
    right: 24px;
    z-index: 2001;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--color-text-muted);
    cursor: pointer;
    transition: var(--transition-fast);
}

.lightbox-close:hover {
    color: var(--color-text);
}

.lightbox-close svg {
    width: 20px;
    height: 20px;
}

/* Rotate hint: these screenshots are wide desktop UI, so on a narrow
   portrait phone even "full screen" keeps them small and hard to read
   (constrained by width, not height). Hidden everywhere else — shown only
   when both conditions hold, and it disappears live if the phone is
   actually rotated, since the media query re-evaluates automatically. */
.lightbox-rotate-hint {
    display: none;
}

@media (max-width: 768px) and (orientation: portrait) {
    .lightbox-rotate-hint {
        display: block;
        position: absolute;
        left: 50%;
        bottom: 24px;
        transform: translateX(-50%);
        color: var(--color-text-muted);
        font-size: 0.8rem;
        text-align: center;
        white-space: nowrap;
    }
}

.modal-btn-row {
    display: flex;
    gap: 16px;
    flex-wrap: wrap;
}

/* --- Scroll Animations (Reveal on Scroll) --- */
/* Only opacity/transform animate here (GPU-composited, no repaint) so the
   staggered reveal of many elements at once — focus cards, journey items,
   language tags — stays at a steady frame rate instead of stuttering.
   border/color transitions keep their own fast timing so hovers still feel snappy. */
.reveal-item {
    opacity: 0;
    transform: translateY(26px);
    transition: opacity 0.9s cubic-bezier(0.16, 1, 0.3, 1),
                transform 0.9s cubic-bezier(0.16, 1, 0.3, 1),
                border-color 0.35s cubic-bezier(0.16, 1, 0.3, 1),
                color 0.35s cubic-bezier(0.16, 1, 0.3, 1),
                background-color 0.35s cubic-bezier(0.16, 1, 0.3, 1);
    will-change: opacity, transform;
}

.reveal-item.revealed {
    opacity: 1;
    transform: translateY(0);
}

/* Per-group stagger delays are assigned dynamically in script.js */

/* --- Responsive Styling --- */
@media (max-width: 992px) {
    .section {
        padding: 90px 0;
    }
    
    .hero-title {
        font-size: 3rem;
    }
    
    .contact-grid {
        grid-template-columns: 1fr;
        gap: 50px;
    }
}

@media (max-width: 768px) {
    :root {
        --header-height: 70px;
    }
    
    .section {
        padding: 80px 0;
    }
    
    .header-actions {
        gap: 14px;
    }

    .nav-toggle {
        display: block;
    }

    .nav {
        position: fixed;
        top: 0;
        right: -100%;
        width: 80%;
        max-width: 320px;
        height: 100vh;
        background-color: #050505;
        border-left: 1px solid var(--color-border);
        box-shadow: -10px 0 40px rgba(0, 0, 0, 0.8);
        z-index: 105;
        padding: 100px 40px;
        transition: right 0.5s cubic-bezier(0.16, 1, 0.3, 1);
    }
    
    .nav.open {
        right: 0;
    }
    
    .nav-list {
        flex-direction: column;
        gap: 32px;
    }
    
    .nav-link {
        font-size: 1.1rem;
    }
    
    .hero-title {
        font-size: 2.3rem;
    }
    
    .hero-description {
        font-size: 1rem;
    }
    
    .projects-grid {
        grid-template-columns: 1fr;
    }
    
    .focus-grid {
        grid-template-columns: 1fr;
    }

    .focus-card {
        padding: 28px 22px;
    }

    .skills-groups {
        grid-template-columns: 1fr;
        gap: 28px;
    }

    /* Sized per card, not uniformly: text length varies a lot between
       sections, and a single height tall enough for the longest one
       ("Contesto"/"Context") left a lot of empty space under the shorter
       cards. Each value covers the longer of the IT/EN copy for that card
       (measured) plus a small buffer, so the internal scroll on
       .spec-card-back is never needed on phones. Placed in this later
       media query (not right after the base .spec-card rule) so it
       actually wins the cascade instead of being silently overridden by
       it. */
    .spec-card:nth-child(1) {
        height: 355px;
    }

    .spec-card:nth-child(2) {
        height: 290px;
    }

    .spec-card:nth-child(3) {
        height: 270px;
    }

    .spec-card:nth-child(4) {
        height: 285px;
    }

    .journey-item {
        grid-template-columns: 1fr;
        gap: 8px;
    }
    
    .journey-year {
        padding-top: 0;
        font-size: 0.85rem;
    }
    
    .modal-container {
        padding: 40px 24px;
    }
    
    .modal-meta-grid {
        grid-template-columns: 1fr;
        gap: 24px;
    }
    
    .footer-container {
        flex-direction: column;
        gap: 16px;
        text-align: center;
    }
}

/* --- Reduced Motion: soften, don't eliminate ---
   Placed last so it wins the cascade against the component rules above it
   (same specificity, later source order). Ambient motion that never stops —
   the blob drift, the hero title's shimmer, the scroll-cue bounce, the
   cursor-chasing spotlight — is exactly the kind of thing that can trigger
   real discomfort for people with vestibular disorders, so that's switched
   off entirely. Functional micro-interactions (hovers, reveal-on-scroll,
   the modal) stay, just shorter and with less travel distance. The cursor
   spotlight, magnetic buttons and card tilt are additionally skipped at the
   JS level (see script.js) since they only exist as mouse-driven motion. */
@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }

    .hero-blob,
    .hero-title .text-light,
    .scroll-down-btn,
    .spec-card {
        animation: none;
    }

    .hero-glow {
        display: none;
    }

    .reveal-item {
        transform: translateY(8px);
    }

    .reveal-item,
    .modal-wrapper,
    .project-card,
    .focus-card,
    .btn,
    .logo,
    .spec-card,
    .spec-card-inner,
    .owr-info-banner,
    .lightbox-img {
        transition-duration: 0.25s;
    }
}

