/* Work + Projects views (homepage): the List view - a typographic index grouped by year.
   Work adds a brand line down the rows and an employer intro where each employer's line
   begins (.wv-list--brand), following the Featured timeline. Heroes become compact cards. */

.wv-list ul,
ul.wv-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.wv-list a {
    color: inherit;
    text-decoration: none;
}

.wv-list a:focus-visible {
    outline: 3px solid var(--highlight-yellow);
    outline-offset: 2px;
    border-radius: 6px;
}

.wv-nowrap {
    white-space: nowrap;
}

.wv-icon {
    font-size: 20px;
    line-height: 1;
    vertical-align: middle;
}

/* ---- Index ---- */

.wv-index-group {
    display: grid;
    grid-template-columns: 88px minmax(0, 1fr);
    gap: 0 16px;
    padding-top: 12px;
    border-top: 1px solid var(--wv-hair);
    margin-bottom: 14px;
}

.wv-index-year {
    position: sticky;
    top: 84px;
    align-self: start;
    margin: 0;
    padding-top: 7px;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: var(--fs-ui);
    font-variant-numeric: tabular-nums;
    opacity: 0.45;
}

.wv-index-group--short .wv-index-year {
    position: static;
}

.wv-index-row {
    display: grid;
    grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr) 92px;
    gap: 16px;
    align-items: baseline;
    padding: 7px 0;
    font-size: var(--fs-ui);
    transition: opacity 0.5s var(--wv-ease) 0.12s;
}

.wv-index-title {
    min-width: 0;
}

.wv-index-name {
    font-family: var(--font-display);
    font-size: 1.25rem;
}

/* Phones: the Talks voice - Nunito bold at the body size - so the list doesn't read as a
   different section there. Desktop keeps the Outfit index. */
@media (max-width: 768px) {
    .wv-index-name {
        font-family: var(--font-body);
        font-weight: 700;
        font-size: var(--fs-body);
        line-height: 1.25;
    }
}

.wv-index-title .wv-icon {
    font-size: 16px;
    margin-left: 4px;
    opacity: 0.6;
}

.wv-index-lead {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    margin-top: 4px;
    font-size: 0.95rem;
    line-height: var(--lh-body);
    opacity: 0.7;
}

