/* ============================================
   Yunbing Han — Portfolio
   Inspired by landonorris.com
   Premium playful design with #55D8FF
   ============================================ */

/* --- Reset & Base --- */
*, *::before, *::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

/* --- Day Theme (default) --- */
:root {
    --primary: #55D8FF;
    --primary-dark: #3ABDE0;
    --secondary: #FF6B9D;
    --accent: #A78BFA;
    --yellow: #FBBF24;
    --green: #34D399;
    --bg: #FAFAFA;
    --bg-secondary: #F0F9FF;
    --surface: #FFFFFF;
    --text: #1E293B;
    --text-secondary: #64748B;
    --border: #E2E8F0;
    --shadow: rgba(0, 0, 0, 0.06);
    --shadow-hover: rgba(0, 0, 0, 0.12);
    --shadow-primary: rgba(85, 216, 255, 0.3);
    /* Nav pill — sits behind the links so they stay readable over any section */
    --nav-bg: rgba(250, 250, 250, 0.92);
    --radius: 20px;
    --radius-sm: 12px;
    --cubic: cubic-bezier(0.65, 0.05, 0, 1);
    --duration: 0.75s;
    --font-display: 'Montserrat', sans-serif;
    --font-heading: 'Montserrat', sans-serif;
    --font-body: 'Montserrat', sans-serif;
    --font-serif: 'Merriweather', serif;
    --section-bg: transparent;
}

/* --- Night Theme --- */
[data-theme="dark"] {
    --primary: #55D8FF;
    --primary-dark: #7AE3FF;
    --secondary: #FF6B9D;
    --accent: #C4B5FD;
    --yellow: #FCD34D;
    --green: #6EE7B7;
    --bg: #111111;
    --bg-secondary: #111111;
    --surface: #1A1A1A;
    --text: #F1F5F9;
    --text-secondary: #94A3B8;
    --border: #2A3A5C;
    --shadow: rgba(0, 0, 0, 0.12);
    --shadow-hover: rgba(0, 0, 0, 0.18);
    --shadow-primary: rgba(85, 216, 255, 0.08);
    --nav-bg: rgba(17, 17, 17, 0.92);
    --section-bg: transparent;
}

/* --- Dot Grid Background Canvas --- */
#dotGridBG {
    position: fixed;
    inset: 0;
    width: 100vw;
    height: 100vh;
    z-index: -1;
    pointer-events: none;
}

/* --- Hidden scrollbar --- */
::-webkit-scrollbar { display: none; }
html { scrollbar-width: none; -ms-overflow-style: none; }

/* --- Selection color --- */
::selection {
    background-color: var(--primary);
    color: var(--text);
}

html {
    scroll-behavior: smooth;
    overscroll-behavior-y: none;
    overflow-anchor: none;
}

body {
    font-family: var(--font-body);
    color: var(--text);
    background: var(--bg);
    overflow-x: hidden;
    overscroll-behavior-y: none;
    overflow-anchor: none;
    line-height: 1.6;
    transition: background var(--duration) var(--cubic), color var(--duration) var(--cubic);
    cursor: none;
}

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

button {
    cursor: none;
}

/* --- Page Transition --- */
.page-transition {
    /* The splash is the site introducing itself, not the case study underneath.
       It paints from its own token so a page that re-points --primary for its
       product palette still opens in the site blue. */
    --splash: #55D8FF;

    position: fixed;
    inset: 0;
    z-index: 9999;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: auto;
    overflow: visible;
    background: var(--splash);
    /* Solid bg guarantees full coverage on mobile Safari (no gaps behind browser chrome).
       The ::before circle handles the shrink animation. */
}

.page-transition::before {
    content: '';
    position: absolute;
    /* Circle must cover all viewport corners including mobile browser chrome.
       200vmax guarantees full coverage on any aspect ratio + safe area. */
    width: 200vmax;
    height: 200vmax;
    border-radius: 50%;
    background: var(--splash);
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) scale(1);
    will-change: transform, opacity;
}

.page-transition.done {
    pointer-events: none;
    background: transparent;
}

.page-transition.done::before {
    animation: splashShrink 1.8s var(--cubic) forwards;
}

/* GPU-composited only: transform — no paint, no layout */
@keyframes splashShrink {
    0%   { transform: translate(-50%, -50%) scale(1); }
    100% { transform: translate(-50%, -50%) scale(0); }
}

.transition-text {
    font-family: var(--font-display);
    font-size: 4rem;
    font-weight: 800;
    color: #ffffff;
    will-change: transform;
    animation: pulseScale 0.8s ease infinite alternate;
    position: relative;
    z-index: 1;
}

.page-transition.done .transition-text {
    animation: splashTextFade 0.5s ease forwards;
}

@keyframes splashTextFade {
    to { opacity: 0; transform: scale(0.8); }
}

@keyframes pulseScale {
    from { transform: scale(1); }
    to { transform: scale(1.1); }
}

/* --- Custom Cursor --- */
.cursor {
    width: 12px;
    height: 12px;
    background: var(--primary);
    border-radius: 50%;
    position: fixed;
    top: 0;
    left: 0;
    pointer-events: none;
    z-index: 9998;
    mix-blend-mode: difference;
    transition: width 0.3s var(--cubic), height 0.3s var(--cubic), background 0.3s var(--cubic);
    will-change: transform;
}

.cursor-follower {
    width: 40px;
    height: 40px;
    border: 1.5px solid var(--primary);
    border-radius: 50%;
    position: fixed;
    top: 0;
    left: 0;
    pointer-events: none;
    z-index: 9997;
    transition: width 0.3s var(--cubic), height 0.3s var(--cubic), border-color 0.3s var(--cubic), opacity 0.3s var(--cubic);
    will-change: transform;
    opacity: 0.5;
}

.cursor.hovering {
    width: 60px;
    height: 60px;
    background: rgba(85, 216, 255, 0.15);
    mix-blend-mode: normal;
}

.cursor-follower.hovering {
    width: 60px;
    height: 60px;
    opacity: 0;
}

/* Hide custom cursor on touch */
@media (pointer: coarse) {
    .cursor, .cursor-follower { display: none; }
    body, a, button { cursor: auto; }
}

/* --- Navigation --- */
.nav {
    /* The header belongs to the site, never to the page under it. A case study
       is free to re-point --primary / --text for its own palette; the nav paints
       from these tokens instead so it reads identically on every page. */
    --nav-ink: #1E293B;
    --nav-muted: #64748B;
    --nav-accent: #55D8FF;

    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 100;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 32px 48px 20px;
    padding-top: max(32px, env(safe-area-inset-top));
    padding-left: max(48px, env(safe-area-inset-left));
    padding-right: max(48px, env(safe-area-inset-right));
    background: transparent;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    transition: box-shadow 0.3s ease, background var(--duration) var(--cubic), transform 0.5s var(--cubic);
}

/* Only --nav-bg stays page-owned: the capsule hides in whatever background it
   sits on, which is the whole point of it. */
[data-theme="dark"] .nav {
    --nav-ink: #F1F5F9;
    --nav-muted: #94A3B8;
    --nav-accent: #55D8FF;
}

.nav.scrolled {
    box-shadow: none;
}

.nav.nav-hidden {
    transform: translateY(-100%);
}

/* Nav adapts: light text over dark hero backgrounds */
.nav .logo-line-serif,
.nav .logo-line-sans {
    transition: color 0.3s ease;
}
.nav.nav-on-dark .logo-line-serif {
    color: #fff;
}
/* The links sit on their own pill, so they keep the theme's own colours over a
   dark section — only the bare logo has to flip to white. */

.nav-logo {
    display: flex;
    flex-direction: column;
    line-height: 1.1;
    color: var(--nav-accent);
    transition: transform 0.3s var(--cubic);
}

.nav-logo .logo-line-serif {
    font-family: var(--font-serif);
    font-size: 1.12rem;
    font-weight: 700;
    color: var(--nav-ink);
}

.nav-logo .logo-line-sans {
    font-family: var(--font-display);
    font-size: 1.02rem;
    font-weight: 600;
    /* Tracked so YUNBING sets to exactly the same advance as HANNAH above it,
       leaving both lines flush left and right. Solved against Merriweather 700
       at 1.12rem over Montserrat 600 at 1.02rem — retune if either changes. */
    letter-spacing: 0.03319em;
    /* Kill the trailing letter-space so it cannot widen the logo box */
    margin-right: -0.03319em;
}

.nav-logo:hover {
    transform: rotate(-5deg) scale(1.1);
}

.nav-links {
    display: flex;
    align-items: center;
    gap: 42px;
    /* Capsule backdrop in the page's own background colour, so scrolling past a
       dark photo or a light section never touches the links' contrast.
       Low and wide: the 32px toggle sets the height, the links ride centred in
       it, which leaves the hover underline (4px under each link) enough room. */
    padding: 6px 26px 6px 32px;
    border-radius: 999px;
    background: var(--nav-bg);
    backdrop-filter: blur(14px) saturate(1.3);
    -webkit-backdrop-filter: blur(14px) saturate(1.3);
    transition: background 0.3s ease;
}

.nav-links a {
    font-family: var(--font-heading);
    font-weight: 500;
    font-size: 0.95rem;
    color: var(--nav-muted);
    position: relative;
    transition: color 0.3s var(--cubic);
}

.nav-links a::after {
    content: '';
    position: absolute;
    bottom: -4px;
    left: 0;
    width: 0;
    height: 3px;
    background: var(--nav-accent);
    border-radius: 2px;
    transition: width 0.4s var(--cubic);
}

.nav-links a:hover,
.nav-links a.nav-active {
    color: var(--nav-ink);
}

.nav-links a:hover::after,
.nav-links a.nav-active::after {
    width: 100%;
}

/* --- Theme Toggle Button --- */
.theme-toggle {
    width: 32px;
    height: 32px;
    border: none;
    background: none;
    color: var(--nav-muted);
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.3s var(--cubic);
    position: relative;
    cursor: pointer;
}

