components:carousel:glass

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
components:carousel:glass [2026/07/07 12:57] ayushcomponents:carousel:glass [2026/09/16 02:59] (current) ayush
Line 1: Line 1:
 <html> <html>
-<head> +    <head> 
-  <link rel="preconnect" href="https://cdn.jsdelivr.net"> +        <link rel="preconnect" href="https://cdn.jsdelivr.net" /
-  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@12/swiper-bundle.min.css">+        <link 
 +            rel="stylesheet" 
 +            href="https://cdn.jsdelivr.net/npm/swiper@12/swiper-bundle.min.css" 
 +        />
  
-  <style> +        <style> 
-    :root { +            :root { 
-      --swiper-pagination-color:                   #007bff; +                /* Swiper */ 
-      --swiper-pagination-bullet-inactive-color:   #ccc; +                --swiper-pagination-color: #007bff; 
-      --swiper-pagination-bullet-inactive-opacity: 1;+                --swiper-pagination-bullet-inactive-color: #ccc; 
 +                --swiper-pagination-bullet-inactive-opacity: 1;
  
-      --c-max-w:  1200px; +                /* Carousel */ 
-      --c-max-h:  650px; +                --c-max-w: 1200px; 
-      --c-radius: 8px;+                --c-max-h: 650px; 
 +                --c-radius: 8px;
  
-      --cap-max-w:         85%; +                /* Caption */ 
-      --cap-shrink-buffer: 36px;  /* increase if text wraps to extra lines */ +                --cap-max-w: 85%; 
-      --cap-min-w:         0px; +                --cap-shrink-buffer: 36px; 
-      --cap-margin:        24px; +                --cap-min-w: 0px; 
-      --cap-bottom: clamp(10px, 3vw,   30px); +                --cap-margin: 24px; 
-      --cap-pad-v:  clamp(10px, 2vh,   18px); +                --cap-bottom: clamp(10px, 3vw, 30px); 
-      --cap-pad-h:  clamp(14px, 2.5vw, 24px); +                --cap-pad-v: clamp(10px, 2vh, 18px); 
-      --cap-radius: 12px; +                --cap-pad-h: clamp(14px, 2.5vw, 24px); 
-      --cap-dur:    0.55s; +                --cap-radius: 12px; 
-      --cap-ease:   ease; +                --cap-dur: 0.55s; 
-      --cap-enter-y: 16px;+                --cap-ease: ease; 
 +                --cap-enter-y: 16px;
  
-      /* dark glass--glass-tint: 0 0 0; --glass-a1: 0.40; --glass-a2: 0.25 */ +                /* Caption glass */ 
-      --glass-tint255 255 255+                --glass-tint: 255 255 255; 
-      --glass-a1  0.12+                --glass-a1: 0.12; 
-      --glass-a2  0.05+                --glass-a2: 0.05; 
-      --glass-blur: 20px+                --glass-blur20px
-      --glass-sat 160%;+                --glass-sat: 160%; 
 +                --glass-border-alpha: 0; 
 +                --glass-rim-alpha: 0; 
 +                --glass-glow-alpha: 0.18
 +                --glass-depth-alpha: 0.12
 +                --glass-shadow-y: 8px; 
 +                --glass-shadow-blur: 32px
 +                --glass-shadow-alpha0.38;
  
-      /* set any alpha to 0 to disable that effect */ +                /* Navigation */ 
-      --glass-border-alpha: 0; +                --nav-glass-tint: 0 0 0; 
-      --glass-rim-alpha:    0; +                --nav-glass-blur: 12px; 
-      --glass-glow-alpha:   0.18+                --nav-glass-sat: 160%; 
-      --glass-depth-alpha 0.12+                --nav-fill-default: 0.45; 
-      --glass-shadow-y    8px+                --nav-fill-hover: 0.62; 
-      --glass-shadow-blur 32px+                --nav-fill-active: 0.78; 
-      --glass-shadow-alpha: 0.38;+                --nav-border-alpha: 0; 
 +                --nav-rim-alpha: 0.32
 +                --nav-glow-alpha: 0.12
 +                --nav-shadow: 
 +                    0 2px 14px rgb(0 0 0 / 0.5), 0 1px 3px rgb(0 0 0 / 0.28)
 +                --nav-shadow-hover: 
 +                    0 4px 22px rgb(0 0 0 / 0.62), 0 2px 6px rgb(0 0 0 / 0.32)
 +                --nav-size: clamp(36px, 5vw, 44px); 
 +                --nav-iconclamp(15px, 2vw, 20px)
 +                --nav-stroke: 2; 
 +                --nav-offset: 16px; 
 +                --nav-hover-scale: 1.1; 
 +                --nav-press-scale: 0.93; 
 +                --nav-dur: 0.3s; 
 +                --nav-ease: cubic-bezier(0.34, 1.56, 0.64, 1); 
 +                --nav-press-dur: 0.1s;
  
-      /* light nav: --nav-glass-tint: 255 255 255 */ +                /* Accent */ 
-      --nav-glass-tint  0 0 0+                --accent#007bff
-      --nav-glass-blur:   12px; +                --accent-hover: #0056b3;
-      --nav-glass-sat:    160%; +
-      --nav-fill-default: 0.45; +
-      --nav-fill-hover:   0.62; +
-      --nav-fill-active:  0.78; +
-      --nav-border-alpha: 0; +
-      --nav-rim-alpha:    0.32; +
-      --nav-glow-alpha:   0.12; +
-      --nav-shadow:       0 2px 14px rgb(0 0 0 / .50), 0 1px 3px rgb(0 0 0 / .28); +
-      --nav-shadow-hover: 0 4px 22px rgb(0 0 0 / .62), 0 2px 6px rgb(0 0 0 / .32); +
-      --nav-size:        clamp(36px, 5vw, 44px); +
-      --nav-icon:        clamp(15px, 2vw, 20px); +
-      --nav-stroke:      2; +
-      --nav-offset:      16px; +
-      --nav-hover-scale: 1.10; +
-      --nav-press-scale: 0.93; +
-      --nav-dur:         0.3s; +
-      --nav-ease:        cubic-bezier(0.34, 1.56, 0.64, 1); +
-      --nav-press-dur:   0.10s;+
  
-      --accent      #007bff+                /* Typography */ 
-      --accent-hover#0056b3;+                --t-titleclamp(1rem, 2.5vw, 1.35rem)
 +                --t-bodyclamp(0.75rem, 1.5vw, 0.9rem); 
 +                --t-btn: clamp(0.75rem, 1.2vw, 0.85rem); 
 +            }
  
-      --t-titleclamp(1rem,   2.5vw, 1.35rem)+            /* Carousel */ 
-      --t-body clamp(.75rem, 1.5vw, .9rem)+            .carousel-wrapper { 
-      --t-btn  clamp(.75rem, 1.2vw, .85rem)+                displayflex
-    }+                justify-contentcenter
 +                width100%
 +            }
  
