/* ============================================================
   Ludumina Labs — 30 / Ludumina Worlds
   Owner: worlds-builder.  All rules scoped to [data-section="worlds"].
   Consumes tokens from tokens.css; defines no shared tokens.

   Accent is mapped to the brand's three pillars, not to individual
   worlds: --cy science, --am art, --vi history. The legend in the
   section head is the key, so the colour actually carries meaning.
   ============================================================ */

[data-section="worlds"] {
  /* local knobs — namespaced, never shadowing a shared token */
  --w-gap: clamp(0.85rem, 1.25vw, 1.3rem);
  --w-pad: clamp(1.05rem, 1.5vw, 1.6rem);
  --w-notch: 22px;
  --w-clip: polygon(
    0 0,
    calc(100% - var(--w-notch)) 0,
    100% var(--w-notch),
    100% 100%,
    var(--w-notch) 100%,
    0 calc(100% - var(--w-notch))
  );
  position: relative;
}

/* ---------- section head: the brand lockup ----------------------- */

[data-section="worlds"] .section-head h2 { line-height: 0.92; }

[data-section="worlds"] .w-lockup {
  display: flex;
  flex-direction: column;
  gap: clamp(0.7rem, 1.4vw, 1.05rem);
}

/* SCIENCE · ART · HISTORY — the key to the card accents */
[data-section="worlds"] .w-pillars {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.55rem 1.05rem;
}
[data-section="worlds"] .w-pillars li {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  font-family: var(--f-mono);
  font-size: var(--t-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  color: var(--ink-60);
}
[data-section="worlds"] .w-pillars i {
  width: 6px;
  height: 6px;
  flex: none;
  background: var(--accent);
  box-shadow: 0 0 9px color-mix(in srgb, var(--accent) 80%, transparent);
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
}

[data-section="worlds"] .w-headside {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.85rem;
  text-align: right;
}
/* AA note: every label in the honesty layer (.w-count, .w-date .micro,
   .w-srcnote, .w-note) sat on --ink-40, which measures ~3.5:1 on --bg and
   fails AA at these sizes. The copy doing the credibility work has to be the
   easiest to read, not the hardest, so all of it is on --ink-60 (~7:1). */
[data-section="worlds"] .w-headside .w-count {
  padding-bottom: 0;
  white-space: normal;
  color: var(--ink-60);
}

/* the trailer's closing date card, restated as chrome */
[data-section="worlds"] .w-date {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.3rem;
  padding: 0.75rem 1.15rem;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.055), rgba(255, 255, 255, 0.015));
  box-shadow: inset 0 0 0 1px var(--line-2);
  clip-path: var(--clip-both);
}
[data-section="worlds"] .w-date .micro { padding-bottom: 0; color: var(--ink-60); }
[data-section="worlds"] .w-date b {
  font-size: clamp(0.85rem, 1.15vw, 1.05rem);
  font-weight: 400;
  letter-spacing: 0.02em;
  color: var(--ink);
  white-space: nowrap;
}

/* ---------- grid --------------------------------------------------
   Six columns, three descending tiers:

     row 1   flagship          full width, media beside copy
     row 2   wide + tall       2/3 landscape poster + 1/3 portrait poster
     row 3   tall + tall + tall

   Two copy treatments only, not three. The flagship puts its copy in a
   panel beside the plate; every other card is the Treasures card's recipe
   — full-bleed art, copy resolving out of a scrim over it — in landscape
   or portrait. The composed posters (a sharp inset floating on flat
   gradient) are gone; every plate is now a straight frame, full-bleed,
   cropped with object-position rather than composited.

   Slot order is decided by plate strength, not by subject: the strongest
   frame gets the biggest slot. That is why Orbital Station holds the wide
   slot and the Parthenon — whose only capture is dominated by the back of
   an avatar's head — sits in a third-width one.
   ------------------------------------------------------------------ */

[data-section="worlds"] .w-grid {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: var(--w-gap);
}

[data-section="worlds"] .w-feature    { grid-column: 1 / -1; }
[data-section="worlds"] .w-card--wide { grid-column: span 4; }
[data-section="worlds"] .w-card--tall { grid-column: span 2; }