.theme-toggle:hover {
    color: var(--nav-accent);
    transform: rotate(15deg);
}

/* A case study locked to one palette keeps the button in place so the header
   never changes shape — greyed out, inert, and saying why on hover. */
.theme-toggle[disabled],
.theme-toggle.is-locked {
    color: #C2CAD4;
    opacity: 0.55;
    cursor: not-allowed;
}

.theme-toggle[disabled]:hover,
.theme-toggle.is-locked:hover {
    color: #C2CAD4;
    transform: none;
}

.icon-sun, .icon-moon {
    position: absolute;
    transition: opacity 0.3s ease, transform 0.5s var(--cubic);
}

.icon-sun {
    opacity: 0;
    transform: scale(0.5) rotate(-90deg);
}

.icon-moon {
    opacity: 1;
    transform: scale(1) rotate(0deg);
}

[data-theme="dark"] .icon-sun {
    opacity: 1;
    transform: scale(1) rotate(0deg);
}

[data-theme="dark"] .icon-moon {
    opacity: 0;
    transform: scale(0.5) rotate(90deg);
}

/* --- Hero Section --- */
.hero {
    height: 100vh;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    position: relative;
    text-transform: uppercase;
    z-index: 3;
    padding: 140px 48px 0;
    overflow: hidden;
}

.hero-gl-canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: 3;
    pointer-events: none;
}

.hero-content {
    position: relative;
    z-index: 2;
    text-align: center;
    max-width: 1100px;
}

/* Hero role titles — overlapping the 3D model */
.hero-titles {
    position: absolute;
    inset: 0;
    z-index: 2;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    padding: 5rem 1.25rem 0;
    pointer-events: none;
}

.hero-title-line {
    display: block;
    line-height: 1;
    white-space: nowrap;
}

.hero-title-line.ht-sans {
    font-family: var(--font-display);
    font-weight: 900;
    color: var(--primary);
}

.hero-title-line.ht-serif {
    font-family: var(--font-serif);
    font-weight: 900;
    font-style: italic;
    color: var(--text);
}

.hero-badge {
    display: inline-block;
    font-family: var(--font-heading);
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--primary);
    background: rgba(85, 216, 255, 0.1);
    padding: 10px 24px;
    border-radius: 50px;
    margin-bottom: 28px;
}

[data-theme="dark"] .hero-badge {
    background: rgba(85, 216, 255, 0.12);
}

.hero-title {
    font-family: var(--font-display);
    font-size: clamp(3rem, 7vw, 5.5rem);
    font-weight: 800;
    line-height: 1.1;
    margin-bottom: 28px;
    letter-spacing: -0.02em;
}

.name-highlight-wrap {
    display: inline;
}

.name-highlight {
    color: var(--text);
}

.hero-subtitle {
    font-family: var(--font-heading);
    font-size: clamp(1.1rem, 2vw, 1.35rem);
    color: var(--text-secondary);
    margin-bottom: 48px;
    line-height: 1.6;
    text-align: center;
}

.hero-cta {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 1.05rem;
    color: var(--text);
    background: var(--primary);
    padding: 16px 36px;
    border-radius: 50px;
    transition: all 0.4s var(--cubic);
    position: relative;
    overflow: hidden;
}

.hero-cta::before {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(135deg, var(--primary), var(--secondary));
    opacity: 0;
    transition: opacity 0.4s var(--cubic);
    border-radius: 50px;
}

.hero-cta:hover::before {
    opacity: 1;
}

.hero-cta span {
    position: relative;
    z-index: 1;
}

.hero-cta:hover {
    transform: translateY(-3px);
    box-shadow: 0 8px 24px var(--shadow-primary);
}

.hero-cta .arrow {
    transition: transform 0.4s var(--cubic);
}

.hero-cta:hover .arrow {
    transform: translateY(3px);
}

/* --- Hero capability speech bubbles (arc over the machine) --- */
.hero-bubbles {
    position: absolute;
    inset: 0;
    z-index: 4;
    pointer-events: none;
}

.hero-bubble-slot {
    position: absolute;
    left: var(--x);
    top: var(--y);
    width: max-content;
    transform: translateX(-50%);
    animation: bubbleFloat var(--float-dur, 7s) ease-in-out infinite;
    animation-delay: var(--float-delay, 0s);
    will-change: transform;
}

.hero-bubble {
    --bubble-bg: #FFFFFF;
    --bubble-border: rgba(30, 41, 59, 0.10);
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    white-space: nowrap;
    padding: 13px 20px;
    background: var(--bubble-bg);
    border: 1.5px solid var(--bubble-border);
    border-radius: 20px;
    box-shadow: 0 10px 26px rgba(0, 0, 0, 0.10);
    font-family: var(--font-heading);
    font-size: clamp(0.78rem, 1vw, 0.92rem);
    font-weight: 600;
    line-height: 1.25;
    color: #1E293B;
    pointer-events: auto;
    transition: transform 0.45s var(--cubic),
                box-shadow 0.45s var(--cubic),
                border-color 0.45s var(--cubic);
    animation: bubblePop 0.6s var(--cubic) backwards;
    animation-delay: var(--pop-delay, 1.2s);
}

.hero-bubble-emoji {
    font-size: 1.05em;
    line-height: 1;
}

/* Tail — always points straight down, anchored per bubble */
.hero-bubble::after {
    content: '';
    position: absolute;
    bottom: -8px;
    width: 15px;
    height: 15px;
    background: var(--bubble-bg);
    border-right: 1.5px solid var(--bubble-border);
    border-bottom: 1.5px solid var(--bubble-border);
    transform: rotate(45deg);
    transition: border-color 0.45s var(--cubic);
}

.hero-bubble.tail-right::after { right: var(--tail-inset, 26px); }
.hero-bubble.tail-left::after  { left: var(--tail-inset, 26px); }

/* Linked bubbles get the full cyan treatment */
a.hero-bubble:hover {
    border-color: var(--primary);
    box-shadow: 0 14px 34px rgba(0, 0, 0, 0.14), 0 0 0 4px rgba(85, 216, 255, 0.18);
    transform: translateY(-4px);
}

a.hero-bubble:hover::after {
    border-color: var(--primary);
}

/* Bubbles without a page yet — a quieter lift, plus the "coming soon" hint */
span.hero-bubble {
    cursor: default;
}

span.hero-bubble:hover,
span.hero-bubble:focus-visible {
    outline: none;
    box-shadow: 0 14px 32px rgba(0, 0, 0, 0.14);
    transform: translateY(-3px);
}

.hero-bubble-hint {
    position: absolute;
    top: calc(100% + 16px);
    left: 50%;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    padding: 9px 14px;
    border-radius: 12px;
    background: rgba(23, 33, 48, 0.94);
    border: 1px solid rgba(255, 255, 255, 0.14);
    box-shadow: 0 10px 24px rgba(0, 0, 0, 0.22);
    color: #FFFFFF;
    text-align: center;
    white-space: nowrap;
    pointer-events: none;
    opacity: 0;
    visibility: hidden;
    transform: translate(-50%, -6px);
    transition: opacity 0.28s var(--cubic),
                transform 0.28s var(--cubic),
                visibility 0.28s;
}

.hero-bubble-hint .hint-title {
    font-size: 0.76rem;
    font-weight: 700;
    letter-spacing: 0.01em;
}

.hero-bubble-hint .hint-sub {
    font-size: 0.68rem;
    font-weight: 500;
    color: rgba(255, 255, 255, 0.72);
}

span.hero-bubble:hover .hero-bubble-hint,
span.hero-bubble:focus-visible .hero-bubble-hint {
    opacity: 1;
    visibility: visible;
    transform: translate(-50%, 0);
}

[data-theme="dark"] .hero-bubble {
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
}

@keyframes bubbleFloat {
    0%, 100% { transform: translate(-50%, 0); }
    50%      { transform: translate(-50%, -10px); }
}

@keyframes bubblePop {
    from { opacity: 0; transform: scale(0.7) translateY(10px); }
    to   { opacity: 1; transform: scale(1) translateY(0); }
}

@media (max-width: 1200px) {
    .hero-bubble {
        padding: 11px 16px;
        gap: 8px;
        border-radius: 17px;
    }
}

@media (max-width: 991px) {
    .hero-bubble {
        padding: 9px 13px;
        gap: 6px;
        border-radius: 15px;
    }

    .hero-bubble::after {
        width: 12px;
        height: 12px;
        bottom: -6px;
    }

    .hero-bubble.tail-right::after { right: min(var(--tail-inset, 26px), 20px); }
    .hero-bubble.tail-left::after  { left: min(var(--tail-inset, 26px), 20px); }
}

@media (max-width: 767px) {
    .hero-bubbles {
        display: none;
    }
}

@media (prefers-reduced-motion: reduce) {
    .hero-bubble-slot,
    .hero-bubble {
        animation: none;
    }
}

/* --- Hero scroll cue --- */
.hero-scroll-cue {
    /* Shared geometry: the goo layer has to line up with the flex children
       above it, so the dot size and the gap are read from here, not retyped. */
    --cue-dot: 38px;
    --cue-gap: 5px;
    position: absolute;
    left: 50%;
    bottom: 34px;
    z-index: 5;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--cue-gap);
    transform: translateX(-50%);
    font-family: var(--font-heading);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-secondary);
    text-decoration: none;
    opacity: 0;
    animation: scrollCueIn 0.7s var(--cubic) 2s forwards;
    transition: color 0.35s var(--cubic);
}

