@charset "UTF-8";/*!
 * mmenu.js
 * mmenujs.com
 *
 * Copyright (c) Fred Heusschen
 * frebsite.nl
 *
 * License: CC-BY-NC-4.0
 * http://creativecommons.org/licenses/by-nc/4.0/
 */:root{--mm-lineheight:22px}.mm-hidden{display:none!important}.mm-wrapper{overflow-x:hidden;position:relative}.mm-menu,.mm-menu *,.mm-menu :after,.mm-menu :before{-webkit-transition-property:none;-o-transition-property:none;transition-property:none;-webkit-transition-duration:.4s;-o-transition-duration:.4s;transition-duration:.4s;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease}:root{--mm-blocker-visibility-delay:0.4s;--mm-blocker-opacity-delay:0s}.mm-blocker{display:block;position:absolute;bottom:100%;top:0;right:0;left:0;z-index:3;opacity:0;background:var(--mm-color-background);-webkit-transition:bottom 0s ease var(--mm-blocker-visibility-delay),width .4s ease,opacity .4s ease var(--mm-blocker-opacity-delay),-webkit-transform .4s ease;transition:bottom 0s ease var(--mm-blocker-visibility-delay),width .4s ease,opacity .4s ease var(--mm-blocker-opacity-delay),-webkit-transform .4s ease;-o-transition:bottom 0s ease var(--mm-blocker-visibility-delay),width .4s ease,opacity .4s ease var(--mm-blocker-opacity-delay),transform .4s ease;transition:bottom 0s ease var(--mm-blocker-visibility-delay),width .4s ease,opacity .4s ease var(--mm-blocker-opacity-delay),transform .4s ease;transition:bottom 0s ease var(--mm-blocker-visibility-delay),width .4s ease,opacity .4s ease var(--mm-blocker-opacity-delay),transform .4s ease,-webkit-transform .4s ease}.mm-blocker:focus-visible{opacity:.75}.mm-btn{-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;position:relative;width:50px;padding:0}.mm-btn--next,[dir=rtl] .mm-btn--prev{--mm-btn-rotate:135deg}.mm-btn--prev,[dir=rtl] .mm-btn--next{--mm-btn-rotate:-45deg}.mm-btn--next:after,.mm-btn--prev:before{content:"";display:block;position:absolute;top:0;bottom:0;width:8px;height:8px;margin:auto;-webkit-box-sizing:border-box;box-sizing:border-box;border:2px solid var(--mm-color-icon);border-bottom:none;border-right:none;-webkit-transform:rotate(var(--mm-btn-rotate));-ms-transform:rotate(var(--mm-btn-rotate));transform:rotate(var(--mm-btn-rotate))}.mm-btn--prev:before{inset-inline-start:23px}.mm-btn--next:after{inset-inline-end:23px}.mm-btn--close:before{content:"×";font-size:150%}.mm-btnreset{padding:0;background:0 0;border:none;cursor:pointer}.mm-divider{-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;position:-webkit-sticky;position:sticky;z-index:2;top:0;min-height:var(--mm-lineheight);padding:calc((var(--mm-listitem-size) * .65 - var(--mm-lineheight)) * .5) 20px;font-size:75%;text-transform:uppercase;background:var(--mm-color-background);background-image:-webkit-gradient(linear,left top,left bottom,from(var(--mm-color-background-highlight)),to(var(--mm-color-background-highlight)));background-image:-o-linear-gradient(var(--mm-color-background-highlight),var(--mm-color-background-highlight));background-image:linear-gradient(var(--mm-color-background-highlight),var(--mm-color-background-highlight));opacity:1;-webkit-transition-property:opacity;-o-transition-property:opacity;transition-property:opacity}.mm-navbar:not(.mm-hidden)~.mm-listview .mm-divider{top:var(--mm-navbar-size)}:root{--mm-listitem-size:50px}.mm-listitem{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;position:relative;padding:0;margin:0;color:var(--mm-color-text);border-color:var(--mm-color-border)}.mm-listitem:after{content:"";border-color:inherit;border-bottom-width:1px;border-bottom-style:solid;display:block;position:absolute;inset-inline-start:20px;inset-inline-end:0;bottom:0}.mm-listitem__btn,.mm-listitem__text{padding:calc((var(--mm-listitem-size) - var(--mm-lineheight))/ 2) 0}.mm-listitem__text{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-ms-flex-preferred-size:10%;flex-basis:10%;display:block;padding-left:20px;padding-right:20px;-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.mm-listitem__btn{display:block;position:relative;width:auto;-webkit-padding-end:50px;padding-inline-end:50px;border-color:inherit;background:rgba(3,2,1,0)}.mm-listitem__btn:not(.mm-listitem__text){border-left-width:1px;border-left-style:solid}.mm-listitem--selected>.mm-listitem__text{background:var(--mm-color-background-emphasis)}.mm-listitem--opened>.mm-listitem__btn,.mm-listitem--opened>.mm-panel{background:var(--mm-color-background-highlight)}.mm-listview{list-style:none;display:block;padding:0;margin:0}.mm-menu{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;padding:0;margin:0;position:absolute;top:0;right:0;bottom:0;left:0;z-index:0;-ms-scroll-chaining:none;overscroll-behavior:none;background:var(--mm-color-background);border-color:var(--mm-color-border);color:var(--mm-color-text);line-height:var(--mm-lineheight);-webkit-tap-highlight-color:var(--mm-color-background-emphasis);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.mm-menu ::-webkit-input-placeholder{color:var(--mm-color-text-dimmed)}.mm-menu ::-moz-placeholder{color:var(--mm-color-text-dimmed)}.mm-menu :-ms-input-placeholder{color:var(--mm-color-text-dimmed)}.mm-menu ::-ms-input-placeholder{color:var(--mm-color-text-dimmed)}.mm-menu ::placeholder{color:var(--mm-color-text-dimmed)}.mm-menu,.mm-menu *{-webkit-box-sizing:border-box;box-sizing:border-box}.mm-menu :focus,.mm-menu :focus-visible,.mm-menu:focus,.mm-menu:focus-visible{outline:0}.mm-menu a,.mm-menu button,.mm-menu label{color:inherit}.mm-menu a:focus,.mm-menu button:focus,.mm-menu label:focus{outline:0}.mm-menu a:focus-visible,.mm-menu button:focus-visible,.mm-menu label:focus-visible{outline:2px solid var(--mm-color-focusring);outline-offset:-5px}.mm-menu input:focus,.mm-menu input:focus-visible,.mm-menu select:focus,.mm-menu select:focus-visible,.mm-menu textarea:focus,.mm-menu textarea:focus-visible{outline:2px solid var(--mm-color-focusring);outline-offset:2px}.mm-menu a,.mm-menu a:active,.mm-menu a:hover,.mm-menu a:link,.mm-menu a:visited{text-decoration:none;color:inherit}:root{--mm-navbar-size:50px}.mm-navbar{display:-webkit-box;display:-ms-flexbox;display:flex;position:-webkit-sticky;position:sticky;top:0;z-index:2;min-height:var(--mm-navbar-size);padding-top:env(safe-area-inset-top);color:var(--mm-color-text-dimmed);text-align:center;opacity:1;background:var(--mm-color-background);border-bottom:1px solid var(--mm-color-border);-webkit-transition-property:opacity;-o-transition-property:opacity;transition-property:opacity}.mm-navbar>*{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-sizing:border-box;box-sizing:border-box}.mm-navbar__btn{-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0}.mm-navbar__title{-webkit-box-flex:1;-ms-flex:1 1 50%;flex:1 1 50%;display:-webkit-box;display:-ms-flexbox;display:flex;padding:0 20px;overflow:hidden}.mm-navbar__title[href="#"]{pointer-events:none}.mm-navbar__title>span{-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.mm-btn.mm-hidden+.mm-navbar__title:not(:last-child){-webkit-padding-start:60px;padding-inline-start:60px;-webkit-padding-end:10px;padding-inline-end:10px}.mm-btn:not(.mm-hidden)+.mm-navbar__title:last-child{-webkit-padding-start:10px;padding-inline-start:10px;-webkit-padding-end:60px;padding-inline-end:60px}.mm-panel{--mm-panel-child-offset:100%;--mm-panel-parent-offset:-30%;position:absolute;left:0;right:0;top:0;bottom:0;z-index:1;-webkit-overflow-scrolling:touch;overflow:hidden;overflow-y:auto;-ms-scroll-chaining:none;overscroll-behavior:contain;color:var(--mm-color-text);border-color:var(--mm-color-border);background:var(--mm-color-background);-webkit-transform:translate3d(var(--mm-panel-child-offset),0,0);transform:translate3d(var(--mm-panel-child-offset),0,0);-webkit-transition-property:inset-inline-start,-webkit-transform;transition-property:inset-inline-start,-webkit-transform;-o-transition-property:transform,inset-inline-start;transition-property:transform,inset-inline-start;transition-property:transform,inset-inline-start,-webkit-transform}[dir=rtl] .mm-panel{--mm-panel-child-offset:-100%;--mm-panel-parent-offset:30%}.mm-panel:after{content:"";display:block;height:var(--mm-listitem-size)}.mm-panel:focus{outline:0}.mm-panel--opened{z-index:2;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-webkit-transition-delay:0s;-o-transition-delay:0s;transition-delay:0s}.mm-panel--parent{-webkit-transform:translate3d(var(--mm-panel-parent-offset),0,0);transform:translate3d(var(--mm-panel-parent-offset),0,0);z-index:0}.mm-panel--highest{z-index:3}.mm-menu--opened .mm-panel--noanimation{-webkit-transition:none!important;-o-transition:none!important;transition:none!important;-webkit-transition-duration:0s!important;-o-transition-duration:0s!important;transition-duration:0s!important}.mm-panel__content{padding:20px}.mm-panels{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;position:relative;height:100%;overflow:hidden;background:var(--mm-color-background);border-color:var(--mm-color-border);color:var(--mm-color-text)}.mm-panels:focus{outline:0}:root{--mm-toggle-size:34px}.mm-toggle{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-item-align:center;align-self:center;-webkit-box-flex:calc(var(--mm-toggle-size) * 1.75);-ms-flex:calc(var(--mm-toggle-size) * 1.75) 0 0px;flex:calc(var(--mm-toggle-size) * 1.75) 0 0;height:var(--mm-toggle-size);-webkit-margin-end:10px;margin-inline-end:10px;-webkit-appearance:none!important;-moz-appearance:none!important;appearance:none!important;border:none!important;border-radius:var(--mm-toggle-size);border:var(--mm-color-border);background:var(--mm-color-border);cursor:pointer;-webkit-transition-property:background-color;-o-transition-property:background-color;transition-property:background-color}.mm-toggle:before{content:"";aspect-ratio:1;margin:2px;border-radius:100%;background:var(--mm-color-background);-webkit-transition-property:-webkit-transform;transition-property:-webkit-transform;-o-transition-property:transform;transition-property:transform;transition-property:transform,-webkit-transform}.mm-toggle:checked{background:#4bd963}.mm-toggle:checked:before{-webkit-transform:translateX(calc(var(--mm-toggle-size) * .75));-ms-transform:translateX(calc(var(--mm-toggle-size) * .75));transform:translateX(calc(var(--mm-toggle-size) * .75))}[dir=rtl] .mm-toggle:checked:before{-webkit-transform:translateX(calc(var(--mm-toggle-size) * -.75));-ms-transform:translateX(calc(var(--mm-toggle-size) * -.75));transform:translateX(calc(var(--mm-toggle-size) * -.75))}.mm-listitem--vertical>.mm-panel{position:static;width:100%;padding:10px 0 10px 20px;-webkit-transform:none!important;-ms-transform:none!important;transform:none!important;-webkit-transition:none!important;-o-transition:none!important;transition:none!important}.mm-listitem--vertical>.mm-panel:after{content:none;display:none}.mm-listitem--vertical:not(.mm-listitem--opened)>.mm-panel{display:none}.mm-listitem--vertical>.mm-listitem__btn{height:var(--mm-listitem-size);bottom:auto}.mm-listitem--vertical .mm-listitem:last-child:after{border-color:transparent}.mm-listitem--opened>.mm-listitem__btn:after{-webkit-transform:rotate(225deg);-ms-transform:rotate(225deg);transform:rotate(225deg);right:19px}:root{--mm-size:80%;--mm-min-size:240px;--mm-max-size:440px}.mm-menu--offcanvas{position:fixed;z-index:0}.mm-page{-webkit-box-sizing:border-box;box-sizing:border-box;min-height:100vh;background:inherit}:where(.mm-slideout){position:relative;z-index:1;width:100%;-webkit-transition-duration:.4s;-o-transition-duration:.4s;transition-duration:.4s;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-property:width,-webkit-transform;transition-property:width,-webkit-transform;-o-transition-property:width,transform;transition-property:width,transform;transition-property:width,transform,-webkit-transform}.mm-wrapper--opened,.mm-wrapper--opened body{overflow:hidden}.mm-wrapper__blocker{background:rgba(0,0,0,.4)}.mm-wrapper--opened .mm-wrapper__blocker{--mm-blocker-visibility-delay:0s;--mm-blocker-opacity-delay:0.4s;bottom:0;opacity:.5}.mm-menu{--mm-translate-horizontal:0;--mm-translate-vertical:0}.mm-menu--position-left,.mm-menu--position-left-front{right:auto}.mm-menu--position-right,.mm-menu--position-right-front{left:auto}.mm-menu--position-left,.mm-menu--position-left-front,.mm-menu--position-right,.mm-menu--position-right-front{width:clamp(var(--mm-min-size),var(--mm-size),var(--mm-max-size))}.mm-menu--position-left-front{--mm-translate-horizontal:-100%}.mm-menu--position-right-front{--mm-translate-horizontal:100%}.mm-menu--position-top{bottom:auto}.mm-menu--position-bottom{top:auto}.mm-menu--position-bottom,.mm-menu--position-top{width:100%;height:clamp(var(--mm-min-size),var(--mm-size),var(--mm-max-size))}.mm-menu--position-top{--mm-translate-vertical:-100%}.mm-menu--position-bottom{--mm-translate-vertical:100%}.mm-menu--position-bottom,.mm-menu--position-left-front,.mm-menu--position-right-front,.mm-menu--position-top{z-index:2;-webkit-transform:translate3d(var(--mm-translate-horizontal),var(--mm-translate-vertical),0);transform:translate3d(var(--mm-translate-horizontal),var(--mm-translate-vertical),0);-webkit-transition-property:-webkit-transform;transition-property:-webkit-transform;-o-transition-property:transform;transition-property:transform;transition-property:transform,-webkit-transform}.mm-menu--position-bottom.mm-menu--opened,.mm-menu--position-left-front.mm-menu--opened,.mm-menu--position-right-front.mm-menu--opened,.mm-menu--position-top.mm-menu--opened{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.mm-wrapper--position-left{--mm-translate-horizontal:clamp(
      var(--mm-min-size),
      var(--mm-size),
      var(--mm-max-size)
  )}.mm-wrapper--position-right{--mm-translate-horizontal:clamp(
      calc(-1 * var(--mm-max-size)),
      calc(-1 * var(--mm-size)),
      calc(-1 * var(--mm-min-size))
  )}.mm-wrapper--position-left .mm-slideout,.mm-wrapper--position-right .mm-slideout{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.mm-wrapper--position-left.mm-wrapper--opened .mm-slideout,.mm-wrapper--position-right.mm-wrapper--opened .mm-slideout{-webkit-transform:translate3d(var(--mm-translate-horizontal),0,0);transform:translate3d(var(--mm-translate-horizontal),0,0)}.mm-wrapper--position-bottom .mm-wrapper__blocker,.mm-wrapper--position-left-front .mm-wrapper__blocker,.mm-wrapper--position-right-front .mm-wrapper__blocker,.mm-wrapper--position-top .mm-wrapper__blocker{z-index:1}.mm-menu--theme-light{--mm-color-background:#f3f3f3;--mm-color-border:rgb(0 0 0 / 0.15);--mm-color-icon:rgb(0 0 0 / 0.4);--mm-color-text:rgb(0 0 0 / 0.8);--mm-color-text-dimmed:rgb(0 0 0 / 0.4);--mm-color-background-highlight:rgb(0 0 0 / 0.05);--mm-color-background-emphasis:rgb(255 255 255 / 0.75);--mm-color-focusring:#06c}.mm-menu--theme-light-contrast{--mm-color-background:#f3f3f3;--mm-color-border:rgb(0 0 0 / 0.5);--mm-color-icon:rgb(0 0 0 / 0.5);--mm-color-text:#000;--mm-color-text-dimmed:rgb(0 0 0 / 0.7);--mm-color-background-highlight:rgb(0 0 0 / 0.05);--mm-color-background-emphasis:rgb(255 255 255 / 0.9);--mm-color-focusring:#06c}.mm-menu--theme-dark{--mm-color-background:#333;--mm-color-border:rgb(0, 0, 0, 0.4);--mm-color-icon:rgb(255, 255, 255, 0.4);--mm-color-text:rgb(255, 255, 255, 0.8);--mm-color-text-dimmed:rgb(255, 255, 255, 0.4);--mm-color-background-highlight:rgb(255, 255, 255, 0.08);--mm-color-background-emphasis:rgb(0, 0, 0, 0.1);--mm-color-focusring:#06c}.mm-menu--theme-dark-contrast{--mm-color-background:#333;--mm-color-border:rgb(255 255 255 / 0.5);--mm-color-icon:rgb(255 255 255 / 0.5);--mm-color-text:#fff;--mm-color-text-dimmed:rgb(255 255 255 / 0.7);--mm-color-background-highlight:rgb(255 255 255 / 0.1);--mm-color-background-emphasis:rgb(0 0 0 / 0.3);--mm-color-focusring:#06c}.mm-menu--theme-white{--mm-color-background:#fff;--mm-color-border:rgb(0 0 0 / 0.15);--mm-color-icon:rgb(0 0 0 / 0.3);--mm-color-text:rgb(0 0 0 / 0.8);--mm-color-text-dimmed:rgb(0 0 0 / 0.3);--mm-color-background-highlight:rgb(0 0 0 / 0.06);--mm-color-background-emphasis:rgb(0 0 0 / 0.03);--mm-color-focusring:#06c}.mm-menu--theme-white-contrast{--mm-color-background:#fff;--mm-color-border:rgb(0 0 0 / 0.5);--mm-color-icon:rgb(0 0 0 / 0.5);--mm-color-text:#000;--mm-color-text-dimmed:rgb(0 0 0 / 0.7);--mm-color-background-highlight:rgb(0 0 0 / 0.07);--mm-color-background-emphasis:rgb(0 0 0 / 0.035);--mm-color-focusring:#06c}.mm-menu--theme-black{--mm-color-background:#000;--mm-color-border:rgb(255 255 255 / 0.2);--mm-color-icon:rgb(255 255 255 / 0.4);--mm-color-text:rgb(255 255 255 / 0.7);--mm-color-text-dimmed:rgb(255 255 255 / 0.4);--mm-color-background-highlight:rgb(255 255 255 / 0.1);--mm-color-background-emphasis:rgb(255 255 255 / 0.06);--mm-color-focusring:#06c}.mm-menu--theme-black-contrast{--mm-color-background:#000;--mm-color-border:rgb(255 255 255 / 0.5);--mm-color-icon:rgb(255 255 255 / 0.5);--mm-color-text:#fff;--mm-color-text-dimmed:rgb(255 255 255 / 0.6);--mm-color-background-highlight:rgb(255 255 255 / 0.125);--mm-color-background-emphasis:rgb(255 255 255 / 0.1);--mm-color-focusring:#06c}.mm-counter{display:block;-webkit-padding-start:20px;padding-inline-start:20px;float:right;color:var(--mm-color-text-dimmed)}[dir=rtl] .mm-counter{float:left}:root{--mm-iconbar-size:50px}.mm-menu--iconbar-left .mm-navbars,.mm-menu--iconbar-left .mm-panels{margin-left:var(--mm-iconbar-size)}.mm-menu--iconbar-right .mm-navbars,.mm-menu--iconbar-right .mm-panels{margin-right:var(--mm-iconbar-size)}.mm-iconbar{display:none;position:absolute;top:0;bottom:0;z-index:2;width:var(--mm-iconbar-size);overflow:hidden;-webkit-box-sizing:border-box;box-sizing:border-box;border:0 solid;border-color:var(--mm-color-border);background:var(--mm-color-background);color:var(--mm-color-text-dimmed);text-align:center}.mm-menu--iconbar-left .mm-iconbar,.mm-menu--iconbar-right .mm-iconbar{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.mm-menu--iconbar-left .mm-iconbar{border-right-width:1px;left:0}.mm-menu--iconbar-right .mm-iconbar{border-left-width:1px;right:0}.mm-iconbar__bottom,.mm-iconbar__top{width:100%;-webkit-overflow-scrolling:touch;overflow:hidden;overflow-y:auto;-ms-scroll-chaining:none;overscroll-behavior:contain}.mm-iconbar__bottom>*,.mm-iconbar__top>*{-webkit-box-sizing:border-box;box-sizing:border-box;display:block;padding:calc((var(--mm-iconbar-size) - var(--mm-lineheight))/ 2) 0}.mm-iconbar__bottom a,.mm-iconbar__bottom a:hover,.mm-iconbar__top a,.mm-iconbar__top a:hover{text-decoration:none}.mm-iconbar__tab--selected{background:var(--mm-color-background-emphasis)}:root{--mm-iconpanel-size:50px}.mm-panel--iconpanel-0{inset-inline-start:calc(0 * var(--mm-iconpanel-size))}.mm-panel--iconpanel-1{inset-inline-start:calc(1 * var(--mm-iconpanel-size))}.mm-panel--iconpanel-2{inset-inline-start:calc(2 * var(--mm-iconpanel-size))}.mm-panel--iconpanel-3{inset-inline-start:calc(3 * var(--mm-iconpanel-size))}.mm-panel--iconpanel-4{inset-inline-start:calc(4 * var(--mm-iconpanel-size))}.mm-panel--iconpanel-first~.mm-panel{inset-inline-start:var(--mm-iconpanel-size)}.mm-menu--iconpanel .mm-panel--parent .mm-divider,.mm-menu--iconpanel .mm-panel--parent .mm-navbar{opacity:0}.mm-menu--iconpanel .mm-panels>.mm-panel--parent{overflow-y:hidden;-webkit-transform:unset;-ms-transform:unset;transform:unset}.mm-menu--iconpanel .mm-panels>.mm-panel:not(.mm-panel--iconpanel-first):not(.mm-panel--iconpanel-0){border-inline-start-width:1px;border-inline-start-style:solid}.mm-navbars{-ms-flex-negative:0;flex-shrink:0}.mm-navbars .mm-navbar{position:relative;padding-top:0;border-bottom:none}.mm-navbars--top{border-bottom:1px solid var(--mm-color-border)}.mm-navbars--top .mm-navbar:first-child{padding-top:env(safe-area-inset-top)}.mm-navbars--bottom{border-top:1px solid var(--mm-color-border)}.mm-navbars--bottom .mm-navbar:last-child{padding-bottom:env(safe-area-inset-bottom)}.mm-navbar__breadcrumbs{-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;-webkit-box-flex:1;-ms-flex:1 1 50%;flex:1 1 50%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;padding:0 20px;overflow-x:auto;-webkit-overflow-scrolling:touch}.mm-navbar__breadcrumbs>*{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-padding-end:6px;padding-inline-end:6px}.mm-navbar__breadcrumbs>a{text-decoration:underline}.mm-navbar__breadcrumbs:not(:last-child){-webkit-padding-end:0;padding-inline-end:0}.mm-btn:not(.mm-hidden)+.mm-navbar__breadcrumbs{-webkit-padding-start:0;padding-inline-start:0}.mm-navbar__tab{padding:0 10px;border:1px solid transparent}.mm-navbar__tab--selected{background:var(--mm-color-background)}.mm-navbar__tab--selected:not(:first-child){border-inline-start-color:var(--mm-color-border)}.mm-navbar__tab--selected:not(:last-child){border-inline-end-color:var(--mm-color-border)}.mm-navbars--top.mm-navbars--has-tabs{border-bottom:none}.mm-navbars--top.mm-navbars--has-tabs .mm-navbar{background:var(--mm-color-background-emphasis)}.mm-navbars--top.mm-navbars--has-tabs .mm-navbar--tabs~.mm-navbar{background:var(--mm-color-background)}.mm-navbars--top.mm-navbars--has-tabs .mm-navbar:not(.mm-navbar--tabs):last-child{border-bottom:1px solid var(--mm-color-border)}.mm-navbars--top .mm-navbar__tab{border-bottom-color:var(--mm-color-border)}.mm-navbars--top .mm-navbar__tab--selected{border-top-color:var(--mm-color-border);border-bottom-color:transparent}.mm-navbars--bottom.mm-navbar--has-tabs{border-top:none}.mm-navbars--bottom.mm-navbar--has-tabs .mm-navbar{background:var(--mm-color-background)}.mm-navbars--bottom.mm-navbar--has-tabs .mm-navbar--tabs,.mm-navbars--bottom.mm-navbar--has-tabs .mm-navbar--tabs~.mm-navbar{background:var(--mm-color-background-emphasis)}.mm-navbars--bottom .mm-navbar__tab{border-top-color:var(--mm-color-border)}.mm-navbars--bottom .mm-navbar__tab--selected{border-bottom-color:var(--mm-color-border);border-top-color:transparent}.mm-searchfield{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;height:var(--mm-navbar-size);padding:0;overflow:hidden}.mm-searchfield__input{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-ms-flex:1;flex:1;-webkit-box-align:center;-ms-flex-align:center;align-items:center;position:relative;width:100%;max-width:100%;padding:0 10px;-webkit-box-sizing:border-box;box-sizing:border-box}.mm-searchfield__input input{display:block;width:100%;max-width:100%;height:calc(var(--mm-navbar-size) * .7);min-height:auto;max-height:auto;margin:0;padding:0 10px;-webkit-box-sizing:border-box;box-sizing:border-box;border:none;border-radius:4px;line-height:calc(var(--mm-navbar-size) * .7);font:inherit;font-size:inherit}.mm-searchfield__input input,.mm-searchfield__input input:focus,.mm-searchfield__input input:hover{background:var(--mm-color-background-highlight);color:var(--mm-color-text)}.mm-menu[class*=-contrast] .mm-searchfield__input input{border:1px solid var(--mm-color-border)}.mm-searchfield__input input::-ms-clear{display:none}.mm-searchfield__btn{display:none;position:absolute;inset-inline-end:0;top:0;bottom:0}.mm-searchfield--searching .mm-searchfield__btn{display:block}.mm-searchfield__cancel{display:block;position:relative;-webkit-margin-end:-100px;margin-inline-end:-100px;-webkit-padding-start:5px;padding-inline-start:5px;-webkit-padding-end:20px;padding-inline-end:20px;visibility:hidden;line-height:var(--mm-navbar-size);text-decoration:none;-webkit-transition-property:visibility,margin;-o-transition-property:visibility,margin;transition-property:visibility,margin}.mm-searchfield--cancelable .mm-searchfield__cancel{visibility:visible;-webkit-margin-end:0;margin-inline-end:0}.mm-panel--search{left:0!important;right:0!important;width:100%!important;border:none!important}.mm-panel__splash{padding:20px}.mm-panel--searching .mm-panel__splash{display:none}.mm-panel__noresults{display:none;padding:40px 20px;color:var(--mm-color-text-dimmed);text-align:center;font-size:150%;line-height:1.4}.mm-panel--noresults .mm-panel__noresults{display:block}:root{--mm-sectionindexer-size:20px}.mm-sectionindexer{background:inherit;text-align:center;font-size:12px;-webkit-box-sizing:border-box;box-sizing:border-box;width:var(--mm-sectionindexer-size);position:absolute;top:0;bottom:0;inset-inline-end:calc(-1 * var(--mm-sectionindexer-size));z-index:5;-webkit-transition-property:inset-inline-end;-o-transition-property:inset-inline-end;transition-property:inset-inline-end;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:space-evenly;-ms-flex-pack:space-evenly;justify-content:space-evenly}.mm-sectionindexer a{color:var(--mm-color-text-dimmed);line-height:1;text-decoration:none;display:block}.mm-sectionindexer~.mm-panel{-webkit-padding-end:0;padding-inline-end:0}.mm-sectionindexer--active{right:0}.mm-sectionindexer--active~.mm-panel{-webkit-padding-end:var(--mm-sectionindexer-size);padding-inline-end:var(--mm-sectionindexer-size)}.mm-menu--selected-hover .mm-listitem__btn,.mm-menu--selected-hover .mm-listitem__text,.mm-menu--selected-parent .mm-listitem__btn,.mm-menu--selected-parent .mm-listitem__text{-webkit-transition-property:background-color;-o-transition-property:background-color;transition-property:background-color}@media (hover:hover){.mm-menu--selected-hover .mm-listview:hover>.mm-listitem--selected:not(:hover)>.mm-listitem__text{background:0 0}.mm-menu--selected-hover .mm-listitem__btn:hover,.mm-menu--selected-hover .mm-listitem__text:hover{background:var(--mm-color-background-emphasis)}}.mm-menu--selected-parent .mm-listitem__btn,.mm-menu--selected-parent .mm-listitem__text{-webkit-transition-delay:.2s;-o-transition-delay:.2s;transition-delay:.2s}@media (hover:hover){.mm-menu--selected-parent .mm-listitem__btn:hover,.mm-menu--selected-parent .mm-listitem__text:hover{-webkit-transition-delay:0s;-o-transition-delay:0s;transition-delay:0s}}.mm-menu--selected-parent .mm-panel--parent .mm-listitem:not(.mm-listitem--selected-parent)>.mm-listitem__text{background:0 0}.mm-menu--selected-parent .mm-listitem--selected-parent>.mm-listitem__btn,.mm-menu--selected-parent .mm-listitem--selected-parent>.mm-listitem__text{background:var(--mm-color-background-emphasis)}:root{--mm-sidebar-collapsed-size:50px;--mm-sidebar-expanded-size:var(--mm-max-size)}.mm-wrapper--sidebar-collapsed .mm-slideout{width:calc(100% - var(--mm-sidebar-collapsed-size));-webkit-transform:translate3d(var(--mm-sidebar-collapsed-size),0,0);transform:translate3d(var(--mm-sidebar-collapsed-size),0,0)}[dir=rtl] .mm-wrapper--sidebar-collapsed .mm-slideout{-webkit-transform:none;-ms-transform:none;transform:none}.mm-wrapper--sidebar-collapsed:not(.mm-wrapper--opened) .mm-menu--sidebar-collapsed .mm-divider,.mm-wrapper--sidebar-collapsed:not(.mm-wrapper--opened) .mm-menu--sidebar-collapsed .mm-navbar{opacity:0}.mm-wrapper--sidebar-expanded .mm-menu--sidebar-expanded{width:var(--mm-sidebar-expanded-size);border-right-width:1px;border-right-style:solid}.mm-wrapper--sidebar-expanded.mm-wrapper--opened{overflow:auto}.mm-wrapper--sidebar-expanded.mm-wrapper--opened .mm-wrapper__blocker{display:none}.mm-wrapper--sidebar-expanded.mm-wrapper--opened .mm-slideout{width:calc(100% - var(--mm-sidebar-expanded-size));-webkit-transform:translate3d(var(--mm-sidebar-expanded-size),0,0);transform:translate3d(var(--mm-sidebar-expanded-size),0,0)}[dir=rtl] .mm-wrapper--sidebar-expanded.mm-wrapper--opened .mm-slideout{-webkit-transform:none;-ms-transform:none;transform:none}
/* ======================================================================
   Bright Cloud Studio Layout Utility Framework (Pure CSS)
   DESKTOP-FIRST • max-width media queries
   ====================================================================== */

/* ======================================================================
   PROJECT TOKENS — EDIT THESE PER SITE
   ====================================================================== */
:root {
  /* Page gutters (site margins). Stepped rather than fluid to keep the
     brightcloudstudio.com shell as designed: 90px, then 30px from 1200px
     and 15px from 850px (see the media queries after this block). */
  --page-gutter: 90px;

  /* Max content width — the single dial for page width. Everything that
     caps content reads this: the .container utility, and the site shell's
     .container_inside rule in website_structure.css. */
  --container-max: 1600px;

/* ======================================================================
   GUTTER SCALE (PROJECT-CONFIGURABLE)
   ======================================================================

   The single source of truth for every gutter value. The .gap-* and
   .pxc-* utilities, the row defaults, and the responsive overrides all
   read from these — so changing a value here retunes the whole site
   without touching a single class name.

   As with the spacing scale, the numbers in class names are STEPS, not
   promises: set --gutter-40 to 32px and .gap-40 becomes 32px.

   NOTE — deliberately SEPARATE from the --space-* scale below.
   The space steps are fluid (--space-40 is clamp(24px, 3vw, 40px)),
   while the fixed gutters are fixed on purpose, so that .gap-40 can
   match a comp exactly. Wiring them together would quietly make every
   fixed gutter fluid and erase the point of the .gap-fluid-* tier.

   Every value must carry a unit — a bare 0 invalidates the column
   calc() that consumes it and the column silently loses its width.
====================================================================== */

  /* Fixed steps */
  --gutter-0:  0px;
  --gutter-16: 16px;
  --gutter-24: 24px;
  --gutter-40: 40px;
  --gutter-60: 60px;

  /* Fluid steps — scale smoothly with the viewport */
  --gutter-fluid-sm: clamp(8px, 1.5vw, 16px);
  --gutter-fluid-md: clamp(12px, 2vw, 32px);
  --gutter-fluid-lg: clamp(24px, 4vw, 64px);

  /* Single-axis fluid (used by .gap-x-fluid / .gap-y-fluid) */
  --gutter-fluid-axis: clamp(12px, 2vw, 40px);

  /* Column inner padding, fluid tier — a SEPARATE scale from the gutters
     above. Inner padding runs wider than a gutter at the top end, so these
     keep their own ceilings (60/80px) rather than the gutter's 64px. */
  --col-pad-fluid-sm: clamp(8px, 1.5vw, 24px);
  --col-pad-fluid:    clamp(16px, 3vw, 60px);
  --col-pad-fluid-lg: clamp(24px, 4vw, 80px);

  /* Default row spacing (desktop) — points at the scale above */
  --row-gap-x: var(--gutter-40);
  --row-gap-y: var(--gutter-40);

  /* Default column inner padding (desktop) — edit per site if needed */
  --row-col-pad-x: var(--gutter-0);

/* ======================================================================
   SPACING SCALE (PROJECT-CONFIGURABLE)
   ======================================================================

   IMPORTANT:
   The numbers in spacing utility class names (mb-40, mt-24, etc.)
   represent spacing STEPS, not fixed pixel values.

   Changing the --space-* values below will update spacing globally
   without changing class names.

   Do NOT assume mb-40 always equals 40px.

   BY DESIGN — FLUID STEPS CONVERGE ON SMALL SCREENS
   -------------------------------------------------
   The larger steps (40/60/80) are fluid clamp() values whose lower bounds
   intentionally overlap the fixed steps below them. Consequence:

     • On narrow viewports (~≤800px) --space-40 sits at its 24px floor, so
       mb-40 and mb-24 render identically. The steps only visibly separate
       on wider screens.

   This is intentional: spacing tightens on mobile and opens up on desktop.
   If you need steps that stay distinct at EVERY width, raise the clamp
   floors (e.g. --space-40: clamp(28px, 3vw, 40px)) — see audit note C7.
====================================================================== */
  --space-0: 0;
  --space-8: 8px;
  --space-12: 12px;
  --space-16: 16px;
  --space-24: 24px;
  --space-40: clamp(24px, 3vw, 40px);
  --space-60: clamp(32px, 5vw, 60px);
  --space-80: clamp(40px, 7vw, 80px);

  /* Major section separation (responsive) */
  --space-section: clamp(32px, 6vw, 96px);
    
    
/* ======================================================================
   SINGLE-COLUMN MAX WIDTH TOKENS (EDIT PER SITE)
   ======================================================================

   Used to constrain one-column rows without affecting global containers.
   Ideal for editorial content, long-form copy, and focused sections.
====================================================================== */

--single-sm: 720px;   /* readable text width */
--single-md: 880px;   /* default content column */
--single-lg: 1040px;  /* wide single-column layouts */


}

@media (max-width: 1200px) {
  :root { --page-gutter: 30px; }
}

@media (max-width: 850px) {
  :root { --page-gutter: 15px; }
}

/* End tokens ======================================================================
=================================================================================== */

/* ======================================================================
   BOX SIZING RESET — REQUIRED BY THE CONTAINER / COLUMN MATH
   ======================================================================

   Padding must be included in declared widths, or max-width and
   padding-inline compound: .container / #main > .inside would render
   (--container-max + 2 × --page-gutter) wide instead of --container-max,
   and percentage columns would overflow once padding is added.

   This reset previously lived in framework_structure.scss, which v3
   replaces — so v3 must carry it itself.
====================================================================== */
html {
  box-sizing: border-box;
}

*,
*::before,
*::after {
  box-sizing: inherit;
}


/* ======================================================================
   CONTAINERS — SAFE TO REUSE ACROSS PROJECTS
   ====================================================================== */
.container {
  margin-inline: auto;
  padding-inline: var(--page-gutter);
  max-width: var(--container-max);
}

.container-fluid {
  width: 100%;
  padding-inline: var(--page-gutter);
}


/* ======================================================================
   THE PAGE CONTAINER LIVES IN THE SITE STYLESHEET — NOT HERE
   ======================================================================

   This framework is CMS-agnostic: it owns containers, rows, columns and
   spacing utilities, but it does NOT claim any CMS-specific selector.

   In the "article = .row" model each article renders into the CMS's main
   content column, and THAT column is what carries the site's max-width,
   centring and page gutter. In Contao that is .container_inside — which
   wraps #main and the left/right columns — and the rule belongs in the
   site shell stylesheet (website_structure.css), alongside the matching
   rules for the header, prefooter and footer.

   Two selectors previously claimed it — this file and the site shell —
   at identical specificity (1,1,0), so whichever stylesheet happened to
   load last silently decided the site's content width. One owner now.

   Nothing here depends on it: with the gap engine rows use no negative
   margins, so they can never overflow their parent. Without a container
   rule, rows simply run the full width of whatever contains them.
====================================================================== */




/* AUDIT NOTE — .bleed-x
   .bleed-x applies negative margins to break out of container gutters.
   Use it for full-bleed backgrounds/sections.

   Avoid putting .bleed-x on elements inside components that already have
   their own padding (cards, modals) unless you intend for it to escape. */

/* Full-bleed helper */
.bleed-x {
  margin-inline: calc(-1 * var(--page-gutter));
  padding-inline: 0;
}

/* Bleeding a COLUMN needs two corrections:

   1. padding — plain .bleed-x ties with .row > * and loses on source
      order, so the gutter padding has to be dropped at higher specificity.

   2. width — a flex item's percentage basis resolves against the row's
      content box, and margins sit OUTSIDE that box. So negative margins
      do not widen the item, they shrink its margin box to (100% - 2×gutter)
      and, because flex-grow is 0 and justify-content is flex-start, the
      whole box simply shifts left: correct bleed on the left, but two
      gutters short on the right. Paying for both margins in the basis
      makes the margin box exactly 100% again, so the band lands flush on
      both edges.

   Only full-width bleeds make sense here; .bleed-x on a fractional
   column is unsupported. */
.row > *.bleed-x {
  flex: 0 0 calc(100% + var(--page-gutter) * 2);
  padding-inline: 0;
}


/* ======================================================================
   HOW GUTTERS WORK — REAL gap + SELF-COMPENSATING COLUMNS
   ======================================================================

   THE PROBLEM WITH NAIVE gap
   --------------------------
   A plain `gap` adds space ON TOP of percentage columns:

     .col-2-3 (66.666%) + .col-1-3 (33.333%) + gap > 100%   → wraps

   THE FIX — COLUMNS PAY FOR THE GUTTER
   ------------------------------------
   Each column subtracts its own fair share of the gutter from its width:

     width = P% - gap × (1 - P)        where P is the column's fraction

   Worked example — 75/25 on a 1200px row with a 40px gap:

     .col-3-4 → 75% of 1200 - 40 × 0.25  =  900 - 10  =  890px
     .col-1-4 → 25% of 1200 - 40 × 0.75  =  300 - 30  =  270px
                                    890 + 40 + 270  =  1200px  ✓

   Any set of fractions summing to 100% fills the row exactly, and the
   leftover gutter is billed to each column in proportion to how much
   width it gives up — which is why the arithmetic always closes.

   WHY THIS BEATS THE OLD NEGATIVE-MARGIN TECHNIQUE
   ------------------------------------------------
     • Real empty space between columns, so column backgrounds, borders
       and cards actually separate (padding gutters cannot do this).
     • No negative margins, so a row can never overflow its parent and
       needs no padded container to sit in.
     • flex-basis stays a real width, so flex-wrap still works: .col-1-1
       claims its own line and N-up grids wrap naturally.
     • .trim becomes unnecessary (kept as a no-op for old markup).

   Vertical spacing between wrapped lines uses the same gap's row axis.
====================================================================== */


/* ======================================================================
   ROW ENGINE — CORE (LEAVE ALONE)
   ====================================================================== */
.row {
  display: flex;
  flex-wrap: wrap;

  /* Row-level spacing defaults (from project tokens) */
  --gap-x: var(--row-gap-x);   /* horizontal gutter between columns */
  --gap-y: var(--row-gap-y);   /* vertical gap between wrapped rows */
  --col-pad-x: var(--row-col-pad-x); /* optional inner padding inside each column */

  /* A REAL gap — genuine empty space between columns.
     Columns give the gutter back out of their own width (see the
     calc() bases below), so percentages never sum past 100%. */
  gap: var(--gap-y) var(--gap-x);
}

/* Optional inner padding, applied INSIDE the column's declared width.
   box-sizing:border-box means this insets content without changing the
   column's outer width — so no .trim compensation is ever needed. */
/* flex-basis 100% is a FALLBACK: a row child with no col-* class (Contao emits
   several of its own — .syndication, .back, and any unclassed element) would
   otherwise shrink-wrap to its content instead of taking a line. Every .col-*
   rule is later in source at equal specificity, so real columns still win. */
.row > * {
  flex: 0 1 100%;
  padding-inline: var(--col-pad-x);
  min-width: 0;
  box-sizing: border-box;
}

/* ----------------------------------------------------------------------
   CONTENT CONTAINMENT
   ----------------------------------------------------------------------
   `.row > *` sets min-width: 0 so columns can shrink below their content's
   intrinsic width — that is what keeps percentage columns honest. The
   side effect is that anything wider than the column (an uploaded image,
   an embed, an unbroken URL) will overflow it and can force horizontal
   scroll on the whole page.

   Scoped to the framework's own boxes: the layout engine created this
   exposure, so it contains it. A site-wide `img { max-width: 100% }`
   baseline, if wanted, belongs in the theme/base layer.
---------------------------------------------------------------------- */

.row > * img,
.row > * svg,
.row > * video,
.row > * canvas,
.row > * iframe,
.row > * embed,
.row > * object {
  max-width: 100%;
}

/* Preserve aspect ratio once max-width starts constraining the element */
.row > * img,
.row > * svg,
.row > * video {
  height: auto;
}

/* Long unbroken strings (URLs, tokens) wrap instead of pushing the column open */
.row > * {
  overflow-wrap: break-word;
}


/* DEPRECATED — .trim existed to cancel the old negative row margins.
   The gap engine has no negative margins, so this is now a no-op.
   Kept so existing markup does not break. Safe to delete later. */
.row.trim {
  margin-inline: 0;
}


/* ======================================================================
   COLUMN WIDTH UTILITIES — HOW flex: 0 0 X% WORKS
   ======================================================================

   flex is shorthand for:
     flex-grow | flex-shrink | flex-basis

   Example:
     flex: 0 0 50%;

   Means:
     - flex-grow:   0  → do NOT grow larger than the base size
     - flex-shrink: 0  → do NOT shrink smaller than the base size
     - flex-basis:  50% → base width is 50% of the row

   Why we use this:
     - Guarantees predictable column widths
     - Prevents stretching or squishing
     - Works cleanly with flex-wrap, gaps, and .trim
     - Avoids layout drift when spacing changes

   IMPORTANT:
     These classes control WIDTH ONLY.
     Prefer controlling spacing at the ROW level (gap utilities).
     Optional inner padding is available via the .pxc-* utilities.

====================================================================== */


/* ======================================================================
   COLUMN WIDTHS
   ====================================================================== */

/* AUDIT NOTE — WHY THESE ARE calc() AND NOT PLAIN PERCENTAGES
   Each column subtracts its own share of the gutter, so a set of
   fractions summing to 100% fits the row EXACTLY with the gap included.
   Plain percentages would sum to 100% + gap and wrap the last column.

   The multiplier is always (1 - P). Adding a new width means adding its
   pair: e.g. a 10% column → calc(10% - var(--gap-x) * 0.9).

   --gap-x must always carry a unit (0px, never 0) or the whole calc()
   is invalid and the column silently loses its width.
   ====================================================================== */
/* Each basis is  P% - gap × (1 - P)  — the column's own share of the
   gutter, subtracted from its width. See the gutter explainer above. */
/* .col divides whatever space is left between however many there are, so
   it behaves like a fraction and stacks with them at 600 (see below).
   .col-auto is an explicit opt-out — "size me to my content" — so it is
   deliberately left OUT of every stacking rule. An icon or a button beside
   a heading should stay beside it on a phone; if you want it to stack,
   use a fraction instead. */
.col       { flex: 1 1 0; }
.col-auto  { flex: 0 0 auto; }
.col-1-1   { flex: 0 0 100%; }                                    /* full width — takes its own line */
.col-3-4   { flex: 0 0 calc(75%     - var(--gap-x, 0px) * 0.25);  }
.col-2-3   { flex: 0 0 calc(200% / 3 - var(--gap-x, 0px) / 3);     }
.col-3-5   { flex: 0 0 calc(60%     - var(--gap-x, 0px) * 0.4);   }
.col-1-2   { flex: 0 0 calc(50%     - var(--gap-x, 0px) * 0.5);   }
.col-2-5   { flex: 0 0 calc(40%     - var(--gap-x, 0px) * 0.6);   }
.col-1-3   { flex: 0 0 calc(100% / 3 - var(--gap-x, 0px) * 2 / 3); }
.col-30    { flex: 0 0 calc(30%     - var(--gap-x, 0px) * 0.7);   }
.col-1-4   { flex: 0 0 calc(25%     - var(--gap-x, 0px) * 0.75);  }
.col-20    { flex: 0 0 calc(20%     - var(--gap-x, 0px) * 0.8);   }

/* Fixed ma-widths */

.single-sm,
.single-md,
.single-lg {
  max-width: var(--single-md); /* overridden per class */
  width: 100%;
}

.single-sm { max-width: var(--single-sm); }
.single-md { max-width: var(--single-md); }
.single-lg { max-width: var(--single-lg); }


/* ======================================================================
   GAP DECISION GUIDE (READ THIS BEFORE ADDING NEW SPACING)
   ======================================================================

   Use this guide to choose the RIGHT gap utility.
   Do not invent new gap values unless absolutely necessary.

   DEFAULT (most sections):
     gap-fluid
     → Responsive, balanced spacing across all screen sizes

   TIGHT / DENSE LAYOUTS:
     gap-fluid-sm  OR  gap-16
     → Icon grids, specs, compact UI sections

   SPACIOUS / PREMIUM SECTIONS:
     gap-fluid-lg  OR  gap-40 / gap-60
     → Hero sections, editorial layouts, feature showcases

   AXIS-SPECIFIC CONTROL:
     gap-x-0/16/24/40/60/fluid  and  gap-y-0/16/24/40/60/fluid
     → When horizontal and vertical rhythm should differ. Combine with a
       gap-* class: `row gap-24 gap-y-60` is 24 across, 60 down.

   PRECISION / MATCHING DESIGNS:
     gap-16 / gap-24 / gap-40
     → When spacing must match comps exactly

   RULE OF THUMB:
     If unsure, use `gap-fluid`.

====================================================================== */


/* ======================================================================
   GAP UTILITIES — EDIT AVAILABLE SIZES AS NEEDED
   ====================================================================== */
.gap-0  { --gap-x: var(--gutter-0);  --gap-y: var(--gutter-0); }
.gap-16 { --gap-x: var(--gutter-16); --gap-y: var(--gutter-16); }
.gap-24 { --gap-x: var(--gutter-24); --gap-y: var(--gutter-24); }
.gap-40 { --gap-x: var(--gutter-40); --gap-y: var(--gutter-40); }
.gap-60 { --gap-x: var(--gutter-60); --gap-y: var(--gutter-60); }

/* ======================================================================
   FLUID GAP UTILITIES (CLAMP-BASED)
   ======================================================================

   Use these when spacing should scale smoothly across screen sizes.
   Prefer these for marketing and editorial layouts.

   Tiers:
     - sm: tight, dense layouts
     - md: most sections  (.gap-fluid and .gap-fluid-md are the same thing)
     - lg: spacious, premium layouts
*/

.gap-fluid-sm {
  --gap-x: var(--gutter-fluid-sm);
  --gap-y: var(--gutter-fluid-sm);
}

/* .gap-fluid is the original name; .gap-fluid-md is an alias so the three
   tiers read consistently (sm / md / lg). Both are supported — existing
   markup using .gap-fluid keeps working. */
.gap-fluid,
.gap-fluid-md {
  --gap-x: var(--gutter-fluid-md);
  --gap-y: var(--gutter-fluid-md);
}

.gap-fluid-lg {
  --gap-x: var(--gutter-fluid-lg);
  --gap-y: var(--gutter-fluid-lg);
}

/* ======================================================================
   SINGLE-AXIS GAPS
   ======================================================================

   Use these when horizontal and vertical rhythm should differ — a card
   grid often wants tight gutters between columns but more separation
   between wrapped rows. Combine with a .gap-* class, or use alone.

     <div class="row gap-24 gap-y-60">   24 across, 60 down

   THE TWO AXES ARE NOT EQUIVALENT — worth understanding before reaching
   for gap-x-*:

     --gap-y  affects ONLY the space between wrapped lines. Nothing else
              reads it, so it can never disturb a column's width.

     --gap-x  is read TWICE: by the row's gap, and by every column's width
              calc (flex-basis: P% - gap × (1-P)). Changing it therefore
              resizes the columns to compensate — which is exactly what
              keeps a row summing to 100% — but it is the bigger lever.

   Both are safe; gap-y-* is simply the more contained of the two.
====================================================================== */

/* Horizontal only — the space between columns on a line */
.gap-x-0     { --gap-x: var(--gutter-0); }
.gap-x-16    { --gap-x: var(--gutter-16); }
.gap-x-24    { --gap-x: var(--gutter-24); }
.gap-x-40    { --gap-x: var(--gutter-40); }
.gap-x-60    { --gap-x: var(--gutter-60); }
.gap-x-fluid { --gap-x: var(--gutter-fluid-axis); }

/* Vertical only — the space between wrapped lines */
.gap-y-0     { --gap-y: var(--gutter-0); }
.gap-y-16    { --gap-y: var(--gutter-16); }
.gap-y-24    { --gap-y: var(--gutter-24); }
.gap-y-40    { --gap-y: var(--gutter-40); }
.gap-y-60    { --gap-y: var(--gutter-60); }
.gap-y-fluid { --gap-y: var(--gutter-fluid-axis); }


/* ======================================================================
   COLUMN INNER PADDING UTILITIES (optional inner inset)
   ====================================================================== */

.pxc-0  { --col-pad-x: var(--gutter-0); }
.pxc-16 { --col-pad-x: var(--gutter-16); }
.pxc-24 { --col-pad-x: var(--gutter-24); }
.pxc-40 { --col-pad-x: var(--gutter-40); }
.pxc-60 { --col-pad-x: var(--gutter-60); }

/* Fluid column padding (default) */
.pxc-fluid {
  --col-pad-x: var(--col-pad-fluid);
}

/* Fluid column padding — SMALL */
.pxc-fluid-sm {
  --col-pad-x: var(--col-pad-fluid-sm);
}

/* Fluid column padding — LARGE (optional) */
.pxc-fluid-lg {
  --col-pad-x: var(--col-pad-fluid-lg);
}


/* ======================================================================
   RESPONSIVE OVERRIDES — DESKTOP FIRST (MAX-WIDTH) • SIMPLIFIED
   ======================================================================

   SIMPLIFIED RESPONSIVE MODEL (CMS-FRIENDLY)
   -----------------------------------------
   We auto-stack fraction columns on smaller screens.

   - Desktop: .col-1-2, .col-2-3, etc. behave as expected
   - Tablet and down: fraction columns become full width (stacked)
   - No md:* / sm:* classes required

   ESCAPE HATCH
   ------------
   If you need a row to KEEP columns side-by-side on tablet/mobile,
   add .no-stack to the row:

     <div class="row no-stack">...</div>

====================================================================== */

/* Tablet and down: stack fraction columns by default */
@media (max-width: 992px) {

  /* Default behavior: stack, unless the row opts out */
  .row:not(.no-stack) > .col-1-3,
  .row:not(.no-stack) > .col-2-3,
  .row:not(.no-stack) > .col-3-4,
  .row:not(.no-stack) > .col-3-5,
  .row:not(.no-stack) > .col-2-5,
  .row:not(.no-stack) > .col-30,
  .row:not(.no-stack) > .col-20 {
    flex: 0 0 100%;
  }
  /* NOTE: .col-1-2 and .col-1-4 are intentionally NOT in this list.
     Both already sit at (or step through) a comfortable 2-up on tablet,
     so they hold there and stack at 600 instead — see the "COLUMNS THAT
     HOLD 2-UP ON TABLET" block below. Use .no-stack to keep any row
     side-by-side at every width. */
}


/* ======================================================================
   MIXED-RATIO PAIRS — EQUALIZE BEFORE STACKING
   ======================================================================

   Unequal two-column pairs (75/25, 66/33, 60/40) shouldn't jump straight
   from their ratio to a full stack — the minor column gets uncomfortably
   narrow on tablet. Instead they step through an even 50/50 (still 2-up)
   before stacking:

     ratio (desktop)  →  50/50 (≤992)  →  stacked (≤600)

   Detection is automatic via :has(): a row is treated as a mixed pair
   ONLY when it holds BOTH partners, so a 3-up of .col-1-3 or a 4-up of
   .col-1-4 is unaffected. Specificity (5 classes) beats the auto-stacker
   above (3), and the :not(.no-stack) guard keeps the escape hatch working.

   These target two-column pairs; adding a third column to the same row is
   unsupported (both partner selectors would still apply at 50%).
====================================================================== */

/* Tablet: equalize the pair to 50/50 (still side-by-side) */
@media (max-width: 992px) {
  .row:not(.no-stack):has(> .col-3-4):has(> .col-1-4) > .col-3-4,
  .row:not(.no-stack):has(> .col-3-4):has(> .col-1-4) > .col-1-4,
  .row:not(.no-stack):has(> .col-2-3):has(> .col-1-3) > .col-2-3,
  .row:not(.no-stack):has(> .col-2-3):has(> .col-1-3) > .col-1-3,
  .row:not(.no-stack):has(> .col-3-5):has(> .col-2-5) > .col-3-5,
  .row:not(.no-stack):has(> .col-3-5):has(> .col-2-5) > .col-2-5 {
    flex: 0 0 calc(50% - var(--gap-x, 0px) * 0.5);
  }
}

/* Mobile: now stack the pair to full width */
@media (max-width: 600px) {
  .row:not(.no-stack):has(> .col-3-4):has(> .col-1-4) > .col-3-4,
  .row:not(.no-stack):has(> .col-3-4):has(> .col-1-4) > .col-1-4,
  .row:not(.no-stack):has(> .col-2-3):has(> .col-1-3) > .col-2-3,
  .row:not(.no-stack):has(> .col-2-3):has(> .col-1-3) > .col-1-3,
  .row:not(.no-stack):has(> .col-3-5):has(> .col-2-5) > .col-3-5,
  .row:not(.no-stack):has(> .col-3-5):has(> .col-2-5) > .col-2-5 {
    flex: 0 0 100%;
  }
}

/* ======================================================================
   TYPOGRAPHY IS NOT THIS FILE'S JOB
   ======================================================================

   THE BOUNDARY
   ------------
   This framework owns LAYOUT: containers, rows, columns, gutters, and the
   spacing UTILITIES you apply to blocks (mb-*, mt-*, section-space).

   It does NOT own type. Paragraph, list, blockquote and heading rhythm —
   margins, line-height, size — belong to the site's typography layer
   (website.scss), which already defines them.

   WHY THERE IS NO RESET HERE ANY MORE
   -----------------------------------
   This file used to declare:

       p, ul, ol, blockquote { margin: 0; }

   …with a .rte flow rule meant to restore the rhythm. The .rte rule was
   commented out, so the reset destroyed spacing and replaced nothing.
   Worse, a bare `p` selector here ties on specificity (0,0,1) with the
   type layer's own `p` rule, so which one won depended purely on CSS
   load order in the Contao layout — the same markup could space
   correctly on one site and collapse on another.

   Removing the reset resolves that: the type layer is the single owner,
   and nothing here competes with it.

   IF YOU NEED TO ZERO A MARGIN, do it in the type layer, or use the
   spacing utilities on a wrapper — never re-add an element reset here.
====================================================================== */


/* ----------------------------------------------------------------------
   THE ONE TYPE-ADJACENT RULE THAT IS GENUINELY LAYOUT
   ----------------------------------------------------------------------

   A trailing bottom margin on the last element inside a column adds
   phantom space below the content but INSIDE the column box. That is
   invisible on plain text, but obvious once a column has a background
   or border (cards), where it reads as uneven padding.

   Scoped to this framework's own boxes rather than resetting elements
   globally, so the type layer keeps full control of rhythm everywhere
   else. (Same approach Bootstrap uses for card bodies.)
---------------------------------------------------------------------- */

/* Contao wraps rich text in a .rte div, so the column's own :last-child is that
   wrapper — whose trailing <p> keeps its margin. Reach one level further so the
   reset lands on the element that actually carries it. */
.row > * > :last-child,
.row > * > :last-child > :last-child {
  margin-bottom: 0;
}


/* ----------------------------------------------------------------------
   OPTIONAL FLOW VARIANTS
   ----------------------------------------------------------------------

   Opt-in rhythm overrides for rich-text wrappers. These are arguably
   typography too and are candidates to move to the type layer — kept
   here for now because existing markup may reference them.
---------------------------------------------------------------------- */

.rte-tight > * + * {
  margin-top: 0.75em;
}

.rte-loose > * + * {
  margin-top: 1.5em;
}


/* ----------------------------------------------------------------------
   GUIDANCE FOR THE TEAM
   ----------------------------------------------------------------------

   - Do NOT put margin utilities (mb-*, mt-*) on <p> tags — paragraph
     rhythm comes from the type layer.
   - DO use margin utilities on SECTIONS, BLOCKS and columns.

   Example (correct):

     <div class="mb-40">
       <p>Paragraph one</p>
       <p>Paragraph two</p>
     </div>

   Example (avoid):

     <p class="mb-24">Paragraph one</p>
     <p class="mb-24">Paragraph two</p>

====================================================================== */

/* Margin bottom */
.mb-0  { margin-bottom: var(--space-0); }
.mb-8  { margin-bottom: var(--space-8); }
.mb-12 { margin-bottom: var(--space-12); }
.mb-16 { margin-bottom: var(--space-16); }
.mb-24 { margin-bottom: var(--space-24); }
.mb-40 { margin-bottom: var(--space-40); }
.mb-60 { margin-bottom: var(--space-60); }
.mb-80 { margin-bottom: var(--space-80); }

/* Margin top */
.mt-0  { margin-top: var(--space-0); }
.mt-8  { margin-top: var(--space-8); }
.mt-12 { margin-top: var(--space-12); }
.mt-16 { margin-top: var(--space-16); }
.mt-24 { margin-top: var(--space-24); }
.mt-40 { margin-top: var(--space-40); }
.mt-60 { margin-top: var(--space-60); }
.mt-80 { margin-top: var(--space-80); }

/* Optional: margin block (top + bottom together) */
.my-24 { margin-block: var(--space-24); }
.my-60 { margin-block: var(--space-60); }


/* Use for consistent spacing between major sections */
.section-space { margin-block: var(--space-section); }
.section-space-top { margin-top: var(--space-section); }
.section-space-bottom { margin-bottom: var(--space-section); }


/* Optional: tighten default spacing on smaller screens (global)
   NOTE: Because we use clamp() utilities, you may not need these.
   Keep these only if your team wants more predictable rhythm. */
   
/* centering */
.center_text {
    text-align: center;
}

/* margin-INLINE only. The `margin: auto` shorthand also set the block axis,
   which silently zeroed every bottom/top margin utility on the same element
   (auto resolves to 0 in normal flow) and, on a flex column, opted the item
   out of cross-axis stretch so it no longer matched its siblings in height. */
.center_element {
    margin-inline: auto;
}

.hor_center {
    justify-content: center;
}


.vert_center {
    align-items: center;
}

.vert_top {
    align-items: flex-start;
}

.vert_bottom {
    align-items: flex-end;
}


/* Element / text alignment (Toolbox: align-left / align-right) */
.align-left,
.align-left img {
    text-align: left;
    margin-inline: 0 auto;
}

.align-right,
.align-right img {
    text-align: right;
    margin-inline: auto 0;
}


@media (max-width: 768px) {
  :root {
    --row-gap-x: var(--gutter-24);
    --row-gap-y: var(--gutter-24);
  }
}

/* ----------------------------------------------------------------------
   MOBILE COLUMN ORDER
   ----------------------------------------------------------------------
   Rows read left-to-right on desktop but top-to-bottom once stacked, so a
   "text beside image" row can end up with the wrong one first on a phone.
   .mobile_col_reverse flips the stacking order without touching the desktop
   layout or the source order (which stays correct for screen readers).
---------------------------------------------------------------------- */
.mobile_col_reverse {
  flex-direction: row;
}

@media (max-width: 600px) {
  .mobile_col_reverse {
    flex-direction: column-reverse;
  }
}


@media (max-width: 480px) {
  :root {
    --row-gap-x: var(--gutter-16);
    --row-gap-y: var(--gutter-16);
  }
}


/* ======================================================================
   COLUMNS THAT HOLD 2-UP ON TABLET  (→ 2 → 1)
   ======================================================================

   EVERY two-column layout now follows the SAME ramp: it reaches an even
   50/50 on tablet, and only stacks on phones.

     .col-1-2 pair   50/50  (> 992)  →  50/50  (≤ 992)  →  1-up  (≤ 600)
     75/25 pair      75/25  (> 992)  →  50/50  (≤ 992)  →  1-up  (≤ 600)
     66/33 pair      66/33  (> 992)  →  50/50  (≤ 992)  →  1-up  (≤ 600)
     60/40 pair      60/40  (> 992)  →  50/50  (≤ 992)  →  1-up  (≤ 600)
     .col-1-4 grid   4-up   (> 992)  →  2-up   (≤ 992)  →  1-up  (≤ 600)

   Previously .col-1-2 sat in the blanket 992 stacker, so a plain 50/50
   stacked EARLIER than a 75/25 — the simpler layout collapsed sooner,
   which is backwards. Both now hold 2-up to 600.

   This is WHY .col-1-2 and .col-1-4 are left out of the blanket 992
   auto-stacker above. The :not(.no-stack) guard keeps the escape hatch
   working: a .row.no-stack holds its columns side-by-side at every width.

   Thirds (.col-1-3 ×3) still stack at 992 — three columns cannot reach an
   even 2-up without orphaning one, so they go straight to 1-up.
====================================================================== */
@media (max-width: 992px) {
  /* A quarter promotes to a half on tablet — UNLESS the row also holds a
     .col-1-2, which is already 50%. Three 50% items fill one line exactly
     and orphan the third at half width, so those rows stack instead. */
  .row:not(.no-stack):not(:has(> .col-1-2)) > .col-1-4 {
    flex: 0 0 calc(50% - var(--gap-x, 0px) * 0.5);
  }
  .row:not(.no-stack):has(> .col-1-2) > .col-1-4,
  .row:not(.no-stack):has(> .col-1-4) > .col-1-2 { flex: 0 0 100%; }
}

/* The :not(:has()) selector matches the tablet rule above. Without it this
   rule was less specific than the one that promotes quarters to halves, so
   quarters stayed 2-up on phones (190px columns at 390px). */
@media (max-width: 600px) {
  .row:not(.no-stack) > .col-1-2,
  .row:not(.no-stack) > .col-1-4,
  .row:not(.no-stack):not(:has(> .col-1-2)) > .col-1-4,
  .row:not(.no-stack) > .col { flex: 0 0 100%; }
}

/* box-sizing lives in framework_v3.css, which uses an inherit-based reset
   so components can opt out. The universal border-box rule that used to be
   here loaded later and silently defeated it.

   body no longer sets overflow-x: hidden either. website_structure.css
   already clips on html, and `hidden` on one axis forces the other to
   `auto` — which turns body into a scroll container and breaks
   position: sticky for everything inside it. `clip` has no such effect. */

#header .background,
#header .background_image {
    overflow-x: hidden;
}

/* THIRD-PARTY COMPONENTS AND THE INHERIT-BASED BOX-SIZING RESET
   Swiper puts `box-sizing: content-box` on .swiper-wrapper, and with the
   inherit-based reset in framework_v3.css every slide and everything in it
   would inherit that: padded boxes inside a slide grow by their padding.
   Each slide starts a border-box subtree again; Swiper sizes slides from the
   outside, so this does not affect its layout maths. */
.swiper-slide {
    box-sizing: border-box;
}

/* Font Awesome icons size themselves (`height: 1em`). The framework's
   `.row > * svg { height: auto }` is meant for content SVGs and collapses an
   inline icon to 0×0, so icons get their height back. */
.row > * svg.svg-inline--fa {
    height: 1em;
}

html {scroll-behavior: smooth;}

/* Moved here from framework_v3.css, which must own no CMS-specific
   selector. .content-image is Contao markup. */
.content-image.center_element img {
    margin-inline: auto;
}

img {
    height: auto;
    max-width: 100%;
    display: block;
    border: 0;
}

body,
form,
fieldset,
h1,
h2,
h3,
h4,
h5,
h6,
figure,
p.active,
p.confirm {

    margin: 0;
    padding: 0;
}

a img { border-bottom: 0; }

header,
footer,
nav,
section,
aside,
article,
figure,
figcaption,
.custom,
.tableless label,
.checkbox_container span,
.radio_container span{
    display: block;
}

/* Controls do not inherit type by default. The old `font-size: 99%` was a
   legacy hack, and it put controls under 16px on mobile — which makes iOS
   Safari zoom the page whenever a field is focused. max() keeps the page's
   own size on desktop and never drops below 16px. */
select,
input,
textarea {
    font-family: inherit;
    font-size: max(16px, 1em);
}

/* .block is a float-clearing relic. Contao puts it on EVERY article, and in
   the layout framework an article is a .row — so an unscoped `overflow:
   hidden` here silently clips any .bleed-x inside a row (and creates a new
   block formatting context on every row). Excluding .row keeps the legacy
   clearing behaviour everywhere it is still wanted. */
.block:not(.row) {
    overflow: hidden;
}

/* Visually hidden but still announced. The previous version used zero
   dimensions and left:-1000px; zero-size elements are skipped by some
   screen readers, and off-screen positioning can cause horizontal scroll
   in RTL. Contao uses this for real assistive text, e.g.
   <span class="invisible">Mandatory field</span>. */
.invisible {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* A visible focus indicator is required (WCAG 2.4.7). This replaces an
   `outline: none` that removed it with no substitute, which left keyboard
   users unable to tell which control they were in — the site search box
   included. :focus-visible keeps it off for mouse users. */
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
button:focus-visible,
a:focus-visible,
[tabindex]:focus-visible {
    outline: 2px solid var(--prime);
    outline-offset: 2px;
}

textarea { min-height: 150px; }

fieldset {
    border: 0;
    margin-inline: 0;
    padding-inline: 0;
    padding-block: 0;
}

fieldset table,
input.text,
input.email,
textarea {
    width: 100%;
}

input.captcha {
    width: 50px;
}

input.checkbox,
.tableless .checkbox_container label,
.checkbox_container span.mandatory,
input.radio,
.tableless .radio_container label,
.radio_container span.mandatory,
.tableless span label,
address,
.pdf_link img,
.content-download img,
.content-downloads img,
.enclosure img {
    display: inline;
}

/* Strip the platform's native control chrome. The body.ios variants that
   used to be listed here were already covered by the unprefixed selectors
   below them, and the companion `-moz-border-radious: 0` was a misspelling
   of a property that has been unnecessary since Firefox 4. */
input.text,
input.submit,
.textarea,
textarea,
input.captcha,
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
    -webkit-appearance: none;
    appearance: none;
}

/* --second matches forms.css, so the required-field asterisk is one colour
   whether the form is a content element or a module. */
.error,
span.mandatory {
    color: var(--second);
}

.confirm {
    color: var(--prime);
}

p.error {
    margin: 0;
    padding-top: 10px;
}

.content-download img,
.content-downloads img,
.enclosure img {
    vertical-align: top;
}

.content-downloads p,
.enclosure p,
p.error {
    padding-bottom: 0;
}

.enclosure { padding-top: 20px; }
/* Table styling lives in tables.css. This stays as a bare reset for
   any table outside a .content-table element. */
table { border-spacing: 0; }
address { font-style: normal; }

/* IMAGE POSITION IN A TEXT ELEMENT
   --------------------------------
   These are FLOATS, deliberately, not flex.

   The editor's choice is literally "floating: left/right", and what that
   means is that the text WRAPS around the image and then continues full
   width beneath it. Flex cannot do that — it produces two rigid columns,
   so a short paragraph beside a tall image leaves a large empty gap and
   the text never flows underneath.

   `display: flow-root` on the parent contains the float, so the image can
   never escape the bottom of its content element. It is the modern
   replacement for a clearfix pseudo-element or `overflow: hidden`, and
   unlike overflow it creates no scroll container and no clipping. */

.content-text.media { display: flow-root; }

/* SPACING AROUND A FLOATED IMAGE
   The gap between the image and the text beside it is a GUTTER — the same
   idea as the space between two columns — so it uses the gutter scale
   rather than a hardcoded value.

   --row-gap-x already steps down at the framework's breakpoints
   (40 -> 24 -> 16), so the float gap tightens on smaller screens in step
   with every column gutter on the site. Retuning --gutter-40 moves both.

   The space BELOW the image is block rhythm, not a gutter, so it comes
   from the spacing scale instead. */

/* A plain `max-width: 50%` keeps scaling with the container, so on a wide
   site the image reaches ~900px and dominates the composition. The pixel
   cap stops it growing once there is plenty of room, which keeps the text
   column reading like a column rather than a narrow strip beside a poster.

   min() takes whichever is smaller, so narrow screens still get the 50%
   behaviour and wide screens settle at a sensible fixed size. */
.content-text.media--left figure,
.content-text.media--right figure {
    max-width: min(50%, 480px);
}

.content-text.media--left figure {
    float: left;
    margin: 0 var(--row-gap-x) var(--space-24) 0;
}

.content-text.media--right figure {
    float: right;
    margin: 0 0 var(--space-24) var(--row-gap-x);
}

/* above / below simply stack. Contao 5.7's text template already renders
   the figure AFTER the text for `below` (content_element/text.html.twig),
   so no reordering is needed. The column-reverse that used to be here
   flipped the whole element and put the headline at the bottom. */
.content-text.media.media--above figure { margin-bottom: var(--space-24); }

.content-text.media.media--below figure { margin-top: var(--space-24); }

/* Too narrow to wrap around: let the image take its own line.

   TUNING NOTE — the awkward zone is roughly 601-768px.
   In that range the image is still taking ~50% while the gutter is still
   at its desktop 40px, so the text column can drop to around 350px and
   the wrap goes ragged. Measured at an 820px viewport: 754px container,
   361px image, 353px of text.

   If a particular site's images or copy make that look bad, raise this
   breakpoint to 768px so the image unfloats before the column gets tight:

       @media (max-width: 768px) { ... }

   Left at 600px by default because it keeps the wrap on small tablets,
   which suits shorter captions and portrait images. Change per site
   rather than globally — it depends on the imagery. */
@media (max-width: 600px) {
    .content-text.media--left figure,
    .content-text.media--right figure {
        float: none;
        max-width: none;
        margin: 0 0 var(--space-24);
    }
}

/* Legacy float utilities, still available for hand-written content. */
.float_left { float: left; }
.float_right figure { float: right; }

.float_clear,
.center,
.clear,
#clear {
    clear: both;
}

/* --------------------------------------------------------------------------
   VIDEO EMBEDS — YouTube and Vimeo
   --------------------------------------------------------------------------
   Contao renders the player as <iframe width="640" height="360">. Those are
   HTML attributes rather than CSS, but they still size the element — so
   overriding only the width makes the embed scale sideways while its height
   stays locked at 360px. It also explains why aspect-ratio alone did nothing
   here: with BOTH dimensions definite, aspect-ratio is ignored outright.

   `height: auto` is what releases it. Once the height is auto the ratio has
   something to drive, and the embed scales on both axes.

   The framework gives .row > * img/svg/video a height: auto but deliberately
   skips iframe, because a bare iframe — a map, an external form — has to
   keep its attribute height; with no ratio to work from it would collapse to
   the 150px default size. So the release happens HERE instead, scoped to the
   players, where a ratio is guaranteed by the rule below.
   -------------------------------------------------------------------------- */

.content-youtube,
.content-vimeo,
.content-youtube iframe,
.content-vimeo iframe {
    width: 100%;
}

.content-youtube iframe,
.content-vimeo iframe {
    height: auto;

    /* The ratio dropdown is optional — Contao ships a blank option — so a
       default is required or an embed with nothing chosen would collapse.
       16/9 is exactly what Contao's own 640x360 attributes describe, so the
       unset case keeps the shape it was already rendering, just fluid.

       Using playerSize for a non-16:9 embed without picking a ratio? Set
       --video-ratio on that element rather than hardcoding a pixel size. */
    aspect-ratio: var(--video-ratio, 16 / 9);

    /* block removes the inline descender gap beneath the player; the auto
       margins centre the tall ratios once max-width starts constraining. */
    display: block;
    margin-inline: auto;
}

/* Every ratio Contao offers. The class is literally `aspect--16:9`, so the
   colon has to be escaped. */
.content-youtube .aspect--16\:9 iframe,
.content-vimeo .aspect--16\:9 iframe {
    aspect-ratio: 16 / 9;
}

.content-youtube .aspect--16\:10 iframe,
.content-vimeo .aspect--16\:10 iframe {
    aspect-ratio: 16 / 10;
}

.content-youtube .aspect--21\:9 iframe,
.content-vimeo .aspect--21\:9 iframe {
    aspect-ratio: 21 / 9;
}

.content-youtube .aspect--4\:3 iframe,
.content-vimeo .aspect--4\:3 iframe {
    aspect-ratio: 4 / 3;
}

.content-youtube .aspect--3\:2 iframe,
.content-vimeo .aspect--3\:2 iframe {
    aspect-ratio: 3 / 2;
}

/* Portrait and square are the two ratios that can run away: in a full-width
   1800px container a 9:16 player works out over 3000px tall. Both are capped
   by WIDTH rather than height — with the width pinned at 100%, a max-height
   would letterbox inside the player instead of resizing it. */
.content-youtube .aspect--9\:16 iframe,
.content-vimeo .aspect--9\:16 iframe {
    aspect-ratio: 9 / 16;
    max-width: calc(var(--video-tall-max, 80vh) * 9 / 16);
}

.content-youtube .aspect--1\:1 iframe,
.content-vimeo .aspect--1\:1 iframe {
    aspect-ratio: 1 / 1;
    max-width: var(--video-tall-max, 80vh);
}


/* --------------------------------------------------------------------------
   SELF-HOSTED PLAYER — the "player" content element
   --------------------------------------------------------------------------
   Same element for both: Contao renders <video> or <audio> depending on the
   file's mime type, wrapped in the figure component so a caption becomes a
   <figcaption>.

   The width/height fields in the back end become HTML ATTRIBUTES on the
   media element, exactly as they do on the YouTube iframe above. The
   difference is that <video> has an intrinsic size, so no ratio needs to be
   invented here: browsers already derive aspect-ratio from those attributes
   the way they do for <img>. Setting an explicit ratio would be actively
   wrong — it would force a 4:3 clip into 16:9.

   So the whole job is releasing the pinned width. Left alone, a video with
   width="640" sits at 640px inside a wider column, and one with no size set
   at all falls back to the 300x150 default for a replaced element.
   -------------------------------------------------------------------------- */

/* Bounded on BOTH axes rather than stretched to the column width. A <video>
   carries an intrinsic ratio, so a max-width and a max-height together are
   enough: the browser shrinks it to satisfy whichever bites first and keeps
   the ratio itself. No ratio has to be declared, and none should be.

   The height ceiling is what makes portrait usable. Measured with a real
   2160x3840 clip: at width 100% it rendered 639x1135 — 1.17x the viewport
   height, and about 3200px tall in a full-width container. With the ceiling
   it settles to roughly 435x774 and stays on screen.

   Trade-off worth knowing: width is `auto`, not 100%, so a video whose
   intrinsic width is SMALLER than the column renders at its own size instead
   of being upscaled. That is deliberate — upscaled video looks soft — but if
   a small clip must fill the column, set the width in the element's player
   size field. */
.content-player video {
    display: block;
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: var(--video-tall-max, 80vh);
    margin-inline: auto;
}

/* A <video> placed by hand (in an HTML element or a news item) fills its
   column and keeps its ratio, as it did before framework v3. Without this it
   renders at its native size, e.g. 1920×1080 overflowing a 1260px column.
   The player element's own rule above is more specific and still wins. */
video {
    width: 100%;
    height: auto;
}

/* Audio has no picture, so it has a fixed control height and only the width
   is worth touching. Full width because a centred 300px control bar in a
   wide column reads as broken rather than deliberate. */
.content-player audio {
    display: block;
    width: 100%;
}

.content-player figure {
    margin: 0;
}

.content-player figcaption {
    margin-top: var(--space-8);
    font-size: 0.875em;
    color: var(--grey-dark);
}

/* --------------------------------------------------------------------------
   PASTED EMBEDS — raw <iframe> in a text or HTML element
   --------------------------------------------------------------------------
   Clients often skip the video content element and paste YouTube's embed
   code straight into the rich text editor. That markup carries no `aspect`
   class and no .content-youtube wrapper, so none of the rules above reach
   it — it arrives as a bare <iframe width="560" height="315">.

   The ratio is genuinely unknown to CSS: it exists only in those two HTML
   attributes, and until recently no CSS could read them. So this works in
   three layers, cheapest first.

   Note a pasted embed is NOT distorted the way a stretched image would be —
   an iframe re-lays out its contents rather than scaling them. A too-narrow
   player letterboxes internally. So the failure mode for anything missed
   here is mild, which is why the rules stay conservative.

   Two places a pasted embed can land, and they are structurally different:

     .rte              inside a text element — a normal descendant
     .mod_article >    the HTML and unfiltered HTML elements emit their
                       markup with NO wrapper div at all, so the embed
                       becomes a DIRECT CHILD of the article

   The second case is the one that surprises. There is no .content-* box to
   hook onto, and a column class set in the back end is silently dropped
   because there is nothing to put it on — which also means the embed becomes
   a flex item of the row and needs to be told to take its own line.
   -------------------------------------------------------------------------- */

/* 1. Nothing pasted may break out of its column, whatever it is. */
.rte :is(iframe, embed, object, video),
.mod_article > :is(iframe, embed, object, video) {
    max-width: 100%;
}

/* An unwrapped embed is a flex item of the row. Give it a full line so it
   does not sit alongside the real columns as if it were one. */
.mod_article > :is(iframe, embed, object, video, .embed-fluid) {
    flex: 0 0 100%;
}

/* 2. Known video hosts get the fluid treatment, with 16:9 assumed — right
      for essentially every player embed code in circulation.

      Deliberately scoped by src rather than applied to every iframe: a map,
      a Spotify player (152px tall), a booking widget or a form embed would
      be wrecked by being forced into 16:9. Matching on host means those keep
      their own height and only video is treated as video.

      Add a host by extending this list. */
:is(.rte iframe, .mod_article > iframe):is(
    [src*="youtube.com"], [src*="youtube-nocookie.com"], [src*="youtu.be"],
    [src*="player.vimeo.com"], [src*="loom.com"], [src*="wistia.net"],
    [src*="dailymotion.com"], [src*="videopress.com"]),
.embed-fluid iframe {
    width: 100%;
    height: auto;                             /* release the attribute height */
    aspect-ratio: var(--video-ratio, 16 / 9);
    display: block;
}

/* 3. Where the browser can read typed attr(), take the REAL ratio from the
      embed's own width/height instead of assuming. This is what makes a
      pasted 4:3 or portrait embed correct rather than merely contained.

      Progressive enhancement only — browsers without it keep the 16:9 above,
      which is why layer 2 is not written as a fallback inside this block.
      [width][height] is required in the selector so the function always has
      both attributes to read. */
@supports (aspect-ratio: attr(width type(<number>)) / attr(height type(<number>))) {
    :is(.rte iframe, .mod_article > iframe)[width][height]:is(
        [src*="youtube.com"], [src*="youtube-nocookie.com"], [src*="youtu.be"],
        [src*="player.vimeo.com"], [src*="loom.com"], [src*="wistia.net"],
        [src*="dailymotion.com"], [src*="videopress.com"]),
    .embed-fluid iframe[width][height] {
        aspect-ratio: attr(width type(<number>), 16) / attr(height type(<number>), 9);

        /* Same 80vh ceiling the 9:16 and 1:1 elements get, for the same
           reason: a pasted portrait embed measured 777x1381 without it.
           Capping WIDTH keeps the ratio true — the width that produces a
           full-height box is height-limit x (w/h). Landscape embeds are far
           from the ceiling at any normal width, so this only ever bites on
           tall ones. */
        max-width: calc(var(--video-tall-max, 80vh)
                        * attr(width type(<number>), 16)
                        / attr(height type(<number>), 9));
        margin-inline: auto;
    }
}

/* TUNING
     --video-ratio      fallback ratio when the editor picks none, and the
                        assumed ratio for a pasted embed. 16/9.
     --video-tall-max   height ceiling for 9:16 and 1:1. 80vh leaves the
                        page furniture visible around a portrait embed.

   An embed from a host not listed above keeps its own size. To make one
   fluid, wrap it in <div class="embed-fluid"> in the editor's source view;
   add style="--video-ratio: 4/3" to that div if it is not 16:9. */

iframe { border: 0; }

/* ==========================================================================
   PAGE SHELL — header, main and footer regions
   ==========================================================================
   Width and gutter come from --container-max and --page-gutter in
   framework_v3.css (1600px; 90 → 30 → 15px gutters).
   ========================================================================== */

html { overflow-x: clip; }

#hero .ce_text {
  width: 100%;
}

/* THE PAGE CONTAINER — one owner per region. fe_page nests
   .container_inside > #main > .inside, so only .container_inside carries
   the max-width and gutter (see framework README). */
#header .inside,
#footer .inside,
.container_inside,
#hero .content-element-group {
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--page-gutter);
}