/* ---------- card shell ------------------------------------------- */

[data-section="worlds"] .w-card {
  position: relative;
  min-width: 0;
  perspective: 1100px;
  --mx: 0;      /* pointer x, -1 .. 1 */
  --my: 0;      /* pointer y, -1 .. 1 */
  --hot: 0;     /* 0 idle, 1 hovered */
}

/* --hot is driven by CSS so the craft survives with JS disabled. Guarded by
   (hover:hover) so it can never stick on a touch screen. */
@media (hover: hover) {
  [data-section="worlds"] .w-card:hover { --hot: 1; }
}
[data-section="worlds"] .w-card:focus-within { --hot: 1; }

/* accent bloom that lives *behind* the clipped frame, so it is not cut off */
[data-section="worlds"] .w-card::before {
  content: "";
  position: absolute;
  inset: 12% 6% 2%;
  background: var(--accent);
  filter: blur(38px);
  opacity: calc(var(--hot) * 0.26);
  transition: opacity 0.5s var(--ease);
  pointer-events: none;
  z-index: 0;
}

/* the 1px notched border: a coloured plate with a 1px inset child on top */
[data-section="worlds"] .w-frame {
  position: relative;
  z-index: 1;
  height: 100%;
  padding: 1px;
  clip-path: var(--clip-both);
  background: var(--line);
  transform:
    translate3d(0, calc(var(--hot) * -6px), 0)
    rotateX(calc(var(--my) * -2deg))
    rotateY(calc(var(--mx) * 2.4deg));
  transform-style: preserve-3d;
  transition:
    transform 0.5s var(--ease),
    background-color 0.5s var(--ease);
  will-change: transform;
}

[data-section="worlds"] .w-feature .w-frame { clip-path: var(--w-clip); }

[data-section="worlds"] .w-card:hover .w-frame,
[data-section="worlds"] .w-card:focus-within .w-frame {
  background: color-mix(in srgb, var(--accent) 62%, transparent);
}

