@layer {
    *,
    *::after,
    *::before {
        box-sizing: border-box;
    }

    :focus-visible {
        outline-offset: 3px;
    }

    html {
        -webkit-text-size-adjust: none;
        text-size-adjust: none;

        line-height: 1.5;
        scrollbar-gutter: stable;
    }

    body{
        margin: 0;
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
    }

    abbr[title] {
        cursor: help;
        text-decoration-line: underline;
        text-decoration-style: dotted;
    }

    /* Links are never the UA blue — they always take the colour of their context.
       The underline is always present but transparent, so it can fade in on
       hover/focus; `text-decoration: none` would leave nothing to transition. */
    a {
        color: currentColor;
        text-decoration-color: transparent;
        transition: text-decoration-color var( --duration-s ) ease-out;
    }

    a:hover,
    a:focus-visible {
        text-decoration-color: currentColor;
    }

    /* Running text is the exception. A link here takes the colour of the prose
       around it, so with the underline hidden there is nothing whatsoever to
       tell it apart until the pointer finds it — and nothing at all for someone
       not using a pointer. The design draws these underlined; hovering thickens
       the line rather than revealing it. */
    :is( .fliesstext, .seiten-text, .bewerbung-hinweis, .job-beschreibung ) a {
        text-decoration-color: currentColor;
        text-decoration-thickness: from-font;
        transition: text-decoration-thickness var( --duration-s ) ease-out;
    }

    :is( .fliesstext, .seiten-text, .bewerbung-hinweis, .job-beschreibung ) a:hover,
    :is( .fliesstext, .seiten-text, .bewerbung-hinweis, .job-beschreibung ) a:focus-visible {
        text-decoration-thickness: 2px;
    }

    @media (forced-colors: active) {
        mark {
            color: HighlightText;
            background-color: Highlight;
        }
    }

    audio,
    iframe,
    img,
    svg,
    video {
        max-block-size: 100%;
        max-inline-size: 100%;
    }

    fieldset {
        min-inline-size: 0;
    }

    label:has(+ input:not([type="radio"], [type="checkbox"]), select, textarea) {
        display: block;
    }

    textarea:not([rows]) {
        min-block-size: 6em;
    }

    button,
    input,
    select,
    textarea {
        font-family: inherit;
        font-size: inherit;
    }

    [type="search"] {
        -webkit-appearance: textfield;
    }

    @supports (-webkit-touch-callout: none) {
        [type="search"] {
            border: 1px solid -apple-system-secondary-label;
            background-color: canvas;
        }
    }

    input:where([type="tel"], [type="url"], [type="email"], [type="number"]):not(:placeholder-shown) {
        direction: ltr;
    }

    table {
        border-collapse: collapse;
        border: 1px solid;
    }

    th,
    td {
        border: 1px solid;
        padding: 0.25em 0.5em;
        vertical-align: top;
    }

    dialog::backdrop {
        background: oklch(0% 0 0 / 0.3);
    }

    dialog,
    [popover],
    dialog::backdrop {
        opacity: 0;
        transition: opacity var( --duration-s ) ease-out,
        display var( --duration-s ) allow-discrete,
        overlay var( --duration-s ) allow-discrete;
    }

    dialog[open],
    :popover-open,
    dialog[open]::backdrop {
        opacity: 1;
    }

    @starting-style {
        dialog[open],
        :popover-open,
        dialog[open]::backdrop {
            opacity: 0;
        }
    }

    @media (prefers-reduced-motion: reduce) {
        dialog,
        [popover],
        dialog::backdrop {
            transition: none;
        }
    }

    [hidden]:not([hidden="until-found"]) {
        display: none !important;
    }

    img {
        display: block;
        /* max-inline-size above constrains the width; without this the height
           attribute keeps its value and the picture is squashed. Every image
           that needs a fixed height overrides this. */
        block-size: auto;
    }

    summary {
        cursor: default;
    }

    iframe {
        border: none;
    }

    @supports(position-area: block-end span-inline-end) {
        [popover] {
            margin: 0;
            position-area: block-end span-inline-end;
        }
    }

    h1, h2, h3, h4, h5, h6{ font-weight: normal; }
    h1, h2, h3, h4, h5, h6, p, ul, ol{  margin: 0; padding: 0; }

    .visually-hidden:not(:focus):not(:active) {
        clip-path: inset(50%);
        block-size: 1px;
        inline-size: 1px;
        overflow: hidden;
        position: absolute;
        white-space: nowrap;
    }
}

@font-face {
    font-family: "Unica";
    src: url("/assets/webfonts/Unica77LLWeb-Regular.woff2") format("woff2");
    font-weight: normal;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "GT Alpina";
    src: url("/assets/webfonts/GT-Alpina-Standard-Regular.woff2") format("woff2");
    font-weight: normal;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "GT Alpina";
    src: url("/assets/webfonts/GT-Alpina-Standard-Bold.woff2") format("woff2");
    font-weight: bold;
    font-style: normal;
    font-display: swap;
}

html{
    --color-green-light: #9BE16D;
    --color-green-dark: #034825;
    --color-blue-light: #AAE1FF;
    --color-blue-dark: #001B85;
    --color-orange: #FF5D01;
    --color-red: #D92A03;
    --color-yellow: #FFE603;
    --color-plume: #8C003B;
    --color-rose: #FFBEFF;
    --color-grey-light: #DADADA;
    --color-grey-dark: #999999;

    /* The design draws both the field border and its placeholder in
       --color-grey-dark, which is 2.85:1 on white — under the 3:1 a control's
       boundary needs and well under the 4.5:1 its text needs. These are the
       nearest greys that pass: 3.03:1 for the border, 4.54:1 for the
       placeholder. */
    --color-feld-rand: #949494;
    --color-feld-platzhalter: #767676;
    --color-black: #000000;
    --color-white: #FFFFFF;

    --font-serif: "GT Alpina", serif;
    --font-sans-serif: "Unica", sans-serif;

    /* Spacing — every gap, padding and margin below snaps to one of these five.
       0.5rem steps up to --space-m, then 1rem steps. */
    --space-xs: 0.5rem;
    --space-s: 1rem;
    --space-m: 1.5rem;
    --space-l: 2.5rem;
    --space-xl: 3.5rem;

    --padding-side: var( --space-l );

    /* Type — the general scale, for sizes the design does not name as a style.
       Each interpolates between its value at 393px wide and at 1440px; the
       named styles below carry their own clamps. */
    --font-size-s: clamp( 1rem, 0.9061rem + 0.3821vw, 1.25rem );     /* 16 → 20 */
    --font-size-m: clamp( 1.25rem, 1.133rem + 0.478vw, 1.5625rem );  /* 20 → 25 */
    --font-size-l: clamp( 1.25rem, 1.0154rem + 0.9551vw, 1.875rem ); /* 20 → 30 */
    --font-size-xl: clamp( 1.5rem, 1.1246rem + 1.5282vw, 2.5rem );   /* 24 → 40 */
    --font-size-2xl: clamp( 2.5rem, 1.937rem + 2.292vw, 4rem );      /* 40 → 64 */
    --font-size-3xl: clamp( 4rem, 2.4988rem + 6.113vw, 8rem );       /* 64 → 128 */

    /* The design's named text styles. Figma names each one twice — a desktop
       style on the 1440 frames and a MOB_ style on the 393 ones — and the two
       do not sit on a common ratio: the big headline is 110/105 on desktop
       (0.955) but 55/58 on mobile (1.055). So size and line-height each
       interpolate between the two ends on their own, and a use site takes
       both halves rather than inventing a ratio from one.

                            desktop @1440              mobile @393
         --typo-headline     Alpina_Headline_01_110   110 / 105    MOB_Alpina_Headline_01    55 / 58
         --typo-band         Alpina_Headline_02_80     80 / 85     MOB:Unica_Headline_02     40 / 43
         --typo-subheadline  Alipina_Subheadline_40    40 / 43     MOB_Alpina_Headline_04    25 / 30
         --typo-lead         Unica_SubHeadline_40      40 / 46     Mob_Unica_Subheadline_25  25 / 30
         --typo-intro        Unica_IntroTexte_50       40 / 50     MOB_Unica_IntroText_25    25 / 30
         --typo-zitat        (Alpina, unnamed)         25 / 30     MOB_Alpina_Zitate         23 / 28
         --typo-liste        Unica_Liste_25            25 / 34     MOB_Unica_Liste           20 / 25
         --typo-text         Unica_Text_25             25 / 30     MOB_Unica_Text_20         20 / 25
         --typo-zeile        Unica_Text_30             30 / 36      (unnamed in Figma)        20 / 25
         --typo-klein        (unnamed in Figma)        20 / 25     MOB_Unica_Text_18         18 / 23
    */
    --typo-headline: clamp( 3.4375rem, 2.1472rem + 5.2531vw, 6.875rem );
    --typo-headline-lh: clamp( 3.625rem, 2.5224rem + 4.4890vw, 6.5625rem );
    --typo-band: clamp( 2.5rem, 1.5616rem + 3.8204vw, 5rem );
    --typo-band-lh: clamp( 2.6875rem, 1.7022rem + 4.0115vw, 5.3125rem );
    --typo-subheadline: clamp( 1.5625rem, 1.2106rem + 1.4327vw, 2.5rem );
    --typo-subheadline-lh: clamp( 1.875rem, 1.5700rem + 1.2416vw, 2.6875rem );
    --typo-lead: clamp( 1.5625rem, 1.2106rem + 1.4327vw, 2.5rem );
    --typo-lead-lh: clamp( 1.875rem, 1.4996rem + 1.5282vw, 2.875rem );
    --typo-intro: clamp( 1.5625rem, 1.2106rem + 1.4327vw, 2.5rem );
    --typo-intro-lh: clamp( 1.875rem, 1.4058rem + 1.9102vw, 3.125rem );
    --typo-zitat: clamp( 1.4375rem, 1.3906rem + 0.1910vw, 1.5625rem );
    --typo-zitat-lh: clamp( 1.75rem, 1.7031rem + 0.1910vw, 1.875rem );
    --typo-liste: clamp( 1.25rem, 1.1327rem + 0.4776vw, 1.5625rem );
    --typo-liste-lh: clamp( 1.5625rem, 1.3514rem + 0.8596vw, 2.125rem );
    --typo-text: clamp( 1.25rem, 1.1327rem + 0.4776vw, 1.5625rem );
    --typo-text-lh: clamp( 1.5625rem, 1.4452rem + 0.4776vw, 1.875rem );
    --typo-zeile: clamp( 1.25rem, 1.0154rem + 0.9551vw, 1.875rem );
    --typo-zeile-lh: clamp( 1.5625rem, 1.2814rem + 1.1461vw, 2.25rem );
    --typo-klein: clamp( 1.125rem, 1.0781rem + 0.1910vw, 1.25rem );
    --typo-klein-lh: clamp( 1.4375rem, 1.3906rem + 0.1910vw, 1.5625rem );

    /* The header and nav-dialog logos must match exactly, or the logo colour
       wipe when the nav rises will not line up — hence one shared value. */
    /* The line the design rules the site with. Drawn as a zero-height vector in
       Figma with the stroke spreading 1px either side of it — 2px in total, not
       the 1px it reads as on the canvas. Stated once so every rule agrees. */
    --linie: 2px solid var( --color-black );

    --logo-height: clamp( 3.875rem, 3.476rem + 1.624vw, 4.9375rem ); /* 62 → 79 */
    /* Exactly four lines of footer text, so the description below the logo lands
       on the same baseline as the address block in the next column. Resolves
       against the footer's own line-height, not this one. */
    --logo-height-footer: 4lh;

    --icon-size: 2.25rem;
    --radius-pill: 40px;

    /* The header is padding + logo, so this stays in step with it on its own.
       Used to size the start page intro to exactly one viewport. */
    --header-padding-block: var( --space-m );
    --header-height: calc( var( --logo-height ) + 2 * var( --header-padding-block ) );

    /* Expressed in lines of the description that sits in these rows, so the box
       keeps its proportion to the type at every width instead of being a fixed
       number that only suits one. 3.5lh is 161px at 1440 (the design draws ~156)
       and 97px at 393. Resolves against #intro's line-height, not this one.
       --intro-row-min is how far they may shrink once the yellow band has
       already reached its own minimum. */
    --intro-row: 3.5lh;
    --intro-row-min: 2lh;

    /* Motion */
    --duration-s: 150ms;
    --duration-m: 250ms;
    --duration-l: 400ms;
    --duration-xl: 750ms;
    --ease-out: cubic-bezier( 0.32, 0.72, 0, 1 );

    /* Only two layers exist; the skip link must clear the sticky header. */
    --z-header: 10;
    --z-skip-link: 20;
}