/* The filtered backdrop — no text inside it, or the blur would eat the text */
.hero-scroll-goo {
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    filter: url(#scrollCueGoo);
    /* Matches the nav pill's translucency. Applied to the whole layer *after*
       the filter, so the alpha hardening still has opaque shapes to work on. */
    opacity: 0.92;
}

.goo-pill {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: calc(var(--cue-dot) + var(--cue-gap));
    border-radius: 999px;
    background: var(--bg);
}

.goo-dot {
    position: absolute;
    bottom: 0;
    left: 50%;
    width: var(--cue-dot);
    height: var(--cue-dot);
    margin-left: calc(var(--cue-dot) / -2);
    border-radius: 50%;
    background: var(--bg);
    animation: scrollCueBounce 2s ease-in-out infinite;
    transition: background 0.35s var(--cubic);
}

.hero-scroll-label {
    position: relative;
    z-index: 1;
    padding: 9px 24px;
}

.hero-scroll-arrow {
    position: relative;
    z-index: 1;
    display: grid;
    place-items: center;
    width: var(--cue-dot);
    height: var(--cue-dot);
    color: var(--text);
    animation: scrollCueBounce 2s ease-in-out infinite;
    transition: color 0.35s var(--cubic);
}

.hero-scroll-cue:hover {
    color: var(--text);
}

.hero-scroll-cue:hover .goo-dot {
    background: var(--primary);
}

.hero-scroll-cue:hover .hero-scroll-arrow {
    color: #1E293B;
}

@keyframes scrollCueIn {
    from { opacity: 0; transform: translate(-50%, 12px); }
    to   { opacity: 1; transform: translate(-50%, 0); }
}

@keyframes scrollCueBounce {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(6px); }
}

@media (max-width: 767px) {
    .hero-scroll-cue {
        --cue-dot: 32px;
        --cue-gap: 4px;
        bottom: 22px;
        font-size: 0.62rem;
    }

    .hero-scroll-label {
        padding: 7px 18px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .hero-scroll-cue {
        opacity: 1;
        animation: none;
    }

    .hero-scroll-arrow,
    .goo-dot {
        animation: none;
    }
}

/* Floating shapes */
.hero-shapes {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
}

.shape {
    position: absolute;
    border-radius: 50%;
    opacity: 0.12;
    transition: opacity var(--duration) var(--cubic);
    filter: blur(1px);
}

[data-theme="dark"] .shape {
    opacity: 0.08;
}

.shape-1 {
    width: 350px;
    height: 350px;
    background: var(--primary);
    top: 8%;
    left: -5%;
    animation: float 10s ease-in-out infinite;
}

.shape-2 {
    width: 250px;
    height: 250px;
    background: var(--secondary);
    top: 15%;
    right: 3%;
    animation: float 8s ease-in-out infinite reverse;
}

.shape-3 {
    width: 180px;
    height: 180px;
    background: var(--accent);
    bottom: 12%;
    left: 8%;
    animation: float 9s ease-in-out infinite 1s;
}

.shape-4 {
    width: 120px;
    height: 120px;
    background: var(--yellow);
    bottom: 22%;
    right: 12%;
    animation: float 7s ease-in-out infinite 0.5s;
    border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%;
}

.shape-5 {
    width: 90px;
    height: 90px;
    background: var(--green);
    top: 55%;
    left: 45%;
    animation: float 11s ease-in-out infinite 2s;
    border-radius: 63% 37% 54% 46% / 55% 48% 52% 45%;
}

/* --- Marquee Strip --- */
.marquee {
    padding: 20px 0;
    text-transform: uppercase;
    background: var(--primary);
    overflow: hidden;
    position: relative;
}

[data-theme="dark"] .marquee {
    background: var(--surface);
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
}

.marquee-track {
    display: flex;
    width: max-content;
    animation: marqueeScroll 25s linear infinite;
}

.marquee-track:hover {
    animation-play-state: paused;
}

.marquee-content {
    display: flex;
    align-items: center;
    gap: 40px;
    padding: 0 20px;
    white-space: nowrap;
}

.marquee-content span {
    font-family: var(--font-display);
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--text);
    letter-spacing: 0.02em;
}

[data-theme="dark"] .marquee-content span {
    color: var(--primary);
}

.marquee-dot {
    width: 8px;
    height: 8px;
    background: #111111;
    border-radius: 50%;
    display: inline-block;
    flex-shrink: 0;
}

[data-theme="dark"] .marquee-dot {
    background: var(--primary);
}

@keyframes marqueeScroll {
    to { transform: translateX(-50%); }
}

/* --- Split Text Animation --- */
.split-text .char {
    display: inline-block;
    opacity: 0;
    transform: translateY(100%);
    transition: opacity 0.6s var(--cubic), transform 0.6s var(--cubic);
}

.split-text.visible .char {
    opacity: 1;
    transform: translateY(0);
}

/* --- Reveal Up Animation --- */
.reveal-up {
    opacity: 0;
    transform: translateY(40px);
    transition: opacity 0.8s var(--cubic), transform 0.8s var(--cubic);
}

.reveal-up.visible {
    opacity: 1;
    transform: translateY(0);
}

/* --- Work Section --- */
.work {
    padding: 120px 48px;
    max-width: 1300px;
    margin: 0 auto;
    position: relative;
    z-index: 2;
    background: var(--bg);
    transition: background var(--duration) var(--cubic);
}

.section-header {
    text-align: center;
    margin-bottom: 72px;
}

.section-title {
    font-family: var(--font-display);
    font-size: clamp(2.2rem, 4.5vw, 3.2rem);
    font-weight: 800;
    margin-bottom: 28px;
    letter-spacing: -0.02em;
}

.filters {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 10px;
}

.filter-btn {
    font-family: var(--font-heading);
    font-size: 0.85rem;
    font-weight: 500;
    padding: 10px 22px;
    border: 2px solid var(--border);
    border-radius: 50px;
    background: transparent;
    color: var(--text-secondary);
    cursor: none;
    transition: all 0.35s var(--cubic);
}

.filter-btn:hover {
    border-color: var(--primary);
    color: var(--primary);
    transform: translateY(-2px);
}

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

.work-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
    gap: 32px;
}

.work-card {
    display: block;
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--surface);
    box-shadow: 0 2px 10px var(--shadow);
    transition: opacity 0.35s var(--cubic), transform 0.5s var(--cubic), box-shadow 0.5s var(--cubic);
    opacity: 1;
    transform: scale(1);
}

.work-card:hover {
    transform: translateY(-12px) scale(1.02);
    box-shadow: 0 12px 28px var(--shadow-hover);
}

.work-card.hidden {
    display: none;
}

.card-image {
    aspect-ratio: 16 / 9;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    overflow: hidden;
}

.card-image::after {
    content: '';
    position: absolute;
    inset: 0;
    background: radial-gradient(circle at 30% 70%, rgba(0,0,0,0.1), transparent 60%);
}

.card-image-overlay {
    position: absolute;
    inset: 0;
    background: rgba(11, 17, 33, 0.4);
    opacity: 0;
    transition: opacity 0.5s var(--cubic);
}

.work-card:hover .card-image-overlay {
    opacity: 1;
}

.card-placeholder {
    font-family: var(--font-heading);
    font-weight: 600;
    color: rgba(255, 255, 255, 0.5);
    font-size: 1.1rem;
    position: relative;
    z-index: 1;
    transition: transform 0.5s var(--cubic);
}

.work-card:hover .card-placeholder {
    transform: scale(1.1);
}

.card-info {
    padding: 28px;
    position: relative;
}

.card-category {
    font-family: var(--font-heading);
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 1.5px;
    color: var(--primary);
}

.card-title {
    font-family: var(--font-display);
    font-size: 1.4rem;
    font-weight: 700;
    margin: 10px 0;
}

.card-desc {
    font-size: 0.9rem;
    color: var(--text-secondary);
    line-height: 1.5;
}

.card-arrow {
    position: absolute;
    top: 28px;
    right: 28px;
    font-size: 1.4rem;
    color: var(--primary);
    opacity: 0;
    transform: translate(-10px, 10px);
    transition: all 0.4s var(--cubic);
}

.work-card:hover .card-arrow {
    opacity: 1;
    transform: translate(0, 0);
}

/* --- About Section --- */
.about {
    padding: 120px 48px;
    background: var(--bg-secondary);
    transition: background var(--duration) var(--cubic);
}

[data-theme="dark"] .about {
    background: var(--bg-secondary);
}

.about-container {
    max-width: 1100px;
    margin: 0 auto;
    display: grid;
    grid-template-columns: 320px 1fr;
    gap: 72px;
    align-items: center;
}

.photo-placeholder {
    width: 320px;
    height: 400px;
    background: linear-gradient(135deg, var(--primary), var(--secondary));
    border-radius: var(--radius);
    display: flex;
    align-items: center;
    justify-content: center;
    color: rgba(255, 255, 255, 0.5);
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 1.1rem;
    transition: transform 0.5s var(--cubic), border-radius 0.5s var(--cubic);
}

.photo-placeholder:hover {
    transform: rotate(-3deg) scale(1.03);
    border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%;
}

.about-text {
    font-size: 1.1rem;
    color: var(--text-secondary);
    margin-bottom: 18px;
    line-height: 1.8;
}

.skills {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 28px;
}

.skill {
    font-family: var(--font-heading);
    font-size: 0.82rem;
    font-weight: 600;
    padding: 10px 18px;
    background: var(--surface);
    border-radius: 50px;
    color: var(--text);
    box-shadow: 0 1px 6px var(--shadow);
    transition: all 0.35s var(--cubic);
}

.skill:hover {
    transform: translateY(-3px);
    box-shadow: 0 4px 12px var(--shadow-primary);
    color: var(--primary);
    background: var(--surface);
}

/* --- Showcase Grid Section (bento grid inspired by landonorris.com) --- */
.showcase-grid {
    padding: 120px 0 250px;
    background: var(--section-bg);
    position: relative;
    z-index: 2;
    overflow: visible;
    transition: background var(--duration) var(--cubic);
}

.showcase-container {
    max-width: none;
    margin: 0;
    padding: 0 1.25rem;
}

.serif {
    font-family: var(--font-serif) !important;
    font-style: italic;
}

.showcase-grid .section-header {
    text-align: left;
}

.showcase-grid .section-title {
    color: var(--text);
}

.showcase-subtitle {
    font-family: var(--font-heading);
    font-size: 1.1rem;
    color: var(--text-secondary);
    text-align: center;
}