[data-section="worlds"] .w-clip {
  position: relative;
  height: 100%;
  clip-path: var(--clip-both);
  background: var(--bg-2);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

[data-section="worlds"] .w-feature .w-clip {
  clip-path: var(--w-clip);
  display: grid;
  grid-template-columns: 1.62fr 1fr;
  align-items: stretch;
}

/* ---------- media ------------------------------------------------ */

[data-section="worlds"] .w-media {
  position: relative;
  overflow: hidden;
  background: #04050C;
  flex: 1 1 auto;
  min-height: 0;
}

[data-section="worlds"] .w-feature .w-media { aspect-ratio: 16 / 9; }

/* every non-flagship card: art fills the whole plate, copy overlays it */
[data-section="worlds"] .w-card--wide .w-media,
[data-section="worlds"] .w-card--tall .w-media {
  position: absolute;
  inset: 0;
}
/* aspect sets the natural height; min-height lets it stretch to a taller
   neighbour rather than leaving a bare strip inside its own border.
   width:100% is load-bearing — without a definite width, a stretched height
   feeds back through aspect-ratio and widens the card past its grid cell. */
[data-section="worlds"] .w-card--wide .w-clip,
[data-section="worlds"] .w-card--tall .w-clip {
  width: 100%;
  min-height: 100%;
}
[data-section="worlds"] .w-card--tall .w-clip { aspect-ratio: 3 / 4; }
[data-section="worlds"] .w-card--wide .w-clip { aspect-ratio: 1600 / 694; }

/* ---- the plate --------------------------------------------------
   .w-plate is the moving box: it holds the still and the loop together
   so both track the pointer identically, and it owns the baseline
   overscale that keeps the frame covered while it travels. Separating
   it from .w-art frees the image's own transform for the slow drift on
   the flagship, which would otherwise fight the parallax.
   ------------------------------------------------------------------ */
[data-section="worlds"] .w-plate {
  position: absolute;
  inset: 0;
  display: block;
  /* art moves *against* the pointer; copy moves *with* it → real separation */
  transform:
    scale(calc(1.045 + var(--hot) * 0.035))
    translate3d(calc(var(--mx) * -11px), calc(var(--my) * -11px), 0);
  transition: transform 0.55s var(--ease);
  will-change: transform;
}
[data-section="worlds"] .w-card--wide .w-plate,
[data-section="worlds"] .w-card--tall .w-plate {
  transform:
    scale(calc(1.03 + var(--hot) * 0.03))
    translate3d(calc(var(--mx) * -8px), calc(var(--my) * -8px), 0);
}

/* The flagship is framed from its left edge: the in-game mission card lives
   in the top-left corner of the capture and is the whole reason this plate
   was chosen, so nothing may crop into it. Origin 0% 50% removes the left
   crop from the overscale, and the pointer offset is biased negative so a
   leftward drift can never expose the frame edge. */
[data-section="worlds"] .w-feature .w-plate {
  transform-origin: 0% 50%;
  transform:
    scale(calc(1.045 + var(--hot) * 0.03))
    translate3d(calc((var(--mx) - 1) * 5.5px), calc(var(--my) * -9px), 0);
}

[data-section="worlds"] .w-art,
[data-section="worlds"] .w-vid {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity 0.5s var(--ease);
}

/* ---- per-plate framing ------------------------------------------
   These crops are the section's art direction. Each value was chosen by
   cutting the frame at that offset and looking at it, not by guessing.
   ------------------------------------------------------------------ */

/* mission card + player + glucose; the empty right third is dropped */
[data-section="worlds"] .w-feature .w-art { object-position: 0% 50%; }
/* ring truss left, lit module right, instruction panel bottom-left */
[data-section="worlds"] .w-card--wide .w-art { object-position: 18% 50%; }
/* the full sweep of the terracotta bank above, wooden floor below */
[data-section="worlds"] .w-media--arena .w-art { object-position: 0% 50%; }
/* the near corner of the colonnade, where the frieze sits clear of the copy */
[data-section="worlds"] .w-media--parthenon .w-art { object-position: 100% 50%; }

/* ---- slow drift on the flagship ---------------------------------
   The section's claim over the bar is that it shows the product working,
   and until now all of that was behind hover — so scrollers and every
   touch user saw exactly what the bar offers: stills in boxes. This is a
   push-in on the sharp native-resolution plate rather than an autoplayed
   loop, because the loops are 480p phone capture: autoplaying one would
   replace the best image in the section with the worst one on first read.
   Origin 0% 0% so the push-in can never eat into the mission card. */
[data-section="worlds"] .w-feature .w-art {
  transform-origin: 0% 0%;
  animation: w-drift 34s var(--ease) infinite alternate;
}
@keyframes w-drift {
  from { transform: scale(1); }
  to   { transform: scale(1.055); }
}

[data-section="worlds"] .w-vid { opacity: 0; }
[data-section="worlds"] .w-card.is-playing .w-vid { opacity: 1; }
[data-section="worlds"] .w-card.is-playing .w-art { opacity: 0; }

/* legibility scrim */
[data-section="worlds"] .w-scrim {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(
      to top,
      rgba(4, 5, 12, 0.97) 0%,
      rgba(4, 5, 12, 0.93) 24%,
      rgba(4, 5, 12, 0.62) 40%,
      rgba(4, 5, 12, 0.18) 60%,
      rgba(4, 5, 12, 0.04) 76%,
      rgba(4, 5, 12, 0.34) 100%
    );
}
/* The landscape card now carries its copy over the art like the portraits,
   so it takes the same base scrim — one plate treatment, not two. Its copy
   block is shallower relative to the frame, so the ramp starts lower. */
[data-section="worlds"] .w-card--wide .w-scrim {
  background:
    linear-gradient(
      to top,
      rgba(4, 5, 12, 0.97) 0%,
      rgba(4, 5, 12, 0.9) 30%,
      rgba(4, 5, 12, 0.5) 48%,
      rgba(4, 5, 12, 0.12) 66%,
      rgba(4, 5, 12, 0.04) 80%,
      rgba(4, 5, 12, 0.34) 100%
    );
}
/* The flagship's plate is a pale daylight frame — the brightest in the
   section — so it needs a real edge into the panel, plus a foot ramp for
   the play control and the loop note. */
[data-section="worlds"] .w-feature .w-scrim {
  background:
    linear-gradient(
      to right,
      rgba(4, 5, 12, 0) 52%,
      rgba(4, 5, 12, 0.62) 100%
    ),
    linear-gradient(
      to top,
      rgba(4, 5, 12, 0.78) 0%,
      rgba(4, 5, 12, 0.22) 18%,
      rgba(4, 5, 12, 0) 38%
    );
}

/* accent wash that blooms up from the base on hover */
[data-section="worlds"] .w-bloom {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(
    115% 62% at 50% 112%,
    color-mix(in srgb, var(--accent) 34%, transparent) 0%,
    transparent 58%
  );
  opacity: calc(var(--hot) * 0.55);
  transition: opacity 0.5s var(--ease);
  mix-blend-mode: screen;
}

/* specular sweep — a light bar that rakes across on hover */
[data-section="worlds"] .w-sweep {
  position: absolute;
  top: -60%;
  bottom: -60%;
  left: 0;
  width: 46%;
  pointer-events: none;
  transform: translateX(-190%) rotate(14deg);
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(255, 255, 255, 0.03) 34%,
    rgba(255, 255, 255, 0.2) 50%,
    rgba(255, 255, 255, 0.03) 66%,
    transparent 100%
  );
  mix-blend-mode: screen;
}
[data-section="worlds"] .w-card:hover .w-sweep,
[data-section="worlds"] .w-card:focus-within .w-sweep {
  animation: w-rake 1.05s var(--ease) 1 both;
}
@keyframes w-rake {
  from { transform: translateX(-190%) rotate(14deg); }
  to   { transform: translateX(400%) rotate(14deg); }
}