/* The header is fixed, so the content starts below it. */
#container {
  padding-top: 200px;
}

.container_inside {
  padding-bottom: 120px;
}

#wrapper { overflow: clip; }

/* ==========================================================================
   BRIGHT CLOUD STUDIO — BRAND LAYER
   ==========================================================================
   Tokens, typography, links, lists and buttons. Layout belongs to
   framework_v3.css; the page shell to website_structure.css.

   Ported from website.scss (framework v1/v2 era). Values are unchanged
   unless a comment says otherwise.
   ========================================================================== */

/* ==========================================================================
   BRAND TOKENS
   ==========================================================================
   Native custom properties, so every stylesheet can read them at runtime
   regardless of load order. This file must be in every layout.
   ========================================================================== */
:root {
  --black: #161613;        /* darkest tone: footer background */
  --white: #fff;

  --text: #333A3F;         /* body copy, links, dark buttons (was $black) */
  --prime: #D73219;        /* brand red: CTAs, accents, active states */
  --second: #333A3F;       /* brand slate */

  /* Page background. The page itself is painted with the animated gradient
     below; --background is the flat cream used behind it and by components
     that need a solid version of it (hero panels, mobile menu). */
  --background: #FFF9F1;
  --page-gradient: linear-gradient(123deg, rgb(251, 234, 217) 0%, rgb(255, 249, 241) 48%, rgb(252, 239, 217) 100%);
  --header-gradient: linear-gradient(123deg, rgb(249, 239, 221) 0%, rgb(255, 249, 241) 48%, rgb(251, 239, 217) 100%);

  /* Borders and rules — a colour, never a shorthand. */
  --stroke: #D9D9D9;

  /* Derived shades. These were SCSS lighten() calls, which cannot operate on
     custom properties, so the resulting values are named here instead. */
  --grey-dark: #87949e;    /* lighten($black, 35%): button hover */
  --grey-light: #f0f0f0;   /* sub-navigation band */
  --text-light: #4a545b;   /* lighten($black, 10%): .intro copy */

  /* Type (Adobe Fonts kit btb8vqw, loaded in fe_page) */
  --type-body: freight-sans-pro, sans-serif;
  --type-display: freight-text-pro, serif;
}

