Changes for page Service Navigator

Last modified by Veronika Kocher on Thursday, 03 Sep 2026 14:15

From version 22.14
edited by Veronika Kocher
on Thursday, 03 Sep 2026 9:34
Change comment: There is no comment for this version
To version 22.9
edited by ZID Server
on Tuesday, 01 Sep 2026 10:21
Change comment: allow comment right for XWiki.p0010210

Summary

Details

Page properties
Author
... ... @@ -1,1 +1,1 @@
1 -XWiki.p0009670
1 +XWiki.server
Content
... ... @@ -114,9 +114,7 @@
114 114   <div style="padding:18px 18px 14px 18px;flex:1;">
115 115   <div style="display:inline-block;font-size:12px;font-weight:700;letter-spacing:.065em;color:#4f4a44;margin-bottom:8px;padding:4px 7px;background:#f3efe8;border-radius:4px;">ART &amp; RESEARCH</div>
116 116   <h3 style="font-size:21px;line-height:1.25;margin:0 0 8px 0;color:#252321;">Art &amp; Research Services</h3>
117 - <p style="color:#6a655e;margin:0 0 8px 0;">Cross-unit guidance for planning, managing, publishing, sharing and preserving artistic and research projects.</p>
118 - <!-- ARSN_ROOT_SCOPE_ROUTING_V1 -->
119 - <div style="font-size:12px;color:#506168;line-height:1.45;margin:0 0 14px 0;padding:7px 9px;background:#eef7f9;border-radius:5px;"><strong>Central project &amp; funding hub:</strong> Support Kunst und Forschung · specialist responsibilities remain with the relevant service units.</div>
117 + <p style="color:#6a655e;margin:0 0 14px 0;">Plan, manage, publish, share and preserve artistic and research projects.</p>
120 120  
121 121   <div style="font-weight:700;margin-bottom:6px;">I need to…</div>
122 122   <ul style="margin:0 0 14px 18px;padding:0;">
... ... @@ -284,699 +284,3 @@
284 284  
285 285  </div>
286 286  {{/html}}
287 -
288 -{{html clean="false"}}
289 -<!-- SN_HORIZONTAL_BOX_HARMONIZER_START -->
290 -<style data-sn-horizontal-box-harmonizer="4">
291 -[data-sn-equal-height-managed],
292 -[data-sn-first-section-aligned]{
293 - box-sizing:border-box;
294 -}
295 -</style>
296 -<script data-sn-horizontal-box-harmonizer="4">
297 -(function(){
298 - "use strict";
299 -
300 - var MOBILE_MAX=767;
301 - var ROW_TOLERANCE=6;
302 - var MIN_W=150;
303 - var MIN_H=36;
304 - var MAX_PARENT_CHILDREN=16;
305 - var SEARCH_DEPTH=5;
306 -
307 - var root=
308 - document.getElementById("xwikicontent")||
309 - document.querySelector(".xwiki-rendering-content")||
310 - document.querySelector("main")||
311 - document.body;
312 -
313 - if(!root)return;
314 -
315 - var heightManaged=new Set();
316 - var sectionManaged=new Set();
317 - var originalMinHeight=new WeakMap();
318 - var originalMarginTop=new WeakMap();
319 - var raf=0;
320 -
321 - function num(v){
322 - var n=parseFloat(v);
323 - return Number.isFinite(n)?n:0;
324 - }
325 -
326 - function visible(el,minW,minH){
327 - if(!el||el.nodeType!==1)return false;
328 -
329 - var s=getComputedStyle(el);
330 -
331 - if(
332 - s.display==="none"||
333 - s.visibility==="hidden"||
334 - Number(s.opacity)===0
335 - ){
336 - return false;
337 - }
338 -
339 - var r=el.getBoundingClientRect();
340 -
341 - return (
342 - r.width>=(minW||1)&&
343 - r.height>=(minH||1)
344 - );
345 - }
346 -
347 - function excluded(el){
348 - return (
349 - !el.matches||
350 - el.matches(
351 - "button,input,select,textarea,option,label,img,svg,canvas,table,thead,tbody,tfoot,tr,td,th,summary,script,style,noscript,template,.btn,.chip,[role=button]"
352 - )
353 - );
354 - }
355 -
356 - function namedLikeBox(el){
357 - var c=
358 - typeof el.className==="string"
359 - ? el.className
360 - : "";
361 -
362 - return /(^|[s_-])(box|card|tile|panel|role|check|service|source|call|area|detail|resource|topic|warn|info)([s_-]|$)/i.test(c);
363 - }
364 -
365 - function boxLike(el){
366 - if(!visible(el,MIN_W,MIN_H)||excluded(el))return false;
367 -
368 - var s=getComputedStyle(el);
369 - var r=el.getBoundingClientRect();
370 -
371 - var border=
372 - num(s.borderTopWidth)+
373 - num(s.borderRightWidth)+
374 - num(s.borderBottomWidth)+
375 - num(s.borderLeftWidth);
376 -
377 - var radius=Math.max(
378 - num(s.borderTopLeftRadius),
379 - num(s.borderTopRightRadius),
380 - num(s.borderBottomLeftRadius),
381 - num(s.borderBottomRightRadius)
382 - );
383 -
384 - var bg=
385 - s.backgroundColor&&
386 - s.backgroundColor!=="rgba(0, 0, 0, 0)"&&
387 - s.backgroundColor!=="transparent";
388 -
389 - var shadow=
390 - s.boxShadow&&
391 - s.boxShadow!=="none";
392 -
393 - return (
394 - namedLikeBox(el)||
395 - border>=1||
396 - (bg&&radius>=3)||
397 - (shadow&&r.width>=180)
398 - );
399 - }
400 -
401 - function saveOriginal(el,map,property){
402 - if(map.has(el))return;
403 -
404 - map.set(el,{
405 - value:el.style.getPropertyValue(property),
406 - priority:el.style.getPropertyPriority(property)
407 - });
408 - }
409 -
410 - function restoreOriginal(el,map,property){
411 - var original=map.get(el);
412 -
413 - if(original&&original.value){
414 - el.style.setProperty(
415 - property,
416 - original.value,
417 - original.priority||""
418 - );
419 - }else{
420 - el.style.removeProperty(property);
421 - }
422 - }
423 -
424 - function reset(){
425 - heightManaged.forEach(function(el){
426 - restoreOriginal(
427 - el,
428 - originalMinHeight,
429 - "min-height"
430 - );
431 -
432 - el.removeAttribute(
433 - "data-sn-equal-height-managed"
434 - );
435 - });
436 -
437 - sectionManaged.forEach(function(el){
438 - restoreOriginal(
439 - el,
440 - originalMarginTop,
441 - "margin-top"
442 - );
443 -
444 - el.removeAttribute(
445 - "data-sn-first-section-aligned"
446 - );
447 - });
448 -
449 - heightManaged.clear();
450 - sectionManaged.clear();
451 - }
452 -
453 - function pickTarget(child){
454 - if(!visible(child,MIN_W,MIN_H))return null;
455 -
456 - if(boxLike(child)){
457 - return child;
458 - }
459 -
460 - var cr=child.getBoundingClientRect();
461 - var q=[];
462 -
463 - Array.from(child.children||[]).forEach(function(el){
464 - q.push({el:el,depth:1});
465 - });
466 -
467 - var best=null;
468 - var bestScore=-Infinity;
469 -
470 - while(q.length){
471 - var item=q.shift();
472 - var el=item.el;
473 -
474 - if(!visible(el,MIN_W,MIN_H))continue;
475 -
476 - var r=el.getBoundingClientRect();
477 -
478 - if(
479 - r.width>=cr.width*.68&&
480 - boxLike(el)
481 - ){
482 - var widthFit=
483 - 1-Math.min(
484 - 1,
485 - Math.abs(cr.width-r.width)/
486 - Math.max(1,cr.width)
487 - );
488 -
489 - var topFit=
490 - 1-Math.min(
491 - 1,
492 - Math.abs(cr.top-r.top)/100
493 - );
494 -
495 - var score=
496 - widthFit*6+
497 - topFit*3+
498 - Math.min(r.height,900)/450+
499 - Math.min(r.width*r.height,900000)/900000;
500 -
501 - if(score>bestScore){
502 - best=el;
503 - bestScore=score;
504 - }
505 - }
506 -
507 - if(item.depth<SEARCH_DEPTH){
508 - Array.from(el.children||[]).forEach(function(next){
509 - q.push({
510 - el:next,
511 - depth:item.depth+1
512 - });
513 - });
514 - }
515 - }
516 -
517 - return best;
518 - }
519 -
520 - function groupsByVisualRow(entries){
521 - var groups=[];
522 -
523 - entries
524 - .slice()
525 - .sort(function(a,b){
526 - return (
527 - a.rect.top-b.rect.top||
528 - a.rect.left-b.rect.left
529 - );
530 - })
531 - .forEach(function(entry){
532 - var group=null;
533 -
534 - for(var i=0;i<groups.length;i++){
535 - if(
536 - Math.abs(
537 - groups[i].top-
538 - entry.rect.top
539 - )<=ROW_TOLERANCE
540 - ){
541 - group=groups[i];
542 - break;
543 - }
544 - }
545 -
546 - if(!group){
547 - group={
548 - top:entry.rect.top,
549 - entries:[]
550 - };
551 - groups.push(group);
552 - }
553 -
554 - group.entries.push(entry);
555 - });
556 -
557 - return groups;
558 - }
559 -
560 - function validHorizontalGroup(group){
561 - if(group.entries.length<2)return false;
562 -
563 - var lefts=
564 - group.entries
565 - .map(function(e){return e.rect.left;})
566 - .sort(function(a,b){return a-b;});
567 -
568 - if(
569 - lefts[lefts.length-1]-
570 - lefts[0]<
571 - 80
572 - ){
573 - return false;
574 - }
575 -
576 - var widths=
577 - group.entries
578 - .map(function(e){return e.rect.width;})
579 - .filter(function(w){return w>0;});
580 -
581 - if(widths.length<2)return false;
582 -
583 - var minWidth=Math.min.apply(Math,widths);
584 - var maxWidth=Math.max.apply(Math,widths);
585 -
586 - return (
587 - maxWidth/
588 - Math.max(1,minWidth)<=
589 - 1.9
590 - );
591 - }
592 -
593 - function normalizeText(text){
594 - return String(text||"")
595 - .replace(/s+/g," ")
596 - .trim()
597 - .toUpperCase();
598 - }
599 -
600 - function exactKnownFirstSection(el){
601 - var text=normalizeText(el.textContent);
602 -
603 - return (
604 - text==="HIER STARTEN"||
605 - text==="ORGANISIEREN & DOKUMENTIEREN"||
606 - text==="ENTSCHEIDEN"||
607 - text==="START HERE"||
608 - text==="GET STARTED"||
609 - text==="ORGANISE & DOCUMENT"||
610 - text==="ORGANIZE & DOCUMENT"||
611 - text==="DECIDE"
612 - );
613 - }
614 -
615 - function visuallyFirstSectionBar(card){
616 - var cardRect=card.getBoundingClientRect();
617 - var candidates=[];
618 -
619 - Array.from(
620 - card.querySelectorAll(
621 - "div,p,span,strong,h3,h4,h5,h6"
622 - )
623 - ).forEach(function(el){
624 - if(!visible(el,20,6))return;
625 - if(excluded(el))return;
626 -
627 - var r=el.getBoundingClientRect();
628 - var relativeTop=r.top-cardRect.top;
629 -
630 - if(
631 - relativeTop<45||
632 - relativeTop>cardRect.height*.72
633 - ){
634 - return;
635 - }
636 -
637 - var widthRatio=
638 - r.width/
639 - Math.max(1,cardRect.width);
640 -
641 - if(
642 - widthRatio<.55||
643 - widthRatio>1.05||
644 - r.height>54
645 - ){
646 - return;
647 - }
648 -
649 - var text=normalizeText(el.textContent);
650 -
651 - if(
652 - text.length<2||
653 - text.length>90
654 - ){
655 - return;
656 - }
657 -
658 - var style=getComputedStyle(el);
659 -
660 - var bg=
661 - style.backgroundColor&&
662 - style.backgroundColor!=="rgba(0, 0, 0, 0)"&&
663 - style.backgroundColor!=="transparent";
664 -
665 - var border=
666 - num(style.borderTopWidth)+
667 - num(style.borderRightWidth)+
668 - num(style.borderBottomWidth)+
669 - num(style.borderLeftWidth);
670 -
671 - var mostlyUpper=
672 - text.length>=3&&
673 - text===text.toUpperCase();
674 -
675 - var exact=exactKnownFirstSection(el);
676 -
677 - var score=
678 - (exact?20:0)+
679 - (bg?6:0)+
680 - (border>=1?2:0)+
681 - (mostlyUpper?4:0)+
682 - (num(style.fontWeight)>=600?1:0);
683 -
684 - if(score>=7){
685 - candidates.push({
686 - el:el,
687 - relativeTop:relativeTop,
688 - width:r.width,
689 - score:score
690 - });
691 - }
692 - });
693 -
694 - if(!candidates.length)return null;
695 -
696 - candidates.sort(function(a,b){
697 - if(a.score!==b.score)return b.score-a.score;
698 - if(Math.abs(a.relativeTop-b.relativeTop)>3){
699 - return a.relativeTop-b.relativeTop;
700 - }
701 - return b.width-a.width;
702 - });
703 -
704 - // For exact known labels always prefer the earliest exact match.
705 - var exacts=candidates.filter(function(c){
706 - return exactKnownFirstSection(c.el);
707 - });
708 -
709 - if(exacts.length){
710 - exacts.sort(function(a,b){
711 - return a.relativeTop-b.relativeTop||b.width-a.width;
712 - });
713 - return exacts[0].el;
714 - }
715 -
716 - // Generic fallback: earliest high-confidence bar.
717 - candidates.sort(function(a,b){
718 - return a.relativeTop-b.relativeTop||b.score-a.score||b.width-a.width;
719 - });
720 -
721 - return candidates[0].el;
722 - }
723 -
724 - function alignFirstSections(cards){
725 - var rows=
726 - cards.map(function(card){
727 - var bar=
728 - visuallyFirstSectionBar(card);
729 -
730 - if(!bar)return null;
731 -
732 - var cardRect=
733 - card.getBoundingClientRect();
734 -
735 - var barRect=
736 - bar.getBoundingClientRect();
737 -
738 - return {
739 - card:card,
740 - bar:bar,
741 - relativeTop:
742 - barRect.top-cardRect.top,
743 - label:
744 - normalizeText(bar.textContent)
745 - };
746 - });
747 -
748 - // Conservative: only align when every card in the horizontal row
749 - // has a reliable first section bar.
750 - if(
751 - rows.some(function(row){
752 - return !row;
753 - })
754 - ){
755 - return null;
756 - }
757 -
758 - var targetTop=
759 - Math.max.apply(
760 - Math,
761 - rows.map(function(row){
762 - return row.relativeTop;
763 - })
764 - );
765 -
766 - rows.forEach(function(row){
767 - var delta=
768 - targetTop-
769 - row.relativeTop;
770 -
771 - if(delta<=1)return;
772 -
773 - saveOriginal(
774 - row.bar,
775 - originalMarginTop,
776 - "margin-top"
777 - );
778 -
779 - var currentMargin=
780 - num(
781 - getComputedStyle(
782 - row.bar
783 - ).marginTop
784 - );
785 -
786 - row.bar.style.setProperty(
787 - "margin-top",
788 - (
789 - currentMargin+
790 - delta
791 - )+"px"
792 - );
793 -
794 - row.bar.setAttribute(
795 - "data-sn-first-section-aligned",
796 - "4"
797 - );
798 -
799 - sectionManaged.add(row.bar);
800 - });
801 -
802 - return {
803 - labels:
804 - rows.map(function(row){
805 - return row.label;
806 - }),
807 - targetRelativeTop:
808 - Math.round(targetTop)
809 - };
810 - }
811 -
812 - function applyGroup(group){
813 - if(!validHorizontalGroup(group)){
814 - return null;
815 - }
816 -
817 - var cards=[];
818 - var seen=new Set();
819 -
820 - group.entries.forEach(function(entry){
821 - if(!seen.has(entry.target)){
822 - seen.add(entry.target);
823 - cards.push(entry.target);
824 - }
825 - });
826 -
827 - if(cards.length<2)return null;
828 -
829 - var firstSection=
830 - alignFirstSections(cards);
831 -
832 - // The section alignment can change natural card heights.
833 - // Measure only afterwards.
834 - var maxHeight=0;
835 -
836 - cards.forEach(function(card){
837 - maxHeight=Math.max(
838 - maxHeight,
839 - card.getBoundingClientRect().height
840 - );
841 - });
842 -
843 - maxHeight=Math.ceil(maxHeight);
844 -
845 - if(maxHeight<MIN_H)return null;
846 -
847 - cards.forEach(function(card){
848 - saveOriginal(
849 - card,
850 - originalMinHeight,
851 - "min-height"
852 - );
853 -
854 - card.style.setProperty(
855 - "min-height",
856 - maxHeight+"px"
857 - );
858 -
859 - card.setAttribute(
860 - "data-sn-equal-height-managed",
861 - "4"
862 - );
863 -
864 - heightManaged.add(card);
865 - });
866 -
867 - return {
868 - cards:cards.length,
869 - height:maxHeight,
870 - firstSection:firstSection
871 - };
872 - }
873 -
874 - function run(){
875 - reset();
876 -
877 - if(
878 - window.innerWidth<=MOBILE_MAX
879 - ){
880 - return;
881 - }
882 -
883 - var parents=
884 - Array.from(
885 - root.querySelectorAll("*")
886 - ).filter(function(parent){
887 - return (
888 - visible(parent,MIN_W,MIN_H)&&
889 - parent.children&&
890 - parent.children.length>=2&&
891 - parent.children.length<=MAX_PARENT_CHILDREN
892 - );
893 - });
894 -
895 - var touched=new Set();
896 -
897 - parents.forEach(function(parent){
898 - var entries=[];
899 -
900 - Array.from(parent.children).forEach(function(child){
901 - if(!visible(child,MIN_W,MIN_H))return;
902 -
903 - var target=pickTarget(child);
904 - if(!target)return;
905 -
906 - entries.push({
907 - target:target,
908 - rect:target.getBoundingClientRect()
909 - });
910 - });
911 -
912 - if(entries.length<2)return;
913 -
914 - groupsByVisualRow(entries).forEach(function(group){
915 - if(!validHorizontalGroup(group))return;
916 -
917 - var signature=
918 - group.entries.map(function(entry){
919 - return entry.target;
920 - });
921 -
922 - if(
923 - !signature.some(function(el){
924 - return !touched.has(el);
925 - })
926 - ){
927 - return;
928 - }
929 -
930 - var applied=
931 - applyGroup(group);
932 -
933 - if(applied){
934 - signature.forEach(function(el){
935 - touched.add(el);
936 - });
937 - }
938 - });
939 - });
940 - }
941 -
942 - function schedule(){
943 - if(raf)cancelAnimationFrame(raf);
944 -
945 - raf=requestAnimationFrame(function(){
946 - raf=requestAnimationFrame(function(){
947 - raf=0;
948 - run();
949 - });
950 - });
951 - }
952 -
953 - addEventListener("resize",schedule,{passive:true});
954 - addEventListener("load",schedule,{once:true});
955 -
956 - root.addEventListener(
957 - "click",
958 - function(){
959 - setTimeout(schedule,0);
960 - },
961 - true
962 - );
963 -
964 - Array.from(root.querySelectorAll("img")).forEach(function(img){
965 - if(!img.complete){
966 - img.addEventListener("load",schedule,{once:true});
967 - }
968 - });
969 -
970 - if(document.fonts&&document.fonts.ready){
971 - document.fonts.ready.then(schedule);
972 - }
973 -
974 - schedule();
975 - setTimeout(schedule,200);
976 - setTimeout(schedule,650);
977 - setTimeout(schedule,1400);
978 -})();
979 -</script>
980 -<!-- SN_HORIZONTAL_BOX_HARMONIZER_END -->
981 -{{/html}}
982 -
XWiki.XWikiRights[3]
levels
... ... @@ -1,1 +1,1 @@
1 -view,comment,edit,script
1 +view,comment