/* ============================================================
   CAROL MUNAR — PORTFOLIO
   style.css
   ============================================================ */


/* ============================================================
   FONTS — @font-face declarations
   ─────────────────────────────────
   @font-face tells the browser "here is a font file to load"
   before we can use it anywhere in the CSS.

   FONT STATUS:
   ✅ Williwaw-Book.otf — file is in /fonts/ folder, ACTIVE
   ⏳ Test Söhne Mono   — file NOT found in /fonts/ yet.
                          Using Space Mono as placeholder.
                          When you have the file, drop it in /fonts/
                          and uncomment the TestSohneMono block below.
   ============================================================ */

/* Williwaw — used for the greeting "Hola! I'm Carol Munar." */
@font-face {
    font-family: 'Williwaw';
    src: url('../fonts/Williwaw-Book.otf') format('opentype');
    font-weight: 400;
    font-style: normal;
    font-display: swap; /* Shows fallback font until Williwaw loads */
}

/*
   Test Söhne Mono — used for the h1 big statement
   Uncomment this block once you drop the font file into /fonts/
   The filename must match exactly!

@font-face {
    font-family: 'TestSohneMono';
    src: url('../fonts/TestSohneMono-Regular.otf') format('opentype');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}
*/


/* ============================================================
   1. DESIGN TOKENS (CSS Variables)
   ─────────────────────────────────
   Think of these as global settings.
   Change here → updates everywhere on the site.
   ============================================================ */
:root {
    --color-text: #1e1e1e;
    --color-bg:   #FFFFFF;
}

/* ── DARK MODE ──
   Activated by adding .dark-mode to <body> via the lamp click.
   Overrides the two root variables — every element that uses them
   (background, text, nav, footer…) switches automatically. */
body.dark-mode {
    --color-text: #e8e6e0;   /* warm off-white — easier on the eyes than pure white */
    --color-bg:   #111111;   /* very dark, not pure black — feels warmer */
}

/* Smooth transition when the lights switch */
body {
    transition: background-color 0.4s ease, color 0.4s ease;
}

/* Elements with hardcoded colors that need dark-mode overrides */
body.dark-mode .chiva-tooltip,
body.dark-mode .plantbig-tooltip {
    background: #222222;
    color: var(--color-text);
}

body.dark-mode .chiva-tooltip a,
body.dark-mode .plantbig-tooltip a,
body.dark-mode .plantbig-tooltip-links a {
    color: var(--color-text);
}

/* Preview hover images — no shadow in dark mode */
body.dark-mode .preview-set img {
    box-shadow: none;
}

/* CTA buttons — black bg/white text in light mode, flip to white bg/dark text in dark mode */
body.dark-mode .about-btn {
    background-color: #e8e6e0;
    border-color: #e8e6e0;
    color: #111111;
}

/* ── LOGO INVERSIONS ──
   These logos are black on transparent — invisible on dark backgrounds.
   filter: invert(1) flips every black pixel to white instantly.
   No need to upload separate dark versions. */

/* Footer social icons: LinkedIn, GitHub, Substack */
body.dark-mode .footer-logos img {
    filter: invert(1);
}

/* "Currently working" — Elternpop inline logo
   Two versions: dark logo for light mode, light logo for dark mode.
   Only one is visible at a time. */
#elternpop-logo-light { display: none; }

body.dark-mode #elternpop-logo-dark  { display: none; }
body.dark-mode #elternpop-logo-light { display: inline; }

/* Adjust case-logo box — background #010101 blends into dark page.
   A faint border keeps the box outline visible. */
body.dark-mode .case-logo[style*="#010101"] {
    outline: 1px solid rgba(255, 255, 255, 0.15);
}


/* ============================================================
   2. RESET & BASE
   ──────────────────
   Removes browser default margins/padding so we start from zero.
   ============================================================ */
*, *::before, *::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html { font-size: 16px; }

/* ── KEYBOARD FOCUS STYLES ──
   Only shows when navigating by keyboard, not on mouse click. */
a:focus-visible,
button:focus-visible {
    outline: 2px solid #1e1e1e;
    outline-offset: 3px;
    border-radius: 2px;
}

body {
    background-color: var(--color-bg);
    color: var(--color-text);
    overflow-x: hidden;
}

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


/* ============================================================
   3. HERO SECTION
   ──────────────────
   Full viewport. "position: relative" makes it the anchor
   for all the absolutely positioned objects inside.
   ============================================================ */
.hero {
    position: relative;
    width: 100vw;
    height: 100vh;
    overflow: hidden;
    background-color: var(--color-bg);
}


/* ============================================================
   4. HERO OBJECTS — shared styles
   ─────────────────────────────────
   All decorative items share these. Each also has its own
   position values via its #id below.
   ============================================================ */
.hero-object {
    position: absolute;
    /* Parallax offset — set each frame by the JS lerp loop via --px and --py */
    transform: translate(var(--px, 0px), var(--py, 0px));
}

.hero-object img {
    pointer-events: none;    /* Clicks pass through */
    user-select: none;
    -webkit-user-drag: none;
}


/* ============================================================
   5. INDIVIDUAL POSITIONS
   ─────────────────────────────────────────────────────────────
   ✅ All values taken directly from the Figma design file.
   Artboard size: 1440px wide × 1054px tall.

   How to read these:
   left: X%  →  X divided by 1440 (viewport width)
   top:  Y%  →  Y divided by 1054 (artboard height)
   width: Xvw → X divided by 1440 (scales with screen width)
   ============================================================ */

/* ── LAMP ── center, hangs from the top (partly off-screen) */
#lamp {
    left: 26.3%;    /* 379px ÷ 1440 */
    top: -16.1%;    /* -170px ÷ 1054 — negative pushes it above the screen */
    width: 12.2vw;  /* 176px ÷ 1440 */
    z-index: 2;
}

/* In dark mode, the lamp is the light source — warm glow */
body.dark-mode #lamp img {
    filter: drop-shadow(0 0 18px rgba(255, 200, 80, 0.55))
            drop-shadow(0 0 40px rgba(255, 160, 40, 0.25));
    transition: filter 0.4s ease;
}