html {
  /* Anchor jumps land below the fixed header */
  scroll-padding-top: 180px;
}

body {
  background: rgb(249, 239, 221);
  background: var(--page-gradient);
  background-size: 400% 400%;
  animation: gradient 8s ease infinite;
  font-size: 1.35em;
  line-height: 1.35em;
  font-family: var(--type-body);
  color: var(--text);
  font-weight: 300;
  font-style: normal;
  font-feature-settings: "lnum";
}

@keyframes gradient {
  0%   { background-position: 0% 50%; }
  50%  { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}

/* ==========================================================================
   HEADINGS & TEXT
   ========================================================================== */
h1 {
  font-size: clamp(3em, 5vw, 5em);
  line-height: 1em;
  font-weight: 300;
  font-family: var(--type-display);
  margin-bottom: 0.25em;
  text-wrap: balance;
}

h1 .small {
  display: block;
  font-size: 0.6em;
  font-weight: 700;
}

h2 {
  margin-bottom: 15px;
  font-size: clamp(1.25em, 1.85vw, 1.85em);
  line-height: 1.125em;
  font-weight: 600;
  text-wrap: balance;
}

.small h2 {
  font-size: clamp(1.25em, 1.4vw, 1.65em);
}

h3 {
  margin: 0 0 10px;
  font-size: clamp(1.125em, 1.5vw, 1.4em);
  line-height: 1.125em;
  font-weight: 500;
}

p {
  font-size: clamp(0.9em, 1.7vw, 1em);
  line-height: 1.35em;
  margin: 0 0 1.35em;
  padding: 0;
}

sup {
  font-size: clamp(0.25em, 0.6vw, 0.4em);
}

strong {
  font-weight: 600;
}

a {
  border-bottom: 1px solid var(--text);
  text-decoration: none;
  color: var(--text);
  transition: all 0.2s ease;
}

a:hover {
  border-bottom: 1px solid var(--prime);
  color: var(--prime);
}

h1 a,
h2 a,
h3 a,
h1 a:hover,
h2 a:hover,
h3 a:hover {
  border-bottom: 0;
}

hr {
  margin-top: 30px;
  margin-bottom: 90px;
  border: 0;
  border-top: 1px solid var(--stroke);
}

.red {
  color: var(--prime);
}

.intro {
  font-size: 1.4em;
  color: var(--text-light);
  text-wrap: balance;
}

.meta {
  font-size: 0.75em;
}

figcaption {
  text-align: center;
  font-size: 0.875em;
}

/* Error text and the required-field asterisk are brand red. website_standard
   colours them with --second, which on this site is the slate. */
.error,
span.mandatory {
  color: var(--prime);
}

/* ==========================================================================
   READING RHYTHM — news and case-study articles
   ==========================================================================
   Long-form article bodies (the news reader on blog posts and case studies)
   use flow spacing: 1em between blocks, nothing before the first or after
   the last, so sections sit evenly. That is the rhythm these pages had under
   framework v2, whose global margin reset produced it. Marketing pages keep
   the 1.35em paragraph margins above. */
.mod_newsreader :is(p, ul, ol, blockquote) {
  margin-block: 0;
}

.mod_newsreader .rte > * + * {
  margin-top: 1em;
}

/* ==========================================================================
   LISTS
   ==========================================================================
   Here rather than in a component file because the list element and a list
   typed into the rich text editor emit the same markup. */
ul,
ol {
  margin: 0 0 1.35em;
  padding-block: 0;
  padding-inline-start: 1em;
}

li {
  margin-bottom: 10px;
}

/* Bullets in the brand red. Lists used as interface (navigation, pagination,
   galleries) reset list-style, so they have no marker to colour. */
ul > li::marker {
  color: var(--prime);
}

/* A nested list belongs to its parent item: its spacing above, none below. */
li > ul,
li > ol {
  margin-block: 10px 0;
}

dl { margin: 0 0 1em; }
dt { font-weight: 600; }
dd { margin: 0 0 0.75em; }
dd:last-child { margin-bottom: 0; }

.hide_bullets ul {
  list-style: none;
}

/* ==========================================================================
   SMALL PRINT
   ========================================================================== */
.small,
.small p {
  font-size: clamp(0.75em, 1.35vh, 1.125em);
}

.small p {
  margin-bottom: 0.875em;
}

.small a,
a.small {
  display: inline-block;
}

.small li {
  margin-bottom: 0;
}

/* ==========================================================================
   BUTTONS
   ==========================================================================
   Matched by intent, not by element (see framework README): a bare `button`
   selector would style every third-party control. Form submits are covered
   by [type="submit"]; anything else that should look like a button gets
   .btn. The three rule sets below must list the same selectors.
   ========================================================================== */
.btn a,
a.btn,
button[type="submit"],
.blog .layout_latest p.more a {
  display: inline-block;
  margin-bottom: 30px;
  padding: 15px 25px;
  text-align: center;
  background-color: var(--prime);
  border-radius: 30px;
  font-size: 1rem;
  color: var(--white);
  cursor: pointer;
  border: 0;
  line-height: 1.35em;
  text-transform: uppercase;
}

.btn a:hover,
a.btn:hover,
button[type="submit"]:hover,
.blog .layout_latest p.more a:hover {
  background-color: var(--grey-dark);
  color: var(--white);
}

.btn.dark a,
a.btn.dark {
  background-color: var(--text);
  color: var(--white);
}

.btn.dark a:hover,
a.btn.dark:hover {
  background-color: var(--prime);
  color: var(--white);
}

/* ==========================================================================
   DOWNLOADS
   ========================================================================== */
a.download-element:after {
  display: inline-block;
  padding: 0 0 0 0.25em;
  border: 0;
  font-family: "Font Awesome 5 Pro";
  text-transform: none;
  content: "\f019";
  font-weight: 900;
}

a.download-element {
  margin-inline: 0.25em;
  padding: 0;
  font-weight: bold;
}

.download-element .size {
  display: none;
}

/* ==========================================================================
   SUB-NAVIGATION IN THE MAIN COLUMN
   ========================================================================== */
#main .mod_navigation ul {
  width: 100%;
  margin: 0 0 30px;
  padding: 18px 0 15px;
  text-align: center;
  background-color: var(--grey-light);
  list-style-type: none;
}