/* Narrower gutters on small screens. Overriding the token means everything that
   uses it — header, intro, footer, nav dialog — follows automatically. */
@media (width < 48rem){
    html{
        --padding-side: 1.25rem;

        /* The mobile frames give the header 81px for a 62px logo — the bar is
           tighter than on desktop, not merely narrower. (The black band above
           it in those frames is the phone's status bar, not part of the page.) */
        --header-padding-block: 0.625rem;
    }
}

body {
    font-family: var( --font-sans-serif );
    line-height: 1.25;

    /* Stated explicitly — without it the page picks up the UA's dark canvas
       when the OS is in dark mode, and the “white” sections render near-black. */
    background-color: var( --color-white );
    color: var( --color-black );
}

.lang-switcher ul {
    display: flex;
    gap: var( --space-s );
    list-style: none;
    margin-inline-end: 1rem;
}

/* Only the current language is underlined at rest; hover/focus is global.
   This one is a <span>, not an <a>, so it needs the line as well as the colour. */
.lang-switcher [aria-current] {
    text-decoration-line: underline;
    text-decoration-color: currentColor;
}

.content-width{
    padding-inline: var( --padding-side );
}

/* Never held back while something inside it has focus: tabbing to the logo or
   the menu button has to bring them on screen, not send focus somewhere
   invisible. */
#main-header:focus-within{
    translate: 0 0;
}

/* Parked just above the viewport rather than hidden, so it stays focusable and
   slides in on the first Tab. */
#skip-to-content-link{
    /* Fixed, not absolute: the header is sticky, so an absolute skip link would
       scroll out of view and focus would land on something off-screen.
       z-index clears the sticky header. */
    position: fixed;
    inset-block-start: 0;
    inset-inline-start: 0;
    z-index: var( --z-skip-link );

    margin: var( --space-xs );
    padding: var( --space-xs ) var( --space-s );

    background-color: var( --color-white );
    color: var( --color-black );

    translate: 0 -200%;
    transition: translate var( --duration-s ) ease-out;
}

#skip-to-content-link:focus{
    translate: 0 0;
}

@media (prefers-reduced-motion: reduce) {
    #skip-to-content-link{
        transition: none;
    }
}

.logo{
    /* A flex item by default may shrink, and shrinking this one distorts it —
       the height is fixed, so a narrower box just squashes the wordmark. */
    flex-shrink: 0;

    svg{
        display: block;

        /* An <svg> with only a viewBox has no intrinsic width, so a tight flex
           row shrinks it to nothing and the reset's max-inline-size: 100% then
           holds it there — the glyphs keep painting at full size outside the
           zero-wide box. Stating the ratio gives the height something to
           derive a width from, and flex-shrink: 0 stops the row taking it. */
        aspect-ratio: 1086.46 / 326.44;
        inline-size: auto;
        flex-shrink: 0;
    }

    /* Lets the same logo sit black on the header and white in the nav dialog. */
    path{
        fill: currentColor;
    }
}

#main-header{
    /* Sticky so the black logo stays behind the nav panel's wipe line at any
       scroll position — otherwise the colour change only works at scroll top. */
    position: sticky;
    inset-block-start: 0;
    z-index: var( --z-header );

    /* Held against the scroll: the offset the script keeps is the distance the
       reader has travelled down since they last turned round, so going down the
       header rides up at exactly the scroll's own rate and simply leaves with
       the content, and coming back up it returns at the same rate, revealing as
       they scroll rather than on a timer. No transition — the movement is the
       reader's own, and easing it would only make it lag behind. */
    translate: 0 calc( var( --kopf-versatz, 0px ) * -1 );

    .content-width{
        display: flex;
        justify-content: space-between;
        gap: var( --space-s );
    }

    background-color: var(--color-white );
    padding-block: var( --header-padding-block );

    .logo svg{
        height: var( --logo-height );
        width: auto;
    }

    /* All three header items — switcher, portal pill, Menü pill — are 30px in
       the design. Set once here; the pills inherit it (the reset makes buttons
       inherit font-size). */
    .links{
        display: flex;
        align-items: center;
        gap: var( --space-s );
        font-size: var( --font-size-l );
    }
}

/* ---- Pill ----------------------------------------------------------------
   Used for Klientenportal, Menü, “Mehr erfahren +”, “Jetzt bewerben!” …
   Markup: <a class="pill pill-solid"> or via the ui.pill() macro in _ui.twig.
   Inherits its font-size from the surrounding context. */
.pill{
    display: inline-flex;
    align-items: center;
    gap: var( --space-xs );

    /* Figma draws the pill with a 2px stroke, 23px of inline padding and a 60px
       box. Its own py-15 is measured against a cap-trimmed text box; the CSS
       line box is taller, so the block padding is what gives way: 7 + 7 padding
       + 2 + 2 border + 42 line box = the same 60px at the design's 30px type. */
    padding: 0.4375rem var( --space-m );
    border: 2px solid var( --color-black );
    border-radius: var( --radius-pill );

    line-height: 1.4;
    white-space: nowrap;
    cursor: pointer;
    /* Opts out of the global link underline — a pill reads as a button. */
    text-decoration: none;

    transition: background-color var( --duration-s ) ease-out,
                color var( --duration-s ) ease-out;
}

.pill-solid{
    background-color: var( --color-black );
    color: var( --color-white );
}

.pill-outline{
    background-color: var( --color-white );
    color: var( --color-black );
}

/* Hover/focus simply swaps the two variants’ fills. */
.pill-solid:hover,
.pill-solid:focus-visible{
    background-color: var( --color-white );
    color: var( --color-black );
}

.pill-outline:hover,
.pill-outline:focus-visible{
    background-color: var( --color-black );
    color: var( --color-white );
}

@media (prefers-reduced-motion: reduce){
    .pill{
        transition: none;
    }
}

.menu-toggle-icon{
    display: none;
}

/* The full header — switcher, Klientenportal, the Menü pill — needs about
   710px beside a 226px logo, so it only fits from roughly 960px up. Below that
   the header is the logo and the menu icon, as the mobile frames draw it. The
   design has no tablet frame; this is where the pieces stop fitting. */
@media (width < 60rem){
    #menu-toggle{
        padding: 0;
        border: none;
        border-radius: 0;
        background: none;
        color: var( --color-black );

        /* The icon is 30px, which would leave a 36px target. 44px is the size a
           finger actually needs; the negative margin keeps the icon itself on
           the 20px gutter so only the hit area grows. */
        display: grid;
        place-items: center;
        min-inline-size: 2.75rem;
        min-block-size: 2.75rem;
        margin-inline-end: -0.25rem;
    }

    .menu-toggle-text{
        display: none;
    }

    .menu-toggle-icon{
        display: block;
        inline-size: var( --icon-size );
    }

    .menu-toggle-icon svg{
        display: block;
        inline-size: 100%;
        block-size: auto;
    }

    /* Menü_Mobil draws the header as the logo and the plus, nothing else. Both
       are still reachable: the Klientenportal is a link in the nav list, and
       the switcher is rendered again inside the dialog. */
    #main-header .lang-switcher,
    #main-header .pill-outline{
        display: none;
    }
}