.showcase-spacer {
    height: 4rem;
}

/* --- Pretext Text Routing (matches chenglou/pretext dynamic-layout demo pattern) --- */
.pretext-text-wrap {
    position: relative;
    max-width: 800px;
    margin: 0 auto;
    padding: 0 1.25rem 3rem;
    min-height: 500px;
    margin-bottom: 4rem;
}

.pretext-text {
    position: relative;
    font-family: var(--font-body);
    font-size: 1.05rem;
    font-weight: 400;
    color: var(--text-secondary);
    letter-spacing: 0.01em;
}

/* Each line is absolutely positioned with white-space:pre — no browser reflow */
.pretext-line {
    position: absolute;
    white-space: pre;
    cursor: text;
    user-select: text;
}

.pretext-line-loc::before {
    content: '\1F4CD ';
    font-size: 0.65rem;
}

.pretext-berry {
    position: absolute;
    top: 0;
    left: 0;
    font-size: 5rem;
    line-height: 1;
    pointer-events: none;
    z-index: 2;
    will-change: transform;
    filter: drop-shadow(0 2px 6px rgba(0,0,0,0.12));
}

/* 4-column bento grid */
.showcase-bento {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1.25rem;
}

/* Card wrapper */
.showcase-card {
    position: relative;
}

/* The "For fun" card — no project behind it, so it gets a flat tinted panel
   instead of the image stack every other card carries. */
.showcase-card-fun {
    cursor: pointer;
}

.showcase-card-fun .showcase-card-frame {
    display: block;
    /* Theme colour washing down to the page background — which is white in the
       light theme and near-black in the dark one, so the fade works in both. */
    background: linear-gradient(180deg, var(--primary) 0%, var(--bg) 100%);
}

/* Resting state: a question mark, i.e. there is something here but not yet */
.fun-dots {
    position: absolute;
    left: 50%;
    top: 50%;
    font-family: var(--font-display);
    font-size: clamp(2.4rem, 7vw, 8rem);
    font-weight: 800;
    line-height: 1;
    letter-spacing: -0.02em;
    color: #FFFFFF;
    transform: translate(-50%, -50%);
    transition: opacity 0.32s var(--cubic), transform 0.5s var(--cubic);
}

.showcase-card-fun:hover .fun-dots,
.showcase-card-fun:focus-visible .fun-dots {
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.45);
}

/* Hover state: the title takes the top of the card */
.fun-title {
    position: absolute;
    top: 0.35rem;
    left: 0.5rem;
    right: 0.4rem;
    /* Sized in vw rather than rem: the card is a fraction of the viewport, so
       this tracks its width instead of drifting out of proportion with it. */
    font-family: var(--font-display);
    font-size: clamp(1.4rem, 6vw, 7rem);
    font-weight: 800;
    line-height: 0.92;
    letter-spacing: -0.035em;
    color: #FFFFFF;
}

.fun-title > span {
    display: block;
    opacity: 0;
    transform: translateY(0.22em) scale(0.94);
    transform-origin: left top;
    transition: opacity 0.4s var(--cubic), transform 0.55s var(--cubic);
}

/* Second line lands a beat later, so the two read as one motion, not a slab */
.fun-title > span:last-child {
    transition-delay: 0.07s;
}

.showcase-card-fun:hover .fun-title > span,
.showcase-card-fun:focus-visible .fun-title > span {
    opacity: 1;
    transform: none;
}

/* Emoji rain — fixed layer over everything, never intercepts the pointer */
.emoji-rain-layer {
    position: fixed;
    inset: 0;
    z-index: 200;
    pointer-events: none;
    overflow: hidden;
}

.emoji-rain-bit {
    position: absolute;
    top: 0;
    left: 0;
    font-size: 120px;
    line-height: 1;
    will-change: transform, opacity;
    user-select: none;
}

/* Card frame — simple rounded rectangle */
.showcase-card-frame {
    aspect-ratio: 3 / 4;
    width: 100%;
    display: flex;
    position: relative;
    border-radius: var(--radius);
    overflow: hidden;
}

/* SVG frame wrapper — hidden (borders removed) */
.showcase-frame-w {
    display: none;
}

/* Image container */
.showcase-card-images {
    z-index: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    position: absolute;
    inset: 0;
}

.showcase-img-base {
    width: 100%;
    height: 100%;
    position: relative;
    transition: transform var(--duration) var(--cubic);
}

.showcase-img-reveal {
    display: none;
}

.showcase-img-placeholder {
    position: absolute;
    z-index: 2;
    font-family: var(--font-heading);
    font-weight: 600;
    color: rgba(255, 255, 255, 0.35);
    font-size: 0.9rem;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    pointer-events: none;
    transition: opacity var(--duration) var(--cubic);
}

/* Hide old reveal element */
.showcase-img-reveal {
    display: none;
}

/* Label panel — grows upward from the card's bottom edge on hover, inside the
   frame. The frame's overflow:hidden both clips it to the card's rounded
   corners and hides it completely when closed, so it needs no radius of its own. */
.showcase-card-tag {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 2;
    display: grid;
    /* 0fr -> 1fr is what lets the panel animate to its own content height;
       a fixed height would break the moment a label wraps to two lines. */
    grid-template-rows: 0fr;
    background: var(--surface);
    color: var(--text);
    overflow: hidden;
    transition: grid-template-rows 0.45s var(--cubic);
}

/* The 0fr row only truly collapses if its child can shrink past its content */
.showcase-card-tag-clip {
    min-height: 0;
    overflow: hidden;
}

/* Padding lives on the innermost element — on the clip it would keep the
   closed panel a few pixels tall. */
.showcase-card-tag-text {
    display: block;
    padding: 1.5rem 1rem 1.4rem;
    font-family: var(--font-heading);
    font-size: 0.82rem;
    font-weight: 600;
    line-height: 1.4;
    letter-spacing: 0.005em;
}

.showcase-card.has-tag:hover .showcase-card-tag,
.showcase-card.has-tag:focus-within .showcase-card-tag {
    grid-template-rows: 1fr;
}

/* Hover effects */
.showcase-card:hover .showcase-img-placeholder {
    opacity: 0;
}

/* Emoji — centered on hover overlay */
.showcase-card-emoji {
    position: absolute;
    top: 40%;
    left: 50%;
    transform: translate(-50%, -50%) scale(0.5);
    z-index: 10;
    font-size: 3.5rem;
    opacity: 0;
    transition: opacity var(--duration) var(--cubic), transform var(--duration) var(--cubic);
    pointer-events: none;
    text-decoration: none;
    line-height: 1;
}

.showcase-card:hover .showcase-card-emoji {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
}

/* Card label — inside hover overlay, bottom-right */
.showcase-card-label {
    position: absolute;
    bottom: 20px;
    right: 20px;
    z-index: 5;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 2px;
    opacity: 0;
    transform: translateY(8px);
    transition: opacity var(--duration) var(--cubic), transform var(--duration) var(--cubic);
    pointer-events: none;
}

.showcase-card:hover .showcase-card-label {
    opacity: 1;
    transform: translateY(0);
}

.showcase-card-name {
    font-family: var(--font-heading);
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--text);
    letter-spacing: 0.02em;
}

.showcase-card-year {
    font-family: var(--font-display);
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--primary);
}

/* --- All My Works Link --- */
.showcase-all-works {
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 5rem 0 2rem;
}

.all-works-link {
    font-family: var(--font-heading);
    font-size: 1.6rem;
    font-weight: 700;
    color: var(--text);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    padding: 1rem 2.5rem;
    border: none;
    border-radius: 60px;
    background: transparent;
    transition: color 0.5s var(--cubic);
    overflow: hidden;
    z-index: 1;
}

.all-works-link::before {
    content: '';
    position: absolute;
    inset: 0;
    background: var(--bg);
    border-radius: 60px;
    transform: scaleX(0);
    transform-origin: right;
    transition: transform 0.5s var(--cubic), box-shadow 0.5s var(--cubic);
    z-index: -1;
    box-shadow: none;
}

.all-works-link::after {
    content: '\2192';
    font-size: 1.5rem;
    transition: transform 0.5s var(--cubic);
}

.all-works-link:hover::before {
    transform: scaleX(1);
    transform-origin: left;
    box-shadow: 0 4px 24px var(--shadow);
}

.all-works-link:hover::after {
    transform: translateX(6px);
}

/* No pointer to hover with, so the reveal can never fire — show the title
   outright and drop the question mark. Keyed on hover capability rather than
   width, since that is the thing that actually decides whether it works. */
@media (hover: none) {
    .showcase-card-fun .fun-dots {
        display: none;
    }

    .showcase-card-fun .fun-title > span {
        opacity: 1;
        transform: none;
    }
}

/* Showcase Responsive — Tablet */
@media (max-width: 991px) {
    .showcase-bento {
        grid-template-columns: repeat(2, 1fr);
    }

    .fun-title {
        font-size: clamp(1.8rem, 12vw, 6rem);
    }

    .fun-dots {
        font-size: clamp(3rem, 14vw, 7rem);
    }
}

/* Showcase Responsive — Mobile */
@media (max-width: 767px) {
    .showcase-grid {
        padding: 80px 0 60px;
    }
    .showcase-container {
        padding: 0 0.75rem;
    }
    .showcase-bento {
        gap: 0.75rem;
    }
    .showcase-card-name,
    .showcase-card-year {
        font-size: 0.7rem;
    }
    .showcase-all-works {
        padding: 2.5rem 0 1rem;
    }
    .all-works-link {
        font-size: 0.95rem;
        padding: 0.6rem 1.4rem;
        gap: 0.4rem;
    }
    .all-works-link::after {
        font-size: 1rem;
    }
}

/* --- Footprint Timeline Section --- */
.footprint-section {
    min-height: 100vh;
    background: var(--bg);
    position: relative;
    z-index: 2;
    overflow: clip;
    transition: background var(--duration) var(--cubic);
}