/* ── LIGHT SWITCH ──
   Figma: x=518, y=403, width=36, height=54 (node switch-on / switch-off).
   left: 518/1440 = 36%. top kept at user-adjusted value.
   Two images stacked — only one visible at a time. */
#lightswitch {
    left: 36%;
    top: 46%;
    width: 2.5vw;     /* 36px ÷ 1440 from Figma */
    min-width: 32px;
    cursor: pointer;
    z-index: 3;
    line-height: 0;   /* removes the invisible gap below inline images */
}

/* Each image declared separately so display:none is never accidentally overridden */
#switch-on-img {
    display: block;   /* block = div height equals image height = full click area */
    width: 100%;
    height: auto;
    pointer-events: none;
}

#switch-off-img {
    display: none;    /* hidden by default in light mode */
    width: 100%;
    height: auto;
    pointer-events: none;
}

/* In dark mode: swap which image is visible */
body.dark-mode #switch-on-img  { display: none;  }
body.dark-mode #switch-off-img { display: block; }

/* ── REGAL (bookshelf) ──
   Figma node 243:1254 — x=73, y=243, width=341 in the 1440×1054 hero. */
#regal {
    left: 5.1%;     /* 73px ÷ 1440 */
    top: 18.1%;     /* 243px ÷ 1054, adjusted */
    width: 23.7vw;  /* 341px ÷ 1440px — exact Figma spec */
    z-index: 1;
}

/* ── VINE PLANT (plant.png) ──
   Sits inside the regal, cascading down from the top area. */
#plant {
    left: 8.6%;     /* 124px ÷ 1440 */
    top: 26.1%;
    width: 10.7vw;
    z-index: 2;
}

/* ── PULP FICTION ── upper area of the regal */
#pulpfiction {
    left: 19.2%;    /* 276px ÷ 1440 */
    top: 79.24%;    /* -1% up */
    width: 5.3vw;
    z-index: 2;
}

/* ── CAMERA ── middle shelf of the regal */
#camera {
    left: 19.3%;    /* 278px ÷ 1440 */
    top: 33.6%;
    width: 4.9vw;
    z-index: 2;
}

/* ── HOVER ANIMATIONS — Pulp Fiction & Camera ────────────────────────────
   WHY target the <img> inside, not the .hero-object div itself?
   → The JS parallax sets transform directly on .hero-object via style.transform.
     If we also set transform on the div via CSS :hover, they would conflict.
   → By targeting the inner <img>, the two transforms live on DIFFERENT elements
     and stack independently: outer div handles parallax, inner img handles hover.

   HOW the two transitions work:
   → The BASE state defines the LEAVE transition (ease-out = snaps back crisply).
   → The :HOVER state defines the ENTER transition (cubic-bezier = springy lift).
   → CSS always uses the transition defined on the STATE you are MOVING TO. */

/* Base state — defines how elements animate back on mouse leave */
[data-element="pulp-fiction"] img,
[data-element="camera"] img,
[data-element="chiva"] img {
    transition: transform 0.25s ease-out, filter 0.25s ease-out;
}

/* Show a pointer cursor on the interactive hero objects */
[data-element="pulp-fiction"],
[data-element="camera"],
[data-element="chiva"] {
    cursor: pointer;
}

/* Pulp Fiction: lift + rotate +3deg + scale — springy enter */
[data-element="pulp-fiction"]:hover img {
    transform: translateY(-12px) rotate(3deg) scale(1.05);
    filter: drop-shadow(0 20px 40px rgba(0,0,0,0.2));
    transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1),
                filter    0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* Camera: lift + rotate -3deg (mirrored) + scale — springy enter */
[data-element="camera"]:hover img {
    transform: translateY(-12px) rotate(-3deg) scale(1.05);
    filter: drop-shadow(0 20px 40px rgba(0,0,0,0.2));
    transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1),
                filter    0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* Chiva: same lift + scale, slight rotation to the right — springy enter */
[data-element="chiva"]:hover img {
    transform: translateY(-12px) rotate(3deg) scale(1.05);
    filter: drop-shadow(0 20px 40px rgba(0,0,0,0.2));
    transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1),
                filter    0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}


/* ── CHIVA ── colorful toy bus, lower-middle shelf of the regal */
#chiva {
    left: 16.0%;    /* 231px ÷ 1440 */
    top: 45.7%;     /* -2% up */
    width: 10.3vw;
    z-index: 2;
}

/* ── CHIVA HOVER TOOLTIP ─────────────────────────────────────────────────────
   The tooltip card is a child of #chiva, positioned ABOVE it with absolute CSS.

   WHY position: absolute?
   → #chiva is already "position: absolute" (from .hero-object).
   → Children of a positioned element are positioned relative to THAT element.
   → So bottom: calc(100% + 8px) means "8px above the top edge of #chiva".

   WHY pointer-events: none when hidden?
   → An invisible element can still block mouse clicks if pointer-events is on.
   → Setting pointer-events: none when hidden lets mouse events pass through it.
   → We re-enable it on hover so the user can move their mouse onto the tooltip
     without it disappearing (hovering a child = still hovering the parent div).

   The ::after pseudo-element creates an invisible "bridge" between the chiva
   and the tooltip. Without it, moving the mouse through the 8px gap would
   briefly leave the hover area → tooltip flickers. The bridge covers that gap.
*/

/* Tooltip card — hidden by default */
.chiva-tooltip {
    position: absolute;
    bottom: calc(100% + 8px);  /* floats 8px above the chiva image */
    left: -80px;                /* shifted 80px left of the chiva */
    width: 224px;               /* from Figma */

    /* Visual style from Figma */
    background: #e5e7eb;
    border-radius: 16px;
    padding: 16px;
    box-shadow: 0px 12px 50px 0px rgba(0,0,0,0.15);

    /* Typography from Figma */
    font-family: 'TestSohneMono', 'Space Mono', monospace;
    font-size: 16px;
    line-height: 1.18;
    color: #000000;

    /* Hidden state */
    opacity: 0;
    pointer-events: none;
    transform: translateY(6px);  /* starts 6px lower, floats up when shown */
    transition: opacity 0.2s ease, transform 0.2s ease;

    /* Stays in front of other hero objects */
    z-index: 10;
}