/* The dialog's copy of the switcher is the compact-header one; above this width
   the header carries it, so only one is ever in the accessibility tree. */
@media (width >= 60rem){
    .nav-dialog-body .lang-switcher{
        display: none;
    }
}

#nav-dialog{
    /* Travel distance of the rise. A shared *length* rather than a percentage,
       because the logo below cancels it out and percentages would resolve
       against each element's own size instead. 100dvh puts the panel's top edge
       exactly on the bottom of the visible viewport, whatever the panel's height. */
    --nav-rise: 100dvh;

    /* Head start for the panel before its contents fade in. Deliberately shorter
       than --duration-l so the two overlap slightly instead of feeling sequential. */
    --nav-content-delay: 200ms;

    /* Lets the nav list tighten up before the dialog has to scroll: 56px of gap
       at 900px tall, 16px at 600px, then the clamps below take over. svh rather
       than dvh so it doesn't jitter as mobile toolbars show and hide. */
    --nav-gap-fluid: calc( -4rem + 13.33svh );

    inline-size: 100%;
    max-inline-size: none;
    block-size: 100%;
    max-block-size: none;
    margin: 0;
    padding: 0;
    border: none;
    overflow: hidden;

    background-color: var( --color-black );
    color: var( --color-white );

    /* Rises from the bottom edge. No fade — the black should read as moving up,
       not as appearing in place. The reset layer transitions dialog opacity, so
       opacity is pinned here to opt this one dialog out of that. */
    opacity: 1;
    translate: 0 var( --nav-rise );
    transition: translate var( --duration-l ) var( --ease-out ),
                display var( --duration-l ) allow-discrete,
                overlay var( --duration-l ) allow-discrete;
}

#nav-dialog[open]{
    translate: 0 0;
}

/* No dimming — the header must stay crisp white while the panel rises past it,
   so the logo reads as a clean black-to-white wipe. The panel is opaque and
   full-viewport once open, so the backdrop is only ever seen mid-transition. */
#nav-dialog::backdrop{
    background: transparent;
}

@starting-style{
    #nav-dialog[open]{
        translate: 0 var( --nav-rise );
    }
}

/* Cancels the panel's rise exactly, so the white logo holds the same screen
   position as the black one in the header behind it. The panel clips it, so the
   rising black edge wipes the logo from black to white in place. */
.nav-dialog-head .logo{
    translate: 0 calc( var( --nav-rise ) * -1 );
    transition: translate var( --duration-l ) var( --ease-out );
}

#nav-dialog[open] .nav-dialog-head .logo{
    translate: 0 0;
}

@starting-style{
    #nav-dialog[open] .nav-dialog-head .logo{
        translate: 0 calc( var( --nav-rise ) * -1 );
    }
}

/* Staged reveal: the black panel rises on its own first, then everything inside
   it fades up in its final position. The logo is deliberately excluded — it is
   already in place and wipes black-to-white as the panel edge passes it. */
.nav-dialog-body,
#menu-close{
    opacity: 0;
    transition: opacity var( --duration-m ) ease-out;
}

#nav-dialog[open] .nav-dialog-body,
#nav-dialog[open] #menu-close{
    opacity: 1;
    transition-delay: var( --nav-content-delay );
}

/* The + and the × are one glyph: the plus, turned 45°. Both copies turn on the
   same clock and easing as the panel rises, so they hold the same angle at every
   instant; the header's fades out under the rising panel while the dialog's
   fades in already matching it. The handover is invisible, and what reads is a
   single element rotating rather than two icons swapping.

   Driven by aria-expanded, which the script already keeps in step — no second
   piece of state to go out of sync. */
.menu-toggle-icon,
#menu-close svg{
    rotate: 0deg;
    transition: rotate var( --duration-l ) var( --ease-out );
}

#menu-toggle[aria-expanded="true"] .menu-toggle-icon{
    rotate: 45deg;
    opacity: 0;
    transition: rotate var( --duration-l ) var( --ease-out ),
                opacity var( --duration-m ) ease-out;
}

#nav-dialog[open] #menu-close svg{
    rotate: 45deg;
}

/* Without this the dialog's copy is created already at 45° — display goes from
   none to block, so there is no previous value to move from. */
@starting-style{
    #nav-dialog[open] #menu-close svg{
        rotate: 0deg;
    }
}

@media (prefers-reduced-motion: reduce){
    .menu-toggle-icon,
    #menu-close svg{
        transition: none;
    }
}

@starting-style{
    #nav-dialog[open] .nav-dialog-body,
    #nav-dialog[open] #menu-close{
        opacity: 0;
    }
}

@media (prefers-reduced-motion: reduce){
    #nav-dialog,
    .nav-dialog-head .logo{
        translate: 0 0;
        transition: none;
    }

    .nav-dialog-body,
    #menu-close{
        opacity: 1;
        transition: none;
    }
}

.nav-dialog-inner{
    display: flex;
    flex-direction: column;
    gap: var( --space-xl );

    block-size: 100%;
    /* The header's own padding, not a value of its own: the logo and the toggle
       in here have to land exactly on the ones behind them, or the black-to-white
       wipe misses the logo and the × misses the +. */
    padding-block: var( --header-padding-block );
    overflow-y: auto;
}

.nav-dialog-head{
    display: flex;
    justify-content: space-between;
    /* Centred, not flex-start: it puts the close button on the logo's centre
       line, which is where the header centres the Menü pill. */
    align-items: center;
    gap: var( --space-s );

    .logo svg{
        height: var( --logo-height );
        width: auto;
    }
}

/* Sits on the Menü pill it replaces — same right edge, same centre line — so
   the pointer lands on it after the click that opened the panel. Its box is
   invisible (no fill, transparent border) and roomier than the icon needs; it
   is still narrower than the pill's label, so the leftmost part of “Menü” is
   not covered. */
#menu-close{
    flex-shrink: 0;
    background: none;
    color: inherit;
    cursor: pointer;
    border: 1px solid transparent;
    padding: var( --space-s ) var( --space-m );

    svg{
        display: block;
        inline-size: var( --icon-size );
        block-size: auto;
    }

    /* Below the pill's width the header shows the bare + instead, so this takes
       that box exactly — same 44px target, same negative margin holding the
       glyph on the 20px gutter — and the two land on the same point. */
    @media (width < 60rem){
        display: grid;
        place-items: center;
        padding: 0;
        border: none;
        min-inline-size: 2.75rem;
        min-block-size: 2.75rem;
        margin-inline-end: -0.25rem;
    }
}

.nav-dialog-body{
    display: flex;
    flex-direction: column;
    gap: var( --space-xl );

    /* At the widths where this panel is the whole navigation, the address is
       not part of it — the footer carries it a scroll away, and leaving it out
       keeps the nav to what it is for. */
    @media (width < 60rem){
        .contact{
            display: none;
        }
    }
}

.main-nav ul{
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: clamp( var( --space-xs ), var( --nav-gap-fluid ), var( --space-m ) );
}

.main-nav a{
    display: inline-block;
    line-height: 1.1;

    /* Design sizes: 40px at 393px wide, 64px at 1440px. Interpolated rather than
       stepped, so the 64px never lands on an 800px-wide window. */
    font-size: var( --font-size-2xl );
}

.main-nav [aria-current="page"]{
    text-decoration-color: currentColor;
}

.contact{
    /* 20px at 393px wide, 25px at 1440px. */
    font-size: var( --font-size-m );

    h2{
        font-size: inherit;
    }

    address{
        font-style: normal;
        /* A blank line, as in the design — keeps the baseline grid intact. */
        margin-block-start: 1lh;
    }
}

/* Bullet motif: the dot before “Bürozeiten” and before the Leistungen subline.
   The footer’s Bürozeiten uses a colon instead, so it is excluded. */
.contact:is( .contact-nav, .contact-start ) h2,
.untertitel,
.sprachen li{
    display: flex;
    align-items: baseline;
    gap: var( --space-xs );
}

/* The disc that marks a subtitle, a contact heading and each Detailleistung.
   Sized in em so it tracks whatever type it sits against. */
.contact:is( .contact-nav, .contact-start ) h2::before,
.untertitel::before,
.detailleistungen > li::before,
.sprachen li::before,
.eckdaten > li::before,
.team-liste > li::before{
    content: "";
    flex-shrink: 0;
    inline-size: 0.7em;
    block-size: 0.7em;
    border-radius: 50%;
    background-color: currentColor;
}

@media (width >= 60rem){
    /* Design puts the contact block left and the nav right, but the nav is the
       point of the dialog, so it stays first in the DOM and is placed visually. */
    .nav-dialog-body{
        display: grid;
        grid-template-columns: 1fr 1fr;
        column-gap: var( --space-l );
        align-items: start;
    }

    .nav-dialog-body .contact{
        grid-column: 1;
        grid-row: 1;
    }

    .nav-dialog-body .main-nav{
        grid-column: 2;
        grid-row: 1;
    }

    .main-nav ul{
        gap: clamp( var( --space-xs ), var( --nav-gap-fluid ), var( --space-xl ) );
    }
}

/* ---- Start page intro ----------------------------------------------------
   Fills exactly one viewport below the sticky header. The yellow block is the
   only flexible row, so it alone absorbs the difference as the viewport height
   changes; the description and the colour fields keep their natural height.

   svh rather than dvh: svh is the *smallest* viewport, so the intro still fits
   with mobile browser chrome showing, and it doesn't reflow as that chrome
   slides away. */
