/* css/ocean-dive.css - Ocean Diving Experience Styles */

/* ===== CSS Variables for Depth Theming ===== */
:root {
    /* Surface colors (sunset) */
    --surface-gradient-start: #ff7e5f;
    --surface-gradient-mid: #feb47b;
    --surface-gradient-end: #4facfe;

    /* Ocean depth colors */
    --shallow-water: #00d4ff;
    --mid-water: #0077b6;
    --deep-water: #023e8a;
    --abyss: #03071e;

    /* Accent colors */
    --bubble-glow: rgba(0, 212, 255, 0.6);
    --bubble-border: rgba(255, 255, 255, 0.3);
    --card-bg: rgba(10, 30, 50, 0.85);
    --card-border: rgba(0, 170, 255, 0.2);

    /* Timing */
    --transition-smooth: 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}

/* ===== Base Layout ===== */
html {
    scroll-behavior: smooth;
    overflow-x: hidden;
}

body.ocean-dive {
    overflow-x: hidden;
    background: var(--abyss);
}

.ocean-container {
    position: relative;
    width: 100%;
}

/* ===== Depth Background Layer ===== */
.depth-background {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: -2;
    background: linear-gradient(180deg,
            var(--surface-gradient-start) 0%,
            var(--surface-gradient-mid) 15%,
            var(--surface-gradient-end) 30%,
            var(--shallow-water) 45%,
            var(--mid-water) 60%,
            var(--deep-water) 80%,
            var(--abyss) 100%);
    background-size: 100% 500vh;
}

/* Once the 3D water has drawn it covers this backdrop completely, so the
   backdrop stops painting at all while the page scrolls (it stays as the
   fallback where WebGL never starts) */
html.ocean-live .depth-background {
    visibility: hidden;
}

/* ===== Cloud Navigation ===== */
.cloud-nav {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    display: flex;
    justify-content: center;
    gap: 3.5rem;
    /* above the prop canvas (z 250): the label prints on the cloud, not under it */
    z-index: 260;
    padding: 1.4rem 1rem 0;
    pointer-events: none;
    transition: opacity 0.5s cubic-bezier(0.25, 1, 0.5, 1), transform 0.6s cubic-bezier(0.25, 1, 0.5, 1);
}

.cloud-link {
    position: relative;
    /* the flight is the answer to a tap: no grey or blue box behind the cloud */
    -webkit-tap-highlight-color: transparent;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    gap: 0;
    width: 150px;
    text-decoration: none;
    pointer-events: auto;
    cursor: pointer;

    /* Gentle float */
    animation: cloudDrift 8s ease-in-out infinite;
    transition: opacity 0.3s ease;
}

/* The cloud itself is a low-poly prop drawn by the stage into this box */
.cloud-link .prop-stage {
    --stage-w: 172px;
    --stage-h: 84px;
}

/* Stagger the clouds */
.cloud-link:nth-child(1) {
    animation-duration: 7s;
    animation-delay: 0s;
    margin-top: 0.3rem;
}

.cloud-link:nth-child(2) {
    animation-duration: 9s;
    animation-delay: -3s;
    margin-top: 0;
}

.cloud-link:nth-child(3) {
    animation-duration: 6.5s;
    animation-delay: -5s;
    margin-top: 0.6rem;
}

.cloud-link:focus-visible {
    outline: 2px solid rgba(255, 244, 226, 0.7);
    outline-offset: 8px;
    border-radius: 30px;
}

/* Waypoint label: the site's instrument voice printed on the puffs — a
   dotted underline at rest (the universal link cue) and a chevron that
   surfaces on hover. It rides the puffs as they bob, rise and swell: the
   prop stage hands the link the cloud's lift (px) and swell every frame. */
.cloud-text {
    position: absolute;
    left: 50%;
    top: 54%;
    transform: translate(-50%, calc(-50% - var(--prop-lift, 0px))) scale(var(--prop-swell, 1));
    font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
    font-size: 0.74rem;
    font-weight: 600;
    color: rgba(72, 52, 86, 0.92);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    white-space: nowrap;
    z-index: 1;
    padding-bottom: 2px;
    border-bottom: 1px dotted rgba(90, 66, 102, 0.55);
    transition: border-color 0.3s ease;
    text-shadow:
        0 0 8px rgba(255, 244, 230, 0.95),
        0 0 16px rgba(255, 236, 218, 0.6);
}

.cloud-text::after {
    content: '›';
    display: inline-block;
    margin-left: 0.4em;
    opacity: 0;
    transform: translateX(-4px);
    transition: opacity 0.3s ease, transform 0.3s ease;
}

.cloud-link:hover .cloud-text,
.cloud-link:focus-visible .cloud-text {
    border-bottom-style: solid;
    border-bottom-color: rgba(90, 66, 102, 0.85);
}

.cloud-link:hover .cloud-text::after,
.cloud-link:focus-visible .cloud-text::after {
    opacity: 1;
    transform: translateX(0);
}