/* the clipped corner catching light */
[data-section="worlds"] .w-glint {
  position: absolute;
  top: 0;
  right: 0;
  width: calc(var(--w-notch) * 2.4);
  height: calc(var(--w-notch) * 2.4);
  pointer-events: none;
  background: linear-gradient(
    225deg,
    color-mix(in srgb, var(--accent) 85%, white) 0%,
    color-mix(in srgb, var(--accent) 50%, transparent) 38%,
    transparent 62%
  );
  opacity: calc(0.16 + var(--hot) * 0.84);
  transition: opacity 0.45s var(--ease);
}
[data-section="worlds"] .w-card:not(.w-feature) .w-glint {
  width: calc(var(--notch) * 2.6);
  height: calc(var(--notch) * 2.6);
}

/* ---------- copy ------------------------------------------------- */

[data-section="worlds"] .w-panel {
  position: relative;
  z-index: 3;
  padding: var(--w-pad);
  transform: translate3d(calc(var(--mx) * 5px), calc(var(--my) * 5px), 0);
  transition: transform 0.55s var(--ease);
  will-change: transform;
}

[data-section="worlds"] .w-card:not(.w-feature) .w-panel {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.5rem;
}

/* the landscape card's copy sits lower in a shallower frame — give it a
   little more room so it does not crowd the notched bottom-left corner */
[data-section="worlds"] .w-card--wide .w-panel {
  padding: clamp(1.15rem, 1.7vw, 1.75rem);
  max-width: 62%;
}

[data-section="worlds"] .w-feature .w-panel {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.62rem;
  padding: clamp(1.4rem, 2.4vw, 2.4rem);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.028), transparent 60%);
  border-left: 1px solid var(--line);
}

[data-section="worlds"] .w-meta {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  flex-wrap: wrap;
}

[data-section="worlds"] .w-idx {
  color: var(--accent);
  opacity: 0.85;
  letter-spacing: 0.14em;
}
[data-section="worlds"] .w-idx::after {
  content: "";
  display: inline-block;
  width: 14px;
  height: 1px;
  margin-left: 0.55rem;
  vertical-align: middle;
  background: var(--accent);
  opacity: 0.5;
}

[data-section="worlds"] .w-subject { color: var(--ink-60); }