/* Small gap between the two text lines ("I'm from Colombia..." / "Based in Berlin") */
.chiva-tooltip p + p {
    margin-top: 6px;
}

/* Invisible bridge covering the 8px gap between tooltip and chiva image.
   This prevents the tooltip from flickering when the mouse crosses the gap. */
.chiva-tooltip::after {
    content: '';
    position: absolute;
    top: 100%;    /* starts at the bottom edge of the tooltip */
    left: 0;
    width: 100%;
    height: 16px; /* covers the 8px gap plus a small safety buffer */
}

/* Elevate the chiva's stacking context on hover so the tooltip
   renders IN FRONT of other hero objects (frame z:3, chair z:4).
   Without this, the tooltip would appear behind those elements. */
[data-element="chiva"]:hover {
    z-index: 10;
}

/* Visible state — triggered when hovering #chiva (the parent div) */
[data-element="chiva"]:hover .chiva-tooltip {
    opacity: 1;
    pointer-events: auto;   /* now the tooltip is interactive (hover-stable) */
    transform: translateY(0);
}


/* ── PLANTBIG HOVER TOOLTIP ──────────────────────────────────────────────────
   Same concept as the chiva tooltip but positioned to the LEFT of the plant.
   The plant lives on the right side of the hero, so the tooltip floats left.

   WHY right: calc(100% + 16px)?
   → The tooltip div is a child of #plantbig.
   → `right: 100%` means "start at the left edge of the parent".
   → The extra 16px adds a breathing gap between tooltip and plant image.

   The reveal animation slides the tooltip in from the right (translateX(8px) → 0)
   while fading in — same technique as the chiva tooltip's translateY. */

/* Pointer cursor — signals the plant is interactive */
[data-element="plantsmall"] {
    cursor: pointer;
}

/* Subtle brightness lift on hover — confirms the interaction is triggering */
[data-element="plantsmall"]:hover img {
    filter: brightness(1.08);
    transition: filter 0.2s ease;
}
[data-element="plantsmall"] img {
    transition: filter 0.2s ease;
}

/* Tooltip card — hidden by default */
.plantbig-tooltip {
    position: absolute;
    /* Place it immediately to the right of the plantsmall div */
    left: calc(100% + 12px);
    /* Align near the top of the plant */
    top: 20px;
    width: 200px;

    /* Same visual style as chiva-tooltip */
    background: #e5e7eb;
    border-radius: 16px;
    padding: 16px;
    box-shadow: 0px 12px 50px 0px rgba(0,0,0,0.15);

    /* Same typography as chiva-tooltip */
    font-family: 'TestSohneMono', 'Space Mono', monospace;
    font-size: 14px;
    line-height: 1.4;
    color: #000000;

    /* Hidden state — slides in from the right */
    opacity: 0;
    pointer-events: none;
    transform: translateX(8px);
    transition: opacity 0.2s ease, transform 0.2s ease;

    z-index: 999; /* above everything — hero objects, frame, chair, hero-text */
}

/* Gap between text lines */
.plantbig-tooltip p + p {
    margin-top: 6px;
}

/* Link group — stacked vertically, each on its own line */
.plantbig-tooltip-links {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-top: 12px;
    border-top: 1px solid rgba(0,0,0,0.12);
    padding-top: 10px;
}

/* Links — same font, underlined to show they're clickable */
.plantbig-tooltip-links a {
    font-family: 'TestSohneMono', 'Space Mono', monospace;
    font-size: 14px;
    line-height: 1.4;
    color: #000000;
    text-decoration: underline;
    text-underline-offset: 3px;
}

.plantbig-tooltip-links a:hover {
    opacity: 0.6;
}

/* No bridge needed — position:fixed tooltips aren't adjacent to their trigger element */

/* Elevate stacking context so tooltip renders above other hero objects including hero-text (z:10) */
[data-element="plantsmall"]:hover {
    z-index: 20;
}

/* Visible state — triggered by EITHER:
   1. CSS :hover on the plant div (most reliable, no JS needed)
   2. JS adding .is-visible class (handles the gap between plant and tooltip)
   3. Mouse hovering the tooltip card itself (keeps it open while reading) */
[data-element="plantsmall"]:hover .plantbig-tooltip,
.plantbig-tooltip.is-visible,
.plantbig-tooltip:hover {
    opacity: 1;
    pointer-events: auto;
    transform: translateX(0);
}


/* ── SUCCULENT ── lower shelf of the regal */
#plantsuculent {
    left: 19.3%;    /* 278px ÷ 1440 */
    top: 65.65%;    /* -2% up */
    width: 4.3vw;
    z-index: 2;
}

/* ── BOOK2 ── bottom shelf of the regal */
#book2 {
    left: 13.9%;    /* 200px ÷ 1440 */
    top: 81.9%;     /* -2% up */
    width: 3.8vw;
    z-index: 2;     /* behind #book */
}

/* ── BOOK ── bottom shelf, next to book2 */
#book {
    left: 14.3%;    /* 206px ÷ 1440 */
    top: 84.0%;     /* -2% up */
    width: 3.5vw;
    z-index: 3;     /* in front of #book2 */
}

/* ── FRAME ── center, the portrait/collage focal point */
#frame {
    left: 39.4%;    /* 568px ÷ 1440 */
    top: 7.7%;      /* moved 20px up from 101px → 80px ÷ 1054 */
    width: 21.1vw;  /* 304px ÷ 1440 */
    z-index: 3;
    overflow: hidden; /* clips the image when it scales up during Ken Burns */
}

/* ── KEN BURNS — portrait frame hover ──
   On hover, the image slowly zooms in and drifts slightly.
   "forwards" keeps the zoomed state when you stop mid-animation.
   The base transition on img resets it smoothly when you mouse out. */
@keyframes ken-burns {
    0%   { transform: scale(1)    translate(0,    0);   }
    100% { transform: scale(1.08) translate(-2%, -1%);  }
}

.portrait-frame:hover img {
    animation: ken-burns 4s ease-out forwards;
}

.portrait-frame img {
    transition: transform 0.5s ease; /* smooth return to scale(1) on mouse-out */
}

