Last modified by Veronika Kocher on Friday, 18 Sep 2026 16:47

From version 41.2
edited by Veronika Kocher
on Friday, 04 Sep 2026 9:18
Change comment: There is no comment for this version
To version 39.22
edited by Veronika Kocher
on Thursday, 03 Sep 2026 9:34
Change comment: There is no comment for this version

Summary

Details

Page properties
Content
... ... @@ -2,14 +2,18 @@
2 2  
3 3  The **Art & Research Services Navigator** helps you find the right guidance, services and resources for each stage of your project.
4 4  
5 -{{info title="Support for Your Project:"}}
5 +{{info title="How responsibilities work"}}
6 +The navigator brings services together around the project lifecycle and the researcher's task. It is a navigation layer across university services, not a separate organisational unit.
6 6  
7 -
8 - **Support Kunst und Forschung (SKF)** provides guidance for projects and grant applications and collaborates with the appropriate university services as needed.
8 +**Support Kunst und Forschung (SKF)** supports project and funding activities — especially project development, funding and calls, proposals, and coordination of funded projects — and, where useful, connects them with the University's relevant services.
9 9  
10 - The Navigator guides you through the project phases to the resources and points of contact relevant to your project.
10 +Depending on the question, these may include the **University Library / Research Data Management & Repository**, **IT**, **Legal and Data Protection**, **Finance and Personnel**, **Publications and Communication**, **Event Management**, the **International Office** and other services.
11 +
12 +The **institute, department or other host unit** remains the artistic or academic home of the project. The navigator brings these offers together along the project stages so you can start from your need rather than from the organisational chart.
11 11  {{/info}}
12 12  
15 +
16 +
13 13  {{html clean="false"}}
14 14  <section data-arsn-search-block-fix="v5" style="margin:20px 0 26px 0;padding:16px 18px;border:1px solid #e3ded6;border-radius:10px;background:#fcfbf8;box-shadow:0 1px 2px rgba(0,0,0,.035);">
15 15   <h2 style="font-size:20px;margin:0 0 6px 0;color:#35312d;">Search the Art &amp; Research Services Navigator</h2>
... ... @@ -435,9 +435,9 @@
435 435  )))
436 436  )))
437 437  
438 -(% class="arsn-phase-cta-wrap" style="padding:0 16px 16px 16px;" %)
442 +(% style="padding:0 16px 16px 16px;" %)
439 439  (((
440 -[[Explore Enable>>https://xwiki.uni-ak.ac.at/bin/view/Service%20Navigator/Art%20%26%20Research%20Services%20Navigator/Enable/||class="btn btn-primary btn-block arsn-phase-cta"]]
444 +[[Explore Enable>>https://xwiki.uni-ak.ac.at/bin/view/Service%20Navigator/Art%20%26%20Research%20Services%20Navigator/Enable/||class="btn btn-primary btn-block"]]
441 441  )))
442 442  )))
443 443  )))
... ... @@ -501,9 +501,9 @@
501 501  )))
502 502  )))
503 503  
504 -(% class="arsn-phase-cta-wrap" style="padding:0 16px 16px 16px;" %)
508 +(% style="padding:0 16px 16px 16px;" %)
505 505  (((
506 -[[Explore Work & Manage>>https://xwiki.uni-ak.ac.at/bin/view/Service%20Navigator/Art%20%26%20Research%20Services%20Navigator/Work%20%26%20Manage/||class="btn btn-primary btn-block arsn-phase-cta"]]
510 +[[Explore Work & Manage>>https://xwiki.uni-ak.ac.at/bin/view/Service%20Navigator/Art%20%26%20Research%20Services%20Navigator/Work%20%26%20Manage/||class="btn btn-primary btn-block"]]
507 507  )))
508 508  )))
509 509  )))
... ... @@ -577,9 +577,9 @@
577 577  )))
578 578  )))
579 579  
580 -(% class="arsn-phase-cta-wrap" style="padding:0 16px 16px 16px;" %)
584 +(% style="padding:0 16px 16px 16px;" %)
581 581  (((
582 -[[Explore Publish & Share>>https://xwiki.uni-ak.ac.at/bin/view/Service%20Navigator/Art%20%26%20Research%20Services%20Navigator/Publish%20%26%20Share/||class="btn btn-primary btn-block arsn-phase-cta"]]
586 +[[Explore Publish & Share>>https://xwiki.uni-ak.ac.at/bin/view/Service%20Navigator/Art%20%26%20Research%20Services%20Navigator/Publish%20%26%20Share/||class="btn btn-primary btn-block"]]
583 583  )))
584 584  )))
585 585  )))
... ... @@ -636,132 +636,23 @@
636 636  )))
637 637  
638 638  {{html clean="false"}}
639 -<!-- SN_SERVICE_NAVIGATOR_MASTER_STYLE_START -->
640 -
641 -<style data-sn-service-navigator-master="1">
642 -/* =========================================================
643 - MASTER TYPOGRAPHY
644 - ========================================================= */
645 -#xwikicontent h1,
646 -#xwikicontent h2,
647 -#xwikicontent h3,
648 -#xwikicontent h4,
649 -#xwikicontent h5,
650 -#xwikicontent h6,
651 -#xwikicontent .box-title,
652 -#xwikicontent [role="heading"],
653 -#xwikicontent h1 a,
654 -#xwikicontent h2 a,
655 -#xwikicontent h3 a,
656 -#xwikicontent h4 a,
657 -#xwikicontent h5 a,
658 -#xwikicontent h6 a,
659 -#xwikicontent .box-title a,
660 -#xwikicontent [role="heading"] a{
661 - text-align:left!important;
662 - text-justify:auto!important;
663 - word-spacing:normal!important;
664 -}
665 -
666 -/* =========================================================
667 - COMING SOON / IN VORBEREITUNG
668 - ========================================================= */
669 -.sn-coming-soon-badge{
670 - display:inline-block;
671 - vertical-align:middle;
672 - margin-left:10px;
673 - padding:4px 8px;
674 - border-radius:14px;
675 - border:1px solid #efd9cc;
676 - background:#fff4ee;
677 - color:#8a4d36;
678 - font-size:11px;
679 - font-weight:700;
680 - letter-spacing:.055em;
681 - line-height:1.2;
682 - white-space:nowrap;
683 -}
684 -
685 -/* =========================================================
686 - NATIVE / DETAIL CALLOUT GEOMETRY
687 - Preserve existing backgrounds.
688 - ========================================================= */
689 -#xwikicontent .arsn-info,
690 -#xwikicontent .dmp-info,
691 -#xwikicontent .ido-info,
692 -#xwikicontent .pp-info,
693 -#xwikicontent .infomessage{
694 - box-sizing:border-box!important;
695 - border-left:4px solid #21b6d7!important;
696 - border-radius:8px;
697 - text-align:left!important;
698 - word-spacing:normal!important;
699 -}
700 -
701 -#xwikicontent .arsn-warn,
702 -#xwikicontent .dmp-warn,
703 -#xwikicontent .ido-warn,
704 -#xwikicontent .pp-warn,
705 -#xwikicontent .warn,
706 -#xwikicontent .warning,
707 -#xwikicontent .warningmessage,
708 -#xwikicontent .errormessage{
709 - box-sizing:border-box!important;
710 - border-left:4px solid #e94b13!important;
711 - border-radius:8px;
712 - text-align:left!important;
713 - word-spacing:normal!important;
714 -}
715 -
716 -[data-sn-master-equal-height],
717 -[data-sn-master-first-row]{
643 +<!-- SN_HORIZONTAL_BOX_HARMONIZER_START -->
644 +<style data-sn-horizontal-box-harmonizer="4">
645 +[data-sn-equal-height-managed],
646 +[data-sn-first-section-aligned]{
718 718   box-sizing:border-box;
719 719  }
720 -
721 -/* =========================================================
722 - FULL-WIDTH THREE-LINE NUMBER / TITLE / SUBTITLE BLOCKS
723 - ========================================================= */
724 -#xwikicontent .arsn-area-label[data-sn-three-line="1"]{
725 - display:grid!important;
726 - grid-template-columns:minmax(0,1fr)!important;
727 - grid-auto-rows:auto!important;
728 - width:100%!important;
729 - max-width:none!important;
730 - box-sizing:border-box!important;
731 - justify-items:start!important;
732 - align-items:start!important;
733 - gap:2px!important;
734 - text-align:left!important;
735 - text-align-last:left!important;
736 - text-justify:auto!important;
737 - word-spacing:normal!important;
738 - white-space:normal!important;
739 -}
740 -#xwikicontent .arsn-area-label[data-sn-three-line="1"] > .arsn-area-number,
741 -#xwikicontent .arsn-area-label[data-sn-three-line="1"] > .sn-area-label-title,
742 -#xwikicontent .arsn-area-label[data-sn-three-line="1"] > .arsn-area-action{
743 - display:block!important;
744 - width:100%!important;
745 - margin:0!important;
746 - text-align:left!important;
747 - text-align-last:left!important;
748 - text-justify:auto!important;
749 - word-spacing:normal!important;
750 - white-space:normal!important;
751 -}
752 752  </style>
753 -
754 -<script data-sn-service-navigator-master="1">
650 +<script data-sn-horizontal-box-harmonizer="4">
755 755  (function(){
756 756   "use strict";
757 757  
758 - var PAGE_KIND="overview";
759 - var PLACEHOLDER=false;
760 - var PLACEHOLDER_LABEL="COMING SOON";
761 -
762 762   var MOBILE_MAX=767;
763 763   var ROW_TOLERANCE=6;
764 - var RESIZE_DEBOUNCE=220;
656 + var MIN_W=150;
657 + var MIN_H=36;
658 + var MAX_PARENT_CHILDREN=16;
659 + var SEARCH_DEPTH=5;
765 765  
766 766   var root=
767 767   document.getElementById("xwikicontent")||
... ... @@ -771,105 +771,93 @@
771 771  
772 772   if(!root)return;
773 773  
774 - var managedHeight=new Set();
775 - var managedMargin=new Set();
776 - var originalHeight=new WeakMap();
777 - var originalMargin=new WeakMap();
669 + var heightManaged=new Set();
670 + var sectionManaged=new Set();
671 + var originalMinHeight=new WeakMap();
672 + var originalMarginTop=new WeakMap();
673 + var raf=0;
778 778  
779 - var resizeTimer=0;
780 - var running=false;
675 + function num(v){
676 + var n=parseFloat(v);
677 + return Number.isFinite(n)?n:0;
678 + }
781 781  
782 - var THEMES=[
783 - {
784 - name:"BLUE",
785 - accent:"#21b6d7",
786 - bg:"#eaf7fb",
787 - text:"#315d68",
788 - labels:[
789 - "HIER STARTEN",
790 - "ENTSCHEIDEN",
791 - "ÜBERPRÜFEN & ANPASSEN",
792 - "START HERE",
793 - "DECIDE",
794 - "REVIEW & ADAPT"
795 - ]
796 - },
797 - {
798 - name:"RED",
799 - accent:"#e94b13",
800 - bg:"#fff1ec",
801 - text:"#8a4d36",
802 - labels:[
803 - "PLANEN & ORGANISIEREN",
804 - "ORGANISIEREN & DOKUMENTIEREN",
805 - "PUBLIZIEREN & PRÄSENTIEREN",
806 - "PLAN & ORGANISE",
807 - "PLAN & ORGANIZE",
808 - "ORGANISE & DOCUMENT",
809 - "ORGANIZE & DOCUMENT",
810 - "PUBLISH & PRESENT"
811 - ]
812 - },
813 - {
814 - name:"YELLOW",
815 - accent:"#f0aa00",
816 - bg:"#fff8e7",
817 - text:"#785b17",
818 - labels:[
819 - "SCHÜTZEN & KLÄREN",
820 - "STANDARDISIEREN & IDENTIFIZIEREN",
821 - "ÖFFNEN, NACHNUTZEN & AUFFINDBAR MACHEN",
822 - "PROTECT & CLARIFY",
823 - "STANDARDISE & IDENTIFY",
824 - "STANDARDIZE & IDENTIFY",
825 - "OPEN, REUSE & MAKE FINDABLE"
826 - ]
827 - },
828 - {
829 - name:"GREEN",
830 - accent:"#38b76a",
831 - bg:"#edf9f1",
832 - text:"#3f7451",
833 - labels:[
834 - "INFRASTRUKTUR EINRICHTEN",
835 - "INFRASTRUKTUR & ZUSAMMENARBEIT EINRICHTEN",
836 - "SPEICHERN & ZUGRIFF STEUERN",
837 - "REPOSITORIUM, ERHALTEN & ÜBERGEBEN",
838 - "SET UP INFRASTRUCTURE",
839 - "SET UP INFRASTRUCTURE & COLLABORATION",
840 - "STORE & CONTROL ACCESS",
841 - "REPOSITORY, PRESERVE & HAND OVER"
842 - ]
680 + function visible(el,minW,minH){
681 + if(!el||el.nodeType!==1)return false;
682 +
683 + var s=getComputedStyle(el);
684 +
685 + if(
686 + s.display==="none"||
687 + s.visibility==="hidden"||
688 + Number(s.opacity)===0
689 + ){
690 + return false;
843 843   }
844 - ];
845 845  
846 - function num(value){
847 - var n=parseFloat(value);
848 - return Number.isFinite(n)?n:0;
693 + var r=el.getBoundingClientRect();
694 +
695 + return (
696 + r.width>=(minW||1)&&
697 + r.height>=(minH||1)
698 + );
849 849   }
850 850  
851 - function norm(value){
852 - return String(value||"")
853 - .replace(/\s+/g," ")
854 - .trim()
855 - .toUpperCase();
701 + function excluded(el){
702 + return (
703 + !el.matches||
704 + el.matches(
705 + "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]"
706 + )
707 + );
856 856   }
857 857  
858 - function visible(el){
859 - if(!el||el.nodeType!==1)return false;
710 + function namedLikeBox(el){
711 + var c=
712 + typeof el.className==="string"
713 + ? el.className
714 + : "";
860 860  
861 - var style=getComputedStyle(el);
862 - var rect=el.getBoundingClientRect();
716 + return /(^|[s_-])(box|card|tile|panel|role|check|service|source|call|area|detail|resource|topic|warn|info)([s_-]|$)/i.test(c);
717 + }
863 863  
719 + function boxLike(el){
720 + if(!visible(el,MIN_W,MIN_H)||excluded(el))return false;
721 +
722 + var s=getComputedStyle(el);
723 + var r=el.getBoundingClientRect();
724 +
725 + var border=
726 + num(s.borderTopWidth)+
727 + num(s.borderRightWidth)+
728 + num(s.borderBottomWidth)+
729 + num(s.borderLeftWidth);
730 +
731 + var radius=Math.max(
732 + num(s.borderTopLeftRadius),
733 + num(s.borderTopRightRadius),
734 + num(s.borderBottomLeftRadius),
735 + num(s.borderBottomRightRadius)
736 + );
737 +
738 + var bg=
739 + s.backgroundColor&&
740 + s.backgroundColor!=="rgba(0, 0, 0, 0)"&&
741 + s.backgroundColor!=="transparent";
742 +
743 + var shadow=
744 + s.boxShadow&&
745 + s.boxShadow!=="none";
746 +
864 864   return (
865 - style.display!=="none"&&
866 - style.visibility!=="hidden"&&
867 - rect.width>20&&
868 - rect.height>4
748 + namedLikeBox(el)||
749 + border>=1||
750 + (bg&&radius>=3)||
751 + (shadow&&r.width>=180)
869 869   );
870 870   }
871 871  
872 - function saveStyle(el,map,property){
755 + function saveOriginal(el,map,property){
873 873   if(map.has(el))return;
874 874  
875 875   map.set(el,{
... ... @@ -878,7 +878,7 @@
878 878   });
879 879   }
880 880  
881 - function restoreStyle(el,map,property){
764 + function restoreOriginal(el,map,property){
882 882   var original=map.get(el);
883 883  
884 884   if(original&&original.value){
... ... @@ -892,470 +892,247 @@
892 892   }
893 893   }
894 894  
895 - function resetRuntime(){
896 - managedHeight.forEach(function(el){
897 - restoreStyle(
778 + function reset(){
779 + heightManaged.forEach(function(el){
780 + restoreOriginal(
898 898   el,
899 - originalHeight,
782 + originalMinHeight,
900 900   "min-height"
901 901   );
785 +
902 902   el.removeAttribute(
903 - "data-sn-master-equal-height"
787 + "data-sn-equal-height-managed"
904 904   );
905 905   });
906 906  
907 - managedMargin.forEach(function(el){
908 - restoreStyle(
791 + sectionManaged.forEach(function(el){
792 + restoreOriginal(
909 909   el,
910 - originalMargin,
794 + originalMarginTop,
911 911   "margin-top"
912 912   );
797 +
913 913   el.removeAttribute(
914 - "data-sn-master-first-row"
799 + "data-sn-first-section-aligned"
915 915   );
916 916   });
917 917  
918 - managedHeight.clear();
919 - managedMargin.clear();
803 + heightManaged.clear();
804 + sectionManaged.clear();
920 920   }
921 921  
922 - function themeFor(text){
923 - var value=norm(text);
807 + function pickTarget(child){
808 + if(!visible(child,MIN_W,MIN_H))return null;
924 924  
925 - for(var i=0;i<THEMES.length;i++){
926 - for(var j=0;j<THEMES[i].labels.length;j++){
927 - var label=THEMES[i].labels[j];
928 -
929 - if(
930 - value===label||
931 - value.indexOf(label+" ")===0||
932 - value.indexOf(label+" -")===0||
933 - value.indexOf(label+" ·")===0
934 - ){
935 - return THEMES[i];
936 - }
937 - }
810 + if(boxLike(child)){
811 + return child;
938 938   }
939 939  
940 - return null;
941 - }
814 + var cr=child.getBoundingClientRect();
815 + var q=[];
942 942  
943 - /* =======================================================
944 - BORDERLESS FILLED RED/ORANGE CTA BUTTONS
945 - ======================================================= */
946 -
947 - function colourDistance(a,b){
948 - return Math.sqrt(
949 - Math.pow(a[0]-b[0],2)+
950 - Math.pow(a[1]-b[1],2)+
951 - Math.pow(a[2]-b[2],2)
952 - );
953 - }
954 -
955 - function makeFilledRedOrangeCTAsBorderless(){
956 - var RED_ORANGE=[233,75,19];
957 -
958 - Array.from(
959 - root.querySelectorAll(
960 - 'a,button,[role="button"],input[type="submit"],input[type="button"]'
961 - )
962 - ).forEach(function(el){
963 - if(!visible(el))return;
964 -
965 - var style=getComputedStyle(el);
966 - var rgb=parseRGB(style.backgroundColor);
967 -
968 - if(!rgb)return;
969 -
970 - if(
971 - colourDistance(
972 - rgb,
973 - RED_ORANGE
974 - )>55
975 - ){
976 - return;
977 - }
978 -
979 - var rect=el.getBoundingClientRect();
980 -
981 - if(
982 - rect.width<80||
983 - rect.height<24
984 - ){
985 - return;
986 - }
987 -
988 - el.style.setProperty(
989 - "border",
990 - "none",
991 - "important"
992 - );
993 -
994 - el.style.setProperty(
995 - "border-left",
996 - "none",
997 - "important"
998 - );
999 -
1000 - el.style.setProperty(
1001 - "border-top",
1002 - "none",
1003 - "important"
1004 - );
1005 -
1006 - el.style.setProperty(
1007 - "border-right",
1008 - "none",
1009 - "important"
1010 - );
1011 -
1012 - el.style.setProperty(
1013 - "border-bottom",
1014 - "none",
1015 - "important"
1016 - );
1017 -
1018 - el.style.setProperty(
1019 - "box-shadow",
1020 - "none",
1021 - "important"
1022 - );
817 + Array.from(child.children||[]).forEach(function(el){
818 + q.push({el:el,depth:1});
1023 1023   });
1024 - }
1025 1025  
1026 - /* =======================================================
1027 - FULL-WIDTH THREE-LINE AREA LABELS
1028 - ======================================================= */
821 + var best=null;
822 + var bestScore=-Infinity;
1029 1029  
1030 - function compactText(value){
1031 - return String(value||"")
1032 - .replace(/\s+/g," ")
1033 - .trim();
1034 - }
824 + while(q.length){
825 + var item=q.shift();
826 + var el=item.el;
1035 1035  
1036 - function makeThreeLineAreaLabels(){
1037 - Array.from(
1038 - root.querySelectorAll(
1039 - ".arsn-area-label"
1040 - )
1041 - ).forEach(function(label){
1042 - if(
1043 - label.getAttribute(
1044 - "data-sn-three-line"
1045 - )==="1"
1046 - ){
1047 - return;
1048 - }
828 + if(!visible(el,MIN_W,MIN_H))continue;
1049 1049  
1050 - var number=
1051 - label.querySelector(
1052 - ":scope > .arsn-area-number"
1053 - );
830 + var r=el.getBoundingClientRect();
1054 1054  
1055 - var action=
1056 - label.querySelector(
1057 - ":scope > .arsn-area-action"
1058 - );
1059 -
1060 1060   if(
1061 - !number||
1062 - !action
833 + r.width>=cr.width*.68&&
834 + boxLike(el)
1063 1063   ){
1064 - return;
1065 - }
836 + var widthFit=
837 + 1-Math.min(
838 + 1,
839 + Math.abs(cr.width-r.width)/
840 + Math.max(1,cr.width)
841 + );
1066 1066  
1067 - var clone=
1068 - label.cloneNode(true);
843 + var topFit=
844 + 1-Math.min(
845 + 1,
846 + Math.abs(cr.top-r.top)/100
847 + );
1069 1069  
1070 - var cloneNumber=
1071 - clone.querySelector(
1072 - ":scope > .arsn-area-number"
1073 - );
849 + var score=
850 + widthFit*6+
851 + topFit*3+
852 + Math.min(r.height,900)/450+
853 + Math.min(r.width*r.height,900000)/900000;
1074 1074  
1075 - var cloneAction=
1076 - clone.querySelector(
1077 - ":scope > .arsn-area-action"
1078 - );
1079 -
1080 - if(cloneNumber){
1081 - cloneNumber.remove();
855 + if(score>bestScore){
856 + best=el;
857 + bestScore=score;
858 + }
1082 1082   }
1083 1083  
1084 - if(cloneAction){
1085 - cloneAction.remove();
861 + if(item.depth<SEARCH_DEPTH){
862 + Array.from(el.children||[]).forEach(function(next){
863 + q.push({
864 + el:next,
865 + depth:item.depth+1
866 + });
867 + });
1086 1086   }
869 + }
1087 1087  
1088 - var titleText=
1089 - compactText(
1090 - clone.textContent
1091 - );
871 + return best;
872 + }
1092 1092  
1093 - if(!titleText){
1094 - return;
1095 - }
874 + function groupsByVisualRow(entries){
875 + var groups=[];
1096 1096  
1097 - var numberNode=
1098 - number.cloneNode(true);
1099 -
1100 - var actionNode=
1101 - action.cloneNode(true);
1102 -
1103 - var titleNode=
1104 - document.createElement(
1105 - "span"
877 + entries
878 + .slice()
879 + .sort(function(a,b){
880 + return (
881 + a.rect.top-b.rect.top||
882 + a.rect.left-b.rect.left
1106 1106   );
884 + })
885 + .forEach(function(entry){
886 + var group=null;
1107 1107  
1108 - titleNode.className=
1109 - "sn-area-label-title";
888 + for(var i=0;i<groups.length;i++){
889 + if(
890 + Math.abs(
891 + groups[i].top-
892 + entry.rect.top
893 + )<=ROW_TOLERANCE
894 + ){
895 + group=groups[i];
896 + break;
897 + }
898 + }
1110 1110  
1111 - titleNode.textContent=
1112 - titleText;
900 + if(!group){
901 + group={
902 + top:entry.rect.top,
903 + entries:[]
904 + };
905 + groups.push(group);
906 + }
1113 1113  
1114 - while(label.firstChild){
1115 - label.removeChild(
1116 - label.firstChild
1117 - );
1118 - }
908 + group.entries.push(entry);
909 + });
1119 1119  
1120 - label.appendChild(
1121 - numberNode
1122 - );
1123 -
1124 - label.appendChild(
1125 - titleNode
1126 - );
1127 -
1128 - label.appendChild(
1129 - actionNode
1130 - );
1131 -
1132 - label.setAttribute(
1133 - "data-sn-three-line",
1134 - "1"
1135 - );
1136 -
1137 - var head=
1138 - label.closest(
1139 - ".arsn-area-head"
1140 - );
1141 -
1142 - if(head){
1143 - head.style.setProperty(
1144 - "width",
1145 - "100%",
1146 - "important"
1147 - );
1148 -
1149 - head.style.setProperty(
1150 - "max-width",
1151 - "100%",
1152 - "important"
1153 - );
1154 -
1155 - head.style.setProperty(
1156 - "box-sizing",
1157 - "border-box",
1158 - "important"
1159 - );
1160 - }
1161 - });
911 + return groups;
1162 1162   }
1163 1163  
1164 - /* =======================================================
1165 - PLACEHOLDER BADGE
1166 - ======================================================= */
914 + function validHorizontalGroup(group){
915 + if(group.entries.length<2)return false;
1167 1167  
1168 - function applyPlaceholderBadge(){
1169 - if(!PLACEHOLDER)return;
917 + var lefts=
918 + group.entries
919 + .map(function(e){return e.rect.left;})
920 + .sort(function(a,b){return a-b;});
1170 1170  
1171 1171   if(
1172 - document.querySelector(
1173 - ".sn-coming-soon-badge"
1174 - )
923 + lefts[lefts.length-1]-
924 + lefts[0]<
925 + 80
1175 1175   ){
1176 - return;
927 + return false;
1177 1177   }
1178 1178  
1179 - var title=
1180 - document.querySelector(
1181 - "#document-title"
1182 - )||
1183 - document.querySelector(
1184 - "h1"
1185 - );
930 + var widths=
931 + group.entries
932 + .map(function(e){return e.rect.width;})
933 + .filter(function(w){return w>0;});
1186 1186  
1187 - if(!title)return;
935 + if(widths.length<2)return false;
1188 1188  
1189 - var badge=
1190 - document.createElement(
1191 - "span"
1192 - );
937 + var minWidth=Math.min.apply(Math,widths);
938 + var maxWidth=Math.max.apply(Math,widths);
1193 1193  
1194 - badge.className=
1195 - "sn-coming-soon-badge";
1196 -
1197 - badge.textContent=
1198 - PLACEHOLDER_LABEL;
1199 -
1200 - badge.setAttribute(
1201 - "aria-label",
1202 - PLACEHOLDER_LABEL
940 + return (
941 + maxWidth/
942 + Math.max(1,minWidth)<=
943 + 1.9
1203 1203   );
945 + }
1204 1204  
1205 - title.appendChild(
1206 - badge
1207 - );
947 + function normalizeText(text){
948 + return String(text||"")
949 + .replace(/s+/g," ")
950 + .trim()
951 + .toUpperCase();
1208 1208   }
1209 1209  
1210 - /* =======================================================
1211 - DETAIL PAGE OWN-ACCENT PROPAGATION
1212 - ======================================================= */
954 + function exactKnownFirstSection(el){
955 + var text=normalizeText(el.textContent);
1213 1213  
1214 - function parseRGB(value){
1215 - var match=String(value||"").match(
1216 - /rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)/i
957 + return (
958 + text==="HIER STARTEN"||
959 + text==="ORGANISIEREN & DOKUMENTIEREN"||
960 + text==="ENTSCHEIDEN"||
961 + text==="START HERE"||
962 + text==="GET STARTED"||
963 + text==="ORGANISE & DOCUMENT"||
964 + text==="ORGANIZE & DOCUMENT"||
965 + text==="DECIDE"
1217 1217   );
1218 -
1219 - if(!match)return null;
1220 -
1221 - return [
1222 - Number(match[1]),
1223 - Number(match[2]),
1224 - Number(match[3])
1225 - ];
1226 1226   }
1227 1227  
1228 - function distance(a,b){
1229 - return Math.sqrt(
1230 - Math.pow(a[0]-b[0],2)+
1231 - Math.pow(a[1]-b[1],2)+
1232 - Math.pow(a[2]-b[2],2)
1233 - );
1234 - }
969 + function visuallyFirstSectionBar(card){
970 + var cardRect=card.getBoundingClientRect();
971 + var candidates=[];
1235 1235  
1236 - function paletteMatch(cssColor){
1237 - var rgb=parseRGB(cssColor);
1238 -
1239 - if(!rgb)return null;
1240 -
1241 - var palette=[
1242 - {hex:"#21b6d7",rgb:[33,182,215]},
1243 - {hex:"#e94b13",rgb:[233,75,19]},
1244 - {hex:"#f0aa00",rgb:[240,170,0]},
1245 - {hex:"#38b76a",rgb:[56,183,106]}
1246 - ];
1247 -
1248 - var best=null;
1249 - var bestDistance=Infinity;
1250 -
1251 - palette.forEach(function(item){
1252 - var d=distance(rgb,item.rgb);
1253 -
1254 - if(d<bestDistance){
1255 - best=item;
1256 - bestDistance=d;
1257 - }
1258 - });
1259 -
1260 - return bestDistance<=30
1261 - ?best
1262 - :null;
1263 - }
1264 -
1265 - function propagateDetailAccents(){
1266 - if(PAGE_KIND!=="detail")return;
1267 -
1268 1268   Array.from(
1269 - root.querySelectorAll(
1270 - ".arsn-call,.dmp-call,.ido-call,.pp-call,"+
1271 - ".arsn-source,.dmp-source,.ido-source,.pp-source"
974 + card.querySelectorAll(
975 + "div,p,span,strong,h3,h4,h5,h6"
1272 1272   )
1273 1273   ).forEach(function(el){
1274 - if(!visible(el))return;
978 + if(!visible(el,20,6))return;
979 + if(excluded(el))return;
1275 1275  
1276 - var style=getComputedStyle(el);
981 + var r=el.getBoundingClientRect();
982 + var relativeTop=r.top-cardRect.top;
1277 1277  
1278 1278   if(
1279 - num(style.borderTopWidth)>=2
985 + relativeTop<45||
986 + relativeTop>cardRect.height*.72
1280 1280   ){
1281 - var match=
1282 - paletteMatch(
1283 - style.borderTopColor
1284 - );
1285 -
1286 - if(match){
1287 - el.style.setProperty(
1288 - "border-left",
1289 - "4px solid "+match.hex,
1290 - "important"
1291 - );
1292 - }
988 + return;
1293 1293   }
1294 - });
1295 1295  
1296 - // Warning families: explicit safety override.
1297 - Array.from(
1298 - root.querySelectorAll(
1299 - ".arsn-warn,.dmp-warn,.ido-warn,.pp-warn,"+
1300 - ".warn,.warning,.warningmessage,.errormessage"
1301 - )
1302 - ).forEach(function(el){
1303 - if(!visible(el))return;
991 + var widthRatio=
992 + r.width/
993 + Math.max(1,cardRect.width);
1304 1304  
1305 - el.style.setProperty(
1306 - "border-left",
1307 - "4px solid #e94b13",
1308 - "important"
1309 - );
1310 - });
995 + if(
996 + widthRatio<.55||
997 + widthRatio>1.05||
998 + r.height>54
999 + ){
1000 + return;
1001 + }
1311 1311  
1312 - // Info families: explicit orientation override.
1313 - Array.from(
1314 - root.querySelectorAll(
1315 - ".arsn-info,.dmp-info,.ido-info,.pp-info,.infomessage"
1316 - )
1317 - ).forEach(function(el){
1318 - if(!visible(el))return;
1003 + var text=normalizeText(el.textContent);
1319 1319  
1320 - el.style.setProperty(
1321 - "border-left",
1322 - "4px solid #21b6d7",
1323 - "important"
1324 - );
1325 - });
1326 - }
1005 + if(
1006 + text.length<2||
1007 + text.length>90
1008 + ){
1009 + return;
1010 + }
1327 1327  
1328 - /* =======================================================
1329 - OVERVIEW SEMANTIC THEME PALETTE
1330 - ======================================================= */
1012 + var style=getComputedStyle(el);
1331 1331  
1332 - function smallestThemeHeaders(){
1333 - return Array.from(
1334 - root.querySelectorAll(
1335 - "div,span,p,strong,h3,h4,h5,h6"
1336 - )
1337 - ).filter(function(el){
1338 - if(!visible(el))return false;
1339 - if(!themeFor(el.textContent))return false;
1014 + var bg=
1015 + style.backgroundColor&&
1016 + style.backgroundColor!=="rgba(0, 0, 0, 0)"&&
1017 + style.backgroundColor!=="transparent";
1340 1340  
1341 - return !Array.from(
1342 - el.children||[]
1343 - ).some(function(child){
1344 - return !!themeFor(
1345 - child.textContent
1346 - );
1347 - });
1348 - });
1349 - }
1350 -
1351 - function findOverviewCard(header){
1352 - var node=header.parentElement;
1353 - var candidates=[];
1354 -
1355 - while(node&&node!==root){
1356 - var rect=node.getBoundingClientRect();
1357 - var style=getComputedStyle(node);
1358 -
1359 1359   var border=
1360 1360   num(style.borderTopWidth)+
1361 1361   num(style.borderRightWidth)+
... ... @@ -1362,755 +1362,315 @@
1362 1362   num(style.borderBottomWidth)+
1363 1363   num(style.borderLeftWidth);
1364 1364  
1365 - if(
1366 - rect.width>=220&&
1367 - rect.width<=800&&
1368 - rect.height>=120&&
1369 - border>=1
1370 - ){
1371 - candidates.push(node);
1372 - }
1025 + var mostlyUpper=
1026 + text.length>=3&&
1027 + text===text.toUpperCase();
1373 1373  
1374 - node=node.parentElement;
1375 - }
1029 + var exact=exactKnownFirstSection(el);
1376 1376  
1377 - if(!candidates.length)return null;
1031 + var score=
1032 + (exact?20:0)+
1033 + (bg?6:0)+
1034 + (border>=1?2:0)+
1035 + (mostlyUpper?4:0)+
1036 + (num(style.fontWeight)>=600?1:0);
1378 1378  
1379 - candidates.sort(function(a,b){
1380 - return (
1381 - b.getBoundingClientRect().height-
1382 - a.getBoundingClientRect().height
1383 - );
1038 + if(score>=7){
1039 + candidates.push({
1040 + el:el,
1041 + relativeTop:relativeTop,
1042 + width:r.width,
1043 + score:score
1044 + });
1045 + }
1384 1384   });
1385 1385  
1386 - return candidates[0];
1387 - }
1048 + if(!candidates.length)return null;
1388 1388  
1389 - function rowCandidates(link,card){
1390 - var result=[];
1391 - var cardRect=
1392 - card.getBoundingClientRect();
1393 -
1394 - var node=link;
1395 -
1396 - while(node&&node!==card){
1397 - if(visible(node)){
1398 - var rect=
1399 - node.getBoundingClientRect();
1400 -
1401 - if(
1402 - rect.height<=105&&
1403 - rect.width>=
1404 - cardRect.width*.50&&
1405 - rect.width<=
1406 - cardRect.width*1.03
1407 - ){
1408 - result.push(node);
1409 - }
1050 + candidates.sort(function(a,b){
1051 + if(a.score!==b.score)return b.score-a.score;
1052 + if(Math.abs(a.relativeTop-b.relativeTop)>3){
1053 + return a.relativeTop-b.relativeTop;
1410 1410   }
1055 + return b.width-a.width;
1056 + });
1411 1411  
1412 - node=node.parentElement;
1413 - }
1058 + // For exact known labels always prefer the earliest exact match.
1059 + var exacts=candidates.filter(function(c){
1060 + return exactKnownFirstSection(c.el);
1061 + });
1414 1414  
1415 - return result;
1416 - }
1417 -
1418 - function chooseOuterRow(
1419 - candidates,
1420 - link
1421 - ){
1422 - if(!candidates.length){
1423 - return link;
1063 + if(exacts.length){
1064 + exacts.sort(function(a,b){
1065 + return a.relativeTop-b.relativeTop||b.width-a.width;
1066 + });
1067 + return exacts[0].el;
1424 1424   }
1425 1425  
1426 - var bordered=
1427 - candidates.filter(function(el){
1428 - return (
1429 - num(
1430 - getComputedStyle(el)
1431 - .borderLeftWidth
1432 - )>=1
1433 - );
1434 - });
1070 + // Generic fallback: earliest high-confidence bar.
1071 + candidates.sort(function(a,b){
1072 + return a.relativeTop-b.relativeTop||b.score-a.score||b.width-a.width;
1073 + });
1435 1435  
1436 - var pool=
1437 - bordered.length
1438 - ?bordered
1439 - :candidates;
1075 + return candidates[0].el;
1076 + }
1440 1440  
1441 - pool.sort(function(a,b){
1442 - var ar=
1443 - a.getBoundingClientRect();
1078 + function alignFirstSections(cards){
1079 + var rows=
1080 + cards.map(function(card){
1081 + var bar=
1082 + visuallyFirstSectionBar(card);
1444 1444  
1445 - var br=
1446 - b.getBoundingClientRect();
1084 + if(!bar)return null;
1447 1447  
1448 - return (
1449 - ar.left-br.left||
1450 - br.width-ar.width
1451 - );
1452 - });
1086 + var cardRect=
1087 + card.getBoundingClientRect();
1453 1453  
1454 - return pool[0]||link;
1455 - }
1089 + var barRect=
1090 + bar.getBoundingClientRect();
1456 1456  
1457 - function applyOverviewPalette(){
1458 - if(PAGE_KIND!=="overview"){
1459 - return [];
1092 + return {
1093 + card:card,
1094 + bar:bar,
1095 + relativeTop:
1096 + barRect.top-cardRect.top,
1097 + label:
1098 + normalizeText(bar.textContent)
1099 + };
1100 + });
1101 +
1102 + // Conservative: only align when every card in the horizontal row
1103 + // has a reliable first section bar.
1104 + if(
1105 + rows.some(function(row){
1106 + return !row;
1107 + })
1108 + ){
1109 + return null;
1460 1460   }
1461 1461  
1462 - var headers=
1463 - smallestThemeHeaders()
1464 - .map(function(el){
1465 - return {
1466 - el:el,
1467 - theme:
1468 - themeFor(
1469 - el.textContent
1470 - ),
1471 - card:
1472 - findOverviewCard(
1473 - el
1474 - )
1475 - };
1112 + var targetTop=
1113 + Math.max.apply(
1114 + Math,
1115 + rows.map(function(row){
1116 + return row.relativeTop;
1476 1476   })
1477 - .filter(function(row){
1478 - return !!row.card;
1479 - });
1118 + );
1480 1480  
1481 - var unique=[];
1482 - var seenHeaders=new Set();
1120 + rows.forEach(function(row){
1121 + var delta=
1122 + targetTop-
1123 + row.relativeTop;
1483 1483  
1484 - headers.forEach(function(row){
1485 - var key=
1486 - row.theme.name+
1487 - "|"+
1488 - Math.round(
1489 - row.card
1490 - .getBoundingClientRect()
1491 - .left
1492 - )+
1493 - "|"+
1494 - Math.round(
1495 - row.el
1496 - .getBoundingClientRect()
1497 - .top
1498 - );
1125 + if(delta<=1)return;
1499 1499  
1500 - if(!seenHeaders.has(key)){
1501 - seenHeaders.add(key);
1502 - unique.push(row);
1503 - }
1504 - });
1505 -
1506 - unique.forEach(function(row){
1507 - var headerRect=
1508 - row.el
1509 - .getBoundingClientRect();
1510 -
1511 - row.el.style.setProperty(
1512 - "background",
1513 - row.theme.bg,
1514 - "important"
1127 + saveOriginal(
1128 + row.bar,
1129 + originalMarginTop,
1130 + "margin-top"
1515 1515   );
1516 1516  
1517 - row.el.style.setProperty(
1518 - "color",
1519 - row.theme.text,
1520 - "important"
1521 - );
1133 + var currentMargin=
1134 + num(
1135 + getComputedStyle(
1136 + row.bar
1137 + ).marginTop
1138 + );
1522 1522  
1523 - row.el.style.setProperty(
1524 - "text-align",
1525 - "left",
1526 - "important"
1140 + row.bar.style.setProperty(
1141 + "margin-top",
1142 + (
1143 + currentMargin+
1144 + delta
1145 + )+"px"
1527 1527   );
1528 1528  
1529 - row.el.style.setProperty(
1530 - "word-spacing",
1531 - "normal",
1532 - "important"
1148 + row.bar.setAttribute(
1149 + "data-sn-first-section-aligned",
1150 + "4"
1533 1533   );
1534 1534  
1535 - var later=
1536 - unique
1537 - .filter(function(other){
1538 - return (
1539 - other.card===row.card&&
1540 - other.el
1541 - .getBoundingClientRect()
1542 - .top>
1543 - headerRect.top+2
1544 - );
1545 - })
1546 - .sort(function(a,b){
1547 - return (
1548 - a.el
1549 - .getBoundingClientRect()
1550 - .top-
1551 - b.el
1552 - .getBoundingClientRect()
1553 - .top
1554 - );
1555 - });
1556 -
1557 - var stopTop=
1558 - later.length
1559 - ?later[0].el
1560 - .getBoundingClientRect()
1561 - .top
1562 - :Infinity;
1563 -
1564 - Array.from(
1565 - row.card.querySelectorAll("a")
1566 - ).forEach(function(link){
1567 - if(
1568 - link.classList &&
1569 - link.classList.contains(
1570 - "arsn-phase-cta"
1571 - )
1572 - ){
1573 - return;
1574 - }
1575 -
1576 - if(!visible(link))return;
1577 -
1578 - var rect=
1579 - link.getBoundingClientRect();
1580 -
1581 - if(
1582 - rect.top<=
1583 - headerRect.bottom-2||
1584 - rect.top>=
1585 - stopTop-2
1586 - ){
1587 - return;
1588 - }
1589 -
1590 - var candidates=
1591 - rowCandidates(
1592 - link,
1593 - row.card
1594 - );
1595 -
1596 - var target=
1597 - chooseOuterRow(
1598 - candidates,
1599 - link
1600 - );
1601 -
1602 - candidates.forEach(function(el){
1603 - el.style.setProperty(
1604 - "border-left",
1605 - "0 solid transparent",
1606 - "important"
1607 - );
1608 - });
1609 -
1610 - target.style.setProperty(
1611 - "border-left",
1612 - "3px solid "+
1613 - row.theme.accent,
1614 - "important"
1615 - );
1616 -
1617 - target.style.setProperty(
1618 - "box-sizing",
1619 - "border-box",
1620 - "important"
1621 - );
1622 - });
1153 + sectionManaged.add(row.bar);
1623 1623   });
1624 1624  
1625 - return unique;
1156 + return {
1157 + labels:
1158 + rows.map(function(row){
1159 + return row.label;
1160 + }),
1161 + targetRelativeTop:
1162 + Math.round(targetTop)
1163 + };
1626 1626   }
1627 1627  
1628 - /* =======================================================
1629 - OVERVIEW CARD HEIGHT + FIRST THEMATIC ROW
1630 - ======================================================= */
1631 -
1632 - function alignOverviewCards(headers){
1633 - if(
1634 - PAGE_KIND!=="overview"||
1635 - window.innerWidth<=MOBILE_MAX
1636 - ){
1637 - return;
1166 + function applyGroup(group){
1167 + if(!validHorizontalGroup(group)){
1168 + return null;
1638 1638   }
1639 1639  
1640 1640   var cards=[];
1641 1641   var seen=new Set();
1642 1642  
1643 - headers.forEach(function(row){
1644 - if(!seen.has(row.card)){
1645 - seen.add(row.card);
1646 - cards.push(row.card);
1174 + group.entries.forEach(function(entry){
1175 + if(!seen.has(entry.target)){
1176 + seen.add(entry.target);
1177 + cards.push(entry.target);
1647 1647   }
1648 1648   });
1649 1649  
1650 - if(cards.length<2){
1651 - return;
1652 - }
1181 + if(cards.length<2)return null;
1653 1653  
1654 - // Group cards by actual top position.
1655 - var groups=[];
1183 + var firstSection=
1184 + alignFirstSections(cards);
1656 1656  
1657 - cards.forEach(function(card){
1658 - var top=
1659 - card.getBoundingClientRect().top;
1186 + // The section alignment can change natural card heights.
1187 + // Measure only afterwards.
1188 + var maxHeight=0;
1660 1660  
1661 - var group=null;
1662 -
1663 - for(var i=0;i<groups.length;i++){
1664 - if(
1665 - Math.abs(
1666 - groups[i].top-top
1667 - )<=ROW_TOLERANCE
1668 - ){
1669 - group=groups[i];
1670 - break;
1671 - }
1672 - }
1673 -
1674 - if(!group){
1675 - group={
1676 - top:top,
1677 - cards:[]
1678 - };
1679 - groups.push(group);
1680 - }
1681 -
1682 - group.cards.push(card);
1190 + cards.forEach(function(card){
1191 + maxHeight=Math.max(
1192 + maxHeight,
1193 + card.getBoundingClientRect().height
1194 + );
1683 1683   });
1684 1684  
1685 - groups.forEach(function(group){
1686 - if(group.cards.length<2){
1687 - return;
1688 - }
1197 + maxHeight=Math.ceil(maxHeight);
1689 1689  
1690 - var firstHeaders=
1691 - group.cards.map(function(card){
1692 - var candidates=
1693 - headers
1694 - .filter(function(row){
1695 - return row.card===card;
1696 - })
1697 - .sort(function(a,b){
1698 - return (
1699 - a.el
1700 - .getBoundingClientRect()
1701 - .top-
1702 - b.el
1703 - .getBoundingClientRect()
1704 - .top
1705 - );
1706 - });
1199 + if(maxHeight<MIN_H)return null;
1707 1707  
1708 - return candidates.length
1709 - ?candidates[0]
1710 - :null;
1711 - });
1201 + cards.forEach(function(card){
1202 + saveOriginal(
1203 + card,
1204 + originalMinHeight,
1205 + "min-height"
1206 + );
1712 1712  
1713 - if(
1714 - !firstHeaders.some(function(row){
1715 - return !row;
1716 - })
1717 - ){
1718 - var targetTop=
1719 - Math.max.apply(
1720 - Math,
1721 - firstHeaders.map(function(row){
1722 - return (
1723 - row.el
1724 - .getBoundingClientRect()
1725 - .top-
1726 - row.card
1727 - .getBoundingClientRect()
1728 - .top
1729 - );
1730 - })
1731 - );
1208 + card.style.setProperty(
1209 + "min-height",
1210 + maxHeight+"px"
1211 + );
1732 1732  
1733 - firstHeaders.forEach(function(row){
1734 - var relativeTop=
1735 - row.el
1736 - .getBoundingClientRect()
1737 - .top-
1738 - row.card
1739 - .getBoundingClientRect()
1740 - .top;
1213 + card.setAttribute(
1214 + "data-sn-equal-height-managed",
1215 + "4"
1216 + );
1741 1741  
1742 - var delta=
1743 - targetTop-relativeTop;
1744 -
1745 - if(delta>1){
1746 - saveStyle(
1747 - row.el,
1748 - originalMargin,
1749 - "margin-top"
1750 - );
1751 -
1752 - var current=
1753 - num(
1754 - getComputedStyle(
1755 - row.el
1756 - ).marginTop
1757 - );
1758 -
1759 - row.el.style.setProperty(
1760 - "margin-top",
1761 - (
1762 - current+delta
1763 - )+"px"
1764 - );
1765 -
1766 - row.el.setAttribute(
1767 - "data-sn-master-first-row",
1768 - "1"
1769 - );
1770 -
1771 - managedMargin.add(
1772 - row.el
1773 - );
1774 - }
1775 - });
1776 - }
1777 -
1778 - var maxHeight=0;
1779 -
1780 - group.cards.forEach(function(card){
1781 - maxHeight=
1782 - Math.max(
1783 - maxHeight,
1784 - card
1785 - .getBoundingClientRect()
1786 - .height
1787 - );
1788 - });
1789 -
1790 - maxHeight=
1791 - Math.ceil(maxHeight);
1792 -
1793 - group.cards.forEach(function(card){
1794 - saveStyle(
1795 - card,
1796 - originalHeight,
1797 - "min-height"
1798 - );
1799 -
1800 - card.style.setProperty(
1801 - "min-height",
1802 - maxHeight+"px"
1803 - );
1804 -
1805 - card.setAttribute(
1806 - "data-sn-master-equal-height",
1807 - "1"
1808 - );
1809 -
1810 - managedHeight.add(
1811 - card
1812 - );
1813 - });
1218 + heightManaged.add(card);
1814 1814   });
1220 +
1221 + return {
1222 + cards:cards.length,
1223 + height:maxHeight,
1224 + firstSection:firstSection
1225 + };
1815 1815   }
1816 1816  
1817 - /* =======================================================
1818 - DETAIL GRID EQUAL HEIGHT, DESKTOP ONLY
1819 - ======================================================= */
1228 + function run(){
1229 + reset();
1820 1820  
1821 - function equaliseDetailGrids(){
1822 1822   if(
1823 - PAGE_KIND!=="detail"||
1824 1824   window.innerWidth<=MOBILE_MAX
1825 1825   ){
1826 1826   return;
1827 1827   }
1828 1828  
1829 - var selectors=[
1830 - ".arsn-grid",
1831 - ".arsn-grid-2",
1832 - ".arsn-grid-3",
1833 - ".dmp-grid",
1834 - ".ido-grid",
1835 - ".pp-grid"
1836 - ];
1837 -
1838 - selectors.forEach(function(selector){
1237 + var parents=
1839 1839   Array.from(
1840 - root.querySelectorAll(selector)
1841 - ).forEach(function(grid){
1842 - var children=
1843 - Array.from(
1844 - grid.children||[]
1845 - ).filter(visible);
1239 + root.querySelectorAll("*")
1240 + ).filter(function(parent){
1241 + return (
1242 + visible(parent,MIN_W,MIN_H)&&
1243 + parent.children&&
1244 + parent.children.length>=2&&
1245 + parent.children.length<=MAX_PARENT_CHILDREN
1246 + );
1247 + });
1846 1846  
1847 - if(children.length<2){
1848 - return;
1849 - }
1249 + var touched=new Set();
1850 1850  
1851 - var groups=[];
1251 + parents.forEach(function(parent){
1252 + var entries=[];
1852 1852  
1853 - children.forEach(function(child){
1854 - var top=
1855 - child
1856 - .getBoundingClientRect()
1857 - .top;
1254 + Array.from(parent.children).forEach(function(child){
1255 + if(!visible(child,MIN_W,MIN_H))return;
1858 1858  
1859 - var group=null;
1257 + var target=pickTarget(child);
1258 + if(!target)return;
1860 1860  
1861 - for(var i=0;i<groups.length;i++){
1862 - if(
1863 - Math.abs(
1864 - groups[i].top-top
1865 - )<=ROW_TOLERANCE
1866 - ){
1867 - group=groups[i];
1868 - break;
1869 - }
1870 - }
1871 -
1872 - if(!group){
1873 - group={
1874 - top:top,
1875 - items:[]
1876 - };
1877 - groups.push(group);
1878 - }
1879 -
1880 - group.items.push(child);
1260 + entries.push({
1261 + target:target,
1262 + rect:target.getBoundingClientRect()
1881 1881   });
1264 + });
1882 1882  
1883 - groups.forEach(function(group){
1884 - if(group.items.length<2){
1885 - return;
1886 - }
1266 + if(entries.length<2)return;
1887 1887  
1888 - var maxHeight=0;
1268 + groupsByVisualRow(entries).forEach(function(group){
1269 + if(!validHorizontalGroup(group))return;
1889 1889  
1890 - group.items.forEach(function(item){
1891 - maxHeight=
1892 - Math.max(
1893 - maxHeight,
1894 - item
1895 - .getBoundingClientRect()
1896 - .height
1897 - );
1271 + var signature=
1272 + group.entries.map(function(entry){
1273 + return entry.target;
1898 1898   });
1899 1899  
1900 - maxHeight=
1901 - Math.ceil(maxHeight);
1276 + if(
1277 + !signature.some(function(el){
1278 + return !touched.has(el);
1279 + })
1280 + ){
1281 + return;
1282 + }
1902 1902  
1903 - group.items.forEach(function(item){
1904 - saveStyle(
1905 - item,
1906 - originalHeight,
1907 - "min-height"
1908 - );
1284 + var applied=
1285 + applyGroup(group);
1909 1909  
1910 - item.style.setProperty(
1911 - "min-height",
1912 - maxHeight+"px"
1913 - );
1914 -
1915 - item.setAttribute(
1916 - "data-sn-master-equal-height",
1917 - "1"
1918 - );
1919 -
1920 - managedHeight.add(item);
1287 + if(applied){
1288 + signature.forEach(function(el){
1289 + touched.add(el);
1921 1921   });
1922 - });
1291 + }
1923 1923   });
1924 1924   });
1925 1925   }
1926 1926  
1927 - /* =======================================================
1928 - RUN / RESPONSIVE SCHEDULING
1929 - ======================================================= */
1296 + function schedule(){
1297 + if(raf)cancelAnimationFrame(raf);
1930 1930  
1931 - function run(){
1932 - if(running)return;
1933 -
1934 - running=true;
1935 -
1936 - try{
1937 - resetRuntime();
1938 - applyPlaceholderBadge();
1939 - propagateDetailAccents();
1940 -
1941 - var headers=
1942 - applyOverviewPalette();
1943 -
1944 - makeThreeLineAreaLabels();
1945 - makeFilledRedOrangeCTAsBorderless();
1946 -
1947 - if(
1948 - window.innerWidth>
1949 - MOBILE_MAX
1950 - ){
1951 - alignOverviewCards(
1952 - headers
1953 - );
1954 -
1955 - equaliseDetailGrids();
1956 - }
1957 - }finally{
1958 - running=false;
1959 - }
1299 + raf=requestAnimationFrame(function(){
1300 + raf=requestAnimationFrame(function(){
1301 + raf=0;
1302 + run();
1303 + });
1304 + });
1960 1960   }
1961 1961  
1962 - function onResize(){
1963 - if(resizeTimer){
1964 - clearTimeout(
1965 - resizeTimer
1966 - );
1967 - }
1307 + addEventListener("resize",schedule,{passive:true});
1308 + addEventListener("load",schedule,{once:true});
1968 1968  
1969 - resizeTimer=
1970 - setTimeout(
1971 - function(){
1972 - resizeTimer=0;
1973 - run();
1974 - },
1975 - RESIZE_DEBOUNCE
1976 - );
1977 - }
1310 + root.addEventListener(
1311 + "click",
1312 + function(){
1313 + setTimeout(schedule,0);
1314 + },
1315 + true
1316 + );
1978 1978  
1979 - async function waitForReady(){
1980 - if(
1981 - document.readyState!=="complete"
1982 - ){
1983 - await new Promise(function(resolve){
1984 - window.addEventListener(
1985 - "load",
1986 - resolve,
1987 - {once:true}
1988 - );
1989 - });
1318 + Array.from(root.querySelectorAll("img")).forEach(function(img){
1319 + if(!img.complete){
1320 + img.addEventListener("load",schedule,{once:true});
1990 1990   }
1322 + });
1991 1991  
1992 - if(
1993 - document.fonts&&
1994 - document.fonts.ready
1995 - ){
1996 - try{
1997 - await document.fonts.ready;
1998 - }catch(error){}
1999 - }
2000 -
2001 - var images=
2002 - Array.from(
2003 - root.querySelectorAll("img")
2004 - );
2005 -
2006 - await Promise.all(
2007 - images.map(function(img){
2008 - if(img.complete){
2009 - return Promise.resolve();
2010 - }
2011 -
2012 - return new Promise(function(resolve){
2013 - var done=function(){
2014 - resolve();
2015 - };
2016 -
2017 - img.addEventListener(
2018 - "load",
2019 - done,
2020 - {once:true}
2021 - );
2022 -
2023 - img.addEventListener(
2024 - "error",
2025 - done,
2026 - {once:true}
2027 - );
2028 - });
2029 - })
2030 - );
2031 -
2032 - run();
1324 + if(document.fonts&&document.fonts.ready){
1325 + document.fonts.ready.then(schedule);
2033 2033   }
2034 2034  
2035 - window.addEventListener(
2036 - "resize",
2037 - onResize,
2038 - {passive:true}
2039 - );
2040 -
2041 - waitForReady();
1328 + schedule();
1329 + setTimeout(schedule,200);
1330 + setTimeout(schedule,650);
1331 + setTimeout(schedule,1400);
2042 2042  })();
2043 2043  </script>
2044 -
2045 -<!-- SN_SERVICE_NAVIGATOR_MASTER_STYLE_END -->
1334 +<!-- SN_HORIZONTAL_BOX_HARMONIZER_END -->
2046 2046  {{/html}}
2047 2047  
2048 -{{html clean="false"}}
2049 -<!-- ARSN_PHASE_CTA_MOBILE_EDGE_FIX_V3_START -->
2050 -<style data-arsn-phase-cta-mobile-edge-fix="3">
2051 -@media (max-width:767px){
2052 -
2053 - /* Remove the white side gutters around the three phase CTAs. */
2054 - #xwikicontent .arsn-phase-cta-wrap{
2055 - box-sizing:border-box!important;
2056 - width:calc(100% + 2px)!important;
2057 - max-width:none!important;
2058 - margin:14px -1px -1px -1px!important;
2059 - padding:0!important;
2060 - border:0!important;
2061 - border-left:0!important;
2062 - box-shadow:none!important;
2063 - background:transparent!important;
2064 - }
2065 -
2066 - /* Full-width orange CTA; no extra border/shadow. */
2067 - #xwikicontent a.arsn-phase-cta{
2068 - display:flex!important;
2069 - align-items:center!important;
2070 - justify-content:center!important;
2071 - gap:8px!important;
2072 -
2073 - box-sizing:border-box!important;
2074 - width:100%!important;
2075 - max-width:none!important;
2076 - min-width:0!important;
2077 -
2078 - margin:0!important;
2079 - padding:12px 14px!important;
2080 -
2081 - border:0!important;
2082 - border-left:0!important;
2083 - border-right:0!important;
2084 - border-top:0!important;
2085 - border-bottom:0!important;
2086 - box-shadow:none!important;
2087 -
2088 - border-radius:8px!important;
2089 -
2090 - text-align:center!important;
2091 - text-align-last:center!important;
2092 - text-justify:auto!important;
2093 - word-spacing:normal!important;
2094 - white-space:normal!important;
2095 - }
2096 -
2097 - /* Keep an XWiki external-link icon on the same line/flex row. */
2098 - #xwikicontent a.arsn-phase-cta::after{
2099 - flex:0 0 auto!important;
2100 - margin-left:2px!important;
2101 - }
2102 -
2103 - #xwikicontent a.arsn-phase-cta > .fa,
2104 - #xwikicontent a.arsn-phase-cta > .icon,
2105 - #xwikicontent a.arsn-phase-cta > .external-link-icon,
2106 - #xwikicontent a.arsn-phase-cta > [class*="external"]{
2107 - position:static!important;
2108 - display:inline-block!important;
2109 - flex:0 0 auto!important;
2110 - margin:0!important;
2111 - }
2112 -}
2113 -</style>
2114 -<!-- ARSN_PHASE_CTA_MOBILE_EDGE_FIX_V3_END -->
2115 -{{/html}}
2116 -