/* RANDOM light/dark theme-toggle animation, built from real elements
   (not a flat screenshot): the background is the real light/dark
   texture photos crossfading, the wordmark is inline currentColor
   SVG, "MADE WITH LOVE" is a real vector image, and the pull-cord's
   line/bulb actually transform between states rather than two
   elements crossfading. The cord is tied directly to the theme: it's
   only ever extended+glowing while dark, and short+inactive while
   light -- there's no separate "tug" gesture.

   `.rd-toggle-loop` can be any shape (including 100vh) because the
   artwork itself lives in `.rd-toggle-canvas`, a fixed 1288x1007 box
   that js/rd-toggle-loop.js scale-to-fits and centers into whatever
   the outer container's real size is -- same
   translate(-50%,-50%)+scale() technique js/landing.js already uses
   for the site's floating project canvas. Every position below is a
   percentage of that fixed 1288x1007 box (measured from the source
   artwork), so it's correct at any output size without re-deriving
   anything. */
.rd-toggle-loop {
  position: relative;
  width: 100%;
  aspect-ratio: 1288 / 1007;
  overflow: hidden;
  display: block;
  background-color: #F3F3F3;
}
.rd-toggle-loop.is-dark { background-color: #0E2735; }
.rd-toggle-loop.is-viewport { width: 100%; height: 100vh; aspect-ratio: auto; }
/* On mobile the hero drops the 100vh treatment entirely and behaves
   exactly like the thumbnail instances: sized to its own native
   1288:1007 aspect ratio instead of the viewport's. */
@media (max-width: 767px) {
  .rd-toggle-loop.is-viewport { height: auto; aspect-ratio: 1288 / 1007; }
  /* .hero-banner itself is hardcoded to a fixed 60vh on mobile
     (gallery.css) for its normal <img>-based heroes; once the loop
     above drops to its own much-shorter native aspect ratio, that
     fixed-height parent would otherwise leave a big empty gap below
     it. Let it size to its (now short) content instead, just here. */
  .hero-banner:has(.rd-toggle-loop.is-viewport) { height: auto; padding: 0; }
}

.rd-toggle-canvas {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 1288px;
  height: 1007px;
}

/* Direct children of the OUTER block (not the scaled-to-contain
   canvas), each independently `cover`-sized to the block's own real
   width/height -- so the texture always fills the whole block edge to
   edge, regardless of whether the canvas ends up letterboxed inside
   it (e.g. a 100vh block whose aspect ratio doesn't match 1288:1007).
   !important because this component gets dropped into host contexts
   (gallery/card/frame images) that carry their own generic `img`
   resets with higher specificity than a two-class selector. */
.rd-toggle-loop .rd-toggle-bg {
  position: absolute !important;
  inset: 0 !important;
  width: 100% !important;
  height: 100% !important;
  object-fit: cover !important;
  display: block !important;
}
.rd-toggle-bg--dark { opacity: 0; transition: opacity ease; }
.rd-toggle-loop.is-dark .rd-toggle-bg--dark { opacity: 1; }

.rd-toggle-wordmark {
  position: absolute;
  left: 4.193%;
  top: 34.66%;
  width: 92.24%;
  aspect-ratio: 1188 / 306;
  color: #3A3C44;
  transition: color ease;
}
.rd-toggle-loop.is-dark .rd-toggle-wordmark { color: #F6F6F6; }
.rd-toggle-wordmark svg { width: 100%; height: 100%; display: block; }

/* Centered under the wordmark and overlapping its bottom edge
   (wordmark spans top 34.66% to 65.05%; mwl's own top sits inside
   that so the letters show through behind it, per the reference).
   !important for the same reason as .rd-toggle-bg above -- host
   contexts' generic `img` resets (e.g. .frame-inner img, .card-image
   img) otherwise win on specificity and stretch this to fill the
   whole box, which is what was rendering it huge and clipped. */
.rd-toggle-loop .rd-toggle-mwl {
  position: absolute !important;
  left: 31.55% !important;
  top: 60% !important;
  width: 36.9% !important;
  height: auto !important;
  aspect-ratio: 605 / 129;
  display: block !important;
}

/* The line and the bulb (triangle+glow) are independently sized/
   positioned -- not one aspect-ratio'd box -- so the line can reach
   however far it needs to (to land inside the "O") without dragging
   the bulb's own size along with it. Both read the same --cord-y
   custom property so the bulb always sits exactly at the line's
   current bottom edge. */
.rd-toggle-cord-line {
  position: absolute;
  left: 73.06%;
  transform: translateX(-50%);
  top: 0;
  width: 2px;
  height: var(--cord-y, 35.65%);
  background-image: repeating-linear-gradient(to bottom, #FF5151 0 3px, transparent 3px 6px);
  transition: height ease;
}
.rd-toggle-loop.is-dark .rd-toggle-cord-line { --cord-y: 41.4%; }

.rd-toggle-cord-shape {
  position: absolute;
  left: 73.06%;
  transform: translateX(-50%);
  top: var(--cord-y, 35.65%);
  width: 9%;
  aspect-ratio: 74 / 75;
  display: block;
  overflow: visible;
  transition: top ease;
}
.rd-toggle-loop.is-dark .rd-toggle-cord-shape { --cord-y: 41.4%; }

.rd-toggle-cord-glow { opacity: 0; transition: opacity ease; }
.rd-toggle-loop.is-dark .rd-toggle-cord-glow { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .rd-toggle-bg--dark,
  .rd-toggle-wordmark,
  .rd-toggle-cord-line,
  .rd-toggle-cord-shape,
  .rd-toggle-cord-glow { transition: none; }
}