/* ── MONSTERA (plantbig) ── right side, tall */
#plantbig {
    left: 56.5%;    /* 813px ÷ 1440 */
    top: -0.8%;     /* -2% up */
    width: 21.6vw;  /* was 27vw — reduced 20% */
    z-index: 2;
}

/* ── PLANTSMALL (white ribbed planter pot) ──
   This is on the RIGHT SIDE of the hero, next to the chair.
   NOT on the regal shelf. */
#plantsmall {
    left: 67.22%;   /* was 69.3% — moved 30px left (30 ÷ 1440 = 2.08%) */
    top: 37.75%;    /* was 38.7% — moved 10px up */
    width: 13.3vw;  /* 192px ÷ 1440 */
    z-index: 3;
}

/* ── CHAIR ── center-left, lower area */
#chair {
    left: 25.2%;    /* 363px ÷ 1440 — corrected from Figma */
    top: 48.9%;     /* 515px ÷ 1054 */
    width: 32vw;    /* 461px ÷ 1440 */
    z-index: 4;
}


/* ============================================================
   6. HERO TEXT
   ─────────────
   Bottom-right area. z-index: 10 keeps it above all images.
   ============================================================ */
.hero-text {
    position: absolute;
    left: 57.6%;    /* 829px ÷ 1440 — corrected from Figma */
    top: 70.5%;     /* 743px ÷ 1054 — corrected from Figma */
    max-width: 28.5%; /* 411px ÷ 1440 — width of the text block */
    z-index: 10;
    /* ↑ z-index:10 = text appears IN FRONT of all the hero images.
       The highest z-index among the objects is chair at z-index:4,
       so z-index:10 guarantees the text is always visible on top. */
}

/* ── "Hola! I'm Carol Munar." ── TestSohneMono Leicht (light weight) */
/* Figma: Test Söhne Mono Leicht, 24px, #1e1e1e, line-height 1.5 */
.hero-text .greeting {
    font-family: 'TestSohneMono', 'Space Mono', monospace;
    font-size: clamp(1rem, 1.67vw, 1.5rem); /* 24px ÷ 1440 = 1.67vw */
    font-weight: 300; /* Leicht = light weight */
    color: var(--color-text);
    margin-bottom: 0.4rem;
    line-height: 1.5;
}

/* ── "I help startups and series A—D teams..." ── Test Söhne Mono (matches Figma) */
/* ⏳ Font file not in /fonts/ yet — Space Mono is the placeholder until you add it */
.hero-text h1 {
    font-family: 'TestSohneMono', 'Space Mono', monospace;
    font-size: clamp(1rem, 1.67vw, 1.5rem); /* 24px — same size as greeting per Figma */
    font-weight: 400;
    line-height: 1.4;
    color: var(--color-text);
    letter-spacing: -0.022em;
}


/* ============================================================
   7. SHARED SECTION STYLES
   ─────────────────────────────────────────────────────────────
   All three content sections (Currently Working, Recently
   Experiences, My Playground) share these base rules.

   padding-left: 13.9vw = 200px at 1440px viewport.
   This matches the consistent left margin in the Figma design.
   ============================================================ */

/* Section headings — "Currently working", "Recently experiences",
   "My Playground" — all use the same style as the hero h1 */
.section-title {
    font-family: 'TestSohneMono', 'Space Mono', monospace;
    font-size: clamp(1rem, 1.67vw, 1.5rem); /* 24px — same as hero text */
    font-weight: 700; /* Figma: Kräftig (bold weight) — distinguishes headings from body */
    color: var(--color-text);
    letter-spacing: -0.011em;
    line-height: 1.4;
    margin-bottom: 2.6rem; /* ~42px — Figma gap from heading to first content item */
}


/* ============================================================
   8. CURRENTLY WORKING SECTION
   ─────────────────────────────────────────────────────────────
   padding-top: 7.5rem (120px) matches the Figma:
   This section starts at y:1019px, and the hero ends at y:900px.
   1019 − 900 = 119px → rounded to 120px (7.5rem).
   ============================================================ */
.section-currently-working {
    padding-top: 7.5rem;    /* 120px gap between hero bottom and this section */
    padding-left: 13.9vw;   /* 200px left margin (200 ÷ 1440 = 13.9%) */
    padding-right: 5vw;     /* small right breathing room */
}

/* "Designing something new called"
   Smaller label above the body description */
.work-label {
    font-family: 'TestSohneMono', 'Space Mono', monospace;
    font-size: 1rem;         /* 16px — Figma uses 16px for body-level text */
    font-weight: 400;
    color: var(--color-text);
    letter-spacing: -0.011em;
    line-height: 1.4;
    margin-bottom: 1rem;     /* 16px gap before the description paragraph */
}

/* The full description paragraph */
.work-body {
    font-family: 'TestSohneMono', 'Space Mono', monospace;
    font-size: 1rem;         /* 16px */
    font-weight: 400;
    color: var(--color-text);
    letter-spacing: -0.011em;
    line-height: 1.4;
    max-width: 53.75vw;      /* 774px ÷ 1440 — text block width from Figma */
}

/* Elternpop logo sits inline after "Designing something new called".
   height: 25px matches the exact logo frame height in Figma (133×25px).
   vertical-align: middle centres it on the text baseline. */
.work-inline-logo {
    height: 25px;
    vertical-align: middle;
    margin-left: 0.3em;
    display: inline;
}


/* ============================================================
   9. RECENTLY EXPERIENCES SECTION
   ─────────────────────────────────────────────────────────────
   margin-top: 5.75rem (92px) — gap between this section and
   the "Currently working" section, derived from Figma:
   y:1270 (this heading) − y:1178 (approx end of prev section).

   Each case study row is a flex container:
   [90×90px logo box] ← 24px gap → [project title text]
   ============================================================ */
.section-recently {
    margin-top: 5.75rem;     /* 92px gap above this section */
    padding-left: 13.9vw;    /* same 200px left margin */
    padding-right: 5vw;
    position: relative;      /* needed so the static preview can be positioned inside */
}

