Changes for page Project Planning & Organisation
Last modified by Veronika Kocher on Friday, 04 Sep 2026 14:45
From version 9.4
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 9.10
edited by Veronika Kocher
on Friday, 04 Sep 2026 14:45
on Friday, 04 Sep 2026 14:45
Change comment:
There is no comment for this version
Summary
-
Page properties (1 modified, 0 added, 0 removed)
Details
- Page properties
-
- Content
-
... ... @@ -52,13 +52,12 @@ 52 52 } 53 53 </style> 54 54 55 - 56 56 <div class="pp"> 57 57 58 58 <section class="card" style="margin-bottom:18px;overflow:hidden;border-left:6px solid #e94b13;"> 59 59 <div class="hero"><img src="https://xwiki.uni-ak.ac.at/bin/download/Service%20Navigator/Art%20%26%20Research%20Services%20Navigator/WebHome/enable.png" alt="Planning and organising an artistic or research project"></div> 60 60 <div style="padding:18px 21px 20px"> 61 -<div class="eye" style="color:#8a4d36;margin-bottom:5px">E NABLE · PROJECT PLANNING & ORGANISATION</div>60 +<div class="eye" style="color:#8a4d36;margin-bottom:5px">PREPARE · PROJECT PLANNING & ORGANISATION</div> 62 62 <h2 style="font-size:27px;line-height:1.2;margin:0 0 8px;color:#2c2926">Build a project that can actually be hosted, funded, staffed and delivered</h2> 63 63 <p style="margin:0;color:#5e5953;line-height:1.6;max-width:1120px">Project planning at the Angewandte is not only a timeline and a budget. A workable project needs an artistic or research home, clear responsibilities, an appropriate funding and administrative route, and early coordination with the university structures triggered by your project.</p> 64 64 </div></section> ... ... @@ -97,7 +97,6 @@ 97 97 </div> 98 98 </section> 99 99 100 - 101 101 <section class="sec"> 102 102 <div class="eye" style="color:#8a4d36;margin-bottom:4px">EXAMPLES · HOW RESEARCH IS SITUATED AT THE ANGEWANDTE</div> 103 103 <h3>Use existing projects to understand possible research profiles and institutional homes</h3> ... ... @@ -415,6 +415,31 @@ 415 415 416 416 <div class="info" style="margin-bottom:14px"><strong>Need help structuring the project?</strong> For funded, artistic, scientific and arts-based research projects, Support Kunst und Forschung is a central coordination point. Bring a short project description, host unit, likely applicant, partners, duration, rough budget and the main things you need from the University.</div> 417 417 416 +<!-- ARSN_TRAINING_WORKSHOPS_V2_START --> 417 +<section class="arsn-training-workshops" data-arsn-training-workshops="v2" style="margin:27px 0 22px 0;"> 418 + <div style="padding:16px 18px;background:#eef8fa;border:1px solid #cfe8ef;border-left:5px solid #21b6d7;border-radius:9px;"> 419 + <div style="font-size:12px;font-weight:700;letter-spacing:.075em;text-transform:uppercase;color:#3f6871;margin-bottom:5px;">TRAINING & WORKSHOPS</div> 420 + <h3 style="font-size:20px;line-height:1.3;margin:0 0 7px;color:#35312d;text-align:left;">Training, workshops & consultation sessions</h3> 421 + <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> 422 + <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> 423 + </div> 424 +</section> 425 +<!-- ARSN_TRAINING_WORKSHOPS_V2_END --> 426 + 427 +<!-- ARSN_PRACTICAL_RESOURCES_V2_START --> 428 +<section class="arsn-practical-resources" data-arsn-practical-resources="v2" style="margin:0 0 27px;"> 429 + <div style="font-size:12px;font-weight:700;letter-spacing:.075em;text-transform:uppercase;color:#8a4d36;margin-bottom:4px;">USEFUL MATERIALS</div> 430 + <h3 style="font-size:22px;line-height:1.25;margin:0 0 8px;color:#35312d;text-align:left;">Practical Resources</h3> 431 + <p style="margin:0 0 12px;color:#5e5953;line-height:1.55;">Use practical resources when you need a concise overview, a step-by-step procedure or a ready-to-use project aid.</p> 432 + <div class="arsn-resource-grid" style="display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;"> 433 + <div style="padding:15px 16px;background:#fcfbf8;border:1px solid #e3ded6;border-top:3px solid #21b6d7;border-radius:9px;"><strong>Info Sheets</strong><br><span data-arsn-coming-soon="true" style="display:inline-block;margin:6px 0 8px;padding:4px 9px;border-radius:14px;background:#fff4ee;border:1px solid #efd9cc;color:#8a4d36;font-size:11px;font-weight:700;letter-spacing:.065em;">COMING SOON</span><div style="color:#625d56;line-height:1.45;">Short reference guides for common questions and decisions.</div></div> 434 + <div style="padding:15px 16px;background:#fcfbf8;border:1px solid #e3ded6;border-top:3px solid #e94b13;border-radius:9px;"><strong>Tutorials</strong><br><span data-arsn-coming-soon="true" style="display:inline-block;margin:6px 0 8px;padding:4px 9px;border-radius:14px;background:#fff4ee;border:1px solid #efd9cc;color:#8a4d36;font-size:11px;font-weight:700;letter-spacing:.065em;">COMING SOON</span><div style="color:#625d56;line-height:1.45;">Step-by-step guidance for specific tasks and workflows.</div></div> 435 + <div style="padding:15px 16px;background:#fcfbf8;border:1px solid #e3ded6;border-top:3px solid #38b76a;border-radius:9px;"><strong>Checklists & Templates</strong><br><span data-arsn-coming-soon="true" style="display:inline-block;margin:6px 0 8px;padding:4px 9px;border-radius:14px;background:#fff4ee;border:1px solid #efd9cc;color:#8a4d36;font-size:11px;font-weight:700;letter-spacing:.065em;">COMING SOON</span><div style="color:#625d56;line-height:1.45;">Ready-to-use checklists and templates for planning, managing and closing projects.</div></div> 436 + </div> 437 + <style>@media(max-width:767px){.arsn-resource-grid{grid-template-columns:1fr!important}}</style> 438 +</section> 439 +<!-- ARSN_PRACTICAL_RESOURCES_V2_END --> 440 + 418 418 <!-- ARSN_SEARCH_TERMS_START --> 419 419 <details style="margin-top:24px;padding-top:10px;border-top:1px solid #e3ded6"> 420 420 <summary style="cursor:pointer;color:#6a655e;font-size:13px">Search terms & related topics</summary> ... ... @@ -426,23 +426,132 @@ 426 426 {{/html}} 427 427 428 428 {{html clean="false"}} 429 -<!-- SN_HORIZONTAL_BOX_HARMONIZER_START --> 430 -<style data-sn-horizontal-box-harmonizer="4"> 431 -[data-sn-equal-height-managed], 432 -[data-sn-first-section-aligned]{ 452 +<!-- SN_SERVICE_NAVIGATOR_MASTER_STYLE_START --> 453 + 454 +<style data-sn-service-navigator-master="1"> 455 +/* ========================================================= 456 + MASTER TYPOGRAPHY 457 + ========================================================= */ 458 +#xwikicontent h1, 459 +#xwikicontent h2, 460 +#xwikicontent h3, 461 +#xwikicontent h4, 462 +#xwikicontent h5, 463 +#xwikicontent h6, 464 +#xwikicontent .box-title, 465 +#xwikicontent [role="heading"], 466 +#xwikicontent h1 a, 467 +#xwikicontent h2 a, 468 +#xwikicontent h3 a, 469 +#xwikicontent h4 a, 470 +#xwikicontent h5 a, 471 +#xwikicontent h6 a, 472 +#xwikicontent .box-title a, 473 +#xwikicontent [role="heading"] a{ 474 + text-align:left!important; 475 + text-justify:auto!important; 476 + word-spacing:normal!important; 477 +} 478 + 479 +/* ========================================================= 480 + COMING SOON / IN VORBEREITUNG 481 + ========================================================= */ 482 +.sn-coming-soon-badge{ 483 + display:inline-block; 484 + vertical-align:middle; 485 + margin-left:10px; 486 + padding:4px 8px; 487 + border-radius:14px; 488 + border:1px solid #efd9cc; 489 + background:#fff4ee; 490 + color:#8a4d36; 491 + font-size:11px; 492 + font-weight:700; 493 + letter-spacing:.055em; 494 + line-height:1.2; 495 + white-space:nowrap; 496 +} 497 + 498 +/* ========================================================= 499 + NATIVE / DETAIL CALLOUT GEOMETRY 500 + Preserve existing backgrounds. 501 + ========================================================= */ 502 +#xwikicontent .arsn-info, 503 +#xwikicontent .dmp-info, 504 +#xwikicontent .ido-info, 505 +#xwikicontent .pp-info, 506 +#xwikicontent .infomessage{ 507 + box-sizing:border-box!important; 508 + border-left:4px solid #21b6d7!important; 509 + border-radius:8px; 510 + text-align:left!important; 511 + word-spacing:normal!important; 512 +} 513 + 514 +#xwikicontent .arsn-warn, 515 +#xwikicontent .dmp-warn, 516 +#xwikicontent .ido-warn, 517 +#xwikicontent .pp-warn, 518 +#xwikicontent .warn, 519 +#xwikicontent .warning, 520 +#xwikicontent .warningmessage, 521 +#xwikicontent .errormessage{ 522 + box-sizing:border-box!important; 523 + border-left:4px solid #e94b13!important; 524 + border-radius:8px; 525 + text-align:left!important; 526 + word-spacing:normal!important; 527 +} 528 + 529 +[data-sn-master-equal-height], 530 +[data-sn-master-first-row]{ 433 433 box-sizing:border-box; 434 434 } 533 + 534 +/* ========================================================= 535 + FULL-WIDTH THREE-LINE NUMBER / TITLE / SUBTITLE BLOCKS 536 + ========================================================= */ 537 +#xwikicontent .arsn-area-label[data-sn-three-line="1"]{ 538 + display:grid!important; 539 + grid-template-columns:minmax(0,1fr)!important; 540 + grid-auto-rows:auto!important; 541 + width:100%!important; 542 + max-width:none!important; 543 + box-sizing:border-box!important; 544 + justify-items:start!important; 545 + align-items:start!important; 546 + gap:2px!important; 547 + text-align:left!important; 548 + text-align-last:left!important; 549 + text-justify:auto!important; 550 + word-spacing:normal!important; 551 + white-space:normal!important; 552 +} 553 +#xwikicontent .arsn-area-label[data-sn-three-line="1"] > .arsn-area-number, 554 +#xwikicontent .arsn-area-label[data-sn-three-line="1"] > .sn-area-label-title, 555 +#xwikicontent .arsn-area-label[data-sn-three-line="1"] > .arsn-area-action{ 556 + display:block!important; 557 + width:100%!important; 558 + margin:0!important; 559 + text-align:left!important; 560 + text-align-last:left!important; 561 + text-justify:auto!important; 562 + word-spacing:normal!important; 563 + white-space:normal!important; 564 +} 435 435 </style> 436 -<script data-sn-horizontal-box-harmonizer="4"> 566 + 567 +<script data-sn-service-navigator-master="1"> 437 437 (function(){ 438 438 "use strict"; 439 439 571 + var PAGE_KIND="detail"; 572 + var PLACEHOLDER=false; 573 + var PLACEHOLDER_LABEL="COMING SOON"; 574 + 440 440 var MOBILE_MAX=767; 441 441 var ROW_TOLERANCE=6; 442 - var MIN_W=150; 443 - var MIN_H=36; 444 - var MAX_PARENT_CHILDREN=16; 445 - var SEARCH_DEPTH=5; 577 + var RESIZE_DEBOUNCE=220; 446 446 447 447 var root= 448 448 document.getElementById("xwikicontent")|| ... ... @@ -452,93 +452,105 @@ 452 452 453 453 if(!root)return; 454 454 455 - var heightManaged=new Set(); 456 - var sectionManaged=new Set(); 457 - var originalMinHeight=new WeakMap(); 458 - var originalMarginTop=new WeakMap(); 459 - var raf=0; 587 + var managedHeight=new Set(); 588 + var managedMargin=new Set(); 589 + var originalHeight=new WeakMap(); 590 + var originalMargin=new WeakMap(); 460 460 461 - function num(v){ 462 - var n=parseFloat(v); 463 - return Number.isFinite(n)?n:0; 464 - } 592 + var resizeTimer=0; 593 + var running=false; 465 465 466 - function visible(el,minW,minH){ 467 - if(!el||el.nodeType!==1)return false; 468 - 469 - var s=getComputedStyle(el); 470 - 471 - if( 472 - s.display==="none"|| 473 - s.visibility==="hidden"|| 474 - Number(s.opacity)===0 475 - ){ 476 - return false; 595 + var THEMES=[ 596 + { 597 + name:"BLUE", 598 + accent:"#21b6d7", 599 + bg:"#eaf7fb", 600 + text:"#315d68", 601 + labels:[ 602 + "HIER STARTEN", 603 + "ENTSCHEIDEN", 604 + "ÜBERPRÜFEN & ANPASSEN", 605 + "START HERE", 606 + "DECIDE", 607 + "REVIEW & ADAPT" 608 + ] 609 + }, 610 + { 611 + name:"RED", 612 + accent:"#e94b13", 613 + bg:"#fff1ec", 614 + text:"#8a4d36", 615 + labels:[ 616 + "PLANEN & ORGANISIEREN", 617 + "ORGANISIEREN & DOKUMENTIEREN", 618 + "PUBLIZIEREN & PRÄSENTIEREN", 619 + "PLAN & ORGANISE", 620 + "PLAN & ORGANIZE", 621 + "ORGANISE & DOCUMENT", 622 + "ORGANIZE & DOCUMENT", 623 + "PUBLISH & PRESENT" 624 + ] 625 + }, 626 + { 627 + name:"YELLOW", 628 + accent:"#f0aa00", 629 + bg:"#fff8e7", 630 + text:"#785b17", 631 + labels:[ 632 + "SCHÜTZEN & KLÄREN", 633 + "STANDARDISIEREN & IDENTIFIZIEREN", 634 + "ÖFFNEN, NACHNUTZEN & AUFFINDBAR MACHEN", 635 + "PROTECT & CLARIFY", 636 + "STANDARDISE & IDENTIFY", 637 + "STANDARDIZE & IDENTIFY", 638 + "OPEN, REUSE & MAKE FINDABLE" 639 + ] 640 + }, 641 + { 642 + name:"GREEN", 643 + accent:"#38b76a", 644 + bg:"#edf9f1", 645 + text:"#3f7451", 646 + labels:[ 647 + "INFRASTRUKTUR EINRICHTEN", 648 + "INFRASTRUKTUR & ZUSAMMENARBEIT EINRICHTEN", 649 + "SPEICHERN & ZUGRIFF STEUERN", 650 + "REPOSITORIUM, ERHALTEN & ÜBERGEBEN", 651 + "SET UP INFRASTRUCTURE", 652 + "SET UP INFRASTRUCTURE & COLLABORATION", 653 + "STORE & CONTROL ACCESS", 654 + "REPOSITORY, PRESERVE & HAND OVER" 655 + ] 477 477 } 657 + ]; 478 478 479 - var r=el.getBoundingClientRect(); 480 - 481 - return ( 482 - r.width>=(minW||1)&& 483 - r.height>=(minH||1) 484 - ); 659 + function num(value){ 660 + var n=parseFloat(value); 661 + return Number.isFinite(n)?n:0; 485 485 } 486 486 487 - function excluded(el){ 488 - return ( 489 - !el.matches|| 490 - el.matches( 491 - "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]" 492 - ) 493 - ); 664 + function norm(value){ 665 + return String(value||"") 666 + .replace(/\s+/g," ") 667 + .trim() 668 + .toUpperCase(); 494 494 } 495 495 496 - function namedLikeBox(el){ 497 - var c= 498 - typeof el.className==="string" 499 - ? el.className 500 - : ""; 671 + function visible(el){ 672 + if(!el||el.nodeType!==1)return false; 501 501 502 - r eturn/(^|[s_-])(box|card|tile|panel|role|check|service|source|call|area|detail|resource|topic|warn|info)([s_-]|$)/i.test(c);503 - }674 + var style=getComputedStyle(el); 675 + var rect=el.getBoundingClientRect(); 504 504 505 - function boxLike(el){ 506 - if(!visible(el,MIN_W,MIN_H)||excluded(el))return false; 507 - 508 - var s=getComputedStyle(el); 509 - var r=el.getBoundingClientRect(); 510 - 511 - var border= 512 - num(s.borderTopWidth)+ 513 - num(s.borderRightWidth)+ 514 - num(s.borderBottomWidth)+ 515 - num(s.borderLeftWidth); 516 - 517 - var radius=Math.max( 518 - num(s.borderTopLeftRadius), 519 - num(s.borderTopRightRadius), 520 - num(s.borderBottomLeftRadius), 521 - num(s.borderBottomRightRadius) 522 - ); 523 - 524 - var bg= 525 - s.backgroundColor&& 526 - s.backgroundColor!=="rgba(0, 0, 0, 0)"&& 527 - s.backgroundColor!=="transparent"; 528 - 529 - var shadow= 530 - s.boxShadow&& 531 - s.boxShadow!=="none"; 532 - 533 533 return ( 534 - namedLikeBox(el)||535 - b order>=1||536 - (bg&&radius>=3)||537 - (shadow&&r.width>=180)678 + style.display!=="none"&& 679 + style.visibility!=="hidden"&& 680 + rect.width>20&& 681 + rect.height>4 538 538 ); 539 539 } 540 540 541 - function save Original(el,map,property){685 + function saveStyle(el,map,property){ 542 542 if(map.has(el))return; 543 543 544 544 map.set(el,{ ... ... @@ -547,7 +547,7 @@ 547 547 }); 548 548 } 549 549 550 - function restore Original(el,map,property){694 + function restoreStyle(el,map,property){ 551 551 var original=map.get(el); 552 552 553 553 if(original&&original.value){ ... ... @@ -561,247 +561,470 @@ 561 561 } 562 562 } 563 563 564 - function reset(){ 565 - heightManaged.forEach(function(el){566 - restore Original(708 + function resetRuntime(){ 709 + managedHeight.forEach(function(el){ 710 + restoreStyle( 567 567 el, 568 - original MinHeight,712 + originalHeight, 569 569 "min-height" 570 570 ); 571 - 572 572 el.removeAttribute( 573 - "data-sn-equal-height -managed"716 + "data-sn-master-equal-height" 574 574 ); 575 575 }); 576 576 577 - sectionManaged.forEach(function(el){578 - restore Original(720 + managedMargin.forEach(function(el){ 721 + restoreStyle( 579 579 el, 580 - originalMargin Top,723 + originalMargin, 581 581 "margin-top" 582 582 ); 583 - 584 584 el.removeAttribute( 585 - "data-sn-first- section-aligned"727 + "data-sn-master-first-row" 586 586 ); 587 587 }); 588 588 589 - heightManaged.clear();590 - sectionManaged.clear();731 + managedHeight.clear(); 732 + managedMargin.clear(); 591 591 } 592 592 593 - function pickTarget(child){594 - if(!visible(child,MIN_W,MIN_H))return null;735 + function themeFor(text){ 736 + var value=norm(text); 595 595 596 - if(boxLike(child)){ 597 - return child; 738 + for(var i=0;i<THEMES.length;i++){ 739 + for(var j=0;j<THEMES[i].labels.length;j++){ 740 + var label=THEMES[i].labels[j]; 741 + 742 + if( 743 + value===label|| 744 + value.indexOf(label+" ")===0|| 745 + value.indexOf(label+" -")===0|| 746 + value.indexOf(label+" ·")===0 747 + ){ 748 + return THEMES[i]; 749 + } 750 + } 598 598 } 599 599 600 - varcr=child.getBoundingClientRect();601 - var q=[];753 + return null; 754 + } 602 602 603 - Array.from(child.children||[]).forEach(function(el){ 604 - q.push({el:el,depth:1}); 756 + /* ======================================================= 757 + BORDERLESS FILLED RED/ORANGE CTA BUTTONS 758 + ======================================================= */ 759 + 760 + function colourDistance(a,b){ 761 + return Math.sqrt( 762 + Math.pow(a[0]-b[0],2)+ 763 + Math.pow(a[1]-b[1],2)+ 764 + Math.pow(a[2]-b[2],2) 765 + ); 766 + } 767 + 768 + function makeFilledRedOrangeCTAsBorderless(){ 769 + var RED_ORANGE=[233,75,19]; 770 + 771 + Array.from( 772 + root.querySelectorAll( 773 + 'a,button,[role="button"],input[type="submit"],input[type="button"]' 774 + ) 775 + ).forEach(function(el){ 776 + if(!visible(el))return; 777 + 778 + var style=getComputedStyle(el); 779 + var rgb=parseRGB(style.backgroundColor); 780 + 781 + if(!rgb)return; 782 + 783 + if( 784 + colourDistance( 785 + rgb, 786 + RED_ORANGE 787 + )>55 788 + ){ 789 + return; 790 + } 791 + 792 + var rect=el.getBoundingClientRect(); 793 + 794 + if( 795 + rect.width<80|| 796 + rect.height<24 797 + ){ 798 + return; 799 + } 800 + 801 + el.style.setProperty( 802 + "border", 803 + "none", 804 + "important" 805 + ); 806 + 807 + el.style.setProperty( 808 + "border-left", 809 + "none", 810 + "important" 811 + ); 812 + 813 + el.style.setProperty( 814 + "border-top", 815 + "none", 816 + "important" 817 + ); 818 + 819 + el.style.setProperty( 820 + "border-right", 821 + "none", 822 + "important" 823 + ); 824 + 825 + el.style.setProperty( 826 + "border-bottom", 827 + "none", 828 + "important" 829 + ); 830 + 831 + el.style.setProperty( 832 + "box-shadow", 833 + "none", 834 + "important" 835 + ); 605 605 }); 837 + } 606 606 607 - var best=null; 608 - var bestScore=-Infinity; 839 + /* ======================================================= 840 + FULL-WIDTH THREE-LINE AREA LABELS 841 + ======================================================= */ 609 609 610 - while(q.length){ 611 - var item=q.shift(); 612 - var el=item.el; 843 + function compactText(value){ 844 + return String(value||"") 845 + .replace(/\s+/g," ") 846 + .trim(); 847 + } 613 613 614 - if(!visible(el,MIN_W,MIN_H))continue; 849 + function makeThreeLineAreaLabels(){ 850 + Array.from( 851 + root.querySelectorAll( 852 + ".arsn-area-label" 853 + ) 854 + ).forEach(function(label){ 855 + if( 856 + label.getAttribute( 857 + "data-sn-three-line" 858 + )==="1" 859 + ){ 860 + return; 861 + } 615 615 616 - var r=el.getBoundingClientRect(); 863 + var number= 864 + label.querySelector( 865 + ":scope > .arsn-area-number" 866 + ); 617 617 868 + var action= 869 + label.querySelector( 870 + ":scope > .arsn-area-action" 871 + ); 872 + 618 618 if( 619 - r .width>=cr.width*.68&&620 - boxLike(el)874 + !number|| 875 + !action 621 621 ){ 622 - var widthFit= 623 - 1-Math.min( 624 - 1, 625 - Math.abs(cr.width-r.width)/ 626 - Math.max(1,cr.width) 627 - ); 877 + return; 878 + } 628 628 629 - var topFit= 630 - 1-Math.min( 631 - 1, 632 - Math.abs(cr.top-r.top)/100 633 - ); 880 + var clone= 881 + label.cloneNode(true); 634 634 635 - var score= 636 - widthFit*6+ 637 - topFit*3+ 638 - Math.min(r.height,900)/450+ 639 - Math.min(r.width*r.height,900000)/900000; 883 + var cloneNumber= 884 + clone.querySelector( 885 + ":scope > .arsn-area-number" 886 + ); 640 640 641 - if(score>bestScore){ 642 - best=el; 643 - bestScore=score; 644 - } 888 + var cloneAction= 889 + clone.querySelector( 890 + ":scope > .arsn-area-action" 891 + ); 892 + 893 + if(cloneNumber){ 894 + cloneNumber.remove(); 645 645 } 646 646 647 - if(item.depth<SEARCH_DEPTH){ 648 - Array.from(el.children||[]).forEach(function(next){ 649 - q.push({ 650 - el:next, 651 - depth:item.depth+1 652 - }); 653 - }); 897 + if(cloneAction){ 898 + cloneAction.remove(); 654 654 } 655 - } 656 656 657 - return best; 658 - } 901 + var titleText= 902 + compactText( 903 + clone.textContent 904 + ); 659 659 660 - function groupsByVisualRow(entries){ 661 - var groups=[]; 906 + if(!titleText){ 907 + return; 908 + } 662 662 663 - entries 664 - .slice() 665 - .sort(function(a,b){ 666 - return ( 667 - a.rect.top-b.rect.top|| 668 - a.rect.left-b.rect.left 910 + var numberNode= 911 + number.cloneNode(true); 912 + 913 + var actionNode= 914 + action.cloneNode(true); 915 + 916 + var titleNode= 917 + document.createElement( 918 + "span" 669 669 ); 670 - }) 671 - .forEach(function(entry){ 672 - var group=null; 673 673 674 - for(var i=0;i<groups.length;i++){ 675 - if( 676 - Math.abs( 677 - groups[i].top- 678 - entry.rect.top 679 - )<=ROW_TOLERANCE 680 - ){ 681 - group=groups[i]; 682 - break; 683 - } 684 - } 921 + titleNode.className= 922 + "sn-area-label-title"; 685 685 686 - if(!group){ 687 - group={ 688 - top:entry.rect.top, 689 - entries:[] 690 - }; 691 - groups.push(group); 692 - } 924 + titleNode.textContent= 925 + titleText; 693 693 694 - group.entries.push(entry); 695 - }); 927 + while(label.firstChild){ 928 + label.removeChild( 929 + label.firstChild 930 + ); 931 + } 696 696 697 - return groups; 933 + label.appendChild( 934 + numberNode 935 + ); 936 + 937 + label.appendChild( 938 + titleNode 939 + ); 940 + 941 + label.appendChild( 942 + actionNode 943 + ); 944 + 945 + label.setAttribute( 946 + "data-sn-three-line", 947 + "1" 948 + ); 949 + 950 + var head= 951 + label.closest( 952 + ".arsn-area-head" 953 + ); 954 + 955 + if(head){ 956 + head.style.setProperty( 957 + "width", 958 + "100%", 959 + "important" 960 + ); 961 + 962 + head.style.setProperty( 963 + "max-width", 964 + "100%", 965 + "important" 966 + ); 967 + 968 + head.style.setProperty( 969 + "box-sizing", 970 + "border-box", 971 + "important" 972 + ); 973 + } 974 + }); 698 698 } 699 699 700 - function validHorizontalGroup(group){ 701 - if(group.entries.length<2)return false; 977 + /* ======================================================= 978 + PLACEHOLDER BADGE 979 + ======================================================= */ 702 702 703 - var lefts= 704 - group.entries 705 - .map(function(e){return e.rect.left;}) 706 - .sort(function(a,b){return a-b;}); 981 + function applyPlaceholderBadge(){ 982 + if(!PLACEHOLDER)return; 707 707 708 708 if( 709 - lefts[lefts.length-1]-710 - lefts[0]<711 - 80985 + document.querySelector( 986 + ".sn-coming-soon-badge" 987 + ) 712 712 ){ 713 - return false;989 + return; 714 714 } 715 715 716 - var widths= 717 - group.entries 718 - .map(function(e){return e.rect.width;}) 719 - .filter(function(w){return w>0;}); 992 + var title= 993 + document.querySelector( 994 + "#document-title" 995 + )|| 996 + document.querySelector( 997 + "h1" 998 + ); 720 720 721 - if( widths.length<2)returnfalse;1000 + if(!title)return; 722 722 723 - var minWidth=Math.min.apply(Math,widths); 724 - var maxWidth=Math.max.apply(Math,widths); 1002 + var badge= 1003 + document.createElement( 1004 + "span" 1005 + ); 725 725 726 - return ( 727 - maxWidth/ 728 - Math.max(1,minWidth)<= 729 - 1.9 1007 + badge.className= 1008 + "sn-coming-soon-badge"; 1009 + 1010 + badge.textContent= 1011 + PLACEHOLDER_LABEL; 1012 + 1013 + badge.setAttribute( 1014 + "aria-label", 1015 + PLACEHOLDER_LABEL 730 730 ); 731 - } 732 732 733 - function normalizeText(text){ 734 - return String(text||"") 735 - .replace(/s+/g," ") 736 - .trim() 737 - .toUpperCase(); 1018 + title.appendChild( 1019 + badge 1020 + ); 738 738 } 739 739 740 - function exactKnownFirstSection(el){ 741 - var text=normalizeText(el.textContent); 1023 + /* ======================================================= 1024 + DETAIL PAGE OWN-ACCENT PROPAGATION 1025 + ======================================================= */ 742 742 743 - return ( 744 - text==="HIER STARTEN"|| 745 - text==="ORGANISIEREN & DOKUMENTIEREN"|| 746 - text==="ENTSCHEIDEN"|| 747 - text==="START HERE"|| 748 - text==="GET STARTED"|| 749 - text==="ORGANISE & DOCUMENT"|| 750 - text==="ORGANIZE & DOCUMENT"|| 751 - text==="DECIDE" 1027 + function parseRGB(value){ 1028 + var match=String(value||"").match( 1029 + /rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)/i 752 752 ); 1031 + 1032 + if(!match)return null; 1033 + 1034 + return [ 1035 + Number(match[1]), 1036 + Number(match[2]), 1037 + Number(match[3]) 1038 + ]; 753 753 } 754 754 755 - function visuallyFirstSectionBar(card){ 756 - var cardRect=card.getBoundingClientRect(); 757 - var candidates=[]; 1041 + function distance(a,b){ 1042 + return Math.sqrt( 1043 + Math.pow(a[0]-b[0],2)+ 1044 + Math.pow(a[1]-b[1],2)+ 1045 + Math.pow(a[2]-b[2],2) 1046 + ); 1047 + } 758 758 1049 + function paletteMatch(cssColor){ 1050 + var rgb=parseRGB(cssColor); 1051 + 1052 + if(!rgb)return null; 1053 + 1054 + var palette=[ 1055 + {hex:"#21b6d7",rgb:[33,182,215]}, 1056 + {hex:"#e94b13",rgb:[233,75,19]}, 1057 + {hex:"#f0aa00",rgb:[240,170,0]}, 1058 + {hex:"#38b76a",rgb:[56,183,106]} 1059 + ]; 1060 + 1061 + var best=null; 1062 + var bestDistance=Infinity; 1063 + 1064 + palette.forEach(function(item){ 1065 + var d=distance(rgb,item.rgb); 1066 + 1067 + if(d<bestDistance){ 1068 + best=item; 1069 + bestDistance=d; 1070 + } 1071 + }); 1072 + 1073 + return bestDistance<=30 1074 + ?best 1075 + :null; 1076 + } 1077 + 1078 + function propagateDetailAccents(){ 1079 + if(PAGE_KIND!=="detail")return; 1080 + 759 759 Array.from( 760 - card.querySelectorAll( 761 - "div,p,span,strong,h3,h4,h5,h6" 1082 + root.querySelectorAll( 1083 + ".arsn-call,.dmp-call,.ido-call,.pp-call,"+ 1084 + ".arsn-source,.dmp-source,.ido-source,.pp-source" 762 762 ) 763 763 ).forEach(function(el){ 764 - if(!visible(el,20,6))return; 765 - if(excluded(el))return; 1087 + if(!visible(el))return; 766 766 767 - var r=el.getBoundingClientRect(); 768 - var relativeTop=r.top-cardRect.top; 1089 + var style=getComputedStyle(el); 769 769 770 770 if( 771 - relativeTop<45|| 772 - relativeTop>cardRect.height*.72 1092 + num(style.borderTopWidth)>=2 773 773 ){ 774 - return; 1094 + var match= 1095 + paletteMatch( 1096 + style.borderTopColor 1097 + ); 1098 + 1099 + if(match){ 1100 + el.style.setProperty( 1101 + "border-left", 1102 + "4px solid "+match.hex, 1103 + "important" 1104 + ); 1105 + } 775 775 } 1107 + }); 776 776 777 - var widthRatio= 778 - r.width/ 779 - Math.max(1,cardRect.width); 1109 + // Warning families: explicit safety override. 1110 + Array.from( 1111 + root.querySelectorAll( 1112 + ".arsn-warn,.dmp-warn,.ido-warn,.pp-warn,"+ 1113 + ".warn,.warning,.warningmessage,.errormessage" 1114 + ) 1115 + ).forEach(function(el){ 1116 + if(!visible(el))return; 780 780 781 - if( 782 - widthRatio<.55|| 783 - widthRatio>1.05|| 784 - r.height>54 785 - ){ 786 - return; 787 - } 1118 + el.style.setProperty( 1119 + "border-left", 1120 + "4px solid #e94b13", 1121 + "important" 1122 + ); 1123 + }); 788 788 789 - var text=normalizeText(el.textContent); 1125 + // Info families: explicit orientation override. 1126 + Array.from( 1127 + root.querySelectorAll( 1128 + ".arsn-info,.dmp-info,.ido-info,.pp-info,.infomessage" 1129 + ) 1130 + ).forEach(function(el){ 1131 + if(!visible(el))return; 790 790 791 - if( 792 - text.length<2|| 793 - text.length>90 794 - ){ 795 - return; 796 - } 1133 + el.style.setProperty( 1134 + "border-left", 1135 + "4px solid #21b6d7", 1136 + "important" 1137 + ); 1138 + }); 1139 + } 797 797 798 - var style=getComputedStyle(el); 1141 + /* ======================================================= 1142 + OVERVIEW SEMANTIC THEME PALETTE 1143 + ======================================================= */ 799 799 800 - var bg= 801 - style.backgroundColor&& 802 - style.backgroundColor!=="rgba(0, 0, 0, 0)"&& 803 - style.backgroundColor!=="transparent"; 1145 + function smallestThemeHeaders(){ 1146 + return Array.from( 1147 + root.querySelectorAll( 1148 + "div,span,p,strong,h3,h4,h5,h6" 1149 + ) 1150 + ).filter(function(el){ 1151 + if(!visible(el))return false; 1152 + if(!themeFor(el.textContent))return false; 804 804 1154 + return !Array.from( 1155 + el.children||[] 1156 + ).some(function(child){ 1157 + return !!themeFor( 1158 + child.textContent 1159 + ); 1160 + }); 1161 + }); 1162 + } 1163 + 1164 + function findOverviewCard(header){ 1165 + var node=header.parentElement; 1166 + var candidates=[]; 1167 + 1168 + while(node&&node!==root){ 1169 + var rect=node.getBoundingClientRect(); 1170 + var style=getComputedStyle(node); 1171 + 805 805 var border= 806 806 num(style.borderTopWidth)+ 807 807 num(style.borderRightWidth)+ ... ... @@ -808,315 +808,677 @@ 808 808 num(style.borderBottomWidth)+ 809 809 num(style.borderLeftWidth); 810 810 811 - var mostlyUpper= 812 - text.length>=3&& 813 - text===text.toUpperCase(); 814 - 815 - var exact=exactKnownFirstSection(el); 816 - 817 - var score= 818 - (exact?20:0)+ 819 - (bg?6:0)+ 820 - (border>=1?2:0)+ 821 - (mostlyUpper?4:0)+ 822 - (num(style.fontWeight)>=600?1:0); 823 - 824 - if(score>=7){ 825 - candidates.push({ 826 - el:el, 827 - relativeTop:relativeTop, 828 - width:r.width, 829 - score:score 830 - }); 1178 + if( 1179 + rect.width>=220&& 1180 + rect.width<=800&& 1181 + rect.height>=120&& 1182 + border>=1 1183 + ){ 1184 + candidates.push(node); 831 831 } 832 - }); 833 833 1187 + node=node.parentElement; 1188 + } 1189 + 834 834 if(!candidates.length)return null; 835 835 836 836 candidates.sort(function(a,b){ 837 - if(a.score!==b.score)return b.score-a.score; 838 - if(Math.abs(a.relativeTop-b.relativeTop)>3){ 839 - return a.relativeTop-b.relativeTop; 840 - } 841 - return b.width-a.width; 1193 + return ( 1194 + b.getBoundingClientRect().height- 1195 + a.getBoundingClientRect().height 1196 + ); 842 842 }); 843 843 844 - // For exact known labels always prefer the earliest exact match. 845 - var exacts=candidates.filter(function(c){ 846 - return exactKnownFirstSection(c.el); 847 - }); 1199 + return candidates[0]; 1200 + } 848 848 849 - if(exacts.length){ 850 - exacts.sort(function(a,b){ 851 - return a.relativeTop-b.relativeTop||b.width-a.width; 852 - }); 853 - return exacts[0].el; 854 - } 1202 + function rowCandidates(link,card){ 1203 + var result=[]; 1204 + var cardRect= 1205 + card.getBoundingClientRect(); 855 855 856 - // Generic fallback: earliest high-confidence bar. 857 - candidates.sort(function(a,b){ 858 - return a.relativeTop-b.relativeTop||b.score-a.score||b.width-a.width; 859 - }); 1207 + var node=link; 860 860 861 - return candidates[0].el; 862 - } 1209 + while(node&&node!==card){ 1210 + if(visible(node)){ 1211 + var rect= 1212 + node.getBoundingClientRect(); 863 863 864 - function alignFirstSections(cards){ 865 - var rows= 866 - cards.map(function(card){ 867 - var bar= 868 - visuallyFirstSectionBar(card); 1214 + if( 1215 + rect.height<=105&& 1216 + rect.width>= 1217 + cardRect.width*.50&& 1218 + rect.width<= 1219 + cardRect.width*1.03 1220 + ){ 1221 + result.push(node); 1222 + } 1223 + } 869 869 870 - if(!bar)return null; 1225 + node=node.parentElement; 1226 + } 871 871 872 - varcardRect=873 - card.getBoundingClientRect();1228 + return result; 1229 + } 874 874 875 - var barRect= 876 - bar.getBoundingClientRect(); 1231 + function chooseOuterRow( 1232 + candidates, 1233 + link 1234 + ){ 1235 + if(!candidates.length){ 1236 + return link; 1237 + } 877 877 878 - return {879 - card:card,880 - bar:bar,881 - relativeTop:882 - barRect.top-cardRect.top,883 - label:884 - normalizeText(bar.textContent)885 - };1239 + var bordered= 1240 + candidates.filter(function(el){ 1241 + return ( 1242 + num( 1243 + getComputedStyle(el) 1244 + .borderLeftWidth 1245 + )>=1 1246 + ); 886 886 }); 887 887 888 - // Conservative: only align when every card in the horizontal row 889 - // has a reliable first section bar. 890 - if( 891 - rows.some(function(row){ 892 - return !row; 893 - }) 894 - ){ 895 - return null; 1249 + var pool= 1250 + bordered.length 1251 + ?bordered 1252 + :candidates; 1253 + 1254 + pool.sort(function(a,b){ 1255 + var ar= 1256 + a.getBoundingClientRect(); 1257 + 1258 + var br= 1259 + b.getBoundingClientRect(); 1260 + 1261 + return ( 1262 + ar.left-br.left|| 1263 + br.width-ar.width 1264 + ); 1265 + }); 1266 + 1267 + return pool[0]||link; 1268 + } 1269 + 1270 + function applyOverviewPalette(){ 1271 + if(PAGE_KIND!=="overview"){ 1272 + return []; 896 896 } 897 897 898 - var targetTop= 899 - Math.max.apply( 900 - Math, 901 - rows.map(function(row){ 902 - return row.relativeTop; 1275 + var headers= 1276 + smallestThemeHeaders() 1277 + .map(function(el){ 1278 + return { 1279 + el:el, 1280 + theme: 1281 + themeFor( 1282 + el.textContent 1283 + ), 1284 + card: 1285 + findOverviewCard( 1286 + el 1287 + ) 1288 + }; 903 903 }) 904 - ); 1290 + .filter(function(row){ 1291 + return !!row.card; 1292 + }); 905 905 906 - rows.forEach(function(row){ 907 - var delta= 908 - targetTop- 909 - row.relativeTop; 1294 + var unique=[]; 1295 + var seenHeaders=new Set(); 910 910 911 - if(delta<=1)return; 1297 + headers.forEach(function(row){ 1298 + var key= 1299 + row.theme.name+ 1300 + "|"+ 1301 + Math.round( 1302 + row.card 1303 + .getBoundingClientRect() 1304 + .left 1305 + )+ 1306 + "|"+ 1307 + Math.round( 1308 + row.el 1309 + .getBoundingClientRect() 1310 + .top 1311 + ); 912 912 913 - saveOriginal( 914 - row.bar, 915 - originalMarginTop, 916 - "margin-top" 1313 + if(!seenHeaders.has(key)){ 1314 + seenHeaders.add(key); 1315 + unique.push(row); 1316 + } 1317 + }); 1318 + 1319 + unique.forEach(function(row){ 1320 + var headerRect= 1321 + row.el 1322 + .getBoundingClientRect(); 1323 + 1324 + row.el.style.setProperty( 1325 + "background", 1326 + row.theme.bg, 1327 + "important" 917 917 ); 918 918 919 - var currentMargin= 920 - num( 921 - getComputedStyle( 922 - row.bar 923 - ).marginTop 924 - ); 1330 + row.el.style.setProperty( 1331 + "color", 1332 + row.theme.text, 1333 + "important" 1334 + ); 925 925 926 - row.bar.style.setProperty( 927 - "margin-top", 928 - ( 929 - currentMargin+ 930 - delta 931 - )+"px" 1336 + row.el.style.setProperty( 1337 + "text-align", 1338 + "left", 1339 + "important" 932 932 ); 933 933 934 - row.bar.setAttribute( 935 - "data-sn-first-section-aligned", 936 - "4" 1342 + row.el.style.setProperty( 1343 + "word-spacing", 1344 + "normal", 1345 + "important" 937 937 ); 938 938 939 - sectionManaged.add(row.bar); 1348 + var later= 1349 + unique 1350 + .filter(function(other){ 1351 + return ( 1352 + other.card===row.card&& 1353 + other.el 1354 + .getBoundingClientRect() 1355 + .top> 1356 + headerRect.top+2 1357 + ); 1358 + }) 1359 + .sort(function(a,b){ 1360 + return ( 1361 + a.el 1362 + .getBoundingClientRect() 1363 + .top- 1364 + b.el 1365 + .getBoundingClientRect() 1366 + .top 1367 + ); 1368 + }); 1369 + 1370 + var stopTop= 1371 + later.length 1372 + ?later[0].el 1373 + .getBoundingClientRect() 1374 + .top 1375 + :Infinity; 1376 + 1377 + Array.from( 1378 + row.card.querySelectorAll("a") 1379 + ).forEach(function(link){ 1380 + if(!visible(link))return; 1381 + 1382 + var rect= 1383 + link.getBoundingClientRect(); 1384 + 1385 + if( 1386 + rect.top<= 1387 + headerRect.bottom-2|| 1388 + rect.top>= 1389 + stopTop-2 1390 + ){ 1391 + return; 1392 + } 1393 + 1394 + var candidates= 1395 + rowCandidates( 1396 + link, 1397 + row.card 1398 + ); 1399 + 1400 + var target= 1401 + chooseOuterRow( 1402 + candidates, 1403 + link 1404 + ); 1405 + 1406 + candidates.forEach(function(el){ 1407 + el.style.setProperty( 1408 + "border-left", 1409 + "0 solid transparent", 1410 + "important" 1411 + ); 1412 + }); 1413 + 1414 + target.style.setProperty( 1415 + "border-left", 1416 + "3px solid "+ 1417 + row.theme.accent, 1418 + "important" 1419 + ); 1420 + 1421 + target.style.setProperty( 1422 + "box-sizing", 1423 + "border-box", 1424 + "important" 1425 + ); 1426 + }); 940 940 }); 941 941 942 - return { 943 - labels: 944 - rows.map(function(row){ 945 - return row.label; 946 - }), 947 - targetRelativeTop: 948 - Math.round(targetTop) 949 - }; 1429 + return unique; 950 950 } 951 951 952 - function applyGroup(group){ 953 - if(!validHorizontalGroup(group)){ 954 - return null; 1432 + /* ======================================================= 1433 + OVERVIEW CARD HEIGHT + FIRST THEMATIC ROW 1434 + ======================================================= */ 1435 + 1436 + function alignOverviewCards(headers){ 1437 + if( 1438 + PAGE_KIND!=="overview"|| 1439 + window.innerWidth<=MOBILE_MAX 1440 + ){ 1441 + return; 955 955 } 956 956 957 957 var cards=[]; 958 958 var seen=new Set(); 959 959 960 - group.entries.forEach(function(entry){961 - if(!seen.has( entry.target)){962 - seen.add( entry.target);963 - cards.push( entry.target);1447 + headers.forEach(function(row){ 1448 + if(!seen.has(row.card)){ 1449 + seen.add(row.card); 1450 + cards.push(row.card); 964 964 } 965 965 }); 966 966 967 - if(cards.length<2)return null; 1454 + if(cards.length<2){ 1455 + return; 1456 + } 968 968 969 - varfirstSection=970 - alignFirstSections(cards);1458 + // Group cards by actual top position. 1459 + var groups=[]; 971 971 972 - // The section alignment can change natural card heights. 973 - // Measure only afterwards. 974 - var maxHeight=0; 975 - 976 976 cards.forEach(function(card){ 977 - maxHeight=Math.max( 978 - maxHeight, 979 - card.getBoundingClientRect().height 980 - ); 1462 + var top= 1463 + card.getBoundingClientRect().top; 1464 + 1465 + var group=null; 1466 + 1467 + for(var i=0;i<groups.length;i++){ 1468 + if( 1469 + Math.abs( 1470 + groups[i].top-top 1471 + )<=ROW_TOLERANCE 1472 + ){ 1473 + group=groups[i]; 1474 + break; 1475 + } 1476 + } 1477 + 1478 + if(!group){ 1479 + group={ 1480 + top:top, 1481 + cards:[] 1482 + }; 1483 + groups.push(group); 1484 + } 1485 + 1486 + group.cards.push(card); 981 981 }); 982 982 983 - maxHeight=Math.ceil(maxHeight); 1489 + groups.forEach(function(group){ 1490 + if(group.cards.length<2){ 1491 + return; 1492 + } 984 984 985 - if(maxHeight<MIN_H)return null; 1494 + var firstHeaders= 1495 + group.cards.map(function(card){ 1496 + var candidates= 1497 + headers 1498 + .filter(function(row){ 1499 + return row.card===card; 1500 + }) 1501 + .sort(function(a,b){ 1502 + return ( 1503 + a.el 1504 + .getBoundingClientRect() 1505 + .top- 1506 + b.el 1507 + .getBoundingClientRect() 1508 + .top 1509 + ); 1510 + }); 986 986 987 - cards.forEach(function(card){ 988 - saveOriginal( 989 - card, 990 - originalMinHeight, 991 - "min-height" 992 - ); 1512 + return candidates.length 1513 + ?candidates[0] 1514 + :null; 1515 + }); 993 993 994 - card.style.setProperty( 995 - "min-height", 996 - maxHeight+"px" 997 - ); 1517 + if( 1518 + !firstHeaders.some(function(row){ 1519 + return !row; 1520 + }) 1521 + ){ 1522 + var targetTop= 1523 + Math.max.apply( 1524 + Math, 1525 + firstHeaders.map(function(row){ 1526 + return ( 1527 + row.el 1528 + .getBoundingClientRect() 1529 + .top- 1530 + row.card 1531 + .getBoundingClientRect() 1532 + .top 1533 + ); 1534 + }) 1535 + ); 998 998 999 - card.setAttribute( 1000 - "data-sn-equal-height-managed", 1001 - "4" 1002 - ); 1537 + firstHeaders.forEach(function(row){ 1538 + var relativeTop= 1539 + row.el 1540 + .getBoundingClientRect() 1541 + .top- 1542 + row.card 1543 + .getBoundingClientRect() 1544 + .top; 1003 1003 1004 - heightManaged.add(card);1005 - });1546 + var delta= 1547 + targetTop-relativeTop; 1006 1006 1007 - return { 1008 - cards:cards.length, 1009 - height:maxHeight, 1010 - firstSection:firstSection 1011 - }; 1549 + if(delta>1){ 1550 + saveStyle( 1551 + row.el, 1552 + originalMargin, 1553 + "margin-top" 1554 + ); 1555 + 1556 + var current= 1557 + num( 1558 + getComputedStyle( 1559 + row.el 1560 + ).marginTop 1561 + ); 1562 + 1563 + row.el.style.setProperty( 1564 + "margin-top", 1565 + ( 1566 + current+delta 1567 + )+"px" 1568 + ); 1569 + 1570 + row.el.setAttribute( 1571 + "data-sn-master-first-row", 1572 + "1" 1573 + ); 1574 + 1575 + managedMargin.add( 1576 + row.el 1577 + ); 1578 + } 1579 + }); 1580 + } 1581 + 1582 + var maxHeight=0; 1583 + 1584 + group.cards.forEach(function(card){ 1585 + maxHeight= 1586 + Math.max( 1587 + maxHeight, 1588 + card 1589 + .getBoundingClientRect() 1590 + .height 1591 + ); 1592 + }); 1593 + 1594 + maxHeight= 1595 + Math.ceil(maxHeight); 1596 + 1597 + group.cards.forEach(function(card){ 1598 + saveStyle( 1599 + card, 1600 + originalHeight, 1601 + "min-height" 1602 + ); 1603 + 1604 + card.style.setProperty( 1605 + "min-height", 1606 + maxHeight+"px" 1607 + ); 1608 + 1609 + card.setAttribute( 1610 + "data-sn-master-equal-height", 1611 + "1" 1612 + ); 1613 + 1614 + managedHeight.add( 1615 + card 1616 + ); 1617 + }); 1618 + }); 1012 1012 } 1013 1013 1014 - function run(){ 1015 - reset(); 1621 + /* ======================================================= 1622 + DETAIL GRID EQUAL HEIGHT, DESKTOP ONLY 1623 + ======================================================= */ 1016 1016 1625 + function equaliseDetailGrids(){ 1017 1017 if( 1627 + PAGE_KIND!=="detail"|| 1018 1018 window.innerWidth<=MOBILE_MAX 1019 1019 ){ 1020 1020 return; 1021 1021 } 1022 1022 1023 - var parents= 1633 + var selectors=[ 1634 + ".arsn-grid", 1635 + ".arsn-grid-2", 1636 + ".arsn-grid-3", 1637 + ".dmp-grid", 1638 + ".ido-grid", 1639 + ".pp-grid" 1640 + ]; 1641 + 1642 + selectors.forEach(function(selector){ 1024 1024 Array.from( 1025 - root.querySelectorAll("*") 1026 - ).filter(function(parent){ 1027 - return ( 1028 - visible(parent,MIN_W,MIN_H)&& 1029 - parent.children&& 1030 - parent.children.length>=2&& 1031 - parent.children.length<=MAX_PARENT_CHILDREN 1032 - ); 1033 - }); 1644 + root.querySelectorAll(selector) 1645 + ).forEach(function(grid){ 1646 + var children= 1647 + Array.from( 1648 + grid.children||[] 1649 + ).filter(visible); 1034 1034 1035 - var touched=new Set(); 1651 + if(children.length<2){ 1652 + return; 1653 + } 1036 1036 1037 - parents.forEach(function(parent){ 1038 - var entries=[]; 1655 + var groups=[]; 1039 1039 1040 - Array.from(parent.children).forEach(function(child){ 1041 - if(!visible(child,MIN_W,MIN_H))return; 1657 + children.forEach(function(child){ 1658 + var top= 1659 + child 1660 + .getBoundingClientRect() 1661 + .top; 1042 1042 1043 - var target=pickTarget(child); 1044 - if(!target)return; 1663 + var group=null; 1045 1045 1046 - entries.push({ 1047 - target:target, 1048 - rect:target.getBoundingClientRect() 1665 + for(var i=0;i<groups.length;i++){ 1666 + if( 1667 + Math.abs( 1668 + groups[i].top-top 1669 + )<=ROW_TOLERANCE 1670 + ){ 1671 + group=groups[i]; 1672 + break; 1673 + } 1674 + } 1675 + 1676 + if(!group){ 1677 + group={ 1678 + top:top, 1679 + items:[] 1680 + }; 1681 + groups.push(group); 1682 + } 1683 + 1684 + group.items.push(child); 1049 1049 }); 1050 - }); 1051 1051 1052 - if(entries.length<2)return; 1687 + groups.forEach(function(group){ 1688 + if(group.items.length<2){ 1689 + return; 1690 + } 1053 1053 1054 - groupsByVisualRow(entries).forEach(function(group){ 1055 - if(!validHorizontalGroup(group))return; 1692 + var maxHeight=0; 1056 1056 1057 - var signature= 1058 - group.entries.map(function(entry){ 1059 - return entry.target; 1694 + group.items.forEach(function(item){ 1695 + maxHeight= 1696 + Math.max( 1697 + maxHeight, 1698 + item 1699 + .getBoundingClientRect() 1700 + .height 1701 + ); 1060 1060 }); 1061 1061 1062 - if( 1063 - !signature.some(function(el){ 1064 - return !touched.has(el); 1065 - }) 1066 - ){ 1067 - return; 1068 - } 1704 + maxHeight= 1705 + Math.ceil(maxHeight); 1069 1069 1070 - var applied= 1071 - applyGroup(group); 1707 + group.items.forEach(function(item){ 1708 + saveStyle( 1709 + item, 1710 + originalHeight, 1711 + "min-height" 1712 + ); 1072 1072 1073 - if(applied){ 1074 - signature.forEach(function(el){ 1075 - touched.add(el); 1714 + item.style.setProperty( 1715 + "min-height", 1716 + maxHeight+"px" 1717 + ); 1718 + 1719 + item.setAttribute( 1720 + "data-sn-master-equal-height", 1721 + "1" 1722 + ); 1723 + 1724 + managedHeight.add(item); 1076 1076 }); 1077 - } 1726 + }); 1078 1078 }); 1079 1079 }); 1080 1080 } 1081 1081 1082 - function schedule(){ 1083 - if(raf)cancelAnimationFrame(raf); 1731 + /* ======================================================= 1732 + RUN / RESPONSIVE SCHEDULING 1733 + ======================================================= */ 1084 1084 1085 - raf=requestAnimationFrame(function(){ 1086 - raf=requestAnimationFrame(function(){ 1087 - raf=0; 1088 - run(); 1089 - }); 1090 - }); 1735 + function run(){ 1736 + if(running)return; 1737 + 1738 + running=true; 1739 + 1740 + try{ 1741 + resetRuntime(); 1742 + applyPlaceholderBadge(); 1743 + propagateDetailAccents(); 1744 + 1745 + var headers= 1746 + applyOverviewPalette(); 1747 + 1748 + makeThreeLineAreaLabels(); 1749 + makeFilledRedOrangeCTAsBorderless(); 1750 + 1751 + if( 1752 + window.innerWidth> 1753 + MOBILE_MAX 1754 + ){ 1755 + alignOverviewCards( 1756 + headers 1757 + ); 1758 + 1759 + equaliseDetailGrids(); 1760 + } 1761 + }finally{ 1762 + running=false; 1763 + } 1091 1091 } 1092 1092 1093 - addEventListener("resize",schedule,{passive:true}); 1094 - addEventListener("load",schedule,{once:true}); 1766 + function onResize(){ 1767 + if(resizeTimer){ 1768 + clearTimeout( 1769 + resizeTimer 1770 + ); 1771 + } 1095 1095 1096 - root.addEventListener( 1097 - "click", 1098 - function(){ 1099 - setTimeout(schedule,0); 1100 - }, 1101 - true 1102 - ); 1773 + resizeTimer= 1774 + setTimeout( 1775 + function(){ 1776 + resizeTimer=0; 1777 + run(); 1778 + }, 1779 + RESIZE_DEBOUNCE 1780 + ); 1781 + } 1103 1103 1104 - Array.from(root.querySelectorAll("img")).forEach(function(img){ 1105 - if(!img.complete){ 1106 - img.addEventListener("load",schedule,{once:true}); 1783 + async function waitForReady(){ 1784 + if( 1785 + document.readyState!=="complete" 1786 + ){ 1787 + await new Promise(function(resolve){ 1788 + window.addEventListener( 1789 + "load", 1790 + resolve, 1791 + {once:true} 1792 + ); 1793 + }); 1107 1107 } 1108 - }); 1109 1109 1110 - if(document.fonts&&document.fonts.ready){ 1111 - document.fonts.ready.then(schedule); 1796 + if( 1797 + document.fonts&& 1798 + document.fonts.ready 1799 + ){ 1800 + try{ 1801 + await document.fonts.ready; 1802 + }catch(error){} 1803 + } 1804 + 1805 + var images= 1806 + Array.from( 1807 + root.querySelectorAll("img") 1808 + ); 1809 + 1810 + await Promise.all( 1811 + images.map(function(img){ 1812 + if(img.complete){ 1813 + return Promise.resolve(); 1814 + } 1815 + 1816 + return new Promise(function(resolve){ 1817 + var done=function(){ 1818 + resolve(); 1819 + }; 1820 + 1821 + img.addEventListener( 1822 + "load", 1823 + done, 1824 + {once:true} 1825 + ); 1826 + 1827 + img.addEventListener( 1828 + "error", 1829 + done, 1830 + {once:true} 1831 + ); 1832 + }); 1833 + }) 1834 + ); 1835 + 1836 + run(); 1112 1112 } 1113 1113 1114 - schedule(); 1115 - setTimeout(schedule,200); 1116 - setTimeout(schedule,650); 1117 - setTimeout(schedule,1400); 1839 + window.addEventListener( 1840 + "resize", 1841 + onResize, 1842 + {passive:true} 1843 + ); 1844 + 1845 + waitForReady(); 1118 1118 })(); 1119 1119 </script> 1120 -<!-- SN_HORIZONTAL_BOX_HARMONIZER_END --> 1848 + 1849 +<!-- SN_SERVICE_NAVIGATOR_MASTER_STYLE_END --> 1121 1121 {{/html}} 1122 1122