/**
 * GF-02 Kopfzeile
 */

.header {
    /* Where the search sheet hangs from the top of the screen; on the narrow one it covers the
       menu it was opened from, so it starts at its upper edge. */
    --sav-header-search-top: 0px;

    display: grid;
    grid-template-areas:
        'home burger'
        'menu menu';
    grid-template-columns: 1fr auto;
    /* 46px, the height the burger holds before it leaves the flow. */
    grid-template-rows: 2.875rem auto;
    align-items: center;
    gap: 2rem;

    /* The page margin comes on top of the content width instead of off it, so the content
       is the 1350px the design draws — the same width a wide block and the footer get, and
       the same one the mark below already places itself by. */
    max-width: calc(var(--sav-content-width) + 2 * var(--sav-page-margin));
    margin-inline: auto;
    padding: 1.875rem var(--sav-page-margin);

    @media (width >= 64rem) {
        /* The sheet covers the logo and leaves the service row standing, as the design draws
           it: the 20px above that row, its own 36px and 24px to the edge of the sheet. */
        --sav-header-search-top: calc(1.25rem + 2.25rem + 1.5rem);

        /* 37px, the height of the service row the navigation stands below. */
        --header-service-height: 2.3125rem;

        grid-template-areas:
            'service service'
            'home navigation';
        /* 64px, the height the navigation holds before it leaves the flow. */
        grid-template-rows: auto 4rem;
        gap: 4.0625rem 2rem;
        /* 20px above, as every page of the design draws it; 40px below. */
        padding-block: 1.25rem 2.5rem;
    }
}

/* Only the artwork is the link: as a block it would stretch across its grid column and
   catch clicks in the empty space next to the logo. */
.header__home {
    grid-area: home;
    display: inline-flex;
    justify-self: start;
}

/* The logo of the open sheet stands beside its close button, on the row the header's own logo sits
   on. From the wide breakpoint on the sheet is that header row itself and already carries a logo,
   so this one is taken out of the grid rather than made invisible, which would leave its place in
   the row standing empty. */
.header__home--menu {
    align-self: center;

    @media (width >= 64rem) {
        display: none;
    }
}

/* The mark stands in the margin beside the content, from the moment the logo above has left
   the screen until it is back. It comes in from the side the logo sits on and never gets
   closer to the edge of the window than the page margin; below the wide breakpoint there is
   no margin to stand in. Without the script that watches the logo it never appears — it
   repeats what the header says anyway. */
.header__mark {
    display: none;

    @media (width >= 64rem) {
        display: block;
        position: fixed;
        z-index: 1;
        top: 2.5rem;
        left: max(var(--sav-page-margin), calc(50% - var(--sav-content-width) / 2 - 5rem));
        width: 60px;
        /* Keeps the link out of the tab order while the mark is not shown. */
        visibility: hidden;
        opacity: 0;
        translate: 40px 0;
        transition:
            opacity var(--sav-duration-fade) var(--sav-ease-out),
            translate var(--sav-duration-fade) var(--sav-ease-out),
            visibility var(--sav-duration-fade);
        transition-behavior: allow-discrete;

        &.header__mark--visible {
            visibility: visible;
            opacity: 1;
            translate: 0 0;
        }

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

        @media (prefers-reduced-motion: reduce) {
            translate: none;

            &.header__mark--visible {
                translate: none;
            }
        }
    }
}

/* The logo is drawn at its design width; height follows the artwork so a new
   file with different proportions does not need a change here. */
.header__logo {
    width: 231px;
    height: auto;

    @media (width >= 64rem) {
        width: 349px;
    }
}

/* Burger and close button are the same round grey field, one in the header, one in the
   open menu at the very same spot. */
.header__burger,
.header__close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 60px;
    height: 46px;
    padding: 0;
    border: 0;
    border-radius: 999px;
    background-color: var(--sav-color-hellgrau);
    color: var(--sav-color-dunkelblau);
    cursor: pointer;

    > svg {
        width: 24px;
        height: 24px;
    }

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

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

    @media (width >= 64rem) {
        display: none;
    }
}

.header__burger {
    grid-area: burger;
    position: fixed;
    z-index: 1;
    top: 1.875rem;
    right: var(--sav-page-margin);
}