[data-section="worlds"] .w-title {
  font-size: clamp(1.02rem, 1.35vw, 1.28rem);
  letter-spacing: 0.005em;
  transform: translateY(calc(var(--hot) * -3px));
  transition: transform 0.45s var(--ease);
}
[data-section="worlds"] .w-card--wide .w-title { font-size: clamp(1.1rem, 1.55vw, 1.45rem); }
[data-section="worlds"] .w-feature .w-title {
  font-size: clamp(1.5rem, 2.5vw, 2.35rem);
  line-height: 1.02;
}

/* the hairline that ignites in the world's accent */
[data-section="worlds"] .w-rule {
  display: block;
  width: 100%;
  height: 1px;
  margin: 0.15rem 0 0.1rem;
  background: var(--line);
  position: relative;
}
[data-section="worlds"] .w-rule::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--accent);
  box-shadow: 0 0 12px color-mix(in srgb, var(--accent) 70%, transparent);
  transform: scaleX(var(--hot));
  transform-origin: left center;
  transition: transform 0.6s var(--ease);
}

/* the company's own trailer line, verbatim — the primary copy on every card */
[data-section="worlds"] .w-tag {
  font-family: var(--f-mono);
  font-size: 0.83rem;
  letter-spacing: 0.04em;
  line-height: 1.45;
  color: color-mix(in srgb, var(--accent) 78%, white);
}
[data-section="worlds"] .w-card--wide .w-tag {
  font-size: clamp(0.92rem, 1.2vw, 1.12rem);
}

/* Human Body has no trailer line because it has no trailer footage. The slot
   used to be held open and empty, which read as a rendering bug rather than
   as honesty: the hole was visible, the point was not. Now the absence is
   written out, in the same slot, in the same face — plain grey rather than
   the world's accent, because it is not a quote. */
[data-section="worlds"] .w-tag--absent {
  color: var(--ink-60);
  letter-spacing: 0.02em;
}
[data-section="worlds"] .w-tag--absent::before {
  content: "";
  display: inline-block;
  width: 10px;
  height: 1px;
  margin-right: 0.55em;
  vertical-align: middle;
  background: currentColor;
  opacity: 0.6;
}

[data-section="worlds"] .w-desc {
  font-size: 0.855rem;
  line-height: 1.55;
  color: var(--ink-60);
  max-width: 42ch;
}
/* reserve two lines so the titles in a row sit on one baseline together
   instead of stepping up and down with copy length */
[data-section="worlds"] .w-card--tall .w-desc { min-height: calc(1.55em * 2); }
[data-section="worlds"] .w-card--wide .w-desc { min-height: calc(1.55em * 2); }
[data-section="worlds"] .w-feature .w-desc {
  font-size: clamp(0.9rem, 1vw, 0.98rem);
  color: var(--ink-80);
}

/* card foot: status on the left, loop control on the right */
[data-section="worlds"] .w-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  width: 100%;
  margin-top: auto;
  padding-top: 0.25rem;
}

/* sits where every sibling card has a Loop button; saying why there isn't
   one is the signal. Was --ink-40 at 0.75 opacity — about 2.4:1, the least
   readable text in the section. */
[data-section="worlds"] .w-srcnote {
  color: var(--ink-60);
  text-align: right;
  letter-spacing: 0.12em;
}

/* status chip */
[data-section="worlds"] .w-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  padding: 0.42em 0.8em;
  color: var(--ink-60);
  background: rgba(255, 255, 255, 0.045);
  box-shadow: inset 0 0 0 1px var(--line);
  clip-path: polygon(0 0, calc(100% - 6px) 0, 100% 6px, 100% 100%, 6px 100%, 0 calc(100% - 6px));
  white-space: nowrap;
}
[data-section="worlds"] .w-chip i {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.7;
  flex: none;
}
[data-section="worlds"] .w-chip--live {
  color: color-mix(in srgb, var(--accent) 72%, white);
  background: color-mix(in srgb, var(--accent) 13%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 45%, transparent);
}
[data-section="worlds"] .w-chip--live i {
  opacity: 1;
  box-shadow: 0 0 8px var(--accent);
  animation: w-pulse 2.6s ease-in-out infinite;
}
@keyframes w-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.35; }
}

