/* ==========================================================================
   MTD Performance - pages.css
   The pieces that arrived with the group-site restructure and do not belong
   to the shared chrome in site.css.

   Table of contents
    1. The intro overlay (index.html only, once per session)
    2. The hero video slider
    3. The Events and Edukasi teaser row
    4. Reduced motion for both
   ========================================================================== */

/* ==========================================================================
   1. The intro overlay
   A full-viewport sheet in the canvas colour, 1.6 seconds, transform and
   opacity only plus one clip-path wipe. intro.js writes html.intro-on the
   moment it decides the intro runs, so the page never paints the hero first.
   The mark is the full MTD Performance logo, the red MTD block with
   PERFORMANCE set under it, wiped in as one piece. There is no skip button:
   the overlay is gone in 1.6 seconds, Escape lifts it early, and it never
   returns in the same session.
   ========================================================================== */

/* the body fade-in belongs to the page, not to the intro: while the overlay
   is up the page is already there, underneath it */
html.intro-on body{opacity:1;transition:none}
html.intro-lock,html.intro-lock body{overflow:hidden}

.intro{
  position:fixed;inset:0;z-index:200;
  /* pure black, the restyle's canvas. The token carries the same value; the
     literal keeps the sheet black even before a theme edit lands. */
  background:#000;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  transform:translateY(0);
  will-change:transform;
}
.intro.is-lifting{
  transform:translateY(-100%);
  transition:transform .4s var(--ease-in-out);
}

.intro-stage{
  display:flex;flex-direction:column;align-items:center;
  padding-inline:var(--gutter);
}

/* 0.0 to 0.7s: the full logo is revealed left to right by a clip-path wipe,
   with the rake riding the top edge of the red block */
.intro-mark{
  position:relative;
  width:min(400px,68vw);
}
.intro-crop{
  overflow:hidden;
  aspect-ratio:1103 / 451;
}
.intro-crop img{
  width:100%;height:auto;display:block;
  clip-path:inset(0 100% 0 0);
  animation:intro-wipe .7s var(--ease-out) forwards;
}
.intro-rake{
  position:absolute;left:0;right:0;top:3%;height:1px;
  background:linear-gradient(90deg,rgba(255,255,255,0) 0%,rgba(255,255,255,.95) 50%,rgba(255,255,255,0) 100%);
  opacity:0;
  transform:translateX(-100%);
  animation:intro-rake .7s var(--ease-out) forwards;
}

@keyframes intro-wipe{
  from{clip-path:inset(0 100% 0 0)}
  to{clip-path:inset(0 0 0 0)}
}
@keyframes intro-rake{
  0%{opacity:0;transform:translateX(-100%)}
  18%{opacity:1}
  82%{opacity:1}
  100%{opacity:0;transform:translateX(100%)}
}

/* 0.8 to 1.1s: the speed streak crosses once under the logo. This is the
   single streak use on the page: when the intro runs, the rail lock reuses
   the same state and never fires a second one. The restyle is black and red
   only, so the streak carries the divider motif's red-white-red grade
   instead of the old red-orange-yellow one. */
