/* DESKTOP hero ring: the still frame, the side pages and the page slide.
   See lantern-hero-ring-layout.css for the map.
   The frame holds still and the pages move through it. lantern-hero-carousel.js
   adds two still layers in the live window's box: .car-back (the white screen
   under the page — the .floatwrap drop-shadow falls from it) and .car-frame
   (hairline border + dots strip, over the page). The live .browser is just
   the page: no border, no shadow, its tab strip kept for height but emptied. */
.car-sides,
.car-back,
.car-frame { display: none; }

  /* ── the window box: one size on every page ─────────────────────────────── */
  #hero .browser,
  body.hero-p2 #hero .browser {
    width: var(--car-w) !important;
    height: var(--car-h) !important;
    overflow: hidden;
    display: flex; flex-direction: column;
  }
  /* the inline and !important shadows need the extra weight */
  #hero .floatwrap > .browser { z-index: 1; border: none !important; box-shadow: none !important; }
  /* a slim strip with three dots is all the chrome left: tab, address bar and
     icons go, the page's own strip is emptied — the frame draws the dots */
  #hero .browser .hh-tab,
  #hero .browser .bbar { display: none !important; }
  #hero .browser .hh-tabstrip { padding: 11px 14px; }
  #hero .browser .hh-tabstrip > * { visibility: hidden; }
  #hero .floatwrap { position: relative; }
  /* the stacked silhouettes of the old slide deck give way to the side pages */
  #hero .floatwrap::before,
  #hero .floatwrap::after { display: none; }

  /* ── the still frame ─────────────────────────────────────────────────── */
  #hero .car-back,
  #hero .car-frame {
    display: block; position: absolute; top: 0; left: 0;
    width: var(--car-w); height: var(--car-h); box-sizing: border-box;
    border-radius: var(--r-lg); pointer-events: none;
  }
  #hero .car-back { background: #fff; z-index: 0; }
  #hero .car-frame { z-index: 2; border: 1px solid rgba(var(--ink-rgb), .2); }
  /* the strip: opaque, so it always covers the page's own emptied one */
  #hero .car-frame::before {
    content: ""; position: absolute; top: 0; left: 0; right: 0;
    height: calc(var(--car-strip-h, 27px) - 1px); background: #efe9dd;
    border-radius: var(--r-lg) var(--r-lg) 0 0;
  }
  #hero .car-frame .bdots {
    position: absolute; left: 13px; top: calc((var(--car-strip-h, 27px) - 9px) / 2 - 1px);
    display: flex; gap: 6px;
  }
  #hero .car-frame .bdots i { width: 9px; height: 9px; border-radius: 50%; display: block; }
  #hero .car-frame .bdots i:nth-child(1) { background: #ff5f57; }
  #hero .car-frame .bdots i:nth-child(2) { background: #febc2e; }
  #hero .car-frame .bdots i:nth-child(3) { background: #28c840; }

  /* ── the side pages: a cover-flow of all five, behind the live window ─────
     Each is a bare white card with a picture of that page
     (hero-slide-<page>-<lang>.jpg, scripts/hero-stills.mjs) and no strip — the
     browser chrome belongs to the frame alone, so the card starts one strip
     lower; the pivot stays the frame's centre. No .browser class on purpose:
     that name carries the view-transition-name and every `#hero .browser`
     lookup in the scripts. Slots (data-rel, lantern-hero-carousel.js): ±1 the
     neighbours, ±2 behind them, ±3 past the ends (round the back of the ring). */
  #hero .car-sides { display: block; position: absolute; inset: 0; z-index: 0; pointer-events: none; }
  #hero .car-side {
    position: absolute; top: var(--car-strip-h, 27px); left: 0; width: var(--car-w);
    height: calc(var(--car-h) - var(--car-strip-h, 27px));
    display: flex; flex-direction: column; overflow: hidden;
    background: #fff;
    border-radius: var(--r-lg);
    box-shadow: 0 30px 60px -30px rgba(58, 36, 2, .25);
    transform-origin: 50% calc(var(--car-h) / 2 - var(--car-strip-h, 27px));
    opacity: 0; transform: none;
    /* transform + opacity only: the compositor moves them without repainting */
    transition: transform var(--car-dur) var(--car-ease), opacity var(--car-dur) ease, filter var(--car-dur) ease;
    will-change: transform;
  }
  #hero .car-side-strip { display: none; }
  /* the page leaving for a side slot must match it: its own emptied strip
     goes clear for the slide (the frame layer covers the incoming page's) */
  html.hero-sliding #hero .browser .hh-tabstrip { background: transparent; }
  #hero .car-side img {
    display: block; flex: 1 1 auto; min-height: 0; width: 100%; object-fit: cover; object-position: top;
    opacity: 0; transition: opacity .25s ease;
  }
  #hero .car-side img.ld { opacity: 1; }
  /* the ±1 pages' depth: a paper veil over their outer half, in place of blur */
  #hero .car-side::after {
    content: ""; position: absolute; inset: 0; pointer-events: none;
    opacity: 0; transition: opacity var(--car-dur) ease;
    background: linear-gradient(to right, rgba(var(--paper-rgb), .1), rgba(var(--paper-rgb), .1) 45%, rgba(var(--paper-rgb), .52));
  }
  #hero .car-side[data-rel^="-"]::after { background: linear-gradient(to left, rgba(var(--paper-rgb), .1), rgba(var(--paper-rgb), .1) 45%, rgba(var(--paper-rgb), .52)); }
  #hero .car-side[data-rel="1"]::after,
  #hero .car-side[data-rel="-1"]::after { opacity: 1; }
  /* a light blur on top of the veil keeps the eye on the centre page */
  #hero .car-side[data-rel="1"]  { opacity: var(--car-o1); z-index: 2; transform: var(--car-t1r); filter: blur(1px); }
  #hero .car-side[data-rel="-1"] { opacity: var(--car-o1); z-index: 2; transform: var(--car-t1l); filter: blur(1px); }
  #hero .car-side[data-rel="2"]  { opacity: var(--car-o2); z-index: 1; transform: var(--car-t2r); filter: blur(2px); }
  #hero .car-side[data-rel="-2"] { opacity: var(--car-o2); z-index: 1; transform: var(--car-t2l); filter: blur(2px); }
  #hero .car-side[data-rel="3"]  { opacity: 0; z-index: 0; transform: var(--car-t3r); }
  #hero .car-side[data-rel="-3"] { opacity: 0; z-index: 0; transform: var(--car-t3l); }
  /* the ring's exit (Mastered → the wall): the pages tuck back behind the
     window, the intro in reverse, then drop out */
  #hero .car-side[data-rel="off"] {
    opacity: 0; transform: var(--car-persp) scale(.9); visibility: hidden;
    transition: opacity .3s ease, transform .4s var(--car-ease), visibility 0s linear .4s;
  }

  /* ── the page slide (View Transition, lantern-deck.js navigate()) ────────
     The live page ("hero-page") slides into the ±1 slot while the next comes
     in from the other side (← mirrors it). The root is not captured, so the
     rest plays live; transitions inside the window are off — the incoming page
     must arrive drawn. The frame and arrows get layers of their own, drawn
     plain (old snapshot dropped: two opaque copies would darken them). */
  html.hero-sliding { view-transition-name: none; }
  html.hero-sliding #hero .browser { view-transition-name: hero-page; }
  html.hero-sliding #hero .browser,
  html.hero-sliding #hero .browser * { transition: none !important; }
  html.hero-sliding #hero .car-frame { view-transition-name: hero-frame; }
  /* demo cursors sit outside the snapshot (the Immerse one is position:fixed):
     hidden for the move, or they float over the sliding pages */
  html.hero-sliding .hw-cursor { opacity: 0 !important; transition: none !important; }
  html.hero-sliding #d-deck .d-prev { view-transition-name: car-prev; }
  html.hero-sliding #d-deck .d-next { view-transition-name: car-next; }
  /* the pseudo tree sits over the whole viewport; clicks fall through to the
     live controls, so a press made mid-move reaches the arrows and is queued */
  html.hero-sliding::view-transition { pointer-events: none; }

  ::view-transition-group(hero-page) { animation: none; }
  ::view-transition-image-pair(hero-page) { isolation: auto; }
  ::view-transition-old(hero-page),
  ::view-transition-new(hero-page) {
    mix-blend-mode: normal; block-size: auto;
    animation-duration: var(--car-dur); animation-timing-function: var(--car-ease);
    animation-fill-mode: both;
  }
  ::view-transition-old(hero-page) { animation-name: car-to-left; }
  ::view-transition-new(hero-page) { animation-name: car-from-right; }
  html.slide-back::view-transition-old(hero-page) { animation-name: car-to-right; }
  html.slide-back::view-transition-new(hero-page) { animation-name: car-from-left; }

  ::view-transition-group(hero-frame),
  ::view-transition-group(car-prev),
  ::view-transition-group(car-next) { animation: none; }
  ::view-transition-old(hero-frame),
  ::view-transition-old(car-prev),
  ::view-transition-old(car-next) { display: none; }
  ::view-transition-new(hero-frame),
  ::view-transition-new(car-prev),
  ::view-transition-new(car-next) { animation: none; mix-blend-mode: normal; }
/* the ±1 slot's look: the live page ends exactly where its side picture
   takes over, and its snapshot fades over the last ~80ms so the picture
   (already in the slot underneath) takes over under a soft blend, not a cut */
@keyframes car-to-left    { from { transform: var(--car-persp); } 82% { opacity: var(--car-o1); } to { transform: var(--car-t1l); opacity: 0; } }
@keyframes car-to-right   { from { transform: var(--car-persp); } 82% { opacity: var(--car-o1); } to { transform: var(--car-t1r); opacity: 0; } }
@keyframes car-from-right { from { transform: var(--car-t1r); opacity: var(--car-o1); } to { transform: var(--car-persp); } }
@keyframes car-from-left  { from { transform: var(--car-t1l); opacity: var(--car-o1); } to { transform: var(--car-persp); } }
@media (prefers-reduced-motion: reduce) {
  #hero .car-side { transition: none; }
}