/* mechanic labels */
[data-section="worlds"] .w-mech {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 0.25rem;
}
[data-section="worlds"] .w-mech li {
  padding: 0.34em 0.7em;
  color: var(--ink-60);
  box-shadow: inset 0 0 0 1px var(--line);
  clip-path: polygon(0 0, calc(100% - 5px) 0, 100% 5px, 100% 100%, 5px 100%, 0 calc(100% - 5px));
}

/* flagship CTA — the one place in this section with a real destination */
[data-section="worlds"] .w-cta {
  align-self: flex-start;
  margin-top: 0.55rem;
  padding: 0.85em 1.5em;
  font-size: 0.72rem;
}
[data-section="worlds"] .w-cta:hover {
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 75%, transparent);
}

/* "Real capture" marks footage from live play. It appears on every world that
   has some and on none that doesn't — its absence on Human Body is the point,
   so it gets a plate rather than a text-shadow and reads over any art. */
[data-section="worlds"] .w-capture {
  position: absolute;
  top: 0.85rem;
  left: 0.85rem;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 0.45em;
  padding: 0.42em 0.7em;
  color: var(--ink-80);
  background: rgba(4, 5, 12, 0.6);
  backdrop-filter: blur(7px);
  -webkit-backdrop-filter: blur(7px);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.09);
  clip-path: polygon(0 0, calc(100% - 6px) 0, 100% 6px, 100% 100%, 6px 100%, 0 calc(100% - 6px));
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.8);
}
[data-section="worlds"] .w-capture::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 9px var(--accent);
}

/* On the flagship the badge would land on top of the in-game mission card,
   which is the most valuable thing in the frame. It moves to the far corner. */
[data-section="worlds"] .w-feature .w-capture {
  left: auto;
  right: 0.85rem;
}

/* Human Body's badge used to be simply absent, which signalled nothing —
   an empty black corner is not a statement. The negative case now occupies
   the same corner as the positive one, in the same plate, with the light
   taken out of the dot: present, and visibly not the same claim. */
[data-section="worlds"] .w-capture--none,
[data-section="worlds"] .w-capture--model {
  color: var(--ink-60);
}
[data-section="worlds"] .w-capture--none::before,
[data-section="worlds"] .w-capture--model::before {
  background: transparent;
  box-shadow: inset 0 0 0 1px currentColor;
}
/* the Parthenon plate is a render but its loop is not, so the badge runs
   longer than the others; let it wrap rather than push past the frame */
[data-section="worlds"] .w-capture--model {
  max-width: calc(100% - 1.7rem);
  align-items: flex-start;
}
[data-section="worlds"] .w-capture--model::before { margin-top: 0.42em; flex: none; }

/* names the loop before it plays, so hovering the flagship is a labelled
   cut to a later step of the same mission rather than an unexplained one */
[data-section="worlds"] .w-loopnote {
  position: absolute;
  z-index: 4;
  left: 1rem;
  bottom: 3.7rem;   /* clears the play control, which owns the corner */
  max-width: min(30ch, 66%);
  padding: 0 0 0 0.1rem;
  color: var(--ink-60);
  line-height: 1.5;
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.95);
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 0.4s var(--ease), transform 0.4s var(--ease);
  pointer-events: none;
}
/* it appears where the play button is, so it takes the button's place only
   once the button has moved out of the way */
[data-section="worlds"] .w-card:hover .w-loopnote,
[data-section="worlds"] .w-card:focus-within .w-loopnote,
[data-section="worlds"] .w-card.is-playing .w-loopnote {
  opacity: 1;
  transform: translateY(0);
  transition-delay: 0.12s;
}

/* ---------- play controls ----------------------------------------
   Hover previews the loop; the button is the same thing made reachable
   by keyboard and touch, so nobody is locked out of the footage.
   ------------------------------------------------------------------ */