/* One case study row — logo + title side by side */
.case-study {
    display: flex;           /* puts logo and text in a row */
    align-items: center;     /* vertically centers them */
    gap: 1.5rem;             /* 24px gap between logo box and title text */
    margin-bottom: 1.5rem;   /* 24px between rows.
                                Why 24px? Figma spacing between row tops = 114px.
                                Logo height = 90px. Gap between rows = 114 − 90 = 24px. */
}

/* When a case-study row is wrapped in an <a> link,
   remove the default link styling (blue color, underline)
   so it looks identical to a plain div. */
a.case-study--link {
    text-decoration: none;   /* removes the blue underline from links */
    color: inherit;          /* inherits the dark text color instead of link blue */
    cursor: default;         /* no pointer on the text — only the logo signals "clickable" */
    transition: opacity 0.15s ease;
}

a.case-study--link:hover {
    opacity: 0.75;           /* subtle dimming on hover to show interactivity */
}

a.case-study--link .case-logo {
    cursor: pointer;         /* pointer cursor only on the logo box */
}

/* The colored square that holds the company logo */
.case-logo {
    width: 90px;             /* fixed size from Figma */
    height: 90px;
    min-width: 90px;         /* prevents flexbox from shrinking it */
    border-radius: 4px;      /* slight rounding from Figma */
    display: flex;           /* centers the logo image inside */
    align-items: center;
    justify-content: center;
}

/* The logo image inside the colored box */
.case-logo img {
    max-width: 75%;          /* keeps logo proportional inside the box */
    max-height: 65%;
    display: block;
}

/* The project title text next to the logo */
.case-title {
    font-family: 'TestSohneMono', 'Space Mono', monospace;
    font-size: 1rem;         /* 16px */
    font-weight: 400;
    color: var(--color-text);
    letter-spacing: -0.011em;
    line-height: 1.4;
    max-width: 377px;        /* widest title width from Figma */
}


/* ============================================================
   10. PROBLEMS I SOLVE / HOW I WORK — two-column section
   ─────────────────────────────────────────────────────────────
   Replaces the old "My Playground" section.
   Figma: two columns inside the 1040px content area.
   Left col width=418px, right col width=421px, gap=200px.
   ============================================================ */
.section-howwork {
    margin-top: 5.75rem; /* 92px — matches the consistent gap between all sections */
    padding-left: 13.9vw;
    padding-right: 13.9vw;   /* matches left margin — content is 1040px wide in Figma */
    padding-bottom: 6rem;
}

/* Figma: display flex, gap 200px, align-items flex-start.
   flex: 1 on each column → both share equal width (≈420px each at 1440px). */
.howwork-grid {
    display: flex;
    gap: clamp(2rem, 13.9vw, 12.5rem);  /* 200px at 1440px, responsive below */
    align-items: flex-start;             /* columns align at top, not stretched */
}

.howwork-col {
    flex: 1;  /* each column fills half the available space */
}

/* Body text — 16px regular, same tracking as the rest of the page.
   line-height: 1.4 matches Figma (not 1.6). */
.howwork-body {
    font-family: 'TestSohneMono', 'Space Mono', monospace;
    font-size: 1rem;         /* 16px */
    font-weight: 400;
    color: var(--color-text);
    letter-spacing: -0.011em;
    line-height: 1.4;        /* matches Figma leading-[1.4] */
}

/* Row of two project items */
.playground-grid {
    display: flex;           /* side by side */
    gap: 1.5rem;             /* 24px gap between the two projects */
    align-items: flex-start; /* items align at the top, not stretched */
    margin-top: 2.6rem;      /* ~42px gap from the section title */
}

/* Each project card (image + caption) */
.playground-item {
    display: flex;
    flex-direction: column;  /* image on top, caption below */
}

/* Both projects — fixed 508px width to match Figma */
.playground-item:first-child,
.playground-item:last-child {
    width: 508px;
}

/* Project screenshot image — fixed 508×441px per Figma */
.playground-item img {
    width: 100%;             /* fills the 508px column width */
    height: 441px;           /* fixed height — both images same size */
    object-fit: cover;       /* crops to fill without stretching */
    display: block;
}

/* Caption text below each image */
.playground-caption {
    font-family: 'TestSohneMono', 'Space Mono', monospace;
    font-size: 1rem;         /* 16px */
    font-weight: 400;
    color: var(--color-text);
    letter-spacing: -0.011em;
    line-height: 1.4;
    max-width: 356px;        /* from Figma: both captions use w-[356px] */
    margin-top: 1.5rem;      /* 24px gap between image bottom and caption */
}


/* ============================================================
   11. ABOUT SECTION — CSS GLITCH + CHROMATIC ABERRATION
   ─────────────────────────────────────────────────────────────
   How the glitch effect works:

   Each paragraph has two invisible "copies" layered on top
   (::before = red channel, ::after = cyan channel).
   These copies are positioned absolutely and use clip-path to
   show only a thin horizontal "slice" at a time.
   All three layers animate with step-end timing — no smooth
   blending, just instant jumps — which gives the digital feel.

   animation-iteration-count: 3 → plays 3 times then stops.
   data-text attribute (set by JS) is what feeds the text into
   the pseudo-elements via content: attr(data-text).
   ============================================================ */


/* ── KEYFRAME 1: Main text — rapid position jitter ── */
@keyframes glitch-move {
    /* Active glitch: 0–15% of the 4s cycle (= first 0.6s) */
    0%   { transform: translate(0); }
    4%   { transform: translate(-2px, 0); }
    8%   { transform: translate(2px, 0.5px); }
    11%  { transform: translate(-1px, -0.5px); }
    14%  { transform: translate(1px, 0); }
    /* Rest period: stays still until the cycle repeats */
    15%  { transform: translate(0); }
    100% { transform: translate(0); }
}

/* ── KEYFRAME 2: Red channel (::before) — left-offset slices ──
   clip-path: inset(top right bottom left)
   e.g. inset(15% 0 55% 0) = show only the band from 15% to 45% of height */
