Last modified by Veronika Kocher on Friday, 04 Sep 2026 14:45

From version 5.13
edited by Veronika Kocher
on Thursday, 03 Sep 2026 15:54
Change comment: There is no comment for this version
To version 5.9
edited by Veronika Kocher
on Thursday, 03 Sep 2026 9:34
Change comment: There is no comment for this version

Summary

Details

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