.header__close {
    grid-area: close;
    justify-self: end;
}

/* Closed, the overlay stands ready but hidden; open, it takes the screen, and only its upper part
   is the white sheet. It owns the whole screen so that every press lands on something of its own —
   the sheet or the field closing it — rather than reaching the page. From the wide breakpoint on it
   is not an overlay at all: its children take their own place in the header grid. */
.header__menu {
    grid-area: menu;

    /* A modal dialog makes what is under it unusable, not unmovable. Only below the breakpoint,
       where the menu is this overlay: above it, a window dragged wide would leave the page
       locked behind a menu that is no longer one. */
    @media (width < 64rem) {
        html:has(&[open]) {
            overflow: hidden;
            /* Stands in for the scrollbar the lock takes away, or the page under the sheet jumps
               sideways wherever scrollbars hold a place of their own. */
            scrollbar-gutter: stable;
        }
    }

    /* Hidden by `visibility` rather than by the `display` the platform gives a closed dialog:
       hiding it that way would have to be animated for the sheet to fade out at all, and the
       breakpoint changes `display` too — so dragging the window narrow left the open sheet's
       contents standing in the header for the length of the fade. `visibility` keeps the
       closed sheet out of the accessibility tree and out of the tab order all the same. */
    display: grid;
    visibility: hidden;

    /* A sheet on its way out still stands over the page for the length of the fade, and a click
       on the burger during it would land on the sheet instead of the button. */
    pointer-events: none;

    /* Fixed rather than placed in the flow: a closing sheet leaves the top layer at once, and
       from its place in the header grid it would slide down into the page while it fades. */
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100dvh;
    max-width: none;
    max-height: none;
    margin: 0;
    padding: 0;
    border: 0;

    /* The white belongs to the sheet, the rest of the screen shows the page through the dim. */
    background: none;
    opacity: 0;
    transition-property: opacity, visibility, overlay;
    transition-duration: var(--sav-duration-unfold);
    transition-timing-function: var(--sav-ease-out);
    transition-behavior: allow-discrete;

    /* The sheet takes what it needs and the field closing it takes the rest. `minmax(0, auto)`,
       or a menu with every panel unfolded would push its lower part off the screen instead of
       scrolling inside itself. */
    grid-template-rows: minmax(0, auto) 1fr;

    /* The page stays visible under the sheet and is dimmed, which is what tells the sheet from
       a screen of its own. */
    &::backdrop {
        background-color: rgb(0 0 0 / 0.15);

        /* Comes with the sheet instead of darkening the page before it is there. */
        opacity: 0;
        transition-property: opacity, display, overlay;
        transition-duration: var(--sav-duration-unfold);
        transition-timing-function: var(--sav-ease-out);
        transition-behavior: allow-discrete;
    }

    &[open]::backdrop {
        opacity: 1;

        @starting-style {
            opacity: 0;
        }
    }

    &[open] {
        visibility: visible;
        opacity: 1;
        pointer-events: auto;
    }

    @media (prefers-reduced-motion: reduce) {
        transition-duration: 150ms;

        &::backdrop {
            transition-duration: 150ms;
        }
    }

    /* Also while open: a window that grows past the breakpoint with the menu open turns it
       back into the plain header row rather than leaving a sheet behind. */
    @media (width >= 64rem) {
        &,
        &[open],
        > .header__sheet {
            display: contents;
        }

        /* The overlay itself stays hidden — it has no box here anyway — and only what it holds is
           shown again. Turning it visible instead would fade it back to hidden on the way to
           the narrow layout, and half a second of an invisible full-screen sheet is half a
           second of catching clicks and standing in the tab order. */
        .header__sheet > * {
            visibility: visible;
            pointer-events: auto;
        }
    }
}

/* The white box the design draws, as far down as what it holds and no further. */
.header__sheet {
    /* The rows belong to the sheet itself, not to the open state of the overlay: a state only
       holds while the attribute is there, and the layout would fall apart the moment it goes —
       with the content jumping into a single row while the sheet is still fading. The children
       keep the area names they carry in the header grid, so the rows are named the same way. */
    display: grid;
    grid-template-areas:
        'home close'
        'navigation navigation'
        'service service';
    grid-template-columns: 1fr auto;
    align-content: start;
    gap: 2rem;
    min-block-size: 0;
    padding: 1.875rem var(--sav-page-margin);
    overflow-y: auto;

    /* A sheet scrolled to its end hands the rest of the gesture to the page behind it. */
    overscroll-behavior: contain;
    background-color: var(--sav-color-weiss);
}