@keyframes glitch-red {
    /* Hidden during rest period */
    0%, 15%, 100% {
        opacity: 0;
        transform: translate(0);
        clip-path: inset(0 0 100% 0);   /* fully hidden */
    }
    /* Softer opacity (0.4 vs old 0.9) and smaller translate (3px vs 5px) */
    4%  {
        opacity: 0.4;
        transform: translate(-3px, 0);
        clip-path: inset(15% 0 55% 0);  /* top-third band */
    }
    8% {
        opacity: 0.35;
        transform: translate(2px, 0);
        clip-path: inset(60% 0 10% 0);  /* lower band */
    }
    11% {
        opacity: 0.4;
        transform: translate(-2px, -0.5px);
        clip-path: inset(30% 0 40% 0);  /* middle band */
    }
    14% {
        opacity: 0.3;
        transform: translate(1px, 0);
        clip-path: inset(70% 0 5% 0);   /* thin sliver at bottom */
    }
}

/* ── KEYFRAME 3: Cyan channel (::after) — right-offset slices ── */
@keyframes glitch-cyan {
    /* Hidden during rest period */
    0%, 15%, 100% {
        opacity: 0;
        transform: translate(0);
        clip-path: inset(0 0 100% 0);   /* fully hidden */
    }
    /* Softer opacity and smaller translate, opposite direction from red */
    4%  {
        opacity: 0.4;
        transform: translate(3px, 0);
        clip-path: inset(50% 0 20% 0);  /* lower-half band */
    }
    8% {
        opacity: 0.35;
        transform: translate(-2px, 0);
        clip-path: inset(20% 0 45% 0);  /* upper-third band */
    }
    11% {
        opacity: 0.4;
        transform: translate(2px, 0.5px);
        clip-path: inset(70% 0 5% 0);   /* thin sliver at bottom */
    }
    14% {
        opacity: 0.3;
        transform: translate(-1px, 0);
        clip-path: inset(10% 0 55% 0);  /* near-top band */
    }
}


.section-about {
    margin-top: 5.75rem; /* 92px — matches the consistent gap between all sections */
    padding-left: 13.9vw;
    padding-right: 13.9vw;
    padding-bottom: 4rem;    /* reduced — footer provides its own bottom spacing now */
}

.about-paragraphs {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    max-width: 600px;
}

/* ── PARAGRAPH BASE + GLITCH ANIMATION ──
   position: relative is required so ::before and ::after
   can sit exactly on top of this element. */
.about-text {
    font-family: 'TestSohneMono', 'Space Mono', monospace;
    font-size: 1rem;
    font-weight: 400;
    color: var(--color-text);
    letter-spacing: -0.011em;
    line-height: 1.6;
    position: relative;  /* anchor for absolutely-positioned pseudo-elements */
    /* 4s cycle: 0.6s glitch burst, then 3.4s rest, loops forever */
    animation: glitch-move 2.5s step-end infinite both;
}

/* ── SHARED PSEUDO-ELEMENT SETUP ──
   content: attr(data-text) reads the paragraph text from a
   data attribute we set in JS — this is how CSS duplicates text.
   background: white hides the areas outside the clip-path slice,
   so only the "glitch slice" is visible at any moment. */
.about-text::before,
.about-text::after {
    content: attr(data-text);
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: #FFFFFF;      /* matches page background — masks outside the slice */
    font-family: inherit;
    font-size: inherit;
    font-weight: inherit;
    letter-spacing: inherit;
    line-height: inherit;
}

/* Red channel — shifts left */
.about-text::before {
    color: #ff2020;
    animation: glitch-red 2.5s step-end infinite both;
}

/* Cyan channel — shifts right */
.about-text::after {
    color: #00e5ff;
    animation: glitch-cyan 2.5s step-end infinite both;
}

/* ── STAGGER DELAYS ──
   Spread 1s apart within the 4s cycle — so they stay offset every loop.
   The delay must be set on the element AND both pseudo-elements. */
/* All paragraphs glitch at the same time — no stagger */
.about-paragraphs .about-text,
.about-paragraphs .about-text::before,
.about-paragraphs .about-text::after { animation-delay: 0s; }


/* ── ABOUT BUTTONS ──────────────────────────────────────────
   Two CTA buttons below the about text: Contact me + Download CV.
   Each is an inline-flex row: [text] [icon].
   Border style keeps it minimal and consistent with the mono font feel. */
.about-buttons {
    display: flex;
    gap: 0.75rem;            /* 12px between buttons — matches Figma spacing */
    margin-top: 2.5rem;      /* space above buttons, below the text block */
}

/* Figma: bg-black, border black, text white, 14px, rounded-[8px], padding 8px, gap 8px */
.about-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;             /* 8px between text and icon */
    padding: 0.5rem;         /* 8px all sides — matches Figma p-[8px] */
    font-family: 'TestSohneMono', 'Space Mono', monospace;
    font-size: 0.875rem;     /* 14px — Figma uses text-[14px] */
    font-weight: 400;
    color: #ffffff;          /* white text on black background */
    background-color: #000000;
    text-decoration: none;
    border: 1px solid #000000;
    border-radius: 8px;      /* Figma: rounded-[8px] */
    letter-spacing: -0.011em;
    line-height: 1.4;
    transition: opacity 0.15s ease;
}

.about-btn:hover {
    opacity: 0.6;
}

.about-btn svg {
    flex-shrink: 0;          /* prevents icon from squishing if text wraps */
}


/* ── FOOTER ─────────────────────────────────────────────────
   Three columns: logos | copyright | credits.
   Uses justify-content: space-between to spread them out. */
.site-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 2rem 13.9vw 3rem;   /* top, sides (same as sections), bottom */
    margin-top: 1rem;
}

/* Logo link group — LinkedIn, GitHub, Substack in a row */
.footer-logos {
    display: flex;
    align-items: center;
    gap: 1rem;               /* 16px between logos */
}

.footer-logos a {
    display: flex;
    align-items: center;
    transition: opacity 0.15s ease;
}

.footer-logos a:hover {
    opacity: 0.6;
}

.footer-logos img {
    width: 24px;
    height: 24px;
    display: block;
}

/* Copyright and credits text */
.footer-copy,
.footer-made {
    font-family: 'TestSohneMono', 'Space Mono', monospace;
    font-size: 0.875rem;     /* 14px — slightly smaller than body */
    font-weight: 400;
    color: var(--color-text);
    letter-spacing: -0.011em;
    line-height: 1.4;
}