#main .mod_navigation li {
  display: inline-block;
}

#main .mod_navigation a,
#main .mod_navigation strong {
  display: block;
  padding-inline: 15px;
  border-bottom: 0;
}

/* ==========================================================================
   SITE UTILITIES
   ==========================================================================
   Small helpers the framework does not provide. */

/* One line of items sized to their content: an icon beside its text.
   Deliberately not a framework .row. An element group that is both a column
   and a row sizes its own column width with its own gap rather than its
   parent's (framework v3 nests rows that way), so a half-width card that was
   also a row would wrap onto its own line. */
.nowrap {
  display: flex;
  flex-wrap: nowrap;
}

/* Default min-width (auto) matters here: it stops the icon shrinking to
   nothing next to a long paragraph. */
.nowrap > :where(:not([class*="col-"])) {
  flex: 0 1 auto;
}

/* LEGACY — v2 "trim". A row with column padding (pxc-*) is pulled out by
   that padding so its outer columns line up with the page edge, as the
   case studies were built under framework v2. The v3 way to separate
   columns is a gap-* class, so new rows should not need this. */
.row.trim {
  margin-inline: calc(-1 * var(--col-pad-x, 0px));
}

.content-element-group.nowrap svg {
  font-size: 2.25em;
  margin-right: 15px;
  margin-top: 10px;
  color: var(--prime);
}