#intro{
    /* A definite height is what lets the rows below shrink — tracks only give way
       against a constrained container. min-content then acts as an escape hatch:
       once even the minimum track sizes no longer fit, the intro grows past the
       viewport and the page scrolls instead of the content overflowing. */
    block-size: calc( 100svh - var( --header-height ) );
    min-block-size: min-content;
    display: grid;

    /* Set here so `lh` in the track sizes below means one line of the
       description; .beschreibung inherits both. */
    font-size: var( --font-size-xl );
    line-height: 1.15; /* 46/40, per the design */

    /* Column widths measured off the design at 1440: 488 / 574 / 373. */
    grid-template-columns: 488fr 574fr 373fr;

    /* The yellow band takes every pixel of slack (1fr) but never drops below its
       own content plus padding (min-content). The two lower rows sit at
       --intro-row while there is room and shrink to --intro-row-min once the
       band has bottomed out — so the band gives way first, then the rows.
       Both lower rows share one min and one max, which is what keeps them equal;
       grid cannot equalise two `auto` rows, and the plume spans both. */
    grid-template-rows:
        minmax( min-content, 1fr )
        minmax( min-content, var( --intro-row ) )
        minmax( var( --intro-row-min ), var( --intro-row ) );
}

.zielgruppen{
    grid-column: 1 / -1;
    grid-row: 1;

    background-color: var( --color-yellow );
    padding: var( --space-m ) var( --padding-side );

    display: flex;
    /* Centred in the band, which matters because the band is the row that grows
       and shrinks with the viewport. */
    align-items: center;
    gap: var( --space-m );
    justify-content: flex-start;

    font-family: var( --font-serif );
    line-height: 1.2;

    /* fussenegger.js narrows --term-size until the label plus the longest term
       fit on one line; the fallback keeps a sensible size without the script.
       Set here so “Für” and the terms share one size. */
    font-size: var( --term-size, var( --font-size-2xl ) );
}

/* The narrow field the reel scrolls behind: exactly one line tall, so only one
   term is ever readable. */
.zielgruppen-window{
    flex: 1 1 auto;
    min-inline-size: 0;
    overflow: hidden;
    block-size: 1lh;

    /* The reel is as tall as every term stacked (~11.600px with the current
       list). overflow alone clips it visually but its height still reached the
       document, so the page scrolled far past the footer into empty white.
       Paint containment stops that without affecting sizing — the reel has to
       stay in flow, because fussenegger.js measures the terms' widths to fit
       them. */
    contain: paint;
}

.zielgruppen-list{
    list-style: none;
    /* --i is the reel position in whole terms, set by fussenegger.js. */
    translate: 0 calc( var( --i, 0 ) * -1lh );
    transition: translate var( --duration-xl ) var( --ease-out );
}

.zielgruppen-list li{
    white-space: nowrap;
    /* Shrink each item to its text. Block items would fill the row, and the
       measurement in fussenegger.js reads their width to size the terms. */
    inline-size: max-content;
}

/* Narrow: “Für” takes its own line, the reel the one below it. */
@media (width < 48rem){
    .zielgruppen{
        flex-direction: column;
        align-items: flex-start;
        justify-content: center;
        gap: 0;
    }

    .zielgruppen-window{
        flex: 0 0 auto;
        inline-size: 100%;
    }
}

@media (prefers-reduced-motion: reduce){
    .zielgruppen-list{
        transition: none;
    }
}

#intro .beschreibung{
    grid-column: 1 / 3;
    grid-row: 2;
    align-content: center;

    padding-inline: var( --padding-side );
    text-wrap: balance;
}

/* Colour only — placement belongs to whatever context the block sits in, or a
   .rose in a Farbband would inherit the intro’s column. */
.farbfeld.orange{ background-color: var( --color-orange ); }
.farbfeld.rose{ background-color: var( --color-rose ); }
.farbfeld.plume{ background-color: var( --color-plume ); }
.farbfeld.blue-light{ background-color: var( --color-blue-light ); }
.farbfeld.blue-dark{ background-color: var( --color-blue-dark ); }
.farbfeld.green-light{ background-color: var( --color-green-light ); }
.farbfeld.green-dark{ background-color: var( --color-green-dark ); }
.farbfeld.yellow{ background-color: var( --color-yellow ); }
.farbfeld.red{ background-color: var( --color-red ); }

/* Full-bleed: the colour fields run to the viewport edges, unlike the text. */
#intro .farbfeld.orange{
    grid-column: 1;
    grid-row: 3;
}

#intro .farbfeld.rose{
    grid-column: 2;
    grid-row: 3;
}

/* Sits on the right and spans the description row *and* the colour row. */
#intro .farbfeld.plume{
    grid-column: 3;
    grid-row: 2 / 4;
}

/* ---- Farbband ------------------------------------------------------------
   Full-bleed band of colour blocks separating two sections. Column ratios and
   height come from the design, passed in per band. */
.farbband{
    display: grid;
    grid-template-columns: var( --farbband-spalten, 1fr );
    /* 287px at 1440 in the design; scales with the viewport, floored so it does
       not become a stripe on a phone. */
    block-size: var( --farbband-hoehe, clamp( 6rem, 20vw, 18rem ) );
}

/* Unica_IntroTexte_50 — 40/50 in the design, so the body line-height already
   matches. Padding in lines keeps the block in the same rhythm as its text. */
/* A section that is nothing but running text — the start page's introduction,
   the Kompetenzen note on Leistungen, the Einleitung on Über uns. */
.fliesstext{
    font-size: var( --typo-intro );
    line-height: var( --typo-intro-lh );
    padding-block: 2lh;
}

#kontakt-teaser{
    /* The rule above the block. On the section rather than the inner wrapper so
       it runs edge to edge, as drawn. */
    border-block-start: var( --linie );
    padding-block: var( --space-l );
    font-size: var( --font-size-m );

    /* Label left, hours and the button in a second column beneath each other.
       The wrappers collapse so h2, p and the pill all sit in this one grid and
       stay aligned to the same two columns. */
    .content-width{
        display: grid;
        grid-template-columns: max-content 1fr;
        column-gap: var( --space-l );
        row-gap: var( --space-m );
        align-items: start;
    }

    .contact,
    .buerozeiten{
        display: contents;
    }

    .pill{
        grid-column: 2;
        justify-self: start;
    }
}

/* Narrow: one column, or the hours are squeezed into a strip and wrap to twice
   the lines they should. */
@media (width < 48rem){
    #kontakt-teaser .content-width{
        grid-template-columns: 1fr;
        row-gap: var( --space-s );
    }

    #kontakt-teaser .pill{
        grid-column: 1;
        margin-block-start: var( --space-s );
    }
}

/* ---- Leistungen teaser ---------------------------------------------------- */
#leistungen-teaser{
    padding-block: var( --space-xl );

    h2{
        font-family: var( --font-serif );
        font-size: var( --font-size-2xl );
        line-height: 1.1;
    }

    .untertitel{
        font-size: var( --font-size-m );
    }
}

/* The columns live on the list, and every row adopts them via subgrid — so the
   number column is sized once against the widest numeral and all four rows line
   up. Sized per row, `min-content` differs for “1.” and “4.” and the details
   column would step sideways from row to row.

   Gutters and gaps are explicit tracks rather than padding + column-gap, so the
   rule above each row can run full-bleed while the content stays inside the
   page gutters. Track ratios come off the design at 1440 (387 / 434 / 389). */
.leistungen-liste{
    list-style: none;
    margin-block-start: var( --space-l );

    display: grid;
    grid-template-columns:
        var( --padding-side )   /* 1 gutter  */
        min-content             /* 2 number  */
        var( --space-l )        /* 3 gap     */
        1.3fr                   /* 4 title   */
        var( --space-l )        /* 5 gap     */
        1.5fr                   /* 6 details */
        var( --space-l )        /* 7 gap     */
        0.5fr                   /* 8 arrow   */
        var( --padding-side );  /* 9 gutter  */

    li{
        grid-column: 1 / -1;
        display: grid;
        grid-template-columns: subgrid;
        border-block-start: var( --linie );
    }

    li:last-child{
        border-block-end: var( --linie );
    }

    a{
        grid-column: 1 / -1;
        display: grid;
        grid-template-columns: subgrid;
        align-items: center;

        padding-block: var( --space-xs );
        text-decoration: none;
    }
}

/* Design centres this on the page, 52px below the last row. */
.leistungen-mehr{
    display: flex;
    justify-content: center;
    margin-block-start: var( --space-xl );
    font-size: var( --font-size-l );
}

.leistung-nummer{ grid-column: 2; }
.leistung-titel{ grid-column: 4; }
.leistung-details{ grid-column: 6; }
.leistung-pfeil{ grid-column: 8; }

.leistung-nummer{
    font-family: var( --font-serif );
    font-size: var( --font-size-3xl );
    line-height: 1;
    letter-spacing: -0.01em;
}

.leistung-titel{
    font-family: var( --font-serif );
    font-size: var( --font-size-xl );
    line-height: 1.05; /* 42/40, per the design */
}

.leistung-details{
    font-size: var( --font-size-s );
    line-height: 1.25; /* 25/20 */

    /* Three lines, then an ellipsis — which is where the “…” in the design
       comes from, rather than being baked into the content. */
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    overflow: hidden;
}

.leistung-pfeil{
    justify-self: end;
    display: grid;
    place-items: center;

    inline-size: 3.125rem;
    aspect-ratio: 1;
    border-radius: 50%;

    background-color: var( --color-black );
    color: var( --color-white );
    transition: background-color var( --duration-s ) ease-out,
                color var( --duration-s ) ease-out;

    .icon-arrow{
        inline-size: 50%;
        fill: currentColor;
    }
}

/* Same treatment as links in the reset: the line is always there, only its
   colour changes, because the line itself cannot be transitioned. This one is a
   <span> inside the row link, so the rule on `a` does not reach it. */
.leistung-titel{
    text-decoration-line: underline;
    text-decoration-color: transparent;
    transition: text-decoration-color var( --duration-s ) ease-out;
}

