/* Block: team-bio
 *
 * The profile popup (Figma "Graeme bio", node 280:1952). A 1143 x 649 white
 * panel, radius 10 on a 1px #b0b0b0 rule, centred over a blurred page: the
 * 298 x 401 portrait sits 33 in from the left and 31 down, the copy column
 * starts 31 past it, and the close sits 36 in from the right.
 *
 * The 649 is Graeme's bio, which is the longest of the five. Height is left to
 * the content here and capped against the viewport instead, so the shorter
 * profiles do not open with dead space under them.
 */
.team-bio {
    width: calc(1143 * var(--tgc-u));
    max-width: calc(100vw - calc(40 * var(--tgc-u)));
    max-height: 86vh;
    /*
     * A modal dialog is centred by the UA's `margin: auto`, which common.css
     * wipes with its `* { margin: 0 }` reset — so it has to be restored here or
     * the panel opens against the top-left.
     */
    inset: 0;
    margin: auto;
    padding: 0;
    border: 1px solid var(--tgc-placeholder);
    border-radius: calc(10 * var(--tgc-u));
    background-color: var(--theme-white);
    color: var(--tgc-ink);
    overflow: hidden;
}

.team-bio::backdrop {
    /* Figma blurs the page behind rather than dimming it. */
    background-color: rgba(252, 249, 240, 0.55);
    backdrop-filter: blur(calc(6 * var(--tgc-u)));
    -webkit-backdrop-filter: blur(calc(6 * var(--tgc-u)));
}

.team-bio__inner {
    position: relative;
    display: grid;
    grid-template-columns: calc(298 * var(--tgc-u)) minmax(0, 1fr);
    gap: calc(31 * var(--tgc-u));
    padding: calc(31 * var(--tgc-u)) calc(36 * var(--tgc-u)) calc(32 * var(--tgc-u)) calc(33 * var(--tgc-u));
    max-height: 86vh;
    overflow-y: auto;
}

/* The portrait column: the LinkedIn disc, when there is one, is centred 30
   under the portrait (Figma node 472:2427). */
.team-bio__aside {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: calc(30 * var(--tgc-u));
}

.team-bio__portrait {
    width: calc(298 * var(--tgc-u));
    aspect-ratio: 298 / 401;
    border-radius: calc(10 * var(--tgc-u));
    overflow: hidden;
    background-color: var(--tgc-violet-soft);
    display: flex;
    align-items: center;
    justify-content: center;
}

.team-bio__initials {
    font-family: var(--tgc-font-display);
    font-size: calc(48 * var(--tgc-ut));
    font-weight: 500;
    letter-spacing: 0.04em;
    color: var(--tgc-violet);
}