.cloud-link:focus-visible {
    outline: 2px solid var(--hud-gold, #ffd36a);
    outline-offset: 6px;
}

@keyframes cloudDrift {
    0%, 100% {
        transform: translateY(0) translateX(0);
    }
    20% {
        transform: translateY(-3px) translateX(5px);
    }
    40% {
        transform: translateY(-5px) translateX(-3px);
    }
    60% {
        transform: translateY(-1px) translateX(4px);
    }
    80% {
        transform: translateY(-4px) translateX(-2px);
    }
}

/* A reload or Back that lands mid-dive: the page sets its scroll state in
   its first frame (html.dive-opening, cleared two frames later), and these
   pieces take that state at once instead of fading over from the surface */
html.dive-opening .cloud-nav,
html.dive-opening #tsunami-trigger-button,
html.dive-opening .depth-background,
html.dive-opening .depth-indicator,
html.dive-opening .depth-fill,
html.dive-opening .specimen-jar {
    transition: none !important;
}

/* ...and until the 3D water has drawn, the backdrop is that water's own
   colour at the restored depth (not the sunset at the top of its gradient) */
html.opening-deep body .depth-background {
    background: var(--opening-water);
}

/* Clouds drift upward and fade immediately when scrolling down past 25px.
   body.camera-underwater is stamped by the 3D scene at the exact breach
   crossing, so on a slow ascent the clouds stay hidden until the eyes are
   genuinely above the water — sky UI only exists above the surface. */
body.scrolled-past-clouds .cloud-nav,
body.is-underwater .cloud-nav,
body.camera-underwater .cloud-nav {
    opacity: 0;
    transform: translateY(-120px);
    pointer-events: none;
}

/* Responsive */
@media (max-width: 640px) {
    .cloud-nav {
        gap: 1rem;
        padding-top: 1.5rem;
    }

    .cloud-link {
        width: 110px;
    }

    .cloud-link .prop-stage {
        --stage-w: 110px;
        --stage-h: 58px;
    }

    .cloud-text {
        font-size: 0.64rem;
        letter-spacing: 0.1em;
    }
}

/* The narrowest phones: three phone-size clouds and their gaps are wider
   than the screen, so the row ran past both edges (and the last label off
   the right); the clouds slim down and close up, the words stay their size */
@media (max-width: 360px) {
    .cloud-nav {
        gap: 0.35rem;
        padding-left: 0.5rem;
        padding-right: 0.5rem;
    }

    .cloud-link {
        width: 96px;
    }

    .cloud-link .prop-stage {
        --stage-w: 96px;
        --stage-h: 51px;
    }
}

/* A phone on its side: the screen is wide but short, so the clouds take
   their phone size and leave the sky to the portrait */
@media (max-height: 540px) and (orientation: landscape) {
    .cloud-nav {
        gap: 1rem;
        padding-top: 1.1rem;
    }

    .cloud-link {
        width: 110px;
    }

    .cloud-link .prop-stage {
        --stage-w: 110px;
        --stage-h: 58px;
    }

    .cloud-text {
        font-size: 0.64rem;
        letter-spacing: 0.1em;
    }
}

/* ===== Ocean Sections ===== */
.ocean-section {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 4rem 1.5rem;
    position: relative;
    z-index: 1;
}

/* The hero is exactly one screen (the site has no global border-box, so
   the section's own padding must not add to its 100vh) — the Dive In
   anchor then sits inside the fold */
.ocean-section.hero-section {
    box-sizing: border-box;
    min-height: 100vh;
    padding-top: 0;
    padding-bottom: 0;
}

.ocean-section.bubble-nav-section {
    min-height: 60vh;
    padding: 2rem 1.5rem;
}

/* ===== Content cards =====
   The sea-glass slabs are retired: the contact card is a signpost prop
   (css/n64-props.css) and nothing else on the dive sits in a box. */

/* ===== Hero Section ===== */
.hero-content {
    text-align: center;
    padding: 2rem;
    animation: fadeInUp 1s ease-out;
}

/* ===== Hero Avatar: a swimmer at the surface =====
   The portrait sits on the horizon line like someone treading water:
   it rides a slow swell, a sea-glass rim catches the light from above
   (brightest on top, fading down the sides), and a faint caustic
   shimmer plays across the photo. */
.hero-avatar-wrap {
    position: relative;
    display: inline-block;
    width: 150px;
    height: 150px;
    margin-bottom: 1.5rem;
    border-radius: 50%;
    animation: avatarBob 7s ease-in-out infinite;
    /* Ring of surface light pooled beneath the swimmer */
    filter: drop-shadow(0 18px 22px rgba(2, 20, 48, 0.35));
}

.hero-avatar {
    display: block;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    object-fit: cover;
    object-position: var(--avatar-focus, 50% 42%);
    border: 3px solid transparent;
    /* Sea-glass rim: transparent border filled by a gradient painted on the
       border-box, so the light reads as coming from the surface */
    background:
        linear-gradient(180deg,
            rgba(232, 246, 255, 0.92),
            rgba(159, 212, 255, 0.55) 38%,
            rgba(159, 212, 255, 0.18) 72%,
            rgba(120, 190, 240, 0.3)) border-box;
    box-shadow:
        0 8px 32px rgba(0, 0, 0, 0.3),
        0 0 0 1px rgba(255, 255, 255, 0.12),
        inset 0 -14px 24px rgba(4, 30, 70, 0.28);
}

/* Caustic shimmer: two soft light patches that drift across the photo,
   the way sunlight nets across a pool. Blended, never opaque. */
.hero-avatar-wrap::before {
    content: '';
    position: absolute;
    inset: 3px;
    border-radius: 50%;
    pointer-events: none;
    background:
        radial-gradient(38% 30% at 30% 22%, rgba(255, 255, 255, 0.5), transparent 70%),
        radial-gradient(30% 24% at 72% 70%, rgba(190, 235, 255, 0.35), transparent 70%);
    mix-blend-mode: soft-light;
    opacity: 0.9;
    animation: avatarCaustics 9s ease-in-out infinite;
}

@keyframes avatarBob {
    0%, 100% { transform: translateY(0) rotate(0deg); }
    50% { transform: translateY(-6px) rotate(-1.2deg); }
}

/* once the surface is left behind, the swimmer and its light hold still
   (the shimmer animates a background, which would repaint every frame) */
body.scrolled-past-clouds .hero-avatar-wrap,
body.scrolled-past-clouds .hero-avatar-wrap::before {
    animation-play-state: paused;
}

@keyframes avatarCaustics {
    0%, 100% { background-position: 0 0, 0 0; opacity: 0.75; }
    50% { background-position: 14px 8px, -12px -10px; opacity: 1; }
}


.hero-name {
    font-size: 3.6rem;
    margin-bottom: 0.6rem;
}

.hero-title {
    font-size: 1.4rem;
    font-weight: 200;
    color: rgba(255, 255, 255, 0.8);
    letter-spacing: 1px;
    margin-bottom: 2rem;
}

.hero-title.hud-sub {
    font-size: 0.95rem;
    letter-spacing: 0.22em;
    /* on a narrow screen it crosses the sun's path on the water */
    text-shadow: 1px 1px 0 rgba(6, 18, 32, 0.9), 0 0 10px rgba(3, 12, 22, 0.8);
}

.scroll-indicator {
    position: absolute;
    bottom: 1.2rem;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.1rem;
    color: rgba(255, 255, 255, 0.7);
    font-size: 0.9rem;
    animation: bounce 2s infinite;
    cursor: pointer;
}

.scroll-indicator .hud-label {
    font-size: 0.95rem;
}

.scroll-indicator .prop-stage--anchor {
    --stage-w: 96px;
    --stage-h: 112px;
}

/* A phone on its side: the clouds keep a band at the top and Dive In one
   at the bottom; the portrait and the name shrink to fit between them, and
   if they still can't, the surface grows taller rather than let anything
   lie on top of anything else */
@media (max-height: 540px) and (orientation: landscape) {
    .ocean-section.hero-section {
        padding-top: 92px;
        padding-bottom: 92px;
    }

    .hero-section .hero-content {
        padding: 0.4rem 1rem;
    }

    .hero-section .hero-avatar-wrap {
        display: block;
        width: 72px;
        height: 72px;
        margin: 0 auto 0.5rem;
    }

    .hero-section .hero-name {
        font-size: 2rem;
        margin-top: 0;
        margin-bottom: 0.3rem;
    }

    .hero-section .hero-title.hud-sub {
        margin-bottom: 0;
    }

    .hero-section .scroll-indicator {
        bottom: 0.5rem;
    }

    .hero-section .scroll-indicator .prop-stage--anchor {
        --stage-w: 60px;
        --stage-h: 64px;
    }
}

@media (max-height: 360px) and (orientation: landscape) {
    /* the shortest screens: the clouds ride higher, so the middle one keeps
       clear of the portrait when the hero's words fill its band (Past's
       quote is taller than Home's subtitle) */
    .cloud-nav {
        padding-top: 0.45rem;
    }

    .hero-section .hero-avatar-wrap {
        width: 56px;
        height: 56px;
    }

    .hero-section .hero-name {
        font-size: 1.7rem;
    }
}

/* A short landscape screen with room for the full-size clouds (a tablet on
   its side, a short laptop window): the same two bands, sized for them */
@media (min-height: 541px) and (max-height: 700px) and (orientation: landscape) {
    .ocean-section.hero-section {
        padding-top: 118px;
        padding-bottom: 150px;
    }

    .hero-section .hero-content {
        padding: 0.5rem 1rem;
    }

    .hero-section .hero-avatar-wrap {
        display: block;
        width: 112px;
        height: 112px;
        margin: 0 auto 1rem;
    }

    .hero-section .hero-name {
        font-size: 3rem;
        margin-top: 0;
    }

    .hero-section .hero-title.hud-sub {
        margin-bottom: 0.5rem;
    }
}

/* A small phone held upright: the portrait and the words keep clear of Dive
   In at the foot of the surface */
@media (max-width: 480px) and (max-height: 700px) and (orientation: portrait) {
    .ocean-section.hero-section {
        padding-top: 96px;
        padding-bottom: 148px;
    }

    .hero-section .hero-content {
        padding: 0.5rem 0.5rem;
    }

    .hero-section .hero-avatar-wrap {
        display: block;
        width: 96px;
        height: 96px;
        margin: 0 auto 0.9rem;
    }

    .hero-section .hero-name {
        margin-top: 0;
    }
}

@keyframes bounce {

    0%,
    20%,
    50%,
    80%,
    100% {
        transform: translateX(-50%) translateY(0);
    }

    40% {
        transform: translateX(-50%) translateY(-10px);
    }

    60% {
        transform: translateX(-50%) translateY(-5px);
    }
}

@keyframes fadeInUp {
    from {
        opacity: 0;
        transform: translateY(30px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* ===== Underwater Transition Section ===== */
.underwater-transition {
    min-height: 200vh;
    display: flex;
    align-items: center;
    justify-content: center;
}

.transition-indicator {
    color: rgba(255, 255, 255, 0.4);
    font-size: 1rem;
    letter-spacing: 3px;
    text-transform: uppercase;
    animation: pulse 2s ease-in-out infinite;
    display: flex;
    align-items: center;
}

/* Animated prefix container: as wide as the prefix showing (it stays in
   the flow and sets the width; the other slides away out of it), so either
   one meets "scending" with the same spacing as the letters within it */
.direction-prefix {
    position: relative;
    display: inline-block;
    overflow: hidden;
    height: 1.2em;
    vertical-align: bottom;
}

.prefix-de,
.prefix-a {
    position: absolute;
    left: 0;
    top: 0;
    letter-spacing: 3px;
    /* Match parent letter-spacing */
    transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1),
        opacity 0.3s ease;
}

/* Default state: Descending (De visible, A hidden) */
.prefix-de {
    position: relative;
    transform: translateY(0);
    opacity: 1;
}

.prefix-a {
    transform: translateY(-100%);
    opacity: 0;
}

/* Ascending state: A visible, De hidden */
.transition-indicator.ascending .prefix-de {
    position: absolute;
    transform: translateY(100%);
    opacity: 0;
}

.transition-indicator.ascending .prefix-a {
    position: relative;
    transform: translateY(0);
    opacity: 1;
}

@keyframes pulse {

    0%,
    100% {
        opacity: 0.3;
    }

    50% {
        opacity: 0.7;
    }
}

/* ===== Sequential Bubble Sections ===== */
.bubble-section {
    min-height: 120vh;
    display: flex;
    align-items: center;
    justify-content: flex-start;
    /* Allow positioning */
    padding: 2rem;
    position: relative;
    width: 100%;
}

/* Float wrapper: the drift animation lives here so hover/focus transforms
   on the bubble itself still apply (a running transform animation on the
   same element would override them). JS randomizes margin-left. */
.bubble-float {
    margin-left: min(30%, calc(100% - 190px));
    width: fit-content;
    animation: bubbleFloat 6s ease-in-out infinite;
}

/* Journey stop: a collectible on a float. The 3D object is drawn by the
   stage into .prop-stage; the word beneath is the HUD voice. */
.bubble-section .dive-prop .prop-stage {
    --stage-w: 220px;
    --stage-h: 220px;
}

.bubble-section .dive-prop .hud-label {
    font-size: 1.45rem;
    margin-top: -0.6rem;
}

@keyframes bubbleFloat {

    0%,
    100% {
        transform: translateY(18px) translateX(0);
    }

    25% {
        transform: translateY(4px) translateX(8px);
    }

    50% {
        transform: translateY(-14px) translateX(-5px);
    }

    75% {
        transform: translateY(2px) translateX(6px);
    }
}

/* ===== Ambient Rising Bubbles ===== */
.ambient-bubbles {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    z-index: 0;
    overflow: hidden;
    transition: opacity 0.4s ease;
}

.ambient-bubble {
    position: absolute;
    bottom: -50px;
    background: radial-gradient(circle at 42% 36%,
            rgba(255, 255, 255, 0.5) 0%,
            rgba(255, 255, 255, 0.06) 22%,
            rgba(3, 24, 54, 0.05) 55%,
            rgba(150, 210, 255, 0.38) 86%,
            transparent 100%);
    border: 1px solid rgba(190, 230, 255, 0.26);
    border-radius: 50%;
    animation: riseSway linear infinite;
    opacity: 0;
}

.ambient-bubble::before {
    content: '';
    position: absolute;
    top: 18%;
    left: 26%;
    width: 22%;
    height: 13%;
    background: rgba(255, 255, 255, 0.55);
    border-radius: 50%;
    filter: blur(0.5px);
}

/* Rising bubbles zigzag — --sway is randomized per bubble by JS */
@keyframes riseSway {
    0% {
        transform: translateY(0) translateX(0);
        opacity: 0;
    }

    8% {
        opacity: 0.8;
    }

    30% {
        transform: translateY(-33vh) translateX(var(--sway, 12px));
    }

    55% {
        transform: translateY(-60vh) translateX(calc(var(--sway, 12px) * -0.6));
    }

    80% {
        transform: translateY(-88vh) translateX(var(--sway, 12px));
        opacity: 0.75;
    }

    100% {
        transform: translateY(-112vh) translateX(calc(var(--sway, 12px) * -0.3));
        opacity: 0;
    }
}

/* ===== God Rays (sunlight shafts in the shallows) ===== */
.god-rays {
    position: fixed;
    inset: -12% -6%;
    pointer-events: none;
    z-index: 0;
    background:
        linear-gradient(104deg, transparent 40%, rgba(150, 215, 255, 0.14) 46%, transparent 52%),
        linear-gradient(86deg, transparent 58%, rgba(150, 215, 255, 0.1) 63%, transparent 69%),
        linear-gradient(96deg, transparent 16%, rgba(150, 215, 255, 0.08) 22%, transparent 30%);
    mix-blend-mode: screen;
    transform-origin: top center;
    animation: raySway 13s ease-in-out infinite alternate;
    opacity: 0;
    transition: opacity 1.2s ease;
}

@keyframes raySway {
    from {
        transform: rotate(-2.2deg) translateX(-8px);
    }

    to {
        transform: rotate(2.4deg) translateX(10px);
    }
}

/* ===== Marine Snow (suspended particulate drifting down) ===== */
.marine-snow {
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 0;
    overflow: hidden;
    opacity: 0;
    transition: opacity 0.8s ease;
}

.snow-fleck {
    position: absolute;
    top: -10px;
    background: rgba(205, 232, 255, 0.5);
    border-radius: 50%;
    filter: blur(0.6px);
    animation: snowFall linear forwards;
}

@keyframes snowFall {
    0% {
        transform: translateY(0) translateX(0);
    }

    100% {
        transform: translateY(108vh) translateX(var(--drift, 30px));
    }
}

/* ===== Foam Burst (crossing the surface) ===== */
.foam-burst {
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 60;
    overflow: hidden;
}

.foam-flash {
    position: absolute;
    inset: 0;
    background: radial-gradient(ellipse at 50% 65%, rgba(220, 242, 255, 0.3), transparent 70%);
    animation: foamFlash 0.9s ease-out forwards;
}

@keyframes foamFlash {
    from {
        opacity: 1;
    }

    to {
        opacity: 0;
    }
}

.foam-fleck {
    position: absolute;
    bottom: -20px;
    background: radial-gradient(circle at 40% 35%,
            rgba(255, 255, 255, 0.9) 0%,
            rgba(220, 240, 255, 0.35) 60%,
            transparent 100%);
    border-radius: 50%;
    animation: foamRush ease-out forwards;
    opacity: 0;
}

@keyframes foamRush {
    0% {
        transform: translateY(0) scale(0.6);
        opacity: 0.95;
    }

    100% {
        transform: translateY(-108vh) scale(1.15);
        opacity: 0;
    }
}

/* On a touch screen the drifting particles go without their soft blur:
   every blurred, moving speck is its own filtered layer to composite */
@media (hover: none) and (pointer: coarse) {

    .snow-fleck,
    .ambient-bubble::before {
        filter: none;
    }
}

/* Groups effects inside .foam-burst so overlapping bursts clean up independently.
   (Surfacing jostles the 3D mesh itself — see the breach disturbance in
   wave-background.js — so only the submerge foam lives in the DOM.) */
.breach-group {
    position: absolute;
    inset: 0;
}

/* ===== Current Surge (Make Waves pushes the particles sideways) ===== */
body.current-surge .ambient-bubbles,
body.current-surge .marine-snow {
    animation: currentSurge 6s ease-in-out;
}

@keyframes currentSurge {

    0%,
    100% {
        transform: translateX(0);
    }

    30% {
        transform: translateX(46px);
    }

    70% {
        transform: translateX(-28px);
    }
}

/* ===== Depth Indicator ===== */
.depth-indicator {
    position: fixed;
    right: 1.5rem;
    top: 50%;
    transform: translateY(-50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    z-index: 100;
    padding: 0.9rem 0.5rem;
    background: rgba(3, 12, 24, 0.82);
    border: 2px solid rgba(216, 181, 106, 0.55);
    outline: 1px solid rgba(216, 181, 106, 0.22);
    outline-offset: 3px;
    border-radius: 0;
    /* Hide initially, show when scrolling */
    opacity: 0;
    transition: opacity 0.4s ease;
}

/* Show depth meter when user has scrolled */
body.has-scrolled .depth-indicator {
    opacity: 1;
}

/* Dive-gauge track with tick marks every 10 m */
.depth-meter {
    width: 4px;
    height: 150px;
    background: repeating-linear-gradient(to bottom,
            rgba(255, 255, 255, 0.45) 0 1px,
            rgba(255, 255, 255, 0.12) 1px 15px);
    border-radius: 0;
    position: relative;
    margin: 0.5rem 0;
}

.depth-fill {
    position: absolute;
    bottom: 0;
    width: 100%;
    background: linear-gradient(to top, var(--shallow-water), var(--deep-water));
    border-radius: 0;
    transition: height 0.3s ease;
}

.depth-label {
    font-family: var(--hud-font, 'Lilita One', sans-serif);
    font-size: 0.7rem;
    color: rgba(255, 244, 216, 0.85);
    text-shadow: 1px 1px 0 rgba(6, 18, 32, 0.9);
    text-transform: uppercase;
    letter-spacing: 1px;
    writing-mode: vertical-rl;
    text-orientation: mixed;
    transform: rotate(180deg);
}

/* Live meters readout under the gauge */
.depth-reading {
    font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
    font-size: 0.68rem;
    letter-spacing: 0.06em;
    color: rgba(190, 225, 255, 0.85);
    font-variant-numeric: tabular-nums;
    margin-top: 0.35rem;
}

/* ===== Timeline Styles ===== */
.timeline {
    position: relative;
    margin: 2rem 0;
    padding: 1rem 0;
}

/* The timeline thread is a string of bioluminescent plankton */
.timeline::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 3px;
    background: radial-gradient(circle, rgba(125, 240, 212, 0.55) 0 1px, transparent 1.7px);
    background-size: 3px 14px;
    background-repeat: repeat-y;
    filter: drop-shadow(0 0 3px rgba(125, 240, 212, 0.45));
}

.timeline-item {
    position: relative;
    padding-left: 2rem;
    margin-bottom: 2rem;
}

.timeline-item::before {
    content: '';
    position: absolute;
    left: -6px;
    top: 0.5rem;
    width: 15px;
    height: 15px;
    background: #7df0d4;
    border: 3px solid var(--card-bg);
    border-radius: 52% 48% 50% 50% / 48% 54% 46% 52%;
    box-shadow: 0 0 10px rgba(125, 240, 212, 0.6);
}

.timeline-date {
    font-size: 0.85rem;
    color: var(--shallow-water);
    margin-bottom: 0.25rem;
    font-weight: 500;
}

.timeline-title {
    font-size: 1.2rem;
    font-weight: 600;
    color: #fff;
    margin-bottom: 0.5rem;
}

.timeline-text {
    color: #a0b5c5;
    line-height: 1.6;
}

/* ===== Project Cards ===== */
.projects-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 1.5rem;
    margin-top: 1.5rem;
}

.project-card {
    background: rgba(20, 40, 60, 0.8);
    border: 1px solid rgba(0, 170, 255, 0.2);
    border-radius: 1rem;
    overflow: hidden;
    transition: transform 0.3s ease, box-shadow 0.3s ease;
    text-decoration: none;
    display: block;
}

.project-card:hover {
    transform: translateY(-8px);
    box-shadow: 0 12px 40px rgba(0, 170, 255, 0.2);
}

.project-card img {
    width: 100%;
    height: 180px;
    object-fit: cover;
    border-bottom: 1px solid rgba(0, 170, 255, 0.2);
}

.project-card-content {
    padding: 1.25rem;
}

.project-card h4 {
    font-size: 1.15rem;
    font-weight: 600;
    color: #fff;
    margin-bottom: 0.5rem;
}

.project-card p {
    font-size: 0.9rem;
    color: #8aa8c0;
    line-height: 1.5;
}

/* ===== Resume Section ===== */
.resume-section {
    max-width: 800px;
}

.resume-header {
    text-align: center;
    margin-bottom: 2rem;
    padding-bottom: 1.5rem;
    border-bottom: 1px solid rgba(0, 170, 255, 0.2);
}

.resume-download-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    background:
        linear-gradient(140deg, #1789c9, #0a4d86) padding-box,
        linear-gradient(180deg, rgba(190, 230, 255, 0.7), rgba(190, 230, 255, 0.12) 55%, transparent) border-box;
    border: 1px solid transparent;
    color: #fff;
    padding: 0.75rem 1.5rem;
    border-radius: 48% 52% 44% 56% / 58% 44% 60% 42%;
    text-decoration: none;
    font-weight: 500;
    transition: transform 0.3s ease, box-shadow 0.3s ease;
    margin-top: 1rem;
}

.resume-download-btn:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 24px rgba(0, 170, 255, 0.3);
}

.resume-content {
    display: grid;
    gap: 2rem;
}

.resume-block h3 {
    font-size: 1.3rem;
    color: var(--shallow-water);
    margin-bottom: 1rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.resume-item {
    margin-bottom: 1.5rem;
    padding-left: 1rem;
    border-left: 2px solid rgba(0, 170, 255, 0.3);
}

.resume-item-header {
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    margin-bottom: 0.5rem;
}

.resume-item h4 {
    font-size: 1.1rem;
    font-weight: 600;
    color: #fff;
}

.resume-item .date {
    font-size: 0.9rem;
    color: var(--shallow-water);
}

.resume-item .company {
    font-size: 1rem;
    color: #8aa8c0;
    margin-bottom: 0.5rem;
}

.resume-item ul {
    list-style: none;
    padding: 0;
}

.resume-item li {
    color: #a0b5c5;
    font-size: 0.95rem;
    line-height: 1.6;
    padding-left: 1.25rem;
    position: relative;
    margin-bottom: 0.25rem;
}

.resume-item li::before {
    content: '▸';
    position: absolute;
    left: 0;
    color: var(--shallow-water);
}

.skills-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

/* Skill tags are small pebbles, each worn a little differently */
.skill-tag {
    color: #9fd4ff;
    padding: 0.4rem 0.85rem;
    font-size: 0.85rem;
    border: 1px solid transparent;
    background:
        linear-gradient(170deg, rgba(70, 150, 220, 0.13), rgba(20, 70, 130, 0.17)) padding-box,
        linear-gradient(180deg,
            rgba(159, 212, 255, 0.4),
            rgba(159, 212, 255, 0.07) 60%,
            transparent) border-box;
    border-radius: 54% 46% 50% 50% / 46% 56% 44% 54%;
}

.skills-grid .skill-tag:nth-child(3n+2) {
    border-radius: 45% 55% 49% 51% / 57% 43% 57% 43%;
}

.skills-grid .skill-tag:nth-child(3n) {
    border-radius: 51% 49% 55% 45% / 45% 53% 47% 55%;
}

/* ===== Footer ===== */
.ocean-footer {
    text-align: center;
    padding: 2rem;
    color: rgba(255, 255, 255, 0.5);
    font-size: 0.85rem;
}

/* ===== Responsive Design ===== */
@media (max-width: 768px) {
    .hero-name {
        font-size: 2.5rem;
    }

    .hero-title {
        font-size: 1.1rem;
    }

    .bubble-nav-container {
        gap: 1.5rem;
    }

    .depth-indicator {
        right: 0.5rem;
        padding: 0.5rem 0.3rem;
    }

    .depth-meter {
        height: 100px;
    }

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

    .resume-item-header {
        flex-direction: column;
    }
}

@media (max-width: 480px) {
    .ocean-section {
        padding: 2rem 1rem;
    }

    .hero-avatar-wrap {
        width: 100px;
        height: 100px;
    }
}

/* ===== Lazy Loading Image Placeholder ===== */
img[loading="lazy"] {
    opacity: 0;
    transition: opacity 0.5s ease;
}

img[loading="lazy"].loaded {
    opacity: 1;
}

img.lazy-placeholder {
    background: linear-gradient(90deg, rgba(30, 50, 70, 0.5) 25%, rgba(40, 60, 80, 0.5) 50%, rgba(30, 50, 70, 0.5) 75%);
    background-size: 200% 100%;
    animation: shimmer 1.5s infinite;
}

@keyframes shimmer {
    0% {
        background-position: 200% 0;
    }

    100% {
        background-position: -200% 0;
    }
}

/* ===== Deep Abyss Section (Easter Eggs) ===== */
.deep-abyss {
    position: relative;
    overflow: hidden;
}

/* Bioluminescent Plankton Container */
.bioluminescent-container {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    z-index: 0;
}

.plankton {
    position: absolute;
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: radial-gradient(circle,
            rgba(0, 255, 200, 1) 0%,
            rgba(0, 255, 180, 0.8) 30%,
            rgba(0, 200, 255, 0.4) 60%,
            transparent 100%);
    box-shadow:
        0 0 8px rgba(0, 255, 200, 0.8),
        0 0 15px rgba(0, 255, 180, 0.5),
        0 0 25px rgba(0, 200, 255, 0.3);
    animation: planktonGlow 4s ease-in-out infinite, planktonDrift 12s linear infinite;
    opacity: 0;
}

/* Randomize plankton positions */
.plankton:nth-child(1) {
    left: 10%;
    top: 20%;
    animation-delay: 0s, 0s;
}

.plankton:nth-child(2) {
    left: 25%;
    top: 60%;
    animation-delay: 0.5s, 1s;
}

.plankton:nth-child(3) {
    left: 45%;
    top: 35%;
    animation-delay: 1s, 2s;
}

.plankton:nth-child(4) {
    left: 65%;
    top: 70%;
    animation-delay: 1.5s, 0.5s;
}

.plankton:nth-child(5) {
    left: 80%;
    top: 25%;
    animation-delay: 2s, 3s;
}

.plankton:nth-child(6) {
    left: 15%;
    top: 80%;
    animation-delay: 2.5s, 1.5s;
}

.plankton:nth-child(7) {
    left: 55%;
    top: 15%;
    animation-delay: 3s, 2.5s;
}

.plankton:nth-child(8) {
    left: 90%;
    top: 50%;
    animation-delay: 3.5s, 0.8s;
}

@keyframes planktonGlow {

    0%,
    100% {
        opacity: 0.2;
        transform: scale(0.8);
    }

    50% {
        opacity: 1;
        transform: scale(1.5);
    }
}

@keyframes planktonDrift {
    0% {
        transform: translateY(0) translateX(0);
    }

    25% {
        transform: translateY(-20px) translateX(15px);
    }

    50% {
        transform: translateY(-10px) translateX(-10px);
    }

    75% {
        transform: translateY(-30px) translateX(20px);
    }

    100% {
        transform: translateY(0) translateX(0);
    }
}

/* Giant Squid Easter Egg */
.giant-squid {
    position: absolute;
    bottom: 10%;
    right: -200px;
    width: 300px;
    height: 150px;
    background: linear-gradient(90deg,
            transparent 0%,
            rgba(30, 20, 40, 0.3) 20%,
            rgba(40, 30, 50, 0.4) 40%,
            rgba(50, 40, 60, 0.3) 60%,
            transparent 100%);
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 300 150'%3E%3Cpath d='M50,75 Q80,40 120,50 Q160,30 200,60 Q240,40 280,75 Q250,90 220,85 Q180,110 140,95 Q100,120 60,90 Q40,95 50,75' fill='black'/%3E%3Cellipse cx='230' cy='65' rx='15' ry='20' fill='black'/%3E%3Cpath d='M40,80 Q20,100 5,130 M60,90 Q45,115 35,140 M80,95 Q70,120 65,145' stroke='black' stroke-width='8' fill='none'/%3E%3C/svg%3E");
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 300 150'%3E%3Cpath d='M50,75 Q80,40 120,50 Q160,30 200,60 Q240,40 280,75 Q250,90 220,85 Q180,110 140,95 Q100,120 60,90 Q40,95 50,75' fill='black'/%3E%3Cellipse cx='230' cy='65' rx='15' ry='20' fill='black'/%3E%3Cpath d='M40,80 Q20,100 5,130 M60,90 Q45,115 35,140 M80,95 Q70,120 65,145' stroke='black' stroke-width='8' fill='none'/%3E%3C/svg%3E");
    mask-size: contain;
    -webkit-mask-size: contain;
    mask-repeat: no-repeat;
    -webkit-mask-repeat: no-repeat;
    opacity: 0;
    animation: squidSwim 30s ease-in-out infinite;
    animation-delay: 5s;
    pointer-events: none;
    z-index: 0;
}

@keyframes squidSwim {
    0% {
        right: -200px;
        opacity: 0;
        transform: translateY(0);
    }

    10% {
        opacity: 0.6;
    }

    40% {
        transform: translateY(-30px);
    }

    60% {
        transform: translateY(20px);
    }

    90% {
        opacity: 0.6;
    }

    100% {
        right: 120%;
        opacity: 0;
        transform: translateY(0);
    }
}

/* ===== Scene-to-Scene Navigation Transitions ===== */
/* Departing via a cloud: fly into it. Departing via a bubble: zoom in until
   it pops. Arrivals come through mist (cloud) or an aqua wash (bubble). */

/* Whichever container holds the zooming element rises above the mist */
.nav-zooming-host {
    z-index: 260 !important;
    position: relative;
}

/* Cloud fly-in (js/nav-transitions.js): the class stops the clouds' drift
   so the flight's own motion can take over */
.cloud-link.nav-zooming {
    animation: none;
}

.cloud-link.nav-zooming .cloud-text {
    opacity: 0;
    transition: opacity 0.18s ease;
}

/* Full-screen mist / wash that closes over the departure */
.nav-mist {
    position: fixed;
    inset: 0;
    z-index: 240;
    pointer-events: none;
    opacity: 0;
}

.nav-mist.mist-cloud {
    /* inside the cloud: over everything, the cloud itself included */
    z-index: 275;
    background: radial-gradient(circle at var(--mx, 50%) var(--my, 15%),
            rgba(255, 252, 247, 1) 0%,
            rgba(255, 247, 238, 0.99) 45%,
            rgba(246, 241, 243, 0.98) 100%);
    transition: opacity 0.5s cubic-bezier(0.55, 0, 0.75, 0.45) 0.22s;
}

/* the cloud's puffs rushing past the camera as it flies through */
.cloud-wisp {
    position: fixed;
    z-index: 272;
    pointer-events: none;
    border-radius: 50%;
    background: radial-gradient(closest-side,
            rgba(255, 253, 248, 0.95) 0%,
            rgba(255, 249, 242, 0.72) 45%,
            rgba(255, 249, 242, 0) 100%);
    will-change: transform, opacity;
}

.nav-mist.mist-bubble {
    background: radial-gradient(circle at var(--mx, 50%) var(--my, 55%),
            rgba(200, 235, 245, 0.98) 0%,
            rgba(60, 140, 185, 0.97) 55%,
            rgba(10, 60, 105, 0.98) 100%);
    transition: opacity 0.4s ease-in 0.18s;
}

.nav-mist.show {
    opacity: 1;
}

/* Bubble pop: droplets thrown outward from the pop point */
.pop-fleck {
    position: fixed;
    left: var(--fx, 50%);
    top: var(--fy, 50%);
    width: 7px;
    height: 7px;
    border-radius: 50%;
    z-index: 261;
    pointer-events: none;
    background: radial-gradient(circle at 40% 35%,
            rgba(255, 255, 255, 0.95) 0%,
            rgba(190, 230, 255, 0.5) 65%,
            transparent 100%);
    animation: popFleck 0.4s ease-out forwards;
}

@keyframes popFleck {
    from {
        transform: translate(0, 0) scale(1);
        opacity: 0.95;
    }

    to {
        transform: translate(var(--pdx, 60px), var(--pdy, -60px)) scale(0.4);
        opacity: 0;
    }
}

/* Arrival: the new scene starts behind mist/wash that parts once loaded.
   The html classes are stamped by an inline head script before first paint. */
html.nav-arriving body::before {
    content: '';
    position: fixed;
    inset: 0;
    z-index: 240;
    pointer-events: none;
    opacity: 1;
    transition: opacity 0.75s ease-out;
}

html.nav-cloud body::before {
    background: radial-gradient(circle at 50% 42%,
            rgba(255, 252, 247, 1) 0%,
            rgba(255, 247, 238, 0.99) 45%,
            rgba(246, 241, 243, 0.98) 100%);
    transform-origin: 50% 42%;
    transition: opacity 0.85s ease-out, transform 0.95s cubic-bezier(0.25, 0.6, 0.35, 1);
}

/* ...and flying out of the cloud, its white opens out past you */
html.nav-cloud.nav-reveal body::before {
    transform: scale(1.4);
}

html.nav-bubble body::before {
    background: radial-gradient(circle at 50% 55%,
            rgba(200, 235, 245, 0.98) 0%,
            rgba(60, 140, 185, 0.97) 55%,
            rgba(10, 60, 105, 0.98) 100%);
}

/* Carried up out of the collapsing cave: the same bright water the bubbles
   closed over, parting as the camera breaks the surface */
html.nav-surface body::before {
    background: radial-gradient(ellipse 120% 90% at 50% 0%,
            rgba(214, 244, 246, 0.99) 0%,
            rgba(120, 196, 214, 0.98) 45%,
            rgba(26, 96, 130, 0.98) 100%);
    transition-duration: 0.9s;
}

html.nav-arriving.nav-reveal body::before {
    opacity: 0;
}

/* ===== Reduced Motion =====
   The ocean holds still: no drifting, wobbling, breathing, or particles.
   (The 3D scene and JS spawners check the same preference themselves.) */
@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }

    .bubble-float,
    .dive-prop,
    .cloud-link,
    .ambient-bubble,
    .god-rays,
    .snow-fleck,
    .foam-fleck,
    .foam-flash,
    .plankton,
    .giant-squid,
    .scroll-indicator,
    .transition-indicator,
    .depth-fill,
    .hero-content,
    .hero-avatar-wrap,
    .hero-avatar-wrap::before {
        animation: none !important;
    }

    body.current-surge .ambient-bubbles,
    body.current-surge .marine-snow {
        animation: none !important;
    }

    .cloud-link.nav-zooming,
    .nav-mist,
    html.nav-arriving body::before {
        transition: none !important;
    }

    .pop-fleck {
        animation: none !important;
        display: none;
    }
}