.leistungen-liste a:hover .leistung-titel,
.leistungen-liste a:focus-visible .leistung-titel{
    text-decoration-color: currentColor;
}



/* Inverts on hover, matching the pills. */
.leistungen-liste a:hover .leistung-pfeil,
.leistungen-liste a:focus-visible .leistung-pfeil{
    background-color: var( --color-white );
    color: var( --color-black );
    box-shadow: inset 0 0 0 1px var( --color-black );
}

@media (prefers-reduced-motion: reduce){
    .leistung-pfeil{
        transition: none;
    }
}

/* Home_Mobil redraws this row rather than just narrowing it: the excerpt drops
   out entirely, the number comes down to 72px, the title wraps to two lines at
   28/30 and the arrow follows it directly instead of being pushed to the far
   edge. The four-track grid could not survive a phone in any case — its
   min-content is 413px against 393px of viewport. */
@media (width < 48rem){
    .leistungen-liste{
        grid-template-columns: 1fr;
    }

    .leistungen-liste a{
        display: flex;
        align-items: center;
        gap: var( --space-m );
        padding: var( --space-m ) var( --padding-side );
    }

    .leistung-nummer{
        font-size: 4.5rem;   /* 72, as drawn */
        margin-inline-end: 0.125rem;

        /* The design trims the numeral's box to its cap height, 49px of the
           72px em — which is what makes the row 99px rather than 120. */
        line-height: 0.68;
    }

    .leistung-titel{
        font-size: 1.75rem;  /* 28/30 */
        line-height: 1.0714;
        margin-inline-end: auto;

        /* “Unternehmensberatung” is 290px on its own and the row has about 230
           to spare. A flex item will not shrink past min-content unless told
           to, so both halves are needed for it to break. */
        min-inline-size: 0;
        hyphens: auto;
    }

    .leistung-pfeil{
        inline-size: 3.0625rem; /* 49 */
    }

    /* Not drawn at this width. */
    .leistung-details{
        display: none;
    }
}

#main-footer{
    background-color: var( --color-black );
    color: var( --color-white );
    padding-block: var( --space-l );

    /* Set here so everything inside shares one line box — that is what makes the
       lh-based logo height and gaps line up across the columns. 25px/30px in the
       design, hence 1.2. */
    font-size: var( --typo-text );
    line-height: var( --typo-text-lh );

    /* Design column offsets at 1440 wide: 40 / 500 / 1075, i.e. roughly
       34 / 42 / 24 of the 1360px content width. */
    .content-width{
        display: grid;
        grid-template-columns: 34fr 42fr 24fr;
        gap: var( --space-l );
        align-items: start;
    }

    /* 112px tall at 1440, scaled down with the viewport like the header logo. */
    .logo svg{
        height: var( --logo-height-footer );
        width: auto;
        padding-block: 0.1em;
    }

    .contact{
        margin: 0;
    }

    .beschreibung{
        text-wrap: balance;
    }
}

.footer-brand p{
    /* One blank line, matching the blank line above the address block opposite. */
    margin-block-start: 1lh;
}

.footer-legal{
    display: flex;
    flex-direction: column;
    /* Copyright sits at the bottom of the column in the design. */
    justify-content: space-between;
    gap: var( --space-xl );
    block-size: 100%;

    ul{
        list-style: none;
    }

    .copyright{
        margin: 0;
    }
}

@media (width < 48rem){
    #main-footer .content-width{
        grid-template-columns: 1fr;
        gap: var( --space-l );
    }

    .footer-legal{
        gap: var( --space-m );
    }
}

/* ---------------------------------------------------------------- Klienten-Info */

/* Image and coloured band fill one viewport between them, so every interior
   page opens at the same height. Rows carry the design's 457:326 proportion;
   the text row may grow past its share on short viewports rather than clip. */
.seiten-intro{
    display: grid;
}

.seiten-intro:has( .seiten-bild ){
    block-size: calc( 100svh - var( --header-height ) );
    min-block-size: min-content;
    grid-template-rows: minmax( 0, 457fr ) minmax( min-content, 326fr );
}

.seiten-bild{
    overflow: hidden;
}

.seiten-bild img{
    display: block;
    inline-size: 100%;
    block-size: auto;

    /* Never taller than the viewport below the header, so a full-bleed image
       cannot take more than a screenful on its own. Past that it crops rather
       than scaling down, which would leave the page narrower than the band
       above it. */
    max-block-size: calc( 100svh - var( --header-height ) );
    object-fit: cover;
}

/* In the intro the image fills whatever the row leaves it, so it crops rather
   than dictating the height. Elsewhere — the footer image — it keeps its own
   proportions. */
.seiten-intro .seiten-bild img{
    block-size: 100%;
    object-fit: cover;
}

.seiten-intro-text{
    font-family: var( --font-serif );

    display: grid;
    /* Text sits at the top of the band; the space below is the band's own. */
    align-content: start;
    padding-block: var( --space-l );
}

/* The large serif headline a page opens or closes on — the intro h1, the CTA
   band, “Unser Team”. The design sets 110/105, 55/58 on mobile. */
.titel-gross{
    font-family: var( --font-serif );
    font-size: var( --typo-headline );
    line-height: var( --typo-headline-lh );
    letter-spacing: -0.02em;
    text-wrap: balance;

    /* German compounds outrun a narrow screen at this size — “Zusammenarbeit”
       alone is 390px against the 353px a 393px viewport leaves. Hyphenation
       breaks it where the language allows rather than letting it bleed past
       the edge; the browser applies the rules for the page’s own lang. */
    hyphens: auto;
}

/* Balancing and hyphenation pull against each other: to even the lines, balance
   takes the earliest break the dictionary offers, giving “Für gute Zu- /
   sammenarbeit” where the frame draws “Für gute / Zusammen- / arbeit”. Greedy
   wrapping produces the drawn break, so the narrow end goes back to it. */
@media (width < 48rem){
    .titel-gross{
        text-wrap: wrap;
    }
}

/* Alpina_Headline_02_80 — the serif a section heading is set in: the numbered
   Leistungen bands, “Unser Team”, “Unsere Benefits”, the figures on Karriere.
   Distinct from .titel-gross above, which the design reserves for a page's own
   h1 and the closing call-to-action band. */
.band-titel,
.abschnitt-titel,
.team-titel,
.titel-band h1,
.zahl{
    font-family: var( --font-serif );
    font-size: var( --typo-band );
    line-height: var( --typo-band-lh );

    /* As on .titel-gross: “Unternehmensberatung” is 414px at this size and a
       phone leaves about 350. No effect on .zahl — a figure has nothing to
       hyphenate. */
    hyphens: auto;
}

/* Layout, gap and the disc all come from the shared .untertitel rule above;
   only what this context changes is repeated. Centred rather than baseline —
   against type this large a baseline-aligned disc sits too low. */
.seiten-intro-text .untertitel{
    align-items: center;

    /* The design draws 30px, but between trimmed text boxes. The line box adds
       half-leading at both ends, so the margin that lands on it is small —
       hence the tight value here and the design's own 40/46 line-height rather
       than the inherited 1.5. */
    margin-block: var( --space-xs ) 0;
    font-family: var( --font-sans-serif );
    font-size: var( --typo-lead );
    line-height: var( --typo-lead-lh );
}

/* The full-bleed coloured band a section opens on — the Klienten-Info years and
   the Leistungen groups. The colour comes from the .farbfeld class beside it.
   flex/gap carry the number that precedes the Leistungen titles and are inert
   on the year bands, which hold a single string. */
.band-titel{
    display: flex;
    align-items: baseline;
    gap: var( --space-s );

    padding: var( --space-l ) var( --padding-side );
}

/* The row list both the Klienten-Info issues and the Leistungen details use:
   full-bleed rules with the text held inside the page padding. The gutters are
   grid tracks rather than padding, so a row's rule can run edge to edge while
   its cells stay aligned. Each list declares its own tracks and cell placement;
   everything they share lives here. */
.zeilen-liste{
    list-style: none;
    margin: 0;
    padding: 0;

    display: grid;
    font-family: var( --font-sans-serif );
    font-size: var( --typo-zeile );
    line-height: var( --typo-zeile-lh );

    /* Direct children only — a row may hold a nested list of its own. */
    > li{
        grid-column: 1 / -1;
        display: grid;
        grid-template-columns: subgrid;
        border-block-start: var( --linie );
    }

    > li:last-child{
        border-block-end: var( --linie );
    }
}

/* The Klienten-Info and Leistungen lists close with a rule. These two do not —
   the design rules only between their rows, leaving the last open to whatever
   follows. */
.team-liste > li:last-child,
.job-liste > li:last-child{
    border-block-end: none;
}

.ausgaben-liste{
    grid-template-columns:
        var( --padding-side )   /* 1 gutter */
        min-content             /* 2 year   */
        var( --space-l )        /* 3 gap    */
        1fr                     /* 4 title  */
        var( --space-m )        /* 5 gap    */
        min-content             /* 6 file   */
        var( --space-m )        /* 7 gap    */
        min-content             /* 8 icon   */
        var( --padding-side );  /* 9 gutter */

    letter-spacing: -0.01em;

    > li > a{
        grid-column: 1 / -1;
        display: grid;
        grid-template-columns: subgrid;
        align-items: center;

        /* Padding on the link, not the row, so the whole item is clickable. */
        padding-block: var( --space-s );
        text-decoration: none;
        transition: background-color var( --duration-s ) ease-out;
    }
}

.ausgabe-jahr{ grid-column: 2; grid-row: 1; }
.ausgabe-titel{ grid-column: 4; grid-row: 1; }

.ausgabe-datei{
    grid-column: 6;
    grid-row: 1;
    justify-self: end;
    text-align: end;
    white-space: nowrap;
    font-size: var( --font-size-s );
}

