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

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