input, textarea, select, [contenteditable=true], [contenteditable=true] * {
    -webkit-user-select: text !important;
    -khtml-user-select: text !important;
    -moz-user-select: text !important;
    -ms-user-select: text !important;
    user-select: text !important;
    outline:none;
}

html, body {
    margin: 0;
    padding:0;
    width:100%;
    
    color:#1a1a1a;
    font-family: 'Poppins',sans-serif;
    font-weight: 500;
    font-style: normal;
    font-size:13px;
    overflow-x:hidden;
    
    background-color:#fff;
    
    -webkit-text-size-adjust: 100%;
    -webkit-font-smoothing: antialiased;
}

@media screen and (max-width: 1000px) {
    html, body { overflow-x:auto; }
}

h1,h2 { font-size:1.5em; font-weight:bold; }
h3 { font-size:1.08em; line-height:1.57em; font-weight:700; color:#061353; margin:0; margin-top:30px; margin-bottom:10px; padding:0; }

p.error, font.error, i.error { color:#BB1A3F; }
p.light, font.light, i.light { color:#97A3B5; }
p.info { color:#6C7382; }

.nobr { white-space:nowrap; }

sub,
sup { line-height:0; font-size:0.6em; vertical-align:sub; }
sup { vertical-align:super; }

img { border:0; }
a { color:inherit; text-decoration:none; }
a:hover { color:#029896; }

a.row { display:block; }
a.row small { color:#97A3B5; }
a.row:hover { color:inherit; background-color:#F2F5F9; border-radius:4px; margin:-5px; padding:5px; }

p a { text-decoration:underline; }

.printonly { display:none; }

[data-slider][data-href],
[data-slider][href] { cursor:pointer; }

.positive { background-color:#19A483; color:#fff; }
.negative { background-color:#BB1A3F; color:#fff; }
.warning { background-color:#ED5A2B; color:#fff; }

*:not(strong).positive:not(.state) { padding-left:3px; padding-right:3px; margin-left:-3px; margin-right:-3px; border-radius:4px; -webkit-box-shadow: 0px 0px 0px 1px #19A483; -moz-box-shadow: 0px 0px 0px 1px #19A483; box-shadow: 0px 0px 0px 1px #19A483; }
*:not(strong).negative:not(.state) { padding-left:3px; padding-right:3px; margin-left:-3px; margin-right:-3px; border-radius:4px; -webkit-box-shadow: 0px 0px 0px 1px #BB1A3F; -moz-box-shadow: 0px 0px 0px 1px #BB1A3F; box-shadow: 0px 0px 0px 1px #BB1A3F; }
*:not(strong).warning:not(.state) { padding-left:3px; padding-right:3px; margin-left:-3px; margin-right:-3px; border-radius:4px; -webkit-box-shadow: 0px 0px 0px 1px #ED5A2B; -moz-box-shadow: 0px 0px 0px 1px #ED5A2B; box-shadow: 0px 0px 0px 1px #ED5A2B; }

.font-positive { color:#19A483 !important; }
.font-negative { color:#BB1A3F !important; }
.font-warning { color:#ED5A2B !important; }

.font-light { color:darkgrey !important; }

span.state { display:inline-block; text-align:center; font-weight:600; font-size:0.92em; background-color:#DEE9FC; color:#2C6EEF; padding:0.3em 0.5em; border-radius:4px;  white-space:nowrap; }
span.state.info { background-color:#F2F5F9; color:#97A3B5; }
span.state.positive { background-color:#F0FCF8; color:#19A483; }
span.state.negative { background-color:#FEEAE8; color:#BB1A3F; }
span.state.warning { background-color:#FFECE1; color:#ED5A2B; }
span.state.blank { background-color:transparent; color:#97A3B5; }

span.state.large { font-size:1em; }
span.state.inline { display:inline; }

.notice { display:block; position:relative; padding:10px; margin-bottom:30px; background-color:#FFECE1; color:#1a1a1a; border-radius:4px; }
.notice[class^="icon-"]:before,
.notice[class*=" icon-"]:before,
.notice td:last-child { color:#ED5A2B; }
.notice[class^="icon-"]:before,
.notice[class*=" icon-"]:before { position:absolute; top:50%; left:10px; margin:0; transform:translateY(-50%); font-size:2.31em;}
.notice[class^="icon-"],
.notice[class*=" icon-"] { padding-left:3.85em; min-height:3em; }
.notice td:last-child { font-weight:600; font-size:1.08em; text-align:right; }
.notice td:last-child a { display:inline-block; padding:0.43em 0.57em; }
.notice :first-child { margin-top:0; }
.notice :last-child { margin-bottom:0; }
.notice a { color:inherit; }
.notice a:hover { color:#1a1a1a; }
.notice h2 { margin:0; padding:0; font-size:inherit; font-weight:bold; line-height:1.69em; }
.notice p { margin:0; padding:0; line-height:1.46em; }

.notice.light { background-color:#F0FCF8; }
.notice.light[class^="icon-"]:before,
.notice.light[class*=" icon-"]:before,
.notice.light td:last-child { color:#19A483; }

.notice:empty,
.notice[data-autocomplete-notice-value="value"][data-value=""],
.notice[data-autocomplete-notice-value="value"]:not([data-value]) { display:none; }

.notice + .notice { margin-top:-20px; }
.input + .notice { margin-top:1em; }

.notice[data-value] + .input { margin-top:-25px; }

[class^="icon-"].large, [class*=" icon-"].large { font-size:1.4em; }

ul.kpi { display:block; list-style:none; margin:0; margin-bottom:-5px; padding:0; overflow:hidden; }
ul.kpi > li { position:relative; display:block; float:left; margin:0; padding:0; padding-bottom:5px; }
ul.kpi > li + li { margin-left:30px; padding-left:30px; }
ul.kpi > li + li:before { content:""; position:absolute; bottom:5px; left:-1px; width:1px; height:1000px; background-color:#E4E9EF; }
ul.kpi > li > span { display:block; font-size:0.92em; line-height:1.67em; color:#6C7382; margin-bottom:5px; }
ul.kpi > li > strong { display:block; color:#061353; font-size:1.85em; line-height:1.33em; font-weight:500; }
ul.kpi.small > li > strong { font-size:1.6em; }
ul.kpi > li > strong.negative { background:transparent; color:#BB1A3F; }

/* In the page head the KPIs scroll sideways rather than wrapping onto a second line. overflow-y stays hidden:
   the divider between them is a 1000px pseudo-element that relies on being clipped, and leaving one axis
   visible would promote the other to auto and add a vertical scrollbar. The bar itself is hidden — trackpad
   and shift+wheel still scroll, and a scrollbar would sit badly against the list's negative bottom margin. */
div.wrapper > div.main > div.content > .head ul.kpi { display:flex; flex-wrap:nowrap; overflow-x:auto; overflow-y:hidden; scrollbar-width:none; -ms-overflow-style:none; }
div.wrapper > div.main > div.content > .head ul.kpi::-webkit-scrollbar { display:none; }
div.wrapper > div.main > div.content > .head ul.kpi > li { float:none; flex:none; white-space:nowrap; }

/* Fade the right edge into the background while there is more to scroll to. A mask rather than an overlay,
   because the list IS the scroll container — an absolutely positioned gradient inside it would scroll away
   with the content. functions.js drops .scroll-more once the end is reached, so the last figure is never
   left half-faded. */
div.wrapper > div.main > div.content > .head ul.kpi.scroll-more { -webkit-mask-image:linear-gradient(to right,#000 calc(100% - 60px),transparent 100%); mask-image:linear-gradient(to right,#000 calc(100% - 60px),transparent 100%); }
ul.kpi > li > small { display:block; margin-top:5px; font-size:0.92em; line-height:1.17em; color:#97A3B5; }
ul.kpi > li > a.button { margin-top:5px; padding:0.3em 0.5em; display:inline-block; }
ul.kpi > li > a.button[class^="icon-"]:before,
ul.kpi > li > a.button[class*=" icon-"]:before { width:auto; margin:auto; margin-right:5px; }

ul.index { display:block; list-style:none; margin:0; margin-bottom:2em; padding:0; border-bottom:1px solid #E4E9EF; }
ul.index > li { position:relative; display:inline-block; margin:0; padding:0; }
ul.index > li a { display:block; position:relative; color:#6C7382; font-size:14px; padding:0.71em 1.43em; font-weight:600; }
ul.index > li a:before { margin-right:0.3em; }
ul.index > li a:hover,
ul.index > li a.selected,
ul.index > li a.search-match { color:#2C6EEF; }
ul.index > li a.selected:after,
ul.index > li a.search-match:after { content:""; position:absolute; bottom:-1px; left:0; right:0; height:3px; background-color:#2C6EEF; }

/* S125: die Reiter zeigen, ohne selbst zu suchen (functions.js, searchIndexApply()), wo eine laufende
   Suche noch Treffer hat. Kein neues Gestaltungsmittel: .search-match teilt sich die Farbe mit :hover/
   .selected oben -- derselbe Blauton, den ein Reiter ohnehin schon annimmt, sobald er "ansprechbar"
   wirkt, nur jetzt durch eine Klasse statt den Mauszeiger ausgelöst. .search-none übernimmt die 55%
   Deckkraft, mit der .permission-group-block.suggested weiter unten in dieser Datei einen Block bereits
   "zurücknimmt", ohne ihn zu verstecken. Beides bleibt aus, solange keine Suche läuft (die Klassen setzt
   ausschliesslich JS, nie PHP) -- der Normalfall (DoD 2) ändert sich damit nicht um ein einziges Byte.

   S126: die Farbe reichte nicht -- .selected zeigt sein Aussehen auch über die Linie (:after direkt
   oben), die .search-match bisher nicht mitbekam. Jetzt teilen sich beide dieselbe :after-Regel, also
   auch dieselbe Linie, gemessen gleich (DoD 1).

   Und der gewählte Reiter ohne eigenen Treffer darf jetzt nicht mehr wie gewählt aussehen (DoD 2) --
   ohne dass die Klasse .selected selbst wandert (siehe searchIndexApply() in functions.js: sie bleibt
   die tatsächliche Auswahl, nur ihr Aussehen wird unterdrückt). .search-none trägt search-none jetzt
   auch auf dem gewählten Reiter selbst; die beiden Regeln darunter nehmen ihm exakt die zwei Dinge
   wieder weg, die .selected ihm gibt (Farbe, Linie) -- übrig bleibt genau das Aussehen eines
   gewöhnlichen, trefferlosen Reiters, samt derselben 55% Deckkraft. */
ul.index > li a.search-none { opacity:0.55; }
ul.index > li a.selected.search-none { color:#6C7382; }
ul.index > li a.selected.search-none:after { content:none; }

.input, label:not([class]) { display:block; position:relative; line-height:1.3em; }
label.input, label:not([class]) { padding:0.77em 0; border-bottom:1px solid transparent; }

.input input:not(.button),
.input textarea,
.input select { display:block; position:relative; font-family:inherit; font-weight:inherit; font-size:inherit; line-height:inherit; color:inherit; background:none; padding:0; margin:0; border:0; width:100%; -webkit-appearance:none; -moz-appearance:none; appearance:none; resize: none; white-space: pre-wrap; word-wrap: break-word; }

.input.large input:not(.button),
.input.large textarea,
.input.large select { font-size:1.54em; font-weight:bold; }

.input.disabled input:not(.button):disabled,
.input.disabled textarea:disabled,
.input.disabled select:disabled { color:#1a1a1a; -webkit-text-fill-color:#1a1a1a; opacity:1; }

.input ::-webkit-input-placeholder { color:#97A3B5; }
.input ::-moz-placeholder { color:#97A3B5; }
.input :-ms-input-placeholder { color:#97A3B5; }
.input :-moz-placeholder { color:#97A3B5; }

.input.error ::-webkit-input-placeholder,
.input.missing ::-webkit-input-placeholder { color:#BB1A3F; }
.input.error .input ::-moz-placeholder,
.input.missing .input ::-moz-placeholder { color:#BB1A3F; }
.input.error .input :-ms-input-placeholder,
.input.missing .input :-ms-input-placeholder { color:#BB1A3F; }
.input.error .input :-moz-placeholder,
.input.missing .input :-moz-placeholder { color:#BB1A3F; }

.input[class^="icon-"]:not(.select), .input[class*=" icon-"]:not(.select) { padding-left:2em; }
.input[class^="icon-"].icon-right:not(.select), .input[class*=" icon-"].icon-right:not(.select) { padding-right:2em; padding-left:0; }
.input[class^="icon-"]:not(.select):not(.disabled), .input[class*=" icon-"]:not(.select):not(.disabled) { cursor:pointer; }

.input[class^="icon-"]:before, .input[class*=" icon-"]:before,
.input.icon-text > span,
.input.icon-text > a { position:absolute; top:0.92em; left:0; margin:0; }
.input.icon-text > span { pointer-events:none; }
.input[class^="icon-"].icon-right:before, .input[class*=" icon-"].icon-right:before,
.input.icon-text.icon-right > span,
.input.icon-text.icon-right > a { right:0; left:auto; }
.input.icon-text > span,
.input.icon-text > a { font-weight:600; }
.input.icon-text > a { background-color:#97A3B5; color:#fff; padding:4px 8px; margin-top:-4px; border-radius:4px; }
.input.icon-text > input:not([readonly]) + a:hover { background-color: #1a1a1a; }
.input.icon-text > input[readonly] + a { cursor:default; background-color:#1a1a1a; }
/* The connected state as plain INFORMATION — what a non-writer sees instead of the connect button. */
.input.icon-text > span.bank-connected { position:absolute; top:0.92em; left:0; font-weight:600; background-color:#1a1a1a; color:#fff; padding:4px 8px; margin:-4px 0 0 0; border-radius:4px; cursor:default; }

.input.icon-text > input:not([readonly]) + a span.readonly { display:none; }
.input.icon-text > input[readonly] + a span.readonly { display:inline; }
.input.icon-text > input[readonly] + a span.readonly + span { display:none; }

.input.select { padding:0; }
.input.select.color { margin:0.77em 0; }
.input.select select { padding:0.77em 0; padding-right:2em; cursor:pointer; }
.input.select.color select { padding:0.77em; padding-right:2.77em; color:#97A3B5; background-color:#F2F5F9; border-radius: 4px; }
.input.select.color.missing select,
.input.select.color.error select { border-bottom-left-radius:0; border-bottom-right-radius:0; color:#BB1A3F; }

.input.select.selected select { color:rgba(18, 23, 40, 1); }
.input.select:after { position:absolute; top:50%; right:0; color:#97A3B5; font-size:0.6em; transform:translateY(-50%); content:"\e822"; pointer-events:none; font-family: "profuturum-icon"; font-style: normal; font-weight: normal; speak: never; text-decoration: inherit; font-variant: normal; text-transform: none; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
.input.select.color:after { right:0.77em; }
.input.select.icon-right select { padding-left:2em; padding-right:0; }
.input.select.color.icon-right select { padding-left:2.77em; padding-right:0.77em; }
.input.select.icon-right:after { left:0; right:auto; }
.input.select.color.icon-right:after { left:0.77em; }
/* A select the rights locked (readonlyFields tags the wrapper): nothing will open, so no arrow inviting a
   click, and no pointer cursor either. */
.input.select.readonly:after { content:none; }
.input.select.readonly select { cursor:default; }

.input.select[class^="icon-"] select, .input.select[class*=" icon-"] select { padding-left:2em; padding-right:2em; }
.input.select.color[class^="icon-"] select, .input.select.color[class*=" icon-"] select { padding-left:2.77em; padding-right:2.77em; }
.input.select[class^="icon-"]:before, .input.select[class*=" icon-"]:before { pointer-events:none; position:absolute; top:0.15em; left:0; margin:0; }
.input.select.color[class^="icon-"]:before, .input.select.color[class*=" icon-"]:before { top:0.92em; left:0.77em; }
.input.select[class^="icon-"].icon-right:before, .input.select[class*=" icon-"].icon-right:before { right:0; left:auto; }
.input.select.color[class^="icon-"].icon-right:before, .input.select.color[class*=" icon-"].icon-right:before { right:0.77em; }

label.input.checkbox,
label.input.radio { cursor:pointer; }
.input.checkbox input,
.input.radio input { position:absolute; opacity:0; cursor:pointer; height:0; width:0; }
.input.checkbox input + span,
.input.radio input + span { box-sizing: border-box; position:relative; display:block; cursor:pointer; float:right; text-align:center; min-height:0; height:1.3em; padding:0; min-width:1.3em; overflow:hidden; border:1px solid #E4E9EF; border-radius:4px; -webkit-border-radius:4px; -moz-border-radius:4px; background-color:#fff; }
.input.radio input + span { width:1.3em; background-color:#E4E9EF; }

.input.checkbox.left { position:relative; padding-left:2.07em; text-align:left; }
.input.checkbox.left input + span { position:absolute; top:0.77em; left:0; }

.input.checkbox.notext { overflow:hidden; }

.input.checkbox input:checked + span,
.input.radio input:checked + span { background-color:#1a1a1a; border-color:#1a1a1a; }

.input.checkbox input:disabled:checked + span,
.input.radio input:disabled:checked + span { background-color:#19A483; border-color:#19A483; }

.input.checkbox input + span:after,
.input.radio input + span:after { position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); font-size:0.7em; text-align:center; line-height:1em; font-family: "profuturum-icon"; font-style: normal; font-weight: normal; speak: never; text-decoration: inherit; font-variant: normal; text-transform: none; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
.input.checkbox input:checked + span:after,
.input.radio input:checked + span:after { color:#fff; }

.input.checkbox input:checked + span:not([data-icon]):not([data-icon-checked]):after,
.input.radio input:checked + span:not([data-icon]):not([data-icon-checked]):after { content:"\e809"; }
.input.checkbox input + span[data-icon][data-icon-checked]:after,
.input.radio input + span[data-icon][data-icon-checked]:after { content:attr(data-icon); }
.input.checkbox input:checked + span[data-icon-checked]:after,
.input.radio input:checked + span[data-icon-checked]:after { content:attr(data-icon-checked); }
.input.checkbox input:checked + span[data-icon]:not([data-icon-checked]):after,
.input.radio input:checked + span[data-icon]:not([data-icon-checked]):after { content:attr(data-icon); }

.input.checkbox.disabled { color:#19A483; }
.input.checkbox.disabled,
.input.checkbox.disabled input + span { cursor:not-allowed; }

/* Ein "left"-Kaestchen in einer TABELLENZELLE sitzt senkrecht mittig, nicht an der Oberkante.
   .input.checkbox.left setzt top:0.77em -- das ist fuer ein Kaestchen NEBEN TEXT gedacht, wo es auf der
   ersten Textzeile sitzen soll. In einer Zelle gilt aber vertical-align:middle, die Zelle ist so hoch wie
   die hoechste Spalte, und die 0.77em schoeben das Kaestchen um genau diesen Betrag unter die Mitte.
   GEMESSEN (Portfolio-Bericht, 3 Projekte, 1280px): ohne diese Zeile box.y-Zellenoberkante 40.36px bei
   81.72px Zeilenhoehe -- 10.01px zu tief; mit ihr 32.42px, also exakt mittig (Zeilenmitte 40.86px minus
   halbe Kaestchenhoehe 8.44px).
   DIESELBE ERKLAERUNG, ZWEI ORTE IM SELEKTOR -- nicht zwei Regeln: die Projektauswahl (S94) braucht
   woertlich, was table.input schon hatte. Eine zweite Regel danebenzuschreiben hiesse, dieselbe Aussage
   zweimal zu fuehren; sie liefen auseinander, ohne je falsch auszusehen. Neu ist hier nur ein SELEKTOR,
   kein CSS-Mittel -- die Zusicherung aus S51 (neue Mittel ausschliesslich in Erklaerungen) bleibt
   unberuehrt. */
table.input td .input.checkbox.left input + span,
.input.list .results td .input.checkbox.left input + span { top:50%; transform:translateY(-50%); }

label.input.missing,
label.input.error { border-color:#BB1A3F; }
label.input:not(.error):not(.disabled):not(.readonly):not(.select.color).focus,
label.input:not(.error):not(.disabled):not(.readonly):not(.select.color):hover { border-radius:4px; border-color:transparent; background-color:#F2F5F9; -webkit-box-shadow:-0.77em 0 0 0 #F2F5F9,0.77em 0 0 0 #F2F5F9; -moz-box-shadow:-0.77em 0 0 0 #F2F5F9,0.77em 0 0 0 #F2F5F9; box-shadow:-0.77em 0 0 0 #F2F5F9,0.77em 0 0 0 #F2F5F9; border-radius:4px; }

.input.input-2 { padding:0; }
.input.input-2 > div:not(.clear) { position:relative; display:block; width:50%; float:left; }
.input.input-2 > div:first-child > .input { margin-right:2.5em; }
.input.input-2 > div:first-child:after { content:''; width:1px; position:absolute; top:0; bottom:0; right:-1px; background-color:#E4E9EF; }
.input.input-2 > div:first-child + div > .input { margin-left:2.5em; }

.input.input-3 { padding:0; }
.input.input-3 > div:not(.clear) { position:relative; display:block; width:25%; float:left; }
.input.input-3 > div:first-child { width:50%; }
.input.input-3 > div:first-child > .input,
.input.input-3 > div:first-child + div > .input { margin-right:2.5em; }
.input.input-3 > div:first-child:after{ content:''; width:1px; position:absolute; top:0; bottom:0; right:-1px; background-color:#E4E9EF; }
.input.input-3 > div:first-child + div > .input { margin-left:2.5em; }

.input:not([data-more][data-more-state=hide]) + .input,
.input:not([data-more][data-more-state=hide]) + .input[data-more][data-more-state=hide] + .input { margin-top:0.92em; }
.input:not([data-more][data-more-state=hide]) + .input.select,
.input.select:not([data-more][data-more-state=hide]) + .input,
.input.select:not([data-more][data-more-state=hide]) + .input[data-more][data-more-state=hide] + .input { margin-top:1.69em; }
.input.select:not([data-more][data-more-state=hide]) + .input.select,
.input.select:not([data-more][data-more-state=hide]) + .input[data-more][data-more-state=hide] + .input.select { margin-top:2.46em; }

.button { display:inline-block; cursor:pointer; margin:0; padding:11px; text-align:center; font-size:1.08em; line-height:1em; font-family:inherit; font-weight:600; border:2px solid transparent; border-radius:4px; background-color:#2C6EEF; color:#fff; -webkit-appearance:none; -moz-appearance:none; appearance:none; }
.input .button { margin-top:0.77em; }
.input.submit .button:not(.plain) { display:block; }
.input.submit { text-align:center; }
.input input.button { width:100%; }
.input + .input .button { margin-top:1.69em; }
.input.select + .input .button,
*:not(.input) + .input .button { margin-top:2.46em; }
.action + .input .button { margin-top:3.47em; }
.input.submit + .input.submit,
form + .input.submit { margin-top:0; }
.input.submit + .input.submit .button,
form + .input.submit .button { margin-top:1.54em; }

.input.list { margin-bottom:2.31em; border-bottom:1px solid #E4E9EF; }
.input.list table tbody tr.hidden,
.input.list:not([data-search-results-visible="0"]) table tbody tr.protected { display:none!important; }
.input.list h2 { font-size:0.92em; font-weight:600; color:#061353; line-height:1.17em; margin:0; padding:0; padding-bottom:1.67em; padding-top:2.31em; margin-top:2.31em; }

/* DIE TRENNLINIE DIESER LISTEN -- EINE ERKLAERUNG, ZWEI STELLEN (S68).
   Der Auftraggeber wollte zwischen Suchfeld und erstem Listeneintrag mehr Abstand und eine Trennlinie,
   "wie bei der Bankauswahl". Die Linie dort ist GEMESSEN und nicht nachgebaut: im Bankenauswahl-Overlay
   (module/bank.overlay.php) steht zwischen Suchfeld und Liste eine Ueberschrift, und die Linie ist deren
   border-top. Echter Browser, 1280x800, Grundschrift 13px:
     1px solid #E4E9EF  ->  computed "1px solid rgb(228, 233, 239)"
   Dieselbe Haarlinie, die .input.list auch unten unter sich zieht (border-bottom, oben) -- im Haus gibt
   es genau diese eine.

   Die Projektauswahl (includes/php/projectselect.inc.php) hat an dieser Stelle KEINE Ueberschrift. Sie
   bekommt deshalb ein eigenes, leeres Kaestchen dafuer: .search:after. Geteilt wird die ERKLAERUNG,
   nicht der Wert -- eine zweite Zeile mit "1px solid #E4E9EF" saehe heute gleich aus und liefe morgen
   auseinander, ohne dabei je falsch auszusehen.

   WARUM NICHT EINFACH DER OBERE RAHMEN DER LISTE (so stand es bis S80): weil die Liste der ROLLENDE
   Kasten ist. Alles, was unter ihrem oberen Rahmen Platz schafft, liegt IN ihr und rollt mit dem Inhalt
   hinaus -- der Abstand unter der Linie verschwand beim Rollen, und die erste sichtbare Zeile klebte an
   ihr. Gemessen, 100 Projekte, drei Rollpositionen (Abstand Linie -> oberster sichtbarer Inhalt):
     bis S80 (padding im Kasten)   oben 21.70   mittendrin 0.00   ganz unten 0.00
     jetzt (Kaestchen davor)       oben 21.70   mittendrin 21.70  ganz unten 21.70
   An der unteren Linie war der Abstand immer konstant 21.70 -- er ist ein margin AUSSERHALB des
   Kastens. Genau diese Bauweise hat die obere Linie jetzt auch, und das ist es, was der Auftraggeber
   mit "so wie bei der unteren linie zum unteren rand des scrollbaren bereichs" verlangt hat.

   DIE BANKAUSWAHL MACHT ES RICHTIG, nachgemessen an genau dieser Eigenschaft (23 Banken, 972px
   rollbar): ihr Abstand Linie -> Inhalt betraegt in allen drei Rollpositionen 61.58px. Ihre Linie und
   der Abstand darunter sitzen auf der Ueberschrift, also AUSSERHALB des rollenden Kastens. Sie ist
   damit Vorbild und nicht ein zweiter Fall derselben Sache.

   DAS KAESTCHEN HAENGT AM SUCHFELD, DIE LINIE IST TROTZDEM NICHT DESSEN RAND -- und das ist der
   Unterschied, an dem eine naheliegende Fassung gescheitert waere. label.input traegt selbst ein
   border-bottom:1px solid transparent (die Regel weiter oben bei label.input), und dieses Band ist
   ZUSTANDSTRAGEND: bei 0 Treffern setzt functions.js .error auf genau dieses .input, und
   "label.input.missing, label.input.error { border-color:#BB1A3F; }" faerbte eine daran gehaengte
   Trennlinie ROT; unter dem Zeiger macht label.input:hover sie transparent und legt eine graue Flaeche
   darueber. Das Pseudoelement ist ein EIGENER Kasten mit einem eigenen Rahmen -- border-color am Label
   erbt sich nicht dorthin. GEMESSEN, alle drei Zustaende, an der Linie und am Feld daneben:
     in Ruhe           Linie rgb(228,233,239)   Feldrand rgba(0,0,0,0)
     Zeiger drauf      Linie rgb(228,233,239)   Feldrand rgba(0,0,0,0), Feld grau hinterlegt
     0 Treffer         Linie rgb(228,233,239)   Feldrand rgb(187,26,63)  -- das rote Signal bleibt
   Die graue Flaeche kann die Linie auch nicht verdecken: das Feld endet bei 132.27, die Linie liegt bei
   152.98, und der Schatten der Hinterlegung hat 0 senkrechten Versatz und 0 Ausbreitung (gemessen
   "rgb(242,245,249) -10.01px 0px 0px 0px, rgb(242,245,249) 10.01px 0px 0px 0px").

   pointer-events:none, wie bei .input.select:after weiter oben: eine gemalte Linie darf keinen Klick
   abfangen.

   DER ANKER KOSTET EINEN PIXEL, benannt statt verschwiegen: top:100% zaehlt vom Polsterrand-Kasten des
   Suchfelds, und der endet 1px ueber dessen Rahmenkante (eben wegen jenes durchsichtigen
   border-bottom). Der Abstand Suchfeld -> Linie ist deshalb gemessen 20.71px statt 21.71px. Der
   Abstand, um den es geht -- Linie -> Liste -- ist unveraendert 21.70px.

   S96 -- EINGERUECKT AUF DIE INHALTSFLUCHT, AUF AUSDRUECKLICHEN WUNSCH. Bis hierher trug das Kaestchen
   dieselben -0.77em wie .results, und die Linie stand auf deren HUELLE (-10.01 .. 1290.01) statt auf der
   Flucht des INHALTS (0 .. 1280), auf der die Linie der Bankauswahl steht -- s.o. Der Auftraggeber wollte
   ausdruecklich genau diese Kante. Das Kaestchen haengt an .search, und .search selbst steht schon auf
   0 .. 1280 (dasselbe Element traegt keine eigene negative Randbreite) -- die Einrueckung ist deshalb
   links:0/rechts:0 statt der geerbten -0.77em, keine zweite Zahl.

   DIE ZEILENHINTERLEGUNG BLEIBT UNBERUEHRT, GEMESSEN STATT ANGENOMMEN: die -0.77em, die .results bis an
   den Rand ragen laesst (Regel weiter unten, .input.list .results), ist eine ANDERE Erklaerung an einem
   ANDEREN Element und stand hier nie zur Debatte. Gemessen vorher/nachher: .results unveraendert bei
   -10.01 .. 1290.01, nur die Linie steht jetzt bei 0 .. 1280 -- dieselbe Kante wie bei der Bankauswahl.

   WENN DER BROWSER DAS KAESTCHEN NICHT KENNT: dann faellt die LINIE weg, und sonst nichts. GEMESSEN
   auf einer Wegwerf-Kopie ohne diese Regel: der Abstand zwischen Suchfeld und Liste steht unveraendert
   (43.41px, denn er ist ein margin an der Liste und haengt nicht am Kaestchen), der Kasten misst 400,
   die Reservierung steht bei 400px, und der Filter arbeitet weiter (data-search-results "1" bei einem
   Treffer). Hoechstens eine Verbesserung entfaellt, nie eine Funktion. */
.input.list h2,
.input.list.projects .search:after { border-top:1px solid #E4E9EF; }
.input.list.projects .search:after { content:''; position:absolute; top:100%; left:0; right:0; margin-top:1.67em; pointer-events:none; }
.input.list[data-search-results="0"] h2 { color:transparent; }
.input.list .results { height:160px; overflow:auto; margin-left:-0.77em; margin-right:-0.77em; margin-bottom:1.67em; }
/* S15/S51 (Aufgabennotizen) -- die Projektauswahl soll von Haus aus 2-3x so hoch sein wie eine gewoehnliche
   Liste. .results ist die GETEILTE Listenhuelle: das Bankenauswahl-Overlay (module/bank.overlay.php) benutzt
   sie genauso, und die Projektliste ist seinerzeit nach dessen Vorbild gebaut. Eine Regel auf .results selbst
   aenderte jede Liste im Haus.

   S15 hat dafuer die Formular-Id des einen Overlays genommen. Seit S51 gibt es die Auswahl an ZWEI Orten
   (Rechteverwaltung und Portfolio-Bericht) aus EINER Quelle -- includes/php/projectselect.inc.php --, und
   damit gibt es etwas Besseres als eine Formular-Id: die Klasse, die genau dieser Baustein setzt. Sie traegt
   die Regel an beide Orte, ohne sie einer dritten, fremden Liste zu geben. Eine zweite Id danebenzuschreiben
   waere die Regel an zwei Orten gewesen -- genau das, was S51 abschaffen soll.

   max-height statt height: bei WENIG Projekten (kein Scrollen noetig) bleibt die Liste so kurz wie ihr
   Inhalt. Gemessen im echten Browser (ws.browser, nicht Teil dieser Suite -- sie hat entschieden, bezeugt
   aber nicht hier), 500px hohes Fenster, 2 Projekte: mit einer FESTEN Hoehe von 400px stand der
   "Weiter"-Knopf bei y=710, ausserhalb des sichtbaren Bereichs; mit max-height stand dieselbe Liste nur
   96px hoch (statt reservierter 400px) und der Knopf bei y=406, INNERHALB des 500px-Fensters. Bei VIELEN
   Projekten verhalten sich beide Formen gleich (beide deckeln bei 400px und scrollen) -- max-height ist
   also nie schlechter, oft besser. */
.input.list.projects .results { height:auto; max-height:400px; }

/* Die gemessenen Zeilenhoehen, und warum sie hier stehen und nicht in PHP.
   S48 hat beim Filtern die Hoehe reserviert und dafuer eine feste Zahl genommen. Die durfte fest sein, weil
   das Suchfeld damals erst ab 13 Projekten kam: 13 Zeilen sind immer ueber dem Deckel. S51 stellt die
   Schwelle auf DREI -- damit faellt diese Voraussetzung, und die feste Zahl wird falsch. GEMESSEN (echter
   Browser, 3 Projekte mit Suchfeld, 1280x800): .results 400px, Tabelle darin 143.74px -- 256.26px leerer
   Kasten. Genau der wortlose Kasten, den S15 verhindern wollte.

   Reserviert wird deshalb, was die UNGEFILTERTE Liste wirklich braucht. Die Pixel dazu stehen HIER, drei
   Zeilen unter der Auffuellung und der Zeilenhoehe, aus denen sie folgen (.input.list .results tr td:
   padding 5px, line-height 1.46em) -- nicht in PHP, wo sie niemand faende, der genau diese Werte aendert.
   PHP liefert nur die ANZAHLEN (--list-rows/-sublines/-titles), und eine Anzahl kann nicht verrotten.

   GEMESSEN im echten Browser, je Zeilenart und an vier Grundschriften (13/16/20/26px), groesster Fehler
   0.02px:

     Ueberschriftzeile    10px + 1.46em   28.98 / 33.36 / 39.20 / 47.96
     Projektzeile         11px + 2.84em   47.91 / 56.42 / 67.80 / 84.83
     Zuschlag Unterzeile        1.30em    16.90 / 20.80 / 26.00 / 33.80

   WAS PASSIERT, WENN JEMAND DIE GRUNDSCHRIFT AENDERT: nichts Stilles. Die Gesetze stehen in em und px
   nebeneinander, weil die Zeile genau so gebaut ist -- die Auffuellung ist fest, der Rest waechst mit der
   Schrift. Deshalb sind sie an allen vier gemessenen Groessen richtig und nicht nur bei den 13px, die das
   Haus heute setzt (style.css:19). Genau daran ist die alte Konstante gestorben: $row_height=33 war die
   Hoehe einer UEBERSCHRIFTZEILE bei 16px Grundschrift (10 + 1.46*16 = 33.36) -- falsche Zeilenart, falsche
   Grundschrift, und beides unsichtbar, weil eine Zahl ohne ihre Herkunft danebenstand.

   min-height, nicht height: die Richtung des Irrtums ist damit gewaehlt. Reservierten wir zu VIEL, stuende
   wieder ein leerer Kasten da; reservieren wir zu WENIG, sinkt die Liste auf ihren Inhalt -- das Verhalten
   von vor S48, unschoen, aber nie ein wortloser Kasten. Der Deckel bleibt max-height:400px, und min() haelt
   die Reservierung darunter: ohne das gewaenne min-height gegen max-height (so die Kaskade) und eine lange
   Liste spraenge ueber ihren eigenen Deckel.

   Gebunden an das Suchfeld (.search + .results), nicht an die Klasse allein: OHNE Suchfeld wird nicht
   gefiltert, da kann nichts springen, und dort muss max-height weiter allein regieren -- sonst faellt S15
   um (dort gemessen: 2 Projekte, 500px hohes Fenster, feste 400px schoben den Knopf auf y=710 aus dem
   Bild).

   WENN DER BROWSER DAS NICHT KENNT (Hausregel des Auftraggebers, 23.09.: ein fehlendes CSS-Mittel darf nie
   etwas kaputtmachen -- hoechstens eine Verbesserung entfaellt, niemals eine Funktion):
   **faellt die Reservierung weg und die Liste sinkt beim Filtern wieder auf ihren Inhalt -- das Springen
   von vor S48, unangenehm, aber nichts ist kaputt.**

   Das ist GEMESSEN, nicht ueberlegt (wir messen sonst immer im neuen Browser). Je Mittel einzeln, indem an
   seiner Stelle ein Funktionsname stand, den der Browser wirklich nicht kennt -- das ist derselbe
   Fehlerpfad, den er bei einem kuenftig unbekannten min()/var() nimmt. 3 Projekte, 1280x800:

     min() unbekannt  min-height faellt auf 0 -> .results 194.44 / 64.81 / 26.90 (ungefiltert / 1 Treffer /
     var() unbekannt  0 Treffer), Knopf wandert 167.54px. Filter, data-search-results UND der Satz fuer den
     Zaehlungen fehlen   leeren Fall arbeiten unveraendert weiter; kein leerer Kasten, nichts faellt
                         zusammen, nichts laeuft ueber. Bei 13 Projekten deckelt und rollt die Liste
                         weiterhin bei 400px.
   Gesund zum Vergleich: 194.45 in allen drei Zustaenden, Knopf unbewegt.

   Der dritte Fall ist kein hypothetischer: wer die Auswahl ohne die Zaehlungen rendert, landet ueber die
   Ersatzwerte var(--list-rows,0) im selben, harmlosen Zustand.

   Warum das sicher ist, und das ist die Regel dahinter: die neuen Mittel stehen ausschliesslich in
   ERKLAERUNGEN (min-height, und die --list-*-Eigenschaften), nie in einem SELEKTOR. Ein unbekanntes Mittel
   in einer Erklaerung laesst nur diese Erklaerung wegfallen; im Selektor macht es die GANZE Regel
   ungueltig. S55 hat genau das gemessen: eine unbekannte Pseudoklasse in einem Hover-Selektor nahm JEDER
   Tabellenzeile im Haus den Hover. Die einfache Erklaerung steht deshalb auch in einer EIGENEN Regel
   (height:auto; max-height:400px, oben) -- faellt die bessere weg, bleibt sie stehen, und sie ist fuer
   sich benutzbar: die Liste deckelt und rollt, nur reserviert sie nichts mehr.

   ERSTE IHRER ART IM HAUS: das hier sind die ersten CSS-Variablen und das erste min() (calc() gab es schon
   viermal). Wer das nachahmt, nehme bitte den GRUND mit, nicht nur die Form: gerechnet wird in CSS, weil
   die Zahlen aus der Zellenauffuellung, der Zeilenhoehe und der Grundschrift folgen -- also aus Dingen,
   die hier stehen. Dieselbe Rechnung in PHP kennt die Grundschrift nicht, und genau daran ist die
   Vorgaengerkonstante gestorben ($row_height=33). Die Anzahlen kommen aus PHP, weil PHP sie WEISS. */
.input.list.projects {
    --list-row-height:calc(11px + 2.84em);
    --list-row-subline:1.3em;
    --list-row-title:calc(10px + 1.46em);
}
.input.list.projects .search + .results {
    min-height:min(400px,calc(var(--list-rows,0) * var(--list-row-height)
                            + var(--list-sublines,0) * var(--list-row-subline)
                            + var(--list-titles,0) * var(--list-row-title)));
}

/* DER ABSTAND UM DIE LINIE -- UND WARUM ER DIE RESERVIERUNG DARUEBER NICHT VERSTELLT (S68, Masse S80).
   Der Auftraggeber zu S68: "sollte nach unten auch einen margin haben (wie die linie unten) und generell
   weniger margins haben. mach es genau wie im bank auswahl overlay linie oben und unten."

   DIE BANKAUSWAHL GEMESSEN, BEIDE LINIEN, statt sie anzusehen (1280x800, Grundschrift 13px):
     Suchfeld -> obere Linie            27.63px   (h2 margin-top:2.31em, bei 0.92em Schrift)
     obere Linie -> Liste               62.59px   (padding 2.31em + Ueberschriftzeile + padding 1.67em)
     Liste -> untere Linie              21.70px   (.results margin-bottom:1.67em)
     untere Linie -> naechstes Element  30.03px   (.input.list margin-bottom:2.31em)
   Daraus die Zahl, die eine Linie im Haus von einer Liste trennt: **1.67em**. Sie steht an beiden
   Stellen, an denen eine Linie eine LISTE beruehrt -- unter der Ueberschrift der Bankauswahl
   (padding-bottom:1.67em) und ueber deren unterer Linie (.results margin-bottom:1.67em). Die 2.31em
   dagegen trennen die Linie von etwas, das KEINE Liste ist (dem Suchfeld oben, dem naechsten Feld unten).

   HIER also 1.67em auf BEIDEN Seiten der oberen Linie. Gemessen: 20.71px darueber (der Anker kostet
   einen Pixel, siehe oben beim Kaestchen), 21.70px darunter -- und darunter im Wortsinn dieselbe Zahl
   wie die 21.71px, die die Liste von der unteren Linie trennen. Die Liste steht damit zwischen ihren
   zwei Linien mittig, auf 0.01px genau, und das ist es, was "linie oben und unten wie bei der
   bankauswahl" messbar heisst.

   BEIDE ABSTAENDE SIND MARGINS UND LIEGEN AUSSERHALB DES ROLLENDEN KASTENS (S83). Der untere war es
   immer (.results margin-bottom), der obere ist es seit S83: er steckt in margin-top:3.34em an der
   Liste -- 1.67em davon ueber der Linie, 1.67em darunter, die Linie selbst haengt als Kaestchen am
   Suchfeld davor und nimmt keinen Platz. Deshalb bleibt der Abstand in JEDER Rollposition stehen.

   ANGENOMMENE ABWEICHUNG, benannt: ueber der Linie nimmt die Bankauswahl 2.31em, hier stehen 1.67em.
   Das ist "generell weniger margins" -- die beiden Saetze des Auftraggebers ziehen dort gegeneinander,
   denn die Bankauswahl misst zwischen Suchfeld und Liste insgesamt 91.22px, also MEHR als die 61.05px,
   die vor S80 hier standen. Seit S83 sind es gemessen 43.41px (20.71 + Linie + 21.70). Wer die 2.31em
   ueber der Linie zurueckhaben will, aendert eine Zahl. Der Auftraggeber hat sich die beiden Faelle als
   Bild zeigen lassen und 1.67em gewaehlt.

   WARUM DER ABSTAND UNTER DER LINIE NICHT IN DEN KASTEN DARF -- zweimal rot belegt, und beim zweiten Mal
   war es die Fassung, die S80 ausgeliefert hat. Alles, was unter dem oberen Rand des rollenden Kastens
   Platz schafft, liegt IN ihm: es rollt mit hinaus (das war S83s Befund), und wenn es zusaetzlich in den
   Inhaltsfluss faellt, zaehlt es nicht in die Reservierung und der Dialog springt. ROT BELEGT auf einer
   Wegwerf-Kopie (margin-top an der Tabelle statt padding am Kasten): 3 Projekte, ungefiltert Knopf
   423.84, gefiltert 402.16 -- **Sprung 21.68px** (Portfolio-Bericht 392.65 -> 370.96, 21.69px). Bei 13
   Projekten springt es nicht, weil der Deckel greift; der Fehler zeigte sich also ausgerechnet nur im
   kleinen Fall. Der Ausweg ist keiner INNERHALB des Kastens, sondern das Kaestchen DAVOR: die Linie
   nimmt keinen Platz, und beide Abstaende sind margins. Die Bankauswahl macht es genauso -- dort traegt
   die Ueberschrift die Linie und den Abstand darunter, beides ausserhalb des rollenden Kastens.

   DIE AUFLAGE, UM DIE ES HIER WIRKLICH GEHT. Darueber reserviert min-height die Hoehe der UNGEFILTERTEN
   Liste, damit beim Filtern nichts springt (S48/S51). Abstand und Linie sitzen deshalb ABSICHTLICH
   AUSSERHALB dieses reservierten Kastens -- seit S83 sogar vollstaendig: der Kasten traegt weder
   border-top noch padding-top mehr (gemessen: beide 0px), nur noch margin-top, und ein margin geht in
   min-height/max-height grundsaetzlich nicht ein. Die Reservierung bleibt damit Wort fuer Wort dieselbe
   Rechnung, und sie stimmt weiter auf die Zeilen. Neu geprueft und nicht uebernommen: min-height
   gemessen 194.46 / 143.76 / 400px wie vorher, der Kasten misst jetzt genau das (194.45 / 143.76 / 400),
   weil Rahmen und Auffuellung fehlen.

   GEMESSEN, vorher und nachher, in denselben drei Zustaenden (ungefiltert / 1 Treffer / 0 Treffer) und
   an BEIDEN Orten (Rechte-Overlay und Portfolio-Bericht), 1280x800, echtes functions.js. "vorher" ist
   dabei S68s Stand (2.31em/2.31em), "nachher" dieser (1.67em/1.67em) -- beide aus DERSELBEN eingefrorenen
   Fassung des Stilblatts gebaut, damit zwischen den zwei Messungen wirklich nur diese Regel steht:
     Rechte-Overlay, 3 Projekte mit Unterzeile   .results 225.48 -> 217.16 (= 1 + 21.71 + 194.45)
                                                 Knopf 440.50 -> 423.86, in allen drei Zustaenden gleich
     Portfolio-Bericht, 3 Projekte ohne Unterzeile  .results 174.78 -> 166.46, Knopf 409.30 -> 392.66
     13 Projekte (am Deckel)                     .results 431.02 -> 422.70, Knopf 646.05 -> 629.41
   Der Knopf rueckt an allen drei Stellen um exakt 16.64px hoch = 8.32 oben + 8.32 unten, und er steht in
   jedem der drei Zustaende still. Der Inhalt ist unveraendert: die Tabelle misst 194.44 bzw. 143.74.

   S83 DARAUF, dieselben drei Zustaende, dieselben zwei Orte, neu gemessen statt uebernommen:
     Rechte-Overlay, 3 Projekte   Kasten 217.16 -> 194.45, Knopf 423.86 -> 422.87
     Portfolio-Bericht, 3 Projekte  Kasten 166.46 -> 143.76, Knopf 392.66 -> 391.67
     13 Projekte (am Deckel)      Kasten 422.70 -> 400.00, Knopf 629.41 -> 628.41
   Der Kasten verliert genau Rahmen und Auffuellung (22.71px), die als margin vor ihm wieder auftauchen;
   der Knopf steht 0.99px hoeher (der eine Pixel des Ankers) und in jedem der drei Zustaende still.

   UND SO SAEHE DER IRRTUM AUS, den das vermeidet -- zweimal rot belegt auf WEGWERF-KOPIEN:
     box-sizing:border-box (Abstand und Linie IM reservierten Kasten), S68s Masse: 3 Projekte,
       ungefiltert 225.46, gefiltert 194.45 -- Knopf springt um 31.00px (Portfolio-Bericht 31.01px)
     margin-top an der Tabelle statt padding am Kasten, S80s Masse: ungefiltert 423.84, gefiltert
       402.16 -- Knopf springt um 21.68px (Portfolio-Bericht 21.69px)
   Beide Male genau das Springen, das S48 beseitigt hat, und beide Male ist der Sprung so gross wie der
   Abstand, den jemand in den Kasten gelegt hat. Wer den Abstand IN den Kasten legt (eine Leerzeile, ein
   Trennelement in der Tabelle, ein margin daran, ein border-box), muss ihn in die Rechnung oben
   aufnehmen. Wer ihn wie hier daneben legt, nicht.

   AM SUCHFELD AUFGEHAENGT, NICHT AN DER KLASSE -- aus demselben Grund wie die Reservierung darueber:
   unter der Schwelle von drei Projekten gibt es kein Suchfeld, also auch nichts zu trennen. Gemessen,
   2 Projekte, beide Orte: computed border-top "0px none", padding-top 0px, margin-top 0px, und die
   Geometrie ist Pixel fuer Pixel die von vorher (Rechte-Overlay .results 129.63, Knopf 276.71;
   Portfolio-Bericht 95.83, Knopf 262.41). S15s Boden bleibt damit unberuehrt.

   DER LEERE FALL. Eine Trennlinie ueber dem Nichts saehe aus wie ein Fehler -- steht aber keine da: der
   Satz fuer "kein Treffer" (p.noresults) liegt INNERHALB von .results, also unter der Linie im
   reservierten Kasten. Gemessen bei 0 Treffern: der Satz steht 21.70px unter der Linie, also genau so
   weit wie sonst die erste Projektzeile. Darueber faerbt functions.js das Suchfeld rot (.error);
   dieselbe Paarung aus roter Feldlinie und grauer Trennlinie zeigt die Bankauswahl bei 0 Treffern auch.

   BEIM ROLLEN (S83): der Abstand bleibt jetzt in jeder Rollposition stehen, weil er kein padding im
   Kasten mehr ist, sondern ein margin davor. Gemessen an BEIDEN Orten, 100 Projekte, Abstand
   Linie -> oberster sichtbarer Inhalt bei scrollTop 0 / Mitte / Anschlag: 21.70 / 21.70 / 21.70 --
   vorher 21.70 / 0.00 / 0.00. Der Inhalt wird an der Kastenkante geschnitten, genau wie unten, und
   genau so weit von der Linie entfernt wie unten von ihrer (21.70).

   WENN DER BROWSER DAS NICHT KENNT: hier steht nur noch margin-top, und das ist so alt wie CSS -- kein
   var(), kein min(), kein calc(). Faellt es doch weg, ruecken Linie und Liste zusammen; die Liste, der
   Filter, der Satz fuer den leeren Fall und die Reservierung darueber arbeiten unveraendert weiter, weil
   keiner von ihnen darauf zugreift. Was passiert, wenn der Browser das KAESTCHEN mit der Linie nicht
   kennt, steht oben bei dessen Regel -- gemessen: die Linie entfaellt, der Abstand bleibt. */
.input.list.projects .search + .results { margin-top:3.34em; }
/* Der leere Fall, der aus der reservierten Hoehe erst folgt: ohne Treffer bliebe ein 400px hoher,
   wortloser Kasten stehen -- schlimmer als der Sprung, den er ersetzt. Sichtbar allein ueber
   [data-search-results="0"], dasselbe Attribut, das functions.js ohnehin auf .input.list setzt und auf
   das die h2-Regel vier Zeilen weiter oben schon steht -- kein zweiter Zaehler und kein eigenes JS.
   Anders als die Hoehenregeln darf das allgemein auf .input.list stehen: es greift nur, wo es ein
   p.noresults GIBT, und das gibt es bisher in genau einer Liste. Die Zellenauffuellung ist die der
   Tabellenzeilen darueber (5px 0.77em), damit der Satz auf der Flucht der Projektnamen steht. */
.input.list .results > p.noresults { display:none; margin:0; padding:5px 0.77em; }
.input.list[data-search-results="0"] .results > p.noresults { display:block; }
.input.list .results table { width:100%; }
.input.list .results tr td,
.input.list .results tr th { padding:5px 0.77em; font-size:1em; color:#6C7382; line-height:1.46em; }
.input.list .results tr td + td,
.input.list .results tr th + th { padding-left:0; }
.input.list .results tr td small,
.input.list .results tr th small { font-size:inherit; color:#97A3B5; line-height:inherit; }
.input.list .results tr td img:first-child,
.input.list .results tr th img:first-child,
.input.list .results tr td input[type=hidden]:first-child + img,
.input.list .results tr th input[type=hidden]:first-child + img { margin-top:0.02em; }
.input.list .results tr.title td,
.input.list .results tr.title th { font-weight:bold; }

/* Ein <label for="..."> auf einen Steuerwert (Checkbox, Eingabefeld) daneben -- wie in
   module/permissionuser.overlay.php und module/cashflow.slider.php -- soll die ganze Zelle treffen, nicht
   nur seinen Textinhalt: block statt inline füllt die Zelle über die volle Breite, damit ein Klick
   irgendwo in der Zeile denselben Wert setzt wie ein Klick auf den Text selbst. */
.input.list .results tr td label[for] { display:block; }

.input.list .results tr:not(.title) td,
.input.list .results tr:not(.title) th { cursor:pointer; }

.input.list .results tr:not(.title):hover td,
.input.list .results tr:not(.title):hover th { background-color:#F2F5F9; }
.input.list[data-list=show] .results tr.filled td,
.input.list[data-list=show] .results tr.filled th { color:inherit; }
.input.list .results tr.selected:not(.title) td,
.input.list .results tr.selected:not(.title) th { background-color:#97A3B5; color:#fff; }
.input.list .results tr.selected:not(.title) td small,
.input.list .results tr.selected:not(.title) th small { color:#F2F5F9; }
.input.list .results tr:not(.title):hover td:first-child,
.input.list .results tr:not(.title):hover th:first-child,
.input.list .results tr.selected:not(.title) td:first-child,
.input.list .results tr.selected:not(.title) th:first-child { border-top-left-radius:4px; border-bottom-left-radius:4px; }
.input.list .results tr:not(.title):hover td:last-child,
.input.list .results tr:not(.title):hover th:last-child,
.input.list .results tr.selected:not(.title) td:last-child,
.input.list .results tr.selected:not(.title) th:last-child { border-top-right-radius:4px; border-bottom-right-radius:4px; }

.input.file > label { display:inline-block; position:relative; cursor:pointer; font-size:0.92em; font-weight:bold; margin:1.25em 0; color:#2C6EEF; }
.input.file.error > label { color:#BB1A3F; }
.input.file > label:hover { color:#1a1a1a; }
.input.file input { visibility:hidden!important; position:absolute!important; left:-9999px!important; }
.input.file > ul { margin:0; padding:0; list-style:none; overflow:hidden; }
.input.file > ul > li { position:relative; display:block; overflow:hidden; float:left; clear:both; line-height:1em; margin-bottom:10px; padding:4px 4px 4px 7px; border-radius:4px; background-color:#F2F5F9; border:1px solid #F2F5F9; color:#2C6EEF; }
.input.file > ul > li.error { color:#BB1A3F; }
.input.file > ul > li span { position:relative; z-index:2;display:inline-block; }
.input.file > ul > li small { position:relative; z-index:2; display:inline-block; font-size:0.85em; line-height:1.18em; margin-left:5px; }
.input.file > ul > li a { position:relative; z-index:3; display:inline-block; color:inherit; padding:5px 5px 5px 8px; margin:-5px -5px -5px -8px; }
.input.file > ul > li a:hover { color:#fff; background-color:#1a1a1a; -webkit-box-shadow: 0px 0px 0px 1000px #1a1a1a; -moz-box-shadow: 0px 0px 0px 1000px #1a1a1a; box-shadow: 0px 0px 0px 1000px #1a1a1a; }
.input.file > ul > li:after,
.input.file > ul > li a:hover:after { display:inline-block; position:relative; z-index:2; cursor:pointer; content:'\e82d'; margin-left:8px; font-family: "profuturum-icon"; font-style: normal; font-weight: normal; speak: never; text-decoration: inherit; font-variant: normal; text-transform: none; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
.input.file > ul > li a:hover:after { position:absolute; left:100%; margin-left:3px; top:5px; }

.input.file > ul > li[data-loading] { background:transparent; border-color:#F2F5F9; }
.input.file > ul > li[data-loading]:before { position:absolute; z-index:1; content:''; top:0; left:0; width:0; bottom:0; background-color:#F2F5F9; }
.input.file > ul > li[data-loading='1']:before { width:1%; }.input.file > ul > li[data-loading='2']:before { width:2%; }.input.file > ul > li[data-loading='3']:before { width:3%; }.input.file > ul > li[data-loading='4']:before { width:4%; }.input.file > ul > li[data-loading='5']:before { width:5%; }.input.file > ul > li[data-loading='6']:before { width:6%; }.input.file > ul > li[data-loading='7']:before { width:7%; }.input.file > ul > li[data-loading='8']:before { width:8%; }.input.file > ul > li[data-loading='9']:before { width:9%; }.input.file > ul > li[data-loading='10']:before { width:10%; }.input.file > ul > li[data-loading='11']:before { width:11%; }.input.file > ul > li[data-loading='12']:before { width:12%; }.input.file > ul > li[data-loading='13']:before { width:13%; }.input.file > ul > li[data-loading='14']:before { width:14%; }.input.file > ul > li[data-loading='15']:before { width:15%; }.input.file > ul > li[data-loading='16']:before { width:16%; }.input.file > ul > li[data-loading='17']:before { width:17%; }.input.file > ul > li[data-loading='18']:before { width:18%; }.input.file > ul > li[data-loading='19']:before { width:19%; }.input.file > ul > li[data-loading='20']:before { width:20%; }.input.file > ul > li[data-loading='21']:before { width:21%; }.input.file > ul > li[data-loading='22']:before { width:22%; }.input.file > ul > li[data-loading='23']:before { width:23%; }.input.file > ul > li[data-loading='24']:before { width:24%; }.input.file > ul > li[data-loading='25']:before { width:25%; }.input.file > ul > li[data-loading='26']:before { width:26%; }.input.file > ul > li[data-loading='27']:before { width:27%; }.input.file > ul > li[data-loading='28']:before { width:28%; }.input.file > ul > li[data-loading='29']:before { width:29%; }.input.file > ul > li[data-loading='30']:before { width:30%; }.input.file > ul > li[data-loading='31']:before { width:31%; }.input.file > ul > li[data-loading='32']:before { width:32%; }.input.file > ul > li[data-loading='33']:before { width:33%; }.input.file > ul > li[data-loading='34']:before { width:34%; }.input.file > ul > li[data-loading='35']:before { width:35%; }.input.file > ul > li[data-loading='36']:before { width:36%; }.input.file > ul > li[data-loading='37']:before { width:37%; }.input.file > ul > li[data-loading='38']:before { width:38%; }.input.file > ul > li[data-loading='39']:before { width:39%; }.input.file > ul > li[data-loading='40']:before { width:40%; }.input.file > ul > li[data-loading='41']:before { width:41%; }.input.file > ul > li[data-loading='42']:before { width:42%; }.input.file > ul > li[data-loading='43']:before { width:43%; }.input.file > ul > li[data-loading='44']:before { width:44%; }.input.file > ul > li[data-loading='45']:before { width:45%; }.input.file > ul > li[data-loading='46']:before { width:46%; }.input.file > ul > li[data-loading='47']:before { width:47%; }.input.file > ul > li[data-loading='48']:before { width:48%; }.input.file > ul > li[data-loading='49']:before { width:49%; }.input.file > ul > li[data-loading='50']:before { width:50%; }.input.file > ul > li[data-loading='51']:before { width:51%; }.input.file > ul > li[data-loading='52']:before { width:52%; }.input.file > ul > li[data-loading='53']:before { width:53%; }.input.file > ul > li[data-loading='54']:before { width:54%; }.input.file > ul > li[data-loading='55']:before { width:55%; }.input.file > ul > li[data-loading='56']:before { width:56%; }.input.file > ul > li[data-loading='57']:before { width:57%; }.input.file > ul > li[data-loading='58']:before { width:58%; }.input.file > ul > li[data-loading='59']:before { width:59%; }.input.file > ul > li[data-loading='60']:before { width:60%; }.input.file > ul > li[data-loading='61']:before { width:61%; }.input.file > ul > li[data-loading='62']:before { width:62%; }.input.file > ul > li[data-loading='63']:before { width:63%; }.input.file > ul > li[data-loading='64']:before { width:64%; }.input.file > ul > li[data-loading='65']:before { width:65%; }.input.file > ul > li[data-loading='66']:before { width:66%; }.input.file > ul > li[data-loading='67']:before { width:67%; }.input.file > ul > li[data-loading='68']:before { width:68%; }.input.file > ul > li[data-loading='69']:before { width:69%; }.input.file > ul > li[data-loading='70']:before { width:70%; }.input.file > ul > li[data-loading='71']:before { width:71%; }.input.file > ul > li[data-loading='72']:before { width:72%; }.input.file > ul > li[data-loading='73']:before { width:73%; }.input.file > ul > li[data-loading='74']:before { width:74%; }.input.file > ul > li[data-loading='75']:before { width:75%; }.input.file > ul > li[data-loading='76']:before { width:76%; }.input.file > ul > li[data-loading='77']:before { width:77%; }.input.file > ul > li[data-loading='78']:before { width:78%; }.input.file > ul > li[data-loading='79']:before { width:79%; }.input.file > ul > li[data-loading='80']:before { width:80%; }.input.file > ul > li[data-loading='81']:before { width:81%; }.input.file > ul > li[data-loading='82']:before { width:82%; }.input.file > ul > li[data-loading='83']:before { width:83%; }.input.file > ul > li[data-loading='84']:before { width:84%; }.input.file > ul > li[data-loading='85']:before { width:85%; }.input.file > ul > li[data-loading='86']:before { width:86%; }.input.file > ul > li[data-loading='87']:before { width:87%; }.input.file > ul > li[data-loading='88']:before { width:88%; }.input.file > ul > li[data-loading='89']:before { width:89%; }.input.file > ul > li[data-loading='90']:before { width:90%; }.input.file > ul > li[data-loading='91']:before { width:91%; }.input.file > ul > li[data-loading='92']:before { width:92%; }.input.file > ul > li[data-loading='93']:before { width:93%; }.input.file > ul > li[data-loading='94']:before { width:94%; }.input.file > ul > li[data-loading='95']:before { width:95%; }.input.file > ul > li[data-loading='96']:before { width:96%; }.input.file > ul > li[data-loading='97']:before { width:97%; }.input.file > ul > li[data-loading='98']:before { width:98%; }.input.file > ul > li[data-loading='99']:before { width:99%; }.input.file > ul > li[data-loading='100']:before { width:100%; }
.input.file > ul > li[data-loading] a { pointer-events:none; }

.input.file.button { position:relative; display:inline-block; padding:0; }
.input.file.button > label { position:relative; z-index:2; color:inherit; margin:-2px; padding:13px; font-size:inherit; font-weight:inherit; line-height:inherit; font-family:inherit; }
.input.file.button > label:hover { color:inherit; }
.input.file.button > label [class^="icon-"]:before,
.input.file.button > label [class*=" icon-"]:before { width:auto; margin-left:0; margin-right:0.7em; }
.input.file.button > ul { display:block; position:absolute; z-index:1; top:0; left:0; right:0; bottom:0; margin:-2px; }
.input.file.button > ul > li { display:none; position:absolute; background:transparent; z-index:1; top:0; left:0; right:0; bottom:0; margin:0; padding:0; border:0; }
.input.file.button > ul > li:last-child { display:block; }
.input.file.button > ul > li:last-child > *,
.input.file.button > ul > li:last-child:after { display:none; }

.input.file.button > ul > li[data-loading] { background-color:#1a1a1a; }
.input.file.button > ul > li[data-loading]:before { background-color:#2C6EEF; }


.button.disabled { background-color:#97A3B5; color:rgba(255,255,255,0.5); }
.button:not(.disabled):hover { background-color:#121728; color:#fff; }
.button[class^="icon-"]:before, .button[class*=" icon-"]:before { margin-left:0; margin-right:0.7em; }
.button[class^="icon-"]:empty:before, .button[class*=" icon-"]:empty:before { margin-right:0; }
/* the trending glyphs are wider than the 1em icon box, which would crowd the label */
.button[class^="icon-trending-"]:before, .button[class*=" icon-trending-"]:before { width:auto; }

.button.plain { background-color:transparent; color:#2C6EEF; }
.button.plain:hover { background-color:transparent; color:#121728; }

.button.small { background-color:#F2F5F9; color:#2C6EEF; font-size:0.92em; }
.button.small.submit { background-color:#2C6EEF; color:#fff; }
.button.small.plain { background-color:transparent; color:#6C7382; }

.button.small:hover { background-color:#121728; color:#fff; }
.button.small.plain:hover { background-color:transparent; color:#121728; }

body.demo .button.fullversion,
body.demo .button.fullversion:hover { color:#97A3B5; cursor:not-allowed; }
.button.futurerelease,
.button.futurerelease:hover { color:#97A3B5 !important; cursor:not-allowed; }

.button.error { background-color:#BB1A3F; color:#fff; }

hr { display:block; border:0; margin:2.46em 0; padding:0; height:1px; width:auto; background-color:#E4E9EF; }
hr.smallmargin { margin:10px 0; }

.icon-profuturum { font-family: "profuturum-icon"; font-style: normal; font-weight: normal; speak: never; text-decoration: inherit; font-variant: normal; text-transform: none; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
div.wrapper { margin:auto; background-color:inherit; }
div.wrapper > div.top { position:fixed; z-index:100010; background-color:#fff; top:0; left:0; right:0; color:#6C7382; padding:30px; border-bottom:1px solid #E4E9EF; line-height:2.2em; }
div.wrapper > div.top .logo { height:2em; margin-top:0.1em; width:auto; float:left; }
div.wrapper > div.top .logo.custom { height:3em; margin-top:-0.5em; }
div.wrapper > div.top > ul { display:block; margin:0; padding:0; list-style:none; float:left; }
div.wrapper > div.top > ul li { position:relative; }
div.wrapper > div.top > ul.right { float:right; }

div.wrapper > div.top > ul li .count { position:absolute; top:0; right:0; text-align:center; font-size:0.65em; width:1.3em; height:1.3em; line-height:1.5em; color:#fff; border-radius:50%; background-color:#E53935; }

div.wrapper > div.top > ul i[class^="icon-"],
div.wrapper > div.top > ul i[class*=" icon-"] { position:relative; top:0.1em; font-size:1.4em; line-height:1.57em; }
div.wrapper > div.top > ul a.account { display:inline-block; width:2.2em; height:2.2em; background-color:#6C7382; color:#fff; border-radius:50%; text-align:center; }        

div.wrapper > div.top > ul a:hover,
div.wrapper > div.top > ul a.selected { color:#2C6EEF; }
div.wrapper > div.top > ul a.account:hover,
div.wrapper > div.top > ul a.account.selected { color:#fff; background-color:#2C6EEF; }
div.wrapper > div.top > ul a:hover .count,
div.wrapper > div.top > ul a.selected .count { background-color:#2C6EEF; }

div.wrapper > div.top > ul > li { display:inline-block; margin:0; padding:0; margin-left:4.5em; }

div.wrapper > div.top > a.close { display:none; }

@media only screen and (max-width: 1000px) {
    div.wrapper > div.top > ul > li { margin-left:2em; }
}
@media only screen and (max-width: 600px) {
    div.wrapper > div.top > ul.right > li { margin-left:0.6em; }
}
@media only screen and (max-width: 500px) {
    div.wrapper > div.top > ul:not(.right) { display:none; }
}
@media only screen and (max-width: 400px) {
    div.wrapper > div.top .logo { height:1.5em; margin-top:0.35em; }
}

div.wrapper > div.main { min-width:850px; padding-top:176px; padding-left:120px; padding-right:30px; padding-bottom:30px; display:block; position:relative; background-color:inherit; }
div.wrapper > div.main.tfoot_float { padding-bottom:0; }
div.wrapper > div.main > div.left { position:fixed; z-index:80; top:176px; left:30px; width:30px; text-align:center; color:#6C7382; font-size:10px; line-height:1em; background-color:inherit; }
body[data-scroll-left] div.wrapper > div.main > div.left { position:absolute; }
div.wrapper > div.main > div.left > ul { list-style:none; display:block; margin:0; padding:0; }
div.wrapper > div.main > div.left > ul > li { display:block; margin:0; margin-bottom:30px; padding:0; position:relative; }
div.wrapper > div.main > div.left > ul > li i { display:block; padding-bottom:1.8em; }
div.wrapper > div.main > div.left > ul > li i:before { font-size:2em; }
div.wrapper > div.main > div.left > ul > li i:first-child:last-child { padding-bottom:0; }
div.wrapper > div.main > div.left > ul > li a { display:block; position:relative; text-align:center; }
div.wrapper > div.main > div.left > ul > li a:hover,
div.wrapper > div.main > div.left > ul > li a.selected { color:#2C6EEF; }
div.wrapper > div.main > div.left > ul > li a span { display:block; position:absolute; bottom:0; left:50%; transform:translateX(-50%); }

body.demo div.wrapper > div.main > div.left > ul > li a.fullversion { color:#97A3B5; cursor:not-allowed; }
div.wrapper > div.main > div.left > ul > li a.futurerelease { color:#97A3B5 !important; cursor:not-allowed; }

div.wrapper > div.main > div.left a.back { width:30px; height:30px; margin-bottom:45px; font-size:0.65em; border-radius:50%; background-color:#DEE9FC; color:#2C6EEF; }
div.wrapper > div.main > div.left a.back:hover,
div.wrapper > div.main > div.left a.back.selected { background-color:#121728; color:#fff; }
div.wrapper > div.main > div.left a.back i { position:absolute; margin-left:-0.4em; top:50%; left:50%; transform:translate(-50%,-50%); }
div.wrapper > div.main > div.left a.back[href='#'] { visibility:hidden; }

@media only screen and (max-height: 760px) {
    div.wrapper > div.main > div.left > ul > li { margin-bottom:20px; }
}
@media only screen and (max-height: 715px) {
    div.wrapper > div.main > div.left > ul > li a:not(.back) i:before { font-size:1.5em; }
}
@media only screen and (max-height: 685px) {
    div.wrapper > div.main > div.left > ul > li { margin-bottom:15px; }
}
@media only screen and (max-height: 660px) {
    div.wrapper > div.main > div.left > ul > li a:not(.back) i:before { font-size:1.25em; }
}

div.wrapper > div.main > div.content > .head .primary { display:block; position:relative; text-align:right; }
div.wrapper > div.main > div.content > .head .primary h1 { display:block; float:left; margin:0; font-size:1.23em; line-height:1.875em; margin-bottom:35px; color:#061353; }
div.wrapper > div.main > div.content > .head .primary .button { margin-top:-5px; }
div.wrapper > div.main > div.content > .head .primary .button.plain + .button:not(.plain) { margin-left:30px; }
div.wrapper > div.main > div.content > .head .primary .phase { float:left; display:inline-block; font-size:0.92em; font-weight:600; line-height:2em; padding-left:0.75em; padding-right:0.75em; margin-top:0.25em; background-color:#F2F5F9; color:#2C6EEF; border-radius:5px; margin-left:30px; }
div.wrapper > div.main > div.content > .head .primary .phase:hover { background-color:#121728; color:#fff; }

div.wrapper > div.main > div.content > .head .secondary { display:block; position:relative; margin-bottom:40px; }

div.wrapper > div.main > div.content > .head .secondary ul.index { margin-top:3em; }

div.wrapper > div.main > div.content > .head .secondary ul.tab { position:absolute; right:0; bottom:0; list-style:none; display:block; margin:0; padding:0; overflow:hidden; }
div.wrapper > div.main > div.content > .head .secondary ul.tab > li { display:inline-block; margin:0; padding:0; }
div.wrapper > div.main > div.content > .head .secondary ul.tab > li.divider { position:relative; width:1px; background-color:#E4E9EF; margin-left:30px; margin-right:30px; }
div.wrapper > div.main > div.content > .head .secondary ul.tab > li.divider:before { position:absolute; content:""; width:1px; top:-500px; left:0; height:1000px; background-color:#E4E9EF; }
div.wrapper > div.main > div.content > .head .secondary ul.tab .button.small:not(.plain):hover { background-color:#F2F5F9; color:#2C6EEF; cursor:default; }

div.wrapper > div.main > div.content > .head .secondary .search { width:33%; }

div.wrapper > div.main > div.content > .head .secondary .search:not(:first-child) { margin-top:40px; }

/* Gibt es eine Tab-Leiste UND einen Kategorienfilter, wird der Filtertext auf die Mitte des Tab-Textes
   gelegt.

   Beide enden an der Unterkante von .secondary — die Leiste, weil sie dort verankert ist, der Filter, weil
   er das letzte Element im Fluss ist. Gleich hoch sind sie deshalb nicht: die Filterzeile bringt ihre
   Polsterung und die 1px-Unterlinie mit und ist ein paar Pixel höher als ein Knopf. Bei gemeinsamer
   Unterkante sitzt ihr Text damit etwas ÜBER der Mitte des Knopfs, und um genau diese Differenz geht es
   nach unten.

:has() ist die Bedingung: eine .secondary, die BEIDE enthält — gleich in welcher Reihenfolge. Ein
   Geschwister-Selektor käme nicht hin, weil der Filter auf der Rechteseite auf die Leiste folgt und auf
   overview und progress davor steht; ein Vorgänger lässt sich in CSS nicht ansprechen. Wo es keinen Filter
   gibt (cashflow, sales), greift nichts.

   Wo :has() fehlt, bleibt alles wie bisher — die Regel entfällt dann ersatzlos, und das ist genau der
   Zustand von vorher.

   position:relative statt eines Randes: die Höhe von .secondary bleibt damit unverändert, und die Leiste
   hängt an deren Unterkante. Verschöbe der Filter den Fluss, wanderte die Leiste mit ihm und der Abstand
   bliebe derselbe.

   z-index: die beiden liegen übereinander. Die Filterzeile ist volle Breite, die Leiste liegt absolut auf
   ihrer rechten Hälfte — und was oben liegt, bekommt den Klick. Der Filter gehört nach oben.

   pointer-events ist dabei die Gegenprobe: läge die volle, grösstenteils leere Filterzeile einfach obenauf,
   nähme sie der Leiste darunter die Klicks ab. Also fängt nur, was wirklich dasteht — die Einträge —, und
   der leere Rest der Zeile lässt durch. */
div.wrapper > div.main > div.content > .head .secondary:has(> ul.tab) > ul.index { position:relative; z-index:2; top:0.2em; pointer-events:none; }
div.wrapper > div.main > div.content > .head .secondary:has(> ul.tab) > ul.index > li { pointer-events:auto; }

.trend-negative { color:#BB1A3F !important; }
.trend-positive { color:#19A483 !important; }
.trend-negative:before,
.trend-positive:before { content:'\e82a'; font-size:0.7em; margin-right:0.5em; font-family: "profuturum-icon"; font-style: normal; font-weight: normal; speak: never; text-decoration: inherit; font-variant: normal; text-transform: none; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
.trend-negative:before { content:'\e829'; }

div.wrapper > div.main > div.content .table { position:relative; overflow:auto; }
div.wrapper > div.main > div.content .table > table { border:0; padding:0; margin:0; } 
div.wrapper > div.main > div.content .table[data-init] > table { min-width:100%; }
div.wrapper > div.main > div.content .table > table td,
div.wrapper > div.main > div.content .table > table th { padding:10px; text-align:left; background-color:inherit; color:inherit; }
div.wrapper > div.main > div.content .table > table tr { background-color:inherit; color:inherit; }
div.wrapper > div.main > div.content .table > table tr.alert { background-color:#FEEAE8; }
div.wrapper > div.main > div.content .table > table tr.alert .state { background-color:#fff; }
div.wrapper > div.main > div.content .table > table td { vertical-align:top; }
div.wrapper > div.main > div.content .table > table td.right,
div.wrapper > div.main > div.content .table > table th.right,
div.wrapper > div.main > div.content .table > table td[align=right],
div.wrapper > div.main > div.content .table > table th[align=right] { text-align:right; }

div.wrapper > div.main > div.content .table > table td.float,
div.wrapper > div.main > div.content .table > table th.float { position:sticky; left:0; }

div.wrapper > div.main > div.content .table > table td.focus,
div.wrapper > div.main > div.content .table > table th.focus { background-color:#F2F5F9; }

div.wrapper > div.main > div.content .table > table td.focus span.state.info,
div.wrapper > div.main > div.content .table > table th.focus span.state.info,
div.wrapper > div.main > div.content .table > table td.selected-row:not([colspan]) span.state.info,
div.wrapper > div.main > div.content .table > table th.selected-row:not([colspan]) span.state.info,
div.wrapper > div.main > div.content .table > table td.selected-col:not([colspan]) span.state.info,
div.wrapper > div.main > div.content .table > table th.selected-col:not([colspan]) span.state.info,
div.wrapper > div.main > div.content .table > table td.focused:not([colspan]) span.state.info,
div.wrapper > div.main > div.content .table > table th.focused:not([colspan]) span.state.info { background-color:#FFF; }

body[data-scroll-left] div.wrapper > div.main > div.content .table > table td.float,
body[data-scroll-left] div.wrapper > div.main > div.content .table > table th.float { position:static; }

div.wrapper > div.main > div.content .table > table td.float:last-child,
div.wrapper > div.main > div.content .table > table th.float:last-child { left:auto; right:0; }

div.wrapper > div.main > div.content .table > table td.line:not(:last-child),
div.wrapper > div.main > div.content .table > table th.line:not(:last-child) { border-right:1px solid #E4E9EF; padding-right:20px; }

div.wrapper > div.main > div.content .table > table td.line:last-child,
div.wrapper > div.main > div.content .table > table th.line:last-child { border-left:1px solid #E4E9EF; padding-left:20px; }

div.wrapper > div.main > div.content .table > table td.line + td,
div.wrapper > div.main > div.content .table > table th.line + th,
div.wrapper > div.main > div.content .table > table th.line + td,
div.wrapper > div.main > div.content .table > table td.marginleft,
div.wrapper > div.main > div.content .table > table th.marginleft { padding-left:20px; }

div.wrapper > div.main > div.content .table > table td.marginright,
div.wrapper > div.main > div.content .table > table th.marginright { padding-right:20px; }

div.wrapper > div.main > div.content .table > table tr.margintop td,
div.wrapper > div.main > div.content .table > table tr.margintop th,
div.wrapper > div.main > div.content .table > table tr.title td,
div.wrapper > div.main > div.content .table > table tr.title th { padding-top:30px; }

div.wrapper > div.main > div.content .table > table thead { font-size:0.92em; line-height:1.17em; background-color:#fff; }
div.wrapper > div.main > div.content .table > table thead .forecast { color:#6C7382; }

div.wrapper > div.main > div.content .table > table thead tr + tr th,
div.wrapper > div.main > div.content .table > table thead tr + tr td { padding-top:0; }

div.wrapper > div.main > div.content .table > table thead th.selected-row:not([colspan]),
div.wrapper > div.main > div.content .table > table thead td.selected-row:not([colspan]),
div.wrapper > div.main > div.content .table > table thead th.selected-col:not([colspan]),
div.wrapper > div.main > div.content .table > table thead td.selected-col:not([colspan]),
div.wrapper > div.main > div.content .table > table thead th.focused:not([colspan]),
div.wrapper > div.main > div.content .table > table thead td.focused:not([colspan]) { background-color:#F2F5F9; }

div.wrapper > div.main > div.content .table > table tbody { color:#6C7382; background-color:#fff; }
div.wrapper > div.main > div.content .table > table tbody .forecast { color:#97A3B5; }

div.wrapper > div.main > div.content .table > table tbody tr.title td { font-weight:bold; }
/* Folded shut, the titles ARE the table — there is nothing under them left to stand out from, and a
   page of bold rows reads as emphasis on nothing. They take the weight of ordinary body text until
   a group opens again. That is 500, not `normal`: html/body sets 500, so `normal` (400) would make
   them THINNER than the rows they are standing in for. */
div.wrapper > div.main > div.content .table > table.all-collapsed tbody tr.title td { font-weight:500; }

/* tr.title collapses the group below it (see groupCollapse* in functions.js) */
div.wrapper > div.main > div.content .table.has-groups > table tbody tr.title,
div.wrapper > div.main > div.content .table.has-groups > table thead tr > th:first-child,
div.wrapper > div.main > div.content .table.has-groups > table thead tr > th.num:first-child + th { cursor:pointer; }

/* The caret sits in the text flow right after the group name — the tfoot one can hang outside the table
   because tfoot.float is position:fixed, which a tbody row cannot do. */
/* helper::group_title() ties the caret to whatever it glues onto (the name's last word with no $after, a
   S13 tag with one) into this span, so the caret can never be stranded alone on the next line. Whatever is
   in FRONT of this span (the rest of the name, or the whole name when there is a tag) still wraps freely. */
div.wrapper > div.main > div.content .table > table tbody tr.title .group-title { white-space:nowrap; }
/* S13, seventh round: the visible gap between a name and its S13 tag (helper.inc.php, group_title()$after)
   is a margin-right HERE, on the name's own wrapper — not on the tag's side (sixth round) and not a plain
   space doing double duty (also sixth round, replaced): a margin only trails correctly for whichever
   element sits BEFORE the line break. Put it on the tag and a wrap turns it into a leading indent on the
   tag's new line; put it on the name and it sits harmlessly past the end of line one instead. This
   wrapper — and therefore this rule — exists only when group_title() actually received a tag ($after);
   the plain-name case never gets it and is unaffected.
   5px, not an em value: the earlier margin (third round, since removed) sat on .state and could reuse
   THAT element's own smaller font-size (0.76em in a table cell) to land on 5px; .group-name sits in the
   ordinary row text with no such reduction, so an em value here would not reproduce the same 5px — a
   plain px does, and matches a small-gap number this file already uses elsewhere (ul.kpi > li > small). */
div.wrapper > div.main > div.content .table > table tbody tr.title .group-name { margin-right:5px; }
/* S13: a .state tag passed into group_title()'s $after (service/permissions.php) sits smaller than the
   name and hangs off the baseline — same problem .group-toggle below solves with vertical-align:middle,
   same fix here. Scoped to ".group-title > .state", NOT to .state itself: .state is used app-wide
   (cashflow, sales, progress, accounts, budget, the member count elsewhere in permissions), and a rule on
   .state would move every pill in the application. */
div.wrapper > div.main > div.content .table > table tbody tr.title .group-title > .state { vertical-align:middle; }
/* S13, fourth round: when the tag wraps onto its own line, it needs a gap ABOVE it. CSS has no way to say
   "only when wrapped" — margin-top on a plain inline element (what .group-title is without this rule) is a
   spec-defined no-op regardless of wrap state, and the only way to make margin-top do anything at all is
   display:inline-block, which then always applies, wrapped or not: there is no middle ground. This rule
   therefore always applies a small downward shift, on every render of a tagged title, not only a wrapped
   one — a deliberate, named trade-off rather than an invisible one, per instruction. 5px reuses the small-
   gap number "ul.kpi > li > small" already uses elsewhere, not a new one. Scoped via :has() (already used
   in this file, see the .secondary:has(> ul.tab) rules above — where :has() is unsupported the rule simply
   does not apply) to a title that actually holds a tag; the tagless case (a group row, or an entry with no
   name) never gets a .state child, so :has(> .state) cannot match it at all. */
div.wrapper > div.main > div.content .table > table tbody tr.title .group-title:has(> .state) { display:inline-block; margin-top:5px; }
div.wrapper > div.main > div.content .table > table tbody tr.title .group-toggle { display:inline-block; margin-left:1.2em; width:1em; font-size:0.55em; line-height:1; vertical-align:middle; color:#97A3B5; font-family:"profuturum-icon"; font-style:normal; font-weight:normal; speak:never; text-transform:none; -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale; }
div.wrapper > div.main > div.content .table > table tbody tr.title .group-toggle:before { content:'\e823'; }
div.wrapper > div.main > div.content .table > table tbody tr.title.collapsed .group-toggle:before { content:'\e822'; }
div.wrapper > div.main > div.content .table > table tbody tr.hide-group { display:none; }
/* the group above is folded away, so the title needs no gap over it */
div.wrapper > div.main > div.content .table > table tbody tr.title.after-collapsed > td { padding-top:10px; }

/* a folded tr.title stands in for its rows: PHP writes the group totals into it, and it takes on the column
   separators the rows below would have drawn (same border as .line) */
div.wrapper > div.main > div.content .table > table tbody tr.title .group-sum { display:none; }
div.wrapper > div.main > div.content .table > table tbody tr.title.collapsed .group-sum { display:inline; }
div.wrapper > div.main > div.content .table > table tbody tr.title.collapsed > td.line-collapsed:not(:last-child) { border-right:1px solid #E4E9EF; padding-right:20px; }
div.wrapper > div.main > div.content .table > table tbody tr.title.collapsed > td.line-collapsed + td { padding-left:20px; } /* td.line + td does this for the real rows */
div.wrapper > div.main > div.content .table > table tbody tr.title.collapsed > td.line-collapsed:last-child { border-left:1px solid #E4E9EF; padding-left:20px; }

/* while searching, a hit inside a collapsed group must surface; non-matches stay hidden via tr.hidden */
div.wrapper > div.main > div.content .table[data-search=true] > table tbody tr.hide-group { display:table-row; }

div.wrapper > div.main > div.content .table > table tbody tr:not(:first-child) td,
div.wrapper > div.main > div.content .table > table tfoot tr:not(:first-child) td,
div.wrapper > div.main > div.content .table > table tfoot tr:not(:first-child) th { border-top:1px solid #E4E9EF; }
div.wrapper > div.main > div.content .table > table tbody tr.noborder + tr:not(:first-child) td,
div.wrapper > div.main > div.content .table > table tfoot tr.noborder + tr:not(:first-child) td,
div.wrapper > div.main > div.content .table > table tfoot tr.noborder + tr:not(:first-child) th,
div.wrapper > div.main > div.content .table > table tbody tr.title + tr:not(:first-child) td,
div.wrapper > div.main > div.content .table > table tfoot tr.title + tr:not(:first-child) td,
div.wrapper > div.main > div.content .table > table tfoot tr.title + tr:not(:first-child) th { border-top:0; }
div.wrapper > div.main > div.content .table > table tbody tr:hover:not(.no-hover):not(.title):not(.info),
div.wrapper > div.main > div.content .table > table tbody tr[data-href-selected],
div.wrapper > div.main > div.content .table > table tbody tr.selected,
div.wrapper > div.main > div.content .table > table tbody th.selected-col:not([colspan]),
div.wrapper > div.main > div.content .table > table tbody td.selected-col:not([colspan]),
div.wrapper > div.main > div.content .table > table tbody th.focused:not([colspan]),
div.wrapper > div.main > div.content .table > table tbody td.focused:not([colspan]) { background-color:#F2F5F9; }

/* Eine Ladezeile ist nichts zum Anfassen — sie leuchtet nicht mehr auf.
   Der Hover der Zeile darüber sagt "hier ist etwas, das auf dich reagiert". Eine Zeile, die nur den Kreisel
   trägt, hat aber noch gar keinen Inhalt: anklicken lässt sich nichts, und das Aufleuchten verspricht etwas,
   das erst gleich kommt.

   Angesetzt wird am Kreisel, NICHT an der Rechtetabelle und nicht an data-permissions-project/-load. Das ist
   kein Geschmack, das ist gemessen: der Lader nimmt diese beiden Attribute beim Anfordern weg
   (functions.js:3607/3627, removeAttr), und im Browser steht die Zeile danach voellig nackt da — class="",
   kein einziges Attribut. Eine Regel auf die Attribute traefe im Moment des Hoverns also nichts mehr. Was
   uebrig bleibt, ist .overview-loading, und das ist zugleich das Merkmal ALLER Ladeanzeigen im Haus.

   td:only-child ist die andere Haelfte und meint woertlich "die Zeile traegt NUR das Ladesymbol". Damit
   bleibt die Projektuebersicht (module/overview.php) aussen vor: deren kalte Zeile fuehrt zehn Zellen mit
   Name, Firma und Zustand und haengt an einem data-href — die ist waehrend des Ladens sehr wohl anklickbar
   und soll ihren Hover behalten.

   Als eigene Regel statt als :not() in der Regel darueber, aus demselben Grund wie bei den :has()-Regeln
   weiter oben: wo :has() nicht unterstuetzt wird, faellt so nur diese Zeile weg (Zustand wie bisher). In ein
   :not() gesetzt haette ein unbekanntes :has() den GANZEN Selektor ungueltig gemacht — und damit jeder
   gewoehnlichen Tabellenzeile im Haus ihren Hover genommen.

   Nur der Hintergrund, sonst nichts: gemessen zeigt diese Zeile weder Handzeiger (cursor:auto) noch
   Tastaturfokus noch ein Klickverhalten, und die Spaltenhervorhebung aus functions.js:797 laesst sie wegen
   des colspan ohnehin aus. Eine cursor- oder outline-Erklaerung waere hier Zierde ohne Messung. */
div.wrapper > div.main > div.content .table > table tbody tr:hover:not(.no-hover):not(.title):not(.info):has(> td:only-child > .overview-loading) { background-color:inherit; }

div.wrapper > div.main > div.content .table[data-search=true] > table tbody tr.hidden,
div.wrapper > div.main > div.content .table:not([data-search-results-visible="0"]) > table tbody tr.protected,
div.wrapper > div.main > div.content .table[data-filter=true] > table tbody tr:not(.filtered):not(.title),
div.wrapper > div.main > div.content .table[data-search=true] > table tfoot,
div.wrapper > div.main > div.content .table[data-filter=true] > table tfoot,
div.wrapper > div.main > div.content .table:not([data-search-results="0"]) [data-search-empty],
div.wrapper > div.main > div.content .table:not([data-search-results="0"]) + [data-search-empty] { display:none!important; }

/* S118: solange nach Projekt lädt, darf im Rumpf nichts stehen ausser dem einen Kreisel unten (data-
   permissions-loading-row) -- weder eine Projektüberschrift (tr.title) noch ein leerer Platzhalter
   (data-permissions-project), und auch keine Zeile, die ein schon eingetroffener Stapel per replaceWith()
   frisch eingesetzt hat: die trägt keinen der beiden Marker mehr, aber sie steht innerhalb DESSELBEN
   tbody und faellt damit unter dieselbe Regel, solange das Attribut an der Tabelle noch steht.
   permissionsRowsLoad() (functions.js) nimmt es erst weg, wenn der letzte Stapel da ist -- erst dann
   erscheint alles auf einmal, wie bei "nach Zugriff", wo es ohnehin nichts zu stapeln gibt. */
div.wrapper > div.main > div.content .table[data-permissions-loading] > table tbody tr:not([data-permissions-loading-row]) { display:none!important; }

div.wrapper > div.main > div.content .table[data-search=true][data-search-results="0"] tr[data-search-empty] { display:table-row!important; }
div.wrapper > div.main > div.content .table[data-search=true][data-search-results="0"] [data-search-empty]:not(tr),
div.wrapper > div.main > div.content .table[data-search=true][data-search-results="0"] + [data-search-empty] { display:block!important; }

div.wrapper > div.main > div.content .table > table thead.float { display:table; position:fixed; z-index:99; top:90px; background-color:#fff; -webkit-box-shadow: 0px -2000px 0px 2000px #ffffff; -moz-box-shadow: 0px -2000px 0px 2000px #ffffff; box-shadow: 0px -2000px 0px 2000px #ffffff; }
div.wrapper > div.main > div.content .table > table thead.float:after { content:''; position:absolute; z-index:98; left:-1000px; right:-1000px; top:0; bottom:0; -webkit-box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.25); -moz-box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.25); box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.25); pointer-events:none; }
div.wrapper > div.main > div.content .table > table thead.float:before,
div.wrapper > div.main > div.content .table > table tfoot.float:before { content:''; position:fixed; z-index:1; right:0; width:30px; height:1000px; top:inherit; background-color:inherit; }
div.wrapper > div.main > div.content .table > table tfoot.float:before { z-index:2; }

div.wrapper > div.main > div.content .table > table tfoot { background-color:#061353; color:#fff; }
div.wrapper > div.main > div.content .table > table tfoot td,
div.wrapper > div.main > div.content .table > table tfoot th { border-color:#4A4180!important; }

div.wrapper > div.main > div.content .table > table tfoot tr.secondary td,
div.wrapper > div.main > div.content .table > table tfoot tr.secondary th { font-weight:normal; color:#97A3B5; }

div.wrapper > div.main > div.content .table > table tfoot.float { display:table; position:fixed; z-index:120; bottom:0; -webkit-box-shadow: 0px 2000px 0px 2000px #061353; -moz-box-shadow: 0px 2000px 0px 2000px #061353; box-shadow: 0px 2000px 0px 2000px #061353; }
div.wrapper > div.main > div.content .table > table tfoot.float + tfoot { visibility:hidden; }

div.wrapper > div.main > div.content .table > table thead.float tr,
div.wrapper > div.main > div.content .table > table tfoot.float tr { position:relative; }

div.wrapper > div.main > div.content .table:not([data-float-sticky="null"]) > table thead.float td,
div.wrapper > div.main > div.content .table:not([data-float-sticky="null"]) > table thead.float th,
div.wrapper > div.main > div.content .table:not([data-float-sticky="null"]) > table tfoot.float td,
div.wrapper > div.main > div.content .table:not([data-float-sticky="null"]) > table tfoot.float th { top:auto!important; }

div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table thead.float td.float,
div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table thead.float th.float,
div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table tfoot.float td.float,
div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table tfoot.float th.float { visibility:hidden; z-index:99; }

div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table thead.float td.float > div,
div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table thead.float th.float > div,
div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table tfoot.float td.float > div,
div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table tfoot.float th.float > div { visibility:visible; position:fixed; z-index:110; top:inherit; left:inherit; right:inherit; height:inherit; width:inherit; padding:inherit; border:inherit; border-color:transparent; will-change:transform; }

div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table thead.float td.float > div:empty,
div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table thead.float th.float > div:empty,
div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table tfoot.float td.float > div:empty,
div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table tfoot.float th.float > div:empty { height:inherit; }

div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table thead.float td.float:before,
div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table thead.float th.float:before,
div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table tfoot.float td.float:before,
div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table tfoot.float th.float:before,
div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table thead.float td.float:after,
div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table thead.float th.float:after,
div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table tfoot.float td.float:after,
div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table tfoot.float th.float:after { visibility:visible; content:''; position:fixed; top:inherit; left:inherit; right:inherit; background-color:inherit; height:inherit; width:inherit; padding:inherit; border:inherit; }
div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table thead.float td.float:before,
div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table thead.float th.float:before { border-color:#E4E9EF; }
div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table tfoot.float td.float:before,
div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table tfoot.float th.float:before,
div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table tfoot.float td.float:after,
div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table tfoot.float th.float:after { height:100px; }

div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table tfoot.float tr.preview:not(.shown) td.float:before,
div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table tfoot.float tr.preview:not(.shown) th.float:before,
div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table tfoot.float tr:last-child td.float:before,
div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table tfoot.float tr:last-child th.float:before { height:1000px; }

div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table thead.float td.float:last-child > div,
div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table thead.float th.float:last-child > div,
div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table tfoot.float td.float:last-child > div,
div.wrapper > div.main > div.content .table[data-float-sticky="null"] > table tfoot.float th.float:last-child > div { right:30px !important; }

div.wrapper > div.main > div.content .table > table thead.float tr td.float:first-child > div:after,
div.wrapper > div.main > div.content .table > table thead.float tr th.float:first-child > div:after,
div.wrapper > div.main > div.content .table > table tfoot.float tr td.float:first-child > div:after,
div.wrapper > div.main > div.content .table > table tfoot.float tr th.float:first-child > div:after,
div.wrapper > div.main > div.content .table > table thead.float tr td.float:last-child > div:after,
div.wrapper > div.main > div.content .table > table thead.float tr th.float:last-child > div:after,
div.wrapper > div.main > div.content .table > table tfoot.float tr td.float:last-child > div:after,
div.wrapper > div.main > div.content .table > table tfoot.float tr th.float:last-child > div:after { content:''; position:absolute; z-index:1; top:-1000px; bottom:0; right:100%; width:1000px; background-color:#fff; }
div.wrapper > div.main > div.content .table > table tfoot.float tr td.float:first-child > div:after,
div.wrapper > div.main > div.content .table > table tfoot.float tr th.float:first-child > div:after,
div.wrapper > div.main > div.content .table > table tfoot.float tr td.float:last-child > div:after,
div.wrapper > div.main > div.content .table > table tfoot.float tr th.float:last-child > div:after { top:0px; bottom:-1000px; background-color:#061353; }
div.wrapper > div.main > div.content .table > table thead.float tr:not(:last-child) td.float:first-child > div:after,
div.wrapper > div.main > div.content .table > table thead.float tr:not(:last-child) th.float:first-child > div:after,
div.wrapper > div.main > div.content .table > table thead.float tr:not(:last-child) td.float:last-child > div:after,
div.wrapper > div.main > div.content .table > table thead.float tr:not(:last-child) th.float:last-child > div:after { bottom:-2px; }
div.wrapper > div.main > div.content .table > table tfoot.float tr:not(:first-child) td.float:first-child > div:after,
div.wrapper > div.main > div.content .table > table tfoot.float tr:not(:first-child) th.float:first-child > div:after,
div.wrapper > div.main > div.content .table > table tfoot.float tr:not(:first-child) td.float:last-child > div:after,
div.wrapper > div.main > div.content .table > table tfoot.float tr:not(:first-child) th.float:last-child > div:after { top:-2px; }

div.wrapper > div.main > div.content .table > table thead.float tr td.float:last-child > div:after,
div.wrapper > div.main > div.content .table > table thead.float tr th.float:last-child > div:after,
div.wrapper > div.main > div.content .table > table tfoot.float tr td.float:last-child > div:after,
div.wrapper > div.main > div.content .table > table tfoot.float tr th.float:last-child > div:after { right:auto; left:100%; }

div.wrapper > div.main > div.content .table[data-float-sticky="unavailable"] > table td.float,
div.wrapper > div.main > div.content .table[data-float-sticky="unavailable"] > table th.float { position:static; }

div.wrapper > div.main > div.content .table[data-float-sticky="unavailable"] > table thead.float > tr,
div.wrapper > div.main > div.content .table[data-float-sticky="unavailable"] > table tfoot.float > tr { position:static; max-height:inherit; top:inherit; background:inherit; }
div.wrapper > div.main > div.content .table[data-float-sticky="unavailable"] > table thead.float > tr:before,
div.wrapper > div.main > div.content .table[data-float-sticky="unavailable"] > table tfoot.float > tr:before,
div.wrapper > div.main > div.content .table[data-float-sticky="unavailable"] > table thead.float > tr:after,
div.wrapper > div.main > div.content .table[data-float-sticky="unavailable"] > table tfoot.float > tr:after { content:''; position:fixed; max-height:inherit; height:1000px; top:inherit; left:0; width:120px; background-color:inherit; }
div.wrapper > div.main > div.content .table[data-float-sticky="unavailable"] > table tfoot.float > tr:before,
div.wrapper > div.main > div.content .table[data-float-sticky="unavailable"] > table tfoot.float > tr:after { top:auto; bottom:0; }

div.wrapper > div.main > div.content .table[data-float-sticky="unavailable"] > table thead.float > tr:after,
div.wrapper > div.main > div.content .table[data-float-sticky="unavailable"] > table tfoot.float > tr:after { left:auto; width:30px; right:0; }

div.wrapper > div.main > div.content .table[data-float-sticky="unavailable"]:not([data-scroll="0"]) > table tfoot tr.preview > :first-child > div:before { display:none; }
div.wrapper > div.main > div.content .table[data-float-sticky="unavailable"] > table thead.float tr td.float:first-child > div:after,
div.wrapper > div.main > div.content .table[data-float-sticky="unavailable"] > table thead.float tr th.float:first-child > div:after,
div.wrapper > div.main > div.content .table[data-float-sticky="unavailable"] > table tfoot.float tr td.float:first-child > div:after,
div.wrapper > div.main > div.content .table[data-float-sticky="unavailable"] > table tfoot.float tr th.float:first-child > div:after,
div.wrapper > div.main > div.content .table[data-float-sticky="unavailable"] > table thead.float tr td.float:last-child > div:after,
div.wrapper > div.main > div.content .table[data-float-sticky="unavailable"] > table thead.float tr th.float:last-child > div:after,
div.wrapper > div.main > div.content .table[data-float-sticky="unavailable"] > table tfoot.float tr td.float:last-child > div:after,
div.wrapper > div.main > div.content .table[data-float-sticky="unavailable"] > table tfoot.float tr th.float:last-child > div:after { display:none; }

div.wrapper > div.main > div.content .table > table tfoot tr.preview:not(.shown) + tr,
div.wrapper > div.main > div.content .table > table tfoot tr.preview:not(.shown) + tr + tr,
div.wrapper > div.main > div.content .table > table tfoot tr.preview:not(.shown) + tr + tr + tr,
div.wrapper > div.main > div.content .table > table tfoot tr.preview:not(.shown) + tr + tr + tr + tr,
div.wrapper > div.main > div.content .table > table tfoot tr.preview:not(.shown) + tr + tr + tr + tr + tr,
div.wrapper > div.main > div.content .table > table tfoot tr.preview:not(.shown) + tr + tr + tr + tr + tr + tr,
div.wrapper > div.main > div.content .table > table tfoot tr.preview:not(.shown) + tr + tr + tr + tr + tr + tr + tr,
div.wrapper > div.main > div.content .table > table tfoot tr.preview:not(.shown) + tr + tr + tr + tr + tr + tr + tr + tr,
div.wrapper > div.main > div.content .table > table tfoot tr.preview:not(.shown) + tr + tr + tr + tr + tr + tr + tr + tr + tr,
div.wrapper > div.main > div.content .table > table tfoot tr.preview:not(.shown) + tr + tr + tr + tr + tr + tr + tr + tr + tr + tr { display:none; }

div.wrapper > div.main > div.content .table > table tfoot tr.preview > :first-child:not(.float) { position:relative; }
div.wrapper > div.main > div.content .table > table tfoot tr.preview > :first-child > div { pointer-events:none; }
div.wrapper > div.main > div.content .table > table tfoot tr.preview > :first-child > div:before { cursor:pointer; pointer-events:auto; content:'\e822'; z-index:110; font-size:0.7em; position:absolute; top:0.5em; margin:0; padding:1em; margin-right:0.5em; right:100%; color:#fff; font-family: "profuturum-icon"; font-style: normal; font-weight: normal; speak: never; text-decoration: inherit; font-variant: normal; text-transform: none; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
div.wrapper > div.main > div.content .table > table tfoot tr.preview.shown > :first-child > div:before { content:'\e823'; }
/* A FLOATING tfoot hangs its caret to the LEFT of the table, in the dark background its box-shadow
   bleeds 2000px outwards. An unfloated tfoot has no such spill — out there is the white page, and on a
   table that starts at the viewport edge, off-screen entirely. So it takes the caret back INSIDE the
   cell, in the text flow right after the label, exactly like the group carets in the body. It sits on
   the dark footer there, so it is white like everything else in it. */
div.wrapper > div.main > div.content .table > table tfoot:not(.float) tr.preview > :first-child > div:before { display:none; }
div.wrapper > div.main > div.content .table > table tfoot:not(.float) tr.preview > :first-child { cursor:pointer; }
div.wrapper > div.main > div.content .table > table tfoot:not(.float) tr.preview > :first-child > div { white-space:nowrap; }
div.wrapper > div.main > div.content .table > table tfoot:not(.float) tr.preview > :first-child > div:after { content:'\e822'; display:inline-block; margin-left:1.2em; width:1em; font-size:0.55em; line-height:1; vertical-align:middle; font-family:"profuturum-icon"; font-style:normal; font-weight:normal; speak:never; text-transform:none; -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale; }
div.wrapper > div.main > div.content .table > table tfoot:not(.float) tr.preview.shown > :first-child > div:after { content:'\e823'; }

div.wrapper > div.main > div.content .table[data-scrollable] thead .scrollable { display:block; position:fixed; right:30px; }
div.wrapper > div.main > div.content .table[data-scrollable] thead.float + thead .scrollable,
div.wrapper > div.main > div.content .table[data-scrollable="0"] thead .scrollable { display:none; }

div.wrapper > div.main > div.content .table td span.state { font-size:0.76em; }
div.wrapper > div.main > div.content .table th span.state { font-size:0.83em; }

div.wrapper > div.main > div.content .tiles > ul { display:flex; flex:auto auto; flex-wrap:wrap; list-style:none; margin:0; padding:0; margin-left:-30px; }
div.wrapper > div.main > div.content .tiles > ul > li { display:block; position:relative; box-sizing:border-box; border:1px solid #E4E9EF; border-radius:4px; width:calc(33.33% - 32px); padding:20px; margin-left:30px; margin-bottom:30px; }
div.wrapper > div.main > div.content .tiles > ul > li.hidden,
div.wrapper > div.main > div.content .tiles:not([data-search-results-visible="0"]) > ul > li.protected { display:none !important; }
div.wrapper > div.main > div.content .tiles > ul > li.alert { background-color:#FEEAE8; }
div.wrapper > div.main > div.content .tiles > ul > li.alert .state { background-color:#fff; }
div.wrapper > div.main > div.content .tiles > ul > li > h2 { margin:0; padding:0; font-size:1.08em; line-height:1.57em; font-weight:700; color:#061353; }
div.wrapper > div.main > div.content .tiles > ul > li > h3 { margin:0; padding:0; color:#97A3B5; font-size:0.92em; line-height:1.17em; font-weight:500; }
div.wrapper > div.main > div.content .tiles > ul > li > span.state { position:absolute; top:20px; right:20px; }
div.wrapper > div.main > div.content .tiles > ul > li > p { margin:0; margin-top:10px; font-weight:500; line-height:1.46em; color:#6C7382; }
div.wrapper > div.main > div.content .tiles > ul > li > ul.kpi { margin-top:30px; }
div.wrapper > div.main > div.content .tiles > ul > li[data-href]:hover { background-color:#F2F5F9; }

@media screen and (min-width: 1900px) {
    div.wrapper > div.main > div.content .tiles > ul > li { width:calc(25% - 32px); }
}
@media screen and (max-width: 1450px) {
    div.wrapper > div.main > div.content .tiles > ul > li { width:calc(50% - 32px); }
}


[data-href] { cursor:pointer; }
.clear { display:block; clear:both; }

div.overlay:not(.shown) > * { display:none !important; }

div.overlay.shown { overflow:auto; z-index:100000!important; } 
div.overlay.shown > div.container { display:table; position:relative; z-index:9999999; width:100%; height:100%; margin:auto; overflow:hidden; }
div.overlay.shown > div.container > .padding { display:table-cell; vertical-align:middle; padding:100px; }
div.overlay.shown > div.container > .padding > div.content { display:block; position:relative; margin:auto; max-width:370px; background-color:#fff; padding:40px 30px; border-radius:4px; -webkit-border-radius:4px; -moz-border-radius:4px; }
/* S64: der Selektor "div.overlay.loading > … > div.content" ist hier WEG. Er liess den Dialog
   zusammenfallen, solange nachgeladen wurde -- auch dann, wenn er Inhalt hatte. GEMESSEN, jede Ursache
   einzeln und jede allein ausreichend (offener Dialog mit Inhalt, 1280x800):
     nur .loading am OVERLAY, Inhalt da   -> 0x0   <- diese Regel, jetzt entfernt
     nur :empty                           -> 0x0   <- bleibt, und deckt das Öffnen ab
     nur .hide am Inhalt                  -> 0x0   <- bleibt
     nur .loading am INHALT               -> 430x178, keine Wirkung
   Der leere Fall verliert dadurch nichts: beim Öffnen aus dem geschlossenen Zustand leert open() den
   Inhalt weiter, :empty greift also wie vorher. Nur beim NACHLADEN eines stehenden Dialogs bleibt der
   Rahmen jetzt stehen -- gemessen 0 von 194 Bildern leer, statt 128 von 163. */
div.overlay.shown > div.container > .padding > div.content.hide,
div.overlay.shown > div.container > .padding > div.content:empty { width:0 !important; height:0 !important; position:static; overflow:hidden; background:none; padding:0; border-radius:0; -webkit-border-radius:0; -moz-border-radius:0; }

div.overlay > div.container > .padding > div.content h2:first-child { margin-top:0; }

/* S10: die Rückfrage einer Aktion, die aus dem eigenen Formular des Overlays heraus gestellt wird (siehe
   confirmationLayer() in functions.js), steht ÜBER diesem Formular statt an seiner Stelle -- eine eigene,
   kleine Ebene innerhalb desselben div.overlay, keine dritte Fläche neben Slider und Overlay. Das Formular
   dahinter bleibt dabei im DOM stehen (siehe .padding > div.content[data-confirm-blocked] unten) und wird
   nur optisch abgedeckt, nicht ersetzt. */
/* S49: position:FIXED, nicht absolute -- der Bezugspunkt ist das Sichtfenster, nicht der gerollte Inhalt.
   div.container ist position:relative UND display:table: es waechst mit dem Formular ueber die Fensterhoehe
   hinaus (div.overlay ist der Roller, overflow:auto), und ein absolut positioniertes Kind spannt sich dann
   ueber diese GESAMTE gewachsene Hoehe statt ueber das Bild. GEMESSEN im echten Browser (1280x800, hohes
   Rechte-Overlay, Behaelter 2553px): der Rueckfragekasten stand bei Rollposition oben auf y=1131..1422 --
   331px UNTER dem Fensterrand -- und bei Rollposition unten auf y=-622..-331, also komplett darueber. In
   KEINER der beiden Stellungen war er zu sehen. Mit fixed steht er in beiden auf y=254..546.
   position:fixed ist hier kein neues Muster: der Ladekringel derselben Flaeche (div.slider +
   div.overlay.loading:after, weiter unten) haengt aus demselben Grund schon am Fenster.

   Der Hintergrund ist derselbe wie der eines gewoehnlichen Overlays -- rgba(26,26,26,0.1), der Wert aus
   "div.slider + div.overlay.shown" unten, nicht laenger ein Sonderwert (0.55). Damit sich nicht ZWEI
   Hintergruende addieren, wird der des Overlays darunter verborgen, solange diese Ebene steht (Regel
   direkt darunter). */
div.overlay.shown > div.container > div.confirm { display:table; position:fixed; top:0; right:0; bottom:0; left:0; width:100%; height:100%; z-index:10; background-color:rgba(26,26,26,0.1); }

/* Verbergen, nicht entfernen: nur die FARBE des unteren Hintergrunds faellt weg, das Element bleibt
   unveraendert stehen. Das ist der Unterschied, der die Aufgaben dieses Hintergrunds rettet -- er ist
   naemlich mehr als Farbe: er ist der Roller (overflow:auto), der Klickfang des Rand-Doppelklick-Waechters
   ($(document).on('dblclick','body > div.overlay.shown') in functions.js) und traegt die Stapelordnung
   (z-index:101000). Alle drei haengen am Element, keine an seiner background-color; ein display:none oder
   ein Abraeumen haette genau sie mitgenommen.
   Das Attribut setzt/entfernt confirmationLayer()/closeConfirmationLayer() -- dieselben zwei Stellen, die
   die Ebene anlegen und abraeumen, also auch bei Tiefe (Overlay -> Rueckfrage -> Rueckfrage) nur einmal.
   Die Spezifitaet (0,3,2) liegt bewusst ueber der von "div.slider + div.overlay.shown" (0,2,2) unten --
   sonst entschiede die Reihenfolge im Blatt, und diese Regel steht weiter oben als jene. */
div.slider + div.overlay.shown[data-confirm-layer] { background-color:transparent; }
div.overlay.shown > div.container > div.confirm > .padding { display:table-cell; vertical-align:middle; padding:40px; }
div.overlay.shown > div.container > div.confirm > .padding > .content { display:block; position:relative; margin:auto; max-width:370px; background-color:#fff; padding:40px 30px; border-radius:4px; -webkit-border-radius:4px; -moz-border-radius:4px; box-shadow:0 4px 24px rgba(0,0,0,0.35); }
div.overlay.shown > div.container > div.confirm > .padding > .content h2:first-child { margin-top:0; }

/* Deckt die Ebene oben das Formular nur optisch ab, bliebe es per Maus über Lücken zwischen den zentrierten
   Elementen trotzdem erreichbar -- blockUnderlyingForm() (functions.js) setzt dieses Attribut zusätzlich zum
   tabindex="-1" auf jedem Feld, solange die Ebene steht. */
div.overlay.shown > div.container > .padding > div.content[data-confirm-blocked] { pointer-events:none; }

div.slider,
div.slider:before,
div.slider > div.padding { width:100%; max-width:600px; background-color:#fff; }
div.slider.extended { max-width:90%; }

/* S56: das auskommentierte overflow unten ist NACHGESEHEN, nicht uebersehen -- und es bleibt aus.

   Die Geschichte: es kam schon auskommentiert auf die Welt. `git log -S` ueber diese Zeichenkette findet
   genau einen Commit (8ac12476, "First frontend version", 07.07.2023 -- der zweite Commit des Repos, mit
   dem style.css ueberhaupt entstand), und `git log -L` ueber diese Zeile findet seither keine Aenderung.
   Es hat also NIEMAND etwas abgeschaltet; hier stand nie etwas an. Der Autor kannte overflow sehr wohl --
   er hat es im selben Block bei div.slider > div.extension und dessen div.content bewusst gesetzt.

   Und es waere heute wirkungslos. GEMESSEN (echtes Chrome, 1280x800, Inhalt 4322px, Seite dahinter nicht
   rollbar), erreichbare Hoehe des Inhalts:
     wie heute (auskommentiert)  -> 775px
     overflow:hidden gesetzt     -> 775px
     overflow-y:auto gesetzt     -> 775px
   Kein Unterschied, und der Grund steht in dieser Regel selbst: mit top:0, bottom:auto und min-height:100%
   hat der Slider KEINE gedeckelte Hoehe -- er waechst mit seinem Inhalt. Wo nichts ueberlaeuft, gibt es
   nichts zu verbergen und nichts zu rollen. Ein `overflow` bekaeme erst dann Bedeutung, wenn die Hoehe
   gedeckelt wuerde, und das waere eine andere Entscheidung als diese Zeile.

   Was einen zu hohen Slider stattdessen traegt: der Roller des DOKUMENTS. Die slider-Verzweigung des
   Fensterhandlers in functions.js schaltet ihn dafuer zwischen position:fixed und position:absolute um.
   Dieses Mittel war intakt, wurde aber beim Oeffnen nicht angefragt -- behoben in functions.js
   (animationend), nicht hier. Der Hilfe-Slider braucht beides nicht: er bringt seinen eigenen Roller mit
   (siehe "Help Slider" weiter unten, .help-content{overflow-y:auto}) und war als einziger nie betroffen --
   gemessen 55875 von 55882px erreichbar, 2236 von 2236 Marken. */
div.slider { display:none; position:fixed; z-index:99999; -webkit-transform:translate3d(100%,0,0); transform:translate3d(100%,0,0); top:0; right:0; min-height:100%; transition:max-width 0.1s linear; /*overflow:hidden;*/ }
div.slider { width:90%; }

div.slider:before { display:block; content:" "; position:absolute; z-index:100; display:block; top:0; right:0; min-height:100%; }
div.slider:before,
div.slider.extended { /*box-shadow: 0 0 15px 0 rgba(199, 203, 205, 0.75);*/ border-left:1px solid #E4E9EF; }

.notransition { transition:none !important; }

div.slider.slide-in,
div.slider.slide-out { display:block; -webkit-animation: transition-slider-in .10s normal; animation: transition-slider-in .10s normal; }
div.slider.slide-out { -webkit-animation: transition-slider-out .10s normal; animation: transition-slider-out .10s normal; }

@-webkit-keyframes transition-slider-in {
    from { -webkit-transform:translate3d(100%,0,0); transform:translate3d(100%,0,0); }
    to { -webkit-transform: translate3d(0,0,0); transform: translate3d(0,0,0); }
}
@keyframes transition-slider-in {
    from { -webkit-transform:translate3d(100%,0,0); transform:translate3d(100%,0,0); }
    to { -webkit-transform: translate3d(0,0,0); transform: translate3d(0,0,0); }
}

@-webkit-keyframes transition-slider-out {
    from { -webkit-transform: translate3d(0,0,0); transform: translate3d(0,0,0); }
    to { -webkit-transform:translate3d(100%,0,0); transform:translate3d(100%,0,0); }
}
@keyframes transition-slider-out {
    from { -webkit-transform: translate3d(0,0,0); transform: translate3d(0,0,0); }
    to { -webkit-transform:translate3d(100%,0,0); transform:translate3d(100%,0,0); }
}

div.slider.shown { display:block; -webkit-transform: translate3d(0,0,0); transform: translate3d(0,0,0); }

div.slider > div.padding { position:relative; z-index:200; float:right; }
div.slider > div.extension { position:absolute; display:none; top:0; left:0; right:500px; bottom:0; min-width:0; z-index:50; overflow:hidden;  background-color:inherit; }
div.slider.extended > div.extension { display:block; }

div.slider > div.padding > [data-slider="false"],
div.slider > div.extension > [data-slider="false"] { position:absolute; top:125px; right:30px; z-index:10; }
div.slider > div.extension > [data-slider="false"] { display:none; }
div.slider > div.padding > [data-slider="false"] > i,
div.slider > div.extension > [data-slider="false"] > i { background-color:transparent; color:#1a1a1a; border-radius:50%; padding:5px; margin-left:1em; width:2.3em; height:2.3em; }
div.slider > div.padding > [data-slider="false"]:hover > i,
div.slider > div.extension > [data-slider="false"]:hover > i { background-color:#1a1a1a; color:#fff; }

div.slider > div.padding > div.content,
div.slider > div.extension > div.content { display:block; padding:30px; padding-top:176px; padding-bottom:50px; }
div.slider > div.padding > div.content.hide,
div.slider > div.extension > div.content.hide { display:none; }

div.slider > div.extension > div.content { position:absolute; top:0; left:0; right:0; bottom:0; overflow:hidden; z-index:5; }

div.slider > div.padding > div.content h3 { font-size:1.2em; }

@media screen and (max-width: 1020px) {
    div.slider.extended { max-width:500px; }
    div.slider > div.extension { right:auto; z-index:300; min-width:100%; }
    div.slider > div.extension > [data-slider="false"] { display:block; }
}

div.slider + div.overlay { opacity:0; }

div.slider + div.overlay.shown,
div.slider.shown + div.overlay,
div.slider.loading + div.overlay,
div.slider.slide-in + div.overlay { display:block !important; z-index:99998; transition:opacity 0.1s linear; background-color:rgba(26,26,26,0.1); opacity:1; position:fixed; top:0; right:0; left:0; bottom:0; }
div.slider + div.overlay.shown { background-color:rgba(26,26,26,0.1); z-index:101000!important; }
div.slider.slide-out + div.overlay { opacity:0; }
div.slider.loading + div.overlay { z-index:100000; }

/* S56: der Ladekringel des OVERLAYS fragt nach .shown, nicht nur nach .loading -- dieselbe Bindung, die
   S58 dem Schleier direkt darunter gegeben hat. Vorher fragte er nur den Ladezustand, und der ueberlebt
   das Schliessen: die Anfrage laeuft weiter, .loading haengt noch, .shown ist schon weg.

   GEMESSEN (echtes Chrome, 1280x800, offener Slider -- dann traegt "div.slider.shown + div.overlay" das
   Overlay auf Deckkraft 1, es ist naemlich zugleich der abdunkelnde Hintergrund des Sliders):

     Slider   | Overlay          | Overlay-Deckkraft | Kringel            | Schleier
     .shown   | (nichts)         | 1                 | content:none       | 0x0
     .shown   | .shown .loading  | 1                 | 50px, dreht        | 1280x800   <- richtig
     .shown   | .loading         | 1                 | 50px, DREHT        | 0x0        <- der Befund
     .shown .loading | (nichts)  | 1                 | 50px, dreht        | 0x0        <- richtig, der SLIDER laedt

   Zeile 3 ist der Fehler: ein Kringel in voller Staerke ueber einer Flaeche, die nicht mehr offen ist,
   waehrend der Schleier derselben Flaeche im selben Bild korrekt verschwunden war. Dieselbe Gattung wie
   S58s Beinahe-Unfall -- ein Element, das sichtbar bleibt, obwohl das, wozu es gehoert, geschlossen ist.

   Der dritte Selektor (div.slider.loading + div.overlay:after) bleibt ABSICHTLICH unangetastet: dort ist
   das Overlay nur der Hintergrund, und geladen wird der SLIDER. Sein Zustand steht schon im Selektor.

   Ohne Befund geprueft, im selben Zug: weitere Elemente dieser Flaeche, die am Ladezustand statt am
   geoeffneten Zustand haengen, gibt es nicht. "div.overlay.loading > div.container > .padding >
   div.content" (oben) kann nicht lecken -- sein Wirt ist ein KIND des Overlays, und
   "div.overlay:not(.shown) > * { display:none !important; }" raeumt jedes Kind ab, sobald .shown faellt.
   Nur ein :after am Overlay SELBST steht ausserhalb dieser Regel, und davon gab es genau dieses eine. */
div.slider + div.overlay.shown.loading:after,
div.slider + div.overlay.shown.loading > div.container > .padding > div.content.loading:after,
div.slider.loading + div.overlay:after { content:" "; position:fixed; top:50%; left:50%; z-index:99999; content: " "; display: block; width: 50px; height: 50px; margin-left:-25px; margin-top:-25px; border-radius: 50%; border: 6px solid #6C7382; border-color: #6C7382 transparent #6C7382 transparent; animation:loading 1.2s linear infinite; }

div.slider + div.overlay.shown.loading:after,
div.slider + div.overlay.shown.loading > div.container > .padding > div.content.loading:after { z-index:102000!important; }

/* S64 (loest S58s Schleier ab): das Warten wird sichtbar, indem der DIALOG SELBST verblasst -- keine
   Schicht darueber.

   WARUM KEINE SCHICHT MEHR. S58 legte einen weissen Schleier ueber die Flaeche. Gemessen: der Kasten war
   1280x800, also das ganze Fenster, und damit lagen DRAUSSEN zwei Hintergruende uebereinander -- der
   gewoehnliche (rgba(26,26,26,0.1)) und der Schleier. Genau die Doppelung, die S49 eine Runde vorher
   beseitigt hatte, nur in der anderen Farbe: Seite 255 -> 232 (Hintergrund) -> 240 (Schleier), und der
   Kontrast des Fliesstextes fiel von 4.42:1 auf 2.36:1, also unter AA.
   Und schaerfer noch: der Schleier lag bei z-index 101500, div.container bei 9999999 -- er lag also UNTER
   dem Dialog. Gemessen im erzwungenen Zustand "Rahmen steht und laedt": oberstes Element in der
   Dialogmitte war der Absatz des Dialogs. Der Schleier deckte alles AUSSER dem, was gemeint war; dass er
   richtig aussah, lag nur daran, dass es waehrend des Ladens keinen Dialog gab (S64 hat das behoben, siehe
   die Zusammenfall-Regel oben). Eine Deckkraft am Inhalt braucht dagegen keine Stapelordnung, keine
   Flaeche und kein z-index -- vier der sechs Eintraege der alten Ausfalltabelle entfallen damit, statt neu
   abgeleitet werden zu muessen.

   DIE ZAHLEN, gemessen (echtes Chrome, echter Ajax-Weg, je Bildrahmen, 60 Hz = 16.7 ms):

   0.2s VERZOEGERUNG hinein. Flackern entsteht durch DAUER, nicht durch Staerke, und die Verzoegerung
       allein macht es selbstbegrenzend -- gemessen ueber die Ladedauer D:
         D=120 -> 0 verblasste Bilder
         D=210 -> 1 Bild, und zwar nur 3.9 % verblasst
         D=260 -> 4 Bilder, 15.5 %
         D>=340 -> volle 0.65
       ES GIBT KEINE LADEDAUER MIT "KURZ UND STARK": kurz heisst zwangslaeufig flach. Die echte schnelle
       Antwort dieses Baums haelt .loading 2.1 bzw. 69.9 ms -> 0 sichtbare Bilder.
       Die Untergrenze gibt die Flaeche selbst vor: der Hintergrund des Overlays blendet in 100 ms ein
       ("transition:opacity 0.1s linear" oben), und der Inhalt liegt darin, seine Deckkraft wird also
       damit multipliziert. 0.2s ist das Doppelte -- die Verblassung beginnt erst, wenn die Flaeche steht.
       Das gilt fuer das OEFFNEN; beim Nachladen eines stehenden Dialogs ist die Deckkraft des Overlays
       schon 1 (gemessen), dort ist die Verzoegerung schlicht die Schwelle gegen kurze Ladevorgaenge.
   0.15s EINBLENDEN, damit der Dialog nicht umschaltet, sondern zurueckweicht.
   0.65 DECKKRAFT ist die groesste Staerke, bei der der Dialog noch Zusammenhang bleibt und nicht Nebel
       wird. Das Element wird als GRUPPE auf den Hintergrund gemischt (hinter ihm liegen 232,232,232):
       Flaeche 247,247,247, Fliesstext 151,156,166 -> 2.57:1, Ueberschrift -> 5.87:1, also ueber AA (4.5).
       Bei 0.60 waeren es 5.02:1, bei 0.50 nur 3.63:1 -- darunter. Gegen S58s Schleier bei gleicher
       Wirkung gerechnet (2.50:1 / 5.58:1) ist das praktisch dasselbe Bild, ohne die Doppelung draussen.

   DIE MINDESTDAUER AUS S58 GIBT ES HIER NICHT, UND ZWAR NICHT AUS NACHLAESSIGKEIT.
   Sie ist baulich unmoeglich: ajax() ERSETZT #overlay_content per replaceWith(). Das verblasste Element
   ist im Augenblick der Antwort weg, ein Rueckweg kann daran also nicht ablaufen. Gemessen: die Deckkraft
   springt beim Tausch in EINEM Bild von 0.65 auf 1, und der neue Inhalt kommt in 0 von allen Laeufen
   verblasst an. Das ist hier richtig, nicht bloss unvermeidlich: eine Anzeige, die von ihrem ERGEBNIS
   abgeloest wird, ist kein Aufblitzen -- S58s Aufblitzen war schlimm, weil danach nichts anders war.
   DIE ALTERNATIVE IST GEMESSEN, damit sie niemand neu erraten muss: haengt die Deckkraft an
   div.container > .padding (das ajax() NICHT ersetzt), laeuft die Mindestdauer wie in S58 -- 316.6 ms bei
   D=210, groesster Schritt <= 0.040 statt 0.35 -- aber dann kommt der NEUE Inhalt 19 bis 30 Bilder lang
   (~317-500 ms) ausgewaschen an. Auftraggeber-Entscheidung: Anker am Inhalt, klare Antwort, Sprung in
   Kauf genommen. Wer die Mindestdauer nachtraegt, weil sie in S58s Aufgabenstellung stand, bekommt diesen
   Preis -- und sollte ihn kennen.

   WAS BEIM AUSFALL GILT (Hausregel 23.09.: ein fehlendes CSS-Mittel darf nie etwas kaputtmachen).
   Im Selektor steht nichts Neues -- nur ">", "+" und Klassen, alles CSS2, und die Ausnahme ist eine
   eigene Regel. Alles Neue steht in Erklaerungen und faellt einzeln weg. Jede Zeile gemessen, indem genau
   diese Erklaerung aus der Kaskade entfernt wurde:
     transition unbekannt -> der Dialog verblasst SOFORT statt nach 0.2s (gemessen: erstes verblasstes
         Bild bei 2.5 ms statt 219.5 ms, bei einer 120-ms-Antwort 10 Bilder lang). Er kommt weiter klar
         zurueck, der neue Inhalt ist unverblasst, 0 leere Bilder, nichts haengt. Es verblasst sichtbar,
         nichts ist kaputt.
     opacity unbekannt -> 0 verblasste Bilder, tiefste Deckkraft 1, nichts aendert sich. Nur die
         Verbesserung entfaellt.
     pointer-events unbekannt -> der ALTE Dialog bleibt anklickbar. Das ist ein Verhaltensrisiko im
         veralteten Stand, KEIN totes Bedienfeld -- und es kann nichts mehr schreiben, weil der tragende
         Riegel in ajax() sitzt (dort begruendet), nicht hier. Genau deshalb ist diese Erklaerung hier
         ableitbar, waehrend sie es bei S58s Schicht nicht war: dort machte ihr Ausfall die ganze
         Anwendung mausunbedienbar (gemessen: Klick auf eine Tabellenzeile traf div.overlay und loeste 0
         Anfragen aus).
   Die Richtung des Irrtums ist gewaehlt: im Zweifel verblasst der Dialog ZU FRUEH oder GAR NICHT --
   niemals bleibt er verblasst stehen.

   position/width/height/z-index kommen nicht vor: es gibt kein Element, das positioniert werden muesste.
   Damit auch keine Hoehenaenderung und kein Sprung -- gemessen vorher/waehrend/nachher, schnelle wie
   langsame Antwort: Seitenhoehe, Huellenhoehe, Zeilenoberkante und Rollposition in allen Ablesungen
   identisch. */
/* S79 -- ZWEI ANKER, WEIL ES ZWEI LADEWEGE GIBT. Der zweite ist erst durch eine Beobachtung des
   Auftraggebers aufgefallen: "ich sehe die loading klasse im padding div, aber keinen visuellen
   unterschied" -- im memberadd-Weg, nach Eingabe der E-Mail auf dem Weg zur Projektauswahl.

   GEMESSEN, welcher Weg das ist (echter Ajax-Weg, Beobachter auf allen vier Ebenen der Flaeche):
   die E-Mail-Stufe (module/permissionuser.overlay.php:52) ist ein Formular MIT
   target="#overlay_content". Ein Formular laeuft durch ajax() und NICHT durch toggleOverlay() --
   und .loading setzt nur ajax() auf das ZIEL, waehrend toggleOverlay() es auf das OVERLAY setzt.
   Ergebnis der Messung: genau ZWEI Klassenwechsel, beide am #overlay_content (bei 8.8 ms hin, bei
   2051.2 ms zurueck); div.overlay bleibt die ganze Zeit "overlay shown", div.container und
   div.padding bekommen NULL Wechsel. (Der Auftraggeber sah die Klasse "im padding div", weil
   #overlay_content das einzige Kind von div.padding ist -- die Klasse steht darin, nicht daran.)
   Die Regel von S64 hing nur am Overlay-Anker und konnte hier also gar nicht greifen -- gemessen
   bei ZWEI SEKUNDEN Dauer und 0 verblassten Bildern. Es war nicht die 0.2s-Schwelle.

   WARUM DER ZWEITE ANKER JETZT SICHER IST, UND IN S64 NICHT WAR. S64 hat ihn bewusst gemieden: die
   Ladeklasse des ZIELS blieb dauerhaft haengen, wenn eine Antwort mit Status 200 das eigene Ziel
   nicht im Rumpf hatte -- das Abraeumen stand im else-Zweig der Statuspruefung. Eine Verblassung an
   einem Anker, der haengenbleibt, waere eine Anwendung, die blass bleibt. S73 hat das Abraeumen VOR
   die Fallunterscheidung gezogen, unbedingt in request.always(). NACHGEMESSEN statt geglaubt, alle
   drei Ausgaenge, jeweils Klasse danach:
     200 ohne eigenes Ziel im Rumpf -> "content", haengt NICHT   (in S64 blieb genau das stehen)
     500                            -> "content", haengt NICHT
     Abbruch durch eine zweite Anfrage (aborted:true) -> "content", haengt NICHT
   Der Grund fuer die Vermeidung ist damit gemessen weg, nicht weggewuenscht. Faellt er zurueck, wird
   die Zusicherung in OverlayWaitVeilTest rot, die genau diese Unbedingtheit festhaelt.

   Beide Anker in EINER Regel, nicht in zwei: gleiche Wirkung, eine Stelle zum Aendern. Und die
   Zahlen (0.2s, 0.15s, 0.65) sind dieselben und aus demselben Grund -- sie stehen unten begruendet.
   Der Rueckweg laeuft auch hier nicht, aus demselben baulichen Grund: ajax() ersetzt das Ziel. */
/* S82 -- WEISS UND DECKKRAFT GETRENNT, statt eine Schicht darueberzulegen.
   Beobachtung des Auftraggebers: "halbtransparenz des overlays beim laden funktioniert - ist aber
   uncool wenn dann drunter der inhalt durchleuchtet. darunter muesste es weiss sein."

   ERKLAERT, UND ZWAR STRUKTURELL: dasselbe Element trug beides. div.content hat sein
   background-color:#fff (Regel weiter oben, zusammen mit padding und border-radius), und S64/S79
   legten die Deckkraft auf GENAU dieses Element. Eine Deckkraft wirkt auf das Element als GRUPPE --
   also auch auf seinen eigenen weissen Grund. Durch den halbdurchsichtigen Dialog hindurch stand
   dann der abgedunkelte Seiteninhalt.

   Die Antwort ist die Trennung, nicht eine zusaetzliche Schicht: das Weiss bleibt beim Inhalt, die
   Deckkraft wandert auf SEINE KINDER. Damit bleibt der Grund deckend und nur das, was darauf steht,
   weicht zurueck.

   DIE PRAEMISSE IST GEMESSEN, nicht angenommen -- "> *" trifft nur ELEMENTE, nackter Text direkt im
   Inhalt bliebe unverblasst. Die echten Module durch ihre echten Harnische gerendert und die oberste
   Ebene ausgezaehlt:
     permissionuser, E-Mail-Stufe   -> ein <form>, kein nackter Text
     permissionuser, Projektauswahl -> ein <form>, kein nackter Text
     memberadd, Rechtekarte         -> ein <div>,  kein nackter Text
   Das ist die Bauform aller vier Overlay-Module (jedes wickelt seinen Inhalt in genau ein Element),
   und die Zusicherung in OverlayWaitVeilTest haelt sie gegen die echten Bytes fest -- wer kuenftig
   einen Satz direkt in den Inhalt schreibt, macht sie rot, nicht nur diesen Kommentar falsch.

   DIE STAERKE IST NEU BEGRUENDET, NICHT UEBERNOMMEN. Die 0.65 aus S64 waren gegen den falschen
   Untergrund gerechnet: gegen die 232,232,232 der abgedunkelten Seite, die eben deshalb durchschien.
   Jetzt steht dort Weiss, also gilt:
     Deckkraft 0.65 gegen Weiss: Text (159,164,174) -> 2.50:1, Ueberschrift (93,102,143) -> 5.58:1
     vorher gerechnet:                                2.57:1                                5.87:1
   Die Zahl bleibt, der Grund ist ein anderer -- und die Luft ist KLEINER: die Ueberschrift verlaesst
   AA (4.5:1) jetzt bei 0.584 statt bei 0.569, der Abstand von 0.65 schrumpft von 0.081 auf 0.066.
   Wer die Staerke erhoehen will, hat bis 0.584 Platz; darunter ist der Dialog nicht mehr Zusammenhang,
   sondern Nebel. (Gegenprobe der Wirkung: 0.65 gegen Weiss ist dasselbe Bild wie S58s weisser Schleier
   0.35 UEBER dem weissen Dialog, damals 2.50:1 / 5.58:1 -- dieselben Zahlen, ohne die Schicht.)

   WARUM NICHT DER SCHLEIER, den der Auftraggeber als Alternative nennt: eine Schicht UEBER dem Inhalt
   braucht pointer-events, und deren Ausfall hat S64s ersten Entwurf gemessen mausunbedienbar gemacht
   (Klick auf eine Tabellenzeile traf div.overlay, 0 ausgeloeste Anfragen), ohne dass man etwas sah.
   Diese Ableitung waere vollstaendig neu zu erbringen. Die Trennung braucht sie nicht: sie fuegt kein
   Element hinzu, nur eine Erklaerung mehr an vorhandenen.

   Die Klicksperre bleibt am INHALT, nicht an den Kindern -- sie soll auch nackten Text und kuenftige
   Kinder abdecken, und sie ist die tragende Haelfte nicht (das ist der Riegel in ajax()). */
div.slider + div.overlay.shown > div.container > .padding > div.content > * { opacity:1; transition:opacity 0.2s linear 0.3s; }
div.slider + div.overlay.shown.loading > div.container > .padding > div.content > *,
div.slider + div.overlay.shown > div.container > .padding > div.content.loading > * { opacity:0.65; transition:opacity 0.15s linear 0.2s; }
div.slider + div.overlay.shown.loading > div.container > .padding > div.content,
div.slider + div.overlay.shown > div.container > .padding > div.content.loading { pointer-events:none; }

/* ABER DAS ZUMACHEN BLEIBT ERREICHBAR -- eine eigene Regel, und der Grund ist gemessen.
   Die Sperre eine Zeile darueber liegt auf dem GANZEN Inhalt. Damit war auch der Schliesser des
   Dialogs gesperrt: echter Mausklick auf ein [data-overlay=false] waehrend des Wartens traf gemessen
   div.padding, das Overlay blieb offen. Bei den 800 ms bis 5,4 s, um die es hier ueberhaupt geht,
   heisst das: der Dialog ist zu, aber man kommt nicht heraus -- und "ein Dialog, aus dem man nicht
   herauskommt, ist die schlimmere Variante von langsam" ist derselbe Satz, mit dem diese Runde
   angefangen hat. ESC und der Rand-Doppelklick griffen weiter (der eine klickt den Schliesser
   programmatisch, der andere zielt auf div.padding ausserhalb des Inhalts) -- aber der sichtbare
   Knopf ist der Weg, den jemand nimmt.

   Warum das den Riegel nicht aufweicht: ein Schliessen SCHREIBT NICHT. Was der Riegel in ajax()
   abweist, ist ausschliesslich ein Formular; [data-overlay=false] traegt im ganzen Baum nur
   Abbrechen-Wege (der generische Handler ruft toggleOverlay(false) bzw. closeConfirmationLayer()).
   Und die Schliesswege selbst sind einzeln gemessen: an jedem ist die Verblassung im selben Bild weg,
   in dem .shown fällt -- auch wenn .loading noch haengt, weil die Anfrage weiterlaeuft.

   Eigene Regel, nicht als :not() in den Selektor oben: faellt sie aus, bleibt die Sperre vollstaendig
   stehen (der Knopf ist dann wieder unerreichbar, wie gemessen) -- eine entfallene Erleichterung,
   keine zerbrochene Funktion. Als :not() haette ihr Ausfall den ganzen Selektor und damit die Sperre
   ungueltig gemacht, also genau die tragende Haelfte weggenommen. Das ist S55s Messung, hier
   angewandt.

   S79: beide Anker, aus demselben Grund wie oben. Die E-Mail-Stufe traegt ihr eigenes "Abbrechen"
   ([data-overlay=false], module/permissionuser.overlay.php:67) -- ohne den zweiten Selektor waere
   genau dort waehrend des Wartens kein Weg hinaus, also derselbe Fehler, den diese Regel fuer den
   ersten Anker behebt. */
div.slider + div.overlay.shown.loading > div.container > .padding > div.content [data-overlay=false],
div.slider + div.overlay.shown > div.container > .padding > div.content.loading [data-overlay=false] { pointer-events:auto; }

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

body > div.clear { position:fixed; right:0; top:0; bottom:0; width:0; z-index:1; }


body.focus div.wrapper > div.top > ul,
body.focus div.wrapper > div.main > div.left { display:none; }
body.focus div.wrapper > div.top > a.close { display:block; float:right; }
body.focus div.wrapper > div.top > a.close > i { background-color:#DEE9FC; border-radius:50%; padding:5px; margin-left:1em; width:2.3em; height:2.3em; }
body.focus div.wrapper > div.top > a.close:hover { color:#2C6EEF; }
body.focus div.wrapper > div.top > a.close:hover > i { background-color:#2C6EEF; color:#fff; }

div.wrapper > div.main > div.content > .body:first-child { margin:auto; max-width:630px; padding-left:440px; padding-right:110px; }
div.wrapper > div.main > div.content > .body:first-child > .context { width:300px; display:block; float:left; margin-left:-440px; }
div.wrapper > div.main > div.content > .body:first-child > .context h1 { font-size:1.85em; line-height:1.08em; padding:0; margin:0; margin-bottom:0.58em; }
div.wrapper > div.main > div.content > .body:first-child > .context ul.progress { list-style:none; margin:0; padding:0; margin-top:40px; }
div.wrapper > div.main > div.content > .body:first-child > .context ul.progress li { position:relative; line-height:1.69em; padding-left:3em; padding-top:0.15em; padding-bottom:0.15em; color:#97A3B5; }
div.wrapper > div.main > div.content > .body:first-child > .context ul.progress li.selected,
div.wrapper > div.main > div.content > .body:first-child > .context ul.progress li.completed { color:#121728; }
div.wrapper > div.main > div.content > .body:first-child > .context ul.progress li:not(:last-child) { min-height:6.62em; }
div.wrapper > div.main > div.content > .body:first-child > .context ul.progress li span:first-child { display:block; position:absolute; top:0; left:0; width:2em; height:2em; border-radius:50%; background-color:#97A3B5; color:#ffffff; line-height:2em; text-align:center; }
div.wrapper > div.main > div.content > .body:first-child > .context ul.progress li span:first-child i { position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); font-size:0.8em; margin-left:-0.1em; }
div.wrapper > div.main > div.content > .body:first-child > .context ul.progress li.selected span:first-child,
div.wrapper > div.main > div.content > .body:first-child > .context ul.progress li.completed span:first-child { background-color:#2C6EEF; }
div.wrapper > div.main > div.content > .body:first-child > .context ul.progress li a:hover { color:#121728; }
div.wrapper > div.main > div.content > .body:first-child > .context ul.progress li.completed span:first-child,
div.wrapper > div.main > div.content > .body:first-child > .context ul.progress li a:hover span:first-child { background-color:#121728; }

div.wrapper > div.main > div.content > .body:first-child > .context ul.progress li + li span:first-child:before,
div.wrapper > div.main > div.content > .body:first-child > .context ul.progress li:not(:last-child) span:first-child:after { position:absolute; content:''; width:2px; height:3.62em; bottom:100%; left:1em; margin-left:-1px; margin-top:0.5em; margin-bottom:0.5em; background-color:#E4E9EF; }
div.wrapper > div.main > div.content > .body:first-child > .context ul.progress li:not(:last-child) span:first-child:after { bottom:auto; top:100%; margin-bottom:0; }

div.wrapper > div.main > div.content > .body:first-child > .data { display:block; float:left; width:100%; }
div.wrapper > div.main > div.content > .body:first-child > .data h2 { font-size:1.23em; line-height:1.5em; padding:0; margin:0; margin-bottom:1em;  }
div.wrapper > div.main > div.content > .body:first-child > .data h2 + .button { float:right; margin-top:-3.4em; }
div.wrapper > div.main > div.content > .body:first-child > .data h2 + .button.plain { border-right:0; }
div.wrapper > div.main > div.content > .body:first-child > .data h2 + .button.plain > label { padding-right:0; }

div.wrapper > div.main > div.content > .body:first-child p { color:#6C7382; line-height:1.46em; }
div.wrapper > div.main > div.content > .body:first-child > .data p + .input { margin:0; margin-top:2.31em; }

div.wrapper > div.main > div.content > .body:first-child> .data * + h2 { margin-top:4.62em; }

@media only screen and (max-width: 1280px) {
    div.wrapper > div.main > div.content > .body:first-child {  padding-left:290px; padding-right:60px; }
    div.wrapper > div.main > div.content > .body:first-child > .context { width:200px; display:block; float:left; margin-left:-290px; }
}

@media only screen and (max-width: 1100px) {
    div.wrapper > div.main > div.content > .body:first-child {  padding-left:270px; padding-right:40px; }
    div.wrapper > div.main > div.content > .body:first-child > .context { width:200px; display:block; float:left; margin-left:-240px; }
}

.datepicker-top-left,.datepicker-top-right{border-top-color:#2C6EEF}
.datepicker-top-left:before,.datepicker-top-right:before{border-bottom-color:#2C6EEF}
.datepicker-bottom-left,.datepicker-bottom-right{border-bottom-color:#2C6EEF}
.datepicker-bottom-left:before,.datepicker-bottom-right:before{border-top-color:#2C6EEF}
.datepicker-panel>ul>li.picked,.datepicker-panel>ul>li.picked:hover{color:#2C6EEF}
.datepicker-panel>ul>li:hover{background-color:#DEE9FC}
.datepicker-panel>ul>li.highlighted{background-color:#DEE9FC}
.datepicker-panel>ul>li.disabled.highlighted,.datepicker-panel>ul>li.disabled:hover.highlighted{background-color:#DEE9FC}

.autocomplete-suggestions-placeholder,
.autocomplete-suggestions { position:absolute; top:100%; left:-10px; right:-10px; margin-top:2px; width:auto !important; border: 1px solid #F2F5F9; background: #F2F5F9; overflow: auto; border-radius:4px; border-radius:4px; }
.autocomplete-suggestions.hidden { display:none !important; }
.autocomplete-suggestion { padding: 0.41em 0.83em; font-size:0.92em; border-bottom:1px solid #fff; white-space: nowrap; overflow: hidden; }
.autocomplete-suggestion:last-child { border-bottom:0; }
.autocomplete-suggestion:empty { display:none; }
.autocomplete-suggestion div.description { font-size:0.87em; line-height:1.54em; }

.autocomplete-selected { background: #FFFFFF; }
.autocomplete-suggestions strong { font-weight: bold; }
.autocomplete-group { padding: 0.17em 1em; }
.autocomplete-group strong { display: block; border-bottom: 1px solid #E4E9EF; }

.autocomplete-suggestions-placeholder,
.autocomplete-suggestions.autocomplete-suggestions-inline { position:relative !important; display:block !important; height:200px !important; top:auto !important; left:auto !important; right:auto !important; bottom:auto !important; width:auto !important; }
.autocomplete-suggestions.autocomplete-suggestions-inline.autocomplete-suggestions-active + .autocomplete-suggestions-placeholder { display:none !important; }

.autocomplete-suggestions-placeholder.plain,
.autocomplete-suggestions.autocomplete-suggestions-inline.plain { background-color:transparent; border:0; padding:0; }

[data-more]:not([data-more-state]),
[data-more][data-more-state='hide'] { display:none !important; }

table.input { width:100%; }
table.input tr { background-color:#fff; }
table.input td,
table.input th { position:relative; text-align:left; padding:0.38em 0.57em; }
table.input th { font-size:0.92em; padding:1.25em 0.84em; }
table.input td:first-child,
table.input th:first-child { padding-left:0; }
table.input td:last-child:not([colspan]),
table.input th:last-child:not([colspan]) { text-align:right; padding-right:0; }
/* When collapseActionColumns folds the action column away at runtime, the hidden cells stay in the DOM so
   :last-child cannot reach the new edge cell — this tag gives it the same flush-right treatment, so a
   runtime-collapsed row reads exactly like one whose column was omitted server-side. */
/* Die letzte Zelle mit Inhalt rückt an den rechten Rand — ausser sie trägt den Sortiergriff.
   In der eigenen Zeile fehlt der Löschbutton (man kann sich nicht selbst entfernen), also wird die
   Griffzelle zur letzten und wäre als einzige nach rechts gerutscht: derselbe Griff säße in einer Zeile
   20px weiter rechts als in allen anderen. Die Ausnahme steht hier statt in einer eigenen Regel — die
   verlöre gegen diese hier an Spezifität (0,3,1 gegen 0,3,2). */
table.input td.action-collapsed-last:not([colspan]):not(.permission-move) { text-align:right; padding-right:0; }

table.input td a { color:#6C7382; }
table.input th a { color:#2C6EEF; }
table.input td a:hover,
table.input th a:hover { color:#1a1a1a; }
table.input hr { position:absolute; margin:0; top:0.38em; bottom:0.38em; left:50%; width:1px; height:auto; }
table.input.block tr:not(:first-child) hr { top:0; }
table.input.block tr:not(:last-child) hr { bottom:0; }

table.input tr.selected td { position:relative; background-color:#F2F5F9; }
table.input tr.selected td:first-child { font-weight:bold; -webkit-box-shadow: -10px 0px 0px 0px rgba(242,245,249,1); -moz-box-shadow: -10px 0px 0px 0px rgba(242,245,249,1); box-shadow: -10px 0px 0px 0px rgba(242,245,249,1); border-top-left-radius:4px; border-bottom-left-radius:4px; }
table.input tr.selected td:last-child { -webkit-box-shadow: 10px 0px 0px 0px rgba(242,245,249,1); -moz-box-shadow: 10px 0px 0px 0px rgba(242,245,249,1); box-shadow: 10px 0px 0px 0px rgba(242,245,249,1); border-top-right-radius:4px; border-bottom-right-radius:4px; }

.action { font-size:0.92em; font-weight:bold; padding:1.25em 0; }
.action a { color:#2C6EEF; }
.action a:hover { color:#1a1a1a; }

/* Zwei Aktionen in einer Zeile — "Benutzer hinzufügen" und "Gruppe hinzufügen" stehen nebeneinander,
   seit es den Hinzufügen-Link je Gruppentabelle nicht mehr gibt. Ohne Abstand kleben sie mit dem einen
   Leerzeichen aneinander, das im Markup zwischen ihnen steht. */
.action > a + a { margin-left:2.3em; }

.action.secondary a { color:#6C7382; }
.action.secondary a:hover { color:#1a1a1a; }

[data-multi-template] { display:none!important; }
[data-multi] .sortable-ghost { visibility:hidden; }

body.plain.center div.wrapper > div.top { position:static; border-color:transparent; text-align:center; margin-top:100px; }
body.plain.center div.wrapper > div.top .logo { margin:auto; float:none; height:40px; }
body.plain.center div.wrapper > div.main { padding:30px; padding-top:0; min-width:0; } 
body.plain.center div.wrapper > div.main > div.content .center { margin:50px 0; }
body.plain.center div.wrapper > div.main > div.content .center > .box { display:block; margin:auto; max-width:400px; padding:40px 30px; background-color:#F2F5F9; border-radius:4px; }
body.plain.center div.wrapper > div.main > div.content .center > .box p a { color:#2C6EEF; text-decoration:underline; }
body.plain.center div.wrapper > div.main > div.content .center > .box p a:hover { color:inherit; }
body.plain.center div.wrapper > div.main > div.content .center > .box > :first-child { margin-top:0; }
body.plain.center div.wrapper > div.main > div.content .center > .box > :last-child { margin-bottom:0; }

body.plain.center div.wrapper > div.main > div.content .center > .box label.input { padding-left:0.77em; padding-right:0.77em; background-color:#FFFFFF; border-radius:4px; }
body.plain.center div.wrapper > div.main > div.content .center > .box label.input.error,
body.plain.center div.wrapper > div.main > div.content .center > .box label.input.missing { border-bottom-left-radius:0; border-bottom-right-radius:0; }

body.plain.center div.wrapper > div.main > div.content .center > .box label.input:not(.error):not(.disabled):not(.readonly):not(.select.color).focus,
body.plain.center div.wrapper > div.main > div.content .center > .box label.input:not(.error):not(.disabled):not(.readonly):not(.select.color):hover { border-color:transparent; border-radius:4px; background-color:#FFFFFF; -webkit-box-shadow:-0.77em 0 0 0 #FFFFFF,0.77em 0 0 0 #FFFFFF; -moz-box-shadow:-0.77em 0 0 0 #FFFFFF,0.77em 0 0 0 #FFFFFF; box-shadow:-0.77em 0 0 0 #FFFFFF,0.77em 0 0 0 #FFFFFF; }

body.plain.center div.wrapper > div.main > div.content .center > .input > .button.plain { color:#97A3B5; }
body.plain.center div.wrapper > div.main > div.content .center > .input > .button.plain:hover { color:#1a1a1a; }

@media only screen and (max-width: 600px) {
    body.plain.center div.wrapper > div.top { margin-top:50px; padding-bottom:0; }
    body.plain.center div.wrapper > div.top .logo { height:30px; }
}

.pagination { overflow:hidden; }
.pagination .button.left { float:left; }
.pagination .button.right { float:right; }

a[href*='/preview/'] .icon-file-document,
a[data-href*='/preview/'] .icon-file-document { cursor: zoom-in; }

a[href*='/f/'] .icon-file-document:before,
a[data-href*='/f/'] .icon-file-document:before { content:'\e804'; }

a[href]:not([data-href]):not([href*='/preview/']):not([href*='/f/']) .icon-file-document:before,
a[data-href]:not([data-href*='/preview/']):not([data-href*='/f/']) .icon-file-document:before { content:'\e80e'; }

[data-href] input[disabled] { pointer-events:none; cursor:pointer; }
[data-href] label { cursor:pointer; }


/* Help Slider */
div.slider > div.padding > div.content:has(.help-slider-container) { padding:0; height:100vh; overflow:hidden; }
.help-slider-container { height:100%; display:flex; flex-direction:column; overflow:hidden; }

.help-slider-header { flex-shrink:0; background-color:#fff; padding:20px 30px; padding-top:176px; border-bottom:1px solid #E4E9EF; z-index:9; }
.help-slider-search-bar { display:flex; align-items:center; gap:8px; }
.help-search-input { display:flex; align-items:center; flex:1; background-color:#F2F5F9; border-radius:4px; padding:0 12px; height:40px; }
.help-search-input i { color:#6C7382; margin-right:8px; font-size:1.1em; }
.help-search-input input { background:none; border:none; outline:none; width:100%; font-family:'Poppins',sans-serif; font-size:13px; color:#1a1a1a; font-weight:500; }
.help-search-input input::placeholder { color:#9CA3AF; }

.help-toc-button { background:none; border:1px solid #E4E9EF; border-radius:4px; width:40px; height:40px; cursor:pointer; display:flex; align-items:center; justify-content:center; color:#6C7382; transition:all 0.15s; }
.help-toc-button:hover, .help-toc-button.active { background-color:#2C6EEF; color:#fff; border-color:#2C6EEF; }

.help-toc { flex:1; padding:15px 30px; background-color:#F2F5F9; border-bottom:1px solid #E4E9EF; overflow-y:auto; min-height:0; }
.help-toc ul { list-style:none; margin:0; padding:0; }
.help-toc li { margin:0; }
.help-toc li a { display:block; padding:6px 0; color:#1a1a1a; text-decoration:none; font-size:13px; border-bottom:1px solid #E4E9EF; }
.help-toc li a:hover { color:#2C6EEF; }
.help-toc li.help-toc-level-3 a { padding-left:20px; color:#6C7382; font-size:12px; }

.help-search-results { flex:1; padding:20px 30px; overflow-y:auto; min-height:0; }
.help-result-box { background-color:#F2F5F9; border:1px solid #E4E9EF; border-radius:4px; padding:15px; margin-bottom:10px; cursor:pointer; transition:border-color 0.15s; }
.help-result-box:hover { border-color:#2C6EEF; }
.help-result-title { font-weight:600; font-size:14px; margin-bottom:6px; color:#1a1a1a; }
.help-result-paragraph { font-size:12px; color:#6C7382; line-height:1.5; }
.help-result-box mark { background-color:#DEE9FC; color:#1a1a1a; border-radius:2px; padding:0 2px; }
.help-no-results { text-align:center; padding:40px 20px; color:#6C7382; font-size:13px; }

.help-content { flex:1; padding:30px; overflow-y:auto; min-height:0; }
.help-content h1 { font-size:1.6em; font-weight:600; margin:0 0 0.8em 0; color:#1a1a1a; line-height:1.3; }
.help-content h2 { font-size:1.3em; font-weight:600; margin:1.8em 0 0.6em 0; color:#1a1a1a; padding-bottom:8px; border-bottom:1px solid #E4E9EF; }
.help-content h3 { font-size:1.1em; font-weight:600; margin:1.4em 0 0.5em 0; color:#1a1a1a; }
.help-content h4 { font-size:1em; font-weight:600; margin:1.2em 0 0.4em 0; color:#1a1a1a; }
.help-content p { margin:0 0 1em 0; line-height:1.7; color:#1a1a1a; }
.help-content ul, .help-content ol { margin:0 0 1em 0; padding-left:20px; }
.help-content li { margin-bottom:4px; line-height:1.6; }
.help-content strong { font-weight:600; }
.help-content hr { border:none; border-top:1px solid #E4E9EF; margin:2em 0; }
.help-content blockquote { margin:0 0 1em 0; padding:12px 16px; background-color:#F2F5F9; border-left:3px solid #BB1A3F; border-radius:0 4px 4px 0; color:#1a1a1a; }
.help-content blockquote p:last-child { margin-bottom:0; }
.help-content code { background-color:#F2F5F9; padding:2px 6px; border-radius:4px; font-size:12px; }
.help-content pre { background-color:#F2F5F9; padding:16px; border-radius:4px; overflow-x:auto; margin:0 0 1em 0; }
.help-content pre code { padding:0; background:none; }
.help-content .help-table-wrap { overflow-x:auto; margin:0 0 1em 0; -webkit-overflow-scrolling:touch; }
.help-content table { width:100%; border-collapse:collapse; margin:0; font-size:12px; }
.help-content table th, .help-content table td { padding:8px 12px; text-align:left; border:1px solid #E4E9EF; }
.help-content table th { background-color:#F2F5F9; font-weight:600; }
.help-content table tr:nth-child(even) td { background-color:#FAFBFC; }
.help-content a { color:#2C6EEF; text-decoration:none; }
.help-content a:hover { text-decoration:underline; }

/* The portfolio overview fills its KPIs per project (see overviewKpiLoad). Two things have to be true
   while they are in flight:

   1. The space is already THERE. The page renders the same tags the real values will use — a span, a
      <br/>, a <small> — with a bar inside instead of a number, and the tile's KPI list keeps its real
      titles. The row is its final height from the first paint, so nothing shifts under the cursor when
      the numbers land. A bar that only reserved one line where the value takes two would still jump.
   2. It looks like it is loading, not like a project with no data. Hence the pulse, and the spinner —
      the app's own (@keyframes loading), just small.

   The spinner is position:absolute so it occupies no space and its removal moves nothing. */
/* Two things have to be true at once, and they pull apart:

   The BOX has to be the text's box — same baseline, same content height — or the row's geometry differs
   from the loaded one and the numbers shift when they land. That is not something to guess a height and a
   vertical-align for; the span CONTAINS text (a digit, painted transparent), so the browser aligns it the
   same way it will align the real figure. Inside <small> it inherits the smaller font and shrinks with it.

   The BAR, though, must not fill that box. Text only occupies the band from the baseline to cap height —
   roughly 0.72em of the 1em box. A bar filling the whole em reads as too tall, and two of them sit closer
   together than the two lines of text ever will. So the bar is a pseudo-element inside the text box: the
   box keeps the layout honest, the band shows where the figures go. */
.skeleton { position:relative; display:inline-block; min-width:4.5em; line-height:1; color:transparent; user-select:none; }
.skeleton.small { min-width:3.5em; }
.skeleton:before { content:''; position:absolute; left:0; right:0; top:0.14em; height:0.72em; border-radius:2px; background-color:#E4E9EF; animation:skeleton-pulse 1.4s ease-in-out infinite; }
.skeleton.small:before { background-color:#F2F5F9; }
@keyframes skeleton-pulse { 0%,100% { opacity:1; } 50% { opacity:0.4; } }

/* The app's own spinner (@keyframes loading), small. */
.overview-loading { display:inline-block; width:14px; height:14px; border-radius:50%; border:2px solid #6C7382; border-color:#6C7382 transparent #6C7382 transparent; animation:loading 1.2s linear infinite; vertical-align:middle; pointer-events:none; }

/* Tile: bottom right, mirroring the status tag's inset from the top right (20px). */
div.wrapper > div.main > div.content .tiles > ul > li > .overview-loading { position:absolute; bottom:20px; right:20px; z-index:2; }

/* Table: the spinner STANDS IN for the status tag, and the status appears when the row has loaded. The
   column width comes from the header, so swapping one for the other moves nothing. */
div.wrapper > div.main > div.content .table > table tbody tr[data-overview-kpi] > td.float.line > span.state { display:none; }

/* Rechte-Dashboard (module/permissions.php): the placeholder spinner sat right against the row above it
   (the table head, a group title, or -- since the finished list now stays put across a reload -- an
   already-loaded row) with only its cells own 1.25em top padding between them. Scoped to
   "table.permissions-overview" -- the table CLASS module/permissions.php alone carries -- not to
   .overview-loading itself: that class is shared with module/overview.php (its state-pill row and its
   absolutely positioned tile spinner), and a rule there would move every loading spinner in the app.
   margin-top on the SPAN, not on the <tr>/<td>: a margin on a table row or cell is ignored by the table
   layout model, so it would have done nothing there.
   30px, after a first attempt at 10px stayed invisible in practice (the selector was verified to match --
   layout::module(true) runs a literal include(), csrf::inject() never touches a <table> -- so 10px simply
   read as too small a change to notice, not as no change at all). 30px is not a new number either: the
   same generous top margin this stylesheet already uses to set a section visibly apart ("h3 {
   margin-top:30px; … }").
   100px: 30px was measured (getBoundingClientRect, real browser) to genuinely move the ring -- 17px gap
   became 46px -- and was STILL reported as stuck, so the fix was not the direction, only the size. A worry
   before raising it further: this span carries vertical-align:middle, which for an inline-block can re-centre
   the box on its line and eat into a one-sided margin, making the RULE'S number read larger than the GAP you
   actually see. Measured directly rather than assumed: across margin-top 0/10/30/50/60/80/100/120px, in both
   the access view (spinner as the table's own first row) and the project view (spinner under a group title),
   the visible gap grows by (almost exactly) the same amount as the margin -- 30px moved the ring 28.6px, 100px
   moved it 98.6px, a constant ~1.4px short of the raw number, not half of it. So there is no hidden halving to
   correct for here: the number IS very close to the gap. 100px is the smallest of the tested candidates the
   Auftraggeber confirmed as clearly visible against the real page -- more than triple the 30px that still read
   as stuck, and, unlike 30px, no longer close to the size this table already uses as its own quiet padding
   (the cell's 1.25em/16px). */
table.permissions-overview .overview-loading { margin-top:100px; }

@media (prefers-reduced-motion: reduce) {
    .skeleton:before { animation:none; }
    .overview-loading { animation:none; }
}

/* The overview: who is on the project, and how much of it they hold. A tick means the whole group;
   otherwise written / seen, because "4 of 7" is the thing you actually want to know at a glance. */
/* The three counts are read as a block, so they line up as one — heading over figure, centred, and the
   figures on tabular digits so 2/5 and 11/15 sit in the same column rather than drifting apart. */
/* The group name and its "maximum rights" button share a line above the member table. */
.permission-group-head { display:flex; align-items:baseline; justify-content:space-between; gap:15px; }
.permission-group-head > label.input.large { flex:1 1 auto; }
.permission-group-head > label.input.large.error-duplicate { border-color:#BB1A3F; }
.permission-group-head > a { flex:0 0 auto; padding-right:0; }

/* One table per group, the way the sale units do it — the name above, the people under it. */
.permission-group-block + .permission-group-block { margin-top:2.5em; }

/* The group offered for the domain of whoever is being dragged. It has to read as an offer rather than as a
   group that already exists, and it is only there while the drag is: faded back, and ringed.

   outline, not border — a border is part of the box, so it would push the block wider than the ones above
   and below it and the dashed ring would not line up with anything. An outline sits outside the box and
   moves nothing. */
/* The dashed ring sits exactly where the field's own hover box does — it IS that box, drawn on the label
   rather than around the block, so it lines up with every other input on the page. */
.permission-group-block.suggested { position:relative; opacity:0.55; }
.permission-group-block.suggested .permission-group-head > label.input.large { margin:0 -13px; padding:0.77em 12px; border:1px dashed #C3CAD5; border-radius:4px; }

/* Nothing in it but the name: nobody is in the group yet, so headings over an empty table and a button to
   add somebody answer questions nobody asked. */
.permission-group-block.suggested [data-permission-group-max-open] { display:none; }   /* a suggestion has no members yet — nothing to cap */
.permission-group-block.suggested table thead,
.permission-group-block.suggested table tfoot,
.permission-group-block.suggested > hr,
.permission-group-block.suggested tr.permission-empty { display:none; }   /* der Vorschlagskasten ist eine Fläche, keine Gruppe mit Abschluss */

/* The drop target, laid over the whole block.

   An empty table body is a box of NO size — measured at 0×0, sitting at x=0 — and Sortable decides what an
   empty list can catch by measuring exactly that box. The 160px reach was therefore being applied at the
   left edge of the window, hundreds of pixels from the block somebody was aiming at. Stretched over the
   block, the ring you can see IS the area that takes the drop. */
.permission-group-block.suggested table { position:static; }   /* .input makes it relative — and it is nought pixels tall, so the body would stretch to nothing */
.permission-group-block.suggested tbody { display:block; position:absolute; left:0; right:0; top:0; bottom:0; }

/* One grid for every group's table. display:table is not decoration: the table carries class="input", and
   .input sets display:block — which stops it being a table box at all, so each group would size itself to
   its own longest address and no two tables would line up. */
.permission-table { display:table; table-layout:fixed; width:100%; }

.permission-table th.permission-summary,
.permission-table td.permission-summary { text-align:center; width:62px; }
.permission-table th.permission-spacer { width:16px; }
.permission-table th.permission-action { width:20px; }

/* Die Rechteübersicht über alle Projekte (module/permissions.php).

   Vierzehn Bereichsspalten neben Name und Adresse: schmal, zentriert, und die Kopfzeilen dürfen umbrechen,
   sonst schiebt "Kostenplanung & Rechnungen" die Tabelle über den Rand. Die Symbolspalten tragen keine
   Zahlen, also brauchen sie auch keine Breite über das Symbol hinaus. */
/* Gleiche Breite für jede Rechtespalte, damit die Kreise eine saubere Rasterlinie bilden — sonst richtet
   sich jede Spalte nach der Länge ihrer Überschrift, und die Kreise stehen versetzt. Der Inhalt ist in
   allen gleich breit (ein Kreis oder ein Gedankenstrich), also gibt es nichts, wofür sie unterschiedlich
   breit sein müssten. */
/* Der volle Pfad ist hier kein Zierrat: die Grundregel der Tabelle setzt text-align und padding mit
   (0,4,5) und schlüge jede kürzere Fassung — die Zentrierung griffe schlicht nicht. */
div.wrapper > div.main > div.content .table > table td.permission-cell,
div.wrapper > div.main > div.content .table > table th.permission-cell { width:52px; text-align:center; white-space:nowrap; }
/* Umbruch nur an Leerzeichen — Wörter werden nicht aufgebrochen. Die Spalte wächst dann eben auf ihr
   längstes Wort; ein zerrissenes "Kostenplan-ung" liest sich schlechter als eine breitere Spalte.

   Kleiner als die Gruppe darüber: die Gruppe ordnet, der Bereich benennt. Stünden beide gleich gross da,
   läse sich die zweite Zeile als vierzehn gleichrangige Spalten und die erste als Dekoration. */
div.wrapper > div.main > div.content .table > table th.permission-cell > div { white-space:normal; line-height:1.2em; font-size:0.85em; font-weight:normal; }

/* Das Dach über den Bereichsspalten: Projekt, Daten, Auswertung. Der Strich unten fasst zusammen, welche
   Spalten dazugehören — bei sechs nebeneinander sagt eine zentrierte Überschrift allein zu wenig. */
div.wrapper > div.main > div.content .table > table th.permission-band { text-align:center; padding-bottom:0.4em; }
/* kein seitlicher Rand: die Zelle hat dieselbe Polsterung wie die Spaltenköpfe darunter, also läuft die
   Unterlinie ohne Zutun genau auf deren Kante — ein Rand hier zöge sie um seine Breite nach innen */
div.wrapper > div.main > div.content .table > table th.permission-band > div { white-space:nowrap; font-weight:600; border-bottom:1px solid #E4E9EF; padding-bottom:0.4em; }

/* Die Grenze zwischen zwei Bereichen, durch Dach, Spaltenkopf und jede Datenzeile hindurch. Nicht die
   .line-Klasse der Tabelle: die bringt padding-right:20px mit, was die Kreise aus der Mitte ihrer 52px
   schöbe. Nur ein Strich, keine Polsterung. */
div.wrapper > div.main > div.content .table > table th.permission-divider,
div.wrapper > div.main > div.content .table > table td.permission-divider { border-left:1px solid #E4E9EF; }

/* Die Mitgliederzahl steht mittig, wie die Kreise daneben — eine Zahl am linken Rand klebt an einem Wort,
   das nicht da ist. Der volle Pfad, weil die Grundregel der Tabelle text-align mit (0,4,5) setzt. */
div.wrapper > div.main > div.content .table > table th.permission-count,
div.wrapper > div.main > div.content .table > table td.permission-count { text-align:center; }
div.wrapper > div.main > div.content .table > table tr.permission-groups > th { padding-top:0; }
/* Der Haken sitzt in einem Kreis: blau gefüllt darf schreiben, hellgrau gefüllt darf lesen. Kein Recht
   bleibt leer — die dritte Marke wäre die auffälligste in einer vierzehnspaltigen Zeile und zeigte das
   Uninteressanteste an. Der Kreis trägt die Aussage, nicht die Strichfarbe: gefüllte Flächen unterscheiden
   sich über eine ganze Tabelle hinweg schneller als zwei Töne desselben Symbols.

   em statt px, damit der Kreis der Schriftgröße der Tabelle folgt; feste Breite und gleiche line-height
   halten ihn rund und den Haken mittig. */
/* Der Rechte-Haken im Kreis — eine Definition für beide Stellen, an denen er vorkommt: die Rechtespalten
   der Übersicht (module/permissions.php) und die Summenzellen im Rechte-Overlay (module/project-user.php).
   Zwei Kopien hiervon wären zwei Anzeigen derselben Sache, die auseinanderlaufen können.

   Zentriert über flex, nicht über line-height: die müsste exakt der Innenhöhe entsprechen, und die ergibt
   sich aus einer Grösse in em minus einem Rahmen in px. */
i.permission-write,
i.permission-read {
    display:inline-flex; align-items:center; justify-content:center;
    box-sizing:border-box; width:1.85em; height:1.85em;
    border:1px solid transparent; border-radius:50%;
    font-size:0.85em; line-height:1; vertical-align:middle;
}

/* Fontello gibt JEDER Glyphe width:1em und margin-right:.2em mit (profuturum-icon.css). Im Kreis schiebt
   dieser rechte Rand den Haken um ein Zehntel nach links — sichtbar, sobald ringsum eine Kontur liegt. */
i.permission-write:before,
i.permission-read:before { width:auto; margin:0; }

/* Gefüllt darf schreiben, hohl darf lesen. Dieselbe Farbe, nur nicht ausgefüllt — das unterscheidet sich
   über eine Spalte hinweg schneller als zwei Töne desselben Symbols. Beide tragen denselben 1px-Rahmen
   (beim Schreiben in der eigenen Farbe), damit die Kreise gleich gross bleiben. */
i.permission-write { background-color:#19A483; border-color:#19A483; color:#FFFFFF; }
i.permission-read  { background-color:#FFFFFF; border-color:#19A483; color:#6C7382; }

/* Die ganze Zeile führt ins Rechte-Overlay, die Gruppenspalte ins Maximum ihrer Gruppe. Die Links sollen
   dabei aussehen wie der Zelleninhalt, den sie umschliessen — ein blau unterstrichener Haken wäre ein
   Bedienelement, das es nicht gibt. Der Zeiger sagt, dass etwas passiert. */
table.permissions-overview td > a { color:inherit; text-decoration:none; display:block; cursor:pointer; }

/* S71: eine Fläche, zwei Namen, dieselben vier Erklärungen — permissions-empty (service/permissions.php,
   und dieselbe Klasse tragen die beiden Ladezeilen aus module/permissions.php) und permission-empty (hier,
   module/project-user.php) sind zwei Klassen für denselben Anstrich. Zusammengelegt ist hier nur die
   DOPPELTE ERKLÄRUNG, nicht der Name: beide Klassen bleiben, wie sie sind, und dieselben Zeilen bleiben
   getroffen wie vorher — nur eine gemeinsame Regel statt zwei wortgleicher.

   Die Namen selbst NICHT zusammengelegt, und das ist gemessen statt Geschmack: permissions-empty gehört
   laut tests/Unit/PermissionTest.php (testNothingThisFeatureAddedReachesAPageItDoesNotBelongTo) exakt
   module/permissions.php und service/permissions.php — käme module/project-user.php als dritte Datei
   dazu, würde genau diese Zusicherung rot. Der naheliegende Weg, der stattdessen die MARKUP-Klasse
   vereinheitlicht, ist in einer früheren Fassung dieser Runde genau daran gescheitert. */
div.wrapper > div.main > div.content .table > table td.permissions-empty,
.permission-table tr.permission-empty > td { text-align:center; font-style:italic; color:#6C7382; padding:1.25em 0; }
table.permissions-overview td .light { color:#6C7382; font-style:italic; }

/* Der Hinweis in einer leeren Gruppe. Sichtbar nur, solange sie eine ist — permissionRegroup() setzt
   .permission-has-members auf die tbody, sobald jemand darin steht. Ohne diese Klasse (erster Aufbau vor
   dem ersten Regroup) zeigt eine gefüllte Gruppe den Hinweis nicht, weil das Markup ihn nur für Gruppen
   ausgibt, die serverseitig leer sind — und leer heisst hier: gerade eben angelegt. */
.permission-table tbody.permission-has-members > tr.permission-empty { display:none; }

/* Der Sortiergriff steht immer links in seiner Zelle — siehe die Ausnahme in der
   action-collapsed-last-Regel weiter oben, die ihn sonst nach rechts zöge. */
.permission-table td.permission-move { text-align:left; padding-right:0; }
/* The counter IS a label.input — same padding, same line, same rule beneath, same colour under the pointer
   as a field has under focus. Replicating those numbers here would only mean they drift the day somebody
   changes them, and the row height would be set by whichever box happened to end up taller. */
/* min-height, not line-height. A tick is not text: with an icon in it the anchor has no line box at all,
   line-height has nothing to act on, and the block collapses to nothing — which is why the cell was short
   exactly for the people who had full access. 1.3em is the line box a line of text would have made. */
.permission-table td.permission-summary > label.input > a { display:block; min-height:1.3em; color:#061353; }

.permission-fraction { font-variant-numeric:tabular-nums; color:#6C7382; }

/* Die Summenzelle zeigt den Kreis; die Zahl dahinter erscheint erst beim Darüberfahren. Auf einen Blick
   soll die Zeile sagen, WAS jemand in dieser Gruppe darf — wie viele von wie vielen ist die Nachfrage.

   Der Gedankenstrich für "gar nichts" steht ohne Kreis daneben und fällt deshalb aus beiden Regeln heraus:
   er bleibt immer sichtbar, sonst wäre die Zelle leer und man wüsste nicht, ob dort nichts gilt oder nichts
   geladen wurde. */
.permission-table td.permission-summary i + .permission-fraction { display:none; }
.permission-table td.permission-summary:hover i { display:none; }
.permission-table td.permission-summary:hover i + .permission-fraction { display:inline; }

/* The matrix opens in the app's own overlay, so it is over the header and looks like every other dialog.
   Only wider: three tables of areas do not fit in a confirmation box. */
div.overlay.shown.permissions > div.container > .padding > div.content { max-width:680px; text-align:left; }
/* The heading brings a top margin of its own, and it lands INSIDE the block — behind the rule. Collapsed,
   the block is nothing BUT the heading, so that margin was the whole difference: 23px above the heading and
   54px below the rule. The block's own margin and padding are the only spacing here. */
div.overlay.shown.permissions > div.container > .padding > div.content > [data-permission-content] > p:first-of-type,
div.overlay.shown.permissions > div.container > .padding > div.content > [data-permission-group-max-content] > p:first-of-type { margin-bottom:2em; }
div.overlay.shown.permissions > div.container > .padding > div.content h3 { margin-top:0; margin-bottom:0; }
div.overlay.shown.permissions > div.container > .padding > div.content .permission-section + .permission-section { margin-top:1.8em; padding-top:1.8em; border-top:1px solid #E4E9EF; }
div.overlay.shown.permissions > div.container > .padding > div.content h3 > a { color:inherit; }

/* Folded away, a block is its heading. You arrived here from ONE of them, so that is the one that opens —
   the other two are a page of scrolling you did not ask for. */
.permission-section.collapsed > p,
.permission-section.collapsed > table { display:none; }

.permission-section h3 .group-toggle { display:inline-block; margin-left:1.2em; width:1em; font-size:0.55em; line-height:1; vertical-align:middle; color:#97A3B5; font-family:"profuturum-icon"; font-style:normal; font-weight:normal; speak:never; text-transform:none; -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale; }
.permission-section h3 .group-toggle:before { content:'\e823'; }
.permission-section.collapsed h3 .group-toggle:before { content:'\e822'; }

.permission-dialog[hidden] { display:none; }

/* Three tables, one grid. Fixed layout and the same widths in each, so the columns line up straight down
   the dialog — read against read, write against write. Three tables that each sized themselves to their own
   longest area name would make the levels wander from block to block.

   display:table is not decoration. The table carries class="input", and .input sets display:block — which
   stops it being a table box at all: the inner table shrink-wraps to its content inside a full-width block,
   so table-layout and width:100% have nothing to act on and the first column never expands. Measured: the
   table reported 680px while its columns added up to 447. */
.permission-matrix { display:table; table-layout:fixed; width:100%; }
.permission-matrix th.permission-level,
.permission-matrix td.permission-level { width:110px; text-align:center; }

/* The last column is a level like the other two, but the app right-aligns the last cell of every row and
   strips its padding — with more specificity than the rule above, so it won, and Schreibrecht sat hard
   against the edge while the other two were centred. Written to outweigh it, not to follow it. */
table.input.permission-matrix th.permission-level:last-child { text-align:center; padding-right:0.84em; }
table.input.permission-matrix td.permission-level:last-child { text-align:center; padding-right:0.57em; }
.permission-matrix td.permission-level > .input.checkbox { display:inline-flex; margin:0; }

/* The headers are controls, not links to somewhere else — they set their whole column. Blue would promise
   navigation, so they read as headers and only answer to the pointer. */
.permission-matrix th.permission-level > a { color:inherit; }
.permission-matrix th.permission-level > a:hover { color:#061353; text-decoration:underline; }

/* A level that cannot be chosen shows a dash instead of a box — and the dash says why, on hover. A box you
   can click but that does nothing is the worst of the three; an empty cell is the second worst.

   Specificity matters here and it bites: the rule above that makes the box an inline-flex carries an element
   as well as its classes, so a hide rule with the same classes and no element LOSES to it, and the box stays
   next to the dash. These are written to outweigh it, not merely to follow it. */
.permission-matrix td.permission-level > .input.checkbox.hidden,
.permission-matrix td.permission-level > .permission-locked.hidden { display:none; }
.permission-matrix td.permission-level > .permission-locked { display:inline-block; color:#C3CAD5; cursor:help; }



/* A page you may only read.

   The server refuses the write regardless — this is what stops somebody filling in a form for ten minutes
   and only then being told. Everything that CHANGES something goes: the save block, and the controls that
   add, remove and move rows.

   The search form is exempt: it posts, but it posts a question, not a change. And so is everything inside
   a [data-readonly-surface]: the hub pane sits in the page's content but follows its OWN write area — its
   own .readonly rules below hide its controls, and the page's readonly must not reach in and hide the
   save button of a pane the person may very well write (the access-exempt editor on a read-only hub). */
body.readonly div.wrapper > div.main > div.content .input.submit:not([data-readonly-surface] *),
body.readonly div.wrapper > div.main > div.content [data-multi-add]:not([data-readonly-surface] *),
body.readonly div.wrapper > div.main > div.content [data-multi-remove]:not([data-readonly-surface] *),
body.readonly div.wrapper > div.main > div.content [data-multi-move]:not([data-readonly-surface] *),
body.readonly div.wrapper > div.main > div.content [data-clear]:not([data-readonly-surface] *),
body.readonly div.wrapper > div.main > div.content [data-confirm-delete]:not([data-readonly-surface] *),
body.readonly div.wrapper > div.main > div.content [data-permission-group-max-open]:not([data-readonly-surface] *),
body.readonly div.wrapper > div.main > div.content [data-submit-overlay]:not([data-readonly-surface] *) { display:none !important; }

/* A surface — a slider, an overlay, the /project hub pane — carries its OWN .readonly (its write area can
   differ from the page's), and the same write controls are hidden inside it, independently of body.readonly. */
#slider_content.readonly .input.submit,
#slider_content.readonly [data-multi-add],
#slider_content.readonly [data-multi-remove],
#slider_content.readonly [data-multi-move],
#slider_content.readonly [data-clear],
#slider_content.readonly [data-confirm-delete],
#slider_content.readonly [data-submit-overlay],
#overlay_content.readonly .input.submit,
#overlay_content.readonly [data-multi-add],
#overlay_content.readonly [data-multi-remove],
#overlay_content.readonly [data-multi-move],
#overlay_content.readonly [data-clear],
#overlay_content.readonly [data-confirm-delete],
#overlay_content.readonly [data-submit-overlay],
[data-readonly-surface].readonly .input.submit,
[data-readonly-surface].readonly [data-multi-add],
[data-readonly-surface].readonly [data-multi-remove],
[data-readonly-surface].readonly [data-multi-move],
[data-readonly-surface].readonly [data-clear],
[data-readonly-surface].readonly [data-confirm-delete],
#slider_content.readonly [data-permission-group-max-open],
#overlay_content.readonly [data-permission-group-max-open],
[data-readonly-surface].readonly [data-permission-group-max-open],
[data-readonly-surface].readonly [data-submit-overlay] { display:none !important; }

/* Kill the readonly flicker on action columns: the action BUTTONS are hidden above, but their now-empty cell
   and the <hr> divider leading to it are server-rendered and only folded by collapseActionColumns() AFTER
   load — so they flash. Hide them from the first paint too (:has() only; where it is unsupported the JS fold
   still runs, flicker and all). collapseActionColumns() then only flush-rights the new last cell. The <hr>
   match is scoped to a divider IMMEDIATELY BEFORE an action cell, so ordinary column dividers stay put. */
body.readonly div.wrapper > div.main > div.content table.input td:has(> [data-multi-move]):not([data-readonly-surface] *),
body.readonly div.wrapper > div.main > div.content table.input td:has(> [data-multi-remove]):not([data-readonly-surface] *),
body.readonly div.wrapper > div.main > div.content table.input td:has(> [data-permission-dialog]):not([data-readonly-surface] *),
body.readonly div.wrapper > div.main > div.content table.input td:has(> hr):has(+ td [data-multi-move]):not([data-readonly-surface] *),
body.readonly div.wrapper > div.main > div.content table.input td:has(> hr):has(+ td [data-multi-remove]):not([data-readonly-surface] *),
#slider_content.readonly table.input td:has(> [data-multi-move]),
#slider_content.readonly table.input td:has(> [data-multi-remove]),
#slider_content.readonly table.input td:has(> [data-permission-dialog]),
#slider_content.readonly table.input td:has(> hr):has(+ td [data-multi-move]),
#slider_content.readonly table.input td:has(> hr):has(+ td [data-multi-remove]),
#overlay_content.readonly table.input td:has(> [data-multi-move]),
#overlay_content.readonly table.input td:has(> [data-multi-remove]),
#overlay_content.readonly table.input td:has(> [data-permission-dialog]),
#overlay_content.readonly table.input td:has(> hr):has(+ td [data-multi-move]),
#overlay_content.readonly table.input td:has(> hr):has(+ td [data-multi-remove]),
[data-readonly-surface].readonly table.input td:has(> [data-multi-move]),
[data-readonly-surface].readonly table.input td:has(> [data-multi-remove]),
[data-readonly-surface].readonly table.input td:has(> [data-permission-dialog]),
[data-readonly-surface].readonly table.input td:has(> hr):has(+ td [data-multi-move]),
[data-readonly-surface].readonly table.input td:has(> hr):has(+ td [data-multi-remove]) { display:none !important; }

/* An autofilled field on a page you may only read — the same case as the file entry below: the field IS
   the control, so it must stop inviting the click that permissionReadonly() refuses. */
body.readonly div.wrapper > div.main > div.content .input > input[data-autofill][readonly]:not([data-readonly-surface] *),
#slider_content.readonly .input > input[data-autofill][readonly],
#overlay_content.readonly .input > input[data-autofill][readonly],
[data-readonly-surface].readonly .input > input[data-autofill][readonly] { cursor:default; }

/* An attached file, on a page you may only read.

   The delete affordance on a file entry is the li's own ::after — the ✕ — not a button, so none of the
   [data-…] rules above touch it. Without this the entry still invites the click that permissionReadonly()
   now refuses: a cross, a pointer cursor, and nothing happening.

   Both crosses go: li::after is the one always on show, and li a:hover::after is the same cross repositioned
   outside the dark fill while the link is hovered — leaving that one would put a delete affordance on the
   download itself.

   The <a> keeps everything else: its pointer, its hover, its href. Downloading a file — and previewing it,
   which runs through the same service/file.php — is a READ, gated on the document's own type and offered to
   whoever may read that type. A read-only member is entitled to both. */
body.readonly div.wrapper > div.main > div.content .input.file > ul > li:not([data-readonly-surface] *),
#slider_content.readonly .input.file > ul > li,
#overlay_content.readonly .input.file > ul > li,
[data-readonly-surface].readonly .input.file > ul > li { cursor:default; }

body.readonly div.wrapper > div.main > div.content .input.file > ul > li:not([data-readonly-surface] *):after,
body.readonly div.wrapper > div.main > div.content .input.file > ul > li:not([data-readonly-surface] *) a:hover:after,
#slider_content.readonly .input.file > ul > li:after,
#slider_content.readonly .input.file > ul > li a:hover:after,
#overlay_content.readonly .input.file > ul > li:after,
#overlay_content.readonly .input.file > ul > li a:hover:after,
[data-readonly-surface].readonly .input.file > ul > li:after,
[data-readonly-surface].readonly .input.file > ul > li a:hover:after { display:none; }

/* The "weitere … hinzufügen" footer row.

   Its <a data-multi-add> is hidden above, but the <tr><th colspan="N"> around it is server-rendered — so a
   read-only user was left with an empty, full-height bordered row under every table. collapseActionColumns()
   does not reach it: that walks children('td'), and this is a lone <th> in a <tfoot>.

   Hidden as a ROW, keyed on the add-link it exists to carry, so it covers the seven tables that have one
   today and any added later. project-budget.php guards its whole <tfoot> server-side and is unaffected
   either way. (:has() only — the JS in readonlyPage() folds the same rows where it is unsupported.) */
body.readonly div.wrapper > div.main > div.content table.input tr:has(> th:only-child > [data-multi-add]):not([data-readonly-surface] *),
#slider_content.readonly table.input tr:has(> th:only-child > [data-multi-add]),
#overlay_content.readonly table.input tr:has(> th:only-child > [data-multi-add]),
[data-readonly-surface].readonly table.input tr:has(> th:only-child > [data-multi-add]) { display:none !important; }

body.readonly div.wrapper > div.main > div.content form:not([data-autosubmit-ajax]) .input.checkbox input:disabled + span,
body.readonly div.wrapper > div.main > div.content form:not([data-autosubmit-ajax]) input:read-only { cursor:default; }
