Changes for page Plan Your Data Management

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

From version 4.15
edited by Veronika Kocher
on Friday, 04 Sep 2026 14:45
Change comment: There is no comment for this version
To version 4.10
edited by Veronika Kocher
on Thursday, 03 Sep 2026 10:09
Change comment: There is no comment for this version

Summary

Details

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