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
Change comment: There is no comment for this version
To version 39.23
edited by Veronika Kocher
on Thursday, 03 Sep 2026 10:09
Change comment: There is no comment for this version

Summary

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="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.
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 &amp; 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 0 16px 0;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 &amp; WORKSHOPS</div>
594 - <h3 style="font-size:20px;line-height:1.3;margin:0 0 7px;color:#35312d;text-align:left;">Training, workshops &amp; 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 deciding where to start? ==
633 +== Need help finding the right route? ==
641 641  
642 -{{info title="Where to start"}}
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,28 +646,12 @@
646 646  {{/info}}
647 647  )))
648 648  
649 -{{html clean="false"}}<!-- SN_SERVICE_NAVIGATOR_MASTER_STYLE_START -->
642 +\n\n
643 +\n\n{{html clean="false"}}
644 +<!-- SN_HORIZONTAL_BOX_HARMONIZER_START -->
650 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 - ========================================================= */
646 +<style data-sn-horizontal-box-harmonizer="7">
647 +/* ---------- Typography: never justify headings ---------- */
671 671  #xwikicontent h1,
672 672  #xwikicontent h2,
673 673  #xwikicontent h3,
... ... @@ -689,105 +689,88 @@
689 689   word-spacing:normal!important;
690 690  }
691 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{
669 +/* ---------- Native XWiki semantic callouts ---------- */
670 +#xwikicontent .box.infomessage,
671 +#xwikicontent .infomessage,
672 +#xwikicontent .box.warningmessage,
673 +#xwikicontent .warningmessage,
674 +#xwikicontent .box.successmessage,
675 +#xwikicontent .successmessage,
676 +#xwikicontent .box.errormessage,
677 +#xwikicontent .errormessage,
678 +#xwikicontent [data-sn-callout-harmonized="1"]{
720 720   box-sizing:border-box!important;
721 - border-left:4px solid #21b6d7!important;
722 - border-radius:8px;
680 + border-radius:8px!important;
681 + border-top:1px solid rgba(0,0,0,.08)!important;
682 + border-right:1px solid rgba(0,0,0,.08)!important;
683 + border-bottom:1px solid rgba(0,0,0,.08)!important;
684 + border-left:4px solid var(--sn-callout-accent,#21b6d7)!important;
685 + padding:14px 16px!important;
723 723   text-align:left!important;
687 + text-justify:auto!important;
724 724   word-spacing:normal!important;
689 + box-shadow:none!important;
725 725  }
726 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,
692 +#xwikicontent .box.infomessage,
693 +#xwikicontent .infomessage{
694 + --sn-callout-accent:#21b6d7;
695 + background:#eaf7fb!important;
696 +}
697 +
698 +#xwikicontent .box.warningmessage,
699 +#xwikicontent .warningmessage{
700 + --sn-callout-accent:#f0aa00;
701 + background:#fff8e7!important;
702 +}
703 +
704 +#xwikicontent .box.successmessage,
705 +#xwikicontent .successmessage{
706 + --sn-callout-accent:#38b76a;
707 + background:#edf9f1!important;
708 +}
709 +
710 +#xwikicontent .box.errormessage,
734 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;
712 + --sn-callout-accent:#e94b13;
713 + background:#fff1ec!important;
740 740  }
741 741  
742 -[data-sn-master-equal-height],
743 -[data-sn-master-first-row]{
744 - box-sizing:border-box;
716 +#xwikicontent [data-sn-callout-harmonized="1"] > :first-child,
717 +#xwikicontent .infomessage > :first-child,
718 +#xwikicontent .warningmessage > :first-child,
719 +#xwikicontent .successmessage > :first-child,
720 +#xwikicontent .errormessage > :first-child{
721 + margin-top:0!important;
745 745  }
746 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;
724 +#xwikicontent [data-sn-callout-harmonized="1"] > :last-child,
725 +#xwikicontent .infomessage > :last-child,
726 +#xwikicontent .warningmessage > :last-child,
727 +#xwikicontent .successmessage > :last-child,
728 +#xwikicontent .errormessage > :last-child{
729 + margin-bottom:0!important;
765 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;
731 +
732 +#xwikicontent [data-sn-equal-height-managed],
733 +#xwikicontent [data-sn-first-section-aligned],
734 +#xwikicontent [data-sn-first-content-aligned]{
735 + box-sizing:border-box;
777 777  }
778 778  </style>
779 779  
780 -<script data-sn-service-navigator-master="1">
739 +<script data-sn-horizontal-box-harmonizer="7">
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;
745 + var MIN_W=150;
746 + var MIN_H=36;
747 + var MAX_PARENT_CHILDREN=18;
748 + var SEARCH_DEPTH=5;
790 790   var RESIZE_DEBOUNCE=220;
750 + var MIN_WIDTH_CHANGE=2;
791 791  
792 792   var root=
793 793   document.getElementById("xwikicontent")||
... ... @@ -797,114 +797,142 @@
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();
760 + var heightManaged=new Set();
761 + var sectionManaged=new Set();
762 + var contentManaged=new Set();
804 804  
764 + var originalMinHeight=new WeakMap();
765 + var originalMarginTop=new WeakMap();
766 +
805 805   var resizeTimer=0;
806 - var running=false;
768 + var lastWidth=-1;
769 + var hasApplied=false;
770 + var applying=false;
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 - ]
772 + function num(v){
773 + var n=parseFloat(v);
774 + return Number.isFinite(n)?n:0;
775 + }
776 +
777 + function visible(el,minW,minH){
778 + if(!el||el.nodeType!==1)return false;
779 +
780 + var s=getComputedStyle(el);
781 +
782 + if(
783 + s.display==="none"||
784 + s.visibility==="hidden"||
785 + Number(s.opacity)===0
786 + ){
787 + return false;
869 869   }
870 - ];
871 871  
872 - function num(value){
873 - var n=parseFloat(value);
874 - return Number.isFinite(n)?n:0;
790 + var r=el.getBoundingClientRect();
791 +
792 + return (
793 + r.width>=(minW||1)&&
794 + r.height>=(minH||1)
795 + );
875 875   }
876 876  
877 - function norm(value){
878 - return String(value||"")
798 + function normalizeText(text){
799 + return String(text||"")
879 879   .replace(/\s+/g," ")
880 880   .trim()
881 881   .toUpperCase();
882 882   }
883 883  
884 - function visible(el){
885 - if(!el||el.nodeType!==1)return false;
805 + function excluded(el){
806 + return (
807 + !el.matches||
808 + el.matches(
809 + "button,input,select,textarea,option,label,img,svg,canvas,table,thead,tbody,tfoot,tr,td,th,summary,script,style,noscript,template,.btn,.chip,[role=button]"
810 + )
811 + );
812 + }
886 886  
887 - var style=getComputedStyle(el);
888 - var rect=el.getBoundingClientRect();
814 + /* ---------- Custom coloured callouts ---------- */
889 889  
816 + function nativeCallout(el){
817 + var c=
818 + typeof el.className==="string"
819 + ? el.className.toLowerCase()
820 + : "";
821 +
890 890   return (
891 - style.display!=="none"&&
892 - style.visibility!=="hidden"&&
893 - rect.width>20&&
894 - rect.height>4
823 + /(^|\s)(infomessage|warningmessage|successmessage|errormessage)(\s|$)/.test(c)
895 895   );
896 896   }
897 897  
898 - function saveStyle(el,map,property){
827 + function customCallout(el){
828 + if(!visible(el,220,42)||excluded(el))return false;
829 +
830 + var r=el.getBoundingClientRect();
831 +
832 + if(r.height>520)return false;
833 +
834 + var s=getComputedStyle(el);
835 +
836 + var bg=
837 + s.backgroundColor&&
838 + s.backgroundColor!=="rgba(0, 0, 0, 0)"&&
839 + s.backgroundColor!=="transparent"&&
840 + s.backgroundColor!=="rgb(255, 255, 255)";
841 +
842 + var left=
843 + num(s.borderLeftWidth);
844 +
845 + return (
846 + bg&&
847 + left>=2
848 + );
849 + }
850 +
851 + function harmoniseCustomCallouts(){
852 + Array.from(
853 + root.querySelectorAll(
854 + "div,aside,section"
855 + )
856 + ).forEach(function(el){
857 + if(nativeCallout(el))return;
858 + if(!customCallout(el))return;
859 +
860 + var s=getComputedStyle(el);
861 +
862 + el.setAttribute(
863 + "data-sn-callout-harmonized",
864 + "1"
865 + );
866 +
867 + if(
868 + s.borderLeftColor
869 + ){
870 + el.style.setProperty(
871 + "--sn-callout-accent",
872 + s.borderLeftColor
873 + );
874 + }
875 + });
876 + }
877 +
878 + /* ---------- Restore only values V7 itself changed ---------- */
879 +
880 + function saveOriginal(el,map,property){
899 899   if(map.has(el))return;
900 900  
901 901   map.set(el,{
902 - value:el.style.getPropertyValue(property),
903 - priority:el.style.getPropertyPriority(property)
884 + value:
885 + el.style.getPropertyValue(
886 + property
887 + ),
888 + priority:
889 + el.style.getPropertyPriority(
890 + property
891 + )
904 904   });
905 905   }
906 906  
907 - function restoreStyle(el,map,property){
895 + function restoreOriginal(el,map,property){
908 908   var original=map.get(el);
909 909  
910 910   if(original&&original.value){
... ... @@ -914,1076 +914,770 @@
914 914   original.priority||""
915 915   );
916 916   }else{
917 - el.style.removeProperty(property);
905 + el.style.removeProperty(
906 + property
907 + );
918 918   }
919 919   }
920 920  
921 921   function resetRuntime(){
922 - managedHeight.forEach(function(el){
923 - restoreStyle(
912 + heightManaged.forEach(function(el){
913 + restoreOriginal(
924 924   el,
925 - originalHeight,
915 + originalMinHeight,
926 926   "min-height"
927 927   );
918 +
928 928   el.removeAttribute(
929 - "data-sn-master-equal-height"
920 + "data-sn-equal-height-managed"
930 930   );
931 931   });
932 932  
933 - managedMargin.forEach(function(el){
934 - restoreStyle(
924 + sectionManaged.forEach(function(el){
925 + restoreOriginal(
935 935   el,
936 - originalMargin,
927 + originalMarginTop,
937 937   "margin-top"
938 938   );
930 +
939 939   el.removeAttribute(
940 - "data-sn-master-first-row"
932 + "data-sn-first-section-aligned"
941 941   );
942 942   });
943 943  
944 - managedHeight.clear();
945 - managedMargin.clear();
946 - }
936 + contentManaged.forEach(function(el){
937 + restoreOriginal(
938 + el,
939 + originalMarginTop,
940 + "margin-top"
941 + );
947 947  
948 - function themeFor(text){
949 - var value=norm(text);
943 + el.removeAttribute(
944 + "data-sn-first-content-aligned"
945 + );
946 + });
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 - }
962 - }
963 -
964 - return null;
948 + heightManaged.clear();
949 + sectionManaged.clear();
950 + contentManaged.clear();
965 965   }
966 966  
967 - /* =======================================================
968 - BORDERLESS FILLED RED/ORANGE CTA BUTTONS
969 - ======================================================= */
953 + /* ---------- Card detection ---------- */
970 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 - );
955 + function namedLikeBox(el){
956 + var c=
957 + typeof el.className==="string"
958 + ? el.className
959 + : "";
960 +
961 + return /(^|[\s_-])(box|card|tile|panel|role|check|service|source|call|area|detail|resource|topic|warn|info)([\s_-]|$)/i.test(c);
977 977   }
978 978  
979 - function makeFilledRedOrangeCTAsBorderless(){
980 - var RED_ORANGE=[233,75,19];
964 + function boxLike(el){
965 + if(
966 + !visible(el,MIN_W,MIN_H)||
967 + excluded(el)
968 + ){
969 + return false;
970 + }
981 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;
972 + var s=getComputedStyle(el);
973 + var r=el.getBoundingClientRect();
988 988  
989 - var style=getComputedStyle(el);
990 - var rgb=parseRGB(style.backgroundColor);
975 + var border=
976 + num(s.borderTopWidth)+
977 + num(s.borderRightWidth)+
978 + num(s.borderBottomWidth)+
979 + num(s.borderLeftWidth);
991 991  
992 - if(!rgb)return;
981 + var radius=Math.max(
982 + num(s.borderTopLeftRadius),
983 + num(s.borderTopRightRadius),
984 + num(s.borderBottomLeftRadius),
985 + num(s.borderBottomRightRadius)
986 + );
993 993  
994 - if(
995 - colourDistance(
996 - rgb,
997 - RED_ORANGE
998 - )>55
999 - ){
1000 - return;
1001 - }
988 + var bg=
989 + s.backgroundColor&&
990 + s.backgroundColor!=="rgba(0, 0, 0, 0)"&&
991 + s.backgroundColor!=="transparent";
1002 1002  
1003 - var rect=el.getBoundingClientRect();
993 + var shadow=
994 + s.boxShadow&&
995 + s.boxShadow!=="none";
1004 1004  
1005 - if(
1006 - rect.width<80||
1007 - rect.height<24
1008 - ){
1009 - return;
1010 - }
997 + return (
998 + namedLikeBox(el)||
999 + border>=1||
1000 + (bg&&radius>=3)||
1001 + (shadow&&r.width>=180)
1002 + );
1003 + }
1011 1011  
1012 - el.style.setProperty(
1013 - "border",
1014 - "none",
1015 - "important"
1016 - );
1005 + function pickTarget(child){
1006 + if(!visible(child,MIN_W,MIN_H))return null;
1017 1017  
1018 - el.style.setProperty(
1019 - "border-left",
1020 - "none",
1021 - "important"
1022 - );
1008 + if(boxLike(child))return child;
1023 1023  
1024 - el.style.setProperty(
1025 - "border-top",
1026 - "none",
1027 - "important"
1028 - );
1010 + var cr=child.getBoundingClientRect();
1011 + var q=[];
1029 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 - );
1013 + Array.from(child.children||[]).forEach(function(el){
1014 + q.push({el:el,depth:1});
1047 1047   });
1048 - }
1049 1049  
1050 - /* =======================================================
1051 - FULL-WIDTH THREE-LINE AREA LABELS
1052 - ======================================================= */
1017 + var best=null;
1018 + var bestScore=-Infinity;
1053 1053  
1054 - function compactText(value){
1055 - return String(value||"")
1056 - .replace(/\s+/g," ")
1057 - .trim();
1058 - }
1020 + while(q.length){
1021 + var item=q.shift();
1022 + 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 - }
1024 + if(!visible(el,MIN_W,MIN_H))continue;
1073 1073  
1074 - var number=
1075 - label.querySelector(
1076 - ":scope > .arsn-area-number"
1077 - );
1026 + 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 - !action
1029 + r.width>=cr.width*.68&&
1030 + boxLike(el)
1087 1087   ){
1088 - return;
1089 - }
1032 + var widthFit=
1033 + 1-Math.min(
1034 + 1,
1035 + Math.abs(cr.width-r.width)/
1036 + Math.max(1,cr.width)
1037 + );
1090 1090  
1091 - var clone=
1092 - label.cloneNode(true);
1039 + var topFit=
1040 + 1-Math.min(
1041 + 1,
1042 + Math.abs(cr.top-r.top)/100
1043 + );
1093 1093  
1094 - var cloneNumber=
1095 - clone.querySelector(
1096 - ":scope > .arsn-area-number"
1097 - );
1045 + var score=
1046 + widthFit*6+
1047 + topFit*3+
1048 + Math.min(r.height,900)/450+
1049 + Math.min(r.width*r.height,900000)/900000;
1098 1098  
1099 - var cloneAction=
1100 - clone.querySelector(
1101 - ":scope > .arsn-area-action"
1102 - );
1103 -
1104 - if(cloneNumber){
1105 - cloneNumber.remove();
1051 + if(score>bestScore){
1052 + best=el;
1053 + bestScore=score;
1054 + }
1106 1106   }
1107 1107  
1108 - if(cloneAction){
1109 - cloneAction.remove();
1057 + if(item.depth<SEARCH_DEPTH){
1058 + Array.from(el.children||[]).forEach(function(next){
1059 + q.push({
1060 + el:next,
1061 + depth:item.depth+1
1062 + });
1063 + });
1110 1110   }
1065 + }
1111 1111  
1112 - var titleText=
1113 - compactText(
1114 - clone.textContent
1115 - );
1067 + return best;
1068 + }
1116 1116  
1117 - if(!titleText){
1118 - return;
1119 - }
1070 + function groupRows(entries){
1071 + 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"
1073 + entries
1074 + .slice()
1075 + .sort(function(a,b){
1076 + return (
1077 + a.rect.top-b.rect.top||
1078 + a.rect.left-b.rect.left
1130 1130   );
1080 + })
1081 + .forEach(function(entry){
1082 + var group=null;
1131 1131  
1132 - titleNode.className=
1133 - "sn-area-label-title";
1084 + for(var i=0;i<groups.length;i++){
1085 + if(
1086 + Math.abs(
1087 + groups[i].top-
1088 + entry.rect.top
1089 + )<=ROW_TOLERANCE
1090 + ){
1091 + group=groups[i];
1092 + break;
1093 + }
1094 + }
1134 1134  
1135 - titleNode.textContent=
1136 - titleText;
1096 + if(!group){
1097 + group={
1098 + top:entry.rect.top,
1099 + entries:[]
1100 + };
1101 + groups.push(group);
1102 + }
1137 1137  
1138 - while(label.firstChild){
1139 - label.removeChild(
1140 - label.firstChild
1141 - );
1142 - }
1104 + group.entries.push(entry);
1105 + });
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 - });
1107 + return groups;
1186 1186   }
1187 1187  
1188 - /* =======================================================
1189 - PLACEHOLDER BADGE
1190 - ======================================================= */
1110 + function validRow(group){
1111 + if(group.entries.length<2)return false;
1191 1191  
1192 - function applyPlaceholderBadge(){
1193 - if(!PLACEHOLDER)return;
1113 + var lefts=
1114 + group.entries
1115 + .map(function(e){return e.rect.left;})
1116 + .sort(function(a,b){return a-b;});
1194 1194  
1195 1195   if(
1196 - document.querySelector(
1197 - ".sn-coming-soon-badge"
1198 - )
1119 + lefts[lefts.length-1]-
1120 + lefts[0]<
1121 + 80
1199 1199   ){
1200 - return;
1123 + return false;
1201 1201   }
1202 1202  
1203 - var title=
1204 - document.querySelector(
1205 - "#document-title"
1206 - )||
1207 - document.querySelector(
1208 - "h1"
1209 - );
1126 + var widths=
1127 + group.entries
1128 + .map(function(e){return e.rect.width;})
1129 + .filter(function(w){return w>0;});
1210 1210  
1211 - if(!title)return;
1131 + if(widths.length<2)return false;
1212 1212  
1213 - var badge=
1214 - document.createElement(
1215 - "span"
1216 - );
1133 + var minW=
1134 + Math.min.apply(Math,widths);
1217 1217  
1218 - badge.className=
1219 - "sn-coming-soon-badge";
1136 + var maxW=
1137 + Math.max.apply(Math,widths);
1220 1220  
1221 - badge.textContent=
1222 - PLACEHOLDER_LABEL;
1223 -
1224 - badge.setAttribute(
1225 - "aria-label",
1226 - PLACEHOLDER_LABEL
1139 + return (
1140 + maxW/
1141 + Math.max(1,minW)<=
1142 + 1.9
1227 1227   );
1228 -
1229 - title.appendChild(
1230 - badge
1231 - );
1232 1232   }
1233 1233  
1234 - /* =======================================================
1235 - DETAIL PAGE OWN-ACCENT PROPAGATION
1236 - ======================================================= */
1146 + /* ---------- Known ARSN first section bars ---------- */
1237 1237  
1238 - function parseRGB(value){
1239 - var match=String(value||"").match(
1240 - /rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)/i
1241 - );
1148 + function knownBar(el){
1149 + var text=
1150 + normalizeText(
1151 + el.textContent
1152 + );
1242 1242  
1243 - if(!match)return null;
1244 -
1245 - return [
1246 - Number(match[1]),
1247 - Number(match[2]),
1248 - Number(match[3])
1249 - ];
1250 - }
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)
1154 + return (
1155 + text==="HIER STARTEN"||
1156 + text==="ORGANISIEREN & DOKUMENTIEREN"||
1157 + text==="ENTSCHEIDEN"||
1158 + text==="START HERE"||
1159 + text==="GET STARTED"||
1160 + text==="ORGANISE & DOCUMENT"||
1161 + text==="ORGANIZE & DOCUMENT"||
1162 + text==="DECIDE"
1257 1257   );
1258 1258   }
1259 1259  
1260 - function paletteMatch(cssColor){
1261 - var rgb=parseRGB(cssColor);
1166 + function findKnownBar(card){
1167 + var cardRect=
1168 + card.getBoundingClientRect();
1262 1262  
1263 - if(!rgb)return null;
1170 + var rows=
1171 + Array.from(
1172 + card.querySelectorAll(
1173 + "div,p,span,strong,h3,h4,h5,h6"
1174 + )
1175 + )
1176 + .filter(function(el){
1177 + if(!visible(el,20,6))return false;
1178 + if(!knownBar(el))return false;
1264 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 - ];
1180 + var r=el.getBoundingClientRect();
1271 1271  
1272 - var best=null;
1273 - var bestDistance=Infinity;
1182 + var rel=
1183 + r.top-
1184 + cardRect.top;
1274 1274  
1275 - palette.forEach(function(item){
1276 - var d=distance(rgb,item.rgb);
1186 + return (
1187 + rel>=35&&
1188 + rel<=
1189 + cardRect.height*.75
1190 + );
1191 + })
1192 + .sort(function(a,b){
1193 + return (
1194 + a.getBoundingClientRect().top-
1195 + b.getBoundingClientRect().top
1196 + );
1197 + });
1277 1277  
1278 - if(d<bestDistance){
1279 - best=item;
1280 - bestDistance=d;
1281 - }
1282 - });
1283 -
1284 - return bestDistance<=30
1285 - ?best
1286 - :null;
1199 + return rows[0]||null;
1287 1287   }
1288 1288  
1289 - function propagateDetailAccents(){
1290 - if(PAGE_KIND!=="detail")return;
1202 + function alignKnownBars(cards){
1203 + var rows=
1204 + cards.map(function(card){
1205 + var bar=
1206 + findKnownBar(card);
1291 1291  
1292 - Array.from(
1293 - root.querySelectorAll(
1294 - ".arsn-call,.dmp-call,.ido-call,.pp-call,"+
1295 - ".arsn-source,.dmp-source,.ido-source,.pp-source"
1296 - )
1297 - ).forEach(function(el){
1298 - if(!visible(el))return;
1208 + if(!bar)return null;
1299 1299  
1300 - var style=getComputedStyle(el);
1210 + var cr=
1211 + card.getBoundingClientRect();
1301 1301  
1302 - if(
1303 - num(style.borderTopWidth)>=2
1304 - ){
1305 - var match=
1306 - paletteMatch(
1307 - style.borderTopColor
1308 - );
1213 + var br=
1214 + bar.getBoundingClientRect();
1309 1309  
1310 - if(match){
1311 - el.style.setProperty(
1312 - "border-left",
1313 - "4px solid "+match.hex,
1314 - "important"
1315 - );
1316 - }
1317 - }
1318 - });
1216 + return {
1217 + bar:bar,
1218 + relativeTop:
1219 + br.top-
1220 + cr.top
1221 + };
1222 + });
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;
1224 + if(
1225 + rows.some(function(row){
1226 + return !row;
1227 + })
1228 + ){
1229 + return false;
1230 + }
1328 1328  
1329 - el.style.setProperty(
1330 - "border-left",
1331 - "4px solid #e94b13",
1332 - "important"
1232 + var target=
1233 + Math.max.apply(
1234 + Math,
1235 + rows.map(function(row){
1236 + return row.relativeTop;
1237 + })
1333 1333   );
1334 - });
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;
1240 + rows.forEach(function(row){
1241 + var delta=
1242 + target-
1243 + row.relativeTop;
1343 1343  
1344 - el.style.setProperty(
1345 - "border-left",
1346 - "4px solid #21b6d7",
1347 - "important"
1245 + if(delta<=1)return;
1246 +
1247 + saveOriginal(
1248 + row.bar,
1249 + originalMarginTop,
1250 + "margin-top"
1348 1348   );
1349 - });
1350 - }
1351 1351  
1352 - /* =======================================================
1353 - OVERVIEW SEMANTIC THEME PALETTE
1354 - ======================================================= */
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;
1364 -
1365 - return !Array.from(
1366 - el.children||[]
1367 - ).some(function(child){
1368 - return !!themeFor(
1369 - child.textContent
1253 + var current=
1254 + num(
1255 + getComputedStyle(
1256 + row.bar
1257 + ).marginTop
1370 1370   );
1371 - });
1372 - });
1373 - }
1374 1374  
1375 - function findOverviewCard(header){
1376 - var node=header.parentElement;
1377 - var candidates=[];
1260 + row.bar.style.setProperty(
1261 + "margin-top",
1262 + (
1263 + current+
1264 + delta
1265 + )+"px"
1266 + );
1378 1378  
1379 - while(node&&node!==root){
1380 - var rect=node.getBoundingClientRect();
1381 - var style=getComputedStyle(node);
1268 + row.bar.setAttribute(
1269 + "data-sn-first-section-aligned",
1270 + "7"
1271 + );
1382 1382  
1383 - var border=
1384 - num(style.borderTopWidth)+
1385 - num(style.borderRightWidth)+
1386 - num(style.borderBottomWidth)+
1387 - num(style.borderLeftWidth);
1388 -
1389 - if(
1390 - rect.width>=220&&
1391 - rect.width<=800&&
1392 - rect.height>=120&&
1393 - border>=1
1394 - ){
1395 - candidates.push(node);
1396 - }
1397 -
1398 - node=node.parentElement;
1399 - }
1400 -
1401 - if(!candidates.length)return null;
1402 -
1403 - candidates.sort(function(a,b){
1404 - return (
1405 - b.getBoundingClientRect().height-
1406 - a.getBoundingClientRect().height
1273 + sectionManaged.add(
1274 + row.bar
1407 1407   );
1408 1408   });
1409 1409  
1410 - return candidates[0];
1278 + return true;
1411 1411   }
1412 1412  
1413 - function rowCandidates(link,card){
1414 - var result=[];
1415 - var cardRect=
1281 + /* ---------- Generic first content after heading ---------- */
1282 +
1283 + function heading(card){
1284 + var cr=
1416 1416   card.getBoundingClientRect();
1417 1417  
1418 - var node=link;
1287 + var rows=
1288 + Array.from(
1289 + card.querySelectorAll(
1290 + "h1,h2,h3,h4,h5,h6,.box-title,[role=heading]"
1291 + )
1292 + )
1293 + .filter(function(el){
1294 + if(!visible(el,20,8))return false;
1419 1419  
1420 - while(node&&node!==card){
1421 - if(visible(node)){
1422 - var rect=
1423 - node.getBoundingClientRect();
1296 + var r=el.getBoundingClientRect();
1424 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 - }
1434 - }
1298 + var rel=
1299 + r.top-
1300 + cr.top;
1435 1435  
1436 - node=node.parentElement;
1437 - }
1438 -
1439 - return result;
1440 - }
1441 -
1442 - function chooseOuterRow(
1443 - candidates,
1444 - link
1445 - ){
1446 - if(!candidates.length){
1447 - return link;
1448 - }
1449 -
1450 - var bordered=
1451 - candidates.filter(function(el){
1452 1452   return (
1453 - num(
1454 - getComputedStyle(el)
1455 - .borderLeftWidth
1456 - )>=1
1303 + rel>=0&&
1304 + rel<=
1305 + Math.min(
1306 + 160,
1307 + cr.height*.45
1308 + )
1457 1457   );
1310 + })
1311 + .sort(function(a,b){
1312 + return (
1313 + a.getBoundingClientRect().top-
1314 + b.getBoundingClientRect().top
1315 + );
1458 1458   });
1459 1459  
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;
1318 + return rows[0]||null;
1479 1479   }
1480 1480  
1481 - function applyOverviewPalette(){
1482 - if(PAGE_KIND!=="overview"){
1483 - return [];
1484 - }
1321 + function firstContent(card,h){
1322 + if(!h)return null;
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 - };
1500 - })
1501 - .filter(function(row){
1502 - return !!row.card;
1503 - });
1324 + var cr=
1325 + card.getBoundingClientRect();
1504 1504  
1505 - var unique=[];
1506 - var seenHeaders=new Set();
1327 + var hr=
1328 + h.getBoundingClientRect();
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 - );
1330 + var rows=
1331 + Array.from(
1332 + card.querySelectorAll(
1333 + "p,div,ul,ol,dl,blockquote"
1334 + )
1335 + )
1336 + .filter(function(el){
1337 + if(
1338 + el===h||
1339 + h.contains(el)||
1340 + el.contains(h)
1341 + ){
1342 + return false;
1343 + }
1523 1523  
1524 - if(!seenHeaders.has(key)){
1525 - seenHeaders.add(key);
1526 - unique.push(row);
1527 - }
1528 - });
1345 + if(!visible(el,30,8))return false;
1529 1529  
1530 - unique.forEach(function(row){
1531 - var headerRect=
1532 - row.el
1533 - .getBoundingClientRect();
1347 + var text=
1348 + String(el.textContent||"")
1349 + .replace(/\s+/g," ")
1350 + .trim();
1534 1534  
1535 - row.el.style.setProperty(
1536 - "background",
1537 - row.theme.bg,
1538 - "important"
1539 - );
1352 + if(text.length<3)return false;
1540 1540  
1541 - row.el.style.setProperty(
1542 - "color",
1543 - row.theme.text,
1544 - "important"
1545 - );
1354 + var r=el.getBoundingClientRect();
1546 1546  
1547 - row.el.style.setProperty(
1548 - "text-align",
1549 - "left",
1550 - "important"
1551 - );
1356 + if(
1357 + r.top<
1358 + hr.bottom-1
1359 + ){
1360 + return false;
1361 + }
1552 1552  
1553 - row.el.style.setProperty(
1554 - "word-spacing",
1555 - "normal",
1556 - "important"
1557 - );
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 1591   if(
1592 - link.classList &&
1593 - link.classList.contains(
1594 - "arsn-phase-cta"
1364 + r.top-cr.top>
1365 + Math.min(
1366 + 280,
1367 + cr.height*.65
1595 1595   )
1596 1596   ){
1597 - return;
1370 + return false;
1598 1598   }
1599 1599  
1600 - if(!visible(link))return;
1601 -
1602 - var rect=
1603 - link.getBoundingClientRect();
1604 -
1605 1605   if(
1606 - rect.top<=
1607 - headerRect.bottom-2||
1608 - rect.top>=
1609 - stopTop-2
1374 + r.height>
1375 + cr.height*.58
1610 1610   ){
1611 - return;
1377 + return false;
1612 1612   }
1613 1613  
1614 - var candidates=
1615 - rowCandidates(
1616 - link,
1617 - row.card
1618 - );
1380 + return true;
1381 + })
1382 + .sort(function(a,b){
1383 + var ar=
1384 + a.getBoundingClientRect();
1619 1619  
1620 - var target=
1621 - chooseOuterRow(
1622 - candidates,
1623 - link
1624 - );
1386 + var br=
1387 + b.getBoundingClientRect();
1625 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"
1389 + return (
1390 + ar.top-br.top||
1391 + ar.height-br.height
1639 1639   );
1640 -
1641 - target.style.setProperty(
1642 - "box-sizing",
1643 - "border-box",
1644 - "important"
1645 - );
1646 1646   });
1647 - });
1648 1648  
1649 - return unique;
1395 + return rows[0]||null;
1650 1650   }
1651 1651  
1652 - /* =======================================================
1653 - OVERVIEW CARD HEIGHT + FIRST THEMATIC ROW
1654 - ======================================================= */
1398 + function alignGeneric(cards){
1399 + var rows=
1400 + cards.map(function(card){
1401 + var h=
1402 + heading(card);
1655 1655  
1656 - function alignOverviewCards(headers){
1657 - if(
1658 - PAGE_KIND!=="overview"||
1659 - window.innerWidth<=MOBILE_MAX
1660 - ){
1661 - return;
1662 - }
1404 + var c=
1405 + firstContent(
1406 + card,
1407 + h
1408 + );
1663 1663  
1664 - var cards=[];
1665 - var seen=new Set();
1410 + if(!h||!c)return null;
1666 1666  
1667 - headers.forEach(function(row){
1668 - if(!seen.has(row.card)){
1669 - seen.add(row.card);
1670 - cards.push(row.card);
1671 - }
1672 - });
1412 + var cr=
1413 + card.getBoundingClientRect();
1673 1673  
1674 - if(cards.length<2){
1675 - return;
1676 - }
1415 + var rr=
1416 + c.getBoundingClientRect();
1677 1677  
1678 - // Group cards by actual top position.
1679 - var groups=[];
1418 + return {
1419 + content:c,
1420 + relativeTop:
1421 + rr.top-cr.top
1422 + };
1423 + });
1680 1680  
1681 - cards.forEach(function(card){
1682 - var top=
1683 - card.getBoundingClientRect().top;
1425 + if(
1426 + rows.some(function(row){
1427 + return !row;
1428 + })
1429 + ){
1430 + return false;
1431 + }
1684 1684  
1685 - var group=null;
1433 + var target=
1434 + Math.max.apply(
1435 + Math,
1436 + rows.map(function(row){
1437 + return row.relativeTop;
1438 + })
1439 + );
1686 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 - }
1441 + rows.forEach(function(row){
1442 + var delta=
1443 + target-
1444 + row.relativeTop;
1697 1697  
1698 - if(!group){
1699 - group={
1700 - top:top,
1701 - cards:[]
1702 - };
1703 - groups.push(group);
1704 - }
1446 + if(delta<=1)return;
1705 1705  
1706 - group.cards.push(card);
1707 - });
1448 + saveOriginal(
1449 + row.content,
1450 + originalMarginTop,
1451 + "margin-top"
1452 + );
1708 1708  
1709 - groups.forEach(function(group){
1710 - if(group.cards.length<2){
1711 - return;
1712 - }
1454 + var current=
1455 + num(
1456 + getComputedStyle(
1457 + row.content
1458 + ).marginTop
1459 + );
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 - });
1461 + row.content.style.setProperty(
1462 + "margin-top",
1463 + (
1464 + current+
1465 + delta
1466 + )+"px"
1467 + );
1731 1731  
1732 - return candidates.length
1733 - ?candidates[0]
1734 - :null;
1735 - });
1469 + row.content.setAttribute(
1470 + "data-sn-first-content-aligned",
1471 + "7"
1472 + );
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 - );
1474 + contentManaged.add(
1475 + row.content
1476 + );
1477 + });
1756 1756  
1757 - firstHeaders.forEach(function(row){
1758 - var relativeTop=
1759 - row.el
1760 - .getBoundingClientRect()
1761 - .top-
1762 - row.card
1763 - .getBoundingClientRect()
1764 - .top;
1479 + return true;
1480 + }
1765 1765  
1766 - var delta=
1767 - targetTop-relativeTop;
1482 + function applyRow(group){
1483 + if(!validRow(group))return false;
1768 1768  
1769 - if(delta>1){
1770 - saveStyle(
1771 - row.el,
1772 - originalMargin,
1773 - "margin-top"
1774 - );
1485 + var cards=[];
1486 + var seen=new Set();
1775 1775  
1776 - var current=
1777 - num(
1778 - getComputedStyle(
1779 - row.el
1780 - ).marginTop
1781 - );
1488 + group.entries.forEach(function(entry){
1489 + if(!seen.has(entry.target)){
1490 + seen.add(entry.target);
1491 + cards.push(entry.target);
1492 + }
1493 + });
1782 1782  
1783 - row.el.style.setProperty(
1784 - "margin-top",
1785 - (
1786 - current+delta
1787 - )+"px"
1788 - );
1495 + if(cards.length<2)return false;
1789 1789  
1790 - row.el.setAttribute(
1791 - "data-sn-master-first-row",
1792 - "1"
1793 - );
1497 + if(
1498 + !alignKnownBars(cards)
1499 + ){
1500 + alignGeneric(cards);
1501 + }
1794 1794  
1795 - managedMargin.add(
1796 - row.el
1797 - );
1798 - }
1799 - });
1800 - }
1503 + var maxHeight=0;
1801 1801  
1802 - var maxHeight=0;
1505 + cards.forEach(function(card){
1506 + maxHeight=
1507 + Math.max(
1508 + maxHeight,
1509 + card.getBoundingClientRect().height
1510 + );
1511 + });
1803 1803  
1804 - group.cards.forEach(function(card){
1805 - maxHeight=
1806 - Math.max(
1807 - maxHeight,
1808 - card
1809 - .getBoundingClientRect()
1810 - .height
1811 - );
1812 - });
1513 + maxHeight=
1514 + Math.ceil(
1515 + maxHeight
1516 + );
1813 1813  
1814 - maxHeight=
1815 - Math.ceil(maxHeight);
1518 + if(maxHeight<MIN_H)return false;
1816 1816  
1817 - group.cards.forEach(function(card){
1818 - saveStyle(
1819 - card,
1820 - originalHeight,
1821 - "min-height"
1822 - );
1520 + cards.forEach(function(card){
1521 + saveOriginal(
1522 + card,
1523 + originalMinHeight,
1524 + "min-height"
1525 + );
1823 1823  
1824 - card.style.setProperty(
1825 - "min-height",
1826 - maxHeight+"px"
1827 - );
1527 + card.style.setProperty(
1528 + "min-height",
1529 + maxHeight+"px"
1530 + );
1828 1828  
1829 - card.setAttribute(
1830 - "data-sn-master-equal-height",
1831 - "1"
1832 - );
1532 + card.setAttribute(
1533 + "data-sn-equal-height-managed",
1534 + "7"
1535 + );
1833 1833  
1834 - managedHeight.add(
1835 - card
1836 - );
1837 - });
1537 + heightManaged.add(card);
1838 1838   });
1539 +
1540 + return true;
1839 1839   }
1840 1840  
1841 - /* =======================================================
1842 - DETAIL GRID EQUAL HEIGHT, DESKTOP ONLY
1843 - ======================================================= */
1543 + function calculate(force){
1544 + if(applying)return;
1844 1844  
1845 - function equaliseDetailGrids(){
1546 + var width=
1547 + Math.round(
1548 + window.innerWidth
1549 + );
1550 +
1551 + var meaningful=
1552 + lastWidth<0||
1553 + Math.abs(
1554 + width-
1555 + lastWidth
1556 + )>=
1557 + MIN_WIDTH_CHANGE;
1558 +
1846 1846   if(
1847 - PAGE_KIND!=="detail"||
1848 - window.innerWidth<=MOBILE_MAX
1560 + hasApplied&&
1561 + !force&&
1562 + !meaningful
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 - ];
1567 + applying=true;
1861 1861  
1862 - selectors.forEach(function(selector){
1863 - Array.from(
1864 - root.querySelectorAll(selector)
1865 - ).forEach(function(grid){
1866 - var children=
1867 - Array.from(
1868 - grid.children||[]
1869 - ).filter(visible);
1569 + try{
1570 + harmoniseCustomCallouts();
1870 1870  
1871 - if(children.length<2){
1872 - return;
1572 + if(width<=MOBILE_MAX){
1573 + if(hasApplied){
1574 + resetRuntime();
1873 1873   }
1874 1874  
1875 - var groups=[];
1577 + hasApplied=false;
1578 + lastWidth=width;
1579 + return;
1580 + }
1876 1876  
1877 - children.forEach(function(child){
1878 - var top=
1879 - child
1880 - .getBoundingClientRect()
1881 - .top;
1582 + if(hasApplied){
1583 + resetRuntime();
1584 + }
1882 1882  
1883 - var group=null;
1586 + var parents=
1587 + Array.from(
1588 + root.querySelectorAll("*")
1589 + )
1590 + .filter(function(parent){
1591 + return (
1592 + visible(
1593 + parent,
1594 + MIN_W,
1595 + MIN_H
1596 + )&&
1597 + parent.children&&
1598 + parent.children.length>=2&&
1599 + parent.children.length<=
1600 + MAX_PARENT_CHILDREN
1601 + );
1602 + });
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 - }
1604 + var touched=
1605 + new Set();
1895 1895  
1896 - if(!group){
1897 - group={
1898 - top:top,
1899 - items:[]
1900 - };
1901 - groups.push(group);
1902 - }
1607 + parents.forEach(function(parent){
1608 + var entries=[];
1903 1903  
1904 - group.items.push(child);
1905 - });
1906 -
1907 - groups.forEach(function(group){
1908 - if(group.items.length<2){
1610 + Array.from(
1611 + parent.children
1612 + ).forEach(function(child){
1613 + if(
1614 + !visible(
1615 + child,
1616 + MIN_W,
1617 + MIN_H
1618 + )
1619 + ){
1909 1909   return;
1910 1910   }
1911 1911  
1912 - var maxHeight=0;
1623 + var target=
1624 + pickTarget(child);
1913 1913  
1914 - group.items.forEach(function(item){
1915 - maxHeight=
1916 - Math.max(
1917 - maxHeight,
1918 - item
1919 - .getBoundingClientRect()
1920 - .height
1921 - );
1626 + if(!target)return;
1627 +
1628 + entries.push({
1629 + target:target,
1630 + rect:
1631 + target.getBoundingClientRect()
1922 1922   });
1633 + });
1923 1923  
1924 - maxHeight=
1925 - Math.ceil(maxHeight);
1635 + groupRows(
1636 + entries
1637 + ).forEach(function(group){
1638 + if(!validRow(group))return;
1926 1926  
1927 - group.items.forEach(function(item){
1928 - saveStyle(
1929 - item,
1930 - originalHeight,
1931 - "min-height"
1932 - );
1640 + var targets=
1641 + group.entries.map(function(entry){
1642 + return entry.target;
1643 + });
1933 1933  
1934 - item.style.setProperty(
1935 - "min-height",
1936 - maxHeight+"px"
1937 - );
1645 + if(
1646 + !targets.some(function(el){
1647 + return !touched.has(el);
1648 + })
1649 + ){
1650 + return;
1651 + }
1938 1938  
1939 - item.setAttribute(
1940 - "data-sn-master-equal-height",
1941 - "1"
1942 - );
1943 -
1944 - managedHeight.add(item);
1945 - });
1653 + if(applyRow(group)){
1654 + targets.forEach(function(el){
1655 + touched.add(el);
1656 + });
1657 + }
1946 1946   });
1947 1947   });
1948 - });
1949 - }
1950 1950  
1951 - /* =======================================================
1952 - RUN / RESPONSIVE SCHEDULING
1953 - ======================================================= */
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 - }
1661 + lastWidth=width;
1662 + hasApplied=true;
1981 1981   }finally{
1982 - running=false;
1664 + applying=false;
1983 1983   }
1984 1984   }
1985 1985  
1986 - function onResize(){
1668 + function resize(){
1987 1987   if(resizeTimer){
1988 1988   clearTimeout(
1989 1989   resizeTimer
... ... @@ -1994,40 +1994,19 @@
1994 1994   setTimeout(
1995 1995   function(){
1996 1996   resizeTimer=0;
1997 - run();
1679 + calculate(false);
1998 1998   },
1999 1999   RESIZE_DEBOUNCE
2000 2000   );
2001 2001   }
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 - });
2014 - }
2015 -
2016 - if(
2017 - document.fonts&&
2018 - document.fonts.ready
2019 - ){
2020 - try{
2021 - await document.fonts.ready;
2022 - }catch(error){}
2023 - }
2024 -
1685 + function waitImages(){
2025 2025   var images=
2026 2026   Array.from(
2027 2027   root.querySelectorAll("img")
2028 2028   );
2029 2029  
2030 - await Promise.all(
1691 + return Promise.all(
2031 2031   images.map(function(img){
2032 2032   if(img.complete){
2033 2033   return Promise.resolve();
... ... @@ -2052,83 +2052,46 @@
2052 2052   });
2053 2053   })
2054 2054   );
1716 + }
2055 2055  
2056 - run();
1718 + async function initial(){
1719 + if(
1720 + document.readyState!==
1721 + "complete"
1722 + ){
1723 + await new Promise(function(resolve){
1724 + addEventListener(
1725 + "load",
1726 + resolve,
1727 + {once:true}
1728 + );
1729 + });
1730 + }
1731 +
1732 + if(
1733 + document.fonts&&
1734 + document.fonts.ready
1735 + ){
1736 + try{
1737 + await document.fonts.ready;
1738 + }catch(error){}
1739 + }
1740 +
1741 + await waitImages();
1742 +
1743 + // Exactly one initial layout calculation.
1744 + calculate(true);
2057 2057   }
2058 2058  
2059 - window.addEventListener(
1747 + addEventListener(
2060 2060   "resize",
2061 - onResize,
1749 + resize,
2062 2062   {passive:true}
2063 2063   );
2064 2064  
2065 - waitForReady();
1753 + initial();
2066 2066  })();
2067 2067  </script>
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}}
1757 +<!-- SN_HORIZONTAL_BOX_HARMONIZER_END -->
1758 +{{/html}}\n