Changes for page Plan Your Data Management
Last modified by Veronika Kocher on Friday, 04 Sep 2026 14:45
From version 4.10
edited by Veronika Kocher
on Thursday, 03 Sep 2026 10:09
on Thursday, 03 Sep 2026 10:09
Change comment:
There is no comment for this version
To version 4.12
edited by Veronika Kocher
on Thursday, 03 Sep 2026 14:15
on Thursday, 03 Sep 2026 14:15
Change comment:
There is no comment for this version
Summary
-
Page properties (1 modified, 0 added, 0 removed)
Details
- Page properties
-
- Content
-
... ... @@ -257,12 +257,13 @@ 257 257 </div> 258 258 {{/html}} 259 259 260 -\n\n 261 -\n\n{{html clean="false"}} 262 -<!-- SN_HORIZONTAL_BOX_HARMONIZER_START --> 260 +{{html clean="false"}} 261 +<!-- SN_SERVICE_NAVIGATOR_MASTER_STYLE_START --> 263 263 264 -<style data-sn-horizontal-box-harmonizer="7"> 265 -/* ---------- Typography: never justify headings ---------- */ 263 +<style data-sn-service-navigator-master="1"> 264 +/* ========================================================= 265 + MASTER TYPOGRAPHY 266 + ========================================================= */ 266 266 #xwikicontent h1, 267 267 #xwikicontent h2, 268 268 #xwikicontent h3, ... ... @@ -284,88 +284,105 @@ 284 284 word-spacing:normal!important; 285 285 } 286 286 287 -/* ---------- Native XWiki semantic callouts ---------- */ 288 -#xwikicontent .box.infomessage, 289 -#xwikicontent .infomessage, 290 -#xwikicontent .box.warningmessage, 291 -#xwikicontent .warningmessage, 292 -#xwikicontent .box.successmessage, 293 -#xwikicontent .successmessage, 294 -#xwikicontent .box.errormessage, 295 -#xwikicontent .errormessage, 296 -#xwikicontent [data-sn-callout-harmonized="1"]{ 288 +/* ========================================================= 289 + COMING SOON / IN VORBEREITUNG 290 + ========================================================= */ 291 +.sn-coming-soon-badge{ 292 + display:inline-block; 293 + vertical-align:middle; 294 + margin-left:10px; 295 + padding:4px 8px; 296 + border-radius:14px; 297 + border:1px solid #efd9cc; 298 + background:#fff4ee; 299 + color:#8a4d36; 300 + font-size:11px; 301 + font-weight:700; 302 + letter-spacing:.055em; 303 + line-height:1.2; 304 + white-space:nowrap; 305 +} 306 + 307 +/* ========================================================= 308 + NATIVE / DETAIL CALLOUT GEOMETRY 309 + Preserve existing backgrounds. 310 + ========================================================= */ 311 +#xwikicontent .arsn-info, 312 +#xwikicontent .dmp-info, 313 +#xwikicontent .ido-info, 314 +#xwikicontent .pp-info, 315 +#xwikicontent .infomessage{ 297 297 box-sizing:border-box!important; 298 - border-radius:8px!important; 299 - border-top:1px solid rgba(0,0,0,.08)!important; 300 - border-right:1px solid rgba(0,0,0,.08)!important; 301 - border-bottom:1px solid rgba(0,0,0,.08)!important; 302 - border-left:4px solid var(--sn-callout-accent,#21b6d7)!important; 303 - padding:14px 16px!important; 317 + border-left:4px solid #21b6d7!important; 318 + border-radius:8px; 304 304 text-align:left!important; 305 - text-justify:auto!important; 306 306 word-spacing:normal!important; 307 - box-shadow:none!important; 308 308 } 309 309 310 -#xwikicontent .box.infomessage, 311 -#xwikicontent .infomessage{ 312 - --sn-callout-accent:#21b6d7; 313 - background:#eaf7fb!important; 314 -} 315 - 316 -#xwikicontent .box.warningmessage, 317 -#xwikicontent .warningmessage{ 318 - --sn-callout-accent:#f0aa00; 319 - background:#fff8e7!important; 320 -} 321 - 322 -#xwikicontent .box.successmessage, 323 -#xwikicontent .successmessage{ 324 - --sn-callout-accent:#38b76a; 325 - background:#edf9f1!important; 326 -} 327 - 328 -#xwikicontent .box.errormessage, 323 +#xwikicontent .arsn-warn, 324 +#xwikicontent .dmp-warn, 325 +#xwikicontent .ido-warn, 326 +#xwikicontent .pp-warn, 327 +#xwikicontent .warn, 328 +#xwikicontent .warning, 329 +#xwikicontent .warningmessage, 329 329 #xwikicontent .errormessage{ 330 - --sn-callout-accent:#e94b13; 331 - background:#fff1ec!important; 331 + box-sizing:border-box!important; 332 + border-left:4px solid #e94b13!important; 333 + border-radius:8px; 334 + text-align:left!important; 335 + word-spacing:normal!important; 332 332 } 333 333 334 -#xwikicontent [data-sn-callout-harmonized="1"] > :first-child, 335 -#xwikicontent .infomessage > :first-child, 336 -#xwikicontent .warningmessage > :first-child, 337 -#xwikicontent .successmessage > :first-child, 338 -#xwikicontent .errormessage > :first-child{ 339 - margin-top:0!important; 338 +[data-sn-master-equal-height], 339 +[data-sn-master-first-row]{ 340 + box-sizing:border-box; 340 340 } 341 341 342 -#xwikicontent [data-sn-callout-harmonized="1"] > :last-child, 343 -#xwikicontent .infomessage > :last-child, 344 -#xwikicontent .warningmessage > :last-child, 345 -#xwikicontent .successmessage > :last-child, 346 -#xwikicontent .errormessage > :last-child{ 347 - margin-bottom:0!important; 343 +/* ========================================================= 344 + FULL-WIDTH THREE-LINE NUMBER / TITLE / SUBTITLE BLOCKS 345 + ========================================================= */ 346 +#xwikicontent .arsn-area-label[data-sn-three-line="1"]{ 347 + display:grid!important; 348 + grid-template-columns:minmax(0,1fr)!important; 349 + grid-auto-rows:auto!important; 350 + width:100%!important; 351 + max-width:none!important; 352 + box-sizing:border-box!important; 353 + justify-items:start!important; 354 + align-items:start!important; 355 + gap:2px!important; 356 + text-align:left!important; 357 + text-align-last:left!important; 358 + text-justify:auto!important; 359 + word-spacing:normal!important; 360 + white-space:normal!important; 348 348 } 349 - 350 -#xwikicontent [data-sn-equal-height-managed], 351 -#xwikicontent [data-sn-first-section-aligned], 352 -#xwikicontent [data-sn-first-content-aligned]{ 353 - box-sizing:border-box; 362 +#xwikicontent .arsn-area-label[data-sn-three-line="1"] > .arsn-area-number, 363 +#xwikicontent .arsn-area-label[data-sn-three-line="1"] > .sn-area-label-title, 364 +#xwikicontent .arsn-area-label[data-sn-three-line="1"] > .arsn-area-action{ 365 + display:block!important; 366 + width:100%!important; 367 + margin:0!important; 368 + text-align:left!important; 369 + text-align-last:left!important; 370 + text-justify:auto!important; 371 + word-spacing:normal!important; 372 + white-space:normal!important; 354 354 } 355 355 </style> 356 356 357 -<script data-sn- horizontal-box-harmonizer="7">376 +<script data-sn-service-navigator-master="1"> 358 358 (function(){ 359 359 "use strict"; 360 360 380 + var PAGE_KIND="detail"; 381 + var PLACEHOLDER=false; 382 + var PLACEHOLDER_LABEL="COMING SOON"; 383 + 361 361 var MOBILE_MAX=767; 362 362 var ROW_TOLERANCE=6; 363 - var MIN_W=150; 364 - var MIN_H=36; 365 - var MAX_PARENT_CHILDREN=18; 366 - var SEARCH_DEPTH=5; 367 367 var RESIZE_DEBOUNCE=220; 368 - var MIN_WIDTH_CHANGE=2; 369 369 370 370 var root= 371 371 document.getElementById("xwikicontent")|| ... ... @@ -375,142 +375,114 @@ 375 375 376 376 if(!root)return; 377 377 378 - var heightManaged=new Set(); 379 - var sectionManaged=new Set(); 380 - var contentManaged=new Set(); 396 + var managedHeight=new Set(); 397 + var managedMargin=new Set(); 398 + var originalHeight=new WeakMap(); 399 + var originalMargin=new WeakMap(); 381 381 382 - var originalMinHeight=new WeakMap(); 383 - var originalMarginTop=new WeakMap(); 384 - 385 385 var resizeTimer=0; 386 - var lastWidth=-1; 387 - var hasApplied=false; 388 - var applying=false; 402 + var running=false; 389 389 390 - function num(v){ 391 - var n=parseFloat(v); 392 - return Number.isFinite(n)?n:0; 393 - } 394 - 395 - function visible(el,minW,minH){ 396 - if(!el||el.nodeType!==1)return false; 397 - 398 - var s=getComputedStyle(el); 399 - 400 - if( 401 - s.display==="none"|| 402 - s.visibility==="hidden"|| 403 - Number(s.opacity)===0 404 - ){ 405 - return false; 404 + var THEMES=[ 405 + { 406 + name:"BLUE", 407 + accent:"#21b6d7", 408 + bg:"#eaf7fb", 409 + text:"#315d68", 410 + labels:[ 411 + "HIER STARTEN", 412 + "ENTSCHEIDEN", 413 + "ÜBERPRÜFEN & ANPASSEN", 414 + "START HERE", 415 + "DECIDE", 416 + "REVIEW & ADAPT" 417 + ] 418 + }, 419 + { 420 + name:"RED", 421 + accent:"#e94b13", 422 + bg:"#fff1ec", 423 + text:"#8a4d36", 424 + labels:[ 425 + "PLANEN & ORGANISIEREN", 426 + "ORGANISIEREN & DOKUMENTIEREN", 427 + "PUBLIZIEREN & PRÄSENTIEREN", 428 + "PLAN & ORGANISE", 429 + "PLAN & ORGANIZE", 430 + "ORGANISE & DOCUMENT", 431 + "ORGANIZE & DOCUMENT", 432 + "PUBLISH & PRESENT" 433 + ] 434 + }, 435 + { 436 + name:"YELLOW", 437 + accent:"#f0aa00", 438 + bg:"#fff8e7", 439 + text:"#785b17", 440 + labels:[ 441 + "SCHÜTZEN & KLÄREN", 442 + "STANDARDISIEREN & IDENTIFIZIEREN", 443 + "ÖFFNEN, NACHNUTZEN & AUFFINDBAR MACHEN", 444 + "PROTECT & CLARIFY", 445 + "STANDARDISE & IDENTIFY", 446 + "STANDARDIZE & IDENTIFY", 447 + "OPEN, REUSE & MAKE FINDABLE" 448 + ] 449 + }, 450 + { 451 + name:"GREEN", 452 + accent:"#38b76a", 453 + bg:"#edf9f1", 454 + text:"#3f7451", 455 + labels:[ 456 + "INFRASTRUKTUR EINRICHTEN", 457 + "INFRASTRUKTUR & ZUSAMMENARBEIT EINRICHTEN", 458 + "SPEICHERN & ZUGRIFF STEUERN", 459 + "REPOSITORIUM, ERHALTEN & ÜBERGEBEN", 460 + "SET UP INFRASTRUCTURE", 461 + "SET UP INFRASTRUCTURE & COLLABORATION", 462 + "STORE & CONTROL ACCESS", 463 + "REPOSITORY, PRESERVE & HAND OVER" 464 + ] 406 406 } 466 + ]; 407 407 408 - var r=el.getBoundingClientRect(); 409 - 410 - return ( 411 - r.width>=(minW||1)&& 412 - r.height>=(minH||1) 413 - ); 468 + function num(value){ 469 + var n=parseFloat(value); 470 + return Number.isFinite(n)?n:0; 414 414 } 415 415 416 - function normal izeText(text){417 - return String( text||"")473 + function norm(value){ 474 + return String(value||"") 418 418 .replace(/\s+/g," ") 419 419 .trim() 420 420 .toUpperCase(); 421 421 } 422 422 423 - function excluded(el){ 424 - return ( 425 - !el.matches|| 426 - el.matches( 427 - "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]" 428 - ) 429 - ); 430 - } 480 + function visible(el){ 481 + if(!el||el.nodeType!==1)return false; 431 431 432 - /* ---------- Custom coloured callouts ---------- */ 483 + var style=getComputedStyle(el); 484 + var rect=el.getBoundingClientRect(); 433 433 434 - function nativeCallout(el){ 435 - var c= 436 - typeof el.className==="string" 437 - ? el.className.toLowerCase() 438 - : ""; 439 - 440 440 return ( 441 - /(^|\s)(infomessage|warningmessage|successmessage|errormessage)(\s|$)/.test(c) 487 + style.display!=="none"&& 488 + style.visibility!=="hidden"&& 489 + rect.width>20&& 490 + rect.height>4 442 442 ); 443 443 } 444 444 445 - function customCallout(el){ 446 - if(!visible(el,220,42)||excluded(el))return false; 447 - 448 - var r=el.getBoundingClientRect(); 449 - 450 - if(r.height>520)return false; 451 - 452 - var s=getComputedStyle(el); 453 - 454 - var bg= 455 - s.backgroundColor&& 456 - s.backgroundColor!=="rgba(0, 0, 0, 0)"&& 457 - s.backgroundColor!=="transparent"&& 458 - s.backgroundColor!=="rgb(255, 255, 255)"; 459 - 460 - var left= 461 - num(s.borderLeftWidth); 462 - 463 - return ( 464 - bg&& 465 - left>=2 466 - ); 467 - } 468 - 469 - function harmoniseCustomCallouts(){ 470 - Array.from( 471 - root.querySelectorAll( 472 - "div,aside,section" 473 - ) 474 - ).forEach(function(el){ 475 - if(nativeCallout(el))return; 476 - if(!customCallout(el))return; 477 - 478 - var s=getComputedStyle(el); 479 - 480 - el.setAttribute( 481 - "data-sn-callout-harmonized", 482 - "1" 483 - ); 484 - 485 - if( 486 - s.borderLeftColor 487 - ){ 488 - el.style.setProperty( 489 - "--sn-callout-accent", 490 - s.borderLeftColor 491 - ); 492 - } 493 - }); 494 - } 495 - 496 - /* ---------- Restore only values V7 itself changed ---------- */ 497 - 498 - function saveOriginal(el,map,property){ 494 + function saveStyle(el,map,property){ 499 499 if(map.has(el))return; 500 500 501 501 map.set(el,{ 502 - value: 503 - el.style.getPropertyValue( 504 - property 505 - ), 506 - priority: 507 - el.style.getPropertyPriority( 508 - property 509 - ) 498 + value:el.style.getPropertyValue(property), 499 + priority:el.style.getPropertyPriority(property) 510 510 }); 511 511 } 512 512 513 - function restore Original(el,map,property){503 + function restoreStyle(el,map,property){ 514 514 var original=map.get(el); 515 515 516 516 if(original&&original.value){ ... ... @@ -520,770 +520,1069 @@ 520 520 original.priority||"" 521 521 ); 522 522 }else{ 523 - el.style.removeProperty( 524 - property 525 - ); 513 + el.style.removeProperty(property); 526 526 } 527 527 } 528 528 529 529 function resetRuntime(){ 530 - heightManaged.forEach(function(el){531 - restore Original(518 + managedHeight.forEach(function(el){ 519 + restoreStyle( 532 532 el, 533 - original MinHeight,521 + originalHeight, 534 534 "min-height" 535 535 ); 536 - 537 537 el.removeAttribute( 538 - "data-sn-equal-height -managed"525 + "data-sn-master-equal-height" 539 539 ); 540 540 }); 541 541 542 - sectionManaged.forEach(function(el){543 - restore Original(529 + managedMargin.forEach(function(el){ 530 + restoreStyle( 544 544 el, 545 - originalMargin Top,532 + originalMargin, 546 546 "margin-top" 547 547 ); 548 - 549 549 el.removeAttribute( 550 - "data-sn-first- section-aligned"536 + "data-sn-master-first-row" 551 551 ); 552 552 }); 553 553 554 - contentManaged.forEach(function(el){ 555 - restoreOriginal( 556 - el, 557 - originalMarginTop, 558 - "margin-top" 559 - ); 540 + managedHeight.clear(); 541 + managedMargin.clear(); 542 + } 560 560 561 - el.removeAttribute( 562 - "data-sn-first-content-aligned" 563 - ); 564 - }); 544 + function themeFor(text){ 545 + var value=norm(text); 565 565 566 - heightManaged.clear(); 567 - sectionManaged.clear(); 568 - contentManaged.clear(); 569 - } 547 + for(var i=0;i<THEMES.length;i++){ 548 + for(var j=0;j<THEMES[i].labels.length;j++){ 549 + var label=THEMES[i].labels[j]; 570 570 571 - /* ---------- Card detection ---------- */ 551 + if( 552 + value===label|| 553 + value.indexOf(label+" ")===0|| 554 + value.indexOf(label+" -")===0|| 555 + value.indexOf(label+" ·")===0 556 + ){ 557 + return THEMES[i]; 558 + } 559 + } 560 + } 572 572 573 - function namedLikeBox(el){ 574 - var c= 575 - typeof el.className==="string" 576 - ? el.className 577 - : ""; 562 + return null; 563 + } 578 578 579 - return /(^|[\s_-])(box|card|tile|panel|role|check|service|source|call|area|detail|resource|topic|warn|info)([\s_-]|$)/i.test(c); 565 + /* ======================================================= 566 + BORDERLESS FILLED RED/ORANGE CTA BUTTONS 567 + ======================================================= */ 568 + 569 + function colourDistance(a,b){ 570 + return Math.sqrt( 571 + Math.pow(a[0]-b[0],2)+ 572 + Math.pow(a[1]-b[1],2)+ 573 + Math.pow(a[2]-b[2],2) 574 + ); 580 580 } 581 581 582 - function boxLike(el){ 583 - if( 584 - !visible(el,MIN_W,MIN_H)|| 585 - excluded(el) 586 - ){ 587 - return false; 588 - } 577 + function makeFilledRedOrangeCTAsBorderless(){ 578 + var RED_ORANGE=[233,75,19]; 589 589 590 - var s=getComputedStyle(el); 591 - var r=el.getBoundingClientRect(); 580 + Array.from( 581 + root.querySelectorAll( 582 + 'a,button,[role="button"],input[type="submit"],input[type="button"]' 583 + ) 584 + ).forEach(function(el){ 585 + if(!visible(el))return; 592 592 593 - var border= 594 - num(s.borderTopWidth)+ 595 - num(s.borderRightWidth)+ 596 - num(s.borderBottomWidth)+ 597 - num(s.borderLeftWidth); 587 + var style=getComputedStyle(el); 588 + var rgb=parseRGB(style.backgroundColor); 598 598 599 - var radius=Math.max( 600 - num(s.borderTopLeftRadius), 601 - num(s.borderTopRightRadius), 602 - num(s.borderBottomLeftRadius), 603 - num(s.borderBottomRightRadius) 604 - ); 590 + if(!rgb)return; 605 605 606 - var bg= 607 - s.backgroundColor&& 608 - s.backgroundColor!=="rgba(0, 0, 0, 0)"&& 609 - s.backgroundColor!=="transparent"; 592 + if( 593 + colourDistance( 594 + rgb, 595 + RED_ORANGE 596 + )>55 597 + ){ 598 + return; 599 + } 610 610 611 - var shadow= 612 - s.boxShadow&& 613 - s.boxShadow!=="none"; 601 + var rect=el.getBoundingClientRect(); 614 614 615 - return ( 616 - namedLikeBox(el)|| 617 - border>=1|| 618 - (bg&&radius>=3)|| 619 - (shadow&&r.width>=180) 620 - ); 621 - } 603 + if( 604 + rect.width<80|| 605 + rect.height<24 606 + ){ 607 + return; 608 + } 622 622 623 - function pickTarget(child){ 624 - if(!visible(child,MIN_W,MIN_H))return null; 610 + el.style.setProperty( 611 + "border", 612 + "none", 613 + "important" 614 + ); 625 625 626 - if(boxLike(child))return child; 616 + el.style.setProperty( 617 + "border-left", 618 + "none", 619 + "important" 620 + ); 627 627 628 - var cr=child.getBoundingClientRect(); 629 - var q=[]; 622 + el.style.setProperty( 623 + "border-top", 624 + "none", 625 + "important" 626 + ); 630 630 631 - Array.from(child.children||[]).forEach(function(el){ 632 - q.push({el:el,depth:1}); 628 + el.style.setProperty( 629 + "border-right", 630 + "none", 631 + "important" 632 + ); 633 + 634 + el.style.setProperty( 635 + "border-bottom", 636 + "none", 637 + "important" 638 + ); 639 + 640 + el.style.setProperty( 641 + "box-shadow", 642 + "none", 643 + "important" 644 + ); 633 633 }); 646 + } 634 634 635 - var best=null; 636 - var bestScore=-Infinity; 648 + /* ======================================================= 649 + FULL-WIDTH THREE-LINE AREA LABELS 650 + ======================================================= */ 637 637 638 - while(q.length){ 639 - var item=q.shift(); 640 - var el=item.el; 652 + function compactText(value){ 653 + return String(value||"") 654 + .replace(/\s+/g," ") 655 + .trim(); 656 + } 641 641 642 - if(!visible(el,MIN_W,MIN_H))continue; 658 + function makeThreeLineAreaLabels(){ 659 + Array.from( 660 + root.querySelectorAll( 661 + ".arsn-area-label" 662 + ) 663 + ).forEach(function(label){ 664 + if( 665 + label.getAttribute( 666 + "data-sn-three-line" 667 + )==="1" 668 + ){ 669 + return; 670 + } 643 643 644 - var r=el.getBoundingClientRect(); 672 + var number= 673 + label.querySelector( 674 + ":scope > .arsn-area-number" 675 + ); 645 645 677 + var action= 678 + label.querySelector( 679 + ":scope > .arsn-area-action" 680 + ); 681 + 646 646 if( 647 - r .width>=cr.width*.68&&648 - boxLike(el)683 + !number|| 684 + !action 649 649 ){ 650 - var widthFit= 651 - 1-Math.min( 652 - 1, 653 - Math.abs(cr.width-r.width)/ 654 - Math.max(1,cr.width) 655 - ); 686 + return; 687 + } 656 656 657 - var topFit= 658 - 1-Math.min( 659 - 1, 660 - Math.abs(cr.top-r.top)/100 661 - ); 689 + var clone= 690 + label.cloneNode(true); 662 662 663 - var score= 664 - widthFit*6+ 665 - topFit*3+ 666 - Math.min(r.height,900)/450+ 667 - Math.min(r.width*r.height,900000)/900000; 692 + var cloneNumber= 693 + clone.querySelector( 694 + ":scope > .arsn-area-number" 695 + ); 668 668 669 - if(score>bestScore){ 670 - best=el; 671 - bestScore=score; 672 - } 697 + var cloneAction= 698 + clone.querySelector( 699 + ":scope > .arsn-area-action" 700 + ); 701 + 702 + if(cloneNumber){ 703 + cloneNumber.remove(); 673 673 } 674 674 675 - if(item.depth<SEARCH_DEPTH){ 676 - Array.from(el.children||[]).forEach(function(next){ 677 - q.push({ 678 - el:next, 679 - depth:item.depth+1 680 - }); 681 - }); 706 + if(cloneAction){ 707 + cloneAction.remove(); 682 682 } 683 - } 684 684 685 - return best; 686 - } 710 + var titleText= 711 + compactText( 712 + clone.textContent 713 + ); 687 687 688 - function groupRows(entries){ 689 - var groups=[]; 715 + if(!titleText){ 716 + return; 717 + } 690 690 691 - entries 692 - .slice() 693 - .sort(function(a,b){ 694 - return ( 695 - a.rect.top-b.rect.top|| 696 - a.rect.left-b.rect.left 719 + var numberNode= 720 + number.cloneNode(true); 721 + 722 + var actionNode= 723 + action.cloneNode(true); 724 + 725 + var titleNode= 726 + document.createElement( 727 + "span" 697 697 ); 698 - }) 699 - .forEach(function(entry){ 700 - var group=null; 701 701 702 - for(var i=0;i<groups.length;i++){ 703 - if( 704 - Math.abs( 705 - groups[i].top- 706 - entry.rect.top 707 - )<=ROW_TOLERANCE 708 - ){ 709 - group=groups[i]; 710 - break; 711 - } 712 - } 730 + titleNode.className= 731 + "sn-area-label-title"; 713 713 714 - if(!group){ 715 - group={ 716 - top:entry.rect.top, 717 - entries:[] 718 - }; 719 - groups.push(group); 720 - } 733 + titleNode.textContent= 734 + titleText; 721 721 722 - group.entries.push(entry); 723 - }); 736 + while(label.firstChild){ 737 + label.removeChild( 738 + label.firstChild 739 + ); 740 + } 724 724 725 - return groups; 742 + label.appendChild( 743 + numberNode 744 + ); 745 + 746 + label.appendChild( 747 + titleNode 748 + ); 749 + 750 + label.appendChild( 751 + actionNode 752 + ); 753 + 754 + label.setAttribute( 755 + "data-sn-three-line", 756 + "1" 757 + ); 758 + 759 + var head= 760 + label.closest( 761 + ".arsn-area-head" 762 + ); 763 + 764 + if(head){ 765 + head.style.setProperty( 766 + "width", 767 + "100%", 768 + "important" 769 + ); 770 + 771 + head.style.setProperty( 772 + "max-width", 773 + "100%", 774 + "important" 775 + ); 776 + 777 + head.style.setProperty( 778 + "box-sizing", 779 + "border-box", 780 + "important" 781 + ); 782 + } 783 + }); 726 726 } 727 727 728 - function validRow(group){ 729 - if(group.entries.length<2)return false; 786 + /* ======================================================= 787 + PLACEHOLDER BADGE 788 + ======================================================= */ 730 730 731 - var lefts= 732 - group.entries 733 - .map(function(e){return e.rect.left;}) 734 - .sort(function(a,b){return a-b;}); 790 + function applyPlaceholderBadge(){ 791 + if(!PLACEHOLDER)return; 735 735 736 736 if( 737 - lefts[lefts.length-1]-738 - lefts[0]<739 - 80794 + document.querySelector( 795 + ".sn-coming-soon-badge" 796 + ) 740 740 ){ 741 - return false;798 + return; 742 742 } 743 743 744 - var widths= 745 - group.entries 746 - .map(function(e){return e.rect.width;}) 747 - .filter(function(w){return w>0;}); 801 + var title= 802 + document.querySelector( 803 + "#document-title" 804 + )|| 805 + document.querySelector( 806 + "h1" 807 + ); 748 748 749 - if( widths.length<2)returnfalse;809 + if(!title)return; 750 750 751 - var minW= 752 - Math.min.apply(Math,widths); 811 + var badge= 812 + document.createElement( 813 + "span" 814 + ); 753 753 754 - var maxW=755 - Math.max.apply(Math,widths);816 + badge.className= 817 + "sn-coming-soon-badge"; 756 756 757 - return ( 758 - maxW/ 759 - Math.max(1,minW)<= 760 - 1.9 819 + badge.textContent= 820 + PLACEHOLDER_LABEL; 821 + 822 + badge.setAttribute( 823 + "aria-label", 824 + PLACEHOLDER_LABEL 761 761 ); 762 - } 763 763 764 - /* ---------- Known ARSN first section bars ---------- */ 765 - 766 - function knownBar(el){ 767 - var text= 768 - normalizeText( 769 - el.textContent 770 - ); 771 - 772 - return ( 773 - text==="HIER STARTEN"|| 774 - text==="ORGANISIEREN & DOKUMENTIEREN"|| 775 - text==="ENTSCHEIDEN"|| 776 - text==="START HERE"|| 777 - text==="GET STARTED"|| 778 - text==="ORGANISE & DOCUMENT"|| 779 - text==="ORGANIZE & DOCUMENT"|| 780 - text==="DECIDE" 827 + title.appendChild( 828 + badge 781 781 ); 782 782 } 783 783 784 - functionfindKnownBar(card){785 - varcardRect=786 - card.getBoundingClientRect();832 + /* ======================================================= 833 + DETAIL PAGE OWN-ACCENT PROPAGATION 834 + ======================================================= */ 787 787 788 - var rows= 789 - Array.from( 790 - card.querySelectorAll( 791 - "div,p,span,strong,h3,h4,h5,h6" 792 - ) 793 - ) 794 - .filter(function(el){ 795 - if(!visible(el,20,6))return false; 796 - if(!knownBar(el))return false; 836 + function parseRGB(value){ 837 + var match=String(value||"").match( 838 + /rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)/i 839 + ); 797 797 798 - varr=el.getBoundingClientRect();841 + if(!match)return null; 799 799 800 - var rel= 801 - r.top- 802 - cardRect.top; 843 + return [ 844 + Number(match[1]), 845 + Number(match[2]), 846 + Number(match[3]) 847 + ]; 848 + } 803 803 804 - return ( 805 - rel>=35&& 806 - rel<= 807 - cardRect.height*.75 808 - ); 809 - }) 810 - .sort(function(a,b){ 811 - return ( 812 - a.getBoundingClientRect().top- 813 - b.getBoundingClientRect().top 814 - ); 815 - }); 816 - 817 - return rows[0]||null; 850 + function distance(a,b){ 851 + return Math.sqrt( 852 + Math.pow(a[0]-b[0],2)+ 853 + Math.pow(a[1]-b[1],2)+ 854 + Math.pow(a[2]-b[2],2) 855 + ); 818 818 } 819 819 820 - function alignKnownBars(cards){ 821 - var rows= 822 - cards.map(function(card){ 823 - var bar= 824 - findKnownBar(card); 858 + function paletteMatch(cssColor){ 859 + var rgb=parseRGB(cssColor); 825 825 826 - if(!bar)return null;861 + if(!rgb)return null; 827 827 828 - var cr= 829 - card.getBoundingClientRect(); 863 + var palette=[ 864 + {hex:"#21b6d7",rgb:[33,182,215]}, 865 + {hex:"#e94b13",rgb:[233,75,19]}, 866 + {hex:"#f0aa00",rgb:[240,170,0]}, 867 + {hex:"#38b76a",rgb:[56,183,106]} 868 + ]; 830 830 831 - var br=832 - bar.getBoundingClientRect();870 + var best=null; 871 + var bestDistance=Infinity; 833 833 834 - return { 835 - bar:bar, 836 - relativeTop: 837 - br.top- 838 - cr.top 839 - }; 840 - }); 873 + palette.forEach(function(item){ 874 + var d=distance(rgb,item.rgb); 841 841 842 - if( 843 - rows.some(function(row){ 844 - return !row; 845 - }) 846 - ){ 847 - return false; 848 - } 876 + if(d<bestDistance){ 877 + best=item; 878 + bestDistance=d; 879 + } 880 + }); 849 849 850 - var target= 851 - Math.max.apply( 852 - Math, 853 - rows.map(function(row){ 854 - return row.relativeTop; 855 - }) 856 - ); 882 + return bestDistance<=30 883 + ?best 884 + :null; 885 + } 857 857 858 - rows.forEach(function(row){ 859 - var delta= 860 - target- 861 - row.relativeTop; 887 + function propagateDetailAccents(){ 888 + if(PAGE_KIND!=="detail")return; 862 862 863 - if(delta<=1)return; 890 + Array.from( 891 + root.querySelectorAll( 892 + ".arsn-call,.dmp-call,.ido-call,.pp-call,"+ 893 + ".arsn-source,.dmp-source,.ido-source,.pp-source" 894 + ) 895 + ).forEach(function(el){ 896 + if(!visible(el))return; 864 864 865 - saveOriginal( 866 - row.bar, 867 - originalMarginTop, 868 - "margin-top" 869 - ); 898 + var style=getComputedStyle(el); 870 870 871 - var current= 872 - num( 873 - getComputedStyle( 874 - row.bar 875 - ).marginTop 876 - ); 900 + if( 901 + num(style.borderTopWidth)>=2 902 + ){ 903 + var match= 904 + paletteMatch( 905 + style.borderTopColor 906 + ); 877 877 878 - row.bar.style.setProperty( 879 - "margin-top", 880 - ( 881 - current+ 882 - delta 883 - )+"px" 884 - ); 908 + if(match){ 909 + el.style.setProperty( 910 + "border-left", 911 + "4px solid "+match.hex, 912 + "important" 913 + ); 914 + } 915 + } 916 + }); 885 885 886 - row.bar.setAttribute( 887 - "data-sn-first-section-aligned", 888 - "7" 889 - ); 918 + // Warning families: explicit safety override. 919 + Array.from( 920 + root.querySelectorAll( 921 + ".arsn-warn,.dmp-warn,.ido-warn,.pp-warn,"+ 922 + ".warn,.warning,.warningmessage,.errormessage" 923 + ) 924 + ).forEach(function(el){ 925 + if(!visible(el))return; 890 890 891 - sectionManaged.add( 892 - row.bar 927 + el.style.setProperty( 928 + "border-left", 929 + "4px solid #e94b13", 930 + "important" 893 893 ); 894 894 }); 895 895 896 - return true; 934 + // Info families: explicit orientation override. 935 + Array.from( 936 + root.querySelectorAll( 937 + ".arsn-info,.dmp-info,.ido-info,.pp-info,.infomessage" 938 + ) 939 + ).forEach(function(el){ 940 + if(!visible(el))return; 941 + 942 + el.style.setProperty( 943 + "border-left", 944 + "4px solid #21b6d7", 945 + "important" 946 + ); 947 + }); 897 897 } 898 898 899 - /* ---------- Generic first content after heading ---------- */ 950 + /* ======================================================= 951 + OVERVIEW SEMANTIC THEME PALETTE 952 + ======================================================= */ 900 900 901 - function heading(card){ 902 - var cr= 903 - card.getBoundingClientRect(); 904 - 905 - var rows= 906 - Array.from( 907 - card.querySelectorAll( 908 - "h1,h2,h3,h4,h5,h6,.box-title,[role=heading]" 909 - ) 954 + function smallestThemeHeaders(){ 955 + return Array.from( 956 + root.querySelectorAll( 957 + "div,span,p,strong,h3,h4,h5,h6" 910 910 ) 911 - .filter(function(el){ 912 - if(!visible(el,20,8))return false; 959 + ).filter(function(el){ 960 + if(!visible(el))return false; 961 + if(!themeFor(el.textContent))return false; 913 913 914 - var r=el.getBoundingClientRect(); 915 - 916 - var rel= 917 - r.top- 918 - cr.top; 919 - 920 - return ( 921 - rel>=0&& 922 - rel<= 923 - Math.min( 924 - 160, 925 - cr.height*.45 926 - ) 963 + return !Array.from( 964 + el.children||[] 965 + ).some(function(child){ 966 + return !!themeFor( 967 + child.textContent 927 927 ); 928 - }) 929 - .sort(function(a,b){ 930 - return ( 931 - a.getBoundingClientRect().top- 932 - b.getBoundingClientRect().top 933 - ); 934 934 }); 935 - 936 - return rows[0]||null; 970 + }); 937 937 } 938 938 939 - function firstContent(card,h){ 940 - if(!h)return null; 973 + function findOverviewCard(header){ 974 + var node=header.parentElement; 975 + var candidates=[]; 941 941 942 - var cr= 943 - card.getBoundingClientRect(); 977 + while(node&&node!==root){ 978 + var rect=node.getBoundingClientRect(); 979 + var style=getComputedStyle(node); 944 944 945 - var hr= 946 - h.getBoundingClientRect(); 981 + var border= 982 + num(style.borderTopWidth)+ 983 + num(style.borderRightWidth)+ 984 + num(style.borderBottomWidth)+ 985 + num(style.borderLeftWidth); 947 947 948 - var rows= 949 - Array.from( 950 - card.querySelectorAll( 951 - "p,div,ul,ol,dl,blockquote" 952 - ) 953 - ) 954 - .filter(function(el){ 955 - if( 956 - el===h|| 957 - h.contains(el)|| 958 - el.contains(h) 959 - ){ 960 - return false; 961 - } 987 + if( 988 + rect.width>=220&& 989 + rect.width<=800&& 990 + rect.height>=120&& 991 + border>=1 992 + ){ 993 + candidates.push(node); 994 + } 962 962 963 - if(!visible(el,30,8))return false; 996 + node=node.parentElement; 997 + } 964 964 965 - var text= 966 - String(el.textContent||"") 967 - .replace(/\s+/g," ") 968 - .trim(); 999 + if(!candidates.length)return null; 969 969 970 - if(text.length<3)return false; 1001 + candidates.sort(function(a,b){ 1002 + return ( 1003 + b.getBoundingClientRect().height- 1004 + a.getBoundingClientRect().height 1005 + ); 1006 + }); 971 971 972 - var r=el.getBoundingClientRect(); 1008 + return candidates[0]; 1009 + } 973 973 974 - if( 975 - r.top< 976 - hr.bottom-1 977 - ){ 978 - return false; 979 - } 1011 + function rowCandidates(link,card){ 1012 + var result=[]; 1013 + var cardRect= 1014 + card.getBoundingClientRect(); 980 980 981 - if( 982 - r.top-cr.top> 983 - Math.min( 984 - 280, 985 - cr.height*.65 986 - ) 987 - ){ 988 - return false; 989 - } 1016 + var node=link; 990 990 1018 + while(node&&node!==card){ 1019 + if(visible(node)){ 1020 + var rect= 1021 + node.getBoundingClientRect(); 1022 + 991 991 if( 992 - r.height> 993 - cr.height*.58 1024 + rect.height<=105&& 1025 + rect.width>= 1026 + cardRect.width*.50&& 1027 + rect.width<= 1028 + cardRect.width*1.03 994 994 ){ 995 - re turn false;1030 + result.push(node); 996 996 } 1032 + } 997 997 998 - return true; 999 - }) 1000 - .sort(function(a,b){ 1001 - var ar= 1002 - a.getBoundingClientRect(); 1034 + node=node.parentElement; 1035 + } 1003 1003 1004 - varbr=1005 - b.getBoundingClientRect();1037 + return result; 1038 + } 1006 1006 1040 + function chooseOuterRow( 1041 + candidates, 1042 + link 1043 + ){ 1044 + if(!candidates.length){ 1045 + return link; 1046 + } 1047 + 1048 + var bordered= 1049 + candidates.filter(function(el){ 1007 1007 return ( 1008 - ar.top-br.top|| 1009 - ar.height-br.height 1051 + num( 1052 + getComputedStyle(el) 1053 + .borderLeftWidth 1054 + )>=1 1010 1010 ); 1011 1011 }); 1012 1012 1013 - return rows[0]||null; 1014 - } 1058 + var pool= 1059 + bordered.length 1060 + ?bordered 1061 + :candidates; 1015 1015 1016 - function alignGeneric(cards){ 1017 - var rows= 1018 - cards.map(function(card){ 1019 - var h= 1020 - heading(card); 1063 + pool.sort(function(a,b){ 1064 + var ar= 1065 + a.getBoundingClientRect(); 1021 1021 1022 - var c= 1023 - firstContent( 1024 - card, 1025 - h 1026 - ); 1067 + var br= 1068 + b.getBoundingClientRect(); 1027 1027 1028 - if(!h||!c)return null; 1070 + return ( 1071 + ar.left-br.left|| 1072 + br.width-ar.width 1073 + ); 1074 + }); 1029 1029 1030 - varcr=1031 - card.getBoundingClientRect();1076 + return pool[0]||link; 1077 + } 1032 1032 1033 - var rr= 1034 - c.getBoundingClientRect(); 1035 - 1036 - return { 1037 - content:c, 1038 - relativeTop: 1039 - rr.top-cr.top 1040 - }; 1041 - }); 1042 - 1043 - if( 1044 - rows.some(function(row){ 1045 - return !row; 1046 - }) 1047 - ){ 1048 - return false; 1079 + function applyOverviewPalette(){ 1080 + if(PAGE_KIND!=="overview"){ 1081 + return []; 1049 1049 } 1050 1050 1051 - var target= 1052 - Math.max.apply( 1053 - Math, 1054 - rows.map(function(row){ 1055 - return row.relativeTop; 1084 + var headers= 1085 + smallestThemeHeaders() 1086 + .map(function(el){ 1087 + return { 1088 + el:el, 1089 + theme: 1090 + themeFor( 1091 + el.textContent 1092 + ), 1093 + card: 1094 + findOverviewCard( 1095 + el 1096 + ) 1097 + }; 1056 1056 }) 1057 - ); 1099 + .filter(function(row){ 1100 + return !!row.card; 1101 + }); 1058 1058 1059 - rows.forEach(function(row){ 1060 - var delta= 1061 - target- 1062 - row.relativeTop; 1103 + var unique=[]; 1104 + var seenHeaders=new Set(); 1063 1063 1064 - if(delta<=1)return; 1106 + headers.forEach(function(row){ 1107 + var key= 1108 + row.theme.name+ 1109 + "|"+ 1110 + Math.round( 1111 + row.card 1112 + .getBoundingClientRect() 1113 + .left 1114 + )+ 1115 + "|"+ 1116 + Math.round( 1117 + row.el 1118 + .getBoundingClientRect() 1119 + .top 1120 + ); 1065 1065 1066 - sa veOriginal(1067 - r ow.content,1068 - originalMarginTop,1069 - "margin-top"1070 - );1122 + if(!seenHeaders.has(key)){ 1123 + seenHeaders.add(key); 1124 + unique.push(row); 1125 + } 1126 + }); 1071 1071 1072 - var current= 1073 - num( 1074 - getComputedStyle( 1075 - row.content 1076 - ).marginTop 1077 - ); 1128 + unique.forEach(function(row){ 1129 + var headerRect= 1130 + row.el 1131 + .getBoundingClientRect(); 1078 1078 1079 - row.content.style.setProperty( 1080 - "margin-top", 1081 - ( 1082 - current+ 1083 - delta 1084 - )+"px" 1133 + row.el.style.setProperty( 1134 + "background", 1135 + row.theme.bg, 1136 + "important" 1085 1085 ); 1086 1086 1087 - row.content.setAttribute( 1088 - "data-sn-first-content-aligned", 1089 - "7" 1139 + row.el.style.setProperty( 1140 + "color", 1141 + row.theme.text, 1142 + "important" 1090 1090 ); 1091 1091 1092 - contentManaged.add( 1093 - row.content 1145 + row.el.style.setProperty( 1146 + "text-align", 1147 + "left", 1148 + "important" 1094 1094 ); 1150 + 1151 + row.el.style.setProperty( 1152 + "word-spacing", 1153 + "normal", 1154 + "important" 1155 + ); 1156 + 1157 + var later= 1158 + unique 1159 + .filter(function(other){ 1160 + return ( 1161 + other.card===row.card&& 1162 + other.el 1163 + .getBoundingClientRect() 1164 + .top> 1165 + headerRect.top+2 1166 + ); 1167 + }) 1168 + .sort(function(a,b){ 1169 + return ( 1170 + a.el 1171 + .getBoundingClientRect() 1172 + .top- 1173 + b.el 1174 + .getBoundingClientRect() 1175 + .top 1176 + ); 1177 + }); 1178 + 1179 + var stopTop= 1180 + later.length 1181 + ?later[0].el 1182 + .getBoundingClientRect() 1183 + .top 1184 + :Infinity; 1185 + 1186 + Array.from( 1187 + row.card.querySelectorAll("a") 1188 + ).forEach(function(link){ 1189 + if(!visible(link))return; 1190 + 1191 + var rect= 1192 + link.getBoundingClientRect(); 1193 + 1194 + if( 1195 + rect.top<= 1196 + headerRect.bottom-2|| 1197 + rect.top>= 1198 + stopTop-2 1199 + ){ 1200 + return; 1201 + } 1202 + 1203 + var candidates= 1204 + rowCandidates( 1205 + link, 1206 + row.card 1207 + ); 1208 + 1209 + var target= 1210 + chooseOuterRow( 1211 + candidates, 1212 + link 1213 + ); 1214 + 1215 + candidates.forEach(function(el){ 1216 + el.style.setProperty( 1217 + "border-left", 1218 + "0 solid transparent", 1219 + "important" 1220 + ); 1221 + }); 1222 + 1223 + target.style.setProperty( 1224 + "border-left", 1225 + "3px solid "+ 1226 + row.theme.accent, 1227 + "important" 1228 + ); 1229 + 1230 + target.style.setProperty( 1231 + "box-sizing", 1232 + "border-box", 1233 + "important" 1234 + ); 1235 + }); 1095 1095 }); 1096 1096 1097 - return true;1238 + return unique; 1098 1098 } 1099 1099 1100 - function applyRow(group){ 1101 - if(!validRow(group))return false; 1241 + /* ======================================================= 1242 + OVERVIEW CARD HEIGHT + FIRST THEMATIC ROW 1243 + ======================================================= */ 1102 1102 1245 + function alignOverviewCards(headers){ 1246 + if( 1247 + PAGE_KIND!=="overview"|| 1248 + window.innerWidth<=MOBILE_MAX 1249 + ){ 1250 + return; 1251 + } 1252 + 1103 1103 var cards=[]; 1104 1104 var seen=new Set(); 1105 1105 1106 - group.entries.forEach(function(entry){1107 - if(!seen.has( entry.target)){1108 - seen.add( entry.target);1109 - cards.push( entry.target);1256 + headers.forEach(function(row){ 1257 + if(!seen.has(row.card)){ 1258 + seen.add(row.card); 1259 + cards.push(row.card); 1110 1110 } 1111 1111 }); 1112 1112 1113 - if(cards.length<2)return false; 1114 - 1115 - if( 1116 - !alignKnownBars(cards) 1117 - ){ 1118 - alignGeneric(cards); 1263 + if(cards.length<2){ 1264 + return; 1119 1119 } 1120 1120 1121 - var maxHeight=0; 1267 + // Group cards by actual top position. 1268 + var groups=[]; 1122 1122 1123 1123 cards.forEach(function(card){ 1124 - maxHeight= 1125 - Math.max( 1126 - maxHeight, 1127 - card.getBoundingClientRect().height 1128 - ); 1271 + var top= 1272 + card.getBoundingClientRect().top; 1273 + 1274 + var group=null; 1275 + 1276 + for(var i=0;i<groups.length;i++){ 1277 + if( 1278 + Math.abs( 1279 + groups[i].top-top 1280 + )<=ROW_TOLERANCE 1281 + ){ 1282 + group=groups[i]; 1283 + break; 1284 + } 1285 + } 1286 + 1287 + if(!group){ 1288 + group={ 1289 + top:top, 1290 + cards:[] 1291 + }; 1292 + groups.push(group); 1293 + } 1294 + 1295 + group.cards.push(card); 1129 1129 }); 1130 1130 1131 - maxHeight=1132 - Math.ceil(1133 - maxHeight1134 - );1298 + groups.forEach(function(group){ 1299 + if(group.cards.length<2){ 1300 + return; 1301 + } 1135 1135 1136 - if(maxHeight<MIN_H)return false; 1303 + var firstHeaders= 1304 + group.cards.map(function(card){ 1305 + var candidates= 1306 + headers 1307 + .filter(function(row){ 1308 + return row.card===card; 1309 + }) 1310 + .sort(function(a,b){ 1311 + return ( 1312 + a.el 1313 + .getBoundingClientRect() 1314 + .top- 1315 + b.el 1316 + .getBoundingClientRect() 1317 + .top 1318 + ); 1319 + }); 1137 1137 1138 - cards.forEach(function(card){ 1139 - saveOriginal( 1140 - card, 1141 - originalMinHeight, 1142 - "min-height" 1143 - ); 1321 + return candidates.length 1322 + ?candidates[0] 1323 + :null; 1324 + }); 1144 1144 1145 - card.style.setProperty( 1146 - "min-height", 1147 - maxHeight+"px" 1148 - ); 1326 + if( 1327 + !firstHeaders.some(function(row){ 1328 + return !row; 1329 + }) 1330 + ){ 1331 + var targetTop= 1332 + Math.max.apply( 1333 + Math, 1334 + firstHeaders.map(function(row){ 1335 + return ( 1336 + row.el 1337 + .getBoundingClientRect() 1338 + .top- 1339 + row.card 1340 + .getBoundingClientRect() 1341 + .top 1342 + ); 1343 + }) 1344 + ); 1149 1149 1150 - card.setAttribute( 1151 - "data-sn-equal-height-managed", 1152 - "7" 1153 - ); 1346 + firstHeaders.forEach(function(row){ 1347 + var relativeTop= 1348 + row.el 1349 + .getBoundingClientRect() 1350 + .top- 1351 + row.card 1352 + .getBoundingClientRect() 1353 + .top; 1154 1154 1155 - heightManaged.add(card);1156 - });1355 + var delta= 1356 + targetTop-relativeTop; 1157 1157 1158 - return true; 1159 - } 1358 + if(delta>1){ 1359 + saveStyle( 1360 + row.el, 1361 + originalMargin, 1362 + "margin-top" 1363 + ); 1160 1160 1161 - function calculate(force){ 1162 - if(applying)return; 1365 + var current= 1366 + num( 1367 + getComputedStyle( 1368 + row.el 1369 + ).marginTop 1370 + ); 1163 1163 1164 - var width= 1165 - Math.round( 1166 - window.innerWidth 1167 - ); 1372 + row.el.style.setProperty( 1373 + "margin-top", 1374 + ( 1375 + current+delta 1376 + )+"px" 1377 + ); 1168 1168 1169 - var meaningful= 1170 - lastWidth<0|| 1171 - Math.abs( 1172 - width- 1173 - lastWidth 1174 - )>= 1175 - MIN_WIDTH_CHANGE; 1379 + row.el.setAttribute( 1380 + "data-sn-master-first-row", 1381 + "1" 1382 + ); 1176 1176 1384 + managedMargin.add( 1385 + row.el 1386 + ); 1387 + } 1388 + }); 1389 + } 1390 + 1391 + var maxHeight=0; 1392 + 1393 + group.cards.forEach(function(card){ 1394 + maxHeight= 1395 + Math.max( 1396 + maxHeight, 1397 + card 1398 + .getBoundingClientRect() 1399 + .height 1400 + ); 1401 + }); 1402 + 1403 + maxHeight= 1404 + Math.ceil(maxHeight); 1405 + 1406 + group.cards.forEach(function(card){ 1407 + saveStyle( 1408 + card, 1409 + originalHeight, 1410 + "min-height" 1411 + ); 1412 + 1413 + card.style.setProperty( 1414 + "min-height", 1415 + maxHeight+"px" 1416 + ); 1417 + 1418 + card.setAttribute( 1419 + "data-sn-master-equal-height", 1420 + "1" 1421 + ); 1422 + 1423 + managedHeight.add( 1424 + card 1425 + ); 1426 + }); 1427 + }); 1428 + } 1429 + 1430 + /* ======================================================= 1431 + DETAIL GRID EQUAL HEIGHT, DESKTOP ONLY 1432 + ======================================================= */ 1433 + 1434 + function equaliseDetailGrids(){ 1177 1177 if( 1178 - hasApplied&& 1179 - !force&& 1180 - !meaningful 1436 + PAGE_KIND!=="detail"|| 1437 + window.innerWidth<=MOBILE_MAX 1181 1181 ){ 1182 1182 return; 1183 1183 } 1184 1184 1185 - applying=true; 1442 + var selectors=[ 1443 + ".arsn-grid", 1444 + ".arsn-grid-2", 1445 + ".arsn-grid-3", 1446 + ".dmp-grid", 1447 + ".ido-grid", 1448 + ".pp-grid" 1449 + ]; 1186 1186 1187 - try{ 1188 - harmoniseCustomCallouts(); 1451 + selectors.forEach(function(selector){ 1452 + Array.from( 1453 + root.querySelectorAll(selector) 1454 + ).forEach(function(grid){ 1455 + var children= 1456 + Array.from( 1457 + grid.children||[] 1458 + ).filter(visible); 1189 1189 1190 - if(width<=MOBILE_MAX){ 1191 - if(hasApplied){ 1192 - resetRuntime(); 1460 + if(children.length<2){ 1461 + return; 1193 1193 } 1194 1194 1195 - hasApplied=false; 1196 - lastWidth=width; 1197 - return; 1198 - } 1464 + var groups=[]; 1199 1199 1200 - if(hasApplied){ 1201 - resetRuntime(); 1202 - } 1466 + children.forEach(function(child){ 1467 + var top= 1468 + child 1469 + .getBoundingClientRect() 1470 + .top; 1203 1203 1204 - var parents= 1205 - Array.from( 1206 - root.querySelectorAll("*") 1207 - ) 1208 - .filter(function(parent){ 1209 - return ( 1210 - visible( 1211 - parent, 1212 - MIN_W, 1213 - MIN_H 1214 - )&& 1215 - parent.children&& 1216 - parent.children.length>=2&& 1217 - parent.children.length<= 1218 - MAX_PARENT_CHILDREN 1219 - ); 1220 - }); 1472 + var group=null; 1221 1221 1222 - var touched= 1223 - new Set(); 1474 + for(var i=0;i<groups.length;i++){ 1475 + if( 1476 + Math.abs( 1477 + groups[i].top-top 1478 + )<=ROW_TOLERANCE 1479 + ){ 1480 + group=groups[i]; 1481 + break; 1482 + } 1483 + } 1224 1224 1225 - parents.forEach(function(parent){ 1226 - var entries=[]; 1485 + if(!group){ 1486 + group={ 1487 + top:top, 1488 + items:[] 1489 + }; 1490 + groups.push(group); 1491 + } 1227 1227 1228 - Array.from( 1229 - parent.children 1230 - ).forEach(function(child){ 1231 - if( 1232 - !visible( 1233 - child, 1234 - MIN_W, 1235 - MIN_H 1236 - ) 1237 - ){ 1493 + group.items.push(child); 1494 + }); 1495 + 1496 + groups.forEach(function(group){ 1497 + if(group.items.length<2){ 1238 1238 return; 1239 1239 } 1240 1240 1241 - var target= 1242 - pickTarget(child); 1501 + var maxHeight=0; 1243 1243 1244 - if(!target)return; 1245 - 1246 - entries.push({ 1247 - target:target, 1248 - rect: 1249 - target.getBoundingClientRect() 1503 + group.items.forEach(function(item){ 1504 + maxHeight= 1505 + Math.max( 1506 + maxHeight, 1507 + item 1508 + .getBoundingClientRect() 1509 + .height 1510 + ); 1250 1250 }); 1251 - }); 1252 1252 1253 - groupRows( 1254 - entries 1255 - ).forEach(function(group){ 1256 - if(!validRow(group))return; 1513 + maxHeight= 1514 + Math.ceil(maxHeight); 1257 1257 1258 - var targets= 1259 - group.entries.map(function(entry){ 1260 - return entry.target; 1261 - }); 1516 + group.items.forEach(function(item){ 1517 + saveStyle( 1518 + item, 1519 + originalHeight, 1520 + "min-height" 1521 + ); 1262 1262 1263 - if( 1264 - !targets.some(function(el){ 1265 - return !touched.has(el); 1266 - }) 1267 - ){ 1268 - return; 1269 - } 1523 + item.style.setProperty( 1524 + "min-height", 1525 + maxHeight+"px" 1526 + ); 1270 1270 1271 - if(applyRow(group)){ 1272 - targets.forEach(function(el){ 1273 - touched.add(el); 1274 - }); 1275 - } 1528 + item.setAttribute( 1529 + "data-sn-master-equal-height", 1530 + "1" 1531 + ); 1532 + 1533 + managedHeight.add(item); 1534 + }); 1276 1276 }); 1277 1277 }); 1537 + }); 1538 + } 1278 1278 1279 - lastWidth=width; 1280 - hasApplied=true; 1540 + /* ======================================================= 1541 + RUN / RESPONSIVE SCHEDULING 1542 + ======================================================= */ 1543 + 1544 + function run(){ 1545 + if(running)return; 1546 + 1547 + running=true; 1548 + 1549 + try{ 1550 + resetRuntime(); 1551 + applyPlaceholderBadge(); 1552 + propagateDetailAccents(); 1553 + 1554 + var headers= 1555 + applyOverviewPalette(); 1556 + 1557 + makeThreeLineAreaLabels(); 1558 + makeFilledRedOrangeCTAsBorderless(); 1559 + 1560 + if( 1561 + window.innerWidth> 1562 + MOBILE_MAX 1563 + ){ 1564 + alignOverviewCards( 1565 + headers 1566 + ); 1567 + 1568 + equaliseDetailGrids(); 1569 + } 1281 1281 }finally{ 1282 - applying=false;1571 + running=false; 1283 1283 } 1284 1284 } 1285 1285 1286 - function resize(){1575 + function onResize(){ 1287 1287 if(resizeTimer){ 1288 1288 clearTimeout( 1289 1289 resizeTimer ... ... @@ -1294,19 +1294,40 @@ 1294 1294 setTimeout( 1295 1295 function(){ 1296 1296 resizeTimer=0; 1297 - calculate(false);1586 + run(); 1298 1298 }, 1299 1299 RESIZE_DEBOUNCE 1300 1300 ); 1301 1301 } 1302 1302 1303 - function waitImages(){ 1592 + async function waitForReady(){ 1593 + if( 1594 + document.readyState!=="complete" 1595 + ){ 1596 + await new Promise(function(resolve){ 1597 + window.addEventListener( 1598 + "load", 1599 + resolve, 1600 + {once:true} 1601 + ); 1602 + }); 1603 + } 1604 + 1605 + if( 1606 + document.fonts&& 1607 + document.fonts.ready 1608 + ){ 1609 + try{ 1610 + await document.fonts.ready; 1611 + }catch(error){} 1612 + } 1613 + 1304 1304 var images= 1305 1305 Array.from( 1306 1306 root.querySelectorAll("img") 1307 1307 ); 1308 1308 1309 - returnPromise.all(1619 + await Promise.all( 1310 1310 images.map(function(img){ 1311 1311 if(img.complete){ 1312 1312 return Promise.resolve(); ... ... @@ -1331,46 +1331,20 @@ 1331 1331 }); 1332 1332 }) 1333 1333 ); 1334 - } 1335 1335 1336 - async function initial(){ 1337 - if( 1338 - document.readyState!== 1339 - "complete" 1340 - ){ 1341 - await new Promise(function(resolve){ 1342 - addEventListener( 1343 - "load", 1344 - resolve, 1345 - {once:true} 1346 - ); 1347 - }); 1348 - } 1349 - 1350 - if( 1351 - document.fonts&& 1352 - document.fonts.ready 1353 - ){ 1354 - try{ 1355 - await document.fonts.ready; 1356 - }catch(error){} 1357 - } 1358 - 1359 - await waitImages(); 1360 - 1361 - // Exactly one initial layout calculation. 1362 - calculate(true); 1645 + run(); 1363 1363 } 1364 1364 1365 - addEventListener( 1648 + window.addEventListener( 1366 1366 "resize", 1367 - resize,1650 + onResize, 1368 1368 {passive:true} 1369 1369 ); 1370 1370 1371 - i nitial();1654 + waitForReady(); 1372 1372 })(); 1373 1373 </script> 1374 1374 1375 -<!-- SN_HORIZONTAL_BOX_HARMONIZER_END --> 1376 -{{/html}}\n 1658 +<!-- SN_SERVICE_NAVIGATOR_MASTER_STYLE_END --> 1659 +{{/html}} 1660 +