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