/* Stretch an element's image to the full column width. */
.img100 img {
  width: 100%;
}

.signup {
  padding: 50px 0;
}

.video-container {
  position: relative;
  padding-bottom: 56.25%; /* 16:9 */
  height: 0;
  overflow: hidden;
  max-width: 100%;
  background: #000;
}

.video-container iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

/* Large rounded corners for images */
.left-rounded figure {
  overflow: hidden;
  border-radius: clamp(30px, 8vw, 190px) 0 0 0;
}

.right-rounded figure {
  overflow: hidden;
  border-radius: 0 clamp(30px, 8vw, 190px) 0 0;
}

/* ==========================================================================
   CARDS & SERVICES
   ========================================================================== */
.col-1-3.quote {
  margin-top: 60px;
}

.card,
.service {
  border: 1px solid var(--prime);
  padding: 60px;
}

.card.media.media--above figure {
  margin-bottom: 15px;
}

.card.media--above.center_text figure img {
  margin: auto;
}

.card.vert_center {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
}

.profile {
  margin-bottom: 60px;
}

/* A grid of team profiles goes 3 -> 2 -> 1 rather than the framework's
   3 -> 1 for thirds: one portrait per line on a tablet is far too large. */
@media (max-width: 992px) {
  .row:not(.no-stack) > .profile.col-1-3 {
    flex-basis: calc(50% - var(--gap-x, 0px) * 0.5);
  }
}