[data-section="worlds"] .w-play {
  display: inline-flex;
  align-items: center;
  gap: 0.7em;
  padding: 0.72em 1.15em;
  font-family: var(--f-mono);
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.15em;
  color: var(--ink);
  background: rgba(6, 8, 18, 0.72);
  backdrop-filter: blur(9px);
  -webkit-backdrop-filter: blur(9px);
  box-shadow: inset 0 0 0 1px var(--line-2);
  clip-path: polygon(0 0, calc(100% - 8px) 0, 100% 8px, 100% 100%, 8px 100%, 0 calc(100% - 8px));
  transition: background-color 0.4s var(--ease), box-shadow 0.4s var(--ease);
}

[data-section="worlds"] .w-feature .w-play {
  position: absolute;
  z-index: 4;
  left: 1rem;
  bottom: 1rem;
}

[data-section="worlds"] .w-play:hover {
  background: rgba(10, 13, 30, 0.9);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 70%, transparent);
}

/* compact variant that lives in a card foot rather than over the plate */
[data-section="worlds"] .w-play--mini {
  flex: none;
  gap: 0.55em;
  padding: 0.42em 0.75em;
  background: rgba(255, 255, 255, 0.045);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  box-shadow: inset 0 0 0 1px var(--line);
  clip-path: polygon(0 0, calc(100% - 6px) 0, 100% 6px, 100% 100%, 6px 100%, 0 calc(100% - 6px));
}
[data-section="worlds"] .w-play--mini .w-play__txt {
  color: var(--ink-60);
  transition: color 0.3s var(--ease);
}
[data-section="worlds"] .w-play--mini:hover .w-play__txt { color: var(--ink); }