/* "Claude Code" link inside the footer credits */
.footer-made a {
    color: inherit;
    text-decoration: underline;
    text-underline-offset: 2px;
}

/* Easter egg hint — subtle, italic, lighter than body text */
.about-text--hint {
    color: #999;
    font-style: italic;
    font-size: 0.875rem;
}


/* ============================================================
   12. MOBILE RESPONSIVE — @media (max-width: 768px)
   ─────────────────────────────────────────────────────────────
   Everything inside this block ONLY applies to screens
   768px wide or narrower (phones, small tablets).
   Desktop browsers skip this entire block.

   Reference artboard: iPhone 16 — 390px wide × 844px tall.
   Position math: left px ÷ 390 = %, top px ÷ 844 = vh.
   ============================================================ */
@media (max-width: 768px) {

    /* ── PREVENT HORIZONTAL SCROLL ──
       Absolutely-positioned hero objects can overflow the viewport.
       overflow-x:hidden clips anything that sticks out the sides. */
    body {
        overflow-x: hidden;
    }

    /* ── HIDE DESKTOP-ONLY FEATURES ──
       Light switch and dark mode are desktop-only interactions.
       Hiding here prevents a flash before JS runs. */
    #lightswitch { display: none; }

    /* ── HERO: ensure it clips overflowing objects ── */
    .hero {
        width: 100vw;
        overflow: hidden;
    }

    /* ── HIDDEN OBJECTS ──
       lamp:    not in the mobile Figma design.
       plantbig: large right-side monstera — too wide for mobile.
       chair:   not in the mobile Figma design. */
    #lamp,
    #plantbig,
    #chair {
        display: none;
    }

    /* ── DISABLE PARALLAX on mobile ──
       The JS mousemove handler is guarded with a width check (see main.js),
       so --px and --py never change on touch devices.
       This rule resets the transform to make absolutely sure objects
       start at their CSS positions, not offset by stale JS values. */
    .hero-object {
        transform: none;
    }

    /* ── REGAL (bookshelf) ──
       Half-visible on the left edge, intentionally cropped.
       Spec: left:-254px, top:30px, width:564px */
    #regal {
        left: -65.1%;   /* -254px ÷ 390 */
        top: 3.55vh;    /* 30px ÷ 844 */
        width: 144.6vw; /* 564px ÷ 390 — wider than screen; left edge crops it */
    }

    /* ── PORTRAIT FRAME ──
       Spec: left:119px, top:-2px, width:304px */
    #frame {
        left: 30.5%;    /* 119px ÷ 390 */
        top: -0.24vh;   /* -2px ÷ 844 — slightly above top edge */
        width: 78vw;    /* 304px ÷ 390 */
    }

    /* ── CHIVA (colorful toy bus) ──
       Spec: left:4px, top:322px */
    #chiva {
        left: 1%;       /* 4px ÷ 390 */
        top: 38.2vh;    /* 322px ÷ 844 */
        width: 37.9vw;  /* unchanged from desktop */
    }

    /* ── CAMERA ──
       Spec: left:51px, top:257px */
    #camera {
        left: 13.1%;    /* 51px ÷ 390 */
        top: 30.5vh;    /* 257px ÷ 844 */
        width: 18.2vw;  /* unchanged */
    }

    /* ── PULP FICTION ──
       Spec: left:48px, top:141px */
    #pulpfiction {
        left: 12.3%;    /* 48px ÷ 390 */
        top: 16.7vh;    /* 141px ÷ 844 */
        width: 19.7vw;  /* unchanged */
    }

    /* ── VINE PLANT — small plant inside the shelf ──
       Spec: left:-103px, top:117px
       Partially off the left edge, hangs over the regal shelf. */
    #plant {
        left: -26.4%;   /* -103px ÷ 390 */
        top: 13.9vh;    /* 117px ÷ 844 */
        width: 39.5vw;  /* unchanged */
    }

    /* ── PLANTSMALL — right of portrait frame ──
       Spec: left:214px, top:344px, width:192px */
    #plantsmall {
        left: 54.9%;    /* 214px ÷ 390 */
        top: 40.8vh;    /* 344px ÷ 844 */
        width: 49.2vw;  /* 192px ÷ 390 */
    }

    /* ── SUCCULENT — keep existing mobile position ── */
    #plantsuculent {
        left: 12.3%;
        top: 57.7vh;
        width: 15.9vw;
    }

    /* ── BOOKS — keep existing mobile positions ── */
    #book2 {
        left: -7.7%;
        top: 59.4vh;
        width: 14.1vw;
    }

    #book {
        left: -6.2%;
        top: 62vh;
        width: 12.8vw;
    }

    /* ── HERO TEXT ──
       Greeting spec: left:30px, top:584px, font-size:32px
       H1 spec:       left:26px, top:637px, width:308px, font-size:24px

       The container sits at the greeting's top (584px = 69.2vh).
       The 4px left difference (30 vs 26) is handled with margin-left on .greeting. */
    .hero-text {
        left: 26px;
        top: 69.2vh;        /* 584px ÷ 844 */
        width: 308px;
        max-width: none;    /* override desktop percentage max-width */
        display: flex;
        flex-direction: column;
    }

    /* "Hola! I'm Carol Munar." — left-aligned, slightly inset */
    .hero-text .greeting {
        font-size: 32px;
        align-self: flex-start;  /* left side (overrides any previous flex-end) */
        margin-left: 4px;        /* 30px position − 26px container = 4px */
    }

    /* Big h1 statement — 24px, full container width */
    .hero-text h1 {
        font-size: 24px;
        width: 308px;
        max-width: none;
    }

    /* ── SECTIONS: swap 13.9vw desktop margin for 24px mobile padding ──
       24px each side on 390px viewport leaves 342px of content width. */
    .section-currently-working,
    .section-recently,
    .section-howwork,
    .section-about {
        padding-left: 24px;
        padding-right: 24px;
    }

    /* ── SECTION TITLES: 24px on mobile ──
       clamp(1rem, 1.67vw, 1.5rem) at 390px resolves to 1rem (16px) —
       too small. This override forces the intended 24px. */
    .section-title {
        font-size: 24px;
    }

    /* ── CURRENTLY WORKING: body text fills full width ── */
    .work-body {
        max-width: 100%;
        font-size: 16px;
    }

    /* ── CASE STUDIES: stack vertically ──
       Desktop: [logo] → [title] in a row.
       Mobile:  logo above title, both left-aligned. */
    .case-study {
        flex-direction: column;
        align-items: flex-start;
    }

    /* Project title: constrained width, 16px */
    .case-title {
        width: 333px;
        max-width: 100%;    /* shrinks on very narrow phones */
        font-size: 16px;
    }

    /* ── PROBLEMS / HOW I WORK: stack to single column on mobile ──
       Desktop uses display: flex so we use flex-direction, not grid-template-columns */
    .howwork-grid {
        flex-direction: column;
        gap: 2rem;
    }

    /* ── ABOUT BUTTONS: stack on very narrow screens ── */
    .about-buttons {
        flex-wrap: wrap;
    }

    /* ── FOOTER: stack vertically, center-aligned ── */
    .site-footer {
        flex-direction: column;
        align-items: flex-start;
        gap: 1rem;
        padding: 2rem 24px 3rem;
    }

    .playground-caption {
        max-width: 100%;
    }

    /* ── ABOUT: text width 339px, 16px ── */
    .about-paragraphs {
        max-width: 339px;
    }

    .about-text {
        font-size: 16px;
    }

    /* ── PROJECT PREVIEW: hidden on mobile ──
       The preview area is desktop-only. JS also guards against this. */
    .project-preview-area {
        display: none;
    }

} /* end @media (max-width: 768px) */