.footprint-header {
    position: absolute;
    top: 30px;
    left: 0;
    right: 0;
    z-index: 3;
    padding: 0 48px;
    text-align: center;
}

.footprint-section .gallery-fan-title {
    color: var(--text);
}

/* Track wrapper — absolutely positioned below header to fill remaining viewport */
.footprint-track-wrapper {
    position: sticky;
    top: 0;
    height: 100vh;
    left: 0;
    right: 0;
    padding: 140px 48px 30px;
    overflow: hidden;
}

.footprint-track {
    display: flex;
    gap: 180px;
    align-items: flex-start;
    height: 100%;
    will-change: transform;
    position: relative;
}

/* Floating balloon inside the track — positioned by JS only */
.footprint-balloon {
    position: absolute;
    top: 0;
    left: 0;
    font-size: 4rem;
    line-height: 1;
    pointer-events: none;
    z-index: 10;
    will-change: transform;
    filter: drop-shadow(0 4px 8px rgba(0,0,0,0.2));
}

/* Individual footprint items — scattered vertically */
.footprint-item {
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
    position: relative;
}

.footprint-img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 0;
    object-fit: contain;
    transition: transform 0.5s var(--cubic);
}

.footprint-item:hover .footprint-img {
    transform: scale(1.03);
}

/* Labels */
.footprint-label {
    display: flex;
    flex-direction: column;
    gap: 1px;
    padding: 0 2px;
    font-family: 'Montserrat', sans-serif;
    white-space: nowrap;
}

.footprint-date {
    font-family: 'Montserrat', sans-serif;
    font-size: 0.82rem;
    font-weight: 700;
    color: var(--primary);
}

.footprint-event {
    font-family: 'Merriweather', serif;
    font-size: 0.88rem;
    font-weight: 700;
    color: var(--text);
    white-space: nowrap;
}

.footprint-location {
    font-family: 'Montserrat', sans-serif;
    font-size: 0.75rem;
    color: var(--text-secondary);
    margin-top: 20px;
}

.footprint-location::before {
    content: '\1F4CD ';
    font-size: 0.65rem;
}

/* --- Per-item layout: 8 groups, staggered vertically --- */

/* 1: Bachelor — starts at top */
.fp-1 {
    width: 150px;
    margin-top: 0;
    align-self: stretch;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
}
.fp-1 .fp-1-top { width: 100%; }

/* 2: Master — pushed down a bit */
.fp-2 {
    width: 210px;
    align-self: flex-end;
}
.fp-2 .footprint-label { margin-left: -16px; }
.fp-2 .footprint-img { margin-left: 60px; }

/* 3: MIT Reality Hack — mid */
.fp-3 {
    width: 190px;
    margin-top: 80px;
}

/* 4: MedVR — pushed down more */
.fp-4 {
    width: 160px;
    margin-top: 180px;
}
.fp-4 .footprint-img { margin-left: -50px; }

/* 4b: MedVR2 — standalone between MedVR and AWE */
.fp-4b {
    width: 250px;
    margin-top: 0;
    margin-left: -200px;
}

/* 5: AWE — bottom aligned */
.fp-5 {
    width: 120px;
    margin-left: -40px;
    align-self: flex-end;
}

/* 6: AR Summer School — pushed down */
.fp-6 {
    width: 220px;
    margin-top: 100px;
    margin-left: -40px;
}
.fp-6-row {
    display: flex;
    align-items: flex-start;
    gap: 10px;
}
.fp-6 .fp-6-top { width: 150px; }

/* 7: MIT Summit — near top */
.fp-7 {
    width: 200px;
    margin-top: 0;
    margin-left: 40px;
}

/* 8: MDIC — mid */
.fp-8 {
    width: 210px;
    margin-top: 140px;
    margin-left: -20px;
}

/* Horizontal offsets within groups for scattered collage look */
.fp-1 .fp-1-bottom { width: 100px; margin-left: 160px; }
.fp-5 .fp-5-bottom { margin-left: 20px; }
.fp-6 .fp-6-bottom { width: 230px; margin-left: 90px; margin-top: 60px; }

/* Labels need position:relative for hull-wrap offset calculations */
.footprint-label { position: relative; }

/* Footprint Responsive — vertical stack on mobile */
@media (max-width: 768px) {
    .footprint-section {
        height: auto;
        overflow: visible;
    }
    .footprint-header {
        position: relative;
        top: auto;
        left: auto;
        right: auto;
        padding: 40px 20px 16px;
        text-align: center;
    }
    .footprint-track-wrapper {
        position: relative;
        top: auto;
        bottom: auto;
        height: auto;
        overflow-x: hidden;
        overflow-y: visible;
        padding: 0 20px 40px;
    }
    .footprint-track {
        flex-direction: column;
        gap: 24px;
        height: auto;
        align-items: flex-start;
    }
    .footprint-balloon {
        display: block;
    }
    /* Reset all per-item desktop overrides */
    .fp-1, .fp-2, .fp-3, .fp-4, .fp-4b, .fp-5, .fp-6, .fp-7, .fp-8 {
        width: 42vw;
        max-width: 180px;
        margin: 0;
        overflow: visible;
    }
    /* Stagger left/right — no overlap (DOM order: 2, 8, 7, 6, 5, 4, 4b, 3, 1) */
    .fp-2  { align-self: flex-end; }
    .fp-8  { align-self: flex-start; }
    .fp-7  { align-self: flex-end; }
    .fp-6  { align-self: flex-start; }
    .fp-5  { align-self: flex-end; }
    /* fp-4 / fp-4b are the same event, so they share the left side */
    .fp-4  { align-self: flex-start; }
    .fp-4b { align-self: flex-start; }
    .fp-3  { align-self: flex-end; }
    .fp-1  { align-self: flex-start; }
    /* Right-side labels pull left so the text stays on screen */
    .fp-2 .footprint-label { margin-left: -16vw; }
    .fp-7 .footprint-label { margin-left: -24vw; }
    .fp-3 .footprint-label { margin-left: -24vw; }
    .fp-1 .fp-1-bottom { width: 60%; margin-left: 0; }
    .fp-2 .footprint-img { margin-left: 0; }
    .fp-4 .footprint-img { margin-left: 0; }
    .fp-6 .fp-6-top { width: 50%; }
    .fp-6 .fp-6-bottom { width: 70%; margin-left: 0; margin-top: 10px; }
    .fp-6-row { gap: 6px; overflow: visible; }
    .fp-6 .footprint-label { flex-shrink: 0; width: max-content; }
    /* Labels extend across center but wrap at screen edge */
    .footprint-label { white-space: normal; overflow: visible; }
    /* Left-side labels: wide enough to reach the right edge of the screen */
    .fp-1 .footprint-label,
    .fp-4 .footprint-label,
    .fp-6 .footprint-label,
    .fp-8 .footprint-label {
        width: calc(100vw - 40px);
    }
    .footprint-date { font-size: 0.75rem; }
    .footprint-event { font-size: 0.8rem; white-space: normal; }
    .footprint-location { font-size: 0.7rem; margin-top: 10px; }
}

/* --- Gallery Fan Section --- */
.gallery-fan {
    /* Generous foot: the fan's outer cards hang low, and 40px left them
       sitting right on top of the footer text. */
    padding: 160px 48px 140px;
    background: var(--section-bg);
    text-align: center;
    position: relative;
    z-index: 2;
    transition: background var(--duration) var(--cubic);
}

.gallery-fan-header {
    margin-bottom: 40px;
    position: relative;
    z-index: 2;
}

.gallery-fan-title {
    font-family: var(--font-display);
    font-size: clamp(2.2rem, 4.5vw, 3.2rem);
    font-weight: 800;
    color: var(--text);
    margin-bottom: 16px;
    letter-spacing: -0.02em;
}

.gallery-fan-subtitle {
    font-family: var(--font-heading);
    font-size: 1.1rem;
    color: var(--text-secondary);
}

/*
 * Fan container + cards — layout only.
 * All transforms (position, rotation, scale) are handled by GSAP,
 * directly ported from landonorris.com source code.
 */
.fan-container {
    justify-content: center;
    align-items: center;
    width: 100%;
    max-width: 80rem;
    height: 26rem;
    display: flex;
    position: relative;
    margin: 0 auto;
}

.fan-card {
    z-index: 0;
    backface-visibility: hidden;
    will-change: transform;
    border-radius: 2.5rem;
    flex: none;
    width: 15rem;
    height: 20rem;
    position: absolute;
    overflow: clip;
    opacity: 1;
}

.fan-card-inner {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

.fan-card-label {
    font-family: var(--font-heading);
    font-weight: 600;
    color: rgba(255, 255, 255, 0.35);
    font-size: 0.95rem;
}

/* Responsive — tablet */
@media (max-width: 991px) {
    .fan-card {
        width: 13rem;
        height: 17.33rem;
    }
    .fan-container {
        height: 22rem;
    }
}

/* Responsive — mobile */
@media (max-width: 767px) {
    .gallery-fan {
        padding: 80px 20px 90px;
    }

    .fan-container {
        height: 20rem;
    }

    .fan-card {
        width: 8rem;
        height: 10.67rem;
        border-radius: 1.5rem;
    }
}

/* Responsive — small mobile */
@media (max-width: 479px) {
    .fan-container { height: 14rem; }
    .fan-card { width: 6.5rem; height: 8.67rem; border-radius: 1.2rem; }
}

/* --- Contact Section --- */
.social-links {
    display: flex;
    justify-content: center;
    gap: 16px;
}

.social-link {
    width: 52px;
    height: 52px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--surface);
    color: var(--text-secondary);
    box-shadow: 0 1px 6px var(--shadow);
    transition: all 0.4s var(--cubic);
}

.social-link:hover {
    transform: translateY(-4px) scale(1.1);
    box-shadow: 0 6px 16px rgba(0,0,0,0.08);
}

.social-link svg {
    display: block;
}

.social-github,
.social-x {
    color: var(--text);
}