-    .carousel-wrapper +            .swiper 
-      displayflex+                width100%
-      justify-contentcenter+                max-widthvar(--c-max-w)
-      width100%+                border-radiusvar(--c-radius)
-    }+                overflow: hidden; 
 +                overscroll-behavior: contain; 
 +                background: #e8e8e8; 
 +                box-shadow: 0 10px 25px rgb(0 0 0 / 0.12); 
 +                transition: box-shadow 0.3s ease;
  
-    .swiper +                &:hover 
-      width: 100%; +                    box-shadow: 0 16px 40px rgb(0 0 0 / 0.18); 
-      max-width: var(--c-max-w); +                } 
-      border-radius: var(--c-radius); +            }
-      overflow: hidden; +
-      overscroll-behavior: contain; +
-      background: #e8e8e8; +
-      box-shadow: 0 10px 25px rgb(0 0 0 / .12); +
-      transition: box-shadow .3s ease;+
  
-      &:hover { box-shadow0 16px 40px rgb(0 0 0 / .18); } +            .swiper-slide { 
-    }+                positionrelative; 
 +                overflow: hidden; 
 +                height: clamp(300px, 55vw, var(--c-max-h)); 
 +            }
  
-    .swiper-slide { +            .swiper-slide img 
-      positionrelative+                displayblock
-      overflowhidden+                width100%
-      height: clamp(300px, 55vw, var(--c-max-h))+                height: 100%; 
-    }+                object-fit: cover
 +            }
  
-    .swiper-slide img { +            /* Caption scrim */
-      width: 100%; +
-      height: 100%; +
-      object-fit: cover; +
-      display: block; +
-    }+
  
-    /* gradient scrim for caption legibility */ +            .swiper-slide::before { 
-    .swiper-slide::before { +                content: ""; 
-      content: ""; +                position: absolute; 
-      position: absolute; +                inset: auto 0 0; 
-      inset: auto 0 0; +                height: 55%; 
-      height: 55%; +                background: linear-gradient( 
-      background: linear-gradient(to top, rgb(0 0 0 / .72), transparent); +                    to top, 
-      pointer-events: none; +                    rgb(0 0 0 / 0.72), 
-      z-index: 1; +                    transparent 
-    }+                ); 
 +                pointer-events: none; 
 +                z-index: 1; 
 +            }
  
-    .slide-caption { +            /* Caption */ 
-      position: absolute; +            .slide-caption { 
-      bottom: var(--cap-bottom); +                position: absolute; 
-      left: 50%; +                bottom: var(--cap-bottom); 
-      min-width: var(--cap-min-w); +                left: 50%; 
-      width: fit-content; +                min-width: var(--cap-min-w); 
-      max-width: min(var(--cap-max-w), calc(100% - var(--cap-margin) * 2)); +                width: fit-content; 
-      padding: var(--cap-pad-v) var(--cap-pad-h); +                max-width: min( 
-      border-radius: var(--cap-radius)+                    var(--cap-max-w), 
-      background: linear-gradient( +                    calc(100% - var(--cap-margin) * 2) 
-        140deg, +                ); 
-        rgb(var(--glass-tint) / var(--glass-a1)) 0%, +                padding: var(--cap-pad-v) var(--cap-pad-h); 
-        rgb(var(--glass-tint) / var(--glass-a2)) 100% +                border-radius: var(--cap-radius);
-      ); +
-      backdrop-filter:         blur(var(--glass-blur)) saturate(var(--glass-sat)); +
-      -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat)); +
-      border: 1px solid rgb(255 255 255 / var(--glass-border-alpha)); +
-      border-top-color: rgb(255 255 255 / var(--glass-rim-alpha)); +
-      box-shadow: +
-        0 var(--glass-shadow-y) var(--glass-shadow-blur) rgb(0 0 0 / var(--glass-shadow-alpha)), +
-        inset 0  1px 0 rgb(255 255 255 / var(--glass-glow-alpha)), +
-        inset 0 -1px 0 rgb(0       / var(--glass-depth-alpha)); +
-      color: #fff; +
-      text-align: center; +
-      text-rendering: optimizeLegibility; +
-      transform: translateX(-50%) translateY(var(--cap-enter-y)); +
-      opacity: 0; +
-      transition: opacity var(--cap-dur) var(--cap-ease), +
-                  transform var(--cap-dur) var(--cap-ease); +
-      z-index: 2;+
  