.intro-streak{
  position:absolute;left:0;right:0;bottom:-14px;height:3px;border-radius:2px;
  background:linear-gradient(90deg,var(--accent) 0%,#FFFFFF 55%,var(--accent) 100%);
  opacity:0;
  transform:translateX(-120%) scaleX(.4);
  transform-origin:left;
  animation:intro-streak .3s var(--ease-out) .8s forwards;
}
@keyframes intro-streak{
  0%{opacity:0;transform:translateX(-120%) scaleX(.4)}
  30%{opacity:1}
  70%{opacity:1}
  100%{opacity:0;transform:translateX(120%) scaleX(.4)}
}

/* ==========================================================================
   2. The hero video slider
   Full viewport, one muted looping film per slide. The restyle centres the
   composition the way the group's own page does: the copy stack sits in the
   lower band of the viewport, centred, over a bottom-up wash and a centred
   radial. Nothing about the slider's behaviour changes with it.
   ========================================================================== */

.hero-slider{
  position:relative;
  height:100vh;height:100svh;
  min-height:560px;
  overflow:hidden;
  isolation:isolate;
  background:#000;
  touch-action:pan-y;
}

.hs-viewport{position:absolute;inset:0}

.hs-slide{
  position:absolute;inset:0;
  opacity:0;
  visibility:hidden;
  transition:opacity .9s var(--ease-out),visibility 0s linear .9s;
}
.hs-slide.is-active{
  opacity:1;
  visibility:visible;
  transition:opacity .9s var(--ease-out),visibility 0s;
  z-index:1;
}

/* --- the film ---------------------------------------------------------- */

.hs-media{position:absolute;inset:0;overflow:hidden}
.hs-poster,
.hs-media video{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;
  transform:scale(1.055);
  transition:transform 7s linear;
}
.hs-slide.is-active .hs-poster,
.hs-slide.is-active .hs-media video{transform:scale(1)}
.hs-media video{opacity:0;transition:opacity .8s var(--ease-out),transform 7s linear}
.hs-slide.is-playing .hs-media video{opacity:1}

/* the portrait film sits in a centred frame, with its own poster blurred and
   darkened behind it, so no letterbox bars ever show */
.hs-slide--portrait .hs-back{
  position:absolute;inset:-6%;
  background-position:center;background-size:cover;background-repeat:no-repeat;
  filter:blur(38px) brightness(.42) saturate(.85);
}
/* the frame is pinned to the top of the stage rather than the middle, and it
   is narrow enough that the centred copy band below starts under its lower
   third instead of across the face of the film: top at the header plus 3vh,
   width min(34vh,80vw). On phones it goes full bleed again, further down. */
.hs-slide--portrait .hs-frame{
  position:absolute;top:calc(var(--nav-h) + 3vh);left:50%;
  width:min(34vh,80vw);
  aspect-ratio:540 / 960;
  transform:translateX(-50%);
  overflow:hidden;
  border-radius:var(--radius);
  box-shadow:0 40px 90px -40px rgba(0,0,0,.95);
}
.hs-slide--portrait .hs-frame .hs-poster,
.hs-slide--portrait .hs-frame video{transform:none;transition:opacity .8s var(--ease-out)}

/* --- the two-layer legibility system ----------------------------------- */

/* the base wash runs bottom-up, the way the group's page grades its hero:
   heaviest under the copy band, almost clear across the middle of the frame
   where the product sits, and a light top veil so the header reads. */
.hs-scrim{
  position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(to top,
    rgba(0,0,0,.88) 0%,rgba(0,0,0,.55) 36%,rgba(0,0,0,.18) 62%,rgba(0,0,0,.35) 100%);
}
/* the local wash is centred under the copy now, not anchored bottom-left:
   an ellipse whose core sits on the copy band and falls off before it
   reaches the middle of the frame */
/* the ellipse is sized in px off the bottom edge rather than in percentages
   of the viewport: the copy band is a fixed height above the floor, so a
   percentage wash slides out from under it the moment the viewport gets
   short. At 1024x768 the percentage version left the kicker at 3.5:1 and at
   820x420 at 1.5:1; this one holds every height with the same numbers. */
.hs-scrim-local{
  position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(ellipse 105vw 520px at 50% calc(100% - 117px),
    rgba(0,0,0,.94) 0%,rgba(0,0,0,.9) 40%,rgba(0,0,0,.8) 60%,
    rgba(0,0,0,.55) 74%,rgba(0,0,0,.22) 88%,rgba(0,0,0,0) 100%);
}
/* slide 1's composite is a cutout on this same pure black, so the film itself
   brings almost nothing bright into the copy band: the widest wash the other
   three need would only be darkening the product's own face. This one is
   measured against that composite instead, and the unit keeps its contrast. */
.hs-slide--photo .hs-scrim-local{
  background:radial-gradient(ellipse 95vw 468px at 50% calc(100% - 108px),
    rgba(0,0,0,.9) 0%,rgba(0,0,0,.84) 42%,rgba(0,0,0,.66) 64%,
    rgba(0,0,0,.3) 82%,rgba(0,0,0,0) 96%);
}

/* --- the copy block, centred in the lower band ------------------------- */

/* the stack sits in the lower band of the viewport: its last row ends 10vh
   off the floor, clear of the dot rail below it, and the kicker rides up from
   there. Measured at 1440x900 the band runs 55 to 89 percent of the viewport
   height on slides 1, 3 and 4 and 50 to 89 on slide 2, which carries two
   sublines. */
.hs-copy-wrap{
  position:absolute;inset:auto 0 0 0;
  padding-bottom:clamp(100px,10vh,140px);
  pointer-events:none;
}
.hs-copy{
  margin:0 auto;
  text-align:center;
  max-width:min(880px,92%);
  text-shadow:var(--tshadow);
  pointer-events:auto;
}
.hs-copy .btn{text-shadow:none}

/* the kicker rides the top of the copy block, the row the wash reaches last
   and where the film is still brightest. Measured against the composited
   frames of all four slides, --accent runs 2.5:1 to 4.0:1 there and cannot
   reach 4.5:1 even on pure black, so over film the kicker uses the lightened
   --accent-on-media instead. The kickers on the flat surfaces use
   --accent-label, the same value under its own name. */
.hs-kicker{
  display:block;
  font-family:var(--mono);font-size:11.5px;font-weight:600;
  letter-spacing:.2em;text-transform:uppercase;color:var(--accent-on-media);
  margin-bottom:16px;
}
/* Saira italic 800, uppercase, the leaning wordmark's own posture. The ch cap
   is set on the headline itself, so it is measured in the display face. */
.hs-headline{
  font-family:var(--display);
  font-style:italic;font-weight:800;
  text-transform:uppercase;
  font-size:clamp(38px,5.6vw,72px);
  letter-spacing:-.01em;
  max-width:18ch;
  margin-inline:auto;
  padding-bottom:.08em;
}
.hl-red{color:var(--accent)}
.hs-subline{
  display:block;
  margin-top:16px;
  margin-inline:auto;
  color:var(--text-primary);
  font-size:clamp(15px,.5vw + 13px,18px);
  max-width:62ch;
}
/* the second subline on slide 2 is the quieter half of the pair */
.hs-subline + .hs-subline{
  margin-top:12px;
  color:var(--text-secondary);
  font-size:clamp(14px,.35vw + 12.5px,16px);
}
.hs-copy .btn-row{margin-top:26px;justify-content:center}

/* entrance: the copy arrives in sequence behind its slide, and the stagger
   delays are retired the moment the slide has settled, so a hover on the
   second button never lags by the stagger */
.hs-copy > *{
  opacity:0;
  transform:translateY(18px);
  transition:opacity .7s var(--ease-out),transform .7s var(--ease-out);
}
.hs-slide.is-active .hs-copy > *{opacity:1;transform:none}
.hs-slide.is-active .hs-copy > *:nth-child(1){transition-delay:.18s}
.hs-slide.is-active .hs-copy > *:nth-child(2){transition-delay:.28s}
.hs-slide.is-active .hs-copy > *:nth-child(3){transition-delay:.38s}
.hs-slide.is-active .hs-copy > *:nth-child(4){transition-delay:.48s}
/* slide 2 carries five children (two sublines), so the stagger and its
   retirement both have to run one step further or the button row keeps the
   fourth step's delay on every later hover */
.hs-slide.is-active .hs-copy > *:nth-child(5){transition-delay:.58s}
.hs-slide.is-active.is-settled .hs-copy > *:nth-child(1),
.hs-slide.is-active.is-settled .hs-copy > *:nth-child(2),
.hs-slide.is-active.is-settled .hs-copy > *:nth-child(3),
.hs-slide.is-active.is-settled .hs-copy > *:nth-child(4),
.hs-slide.is-active.is-settled .hs-copy > *:nth-child(5){transition-delay:0s}

/* the copy is centred on the viewport now, so it does not step around the
   arrows: it is capped so it never reaches them. The lane each arrow needs is
   its offset plus its 48px width plus a 20px gap, and above 1024 the rail
   pushes the left arrow inward by its own width. */
@media (min-width:721px){
  .hs-copy{
    max-width:min(880px,calc(100vw - 2 * (clamp(14px,2.4vw,30px) + 68px)));
  }
}
@media (min-width:1024px) and (min-height:561px){
  .hs-copy{
    max-width:min(880px,calc(100vw - 2 * (var(--rail-w) + clamp(14px,2.4vw,30px) + 68px)));
  }
}

/* --- controls ---------------------------------------------------------- */

.hs-arrow{
  position:absolute;top:50%;z-index:4;
  width:48px;height:48px;
  transform:translateY(-50%);
  display:inline-flex;align-items:center;justify-content:center;
  border:1px solid var(--line-interactive);border-radius:50%;
  background:rgba(0,0,0,.5);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  color:var(--text-secondary);
  cursor:pointer;
  transition:color .26s var(--ease-out),border-color .26s var(--ease-out),
             background-color .26s var(--ease-out),transform .26s var(--ease-out);
}
.hs-arrow:hover{color:var(--text-primary);border-color:var(--accent);background:rgba(0,0,0,.78)}
.hs-arrow svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.hs-prev{left:clamp(14px,2.4vw,30px)}
.hs-next{right:clamp(14px,2.4vw,30px)}
.hs-prev:hover{transform:translate(-2px,-50%)}
.hs-next:hover{transform:translate(2px,-50%)}

/* the REL VOLTASE rail is armed at exactly this gate, and its hit blocks are a
   full --rail-w wide over the left edge at z-index 80. The hero sets
   isolation:isolate, so the arrow cannot be raised above them: it moves clear
   of the rail instead, the same way the copy lane already does. */
@media (min-width:1024px) and (min-height:561px){
  .hs-prev{left:calc(var(--rail-w) + clamp(14px,2.4vw,30px))}
}

.hs-dots{
  position:absolute;left:0;right:0;bottom:clamp(24px,3.6vh,44px);z-index:4;
  display:flex;align-items:center;justify-content:center;gap:10px;
  padding-inline:var(--gutter);
}
.hs-dotset{display:flex;align-items:center;gap:10px;min-width:0}
.hs-dot{
  position:relative;
  width:64px;height:44px;
  display:inline-flex;align-items:center;
  cursor:pointer;
  background:none;border:0;padding:0;
}
.hs-dot-track{
  position:relative;display:block;width:100%;height:3px;border-radius:2px;
  background:rgba(255,255,255,.26);
  overflow:hidden;
}
.hs-dot:hover .hs-dot-track{background:rgba(255,255,255,.42)}
.hs-dot-fill{
  position:absolute;inset:0;display:block;border-radius:2px;
  background:var(--accent);
  transform:scaleX(0);
  transform-origin:left;
}
.hs-dot.is-active .hs-dot-fill{
  animation:hs-fill var(--hs-dur,9000ms) linear forwards;
}
.hero-slider.is-paused .hs-dot.is-active .hs-dot-fill{animation-play-state:paused}
.hero-slider.no-timer .hs-dot.is-active .hs-dot-fill{animation:none;transform:scaleX(1)}
@keyframes hs-fill{from{transform:scaleX(0)}to{transform:scaleX(1)}}

/* the play control: the only way a film starts under reduced motion */
.hs-play{
  position:absolute;top:50%;left:50%;z-index:3;
  width:76px;height:76px;
  transform:translate(-50%,-50%);
  display:none;align-items:center;justify-content:center;
  border:1px solid var(--line-interactive);border-radius:50%;
  background:rgba(0,0,0,.6);
  color:var(--text-primary);
  cursor:pointer;
}
.hs-play svg{width:24px;height:24px;fill:currentColor;margin-left:3px}
.hs-play:hover{border-color:var(--accent)}
.hero-slider.no-timer .hs-slide.is-active .hs-play{display:inline-flex}
.hero-slider.no-timer .hs-slide.is-playing .hs-play{display:none}

/* the pause toggle: on at every breakpoint, the one control that stops the
   rotation and the film for good. The play control below it is a different
   job: it starts a single film under reduced motion. */
.hs-toggle{
  flex:0 0 auto;
  width:44px;height:44px;
  display:inline-flex;align-items:center;justify-content:center;
  margin-right:4px;
  border:1px solid var(--line-interactive);border-radius:50%;
  background:rgba(0,0,0,.5);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  color:var(--text-secondary);
  cursor:pointer;
  transition:color .26s var(--ease-out),border-color .26s var(--ease-out),
             background-color .26s var(--ease-out);
}
.hs-toggle:hover{color:var(--text-primary);border-color:var(--accent);background:rgba(0,0,0,.78)}
.hs-toggle svg{width:17px;height:17px;fill:currentColor}
.hs-toggle .hs-ico-play{display:none}
.hero-slider.user-paused .hs-toggle .hs-ico-pause{display:none}
.hero-slider.user-paused .hs-toggle .hs-ico-play{display:inline-block}

/* the counter, a quiet mono chip leading the dots so it never collides with
   the floating WhatsApp button in the corner */
.hs-count{
  align-self:center;
  margin-right:6px;
  padding:5px 10px;
  pointer-events:none;
}

/* --- phones: same slider, same films, no arrows ------------------------ */

@media (max-width:720px){
  .hs-arrow{display:none}
  .hs-count{display:none}
  .hs-copy{max-width:min(560px,92%)}
  .hs-copy-wrap{padding-bottom:clamp(96px,15vh,132px)}
  .hs-headline{font-size:clamp(30px,8.4vw,44px);max-width:15ch}
  .hs-subline{font-size:15px;max-width:46ch}
  .hs-subline + .hs-subline{font-size:13.5px;max-width:50ch}
  /* The phone copy runs almost the full width and is centred, so the wash is
     a vertical band with a centred ellipse sitting on the copy instead of the
     desktop's wider, flatter ellipse. --accent-on-media cannot reach 3.5:1
     against any backdrop lighter than itself, so the band has to carry the
     whole copy stack down to about luminance .07, a composited pixel no
     brighter than 58 under the kicker row. Both gradients are anchored in px
     off the bottom edge, because the stack is a fixed height above the floor
     on every phone while its share of the viewport is not. Re-measured at
     375x812 against the running films, sampling only the glyph boxes, the
     four kickers read 8.28:1, 6.62:1, 7.25:1 and 7.82:1 and nothing in the
     copy is under 4.32:1. */
  .hs-scrim-local{
    background:
      linear-gradient(to top,
        rgba(0,0,0,.9) 0,rgba(0,0,0,.88) 360px,rgba(0,0,0,.82) 430px,
        rgba(0,0,0,.6) 480px,rgba(0,0,0,.25) 530px,rgba(0,0,0,0) 580px),
      radial-gradient(ellipse 120vw 300px at 50% calc(100% - 60px),
        rgba(0,0,0,.55) 0%,rgba(0,0,0,.32) 58%,rgba(0,0,0,0) 92%);
  }
  /* slide 2 is the one slide with two paragraphs, and on a 375 wide phone
     that stack is 55 percent of the viewport tall: it starts around 30
     percent, far above the band the other three need. Its own film is also
     the brightest of the four (a full-bleed photograph with specular
     highlights on the casing, raw pixels up to 243 under the kicker row), so
     it carries its own wash, ramped in higher and heavier. The photograph
     still reads clean through its top quarter, where the unit sits. */
  .hs-slide--still .hs-scrim-local{
    background:linear-gradient(to top,
      rgba(0,0,0,.92) 0,rgba(0,0,0,.9) 420px,rgba(0,0,0,.86) 560px,
      rgba(0,0,0,.6) 640px,rgba(0,0,0,.2) 700px,rgba(0,0,0,0) 760px);
  }
  /* the frame is full bleed here, so the blurred backdrop is covered edge to
     edge and only costs a full-viewport blur on the smallest devices */
  .hs-slide--portrait .hs-back{display:none}
  .hs-slide--portrait .hs-frame{
    top:0;left:0;transform:none;
    width:100%;height:100%;aspect-ratio:auto;border-radius:0;box-shadow:none;
  }
  .hs-slide--portrait .hs-frame video,
  .hs-slide--portrait .hs-frame .hs-poster{object-fit:cover}
  .hs-dots{justify-content:flex-start}
  .hs-dot{width:46px}
}

/* the Batik slide on an upright phone. The composite is a landscape frame
   with the unit standing dead centre, and the copy's wash runs from about 43
   percent of the viewport down: full bleed, the two land on the same pixels
   and the wash blacks the unit out. So the media stops above the copy band
   instead of running behind it. The unit was photographed as a cutout on
   this same canvas and the box is filled with pure black, so the frame ends
   without a seam; the copy then sits on bare canvas, darker than any wash
   the scrim could lay down. The window is also far wider this way, the whole
   16:9 frame rather than the 26 percent slice a full-bleed cover would show,
   so the body reads: engraving, logo and both mounting ears. */
@media (max-width:720px) and (orientation:portrait){
  .hs-slide--photo{background:#000}
  /* the box starts below the header and is the smaller of 38 percent of the
     slider and what is left once the centred copy stack has taken its 560px,
     so the body clears the kicker on a 667 tall phone as well as an 812. It
     is never wider than its own 16:9 frame either: a box wider than that
     makes object-fit:cover crop top and bottom instead of the sides, and on a
     short phone that sliced the feet off the unit. Where the box runs narrow
     it is centred, and the bars beside it are the same pure black. */
  .hs-slide--photo .hs-media{
    --hs-photo-h:clamp(120px,100svh - 460px,36svh);
    inset:76px 0 auto 0;
    margin-inline:auto;
    height:var(--hs-photo-h);
    width:min(100%,calc(var(--hs-photo-h) * 16 / 9));
    /* the film's own black is rgb(9,11,12), not the page's pure black, so the
       box would end on a visible step. The mask fades its edges out instead:
       no seam, and nothing about it animates. */
    -webkit-mask-image:linear-gradient(180deg,#000 calc(100% - 34px),rgba(0,0,0,0) 100%),
                       linear-gradient(90deg,rgba(0,0,0,0) 0,#000 14px,#000 calc(100% - 14px),rgba(0,0,0,0) 100%);
    mask-image:linear-gradient(180deg,#000 calc(100% - 34px),rgba(0,0,0,0) 100%),
               linear-gradient(90deg,rgba(0,0,0,0) 0,#000 14px,#000 calc(100% - 14px),rgba(0,0,0,0) 100%);
    -webkit-mask-composite:source-in;
    mask-composite:intersect;
  }
  /* the composite is centred now, so the window is centred on it and lifted
     a little: the cable leaves the top of the frame and the body sits just
     under the middle */
  .hs-slide--photo .hs-poster,
  .hs-slide--photo .hs-media video{object-position:50% 42%}
  /* the wash only has to start where the product stops: over it the gradient
     would be darkening the thing it is there to sell, and under it there is
     nothing to darken but the canvas the copy already reads cleanly against */
  .hs-slide--photo .hs-scrim-local{
    background:linear-gradient(180deg,
      rgba(0,0,0,0) 42%,rgba(0,0,0,.34) 48%,rgba(0,0,0,.62) 54%,
      rgba(0,0,0,.72) 62%,rgba(0,0,0,.74) 100%);
  }
  /* and the base wash stops short of the box for the same reason */
  .hs-slide--photo .hs-scrim{
    background:linear-gradient(to top,
      rgba(0,0,0,.88) 0%,rgba(0,0,0,.5) 34%,rgba(0,0,0,0) 56%);
  }
}

/* a short upright phone (an iPhone SE or an 8 at 375x667). Slide 2 carries
   two paragraphs, and at the tall-phone type scale that stack runs two
   thirds of the screen and starts under the header. The type steps down so
   the stack fits the screen it is on; the washes are anchored in px off the
   bottom edge, so they follow it without a second set of numbers. */
@media (max-width:720px) and (max-height:700px) and (orientation:portrait){
  .hs-kicker{margin-bottom:10px}
  .hs-headline{font-size:clamp(26px,7.4vw,34px);max-width:16ch}
  .hs-subline{font-size:14px;line-height:1.48;margin-top:12px}
  .hs-subline + .hs-subline{font-size:12.5px;margin-top:8px}
  .hs-copy .btn-row{margin-top:18px}
  .hs-copy-wrap{padding-bottom:clamp(88px,13vh,110px)}
}

/* a short landscape phone: the copy has to fit above the dots, and the
   portrait frame shrinks again so the centred stack has a lane at all */
@media (max-height:560px){
  .hero-slider{min-height:420px}
  .hs-copy-wrap{padding-bottom:92px}     /* the dots row needs its own lane */
  .hs-headline{font-size:clamp(24px,4.4vw,34px)}
  .hs-subline{margin-top:10px;font-size:14px}
  .hs-subline + .hs-subline{margin-top:8px;font-size:13px}
  .hs-copy .btn-row{margin-top:16px}
  .hs-slide--portrait .hs-frame{width:min(26vh,60vw);top:calc(var(--nav-h) + 1.5vh)}
}

/* the slider sits under the fixed header, so the rail starts below it */
.hero-slider .container{position:relative;height:100%}

/* ==========================================================================
   3. The Events and Edukasi teaser row
   Photo left, copy right, twice. A different skeleton from the card grid
   above it and from the full-bleed hold panel below it.
   ========================================================================== */

.teaser-section{padding-top:0}

.teaser-row{
  display:grid;
  grid-template-columns:repeat(2,1fr);
  gap:clamp(18px,2.4vw,28px);
}
.teaser{
  display:grid;
  grid-template-columns:minmax(132px,38%) 1fr;
  align-items:stretch;
  background:linear-gradient(178deg,var(--panel) 0%,#14171C 100%);
  border:1px solid var(--line);
  border-radius:var(--radius);
  overflow:hidden;
  transition:transform .4s var(--ease-out),border-color .4s var(--ease-out),
             box-shadow .4s var(--ease-out);
}
.teaser:hover{
  transform:translateY(-3px);
  border-color:#39404C;
  box-shadow:0 26px 48px -32px rgba(5,5,10,.95);
}
.teaser-media{position:relative;overflow:hidden;min-height:172px}
.teaser-media img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  transform:scale(1.02);
  transition:transform .6s var(--ease-out);
}
.teaser:hover .teaser-media img{transform:scale(1.07)}
.teaser-media::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(90deg,rgba(8,9,13,.28) 0%,rgba(8,9,13,.7) 100%);
}
.teaser-copy{padding:clamp(18px,2vw,26px)}
.teaser-copy h3{margin-bottom:10px}
.teaser-copy p{color:var(--text-secondary);max-width:34ch}
.teaser-copy .btn{margin-top:18px}

@media (max-width:860px){
  .teaser-row{grid-template-columns:1fr}
}
@media (max-width:440px){
  .teaser{grid-template-columns:1fr}
  .teaser-media{min-height:150px}
  .teaser-media::after{background:linear-gradient(180deg,rgba(8,9,13,.2) 0%,rgba(8,9,13,.72) 100%)}
}

/* ==========================================================================
   4. Reduced motion
   Posters only, no auto-advance, the arrows and the dots still work, and the
   intro never runs at all (intro.js removes it before it can paint).
   ========================================================================== */

@media (prefers-reduced-motion:reduce){
  .intro{display:none}
  .hs-poster,.hs-media video{transform:none!important;transition:none!important}
  .hs-slide{transition:none}
  .hs-copy > *{opacity:1!important;transform:none!important;transition:none!important}
  .hs-dot-fill{animation:none!important}
  .hs-dot.is-active .hs-dot-fill{transform:scaleX(1)}
  .teaser-media img{transform:none!important}
}

/* the same final states applied live when the visitor flips reduced motion
   on mid-session: site.js adds body.pinned */
body.pinned .hs-copy > *{opacity:1;transform:none;transition:none}
body.pinned .hs-dot.is-active .hs-dot-fill{animation:none;transform:scaleX(1)}
body.pinned .hs-poster,body.pinned .hs-media video{transform:none;transition:none}