.titles-section {
    position: relative;
    z-index: 1;
    padding: 0 1.25rem;
    background: var(--section-bg);
    overflow: hidden;
    transition: background var(--duration) var(--cubic);
}

.footer-titles-block {
    display: block;
}

.footer-titles-block .hero-title-line {
    display: block;
    width: fit-content;
    white-space: nowrap;
    line-height: 1.05;
    font-size: 5vw;
}

/* --- Animations --- */
@keyframes wave {
    0%, 100% { transform: rotate(0deg); }
    15% { transform: rotate(14deg); }
    30% { transform: rotate(-8deg); }
    40% { transform: rotate(14deg); }
    50% { transform: rotate(-4deg); }
    60% { transform: rotate(10deg); }
    70% { transform: rotate(0deg); }
}

@keyframes float {
    0%, 100% { transform: translateY(0) rotate(0deg); }
    50% { transform: translateY(-25px) rotate(5deg); }
}

/* --- Responsive --- */
@media (max-width: 768px) {
    .nav {
        padding: 24px 20px 16px;
    }

    .nav-links {
        gap: 24px;
        padding: 6px 16px 6px 20px;
    }

    .hero {
        padding: 100px 20px 0;
    }

    .work {
        padding: 80px 20px;
    }

    .work-grid {
        grid-template-columns: 1fr;
    }

    .about {
        padding: 80px 20px;
    }

    .about-container {
        grid-template-columns: 1fr;
        gap: 48px;
        text-align: center;
    }

    .photo-placeholder {
        width: 220px;
        height: 280px;
        margin: 0 auto;
    }

    .skills {
        justify-content: center;
    }

    .filters {
        gap: 6px;
    }

    .filter-btn {
        font-size: 0.8rem;
        padding: 7px 16px;
    }

    .shape-1 { width: 200px; height: 200px; }
    .shape-2 { width: 150px; height: 150px; }
    .shape-3 { width: 100px; height: 100px; }

    .marquee-content span {
        font-size: 0.9rem;
    }
}

@media (max-width: 480px) {
    .nav-links {
        gap: 16px;
        padding: 6px 12px 6px 16px;
    }

    .nav-links a {
        font-size: 0.85rem;
    }

    .hero-subtitle {
        font-size: 1rem;
    }

    .card-image {
        aspect-ratio: 16 / 9;
    }
}

/* ============================================
   Lake — scrolling opens a body of water, the email sits on it
   ============================================ */
/* Not pinned. A sticky stage holds the picture still while the page keeps
   scrolling, which is exactly what pushed the section below it out of reach —
   the lake now travels up the page like any other block. */
.lake-section {
    padding: 24px 0 16px;
    position: relative;
    z-index: 1;
    background: var(--bg);
    transition: background var(--duration) var(--cubic);
}

.lake-stage {
    position: relative;
    height: 44vh;
    overflow: hidden;
}

.lake-canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
}

.lake-caption {
    position: absolute;
    left: 50%;
    /* Centred on the water: the shader puts the lake at 0.53 from the bottom,
       which is this same 47% from the top. */
    top: 47%;
    width: max-content;
    max-width: 92vw;
    text-align: center;
    transform: translate(-50%, calc(-50% + 16px));
    opacity: 0;
    will-change: opacity, transform;
}

.lake-email {
    display: block;
    position: relative;
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: clamp(0.95rem, 2.4vw, 1.55rem);
    letter-spacing: 0.04em;
    color: #FFFFFF;
    text-decoration: none;
    text-shadow: 0 2px 20px rgba(3, 26, 40, 0.55);
    white-space: nowrap;
}

/* White pucks read cleanly on the water in both themes, so these do not follow
   --surface the way the ones down in the contact section do. */
.lake-socials {
    margin-top: 18px;
    gap: 14px;
}

.lake-socials .social-link {
    width: 44px;
    height: 44px;
    background: #FFFFFF;
    color: #1E293B;
    box-shadow: 0 4px 16px rgba(3, 26, 40, 0.28);
}

.lake-socials .social-link:hover {
    box-shadow: 0 8px 22px rgba(3, 26, 40, 0.34);
}

@media (max-width: 767px) {
    .lake-socials {
        margin-top: 14px;
        gap: 10px;
    }

    .lake-socials .social-link {
        width: 38px;
        height: 38px;
    }

    .lake-section {
        padding: 16px 0 12px;
    }

    .lake-stage {
        height: 38vh;
    }

    .lake-caption {
        top: 47%;
    }
}

/* ============================================
   Mac OS X Panther Window
   ============================================ */
.panther-section {
    padding: 56px 48px 80px;
    display: flex;
    justify-content: flex-start;
    align-items: center;
    flex-direction: column;
    position: relative;
    z-index: 1;
    background: var(--bg);
    transition: background var(--duration) var(--cubic);
    overflow: visible;
    overflow-anchor: none;
}

.panther-header {
    margin-bottom: 48px;
    text-align: center;
}

/* ---- macOS Folder ---- */
.mac-folder {
    position: relative;
    width: 220px;
    height: 165px;
    cursor: pointer;
    z-index: 10;
    margin-bottom: 10px;
    filter: drop-shadow(0 8px 20px rgba(0,0,0,0.15));
    flex-shrink: 0;
    /* Initial state — GSAP will animate scale + opacity on scroll */
    transform: scale(0.3);
    opacity: 0;
}

.mac-folder.folder-opened {
    cursor: pointer;
}

.mac-folder:hover {
    filter: drop-shadow(0 12px 28px rgba(0,0,0,0.22));
}

.mac-folder:hover .mac-folder-front {
    transform: perspective(600px) rotateX(-18deg);
}

/* Folder back panel */
.mac-folder-back {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 85%;
    background: linear-gradient(to bottom, #6BB8E8 0%, #5BA4D6 50%, #4A92C4 100%);
    border-radius: 2px 2px 4px 4px;
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.3);
}

.mac-folder-tab {
    position: absolute;
    top: -14px;
    left: 8px;
    width: 55px;
    height: 16px;
    background: linear-gradient(to bottom, #6BB8E8 0%, #5BA4D6 100%);
    border-radius: 4px 4px 0 0;
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.3);
}

