.topic-tile {
    /* How far one tile rests below the one before it while they stack, and so how much stays showing. */
    --topic-tile-stack-step: 6rem;

    /* 32px → 40px */
    --topic-tile-marker-size: clamp(2rem, 2rem + (100vw - 24.375rem) * 0.00598, 2.5rem);

    position: relative;
    display: grid;
    grid-template-columns: 1fr auto;

    /* The name at the top, the text at the bottom, the gap the least they keep from each other. */
    grid-template-rows: auto 1fr;
    gap: 2rem;
    padding: 2rem;

    /* 38px → 48px */
    padding-block-end: clamp(2.375rem, 2.375rem + (100vw - 24.375rem) * 0.00748, 3rem);

    /* The drawn proportion as a least height; a tile needing more room grows past it and takes the
       row along. One tile is the row less its gutters, in thirds from the wide breakpoint on. */
    min-block-size: calc(100cqw * 420 / 350);
    border-radius: var(--sav-radius);
    background-color: var(--sav-topic-light);
    color: var(--sav-color-dunkelblau);

    @media (width >= 64rem) {
        min-block-size: calc((100cqw - 2 * var(--sav-grid-gutter)) / 3 * 573 / 430);
    }

    @media (prefers-reduced-motion: no-preference) {
        transition: background-color 0.2s;
    }

    /* Stacked, the tiles slide over one another down the page and apart again on the way up.
       A tile lets go of its step once its margin box reaches the end of the list, so step plus room
       below has to match across them — or the one resting deepest lets go first and is dragged
       across the others. Each tile pulls its predecessor's room back in so the three still rest
       where the design puts them. */
    @media (width < 64rem) and (prefers-reduced-motion: no-preference) {
        position: sticky;
        inset-block-start: calc(var(--sav-header-height, 0px) + var(--topic-tile-stack, 0rem));

        &:first-child {
            margin-block-end: calc(2 * var(--topic-tile-stack-step));
        }

        &:nth-child(2) {
            --topic-tile-stack: var(--topic-tile-stack-step);

            margin-block-start: calc(-2 * var(--topic-tile-stack-step));
            margin-block-end: var(--topic-tile-stack-step);
        }

        &:nth-child(3) {
            margin-block-start: calc(-1 * var(--topic-tile-stack-step));
        }

        /* As deep as the stack goes; a fourth tile would rest on the same step. */
        &:nth-child(n + 3) {
            --topic-tile-stack: calc(2 * var(--topic-tile-stack-step));
        }
    }

    /* Only a tile that leads somewhere answers the pointer. */
    &:has(.topic-tile__link):hover,
    &:has(.topic-tile__link:focus-visible) {
        background-color: var(--sav-topic-strong);
    }

    /* The ring belongs on the tile, since the link covers it whole. */
    &:has(.topic-tile__link:focus-visible) {
        outline: 2px solid var(--sav-color-dunkelblau);
        outline-offset: 2px;
    }

    /* `[hidden]` is a user agent rule and loses to the author `display` above. */
    &[hidden] {
        display: none;
    }
}

.topic-tile__title {
    grid-row: 1;
    grid-column: 1;
}

.topic-tile__link {
    color: inherit;
    text-decoration: none;

    /* Stretched over the tile, so one link in the tab order carries the whole of it. Its text stops
       being selectable, which is the price. */
    &::after {
        position: absolute;
        inset: 0;
        content: '';
    }

    &:focus-visible {
        outline: none;
    }
}

.topic-tile__marker {
    display: flex;
    grid-row: 1;
    grid-column: 2;
    align-items: center;
    justify-content: center;
    inline-size: var(--topic-tile-marker-size);
    block-size: var(--topic-tile-marker-size);
    border: 1.5px solid currentcolor;
    border-radius: 50%;

    /* 25.6px of the 40px disc: the glyph fills 62.5% of its own box, the design's arrow 40% of the
       disc. Off the disc rather than in per cent, which the border would eat into. */
    & .icon {
        inline-size: calc(var(--topic-tile-marker-size) * 0.64);
        block-size: calc(var(--topic-tile-marker-size) * 0.64);
    }

    /* The arrow waits inside the padding edge and slides out onto it while the tile is pointed at —
       only where there is a pointer; elsewhere it stands on the edge, as the phone is drawn. */
    @media (hover: hover) and (pointer: fine) {
        translate: -0.375rem 0;

        @media (prefers-reduced-motion: no-preference) {
            transition: translate var(--sav-duration-fade) var(--sav-ease-out);
        }

        :is(.topic-tile:hover, .topic-tile:has(.topic-tile__link:focus-visible)) & {
            translate: 0 0;
        }
    }
}

.topic-tile__text {
    grid-row: 2;
    grid-column: 1 / -1;
    align-self: end;
}
