/* =========================================================
   ROOT
========================================================= */

:root {
  /* Height of the header logo, stepped down per breakpoint at the end of this file. The
     logo is sized by height rather than by width so that the header bar keeps the same
     height whatever aspect ratio a tenant uploads under 'logo' in the theme settings. */
  --header-logo-height: 110px;
}

/* =========================================================
   GLOBAL ELEMENTS
========================================================= */

/* Document */
html {
}

/* Was a style attribute on the <body> tag in header.php. The property is only defined when
   an image is configured, see mein_customizer_css() in functions.php - without one the
   fallback applies and the body looks exactly as it did without the attribute. */
body {
  background-image: var(--body-background-image, none);
  background-size: 100%;
  background-repeat: no-repeat;
}

section {
}

main {
}

/* Headings */
h1,
h2,
h3,
h4,
h5,
h6 {
}

/* Text elements */
p {
}

strong {
}

em {
}

small {
}

/* Links */
a {
}

/* Lists */
ul,
ol {
}

li {
}

/* Media */
img {
}

picture {
}

figure {
}

figcaption {
}

/* Tables */
table {
}

thead {
}

tbody {
}

tr {
}

th,
td {
}

/* Misc */
hr {
}

blockquote {
}

code {
}

pre {
}

iframe,
datalist {
}

/* =========================================================
   HELPER CLASSES
========================================================= */

/* Spacing between two buttons standing next to each other. Used by the action rows of
   dokumente, eakonzept, kinder, mitarbeiter and news - it only ever lived in the <style>
   tag of snippets/news/edit.php, so everywhere else the class did nothing at all. */
.margin-right {
  margin-right: 10px;
}

/* =========================================================
   UI ELEMENTS
========================================================= */

/* The main call to action of a view. Both properties stay undefined until the theme settings
   carry a colour, so an unconfigured site keeps the button on the main colour it had before. */