/* Folder front panel */
.mac-folder-front {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 78%;
    background: linear-gradient(to bottom, #7EC8F0 0%, #60ACD8 30%, #4A98C6 100%);
    border-radius: 2px 2px 4px 4px;
    transform-origin: bottom center;
    transition: transform 0.4s var(--cubic);
    box-shadow:
        0 2px 6px rgba(0,0,0,0.12),
        inset 0 1px 0 rgba(255,255,255,0.4);
    z-index: 2;
}

.mac-folder-front::before {
    content: '';
    position: absolute;
    top: 6px;
    left: 10%;
    right: 10%;
    height: 2px;
    background: rgba(255,255,255,0.2);
    border-radius: 1px;
}

.mac-folder-front::after {
    content: '';
    position: absolute;
    top: 12px;
    left: 10%;
    right: 20%;
    height: 2px;
    background: rgba(255,255,255,0.12);
    border-radius: 1px;
}

.mac-folder-tab-front {
    display: none;
}

/* Folder label */
.mac-folder-label {
    position: absolute;
    bottom: -30px;
    left: 50%;
    transform: translateX(-50%);
    font-family: 'Lucida Grande', Helvetica, sans-serif;
    font-size: 14px;
    font-weight: 500;
    color: var(--text-secondary);
    white-space: nowrap;
    text-shadow: 0 1px 0 rgba(255,255,255,0.6);
    transition: opacity 0.3s ease;
}

/* Folder lid close transition */
.mac-folder-front {
    transition: transform 0.4s var(--cubic);
}

.mac-folder.folder-opened .mac-folder-front {
    transition: transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* Folder open animation */
.mac-folder.folder-opened .mac-folder-front {
    transform: perspective(600px) rotateX(-75deg);
    transition: transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* Dark mode folder */
[data-theme="dark"] .mac-folder-back {
    background: linear-gradient(to bottom, #4A7A9E 0%, #3A6888 50%, #2D5876 100%);
}

[data-theme="dark"] .mac-folder-tab {
    background: linear-gradient(to bottom, #4A7A9E 0%, #3A6888 100%);
}

[data-theme="dark"] .mac-folder-front {
    background: linear-gradient(to bottom, #5A90B4 0%, #4278A0 30%, #346A8E 100%);
}

[data-theme="dark"] .mac-folder-label {
    text-shadow: none;
}

/* ---- Window animation states ---- */
.panther-window.window-hidden {
    visibility: hidden;
    pointer-events: none;
    opacity: 0;
}

/* Clip wrapper: overflow-hidden container whose height is animated
   to smoothly push content below when the window opens/closes. */
.panther-window-clip {
    overflow: hidden;
    height: 0;
    width: 100%;
    max-width: min(1088px, calc(100vw - 40px));
    padding: 0 20px;
    margin-top: 36px;
    box-sizing: border-box;
}

.panther-window-clip.is-open {
    overflow: visible;
}

.panther-window {
    width: 100%;
    min-height: 200px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    border-radius: 5px;
    box-shadow:
        0 12px 40px rgba(0, 0, 0, 0.35),
        0 0 0 1px rgba(0, 0, 0, 0.25);
    font-family: 'Lucida Grande', 'Lucida Sans Unicode', Helvetica, sans-serif;
    position: relative;
    z-index: 20;
    overflow-anchor: none;
}

.panther-window.window-resized .panther-content {
    min-height: 0;
    height: auto;
    flex: 1 1 auto;
}

/* --- Brushed Metal Texture (shared base) --- */
.panther-titlebar,
.panther-toolbar,
.panther-ruler {
    background-color: #C4C4C4;
}

/* --- Title Bar --- */
.panther-titlebar {
    height: 24px;
    display: flex;
    align-items: center;
    padding: 0 8px;
    background: linear-gradient(to bottom, #D8D8D8 0%, #E2E2E2 35%, #BABABA 65%, #A8A8A8 100%);
    border-bottom: 1px solid #888;
    position: relative;
    flex-shrink: 0;
    border-radius: 5px 5px 0 0;
}

.panther-title-text {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    font-size: 13px;
    font-weight: bold;
    color: #222;
    text-shadow: 0 1px 0 rgba(255, 255, 255, 0.45);
    white-space: nowrap;
    pointer-events: none;
}

/* --- Traffic Light Buttons --- */
.panther-traffic-lights {
    display: flex;
    align-items: center;
    gap: 8px;
    z-index: 1;
    flex-shrink: 0;
}

.panther-btn {
    width: 13px;
    height: 13px;
    border-radius: 50%;
    border: 1px solid rgba(0, 0, 0, 0.2);
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: default;
    position: relative;
    transition: none;
    outline: none;
    -webkit-appearance: none;
}

.panther-btn svg {
    opacity: 0;
    transition: opacity 0.15s ease;
    color: rgba(0, 0, 0, 0.55);
}

.panther-traffic-lights:hover .panther-btn svg {
    opacity: 1;
}

.panther-btn-close {
    background: radial-gradient(circle at 35% 30%, #F5918A 0%, #ED6A5F 40%, #E24B41 100%);
    border-color: #E24B41;
}

.panther-btn-minimize {
    background: radial-gradient(circle at 35% 30%, #FCD668 0%, #F6BE50 40%, #E1A73E 100%);
    border-color: #E1A73E;
}

.panther-btn-maximize {
    background: radial-gradient(circle at 35% 30%, #85D67A 0%, #61C555 40%, #2DAC2F 100%);
    border-color: #2DAC2F;
}

.panther-btn-close:active {
    background: radial-gradient(circle at 35% 30%, #C06058, #B15048, #A14239);
    border-color: #A14239;
}

.panther-btn-minimize:active {
    background: radial-gradient(circle at 35% 30%, #CCA050, #B8923B, #A67F36);
    border-color: #A67F36;
}

.panther-btn-maximize:active {
    background: radial-gradient(circle at 35% 30%, #62AB58, #4A9741, #428234);
    border-color: #428234;
}

/* --- Toolbar --- */
.panther-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 3px 8px;
    height: 30px;
    background: linear-gradient(to bottom, #CCCCCC 0%, #D6D6D6 40%, #B8B8B8 60%, #AAAAAA 100%);
    border-bottom: 1px solid #888;
    flex-shrink: 0;
    overflow: visible;
}

.panther-toolbar-group {
    display: flex;
    align-items: center;
    gap: 3px;
}

.panther-toolbar-right {
    margin-left: auto;
}

.panther-toolbar-btn {
    font-family: 'Lucida Grande', 'Lucida Sans Unicode', Helvetica, sans-serif;
    font-size: 11px;
    color: #333;
    padding: 2px 8px;
    border: 1px solid #9C9C9C;
    border-radius: 4px;
    cursor: default;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    background-image: linear-gradient(
        to bottom,
        #FFFFFF 0%,
        #F6F6F6 30%,
        #F0F0F0 50%,
        #E8E8E8 70%,
        #EEEEEE 100%
    );
    box-shadow:
        0 1px 1px rgba(0, 0, 0, 0.1),
        inset 0 1px 0 rgba(255, 255, 255, 0.7);
    outline: none;
    -webkit-appearance: none;
    line-height: 1.4;
    white-space: nowrap;
}

.panther-toolbar-btn:active {
    border-color: #705EBB;
    background-image: linear-gradient(
        to bottom,
        #ACC5E9 0%,
        #A3C0F2 18%,
        #61A0ED 39%,
        #55A3F2 70%,
        #82C2F1 92%,
        #9AD2F2 100%
    );
    color: #fff;
}

.panther-toolbar-btn:active svg path {
    stroke: #fff;
}

.panther-toolbar-icon {
    width: 22px;
    height: 20px;
    border: 1px solid transparent;
    border-radius: 3px;
    background: transparent;
    cursor: default;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: #555;
    padding: 0;
    outline: none;
    -webkit-appearance: none;
}

.panther-toolbar-icon:hover {
    border-color: #9C9C9C;
    background: linear-gradient(to bottom, #f4f4f4, #e0e0e0);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5);
}

.panther-toolbar-icon:active,
.panther-icon-active {
    border-color: #705EBB;
    background: linear-gradient(to bottom, #82B5EB 0%, #61A0ED 40%, #55A3F2 100%);
    color: #fff;
}

.panther-toolbar-divider {
    width: 1px;
    height: 18px;
    background: linear-gradient(to bottom, transparent, #999, transparent);
    margin: 0 4px;
}

/* --- Dropdown Wrapper --- */
.panther-dropdown-wrap {
    position: relative;
}

/* --- Aqua Dropdown Menu --- */
.panther-menu {
    display: none;
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    min-width: 170px;
    background: #fff;
    border: 1px solid #808080;
    border-radius: 5px;
    box-shadow:
        0 6px 20px rgba(0, 0, 0, 0.28),
        0 0 0 1px rgba(0, 0, 0, 0.06),
        inset 0 0 0 1px rgba(255, 255, 255, 0.5);
    padding: 4px 0;
    z-index: 100;
    font-family: 'Lucida Grande', 'Lucida Sans Unicode', Helvetica, sans-serif;
    font-size: 12px;
    color: #222;
    animation: pantherMenuIn 0.12s ease-out;
}

.panther-menu.panther-menu-open {
    display: block;
}

@keyframes pantherMenuIn {
    from { opacity: 0; transform: translateY(-4px) scaleY(0.95); }
    to   { opacity: 1; transform: translateY(0) scaleY(1); }
}

.panther-menu-item {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 4px 12px 4px 6px;
    cursor: default;
    border-radius: 3px;
    margin: 0 4px;
    transition: none;
}

.panther-menu-item:hover {
    background: linear-gradient(to bottom, #3D80DF 0%, #2968C8 100%);
    color: #fff;
}

.panther-menu-item:hover .panther-menu-check,
.panther-menu-item:hover .panther-menu-label,
.panther-menu-item:hover .panther-menu-preview,
.panther-menu-item:hover .panther-menu-shortcut {
    color: #fff;
}

.panther-menu-check {
    width: 14px;
    font-size: 11px;
    color: #2968C8;
    text-align: center;
    flex-shrink: 0;
    opacity: 0;
}

.panther-menu-active .panther-menu-check {
    opacity: 1;
}

.panther-menu-label {
    flex: 1;
}

.panther-menu-preview {
    font-size: 13px;
    color: #888;
    margin-left: auto;
    flex-shrink: 0;
}

.panther-menu-shortcut {
    font-size: 10px;
    color: #888;
    margin-left: auto;
    flex-shrink: 0;
    font-variant-numeric: tabular-nums;
}

.panther-menu-separator {
    height: 1px;
    background: #D8D8D8;
    margin: 4px 8px;
}

/* Active dropdown button state (while menu is open) */
.panther-toolbar-btn.panther-dropdown-open {
    border-color: #705EBB;
    background-image: linear-gradient(
        to bottom,
        #ACC5E9 0%,
        #A3C0F2 18%,
        #61A0ED 39%,
        #55A3F2 70%,
        #82C2F1 92%,
        #9AD2F2 100%
    );
    color: #fff;
}

.panther-toolbar-btn.panther-dropdown-open svg path {
    stroke: #fff;
}

/* --- Ruler --- */
.panther-ruler {
    height: 20px;
    background: linear-gradient(to bottom, #E0E0E0 0%, #F0F0F0 30%, #F0F0F0 70%, #D0D0D0 100%);
    border-bottom: 1px solid #A0A0A0;
    position: relative;
    overflow: hidden;
}

.panther-ruler-track {
    position: absolute;
    inset: 0;
    background:
        repeating-linear-gradient(
            to right,
            #888 0px,
            #888 1px,
            transparent 1px,
            transparent 16.66%
        );
    background-size: 100% 14px;
    background-position: bottom left;
    background-repeat: repeat-x;
}

.panther-ruler-track::before {
    content: '';
    position: absolute;
    inset: 0;
    background:
        repeating-linear-gradient(
            to right,
            #AAA 0px,
            #AAA 1px,
            transparent 1px,
            transparent 8.33%
        );
    background-size: 100% 9px;
    background-position: bottom left;
    background-repeat: repeat-x;
}

.panther-ruler-track::after {
    content: '';
    position: absolute;
    inset: 0;
    background:
        repeating-linear-gradient(
            to right,
            #CCC 0px,
            #CCC 1px,
            transparent 1px,
            transparent 1.666%
        );
    background-size: 100% 5px;
    background-position: bottom left;
    background-repeat: repeat-x;
}

.panther-ruler-numbers {
    position: absolute;
    inset: 0;
    font-size: 8px;
    color: #555;
    font-family: 'Lucida Grande', Helvetica, sans-serif;
}

.panther-ruler-numbers span {
    position: absolute;
    bottom: 4px;
    transform: translateX(-50%);
    font-weight: bold;
    line-height: 1;
}

.panther-ruler-numbers span:first-child {
    transform: translateX(2px);
}

.panther-ruler-numbers span:last-child {
    transform: translateX(-100%);
}

/* --- Content Area --- */
.panther-content {
    background: #fff;
    min-height: 420px;
    height: 420px;
    flex: 0 0 auto;
    padding: 10px 14px;
    font-family: 'Times New Roman', Times, serif;
    font-size: 16px;
    color: #000;
    line-height: 1.5;
    outline: none;
    cursor: text;
    overflow-x: hidden;
    overflow-y: auto;
    border: none;
    border-radius: 0 0 5px 5px;
}

.panther-content p {
    margin-bottom: 12px;
    text-indent: -2em;
    padding-left: 2em;
}

.panther-content p:last-child {
    margin-bottom: 0;
}

/* --- Resize Handle --- */
.panther-resize-handle {
    position: absolute;
    bottom: 2px;
    right: 2px;
    width: 14px;
    height: 14px;
    cursor: nwse-resize;
    opacity: 0.6;
    display: flex;
    align-items: center;
    justify-content: center;
}


/* --- Panther Window: Dark Theme Adjustments --- */
[data-theme="dark"] .panther-window {
    box-shadow:
        0 12px 40px rgba(0, 0, 0, 0.6),
        0 0 0 1px rgba(255, 255, 255, 0.08);
}

[data-theme="dark"] .panther-content {
    background: #1a1a1a;
    color: #e0e0e0;
}

/* --- Panther Responsive --- */
@media (max-width: 768px) {
    .panther-section {
        padding: 80px 20px 60px;
    }

    .panther-window {
        max-width: 100%;
    }

    .panther-window-clip {
        max-width: calc(100vw - 20px);
        padding: 0 10px;
        margin-top: 28px;
    }

    .panther-toolbar-btn span {
        font-size: 10px;
    }

    #pantherCiteWrap .panther-menu {
        left: auto;
        right: 0;
    }
}

@media (max-width: 480px) {
    .panther-window-clip {
        max-width: calc(100vw - 12px);
        padding: 0 6px;
        margin-top: 22px;
    }

    .panther-toolbar-right {
        display: none;
    }

    .panther-content {
        min-height: 240px;
    }
}

/* ============================================
   Project Detail Page
   ============================================ */

/* --- Hero Banner --- */
.pd-hero {
    position: relative;
    width: 100%;
    height: 70vh;
    min-height: 450px;
    max-height: 800px;
    overflow: hidden;
    display: flex;
    align-items: flex-end;
    z-index: 2;
}

.pd-hero-image {
    position: absolute;
    inset: -20% 0 0 0;
    width: 100%;
    height: 120%;
    background-size: cover;
    background-position: center;
    will-change: transform;
}

.pd-hero-overlay {
    position: absolute;
    inset: 0;
    background: linear-gradient(to top, rgba(0,0,0,0.7) 0%, rgba(0,0,0,0.1) 50%, transparent 100%);
    z-index: 1;
}

.pd-hero-content {
    position: relative;
    z-index: 2;
    padding: 0 48px 60px;
    max-width: 900px;
}

.pd-category {
    display: inline-block;
    font-family: var(--font-heading);
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 2px;
    color: var(--primary);
    margin-bottom: 16px;
}

.pd-title {
    font-family: var(--font-display);
    font-size: clamp(2.8rem, 6vw, 5rem);
    font-weight: 800;
    color: #fff;
    line-height: 1.1;
    letter-spacing: -0.02em;
    margin-bottom: 16px;
}

.pd-tagline {
    font-family: var(--font-body);
    font-size: clamp(1rem, 2vw, 1.25rem);
    color: rgba(255, 255, 255, 0.75);
    line-height: 1.6;
    max-width: 600px;
}

/* --- Project Meta --- */
.pd-meta {
    position: relative;
    z-index: 2;
    padding: 60px 48px;
    border-bottom: none;
    background: var(--bg);
    transition: background var(--duration) var(--cubic);
}

.pd-meta-grid {
    max-width: 1100px;
    margin: 0 auto;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 32px;
}

.pd-meta-item {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.pd-meta-label {
    font-family: var(--font-heading);
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 1.5px;
    color: var(--primary);
}

.pd-meta-value {
    font-family: var(--font-body);
    font-size: 0.95rem;
    color: var(--text);
    line-height: 1.5;
}

/* --- Project Content --- */
.pd-content {
    position: relative;
    z-index: 2;
    max-width: 1100px;
    margin: 0 auto;
    padding: 80px 48px 40px;
    background: var(--bg);
    transition: background var(--duration) var(--cubic);
}

.pd-section {
    margin-bottom: 80px;
}

.pd-section-header {
    display: flex;
    align-items: baseline;
    gap: 20px;
    margin-bottom: 28px;
}

.pd-section-number {
    font-family: var(--font-display);
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--primary);
    flex-shrink: 0;
}

.pd-section-title {
    font-family: var(--font-display);
    font-size: clamp(1.6rem, 3vw, 2.2rem);
    font-weight: 700;
    color: var(--text);
    letter-spacing: -0.02em;
}

.pd-section-body {
    padding-left: 52px;
}

.pd-section-body p {
    font-family: var(--font-body);
    font-size: 1.05rem;
    color: var(--text-secondary);
    line-height: 1.8;
    margin-bottom: 20px;
}

.pd-section-body p:last-child {
    margin-bottom: 0;
}

.pd-section-body ul {
    list-style: none;
    padding: 0;
    margin: 16px 0 0;
}

.pd-section-body ul li {
    font-family: var(--font-body);
    font-size: 1.05rem;
    color: var(--text-secondary);
    line-height: 1.8;
    padding-left: 20px;
    position: relative;
}

.pd-section-body ul li::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0.75em;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--primary);
}

/* --- Overview Statement --- */
.pd-overview-statement {
    max-width: 100%;
    margin: 0 0 60px;
    padding: 40px 48px;
    text-align: center;
    background: rgba(60, 130, 220, 0.08);
    border-radius: var(--radius);
}

.pd-overview-statement p {
    font-size: 1.25rem;
    line-height: 1.9;
    color: var(--text-secondary);
    font-weight: 400;
    letter-spacing: 0.01em;
    margin: 0;
}

.pd-highlight {
    color: var(--primary);
    font-weight: 600;
}

/* --- Full-width Image --- */
.pd-image-full {
    margin: 60px 0 80px;
    border-radius: 48px;
    overflow: hidden;
}

.pd-image-full img {
    width: 100%;
    height: auto;
    display: block;
    object-fit: cover;
}

/* --- Two-column Image Grid --- */
.pd-image-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px;
    margin: 60px 0 80px;
}

.pd-image-col {
    border-radius: 48px;
    overflow: hidden;
}

.pd-image-col img {
    width: 100%;
    height: 100%;
    display: block;
    object-fit: cover;
}

/* --- Project Navigation (prev/next) --- */
.pd-nav {
    position: relative;
    z-index: 2;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 40px 48px;
    border-top: 1px solid var(--border);
    max-width: 1196px;
    margin: 0 auto;
    background: var(--bg);
    transition: background var(--duration) var(--cubic), border-color var(--duration) var(--cubic);
}

.pd-nav-link {
    display: flex;
    align-items: center;
    gap: 12px;
    font-family: var(--font-heading);
    font-size: 1rem;
    font-weight: 600;
    color: var(--text);
    transition: color 0.3s var(--cubic);
}

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

.pd-nav-arrow {
    font-size: 1.4rem;
    transition: transform 0.3s var(--cubic);
}

.pd-nav-back:hover .pd-nav-arrow {
    transform: translateX(-4px);
}

.pd-nav-next:hover .pd-nav-arrow {
    transform: translateX(4px);
}

.pd-nav-next {
    margin-left: auto;
    flex-direction: row-reverse;
}

/* --- Responsive --- */
@media (max-width: 768px) {
    .pd-hero {
        height: 50vh;
        min-height: 350px;
    }

    .pd-hero-content {
        padding: 0 20px 40px;
    }

    .pd-meta {
        padding: 40px 20px;
    }

    .pd-meta-grid {
        grid-template-columns: 1fr 1fr;
        gap: 24px;
    }

    .pd-content {
        padding: 60px 20px 20px;
    }

    .pd-section-body {
        padding-left: 0;
    }

    .pd-image-grid {
        grid-template-columns: 1fr;
    }

    .pd-overview-statement p {
        font-size: 1rem;
    }

    .pd-image-full {
        margin: 24px 0 28px;
    }

    .pd-image-grid {
        margin: 24px 0 28px;
    }

    .pd-nav {
        padding: 32px 20px;
    }
}

@media (max-width: 480px) {
    .pd-meta-grid {
        grid-template-columns: 1fr;
        gap: 20px;
    }

    .pd-section {
        margin-bottom: 60px;
    }
}

/* --- Showcase Card Link Wrapper --- */
.showcase-card-link {
    display: block;
    text-decoration: none;
    color: inherit;
}

/* ============================================
   Wave Contact — the water band that closes the Icovela case study,
   repeated at the foot of the homepage. The shader (wave-contact.js)
   washes out to white as it rises to the shoreline, so the band is
   light in both themes; the top edge fades out of the page colour
   instead of butting against it.
   ============================================ */
.wave-contact {
    position: relative;
    overflow: hidden;
    min-height: clamp(400px, 48vh, 560px);
    padding: 5.5rem 0 4rem;
    background: linear-gradient(to bottom, var(--bg) 0, #FAFAFA 160px);
    transition: background var(--duration) var(--cubic);
}

.wave-contact-canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
    pointer-events: none;
}

.wave-contact-wrap {
    position: relative;
    max-width: 1120px;
    margin: 0 auto;
    padding: 0 2rem;
    text-align: center;
}

.wave-contact-mail {
    display: block;
    width: fit-content;
    margin: 0 auto;
    font-family: var(--font-heading);
    font-size: clamp(1.5rem, 3.4vw, 2.4rem);
    font-weight: 700;
    letter-spacing: 0.01em;
    color: #101215;
    text-decoration: none;
}

/* No white pucks here: the marks sit straight on the water, centred under
   the email rather than hanging off its left edge. */
.wave-contact .social-links {
    justify-content: center;
    margin-top: 1.75rem;
    gap: 1.4rem;
}

.wave-contact .social-link {
    width: auto;
    height: auto;
    background: none;
    box-shadow: none;
    color: #101215;
}

/* The marks ship at 22px in the markup; scale them up here so they keep
   their footing under the enlarged email. */
.wave-contact .social-link svg {
    width: 30px;
    height: 30px;
}

.wave-contact .social-link:hover {
    box-shadow: none;
}

@media (max-width: 767px) {
    .wave-contact {
        min-height: 320px;
        padding: 4.5rem 0 2.5rem;
    }

    .wave-contact-wrap {
        padding: 0 1.25rem;
    }

    .wave-contact .social-link svg {
        width: 26px;
        height: 26px;
    }
}
