/**
 * KO-03 Button
 */

/* `.button__link` is the button itself and carries its whole appearance — variant, size,
   states, arrow. `.button` is only the box WordPress lays out around the block, so a
   component that places a button somewhere else needs the wrapper and its classes not at
   all. Medium is the default size; `--small` and `--large` are set by the embedding
   component — on the button itself where it embeds the partial, and as
   `data-button-size` on a box around it where the button arrives as a block of its own and
   carries no class the embedding component could add.

   Every step shrinks towards mobile, taken from the text styles the design binds to
   each instance: medium 46 → 36 px (16/26 → 14/22, the `xs` steps of the scale) and
   large 56 → 46 px (20/32 → 18/28, whose line-height is the `m` step while the size
   sits between two steps and is interpolated here). A height is the line-height plus
   the block padding plus the 1 px border, so the padding scales along. */
.button__link {
    --button-padding-inline: 2rem;
    --button-icon: 1.25rem;
    --button-icon-gap: 0.5rem;

    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding-block: clamp(0.375rem, 0.3204rem + 0.2242vw, 0.5625rem);
    padding-inline: var(--button-padding-inline);
    border: 1px solid transparent;
    border-radius: 3.125rem;
    font-size: var(--sav-text-xs-size);
    line-height: var(--sav-text-xs-line);
    font-weight: var(--sav-font-weight-regular);
    text-decoration: none;

    /* A link brings the pointer along, a real button element does not. */
    cursor: pointer;

    /* Motion is the enhancement, so it is asked for rather than taken away. The padding is
       named as its two longhands: WebKit runs no transition for the `padding-inline`
       shorthand, and the button would snap narrower while the arrow slides in. */
    @media (prefers-reduced-motion: no-preference) {
        transition:
            color 0.2s,
            background-color 0.2s,
            border-color 0.2s,
            padding-inline-start 0.2s,
            padding-inline-end 0.2s;
    }

    &:focus-visible {
        outline: 2px solid var(--sav-color-dunkelblau);
        outline-offset: 2px;
    }

    /* The arrow slides into the padding, so a button keeps its width and stops nudging its
       neighbours on hover — the styleguide draws both states equally wide. Only where an
       arrow exists: the editor renders the label alone and would otherwise just shrink.
       Tertiary has no padding to give and grows by the arrow instead. */
    &:is(.button__link--primary, .button__link--secondary):not(.button__link--no-arrow):has(.button__icon):is(
            :hover,
            :active
        ) {
        padding-inline: calc(var(--button-padding-inline) - (var(--button-icon) + var(--button-icon-gap)) / 2);
    }
}

/* Smaller and larger size step. The small arrow shrinks along with the label, since an
   arrow taller than the line box would stretch the button past its 36 px. */
.button__link--small {
    --button-padding-inline: 1.5rem;
    --button-icon: 0.875rem;

    padding-block: 0.625rem;
    font-size: var(--sav-text-label-size);
    line-height: var(--sav-text-label-line);
}

/* 18 → 20 px: the scale steps around it (18 → 22 and 16 → 20), so this one pair is
   interpolated here instead of coming from a token. The inner padding narrows towards
   mobile as well, 32 → 24 px, which is the only size that does. */
.button__link--large,
[data-button-size='large'] .button__link {
    --button-padding-inline: clamp(1.5rem, 1.5rem + (100vw - 24.375rem) * 0.005979, 2rem);

    padding-block: clamp(0.5rem, 0.4454rem + 0.2242vw, 0.6875rem);
    font-size: clamp(1.125rem, 1.0886rem + 0.1495vw, 1.25rem);
    line-height: var(--sav-text-m-line);
}

/* Primary — filled, darkening on interaction. */
.button__link--primary {
    background-color: var(--sav-color-dunkelblau);
    color: var(--sav-color-weiss);

    &:hover,
    &:active {
        background-color: var(--sav-color-dunkelblau-hover);
    }
}

/* Secondary — an outline that fills on interaction. */
.button__link--secondary {
    border-color: var(--sav-color-dunkelblau);
    color: var(--sav-color-dunkelblau);

    &:hover,
    &:active {
        background-color: var(--sav-color-dunkelblau);
        color: var(--sav-color-weiss);
    }
}

/* Tertiary — text only; after the sizes so it stays text at any size. */
.button__link--tertiary {
    padding: 0;
    border: 0;
    color: var(--sav-color-dunkelblau);
    font-size: 1.125rem;
    line-height: 1.5625rem;

    &:hover,
    &:active {
        color: var(--sav-color-dunkelblau-hover);
    }
}

/* The arrow is a hover affordance: the icon is hidden at rest and slides in on hover,
   in every variant. `--no-arrow` is the second primary row of the styleguide, which
   stays bare on hover, and `--arrow-down` turns the arrow downwards (e.g. a download).
   It inherits the text colour through `currentColor` on the inlined SVG. */
.button__icon {
    display: flex;
    flex: none;
    inline-size: 0;
    block-size: var(--button-icon);
    margin-inline-start: 0;
    overflow: hidden;
    opacity: 0;

    @media (prefers-reduced-motion: no-preference) {
        transition:
            inline-size 0.2s,
            margin-inline-start 0.2s,
            opacity 0.2s;
    }

    & svg {
        inline-size: var(--button-icon);
        block-size: var(--button-icon);
    }

    .button__link:not(.button__link--no-arrow):is(:hover, :active) & {
        inline-size: var(--button-icon);
        margin-inline-start: var(--button-icon-gap);
        opacity: 1;
    }

    /* Wherever the hover above cannot be reached — the same condition, negated — the state it
       would bring is the one the link rests in, or the arrow the design draws is never seen on a
       touch screen. The tertiary variant alone: the design draws the arrow beside a text link, and
       the filled variants carry their label without one. */
    @media not ((hover: hover) and (pointer: fine)) {
        .button__link--tertiary:not(.button__link--no-arrow) & {
            inline-size: var(--button-icon);
            margin-inline-start: var(--button-icon-gap);
            opacity: 1;
        }
    }

    .button__link--arrow-down & {
        rotate: 90deg;
    }
}
