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