@media (max-width: 600px) {
  .row:not(.no-stack) > .profile.col-1-3 {
    flex-basis: 100%;
  }
}

.profile img {
  margin-bottom: 10px;
}

.profile h3 {
  margin-bottom: 0;
}

.social {
  display: block;
}

.social a {
  border-bottom: 0;
}

.services .rte strong {
  text-transform: uppercase;
  font-size: 0.9em;
}

.services .rte ul {
  list-style: none;
  padding: 0;
  margin-bottom: 30px;
  margin-top: 0;
}

.services .rte ul li {
  margin-bottom: 8px;
}

/* A service is an element group laid out as a row: a fixed-width intro
   (text + image) beside a list that takes the rest. `flex` rather than
   `width`, because the framework's `.row > *` sets a flex-basis that a
   width cannot override. */
.service {
  container-type: inline-size;
  flex-wrap: nowrap;
  margin-bottom: 90px;
  padding: 90px;
  padding-bottom: 60px;
}

/* The headline sits above the copy, so this column is the graphic alone and
   can run wider. The graphic fills it. */
.service > .content-text.media {
  flex: 0 0 520px;
  padding-right: 90px;
}

/* An engraved graphic fills whatever column it sits in, here and on the
   service landing pages. svg as well as img: engraved-draw.js swaps the
   graphic for inline markup so it can draw itself when it scrolls into view. */