/* ── PROJECT PREVIEW AREA (multi-image mosaic, right-aligned) ──
   Sits to the right of the project list inside .section-recently.
   position:absolute works because .section-recently has position:relative.
   pointer-events:none lets clicks pass through to the rows below. */
.project-preview-area {
    position: absolute;
    /* Figma: hover frame starts at x=710 on a 1440px canvas.
       That's right after the case list ends:
       section left padding (13.9vw ≈ 200px) + logo (90px) + gap (24px) + title (377px) + gap (24px) = ~515px of content
       So: 13.9vw + 515px ≈ 715px — matches Figma's x=710. */
    left: calc(13.9vw + 515px);
    top: 0;
    width: 572px;   /* 340px × 1.2 × 1.4 */
    height: 100%;
    pointer-events: none;
}

/* Each .preview-set holds the images for ONE project.
   Images are absolutely positioned inside. The container itself has no
   background — the images handle their own visibility via animation. */
.preview-set {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);  /* vertically centered in the area */
    width: 572px;   /* 340px × 1.2 × 1.4 */
    overflow: visible;
    padding: 8px;
    margin: -8px;
    background: transparent;
    box-shadow: none;
    /* No opacity here — each image animates independently */
}

/* All images start hidden and 12px below their final position.
   This transition is the EXIT — quick fade out when mouse leaves. */
.preview-set img {
    position: absolute;
    border-radius: 2px;
    display: block;
    border: none;
    box-shadow: none;
    background: transparent;
    object-fit: cover;
    opacity: 0;
    transform: translateY(12px);
    transition: opacity 0.2s ease, transform 0.2s ease;
    mix-blend-mode: multiply;
}

/* ENTER animation — triggered when JS adds .visible to the parent set.
   Each image slides up + fades in with a springy ease.
   The stagger delays make them appear one after the other, not all at once. */
.preview-set.visible img {
    opacity: 1;
    transform: translateY(0);
    transition: opacity 0.4s ease,
                transform 0.5s cubic-bezier(0.16, 1, 0.3, 1); /* spring ease */
}

/* Stagger: each image enters 70ms after the previous one */
.preview-set.visible img:nth-child(1) { transition-delay: 0s;     }
.preview-set.visible img:nth-child(2) { transition-delay: 0.07s;  }
.preview-set.visible img:nth-child(3) { transition-delay: 0.14s;  }


/* ── ALPHIN — 3-image mosaic (all values × 1.2 × 1.4)
   Layout: wide banner on top, two panels side-by-side below */
#preview-alphin { height: 423px; }

#preview-alphin img:nth-child(1) {   /* hover1 — top banner */
    left: 0;    top: 0;
    width: 398px; height: 150px;
}
#preview-alphin img:nth-child(2) {   /* hover2 — bottom right */
    left: 245px; top: 162px;
    width: 232px; height: 204px;
}
#preview-alphin img:nth-child(3) {   /* hover3 — bottom left, tallest */
    left: 0;    top: 162px;
    width: 232px; height: 259px;
}


/* ── ADJUST — 2 images stacked (all values × 1.2 × 1.4) */
#preview-adjust { height: 353px; }

#preview-adjust img:nth-child(1) {   /* hover1 — thin strip */
    left: 0; top: 69px;
    width: 566px; height: 91px;
}
#preview-adjust img:nth-child(2) {   /* hover2 — main card below */
    left: 0; top: 174px;
    width: 571px; height: 179px;
}


/* ── AGROFY — 2 images side by side (all values × 1.2 × 1.4) */
#preview-agrofy { height: 389px; }

#preview-agrofy img:nth-child(1) {   /* hover1 — left, tall */
    left: 8px;   top: 32px;
    width: 267px; height: 358px;
}
#preview-agrofy img:nth-child(2) {   /* hover2 — right, shorter */
    left: 295px; top: 32px;
    width: 267px; height: 174px;
}


/* ── ESTYLAR — 3 images (all values × 1.2 × 1.4) */
#preview-estylar { height: 410px; }

#preview-estylar img:nth-child(1) {  /* hover1 — top strip */
    left: 84px;  top: 10px;
    width: 277px; height: 67px;
}
#preview-estylar img:nth-child(2) {  /* hover2 — center-left */
    left: 84px;  top: 116px;
    width: 249px; height: 291px;
}
#preview-estylar img:nth-child(3) {  /* hover3 — right narrow strip */
    left: 396px; top: 118px;
    width: 92px;  height: 294px;
}




/* ── HEAD TRACKING BUTTON ──────────────────────────────────────
   Small monospace text button, positioned in the bottom-center
   of the hero. Matches the site's typographic style.
   Active state shows a pulsing dot to signal the camera is on. */