.team-bio__portrait img,
.team-bio__canvas {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* The exported mark is the whole 65px disc, as in the footer: the disc takes
   currentColor and the glyph --tgc-social-glyph, which defaults to white. */
.team-bio__social {
    display: block;
    width: calc(65 * var(--tgc-u));
    height: calc(65 * var(--tgc-u));
    border-radius: 50%;
    color: var(--tgc-violet);
    transition: color 0.2s ease;
}

.team-bio__social:hover,
.team-bio__social:focus-visible {
    color: var(--tgc-violet-dark);
}

.team-bio__social svg {
    display: block;
    width: 100%;
    height: 100%;
}

/* The guarded portrait is a frame of tile layers (scripts/tgc-guard.js). */
.team-bio__canvas {
    position: relative;
}

.team-bio__canvas > canvas {
    position: absolute;
    display: block;
}

/* No "Save image as" on a guarded portrait or name, including the name where
   it is painted inline in the bio copy: the pointer passes through to what is
   behind (see styles/blocks/team-grid.css). */
.team-bio__canvas,
.team-bio__name-canvas,
.team-bio__word > canvas {
    pointer-events: none;
    -webkit-user-select: none;
    user-select: none;
}

/*
 * A name painted inline in the bio copy: a stretched no-break space that
 * takes the selection highlight like any word, with the painted canvas laid
 * over it (scripts/tgc-guard.js).
 */
.team-bio__word {
    position: relative;
}

.team-bio__word > canvas {
    position: absolute;
    top: 0;
    left: 0;
    /* The slot's stretching letter-spacing must not reach the painted word. */
    letter-spacing: normal;
}

/*
 * The painted name cannot follow a selection colour change, and some systems
 * (Windows among them) turn selected text white. So the bio copy sets its own
 * highlight and keeps the text colour, and the painted word matches either way.
 */
.team-bio__text ::selection {
    background-color: var(--tgc-lilac);
    color: var(--tgc-ink-muted);
}

/* The copy column stops short of the close, which is why it is not the full
   width of what is left. */
.team-bio__body {
    max-width: calc(676 * var(--tgc-u));
}

.team-bio__name {
    font-size: calc(20 * var(--tgc-ut));
    font-weight: 600;
    line-height: calc(30 * var(--tgc-ut));
    color: var(--tgc-ink);
}

/* Holds its line before the painter sizes it, so the role does not jump. */
.team-bio__name-canvas {
    display: block;
    height: calc(30 * var(--tgc-ut));
    max-width: 100%;
}

.team-bio__role {
    font-size: calc(20 * var(--tgc-ut));
    font-weight: 500;
    line-height: calc(30 * var(--tgc-ut));
    color: var(--tgc-ink);
}

/*
 * Figma sets 16px, which the type floor scales to 13.6 on a 1440 laptop —
 * too small for several hundred words someone actually reads. Floored at 15
 * so it stays below the 17px name without becoming hard work.
 */
.team-bio__text {
    margin-top: calc(20 * var(--tgc-u));
    font-size: max(15px, calc(16 * var(--tgc-ut)));
    font-weight: 500;
    line-height: max(25px, calc(26 * var(--tgc-ut)));
    color: var(--tgc-ink-muted);
}

.team-bio__text p + p {
    margin-top: calc(26 * var(--tgc-u));
}

.team-bio__close {
    position: absolute;
    top: calc(41 * var(--tgc-u));
    right: calc(36 * var(--tgc-u));
    display: flex;
    align-items: center;
    justify-content: center;
    /* Figma draws a 15px glyph; the target around it is finger-sized. */
    width: calc(40 * var(--tgc-u));
    height: calc(40 * var(--tgc-u));
    margin: calc(-12 * var(--tgc-u)) calc(-12 * var(--tgc-u)) 0 0;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: none;
    color: var(--tgc-ink);
    cursor: pointer;
    transition: background-color 0.2s ease, color 0.2s ease;
}

.team-bio__close:hover {
    background-color: var(--tgc-violet-soft);
    color: var(--tgc-violet);
}

.team-bio__close svg {
    width: calc(15 * var(--tgc-u));
    height: calc(15 * var(--tgc-u));
}

/* Open/close. The dialog is display:none when shut, so the entry runs from a
   class the script adds on the frame after showModal(). */
.team-bio[open] {
    animation: team-bio-in 0.28s cubic-bezier(0.22, 1, 0.36, 1);
}

.team-bio[open]::backdrop {
    animation: team-bio-backdrop-in 0.28s ease;
}

.team-bio.is-closing {
    animation: team-bio-out 0.18s ease forwards;
}

.team-bio.is-closing::backdrop {
    animation: team-bio-backdrop-in 0.18s ease reverse;
}

@keyframes team-bio-in {
    from {
        opacity: 0;
        transform: translateY(calc(12 * var(--tgc-u))) scale(0.98);
    }
}

@keyframes team-bio-out {
    to {
        opacity: 0;
        transform: scale(0.99);
    }
}

@keyframes team-bio-backdrop-in {
    from {
        opacity: 0;
    }
}

@media (max-width: 968px) {
    .team-bio {
        width: calc(100vw - 32px);
        max-height: 88vh;
    }

    .team-bio__inner {
        grid-template-columns: minmax(0, 1fr);
        gap: 20px;
        padding: 20px;
        max-height: 88vh;
    }

    /* Portrait above the copy, and not so tall that the bio is pushed off. */
    .team-bio__portrait {
        width: 180px;
        margin: 0 auto;
    }

    .team-bio__close {
        top: 8px;
        right: 8px;
        margin: 0;
    }
}

@media (prefers-reduced-motion: reduce) {
    .team-bio[open],
    .team-bio[open]::backdrop,
    .team-bio.is-closing,
    .team-bio.is-closing::backdrop {
        animation: none;
    }
}