.service > .content-text.media figure :is(img, svg),
img[src*="-engraved.svg"],
svg.armed {
  width: 100%;
  height: auto;
}

/* An image-only element still renders its (empty) rich-text wrapper. */
.service .rte:empty {
  display: none;
}

.service > :not(.media) {
  flex: 1 1 0;
}

.service h2 {
  font-family: var(--type-display);
  font-size: clamp(2em, 5vw, 3.25em);
  font-weight: 400;
  margin-bottom: 25px;
}

@container (max-width: 950px) {
  .service > .content-text.media {
    flex-basis: 430px;
    padding-right: 60px;
  }
}

@container (max-width: 850px) {
  .service > .content-text.media {
    flex-basis: 350px;
    padding-right: 30px;
  }
}

@container (max-width: 790px) {
  .service > .content-text.media {
    flex-basis: 300px;
    padding-right: 30px;
  }
}

@media only screen and (max-width: 1350px) {
  .service {
    padding-inline: 60px;
    padding-block: 45px 15px;
  }
}

@media only screen and (max-width: 730px) {
  .service {
    flex-wrap: wrap;
  }

  .service > .content-text.media {
    text-align: center;
    max-width: 500px;
    margin: 0 auto 30px;
    padding: 0;
  }

  .service > .content-text.media h2 {
    margin-bottom: 25px;
  }

  .service > :not(.media) {
    flex-basis: 100%;
  }
}

@media only screen and (max-width: 550px) {
  .service {
    padding-inline: 45px;
    padding-block: 30px 0;
  }
}

/* ==========================================================================
   SERVICES — ONE THREAD, FIVE STATIONS
   ==========================================================================
   services-thread.js draws a hairline down the cards' left border, moves a
   node along it with the scroll, and marks the nearest card .is-current. The
   number before each headline is a counter, grey until its station is
   current. The copy rises in once the script has armed the card (.svc-armed),
   so without JavaScript it is simply visible. */
.mod_article:has(> .service) {
  position: relative;
  isolation: isolate;     /* keeps the thread's z-index behind the cards only */
  counter-reset: svc;
}

.service {
  counter-increment: svc;
}

.service h2::before {
  content: counter(svc, decimal-leading-zero);
  display: block;
  margin-bottom: 0.55em;
  font-family: var(--type-body);
  font-size: 0.36em;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--text-light);
  opacity: 0.5;
  transition: color 0.4s ease, opacity 0.4s ease;
}

.service.is-current h2::before {
  color: var(--prime);
  opacity: 1;
}

.svc-thread {
  position: absolute;
  z-index: -1;
  width: 1px;
  background-color: var(--stroke);
  pointer-events: none;
}

.svc-node {
  position: absolute;
  top: -6.5px;
  left: 50%;
  width: 13px;
  height: 13px;
  margin-left: -6.5px;
  border-radius: 50%;
  background-color: var(--prime);
  will-change: transform;
}

/* The cards stack and the graphics centre on small screens: no thread. */
@media (max-width: 730px) {
  .svc-thread {
    display: none;
  }
}

/* The copy arrives when the card does, one block after another. */
.service.svc-armed > :not(.media) .rte > * {
  opacity: 0;
}