/* What is left of the screen beside the sheet: a control, so the press that ends the sheet is one
   the field has taken. Nothing is drawn — the dim belongs to the backdrop behind it. */
.header__dismiss {
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;

    @media (width >= 64rem) {
        display: none;
    }
}

.header__navigation {
    grid-area: navigation;

    @media (width >= 64rem) {
        /* 122px: the row the bar shares with the logo, below the service row and the gap. */
        --header-navigation-top: calc(1.25rem + var(--header-service-height) + 4.0625rem);

        /* 82px, up to the 40px the bar comes to rest at. */
        --header-navigation-travel: calc(var(--header-navigation-top) - 2.5rem);

        /* Unsupported, the shorthand would run against the document timeline and be over
           before the first paint, leaving the bar at rest above an unscrolled page. */
        @supports (animation-timeline: scroll()) {
            position: fixed;
            z-index: 1;

            /* A page too short to scroll keeps it here: that timeline never runs. */
            top: var(--header-navigation-top);
            right: max(var(--sav-page-margin), calc(50% - var(--sav-content-width) / 2));
            animation: header-navigation-settle linear both;
            animation-timeline: scroll();
            animation-range: 0 var(--header-navigation-travel);
        }
    }
}

/* Tied to the scroll position rather than to a duration, so there is no motion of its own
   to reduce. */
@keyframes header-navigation-settle {
    to {
        translate: 0 calc(-1 * var(--header-navigation-travel));
    }
}

/* What the sheet holds settles into place when it opens; the button that closes it stands
   still, on the very spot the burger stood on, so the one reads as the other. The way back
   carries no movement — the sheet is fading, and content sliding underneath it looks like an
   accident. */
@media (width < 64rem) {
    /* An animation rather than a transition: it runs the moment the sheet opens and leaves no
       state behind, so closing it drops the movement instead of playing it backwards. */
    .header__menu[open] .header__navigation,
    .header__menu[open] .header__service {
        animation: header-menu-settle var(--sav-duration-unfold) var(--sav-ease-out);

        @media (prefers-reduced-motion: reduce) {
            animation: none;
        }
    }
}

@keyframes header-menu-settle {
    from {
        translate: 0 -0.75rem;
    }
}

.header__service {
    grid-area: service;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1.5rem;

    /* The service links sit left, everything after them right, without a
       wrapper of their own. */
    .service-navigation {
        margin-inline-end: auto;
    }

    /* Stacked in the sheet, the links no longer fill the row, and the two fields beside them would
       move up next to «Offene Stellen» instead of standing under the list. The stacking itself
       belongs to the navigation. */
    @media (width < 64rem) {
        .service-navigation {
            inline-size: 100%;
            margin-inline-end: 0;
        }
    }
}

.header__search {
    display: inline-flex;
    align-items: center;
    padding: 0;
    border: 0;
    background: none;
    color: var(--sav-color-dunkelblau);
    cursor: pointer;

    > svg {
        width: 26px;
        height: 26px;
    }

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

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

    /* In the menu the design draws the search as a field across the whole column, from the wide
       breakpoint on as the magnifier alone. */
    @media (width < 64rem) {
        justify-content: space-between;
        gap: 1rem;
        inline-size: 100%;
        min-block-size: 3.75rem;
        padding-inline: 1.5rem;
        border-radius: 6.25rem;
        background-color: var(--sav-color-hellgrau);
    }
}

.header__search-label {
    /* The size the design gives the field in the sheet, in place of the smaller one a narrow screen
       would interpolate to. */
    font-size: 1rem;
    line-height: 1.625rem;

    @media (width >= 64rem) {
        display: none;
    }
}

.header__extranet {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 2.25rem;
    padding: 0.25rem 1.25rem;
    border: 1px solid var(--sav-color-dunkelblau);
    border-radius: 999px;
    color: var(--sav-color-dunkelblau);
    font-size: var(--sav-text-xs-size);
    line-height: var(--sav-text-xs-line);
    text-decoration: none;

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

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