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