.service.svc-armed.in-view > :not(.media) .rte > * {
  animation: svc-rise 0.7s cubic-bezier(0.22, 1, 0.36, 1) both;
  animation-delay: calc(var(--k, 6) * 90ms);
}

.service .rte > :nth-child(1) { --k: 0; }
.service .rte > :nth-child(2) { --k: 1; }
.service .rte > :nth-child(3) { --k: 2; }
.service .rte > :nth-child(4) { --k: 3; }
.service .rte > :nth-child(5) { --k: 4; }
.service .rte > :nth-child(6) { --k: 5; }

@keyframes svc-rise {
  from {
    opacity: 0;
    transform: translateY(18px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .service.svc-armed > :not(.media) .rte > * {
    opacity: 1;
    animation: none;
  }
}

/* ==========================================================================
   HEADER — fixed bar with logo, main navigation and contact links
   ==========================================================================
   Markup: the "Header - Wrapper" HTML module (.header_left, .logo,
   .contact, .phone, .btn, .menu). Below 670px the navigation hides and
   .menu opens the mmenu panel (module "Mobile Nav", #menu).
   ========================================================================== */

#header {
  position: fixed;
  width: 100%;
  z-index: 400;
  background: var(--background);
  background: var(--header-gradient);
  top: 0;
  left: 0;
  height: max-content;
}

#header .inside,
#header .header_left,
#header .contact {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

#header .header_left {
  width: 100%;
  padding-right: 3.75%;
}

#header .contact {
  border-left: 1px solid var(--stroke);
  align-self: stretch;
  font-size: 0.75em;
  padding-left: 5%;
}

#header .contact .btn {
  padding: 7px 15px;
  margin-left: 30px;
}

#header .btn {
  margin-bottom: 0;
}

#header .logo {
  width: 60px;
  margin-right: 60px;
  padding: 18px 0;
}

#header a {
  border-bottom: 0;
}

#header .mod_navigation ul {
  font-size: 0.822em;
  font-weight: 500;
}

#header .mod_navigation ul,
#header .mod_navigation li {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  align-items: center;
  line-height: 1em;
}

/* strong.forward is Contao's "active" for a forward page whose target is the
   current page: the Discovery entry in the Services dropdown. */
#header .mod_navigation a,
#header .mod_navigation strong.active,
#header .mod_navigation strong.forward {
  padding: 10px 20px;
  font-weight: 400;
}

#header .mod_navigation strong.active,
#header .mod_navigation strong.forward {
  color: var(--prime);
}

#header .menu {
  display: none;
}

/* DROPDOWN — the second level under a top item (Services). It opens on hover
   and on keyboard focus, and the parent stays a real link. Contao's .block
   sets overflow hidden, which would clip the panel. Below 670px the whole
   nav is replaced by the mmenu panel, which nests the level itself. */
#header .mod_navigation,
#header .mod_navigation.block {
  overflow: visible;
}

#header .mod_navigation li {
  position: relative;
}

#header .mod_navigation ul.level_2 {
  position: absolute;
  top: 100%;
  left: 20px;
  z-index: 1000;
  flex-direction: column;
  align-items: stretch;
  min-width: 270px;
  padding: 8px 0;
  background: var(--background);
  border: 1px solid var(--stroke);
  border-radius: 0 12px 12px 12px;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity 0.25s ease, transform 0.25s ease, visibility 0s linear 0.25s;
  pointer-events: none;
}

#header .mod_navigation li:hover > ul.level_2,
#header .mod_navigation li:focus-within > ul.level_2 {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity 0.25s ease, transform 0.25s ease;
  pointer-events: auto;
}

#header .mod_navigation ul.level_2 li {
  display: block;
}

#header .mod_navigation ul.level_2 a,
#header .mod_navigation ul.level_2 strong.active,
#header .mod_navigation ul.level_2 strong.forward {
  display: block;
  padding: 11px 22px;
  white-space: nowrap;
  line-height: 1.2em;
}

#header .mod_navigation ul.level_2 a:hover {
  color: var(--prime);
}

/* The parent of the current page reads as current too. */
#header .mod_navigation li.trail > a {
  color: var(--prime);
}

@media only screen and (max-width: 1290px) {
  #header .mod_navigation ul {
    font-size: 0.75em;
  }
}

@media only screen and (max-width: 1200px) {
  #header .mod_navigation a {
    padding: 10px 15px;
  }

  #header .logo {
    width: 65px;
    margin-right: 45px;
  }

  #header .contact {
    padding-left: 3.8%;
  }
}

@media only screen and (max-width: 970px) {
  #header .mod_navigation a {
    padding: 10px;
  }

  #header .logo {
    width: 55px;
    margin-right: 20px;
  }

  #header .contact .btn {
    margin-left: 15px;
  }
}

@media only screen and (max-width: 860px) {
  #header .logo {
    width: 45px;
    margin-right: 15px;
  }

  #header .mod_navigation ul {
    font-size: 0.7em;
  }

  #header .mod_navigation a {
    padding: 10px;
  }

  #header .contact .btn {
    padding: 6px 12px;
    margin-left: 15px;
    font-size: 0.875em;
  }
}

@media only screen and (max-width: 670px) {
  #header .contact {
    border-left: 0;
  }

  #header .inside {
    padding-right: 0;
  }

  #header .logo {
    padding-block: 15px;
    width: 55px;
  }

  #header .mod_navigation {
    display: none;
  }

  #header .menu {
    display: flex;
    justify-content: center;
    align-items: center;
    background-color: var(--prime);
    color: var(--white);
    height: 100%;
    padding: 20px;
    margin-left: 15px;
    font-size: 1.25em;
  }
}

@media only screen and (max-width: 600px) {
  #header {
    bottom: 0;
    border-bottom: 0;
    border-top: 1px solid var(--stroke);
  }
}

/* ==========================================================================
   MOBILE MENU (mmenu, module "Mobile Nav")
   ========================================================================== */
.mm-menu--theme-light {
  background: var(--background) !important;
  --mm-color-background: var(--background) !important;
}

.mm-navbar__title {
  color: var(--black) !important;
}

.mm-wrapper--opened .mm-wrapper__blocker {
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(40px);
  opacity: 0.95;
}

.mm-listitem__text {
  padding-block: 30px;
}

/* ==========================================================================
   FOOTER
   ==========================================================================
   Markup: the "Footer - Wrapper" HTML module — three .footer_col columns
   (.address, .footer_nav and one plain) inside a flex #footer .inside.
   These used to be `size33` framework classes; they are layout hooks for
   this file only, so they now have their own name.
   ========================================================================== */

#footer {
  background-color: var(--black);
  padding-top: 75px;
  font-size: 0.75em;
  line-height: 1.35em;
  color: var(--white);
}

#footer .inside {
  display: flex;
}

#footer .logo {
  width: 70px;
  margin-right: 25px;
}

#footer a {
  border-bottom: 1px solid var(--white);
  color: var(--white);
}

#footer .contact {
  display: inline-block;
  margin-bottom: 30px;
}

#footer .copyright {
  margin-top: 100px;
  font-size: 0.8em;
}

#footer .social a {
  border-bottom: 0;
}

#footer address {
  display: block;
}

#footer .blog {
  margin-top: 30px;
}

#footer ul,
#footer li {
  list-style: none;
  padding: 0;
  margin: 0;
}

#footer .mod_navigation a {
  border-bottom: 0;
}

/* Columns, separated by a rule with a red dot at the top */
#footer .footer_col {
  width: 33.333%;
  border-right: 1px solid var(--white);
  padding-bottom: 160px;
  position: relative;
  padding-inline: 30px;
}

#footer .footer_col.address {
  display: flex;
  width: 41%;
}

#footer .footer_col.footer_nav {
  width: 25%;
}

#footer .footer_col:after {
  content: " ";
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background-color: var(--prime);
  position: absolute;
  top: 0;
  right: -10px;
}

#footer .footer_col:last-child {
  border-right: 0;
}

#footer .footer_col:last-child:after {
  display: none;
}

/* Mailchimp signup */
#footer form {
  padding: 0;
  margin: 0;
}

#footer #mc_embed_signup form,
#footer #mc-embedded-subscribe {
  margin: 0 !important;
}

#footer .clear {
  height: inherit;
  font-size: inherit;
}

#footer input.btn {
  font-size: 1em !important;
  background-color: var(--prime);
  padding: 7px 15px;
  display: inline-block;
  color: var(--white);
  border: 0;
  font-weight: 300;
  text-transform: uppercase;
  border-radius: 5px;
  cursor: pointer;
}

#footer input.btn:hover {
  background-color: var(--white);
  color: var(--prime);
}

@media only screen and (max-width: 1330px) {
  #footer .footer_col.address {
    width: 450px;
    flex-shrink: 0;
    flex-basis: 450px;
  }

  #footer .footer_col.footer_nav {
    width: 200px;
    flex-basis: 200px;
    flex-shrink: 0;
  }
}

@media only screen and (max-width: 900px) {
  #footer .inside {
    flex-wrap: wrap;
    padding-bottom: 80px;
  }

  #footer .inside .logo {
    width: 70px;
    padding-right: 10px;
  }

  #footer .footer_col,
  #footer .footer_col.address,
  #footer .footer_col.footer_nav {
    border: 0;
    padding-left: 95px;
    width: 100%;
    flex-basis: 100%;
    padding-bottom: 15px;
  }

  #footer .footer_col.address {
    padding-left: 0;
  }

  #footer .footer_col:after {
    display: none;
  }

  #footer .copyright {
    margin-top: 10px;
  }

  #footer .blog {
    margin-top: 0;
  }
}

/* ==========================================================================
   FORMS
   ==========================================================================
   Two parts, kept separate on purpose:

     PART 1 — LAYOUT   how form fields sit in the column framework
     PART 2 — BRAND    how they look

   Part 1 is the framework's and should rarely need touching. Part 2 is
   brightcloudstudio.com's, ported from forms.scss.

   SCOPE: `.formbody`, which Contao uses for the form content element and for
   every member module alike.
   ========================================================================== */


/* ==========================================================================
   PART 1 — LAYOUT (framework v3)
   ==========================================================================
   .formbody behaves as a framework row, so a `col-*` class on a form field
   works exactly as it does on a content element — same widths, gutter and
   stacking. Editors set it through the Theme Toolbox.
   ========================================================================== */

.formbody {
  display: flex;
  flex-wrap: wrap;
  --gap-x: var(--row-gap-x);
  --gap-y: var(--row-gap-y);
  gap: var(--gap-y) var(--gap-x);
}

/* Every child defaults to a full line. :where() keeps this at zero
   specificity so the col-* widths win. */
:where(.formbody) > * {
  flex: 0 1 100%;
  min-width: 0;
}

/* Row gaps space the fields, so widgets carry no margin of their own.
   :where() keeps it at zero specificity, so a spacing class an editor puts
   on a field (mb-24) still adds to the gap. */
:where(.formbody > .widget) {
  margin: 0;
}

@media (max-width: 992px) {
  form:not(.no-stack) .formbody > .col-1-3,
  form:not(.no-stack) .formbody > .col-2-3,
  form:not(.no-stack) .formbody > .col-3-4,
  form:not(.no-stack) .formbody > .col-3-5,
  form:not(.no-stack) .formbody > .col-2-5,
  form:not(.no-stack) .formbody > .col-30,
  form:not(.no-stack) .formbody > .col-20 {
    flex-basis: 100%;
  }

  form:not(.no-stack) .formbody > .col-1-4 {
    flex-basis: calc(50% - var(--gap-x, 0px) * 0.5);
  }
}

@media (max-width: 600px) {
  form:not(.no-stack) .formbody > .col-1-2,
  form:not(.no-stack) .formbody > .col-1-4 {
    flex-basis: 100%;
  }
}

.formbody label {
  display: block;
}

.formbody input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]),
.formbody select,
.formbody textarea {
  width: 100%;
  max-width: 100%;
}

.formbody textarea {
  display: block;
  resize: vertical;
}

.formbody .checkbox_container label,
.formbody .radio_container label {
  display: inline-block;
}


/* ==========================================================================
   PART 2 — BRAND (brightcloudstudio.com)
   ========================================================================== */

/* Fields sit close together: the gap stands in for the 15px each input
   used to carry below it. */
.formbody {
  max-width: 800px;
  --gap-y: var(--gutter-16);
}

.formbody input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]),
.formbody select,
.formbody textarea {
  padding: 15px 20px;
  border: 2px solid var(--prime);
  border-radius: 10px;
  background-color: var(--white);
  color: var(--text);
  font: inherit;
  line-height: normal;
}

.formbody input:focus-visible,
.formbody select:focus-visible,
.formbody textarea:focus-visible {
  outline: 2px solid var(--text);
  outline-offset: 2px;
}

legend,
.formbody .widget-text label,
.formbody .widget-textarea label,
.formbody .widget-select label,
.formbody .widget-upload label,
.formbody .widget-checkbox > fieldset > legend {
  font-weight: 600;
  font-size: 1.25em;
  margin-bottom: 10px;
}

.formbody .widget-checkbox legend {
  font-size: 1em;
  font-weight: 300;
  margin-bottom: 0;
}

/* A single opt-in checkbox reads as the question itself */
.formbody .checkbox_container label {
  font-weight: 600;
  font-size: 1.25em;
}

.formbody span.mandatory {
  color: var(--prime);
}

.formbody p.error,
.formbody .widget .error {
  color: var(--prime);
  font-size: 0.875em;
}

.formbody input.captcha {
  width: 60px;
  padding: 10px 15px;
}

fieldset {
  width: 100%;
  border-bottom: 1px solid var(--text);
  padding-bottom: 45px;
  margin-bottom: 35px;
}

.formbody .widget-submit button {
  margin-bottom: 0;
}

/* The referral form is narrower and centred */
.referral {
  max-width: 700px;
  margin: auto;
}

/* Confirmation panel shown after sending */
.form-confirmation {
  max-width: 500px;
  background-color: var(--prime);
  padding: 60px 60px 45px;
  color: var(--white);
  margin: auto;
  border-radius: 10px;
}

.form-confirmation .btn {
  background-color: var(--white);
  color: var(--prime);
  text-wrap: balance;
}

.form-confirmation .btn:hover {
  background-color: var(--text);
}