[data-section="worlds"] .w-play__ico {
  width: 0;
  height: 0;
  flex: none;
  border-style: solid;
  border-width: 5px 0 5px 8px;
  border-color: transparent transparent transparent var(--accent);
  transition: border-color 0.3s var(--ease);
}
[data-section="worlds"] .w-card.is-playing .w-play__ico {
  width: 8px;
  height: 10px;
  border: 0;
  background: var(--accent);
  -webkit-mask: linear-gradient(#000 0 0) 0 0 / 3px 100% no-repeat,
                linear-gradient(#000 0 0) 100% 0 / 3px 100% no-repeat;
          mask: linear-gradient(#000 0 0) 0 0 / 3px 100% no-repeat,
                linear-gradient(#000 0 0) 100% 0 / 3px 100% no-repeat;
}

/* ---------- honesty footnote ------------------------------------- */

/* This paragraph is the section's credibility. It was set at 12.8px on
   --ink-40 — ~3.5:1, below AA — i.e. the hardest text here to read was the
   text asking to be believed. Same content, at --ink-60 (~7:1) and a size
   that does not need squinting. */
[data-section="worlds"] .w-note {
  margin-top: clamp(1.5rem, 2.6vw, 2.4rem);
  padding-top: 1.05rem;
  border-top: 1px solid var(--line);
  font-size: 0.855rem;
  line-height: 1.65;
  color: var(--ink-60);
  max-width: 78ch;
}
[data-section="worlds"] .w-note .micro {
  display: block;
  color: var(--ink-60);
  margin-bottom: 0.3rem;
}

/* ============================================================
   Responsive
   ============================================================ */

@media (max-width: 1180px) {
  /* the loop label stops earning its width before the chip does */
  [data-section="worlds"] .w-play--mini .w-play__txt { display: none; }
  [data-section="worlds"] .w-play--mini { padding: 0.5em 0.7em; }
}

@media (max-width: 1080px) {
  /* four portraits pair off cleanly two to a row, landscape goes full width */
  [data-section="worlds"] .w-card--wide { grid-column: 1 / -1; }
  [data-section="worlds"] .w-card--tall { grid-column: span 3; }

  [data-section="worlds"] .w-feature .w-clip {
    display: flex;
    flex-direction: column;
  }
  [data-section="worlds"] .w-feature .w-media { aspect-ratio: 16 / 9; flex: none; }
  [data-section="worlds"] .w-feature .w-panel {
    border-left: 0;
    border-top: 1px solid var(--line);
  }
  [data-section="worlds"] .w-play--mini .w-play__txt { display: inline; }
}

@media (max-width: 780px) {
  [data-section="worlds"] .w-play--mini .w-play__txt { display: none; }
}

@media (max-width: 640px) {
  [data-section="worlds"] .w-headside {
    align-items: flex-start;
    text-align: left;
    width: 100%;
  }
}

@media (max-width: 620px) {
  [data-section="worlds"] { --w-notch: 16px; }
  [data-section="worlds"] .w-grid { grid-template-columns: minmax(0, 1fr); }
  [data-section="worlds"] .w-card,
  [data-section="worlds"] .w-card--wide,
  [data-section="worlds"] .w-card--tall { grid-column: 1 / -1; }

  [data-section="worlds"] .w-feature .w-media { aspect-ratio: 4 / 3; }
  [data-section="worlds"] .w-card--tall .w-clip { aspect-ratio: 4 / 5; }
  /* a 2.3:1 banner is too shallow to carry overlaid copy at phone width */
  [data-section="worlds"] .w-card--wide .w-clip { aspect-ratio: 5 / 4; }
  [data-section="worlds"] .w-card--wide .w-panel { max-width: none; }
  [data-section="worlds"] .w-title { font-size: 1.15rem; }
  [data-section="worlds"] .w-card--wide .w-title { font-size: 1.15rem; }
  [data-section="worlds"] .w-desc { font-size: 0.875rem; max-width: none; }
  [data-section="worlds"] .w-card--tall .w-desc,
  [data-section="worlds"] .w-card--wide .w-desc { min-height: 0; }
  [data-section="worlds"] .w-play { font-size: 0.66rem; }
  [data-section="worlds"] .w-feature .w-play { left: 0.8rem; bottom: 0.8rem; }
  [data-section="worlds"] .w-play--mini .w-play__txt { display: inline; }
  [data-section="worlds"] .w-capture { top: 0.6rem; left: 0.6rem; }
  [data-section="worlds"] .w-feature .w-capture { left: auto; right: 0.6rem; }
  [data-section="worlds"] .w-loopnote { left: 0.8rem; bottom: 3.4rem; max-width: 78%; }
}

@media (max-width: 420px) {
  [data-section="worlds"] .w-foot { flex-wrap: wrap; row-gap: 0.45rem; }
  [data-section="worlds"] .w-srcnote { text-align: left; }
}

/* ============================================================
   Reduced motion — no parallax, no sweep, no autoplay, static cards
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  [data-section="worlds"] .w-frame,
  [data-section="worlds"] .w-plate,
  [data-section="worlds"] .w-art,
  [data-section="worlds"] .w-vid,
  [data-section="worlds"] .w-panel,
  [data-section="worlds"] .w-title {
    transform: none !important;
    transition: none !important;
  }
  /* the flagship push-in is motion we start ourselves, so it stops */
  [data-section="worlds"] .w-feature .w-art { animation: none !important; }
  /* the loop note is still shown — it is information, not decoration */
  [data-section="worlds"] .w-loopnote {
    opacity: 1;
    transform: none;
    transition: none;
  }
  [data-section="worlds"] .w-sweep { display: none; }
  [data-section="worlds"] .w-card:hover .w-sweep,
  [data-section="worlds"] .w-card:focus-within .w-sweep { animation: none; }
  [data-section="worlds"] .w-chip--live i { animation: none; }
  [data-section="worlds"] .w-rule::after { transform: scaleX(1); opacity: 0.55; }
  [data-section="worlds"] .w-card::before { opacity: 0.12; }
  [data-section="worlds"] .w-plate { transform: scale(1.02) !important; }
  [data-section="worlds"] .w-pillars i { box-shadow: none; }
}

/* Fallback for engines without color-mix(): keep everything legible. */
@supports not (color: color-mix(in srgb, red 50%, blue)) {
  [data-section="worlds"] .w-tag,
  [data-section="worlds"] .w-chip--live { color: var(--accent); }
  [data-section="worlds"] .w-card:hover .w-frame,
  [data-section="worlds"] .w-card:focus-within .w-frame { background: var(--accent); }
  [data-section="worlds"] .w-bloom { background: none; }
  [data-section="worlds"] .w-glint {
    background: linear-gradient(225deg, var(--accent) 0%, transparent 60%);
  }
  [data-section="worlds"] .w-pillars i { box-shadow: none; }
}
