/* ==========================================================================
   Tomás Russo — portfolio
   Black field, heavy Inter, and a colour per project that only fully arrives
   when you reach for it.
   ========================================================================== */

:root {
    --bg:     #000000;
    --ink:    #ffffff;
    --ink-2:  #c9cacc;
    --slate:  #a7a9ac;
    --band:   8px;

    /* One colour per project, all three deep enough to carry white copy at AA.
       That constraint is what sets their depth: a genuinely light blue tops out
       around 2.9:1 against white, so the route planner's blue is pulled down
       until white works. Every flood then shares one legend colour — white —
       which is what keeps the separating band from ever having to change. */
    --green: #00702e;
    --navy:  #0039a6;
    --azure: #00719b;

    --snap: 150ms linear;
    --draw: cubic-bezier(0.18, 0.9, 0.3, 1);

    --pad-x: clamp(28px, 3.6vw, 76px);
    --pad-y: clamp(40px, 4.4vw, 72px);
}

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

html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }

body {
    display: grid;
    grid-template-columns: clamp(320px, 31vw, 540px) minmax(0, 1fr);
    min-height: 100vh;
    margin: 0;
    background: var(--bg);
    color: var(--ink);
    font-family: Inter, system-ui, -apple-system, "Helvetica Neue", Helvetica, sans-serif;
    font-optical-sizing: auto;
    font-size: 17px;
    line-height: 1.6;
    font-feature-settings: "cv05" 1, "cv08" 1, "ss03" 1;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

a { color: inherit; }

/* white reads on the black field and on all three floods, so the ring
   never has to change either */
:focus-visible {
    outline: 3px solid var(--ink);
    outline-offset: 4px;
}

.sr-only {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.skip {
    position: absolute;
    left: 20px;
    top: -72px;
    z-index: 20;
    padding: 14px 22px;
    background: var(--ink);
    color: var(--bg);
    font-size: 15px;
    font-weight: 700;
    text-decoration: none;
    transition: top 160ms var(--draw);
}
.skip:focus { top: 20px; }

.arrow {
    width: 17px;
    height: 12px;
    flex: none;
    overflow: visible;
    transition: transform 200ms var(--draw);
}
.arrow__bar  { stroke: currentColor; stroke-width: 2.4; fill: none; }
.arrow__head { fill: currentColor; }
.arrow--up   { rotate: -45deg; }

/* Left panel --------------------------------------------------------------- */

.panel {
    position: sticky;
    top: 0;
    align-self: start;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 48px;
    height: 100vh;
    padding: var(--pad-y) var(--pad-x);
}

.name {
    margin: 0;
    font-size: clamp(54px, 6.6vw, 116px);
    font-weight: 700;
    line-height: 0.89;
    letter-spacing: -0.052em;
}

/* Now a sentence rather than a label, so it needs a measure and a much
   tighter leading — body line-height under a name set at 0.89 reads slack.
   The role itself carries the weight; the rest steps back. */
.role {
    margin: clamp(24px, 2.8vw, 38px) 0 0;
    max-width: 30ch;
    font-size: clamp(17px, 1.45vw, 20px);
    font-weight: 450;
    line-height: 1.34;
    letter-spacing: -0.016em;
    color: var(--slate);
    text-wrap: balance;
}

.role__job {
    font-weight: 600;
    color: var(--ink);
}

.social {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
}

.social a {
    display: inline-flex;
    align-items: center;
    gap: 12px;
    font-size: 17px;
    font-weight: 600;
    letter-spacing: -0.012em;
    text-decoration: none;
    transition: color var(--snap);
}
.social a:hover { color: var(--slate); }
.social a:hover .arrow { transform: translate(4px, -4px); }

/* Projects ----------------------------------------------------------------- */

.project {
    --fg:   var(--ink);
    --fg-2: var(--ink-2);
    --fg-3: var(--slate);
    --edge: #2e2e31;

    position: relative;
    display: grid;
    grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr);
    column-gap: clamp(36px, 4.6vw, 96px);
    padding: var(--pad-y) var(--pad-x) clamp(48px, 5vw, 80px);
    color: var(--fg);
    transition: background-color var(--snap);
}

/* bands close the stack top and bottom, not just between */
.project { border-top: var(--band) solid var(--ink); }
.project:last-of-type { border-bottom: var(--band) solid var(--ink); }

.project:nth-of-type(1) { --line: var(--green); }
.project:nth-of-type(2) { --line: var(--navy); }
.project:nth-of-type(3) { --line: var(--azure); }

/* The flood. Type stays white throughout, so only the background actually
   moves — and the band above is left alone, which is what was making it
   vanish into the black above it. */
.project:hover,
.project:focus-within {
    background-color: var(--line);
    --fg-2: #fff;
    --fg-3: rgba(255, 255, 255, 0.9);
    --edge: rgba(255, 255, 255, 0.7);
}

.project__lead { position: relative; }

.project__name {
    margin: 0;
    font-size: clamp(30px, 3.15vw, 52px);
    font-weight: 700;
    line-height: 1.02;
    letter-spacing: -0.04em;
}

.project__name a { text-decoration: none; }

/* the name block is clickable anywhere; the copy stays selectable */
.project__name a::after {
    content: "";
    position: absolute;
    inset: 0;
}

/* Year and stack sit on one line at one size, separated by weight and tone
   alone. Two near-but-unequal sizes read as a mistake rather than a contrast,
   and tracking this open on mixed-case text just looks loose. */
.project__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    column-gap: clamp(14px, 1.3vw, 21px);
    row-gap: 8px;
    margin-top: clamp(16px, 1.7vw, 26px);
}