.wv-index-meta {
    opacity: 0.6;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.wv-index-type {
    font-style: italic;
    text-align: right;
    opacity: 0.55;
}

.wv-index-row.is-hero .wv-index-name {
    font-weight: 700;
}

.wv-index-row.is-soon {
    opacity: 0.5;
}

/* Spotlight: only while a clickable row or hero card is under the pointer (or has keyboard
   focus) - not when hovering the employer intros, year column or the gaps between rows.
   Dimming is quick; coming back is slower and waits a beat (the rest-state transition on
   the rows/cards), so sliding between rows across a gap doesn't flash everything bright. */
.wv-list:has(:is(.wv-index-row, .wv-icard):focus-visible) :is(.wv-index-row, .wv-icard):not(:focus-visible) {
    opacity: 0.4;
    transition: opacity 0.2s ease-out;
}

@media (hover: hover) and (pointer: fine) {
    .wv-list:has(:is(.wv-index-row, .wv-icard):hover) :is(.wv-index-row, .wv-icard):not(:hover) {
        opacity: 0.4;
        transition: opacity 0.2s ease-out;
    }
}

.wv-peek {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 60;
    width: 240px;
    aspect-ratio: 4 / 3;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.18s;
}

.wv-peek img,
.wv-peek video {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 12px;
    box-shadow: 0 18px 40px rgba(55, 44, 9, 0.22);
    transform: scale(0.9) rotate(-2deg);
    transition: transform 0.3s var(--wv-ease);
}

/* The loop sits over the still and shows once it's playing. */
.wv-peek video {
    position: absolute;
    inset: 0;
    opacity: 0;
}

.wv-peek.has-video video {
    opacity: 1;
}

/* Media marked to show whole: the preview takes the still's own shape. */
.wv-peek.is-contain {
    aspect-ratio: auto;
}

.wv-peek.is-contain img {
    height: auto;
}

.wv-peek.is-contain video {
    object-fit: contain;
    background: #fff;
}

.wv-peek.is-on {
    opacity: 1;
}

.wv-peek.is-on img,
.wv-peek.is-on video {
    transform: none;
}

@media (max-width: 768px) {
    .wv-index-group {
        grid-template-columns: minmax(0, 1fr);
    }

    .wv-index-year {
        position: static;
        padding: 0 0 4px;
    }

    .wv-index-row {
        grid-template-columns: minmax(0, 1fr) auto;
    }

    .wv-index-meta {
        display: none;
    }
}

/* ---- Brand lines ---- */

.wv-brand--fitxr {
    --brand-a: var(--fitxr-start);
    --brand-b: var(--fitxr-end);
    --brand-mid: #2593e9;
}

.wv-brand--ultraleap {
    --brand-a: var(--ultraleap-start);
    --brand-b: var(--ultraleap-end);
    --brand-mid: #00dca8;
}

/* Personal work takes Pip pink. */
.wv-brand--personal {
    --brand-a: #ffb3c5;
    --brand-b: var(--highlight-pip);
    --brand-mid: var(--highlight-pip);
}

/* Brand line - follows the live timeline in Featured:
   - a logo column on the left; the employer intro's logo sits in it
   - the line runs in that column, flush with the logo's right edge (as the live bar is)
   - the line starts after the intro, not beside it
   Each row draws its own segment, so consecutive rows from one employer read as one
   continuous line that changes colour where the employer does. */
.wv-list--brand {
    --f-logo: 48px;  /* logo column */
    --f-gap: 14px;   /* logo column -> text */
    --f-bar: 6px;    /* line width */
}

.wv-list--brand .wv-index-li {
    position: relative;
    padding-left: calc(var(--f-logo) + var(--f-gap));
}

.wv-list--brand .wv-index-li::before {
    content: '';
    position: absolute;
    left: calc(var(--f-logo) - var(--f-bar));
    top: 0;
    bottom: 0;
    width: var(--f-bar);
    background: var(--brand-mid);
}

/* No middle column on the brand line (the line says whose work it is): title | type. */
.wv-list--brand .wv-index-row {
    grid-template-columns: minmax(0, 1fr) auto;
}

/* Run starts: first row of a year, or the first row after an intro. */
.wv-list--brand .wv-index-li:first-child::before,
.wv-list--brand .wv-eintro-li + .wv-index-li::before {
    top: 6px;
    border-radius: 999px 999px 0 0;
}

/* Run ends: last row of a year, or the row before the next employer's intro. */
.wv-list--brand .wv-index-li:last-child::before,
.wv-list--brand .wv-index-li:has(+ .wv-eintro-li)::before {
    bottom: 6px;
    border-radius: 0 0 999px 999px;
}

/* A one-row run is both start and end. */
.wv-list--brand .wv-index-li:only-child::before,
.wv-list--brand .wv-index-li:first-child:has(+ .wv-eintro-li)::before,
.wv-list--brand .wv-eintro-li + .wv-index-li:last-child::before,
.wv-list--brand .wv-eintro-li + .wv-index-li:has(+ .wv-eintro-li)::before {
    border-radius: 999px;
}

/* ---- Employer intro row ---- */

/* The intro spans the logo column itself (its logo sits where the line runs) and has
   no line of its own - the line begins with the first row under it. */
.wv-list--brand .wv-index-li.wv-eintro-li {
    padding: 10px 0 12px;
}

.wv-list--brand .wv-index-li.wv-eintro-li::before {
    content: none;
}

/* An intro mid-list (Ultraleap, part-way through 2024) needs a clear break above it so
   the two employers read as separate groups; the space stays empty. */
.wv-list--brand .wv-index-li.wv-eintro-li:not(:first-child) {
    padding-top: 44px;
}

/* Landing spot for the bio's employer links: clear the pinned switcher. */
.wv-eintro-li {
    scroll-margin-top: 80px;
}

.wv-eintro {
    display: grid;
    grid-template-columns: var(--f-logo, 48px) minmax(0, 1fr);
    gap: var(--f-gap, 14px);
    align-items: start;
}

.wv-eintro-logo {
    display: block;
    width: var(--f-logo, 48px);
    height: var(--f-logo, 48px);
    border-radius: 12px;
    object-fit: cover;
}

.wv-eintro-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.wv-eintro-name {
    margin: 0;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: var(--fs-card);
    line-height: 1.05;
}

.wv-eintro-meta {
    margin: 0;
    font-size: 0.95rem;
    opacity: 0.7;
}

.wv-eintro-desc {
    margin: 6px 0 0;
    font-size: 1rem;
    line-height: var(--lh-body);
    opacity: 0.85;
}

/* Phones: body size, with the site's prose tuning (taller lowercase), like the bio. */
@media (max-width: 768px) {
    .wv-eintro-meta {
        font-size: var(--fs-ui);
    }

    .wv-eintro-desc {
        font-size: var(--fs-ui);
        font-variation-settings: 'YTLC' 500, 'wdth' 100;
    }
}

@media (max-width: 768px) {
    .wv-list--brand {
        --f-logo: 40px;
        --f-gap: 12px;
        --f-bar: 5px;
    }

    .wv-eintro-logo {
        border-radius: 10px;
    }
}

/* ---- Index hero card ----
   A compact strip, barely taller than two rows: it lifts a hero out of the table
   without breaking the index rhythm. */

.wv-icard-li {
    margin: 8px 0 10px;
}

.wv-icard {
    transition: opacity 0.5s var(--wv-ease) 0.12s;
    display: grid;
    grid-template-columns: 112px minmax(0, 1fr) auto;
    align-items: center;
    gap: 16px;
    padding: 8px 14px 8px 8px;
    border-radius: 16px;
    background: var(--card-bg, rgba(55, 44, 9, 0.05));
}

/* Must out-rank `.wv-list a { color: inherit }`, or brand cards get brown ink on their own colour. */
.wv-list .wv-icard {
    color: var(--card-ink, var(--text-color));
}

.wv-icard-media {
    position: relative;
    display: block;
    aspect-ratio: 4 / 3;
    border-radius: 10px;
    overflow: hidden;
    background: var(--wv-tint);
}

.wv-icard-media img,
.wv-icard-media video {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.6s var(--wv-ease);
}

.wv-icard-body {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.wv-icard-meta {
    font-size: 0.85rem;
    opacity: 0.65;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.wv-icard-title {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.25rem;
    line-height: 1.15;
}

/* The short line wraps rather than truncating: the text column is only ~240-310px, and
   two lines still fit beside the thumb, so the card barely grows. Balanced, not just
   pretty: on a two-line block pretty may still leave one word on the last line. */
.wv-icard-lead {
    font-size: 0.95rem;
    line-height: 1.3;
    opacity: 0.8;
    text-wrap: balance;
}

.wv-icard-cta {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    height: 32px;
    padding: 0 8px 0 12px;
    border-radius: 999px;
    background: var(--text-color);
    color: var(--bg-color);
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 0.9rem;
    white-space: nowrap;
}

.wv-icard-cta .wv-icon {
    font-size: 18px;
}

/* On a brand colour, a dimmed short line goes muddy: show it at full ink, like the title. */
.wv-icard--brand .wv-icard-lead {
    opacity: 1;
}

.wv-icard--brand .wv-icard-cta {
    background: var(--card-ink);
    color: var(--card-bg);
}

.wv-icard-cta.is-soon {
    opacity: 0.5;
}

@media (hover: hover) {
    a.wv-icard:hover .wv-icard-media img,
    a.wv-icard:hover .wv-icard-media video {
        transform: scale(1.06);
    }
}

/* Phones and narrow windows: smaller thumb and title, CTA shrunk to its icon, body-size
   short line. The card stays side by side while there's room for it. */
@media (max-width: 768px) {
    .wv-icard {
        grid-template-columns: 76px minmax(0, 1fr) auto;
        gap: 12px;
        padding: 6px 10px 6px 6px;
    }

    .wv-icard-title {
        font-size: 1.05rem;
    }

    .wv-icard-meta {
        display: none;
    }

    .wv-icard-lead {
        font-size: var(--fs-ui);
        font-variation-settings: 'YTLC' 500, 'wdth' 100;
    }

    .wv-icard-cta {
        width: 32px;
        padding: 0;
        justify-content: center;
        font-size: 0;
    }
}

/* Narrow phones: beside the thumb the short line would get ~135px and run to 5 lines, so
   thumb, title and CTA share the top row and the line runs full width underneath -
   filling each line (pretty), not splitting it evenly. Wider than this, the stacked card
   just leaves both rows half empty. */
@media (max-width: 560px) {
    .wv-icard {
        grid-template-areas:
            "media title cta"
            "lead  lead  lead";
        gap: 8px 12px;
        padding: 6px 10px 8px 6px;
    }

    .wv-icard-media { grid-area: media; }
    .wv-icard-body { display: contents; }
    .wv-icard-title { grid-area: title; align-self: center; }
    .wv-icard-lead { grid-area: lead; padding-left: 4px; text-wrap: pretty; }
    .wv-icard-cta { grid-area: cta; }
}

/* On the brand line the card's spacing is padding, not margin, so its brand segment meets the rows'. */
.wv-list--brand .wv-icard-li {
    margin: 0;
    padding-top: 8px;
    padding-bottom: 10px;
}

@media (prefers-reduced-motion: reduce) {
    /* !important: the spotlight's dim rules set their own transitions. */
    .wv-index-row,
    .wv-icard {
        transition: none !important;
    }
}