.button.primary {
  background-color: var(--primary-button-background-color, var(--primary-color));
  border-color: var(--primary-button-background-color, var(--primary-color));
  color: var(--primary-button-text-color, #FFFFFF);

  &:hover,
  &:focus,
  &:focus-visible,
  &:active {
    background-color: var(--primary-button-background-color, var(--primary-color));
    border-color: var(--primary-button-background-color, var(--primary-color));
    color: var(--primary-button-text-color, #FFFFFF);
  }
}

.button.secondary {
  background-color: var(--secondary-button-background-color, #5B977B);
  border-color: var(--secondary-button-background-color, #5B977B);
  color: var(--secondary-button-text-color, #FFFFFF);

  &:hover,
  &:focus,
  &:focus-visible,
  &:active {
    background-color: var(--secondary-button-background-color, #5B977B);
    border-color: var(--secondary-button-background-color, #5B977B);
    color: var(--secondary-button-text-color, #FFFFFF);
  }
}

/* A link that does nothing but wrap a button - the "Drucken" links of the kinder module are
   built that way - must not underline its label. Bootstrap 3 underlines a:hover and a:focus,
   and text-decoration set on the anchor propagates into the button inside it: a descendant
   cannot take it back, which is why the text-decoration: none of .button:hover in
   legacy-style.css never reaches it. Anchors that carry .button themselves are already
   covered by that rule and are deliberately not matched here.

   :has() carries the specificity of its argument, so this beats bootstrap's a:hover
   regardless of load order. It needs the same browser generation as the native nesting
   used throughout this file; where it is missing the underline simply returns. */
a:has(> .button):hover,
a:has(> .button):focus {
  text-decoration: none;
}

/* Dismissive actions such as deleting, deactivating or cancelling out of a view. Replaces
   the hardcoded .button.red of legacy-style.css, which the remaining views still carry. */
.button.cancel {
  background-color: var(--cancel-button-background-color, #D10000);
  border-color: var(--cancel-button-background-color, #D10000);
  color: var(--cancel-button-text-color, #FFFFFF);

  &:hover,
  &:focus,
  &:focus-visible,
  &:active {
    background-color: var(--cancel-button-background-color, #D10000);
    border-color: var(--cancel-button-background-color, #D10000);
    color: var(--cancel-button-text-color, #FFFFFF);
  }
}

/* A generated certificate stays visibly disabled after it has been created. The
   semantic primary class is loaded after legacy-style.css and would otherwise paint
   over the existing grey state. */
.button.primary.grey {
  background-color: #95989a;
  border-color: #95989a;

  &:hover,
  &:focus,
  &:focus-visible,
  &:active {
    background-color: #95989a;
    border-color: #95989a;
  }
}

/* Error banner above a backend form, printed instead of ending the request when a save
   handler sends the form back - see snippets/mitarbeiter/edit.php. Colours are the ones
   bootstrap 3 uses for its danger state, so it sits in the loaded framework's palette. */
.form-notice {
  margin-bottom: 20px;
  padding: 12px 15px;
  border: 1px solid #ebccd1;
  border-left-width: 4px;
  border-left-color: #d9534f;
  background-color: #f2dede;
  color: #a94442;
}

/* =========================================================
   CUSTOM BLOCKS
========================================================= */

/* The shared upload field, rendered by mein_file_field() in inc/files/file-field.php
   and driven by initFileFields() in assets/js/custom.js.

   The look is the one snippets/news/edit.php carried in a <style> tag of its own, on
   the field's own class names instead of .file-upload-box - that class is still worn
   by the forms which have not been migrated yet, and styling it here would restyle
   them along the way.

   Not nested under a body.page-template-* selector on purpose: the field is a
   building block and appears wherever a form takes a file. */
.file-field {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 150px;
  padding: 20px;
  border: 2px dashed #ccc;
  text-align: center;
  transition: border-color 0.3s ease;

  &:hover {
    border-color: #999;
  }

  /* Empty keeps the dashed "drop something here" frame, a field that holds a file
     gets a solid one. Deliberately a neutral grey rather than --primary-color: the
     state has to read the same in every corporate design. */
  &.has-file {
    border-style: solid;
    border-color: #bbb;
  }

  & .file-field-preview,
  & .file-field-video {
    display: block;
    width: auto;
    max-width: 100%;
    height: auto;
    max-height: 300px;
    margin: 10px auto;
    border-radius: 4px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    object-fit: contain;
  }

  /* Image and video take turns, the javascript switches them by the hidden
     attribute. The rule above sets a display and would otherwise beat the
     browser's own [hidden] rule, which is only a single class worth of
     specificity - hence the attribute spelled out on both selectors. */
  & .file-field-preview[hidden],
  & .file-field-video[hidden] {
    display: none;
  }

  /* A file with no inline representation - a pdf above all. It takes the place of
     the preview image, which showed the same placeholder an empty field has and made
     the two indistinguishable. */
  & .file-field-doc {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    margin: 10px auto;
    padding: 10px;
    max-width: 100%;
    /* Long file names must not push the box wider than its column. */
    overflow-wrap: break-word;
    /* break-word alone does not break a name without a single space in it. */
    word-break: break-word;
  }

  /* Same reason as the two rules above: the display set here would otherwise beat
     the browser's own [hidden] rule. */
  & .file-field-doc[hidden],
  & .file-field-doc-type[hidden],
  & .file-field-doc-link[hidden] {
    display: none;
  }

  /* A sheet of paper with the file's extension written on it. Drawn here rather than
     taken from an icon font: the theme's own carries a single document glyph, which
     would put a pdf symbol on a word file, and the Font Awesome stylesheet that
     functions.php enqueues has no font files behind it - every fa-* class comes out
     as an empty box.

     The shape is a mask rather than a background image, so it takes its colour from
     currentColor and follows whatever the surrounding design sets. */
  & .file-field-doc-icon {
    position: relative;
    display: block;
    width: 64px;
    height: 64px;
    color: #8a8a8a;

    &::before {
      content: "";
      position: absolute;
      inset: 0;
      background-color: currentColor;
      -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z'/%3E%3Cpath d='M14 3v5h5'/%3E%3C/svg%3E") center / contain no-repeat;
      mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z'/%3E%3Cpath d='M14 3v5h5'/%3E%3C/svg%3E") center / contain no-repeat;
    }
  }

  /* Sits in the lower half of the sheet, clear of the folded corner. A long extension
     is rare, so it may use the full width rather than being cut short. */
  & .file-field-doc-ext {
    position: absolute;
    left: 4px;
    right: 4px;
    bottom: 15px;
    font-size: 12px;
    font-weight: bold;
    letter-spacing: 0.5px;
    line-height: 1;
  }

  & .file-field-doc-name {
    font-weight: bold;
  }

  & .file-field-doc-type {
    color: #666;
    font-size: 12px;
  }

  & .file-field-doc-link {
    font-size: 12px;
  }

  /* Sits in the top left corner above the preview, the way the news box has it.

     A real <button> rather than the clickable <div> the older boxes use, so it is
     reachable by keyboard and announced as a control. That means undoing what the
     bare "button" rule in legacy-style.css hands every button on the page - the
     162px min-width, the filled primary background and the bold white label. */
  & .file-field-remove {
    position: absolute;
    left: 0;
    top: 0;
    z-index: 5;
    min-width: 0;
    padding: 5px 10px;
    border: 1px solid #ddd;
    border-radius: 3px;
    background: rgba(255, 255, 255, 0.9);
    color: #333;
    font-size: 12px;
    font-weight: normal;
    cursor: pointer;
    transition: background-color 0.2s ease;

    &:hover {
      border-color: #999;
      background: rgba(255, 255, 255, 1);
      box-shadow: none;
      color: #333;
    }
  }

  & .file-field-input {
    max-width: 300px;
    margin-top: 15px;
  }

  & .file-field-info {
    margin-top: 10px;
    margin-bottom: 0;
    padding: 8px;
    border-radius: 4px;
    background: #f8f9fa;
    font-size: 12px;
    /* Long file names must not push the box wider than its column. */
    overflow-wrap: break-word;
  }

  & .file-field-info-type {
    color: #666;
  }
}

/* The old document form fixed only its preview image at 134px inline. Keep that
   size local to the preview-image field while the shared component owns the rest. */
body.page-template-template_backend_dokumente .dokument-preview-upload .file-field-preview {
  /* height: 134px; */
}

/* The map of template_backend_map.php and template_versorgungsmap.php, driven by
   initBackendMap() / initVersorgungsmap() in assets/js/custom.js.

   Not nested under a body.page-template-* selector, for the same reason .file-field is not:
   both templates render the same snippets/map/show_map_admin.php and used to carry a byte
   identical <style> block of their own, so this is one building block rather than two page
   styles. The rest came from the style attributes of that snippet. */

/* The panel gives the map its full width - the map draws its own frame. */
.map-content {
  padding-top: 0;
  padding-left: 0;
  padding-right: 0;
}

/* Positioned, so the loading overlay below can fill it. The z-index was carried inline and is
   kept: it lifts the map above the panel it sits in. */
#map-canvas {
  position: relative;
  z-index: 25;
  width: 100%;
  height: 600px;
}

/* Covers the map until the markers are in. Hidden by the script once every request is done. */
#map-loading-overlay {
  position: absolute;
  inset: 0;
  z-index: 9999;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.9);
}

.map-loading-box {
  text-align: center;
}

.map-loading-title {
  margin: 0;
  color: #333;
  font-size: 16px;
}

.map-loading-hint {
  margin: 5px 0 0;
  color: #666;
  font-size: 14px;
}

.map-spinner {
  width: 50px;
  height: 50px;
  margin: 0 auto 20px;
  border: 4px solid #f3f3f3;
  border-top: 4px solid #3498db;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

/* The bubble a group of markers collapses into. Leaflet wraps the icon in a div of its own,
   which brings a background and a border along - both are in the way of the image below. */
.custom-cluster-icon {
  background: transparent !important;
  border: none !important;
}

/* The badge itself. Everything static lives here now; the script only sets the two values that
   actually vary - the image and the colour of the count, see mein_map_markers(). They used to
   be written into a style attribute together with all of the below, once per template. */
.custom-cluster-icon .map-cluster-badge {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 50px;
  height: 50px;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  font-family: "comic sans ms";
  font-size: 16px;
  font-weight: bold;
}

.leaflet-popup-content-wrapper {
  border-radius: 8px;
}

.leaflet-popup-content {
  margin: 10px 15px;
  font-size: 16px;
  line-height: 1.4;
}

/* The "Adresse suchen" box in the top right corner of both maps, added by addMapGeocoder()
   in assets/js/custom.js. Three stylesheets meet on it: leaflet's own, the plugin's
   (assets/js/leaflet-control-geocoder/dist/Control.Geocoder.css) and legacy-style.css, whose
   bare button rule makes a portal button out of the magnifier - 162px wide, padded and bold.
   Only the shape of that is taken back below, the main colour stays; .file-field-remove above
   undoes the whole of it. Both library stylesheets are enqueued ahead of this file, see
   projekt_scripts_styles(), so none of the rules below has to reach for !important. */
.leaflet-control-geocoder {
  /* The box open is the magnifier plus this; the field takes what the magnifier leaves and the
     hits below take the whole width. One value keeps the three in step, the media queries at
     the end of this file narrow it for small screens. */
  --geocoder-field-width: 260px;
  --geocoder-icon-size: 40px;

  /* Magnifier and field in one row, the hits below it: the flex-basis of 100% forces the wrap. */
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  /* Clips the result list into the rounded corners, so the last hit needs no corner rule of
     its own. */
  overflow: hidden;

  /* The frame. On a touch capable browser - which windows reports here as well - leaflet
     draws its controls with 2px of translucent black and clips their background to the
     padding box, so the map shows through the rounded corners as pale gaps. That rule reads
     .leaflet-touch .leaflet-bar, hence the .leaflet-bar here: it takes the same two classes
     and comes later. A solid hairline instead, with the background under it and the drop
     shadow leaflet gives a control everywhere else. */
  &.leaflet-bar {
    border: 1px solid #d5d5d5;
    border-radius: 6px;
    background-clip: border-box;
    box-shadow: 0 1px 5px rgba(0, 0, 0, 0.4);
  }
  /* Without this the box stays on leaflet's Helvetica while the portal reads Noto Sans. */
  font-family: var(--primary-font), "Noto Sans", sans-serif;

  /* Open - with the field, with a list of hits or with both - the box is as wide as its row.
     Spelled out rather than left to the content: a wrapping flex container takes its intrinsic
     width from all of its items in one line, so the box would end up as wide as the row plus
     the list below it. Closed there is nothing but the magnifier, and it shrinks back to that. */
  &.leaflet-control-geocoder-expanded,
  &.leaflet-control-geocoder-options-open {
    width: calc(var(--geocoder-icon-size) + var(--geocoder-field-width));
  }

  /* The magnifier keeps the main colour the bare button rule of legacy-style.css gives every
     button of the portal - what goes is the 162px min-width of a portal button, which blew
     the map control up into a bar. */
  & .leaflet-control-geocoder-icon {
    width: var(--geocoder-icon-size);
    height: var(--geocoder-icon-size);
    min-width: 0;
    padding: 0;
    /* Square: the corner comes from the box clipping it, and a rounded button inside a rounded
       box leaves a white sliver between the two curves. */
    border-radius: 0;
    background-color: var(--primary-color);
    /* The plugin ships an svg without a size of its own, which would grow to the whole box. */
    background-size: 24px 24px;
    font-weight: normal;

    /* The colour stays, only a shade darker - the drop shadow of a portal button would sit
       inside the box and read as a smudge. */
    &:hover,
    &:focus {
      background-color: var(--primary-color);
      box-shadow: none;
      filter: brightness(0.95);
    }
  }

  /* Takes whatever the magnifier leaves of the row, rather than carrying a width of its own.
     From zero up, not from the width of the field inside it: the 2px frame of .leaflet-bar
     comes off the inside of the box, and a field measured on its own content is those two
     pixels too wide - it would drop onto a line of its own, below the magnifier. */
  & .leaflet-control-geocoder-form {
    flex: 1 1 0;
    min-width: 0;
  }

  /* The field had neither a height nor a padding: the text sat straight against the icon and
     off the vertical centre of the box. display: block takes the descender space out of the
     line box, which would otherwise make the row taller than the field. */
  & .leaflet-control-geocoder-form input {
    display: block;
    width: 100%;
    height: var(--geocoder-icon-size);
    padding: 0 12px 0 4px;
    color: #4E4E4E;
    font-family: inherit;
    /* The plugin's 120% of leaflet's 12px came out at 14px next to a portal reading at 20px. */
    font-size: 18px;
    line-height: var(--geocoder-icon-size);

    &::placeholder {
      color: #999;
      opacity: 1;
    }
  }

  /* The whole box answers the focus of the field inside it - on the frame it already has,
     rather than with a second ring around it. */
  &:focus-within {
    border-color: #8a8a8a;
  }

  /* The hits: 12px next to a portal reading at 20px, held at a fixed 272px and cut off at the
     end of the first line - a long address lost its town that way. */
  & .leaflet-control-geocoder-alternatives {
    flex: 0 0 100%;
    /* The list sits inside the panel's .content, where legacy-style.css indents every ul by
       30px - which pushed the hits away from the field above them. */
    padding-left: 0;
    /* A long list scrolls instead of running across half of the map. */
    max-height: 260px;
    overflow-y: auto;
    border-top: 1px solid #e5e5e5;

    & li {
      padding: 10px 14px;
      border-bottom-color: #eee;
      white-space: normal;
      font-size: 17px;
      line-height: 1.35;

      /* Deliberately a neutral grey rather than --primary-color: the state has to read the
         same in every corporate design, the way the upload field above has it. */
      &:hover,
      &.leaflet-control-geocoder-selected {
        background-color: #f2f4f7;
      }
    }

    & li a {
      display: block;
      color: #4E4E4E;
      text-decoration: none;
    }

    /* Street and house number first, the rest of the address smaller and grey below it. */
    & .leaflet-control-geocoder-address-context {
      display: block;
      color: #767676;
      font-size: 15px;
    }
  }

  /* The message for a search that found nothing. The plugin puts it on margins of its own;
     here it lines up with the hits above it. */
  & .leaflet-control-geocoder-error {
    flex: 0 0 100%;
    margin: 0;
    padding: 10px 14px;
    border-top: 1px solid #e5e5e5;
    color: #767676;
    font-size: 16px;
  }
}

/* =========================================================
   HEADER, FOOTER
========================================================= */

/* The header used to be a bootstrap grid row of floated columns, and the logo had no size
   of its own: it filled whatever its column left over. That column goes from col-md-2 to
   col-xs-4 at 992px, so the logo tripled in size exactly where the screen gets smaller
   (245px wide at 976px against 86px at 995px), and a legacy rule shrank it to 28px below
   481px. It is a flex row now, and the logo is sized by --header-logo-height. Everything
   here was moved out of legacy-style.css; the float declarations are the only thing that
   did not come along. */
header {
  position: relative;
  z-index: 99;
  padding-top: 15px;
  padding-bottom: 0;
  background-color: #FFF;
  background-repeat: no-repeat;
  font-size: 18px;

  & a {
    margin-left: 10px;
    font-weight: bold;
  }
}

/* The padding is the 15px gutter the .container-fluid around this used to bring. That class
   is gone: its clearfix ::before/::after become flex items here, and the first of them ate a
   whole gap in front of the logo. A clearfix has nothing left to clear anyway. */
.header-bar {
  display: flex;
  align-items: flex-start;
  gap: 15px;
  padding: 0 15px;
}

/* The 50px the old .navbar-brand carried plus the 15px gutter of the dropped grid column,
   so the logo keeps the exact position it had on the desktop. */
.header-logo {
  flex: 0 0 auto;
  margin-left: 65px;
  margin-bottom: 25px;

  /* Both axes auto with a max on each: the browser scales the image down to fit whichever
     limit binds first and keeps the aspect ratio. A logo smaller than the limit is left at
     its own size rather than blown up. */
  & img {
    display: block;
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: var(--header-logo-height);
  }
}

.header-actions {
  flex: 1 1 auto;
  min-width: 0;
}

.user-info {
  font-size: 14px;
  text-align: right;
}

.custom_nav {
  padding-top: 30px;

  /* The menu sits at the right edge of the bar. It got there through float: right on the
     list, which is what right aligns a shrink to fit box in a float layout; justify-content
     is the flex equivalent. float: none takes the list and its items out of bootstrap's
     floated navbar layout - assets/bootstrap-3/ is vendor code we do not edit, so this is
     the only way to drop those two floats. */
  & ul {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    float: none;
    margin: 0;
  }

  & ul li {
    display: flex;
    float: none;
    border-right: 1px solid #4E4E4E;
  }

  & ul li:last-child {
    border: none;
  }

  & ul li:last-child a {
    margin-right: 0;
    padding-right: 0;
  }

  & ul li a {
    margin-left: 0;
    padding: 0 10px;
    font-size: 17px;
    font-weight: bold;
  }

  & ul li a:focus {
    background-color: transparent;
  }

  & ul li a:hover,
  & ul li.current-menu-item a {
    background-color: transparent;
    color: var(--primary-color);
  }
}

/* Hidden until the tablet breakpoint at the end of this file swaps the two navigations. */
.responsive-nav-button {
  display: none;
  flex: 0 0 auto;
  padding: 2px 5px;
  border: 2px solid var(--primary-color);
  border-radius: 4px;
  color: var(--primary-color);
  cursor: pointer;
}

/* The off canvas navigation, slid in by toggleNav() in assets/js/custom.js. */
.responsive-nav {
  display: none;
  position: fixed;
  top: 0;
  right: -100%;
  width: 100%;
  height: 100%;
  background-color: var(--primary-color);
  text-align: center;
  transition: right 0.5s ease-out;

  &.open {
    right: 0;
  }

  /* Same wp_nav_menu() output as .custom_nav above, so bootstrap floats this list and its
     items too - they stack here and the float only ever got in the way. */
  & ul {
    float: none;
    width: 100%;
    margin: 0;
    padding-top: 30px;
  }

  & li {
    float: none;
    width: 100%;
  }

  & li a {
    color: #FFF;
  }

  & li a:hover {
    background-color: transparent;
    color: #FFF;
  }

  /* Was float: right. The icon inside is inline, so aligning the text does the same job. */
  & .closelink {
    margin-top: 15px;
    margin-right: 15px;
    color: #FFF;
    text-align: right;
    cursor: pointer;
  }
}

footer {

}

/* =========================================================
   PAGE TYPES (page.php, single.php, archive.php, etc.)
========================================================= */

/* =========================================================
   TEMPLATES (template-*.php)
========================================================= */

/* template_backend_rundmail.php

   The module used to be laid out entirely by floats - the bootstrap grid, .new-button,
   .recipients-overlay .button.choose, .edit-button and .show_all .button. All of it is flex
   and grid now, and the rules that were only ever used here moved out of legacy-style.css into
   this block. What stayed behind there are the two global floats that reach in from outside
   and are taken back at the top: .content and .big-panel hr. */
body.page-template-template_backend_rundmail {

  /* Both are full width blocks; the float they carry from legacy-style.css does nothing but
     leave floats in a module that is meant to have none. */
  & .big-panel > .content,
  & .big-panel hr {
    float: none;
  }

  /* Heading and the buttons beside it - formerly a .row with a col-lg-8 and a nested row of
     two col-lg-6, each holding a .new-button floated to the right. */
  & .rundmail-header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 15px;
  }

  & .rundmail-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 30px;
  }

  /* The submit row of both forms. legacy-style.css floats every .button inside a .show_all
     panel to the left and takes that back for .create-form .button.red only - a class these
     buttons do not carry, the same reason verbandsbuch and verbesserungsmanagement carry a
     block like this one. */
  & .form-actions {
    display: flex;
    justify-content: flex-end;
  }

  & .rundmail-header .button,
  & .form-actions .button,
  & .rundmail-overlay-actions .button,
  & .rundmail-overlay-footer .button {
    float: none;
    margin-bottom: 0;
  }

  /* The dropdown stood in a col-md-3 of a .row: a quarter of a row that was 30px wider than
     this box, minus the 30px of column padding. The two <br> that followed it are the margin. */
  & .rundmail-template-select {
    margin-bottom: 30px;

    & .choose-vorlage {
      width: calc(25% - 22.5px);
    }
  }

  /* Two <br> used to stand between the checkbox above and this one. */
  & .rundmail-testmail {
    margin-top: 57px;
  }

  /* The last floats of the module, out of the global input[type="checkbox"] rule of
     legacy-style.css. Both boxes are followed by their own caption, so they sit in the line
     rather than beside it - the margin-top the float needed goes with it. */
  & .text-check {
    float: none;
    margin-top: 0;
    vertical-align: middle;
  }

  & .mail-box .title {
    padding-top: 15px;
  }

  /* The heading of one Textvorlage and the pencil that edits it. .edit-button used to float the
     pencil right and pull it back up into the heading with a negative margin; a flex row puts
     it there without either. */
  & .textvorlage-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 15px;
  }

  & .textvorlage-edit {
    flex: 0 0 auto;
    color: var(--secondary-button-background-color, #5B977B);
    font-size: 24px;
  }

  /* --- The recipient overlay, formerly .recipients-overlay in legacy-style.css --- */

  & .recipients-overlay {
    display: none;
    position: fixed;
    top: 150px;
    left: 0;
    right: 0;
    z-index: 100;
    width: 1020px;
    max-width: 100%;
    height: 600px;
    max-height: 100%;
    margin: auto;
    padding: 20px;
    border: 1px solid #000;
    background-color: #FFF;
    box-shadow: 0 3px 6px #999999;
    overflow-y: scroll;

    & .close-button {
      position: absolute;
      top: 0;
      right: 20px;
    }

    & .letter {
      margin-top: 19px;
      margin-bottom: -10px;
    }

    & input {
      cursor: pointer;
    }
  }

  /* Holds the absolutely positioned close button off the group of buttons below it, and reaches
     as far out as the recipient rows do - that is what the close button is placed against. */
  & .rundmail-overlay-header {
    position: relative;
    bottom: 0;
    height: 20px;
    margin: 0 -15px 16px;
  }

  /* One group per line, four to a line - the columns the buttons stood in. Kept as separate
     groups rather than one flowing row because that is what they are: apply and discard,
     the subsets, the sites of the network. In one row the last button of a group would slide
     up into the free slot of the group above it. */
  & .rundmail-overlay-actions {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    column-gap: 30px;
    row-gap: 15px;
    /* Padding, not margin: the first letter below the last group carries a margin-top of its
       own, and two margins would collapse into one where the two boxes used to keep both. */
    padding-bottom: 15px;
  }

  /* The rows reach 15px further out than the text above them, the way the negative margin of
     their .row did - that is where the separator lines get their length from. */
  & .rundmail-recipient {
    display: flex;
    align-items: center;
    margin: 0 -15px;
    border-bottom: 1px solid var(--primary-color);

    & .rundmail-recipient-name {
      flex: 0 0 83.3333%;
      padding-left: 60px;
    }

    & input[type="checkbox"] {
      float: none;
      flex: 0 0 auto;
      margin: 0 10px 0 15px;
    }
  }

  /* The second "Übernehmen", at the end of a list several hundred rows long. It stood in a
     col-lg-11 and left the twelfth column empty beside it. */
  & .rundmail-overlay-footer {
    display: flex;
    justify-content: flex-end;
    padding-right: 8.3333%;
    margin-bottom: 15px;
  }
}

/* template_backend_termine.php */
body.page-template-template_backend_termine {

  & .termin-date-administration {
    font-size: 24px;
  }

  & .termin-date-mitarbeiter {
    font-size: 23px;
  }

  & .termin-timestamp {
    display: none;
  }

  & .termin-link {
    text-decoration: underline;
  }

  & .profile_image_termine {
    width: 1em;
    height: 1em;
    object-fit: cover;
    vertical-align: text-bottom;
  }

  & .termin-certificate-success {
    margin-bottom: 30px;
    padding: 0 30px 30px;
  }

  & .termin-certificate-submit {
    margin-left: 5px;
  }

  /* Was a pair of bootstrap columns (col-lg-9 / col-lg-3) with the button floated right.
     The flex-basis values are the widths those columns had at every breakpoint; the
     button keeps its natural width and is pushed to the right edge by the free space. */
  & .create-form .teilnehmerselect {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    float: none; /* legacy-style.css floats the row */
  }

  & .create-form .teilnehmerselect select {
    flex: 0 1 75%;
    max-width: 400px; /* was a style attribute on the select */
  }

  /* width, because legacy-style.css hands the button a width of 100% below 1200px - it
     used to mean "fill the 25% column" and would mean "fill the whole row" here. The
     width it gets instead comes from the media queries at the end of this file. */
  & .create-form .teilnehmerselect .button.cancel {
    flex: 0 0 auto;
    width: auto;
  }

  /* Was a style attribute on the button. Applies to the certificate dialog of the
     overview as well, which carries the same values inline. */
  & .add-teilnehmer {
    margin-top: 10px;
    margin-bottom: 50px;
  }
}

/* template_startseite.php */
body.page-template-template_startseite {

  /* Same size as the login messages beside it, which still carry it as a style attribute. */
  & .login-notice {
    font-size: 15pt;
  }

  & input#user_pass {
    text-security: disc;
    -webkit-text-security: disc;
    -mox-text-security: disc; /* typo kept as in original */
  }

  & .startseite-logo-wrap {
    display: flex;
    justify-content: center;
    width: 100%;
    margin-bottom: 15px;

    /* Was a style attribute on each of the two img tags, one value per hard coded file.
       The logos come from the settings now, so the cap belongs to the panel: the second
       one is shown at half the width of the first, as it always was. */
    & img {
      max-width: 200px;
    }

    &.is-small img {
      max-width: 100px;
    }
  }

  & .startseite-col-spacing {
    margin-top: 30px;
  }
}

/* template_forgotpassword.php */
body.page-template-template_forgotpassword {

  /* Was float: left - nothing has ever stood beside the column, so a plain block
     box lays it out the same way. */
  & #wp_pass_reset {
    width: 50%;
    padding-top: 30px;

    & input[type="text"] {
      width: 100%;
      text-align: center;
    }

    & input.button {
      margin-top: 15px;
      padding-top: 6px;
      padding-bottom: 6px;
    }
  }

  /* The login link sits left of the submit button, which comes first in the
     markup so tabbing still reaches it first - hence the reversed row. The
     items keep their own margins, which is where their 10px offset comes from. */
  & .password-reset-actions {
    display: flex;
    flex-direction: row-reverse;
    justify-content: space-between;
    align-items: flex-start;
  }

  /* inline-block, because the vertical margin used to come from the float. The
     link also shows up on its own, outside the flex row above. */
  & .back-to-login {
    display: inline-block;
    font-size: 16px;
    margin-top: 25px;
  }
}

/* template_backend_news.php */
body.page-template-template_backend_news {

  /* Everything below was a style attribute in snippets/news/show.php. */

  & .news-heading {
    padding-bottom: 10px;
  }

  /* The detail view pads its panel the way an untabled one is padded. The full class
     chain is needed to out-specify .big-panel > .content.table in legacy-style.css,
     which pulls the horizontal padding down to 15px. The gap sets the media block and
     the extra file apart. */
  & .big-panel > .content.news-detail {
    display: flex;
    flex-direction: column;
    gap: 30px;
    padding-left: 50px;
    padding-right: 50px;
  }

  /* Media beside text. Both halves get their width from legacy-style.css, which sets
     them to 50% and stacks them below 992px. */
  & .newscontent {
    display: flex;
  }

  & .news-left img {
    width: 100%;
    max-width: 100%;
    height: auto;
  }

  & .extra-file-download {
    margin: 20px 0;
    padding: 15px;
    background: #f8f9fa;
    border-radius: 4px;

    & h4 {
      margin-top: 0;
    }
  }

  & .download-link {
    display: inline-block;
    padding: 8px 12px;
    border: 1px solid #0073aa;
    border-radius: 3px;
    color: #0073aa;
    text-decoration: none;
  }

  & .news-error {
    margin: 20px 0;
    padding: 20px;
    background: #f8d7da;
    border-radius: 4px;
    color: #721c24;
  }

  /* Everything below was a <style> tag at the end of snippets/news/edit.php. The rules
     for the upload box are gone with it: the shared field brings its own, see .file-field
     above. */

  & .form-required-field {
    color: #d93025;
    font-weight: bold;
  }

  & .form-actions {
    margin-top: 30px;
    padding-top: 20px;
    border-top: 1px solid #eee;

    /* legacy-style.css only hands these links inline-block through .create-form .button.red,
       which they no longer carry. Without it the min-width of 162px every button gets would
       not apply - min-width has no effect on a non-replaced inline element - and the links
       would shrink to the width of their label while the submit button kept its width. */
    & .button {
      display: inline-block;
    }
  }

  /* Was written without a scope in the <style> tag and therefore hit every input on the
     page, the search field of the overview included. */
  & .news-edit-form {

    & input[type="text"] {
      width: 100%;
      padding: 8px 12px;
      border: 1px solid #ddd;
      border-radius: 4px;

      &:focus {
        border-color: #007cba;
        outline: none;
        box-shadow: 0 0 5px rgba(0, 124, 186, 0.3);
      }
    }
  }

  /* The action column of both overviews. The buttons used to stick out of it: the column
     is 143px wide, while "button" in legacy-style.css hands every button a min-width of
     162px - and .show_all .button floats them left, into a column that is meant to be
     right aligned.

     They fill the column now, capped at the 162px they had before, so they keep their
     familiar size wherever there is room and only shrink in the narrow lg column. Their
     longest label, "Beitrag Ansehen", needs 127px - which is why the column itself grows
     below 1200px, see the col-md-3 in snippets/news/show_all_admin.php. */
  & .news-actions {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 10px;

    & .button {
      float: none;
      min-width: 0;
      width: 100%;
      max-width: 162px;
      margin-bottom: 0;
    }
  }
}

/* template_backend_mitarbeiter.php */
body.page-template-template_backend_mitarbeiter {

  /* The three button rows above the overview, formerly style attributes in
     snippets/mitarbeiter/show.php. */
  & .mitarbeiter-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    justify-content: flex-end;
    align-items: center;
  }

  /* The rows below the first one carried their spacing inline as well. */
  & .mitarbeiter-actions + .mitarbeiter-actions {
    margin-top: 8px;
  }

  & .mitarbeiter-actions:last-child {
    margin-bottom: 15px;
  }

  & .mitarbeiter-export-form {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 0;

    & select {
      height: 35px;
      min-width: 140px;
    }
  }

  /* Reminder in the employee form whose window has opened. Was a style attribute
     built in php in snippets/mitarbeiter/edit.php. */
  & .custom-panel .title.is-due {
    color: red;
  }

  /* The Elternzeit checkbox shares its row with the two datepickers, whose inputs
     fill the panel - the label lines the box up with them instead of letting it sit
     on the baseline of the text. */
  & .custom-panel .content .checkbox-label {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    font-weight: normal;

    & input[type="checkbox"] {
      width: auto;
      margin: 0;
    }
  }

  /* The "Medizinprodukt hinzufügen" button below the list of einweisungen. Was bootstrap's
     .pull-left on the button; a flex container leaves it at its own width on the left edge
     without one. Same solution as .kinder-add-row and .medizinprodukt-add-row above. */
  & .mitarbeiter-add-row {
    display: flex;
  }

  /* The row of actions closing the form. legacy-style.css only hands these links inline-block
     through .create-form .button.red, which they no longer carry. Without it the min-width of
     162px every button gets would not apply - min-width has no effect on a non-replaced inline
     element - and the links would shrink to the width of their label while the submit button
     kept its width. Same rule as in the kinder and eakonzept blocks. */
  & .form-actions .button {
    display: inline-block;
  }
}

/* template_backend_dokumente.php */
body.page-template-template_backend_dokumente {

  /* Everything below was a style attribute in snippets/dokumente/show.php. */

  & .dokument-heading {
    padding-bottom: 10px;
  }

  /* The detail view pads its panel the way an untabled one is padded. The full class
     chain is needed to out-specify .big-panel > .content.table in legacy-style.css,
     which pulls the horizontal padding down to 15px. Same as .news-detail above. */
  & .big-panel > .content.dokument-detail {
    padding-left: 50px;
    padding-right: 50px;
  }

  /* Was float: left with width: 100% - a plain block box lays it out the same way,
     it is the only child of a full width parent and nothing stands beside it. */
  & .dokument-file {
    padding-bottom: 30px;
  }

  & .dokument-frame {
    width: 100%;
    height: 900px;
    border: none;
  }

  /* Was float: left, which made the image a block box at its natural size. display:
     block keeps exactly that, without the baseline gap an inline image would leave
     underneath it. */
  & .dokument-image {
    display: block;
    width: auto;
  }

  /* The row of actions closing the form. legacy-style.css only hands these links inline-block
     through .create-form .button.red, which they no longer carry. Without it the min-width of
     162px every button gets would not apply - min-width has no effect on a non-replaced inline
     element - and the links would shrink to the width of their label while the submit button
     kept its width. Same rule as in the mitarbeiter and news blocks. */
  & .form-actions .button {
    display: inline-block;
  }
}

/* template_backend_kinder.php */
body.page-template-template_backend_kinder {

  /* Everything below was a style attribute in the snippets of the kinder module. */

  /* The print link above the form. Was float: right on an inline anchor around a block
     button, which text-align alone could not have pushed over. */
  & .kinder-print {
    display: flex;
    justify-content: flex-end;
  }

  /* A row of upload fields standing side by side - the two "Dienstplan" fields of the
     Notfallblatt, the three "Protokolle Fallbesprechungen" of the news. They used to be
     .file-upload-box, which legacy-style.css floats; the shared .file-field is not
     floated, so the row arranges them itself. */
  & .kinder-file-row {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;

    & .file-field {
      flex: 0 1 320px;
    }
  }

  /* The lines of one repeatable entry - place, contact person. The first one sits
     right below the heading of its entry and keeps its distance from the wrapper. */
  & .kinder-entry-row + .kinder-entry-row {
    margin-top: 15px;
  }

  /* The "… hinzufügen" button below a list of entries. Was a margin-top plus bootstrap's
     .pull-left on the button; a flex container leaves it at its own width without one. */
  & .kinder-add-row {
    display: flex;
    margin-top: 50px;
  }

  /* Write access checkbox and its caption on one line. Was float: left on the checkbox,
     with the caption running around it. */
  & .kinder-rechte-label {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    font-weight: normal;

    & input[type="checkbox"] {
      width: auto;
      margin: 0;
    }
  }

  /* An answer of the AEDL questions, so its wording selects the button in front of it and
     not only the button itself. The caption used to be a bare text node next to the input.
     Deliberately not the flex layout of .kinder-rechte-label above: these stay on the text
     baseline, and the 10px gap keeps coming from .create-form input[type="radio"] in
     legacy-style.css. Only bootstrap's bold label and its bottom margin are undone -
     .create-form label already carries the pointer. */
  & .kinder-radio-label {
    margin: 0;
    font-weight: normal;
  }

  /* The free text of the allergy and directive questions, shown only for the answer it
     belongs to. Hidden through the hidden attribute now, see initKinderFields() in
     assets/js/custom.js. */
  & .kinder-conditional-text {
    margin-top: 15px;
  }

  /* The ablaufplan, the pflegeplanung and the medizinprodukte sheet each hold a single
     .bereich, so it needs no closing line - .bereich in legacy-style.css draws one on
     every block. */
  & .ablaufplan-bereich,
  & .medizinprodukte-bereich {
    border-bottom: 0;
  }

  /* "Neue Aufgabe", "Neue Zeile" and "Neues Medizinprodukt" sit to the right above their
     list of rows. Was bootstrap's .pull-right on the button; a flex container puts it in
     the same place without a float - the same solution as .kinder-print above. */
  & .ablaufplan-add-row,
  & .medizinprodukte-add-row {
    display: flex;
    justify-content: flex-end;
  }

  & .medizinprodukte-provider-heading {
    padding-right: 0;
    padding-left: 15px;
    font-size: 12px;
  }

  /* The two PDF links below the list used to be floated and spaced inline. */
  & .medizinprodukte-print-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: flex-start;
  }

  /* The monthly bezugspflege report. Everything below was a style attribute in
     snippets/kinder/edit-bezugspflege.php. */

  /* The note under the two free text questions. Kept at the plain keyword the style
     attribute used, so the colour stays the one it has always been. */
  & .bezugspflege-hint {
    color: red;
  }

  /* One material item: its caption on the left, the count field on the right, both on
     the same line even when the caption wraps. Used to be float: left with width: 100%
     on the wrapper and the field floated right, where a caption that filled the row
     pushed the field onto the next line - the two columns drifted apart from the third
     item onwards. The bottom margin replaces the <br /> that closed each item. */
  & .bezugspflege-material-item {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 8px;
    font-weight: normal;
  }

  /* width, because .create-form input in legacy-style.css sets every field to 100% -
     the 80px used to come from the style attribute that also floated it. flex-basis
     alone would not beat that rule, the shorthand's own width does. */
  & .bezugspflege-material-item input[type="text"] {
    flex: 0 0 80px;
    width: 80px;
  }

  /* The reprint list stacks .kinder-rechte-label rows, which carry no margin of their
     own - the spacing used to come from the <br /> closing each line. */
  & .bezugspflege-check-item + .bezugspflege-check-item {
    margin-top: 8px;
  }

  & .bezugspflege-sonstiges {
    margin-top: 30px;
  }

  & .bezugspflege-subheading {
    padding-top: 30px;
  }

  /* The five read only "Datum letzte Aktualisierung" rows close the sheet as one block,
     so only the last of them may draw a line - .bereich in legacy-style.css draws one
     under every block. */
  & .bezugspflege-stand {
    border-bottom: 0;
  }

  /* The row of actions closing the form. */
  & .form-actions {
    padding-top: 30px;

    /* legacy-style.css only hands these links inline-block through .create-form .button.red,
       which they no longer carry. Without it the min-width of 162px every button gets would
       not apply - min-width has no effect on a non-replaced inline element - and the links
       would shrink to the width of their label while the submit button kept its width. */
    & .button-wrapper .button {
      display: inline-block;
    }
  }
}

/* template_backend_eakonzept.php */
body.page-template-template_backend_eakonzept {

  /* The section the "Einstellungsgespräch bereits erfolgt" checkbox folds away. The snippet
     wrote a style="display: none;" onto the div; the hidden attribute carries that state now,
     so initEakonzeptInterview() can toggle it without a reload. Bootstrap sets display on
     enough of what may sit in here that the attribute needs the help. */
  & .interview-wrap[hidden] {
    display: none;
  }

  /* The row of actions closing the form. */
  & .form-actions {

    /* legacy-style.css only hands the cancel link inline-block through
       .create-form .button.red, which it no longer carries. Without it the min-width of 162px
       every button gets would not apply and the link would shrink to the width of its label.
       Same rule as in the kinder block above. */
    & .button {
      display: inline-block;
    }
  }
}

/* template_backend_medizinprodukte.php */
body.page-template-template_backend_medizinprodukte {

  /* The register is one long list inside the form rather than a panel of its own. Was
     style="min-height:0;box-shadow:none;" on the .big-panel. */
  & .big-panel.show_all {
    min-height: 0;
    box-shadow: none;
  }

  /* The two export links above the list. They were inline-blocks separated by the
     whitespace between the tags, which is where the 6px gap comes from; .export_button in
     legacy-style.css pushed them right through margin-left: auto, which a flex row does
     without a margin that would also separate the two. */
  & .medizinprodukt-export-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    justify-content: flex-end;
  }

  /* "Neues Medizinprodukt" sits to the right above the list. Was bootstrap's .pull-right
     on the button - the same solution as .kinder-print in the kinder block above. */
  & .medizinprodukt-add-row {
    display: flex;
    justify-content: flex-end;
  }

  /* The four columns of one row. Was a <div style="float:left;width:100%"> whose only job
     was to contain the floated grid columns inside it; the flex row does that, and the
     columns keep the widths and the wrapping their classes give them. */
  & .medizinprodukt-row {
    display: flex;
    flex-wrap: wrap;
  }

  /* The three fields of a row carry no box of their own and come out at the browser's
     defaults, which differ per element: an input measures 34.56px - one line-height plus
     1px of padding and 2px of border on each side - while a select has neither padding
     nor the second border pixel and stops at 29px. One height for all of them puts the
     "Art/Typ" column back on the line of the two beside it. */
  & .medizinprodukt-row input[type="text"],
  & .medizinprodukt-row select {
    height: 35px;
  }

  /* The action column: the "!" badge, the expander, the trash icon. All three were floated
     - the first two left, the last one right - which is what the gap and the auto margin
     replace. */
  & .medizinprodukt-actions {
    display: flex;
    align-items: flex-start;
    gap: 5px;
  }

  /* Moved here from legacy-style.css together with the rules below: both classes only ever
     appeared in snippets/medizinprodukte/. The !important widths came along, they beat
     .create-form input in legacy-style.css, which sets every field to 100%. */
  & .changeEinweisung,
  & .toggleEinweisung {
    width: 30px !important;
    height: 30px !important;
    border: 2px solid #707070;
    border-radius: 18px;
    color: #707070;
    opacity: 1;
    text-align: center;
    cursor: pointer;
  }

  /* Red marks a device an einweisung is required for. Deliberately the plain colour it has
     always been rather than a theme variable - it reads as a warning, not as branding. */
  & .changeEinweisung:hover,
  & .changeEinweisung.active {
    border: 2px solid white;
    background-color: #D10000;
    color: white;
  }

  /* The chevron points down while the einweisungen are folded away and turns over when they
     open. Driven by the "collapsed" class rather than by aria-expanded: bootstrap 3 keeps
     that class in step with the panel but leaves the attribute at the value the markup
     rendered. The row starts out carrying it, see snippets/medizinprodukte/row.php. */
  & .toggleEinweisung .glyphicon {
    transition: transform 0.3s ease;
  }

  & .toggleEinweisung:not(.collapsed) .glyphicon {
    transform: rotate(180deg);
  }

  & .medizinprodukt-actions .delete-me-element {
    /* Was float: right. */
    margin-left: auto;
    margin-top: 2px;
    font-size: 27px;
  }

  /* The employees registered on one device, folded away behind the expander. Bootstrap
     hides .collapse and shows it as a block; the flex row is what contains the grid columns
     inside it, the way the float: left of the former style attribute did - without it the
     row's closing line would ride up over them. */
  & .medizinprodukt-einweisungen.in {
    display: flex;
    flex-wrap: wrap;
  }

  /* Was <br /><b>Einweisung fehlt für:</b><br /><br /> - the padding is the empty line
     above and below it, one line-height each. */
  & .medizinprodukt-einweisungen-title {
    flex: 0 0 100%;
    margin: 0;
    padding: 1.42857em 15px;
    font-weight: bold;
  }

  /* One employee's state. Both the link and the static badge used to be floated and closed
     by two <br />, which the padding below replaces; a flex item takes the width of its
     content, which is what the style attributes asked for with width: auto. */
  & .medizinprodukt-einweisung-status {
    display: flex;
    align-items: flex-start;
    padding-bottom: 27px;

    /* .show_all .button in legacy-style.css floats these and sets them off by 10px; the
       row lays them out instead, and the padding above carries the spacing. */
    & .button {
      margin-bottom: 0;
    }
  }

  /* An einweisung that has already been given is a state, not a button. */
  & .medizinprodukt-einweisung-done {
    cursor: default;
  }

  /* The row of actions closing the form, formerly style="padding-top:30px". The buttons
     were inline-blocks separated by the whitespace between the tags - the same 6px as the
     export links above. A flex row, because "Speichern" carries .button now and would
     otherwise be floated left by .show_all .button in legacy-style.css. */
  & .form-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    justify-content: flex-end;
    padding-top: 30px;
    padding-bottom: 10px;

    & .button {
      margin-bottom: 0;
    }
  }
}

/* template_backend_umfragen.php */
body.page-template-template_backend_umfragen {

  /* The action column of both overviews. The buttons used to stick out of it: legacy-style.css
     gives every button a min-width of 162px and .show_all .button floats them left, into a
     column that is meant to be right aligned - at sm they left the panel altogether.

     The column is wide enough for those 162px on every breakpoint now, see the grid classes in
     snippets/umfrage/show_all_admin.php and its counterpart for the employee. The flex column
     lays the buttons out instead of letting them float, and the cap keeps them at their familiar
     width where the column is wider - on xs above all, where it spans the whole card. Same
     solution as .news-actions above. */
  & .survey-actions {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 10px;

    & .button {
      float: none;
      min-width: 0;
      width: 100%;
      max-width: 162px;
      margin-bottom: 0;
    }
  }

  /* Was the text-right of the column: a flex item shrinks to its widest line, so the shorter
     second line of a date option needs the alignment of its own. */
  & .survey-result {
    text-align: right;
  }

  /* The "Neue Option" dialog of the survey form, hidden until the "+" tile opens it.
     Moved here from legacy-style.css together with the markup, which now only renders
     on the form. The vendor prefixed box-shadow twins are gone; every browser the
     portal runs on has had the unprefixed property for a decade. */
  & .new-date-overlay {
    display: none;
    position: fixed;
    top: 200px;
    right: 0;
    left: 0;
    width: 1020px;
    max-width: 100%;
    height: 500px;
    max-height: 100%;
    margin: auto;
    padding: 20px;
    background-color: #FFF;
    border: 1px solid #000;
    box-shadow: 0 3px 6px #999999;

    /* Formerly style="margin-top:20px;margin-bottom:20px" on the row. */
    & .art-select {
      margin: 20px 0;
    }

    /* The label replaces a bare "Art:" text node - bootstrap would print it bold and
       set it off by 5px, which is not what stood there. */
    & .art-select label {
      margin-bottom: 0;
      font-weight: normal;
    }

    /* Formerly style="display:none" on the row. The script switches the two
       .art-wrapper rows by setting an inline display, which outranks this. */
    & .text-wrapper {
      display: none;
    }

    /* Positioned absolutely, so the float legacy-style.css also set here never did
       anything. */
    & .button {
      position: absolute;
      right: 20px;
      bottom: 20px;
    }

    & .close-button {
      position: absolute;
      top: 20px;
      right: 20px;
    }
  }

  /* The option tiles of the survey form, moved here from legacy-style.css. They were the
     last float layout of this module, and nothing outside snippets/umfrage/edit.php and the
     rows appendSurveyOption() builds for it ever used these four class names.

     align-items is the one line that is not a straight translation: floats leave every tile
     at its natural height, while flex stretches a row to its tallest item - which the "+"
     tile with its 84px glyph would show immediately. The 19% + 1% keep five tiles per row,
     at every width; these rules never had a media query and still do not. */
  & .all_dates {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
  }

  & .datewrapper,
  & .more {
    flex: 0 0 19%;
    margin-right: 1%;
    background-color: #FFF;
    text-align: center;
  }

  & .datewrapper {
    position: relative;
    padding: 30px 15px;
    margin-bottom: 30px;
  }

  & .more {
    font-size: 84px;
    cursor: pointer;
  }

  /* The inputs of a tile are read, not typed in - only the date of a date option is visible
     at all. The width comes from .create-form input in legacy-style.css. */
  & .datewrapper input {
    cursor: default;
    border: none;
    text-align: center;
    font-size: 22px;
    padding: 0;
  }

  & .datewrapper .timeinfo {
    font-size: 16px;
    margin-top: 30px;
  }

  /* Beats the .create-form .delete-self of legacy-style.css, which pulls the icon of the
     form rows out to the right - the same way the old .datewrapper .delete-self did by
     standing further down in that file. */
  & .datewrapper .delete-self {
    position: absolute;
    top: -5px;
    right: -5px;
    color: #D10000;
  }

  /* legacy-style.css only hands these links inline-block through .create-form .button.red,
     which they no longer carry. Without it the min-width of 162px every button gets would
     not apply - min-width has no effect on a non-replaced inline element - and the links
     would shrink to the width of their label while the submit button kept its width. */
  & .create-form .text-right .button {
    display: inline-block;
  }
}

/* template_backend_verbesserungsmanagement.php */
body.page-template-template_backend_verbesserungsmanagement {

  /* The form sits inside a .show_all panel, and legacy-style.css floats every .button in one
     of those to the left with 10px underneath it. It takes that back for
     .create-form .button.red only - a class the send button does not carry - so without this
     the button would leave its right aligned row the moment it became a semantic .button.
     The values are the ones it had while it wore no class at all. */
  & .create-form .text-right .button {
    float: none;
    display: inline-block;
    margin-bottom: 0;
  }

  /* Without a configured address the notice takes the place of the form, see
     snippets/verbesserungsmanagement/edit.php. It keeps the distance to the page text above
     that the form gets from its own margin, so the two do not end up stuck together. */
  & .form-notice {
    margin-top: 30px;
  }
}

/* template_backend_verbandsbuch.php */
body.page-template-template_backend_verbandsbuch {

  /* Same as the block above: the form sits inside a .show_all panel, where legacy-style.css
     floats every .button to the left with 10px underneath it and only takes that back for
     .create-form .button.red - a class the send button does not carry. Without this the
     button would leave its right aligned row the moment it became a semantic .button. The
     values are the ones it had while it wore no class at all. */
  & .create-form .text-right .button {
    float: none;
    display: inline-block;
    margin-bottom: 0;
  }

  /* Without a configured address the notice takes the place of the form, which is what
     otherwise brings the distance to the heading above along in its own padding. */
  & .form-notice {
    margin-top: 30px;
  }
}

/* template_backend_dashboard.php */
body.page-template-template_backend_dashboard {

  /* Everything the template styles sits inside its .container.dashboard, a class no other
     template carries. The rules stay nested under it: .content and .entry are names the page
     chrome uses as well - header.php wraps every page in a <section class="content"> - and
     that is what the .dashboard prefix kept them off in legacy-style.css. */
  & .dashboard {

    /* How overdue a date is, formerly a style attribute holding the colour keyword: the two
       panels at the top and the resuscitation panel below them. Exactly one of the three is
       set at a time, so nothing here depends on the order they stand in. The keywords are the
       ones the attributes used, down to is-current - the resuscitation line is really black,
       not the #4E4E4E the page inherits. */
    & .is-due {
      color: red;
    }

    & .is-due-soon {
      color: orange;
    }

    & .is-current {
      color: black;
    }

    /* That line used to sit in a <span> carrying this padding and a float, wrapped around the
       column below it - a block inside an inline element. The column carries it now. */
    & .reanimation-status {
      padding-top: 15px;
      padding-bottom: 15px;
    }

    /* The heading of a panel and the "Alle ..." link beside it. legacy-style.css floated the
       link right, in a rule that existed for this template alone. Aligned on the baseline,
       which is where the margin-top of 5px used to put the smaller text. */
    & .custom-panel > .title {
      display: flex;
      align-items: baseline;
      justify-content: space-between;
    }

    & .right-link {
      font-size: 14px;
      margin-right: 15px;
    }

    /* Was .dashboard .content, and takes back the 30px 70px that .custom-panel > .content
       gives every panel of the portal - here through specificity rather than through the
       load order it relied on before. */
    & .content {
      padding: 0 15px;
    }

    & .entry {
      border-bottom: 1px solid var(--primary-color);
      padding: 25px 50px;
      line-height: 20px;
    }

    & .entry:last-child {
      border-bottom: none;
    }

    /* The booking links of the Betriebsarzt panel, two to a line. */
    & .custom-panel ul {
      column-count: 2;
      padding-left: 0;
      list-style-type: none;

      & li {
        margin-bottom: 10px;

        & a {
          display: block;
          width: 100%;
        }

        &::marker {
          color: var(--primary-color);
        }
      }
    }

    /* News and Umfragen, the two panels of the bottom row, end up the same height. That used
       to be initDashboard() in assets/js/custom.js: it waited for the load event, because the
       news carry images, and then set the height of the taller .content on both. The columns
       keep the widths bootstrap gives them - a flex item ignores the float they carry. */
    & .dashboard-panels {
      display: flex;
      flex-wrap: wrap;
    }

    & .dashboard-panels > [class*="col-"] {
      display: flex;
    }

    /* legacy-style.css lays a panel out as an inline-block; as a flex column it needs the
       width of its column back. */
    & .dashboard-panels .custom-panel {
      display: flex;
      flex-direction: column;
      width: 100%;
    }

    & .dashboard-panels .custom-panel > .content {
      flex: 1;
    }
  }
}

/* =========================================================
   MODULES / PARTIALS / TEMPLATE PARTS
========================================================= */

/* =========================================================
   MODAL
========================================================= */

/* The medical device picker. The very same markup stands in
   snippets/kinder/edit-medizinprodukte.php and in snippets/mitarbeiter/edit.php, so it
   is styled once here rather than under either page - it used to be maintained twice,
   and the two copies had already drifted apart.

   Only two things belong in this block: what the style attributes of the two snippets
   used to do, and the colours that come out of the ACF button options. The modal frame,
   the list and their floats keep coming from legacy-style.css. */
#medizinprodukteModal {

  /* Legacy pulls the close button up by a negative margin and leaves it at bootstrap's
     opacity of .2, where it is barely visible. A flex header places it without the
     margin, and the button colours make it readable. */
  & .modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 15px;

    & .modal-title {
      flex: 1 1 auto;
    }

    & button.close {
      flex: 0 0 auto;
      min-width: 0;
      margin: 0;
      background-color: var(--primary-button-background-color, var(--primary-color));
      border-color: var(--primary-button-background-color, var(--primary-color));
      color: var(--primary-button-text-color, #FFFFFF);
      opacity: 1;
      text-shadow: none;
    }
  }

  /* The list sits inside a modal, so it drops the panel chrome .big-panel brings along
     in legacy-style.css. */
  & #show_all_medizin {
    min-height: 0;
    box-shadow: none;
    background-color: transparent;

    & .title,
    & .filter {
      background-color: transparent;
    }

    & .filter-item,
    & .filter-item2 {
      background-color: var(--primary-button-background-color, var(--primary-color));
      border-color: var(--primary-button-text-color, #FFFFFF) !important;
      color: var(--primary-button-text-color, #FFFFFF);
    }

    & input.search {
      background-color: var(--primary-button-background-color, var(--primary-color));
      color: var(--primary-button-text-color, #FFFFFF);

      /* Legacy paints the placeholder white through .filter ::placeholder while leaving
         the typed text black. Both follow the field now. */
      &::placeholder {
        color: inherit;
        opacity: 1;
      }
    }

    /* Everything else about a row is already set in legacy-style.css. Only the hover
       needs the text colour to go with the background it gets there. */
    & .medizinprodukt-item:hover {
      background-color: var(--primary-button-background-color, var(--primary-color));
      color: var(--primary-button-text-color, #FFFFFF);
    }
  }
}

/* =========================================================
   MEDIA QUERIES
========================================================= */

/* Large desktops */
@media (max-width: 1399.98px) {

  :root {
    --header-logo-height: 95px;
  }
}

/* Desktops / laptops */
@media (max-width: 1199.98px) {

  :root {
    --header-logo-height: 80px;
  }

  /* legacy-style.css lets the button fill its 25% column from here on down. Without
     that column the width has to come from the flex item itself, otherwise the button
     would stretch across the whole row. */
  body.page-template-template_backend_termine .create-form .teilnehmerselect .button.cancel {
    flex: 0 0 25%;
    min-width: 0;
  }
}

/* Tablets */
@media (max-width: 991.98px) {

  :root {
    --header-logo-height: 70px;
  }

  /* The button at the end of the recipient list took the full width of its row from here on
     down - it was a col-sm-12 below the col-lg-11 above. */
  body.page-template-template_backend_rundmail .rundmail-overlay-footer {
    padding-right: 0;
  }

  /* The burger takes over from the wide navigation. legacy-style.css swapped the two at
     max-width: 992px, which overlaps bootstrap's md by one pixel - at exactly 992px the
     theme showed the burger and the desktop menu at the same time. */
  .custom_nav {
    display: none;
  }

  .responsive-nav,
  .responsive-nav-button {
    display: block;
  }

  .header-bar {
    align-items: center;
  }

  /* The desktop indent goes: below this width the page container runs full width with the
     same 15px padding as the bar, so the logo lines up with the headline underneath it. */
  .header-logo {
    margin-left: 0;
    margin-bottom: 10px;
  }

  .header-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
  }

  /* Same as above, minus the 10px the legacy rule sets the button off by. */
  body.page-template-template_backend_termine .create-form .teilnehmerselect .button.cancel {
    flex: 0 0 calc(25% - 10px);
  }

  /* A row of a dashboard panel loses the indent it has on wide screens. Was the same rule at
     max-width: 992px in legacy-style.css, which overlaps bootstrap's md by one pixel. */
  body.page-template-template_backend_dashboard .dashboard .entry {
    padding: 15px 0;
  }

  /* From here on down the four columns of a device row are col-sm-12 and stack, each one
     flush against the next - the two text fields, the type and the row of actions ran into
     one block. Only the row gap: the columns are on a line of their own each, so the
     declaration does nothing above this width, where they sit side by side. */
  body.page-template-template_backend_medizinprodukte .medizinprodukt-row {
    row-gap: 10px;
  }

  /* The two columns of an einweisung row are col-md-*, so below this width they carry no
     width at all and a flex item then takes the width of its content: the names ran into
     the badges of the rows beside them. Each of them holds a line of its own again, the
     way the block level columns inside the former float wrapper did. */
  body.page-template-template_backend_medizinprodukte .medizinprodukt-einweisung-name,
  body.page-template-template_backend_medizinprodukte .medizinprodukt-einweisung-status {
    flex: 0 0 100%;
  }

  /* The Bearbeiten button keeps the 162px minimum width legacy-style.css gives every
     button, which no longer fits the two grid columns it sits in on wider screens - it
     used to stick out of the panel. Its column is twice as wide from here on down (see
     snippets/mitarbeiter/show.php) and lays the button out instead of letting it float,
     so that it stays on the edge the wider screens line it up with. A flex item ignores
     the float legacy-style.css puts on it, no reset needed. */
  body.page-template-template_backend_mitarbeiter .show_all .entry .text-right {
    display: flex;
    justify-content: flex-end;
    align-items: flex-start;
  }
}

/* Large phones */
@media (max-width: 767.98px) {

  :root {
    --header-logo-height: 60px;
  }

  /* Same reduction the news box made below this width. */
  .file-field .file-field-preview,
  .file-field .file-field-video {
    max-height: 200px;
  }

  .file-field .file-field-doc-icon {
    width: 52px;
    height: 52px;
  }

  .file-field .file-field-doc-ext {
    bottom: 12px;
    font-size: 10px;
  }

  .file-field .file-field-remove {
    padding: 3px 6px;
    font-size: 11px;
  }

  /* Below this width the heading and the button beside it are on a line of their own each, and
     the button ends up flush on the panel underneath it. */
  body.page-template-template_backend_umfragen .new-button {
    margin-bottom: 15px;
  }

  /* The four dashboard rules of the max-width: 768px block of legacy-style.css, which overlaps
     bootstrap's sm by one pixel. From here on down the two panels of the bottom row are on a
     line of their own each and need the distance between them; a panel keeps less of its
     padding; and the place of a termin moves under the rest of the row instead of staying
     right aligned in a column of its own. */
  body.page-template-template_backend_dashboard .dashboard .dashboard-panels > [class*="col-"]:first-child .custom-panel {
    margin-bottom: 30px;
  }

  body.page-template-template_backend_dashboard .dashboard .custom-panel > .content {
    padding: 15px;
  }

  body.page-template-template_backend_dashboard .dashboard .single-event.entry .text-right {
    text-align: left;
  }

  /* The button of a survey row, which legacy-style.css floats left from here on down to get it
     out of the right aligned column it shares with nothing else. A flex container puts it on
     the same edge and leaves it at its own width. */
  body.page-template-template_backend_dashboard .dashboard .single-survey .text-right {
    display: flex;
    margin-top: 5px;
  }

  /* The booking links are laid out by the list above, not by the float legacy-style.css hands
     every dashboard button here - a floated block would take its <li> down to no height at
     all. What is left of that rule is the distance it kept. */
  body.page-template-template_backend_dashboard .dashboard .custom-panel ul .button {
    margin-top: 5px;
  }

  /* Two to a line instead of four - the col-xs-6 the overlay buttons used to carry. */
  body.page-template-template_backend_rundmail .rundmail-overlay-actions {
    grid-template-columns: repeat(2, 1fr);
  }

  /* Each of the two buttons had a column of its own from here on down - col-xs-12 - so they
     stand under one another, right aligned, and keep the width a button has. */
  body.page-template-template_backend_rundmail .rundmail-actions {
    flex: 1 1 100%;
    flex-direction: column;
    align-items: flex-end;
    gap: 8px;
    /* The same distance the umfragen button above keeps from the panel it would otherwise
       end up flush on. */
    margin-bottom: 15px;

    & .button {
      min-width: 162px;
      max-width: 100%;
    }
  }

  /* The map runs the full width of the screen from here on down, where the box at its desktop
     width would cover most of it. The field gives way, and the type comes down a step with it
     - on a phone it is read from much closer. The magnifier keeps its 40px: that is what a
     finger needs. */
  .leaflet-control-geocoder {
    --geocoder-field-width: 220px;

    & .leaflet-control-geocoder-form input {
      font-size: 16px;
    }

    & .leaflet-control-geocoder-alternatives li {
      font-size: 15px;
    }

    & .leaflet-control-geocoder-alternatives .leaflet-control-geocoder-address-context {
      font-size: 13px;
    }

    & .leaflet-control-geocoder-error {
      font-size: 14px;
    }
  }
}

/* Small phones */
@media (max-width: 575.98px) {

  :root {
    --header-logo-height: 56px;
  }

  /* Too narrow for logo, name and burger side by side: the bar wraps, the burger stays up
     on the logo's line and the "Angemeldet als" block moves into a line of its own. */
  .header-bar {
    flex-wrap: wrap;
  }

  .header-logo {
    order: 1;
  }

  .responsive-nav-button {
    order: 2;
    margin-left: auto;
  }

  .header-actions {
    order: 3;
    flex: 0 0 100%;
  }

  /* Same again for the narrowest phones, where the map itself is barely 260px wide. */
  .leaflet-control-geocoder {
    --geocoder-field-width: 190px;
  }
}
