Changes for page Art & Research Services Navigator
Last modified by Veronika Kocher on Friday, 18 Sep 2026 16:47
From 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
To 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
Summary
-
Page properties (1 modified, 0 added, 0 removed)
Details
- Page properties
-
- Content
-
... ... @@ -1,19 +1,13 @@ 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 theright guidance, services and resources for each stage of your project.3 +The **Art & Research Services Navigator** helps you find relevant guidance, services and resources for each stage of your project. 4 4 5 -{{info title=" How responsibilitieswork"}}6 - Thenavigatorbrings servicestogether aroundthe projectlifecycleand theresearcher's task. Itis anavigationlayeracrossuniversity services,notaseparateorganisational unit.5 +{{info title="Support for Your Project:"}} 6 + **Support Kunst und Forschung (SKF)** provides guidance for projects and grant applications and collaborates with the appropriate university services as needed. 7 7 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. 8 + The Navigator guides you through the project phases to the resources and points of contact relevant to your project. 13 13 {{/info}} 14 14 15 - 16 - 17 17 {{html clean="false"}} 18 18 <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);"> 19 19 <h2 style="font-size:20px;margin:0 0 6px 0;color:#35312d;">Search the Art & Research Services Navigator</h2> ... ... @@ -361,7 +361,7 @@ 361 361 (% style="padding:18px 17px 17px 17px;flex:1;" %) 362 362 ((( 363 363 (% style="font-size:19px;font-weight:700;margin-bottom:2px;" %) 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;"]]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;"]] 365 365 366 366 (% style="color:#666;margin-bottom:16px;" %) 367 367 Prepare your project before the main work begins. ... ... @@ -439,9 +439,9 @@ 439 439 ))) 440 440 ))) 441 441 442 -(% style="padding:0 16px 16px 16px;" %) 436 +(% class="arsn-phase-cta-wrap" style="padding:0 16px 16px 16px;" %) 443 443 ((( 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"]] 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"]] 445 445 ))) 446 446 ))) 447 447 ))) ... ... @@ -505,9 +505,9 @@ 505 505 ))) 506 506 ))) 507 507 508 -(% style="padding:0 16px 16px 16px;" %) 502 +(% class="arsn-phase-cta-wrap" style="padding:0 16px 16px 16px;" %) 509 509 ((( 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"]] 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"]] 511 511 ))) 512 512 ))) 513 513 ))) ... ... @@ -525,7 +525,7 @@ 525 525 (% style="font-size:19px;font-weight:700;margin-bottom:2px;" %) 526 526 [[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;"]] 527 527 528 -(% style="color:#666; margin-bottom:16px;" %)522 +(% class="arsn-phase-subtitle" style="color:#666;background:transparent;margin:2px 0 16px 0;padding:0;" %) 529 529 Decide how outputs should be shared, published, made findable and preserved. 530 530 531 531 (% 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;" %) ... ... @@ -581,9 +581,9 @@ 581 581 ))) 582 582 ))) 583 583 584 -(% style="padding:0 16px 16px 16px;" %) 578 +(% class="arsn-phase-cta-wrap" style="padding:0 16px 16px 16px;" %) 585 585 ((( 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"]] 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"]] 587 587 ))) 588 588 ))) 589 589 ))) ... ... @@ -592,6 +592,19 @@ 592 592 593 593 (% style="margin-top:30px;" %) 594 594 ((( 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 + 595 595 == Practical resources == 596 596 597 597 Use practical resources when you need a concise overview, a step-by-step procedure or a ready-to-use project aid. ... ... @@ -630,9 +630,9 @@ 630 630 631 631 (% style="margin-top:30px;" %) 632 632 ((( 633 -== Need help findingtheright route? ==640 +== Need help deciding where to start? == 634 634 635 -{{info title=" Start withtheright service"}}642 +{{info title="Where to start"}} 636 636 For **project development, funding, proposals and coordination of funded art and research projects**, **Support Kunst und Forschung** is a good place to start. 637 637 638 638 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. ... ... @@ -639,24 +639,148 @@ 639 639 {{/info}} 640 640 ))) 641 641 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]{ 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]{ 647 647 box-sizing:border-box; 648 648 } 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 +} 649 649 </style> 650 -<script data-sn-horizontal-box-harmonizer="4"> 779 + 780 +<script data-sn-service-navigator-master="1"> 651 651 (function(){ 652 652 "use strict"; 653 653 784 + var PAGE_KIND="overview"; 785 + var PLACEHOLDER=false; 786 + var PLACEHOLDER_LABEL="COMING SOON"; 787 + 654 654 var MOBILE_MAX=767; 655 655 var ROW_TOLERANCE=6; 656 - var MIN_W=150; 657 - var MIN_H=36; 658 - var MAX_PARENT_CHILDREN=16; 659 - var SEARCH_DEPTH=5; 790 + var RESIZE_DEBOUNCE=220; 660 660 661 661 var root= 662 662 document.getElementById("xwikicontent")|| ... ... @@ -666,93 +666,105 @@ 666 666 667 667 if(!root)return; 668 668 669 - var heightManaged=new Set(); 670 - var sectionManaged=new Set(); 671 - var originalMinHeight=new WeakMap(); 672 - var originalMarginTop=new WeakMap(); 673 - var raf=0; 800 + var managedHeight=new Set(); 801 + var managedMargin=new Set(); 802 + var originalHeight=new WeakMap(); 803 + var originalMargin=new WeakMap(); 674 674 675 - function num(v){ 676 - var n=parseFloat(v); 677 - return Number.isFinite(n)?n:0; 678 - } 805 + var resizeTimer=0; 806 + var running=false; 679 679 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; 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 + ] 691 691 } 870 + ]; 692 692 693 - var r=el.getBoundingClientRect(); 694 - 695 - return ( 696 - r.width>=(minW||1)&& 697 - r.height>=(minH||1) 698 - ); 872 + function num(value){ 873 + var n=parseFloat(value); 874 + return Number.isFinite(n)?n:0; 699 699 } 700 700 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 - ); 877 + function norm(value){ 878 + return String(value||"") 879 + .replace(/\s+/g," ") 880 + .trim() 881 + .toUpperCase(); 708 708 } 709 709 710 - function namedLikeBox(el){ 711 - var c= 712 - typeof el.className==="string" 713 - ? el.className 714 - : ""; 884 + function visible(el){ 885 + if(!el||el.nodeType!==1)return false; 715 715 716 - r eturn/(^|[s_-])(box|card|tile|panel|role|check|service|source|call|area|detail|resource|topic|warn|info)([s_-]|$)/i.test(c);717 - }887 + var style=getComputedStyle(el); 888 + var rect=el.getBoundingClientRect(); 718 718 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 - 747 747 return ( 748 - namedLikeBox(el)||749 - b order>=1||750 - (bg&&radius>=3)||751 - (shadow&&r.width>=180)891 + style.display!=="none"&& 892 + style.visibility!=="hidden"&& 893 + rect.width>20&& 894 + rect.height>4 752 752 ); 753 753 } 754 754 755 - function save Original(el,map,property){898 + function saveStyle(el,map,property){ 756 756 if(map.has(el))return; 757 757 758 758 map.set(el,{ ... ... @@ -761,7 +761,7 @@ 761 761 }); 762 762 } 763 763 764 - function restore Original(el,map,property){907 + function restoreStyle(el,map,property){ 765 765 var original=map.get(el); 766 766 767 767 if(original&&original.value){ ... ... @@ -775,247 +775,468 @@ 775 775 } 776 776 } 777 777 778 - function reset(){ 779 - heightManaged.forEach(function(el){780 - restore Original(921 + function resetRuntime(){ 922 + managedHeight.forEach(function(el){ 923 + restoreStyle( 781 781 el, 782 - original MinHeight,925 + originalHeight, 783 783 "min-height" 784 784 ); 785 - 786 786 el.removeAttribute( 787 - "data-sn-equal-height -managed"929 + "data-sn-master-equal-height" 788 788 ); 789 789 }); 790 790 791 - sectionManaged.forEach(function(el){792 - restore Original(933 + managedMargin.forEach(function(el){ 934 + restoreStyle( 793 793 el, 794 - originalMargin Top,936 + originalMargin, 795 795 "margin-top" 796 796 ); 797 - 798 798 el.removeAttribute( 799 - "data-sn-first- section-aligned"940 + "data-sn-master-first-row" 800 800 ); 801 801 }); 802 802 803 - heightManaged.clear();804 - sectionManaged.clear();944 + managedHeight.clear(); 945 + managedMargin.clear(); 805 805 } 806 806 807 - function pickTarget(child){808 - if(!visible(child,MIN_W,MIN_H))return null;948 + function themeFor(text){ 949 + var value=norm(text); 809 809 810 - if(boxLike(child)){ 811 - return child; 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 + } 812 812 } 813 813 814 - varcr=child.getBoundingClientRect();815 - var q=[];964 + return null; 965 + } 816 816 817 - Array.from(child.children||[]).forEach(function(el){ 818 - q.push({el:el,depth:1}); 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 + ); 819 819 }); 1048 + } 820 820 821 - var best=null; 822 - var bestScore=-Infinity; 1050 + /* ======================================================= 1051 + FULL-WIDTH THREE-LINE AREA LABELS 1052 + ======================================================= */ 823 823 824 - while(q.length){ 825 - var item=q.shift(); 826 - var el=item.el; 1054 + function compactText(value){ 1055 + return String(value||"") 1056 + .replace(/\s+/g," ") 1057 + .trim(); 1058 + } 827 827 828 - if(!visible(el,MIN_W,MIN_H))continue; 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 + } 829 829 830 - var r=el.getBoundingClientRect(); 1074 + var number= 1075 + label.querySelector( 1076 + ":scope > .arsn-area-number" 1077 + ); 831 831 1079 + var action= 1080 + label.querySelector( 1081 + ":scope > .arsn-area-action" 1082 + ); 1083 + 832 832 if( 833 - r .width>=cr.width*.68&&834 - boxLike(el)1085 + !number|| 1086 + !action 835 835 ){ 836 - var widthFit= 837 - 1-Math.min( 838 - 1, 839 - Math.abs(cr.width-r.width)/ 840 - Math.max(1,cr.width) 841 - ); 1088 + return; 1089 + } 842 842 843 - var topFit= 844 - 1-Math.min( 845 - 1, 846 - Math.abs(cr.top-r.top)/100 847 - ); 1091 + var clone= 1092 + label.cloneNode(true); 848 848 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; 1094 + var cloneNumber= 1095 + clone.querySelector( 1096 + ":scope > .arsn-area-number" 1097 + ); 854 854 855 - if(score>bestScore){ 856 - best=el; 857 - bestScore=score; 858 - } 1099 + var cloneAction= 1100 + clone.querySelector( 1101 + ":scope > .arsn-area-action" 1102 + ); 1103 + 1104 + if(cloneNumber){ 1105 + cloneNumber.remove(); 859 859 } 860 860 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 - }); 1108 + if(cloneAction){ 1109 + cloneAction.remove(); 868 868 } 869 - } 870 870 871 - return best; 872 - } 1112 + var titleText= 1113 + compactText( 1114 + clone.textContent 1115 + ); 873 873 874 - function groupsByVisualRow(entries){ 875 - var groups=[]; 1117 + if(!titleText){ 1118 + return; 1119 + } 876 876 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 1121 + var numberNode= 1122 + number.cloneNode(true); 1123 + 1124 + var actionNode= 1125 + action.cloneNode(true); 1126 + 1127 + var titleNode= 1128 + document.createElement( 1129 + "span" 883 883 ); 884 - }) 885 - .forEach(function(entry){ 886 - var group=null; 887 887 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 - } 1132 + titleNode.className= 1133 + "sn-area-label-title"; 899 899 900 - if(!group){ 901 - group={ 902 - top:entry.rect.top, 903 - entries:[] 904 - }; 905 - groups.push(group); 906 - } 1135 + titleNode.textContent= 1136 + titleText; 907 907 908 - group.entries.push(entry); 909 - }); 1138 + while(label.firstChild){ 1139 + label.removeChild( 1140 + label.firstChild 1141 + ); 1142 + } 910 910 911 - return groups; 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 + }); 912 912 } 913 913 914 - function validHorizontalGroup(group){ 915 - if(group.entries.length<2)return false; 1188 + /* ======================================================= 1189 + PLACEHOLDER BADGE 1190 + ======================================================= */ 916 916 917 - var lefts= 918 - group.entries 919 - .map(function(e){return e.rect.left;}) 920 - .sort(function(a,b){return a-b;}); 1192 + function applyPlaceholderBadge(){ 1193 + if(!PLACEHOLDER)return; 921 921 922 922 if( 923 - lefts[lefts.length-1]-924 - lefts[0]<925 - 801196 + document.querySelector( 1197 + ".sn-coming-soon-badge" 1198 + ) 926 926 ){ 927 - return false;1200 + return; 928 928 } 929 929 930 - var widths= 931 - group.entries 932 - .map(function(e){return e.rect.width;}) 933 - .filter(function(w){return w>0;}); 1203 + var title= 1204 + document.querySelector( 1205 + "#document-title" 1206 + )|| 1207 + document.querySelector( 1208 + "h1" 1209 + ); 934 934 935 - if( widths.length<2)returnfalse;1211 + if(!title)return; 936 936 937 - var minWidth=Math.min.apply(Math,widths); 938 - var maxWidth=Math.max.apply(Math,widths); 1213 + var badge= 1214 + document.createElement( 1215 + "span" 1216 + ); 939 939 940 - return ( 941 - maxWidth/ 942 - Math.max(1,minWidth)<= 943 - 1.9 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 944 944 ); 945 - } 946 946 947 - function normalizeText(text){ 948 - return String(text||"") 949 - .replace(/s+/g," ") 950 - .trim() 951 - .toUpperCase(); 1229 + title.appendChild( 1230 + badge 1231 + ); 952 952 } 953 953 954 - function exactKnownFirstSection(el){ 955 - var text=normalizeText(el.textContent); 1234 + /* ======================================================= 1235 + DETAIL PAGE OWN-ACCENT PROPAGATION 1236 + ======================================================= */ 956 956 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" 1238 + function parseRGB(value){ 1239 + var match=String(value||"").match( 1240 + /rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)/i 966 966 ); 1242 + 1243 + if(!match)return null; 1244 + 1245 + return [ 1246 + Number(match[1]), 1247 + Number(match[2]), 1248 + Number(match[3]) 1249 + ]; 967 967 } 968 968 969 - function visuallyFirstSectionBar(card){ 970 - var cardRect=card.getBoundingClientRect(); 971 - var candidates=[]; 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 + } 972 972 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 + 973 973 Array.from( 974 - card.querySelectorAll( 975 - "div,p,span,strong,h3,h4,h5,h6" 1293 + root.querySelectorAll( 1294 + ".arsn-call,.dmp-call,.ido-call,.pp-call,"+ 1295 + ".arsn-source,.dmp-source,.ido-source,.pp-source" 976 976 ) 977 977 ).forEach(function(el){ 978 - if(!visible(el,20,6))return; 979 - if(excluded(el))return; 1298 + if(!visible(el))return; 980 980 981 - var r=el.getBoundingClientRect(); 982 - var relativeTop=r.top-cardRect.top; 1300 + var style=getComputedStyle(el); 983 983 984 984 if( 985 - relativeTop<45|| 986 - relativeTop>cardRect.height*.72 1303 + num(style.borderTopWidth)>=2 987 987 ){ 988 - return; 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 + } 989 989 } 1318 + }); 990 990 991 - var widthRatio= 992 - r.width/ 993 - Math.max(1,cardRect.width); 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; 994 994 995 - if( 996 - widthRatio<.55|| 997 - widthRatio>1.05|| 998 - r.height>54 999 - ){ 1000 - return; 1001 - } 1329 + el.style.setProperty( 1330 + "border-left", 1331 + "4px solid #e94b13", 1332 + "important" 1333 + ); 1334 + }); 1002 1002 1003 - var text=normalizeText(el.textContent); 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; 1004 1004 1005 - if( 1006 - text.length<2|| 1007 - text.length>90 1008 - ){ 1009 - return; 1010 - } 1344 + el.style.setProperty( 1345 + "border-left", 1346 + "4px solid #21b6d7", 1347 + "important" 1348 + ); 1349 + }); 1350 + } 1011 1011 1012 - var style=getComputedStyle(el); 1352 + /* ======================================================= 1353 + OVERVIEW SEMANTIC THEME PALETTE 1354 + ======================================================= */ 1013 1013 1014 - var bg= 1015 - style.backgroundColor&& 1016 - style.backgroundColor!=="rgba(0, 0, 0, 0)"&& 1017 - style.backgroundColor!=="transparent"; 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; 1018 1018 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 + 1019 1019 var border= 1020 1020 num(style.borderTopWidth)+ 1021 1021 num(style.borderRightWidth)+ ... ... @@ -1022,315 +1022,749 @@ 1022 1022 num(style.borderBottomWidth)+ 1023 1023 num(style.borderLeftWidth); 1024 1024 1025 - var mostlyUpper= 1026 - text.length>=3&& 1027 - text===text.toUpperCase(); 1028 - 1029 - var exact=exactKnownFirstSection(el); 1030 - 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); 1037 - 1038 - if(score>=7){ 1039 - candidates.push({ 1040 - el:el, 1041 - relativeTop:relativeTop, 1042 - width:r.width, 1043 - score:score 1044 - }); 1389 + if( 1390 + rect.width>=220&& 1391 + rect.width<=800&& 1392 + rect.height>=120&& 1393 + border>=1 1394 + ){ 1395 + candidates.push(node); 1045 1045 } 1046 - }); 1047 1047 1398 + node=node.parentElement; 1399 + } 1400 + 1048 1048 if(!candidates.length)return null; 1049 1049 1050 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; 1054 - } 1055 - return b.width-a.width; 1404 + return ( 1405 + b.getBoundingClientRect().height- 1406 + a.getBoundingClientRect().height 1407 + ); 1056 1056 }); 1057 1057 1058 - // For exact known labels always prefer the earliest exact match. 1059 - var exacts=candidates.filter(function(c){ 1060 - return exactKnownFirstSection(c.el); 1061 - }); 1410 + return candidates[0]; 1411 + } 1062 1062 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; 1068 - } 1413 + function rowCandidates(link,card){ 1414 + var result=[]; 1415 + var cardRect= 1416 + card.getBoundingClientRect(); 1069 1069 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 - }); 1418 + var node=link; 1074 1074 1075 - return candidates[0].el; 1076 - } 1420 + while(node&&node!==card){ 1421 + if(visible(node)){ 1422 + var rect= 1423 + node.getBoundingClientRect(); 1077 1077 1078 - function alignFirstSections(cards){ 1079 - var rows= 1080 - cards.map(function(card){ 1081 - var bar= 1082 - visuallyFirstSectionBar(card); 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 + } 1434 + } 1083 1083 1084 - if(!bar)return null; 1436 + node=node.parentElement; 1437 + } 1085 1085 1086 - varcardRect=1087 - card.getBoundingClientRect();1439 + return result; 1440 + } 1088 1088 1089 - var barRect= 1090 - bar.getBoundingClientRect(); 1442 + function chooseOuterRow( 1443 + candidates, 1444 + link 1445 + ){ 1446 + if(!candidates.length){ 1447 + return link; 1448 + } 1091 1091 1092 - return {1093 - card:card,1094 - bar:bar,1095 - relativeTop:1096 - barRect.top-cardRect.top,1097 - label:1098 - normalizeText(bar.textContent)1099 - };1450 + var bordered= 1451 + candidates.filter(function(el){ 1452 + return ( 1453 + num( 1454 + getComputedStyle(el) 1455 + .borderLeftWidth 1456 + )>=1 1457 + ); 1100 1100 }); 1101 1101 1102 - // Conservative: only align when every card in the horizontal row 1103 - // has a reliable first section bar. 1104 - if( 1105 - rows.some(function(row){ 1106 - return !row; 1107 - }) 1108 - ){ 1109 - return null; 1460 + var pool= 1461 + bordered.length 1462 + ?bordered 1463 + :candidates; 1464 + 1465 + pool.sort(function(a,b){ 1466 + var ar= 1467 + a.getBoundingClientRect(); 1468 + 1469 + var br= 1470 + b.getBoundingClientRect(); 1471 + 1472 + return ( 1473 + ar.left-br.left|| 1474 + br.width-ar.width 1475 + ); 1476 + }); 1477 + 1478 + return pool[0]||link; 1479 + } 1480 + 1481 + function applyOverviewPalette(){ 1482 + if(PAGE_KIND!=="overview"){ 1483 + return []; 1110 1110 } 1111 1111 1112 - var targetTop= 1113 - Math.max.apply( 1114 - Math, 1115 - rows.map(function(row){ 1116 - return row.relativeTop; 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 + }; 1117 1117 }) 1118 - ); 1501 + .filter(function(row){ 1502 + return !!row.card; 1503 + }); 1119 1119 1120 - rows.forEach(function(row){ 1121 - var delta= 1122 - targetTop- 1123 - row.relativeTop; 1505 + var unique=[]; 1506 + var seenHeaders=new Set(); 1124 1124 1125 - if(delta<=1)return; 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 + ); 1126 1126 1127 - saveOriginal( 1128 - row.bar, 1129 - originalMarginTop, 1130 - "margin-top" 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" 1131 1131 ); 1132 1132 1133 - var currentMargin= 1134 - num( 1135 - getComputedStyle( 1136 - row.bar 1137 - ).marginTop 1138 - ); 1541 + row.el.style.setProperty( 1542 + "color", 1543 + row.theme.text, 1544 + "important" 1545 + ); 1139 1139 1140 - row.bar.style.setProperty( 1141 - "margin-top", 1142 - ( 1143 - currentMargin+ 1144 - delta 1145 - )+"px" 1547 + row.el.style.setProperty( 1548 + "text-align", 1549 + "left", 1550 + "important" 1146 1146 ); 1147 1147 1148 - row.bar.setAttribute( 1149 - "data-sn-first-section-aligned", 1150 - "4" 1553 + row.el.style.setProperty( 1554 + "word-spacing", 1555 + "normal", 1556 + "important" 1151 1151 ); 1152 1152 1153 - sectionManaged.add(row.bar); 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 + }); 1154 1154 }); 1155 1155 1156 - return { 1157 - labels: 1158 - rows.map(function(row){ 1159 - return row.label; 1160 - }), 1161 - targetRelativeTop: 1162 - Math.round(targetTop) 1163 - }; 1649 + return unique; 1164 1164 } 1165 1165 1166 - function applyGroup(group){ 1167 - if(!validHorizontalGroup(group)){ 1168 - return null; 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; 1169 1169 } 1170 1170 1171 1171 var cards=[]; 1172 1172 var seen=new Set(); 1173 1173 1174 - group.entries.forEach(function(entry){1175 - if(!seen.has( entry.target)){1176 - seen.add( entry.target);1177 - cards.push( entry.target);1667 + headers.forEach(function(row){ 1668 + if(!seen.has(row.card)){ 1669 + seen.add(row.card); 1670 + cards.push(row.card); 1178 1178 } 1179 1179 }); 1180 1180 1181 - if(cards.length<2)return null; 1674 + if(cards.length<2){ 1675 + return; 1676 + } 1182 1182 1183 - varfirstSection=1184 - alignFirstSections(cards);1678 + // Group cards by actual top position. 1679 + var groups=[]; 1185 1185 1186 - // The section alignment can change natural card heights. 1187 - // Measure only afterwards. 1188 - var maxHeight=0; 1189 - 1190 1190 cards.forEach(function(card){ 1191 - maxHeight=Math.max( 1192 - maxHeight, 1193 - card.getBoundingClientRect().height 1194 - ); 1682 + var top= 1683 + card.getBoundingClientRect().top; 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); 1195 1195 }); 1196 1196 1197 - maxHeight=Math.ceil(maxHeight); 1709 + groups.forEach(function(group){ 1710 + if(group.cards.length<2){ 1711 + return; 1712 + } 1198 1198 1199 - if(maxHeight<MIN_H)return null; 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 + }); 1200 1200 1201 - cards.forEach(function(card){ 1202 - saveOriginal( 1203 - card, 1204 - originalMinHeight, 1205 - "min-height" 1206 - ); 1732 + return candidates.length 1733 + ?candidates[0] 1734 + :null; 1735 + }); 1207 1207 1208 - card.style.setProperty( 1209 - "min-height", 1210 - maxHeight+"px" 1211 - ); 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 + ); 1212 1212 1213 - card.setAttribute( 1214 - "data-sn-equal-height-managed", 1215 - "4" 1216 - ); 1757 + firstHeaders.forEach(function(row){ 1758 + var relativeTop= 1759 + row.el 1760 + .getBoundingClientRect() 1761 + .top- 1762 + row.card 1763 + .getBoundingClientRect() 1764 + .top; 1217 1217 1218 - heightManaged.add(card);1219 - });1766 + var delta= 1767 + targetTop-relativeTop; 1220 1220 1221 - return { 1222 - cards:cards.length, 1223 - height:maxHeight, 1224 - firstSection:firstSection 1225 - }; 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 + }); 1838 + }); 1226 1226 } 1227 1227 1228 - function run(){ 1229 - reset(); 1841 + /* ======================================================= 1842 + DETAIL GRID EQUAL HEIGHT, DESKTOP ONLY 1843 + ======================================================= */ 1230 1230 1845 + function equaliseDetailGrids(){ 1231 1231 if( 1847 + PAGE_KIND!=="detail"|| 1232 1232 window.innerWidth<=MOBILE_MAX 1233 1233 ){ 1234 1234 return; 1235 1235 } 1236 1236 1237 - var parents= 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){ 1238 1238 Array.from( 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 - }); 1864 + root.querySelectorAll(selector) 1865 + ).forEach(function(grid){ 1866 + var children= 1867 + Array.from( 1868 + grid.children||[] 1869 + ).filter(visible); 1248 1248 1249 - var touched=new Set(); 1871 + if(children.length<2){ 1872 + return; 1873 + } 1250 1250 1251 - parents.forEach(function(parent){ 1252 - var entries=[]; 1875 + var groups=[]; 1253 1253 1254 - Array.from(parent.children).forEach(function(child){ 1255 - if(!visible(child,MIN_W,MIN_H))return; 1877 + children.forEach(function(child){ 1878 + var top= 1879 + child 1880 + .getBoundingClientRect() 1881 + .top; 1256 1256 1257 - var target=pickTarget(child); 1258 - if(!target)return; 1883 + var group=null; 1259 1259 1260 - entries.push({ 1261 - target:target, 1262 - rect:target.getBoundingClientRect() 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); 1263 1263 }); 1264 - }); 1265 1265 1266 - if(entries.length<2)return; 1907 + groups.forEach(function(group){ 1908 + if(group.items.length<2){ 1909 + return; 1910 + } 1267 1267 1268 - groupsByVisualRow(entries).forEach(function(group){ 1269 - if(!validHorizontalGroup(group))return; 1912 + var maxHeight=0; 1270 1270 1271 - var signature= 1272 - group.entries.map(function(entry){ 1273 - return entry.target; 1914 + group.items.forEach(function(item){ 1915 + maxHeight= 1916 + Math.max( 1917 + maxHeight, 1918 + item 1919 + .getBoundingClientRect() 1920 + .height 1921 + ); 1274 1274 }); 1275 1275 1276 - if( 1277 - !signature.some(function(el){ 1278 - return !touched.has(el); 1279 - }) 1280 - ){ 1281 - return; 1282 - } 1924 + maxHeight= 1925 + Math.ceil(maxHeight); 1283 1283 1284 - var applied= 1285 - applyGroup(group); 1927 + group.items.forEach(function(item){ 1928 + saveStyle( 1929 + item, 1930 + originalHeight, 1931 + "min-height" 1932 + ); 1286 1286 1287 - if(applied){ 1288 - signature.forEach(function(el){ 1289 - touched.add(el); 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); 1290 1290 }); 1291 - } 1946 + }); 1292 1292 }); 1293 1293 }); 1294 1294 } 1295 1295 1296 - function schedule(){ 1297 - if(raf)cancelAnimationFrame(raf); 1951 + /* ======================================================= 1952 + RUN / RESPONSIVE SCHEDULING 1953 + ======================================================= */ 1298 1298 1299 - raf=requestAnimationFrame(function(){ 1300 - raf=requestAnimationFrame(function(){ 1301 - raf=0; 1302 - run(); 1303 - }); 1304 - }); 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 + } 1305 1305 } 1306 1306 1307 - addEventListener("resize",schedule,{passive:true}); 1308 - addEventListener("load",schedule,{once:true}); 1986 + function onResize(){ 1987 + if(resizeTimer){ 1988 + clearTimeout( 1989 + resizeTimer 1990 + ); 1991 + } 1309 1309 1310 - root.addEventListener( 1311 - "click", 1312 - function(){ 1313 - setTimeout(schedule,0); 1314 - }, 1315 - true 1316 - ); 1993 + resizeTimer= 1994 + setTimeout( 1995 + function(){ 1996 + resizeTimer=0; 1997 + run(); 1998 + }, 1999 + RESIZE_DEBOUNCE 2000 + ); 2001 + } 1317 1317 1318 - Array.from(root.querySelectorAll("img")).forEach(function(img){ 1319 - if(!img.complete){ 1320 - img.addEventListener("load",schedule,{once:true}); 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 + }); 1321 1321 } 1322 - }); 1323 1323 1324 - if(document.fonts&&document.fonts.ready){ 1325 - document.fonts.ready.then(schedule); 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(); 1326 1326 } 1327 1327 1328 - schedule(); 1329 - setTimeout(schedule,200); 1330 - setTimeout(schedule,650); 1331 - setTimeout(schedule,1400); 2059 + window.addEventListener( 2060 + "resize", 2061 + onResize, 2062 + {passive:true} 2063 + ); 2064 + 2065 + waitForReady(); 1332 1332 })(); 1333 1333 </script> 1334 -<!-- SN_HORIZONTAL_BOX_HARMONIZER_END --> 1335 -{{/html}} 1336 1336 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}}