.ausgabe-icon{
    grid-column: 8;
    grid-row: 1;
    display: flex;
    align-items: center;

    /* Stated on the wrapper, not the <svg>: the sprite-referencing <svg> has no
       intrinsic size, so a min-content column measuring it resolves to zero —
       and the reset's max-inline-size: 100% then caps the icon at zero too.
       0.68em is 20px against the design's 30px type; 0.62em keeps the icon's
       own 20 × 21.99 proportion. */
    inline-size: 0.62em;
    block-size: 0.68em;
}

.icon-download{
    inline-size: 100%;
    block-size: 100%;
    fill: currentColor;
}

/* The whole row lights up. The link spans the gutter tracks as well as the
   text, so the fill runs edge to edge like the rules above and below it. */
.ausgaben-liste > li > a:hover,
.ausgaben-liste > li > a:focus-visible{
    background-color: var( --color-blue-light );
}

/* “Mehr anzeigen”. The summary is the pill; the years it reveals sit inside the
   same <details>, so they simply appear beneath it. */
.ausgaben-archiv > summary{
    /* .pill is inline-flex, and an inline box ignores auto margins — so the
       summary is made a block-level flex box to centre it. */
    display: flex;
    inline-size: max-content;
    margin: var( --space-xl ) auto;
    list-style: none;
    font-family: var( --font-sans-serif );
    font-size: var( --font-size-l );
}

/* Nothing left to reveal once it is open. */
.ausgaben-archiv[open] > summary{
    display: none;
}

.ausgaben-archiv > summary::-webkit-details-marker{
    display: none;
}



@media (width < 48rem){
    .ausgaben-liste{
        grid-template-columns:
            var( --padding-side )
            min-content
            var( --space-m )
            1fr
            var( --space-s )
            min-content
            var( --space-s )
            min-content
            var( --padding-side );
    }

    .band-titel{
        padding-block: var( --space-m );
    }
}

/* The sprite only defines the symbol — it must never take up space. */
.icon-sprite{
    display: none;
}

/* The issue's article headings, under the title. One line each in the field;
   run together here so a row stays a row — 219 of them stacked out in full
   would make the archive unreadable. */
.ausgabe-themen{
    grid-column: 4;
    grid-row: 2;

    margin: 0;
    margin-block-start: var( --space-xs );
    padding: 0;
    list-style: none;

    /* Kept to size for its hierarchy rather than a lighter colour: a muted grey
       fails contrast against the blue the row takes on hover (2:1), and against
       white too (2.9:1). The design sets every row in black. */
    font-size: var( --font-size-s );
    line-height: 1.3;

    /* Two lines, then an ellipsis. */
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
}

.ausgabe-themen li{
    display: inline;
}

.ausgabe-themen li:not(:last-child)::after{
    content: " · ";
}


/* ------------------------------------------------------------------ Leistungen */

.leistung-gruppe{
    /* The start page links to “#slug”; without this the sticky header would
       cover the band the anchor lands on. */
    scroll-margin-block-start: var( --header-height );
}

.detailleistungen{
    grid-template-columns:
        var( --padding-side )   /* 1 gutter */
        min-content             /* 2 disc   */
        var( --space-l )        /* 3 gap    */
        1fr                     /* 4 text   */
        var( --padding-side );  /* 5 gutter */

    > li{
        align-items: center;
        padding-block: var( --space-s );
    }

    /* Geometry comes from the shared disc rule; only its track is set here. */
    > li::before{
        grid-column: 2;
    }

    > li > span{
        grid-column: 4;
    }
}

.cta-band{
    padding-block: var( --space-xl );
    font-family: var( --font-serif );
}

.cta-band .pill{
    margin-block-start: var( --space-l );
    font-family: var( --font-sans-serif );
    font-size: var( --font-size-l );
}


/* --------------------------------------------------------------------- Über uns */

/* Kanzlei facts in columns divided by full-height rules, as drawn. The rule
   above the block is the section's own, so it runs edge to edge. */
#kanzlei-daten{
    border-block-start: var( --linie );
    padding-block: var( --space-l );

    .content-width{
        display: grid;
        grid-template-columns: repeat( auto-fit, minmax( 15rem, 1fr ) );
        gap: var( --space-l );
    }
}

.daten-spalte{
    /* The divider belongs to the column that follows it, so the first has none
       and the rules land between rather than around. */
    padding-inline-start: var( --space-l );
    border-inline-start: var( --linie );

    font-size: var( --typo-klein );
    line-height: var( --typo-klein-lh );
}

.daten-spalte:first-child{
    padding-inline-start: 0;
    border-inline-start: none;
}

.daten-spalte h2{
    margin-block-end: var( --space-m );
    font-family: var( --font-serif );
    font-size: var( --typo-subheadline );
    line-height: var( --typo-subheadline-lh );
}

.adresse{
    font-style: normal;
}

/* The design separates the three blocks — name, street, the contact lines —
   with a blank line, and keeps the contact lines together. */
.adresse-kanzlei{
    display: grid;
    gap: 1lh;
}

@media (width < 48rem){
    /* Stacked, so the rules run above each column instead of beside it. */
    .daten-spalte{
        padding-inline-start: 0;
        border-inline-start: none;
        padding-block-start: var( --space-m );
        border-block-start: var( --linie );
    }

    .daten-spalte:first-child{
        padding-block-start: 0;
        border-block-start: none;
    }
}

.sprachen{
    list-style: none;
}

#team{
    padding-block-start: var( --space-l );
}

.team-titel{
    margin-block-end: var( --space-l );
}

/* The groups are rows of the shared list: a rule above each, the disc in the
   second track and the group's content in the fourth. */
.team-liste{
    /* One measure for a group's content. Wide enough to keep “Die
       Saubermacherin mit grünem Daumen” (716px) on one line, narrow enough that
       “Bilanzierung, Buchhaltung und Lohnverrechnung” (858px) breaks in two as
       the design draws it — and the width the two name columns fill. */
    --gruppe-mass: 49rem;

    grid-template-columns:
        var( --padding-side )   /* 1 gutter */
        min-content             /* 2 disc   */
        var( --space-l )        /* 3 gap    */
        1fr                     /* 4 group  */
        var( --padding-side );  /* 5 gutter */

    /* The row carries the heading's size, so the shared disc — sized in em —
       comes out at the 28px the design draws beside a 40px heading. */
    > li{
        font-size: var( --typo-subheadline );
        padding-block: var( --space-m );
    }

    /* Geometry comes from the shared disc rule; this places it and lifts it to
       the heading's first line rather than the row's middle. */
    > li::before{
        grid-column: 2;
        grid-row: 1;
        align-self: start;
        margin-block-start: 0.32em;
    }

    > li > h3{
        grid-column: 4;
        grid-row: 1;
        font-family: var( --font-serif );
        /* Takes the row's size rather than the UA's 1.17em for an h3;
           43/40 per the design. */
        font-size: 1em;
        line-height: var( --typo-subheadline-lh );

        max-inline-size: var( --gruppe-mass );
        /* Splits the one heading that wraps into even halves, as drawn. */
        text-wrap: balance;
    }

    /* Under the heading, not in the gutter it would otherwise auto-place into. */
    > li > .team-namen{
        grid-column: 4;
        grid-row: 2;
    }
}

.team-namen{
    list-style: none;
    margin-block-start: var( --space-s );
    font-size: var( --typo-liste );
    line-height: var( --typo-liste-lh );

    /* Two columns of roughly 23rem, as drawn — without this the names spread
       across the whole row and the pairing is lost. */
    max-inline-size: var( --gruppe-mass );

    column-gap: var( --space-l );
}

/* One column, except for a list long enough to warrant two — which is how the
   design sets it: the seventeen-name group splits, the four-name one does not.
   Counted with :has() rather than a column width, so the break depends on the
   list rather than on how much room happens to be going. */
.team-namen:has( li:nth-child( 10 ) ){
    columns: 2;
}

@media (width < 48rem){
    .team-namen:has( li:nth-child( 10 ) ){
        columns: 1;
    }
}


/* ---------------------------------------------------------------------- Karriere */

/* Every block on this page opens the same way: a heading with a rule above it,
   running edge to edge. */
/* The heading sits centred between its two rules, so the air is equal on both
   sides. Figma measures 50px each way — but from a cap-trimmed text box, where
   the CSS line box carries half-leading above and below that Figma does not
   count. Hence two versions of the same thing: the fallback subtracts that
   leading from the padding by hand, and where text-box-trim exists the box
   hugs the cap and the baseline just as Figma's does, so the design's own 50px
   can be stated literally. */
.abschnitt-titel{
    border-block-start: var( --linie );
    padding-block: 2.125rem;
}

@supports ( text-box: trim-both cap alphabetic ){
    .abschnitt-titel{
        text-box: trim-both cap alphabetic;
        padding-block: 3.125rem;
    }
}

/* In the design every section heading sits between two rules. The lists below
   supply the lower one themselves — the first row of the job list and the top
   row of the benefits grid both carry a rule — but a carousel and the figures
   have none, so those two draw it. Stated on the content rather than as a
   border under the heading, which would double up against the lists. */
.abschnitt-titel + .karussell,
.abschnitt-titel + .zahlen-liste{
    border-block-start: var( --linie );
}

/* Only the carousel needs air under the rule — its items are images, which
   would otherwise sit right against the line. */
.abschnitt-titel + .karussell{
    padding-block-start: var( --space-l );
}

@media (width < 48rem){
    .abschnitt-titel{
        /* At 40/43 the line box is only 16px taller than the trimmed box, so
           less of the gap is absorbed by the line and the padding gives it back. */
        padding-block: 1.5rem;
    }

    @supports ( text-box: trim-both cap alphabetic ){
        .abschnitt-titel{
            padding-block: 2rem;
        }
    }
}

/* A full-bleed image is an edge in its own right; a rule laid against one reads
   as a second line. The design leaves the heading after the Karriere photo
   unruled for exactly that reason. */