.project__year,
.project__stack {
    margin: 0;
    font-size: 16px;
    letter-spacing: -0.01em;
}

.project__year {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--fg);
}

.project__stack {
    font-weight: 450;
    color: var(--fg-3);
    transition: color var(--snap);
}

/* At line-height 1.02 the title's half-leading is negative, so its cap already
   lands within ~2px of the description's. Any padding here reads as the title
   floating high. */
.project__detail { padding-top: 0; }

.project__text {
    margin: 0;
    max-width: 62ch;
    font-size: clamp(16px, 1.1vw, 18px);
    line-height: 1.58;
    color: var(--fg-2);
    text-wrap: pretty;
    transition: color var(--snap);
}
.project__text + .project__text { margin-top: 22px; }

.project__link {
    position: relative;
    z-index: 1;
    display: inline-flex;
    align-items: center;
    gap: 14px;
    margin-top: clamp(28px, 3vw, 40px);
    padding-bottom: 8px;
    font-size: 16px;
    font-weight: 600;
    letter-spacing: -0.012em;
    text-decoration: none;
    border-bottom: 2px solid var(--edge);
    transition: border-color var(--snap);
}
.project__link:hover { border-color: currentColor; }
.project__link:hover .arrow { transform: translateX(5px); }

/* Load --------------------------------------------------------------------- */

@keyframes rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

.name   { animation: rise 620ms var(--draw) both; }
.role   { animation: rise 620ms var(--draw) 70ms both; }
.social { animation: rise 560ms var(--draw) 420ms both; }

.project:nth-of-type(1) { --d: 0.16s; }
.project:nth-of-type(2) { --d: 0.28s; }
.project:nth-of-type(3) { --d: 0.40s; }

.project__name   { animation: rise 560ms var(--draw) var(--d) both; }
.project__meta   { animation: rise 560ms var(--draw) calc(var(--d) + 0.08s) both; }
.project__detail { animation: rise 560ms var(--draw) calc(var(--d) + 0.14s) both; }

/* Stacked ------------------------------------------------------------------ */

@media (max-width: 1080px) {
    .project {
        grid-template-columns: minmax(0, 1fr);
        row-gap: clamp(26px, 3vw, 36px);
    }
    .project__text { max-width: 68ch; }
}

@media (max-width: 900px) {
    body {
        grid-template-columns: minmax(0, 1fr);
        min-height: 0;
    }

    .panel {
        position: static;
        height: auto;
        gap: clamp(40px, 7vw, 64px);
        padding: clamp(40px, 8vw, 72px) var(--pad-x) clamp(36px, 6vw, 56px);
    }

    .name { font-size: clamp(50px, 13vw, 96px); }

    .social { flex-direction: row; gap: 28px; }

    .project { padding-top: clamp(36px, 7vw, 56px); }
    .project__name { font-size: clamp(28px, 6.4vw, 44px); }
}

/* the flood is a pointer affordance; on touch, :hover sticks after a tap */
@media (hover: none) {
    .project:hover {
        background-color: transparent;
        --fg:   var(--ink);
        --fg-2: var(--ink-2);
        --fg-3: var(--slate);
        --edge: #2e2e31;
    }
}

/* Motion preferences ------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: 1ms !important;
        animation-delay: 0ms !important;
        transition-duration: 1ms !important;
    }
}