-      & h3 { +                backgroundlinear-gradient( 
-        margin0 0 4px; +                    140deg, 
-        font-size: var(--t-title)+                    rgb(var(--glass-tint/ var(--glass-a1)) 0%, 
-        font-weight: 700; +                    rgb(var(--glass-tint) / var(--glass-a2)) 100% 
-        letter-spacing: 0.5px; +                );
-        line-height: 1.2; +
-        padding-bottom: 4px; +
-        border-bottom: 1px solid rgb(255 255 255 / .25); +
-        text-wrap: balance; +
-      }+
  
-      & p { +                backdrop-filterblur(var(--glass-blur)
-        margin: 0 0 10px; +                    saturate(var(--glass-sat));
-        font-size: var(--t-body); +
-        font-weight: 500; +
-        line-height: 1.5; +
-        text-wrap: balance; +
-      }+
  
-      & .slide-btn { +                -webkit-backdrop-filterblur(var(--glass-blur)
-        display: inline-block; +                    saturate(var(--glass-sat));
-        padding: .4em 1.2em; +
-        border-radius: 999px; +
-        background: var(--accent); +
-        color: #fff; +
-        font-size: var(--t-btn)+
-        font-weight: 600; +
-        text-decoration: none; +
-        box-shadow: 0 3px 8px rgb(0 0 0 / .28)+
-        transition: background .22s ease, transform .22s ease, box-shadow .22s ease;+
  
-        &:hover { +                border1px solid rgb(255 255 255 / var(--glass-border-alpha));
-          background: var(--accent-hover); +
-          transform: translateY(-2px)+
-          box-shadow: 0 6px 16px rgb(0 0 0 / .38); +
-        } +
-      } +
-    }+
  
-    .swiper-slide-active .slide-caption { +                border-top-colorrgb(255 255 255 / var(--glass-rim-alpha));
-      opacity1; +
-      transform: translateX(-50%translateY(0); +
-    }+
  
-    /* navtyped @property lets the gradient fill animate between states */ +                box-shadow
-    @property --nav-fill-a { +                    0 var(--glass-shadow-y) var(--glass-shadow-blur) 
-      syntax:        '<number>'; +                        rgb(0 0 0 / var(--glass-shadow-alpha)), 
-      inherits:      false; +                    inset 0 1px 0 rgb(255 255 255 / var(--glass-glow-alpha)), 
-      initial-value: 0; +                    inset 0 -1px rgb(0 0 0 / var(--glass-depth-alpha));
-    }+
  
-    .carousel-nav { +                color: #fff
-      -webkit-appearance: none; +                text-align: center; 
-      appearance: none; +                text-renderingoptimizeLegibility;
-      -webkit-tap-highlight-color: transparent+
-      user-select: none; +
-      -webkit-user-select: none; +
-      touch-action: manipulation; +
-      outline: none; +
-      border: none; +
-      padding: 0; +
-      margin: 0; +
-      position: absolute; +
-      top: 50%; +
-      z-index: 10; +
-      display: flex; +
-      align-items: center; +
-      justify-contentcenter; +
-      flex-shrink: 0; +
-      cursor: pointer; +
-      width: var(--nav-size); +
-      height: var(--nav-size); +
-      border-radius: 50%; +
-      --nav-fill-a: var(--nav-fill-default); +
-      background: linear-gradient( +
-        135deg, +
-        rgb(var(--nav-glass-tint) / var(--nav-fill-a)) 0%, +
-        rgb(var(--nav-glass-tint) / max(0, calc(var(--nav-fill-a) - 0.20))) 100% +
-      ); +
-      backdrop-filter:         blur(var(--nav-glass-blur)) saturate(var(--nav-glass-sat)); +
-      -webkit-backdrop-filter: blur(var(--nav-glass-blur)) saturate(var(--nav-glass-sat)); +
-      border: 1px solid rgb(255 255 255 / var(--nav-border-alpha)); +
-      border-top-color: rgb(255 255 255 / var(--nav-rim-alpha)); +
-      box-shadow: var(--nav-shadow), inset 0 1px 0 rgb(255 255 255 / var(--nav-glow-alpha)); +
-      color: #fff; +
-      transform: translateY(-50%); +
-      transition: --nav-fill-a .18s ease, box-shadow .18s ease, +
-                  transform var(--nav-dur) var(--nav-ease); +
-    }+
  
-    .carousel-nav::-moz-focus-inner { border: 0; padding: 0}+                transformtranslateX(-50%) translateY(var(--cap-enter-y));
  
-    .carousel-nav--prev { left var(--nav-offset)+                opacity0;
-    .carousel-nav--next { right: var(--nav-offset); }+
  
-    .carousel-nav:hover { +                transition
-      --nav-fill-a: var(--nav-fill-hover)+                    opacity var(--cap-dur) var(--cap-ease), 
-      box-shadow: var(--nav-shadow-hover), inset 0 1px 0 rgb(255 255 255 / var(--nav-glow-alpha)); +                    transform var(--cap-dur) var(--cap-ease);
-      transform: translateY(-50%) scale(var(--nav-hover-scale)); +
-      color: #fff; +
-    }+
  
-    .carousel-nav:active { +                z-index2
-      --nav-fill-a: var(--nav-fill-active); +            }
-      color: #fff; +
-      transform: translateY(-50%) scale(var(--nav-press-scale)); +
-      transition-duration: var(--nav-press-dur); +
-      transition-timing-function: ease+
-    }+
  
-    .carousel-nav:focus         outline: 0; } +            /* Scoped caption typography */ 
-    .carousel-nav:focus-visible { outline2px solid rgb(255 255 255 / .75); outline-offset: 3px; }+            #prom-swiper .slide-caption h3 { 
 +                margin: 0 0 4px
 +                padding-bottom4px; 
 +                border-bottom1px solid rgb(255 255 255 / 0.25);
  
-    .carousel-nav.swiper-button-disabled { opacity: .4cursornot-allowedpointer-eventsnone}+                font-size: var(--t-title); 
 +                font-weight700; 
 +                line-height: 1.2; 
 +                letter-spacing0.5px;
  
-    .carousel-nav svg { +                text-wrapbalance
-      strokecurrentColor; +            }
-      width: var(--nav-icon); +
-      height: var(--nav-icon); +
-      stroke-width: var(--nav-stroke); +
-      flex-shrink: 0; +
-      shape-rendering: geometricPrecision; +
-      filter: drop-shadow(0 1px 3px rgb(0 0 0 / .5))+
-    }+
  
-    .swiper-pagination-bullet +            #prom-swiper .slide-caption p 
-      transitiontransform .2s ease; +                margin0 0 10px;
-      &:hover { transform: scale(1.25);+
-    }+
  
-    @media (prefers-reduced-motion: reduce{ +                font-size: var(--t-body); 
-      .slide-caption, +                font-weight: 500; 
-      .swiper-slide-active .slide-caption, +                line-height: 1.5; 
-      .carousel-nav, +                letter-spacingnormal;
-      .swiper-pagination-bullet { transitionnone+
-    } +
-  </style> +
-</head>+
  
-<body> +                text-wrap: balance; 
-  <div class="carousel-wrapper"> +            }
-    <div class="swiper" id="prom-swiper"> +
-      <div class="swiper-wrapper"></div> +
-      <div class="swiper-pagination"></div>+
  
-      <button class="carousel-nav carousel-nav--prev" aria-label="Previous slide"> +            #prom-swiper .slide-caption .slide-btn { 
-        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" +                displayinline-block; 
-             fill="none" stroke="currentColor" +                padding: 0.4em 1.2em; 
-             stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> +                border-radius: 999px;
-          <path d="M10.5 19.5 3 12m0 7.5-7.5M3 12h18"/> +
-        </svg> +
-      </button>+
  
-      <button class="carousel-nav carousel-nav--next" aria-label="Next slide"> +                background: var(--accent); 
-        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" +                color#fff;
-             fill="none" stroke="currentColor" +
-             stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> +
-          <path d="M13.5 4.5 21 12m0 0-7.5 7.5M21 12H3"/> +
-        </svg> +
-      </button> +
-    </div> +
-  </div>+
  
-  <script type="module"> +                font-size: var(--t-btn); 
-    import Swiper from 'https://cdn.jsdelivr.net/npm/swiper@12/swiper-bundle.min.mjs';+                font-weight600; 
 +                line-height: normal;
  
-    const BASE = 'https://www2.meteo.uni-bonn.de/spp2115/lib/exe/fetch.php?media=slideshow:';+                text-decorationnone;
  
-    const slides = [ +                box-shadow0 3px 8px rgb(0 0 0.28);
-      { +
-        src:   'https://www2.meteo.uni-bonn.de/realpep/lib/exe/fetch.php?media=slideshow:prepep_group_cropped.jpg', +
-        alt:   'PrePEP Conference', +
-        title: 'PrePEP Conference', +
-        desc:  'From 17 to 21 March, the PrePEP conference offered 84 oral presentations including 9 invited keynotes, as well as a poster session on 18 March.', +
-        cta:   { href: 'https://indico.kit.edu/e/prepep', text: 'More Information' }, +
-      }, +
-      { +
-        src:   BASE + 'prom_leipzig_2024_slider_cropped.jpg', +
-        alt:   'PROM All-Hands Meeting 2024', +
-        title: 'PROM All-Hands Meeting 2024', +
-        desc:  'The PROM All-Hands Meeting 2024 took place in Leipzig on July 24-26 2024.', +
-      }, +
-      { +
-        src:   BASE + '2_sailandsnow.png', +
-        alt:   'CORSIPP', +
-        title: 'CORSIPP', +
-        desc:  'In the PROM sub-project CORSIPP, scientists from the University of Leipzig are exploring the orographically influenced riming of snow particles, the associated secondary ice production and its effects on precipitation rates.', +
-        cta:   { href: 'https://unileipzig.pageflow.io/in-search-of-snow-s-secrets', text: 'More Information' }, +
-      }, +
-      { +
-        src:   BASE + '0_17_19_july_2023.jpg', +
-        alt:   'SPP PROM All-Hands Meeting', +
-        title: 'SPP PROM All-Hands Meeting', +
-        desc:  'The last PROM all-hands meeting took place in Kiel on 17-19 July 2023.', +
-      }, +
-      { +
-        src:   BASE + '16hydrocolumn_en.jpg', +
-        alt:   'HydroColumn', +
-        title: 'HydroColumn', +
-        desc:  'Doppler spectra derived from new operational C-band birdbath scan indicating simultaneously occurring fast-falling rimed snow (mode 1) and slower-falling more pristine snow particles (mode 2).', +
-      }, +
-      { +
-        src:   BASE + '5_imprint_upscaled.png', +
-        alt:   'IMPRINT', +
-        title: 'IMPRINT', +
-        desc:  'First TRIPEx-pol measurement campaign combining triple-frequency radar, Doppler spectra, and polarimetry took place in winter 2018/19 in Jülich close to Cologne.', +
-      }, +
-      { +
-        src:   BASE + '18operationhydrometeors_en.jpg', +
-        alt:   'OperationHydrometeors', +
-        title: 'OperationHydrometeors', +
-        desc:  'In addition to the dominant hydrometeor type, polarimetry allows to derive hydrometeor partitioning ratios, defined as the relative mass contribution of a specific hydrometeor type.', +
-      }, +
-      { +
-        src:   BASE + '19police_en.jpg', +
-        alt:   'POLICE', +
-        title: 'POLICE', +
-        desc:  'Colocated radar and airborne in-situ measurements enable us to determine the accuracy of polarimetric microphysical retrievals. Recently developed ice water content retrievals show high correlation (0.96) and low RMSE=0.19g/.', +
-      }, +
-      { +
-        src:   BASE + '20redpol_en.jpg', +
-        alt:   'REDPOL', +
-        title: 'REDPOL', +
-        desc:  'Surface pressure tendency in nature run (left), after assimilation of radial wind and radar reflectivity with LETKF (middle) and with new integrated mass-flux adjustment filter (right).', +
-      }, +
-      { +
-        src:   BASE + '21wrad_en.jpg', +
-        alt:   'Phased-array Radar', +
-        title: 'Phased-array Radar', +
-        desc:  'Radiation diagram (3D) and cross-polar discrimination (projected) of a 4 by 4 sub-array tile of the forerunner phased-array weather radar prototype. Simulated (left) and measured results (right) at 45° scan angle.', +
-      }, +
-      { +
-        src:   BASE + '22para_en_crop.jpg', +
-        alt:   'PARA', +
-        title: 'PARA', +
-        desc:  'Ice (top) and snow contributions (bottom) to Quasi-Vertical-Profiles of reflectivity derived from BoXPol measurements assuming an exponential distribution.', +
-      }, +
-      { +
-        src:   BASE + '23ilacpr_en.jpg', +
-        alt:   'ILACPR', +
-        title: 'ILACPR', +
-        desc:  'Simulated (left) and observed (right) cross-sections of differential reflectivity (ZDR) for a summertime convective storm on 5 July 2015.', +
-      }, +
-      { +
-        src:   BASE + '24prom_icepolcka_dlr.jpg', +
-        alt:   'IcePolCKa', +
-        title: 'IcePolCKa', +
-        desc:  'Combined observations from C-band and Ka-band radars (POLDIRAD and miraMACS) allow to constrain the shape and size of aggregating snow particles.', +
-      }, +
-      { +
-        src:   BASE + '25pincicc.jpg', +
-        alt:   'PICNICC', +
-        title: 'PICNICC', +
-        desc:  'Retrievals of riming based on vertically-pointing 94 GHz cloud radar Doppler spectra observations and 35 GHz SLDR observations during PICNICC in Punta Arenas, Sep 11, 2019.', +
-      }, +
-    ];+
  
-    const renderSlide = ({ src, alt, title, desc, cta }, i) => `+                transition: 
 +                    background 0.22s ease, 
 +                    transform 0.22s ease, 
 +                    box-shadow 0.22s ease; 
 +            } 
 + 
 +            #prom-swiper .slide-caption .slide-btn:hover { 
 +                background: var(--accent-hover); 
 +                color: #fff; 
 +                transform: translateY(-2px); 
 +                box-shadow: 0 6px 16px rgb(0 0 0 / 0.38); 
 +            } 
 + 
 +            .swiper-slide-active .slide-caption { 
 +                opacity: 1; 
 +                transform: translateX(-50%) translateY(0); 
 +            } 
 + 
 +            /* Navigation */ 
 +            @property --nav-fill-a { 
 +                syntax: "<number>"; 
 +                inherits: false; 
 +                initial-value: 0; 
 +            } 
 + 
 +            .carousel-nav { 
 +                -webkit-appearance: none; 
 +                appearance: none; 
 +                -webkit-tap-highlight-color: transparent; 
 + 
 +                user-select: none; 
 +                -webkit-user-select: none; 
 +                touch-action: manipulation; 
 + 
 +                outline: none; 
 +                border: none; 
 +                padding: 0; 
 +                margin: 0; 
 + 
 +                position: absolute; 
 +                top: 50%; 
 +                z-index: 10; 
 + 
 +                display: flex; 
 +                align-items: center; 
 +                justify-content: center; 
 +                flex-shrink: 0; 
 + 
 +                cursor: pointer; 
 + 
 +                width: var(--nav-size); 
 +                height: var(--nav-size); 
 +                border-radius: 50%; 
 + 
 +                --nav-fill-a: var(--nav-fill-default); 
 + 
 +                background: linear-gradient( 
 +                    135deg, 
 +                    rgb(var(--nav-glass-tint) / var(--nav-fill-a)) 0%, 
 +                    rgb( 
 +                            var(--nav-glass-tint) / 
 +                                max(0, calc(var(--nav-fill-a) - 0.2)) 
 +                        ) 
 +                        100% 
 +                ); 
 + 
 +                backdrop-filter: blur(var(--nav-glass-blur)) 
 +                    saturate(var(--nav-glass-sat)); 
 + 
 +                -webkit-backdrop-filter: blur(var(--nav-glass-blur)) 
 +                    saturate(var(--nav-glass-sat)); 
 + 
 +                border: 1px solid rgb(255 255 255 / var(--nav-border-alpha)); 
 + 
 +                border-top-color: rgb(255 255 255 / var(--nav-rim-alpha)); 
 + 
 +                box-shadow: 
 +                    var(--nav-shadow), 
 +                    inset 0 1px 0 rgb(255 255 255 / var(--nav-glow-alpha)); 
 + 
 +                color: #fff; 
 + 
 +                transform: translateY(-50%); 
 + 
 +                transition: 
 +                    --nav-fill-a 0.18s ease, 
 +                    box-shadow 0.18s ease, 
 +                    transform var(--nav-dur) var(--nav-ease); 
 +            } 
 + 
 +            .carousel-nav::-moz-focus-inner { 
 +                border: 0; 
 +                padding: 0; 
 +            } 
 + 
 +            .carousel-nav--prev { 
 +                left: var(--nav-offset); 
 +            } 
 + 
 +            .carousel-nav--next { 
 +                right: var(--nav-offset); 
 +            } 
 + 
 +            .carousel-nav:hover { 
 +                --nav-fill-a: var(--nav-fill-hover); 
 + 
 +                box-shadow: 
 +                    var(--nav-shadow-hover), 
 +                    inset 0 1px 0 rgb(255 255 255 / var(--nav-glow-alpha)); 
 + 
 +                color: #fff; 
 + 
 +                transform: translateY(-50%) scale(var(--nav-hover-scale)); 
 +            } 
 + 
 +            .carousel-nav:active { 
 +                --nav-fill-a: var(--nav-fill-active); 
 + 
 +                color: #fff; 
 + 
 +                transform: translateY(-50%) scale(var(--nav-press-scale)); 
 + 
 +                transition-duration: var(--nav-press-dur); 
 +                transition-timing-function: ease; 
 +            } 
 + 
 +            .carousel-nav:focus { 
 +                outline: 0; 
 +            } 
 + 
 +            .carousel-nav:focus-visible { 
 +                outline: 2px solid rgb(255 255 255 / 0.75); 
 +                outline-offset: 3px; 
 +            } 
 + 
 +            .carousel-nav.swiper-button-disabled { 
 +                opacity: 0.4; 
 +                cursor: not-allowed; 
 +                pointer-events: none; 
 +            } 
 + 
 +            .carousel-nav svg { 
 +                width: var(--nav-icon); 
 +                height: var(--nav-icon); 
 + 
 +                flex-shrink: 0; 
 + 
 +                stroke: currentColor; 
 +                stroke-width: var(--nav-stroke); 
 + 
 +                shape-rendering: geometricPrecision; 
 + 
 +                filter: drop-shadow(0 1px 3px rgb(0 0 0 / 0.5)); 
 +            } 
 + 
 +            /* Pagination */ 
 +            .swiper-pagination-bullet { 
 +                transition: transform 0.2s ease; 
 + 
 +                &:hover { 
 +                    transform: scale(1.25); 
 +                } 
 +            } 
 + 
 +            /* Reduced motion */ 
 +            @media (prefers-reduced-motion: reduce) { 
 +                .slide-caption, 
 +                .swiper-slide-active .slide-caption, 
 +                .carousel-nav, 
 +                .swiper-pagination-bullet { 
 +                    transition: none; 
 +                } 
 +            } 
 +        </style> 
 +    </head> 
 + 
 +    <body> 
 +        <div class="carousel-wrapper"> 
 +            <div class="swiper" id="prom-swiper"> 
 +                <div class="swiper-wrapper"></div> 
 +                <div class="swiper-pagination"></div> 
 + 
 +                <button 
 +                    class="carousel-nav carousel-nav--prev" 
 +                    aria-label="Previous slide" 
 +                > 
 +                    <svg 
 +                        xmlns="http://www.w3.org/2000/svg" 
 +                        viewBox="0 0 24 24" 
 +                        fill="none" 
 +                        stroke="currentColor" 
 +                        stroke-linecap="round" 
 +                        stroke-linejoin="round" 
 +                        aria-hidden="true" 
 +                    > 
 +                        <path d="M10.5 19.5 3 12m0 0 7.5-7.5M3 12h18" /> 
 +                    </svg> 
 +                </button> 
 + 
 +                <button 
 +                    class="carousel-nav carousel-nav--next" 
 +                    aria-label="Next slide" 
 +                > 
 +                    <svg 
 +                        xmlns="http://www.w3.org/2000/svg" 
 +                        viewBox="0 0 24 24" 
 +                        fill="none" 
 +                        stroke="currentColor" 
 +                        stroke-linecap="round" 
 +                        stroke-linejoin="round" 
 +                        aria-hidden="true" 
 +                    > 
 +                        <path d="M13.5 4.5 21 12m0 0-7.5 7.5M21 12H3" /> 
 +                    </svg> 
 +                </button> 
 +            </div> 
 +        </div> 
 + 
 +        <script type="module"> 
 +            import Swiper from "https://cdn.jsdelivr.net/npm/swiper@12/swiper-bundle.min.mjs"; 
 + 
 +            const BASE = 
 +                "https://www2.meteo.uni-bonn.de/spp2115/lib/exe/fetch.php?media=slideshow:"; 
 + 
 +            const slides = [ 
 +                { 
 +                    src: "https://www2.meteo.uni-bonn.de/realpep/lib/exe/fetch.php?media=slideshow:prepep_group_cropped.jpg", 
 +                    alt: "PrePEP Conference", 
 +                    title: "PrePEP Conference", 
 +                    desc: "From 17 to 21 March, the PrePEP conference offered 84 oral presentations including 9 invited keynotes, as well as a poster session on 18 March.", 
 +                    cta: { 
 +                        href: "https://indico.kit.edu/e/prepep", 
 +                        text: "More Information", 
 +                    }, 
 +                }, 
 +                { 
 +                    src: BASE + "prom_leipzig_2024_slider_cropped.jpg", 
 +                    alt: "PROM All-Hands Meeting 2024", 
 +                    title: "PROM All-Hands Meeting 2024", 
 +                    desc: "The PROM All-Hands Meeting 2024 took place in Leipzig on July 24-26 2024.", 
 +                }, 
 +                { 
 +                    src: BASE + "2_sailandsnow.png", 
 +                    alt: "CORSIPP", 
 +                    title: "CORSIPP", 
 +                    desc: "In the PROM sub-project CORSIPP, scientists from the University of Leipzig are exploring the orographically influenced riming of snow particles, the associated secondary ice production and its effects on precipitation rates.", 
 +                    cta: { 
 +                        href: "https://unileipzig.pageflow.io/in-search-of-snow-s-secrets", 
 +                        text: "More Information", 
 +                    }, 
 +                }, 
 +                { 
 +                    src: BASE + "0_17_19_july_2023.jpg", 
 +                    alt: "SPP PROM All-Hands Meeting", 
 +                    title: "SPP PROM All-Hands Meeting", 
 +                    desc: "The last PROM all-hands meeting took place in Kiel on 17-19 July 2023.", 
 +                }, 
 +                { 
 +                    src: BASE + "16hydrocolumn_en.jpg", 
 +                    alt: "HydroColumn", 
 +                    title: "HydroColumn", 
 +                    desc: "Doppler spectra derived from new operational C-band birdbath scan indicating simultaneously occurring fast-falling rimed snow (mode 1) and slower-falling more pristine snow particles (mode 2).", 
 +                }, 
 +                { 
 +                    src: BASE + "5_imprint_upscaled.png", 
 +                    alt: "IMPRINT", 
 +                    title: "IMPRINT", 
 +                    desc: "First TRIPEx-pol measurement campaign combining triple-frequency radar, Doppler spectra, and polarimetry took place in winter 2018/19 in Jülich close to Cologne.", 
 +                }, 
 +                { 
 +                    src: BASE + "18operationhydrometeors_en.jpg", 
 +                    alt: "OperationHydrometeors", 
 +                    title: "OperationHydrometeors", 
 +                    desc: "In addition to the dominant hydrometeor type, polarimetry allows to derive hydrometeor partitioning ratios, defined as the relative mass contribution of a specific hydrometeor type.", 
 +                }, 
 +                { 
 +                    src: BASE + "19police_en.jpg", 
 +                    alt: "POLICE", 
 +                    title: "POLICE", 
 +                    desc: "Colocated radar and airborne in-situ measurements enable us to determine the accuracy of polarimetric microphysical retrievals. Recently developed ice water content retrievals show high correlation (0.96) and low RMSE=0.19g/m³.", 
 +                }, 
 +                { 
 +                    src: BASE + "20redpol_en.jpg", 
 +                    alt: "REDPOL", 
 +                    title: "REDPOL", 
 +                    desc: "Surface pressure tendency in nature run (left), after assimilation of radial wind and radar reflectivity with LETKF (middle) and with new integrated mass-flux adjustment filter (right).", 
 +                }, 
 +                { 
 +                    src: BASE + "21wrad_en.jpg", 
 +                    alt: "Phased-array Radar", 
 +                    title: "Phased-array Radar", 
 +                    desc: "Radiation diagram (3D) and cross-polar discrimination (projected) of a 4 by 4 sub-array tile of the forerunner phased-array weather radar prototype. Simulated (left) and measured results (right) at 45° scan angle.", 
 +                }, 
 +                { 
 +                    src: BASE + "22para_en_crop.jpg", 
 +                    alt: "PARA", 
 +                    title: "PARA", 
 +                    desc: "Ice (top) and snow contributions (bottom) to Quasi-Vertical-Profiles of reflectivity derived from BoXPol measurements assuming an exponential distribution.", 
 +                }, 
 +                { 
 +                    src: BASE + "23ilacpr_en.jpg", 
 +                    alt: "ILACPR", 
 +                    title: "ILACPR", 
 +                    desc: "Simulated (left) and observed (right) cross-sections of differential reflectivity (ZDR) for a summertime convective storm on 5 July 2015.", 
 +                }, 
 +                { 
 +                    src: BASE + "24prom_icepolcka_dlr.jpg", 
 +                    alt: "IcePolCKa", 
 +                    title: "IcePolCKa", 
 +                    desc: "Combined observations from C-band and Ka-band radars (POLDIRAD and miraMACS) allow to constrain the shape and size of aggregating snow particles.", 
 +                }, 
 +                { 
 +                    src: BASE + "25pincicc.jpg", 
 +                    alt: "PICNICC", 
 +                    title: "PICNICC", 
 +                    desc: "Retrievals of riming based on vertically-pointing 94 GHz cloud radar Doppler spectra observations and 35 GHz SLDR observations during PICNICC in Punta Arenas, Sep 11, 2019.", 
 +                }, 
 +            ]; 
 + 
 +            const renderSlide = ({ src, alt, title, desc, cta }, i) => `
       <div class="swiper-slide">       <div class="swiper-slide">
-        <img src="${src}" alt="${alt}"${i >= 2 ? ' loading="lazy" decoding="async"'''}>+        <img src="${src}" alt="${alt}"${i >= 2 ? ' loading="lazy" decoding="async"'""}>
         <div class="slide-caption">         <div class="slide-caption">
           <h3>${title}</h3>           <h3>${title}</h3>
           <p>${desc}</p>           <p>${desc}</p>
-          ${cta ? `<a class="slide-btn" href="${cta.href}" target="_blank" rel="noopener noreferrer">${cta.text}</a>` : ''}+          ${cta ? `<a class="slide-btn" href="${cta.href}" target="_blank" rel="noopener noreferrer">${cta.text}</a>` : ""}
         </div>         </div>
       </div>`;       </div>`;
  
-    document.querySelector('#prom-swiper .swiper-wrapper').innerHTML = +            document.querySelector("#prom-swiper .swiper-wrapper").innerHTML = 
-      slides.map(renderSlide).join('');+                slides.map(renderSlide).join("");
  
-    // prevent focus-on-click so the button never turns white after clicking +            // prevent focus-on-click so the button never turns white after clicking 
-    document.querySelectorAll('.carousel-nav').forEach(btn => +            document 
-      btn.addEventListener('mousedown', e => e.preventDefault()) +                .querySelectorAll(".carousel-nav") 
-    );+                .forEach((btn=> 
 +                    btn.addEventListener("mousedown"(e=> 
 +                        e.preventDefault()
 +                    ), 
 +                );
  
-    // shrink each caption to hug its balanced text: target = maxContent / lineCount + buffer +            // shrink each caption to hug its balanced text: target = maxContent / lineCount + buffer 
-    function fitCaptionsToBalancedText() { +            function fitCaptionsToBalancedText() { 
-      const captions = [...document.querySelectorAll('.slide-caption')]; +                const captions = [ 
-      if (!captions.length) return;+                    ...document.querySelectorAll(".slide-caption")
 +                ]; 
 +                if (!captions.length) return;
  
-      captions.forEach(c => (c.style.width = '')); +                captions.forEach((c=> (c.style.width = "")); 
-      void document.body.getBoundingClientRect();+                void document.body.getBoundingClientRect();
  
-      const info = captions.map(caption => { +                const info = captions.map((caption=> { 
-        let maxLines = 0; +                    let maxLines = 0; 
-        caption.querySelectorAll('h3, p').forEach(el => { +                    caption.querySelectorAll("h3, p").forEach((el=> { 
-          const lh = parseFloat(getComputedStyle(el).lineHeight); +                        const lh = parseFloat(getComputedStyle(el).lineHeight); 
-          if (!lh) return; +                        if (!lh) return; 
-          const lines = Math.round(el.getBoundingClientRect().height / lh); +                        const lines = Math.round( 
-          if (lines > maxLines) maxLines = lines; +                            el.getBoundingClientRect().height / lh
-        }); +                        ); 
-        return { caption, maxLines }; +                        if (lines > maxLines) maxLines = lines; 
-      });+                    }); 
 +                    return { caption, maxLines }; 
 +                });
  
-      const textEls = [...document.querySelectorAll( +                const textEls = [ 
-        '#prom-swiper .slide-caption h3, #prom-swiper .slide-caption p' +                    ...document.querySelectorAll( 
-      )]; +                        "#prom-swiper .slide-caption h3, #prom-swiper .slide-caption p", 
-      textEls.forEach(el => (el.style.whiteSpace = 'nowrap')); +                    )
-      void document.body.getBoundingClientRect();+                ]; 
 +                textEls.forEach((el=> (el.style.whiteSpace = "nowrap")); 
 +                void document.body.getBoundingClientRect();
  
-      info.forEach(d => { +                info.forEach((d=> { 
-        d.maxContent = 0; +                    d.maxContent = 0; 
-        d.caption.querySelectorAll('h3, p').forEach(el => { +                    d.caption.querySelectorAll("h3, p").forEach((el=> { 
-          if (el.scrollWidth > d.maxContent) d.maxContent = el.scrollWidth; +                        if (el.scrollWidth > d.maxContent) 
-        }); +                            d.maxContent = el.scrollWidth; 
-        const btn = d.caption.querySelector('.slide-btn'); +                    }); 
-        d.btnW = btn ? btn.getBoundingClientRect().width : 0; +                    const btn = d.caption.querySelector(".slide-btn"); 
-      });+                    d.btnW = btn ? btn.getBoundingClientRect().width : 0; 
 +                });
  
-      textEls.forEach(el => (el.style.whiteSpace = ''));+                textEls.forEach((el=> (el.style.whiteSpace = ""));
  
-      info.forEach(({ caption, maxLines, maxContent, btnW }) => { +                info.forEach(({ caption, maxLines, maxContent, btnW }) => { 
-        if (maxLines <= 1 || !maxContent) return; +                    if (maxLines <= 1 || !maxContent) return; 
-        const cs      = getComputedStyle(caption); +                    const cs = getComputedStyle(caption); 
-        const buffer  = parseFloat(cs.getPropertyValue('--cap-shrink-buffer')) || 0; +                    const buffer = 
-        const padH    = parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight); +                        parseFloat( 
-        const contentW = Math.max(maxContent / maxLines + buffer, btnW); +                            cs.getPropertyValue("--cap-shrink-buffer")
-        caption.style.width = `${Math.ceil(contentW + padH)}px`; +                        ) || 0; 
-      }); +                    const padH = 
-    }+                        parseFloat(cs.paddingLeft) + 
 +                        parseFloat(cs.paddingRight); 
 +                    const contentW = Math.max( 
 +                        maxContent / maxLines + buffer, 
 +                        btnW
 +                    ); 
 +                    caption.style.width = `${Math.ceil(contentW + padH)}px`; 
 +                }); 
 +            }
  
-    const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;+            const reducedMotion = window.matchMedia( 
 +                "(prefers-reduced-motion: reduce)", 
 +            ).matches;
  
-    const swiper = new Swiper('#prom-swiper', { +            const swiper = new Swiper("#prom-swiper", { 
-      loop:       true, +                loop: true, 
-      speed:      reducedMotion ? 1 : 700, +                speed: reducedMotion ? 1 : 700, 
-      grabCursor: true, +                grabCursor: true, 
-      effect:     'fade'+                effect: "fade"
-      fadeEffect: { crossFade: true },+                fadeEffect: { crossFade: true },
  
-      autoplay: { +                autoplay: { 
-        delay:                20000, +                    delay: 20000, 
-        disableOnInteraction: false, +                    disableOnInteraction: false, 
-        pauseOnMouseEnter:    true, +                    pauseOnMouseEnter: true, 
-      },+                },
  
-      pagination: { +                pagination: { 
-        el:             '.swiper-pagination'+                    el: ".swiper-pagination"
-        clickable:      true, +                    clickable: true, 
-        dynamicBullets: true, +                    dynamicBullets: true, 
-      },+                },
  
-      navigation: { +                navigation: { 
-        prevEl: '.carousel-nav--prev'+                    prevEl: ".carousel-nav--prev"
-        nextEl: '.carousel-nav--next'+                    nextEl: ".carousel-nav--next"
-      },+                },
  
-      keyboard: { enabled: true, onlyInViewport: true },+                keyboard: { enabled: true, onlyInViewport: true },
  
-      a11y: { +                a11y: { 
-        prevSlideMessage:        'Previous slide'+                    prevSlideMessage: "Previous slide"
-        nextSlideMessage:        'Next slide'+                    nextSlideMessage: "Next slide"
-        paginationBulletMessage: 'Go to slide {{index}}'+                    paginationBulletMessage: "Go to slide {{index}}"
-      }, +                }, 
-    });+            });
  
-    fitCaptionsToBalancedText();+            fitCaptionsToBalancedText();
  
-    let resizeTimer; +            let resizeTimer; 
-    window.addEventListener('resize', () => { +            window.addEventListener("resize", () => { 
-      clearTimeout(resizeTimer); +                clearTimeout(resizeTimer); 
-      resizeTimer = setTimeout(fitCaptionsToBalancedText, 150); +                resizeTimer = setTimeout(fitCaptionsToBalancedText, 150); 
-    });+            });
  
-    // promote GPU layers only during the cross-fade, release at rest +            // promote GPU layers only during the cross-fade, release at rest 
-    const imgs = [...document.querySelectorAll('#prom-swiper .swiper-slide img')]; +            const imgs = [ 
-    const setWC = v => imgs.forEach(img => (img.style.willChange = v)); +                ...document.querySelectorAll("#prom-swiper .swiper-slide img")
-    swiper.on('slideChangeTransitionStart', () => setWC('opacity')); +            ]; 
-    swiper.on('slideChangeTransitionEnd'  () => setWC('auto'));+            const setWC = (v=> 
 +                imgs.forEach((img=> (img.style.willChange = v)); 
 +            swiper.on("slideChangeTransitionStart", () => setWC("opacity")); 
 +            swiper.on("slideChangeTransitionEnd", () => setWC("auto"));
  
-    // pause autoplay when scrolled out of view +            // pause autoplay when scrolled out of view 
-    new IntersectionObserver( +            new IntersectionObserver( 
-      ([entry]) => entry.isIntersecting +                ([entry]) => 
-        ? swiper.autoplay.start() +                    entry.isIntersecting 
-        : swiper.autoplay.stop(), +                        ? swiper.autoplay.start() 
-      { threshold: 0.2 } +                        : swiper.autoplay.stop(), 
-    ).observe(document.getElementById('prom-swiper')); +                { threshold: 0.2 }, 
-  </script> +            ).observe(document.getElementById("prom-swiper")); 
-</body>+        </script> 
 +    </body>
 </html> </html>
 +
  • components/carousel/glass.txt
  • Last modified: 2026/09/16 02:59
  • by ayush