.seiten-bild + * > .abschnitt-titel:first-child{
    border-block-start: none;
}

/* The track scrolls and snaps by itself; the buttons only nudge it along. */
.karussell-spur{
    list-style: none;
    display: flex;
    gap: var( --space-m );
    padding-inline: var( --padding-side );

    overflow-x: auto;
    scroll-snap-type: inline mandatory;
    scroll-padding-inline: var( --padding-side );
    /* The row is focusable so it can be scrolled from the keyboard; it should
       not also show a scrollbar over the design. */
    scrollbar-width: none;
}

.karussell-spur::-webkit-scrollbar{
    display: none;
}

.karussell-spur > *{
    flex: none;

    /* The item in play sits in the middle of the row. The first and last cannot
       reach the middle — there is nothing before or after them to scroll — so
       the browser stops at the ends of the range and they rest against the
       edges, which is what the design shows. */
    scroll-snap-align: center;
}

.karussell-steuerung{
    display: flex;
    justify-content: space-between;
    padding-block: var( --space-m );
}

.karussell-steuerung button{
    display: grid;
    place-items: center;
    inline-size: var( --icon-size );
    block-size: var( --icon-size );

    padding: 0;
    border: none;
    background: none;
    color: inherit;
    cursor: pointer;
}

.karussell-zurueck .icon-arrow{
    rotate: 180deg;
}

/* At either end of the run the corresponding arrow greys out rather than
   sitting there looking live. */
.karussell-steuerung button:disabled{
    color: var( --color-grey-light );
    cursor: default;
}

.karussell-steuerung .icon-arrow{
    inline-size: 100%;
    fill: currentColor;
    transition: translate var( --duration-s ) ease-out;
}

.karussell-steuerung button:enabled:hover .icon-arrow,
.karussell-steuerung button:enabled:focus-visible .icon-arrow{
    translate: 0.15em 0;
}

/* One height for the row, and each photo keeps its own proportions — so the
   widths differ and a portrait shot stays a portrait.

   70svh is the ceiling. The second term keeps a landscape shot from outgrowing
   the screen it is on: at 3:2 the width is the height and a half, so capping
   the height at 60vw holds the widest item to about 90vw and a phone still
   shows a whole photograph rather than the middle of one. svh rather than vh so
   the row does not resize as mobile toolbars come and go. */
.galerie-bild{
    block-size: min( 70svh, 60vw );

    picture{
        display: block;
        block-size: 100%;
    }

    img{
        block-size: 100%;
        /* The reset caps images at their container's width and lets the height
           follow; here it is the other way round, so both halves are undone. */
        inline-size: auto;
        max-inline-size: none;
    }
}

.zitat{
    inline-size: min( 80vw, 29.375rem ); /* 470px, as drawn */
    display: grid;
    place-items: center;
    padding: var( --space-l );
    border-radius: 20px;
}

.zitat blockquote{
    margin: 0;
    max-inline-size: 22rem; /* 350px — the measure the design sets */
    text-align: center;

    font-family: var( --font-serif );
    font-size: var( --typo-zitat );
    line-height: var( --typo-zitat-lh );
    letter-spacing: -0.02em;
}

/* Three figures divided by full-height rules, as on Über uns. */
.zahlen-liste{
    list-style: none;
    display: grid;
    grid-template-columns: repeat( auto-fit, minmax( 12rem, 1fr ) );

    > li{
        display: grid;
        justify-items: center;
        gap: var( --space-xs );
        padding: var( --space-l ) var( --space-m );
        border-inline-start: var( --linie );
        text-align: center;
    }

    > li:first-child{
        border-inline-start: none;
    }
}


.zahl-bezeichnung{
    font-size: var( --typo-klein );
    line-height: var( --typo-klein-lh );
}

/* Three across then two, divided by rules — the design's arrangement falls out
   of a three-column grid with the last row centred. */
/* Three across, then whatever is left sharing the full width — the design's
   3 + 2. Flex rather than grid: a wrapped flex row lets the last two grow to
   half each, where a three-track grid would leave them in the first two
   columns with a gap on the right. */
.benefit-liste{
    list-style: none;
    display: flex;
    flex-wrap: wrap;

    > li{
        flex: 1 1 30%;

        display: grid;
        justify-items: center;
        align-content: start;
        gap: var( --space-m );
        padding: var( --space-l ) var( --space-m );

        border-inline-start: var( --linie );
        border-block-start: var( --linie );

        text-align: center;
        font-size: var( --typo-klein );
        line-height: var( --typo-klein-lh );
    }

    /* The rules sit between items, so the one opening each row goes without.
       Three per row is fixed by the flex basis until the narrow layout stacks
       them, so counting in threes is safe here. */
    > li:nth-child( 3n + 1 ){
        border-inline-start: none;
    }
}

.icon-benefit{
    inline-size: min( 13rem, 100% );
    block-size: auto;
    aspect-ratio: 3 / 2;

    /* The five source files each carried this as an embedded <style>; it lives
       here instead so the marks take the colour of their context. */
    fill: none;
    stroke: currentColor;
    stroke-linecap: round;
    stroke-linejoin: round;
    stroke-width: 3;
}

.job-liste{
    grid-template-columns:
        var( --padding-side )   /* 1 gutter */
        1fr                     /* 2 title  */
        var( --space-l )        /* 3 gap    */
        2fr                     /* 4 text   */
        var( --padding-side );  /* 5 gutter */

    > li{
        padding-block: var( --space-l );
    }

    > li > h3{
        grid-column: 2;
        grid-row: 1;
        font-family: var( --font-serif );
        font-size: var( --typo-subheadline );
        line-height: var( --typo-subheadline-lh );
    }

    > li > .job-eckdaten{
        grid-column: 2;
        grid-row: 2;
        margin-block-start: var( --space-s );
        font-size: var( --typo-klein );
        line-height: var( --typo-klein-lh );
    }

    > li > .job-text{
        grid-column: 4;
        grid-row: 1 / 3;
        font-size: var( --typo-klein );
        line-height: var( --typo-klein-lh );
    }
}

.job-text .pill{
    margin-block-start: var( --space-m );
    font-size: var( --typo-klein );
}

@media (prefers-reduced-motion: reduce){
    .karussell-spur{
        scroll-behavior: auto;
    }

    .karussell-steuerung .icon-arrow{
        transition: none;
    }
}

@media (width < 48rem){
    .zahlen-liste > li,
    .benefit-liste > li{
        border-inline-start: none;
        border-block-start: var( --linie );
    }

    .job-liste{
        grid-template-columns:
            var( --padding-side )
            1fr
            var( --padding-side );

        > li > h3,
        > li > .job-eckdaten,
        > li > .job-text{
            grid-column: 2;
            grid-row: auto;
        }

        > li > .job-text{
            margin-block-start: var( --space-m );
        }
    }
}

/* ---------------------------------------------------------------- Job / Bewerbung */

/* The opening of a page below the top level — a job, the Impressum, the
   Datenschutzerklärung. No hero image: a coloured band carries the headline
   straight under the header, at the 80/85 band size.

   153px tall at 1440 around an 85px line, 107px at 393 around 86px of two 43px
   lines — so the air around the headline is nearly all of the difference, and
   it is much tighter on a phone. */
.titel-band{
    padding-block: var( --titel-band-luft );
    --titel-band-luft: 2.125rem;

    h1{
        margin: 0;
    }

    /* Figma's 153px band holds a 54px cap-trimmed headline with 49px either
       side. Trimming makes the CSS box the same 54px, so that 49 can be stated
       rather than derived; without it the padding absorbs the line's leading
       instead. */
    @supports ( text-box: trim-both cap alphabetic ){
        --titel-band-luft: 3.0625rem;

        h1{
            text-box: trim-both cap alphabetic;
        }
    }
}

/* The facts sit on a colour band. Same block proportions as the decorative
   .farbband, but this one carries content, so its height comes from the list
   rather than from a viewport clamp. */
.eckdaten-band{
    display: grid;
    grid-template-columns: 720fr 355fr 365fr;
    min-block-size: 9.0625rem; /* 145px, as drawn */
}

.eckdaten-feld{
    display: grid;
    align-items: center;
}

.eckdaten{
    list-style: none;
    font-size: var( --typo-klein );
    line-height: var( --typo-klein-lh );

    /* The disc rule shared with .untertitel and the other lists sets the marker;
       only the grid it sits in is stated here. */
    > li{
        display: grid;
        grid-template-columns: max-content 1fr;
        align-items: baseline;
        column-gap: var( --space-xs );
    }
}

.job-beschreibung{
    padding-block: var( --space-l );
    font-size: var( --typo-klein );
    line-height: var( --typo-klein-lh );

    p{
        max-inline-size: 46rem; /* 740px, the measure the design sets */
        margin: 0;
    }
}

/* ---- the form --------------------------------------------------------------- */

/* Rules above and below the standing text, running edge to edge as on the
   other pages. */
.bewerbung-hinweis{
    border-block: var( --linie );
    padding-block: var( --space-l );
    margin: 0;

    /* 49px from each rule to the text in Figma, measured to its trimmed box. */
    @supports ( text-box: trim-both cap alphabetic ){
        text-box: trim-both cap alphabetic;
        padding-block: 3.0625rem;
    }


    font-size: var( --typo-zeile );
    line-height: var( --typo-zeile-lh );
}

.bewerbung-dank{
    padding: var( --space-m ) var( --padding-side );
    margin-block: var( --space-l ) 0;
    background-color: var( --color-green-light );

    font-size: var( --typo-zeile );
    line-height: var( --typo-zeile-lh );
}

.bewerbung-formular{
    padding-block: var( --space-xl );

    /* 670px at 1440 — the width of the e-mail field and the textarea, and what
       the two name fields add up to. */
    --feld-breite: 41.875rem;

    /* The design puts 125px between one field's label and the next: the label,
       15px to its input, the 45px input, then 50px of air. The 15 is measured
       from the label's cap-trimmed box, so untrimmed it is 5px of margin plus
       the line's own leading. */
    --feld-label-abstand: 0.3125rem;
    --feld-abstand: 3.125rem;
}

.pflicht-hinweis{
    margin-block: 0 var( --space-l );
    font-size: var( --typo-klein );
    line-height: var( --typo-klein-lh );
}

.feld{
    display: grid;
    gap: var( --feld-label-abstand );
    margin-block: 0 var( --feld-abstand );
    max-inline-size: var( --feld-breite );

    /* The design's fieldset carries no border or padding of its own. */
    border: none;
    padding: 0;
    min-inline-size: 0;
}

.feld > label,
.feld > legend{
    font-size: var( --typo-klein );
    line-height: var( --typo-klein-lh );
    padding: 0;
}

@supports ( text-box: trim-both cap alphabetic ){
    .feld > label,
    .feld > legend{
        text-box: trim-both cap alphabetic;
    }

    .bewerbung-formular{
        --feld-label-abstand: 0.9375rem;
    }
}

/* A <legend> is the fieldset's own box rather than a grid item, so the grid's
   gap does not reach it — it carries the same distance itself. */
.feld > legend{
    margin-block-end: var( --feld-label-abstand );
}

/* Half the row, less the 20px between them. */
.feld-paar{
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var( --space-s );
}

.feld-halb{
    display: grid;
    gap: 0.3125rem;
}

.feld-schmal{
    max-inline-size: calc( ( var( --feld-breite ) - var( --space-s ) ) / 2 );
}

.bewerbung-formular :is( input, textarea ){
    inline-size: 100%;
    padding: 0.625rem;
    border: 1px solid var( --color-feld-rand );
    border-radius: 6px;

    font: inherit;
    font-size: var( --typo-klein );
    line-height: var( --typo-klein-lh );
    color: var( --color-black );
    background-color: var( --color-white );
}

.bewerbung-formular :is( input, textarea )::placeholder{
    color: var( --color-feld-platzhalter );
    opacity: 1; /* Firefox dims placeholders on top of the colour. */
}

.bewerbung-formular input:not( [type="file"] ){
    block-size: 2.8125rem; /* 45px, as drawn */
}

.bewerbung-formular textarea{
    block-size: 11.25rem; /* 180px */
    resize: vertical;
}

.bewerbung-formular :is( input, textarea )[aria-invalid="true"]{
    border-color: var( --color-red );
    border-width: 2px;
}

.feld-fehler{
    margin: 0;
    font-size: var( --typo-klein );
    line-height: var( --typo-klein-lh );
    color: var( --color-red );
}

.fehler-liste{
    margin-block-end: var( --space-l );
    padding: var( --space-m );
    border: 2px solid var( --color-red );
    max-inline-size: var( --feld-breite );

    font-size: var( --typo-klein );
    line-height: var( --typo-klein-lh );

    p{ margin-block: 0 var( --space-xs ); }
    ul{ margin: 0; padding-inline-start: 1.2em; }
}

/* Off-screen rather than display:none — a field that is not rendered at all is
   one some bots learn to skip. */
.honigtopf{
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    overflow: hidden;
    clip-path: inset( 50% );
    white-space: nowrap;
}

.dokumente{
    margin-block: var( --space-xl ) var( --space-l );
    max-inline-size: var( --feld-breite );

    h2{
        font-size: var( --typo-zeile );
        line-height: var( --typo-zeile-lh );
        margin: 0;
    }

    > p{
        margin-block: 0 var( --space-l );
        font-size: var( --typo-klein );
        line-height: var( --typo-klein-lh );
    }
}

/* The design labels this control “Datei hinzufügen”. A native file input takes
   both its button text and its “no file chosen” text from the browser's own
   locale, so on a German-only site it can read “Välj fil” — wrong language and
   wrong words. The input therefore stays a real, focusable input but goes
   out of sight, and the pill beside it is a second <label> pointing at it,
   which opens the picker with no script involved.

   Only the chosen file's name needs script, so the input is hidden only once
   script is known to be running. */
.datei-zeile{
    display: flex;
    align-items: center;
    gap: var( --space-s );
    flex-wrap: wrap;
}

.js .feld-datei input[type="file"]{
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    /* The shared field rule gives every input padding and a border; both would
       otherwise still occupy space around the 1px box. */
    padding: 0;
    border: none;
    overflow: hidden;
    clip-path: inset( 50% );
    white-space: nowrap;
}

/* Without script the native control is the whole story, so the pill steps out
   of the way rather than duplicating it. */
html:not( .js ) .datei-button{
    display: none;
}

.datei-button{
    /* The same component as .pill, one size down: 2px stroke, 15px each side,
       a 39px box. As there, the block padding absorbs the difference between
       Figma's cap-trimmed text box and the 25px line box — 5 + 5 + 2 + 2 + 25. */
    padding: 0.3125rem 0.9375rem;
    border: 2px solid var( --color-black );
    border-radius: 40px;

    font-size: var( --typo-klein );
    line-height: var( --typo-klein-lh );
    white-space: nowrap;
    cursor: pointer;

    transition: background-color var( --duration-s ) ease-out,
                color var( --duration-s ) ease-out;
}

.datei-button:hover{
    background-color: var( --color-black );
    color: var( --color-white );
}

/* The input carries the focus but is out of sight, so the ring is drawn on the
   pill that stands in for it. */
.feld-datei:focus-within .datei-button{
    outline: 2px solid var( --color-black );
    outline-offset: 2px;
}

.datei-name{
    font-size: var( --typo-klein );
    line-height: var( --typo-klein-lh );
}

.bewerbung-abschluss{
    border-block-start: var( --linie );
    padding-block-start: var( --space-l );
}

.bewerbung-freude{
    margin-block: 0 var( --space-m );
    font-size: var( --typo-zeile );
    line-height: var( --typo-zeile-lh );
}

/* .pill takes its height from the type around it, and the design draws the
   submit at the full 60px — so it is set against the 30px scale, not the 20px
   the fields use. */
.bewerbung-abschluss .pill{
    font-size: var( --typo-zeile );
}

@media (width < 48rem){
    .titel-band{
        --titel-band-luft: 0.625rem;

        /* Bewerbungsvorlage_Mobil: a 107px band around a 68px two-line trimmed
           headline, so 19.5px either side. */
        @supports ( text-box: trim-both cap alphabetic ){
            --titel-band-luft: 1.21875rem;
        }
    }


    /* The band keeps the green block for the list and stacks the two accents
       beside it, as Bewerbungsvorlage_Mobil draws them. */
    .eckdaten-band{
        grid-template-columns: 298fr 95fr;
        min-block-size: 8.6875rem; /* 139px */
    }

    .eckdaten-feld{
        grid-row: span 2;
    }

    .feld-paar{
        grid-template-columns: 1fr;
    }

    .feld-schmal{
        max-inline-size: none;
    }
}

/* ------------------------------------------------------- Impressum / Datenschutz */

/* The legal pages: a headline band, the firm's masthead, then running text in
   one column. 750px wide at 1440, as drawn — a measure, not the full width. */
.seiten-text{
    padding-block: var( --space-xl );

    /* 750px of text at 1440, as drawn. The page gutters sit inside this box
       (.content-width pads it), so they are added on rather than eaten out of
       the measure. */
    --text-mass: 46.875rem;
    max-inline-size: calc( var( --text-mass ) + 2 * var( --padding-side ) );

    font-size: var( --typo-klein );
    line-height: var( --typo-klein-lh );

    /* CKEditor writes plain <p>/<h2>/<ul>, so the prose is styled by element.
       One rhythm for the lot: a line of space between blocks. */
    :is( p, ul, ol ){
        margin-block: 0 1lh;
    }

    :is( ul, ol ){
        padding-inline-start: 1.2em;
    }

    /* “Design & Webentwicklung” and anything else the editor promotes. The
       field offers h2 and h3 only — the page's h1 is the entry title. */
    :is( h2, h3 ){
        font-size: var( --typo-liste );
        line-height: var( --typo-liste-lh );
        margin-block: 2lh 0;
    }

    /* The scale has no step between the h2's 25 and the body's 20, so a third
       level is set apart by face rather than by an invented size. */
    h3{
        font-family: var( --font-serif );
        font-size: var( --typo-klein );
        line-height: var( --typo-klein-lh );
        margin-block-start: 1lh;
    }

    /* CKEditor can write <strong>, which the design never does. Unica ships
       Regular only, so a bold run here would be synthesised by the browser;
       GT Alpina has a real Bold, so emphasis borrows that rather than a faked
       weight. */
    strong{
        font-family: var( --font-serif );
        font-weight: 700;
    }

    > :last-child{
        margin-block-end: 0;
    }
}

.seiten-text-kanzlei{
    margin-block-end: 2lh;
    /* 334px at 1440 as drawn, down to the 205px the header and footer logos
       use on a phone — at full size it would all but fill a 353px column. */
    --wortmarke-breite: clamp( 12.8125rem, 9.7862rem + 12.3209vw, 20.875rem );

    .logo svg{
        /* 334px wide at 1440 in the design, and it shrinks with the page. */
        inline-size: min( 100%, var( --wortmarke-breite ) );
        block-size: auto;
    }

    .rechtsform{
        margin-block: var( --space-xs ) 0;
        font-size: var( --typo-text );
        line-height: var( --typo-text-lh );

        /* Held to the wordmark's width so it breaks beneath it the way the
           frame draws it, rather than running the full measure. At the wordmark's
           narrow end that would force a third line, so a phone gets the full
           column instead. */
        max-inline-size: var( --wortmarke-breite );

        @media (width < 48rem){
            max-inline-size: none;
        }
    }
}
