@import url("https://fonts.googleapis.com/css2?family=Michroma&display=swap");


/*
  The lightbox button morph changes height, so its horizontal shear run
  must change at the same time to preserve the site's master angle.

  Registering this custom property as a <length> lets Web Animations
  interpolate it continuously rather than treating it as a discrete value.
*/
@property --media-lightbox-morph-shear {
  syntax: "<length>";

  /*
    IMPORTANT:
    The animated value lives on .media-lightbox-button-morph, while the
    visible skewed face is its ::before pseudo-element. This MUST inherit
    so the face uses the same continuously animated shear value.
  */
  inherits: true;

  initial-value: 32px;
}


:root {
  /*
    =========================================================
    Master per-page accent palette
    =========================================================

    These live at :root because both major UI systems need them:
      - the fixed header/nav buttons
      - the page frames + desktop sidebar, which live in <main>

    Edit these five RGB triplets to retheme the pages.
  */
  --accent-about-rgb: 255, 114, 2;
  --accent-contact-rgb: 255, 114, 2;

  --accent-brobots-rgb: 224, 255, 38;   /* #e0ff26 */
  --accent-etherian-rgb: 54, 232, 232;
  --accent-halodoom-rgb: 0, 187, 63;     /* #00bb3f */

  /*
    Current-page button darkness.

    50% = an even accent/black mix.
    Higher = brighter/more accent.
    Lower = darker/more black.
  */
  --active-page-accent-share: 50%;

  /*
    Outgoing-button release time.

    Incoming/pressed activation keeps the normal button transition speed.
    This longer duration is used ONLY when an outgoing page returns to its
    button and that button fades back to its normal state.
  */
  --active-page-release-duration: 580ms;

  /*
    Screenshot lightbox animation timing.
  */
  --media-lightbox-duration: 520ms;
  --media-lightbox-button-duration: 460ms;
  --media-lightbox-close-state-duration: 190ms;

  /*
    Desktop/tablet -> mobile handoff.
    These affect only the breakpoint-collapse animation.
  */
  --mobile-ui-collapse-duration: 620ms;
  --mobile-lightbox-collapse-duration: 560ms;
  --mobile-page-real-fade-duration: 220ms;
  --media-lightbox-ease:
    cubic-bezier(0.18, 0.78, 0.22, 1);

  /*
    Master UI diagonal angle.

    This used to live only on .site-header, which meant page-content modules
    elsewhere in the DOM could not inherit it. Keep it global so header,
    page-frame details, and media modules can all derive the exact same slope.
  */
  --button-shear-angle: -40deg;
}


/* ---------------------------------------------------------
   Simulacrum Interactive — responsive header shell

   This version links:
   - button height
   - shear amount
   - minimum visible face width
   - overlap amount

   It also adds a "merge" transition:
   - icon-button spacing closes smoothly to 0 before mobile mode
   - the hamburger appears at the same collective width
   - the hamburger then contracts as the viewport narrows
   --------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  min-width: 320px;
}

body {
  margin: 0;
  min-height: 100vh;
  background: #474847;
  color: #f0f0f0;
  font-family: Arial, Helvetica, sans-serif;
}


/* =========================================================
   Global background video
   ========================================================= */

.site-background {
  /*
    The video bezel is now the ACTUAL border around the video.

    Previously the element itself was inset from the viewport, so most of
    the visible grey area was really the BODY background behind it. That is
    why changing --background-video-frame-color barely appeared to do
    anything.

    Now the background fills the viewport and the border supplies the full
    bezel thickness, so this color variable directly controls the visible
    frame around the video.
  */
  --background-video-frame-width:
    clamp(16px, 1.4vw, 24px);

  --background-video-frame-color:
    rgb(18, 20, 22);

  position: fixed;
  inset: 0;

  z-index: -2;

  overflow: hidden;

  pointer-events: none;

  background:
    var(--background-video-frame-color);

  /*
    Keep the OUTSIDE perfectly square to the viewport. The dark background
    itself becomes the visible border, so there are no rounded outer corners
    where the body/background can bleed through.
  */
  border: 0;
  border-radius: 0;

  box-shadow:
    inset 0 0 10px rgba(0, 0, 0, 0.34);
}


.site-background-video {
  position: absolute;

  /*
    Keep a modest opaque dark-grey margin around the video, but make the
    video explicitly fill the remaining rectangle. Using width:auto /
    height:auto here allowed the replaced video element to fall back toward
    its intrinsic dimensions, which caused the huge empty area.
  */
  top:
    var(--background-video-frame-width);

  right:
    var(--background-video-frame-width);

  bottom:
    var(--background-video-frame-width);

  left:
    var(--background-video-frame-width);

  width:
    calc(
      100%
      -
      (var(--background-video-frame-width) * 2)
    );

  height:
    calc(
      100%
      -
      (var(--background-video-frame-width) * 2)
    );

  object-fit: cover;

  /*
    Round ONLY the inner edge of the video opening.

    The parent .site-background remains perfectly square to the viewport,
    so the outside corners never expose the page background. This radius
    only clips the video itself, letting the opaque dark-grey backing show
    through in the tiny corner wedges underneath the decorative frame.
  */
  border-radius:
    clamp(10px, 0.9vw, 16px);

  opacity: 0.62;

  pointer-events: none;
}


/*
  iOS Safari can occasionally refuse decorative autoplay (for example in
  Low Power Mode) and draw its own large play affordance over the video.

  This video is intentionally non-interactive, so suppress WebKit's native
  playback UI rather than allowing an unclickable control to appear.
*/
.site-background-video::-webkit-media-controls {
  display: none !important;
}


.site-background-video::-webkit-media-controls-panel {
  display: none !important;
}


.site-background-video::-webkit-media-controls-play-button {
  display: none !important;
}


.site-background-video::-webkit-media-controls-start-playback-button {
  display: none !important;
  -webkit-appearance: none;
}


/*
  Used by JS only as a harmless state hook when autoplay is temporarily
  blocked. The normal site background remains visible underneath.
*/
.site-background-video.is-autoplay-blocked {
  pointer-events: none;
}


/*
  Neutral dark veil keeps the motion atmospheric and prevents the
  background from competing with the header/page-frame UI.
*/
.site-background::after {
  content: "";

  position: absolute;
  inset: 0;

  background:
    rgba(18, 20, 22, 0.28);

  pointer-events: none;
}


/*
  Decorative motion is disabled for users who prefer reduced motion.
  The normal body background remains as the fallback.
*/
@media (prefers-reduced-motion: reduce) {
  .site-background-video {
    display: none;
  }
}


/* =========================================================
   Fixed header wrapper
   ========================================================= */

.site-header {
  --frame-height: clamp(82px, calc(64px + 3.9vw), 120px);
  --frame-pad-x: clamp(6px, 1vw, 14px);
  --frame-pad-y: clamp(6px, 0.7vw, 10px);

  --right-stretch-width:
    clamp(46px, calc((100vw - 420px) * 0.33), 520px);

  /*
    Horizontal alignment for the hamburger control.
    Matching the nav's -20px offset keeps the hamburger aligned with
    the collapsing icon-button group during the transition.
  */
  --menu-toggle-offset-x: -20px;

  /*
    Button geometry:
    35px shear at 48px height ~= 0.73 ratio.
  */
  --button-height:
    clamp(34px, calc(var(--frame-height) * 0.44), 48px);

  --button-shear:
    calc(var(--button-height) * 0.73);

  /*
    Master diagonal angle.

    This controls the nav buttons and hamburger directly.
    header-menu.js also reads this same value and rebuilds the
    mobile dropdown SVG shell corners so all diagonals stay matched.

    More negative = stronger slant.
  */
  /*
    --button-shear-angle is defined globally at :root so page modules can
    share this exact same diagonal.
  */

  /*
    Minimum usable horizontal face width AFTER the diagonal cut.
  */
  --button-face-min: 34px;

  /*
    Shared button appearance controls.
    These affect both the nav buttons and the hamburger.

    All colors are complete rgba() values, so the alpha channel directly
    controls the opacity of that specific part.
  */
  --button-border-width: 2px;

  /*
    Normal button gradient.

    --button-gradient-color is one shared RGBA color.
    Its A value is the MASTER opacity.

    The three intensity values multiply that master alpha at each
    gradient stop. Example:
      color alpha 0.80 × top intensity 0.25 = final alpha 0.20

    CSS cannot cleanly unpack three independent scalar intensities from
    one rgb() custom property, so keeping these as three explicit numbers
    is the native/maintainable solution.
  */
  --button-gradient-color: rgba(110, 110, 110, 0.78);

  --button-gradient-top-intensity: 0.35;
  --button-gradient-mid-intensity: 0.75;
  --button-gradient-bottom-intensity: 0.22;

  --button-border-color: rgba(240, 240, 240, 0.2);

  /* =======================================================
     Per-page accent palette
     =======================================================

     These five values are the MASTER page colors.
     Everything page-specific derives from them:
       - nav-button hover/focus
       - page morph animation
       - page-frame rails/highlights/dots
       - desktop secondary-panel triangle/accent

     Tweak these later without touching the individual effects.
  */
  /*
    Default remains Simulacrum orange.
  */
  --nav-accent-rgb:
    var(--accent-about-rgb);

  /*
    These remain as orange fallbacks for non-page controls.
    Page nav buttons calculate their hover directly from their own
    --nav-accent-rgb below.
  */
  --button-hover-color:
    rgba(255, 114, 2, 0.25);

  --button-hover-border-color:
    rgba(255, 210, 165, 0.4);

  /*
    Mobile menu visual controls.
  */

  /*
    Dropdown height controls.

    --mobile-menu-base-height is the design's full-height reference.
    --mobile-menu-height-scale compresses the overall menu vertically.

    The menu container itself changes height, while JavaScript redraws
    the SVG corner geometry in real rendered pixels so the corner cuts
    do NOT get squashed with the box.

      1    = 420px
      0.8  = 336px
      0.66 = 277.2px
  */
  --mobile-menu-base-height: 420px;
  --mobile-menu-height-scale: 0.75;

  --mobile-menu-height:
    calc(
      var(--mobile-menu-base-height)
      * var(--mobile-menu-height-scale)
    );

  --mobile-menu-shell-color: rgba(28, 30, 32, 0.65);
  --mobile-menu-shell-border-color: rgba(232, 236, 240, 0.2);
  --mobile-menu-shell-inner-border-color: rgba(120, 126, 132, 0.3);

  --mobile-menu-accent-color: rgba(255, 114, 2, 0.95);
  --mobile-menu-accent-soft: var(--secondary-panel-accent);

  --mobile-menu-link-color: rgba(38, 40, 42, 0.9);
  --mobile-menu-link-border-color: rgba(236, 238, 240, 0.2);

  /*
    Mobile menu animation controls.

    These are read by header-menu.js so the animation can be tuned
    from CSS without editing the JavaScript.
  */

  /*
    Overall open / close timing.
  */
  --menu-morph-duration: 1050ms;
  --menu-morph-close-duration: 895ms;

  /*
    Neck extrusion distance, measured in hamburger-button heights.
  */
  --menu-morph-extension-multiplier: 1.5;

  /*
    Animation timeline positions.

    Separate start/end values make it easy to create or remove delays.

    Example:
      neck ends at 13%
      parallelogram starts at 16%

    = 3% pause between those stages.
  */
  --menu-morph-neck-end: 13%;

  --menu-morph-parallelogram-start: 13%;
  --menu-morph-parallelogram-end: 27%;

  --menu-morph-reshape-start: 27%;

  /*
    Stage easing.

    Supported by header-menu.js:
      linear
      ease-in
      ease-out
      ease-in-out
  */
  --menu-morph-neck-ease: ease-out;
  --menu-morph-parallelogram-ease: ease-in-out;
  --menu-morph-reshape-ease: ease-out;

  /*
    Hamburger -> X timing, measured across the whole morph.
  */
  --menu-morph-icon-switch-at: 5%;
  --menu-morph-close-icon-switch-at: 5%;

  /*
    Real-menu handoff.

    80% means the real menu begins appearing during the final 20%
    of the fake-menu animation.

    Lower = earlier.
    Higher = later.
  */
  --menu-morph-real-menu-reveal-at: 55%;
  --menu-morph-fake-menu-fade-start: 45%;

  /*
    Crossfade speeds between the temporary SVG menu and the real menu.
  */
  --menu-morph-real-menu-fade-duration: 850ms;
  --menu-morph-fake-menu-fade-duration: 850ms;

  /*
    Launch parallelogram size.

    These control how large the detached "seed" parallelogram becomes
    BEFORE it begins travelling / reshaping into the final target.

    Keeping this smaller prevents the intermediate shape from becoming
    wider than the viewport near the header.
  */
  --menu-morph-parallelogram-width-ratio: 0.70;
  --menu-morph-parallelogram-depth-ratio: 0.50;

  /*
    Safety margin used to keep the launch parallelogram inside the
    viewport. This only constrains the detached Stage-2 launch shape;
    the final real menu/frame can still use its normal layout.
  */
  --menu-morph-viewport-safe-inset: 12px;

  /*
    Page-frame morph controls.

    Page morphs use their own timing family so their much larger motion
    can be tuned independently from the hamburger dropdown.
  */
  --page-morph-duration: 1150ms;
  --page-morph-close-duration: 950ms;

  --page-morph-extension-multiplier: 1.5;

  --page-morph-neck-end: 13%;
  --page-morph-parallelogram-start: 13%;
  --page-morph-parallelogram-end: 27%;
  --page-morph-reshape-start: 27%;

  --page-morph-neck-ease: ease-out;
  --page-morph-parallelogram-ease: ease-in-out;
  --page-morph-reshape-ease: ease-out;

  /*
    Page-frame crossfade.
  */
  --page-morph-real-frame-reveal-at: 55%;
  --page-morph-fake-frame-fade-start: 45%;

  --page-morph-real-frame-fade-duration: 850ms;
  --page-morph-fake-frame-fade-duration: 850ms;

  /*
    Page launch shape is intentionally much smaller than the final page
    frame. Stage 3 now does most of the growing while the shape is also
    travelling into position.
  */
  --page-morph-parallelogram-width-ratio: 0.32;
  --page-morph-parallelogram-depth-ratio: 0.22;

  --page-morph-viewport-safe-inset: 12px;

  /*
    Page-to-page switching.

    When a DIFFERENT page is selected, we no longer return all the way
    through the neck/button animation. Instead:

      page A -> detached transfer parallelogram
             -> page B

    These timings are independent from ordinary page open/close.

    --page-switch-overlap controls how long the incoming expansion starts
    BEFORE the outgoing collapse has finished.

      0ms   = strictly sequential
      100ms = slight overlap
      250ms = much more simultaneous
  */
  --page-switch-collapse-duration: 450ms;
  --page-switch-expand-duration: 600ms;
  --page-switch-overlap: 110ms;

  /*
    Outgoing real-page fade speed during quick returns.
    Multiplies --page-morph-real-frame-fade-duration.
  */
  --page-switch-return-frame-fade-multiplier: 0.1;

  /*
    Quick-return phase allocation.

    These values do NOT change the total return duration; they only decide
    how that time is distributed between the three visual stages.

    Increasing the first value gives the page -> parallelogram shape
    transformation more screen time while keeping the overall return quick.
  */
  --page-switch-return-parallelogram-at: 69%;
  --page-switch-return-reattach-at: 70%;

  /*
    Outgoing-page color return.

    This is measured across the ENTIRE quick-return animation.

      20% = reaches its page accent very quickly
      55% = gradual transition through roughly the first half
      69% = reaches full accent exactly as the parallelogram is formed

    Because --page-switch-return-parallelogram-at is currently 69%,
    values up to 69% keep the color transition inside that first stage.
  */
  --page-switch-return-color-complete-at: 80%;

  /*
    MERGE TRANSITION

    Normal spacing is 10px.
    From 1000px -> 700px, that spacing smoothly closes to 0.

      1000px = 10px
       920px =  5px
       840px =  0px
  */
  --button-spacing:
    clamp(0px, calc((100vw - 840px) * 0.0625), 10px);

  /*
    The minimum collective footprint of all five buttons.

    Five buttons:
      5 × (shear + face)
    Four overlaps:
      -4 × shear
    Four spaces:
      +4 × spacing

    Result:
      shear + (5 × face) + (4 × spacing)

    button-face-min = 34px, so five faces = 170px.
  */
  --button-group-width:
    calc(
      var(--button-shear)
      + 170px
      + var(--button-spacing)
      + var(--button-spacing)
      + var(--button-spacing)
      + var(--button-spacing)
    );

  position: fixed;
  z-index: 1000;
  top: 0;
  left: 0;

  width: 100%;

  padding:
    var(--frame-pad-y)
    var(--frame-pad-x);

  pointer-events: none;
}


/* =========================================================
   Five-piece raster frame
   ========================================================= */

.banner-frame {
  width: 100%;
  height: var(--frame-height);

  display: grid;
  align-items: stretch;

  grid-template-columns:
    calc(var(--frame-height) * 459 / 386)
    minmax(0, 1fr)
    calc(var(--frame-height) * 696 / 386)
    minmax(0, var(--right-stretch-width))
    calc(var(--frame-height) * 289 / 386);

  overflow: visible;
}

.banner-piece {
  min-width: 0;
  height: 100%;
}


/* =========================================================
   Fixed raster pieces
   ========================================================= */

.banner-left {
  width: calc(var(--frame-height) * 459 / 386);
  height: var(--frame-height);

  background:
    url("assets/header/banner-left.webp")
    center / 100% 100%
    no-repeat;
}

.banner-center {
  width: calc(var(--frame-height) * 696 / 386);
  height: var(--frame-height);

  background:
    url("assets/header/banner-center.webp")
    center / 100% 100%
    no-repeat;
}

.banner-right {
  width: calc(var(--frame-height) * 289 / 386);
  height: var(--frame-height);

  background:
    url("assets/header/banner-right.webp")
    center / 100% 100%
    no-repeat;
}


/* =========================================================
   Stretch zones
   ========================================================= */

.banner-left-stretch {
  background-image:
    url("assets/header/banner-leftstretch.webp");

  background-repeat: repeat-x;
  background-position: left center;
  background-size: auto 100%;

  margin-left: -1px;
}

.banner-right-stretch {
  background-image:
    url("assets/header/banner-rightstretch.webp");

  background-repeat: no-repeat;
  background-position: center;
  background-size: 100% 100%;

  margin-right: -1px;
}


/* =========================================================
   Foreground content layer
   ========================================================= */

.header-content {
  position: absolute;
  z-index: 1;

  top: var(--frame-pad-y);
  right: var(--frame-pad-x);
  bottom: var(--frame-pad-y);
  left: var(--frame-pad-x);

  display: grid;
  grid-template-rows: 1fr;

  grid-template-columns:
    calc(var(--frame-height) * 459 / 386)
    minmax(0, 1fr)
    calc(var(--frame-height) * 696 / 386)
    minmax(0, var(--right-stretch-width))
    calc(var(--frame-height) * 289 / 386);

  align-items: center;

  pointer-events: auto;
}


/* =========================================================
   Brand / logo
   ========================================================= */

.brand {
  grid-column: 1 / 3;
  grid-row: 1;

  align-self: stretch;
  justify-self: stretch;

  display: flex;
  align-items: center;
  justify-content: flex-start;

  padding-left:
    clamp(65px, calc(var(--frame-height) * 0.32), 80px);

  padding-right: 12px;
  padding-bottom: 0;

  min-width: 0;
  overflow: visible;

  text-decoration: none;
}

.brand-logo {
  display: block;

  height: calc(var(--frame-height) * 0.561);
  width: auto;

  max-width: none;
  max-height: none;

  flex: none;

  object-fit: contain;
}


/* =========================================================
   Main navigation
   ========================================================= */

.main-nav {
  grid-column: 4;
  grid-row: 1;

  align-self: stretch;
  justify-self: stretch;

  display: flex;
  align-items: center;
  justify-content: center;

  padding: 0;
  gap: 0;

  min-width: 0;

  /*
    Intentionally visible:
    the overlapped button row may extend beyond column 4.
  */
  overflow: visible;

  opacity: 1;
  transform: translateX(-20px) scale(1);
  transform-origin: right center;

  transition:
    opacity 280ms ease,
    transform 240ms ease;
}


/* =========================================================
   Sheared nav buttons
   ========================================================= */

.nav-button {
  position: relative;
  isolation: isolate;

  flex: 1 1 0;

  min-width:
    calc(var(--button-shear) + var(--button-face-min));

  max-width: none;

  height: var(--button-height);

  display: flex;
  align-items: center;
  justify-content: center;

  gap: clamp(4px, 0.35vw, 7px);

  padding-inline:
    clamp(10px, 0.65vw, 16px);

  color: #f0f0f0;
  text-decoration: none;

  font-size: clamp(10px, 0.68vw, 14px);
  line-height: 1;
  white-space: nowrap;

  transition:
    padding 160ms ease,
    gap 160ms ease,
    opacity 280ms ease,
    transform 140ms ease;
}


/*
  The diagonal sections overlap each other.

  --button-spacing controls the visible gap between button faces.
  Because --button-spacing becomes 0 near 700px, the five icon
  buttons smoothly "zip together" immediately before the menu swap.
*/
.nav-button + .nav-button {
  margin-left:
    calc((var(--button-shear) * -1) + var(--button-spacing));
}


.nav-button::before {
  /*
    Single skewed glass surface.

    Because this is a real transformed rectangle rather than a clipped
    polygon with a backing layer, its CSS border follows the full shape
    cleanly and the interior can be genuinely transparent.
  */
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;

  /*
    Narrow the rectangle by one full shear width before skewing.
    The skew then pushes the top/bottom edges outward by half a shear,
    recreating the same parallelogram footprint.
  */
  left: calc(var(--button-shear) / 2);
  right: calc(var(--button-shear) / 2);

  z-index: -1;

  transform: skewX(var(--button-shear-angle));
  transform-origin: center;

  border:
    var(--button-border-width)
    solid
    var(--button-border-color);

  background-image:
    linear-gradient(
      180deg,
      rgb(
        from var(--button-gradient-color)
        r g b /
        calc(alpha * var(--button-gradient-top-intensity))
      ),
      rgb(
        from var(--button-gradient-color)
        r g b /
        calc(alpha * var(--button-gradient-mid-intensity))
      ) 38%,
      rgb(
        from var(--button-gradient-color)
        r g b /
        calc(alpha * var(--button-gradient-bottom-intensity))
      )
    );

  background-color:
    transparent;

  transition:
    background-color 170ms ease,
    border-color 170ms ease,
    box-shadow 170ms ease;
}



/* Page-specific nav-button accent assignment. */
.nav-button[href="#about"] {
  --nav-accent-rgb:
    var(--accent-about-rgb);
}


.nav-button[href="#brobots"] {
  --nav-accent-rgb:
    var(--accent-brobots-rgb);
}


.nav-button[href="#etherian"] {
  --nav-accent-rgb:
    var(--media-lightbox-close-accent-rgb, var(--accent-etherian-rgb));
}


.nav-button[href="#halodoom"] {
  --nav-accent-rgb:
    var(--accent-halodoom-rgb);
}


.nav-button[href="#contact"] {
  --nav-accent-rgb:
    var(--accent-contact-rgb);
}


/*
  Pressed/current-page state.

  The visible color mixes the page accent with black. The amount of
  accent retained is controlled globally by --active-page-accent-share.
*/
.nav-button.is-page-active::before,
.nav-button[aria-current="page"]::before {
  background-color:
    color-mix(
      in srgb,
      rgb(var(--nav-accent-rgb))
        var(--active-page-accent-share),
      black
    );

  border-color:
    color-mix(
      in srgb,
      rgb(var(--nav-accent-rgb))
        var(--active-page-accent-share),
      black
    );

  box-shadow:
    inset 0 0 0 1px
      rgba(255, 255, 255, 0.12),

    0 0 7px
      rgba(
        var(--nav-accent-rgb),
        0.20
      );
}


/*
  Keep the pressed state dominant when the active button is hovered.
*/
/*
  Outgoing-page release state.

  JS adds .is-page-releasing for only the button whose page is returning.
  The incoming selection continues to use the normal 170ms transition.
*/
.nav-button.is-page-releasing::before {
  transition-duration:
    var(--active-page-release-duration);
}


.mobile-menu-link.is-page-releasing
.mobile-menu-link-shell-path {
  transition-duration:
    var(--active-page-release-duration);
}


.nav-button.is-page-active:hover::before,
.nav-button.is-page-active:focus-visible::before,
.nav-button[aria-current="page"]:hover::before,
.nav-button[aria-current="page"]:focus-visible::before {
  background-color:
    color-mix(
      in srgb,
      rgb(var(--nav-accent-rgb))
        var(--active-page-accent-share),
      black
    );

  border-color:
    color-mix(
      in srgb,
      rgb(var(--nav-accent-rgb))
        var(--active-page-accent-share),
      black
    );
}


.nav-button:hover::before,
.nav-button:focus-visible::before {
  border-color:
    rgba(
      var(--nav-accent-rgb),
      0.48
    );

  background-color:
    rgba(
      var(--nav-accent-rgb),
      0.25
    );
}


.nav-button:focus-visible {
  outline:
    2px solid
    rgba(
      var(--nav-accent-rgb),
      0.9
    );

  outline-offset: 2px;
}


/* Placeholder symbols until final icons are created. */

.nav-icon {
  flex: 0 0 auto;

  width: 1em;
  height: 1em;

  display: none;
  align-items: center;
  justify-content: center;

  font-size: 0.9em;
  line-height: 1;
}

.nav-label {
  display: inline-block;

  max-width: 90px;
  opacity: 1;

  overflow: hidden;
  white-space: nowrap;

  transition:
    opacity 280ms ease;
}


/* =========================================================
   Compact state
   ========================================================= */

@media (max-width: 1400px) {
  .nav-button {
    padding-inline: 4px;
    gap: 0;
  }

  .nav-label {
    max-width: 0;
    opacity: 0;
    margin: 0;
  }

  .nav-icon {
    display: inline-flex;
    font-size: 1em;
  }
}


/* =========================================================
   Mobile hamburger
   ========================================================= */

.menu-toggle {
  --menu-height:
    clamp(34px, calc(var(--frame-height) * 0.44), 46px);

  --menu-shear:
    calc(var(--menu-height) * 0.73);

  /*
    Normal compact hamburger size once the collapse finishes.
  */
  --menu-min-width:
    calc(var(--menu-shear) + 32px);

  grid-column: 4;
  grid-row: 1;

  justify-self: center;
  align-self: center;

  position: relative;
  isolation: isolate;

  /*
    At exactly 750px:
      27vw - 226.8px = 0
    so this resolves to exactly --button-group-width.

    Below 750px it removes about 0.27px of width for every 1px
    the viewport shrinks, until it reaches --menu-min-width.

    This gives:
      five tightly-packed buttons
              ↓
      one equally-wide hamburger panel
              ↓
      normal compact hamburger
  */
  width:
    clamp(
      var(--menu-min-width),
      calc(var(--button-group-width) + 27vw - 202.5px),
      var(--button-group-width)
    );

  min-width: var(--menu-min-width);

  height: var(--menu-height);

  margin: 0;
  padding: 0;

  display: flex;
  align-items: center;
  justify-content: center;

  border: 0;
  background: transparent;
  color: #f0f0f0;

  opacity: 0;

  /*
    Keep the hidden version at full scale. That way the crossfade
    doesn't introduce a second size change at the swap point.
  */
  transform: translateX(var(--menu-toggle-offset-x)) scale(1);

  pointer-events: none;

  transition:
    opacity 280ms ease,
    transform 140ms ease;
}

.menu-toggle::before {
  /*
    Same skewed-surface construction as the nav buttons so the
    hamburger shares exactly the same border/glass behavior.
  */
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;

  left: calc(var(--menu-shear) / 2);
  right: calc(var(--menu-shear) / 2);

  z-index: -1;

  transform: skewX(var(--button-shear-angle));
  transform-origin: center;

  border:
    var(--button-border-width)
    solid
    var(--button-border-color);

  background:
    linear-gradient(
      180deg,
      rgb(
        from var(--button-gradient-color)
        r g b /
        calc(alpha * var(--button-gradient-top-intensity))
      ),
      rgb(
        from var(--button-gradient-color)
        r g b /
        calc(alpha * var(--button-gradient-mid-intensity))
      ) 38%,
      rgb(
        from var(--button-gradient-color)
        r g b /
        calc(alpha * var(--button-gradient-bottom-intensity))
      )
    );

  transition:
    background 120ms ease,
    border-color 120ms ease;
}

.menu-toggle:hover::before,
.menu-toggle:focus-visible::before {
  border-color: var(--button-hover-border-color);

  background: var(--button-hover-color);
}


.menu-toggle-lines,
.menu-toggle-lines::before,
.menu-toggle-lines::after {
  display: block;

  width: 18px;
  height: 2px;

  background: currentColor;

  content: "";
}

.menu-toggle-lines {
  position: relative;
}

.menu-toggle-lines::before {
  position: absolute;
  top: -6px;
  left: 0;
}

.menu-toggle-lines::after {
  position: absolute;
  top: 6px;
  left: 0;
}


/* =========================================================
   Mobile state / merge point
   ========================================================= */

@media (max-width: 750px) {
  .main-nav {
    /*
      Fade the five-button group without shrinking it.
      By this point --button-spacing has already reached 0.
    */
    opacity: 0;
    transform: translateX(-20px) scale(1);
    pointer-events: none;
  }

  .menu-toggle {
    /*
      At 750px this starts at the collective width of the five
      collapsed icon buttons. From here it contracts continuously
      as the viewport narrows.
    */
    opacity: 1;
    transform: translateX(var(--menu-toggle-offset-x)) scale(1);
    pointer-events: auto;
  }
}


/* =========================================================
   Uniform header scaling below 485px
   ========================================================= */

/*
  485px is the minimum designed width of the header.

  Below this point the internal layout stops adapting. We freeze the
  composition at its 485px state, then uniformly scale the complete
  header — frame, logo, hamburger, dropdown and all — to the viewport.
*/
@media (max-width: 485px) {
  .site-header {
    /*
      Freeze responsive values at their 485px results.
    */
    --frame-height: 82.915px;
    --frame-pad-x: 6px;
    --frame-pad-y: 6px;
    --right-stretch-width: 46px;
    --button-spacing: 0px;

    /*
      Layout stays 485px wide; rendering scales uniformly.
    */
    width: 485px;

    transform:
      scale(calc(100vw / 485px));

    transform-origin: top left;
  }

  /*
    This normally contains a vw term, so freeze it at the value it has
    at the 485px breakpoint.
  */
  .menu-toggle {
    /*
      Match the live hamburger width at exactly 485px.

      With the new 750px collapse origin, the responsive formula resolves
      to ~125.08px here. Freezing to the old 100.78px value caused the
      visible size pop as the header entered its uniform-scaling mode.
    */
    width: 125.08px;
  }

  /*
    The dropdown has already reached its minimum width by 485px.
  */
  .mobile-menu {
    width: 236px;
  }
}


/* =========================================================
   Temporary demo page
   ========================================================= */

.page-demo {
  padding-top:
    calc(var(--frame-height) + (var(--frame-pad-y) * 2) + 42px);

  padding-right: clamp(24px, 6vw, 100px);
  padding-bottom: 80px;
  padding-left: clamp(24px, 6vw, 100px);
}



/* =========================================================
   Inline SVG page-frame morph targets
   ========================================================= */

/*
  These are the REAL page frames that the temporary morph SVG hands off
  into. The outer silhouette remains generated from the same geometry as
  the animation target, while the richer border is layered inside it.
*/
.prototype-page-frame {
  /*
    Shared vertical composition adjustment for tablet + desktop.

    Negative = move the page frame upward.
    Positive = move it downward.

    This changes the actual layout rectangle rather than using transform,
    so the morph target geometry and desktop popout continue to measure the
    correct position.
  */
  --page-frame-shift-y: -18px;

  position: fixed;
  z-index: 20;

  top:
    calc(
      clamp(82px, calc(64px + 3.9vw), 120px)
      + (clamp(6px, 0.7vw, 10px) * 2)
      + 20px
      + var(--page-frame-shift-y)
    );

  /*
    Tablet frame horizontal breathing room.
    Increase/decrease this single value to move both sides inward.
  */
  --page-frame-side-padding:
    clamp(28px, 3vw, 46px);

  right:
    var(--page-frame-side-padding);

  /*
    Increase the bottom clearance by the same amount the frame moves upward,
    preserving its existing tablet height.
  */
  bottom:
    calc(
      clamp(18px, 2vw, 30px)
      - var(--page-frame-shift-y)
    );

  left:
    var(--page-frame-side-padding);

  /*
    The frame itself fades in. The center is genuinely transparent;
    future HTML content lives in .prototype-page-frame-content.
  */
  opacity: 0;
  pointer-events: none;

  transition:
    opacity var(--prototype-page-frame-fade-duration, 850ms) ease;

  /*
    Base frame theme. These can later be overridden per [data-page].
  */
  --page-frame-shell: rgba(17, 19, 22, 0.92);
  --page-frame-shell-mid: rgba(35, 39, 44, 0.68);

  --page-frame-chrome-bright: rgba(238, 241, 244, 0.72);
  --page-frame-chrome-mid: rgba(135, 142, 150, 0.44);
  --page-frame-chrome-dark: rgba(62, 67, 73, 0.72);

  --page-accent-rgb:
    var(--accent-about-rgb);

  --page-frame-orange:
    rgba(
      var(--page-accent-rgb),
      0.92
    );

  --page-frame-orange-soft:
    rgba(
      var(--page-accent-rgb),
      0.34
    );

  --page-frame-accent-highlight:
    rgba(
      var(--page-accent-rgb),
      1
    );

  --page-frame-detail: rgba(150, 157, 165, 0.38);
  --page-frame-glass-line: rgba(255, 255, 255, 0.09);
}


.prototype-page-frame-shell {
  position: absolute;
  inset: 0;

  width: 100%;
  height: 100%;

  overflow: visible;

  pointer-events: none;
}


/* -------------------------
   Main structural ring
   ------------------------- */

.page-frame-ring {
  fill: var(--page-frame-shell);

  /*
    Small shadow + inner orange warmth gives the otherwise vector-clean
    frame some of the rendered/glass character of the concept image.
  */
  filter:
    drop-shadow(0 5px 9px rgba(0, 0, 0, 0.42))
    drop-shadow(
      0 0 3px
      rgba(
        var(--page-accent-rgb),
        0.10
      )
    );
}


.page-frame-edge,
.page-frame-orange-rail,
.page-frame-orange-highlight,
.page-frame-bottom-notch,
.page-frame-detail-line {
  fill: none;

  vector-effect: non-scaling-stroke;
  stroke-linejoin: miter;
}


.page-frame-edge--outer {
  stroke: var(--page-frame-detail);
  stroke-width: 2.4;
}


.page-frame-edge--chrome {
  stroke: var(--page-frame-chrome-mid);
  stroke-width: 1.3;
}


.page-frame-edge--inner {
  stroke: var(--page-frame-glass-line);
  stroke-width: 1.2;
}


.page-frame-orange-rail {
  stroke: var(--page-frame-orange);
  stroke-width: 1.65;

  filter:
    drop-shadow(0 0 2px var(--page-frame-orange-soft));
}


.page-frame-orange-highlight {
  stroke:
    var(--page-frame-accent-highlight);
  stroke-width: 2.2;
  stroke-linecap: round;

  filter:
    drop-shadow(0 0 3px var(--page-frame-orange-soft));
}


/* -------------------------
   Micro details
   ------------------------- */

.page-frame-detail-line {
  stroke: var(--page-frame-detail);
  stroke-width: 1.15;
  stroke-linecap: round;
}


.page-frame-detail-dot,
.page-frame-bottom-dots circle {
  fill: var(--page-frame-orange);
}




.page-frame-bottom-notch {
  stroke: var(--page-frame-orange);
  stroke-width: 1.35;

  filter:
    drop-shadow(0 0 2px var(--page-frame-orange-soft));
}


.page-frame-bottom-dots {
  opacity: 0.88;
}


/* -------------------------
   Future real page content
   ------------------------- */

.prototype-page-frame-content {
  position: absolute;

  /*
    JS writes the exact transparent-window offsets as CSS variables so
    HTML content automatically tracks the generated inner cutout.
  */
  top: var(--page-content-top, 48px);
  right: var(--page-content-right, 48px);
  bottom: var(--page-content-bottom, 48px);
  left: var(--page-content-left, 48px);

  min-width: 0;
  min-height: 0;

  overflow: hidden;

  pointer-events: auto;

  /*
    Each page interior responds to the ACTUAL usable frame opening rather
    than to the browser viewport. This keeps page modules independent from
    the frame's tablet/desktop layout rules.
  */
  container-type: size;
  container-name: page-content;
}


/* =========================================================
   Modular page-content foundation
   ========================================================= */

/*
  A .game-page is the self-contained interior of one morphing page frame.
  The global frame controls placement/morphing; the module controls only
  its own internal layout.
*/
.game-page {
  width: 100%;
  height: 100%;

  min-width: 0;
  min-height: 0;

  overflow: hidden;
}


/* =========================================================
   Media browser — Step 2 continuous responsive prototype
   ========================================================= */

/*
  One continuous composition scale now drives the viewer, thumbnail rail,
  arrows, spacing, and corner cuts.

  This avoids the previous breakpoint "pop" and prevents odd wide/short
  containers from making one part of the layout outgrow another.
*/
.media-browser {
  /*
    Generic per-page media accent. Brobots / Etherian / Halodoom all inherit
    their own page-frame theme automatically.
  */
  --media-accent-rgb:
    var(--page-accent-rgb);

  /*
    Padding responds to whichever dimension is more restrictive.
    There are no hard mode changes here.
  */
  --media-browser-outer-padding:
    clamp(
      18px,
      min(4.2cqw, 4.2cqh),
      42px
    );

  --media-browser-row-gap:
    clamp(
      12px,
      min(3cqw, 3cqh),
      28px
    );

  /*
    The whole media composition is sized from BOTH available width and
    available height.

    Vertical budget:
      viewer = 56.25% of composition width
      thumbnails = ~15% of composition width
      + one row gap

    1.38 is a small safety margin below the theoretical maximum, leaving
    breathing room even in unusually wide/short frame openings.
  */
  --media-composition-width:
    min(
      720px,
      calc(
        100cqw
        -
        (var(--media-browser-outer-padding) * 2)
      ),
      calc(
        (
          100cqh
          -
          (var(--media-browser-outer-padding) * 2)
          -
          var(--media-browser-row-gap)
        )
        * 1.38
      )
    );

  --media-thumb-width:
    calc(
      var(--media-composition-width) * 0.20
    );

  --media-arrow-width:
    calc(
      var(--media-composition-width) * 0.055
    );

  --media-strip-gap:
    clamp(
      8px,
      calc(var(--media-composition-width) * 0.025),
      20px
    );

  --media-thumb-gap:
    clamp(
      8px,
      calc(var(--media-composition-width) * 0.024),
      18px
    );

  /*
    IMPORTANT:
    --button-shear-angle now lives at :root, so this module can actually
    inherit it. The positive angle is used only for the trigonometric corner
    calculation; the visual slope remains exactly the same as the header.
  */
  --media-corner-angle:
    calc(var(--button-shear-angle) * -1);

  /*
    Corner rise changes smoothly with the composition size.
    Corner run is derived from the angle using the same relation as the
    frame/morph JS: horizontal run = vertical rise × tan(angle).
    The slope itself NEVER changes.
  */
  --media-viewer-corner-rise:
    clamp(
      14px,
      calc(var(--media-composition-width) * 0.038),
      28px
    );

  --media-thumb-corner-rise:
    clamp(
      7px,
      calc(var(--media-composition-width) * 0.018),
      13px
    );

  --media-viewer-corner-run:
    calc(
      var(--media-viewer-corner-rise)
      *
      tan(var(--media-corner-angle))
    );

  --media-thumb-corner-run:
    calc(
      var(--media-thumb-corner-rise)
      *
      tan(var(--media-corner-angle))
    );

  width: 100%;
  height: 100%;

  min-width: 0;
  min-height: 0;

  display: flex;
  flex-direction: column;

  align-items: center;
  justify-content: center;

  gap:
    var(--media-browser-row-gap);

  padding:
    var(--media-browser-outer-padding);

  overflow: hidden;
}


.media-viewer {
  flex: 0 0 auto;

  width:
    var(--media-composition-width);

  max-width: 100%;

  aspect-ratio: 16 / 9;

  min-width: 0;
  min-height: 0;

  display: grid;
  place-items: center;

  overflow: hidden;

  border:
    1px solid
    rgba(
      var(--page-accent-rgb),
      0.58
    );

  background:
    rgba(18, 21, 24, 0.28);

  clip-path:
    polygon(
      var(--media-viewer-corner-run) 0,
      100% 0,
      100% calc(100% - var(--media-viewer-corner-rise)),
      calc(100% - var(--media-viewer-corner-run)) 100%,
      0 100%,
      0 var(--media-viewer-corner-rise)
    );
}


.media-prototype-label {
  color:
    rgba(
      var(--page-accent-rgb),
      0.86
    );

  font-size:
    clamp(
      10px,
      calc(var(--media-composition-width) * 0.025),
      18px
    );

  letter-spacing:
    0.12em;

  opacity: 0.76;
}


.media-strip {
  flex: 0 0 auto;

  width:
    var(--media-composition-width);

  max-width: 100%;

  min-width: 0;
  min-height: 0;

  display: grid;

  grid-template-columns:
    var(--media-arrow-width)
    minmax(0, 1fr)
    var(--media-arrow-width);

  align-items: center;

  gap:
    var(--media-strip-gap);
}


.media-thumbnails {
  min-width: 0;
  min-height: 0;

  display: grid;
  grid-auto-flow: column;

  /*
    Keep three media tiles visible at once. Additional items remain in the
    same reusable rail and are revealed by the generic controller/arrows.
  */
  grid-auto-columns:
    calc(
      (
        100%
        -
        (var(--media-thumb-gap) * 2)
      )
      / 3
    );

  align-items: center;

  gap:
    var(--media-thumb-gap);

  overflow-x: auto;
  overflow-y: hidden;

  /*
    JS now controls when rail movement is smooth vs immediate.
    Keeping CSS at auto prevents viewport resizes/fullscreen changes from
    animating toward stale pixel scroll positions.
  */
  scroll-behavior: auto;
  scroll-snap-type: none;

  scrollbar-width: none;

  overscroll-behavior-inline: contain;

  /*
    The thumbnail rail is positioned by our logical media index.
    Disable browser scroll anchoring so a desktop/tablet layout handoff
    cannot temporarily "help" by preserving an obsolete pixel position.
  */
  overflow-anchor: none;
}

.media-thumbnails::-webkit-scrollbar {
  display: none;
}


.media-thumbnail {
  flex: 0 0 auto;

  width: 100%;

  aspect-ratio: 4 / 3;

  min-width: 0;
  min-height: 0;

  padding:
    clamp(
      4px,
      calc(var(--media-composition-width) * 0.012),
      10px
    );

  border:
    1px solid
    rgba(
      var(--page-accent-rgb),
      0.48
    );

  background:
    rgba(20, 23, 27, 0.34);

  color:
    rgba(240, 240, 240, 0.74);

  clip-path:
    polygon(
      var(--media-thumb-corner-run) 0,
      calc(100% - var(--media-thumb-corner-run)) 0,
      100% var(--media-thumb-corner-rise),
      100% calc(100% - var(--media-thumb-corner-rise)),
      calc(100% - var(--media-thumb-corner-run)) 100%,
      var(--media-thumb-corner-run) 100%,
      0 calc(100% - var(--media-thumb-corner-rise)),
      0 var(--media-thumb-corner-rise)
    );
}


.media-thumbnail.is-selected {
  border-color:
    rgba(
      var(--page-accent-rgb),
      0.92
    );

  background:
    rgba(
      var(--page-accent-rgb),
      0.12
    );
}


.media-thumbnail-type {
  font-size:
    clamp(
      8px,
      calc(var(--media-composition-width) * 0.017),
      13px
    );

  letter-spacing:
    0.08em;
}


.media-arrow {
  width:
    var(--media-arrow-width);

  height:
    calc(var(--media-thumb-width) * 0.75);

  padding: 0;

  display: grid;
  place-items: center;

  border: 0;
  background: transparent;

  color:
    rgba(
      var(--page-accent-rgb),
      0.86
    );

  font-size:
    clamp(
      22px,
      calc(var(--media-composition-width) * 0.055),
      42px
    );

  line-height: 1;

  opacity: 0.78;
}




/* ---------------------------------------------------------
   Real media content
   --------------------------------------------------------- */

.media-viewer-stage {
  position: absolute;
  inset: 0;

  display: grid;
  place-items: center;

  overflow: hidden;

  opacity: 0;

  transition:
    opacity 180ms ease;
}

.media-viewer-stage.is-ready {
  opacity: 1;
}

.media-viewer {
  position: relative;
}

.media-viewer-image,
.media-viewer-video,
.media-viewer-youtube {
  width: 100%;
  height: 100%;

  display: block;

  border: 0;

  background:
    rgba(8, 10, 12, 0.72);
}

.media-viewer-image {
  object-fit: contain;

  cursor: zoom-in;
}

.media-viewer-video {
  object-fit: contain;
}

.media-viewer-youtube {
  aspect-ratio: 16 / 9;
}


.media-youtube-local-fallback {
  position: relative;

  width: 100%;
  height: 100%;

  display: grid;
  place-items: center;

  overflow: hidden;

  background:
    rgba(8, 10, 12, 0.82);
}


.media-youtube-local-fallback-image {
  position: absolute;
  inset: 0;

  width: 100%;
  height: 100%;

  object-fit: cover;

  opacity: 0.62;
}


.media-youtube-local-fallback::after {
  content: "";

  position: absolute;
  inset: 0;

  background:
    rgba(6, 8, 10, 0.34);

  pointer-events: none;
}


.media-youtube-local-fallback-link {
  position: relative;
  z-index: 1;

  display: inline-flex;
  align-items: center;
  gap: 10px;

  padding:
    12px
    18px;

  border:
    1px solid
    rgba(
      var(--page-accent-rgb),
      0.72
    );

  background:
    rgba(12, 15, 18, 0.84);

  color: #ffffff;

  text-decoration: none;

  pointer-events: auto;
}


.media-youtube-local-fallback-link:hover,
.media-youtube-local-fallback-link:focus-visible {
  background:
    rgba(
      var(--page-accent-rgb),
      0.22
    );
}


.media-thumbnail {
  position: relative;

  overflow: hidden;

  cursor: pointer;

  transition:
    border-color 150ms ease,
    background-color 150ms ease,
    opacity 150ms ease,
    transform 150ms ease;
}

.media-thumbnail:hover,
.media-thumbnail:focus-visible {
  border-color:
    rgba(
      var(--page-accent-rgb),
      0.78
    );

  transform:
    translateY(-2px);
}

.media-thumbnail:focus-visible {
  outline: none;
}

.media-thumbnail-image {
  position: absolute;
  inset: 0;

  width: 100%;
  height: 100%;

  object-fit: cover;

  pointer-events: none;
}

.media-thumbnail-overlay,
.media-thumbnail-local-video {
  position: absolute;
  inset: 0;

  display: flex;
  align-items: center;
  justify-content: center;

  gap:
    clamp(
      4px,
      calc(var(--media-composition-width) * 0.008),
      8px
    );

  padding:
    clamp(
      5px,
      calc(var(--media-composition-width) * 0.012),
      10px
    );

  pointer-events: none;
}

.media-thumbnail-overlay {
  align-items: flex-end;
  justify-content: flex-start;

  background:
    linear-gradient(
      180deg,
      transparent 46%,
      rgba(7, 9, 11, 0.76)
    );
}

.media-thumbnail-local-video {
  flex-direction: column;

  background:
    linear-gradient(
      135deg,
      rgba(24, 28, 32, 0.86),
      rgba(9, 11, 13, 0.94)
    );
}

.media-thumbnail-play {
  display: grid;
  place-items: center;

  color:
    rgba(
      var(--page-accent-rgb),
      0.96
    );

  font-size:
    clamp(
      13px,
      calc(var(--media-composition-width) * 0.024),
      21px
    );

  filter:
    drop-shadow(
      0 0 4px
      rgba(
        var(--page-accent-rgb),
        0.34
      )
    );
}

.media-thumbnail.is-selected {
  box-shadow:
    inset 0 0 0 1px
    rgba(
      var(--page-accent-rgb),
      0.42
    );
}

.media-arrow {
  cursor: pointer;

  transition:
    opacity 150ms ease,
    color 150ms ease,
    transform 150ms ease;
}

.media-arrow:hover,
.media-arrow:focus-visible {
  opacity: 1;

  color:
    rgba(
      var(--page-accent-rgb),
      1
    );

  transform:
    scale(1.08);
}

.media-arrow:focus-visible {
  outline: none;
}

.media-arrow:disabled {
  opacity: 0.28;

  cursor: default;

  transform: none;
}


/* ---------------------------------------------------------
   Fullscreen screenshot preview
   --------------------------------------------------------- */

.media-lightbox {
  /*
    Keep the existing automatic image sizing/centering behavior.

    Instead of calculating image geometry in JS, reserve control gutters
    around the lightbox. The image still uses normal max-width/max-height
    containment inside this padded box.
  */
  --media-lightbox-side-gutter:
    clamp(76px, 7vw, 116px);

  /*
    Slightly larger than before because the X is now locked to the banner
    button's Y position instead of drifting upward during its morph.
  */
  --media-lightbox-top-gutter:
    clamp(112px, 11vh, 152px);

  --media-lightbox-bottom-gutter:
    clamp(30px, 4vh, 48px);

  position: fixed;
  inset: 0;

  z-index: 5000;

  display: grid;
  place-items: center;

  padding:
    var(--media-lightbox-top-gutter)
    var(--media-lightbox-side-gutter)
    var(--media-lightbox-bottom-gutter);

  background:
    rgba(5, 7, 9, 0);

  backdrop-filter:
    blur(0);

  -webkit-backdrop-filter:
    blur(0);

  opacity: 0;
  visibility: hidden;

  pointer-events: none;

  transition:
    background-color
      var(--media-lightbox-duration)
      var(--media-lightbox-ease),

    backdrop-filter
      var(--media-lightbox-duration)
      var(--media-lightbox-ease),

    -webkit-backdrop-filter
      var(--media-lightbox-duration)
      var(--media-lightbox-ease),

    opacity
      var(--media-lightbox-duration)
      var(--media-lightbox-ease),

    visibility
      0s linear
      var(--media-lightbox-duration);
}


.media-lightbox.is-open {
  background:
    rgba(5, 7, 9, 0.94);

  backdrop-filter:
    blur(10px);

  -webkit-backdrop-filter:
    blur(10px);

  opacity: 1;
  visibility: visible;

  pointer-events: auto;

  transition-delay: 0s;
}


.media-lightbox-image {
  display: block;

  /*
    Automatic intrinsic-ratio sizing remains intact.
    The lightbox's padding defines the safe rectangle, so the screenshot
    cannot overlap the X button or side arrows.
  */
  /*
    Use explicit viewport-derived limits instead of percentage max sizes.

    This keeps the screenshot fully inside the safe rectangle even when the
    browser becomes very wide but short, where percentage sizing inside the
    grid could allow the intrinsic image height to poke below the viewport.
  */
  max-width:
    calc(
      100vw -
      (var(--media-lightbox-side-gutter) * 2)
    );

  max-height:
    calc(
      100vh -
      var(--media-lightbox-top-gutter) -
      var(--media-lightbox-bottom-gutter)
    );

  width: auto;
  height: auto;

  object-fit: contain;

  opacity: 0;

  box-shadow:
    0 18px 60px
    rgba(0, 0, 0, 0.58);
}


.media-lightbox.is-settled
.media-lightbox-image {
  opacity: 1;
}


/*
  The real close button is hidden while the temporary morph proxy travels
  from/to the selected header button. It appears only after the morph lands.
*/
.media-lightbox-close {
  position: absolute;

  top:
    var(
      --media-lightbox-close-top,
      clamp(14px, 2vw, 26px)
    );

  right:
    clamp(14px, 2vw, 26px);

  /*
    JS copies the selected banner button's live dimensions here.
    This keeps tablet-icon and desktop-text button sizes consistent.
  */
  width:
    var(
      --media-lightbox-close-width,
      54px
    );

  height:
    var(
      --media-lightbox-close-height,
      46px
    );

  display: grid;
  place-items: center;

  margin: 0;
  padding: 0;

  border: 0;
  background: transparent;

  color: #ffffff;

  font: inherit;
  font-size:
    clamp(24px, 3vw, 32px);

  line-height: 1;

  cursor: pointer;

  isolation: isolate;

  /*
    JS copies the originating page accent here as an RGB triplet.
  */
  --media-lightbox-close-accent-rgb:
    var(--media-lightbox-close-accent-rgb, var(--accent-etherian-rgb));

  /*
    Height-only reduction for the fullscreen X.
    Width remains matched to the source banner button.
  */
  --media-lightbox-close-height-scale:
    0.7;

  opacity: 0;

  /*
    No opacity transition here: the temporary button morph already arrives
    visibly at this exact position/appearance. The real X simply takes over
    on the next frame instead of visibly fading in a second time.
  */
  transition: none;
}


/*
  Same construction as .nav-button::before.

  Rather than approximating the selected button's appearance, JS copies
  the COMPUTED pseudo-element styles from that exact button:
    - gradient
    - active-page tint
    - border
    - glow/shadow
    - shear size
*/
.media-lightbox-close::before {
  content: "";

  position: absolute;
  top: 0;
  bottom: 0;

  left:
    calc(
      var(
        --media-lightbox-close-shear,
        32px
      )
      / 2
    );

  right:
    calc(
      var(
        --media-lightbox-close-shear,
        32px
      )
      / 2
    );

  z-index: -1;

  transform:
    skewX(var(--button-shear-angle));

  transform-origin:
    center;

  border-style:
    solid;

  border-width:
    var(
      --media-lightbox-close-border-width,
      var(--button-border-width)
    );

  border-color:
    var(
      --media-lightbox-close-border-color,
      var(--button-border-color)
    );

  background-image:
    var(
      --media-lightbox-close-background-image,
      none
    );

  background-color:
    var(
      --media-lightbox-close-background-color,
      transparent
    );

  box-shadow:
    var(
      --media-lightbox-close-box-shadow,
      none
    );

  transition:
    background-color
      var(--media-lightbox-close-state-duration)
      ease,
    border-color
      var(--media-lightbox-close-state-duration)
      ease,
    box-shadow
      var(--media-lightbox-close-state-duration)
      ease;
}


.media-lightbox.is-settled
.media-lightbox-close {
  opacity: 1;
}


/*
  X BUTTON STATE MODEL

  1) Formation begins in the SELECTED/PRESSED styling copied from the
     originating banner button.
  2) Once settled, it fades to the normal UNPRESSED banner-button styling.
  3) Hover/focus uses the originating banner button's normal HOVER styling.
  4) When closing starts by ANY method, .is-closing overrides hover and
     fades the X back into the SELECTED/PRESSED styling before it moves.
*/
.media-lightbox.is-settled
.media-lightbox-close::before {
  border-color:
    var(
      --media-lightbox-close-unpressed-border-color,
      var(--button-border-color)
    );

  background-color:
    var(
      --media-lightbox-close-unpressed-background-color,
      transparent
    );

  box-shadow:
    var(
      --media-lightbox-close-unpressed-box-shadow,
      none
    );
}


.media-lightbox-close > span {
  position: relative;
  z-index: 1;
}


/* Match the HOME banner button's ordinary hover state. */
.media-lightbox.is-settled:not(.is-closing)
.media-lightbox-close:hover::before,
.media-lightbox.is-settled:not(.is-closing)
.media-lightbox-close:focus-visible::before {
  border-color:
    var(
      --media-lightbox-close-hover-border-color,
      rgba(
        var(--media-lightbox-close-accent-rgb),
        0.48
      )
    );

  background-color:
    var(
      --media-lightbox-close-hover-background-color,
      rgba(
        var(--media-lightbox-close-accent-rgb),
        0.25
      )
    );

  box-shadow:
    var(
      --media-lightbox-close-hover-box-shadow,
      none
    );
}


/*
  Pressed/selected state. This deliberately wins over :hover so clicking
  the X, Escape, or backdrop close all produce the exact same press-in.
*/
.media-lightbox.is-settled.is-closing
.media-lightbox-close::before {
  border-color:
    var(
      --media-lightbox-close-selected-border-color,
      var(--media-lightbox-close-border-color)
    );

  background-color:
    var(
      --media-lightbox-close-selected-background-color,
      var(--media-lightbox-close-background-color)
    );

  box-shadow:
    var(
      --media-lightbox-close-selected-box-shadow,
      var(--media-lightbox-close-box-shadow)
    );
}


.media-lightbox-close:focus-visible {
  outline:
    2px solid
    rgba(
      var(--media-lightbox-close-accent-rgb, var(--accent-etherian-rgb)),
      0.74
    );

  outline-offset: 3px;
}



/* ---------------------------------------------------------
   Fullscreen screenshot navigation
   --------------------------------------------------------- */

.media-lightbox-arrow {
  position: absolute;
  top: 50%;

  width:
    clamp(42px, 4vw, 54px);

  height:
    clamp(62px, 7vw, 86px);

  display: grid;
  place-items: center;

  padding: 0;

  border: 0;
  background: transparent;

  color:
    rgba(
      var(--media-lightbox-close-accent-rgb, var(--accent-etherian-rgb)),
      0.92
    );

  font: inherit;
  font-size:
    clamp(34px, 4vw, 52px);

  line-height: 1;

  cursor: pointer;

  transform:
    translateY(-50%);

  opacity: 0;

  pointer-events: none;

  transition:
    opacity 160ms ease,
    transform 160ms ease,
    color 160ms ease;
}


.media-lightbox.is-settled
.media-lightbox-arrow {
  opacity: 0.82;

  pointer-events: auto;
}


.media-lightbox-arrow--previous {
  left:
    calc(
      var(--media-lightbox-side-gutter) / 2
      - 22px
    );
}


.media-lightbox-arrow--next {
  right:
    calc(
      var(--media-lightbox-side-gutter) / 2
      - 22px
    );
}


.media-lightbox-arrow:hover,
.media-lightbox-arrow:focus-visible {
  color:
    rgba(
      var(--media-lightbox-close-accent-rgb, var(--accent-etherian-rgb)),
      1
    );

  opacity: 1;

  transform:
    translateY(-50%)
    scale(1.08);
}


.media-lightbox-arrow:focus-visible {
  outline: none;
}


.media-lightbox-arrow:disabled {
  color:
    rgba(
      170,
      176,
      182,
      0.48
    );

  /*
    Stay fully hidden during the opening morph, exactly like an enabled
    arrow. The settled rule below is the only place that reveals it.
  */
  opacity: 0;

  cursor: default;

  pointer-events: none;

  transform:
    translateY(-50%);
}


/*
  Once the lightbox has finished opening, disabled arrows fade from zero
  to their greyed-out resting opacity at the same time as enabled arrows.
*/
.media-lightbox.is-settled
.media-lightbox-arrow:disabled {
  opacity: 0.46;
}



/* ---------------------------------------------------------
   Temporary opening/closing image proxy
   --------------------------------------------------------- */

.media-lightbox-image-morph {
  position: fixed;

  z-index: 5002;

  margin: 0;

  display: block;

  object-fit: contain;

  pointer-events: none;

  will-change:
    left,
    top,
    width,
    height,
    clip-path,
    box-shadow;

  box-shadow:
    0 0 0
    rgba(0, 0, 0, 0);
}


/* ---------------------------------------------------------
   Header-button -> lightbox-close morph proxy
   --------------------------------------------------------- */

.media-lightbox-button-morph {
  position: fixed;

  z-index: 5003;

  display: grid;
  place-items: center;

  padding: 0;

  color: #f0f0f0;

  pointer-events: none;

  will-change:
    left,
    top,
    width,
    height;
}


.media-lightbox-button-morph::before {
  content: "";

  position: absolute;

  top: 0;
  bottom: 0;

  left:
    calc(
      var(--media-lightbox-morph-shear, 32px)
      / 2
    );

  right:
    calc(
      var(--media-lightbox-morph-shear, 32px)
      / 2
    );

  border-style:
    solid;

  border-width:
    var(
      --media-lightbox-morph-border-width,
      var(--button-border-width)
    );

  border-color:
    var(
      --media-lightbox-morph-border-color,
      var(--button-border-color)
    );

  background-image:
    var(
      --media-lightbox-morph-background-image,
      none
    );

  background-color:
    var(
      --media-lightbox-morph-background-color,
      transparent
    );

  box-shadow:
    var(
      --media-lightbox-morph-box-shadow,
      none
    );

  transform:
    skewX(var(--button-shear-angle));

  transform-origin:
    center;

  /*
    Used on the RETURN journey so the proxy can fade from the X's resting
    appearance back into the selected banner-button appearance while it
    travels home.
  */
  transition:
    background-color 190ms ease,
    border-color 190ms ease,
    box-shadow 190ms ease;
}


.media-lightbox-button-morph-label,
.media-lightbox-button-morph-x {
  position: absolute;

  z-index: 1;

  display: grid;
  place-items: center;

  inset: 0;

  line-height: 1;
}


.media-lightbox-button-morph-label {
  font-size:
    clamp(10px, 0.68vw, 14px);

  opacity: 1;
}


.media-lightbox-button-morph-x {
  font-size:
    clamp(24px, 3vw, 32px);

  opacity: 0;
}


.nav-button.is-lightbox-morph-source {
  visibility: hidden;
}


body.is-media-lightbox-open {
  overflow: hidden;
}


@media (prefers-reduced-motion: reduce) {
  .media-lightbox {
    transition-duration: 1ms;
  }

  .media-lightbox-image-morph,
  .media-lightbox-button-morph {
    display: none;
  }
}


/* -------------------------
   Open state
   ------------------------- */

.prototype-page-frame.is-open {
  opacity: 1;

  /*
    Once the real page is open, restore pointer interaction for its HTML
    content. The closed frame itself can remain non-interactive.
  */
  pointer-events: auto;
}


.prototype-page-frame:not(.is-open)
.prototype-page-frame-content {
  pointer-events: none;
}


.prototype-page-frame.is-open
.prototype-page-frame-content,
.prototype-page-frame.is-open
.game-page,
.prototype-page-frame.is-open
.media-browser,
.prototype-page-frame.is-open
.media-viewer,
.prototype-page-frame.is-open
.media-strip,
.prototype-page-frame.is-open
.media-thumbnails,
.prototype-page-frame.is-open
.media-thumbnail,
.prototype-page-frame.is-open
.media-arrow,
.prototype-page-frame.is-open
.media-viewer-stage,
.prototype-page-frame.is-open
.media-viewer-youtube,
.prototype-page-frame.is-open
.media-viewer-video {
  pointer-events: auto;
}


/*
  Page-specific theme assignment.
  All detailed frame/morph colors derive from these master accent values.
*/
.prototype-page-frame[data-page="about"] {
  --page-accent-rgb:
    var(--accent-about-rgb);

  --page-frame-orange:
    rgba(
      var(--accent-about-rgb),
      0.92
    );

  --page-frame-orange-soft:
    rgba(
      var(--accent-about-rgb),
      0.34
    );

  --page-frame-accent-highlight:
    rgba(
      var(--accent-about-rgb),
      1
    );

  --secondary-panel-accent:
    rgba(
      var(--accent-about-rgb),
      0.42
    );

  --secondary-panel-morph-fill:
    rgba(
      var(--accent-about-rgb),
      0.68
    );

  --secondary-panel-morph-fill-mid:
    rgba(
      var(--accent-about-rgb),
      0.58
    );

  --secondary-panel-morph-border:
    rgba(
      var(--accent-about-rgb),
      0.88
    );

  --secondary-panel-morph-border-mid:
    rgba(
      var(--accent-about-rgb),
      0.82
    );

  --secondary-panel-morph-inner:
    rgba(
      var(--accent-about-rgb),
      0.16
    );

  --secondary-panel-morph-inner-mid:
    rgba(
      var(--accent-about-rgb),
      0.14
    );
}


.prototype-page-frame[data-page="brobots"] {
  --page-accent-rgb:
    var(--accent-brobots-rgb);

  --page-frame-orange:
    rgba(
      var(--accent-brobots-rgb),
      0.92
    );

  --page-frame-orange-soft:
    rgba(
      var(--accent-brobots-rgb),
      0.34
    );

  --page-frame-accent-highlight:
    rgba(
      var(--accent-brobots-rgb),
      1
    );

  --secondary-panel-accent:
    rgba(
      var(--accent-brobots-rgb),
      0.42
    );

  --secondary-panel-morph-fill:
    rgba(
      var(--accent-brobots-rgb),
      0.68
    );

  --secondary-panel-morph-fill-mid:
    rgba(
      var(--accent-brobots-rgb),
      0.58
    );

  --secondary-panel-morph-border:
    rgba(
      var(--accent-brobots-rgb),
      0.88
    );

  --secondary-panel-morph-border-mid:
    rgba(
      var(--accent-brobots-rgb),
      0.82
    );

  --secondary-panel-morph-inner:
    rgba(
      var(--accent-brobots-rgb),
      0.16
    );

  --secondary-panel-morph-inner-mid:
    rgba(
      var(--accent-brobots-rgb),
      0.14
    );
}


.prototype-page-frame[data-page="etherian"] {
  --page-accent-rgb:
    var(--media-lightbox-close-accent-rgb, var(--accent-etherian-rgb));

  --page-frame-orange:
    rgba(
      var(--media-lightbox-close-accent-rgb, var(--accent-etherian-rgb)),
      0.92
    );

  --page-frame-orange-soft:
    rgba(
      var(--media-lightbox-close-accent-rgb, var(--accent-etherian-rgb)),
      0.34
    );

  --page-frame-accent-highlight:
    rgba(
      var(--media-lightbox-close-accent-rgb, var(--accent-etherian-rgb)),
      1
    );

  --secondary-panel-accent:
    rgba(
      var(--media-lightbox-close-accent-rgb, var(--accent-etherian-rgb)),
      0.42
    );

  --secondary-panel-morph-fill:
    rgba(
      var(--media-lightbox-close-accent-rgb, var(--accent-etherian-rgb)),
      0.68
    );

  --secondary-panel-morph-fill-mid:
    rgba(
      var(--media-lightbox-close-accent-rgb, var(--accent-etherian-rgb)),
      0.58
    );

  --secondary-panel-morph-border:
    rgba(
      var(--media-lightbox-close-accent-rgb, var(--accent-etherian-rgb)),
      0.88
    );

  --secondary-panel-morph-border-mid:
    rgba(
      var(--media-lightbox-close-accent-rgb, var(--accent-etherian-rgb)),
      0.82
    );

  --secondary-panel-morph-inner:
    rgba(
      var(--media-lightbox-close-accent-rgb, var(--accent-etherian-rgb)),
      0.16
    );

  --secondary-panel-morph-inner-mid:
    rgba(
      var(--media-lightbox-close-accent-rgb, var(--accent-etherian-rgb)),
      0.14
    );
}


.prototype-page-frame[data-page="halodoom"] {
  --page-accent-rgb:
    var(--accent-halodoom-rgb);

  --page-frame-orange:
    rgba(
      var(--accent-halodoom-rgb),
      0.92
    );

  --page-frame-orange-soft:
    rgba(
      var(--accent-halodoom-rgb),
      0.34
    );

  --page-frame-accent-highlight:
    rgba(
      var(--accent-halodoom-rgb),
      1
    );

  --secondary-panel-accent:
    rgba(
      var(--accent-halodoom-rgb),
      0.42
    );

  --secondary-panel-morph-fill:
    rgba(
      var(--accent-halodoom-rgb),
      0.68
    );

  --secondary-panel-morph-fill-mid:
    rgba(
      var(--accent-halodoom-rgb),
      0.58
    );

  --secondary-panel-morph-border:
    rgba(
      var(--accent-halodoom-rgb),
      0.88
    );

  --secondary-panel-morph-border-mid:
    rgba(
      var(--accent-halodoom-rgb),
      0.82
    );

  --secondary-panel-morph-inner:
    rgba(
      var(--accent-halodoom-rgb),
      0.16
    );

  --secondary-panel-morph-inner-mid:
    rgba(
      var(--accent-halodoom-rgb),
      0.14
    );
}


.prototype-page-frame[data-page="contact"] {
  --page-accent-rgb:
    var(--accent-contact-rgb);

  --page-frame-orange:
    rgba(
      var(--accent-contact-rgb),
      0.92
    );

  --page-frame-orange-soft:
    rgba(
      var(--accent-contact-rgb),
      0.34
    );

  --page-frame-accent-highlight:
    rgba(
      var(--accent-contact-rgb),
      1
    );

  --secondary-panel-accent:
    rgba(
      var(--accent-contact-rgb),
      0.42
    );

  --secondary-panel-morph-fill:
    rgba(
      var(--accent-contact-rgb),
      0.68
    );

  --secondary-panel-morph-fill-mid:
    rgba(
      var(--accent-contact-rgb),
      0.58
    );

  --secondary-panel-morph-border:
    rgba(
      var(--accent-contact-rgb),
      0.88
    );

  --secondary-panel-morph-border-mid:
    rgba(
      var(--accent-contact-rgb),
      0.82
    );

  --secondary-panel-morph-inner:
    rgba(
      var(--accent-contact-rgb),
      0.16
    );

  --secondary-panel-morph-inner-mid:
    rgba(
      var(--accent-contact-rgb),
      0.14
    );
}


/*
  Page frames only participate in the middle/icon-button mode for now.
*/
@media (max-width: 750px) {
  .prototype-page-frame {
    display: none;
  }
}


/* =========================================================
   Full-text desktop page layout
   ========================================================= */

/*
  Above 1400px the full text nav buttons use the SAME page morph system,
  but the final page frame occupies only the LEFT half of the viewport.

  The reference composition is almost square, so aspect ratio wins over
  filling arbitrary available space. The frame grows as large as possible
  while staying:
    - inside the left half
    - below the header
    - vertically centered in the available area
*/
@media (min-width: 1401px) {
  .prototype-page-frame {
    --desktop-page-aspect: 1.006;

    --desktop-page-area-top:
      calc(
        clamp(82px, calc(64px + 3.9vw), 120px)
        + (clamp(6px, 0.7vw, 10px) * 2)
        + 18px
      );

    --desktop-page-available-width:
      calc(
        50vw -
        (var(--desktop-page-gap) * 2)
      );

    --desktop-page-available-height:
      calc(
        100vh -
        var(--desktop-page-area-top) -
        var(--desktop-page-gap)
      );

    /*
      Width is constrained by BOTH:
        left-half width
        available height × target aspect ratio
    */
    --desktop-page-width:
      min(
        var(--desktop-page-available-width),
        calc(
          var(--desktop-page-available-height)
          * var(--desktop-page-aspect)
        )
      );

    --desktop-page-height:
      calc(
        var(--desktop-page-width)
        / var(--desktop-page-aspect)
      );

    width:
      var(--desktop-page-width);

    height:
      var(--desktop-page-height);

    /*
      Center horizontally inside the left 50vw, then add a little extra
      clearance from the viewport's left frame.
    */
    --desktop-page-left-padding:
      clamp(18px, 1.6vw, 30px);

    left:
      calc(
        25vw
        -
        (var(--desktop-page-width) / 2)
        +
        var(--desktop-page-left-padding)
      );

    right: auto;
    bottom: auto;

    /*
      Center vertically inside the area beneath the header.
    */
    top:
      calc(
        var(--desktop-page-area-top)
        +
        (
          var(--desktop-page-available-height)
          -
          var(--desktop-page-height)
        ) / 2
        +
        var(--page-frame-shift-y)
      );
  }
}



/* =========================================================
   Desktop secondary glass panel
   ========================================================= */

/*
  This panel exists on every page frame, but only appears in full-text
  desktop mode. It sits BEHIND the main frame and slides out from the
  main frame's right edge after the main page has finished forming.
*/
.prototype-page-frame {
  /*
    Desktop <-> tablet composition transition.
    These control only the FRAME resize between the two layouts.
    The sidebar uses its own close/open timings.
  */
  --page-layout-transition-duration: 480ms;

  --page-layout-transition-ease:
    cubic-bezier(0.20, 0.72, 0.22, 1);

  /*
    Keep this available outside the desktop media query as well. It lets
    the popout retain its desktop geometry for a few hundred milliseconds
    while it gets sucked back in after crossing the breakpoint.
  */
  --desktop-page-gap:
    clamp(16px, 1.15vw, 26px);

  --secondary-panel-delay: 160ms;

  /*
    Triangle -> panel morph timing.
  */
  --secondary-panel-duration: 720ms;
  --secondary-panel-close-duration: 460ms;

  /*
    Fraction of the open animation spent growing from the tiny seed
    triangle into the large triangle before the final panel reshape.
  */
  --secondary-panel-triangle-stage: 38%;

  --secondary-panel-ease:
    cubic-bezier(0.18, 0.78, 0.22, 1);

  --secondary-panel-close-ease:
    cubic-bezier(0.55, 0, 0.72, 0.28);

  /*
    Small overlap under the main frame strengthens the illusion that
    this panel physically slides out from behind it.
  */
  --secondary-panel-overlap: 22px;

  /*
    Final desktop popout placement.
    The lower inset is intentionally larger so the panel clears the
    main frame's bottom-right angled section.
  */
  --secondary-panel-top-inset: 4.5%;
  --secondary-panel-bottom-inset: 11%;

  /*
    Vertical size of the final right-side diagonal cuts. JS converts
    this into the matching horizontal offset using the SAME master
    frame/button/menu slope, so the angle never stretches.
  */
  --secondary-panel-corner-height:
    clamp(42px, 8.5%, 68px);

  --secondary-panel-fill:
    rgba(105, 118, 138, 0.24);

  --secondary-panel-border:
    rgba(194, 205, 218, 0.28);

  --secondary-panel-inner-border:
    rgba(255, 255, 255, 0.08);

  --secondary-panel-highlight:
    rgba(255, 255, 255, 0.06);

  --secondary-panel-accent:
    rgba(
      var(--page-accent-rgb),
      0.42
    );

  /*
    Triangle -> glass morph colors. JavaScript reads these so the same
    secondary-panel animation automatically inherits each page's accent.
  */
  --secondary-panel-morph-fill:
    rgba(
      var(--page-accent-rgb),
      0.68
    );

  --secondary-panel-morph-fill-mid:
    rgba(
      var(--page-accent-rgb),
      0.58
    );

  --secondary-panel-morph-border:
    rgba(
      var(--page-accent-rgb),
      0.88
    );

  --secondary-panel-morph-border-mid:
    rgba(
      var(--page-accent-rgb),
      0.82
    );

  --secondary-panel-morph-inner:
    rgba(
      var(--page-accent-rgb),
      0.16
    );

  --secondary-panel-morph-inner-mid:
    rgba(
      var(--page-accent-rgb),
      0.14
    );

  /*
    Establish a predictable local layer stack:
      secondary panel
      main SVG frame
      page content
  */
  isolation: isolate;
}


.prototype-page-frame-shell {
  z-index: 2;
}


.prototype-page-frame-content {
  z-index: 3;
}


.desktop-secondary-panel {
  display: none;
}


/*
  Only the full-text PC mode gets the secondary panel for now.
*/
@media (min-width: 1401px) {
  .desktop-secondary-panel {
    position: absolute;

    display: block;

    /*
      Final panel begins exactly at the main frame's right edge, with a
      small amount tucked underneath it so the triangle feels attached.
    */
    left:
      calc(
        100% -
        var(--secondary-panel-overlap)
      );

    top:
      var(--secondary-panel-top-inset);

    --desktop-popout-right-padding:
      clamp(18px, 1.6vw, 30px);

    width:
      calc(
        50vw
        -
        var(--desktop-page-gap)
        +
        var(--secondary-panel-overlap)
        -
        var(--desktop-page-left-padding)
        -
        var(--desktop-popout-right-padding)
      );

    bottom:
      var(--secondary-panel-bottom-inset);

    height: auto;

    z-index: 1;

    pointer-events: none;

    /*
      The container itself does not slide anymore. The glass surface
      morphs inside this final layout box.
    */
    opacity: 1;
  }


  .desktop-secondary-panel-glass {
    position: absolute;
    inset: 0;

    /*
      Default resting state is the tiny triangle, anchored to the
      center-right edge of the main page frame.
      JS animates this through a large triangle into the final panel.
    */
    clip-path:
      polygon(
        0 47%,
        0 47%,
        7% 50%,
        7% 50%,
        0 53%,
        0 53%
      );

    background-color:
      var(--secondary-panel-morph-fill);

    backdrop-filter:
      blur(18px)
      saturate(112%);

    -webkit-backdrop-filter:
      blur(18px)
      saturate(112%);

    box-shadow:
      inset 0 0 0 3px
        var(--secondary-panel-morph-inner),

      inset 18px 0 40px
        rgba(255, 255, 255, 0.025),

      0 8px 24px
        rgba(0, 0, 0, 0.16);

    opacity: 0;

    will-change:
      clip-path,
      background-color,
      box-shadow,
      opacity;
  }


  /*
    Soft glass reflection. Kept separate so the base fill can interpolate
    cleanly from orange into the final grey glass.
  */
  .desktop-secondary-panel-glass::after {
    content: "";

    position: absolute;
    inset: 0;

    background:
      linear-gradient(
        115deg,
        var(--secondary-panel-highlight),
        transparent 23%,
        transparent 70%
      );

    pointer-events: none;
  }


  /*
    A faint connection rail stays on the main-frame side of the panel.
    It is revealed naturally by the clip-path morph.
  */
  .desktop-secondary-panel-glass::before {
    content: "";

    position: absolute;

    top: 4%;
    bottom: 4%;
    left: 0;

    width: 1px;

    background:
      var(--secondary-panel-accent);

    box-shadow:
      0 0 5px
      var(--secondary-panel-morph-inner);
  }


  .desktop-secondary-panel-content {
    position: absolute;

    top: 5%;
    right: 8%;
    bottom: 5%;
    left:
      calc(
        var(--secondary-panel-overlap) +
        4%
      );

    min-width: 0;
    min-height: 0;

    overflow: hidden;

    pointer-events: auto;

    /*
      Content is hidden until the morph is essentially complete.
    */
    opacity: 0;

    transition:
      opacity 180ms ease;
  }


  .prototype-page-frame.is-secondary-open
  .desktop-secondary-panel-content {
    opacity: 1;

    transition-delay:
      calc(
        var(--secondary-panel-duration) * 0.78
      );
  }
}



/*
  During the desktop -> tablet handoff the media query has already changed,
  but we temporarily keep the desktop popout alive long enough to reverse
  its triangle morph before the main frame resizes.

  The main frame itself is visually held in its old desktop rectangle by
  a FLIP transform in JavaScript.
*/

.prototype-page-frame.is-layout-transitioning
.desktop-secondary-panel-glass {
  position: absolute;
  inset: 0;

  clip-path:
    polygon(
      0 47%,
      0 47%,
      7% 50%,
      7% 50%,
      0 53%,
      0 53%
    );

  background-color:
    var(--secondary-panel-morph-fill);

  backdrop-filter:
    blur(18px)
    saturate(112%);

  -webkit-backdrop-filter:
    blur(18px)
    saturate(112%);

  box-shadow:
    inset 0 0 0 3px
      var(--secondary-panel-morph-inner),

    inset 18px 0 40px
      rgba(255, 255, 255, 0.025),

    0 8px 24px
      rgba(0, 0, 0, 0.16);

  opacity: 0;

  will-change:
    clip-path,
    background-color,
    box-shadow,
    opacity;
}


.prototype-page-frame.is-layout-transitioning
.desktop-secondary-panel-glass::before {
  content: "";

  position: absolute;

  top: 4%;
  bottom: 4%;
  left: 0;

  width: 1px;

  background:
    var(--secondary-panel-accent);

  box-shadow:
    0 0 5px
    var(--secondary-panel-morph-inner);
}


.prototype-page-frame.is-layout-transitioning
.desktop-secondary-panel-glass::after {
  content: "";

  position: absolute;
  inset: 0;

  background:
    linear-gradient(
      115deg,
      var(--secondary-panel-highlight),
      transparent 23%,
      transparent 70%
    );

  pointer-events: none;
}


.prototype-page-frame.is-layout-transitioning
.desktop-secondary-panel-content {
  position: absolute;

  top: 5%;
  right: 8%;
  bottom: 5%;

  left:
    calc(
      var(--secondary-panel-overlap)
      +
      4%
    );

  min-width: 0;
  min-height: 0;

  overflow: hidden;

  pointer-events: none;

  opacity: 0;
}


.prototype-page-frame.is-layout-transitioning
.desktop-secondary-panel {
  position: absolute;

  display: block;

  left:
    calc(
      100% -
      var(--secondary-panel-overlap)
    );

  top:
    var(--secondary-panel-top-inset);

  --desktop-popout-right-padding:
    clamp(18px, 1.6vw, 30px);

  width:
    calc(
      50vw
      -
      var(--desktop-page-gap)
      +
      var(--secondary-panel-overlap)
      -
      var(--desktop-page-left-padding, 0px)
      -
      var(--desktop-popout-right-padding)
    );

  bottom:
    var(--secondary-panel-bottom-inset);

  height: auto;

  z-index: 1;

  pointer-events: none;
}


.prototype-page-frame.is-layout-transitioning {
  /*
    JavaScript owns the frame rectangle during the breakpoint handoff.
    Width/height are regenerated continuously so the shared diagonal
    geometry remains correct even while the browser window is still moving.
  */
  will-change: left, top, width, height;
}


/*
  Reduced-motion keeps the final visual composition but removes the slide.
*/
@media (min-width: 1401px) and (prefers-reduced-motion: reduce) {
  .desktop-secondary-panel,
  .prototype-page-frame.is-secondary-open
  .desktop-secondary-panel {
    transition: none;
  }
}


/* =========================================================
   Very narrow safety behavior
   ========================================================= */

@media (max-width: 380px) {
  .site-header {
    --frame-pad-x: 4px;
    --frame-pad-y: 5px;
  }
}


/* =========================================================
   Functional mobile menu
   ========================================================= */

/*
  Static visual pass based on the chosen concept direction:
  - clean/translucent glass from concept 3
  - stronger framing + orange edge accents from concept 1
  - SVG owns unusual shell/button geometry
  - links remain normal HTML
*/
.mobile-menu {
  grid-column: 4 / 6;
  grid-row: 1;

  position: absolute;
  top: calc(100% - 9px);
  right: 0;

  width: clamp(236px, 48vw, 330px);
  height: var(--mobile-menu-height);

  padding: 0;

  z-index: -1;

  background: none;
  border: 0;

  opacity: 0;

  transform:
    translateY(-10px)
    scaleY(0.92);

  transform-origin: top right;

  pointer-events: none;

  transition:
    opacity 280ms ease,
    transform 160ms ease;
}


/* -------------------------
   Outer SVG shell
   ------------------------- */

.mobile-menu-shell {
  position: absolute;
  inset: 0;

  width: 100%;
  height: 100%;

  overflow: visible;

  pointer-events: none;
}

.mobile-menu-shell-path {
  vector-effect: non-scaling-stroke;
  stroke-linejoin: miter;
}

.mobile-menu-shell-path--outer {
  fill: var(--mobile-menu-shell-color);
  stroke: var(--mobile-menu-shell-border-color);
  stroke-width: 3;
}

.mobile-menu-shell-path--inner {
  fill: none;
  stroke: var(--mobile-menu-shell-inner-border-color);
  stroke-width: 2;
}

.mobile-menu-shell-accent {
  fill: none;
  stroke: var(--mobile-menu-accent-color);
  stroke-width: 3;

  vector-effect: non-scaling-stroke;
  stroke-linecap: square;

  filter:
    drop-shadow(0 0 3px var(--mobile-menu-accent-soft));
}

.mobile-menu-shell-accent--corner {
  stroke-width: 2.4;
}


/* -------------------------
   Opened state
   ------------------------- */

.mobile-menu.is-open {
  opacity: 1;

  transform:
    translateY(0)
    scaleY(1);

  pointer-events: auto;
}


/* -------------------------
   Link stack
   ------------------------- */

.mobile-menu-links {
  position: relative;
  z-index: 1;

  width: 100%;
  height: 100%;

  padding:
    calc(clamp(34px, 5vw, 46px) * var(--mobile-menu-height-scale))
    clamp(22px, 4vw, 34px)
    calc(clamp(28px, 4vw, 38px) * var(--mobile-menu-height-scale));

  display: flex;
  flex-direction: column;

  gap:
    calc(
      clamp(10px, 1.8vw, 16px)
      * var(--mobile-menu-height-scale)
    );
}


/* -------------------------
   Individual menu items
   ------------------------- */

.mobile-menu-link {
  position: relative;
  isolation: isolate;

  /*
    Each mobile menu button carries its own page accent.
    Defaults to About/Contact orange unless overridden below.
  */
  --mobile-menu-item-accent-rgb:
    var(--accent-about-rgb);

  --mobile-menu-accent-color:
    rgba(
      var(--mobile-menu-item-accent-rgb),
      0.95
    );

  --mobile-menu-accent-soft:
    rgba(
      var(--mobile-menu-item-accent-rgb),
      0.24
    );

  --mobile-menu-item-hover-fill:
    rgba(
      var(--mobile-menu-item-accent-rgb),
      0.25
    );

  --mobile-menu-item-hover-border:
    rgba(
      var(--mobile-menu-item-accent-rgb),
      0.48
    );

  /*
    All five items divide the available inner height evenly.
    min-height: 0 is important: it allows them to shrink enough to
    remain inside the frame even at smaller menu-height scales.
  */
  flex: 1 1 0;
  min-height: 0;

  display: flex;
  align-items: center;

  padding:
    0
    clamp(42px, 8vw, 58px)
    0
    clamp(20px, 4vw, 30px);

  color: #f0f0f0;
  text-decoration: none;

  overflow: visible;
}


/*
  SVG plate behind each real HTML link.
*/
.mobile-menu-link-shell {
  position: absolute;
  inset: 0;

  z-index: -1;

  width: 100%;
  height: 100%;

  overflow: visible;

  pointer-events: none;
}

.mobile-menu-link-shell-path {
  fill: var(--mobile-menu-link-color);
  stroke: var(--mobile-menu-link-border-color);

  stroke-width: 1.4;

  vector-effect: non-scaling-stroke;
  stroke-linejoin: miter;

  transition:
    fill 170ms ease,
    stroke 170ms ease,
    filter 170ms ease;
}


/*
  Subtle glossy sweep.
*/
.mobile-menu-link::after {
  content: "";

  position: absolute;
  z-index: -1;

  top: 2px;
  right: 12%;
  bottom: 2px;
  left: 62%;

  background:
    linear-gradient(
      135deg,
      rgba(255,255,255,0.035),
      rgba(255,255,255,0)
    );

  transform: skewX(var(--button-shear-angle));

  pointer-events: none;
}


/* -------------------------
   Link text / decorations
   ------------------------- */

.mobile-menu-link-text {
  position: relative;
  z-index: 2;

  font-size: clamp(17px, 3vw, 22px);
  line-height: 1;
}

.mobile-menu-link-marker,
.mobile-menu-link-motif {
  position: absolute;
  z-index: 2;

  right: clamp(15px, 3vw, 22px);
  top: 50%;

  transform: translateY(-50%);

  display: flex;
  align-items: center;
  justify-content: center;

  width: 24px;
  height: 22px;

  color: var(--mobile-menu-accent-color);

  pointer-events: none;
}

.mobile-menu-link-marker {
  left: clamp(10px, 2vw, 15px);
  right: auto;

  width: 18px;
  height: 20px;
}

.mobile-menu-link-marker svg,
.mobile-menu-link-motif svg {
  width: 100%;
  height: 100%;
}

.mobile-menu-link-marker path {
  fill: currentColor;

  filter:
    drop-shadow(0 0 4px var(--mobile-menu-accent-soft));
}

.mobile-menu-link-motif circle {
  fill: currentColor;

  filter:
    drop-shadow(0 0 2px var(--mobile-menu-accent-soft));
}


/* -------------------------
   Per-page mobile accents
   ------------------------- */

.mobile-menu-link[href="#about"] {
  --mobile-menu-item-accent-rgb:
    var(--accent-about-rgb);
}


.mobile-menu-link[href="#brobots"] {
  --mobile-menu-item-accent-rgb:
    var(--accent-brobots-rgb);
}


.mobile-menu-link[href="#etherian"] {
  --mobile-menu-item-accent-rgb:
    var(--media-lightbox-close-accent-rgb, var(--accent-etherian-rgb));
}


.mobile-menu-link[href="#halodoom"] {
  --mobile-menu-item-accent-rgb:
    var(--accent-halodoom-rgb);
}


.mobile-menu-link[href="#contact"] {
  --mobile-menu-item-accent-rgb:
    var(--accent-contact-rgb);
}


/* -------------------------
   Active / hover states
   ------------------------- */

.mobile-menu-link:hover .mobile-menu-link-shell-path,
.mobile-menu-link:focus-visible .mobile-menu-link-shell-path {
  fill:
    var(--mobile-menu-item-hover-fill);

  stroke:
    var(--mobile-menu-item-hover-border);
}


/*
  Mobile pressed/current-page state uses the same accent-to-black
  treatment as the desktop buttons.
*/
.mobile-menu-link.is-page-active .mobile-menu-link-shell-path,
.mobile-menu-link[aria-current="page"] .mobile-menu-link-shell-path {
  fill:
    color-mix(
      in srgb,
      rgb(var(--mobile-menu-item-accent-rgb))
        var(--active-page-accent-share),
      black
    );

  stroke:
    color-mix(
      in srgb,
      rgb(var(--mobile-menu-item-accent-rgb))
        var(--active-page-accent-share),
      black
    );

  filter:
    drop-shadow(
      0 0 5px
      rgba(
        var(--mobile-menu-item-accent-rgb),
        0.18
      )
    );
}


.mobile-menu-link.is-page-active:hover .mobile-menu-link-shell-path,
.mobile-menu-link.is-page-active:focus-visible .mobile-menu-link-shell-path,
.mobile-menu-link[aria-current="page"]:hover .mobile-menu-link-shell-path,
.mobile-menu-link[aria-current="page"]:focus-visible .mobile-menu-link-shell-path {
  fill:
    color-mix(
      in srgb,
      rgb(var(--mobile-menu-item-accent-rgb))
        var(--active-page-accent-share),
      black
    );

  stroke:
    color-mix(
      in srgb,
      rgb(var(--mobile-menu-item-accent-rgb))
        var(--active-page-accent-share),
      black
    );
}

.mobile-menu-link:hover,
.mobile-menu-link:focus-visible {
  color: #ffffff;
}

.mobile-menu-link:focus-visible {
  outline: none;
}


/*
  Hover marker on inactive items.
*/
.mobile-menu-link:hover::before,
.mobile-menu-link:focus-visible::before {
  content: "";

  position: absolute;

  left: clamp(10px, 2vw, 15px);
  top: 50%;

  width: 0;
  height: 0;

  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
  border-left: 9px solid var(--mobile-menu-accent-color);

  transform: translateY(-50%);

  filter:
    drop-shadow(0 0 3px var(--mobile-menu-accent-soft));
}


/* -------------------------
   Small-screen tightening
   ------------------------- */

@media (max-width: 520px) {
  /*
    Width continues to use the same smooth rule.
    Vertical fitting is handled by --mobile-menu-height-scale and the
    flex layout above, so no second height/padding system is needed here.
  */
}


/* =========================================================
   Hamburger -> close icon
   ========================================================= */

/*
  The centre line fades while the upper/lower lines rotate into an X.
  aria-expanded is controlled by the JavaScript.
*/
.menu-toggle-lines,
.menu-toggle-lines::before,
.menu-toggle-lines::after {
  transition:
    transform 140ms ease,
    opacity 100ms linear,
    top 140ms ease;
}

.menu-toggle[aria-expanded="true"] .menu-toggle-lines {
  background: transparent;
}

.menu-toggle[aria-expanded="true"] .menu-toggle-lines::before {
  top: 0;
  transform: rotate(45deg);
}

.menu-toggle[aria-expanded="true"] .menu-toggle-lines::after {
  top: 0;
  transform: rotate(-45deg);
}


/* =========================================================
   Mobile menu visibility
   ========================================================= */

/*
  The menu only participates in the mobile/hamburger layout.
  Keeping display:none outside this breakpoint prevents the hidden
  dropdown from catching focus or interfering with desktop layout.
*/
@media (min-width: 751px) {
  .mobile-menu {
    display: none;
  }
}


/* =========================================================
   Structural resize tracking
   ========================================================= */

/*
  Important distinction:

  The apparent smoothness of the banner/frame while resizing comes from
  viewport-driven clamp()/calc() values updating continuously — NOT from a
  CSS transition.

  So the structural geometry should follow the viewport immediately. We
  explicitly disable transitions only on the decorative frame/banner
  geometry, while leaving button fades, hover lerps, menu morphs, etc.
  completely untouched.
*/
.site-header,
.banner-frame,
.banner-piece,
.viewport-frame,
.viewport-frame-piece,
.viewport-frame-stretch {
  transition: none !important;
}


/*
  The raster banner is decorative only, so clip it to its own box. This
  prevents a transient overshoot from becoming visible during very fast
  window drags without clipping the nav/menu layer that sits above it.
*/
.banner-frame {
  overflow: hidden;
}


/* =========================================================
   Viewport frame — fixed/non-stretchable anchor pieces
   ========================================================= */

/*
  The outer border now follows the SAME size curve as the title banner.

  Desktop/tablet:
    banner frame height = clamp(82px, 64px + 3.9vw, 120px)
    border scale        = banner frame height / 120px

  Below 485px:
    the banner freezes at its 485px layout size, then the entire header
    uniformly scales by 100vw / 485px.

    The border mirrors that exact second-stage scale as well.

  The pieces themselves are never stretched independently in X/Y:
  their width and height are both multiplied by the same scalar.
*/
.viewport-frame {
  --viewport-frame-banner-height:
    clamp(82px, calc(64px + 3.9vw), 120px);

  --viewport-frame-scale:
    calc(
      var(--viewport-frame-banner-height)
      / 120px
    );

  position: fixed;
  inset: 0;

  z-index: 1100;

  overflow: hidden;

  pointer-events: none;

  user-select: none;
}


.viewport-frame-piece {
  position: absolute;

  display: block;

  max-width: none;
  max-height: none;

  object-fit: contain;

  pointer-events: none;

  -webkit-user-drag: none;
}


.viewport-frame-stretch {
  position: absolute;

  display: block;

  max-width: none;
  max-height: none;

  object-fit: fill;

  pointer-events: none;

  -webkit-user-drag: none;

  z-index: 0;
}

.viewport-frame-piece {
  z-index: 1;
}

/*
  Shared thickness for the stretchable frame fill.
  This follows the exact same scale system as the fixed anchors.
*/
.viewport-frame {
  --viewport-frame-stretch-thickness:
    calc(21px * var(--viewport-frame-scale));
}


/* -------------------------
   Stretchable fill strips
   ------------------------- */

.viewport-frame-stretch--top {
  top: 0;
  left: 0;

  width: 100vw;
  height: var(--viewport-frame-stretch-thickness);
}

.viewport-frame-stretch--bottom {
  left: 5vw;
  bottom: 0;

  width: 90vw;
  height: var(--viewport-frame-stretch-thickness);

  transform: rotate(180deg);
}

.viewport-frame-stretch--right {
  top: 50%;
  left: calc(100% - (var(--viewport-frame-stretch-thickness) / 2));

  width: 90vh;
  height: var(--viewport-frame-stretch-thickness);

  transform:
    translate(-50%, -50%)
    rotate(90deg);
}

.viewport-frame-stretch--left {
  top: 50%;
  left: calc(var(--viewport-frame-stretch-thickness) / 2);

  width: 90vh;
  height: var(--viewport-frame-stretch-thickness);

  transform:
    translate(-50%, -50%)
    rotate(270deg);
}


/* -------------------------
   Top anchors
   ------------------------- */

.viewport-frame-piece--top-left {
  top: 0;
  left: 0;

  width:
    calc(97px * var(--viewport-frame-scale));

  height:
    calc(151px * var(--viewport-frame-scale));
}


.viewport-frame-piece--top {
  top: 0;
  left: 50%;

  width:
    calc(403px * var(--viewport-frame-scale));

  height:
    calc(49px * var(--viewport-frame-scale));

  transform:
    translateX(-50%);
}


.viewport-frame-piece--top-right {
  top: 0;
  right: 0;

  width:
    calc(96px * var(--viewport-frame-scale));

  height:
    calc(151px * var(--viewport-frame-scale));
}


/* -------------------------
   Side-center anchors
   ------------------------- */

/*
  Scaling is applied to width/height rather than through transform:scale().
  That leaves translateY(-50%) completely independent from scale, so these
  pieces remain mathematically centered at every viewport size.
*/
.viewport-frame-piece--left-center {
  top: 50%;
  left: 0;

  width:
    calc(35px * var(--viewport-frame-scale));

  height:
    calc(153px * var(--viewport-frame-scale));

  transform:
    translateY(-50%);
}


.viewport-frame-piece--right-center {
  top: 50%;
  right: 0;

  width:
    calc(35px * var(--viewport-frame-scale));

  height:
    calc(153px * var(--viewport-frame-scale));

  transform:
    translateY(-50%);
}


/*
  The blue side-center ornaments are intended to visually sit on TOP of
  the rest of the frame when the viewport gets extremely short/narrow.
  Giving only these two pieces a higher local z-index makes the overlap
  look intentional without changing the normal desktop composition.
*/
.viewport-frame-piece--left-center,
.viewport-frame-piece--right-center {
  z-index: 3;
}


/* -------------------------
   Bottom anchors
   ------------------------- */

.viewport-frame-piece--bottom-left {
  bottom: 0;
  left: 0;

  width:
    calc(267px * var(--viewport-frame-scale));

  height:
    calc(129px * var(--viewport-frame-scale));
}


.viewport-frame-piece--bottom {
  bottom: 0;
  left: 50%;

  width:
    calc(128px * var(--viewport-frame-scale));

  height:
    calc(29px * var(--viewport-frame-scale));

  transform:
    translateX(-50%);
}


.viewport-frame-piece--bottom-right {
  right: 0;
  bottom: 0;

  width:
    calc(266px * var(--viewport-frame-scale));

  height:
    calc(131px * var(--viewport-frame-scale));
}


/*
  Below 485px the existing header stops recomputing its internal layout
  and uniformly scales its frozen 485px composition.

  Mirror that exact behavior here:
    scale at 485px = 82.915 / 120
    then multiply by the same 100vw / 485px factor used by .site-header.
*/
@media (max-width: 485px) {
  .viewport-frame {
    --viewport-frame-banner-height: 82.915px;

    --viewport-frame-scale:
      calc(
        (82.915 / 120)
        *
        (100vw / 485px)
      );
  }
}



/* =========================================================
   Etherian desktop information panel — Step 1 structure
   ========================================================= */

/*
  This first pass deliberately leaves the existing secondary-panel morph
  geometry untouched. The layered treatment lives INSIDE the current final
  popout silhouette, so the triangle -> popout animation still has one clear
  destination shape.
*/
@media (min-width: 1401px) {
  #etherian-page-frame .desktop-secondary-panel-content {
    top: 3.5%;
    right: 4.5%;
    bottom: 3.5%;

    left:
      calc(
        var(--secondary-panel-overlap) +
        3%
      );

    overflow: visible;
  }


  #etherian-page-frame .game-info {
    position: relative;

    width: 100%;
    height: 100%;

    min-width: 0;
    min-height: 0;

    color: rgba(244, 248, 250, 0.96);

    isolation: isolate;
  }


  /*
    The screenshot behaves like imagery suspended IN the glass, not a second
    media card. It is strongest at the upper-right and dissolves into the
    information field.
  */
  #etherian-page-frame .game-info-background {
    position: absolute;
    inset: 2% 0 4% 14%;

    z-index: 0;

    overflow: hidden;

    opacity: 0.33;

    clip-path:
      polygon(
        7% 0,
        100% 0,
        100% 90%,
        93% 100%,
        0 100%,
        0 8%
      );

    pointer-events: none;
  }


  #etherian-page-frame .game-info-background-image {
    width: 100%;
    height: 100%;

    object-fit: cover;
    object-position: 58% 44%;

    filter:
      saturate(0.88)
      contrast(0.94)
      brightness(0.72);

    -webkit-mask-image:
      linear-gradient(
        105deg,
        transparent 0%,
        rgba(0, 0, 0, 0.16) 18%,
        rgba(0, 0, 0, 0.70) 54%,
        rgba(0, 0, 0, 0.92) 100%
      );

    mask-image:
      linear-gradient(
        105deg,
        transparent 0%,
        rgba(0, 0, 0, 0.16) 18%,
        rgba(0, 0, 0, 0.70) 54%,
        rgba(0, 0, 0, 0.92) 100%
      );
  }


  /*
    Two restrained inner panes create the layered dossier feeling while
    staying almost entirely inside the existing popout silhouette.
  */
  #etherian-page-frame .game-info-layer {
    position: absolute;

    z-index: 1;

    pointer-events: none;

    border:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.17
      );

    background:
      rgba(
        var(--page-accent-rgb),
        0.025
      );

    clip-path:
      polygon(
        5% 0,
        100% 0,
        100% 91%,
        94% 100%,
        0 100%,
        0 7%
      );
  }


  #etherian-page-frame .game-info-layer--rear {
    inset: 0.5% 1.5% 1.5% 5.5%;

    transform:
      translate(1.6%, -1.4%);

    opacity: 0.58;
  }


  #etherian-page-frame .game-info-layer--mid {
    inset: 2.5% 3.5% 3% 2%;

    transform:
      translate(-0.8%, 0.7%);

    opacity: 0.78;
  }


  #etherian-page-frame .game-info-surface {
    position: relative;

    z-index: 2;

    width: 100%;
    height: 100%;

    min-width: 0;
    min-height: 0;

    display: grid;

    grid-template-rows:
      auto
      auto
      minmax(0, 1fr)
      auto
      auto;

    align-content: center;

    gap:
      clamp(10px, 1.15vh, 18px);

    padding:
      clamp(22px, 2.15vw, 38px)
      clamp(22px, 2.25vw, 42px)
      clamp(20px, 2vw, 34px)
      clamp(24px, 2.4vw, 46px);

    border:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.26
      );

    background:
      linear-gradient(
        105deg,
        rgba(20, 29, 34, 0.72) 0%,
        rgba(22, 34, 40, 0.60) 48%,
        rgba(19, 31, 37, 0.40) 100%
      );

    backdrop-filter:
      blur(10px)
      saturate(112%);

    -webkit-backdrop-filter:
      blur(10px)
      saturate(112%);

    clip-path:
      polygon(
        5% 0,
        100% 0,
        100% 90%,
        94% 100%,
        0 100%,
        0 7%
      );

    box-shadow:
      inset 0 0 0 1px rgba(255, 255, 255, 0.035),
      inset 18px 0 42px rgba(255, 255, 255, 0.018);
  }


  #etherian-page-frame .game-info-header {
    display: flex;
    flex-direction: column;

    align-items: flex-start;

    gap:
      clamp(5px, 0.65vh, 10px);

    min-width: 0;
  }


  #etherian-page-frame .game-info-logo {
    display: block;

    width:
      min(
        68%,
        440px
      );

    max-height:
      clamp(70px, 12vh, 132px);

    object-fit: contain;
    object-position: left center;
  }


  #etherian-page-frame .game-info-kicker {
    margin: 0;

    color:
      rgba(
        var(--page-accent-rgb),
        0.93
      );

    font-size:
      clamp(9px, 0.72vw, 13px);

    font-weight: 700;

    letter-spacing:
      0.34em;
  }


  #etherian-page-frame .game-info-blurb {
    max-width: 94%;

    margin: 0;

    color:
      rgba(246, 249, 251, 0.92);

    font-size:
      clamp(12px, 0.86vw, 16px);

    line-height: 1.48;
  }


  #etherian-page-frame .game-info-features {
    min-height: 0;

    display: grid;

    grid-template-columns:
      repeat(2, minmax(0, 1fr));

    align-content: center;

    gap:
      clamp(8px, 0.75vw, 14px);
  }


  #etherian-page-frame .game-info-feature {
    min-width: 0;

    display: grid;

    grid-template-columns:
      clamp(34px, 2.7vw, 48px)
      minmax(0, 1fr);

    align-items: center;

    gap:
      clamp(8px, 0.7vw, 13px);

    padding:
      clamp(7px, 0.65vw, 11px);

    border:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.20
      );

    background:
      linear-gradient(
        115deg,
        rgba(
          var(--page-accent-rgb),
          0.075
        ),
        rgba(16, 22, 26, 0.18)
      );

    clip-path:
      polygon(
        8px 0,
        100% 0,
        100% calc(100% - 8px),
        calc(100% - 8px) 100%,
        0 100%,
        0 8px
      );
  }


  #etherian-page-frame .game-info-feature-icon {
    display: grid;
    place-items: center;

    aspect-ratio: 1;

    color:
      rgba(
        var(--page-accent-rgb),
        0.96
      );

    border:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.45
      );

    font-size:
      clamp(18px, 1.5vw, 26px);

    line-height: 1;

    clip-path:
      polygon(
        25% 0,
        75% 0,
        100% 25%,
        100% 75%,
        75% 100%,
        25% 100%,
        0 75%,
        0 25%
      );
  }


  #etherian-page-frame .game-info-feature-copy {
    min-width: 0;

    display: flex;
    flex-direction: column;

    gap: 3px;
  }


  #etherian-page-frame .game-info-feature-copy strong {
    color:
      rgba(
        var(--page-accent-rgb),
        0.96
      );

    font-size:
      clamp(8px, 0.61vw, 11px);

    letter-spacing:
      0.13em;
  }


  #etherian-page-frame .game-info-feature-copy small {
    overflow: hidden;

    color: rgba(232, 239, 243, 0.70);

    font-size:
      clamp(8px, 0.58vw, 10px);

    line-height: 1.25;

    white-space: nowrap;

    text-overflow: ellipsis;
  }


  #etherian-page-frame .game-info-facts {
    display: grid;

    grid-template-columns:
      repeat(3, minmax(0, 1fr));

    border-top:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.28
      );

    border-bottom:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.18
      );
  }


  #etherian-page-frame .game-info-fact {
    position: relative;

    min-width: 0;

    display: flex;
    flex-direction: column;

    gap: 4px;

    padding:
      clamp(9px, 0.75vw, 13px)
      clamp(8px, 0.8vw, 14px);
  }


  #etherian-page-frame
  .game-info-fact +
  .game-info-fact::before {
    content: "";

    position: absolute;

    top: 22%;
    bottom: 22%;
    left: 0;

    width: 1px;

    background:
      rgba(
        var(--page-accent-rgb),
        0.24
      );
  }


  #etherian-page-frame .game-info-fact span {
    color:
      rgba(
        var(--page-accent-rgb),
        0.78
      );

    font-size:
      clamp(8px, 0.58vw, 10px);

    letter-spacing:
      0.18em;
  }


  #etherian-page-frame .game-info-fact strong {
    overflow: hidden;

    color: rgba(244, 248, 250, 0.92);

    font-size:
      clamp(10px, 0.72vw, 13px);

    font-weight: 500;

    white-space: nowrap;

    text-overflow: ellipsis;
  }


  #etherian-page-frame .game-info-actions {
    display: grid;

    grid-template-columns:
      minmax(0, 1.35fr)
      minmax(0, 0.9fr);

    gap:
      clamp(10px, 0.85vw, 16px);
  }


  #etherian-page-frame .game-info-action {
    min-width: 0;

    display: flex;

    align-items: center;
    justify-content: space-between;

    gap: 12px;

    padding:
      clamp(10px, 0.8vw, 14px)
      clamp(14px, 1vw, 18px);

    border:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.48
      );

    background:
      rgba(15, 21, 25, 0.42);

    color: rgba(248, 251, 252, 0.96);

    font: inherit;

    font-size:
      clamp(9px, 0.68vw, 12px);

    font-weight: 700;

    letter-spacing:
      0.11em;

    cursor: default;

    clip-path:
      polygon(
        10px 0,
        100% 0,
        100% calc(100% - 10px),
        calc(100% - 10px) 100%,
        0 100%,
        0 10px
      );
  }


  #etherian-page-frame .game-info-action--primary {
    background:
      linear-gradient(
        110deg,
        rgba(
          var(--page-accent-rgb),
          0.10
        ),
        rgba(
          var(--page-accent-rgb),
          0.10
        )
      );

    box-shadow:
      inset 0 0 0 1px
      rgba(
        var(--page-accent-rgb),
        0.10
      );
  }


  /*
    This is intentionally just the desktop content composition. Tablet
    stacking will be a separate pass once we like this hierarchy.
  */
}


/* =========================================================
   Etherian desktop information panel — Step 1B refinement
   Hierarchy/content pass; existing frame/morph geometry untouched.
   ========================================================= */

@media (min-width: 1401px) {
  /*
    Give the identity/blurb area a little more room while reducing the
    visual weight of the feature section below it.
  */
  #etherian-page-frame .game-info-surface {
    grid-template-rows:
      auto
      auto
      minmax(0, 0.78fr)
      auto
      auto;

    gap:
      clamp(12px, 1.35vh, 20px);

    padding-top:
      clamp(26px, 2.55vw, 44px);
  }


  #etherian-page-frame .game-info-header {
    gap:
      clamp(7px, 0.8vh, 12px);
  }


  #etherian-page-frame .game-info-logo {
    width:
      min(
        70%,
        460px
      );
  }


  #etherian-page-frame .game-info-blurb {
    max-width: 91%;

    line-height: 1.54;
  }


  /*
    Let the screenshot read more clearly as imagery trapped inside the glass.
    It is still deliberately strongest on the right and fades underneath text.
  */
  #etherian-page-frame .game-info-background {
    inset: 0.5% -0.5% 1.5% 9%;

    opacity: 0.47;
  }


  #etherian-page-frame .game-info-background-image {
    object-position: 60% 42%;

    filter:
      saturate(0.94)
      contrast(0.96)
      brightness(0.78);

    -webkit-mask-image:
      linear-gradient(
        102deg,
        transparent 0%,
        rgba(0, 0, 0, 0.06) 13%,
        rgba(0, 0, 0, 0.36) 35%,
        rgba(0, 0, 0, 0.82) 66%,
        rgba(0, 0, 0, 0.96) 100%
      );

    mask-image:
      linear-gradient(
        102deg,
        transparent 0%,
        rgba(0, 0, 0, 0.06) 13%,
        rgba(0, 0, 0, 0.36) 35%,
        rgba(0, 0, 0, 0.82) 66%,
        rgba(0, 0, 0, 0.96) 100%
      );
  }


  /*
    Features now behave more like an editorial strip than four separate
    dashboard cards. The icons remain distinct; the surrounding boxes recede.
  */
  #etherian-page-frame .game-info-features {
    gap:
      clamp(6px, 0.55vw, 10px)
      clamp(14px, 1.05vw, 20px);

    padding:
      clamp(5px, 0.4vw, 8px)
      0;

    border-top:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.22
      );

    border-bottom:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.14
      );
  }


  #etherian-page-frame .game-info-feature {
    grid-template-columns:
      clamp(30px, 2.35vw, 42px)
      minmax(0, 1fr);

    gap:
      clamp(8px, 0.65vw, 12px);

    padding:
      clamp(7px, 0.5vw, 9px)
      clamp(5px, 0.4vw, 8px);

    border: 0;

    background: transparent;

    clip-path: none;
  }


  #etherian-page-frame .game-info-feature-icon {
    border-color:
      rgba(
        var(--page-accent-rgb),
        0.34
      );

    background:
      rgba(
        var(--page-accent-rgb),
        0.045
      );

    font-size:
      clamp(16px, 1.25vw, 22px);
  }


  #etherian-page-frame .game-info-feature-copy strong {
    font-size:
      clamp(8px, 0.59vw, 10.5px);

    letter-spacing:
      0.14em;
  }


  #etherian-page-frame .game-info-feature-copy small {
    font-size:
      clamp(7.5px, 0.54vw, 9.5px);

    color:
      rgba(232, 239, 243, 0.64);
  }


  /*
    Quick facts stay compact and factual rather than repeating the genre
    description immediately beneath the logo.
  */
  #etherian-page-frame .game-info-facts {
    background:
      linear-gradient(
        90deg,
        rgba(
          var(--page-accent-rgb),
          0.035
        ),
        rgba(12, 18, 22, 0.08)
      );
  }


  #etherian-page-frame .game-info-fact {
    padding-top:
      clamp(8px, 0.65vw, 11px);

    padding-bottom:
      clamp(8px, 0.65vw, 11px);
  }


  /*
    One strong store action, one quieter media action.
  */
  #etherian-page-frame .game-info-action--primary {
    border-color:
      rgba(
        var(--page-accent-rgb),
        0.62
      );

    background:
      linear-gradient(
        110deg,
        rgba(
          var(--page-accent-rgb),
          0.34
        ),
        rgba(
          var(--page-accent-rgb),
          0.12
        )
      );
  }


  #etherian-page-frame .game-info-action--secondary {
    border-color:
      rgba(
        var(--page-accent-rgb),
        0.28
      );

    color:
      rgba(238, 244, 247, 0.84);
  }
}


/* =========================================================
   Etherian desktop information panel — Step 1C visual polish
   Existing popout/morph geometry remains untouched.
   ========================================================= */

@media (min-width: 1401px) {

  /* ---------------------------------------------------------
     Screenshot-bearing glass layer
     --------------------------------------------------------- */

  #etherian-page-frame .game-info-background {
    /*
      Pull the photographic layer farther right and slightly upward so it
      reads as a deliberate inset pane instead of a generic full-panel wash.
    */
    inset:
      -1.2%
      -0.8%
      8%
      31%;

    opacity: 0.54;

    overflow: hidden;

    border:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.16
      );

    background:
      rgba(
        var(--page-accent-rgb),
        0.028
      );

    clip-path:
      polygon(
        7% 0,
        100% 0,
        100% 86%,
        93% 100%,
        0 100%,
        0 10%
      );

    box-shadow:
      inset 0 0 0 1px rgba(255,255,255,0.018);
  }


  #etherian-page-frame .game-info-background::after {
    content: "";

    position: absolute;
    inset: 0;

    pointer-events: none;

    background:
      linear-gradient(
        90deg,
        rgba(17, 27, 32, 0.92) 0%,
        rgba(17, 27, 32, 0.60) 27%,
        rgba(17, 27, 32, 0.22) 58%,
        rgba(17, 27, 32, 0.08) 100%
      );
  }


  #etherian-page-frame .game-info-background-image {
    width: 112%;
    height: 112%;

    transform:
      translate(
        -4%,
        -5%
      );

    object-fit: cover;

    /*
      Favor the ringed sky / floating-island area so the image contributes
      atmosphere without competing directly with the text.
    */
    object-position: 69% 30%;

    filter:
      saturate(0.90)
      contrast(0.92)
      brightness(0.74);

    -webkit-mask-image: none;
    mask-image: none;
  }


  /* ---------------------------------------------------------
     Layered glass / asymmetry
     --------------------------------------------------------- */

  #etherian-page-frame .game-info-layer--rear {
    inset:
      -1.3%
      0.4%
      0.8%
      6.8%;

    transform:
      translate(
        2.2%,
        -1.2%
      );

    opacity: 0.64;

    border-color:
      rgba(
        var(--page-accent-rgb),
        0.15
      );
  }


  #etherian-page-frame .game-info-layer--mid {
    inset:
      1.4%
      2.3%
      2%
      1.2%;

    transform:
      translate(
        -0.5%,
        0.9%
      );

    opacity: 0.82;

    border-color:
      rgba(
        var(--page-accent-rgb),
        0.20
      );
  }


  /*
    Small cyan rail on the far-right edge: enough asymmetry to make the
    panel feel constructed without turning it into a HUD.
  */
  #etherian-page-frame .game-info::after {
    content: "";

    position: absolute;

    z-index: 3;

    top: 18%;
    right: 0.35%;

    width: 2px;
    height: 28%;

    background:
      linear-gradient(
        to bottom,
        transparent,
        rgba(
          var(--page-accent-rgb),
          0.62
        ) 18%,
        rgba(
          var(--page-accent-rgb),
          0.28
        ) 76%,
        transparent
      );

    box-shadow:
      0 0 14px
      rgba(
        var(--page-accent-rgb),
        0.22
      );

    pointer-events: none;
  }


  /* ---------------------------------------------------------
     Front surface polish
     --------------------------------------------------------- */

  #etherian-page-frame .game-info-surface {
    grid-template-rows:
      auto
      auto
      minmax(0, 0.70fr)
      auto
      auto;

    gap:
      clamp(11px, 1.22vh, 18px);

    padding:
      clamp(26px, 2.35vw, 42px)
      clamp(24px, 2.2vw, 40px)
      clamp(22px, 1.9vw, 34px)
      clamp(28px, 2.55vw, 48px);

    background:
      linear-gradient(
        102deg,
        rgba(18, 27, 32, 0.80) 0%,
        rgba(20, 31, 36, 0.67) 43%,
        rgba(18, 30, 35, 0.47) 72%,
        rgba(18, 30, 35, 0.34) 100%
      );

    border-color:
      rgba(
        var(--page-accent-rgb),
        0.30
      );

    box-shadow:
      inset 0 0 0 1px rgba(255,255,255,0.032),
      inset 28px 0 56px rgba(255,255,255,0.012),
      inset -1px 0 0
      rgba(
        var(--page-accent-rgb),
        0.10
      );
  }


  #etherian-page-frame .game-info-logo {
    width:
      min(
        67%,
        450px
      );

    margin-left:
      -0.6%;
  }


  #etherian-page-frame .game-info-kicker {
    letter-spacing:
      0.31em;

    opacity: 0.94;
  }


  #etherian-page-frame .game-info-blurb {
    max-width: 89%;

    font-size:
      clamp(12px, 0.84vw, 15px);

    line-height: 1.52;
  }


  /* ---------------------------------------------------------
     Feature strip polish
     --------------------------------------------------------- */

  #etherian-page-frame .game-info-features {
    grid-template-columns:
      repeat(2, minmax(0, 1fr));

    column-gap:
      clamp(18px, 1.3vw, 24px);

    row-gap:
      clamp(7px, 0.6vw, 11px);

    padding:
      clamp(7px, 0.55vw, 10px)
      0;

    border-top-color:
      rgba(
        var(--page-accent-rgb),
        0.20
      );

    border-bottom-color:
      rgba(
        var(--page-accent-rgb),
        0.13
      );
  }


  #etherian-page-frame .game-info-feature {
    position: relative;

    padding:
      clamp(6px, 0.48vw, 9px)
      clamp(4px, 0.3vw, 6px);
  }


  #etherian-page-frame .game-info-feature::after {
    content: "";

    position: absolute;

    right: 0;
    bottom: 0;

    width:
      clamp(18px, 1.8vw, 30px);

    height: 1px;

    background:
      rgba(
        var(--page-accent-rgb),
        0.13
      );
  }


  #etherian-page-frame .game-info-feature-icon {
    background:
      linear-gradient(
        135deg,
        rgba(
          var(--page-accent-rgb),
          0.08
        ),
        rgba(12, 18, 22, 0.05)
      );

    box-shadow:
      inset 0 0 0 1px
      rgba(
        var(--page-accent-rgb),
        0.035
      );
  }


  #etherian-page-frame .game-info-feature-copy strong {
    line-height: 1.15;
  }


  #etherian-page-frame .game-info-feature-copy small {
    line-height: 1.22;
  }


  /* ---------------------------------------------------------
     Metadata row polish
     --------------------------------------------------------- */

  #etherian-page-frame .game-info-facts {
    border-top-color:
      rgba(
        var(--page-accent-rgb),
        0.24
      );

    border-bottom-color:
      rgba(
        var(--page-accent-rgb),
        0.16
      );

    background:
      linear-gradient(
        90deg,
        rgba(
          var(--page-accent-rgb),
          0.028
        ),
        rgba(12, 18, 22, 0.055)
      );
  }


  #etherian-page-frame .game-info-fact span {
    font-size:
      clamp(7.5px, 0.54vw, 9.5px);

    letter-spacing:
      0.19em;
  }


  #etherian-page-frame .game-info-fact strong {
    font-size:
      clamp(9.5px, 0.68vw, 12.5px);
  }


  /* ---------------------------------------------------------
     CTA polish
     --------------------------------------------------------- */

  #etherian-page-frame .game-info-actions {
    grid-template-columns:
      minmax(0, 1.42fr)
      minmax(0, 0.88fr);

    gap:
      clamp(11px, 0.9vw, 17px);
  }


  #etherian-page-frame .game-info-action {
    padding-top:
      clamp(10px, 0.72vw, 13px);

    padding-bottom:
      clamp(10px, 0.72vw, 13px);
  }


  #etherian-page-frame .game-info-action--primary {
    box-shadow:
      inset 0 0 0 1px
      rgba(
        var(--page-accent-rgb),
        0.12
      ),
      0 0 18px
      rgba(
        var(--page-accent-rgb),
        0.055
      );
  }
}


/* =========================================================
   TEMPORARY STUDY VARIANT
   Original popout glass frame + Etherian info only.
   Screenshot and decorative inner glass layers disabled.
   ========================================================= */

@media (min-width: 1401px) {
  #etherian-page-frame .game-info-background,
  #etherian-page-frame .game-info-layer--rear,
  #etherian-page-frame .game-info-layer--mid,
  #etherian-page-frame .game-info::after {
    display: none !important;
  }


  /*
    Strip the extra front-surface pane treatment too, so what remains
    visually is the original secondary-panel glass/frame underneath,
    with only the Etherian content laid over it.
  */
  #etherian-page-frame .game-info-surface {
    border: 0;

    background: transparent;

    backdrop-filter: none;
    -webkit-backdrop-filter: none;

    clip-path: none;

    box-shadow: none;
  }
}


/* =========================================================
   Etherian popout — numbered layered-glass study
   Based on the user's 1 / 2 / 3 / 4 sketch.
   ========================================================= */

@media (min-width: 1401px) {

  /*
    Shared angle token.

    IMPORTANT:
    Every sloped edge below derives its horizontal run from the site's
    existing --button-shear-angle instead of inventing a second angle.
  */
  #etherian-page-frame .desktop-secondary-panel {
    --etherian-glass-angle:
      calc(
        var(--button-shear-angle) * -1
      );

    /*
      Outer clipping shape for the whole decorative stack.
      This mirrors the final popout's right-hand diagonal logic so none of
      the added panes can visibly escape the original glass frame.
    */
    --etherian-stack-cut-rise:
      clamp(42px, 4.1vw, 68px);

    --etherian-stack-cut-run:
      calc(
        var(--etherian-stack-cut-rise)
        *
        tan(
          var(--etherian-glass-angle)
        )
      );
  }


  #etherian-page-frame .etherian-popout-layer-stack {
    position: absolute;
    inset: 0;

    z-index: 1;

    overflow: hidden;

    /*
      Clip the entire system to the ORIGINAL popout silhouette.
    */
    clip-path:
      polygon(
        0 0,
        calc(
          100% -
          var(--etherian-stack-cut-run)
        ) 0,
        100%
        var(--etherian-stack-cut-rise),
        100%
        calc(
          100% -
          var(--etherian-stack-cut-rise)
        ),
        calc(
          100% -
          var(--etherian-stack-cut-run)
        ) 100%,
        0 100%
      );

    pointer-events: none;

    opacity: 0;

    transition:
      opacity 220ms ease;

    /*
      The original morphing glass remains the physical popout.
      These panes become visible only near the end, along with the content.
    */
  }


  #etherian-page-frame.is-secondary-open
  .etherian-popout-layer-stack {
    opacity: 1;

    transition-delay:
      calc(
        var(--secondary-panel-duration) * 0.74
      );
  }


  #etherian-page-frame .etherian-popout-glass-layer {
    position: absolute;

    /*
      Each layer gets its own diagonal rise, but EVERY run derives from
      the shared master angle.
    */
    --layer-cut-rise:
      clamp(44px, 4.8vw, 78px);

    --layer-cut-run:
      calc(
        var(--layer-cut-rise)
        *
        tan(
          var(--etherian-glass-angle)
        )
      );

    border:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.16
      );

    background:
      linear-gradient(
        115deg,
        rgba(255,255,255,0.022),
        rgba(
          var(--page-accent-rgb),
          0.034
        ) 45%,
        rgba(20,28,34,0.020)
      );

    box-shadow:
      inset 0 0 0 1px
      rgba(255,255,255,0.018);

    backdrop-filter:
      blur(2px)
      saturate(108%);

    -webkit-backdrop-filter:
      blur(2px)
      saturate(108%);
  }


  /*
    1 — backmost / broadest pane.
    Nearly fills the original popout but sits slightly inward.
  */
  #etherian-page-frame .etherian-popout-glass-layer--1 {
    z-index: 1;

    inset:
      2.5%
      1.7%
      5.5%
      0;

    --layer-cut-rise:
      clamp(54px, 5.4vw, 86px);

    clip-path:
      polygon(
        0 0,
        calc(
          100% -
          var(--layer-cut-run)
        ) 0,
        100%
        var(--layer-cut-rise),
        100%
        calc(
          100% -
          var(--layer-cut-rise)
        ),
        calc(
          100% -
          var(--layer-cut-run)
        ) 100%,
        0 100%
      );

    opacity: 0.42;

    border-color:
      rgba(
        220, 230, 242,
        0.18
      );
  }


  /*
    2 — second pane.
    Starts lower and lands farther inward on the right, matching the
    second red outline in the sketch.
  */
  #etherian-page-frame .etherian-popout-glass-layer--2 {
    z-index: 2;

    inset:
      7.5%
      6.2%
      8.5%
      0;

    --layer-cut-rise:
      clamp(62px, 6.1vw, 96px);

    clip-path:
      polygon(
        0 0,
        calc(
          100% -
          var(--layer-cut-run)
        ) 0,
        100%
        var(--layer-cut-rise),
        100%
        calc(
          100% -
          var(--layer-cut-rise) * 0.42
        ),
        calc(
          100% -
          var(--layer-cut-run) * 0.42
        ) 100%,
        0 100%
      );

    opacity: 0.50;

    border-color:
      rgba(
        var(--page-accent-rgb),
        0.18
      );

    background:
      linear-gradient(
        118deg,
        rgba(
          var(--page-accent-rgb),
          0.022
        ),
        rgba(255,255,255,0.018)
      );
  }


  /*
    3 — principal inner pane.
    This is the pane the content visually sits over. It uses the same
    sloped corner relation but is narrower and more pronounced.
  */
  #etherian-page-frame .etherian-popout-glass-layer--3 {
    z-index: 3;

    inset:
      11.5%
      12.2%
      13.5%
      0;

    --layer-cut-rise:
      clamp(70px, 7vw, 110px);

    clip-path:
      polygon(
        0 0,
        calc(
          100% -
          var(--layer-cut-run)
        ) 0,
        100%
        var(--layer-cut-rise),
        100% 100%,
        0 100%
      );

    opacity: 0.58;

    border-color:
      rgba(
        var(--page-accent-rgb),
        0.22
      );

    background:
      linear-gradient(
        110deg,
        rgba(255,255,255,0.016),
        rgba(
          var(--page-accent-rgb),
          0.045
        )
      );
  }


  /*
    4 — foreground lower pane.
    Begins around the feature/facts area and cuts down into the right edge,
    matching the lower red outline from the sketch.
  */
  #etherian-page-frame .etherian-popout-glass-layer--4 {
    z-index: 4;

    left: 0;
    right: 13.6%;
    top: 49%;
    bottom: 0;

    --layer-cut-rise:
      clamp(46px, 4.8vw, 76px);

    clip-path:
      polygon(
        0 0,
        calc(
          100% -
          var(--layer-cut-run)
        ) 0,
        100%
        var(--layer-cut-rise),
        100% 100%,
        0 100%
      );

    opacity: 0.66;

    border-color:
      rgba(
        var(--page-accent-rgb),
        0.24
      );

    background:
      linear-gradient(
        108deg,
        rgba(
          var(--page-accent-rgb),
          0.040
        ),
        rgba(255,255,255,0.018)
      );
  }


  /*
    The original morphing glass is z-index 0 by default in the panel;
    decorative panes sit above it, while content remains on top.
  */
  #etherian-page-frame .desktop-secondary-panel-glass {
    z-index: 0;
  }


  #etherian-page-frame .desktop-secondary-panel-content {
    z-index: 2;
  }


  /*
    Keep the content visually above all four pane fills even though the
    layer stack itself occupies z-index 1.
  */
  #etherian-page-frame .game-info {
    z-index: 2;
  }
}


/* =========================================================
   Etherian layered glass — stronger opacity pass
   Geometry/order unchanged; only material presence is increased.
   ========================================================= */

@media (min-width: 1401px) {

  #etherian-page-frame .etherian-popout-glass-layer {
    border-color:
      rgba(
        var(--page-accent-rgb),
        0.24
      );

    background:
      linear-gradient(
        115deg,
        rgba(255,255,255,0.055),
        rgba(
          var(--page-accent-rgb),
          0.085
        ) 44%,
        rgba(26,36,42,0.055)
      );

    box-shadow:
      inset 0 0 0 1px
      rgba(255,255,255,0.032);

    backdrop-filter:
      blur(4px)
      saturate(112%);

    -webkit-backdrop-filter:
      blur(4px)
      saturate(112%);
  }


  #etherian-page-frame .etherian-popout-glass-layer--1 {
    opacity: 0.62;

    border-color:
      rgba(
        220, 230, 242,
        0.26
      );

    background:
      linear-gradient(
        116deg,
        rgba(255,255,255,0.060),
        rgba(177,202,216,0.065) 52%,
        rgba(28,36,42,0.040)
      );
  }


  #etherian-page-frame .etherian-popout-glass-layer--2 {
    opacity: 0.70;

    border-color:
      rgba(
        var(--page-accent-rgb),
        0.28
      );

    background:
      linear-gradient(
        118deg,
        rgba(
          var(--page-accent-rgb),
          0.070
        ),
        rgba(255,255,255,0.050)
      );
  }


  #etherian-page-frame .etherian-popout-glass-layer--3 {
    opacity: 0.76;

    border-color:
      rgba(
        var(--page-accent-rgb),
        0.32
      );

    background:
      linear-gradient(
        110deg,
        rgba(255,255,255,0.045),
        rgba(
          var(--page-accent-rgb),
          0.095
        )
      );
  }


  #etherian-page-frame .etherian-popout-glass-layer--4 {
    opacity: 0.82;

    border-color:
      rgba(
        var(--page-accent-rgb),
        0.35
      );

    background:
      linear-gradient(
        108deg,
        rgba(
          var(--page-accent-rgb),
          0.105
        ),
        rgba(255,255,255,0.048)
      );
  }
}


/* =========================================================
   Etherian layered glass — restored clean baseline
   No experimental full-perimeter border system.
   ========================================================= */

@media (min-width: 1401px) {
  #etherian-page-frame .etherian-popout-glass-layer--1 {
    opacity: 0.50;
  }

  #etherian-page-frame .etherian-popout-glass-layer--2 {
    opacity: 0.58;
  }

  #etherian-page-frame .etherian-popout-glass-layer--3 {
    opacity: 0.64;
  }

  #etherian-page-frame .etherian-popout-glass-layer--4 {
    right: 20%;
    opacity: 0.70;
  }
}


/* =========================================================
   Etherian decorative glass panes — borderless
   ========================================================= */

@media (min-width: 1401px) {

  /*
    Main popout glass:
    remove only the 1px outer inset line that was incomplete on diagonals.
    Preserve the 3px inner highlight and all glass/shadow behavior.
  */
  


  /*
    Inner layered panes:
    remove their explicit CSS border entirely so straight edges do not
    appear outlined while diagonal clip edges remain unoutlined.
  */
  #etherian-page-frame .etherian-popout-glass-layer {
    border-color: transparent !important;
    border-width: 0 !important;
  }


  /*
    Keep a very faint internal glass rim so the panes still read as layered
    sheets rather than disappearing into one another. This is an inset glow,
    not a hard perimeter line.
  */
  #etherian-page-frame .etherian-popout-glass-layer {
    box-shadow:
      inset 0 0 0 1px
      rgba(255, 255, 255, 0.018);
  }
}


/* =========================================================
   Generic desktop popouts — rimless glass
   Shared by About, Brobots, Etherian, Halodoom, and Contact.
   Etherian-specific styling belongs only to its content/decorative panes.
   ========================================================= */

@media (min-width: 1401px) {
  .prototype-page-frame
  .desktop-secondary-panel-glass,
  .prototype-page-frame.is-layout-transitioning
  .desktop-secondary-panel-glass {
    box-shadow:
      inset 18px 0 40px
        rgba(255, 255, 255, 0.025),

      0 8px 24px
        rgba(0, 0, 0, 0.16) !important;
  }
}



/* =========================================================
   Etherian glass geometry + feature crowding polish
   ========================================================= */

@media (min-width: 1401px) {

  /*
    Layer 3 is the pane that begins just above the Etherian logo.
    Its original polygon had a vertical right edge running all the way
    to the bottom, producing a square lower-right corner above the CTAs.

    Give that lower edge the same shared-angle treatment as the other panes.
  */
  #etherian-page-frame .etherian-popout-glass-layer--3 {
    clip-path:
      polygon(
        0 0,

        calc(
          100% -
          var(--layer-cut-run)
        ) 0,

        100%
        var(--layer-cut-rise),

        100%
        calc(
          100% -
          var(--layer-cut-rise) * 0.42
        ),

        calc(
          100% -
          var(--layer-cut-run) * 0.42
        ) 100%,

        0 100%
      );
  }


  /*
    Feature cards remain laid out normally so their geometry can still be
    measured while hidden. JS only fades them away when they actually start
    colliding with one another or escaping their allotted grid area.
  */
  #etherian-page-frame .game-info-features {
    transition:
      opacity 120ms ease;
  }


  #etherian-page-frame
  .game-info-features.is-crowded {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
  }
}


/* =========================================================
   Etherian responsive desktop composition
   Three states:
   - standard: existing composition, but top identity is anchored
   - compact: moderate width/height pressure
   - tight: strong desktop pressure before tablet handoff

   State classes are applied from the actual secondary-panel content size,
   not the browser width, so the layout reacts to the space it really owns.
   ========================================================= */

@media (min-width: 1401px) {

  /* -------------------------------------------------------
     STANDARD DESKTOP
     Stop vertically re-centering the whole dossier as its children wrap.
     This is the main reason the Etherian logo appeared to "wander".
     ------------------------------------------------------- */

  #etherian-page-frame .game-info-surface {
    align-content: stretch;

    grid-template-rows:
      auto
      auto
      minmax(0, 1fr)
      auto
      auto;
  }


  #etherian-page-frame .game-info-header {
    align-self: start;
  }


  /*
    Use a bounded physical-feeling logo size rather than a percentage of
    the changing panel width. It can still scale, but much less dramatically.
  */
  #etherian-page-frame .game-info-logo {
    width:
      clamp(
        250px,
        30vw,
        430px
      );

    max-width: 62%;

    max-height:
      clamp(
        76px,
        11vh,
        126px
      );

    margin-left: 0;
  }


  /*
    Character-based line length makes the blurb's wrapping feel intentional.
    It no longer expands/contracts as aggressively with the panel.
  */
  #etherian-page-frame .game-info-blurb {
    width: min(100%, 76ch);
    max-width: 76ch;
  }


  /* -------------------------------------------------------
     COMPACT DESKTOP
     ------------------------------------------------------- */

  #etherian-page-frame.is-info-compact
  .game-info-surface {
    gap:
      clamp(8px, 0.9vh, 13px);

    padding:
      clamp(20px, 1.75vw, 30px)
      clamp(20px, 1.7vw, 30px)
      clamp(18px, 1.55vw, 27px)
      clamp(22px, 1.9vw, 34px);
  }


  #etherian-page-frame.is-info-compact
  .game-info-header {
    gap:
      clamp(4px, 0.5vh, 7px);
  }


  #etherian-page-frame.is-info-compact
  .game-info-logo {
    width:
      clamp(
        220px,
        25vw,
        350px
      );

    max-width: 58%;

    max-height:
      clamp(
        66px,
        9.5vh,
        104px
      );
  }


  #etherian-page-frame.is-info-compact
  .game-info-kicker {
    font-size:
      clamp(8px, 0.62vw, 11px);

    letter-spacing: 0.27em;
  }


  #etherian-page-frame.is-info-compact
  .game-info-blurb {
    width: min(100%, 70ch);
    max-width: 70ch;

    font-size:
      clamp(11px, 0.76vw, 13.5px);

    line-height: 1.43;
  }


  #etherian-page-frame.is-info-compact
  .game-info-features {
    column-gap:
      clamp(12px, 0.9vw, 18px);

    row-gap:
      clamp(5px, 0.42vw, 8px);

    padding:
      clamp(4px, 0.36vw, 7px)
      0;
  }


  #etherian-page-frame.is-info-compact
  .game-info-feature {
    grid-template-columns:
      clamp(27px, 2.15vw, 36px)
      minmax(0, 1fr);

    gap:
      clamp(6px, 0.5vw, 9px);

    padding:
      clamp(4px, 0.34vw, 6px)
      clamp(3px, 0.26vw, 5px);
  }


  #etherian-page-frame.is-info-compact
  .game-info-feature-icon {
    font-size:
      clamp(14px, 1.12vw, 20px);
  }


  #etherian-page-frame.is-info-compact
  .game-info-feature-copy strong {
    font-size:
      clamp(7.5px, 0.53vw, 9.5px);

    letter-spacing: 0.12em;
  }


  #etherian-page-frame.is-info-compact
  .game-info-feature-copy small {
    font-size:
      clamp(7px, 0.49vw, 8.8px);
  }


  #etherian-page-frame.is-info-compact
  .game-info-fact {
    gap: 2px;

    padding:
      clamp(6px, 0.48vw, 8px)
      clamp(6px, 0.58vw, 10px);
  }


  #etherian-page-frame.is-info-compact
  .game-info-actions {
    gap:
      clamp(8px, 0.62vw, 11px);
  }


  #etherian-page-frame.is-info-compact
  .game-info-action {
    padding:
      clamp(8px, 0.6vw, 10px)
      clamp(11px, 0.8vw, 14px);
  }


  /* -------------------------------------------------------
     TIGHT DESKTOP
     Preserve identity/blurb + facts/CTAs first. Features remain available
     while they fit, but the JS crowding guard can retire them gracefully.
     ------------------------------------------------------- */

  #etherian-page-frame.is-info-tight
  .game-info-surface {
    gap:
      clamp(6px, 0.68vh, 9px);

    padding:
      clamp(16px, 1.35vw, 22px)
      clamp(17px, 1.4vw, 24px)
      clamp(15px, 1.25vw, 21px)
      clamp(18px, 1.55vw, 27px);
  }


  #etherian-page-frame.is-info-tight
  .game-info-logo {
    width:
      clamp(
        190px,
        21vw,
        290px
      );

    max-width: 54%;

    max-height:
      clamp(
        58px,
        8vh,
        86px
      );
  }


  #etherian-page-frame.is-info-tight
  .game-info-kicker {
    font-size:
      clamp(7.5px, 0.56vw, 9.5px);

    letter-spacing: 0.23em;
  }


  #etherian-page-frame.is-info-tight
  .game-info-blurb {
    width: min(100%, 64ch);
    max-width: 64ch;

    font-size:
      clamp(10.5px, 0.7vw, 12.5px);

    line-height: 1.38;
  }


  #etherian-page-frame.is-info-tight
  .game-info-features {
    column-gap:
      clamp(9px, 0.65vw, 13px);

    row-gap: 4px;

    padding: 3px 0;
  }


  #etherian-page-frame.is-info-tight
  .game-info-feature {
    grid-template-columns:
      clamp(24px, 1.85vw, 31px)
      minmax(0, 1fr);

    gap: 5px;

    padding: 3px 2px;
  }


  #etherian-page-frame.is-info-tight
  .game-info-feature-icon {
    font-size:
      clamp(12px, 0.92vw, 17px);
  }


  #etherian-page-frame.is-info-tight
  .game-info-feature-copy strong {
    font-size:
      clamp(7px, 0.48vw, 8.5px);

    letter-spacing: 0.10em;
  }


  #etherian-page-frame.is-info-tight
  .game-info-feature-copy small {
    font-size:
      clamp(6.7px, 0.45vw, 8px);
  }


  #etherian-page-frame.is-info-tight
  .game-info-fact {
    padding:
      5px
      clamp(5px, 0.46vw, 8px);
  }


  #etherian-page-frame.is-info-tight
  .game-info-fact span {
    font-size:
      clamp(7px, 0.48vw, 8.5px);

    letter-spacing: 0.15em;
  }


  #etherian-page-frame.is-info-tight
  .game-info-fact strong {
    font-size:
      clamp(9px, 0.6vw, 11px);
  }


  #etherian-page-frame.is-info-tight
  .game-info-action {
    padding:
      7px
      clamp(9px, 0.68vw, 12px);

    font-size:
      clamp(8px, 0.58vw, 10px);

    letter-spacing: 0.09em;
  }


  /*
    Let the feature cards tolerate a little pressure before disappearing.
    The JS class is only set after a 14px encroachment threshold is exceeded.
  */
  #etherian-page-frame
  .game-info-features.is-crowded {
    transition:
      opacity 130ms ease;

    opacity: 0;
    visibility: hidden;
    pointer-events: none;
  }
}


/* =========================================================
   Etherian responsive desktop — smoothed state transitions
   Philosophy:
   - fluid sizing remains continuous
   - compact/tight states only make larger structural decisions
   - state changes animate instead of popping
   ========================================================= */

@media (min-width: 1401px) {

  /*
    Animate the properties that were visibly snapping when a state class
    changed. Keep the timing short enough to follow active window resizing.
  */
  #etherian-page-frame .game-info-surface,
  #etherian-page-frame .game-info-header,
  #etherian-page-frame .game-info-logo,
  #etherian-page-frame .game-info-kicker,
  #etherian-page-frame .game-info-blurb,
  #etherian-page-frame .game-info-features,
  #etherian-page-frame .game-info-feature,
  #etherian-page-frame .game-info-feature-icon,
  #etherian-page-frame .game-info-feature-copy strong,
  #etherian-page-frame .game-info-feature-copy small,
  #etherian-page-frame .game-info-fact,
  #etherian-page-frame .game-info-fact span,
  #etherian-page-frame .game-info-fact strong,
  #etherian-page-frame .game-info-actions,
  #etherian-page-frame .game-info-action {
    transition:
      width 210ms ease,
      max-width 210ms ease,
      max-height 210ms ease,
      padding 210ms ease,
      gap 210ms ease,
      font-size 210ms ease,
      line-height 210ms ease,
      letter-spacing 210ms ease,
      opacity 180ms ease,
      transform 180ms ease;
  }


  /*
    Restore more continuous "living" behavior between states.
    These values interpolate with the actual panel size instead of waiting
    for a class flip.
  */
  #etherian-page-frame .game-info-surface {
    padding:
      clamp(16px, 1.65cqw, 34px)
      clamp(17px, 1.55cqw, 32px)
      clamp(15px, 1.45cqw, 29px)
      clamp(18px, 1.75cqw, 36px);

    gap:
      clamp(7px, 0.78cqh, 14px);
  }


  #etherian-page-frame .game-info-logo {
    width:
      clamp(
        220px,
        27cqw,
        390px
      );

    max-width: 60%;

    max-height:
      clamp(
        66px,
        10cqh,
        112px
      );
  }


  #etherian-page-frame .game-info-kicker {
    font-size:
      clamp(8px, 0.60cqw, 11px);

    letter-spacing:
      clamp(0.22em, 0.26em, 0.28em);
  }


  #etherian-page-frame .game-info-blurb {
    width:
      min(
        100%,
        clamp(
          58ch,
          67cqw,
          76ch
        )
      );

    max-width: 76ch;

    font-size:
      clamp(10.8px, 0.70cqw, 13.5px);

    line-height:
      clamp(1.38, 1.42, 1.46);
  }


  #etherian-page-frame .game-info-features {
    column-gap:
      clamp(10px, 0.85cqw, 18px);

    row-gap:
      clamp(4px, 0.38cqw, 8px);

    padding:
      clamp(3px, 0.32cqw, 7px)
      0;
  }


  #etherian-page-frame .game-info-feature {
    grid-template-columns:
      clamp(25px, 2cqw, 36px)
      minmax(0, 1fr);

    gap:
      clamp(5px, 0.46cqw, 9px);

    padding:
      clamp(3px, 0.3cqw, 6px)
      clamp(2px, 0.24cqw, 5px);
  }


  #etherian-page-frame .game-info-feature-icon {
    font-size:
      clamp(13px, 1.02cqw, 20px);
  }


  #etherian-page-frame .game-info-feature-copy strong {
    font-size:
      clamp(7.3px, 0.50cqw, 9.5px);

    letter-spacing:
      clamp(0.10em, 0.115em, 0.12em);
  }


  #etherian-page-frame .game-info-feature-copy small {
    font-size:
      clamp(6.9px, 0.46cqw, 8.8px);
  }


  #etherian-page-frame .game-info-fact {
    padding:
      clamp(5px, 0.44cqw, 8px)
      clamp(5px, 0.54cqw, 10px);
  }


  #etherian-page-frame .game-info-action {
    padding:
      clamp(7px, 0.56cqw, 10px)
      clamp(9px, 0.74cqw, 14px);

    font-size:
      clamp(8px, 0.55cqw, 10px);
  }


  /*
    Compact now only nudges hierarchy and density. It no longer abruptly
    restyles every element.
  */
  #etherian-page-frame.is-info-compact
  .game-info-logo {
    max-width: 57%;
  }


  #etherian-page-frame.is-info-compact
  .game-info-blurb {
    max-width: 70ch;
  }


  /*
    Tight mode makes one decisive structural change:
    retire the feature block rather than shrinking it into illegibility.
  */
  #etherian-page-frame.is-info-tight
  .game-info-features {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;

    transform:
      translateY(-4px);
  }


  /*
    When tight mode hides features, allow the remaining rows to reclaim
    the vertical breathing room naturally.
  */
  #etherian-page-frame.is-info-tight
  .game-info-surface {
    grid-template-rows:
      auto
      auto
      minmax(0, 0.18fr)
      auto
      auto;
  }


  /*
    The crowding guard remains a fallback, but behaves visually like the
    tight-state transition rather than an abrupt disappearance.
  */
  #etherian-page-frame
  .game-info-features.is-crowded {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;

    transform:
      translateY(-4px);
  }
}


/* =========================================================
   Etherian responsive desktop — proportion-preserving pass
   Preserve the original hero composition for much longer.
   Compress whitespace first, optional content second, type last.
   ========================================================= */

@media (min-width: 1401px) {

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

  /*
    Keep the logo visually substantial. It can ease down a little, but no
    longer miniaturizes as the panel approaches tablet territory.
  */
  #etherian-page-frame .game-info-logo,
  #etherian-page-frame.is-info-compact .game-info-logo,
  #etherian-page-frame.is-info-tight .game-info-logo {
    width:
      clamp(
        270px,
        29cqw,
        410px
      );

    max-width: 61%;

    max-height:
      clamp(
        78px,
        10.5cqh,
        116px
      );
  }


  #etherian-page-frame .game-info-kicker,
  #etherian-page-frame.is-info-compact .game-info-kicker,
  #etherian-page-frame.is-info-tight .game-info-kicker {
    font-size:
      clamp(
        9px,
        0.60cqw,
        11px
      );

    letter-spacing: 0.27em;
  }


  /*
    Preserve readable body copy. Let the line length adjust before the
    typography itself becomes noticeably smaller.
  */
  #etherian-page-frame .game-info-blurb,
  #etherian-page-frame.is-info-compact .game-info-blurb,
  #etherian-page-frame.is-info-tight .game-info-blurb {
    width:
      min(
        100%,
        clamp(
          62ch,
          68cqw,
          76ch
        )
      );

    max-width: 76ch;

    font-size:
      clamp(
        11.8px,
        0.72cqw,
        13.8px
      );

    line-height: 1.44;
  }


  /* -------------------------------------------------------
     Features
     ------------------------------------------------------- */

  /*
    Keep features at a readable scale. Tight mode fades the whole group
    rather than shrinking individual cards into a miniature version.
  */
  #etherian-page-frame .game-info-feature,
  #etherian-page-frame.is-info-compact .game-info-feature,
  #etherian-page-frame.is-info-tight .game-info-feature {
    grid-template-columns:
      clamp(30px, 2.05cqw, 38px)
      minmax(0, 1fr);

    gap:
      clamp(6px, 0.46cqw, 9px);

    padding:
      clamp(4px, 0.32cqw, 7px)
      clamp(3px, 0.25cqw, 6px);
  }


  #etherian-page-frame .game-info-feature-icon,
  #etherian-page-frame.is-info-compact .game-info-feature-icon,
  #etherian-page-frame.is-info-tight .game-info-feature-icon {
    font-size:
      clamp(
        15px,
        1.02cqw,
        20px
      );
  }


  #etherian-page-frame .game-info-feature-copy strong,
  #etherian-page-frame.is-info-compact .game-info-feature-copy strong,
  #etherian-page-frame.is-info-tight .game-info-feature-copy strong {
    font-size:
      clamp(
        8px,
        0.51cqw,
        9.5px
      );
  }


  #etherian-page-frame .game-info-feature-copy small,
  #etherian-page-frame.is-info-compact .game-info-feature-copy small,
  #etherian-page-frame.is-info-tight .game-info-feature-copy small {
    font-size:
      clamp(
        7.5px,
        0.47cqw,
        8.8px
      );
  }


  /*
    Don't change the grid row structure in tight mode. That was a visible
    pop. The feature group now fades in place, keeping the lower metadata /
    CTA region anchored while resizing.
  */
  #etherian-page-frame.is-info-tight .game-info-surface {
    grid-template-rows:
      auto
      auto
      minmax(0, 1fr)
      auto
      auto;
  }


  #etherian-page-frame.is-info-tight .game-info-features,
  #etherian-page-frame .game-info-features.is-crowded {
    opacity: 0;

    /*
      Visibility stays visible during resizing so there is no discrete
      visibility switch mid-fade. Pointer events are enough here because
      these are informational cards, not controls.
    */
    visibility: visible;

    pointer-events: none;

    transform:
      translateY(-3px);
  }


  /* -------------------------------------------------------
     Facts + CTAs: treat these as stable anchors
     ------------------------------------------------------- */

  #etherian-page-frame .game-info-fact,
  #etherian-page-frame.is-info-compact .game-info-fact,
  #etherian-page-frame.is-info-tight .game-info-fact {
    padding:
      clamp(7px, 0.46cqw, 10px)
      clamp(7px, 0.55cqw, 11px);
  }


  #etherian-page-frame .game-info-fact span,
  #etherian-page-frame.is-info-compact .game-info-fact span,
  #etherian-page-frame.is-info-tight .game-info-fact span {
    font-size:
      clamp(
        8px,
        0.49cqw,
        9.5px
      );
  }


  #etherian-page-frame .game-info-fact strong,
  #etherian-page-frame.is-info-compact .game-info-fact strong,
  #etherian-page-frame.is-info-tight .game-info-fact strong {
    font-size:
      clamp(
        10px,
        0.62cqw,
        12px
      );
  }


  /*
    Buttons keep a stable physical height and readable type. Their width can
    continue to follow the available panel width, but they no longer flatten
    and miniaturize near the desktop/tablet handoff.
  */
  #etherian-page-frame .game-info-actions,
  #etherian-page-frame.is-info-compact .game-info-actions,
  #etherian-page-frame.is-info-tight .game-info-actions {
    grid-template-columns:
      minmax(0, 1.25fr)
      minmax(0, 0.95fr);

    gap:
      clamp(
        9px,
        0.65cqw,
        13px
      );
  }


  #etherian-page-frame .game-info-action,
  #etherian-page-frame.is-info-compact .game-info-action,
  #etherian-page-frame.is-info-tight .game-info-action {
    min-height:
      clamp(
        40px,
        4.7cqh,
        48px
      );

    padding:
      0
      clamp(
        12px,
        0.78cqw,
        16px
      );

    gap:
      clamp(
        8px,
        0.55cqw,
        12px
      );

    font-size:
      clamp(
        9.5px,
        0.57cqw,
        11px
      );

    letter-spacing: 0.10em;
  }


  /*
    Avoid transitioning typography/layout values during every state flip.
    Those transitions lagged behind the live resize and created a second,
    visible "catch-up" motion. Keep only genuinely visual transitions.
  */
  #etherian-page-frame .game-info-surface,
  #etherian-page-frame .game-info-header,
  #etherian-page-frame .game-info-logo,
  #etherian-page-frame .game-info-kicker,
  #etherian-page-frame .game-info-blurb,
  #etherian-page-frame .game-info-feature,
  #etherian-page-frame .game-info-feature-icon,
  #etherian-page-frame .game-info-feature-copy strong,
  #etherian-page-frame .game-info-feature-copy small,
  #etherian-page-frame .game-info-fact,
  #etherian-page-frame .game-info-fact span,
  #etherian-page-frame .game-info-fact strong,
  #etherian-page-frame .game-info-actions,
  #etherian-page-frame .game-info-action {
    transition: none;
  }


  #etherian-page-frame .game-info-features {
    transition:
      opacity 190ms ease,
      transform 190ms ease;
  }
}


/* =========================================================
   Etherian responsive desktop — spacing + feature-collapse fix
   ========================================================= */

@media (min-width: 1401px) {

  /*
    The default panel had too much vertical distribution because the middle
    row was allowed to absorb a large amount of spare height. Keep the whole
    information stack more compact and top-weighted instead.
  */
  #etherian-page-frame .game-info-surface {
    align-content: start;

    grid-template-rows:
      auto
      auto
      auto
      auto
      auto;

    row-gap:
      clamp(
        8px,
        0.72cqh,
        14px
      );
  }


  /*
    The feature region should only occupy the space its content actually
    needs. This prevents the large airy gap seen in the wide layout.
  */
  #etherian-page-frame .game-info-features {
    align-content: start;

    min-height: 0;

    max-height: 180px;

    margin-block:
      clamp(
        2px,
        0.22cqh,
        5px
      );

    overflow: hidden;

    transition:
      opacity 190ms ease,
      transform 190ms ease,
      max-height 220ms ease,
      margin 220ms ease;
  }


  /*
    Hidden features now collapse their own vertical footprint instead of
    leaving an empty middle band between the blurb and facts/buttons.
  */
  #etherian-page-frame
  .game-info-features.is-crowded,
  #etherian-page-frame
  .game-info-features.is-structure-hidden {
    opacity: 0;

    max-height: 0;

    margin-block: 0;

    transform:
      translateY(-3px);

    pointer-events: none;
  }


  /*
    Tight mode no longer automatically hides the feature block. Its job is
    only to tighten spacing. Actual collision detection decides whether the
    features really need to disappear.
  */
  #etherian-page-frame.is-info-tight
  .game-info-features {
    opacity: 1;

    max-height: 180px;

    margin-block:
      clamp(
        1px,
        0.15cqh,
        4px
      );

    transform: none;

    pointer-events: auto;
  }


  /*
    Slightly tighten the separation between the top identity group and the
    rest of the dossier without making the layout feel cramped.
  */
  #etherian-page-frame .game-info-header {
    margin-bottom:
      clamp(
        1px,
        0.18cqh,
        4px
      );
  }


  #etherian-page-frame .game-info-blurb {
    margin-bottom:
      clamp(
        2px,
        0.25cqh,
        5px
      );
  }


  #etherian-page-frame .game-info-facts {
    margin-top:
      clamp(
        2px,
        0.22cqh,
        5px
      );
  }


  #etherian-page-frame .game-info-actions {
    margin-top:
      clamp(
        1px,
        0.16cqh,
        4px
      );
  }
}


/* =========================================================
   Etherian info — proportional three-zone vertical layout
   Top: identity + blurb
   Middle: features
   Bottom: facts + actions

   The surface is centered as a composition at generous sizes.
   Spacing compresses continuously. The middle track can smoothly
   collapse to 0 when there genuinely isn't enough room.
   ========================================================= */

@media (min-width: 1401px) {

  #etherian-page-frame .game-info-surface {
    --feature-zone-height: 118px;

    display: grid;

    grid-template-rows:
      auto
      var(--feature-zone-height)
      auto;

    align-content: center;

    row-gap:
      clamp(
        11px,
        1.25cqh,
        20px
      );

    padding:
      clamp(22px, 3.2cqh, 40px)
      clamp(20px, 1.65cqw, 34px)
      clamp(20px, 2.9cqh, 36px)
      clamp(22px, 1.8cqw, 38px);

    transition:
      grid-template-rows 230ms
      cubic-bezier(0.2, 0.78, 0.24, 1),
      row-gap 180ms ease,
      padding 180ms ease;
  }


  /* Remove the old discrete responsive-state behavior from the composition. */
  #etherian-page-frame.is-info-compact .game-info-surface,
  #etherian-page-frame.is-info-tight .game-info-surface {
    grid-template-rows:
      auto
      var(--feature-zone-height)
      auto;

    align-content: center;
  }


  #etherian-page-frame .game-info-top-zone,
  #etherian-page-frame .game-info-bottom-zone {
    min-width: 0;

    display: grid;

    align-content: start;
  }


  #etherian-page-frame .game-info-top-zone {
    row-gap:
      clamp(
        7px,
        0.68cqh,
        11px
      );
  }


  #etherian-page-frame .game-info-bottom-zone {
    row-gap:
      clamp(
        7px,
        0.62cqh,
        11px
      );
  }


  /*
    Remove spacing rules that previously belonged to separate grid rows.
    Zone gaps now own the vertical rhythm.
  */
  #etherian-page-frame .game-info-header,
  #etherian-page-frame .game-info-blurb,
  #etherian-page-frame .game-info-facts,
  #etherian-page-frame .game-info-actions {
    margin-top: 0;
    margin-bottom: 0;
  }


  /*
    Preserve the good desktop proportions instead of scaling everything down.
  */
  #etherian-page-frame .game-info-logo,
  #etherian-page-frame.is-info-compact .game-info-logo,
  #etherian-page-frame.is-info-tight .game-info-logo {
    width:
      clamp(
        280px,
        28cqw,
        405px
      );

    max-width: 60%;

    max-height:
      clamp(
        80px,
        10.5cqh,
        116px
      );
  }


  #etherian-page-frame .game-info-blurb,
  #etherian-page-frame.is-info-compact .game-info-blurb,
  #etherian-page-frame.is-info-tight .game-info-blurb {
    width:
      min(
        100%,
        74ch
      );

    max-width: 74ch;

    font-size:
      clamp(
        11.8px,
        0.72cqw,
        13.8px
      );

    line-height: 1.44;
  }


  /*
    The feature grid fills a dedicated animated track. It never sits under
    the facts/actions, so clipping-by-overlap cannot happen.
  */
  #etherian-page-frame .game-info-features,
  #etherian-page-frame.is-info-tight .game-info-features,
  #etherian-page-frame
  .game-info-features.is-crowded {
    min-height: 0;
    height: 100%;
    max-height: none;

    margin: 0;

    align-content: center;

    overflow: hidden;

    opacity: 1;
    visibility: visible;
    transform: none;

    transition:
      opacity 170ms ease;
  }


  #etherian-page-frame
  .game-info-surface.is-features-collapsed
  .game-info-features {
    opacity: 0;

    pointer-events: none;
  }


  /*
    Facts and buttons remain stable anchors. Their proportions no longer
    change when compact/tight bookkeeping classes toggle.
  */
  #etherian-page-frame .game-info-fact,
  #etherian-page-frame.is-info-compact .game-info-fact,
  #etherian-page-frame.is-info-tight .game-info-fact {
    padding:
      clamp(7px, 0.48cqw, 10px)
      clamp(7px, 0.56cqw, 11px);
  }


  #etherian-page-frame .game-info-action,
  #etherian-page-frame.is-info-compact .game-info-action,
  #etherian-page-frame.is-info-tight .game-info-action {
    min-height:
      clamp(
        40px,
        4.7cqh,
        48px
      );

    padding:
      0
      clamp(
        12px,
        0.78cqw,
        16px
      );

    font-size:
      clamp(
        9.5px,
        0.57cqw,
        11px
      );
  }
}


/* =========================================================
   Etherian three-zone grid — roomy desktop scaling polish
   ========================================================= */

@media (min-width: 1401px) {

  /*
    Let the composition grow more confidently when it has the room.
    The mins stay close to the current good compact values; the maxes are
    roughly 20–25% larger than the previous pass.
  */
  #etherian-page-frame .game-info-logo {
    width:
      clamp(
        285px,
        30cqw,
        500px
      );

    max-width: 63%;

    max-height:
      clamp(
        82px,
        11.5cqh,
        142px
      );
  }


  #etherian-page-frame .game-info-kicker {
    font-size:
      clamp(
        9px,
        0.66cqw,
        13px
      );

    letter-spacing:
      clamp(
        0.25em,
        0.28em,
        0.30em
      );
  }


  #etherian-page-frame .game-info-blurb {
    width:
      min(
        100%,
        76ch
      );

    max-width: 76ch;

    font-size:
      clamp(
        12px,
        0.78cqw,
        16.5px
      );

    line-height: 1.46;
  }


  #etherian-page-frame .game-info-feature {
    grid-template-columns:
      clamp(
        32px,
        2.2cqw,
        46px
      )
      minmax(0, 1fr);

    gap:
      clamp(
        7px,
        0.52cqw,
        11px
      );

    padding:
      clamp(
        5px,
        0.36cqw,
        8px
      )
      clamp(
        4px,
        0.3cqw,
        7px
      );
  }


  #etherian-page-frame .game-info-feature-icon {
    font-size:
      clamp(
        16px,
        1.1cqw,
        23px
      );
  }


  #etherian-page-frame .game-info-feature-copy strong {
    font-size:
      clamp(
        8px,
        0.56cqw,
        10.5px
      );
  }


  #etherian-page-frame .game-info-feature-copy small {
    font-size:
      clamp(
        7.5px,
        0.50cqw,
        9.5px
      );
  }


  #etherian-page-frame .game-info-fact span {
    font-size:
      clamp(
        8px,
        0.54cqw,
        10px
      );
  }


  #etherian-page-frame .game-info-fact strong {
    font-size:
      clamp(
        10px,
        0.68cqw,
        13px
      );
  }


  #etherian-page-frame .game-info-action {
    min-height:
      clamp(
        41px,
        5cqh,
        54px
      );

    padding:
      0
      clamp(
        13px,
        0.86cqw,
        19px
      );

    font-size:
      clamp(
        9.5px,
        0.62cqw,
        12px
      );
  }


  /*
    At genuinely roomy sizes, increase the composition's breathing room too,
    but keep it centered rather than pushing the rows apart individually.
  */
  #etherian-page-frame .game-info-surface {
    row-gap:
      clamp(
        12px,
        1.45cqh,
        24px
      );

    padding:
      clamp(
        24px,
        3.5cqh,
        46px
      )
      clamp(
        22px,
        1.85cqw,
        38px
      )
      clamp(
        22px,
        3.2cqh,
        42px
      )
      clamp(
        24px,
        2cqw,
        42px
      );
  }


  /*
    The feature track transition remains the only structural animation.
    Slightly lengthen it so the collapse/reopen reads as one deliberate move.
  */
  #etherian-page-frame .game-info-surface {
    transition:
      grid-template-rows 260ms
      cubic-bezier(0.2, 0.78, 0.24, 1),
      row-gap 180ms ease,
      padding 180ms ease;
  }
}


/* =========================================================
   Etherian three-zone grid — large-desktop scale-up
   Preserve the same proportions, but actually use the extra room.
   ========================================================= */

@media (min-width: 1401px) {

  /*
    The previous cqw coefficients were too conservative, so most elements
    sat on their minimum clamp values even on a roomy desktop. Raise the
    fluid terms so the composition genuinely grows with the popout.
  */

  #etherian-page-frame .game-info-logo {
    width:
      clamp(
        285px,
        36cqw,
        540px
      );

    max-width: 66%;

    max-height:
      clamp(
        82px,
        13cqh,
        150px
      );
  }


  #etherian-page-frame .game-info-kicker {
    font-size:
      clamp(
        9px,
        0.78cqw,
        13.5px
      );
  }


  #etherian-page-frame .game-info-blurb {
    max-width: 78ch;

    font-size:
      clamp(
        12px,
        0.98cqw,
        17px
      );

    line-height: 1.46;
  }


  #etherian-page-frame .game-info-feature {
    grid-template-columns:
      clamp(
        32px,
        2.65cqw,
        50px
      )
      minmax(0, 1fr);

    gap:
      clamp(
        7px,
        0.66cqw,
        12px
      );

    padding:
      clamp(
        5px,
        0.46cqw,
        9px
      )
      clamp(
        4px,
        0.38cqw,
        8px
      );
  }


  #etherian-page-frame .game-info-feature-icon {
    font-size:
      clamp(
        16px,
        1.35cqw,
        25px
      );
  }


  #etherian-page-frame .game-info-feature-copy strong {
    font-size:
      clamp(
        8px,
        0.68cqw,
        11px
      );
  }


  #etherian-page-frame .game-info-feature-copy small {
    font-size:
      clamp(
        7.5px,
        0.60cqw,
        10px
      );
  }


  #etherian-page-frame .game-info-fact span {
    font-size:
      clamp(
        8px,
        0.63cqw,
        10.5px
      );
  }


  #etherian-page-frame .game-info-fact strong {
    font-size:
      clamp(
        10px,
        0.78cqw,
        13.5px
      );
  }


  #etherian-page-frame .game-info-action {
    min-height:
      clamp(
        41px,
        5.8cqh,
        58px
      );

    padding:
      0
      clamp(
        13px,
        1.02cqw,
        21px
      );

    font-size:
      clamp(
        9.5px,
        0.75cqw,
        12.5px
      );
  }


  /*
    Let the complete 3-zone composition breathe more as the panel grows,
    but keep the spacing proportional rather than simply pushing rows apart.
  */
  #etherian-page-frame .game-info-surface {
    row-gap:
      clamp(
        12px,
        1.7cqh,
        28px
      );

    padding:
      clamp(
        24px,
        4.1cqh,
        52px
      )
      clamp(
        22px,
        2.15cqw,
        44px
      )
      clamp(
        22px,
        3.7cqh,
        48px
      )
      clamp(
        24px,
        2.35cqw,
        48px
      );
  }


  #etherian-page-frame .game-info-top-zone {
    row-gap:
      clamp(
        7px,
        0.9cqh,
        13px
      );
  }


  #etherian-page-frame .game-info-bottom-zone {
    row-gap:
      clamp(
        7px,
        0.78cqh,
        13px
      );
  }
}


/*
  Give especially wide desktop layouts another small lift.
  This is intentionally modest: the fluid cqw/cqh rules above do most of
  the work, while this prevents very large monitors from feeling underfilled.
*/
@media (min-width: 1900px) {

  #etherian-page-frame .game-info-logo {
    max-width: 68%;
  }


  #etherian-page-frame .game-info-blurb {
    max-width: 80ch;
  }


  #etherian-page-frame .game-info-surface {
    padding-left:
      clamp(
        28px,
        2.55cqw,
        54px
      );

    padding-right:
      clamp(
        26px,
        2.35cqw,
        50px
      );
  }
}


/* =========================================================
   Etherian blurb — stable line-measure box
   Scale the box and type together so wrapping stays effectively fixed.
   ========================================================= */

@media (min-width: 1401px) {

  /*
    The previous blurb used a width that eventually hit 100%, so nearby
    desktop sizes could push a word onto the next line.

    Using a fixed character measure means the text box grows/shrinks with
    the font itself. The visual size changes, but the line length in
    characters remains essentially constant.
  */
  #etherian-page-frame .game-info-blurb {
    width: 64ch;
    max-width: none;

    font-size:
      clamp(
        12px,
        0.98cqw,
        17px
      );

    line-height: 1.46;
  }


  /*
    Only when the available desktop popout becomes genuinely narrower than
    that preferred measure do we allow the box to compress. This should now
    happen very close to the tablet handoff rather than throughout desktop.
  */
  #etherian-page-frame .game-info-top-zone {
    min-width: 0;
  }


  #etherian-page-frame .game-info-blurb {
    max-inline-size:
      min(
        64ch,
        calc(100cqw - 48px)
      );
  }
}


/* =========================================================
   Etherian three-zone grid — width-pressure compensation
   Keep the blurb's 64ch measure, but let its physical size and the
   surrounding vertical whitespace compress a little earlier as the
   popout narrows. This gives the feature zone room before it has to cull.
   ========================================================= */

@media (min-width: 1401px) {

  /*
    Keep the same character measure, but make the font respond a little
    more strongly to narrowing width. Since `ch` scales with the font,
    the box itself gets physically smaller without changing line breaks.
  */
  #etherian-page-frame .game-info-blurb {
    width: 64ch;

    max-inline-size:
      min(
        64ch,
        calc(100cqw - 40px)
      );

    font-size:
      clamp(
        11.4px,
        0.84cqw,
        17px
      );

    line-height: 1.45;
  }


  /*
    Width pressure now also compresses vertical rhythm. Previously only
    height affected these values, so a narrower window could make the blurb
    taller without freeing any vertical space elsewhere.
  */
  #etherian-page-frame .game-info-surface {
    row-gap:
      clamp(
        9px,
        min(
          1.65cqh,
          1.05cqw
        ),
        26px
      );

    padding-top:
      clamp(
        20px,
        min(
          3.8cqh,
          2.4cqw
        ),
        48px
      );

    padding-bottom:
      clamp(
        18px,
        min(
          3.4cqh,
          2.15cqw
        ),
        44px
      );
  }


  #etherian-page-frame .game-info-top-zone {
    row-gap:
      clamp(
        6px,
        min(
          0.85cqh,
          0.62cqw
        ),
        12px
      );
  }


  #etherian-page-frame .game-info-bottom-zone {
    row-gap:
      clamp(
        6px,
        min(
          0.74cqh,
          0.56cqw
        ),
        12px
      );
  }
}


/* =========================================================
   Etherian logo priority pass
   Preserve logo scale; let supporting copy/metadata compress first.
   ========================================================= */

@media (min-width: 1401px) {

  /*
    Keep the logo visually stable across desktop compression.
    It now has a much tighter min/max range, so the identity does not
    shrink as aggressively as the supporting information.
  */
  #etherian-page-frame .game-info-logo {
    width:
      clamp(
        320px,
        31cqw,
        420px
      );

    max-width: 64%;

    max-height:
      clamp(
        92px,
        11.5cqh,
        122px
      );
  }


  /*
    Let supporting copy yield a little more under pressure instead.
  */
  #etherian-page-frame .game-info-blurb {
    font-size:
      clamp(
        10.8px,
        0.82cqw,
        16.5px
      );
  }


  #etherian-page-frame .game-info-kicker {
    font-size:
      clamp(
        8.5px,
        0.60cqw,
        12.5px
      );
  }


  /*
    Metadata is lower priority than the logo, so it can compress a little
    further before the identity does.
  */
  #etherian-page-frame .game-info-fact span {
    font-size:
      clamp(
        7.5px,
        0.50cqw,
        10px
      );
  }


  #etherian-page-frame .game-info-fact strong {
    font-size:
      clamp(
        9.5px,
        0.64cqw,
        13px
      );
  }
}


/* =========================================================
   Etherian logo priority — large-frame prominence
   Keep the protected desktop minimum, but allow a stronger lift
   once the popout itself becomes genuinely roomy.
   ========================================================= */

@media (min-width: 1401px) {

  #etherian-page-frame .game-info-logo {
    width:
      clamp(
        320px,
        31cqw,
        420px
      );
  }
}


/*
  Large-frame lift:
  once the popout is comfortably large, let the logo become a more
  prominent hero element again without weakening its protected minimum.
*/
@container (min-width: 980px) {

  #etherian-page-frame .game-info-logo {
    width:
      clamp(
        390px,
        38cqw,
        520px
      );

    max-width: 68%;

    max-height:
      clamp(
        108px,
        13cqh,
        148px
      );
  }
}


/*
  Extra-wide desktop refinement.
*/
@container (min-width: 1180px) {

  #etherian-page-frame .game-info-logo {
    width:
      clamp(
        430px,
        40cqw,
        560px
      );

    max-width: 70%;
  }
}


/* =========================================================
   Etherian logo priority — working large-desktop lift
   ========================================================= */

/*
  The previous lift used @container, but the secondary popout is a sibling
  of the page-content container rather than a descendant of it, so those
  queries never matched. Use the actual desktop viewport thresholds here.

  Normal desktop still keeps the protected 320–420px logo range.
  Large desktop restores the stronger hero-logo growth we had earlier.
*/

@media (min-width: 1900px) {

  #etherian-page-frame .game-info-logo {
    width:
      clamp(
        410px,
        23vw,
        520px
      );

    max-width: 68%;

    max-height:
      clamp(
        112px,
        12.5vh,
        148px
      );
  }
}


@media (min-width: 2200px) {

  #etherian-page-frame .game-info-logo {
    width:
      clamp(
        470px,
        24vw,
        560px
      );

    max-width: 70%;

    max-height: 156px;
  }
}


/* =========================================================
   Etherian logo priority — smooth large-desktop growth
   Replace the stepped 1900px / 2200px jumps with one continuous curve.
   ========================================================= */

@media (min-width: 1401px) {

  /*
    Protected at smaller desktop sizes, then grows continuously as the
    viewport gets roomier. The cap is about 15% larger than the previous
    420px desktop maximum:
      420px × 1.15 ≈ 483px

    Because this is one continuous clamp() rather than breakpoint jumps,
    there is no threshold pop.
  */
  #etherian-page-frame .game-info-logo {
    width:
      clamp(
        320px,
        calc(27.2vw - 118px),
        483px
      );

    max-width: 68%;

    max-height:
      clamp(
        92px,
        calc(7.8vw - 18px),
        140px
      );

    transition:
      width 140ms ease-out,
      max-height 140ms ease-out;
  }
}


/* =========================================================
   Etherian logo priority — feature-collapse emphasis
   When the middle feature zone retires, use some of the reclaimed
   vertical space to give the logo a modest additional lift.
   ========================================================= */

@media (min-width: 1401px) {

  #etherian-page-frame
  .game-info-surface.is-features-collapsed
  .game-info-logo {
    width:
      clamp(
        340px,
        calc(29.5vw - 122px),
        520px
      );

    max-width: 70%;

    max-height:
      clamp(
        100px,
        calc(8.6vw - 18px),
        150px
      );
  }
}


/* =========================================================
   Etherian backmost glass pane — screenshot atmosphere
   Screenshot 5 fills the pane by height, preserving its aspect ratio.
   Its top-right corner is anchored to the pane's top-right corner.
   ========================================================= */

@media (min-width: 1401px) {

  #etherian-page-frame
  .etherian-popout-glass-layer--1 {
    overflow: hidden;
  }


  #etherian-page-frame
  .etherian-popout-layer-image {
    position: absolute;

    top: 0;
    right: 0;

    height: 100%;
    width: auto;

    max-width: none;

    display: block;

    object-fit: contain;
    object-position: top right;

    pointer-events: none;

    /*
      Keep it atmospheric rather than reading as a literal screenshot card.
      The pane's own glass treatment remains above/around it.
    */
    opacity: 0.40;

    filter:
      saturate(0.92)
      contrast(0.96)
      brightness(0.88);
  }


  /*
    Preserve the pane's glass veil over the screenshot by adding a subtle
    tint layer above the image but below any content.
  */
  #etherian-page-frame
  .etherian-popout-glass-layer--1::before {
    content: "";

    position: absolute;
    inset: 0;

    z-index: 1;

    background:
      linear-gradient(
        110deg,
        rgba(18, 30, 34, 0.22),
        rgba(
          var(--page-accent-rgb),
          0.055
        ) 48%,
        rgba(10, 18, 22, 0.10)
      );

    pointer-events: none;
  }


  #etherian-page-frame
  .etherian-popout-layer-image {
    z-index: 0;
  }
}


/* =========================================================
   Etherian screenshot — top-right gradient reveal
   Keep only the upper-right portion of the image visible and
   feather it smoothly into the surrounding glass.
   ========================================================= */

@media (min-width: 1401px) {

  #etherian-page-frame
  .etherian-popout-layer-image {
    /*
      Radial mask anchored to the same top-right point as the image itself.
      Opaque near the corner, then smoothly fades away toward the left/bottom.
    */
    -webkit-mask-image:
      radial-gradient(
        ellipse 78% 72%
        at 100% 0%,
        rgba(0, 0, 0, 1) 0%,
        rgba(0, 0, 0, 0.96) 30%,
        rgba(0, 0, 0, 0.72) 48%,
        rgba(0, 0, 0, 0.30) 66%,
        rgba(0, 0, 0, 0) 84%
      );

    mask-image:
      radial-gradient(
        ellipse 78% 72%
        at 100% 0%,
        rgba(0, 0, 0, 1) 0%,
        rgba(0, 0, 0, 0.96) 30%,
        rgba(0, 0, 0, 0.72) 48%,
        rgba(0, 0, 0, 0.30) 66%,
        rgba(0, 0, 0, 0) 84%
      );

    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;

    -webkit-mask-size: 100% 100%;
    mask-size: 100% 100%;
  }
}


/* =========================================================
   Etherian screenshot — final opacity polish
   ========================================================= */

@media (min-width: 1401px) {

  #etherian-page-frame
  .etherian-popout-layer-image {
    opacity: 0.30;
  }
}


/* =========================================================
   Etherian decorative stack — tablet handoff fade
   Ensure the screenshot + extra glass panes leave with the popout.
   ========================================================= */

/*
  During the desktop -> tablet FLIP/retract handoff, the generic popout
  content is forced to opacity: 0, but Etherian's decorative glass stack is
  a separate sibling and was not participating in that fade.

  Fade the whole stack immediately when the layout transition begins.
  Because the screenshot lives inside layer 1, it now fades in perfect sync
  with the other Etherian decorative panes.
*/
.prototype-page-frame.is-layout-transitioning
.etherian-popout-layer-stack {
  opacity: 0 !important;

  transition:
    opacity 180ms ease !important;

  transition-delay: 0ms !important;
}


/*
  Also remove the delayed desktop reveal while the breakpoint handoff is
  active, so an old is-secondary-open state cannot fight the fade.
*/
#etherian-page-frame.is-layout-transitioning.is-secondary-open
.etherian-popout-layer-stack {
  opacity: 0 !important;
  transition-delay: 0ms !important;
}


/* =========================================================
   Etherian info — slower established desktop reveal
   ========================================================= */

@media (min-width: 1401px) {

  #etherian-page-frame
  .desktop-secondary-panel-content {
    transition:
      opacity 650ms ease !important;
  }


  #etherian-page-frame.is-secondary-open
  .desktop-secondary-panel-content {
    transition:
      opacity 650ms ease !important;

    /*
      Keep the same established reveal phase; only lengthen the fade itself.
    */
    transition-delay:
      calc(
        var(--secondary-panel-duration) * 0.78
      ) !important;
  }
}


/* =========================================================
   Etherian screenshot — breakpoint handoff hard-hide
   ========================================================= */

/*
  The screenshot's positioning/mask rules live inside the desktop
  (min-width: 1401px) block. The instant we cross into tablet, those rules
  stop applying before the retract has finished.

  During the handoff, explicitly hide the screenshot itself so it cannot
  survive as an unstyled/intrinsic <img> while the decorative stack is
  retracting.
*/
#etherian-page-frame.is-layout-transitioning
.etherian-popout-layer-image {
  opacity: 0 !important;

  transition:
    opacity 220ms ease !important;

  transition-delay: 0ms !important;

  pointer-events: none !important;
}


/*
  Keep the decorative stack itself in the desktop positioning context for
  the brief handoff interval, even though the desktop media query has
  already turned off.
*/
#etherian-page-frame.is-layout-transitioning
.etherian-popout-layer-stack {
  position: absolute;
  inset: 0;

  overflow: hidden;

  pointer-events: none;
}


/* =========================================================
   Etherian screenshot — preserve desktop geometry during handoff
   ========================================================= */

/*
  The clip exposed the actual issue: the screenshot is not merely failing
  to fade. At <=1400px its normal desktop-only positioning rules disappear,
  so the <img> briefly falls back into ordinary document flow and becomes
  the large rectangular tile visible beside the gallery.

  While the responsive handoff class is active, explicitly preserve the
  screenshot's desktop geometry so the existing opacity fade can happen
  without the image reflowing.
*/
#etherian-page-frame.is-layout-transitioning
.etherian-popout-layer-image {
  position: absolute !important;

  top: 0 !important;
  right: 0 !important;

  height: 100% !important;
  width: auto !important;

  max-width: none !important;
  max-height: none !important;

  display: block !important;

  object-fit: contain !important;
  object-position: top right !important;

  z-index: 0 !important;

  opacity: 0 !important;

  filter:
    saturate(0.92)
    contrast(0.96)
    brightness(0.88) !important;

  -webkit-mask-image:
    radial-gradient(
      ellipse 78% 72%
      at 100% 0%,
      rgba(0, 0, 0, 1) 0%,
      rgba(0, 0, 0, 0.96) 30%,
      rgba(0, 0, 0, 0.72) 48%,
      rgba(0, 0, 0, 0.30) 66%,
      rgba(0, 0, 0, 0) 84%
    ) !important;

  mask-image:
    radial-gradient(
      ellipse 78% 72%
      at 100% 0%,
      rgba(0, 0, 0, 1) 0%,
      rgba(0, 0, 0, 0.96) 30%,
      rgba(0, 0, 0, 0.72) 48%,
      rgba(0, 0, 0, 0.30) 66%,
      rgba(0, 0, 0, 0) 84%
    ) !important;

  -webkit-mask-repeat: no-repeat !important;
  mask-repeat: no-repeat !important;

  -webkit-mask-size: 100% 100% !important;
  mask-size: 100% 100% !important;

  transition:
    opacity 220ms ease !important;

  transition-delay: 0ms !important;

  pointer-events: none !important;
}


/*
  Once the handoff is complete and we are genuinely in tablet mode, this
  decorative desktop-only screenshot should not participate in layout at
  all. This is the safety net that prevents an intrinsic <img> rectangle
  from ever appearing in the tablet composition.
*/
@media (max-width: 1400px) {
  #etherian-page-frame:not(.is-layout-transitioning)
  .desktop-secondary-panel
  .etherian-popout-layer-image {
    display: none !important;
  }
}


/* =========================================================
   Etherian legacy screenshot-0 layer — disable in ALL layouts
   ========================================================= */

/*
  Root cause of the "stuck screenshot" during desktop -> tablet:

  .game-info-background contains etherian-screenshot-0.jpg.

  We had already disabled this old/parked background system, but ONLY inside
  @media (min-width: 1401px). The instant the viewport crossed to tablet,
  that desktop-only display:none rule stopped applying and screenshot-0
  became visible again during the handoff.

  This layer is no longer part of the current Etherian design at any size,
  so disable it globally rather than only on desktop.
*/
#etherian-page-frame .game-info-background,
#etherian-page-frame .game-info-layer--rear,
#etherian-page-frame .game-info-layer--mid,
#etherian-page-frame .game-info::after {
  display: none !important;
}


/* =========================================================
   Etherian responsive snapshot pass
   No extra breakpoint layout overrides are needed here.
   The outgoing desktop info is now a frozen JS snapshot, so the real
   tablet layout is free to reflow invisibly underneath it.
   ========================================================= */


/* =========================================================
   PERFORMANCE TEST — disable Etherian backdrop blur only
   Temporary diagnostic pass.
   ========================================================= */

#etherian-page-frame .desktop-secondary-panel-glass,
#etherian-page-frame .etherian-popout-glass-layer,
#etherian-page-frame .game-info-surface {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}


/* =========================================================
   HALODOOM — first-pass info layout
   Mirrors the established Etherian layout/material system for now.
   ========================================================= */

@media (min-width: 1401px){
#halodoom-page-frame .desktop-secondary-panel-content {
    top: 3.5%;
    right: 4.5%;
    bottom: 3.5%;

    left:
      calc(
        var(--secondary-panel-overlap) +
        3%
      );

    overflow: visible;
  }
#halodoom-page-frame .game-info {
    position: relative;

    width: 100%;
    height: 100%;

    min-width: 0;
    min-height: 0;

    color: rgba(244, 248, 250, 0.96);

    isolation: isolate;
  }
#halodoom-page-frame .game-info-background {
    position: absolute;
    inset: 2% 0 4% 14%;

    z-index: 0;

    overflow: hidden;

    opacity: 0.33;

    clip-path:
      polygon(
        7% 0,
        100% 0,
        100% 90%,
        93% 100%,
        0 100%,
        0 8%
      );

    pointer-events: none;
  }
#halodoom-page-frame .game-info-background-image {
    width: 100%;
    height: 100%;

    object-fit: cover;
    object-position: 58% 44%;

    filter:
      saturate(0.88)
      contrast(0.94)
      brightness(0.72);

    -webkit-mask-image:
      linear-gradient(
        105deg,
        transparent 0%,
        rgba(0, 0, 0, 0.16) 18%,
        rgba(0, 0, 0, 0.70) 54%,
        rgba(0, 0, 0, 0.92) 100%
      );

    mask-image:
      linear-gradient(
        105deg,
        transparent 0%,
        rgba(0, 0, 0, 0.16) 18%,
        rgba(0, 0, 0, 0.70) 54%,
        rgba(0, 0, 0, 0.92) 100%
      );
  }
#halodoom-page-frame .game-info-layer {
    position: absolute;

    z-index: 1;

    pointer-events: none;

    border:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.17
      );

    background:
      rgba(
        var(--page-accent-rgb),
        0.025
      );

    clip-path:
      polygon(
        5% 0,
        100% 0,
        100% 91%,
        94% 100%,
        0 100%,
        0 7%
      );
  }
#halodoom-page-frame .game-info-layer--rear {
    inset: 0.5% 1.5% 1.5% 5.5%;

    transform:
      translate(1.6%, -1.4%);

    opacity: 0.58;
  }
#halodoom-page-frame .game-info-layer--mid {
    inset: 2.5% 3.5% 3% 2%;

    transform:
      translate(-0.8%, 0.7%);

    opacity: 0.78;
  }
#halodoom-page-frame .game-info-surface {
    position: relative;

    z-index: 2;

    width: 100%;
    height: 100%;

    min-width: 0;
    min-height: 0;

    display: grid;

    grid-template-rows:
      auto
      auto
      minmax(0, 1fr)
      auto
      auto;

    align-content: center;

    gap:
      clamp(10px, 1.15vh, 18px);

    padding:
      clamp(22px, 2.15vw, 38px)
      clamp(22px, 2.25vw, 42px)
      clamp(20px, 2vw, 34px)
      clamp(24px, 2.4vw, 46px);

    border:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.26
      );

    background:
      linear-gradient(
        105deg,
        rgba(20, 29, 34, 0.72) 0%,
        rgba(22, 34, 40, 0.60) 48%,
        rgba(19, 31, 37, 0.40) 100%
      );

    backdrop-filter:
      blur(10px)
      saturate(112%);

    -webkit-backdrop-filter:
      blur(10px)
      saturate(112%);

    clip-path:
      polygon(
        5% 0,
        100% 0,
        100% 90%,
        94% 100%,
        0 100%,
        0 7%
      );

    box-shadow:
      inset 0 0 0 1px rgba(255, 255, 255, 0.035),
      inset 18px 0 42px rgba(255, 255, 255, 0.018);
  }
#halodoom-page-frame .game-info-header {
    display: flex;
    flex-direction: column;

    align-items: flex-start;

    gap:
      clamp(5px, 0.65vh, 10px);

    min-width: 0;
  }
#halodoom-page-frame .game-info-logo {
    display: block;

    width:
      min(
        68%,
        440px
      );

    max-height:
      clamp(70px, 12vh, 132px);

    object-fit: contain;
    object-position: left center;
  }
#halodoom-page-frame .game-info-kicker {
    margin: 0;

    color:
      rgba(
        var(--page-accent-rgb),
        0.93
      );

    font-size:
      clamp(9px, 0.72vw, 13px);

    font-weight: 700;

    letter-spacing:
      0.34em;
  }
#halodoom-page-frame .game-info-blurb {
    max-width: 94%;

    margin: 0;

    color:
      rgba(246, 249, 251, 0.92);

    font-size:
      clamp(12px, 0.86vw, 16px);

    line-height: 1.48;
  }
#halodoom-page-frame .game-info-features {
    min-height: 0;

    display: grid;

    grid-template-columns:
      repeat(2, minmax(0, 1fr));

    align-content: center;

    gap:
      clamp(8px, 0.75vw, 14px);
  }
#halodoom-page-frame .game-info-feature {
    min-width: 0;

    display: grid;

    grid-template-columns:
      clamp(34px, 2.7vw, 48px)
      minmax(0, 1fr);

    align-items: center;

    gap:
      clamp(8px, 0.7vw, 13px);

    padding:
      clamp(7px, 0.65vw, 11px);

    border:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.20
      );

    background:
      linear-gradient(
        115deg,
        rgba(
          var(--page-accent-rgb),
          0.075
        ),
        rgba(16, 22, 26, 0.18)
      );

    clip-path:
      polygon(
        8px 0,
        100% 0,
        100% calc(100% - 8px),
        calc(100% - 8px) 100%,
        0 100%,
        0 8px
      );
  }
#halodoom-page-frame .game-info-feature-icon {
    display: grid;
    place-items: center;

    aspect-ratio: 1;

    color:
      rgba(
        var(--page-accent-rgb),
        0.96
      );

    border:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.45
      );

    font-size:
      clamp(18px, 1.5vw, 26px);

    line-height: 1;

    clip-path:
      polygon(
        25% 0,
        75% 0,
        100% 25%,
        100% 75%,
        75% 100%,
        25% 100%,
        0 75%,
        0 25%
      );
  }
#halodoom-page-frame .game-info-feature-copy {
    min-width: 0;

    display: flex;
    flex-direction: column;

    gap: 3px;
  }
#halodoom-page-frame .game-info-feature-copy strong {
    color:
      rgba(
        var(--page-accent-rgb),
        0.96
      );

    font-size:
      clamp(8px, 0.61vw, 11px);

    letter-spacing:
      0.13em;
  }
#halodoom-page-frame .game-info-feature-copy small {
    overflow: hidden;

    color: rgba(232, 239, 243, 0.70);

    font-size:
      clamp(8px, 0.58vw, 10px);

    line-height: 1.25;

    white-space: nowrap;

    text-overflow: ellipsis;
  }
#halodoom-page-frame .game-info-facts {
    display: grid;

    grid-template-columns:
      repeat(3, minmax(0, 1fr));

    border-top:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.28
      );

    border-bottom:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.18
      );
  }
#halodoom-page-frame .game-info-fact {
    position: relative;

    min-width: 0;

    display: flex;
    flex-direction: column;

    gap: 4px;

    padding:
      clamp(9px, 0.75vw, 13px)
      clamp(8px, 0.8vw, 14px);
  }
#halodoom-page-frame
  .game-info-fact +
  .game-info-fact::before {
    content: "";

    position: absolute;

    top: 22%;
    bottom: 22%;
    left: 0;

    width: 1px;

    background:
      rgba(
        var(--page-accent-rgb),
        0.24
      );
  }
#halodoom-page-frame .game-info-fact span {
    color:
      rgba(
        var(--page-accent-rgb),
        0.78
      );

    font-size:
      clamp(8px, 0.58vw, 10px);

    letter-spacing:
      0.18em;
  }
#halodoom-page-frame .game-info-fact strong {
    overflow: hidden;

    color: rgba(244, 248, 250, 0.92);

    font-size:
      clamp(10px, 0.72vw, 13px);

    font-weight: 500;

    white-space: nowrap;

    text-overflow: ellipsis;
  }
#halodoom-page-frame .game-info-actions {
    display: grid;

    grid-template-columns:
      minmax(0, 1.35fr)
      minmax(0, 0.9fr);

    gap:
      clamp(10px, 0.85vw, 16px);
  }
#halodoom-page-frame .game-info-action {
    min-width: 0;

    display: flex;

    align-items: center;
    justify-content: space-between;

    gap: 12px;

    padding:
      clamp(10px, 0.8vw, 14px)
      clamp(14px, 1vw, 18px);

    border:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.48
      );

    background:
      rgba(15, 21, 25, 0.42);

    color: rgba(248, 251, 252, 0.96);

    font: inherit;

    font-size:
      clamp(9px, 0.68vw, 12px);

    font-weight: 700;

    letter-spacing:
      0.11em;

    cursor: default;

    clip-path:
      polygon(
        10px 0,
        100% 0,
        100% calc(100% - 10px),
        calc(100% - 10px) 100%,
        0 100%,
        0 10px
      );
  }
#halodoom-page-frame .game-info-action--primary {
    background:
      linear-gradient(
        110deg,
        rgba(
          var(--page-accent-rgb),
          0.10
        ),
        rgba(
          var(--page-accent-rgb),
          0.10
        )
      );

    box-shadow:
      inset 0 0 0 1px
      rgba(
        var(--page-accent-rgb),
        0.10
      );
  }
}

@media (min-width: 1401px){
#halodoom-page-frame .game-info-surface {
    grid-template-rows:
      auto
      auto
      minmax(0, 0.78fr)
      auto
      auto;

    gap:
      clamp(12px, 1.35vh, 20px);

    padding-top:
      clamp(26px, 2.55vw, 44px);
  }
#halodoom-page-frame .game-info-header {
    gap:
      clamp(7px, 0.8vh, 12px);
  }
#halodoom-page-frame .game-info-logo {
    width:
      min(
        70%,
        460px
      );
  }
#halodoom-page-frame .game-info-blurb {
    max-width: 91%;

    line-height: 1.54;
  }
#halodoom-page-frame .game-info-background {
    inset: 0.5% -0.5% 1.5% 9%;

    opacity: 0.47;
  }
#halodoom-page-frame .game-info-background-image {
    object-position: 60% 42%;

    filter:
      saturate(0.94)
      contrast(0.96)
      brightness(0.78);

    -webkit-mask-image:
      linear-gradient(
        102deg,
        transparent 0%,
        rgba(0, 0, 0, 0.06) 13%,
        rgba(0, 0, 0, 0.36) 35%,
        rgba(0, 0, 0, 0.82) 66%,
        rgba(0, 0, 0, 0.96) 100%
      );

    mask-image:
      linear-gradient(
        102deg,
        transparent 0%,
        rgba(0, 0, 0, 0.06) 13%,
        rgba(0, 0, 0, 0.36) 35%,
        rgba(0, 0, 0, 0.82) 66%,
        rgba(0, 0, 0, 0.96) 100%
      );
  }
#halodoom-page-frame .game-info-features {
    gap:
      clamp(6px, 0.55vw, 10px)
      clamp(14px, 1.05vw, 20px);

    padding:
      clamp(5px, 0.4vw, 8px)
      0;

    border-top:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.22
      );

    border-bottom:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.14
      );
  }
#halodoom-page-frame .game-info-feature {
    grid-template-columns:
      clamp(30px, 2.35vw, 42px)
      minmax(0, 1fr);

    gap:
      clamp(8px, 0.65vw, 12px);

    padding:
      clamp(7px, 0.5vw, 9px)
      clamp(5px, 0.4vw, 8px);

    border: 0;

    background: transparent;

    clip-path: none;
  }
#halodoom-page-frame .game-info-feature-icon {
    border-color:
      rgba(
        var(--page-accent-rgb),
        0.34
      );

    background:
      rgba(
        var(--page-accent-rgb),
        0.045
      );

    font-size:
      clamp(16px, 1.25vw, 22px);
  }
#halodoom-page-frame .game-info-feature-copy strong {
    font-size:
      clamp(8px, 0.59vw, 10.5px);

    letter-spacing:
      0.14em;
  }
#halodoom-page-frame .game-info-feature-copy small {
    font-size:
      clamp(7.5px, 0.54vw, 9.5px);

    color:
      rgba(232, 239, 243, 0.64);
  }
#halodoom-page-frame .game-info-facts {
    background:
      linear-gradient(
        90deg,
        rgba(
          var(--page-accent-rgb),
          0.035
        ),
        rgba(12, 18, 22, 0.08)
      );
  }
#halodoom-page-frame .game-info-fact {
    padding-top:
      clamp(8px, 0.65vw, 11px);

    padding-bottom:
      clamp(8px, 0.65vw, 11px);
  }
#halodoom-page-frame .game-info-action--primary {
    border-color:
      rgba(
        var(--page-accent-rgb),
        0.62
      );

    background:
      linear-gradient(
        110deg,
        rgba(
          var(--page-accent-rgb),
          0.34
        ),
        rgba(
          var(--page-accent-rgb),
          0.12
        )
      );
  }
#halodoom-page-frame .game-info-action--secondary {
    border-color:
      rgba(
        var(--page-accent-rgb),
        0.28
      );

    color:
      rgba(238, 244, 247, 0.84);
  }
}

@media (min-width: 1401px){
#halodoom-page-frame .game-info-background {
    
    inset:
      -1.2%
      -0.8%
      8%
      31%;

    opacity: 0.54;

    overflow: hidden;

    border:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.16
      );

    background:
      rgba(
        var(--page-accent-rgb),
        0.028
      );

    clip-path:
      polygon(
        7% 0,
        100% 0,
        100% 86%,
        93% 100%,
        0 100%,
        0 10%
      );

    box-shadow:
      inset 0 0 0 1px rgba(255,255,255,0.018);
  }
#halodoom-page-frame .game-info-background::after {
    content: "";

    position: absolute;
    inset: 0;

    pointer-events: none;

    background:
      linear-gradient(
        90deg,
        rgba(17, 27, 32, 0.92) 0%,
        rgba(17, 27, 32, 0.60) 27%,
        rgba(17, 27, 32, 0.22) 58%,
        rgba(17, 27, 32, 0.08) 100%
      );
  }
#halodoom-page-frame .game-info-background-image {
    width: 112%;
    height: 112%;

    transform:
      translate(
        -4%,
        -5%
      );

    object-fit: cover;

    
    object-position: 69% 30%;

    filter:
      saturate(0.90)
      contrast(0.92)
      brightness(0.74);

    -webkit-mask-image: none;
    mask-image: none;
  }
#halodoom-page-frame .game-info-layer--rear {
    inset:
      -1.3%
      0.4%
      0.8%
      6.8%;

    transform:
      translate(
        2.2%,
        -1.2%
      );

    opacity: 0.64;

    border-color:
      rgba(
        var(--page-accent-rgb),
        0.15
      );
  }
#halodoom-page-frame .game-info-layer--mid {
    inset:
      1.4%
      2.3%
      2%
      1.2%;

    transform:
      translate(
        -0.5%,
        0.9%
      );

    opacity: 0.82;

    border-color:
      rgba(
        var(--page-accent-rgb),
        0.20
      );
  }
#halodoom-page-frame .game-info::after {
    content: "";

    position: absolute;

    z-index: 3;

    top: 18%;
    right: 0.35%;

    width: 2px;
    height: 28%;

    background:
      linear-gradient(
        to bottom,
        transparent,
        rgba(
          var(--page-accent-rgb),
          0.62
        ) 18%,
        rgba(
          var(--page-accent-rgb),
          0.28
        ) 76%,
        transparent
      );

    box-shadow:
      0 0 14px
      rgba(
        var(--page-accent-rgb),
        0.22
      );

    pointer-events: none;
  }
#halodoom-page-frame .game-info-surface {
    grid-template-rows:
      auto
      auto
      minmax(0, 0.70fr)
      auto
      auto;

    gap:
      clamp(11px, 1.22vh, 18px);

    padding:
      clamp(26px, 2.35vw, 42px)
      clamp(24px, 2.2vw, 40px)
      clamp(22px, 1.9vw, 34px)
      clamp(28px, 2.55vw, 48px);

    background:
      linear-gradient(
        102deg,
        rgba(18, 27, 32, 0.80) 0%,
        rgba(20, 31, 36, 0.67) 43%,
        rgba(18, 30, 35, 0.47) 72%,
        rgba(18, 30, 35, 0.34) 100%
      );

    border-color:
      rgba(
        var(--page-accent-rgb),
        0.30
      );

    box-shadow:
      inset 0 0 0 1px rgba(255,255,255,0.032),
      inset 28px 0 56px rgba(255,255,255,0.012),
      inset -1px 0 0
      rgba(
        var(--page-accent-rgb),
        0.10
      );
  }
#halodoom-page-frame .game-info-logo {
    width:
      min(
        67%,
        450px
      );

    margin-left:
      -0.6%;
  }
#halodoom-page-frame .game-info-kicker {
    letter-spacing:
      0.31em;

    opacity: 0.94;
  }
#halodoom-page-frame .game-info-blurb {
    max-width: 89%;

    font-size:
      clamp(12px, 0.84vw, 15px);

    line-height: 1.52;
  }
#halodoom-page-frame .game-info-features {
    grid-template-columns:
      repeat(2, minmax(0, 1fr));

    column-gap:
      clamp(18px, 1.3vw, 24px);

    row-gap:
      clamp(7px, 0.6vw, 11px);

    padding:
      clamp(7px, 0.55vw, 10px)
      0;

    border-top-color:
      rgba(
        var(--page-accent-rgb),
        0.20
      );

    border-bottom-color:
      rgba(
        var(--page-accent-rgb),
        0.13
      );
  }
#halodoom-page-frame .game-info-feature {
    position: relative;

    padding:
      clamp(6px, 0.48vw, 9px)
      clamp(4px, 0.3vw, 6px);
  }
#halodoom-page-frame .game-info-feature::after {
    content: "";

    position: absolute;

    right: 0;
    bottom: 0;

    width:
      clamp(18px, 1.8vw, 30px);

    height: 1px;

    background:
      rgba(
        var(--page-accent-rgb),
        0.13
      );
  }
#halodoom-page-frame .game-info-feature-icon {
    background:
      linear-gradient(
        135deg,
        rgba(
          var(--page-accent-rgb),
          0.08
        ),
        rgba(12, 18, 22, 0.05)
      );

    box-shadow:
      inset 0 0 0 1px
      rgba(
        var(--page-accent-rgb),
        0.035
      );
  }
#halodoom-page-frame .game-info-feature-copy strong {
    line-height: 1.15;
  }
#halodoom-page-frame .game-info-feature-copy small {
    line-height: 1.22;
  }
#halodoom-page-frame .game-info-facts {
    border-top-color:
      rgba(
        var(--page-accent-rgb),
        0.24
      );

    border-bottom-color:
      rgba(
        var(--page-accent-rgb),
        0.16
      );

    background:
      linear-gradient(
        90deg,
        rgba(
          var(--page-accent-rgb),
          0.028
        ),
        rgba(12, 18, 22, 0.055)
      );
  }
#halodoom-page-frame .game-info-fact span {
    font-size:
      clamp(7.5px, 0.54vw, 9.5px);

    letter-spacing:
      0.19em;
  }
#halodoom-page-frame .game-info-fact strong {
    font-size:
      clamp(9.5px, 0.68vw, 12.5px);
  }
#halodoom-page-frame .game-info-actions {
    grid-template-columns:
      minmax(0, 1.42fr)
      minmax(0, 0.88fr);

    gap:
      clamp(11px, 0.9vw, 17px);
  }
#halodoom-page-frame .game-info-action {
    padding-top:
      clamp(10px, 0.72vw, 13px);

    padding-bottom:
      clamp(10px, 0.72vw, 13px);
  }
#halodoom-page-frame .game-info-action--primary {
    box-shadow:
      inset 0 0 0 1px
      rgba(
        var(--page-accent-rgb),
        0.12
      ),
      0 0 18px
      rgba(
        var(--page-accent-rgb),
        0.055
      );
  }
}

@media (min-width: 1401px){
#halodoom-page-frame .game-info-background,
  #halodoom-page-frame .game-info-layer--rear,
  #halodoom-page-frame .game-info-layer--mid,
  #halodoom-page-frame .game-info::after {
    display: none !important;
  }
#halodoom-page-frame .game-info-surface {
    border: 0;

    background: transparent;

    backdrop-filter: none;
    -webkit-backdrop-filter: none;

    clip-path: none;

    box-shadow: none;
  }
}

@media (min-width: 1401px){
#halodoom-page-frame .desktop-secondary-panel {
    --etherian-glass-angle:
      calc(
        var(--button-shear-angle) * -1
      );

    
    --etherian-stack-cut-rise:
      clamp(42px, 4.1vw, 68px);

    --etherian-stack-cut-run:
      calc(
        var(--etherian-stack-cut-rise)
        *
        tan(
          var(--etherian-glass-angle)
        )
      );
  }
#halodoom-page-frame .etherian-popout-layer-stack {
    position: absolute;
    inset: 0;

    z-index: 1;

    overflow: hidden;

    
    clip-path:
      polygon(
        0 0,
        calc(
          100% -
          var(--etherian-stack-cut-run)
        ) 0,
        100%
        var(--etherian-stack-cut-rise),
        100%
        calc(
          100% -
          var(--etherian-stack-cut-rise)
        ),
        calc(
          100% -
          var(--etherian-stack-cut-run)
        ) 100%,
        0 100%
      );

    pointer-events: none;

    opacity: 0;

    transition:
      opacity 220ms ease;

    
  }
#halodoom-page-frame.is-secondary-open
  .etherian-popout-layer-stack {
    opacity: 1;

    transition-delay:
      calc(
        var(--secondary-panel-duration) * 0.74
      );
  }
#halodoom-page-frame .etherian-popout-glass-layer {
    position: absolute;

    
    --layer-cut-rise:
      clamp(44px, 4.8vw, 78px);

    --layer-cut-run:
      calc(
        var(--layer-cut-rise)
        *
        tan(
          var(--etherian-glass-angle)
        )
      );

    border:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.16
      );

    background:
      linear-gradient(
        115deg,
        rgba(255,255,255,0.022),
        rgba(
          var(--page-accent-rgb),
          0.034
        ) 45%,
        rgba(20,28,34,0.020)
      );

    box-shadow:
      inset 0 0 0 1px
      rgba(255,255,255,0.018);

    backdrop-filter:
      blur(2px)
      saturate(108%);

    -webkit-backdrop-filter:
      blur(2px)
      saturate(108%);
  }
#halodoom-page-frame .etherian-popout-glass-layer--1 {
    z-index: 1;

    inset:
      2.5%
      1.7%
      5.5%
      0;

    --layer-cut-rise:
      clamp(54px, 5.4vw, 86px);

    clip-path:
      polygon(
        0 0,
        calc(
          100% -
          var(--layer-cut-run)
        ) 0,
        100%
        var(--layer-cut-rise),
        100%
        calc(
          100% -
          var(--layer-cut-rise)
        ),
        calc(
          100% -
          var(--layer-cut-run)
        ) 100%,
        0 100%
      );

    opacity: 0.42;

    border-color:
      rgba(
        220, 230, 242,
        0.18
      );
  }
#halodoom-page-frame .etherian-popout-glass-layer--2 {
    z-index: 2;

    inset:
      7.5%
      6.2%
      8.5%
      0;

    --layer-cut-rise:
      clamp(62px, 6.1vw, 96px);

    clip-path:
      polygon(
        0 0,
        calc(
          100% -
          var(--layer-cut-run)
        ) 0,
        100%
        var(--layer-cut-rise),
        100%
        calc(
          100% -
          var(--layer-cut-rise) * 0.42
        ),
        calc(
          100% -
          var(--layer-cut-run) * 0.42
        ) 100%,
        0 100%
      );

    opacity: 0.50;

    border-color:
      rgba(
        var(--page-accent-rgb),
        0.18
      );

    background:
      linear-gradient(
        118deg,
        rgba(
          var(--page-accent-rgb),
          0.022
        ),
        rgba(255,255,255,0.018)
      );
  }
#halodoom-page-frame .etherian-popout-glass-layer--3 {
    z-index: 3;

    inset:
      11.5%
      12.2%
      13.5%
      0;

    --layer-cut-rise:
      clamp(70px, 7vw, 110px);

    clip-path:
      polygon(
        0 0,
        calc(
          100% -
          var(--layer-cut-run)
        ) 0,
        100%
        var(--layer-cut-rise),
        100% 100%,
        0 100%
      );

    opacity: 0.58;

    border-color:
      rgba(
        var(--page-accent-rgb),
        0.22
      );

    background:
      linear-gradient(
        110deg,
        rgba(255,255,255,0.016),
        rgba(
          var(--page-accent-rgb),
          0.045
        )
      );
  }
#halodoom-page-frame .etherian-popout-glass-layer--4 {
    z-index: 4;

    left: 0;
    right: 13.6%;
    top: 49%;
    bottom: 0;

    --layer-cut-rise:
      clamp(46px, 4.8vw, 76px);

    clip-path:
      polygon(
        0 0,
        calc(
          100% -
          var(--layer-cut-run)
        ) 0,
        100%
        var(--layer-cut-rise),
        100% 100%,
        0 100%
      );

    opacity: 0.66;

    border-color:
      rgba(
        var(--page-accent-rgb),
        0.24
      );

    background:
      linear-gradient(
        108deg,
        rgba(
          var(--page-accent-rgb),
          0.040
        ),
        rgba(255,255,255,0.018)
      );
  }
#halodoom-page-frame .desktop-secondary-panel-glass {
    z-index: 0;
  }
#halodoom-page-frame .desktop-secondary-panel-content {
    z-index: 2;
  }
#halodoom-page-frame .game-info {
    z-index: 2;
  }
}

@media (min-width: 1401px){
#halodoom-page-frame .etherian-popout-glass-layer {
    border-color:
      rgba(
        var(--page-accent-rgb),
        0.24
      );

    background:
      linear-gradient(
        115deg,
        rgba(255,255,255,0.055),
        rgba(
          var(--page-accent-rgb),
          0.085
        ) 44%,
        rgba(26,36,42,0.055)
      );

    box-shadow:
      inset 0 0 0 1px
      rgba(255,255,255,0.032);

    backdrop-filter:
      blur(4px)
      saturate(112%);

    -webkit-backdrop-filter:
      blur(4px)
      saturate(112%);
  }
#halodoom-page-frame .etherian-popout-glass-layer--1 {
    opacity: 0.62;

    border-color:
      rgba(
        220, 230, 242,
        0.26
      );

    background:
      linear-gradient(
        116deg,
        rgba(255,255,255,0.060),
        rgba(177,202,216,0.065) 52%,
        rgba(28,36,42,0.040)
      );
  }
#halodoom-page-frame .etherian-popout-glass-layer--2 {
    opacity: 0.70;

    border-color:
      rgba(
        var(--page-accent-rgb),
        0.28
      );

    background:
      linear-gradient(
        118deg,
        rgba(
          var(--page-accent-rgb),
          0.070
        ),
        rgba(255,255,255,0.050)
      );
  }
#halodoom-page-frame .etherian-popout-glass-layer--3 {
    opacity: 0.76;

    border-color:
      rgba(
        var(--page-accent-rgb),
        0.32
      );

    background:
      linear-gradient(
        110deg,
        rgba(255,255,255,0.045),
        rgba(
          var(--page-accent-rgb),
          0.095
        )
      );
  }
#halodoom-page-frame .etherian-popout-glass-layer--4 {
    opacity: 0.82;

    border-color:
      rgba(
        var(--page-accent-rgb),
        0.35
      );

    background:
      linear-gradient(
        108deg,
        rgba(
          var(--page-accent-rgb),
          0.105
        ),
        rgba(255,255,255,0.048)
      );
  }
}

@media (min-width: 1401px){
#halodoom-page-frame .etherian-popout-glass-layer--1 {
    opacity: 0.50;
  }
#halodoom-page-frame .etherian-popout-glass-layer--2 {
    opacity: 0.58;
  }
#halodoom-page-frame .etherian-popout-glass-layer--3 {
    opacity: 0.64;
  }
#halodoom-page-frame .etherian-popout-glass-layer--4 {
    right: 20%;
    opacity: 0.70;
  }
}

@media (min-width: 1401px){
#halodoom-page-frame .etherian-popout-glass-layer {
    border-color: transparent !important;
    border-width: 0 !important;
  }
#halodoom-page-frame .etherian-popout-glass-layer {
    box-shadow:
      inset 0 0 0 1px
      rgba(255, 255, 255, 0.018);
  }
}

@media (min-width: 1401px){
#halodoom-page-frame .etherian-popout-glass-layer--3 {
    clip-path:
      polygon(
        0 0,

        calc(
          100% -
          var(--layer-cut-run)
        ) 0,

        100%
        var(--layer-cut-rise),

        100%
        calc(
          100% -
          var(--layer-cut-rise) * 0.42
        ),

        calc(
          100% -
          var(--layer-cut-run) * 0.42
        ) 100%,

        0 100%
      );
  }
#halodoom-page-frame .game-info-features {
    transition:
      opacity 120ms ease;
  }
#halodoom-page-frame
  .game-info-features.is-crowded {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
  }
}

@media (min-width: 1401px){
#halodoom-page-frame .game-info-surface {
    align-content: stretch;

    grid-template-rows:
      auto
      auto
      minmax(0, 1fr)
      auto
      auto;
  }
#halodoom-page-frame .game-info-header {
    align-self: start;
  }
#halodoom-page-frame .game-info-logo {
    width:
      clamp(
        250px,
        30vw,
        430px
      );

    max-width: 62%;

    max-height:
      clamp(
        76px,
        11vh,
        126px
      );

    margin-left: 0;
  }
#halodoom-page-frame .game-info-blurb {
    width: min(100%, 76ch);
    max-width: 76ch;
  }
#halodoom-page-frame.is-info-compact
  .game-info-surface {
    gap:
      clamp(8px, 0.9vh, 13px);

    padding:
      clamp(20px, 1.75vw, 30px)
      clamp(20px, 1.7vw, 30px)
      clamp(18px, 1.55vw, 27px)
      clamp(22px, 1.9vw, 34px);
  }
#halodoom-page-frame.is-info-compact
  .game-info-header {
    gap:
      clamp(4px, 0.5vh, 7px);
  }
#halodoom-page-frame.is-info-compact
  .game-info-logo {
    width:
      clamp(
        220px,
        25vw,
        350px
      );

    max-width: 58%;

    max-height:
      clamp(
        66px,
        9.5vh,
        104px
      );
  }
#halodoom-page-frame.is-info-compact
  .game-info-kicker {
    font-size:
      clamp(8px, 0.62vw, 11px);

    letter-spacing: 0.27em;
  }
#halodoom-page-frame.is-info-compact
  .game-info-blurb {
    width: min(100%, 70ch);
    max-width: 70ch;

    font-size:
      clamp(11px, 0.76vw, 13.5px);

    line-height: 1.43;
  }
#halodoom-page-frame.is-info-compact
  .game-info-features {
    column-gap:
      clamp(12px, 0.9vw, 18px);

    row-gap:
      clamp(5px, 0.42vw, 8px);

    padding:
      clamp(4px, 0.36vw, 7px)
      0;
  }
#halodoom-page-frame.is-info-compact
  .game-info-feature {
    grid-template-columns:
      clamp(27px, 2.15vw, 36px)
      minmax(0, 1fr);

    gap:
      clamp(6px, 0.5vw, 9px);

    padding:
      clamp(4px, 0.34vw, 6px)
      clamp(3px, 0.26vw, 5px);
  }
#halodoom-page-frame.is-info-compact
  .game-info-feature-icon {
    font-size:
      clamp(14px, 1.12vw, 20px);
  }
#halodoom-page-frame.is-info-compact
  .game-info-feature-copy strong {
    font-size:
      clamp(7.5px, 0.53vw, 9.5px);

    letter-spacing: 0.12em;
  }
#halodoom-page-frame.is-info-compact
  .game-info-feature-copy small {
    font-size:
      clamp(7px, 0.49vw, 8.8px);
  }
#halodoom-page-frame.is-info-compact
  .game-info-fact {
    gap: 2px;

    padding:
      clamp(6px, 0.48vw, 8px)
      clamp(6px, 0.58vw, 10px);
  }
#halodoom-page-frame.is-info-compact
  .game-info-actions {
    gap:
      clamp(8px, 0.62vw, 11px);
  }
#halodoom-page-frame.is-info-compact
  .game-info-action {
    padding:
      clamp(8px, 0.6vw, 10px)
      clamp(11px, 0.8vw, 14px);
  }
#halodoom-page-frame.is-info-tight
  .game-info-surface {
    gap:
      clamp(6px, 0.68vh, 9px);

    padding:
      clamp(16px, 1.35vw, 22px)
      clamp(17px, 1.4vw, 24px)
      clamp(15px, 1.25vw, 21px)
      clamp(18px, 1.55vw, 27px);
  }
#halodoom-page-frame.is-info-tight
  .game-info-logo {
    width:
      clamp(
        190px,
        21vw,
        290px
      );

    max-width: 54%;

    max-height:
      clamp(
        58px,
        8vh,
        86px
      );
  }
#halodoom-page-frame.is-info-tight
  .game-info-kicker {
    font-size:
      clamp(7.5px, 0.56vw, 9.5px);

    letter-spacing: 0.23em;
  }
#halodoom-page-frame.is-info-tight
  .game-info-blurb {
    width: min(100%, 64ch);
    max-width: 64ch;

    font-size:
      clamp(10.5px, 0.7vw, 12.5px);

    line-height: 1.38;
  }
#halodoom-page-frame.is-info-tight
  .game-info-features {
    column-gap:
      clamp(9px, 0.65vw, 13px);

    row-gap: 4px;

    padding: 3px 0;
  }
#halodoom-page-frame.is-info-tight
  .game-info-feature {
    grid-template-columns:
      clamp(24px, 1.85vw, 31px)
      minmax(0, 1fr);

    gap: 5px;

    padding: 3px 2px;
  }
#halodoom-page-frame.is-info-tight
  .game-info-feature-icon {
    font-size:
      clamp(12px, 0.92vw, 17px);
  }
#halodoom-page-frame.is-info-tight
  .game-info-feature-copy strong {
    font-size:
      clamp(7px, 0.48vw, 8.5px);

    letter-spacing: 0.10em;
  }
#halodoom-page-frame.is-info-tight
  .game-info-feature-copy small {
    font-size:
      clamp(6.7px, 0.45vw, 8px);
  }
#halodoom-page-frame.is-info-tight
  .game-info-fact {
    padding:
      5px
      clamp(5px, 0.46vw, 8px);
  }
#halodoom-page-frame.is-info-tight
  .game-info-fact span {
    font-size:
      clamp(7px, 0.48vw, 8.5px);

    letter-spacing: 0.15em;
  }
#halodoom-page-frame.is-info-tight
  .game-info-fact strong {
    font-size:
      clamp(9px, 0.6vw, 11px);
  }
#halodoom-page-frame.is-info-tight
  .game-info-action {
    padding:
      7px
      clamp(9px, 0.68vw, 12px);

    font-size:
      clamp(8px, 0.58vw, 10px);

    letter-spacing: 0.09em;
  }
#halodoom-page-frame
  .game-info-features.is-crowded {
    transition:
      opacity 130ms ease;

    opacity: 0;
    visibility: hidden;
    pointer-events: none;
  }
}

@media (min-width: 1401px){
#halodoom-page-frame .game-info-surface,
  #halodoom-page-frame .game-info-header,
  #halodoom-page-frame .game-info-logo,
  #halodoom-page-frame .game-info-kicker,
  #halodoom-page-frame .game-info-blurb,
  #halodoom-page-frame .game-info-features,
  #halodoom-page-frame .game-info-feature,
  #halodoom-page-frame .game-info-feature-icon,
  #halodoom-page-frame .game-info-feature-copy strong,
  #halodoom-page-frame .game-info-feature-copy small,
  #halodoom-page-frame .game-info-fact,
  #halodoom-page-frame .game-info-fact span,
  #halodoom-page-frame .game-info-fact strong,
  #halodoom-page-frame .game-info-actions,
  #halodoom-page-frame .game-info-action {
    transition:
      width 210ms ease,
      max-width 210ms ease,
      max-height 210ms ease,
      padding 210ms ease,
      gap 210ms ease,
      font-size 210ms ease,
      line-height 210ms ease,
      letter-spacing 210ms ease,
      opacity 180ms ease,
      transform 180ms ease;
  }
#halodoom-page-frame .game-info-surface {
    padding:
      clamp(16px, 1.65cqw, 34px)
      clamp(17px, 1.55cqw, 32px)
      clamp(15px, 1.45cqw, 29px)
      clamp(18px, 1.75cqw, 36px);

    gap:
      clamp(7px, 0.78cqh, 14px);
  }
#halodoom-page-frame .game-info-logo {
    width:
      clamp(
        220px,
        27cqw,
        390px
      );

    max-width: 60%;

    max-height:
      clamp(
        66px,
        10cqh,
        112px
      );
  }
#halodoom-page-frame .game-info-kicker {
    font-size:
      clamp(8px, 0.60cqw, 11px);

    letter-spacing:
      clamp(0.22em, 0.26em, 0.28em);
  }
#halodoom-page-frame .game-info-blurb {
    width:
      min(
        100%,
        clamp(
          58ch,
          67cqw,
          76ch
        )
      );

    max-width: 76ch;

    font-size:
      clamp(10.8px, 0.70cqw, 13.5px);

    line-height:
      clamp(1.38, 1.42, 1.46);
  }
#halodoom-page-frame .game-info-features {
    column-gap:
      clamp(10px, 0.85cqw, 18px);

    row-gap:
      clamp(4px, 0.38cqw, 8px);

    padding:
      clamp(3px, 0.32cqw, 7px)
      0;
  }
#halodoom-page-frame .game-info-feature {
    grid-template-columns:
      clamp(25px, 2cqw, 36px)
      minmax(0, 1fr);

    gap:
      clamp(5px, 0.46cqw, 9px);

    padding:
      clamp(3px, 0.3cqw, 6px)
      clamp(2px, 0.24cqw, 5px);
  }
#halodoom-page-frame .game-info-feature-icon {
    font-size:
      clamp(13px, 1.02cqw, 20px);
  }
#halodoom-page-frame .game-info-feature-copy strong {
    font-size:
      clamp(7.3px, 0.50cqw, 9.5px);

    letter-spacing:
      clamp(0.10em, 0.115em, 0.12em);
  }
#halodoom-page-frame .game-info-feature-copy small {
    font-size:
      clamp(6.9px, 0.46cqw, 8.8px);
  }
#halodoom-page-frame .game-info-fact {
    padding:
      clamp(5px, 0.44cqw, 8px)
      clamp(5px, 0.54cqw, 10px);
  }
#halodoom-page-frame .game-info-action {
    padding:
      clamp(7px, 0.56cqw, 10px)
      clamp(9px, 0.74cqw, 14px);

    font-size:
      clamp(8px, 0.55cqw, 10px);
  }
#halodoom-page-frame.is-info-compact
  .game-info-logo {
    max-width: 57%;
  }
#halodoom-page-frame.is-info-compact
  .game-info-blurb {
    max-width: 70ch;
  }
#halodoom-page-frame.is-info-tight
  .game-info-features {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;

    transform:
      translateY(-4px);
  }
#halodoom-page-frame.is-info-tight
  .game-info-surface {
    grid-template-rows:
      auto
      auto
      minmax(0, 0.18fr)
      auto
      auto;
  }
#halodoom-page-frame
  .game-info-features.is-crowded {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;

    transform:
      translateY(-4px);
  }
}

@media (min-width: 1401px){
#halodoom-page-frame .game-info-logo,
  #halodoom-page-frame.is-info-compact .game-info-logo,
  #halodoom-page-frame.is-info-tight .game-info-logo {
    width:
      clamp(
        270px,
        29cqw,
        410px
      );

    max-width: 61%;

    max-height:
      clamp(
        78px,
        10.5cqh,
        116px
      );
  }
#halodoom-page-frame .game-info-kicker,
  #halodoom-page-frame.is-info-compact .game-info-kicker,
  #halodoom-page-frame.is-info-tight .game-info-kicker {
    font-size:
      clamp(
        9px,
        0.60cqw,
        11px
      );

    letter-spacing: 0.27em;
  }
#halodoom-page-frame .game-info-blurb,
  #halodoom-page-frame.is-info-compact .game-info-blurb,
  #halodoom-page-frame.is-info-tight .game-info-blurb {
    width:
      min(
        100%,
        clamp(
          62ch,
          68cqw,
          76ch
        )
      );

    max-width: 76ch;

    font-size:
      clamp(
        11.8px,
        0.72cqw,
        13.8px
      );

    line-height: 1.44;
  }
#halodoom-page-frame .game-info-feature,
  #halodoom-page-frame.is-info-compact .game-info-feature,
  #halodoom-page-frame.is-info-tight .game-info-feature {
    grid-template-columns:
      clamp(30px, 2.05cqw, 38px)
      minmax(0, 1fr);

    gap:
      clamp(6px, 0.46cqw, 9px);

    padding:
      clamp(4px, 0.32cqw, 7px)
      clamp(3px, 0.25cqw, 6px);
  }
#halodoom-page-frame .game-info-feature-icon,
  #halodoom-page-frame.is-info-compact .game-info-feature-icon,
  #halodoom-page-frame.is-info-tight .game-info-feature-icon {
    font-size:
      clamp(
        15px,
        1.02cqw,
        20px
      );
  }
#halodoom-page-frame .game-info-feature-copy strong,
  #halodoom-page-frame.is-info-compact .game-info-feature-copy strong,
  #halodoom-page-frame.is-info-tight .game-info-feature-copy strong {
    font-size:
      clamp(
        8px,
        0.51cqw,
        9.5px
      );
  }
#halodoom-page-frame .game-info-feature-copy small,
  #halodoom-page-frame.is-info-compact .game-info-feature-copy small,
  #halodoom-page-frame.is-info-tight .game-info-feature-copy small {
    font-size:
      clamp(
        7.5px,
        0.47cqw,
        8.8px
      );
  }
#halodoom-page-frame.is-info-tight .game-info-surface {
    grid-template-rows:
      auto
      auto
      minmax(0, 1fr)
      auto
      auto;
  }
#halodoom-page-frame.is-info-tight .game-info-features,
  #halodoom-page-frame .game-info-features.is-crowded {
    opacity: 0;

    
    visibility: visible;

    pointer-events: none;

    transform:
      translateY(-3px);
  }
#halodoom-page-frame .game-info-fact,
  #halodoom-page-frame.is-info-compact .game-info-fact,
  #halodoom-page-frame.is-info-tight .game-info-fact {
    padding:
      clamp(7px, 0.46cqw, 10px)
      clamp(7px, 0.55cqw, 11px);
  }
#halodoom-page-frame .game-info-fact span,
  #halodoom-page-frame.is-info-compact .game-info-fact span,
  #halodoom-page-frame.is-info-tight .game-info-fact span {
    font-size:
      clamp(
        8px,
        0.49cqw,
        9.5px
      );
  }
#halodoom-page-frame .game-info-fact strong,
  #halodoom-page-frame.is-info-compact .game-info-fact strong,
  #halodoom-page-frame.is-info-tight .game-info-fact strong {
    font-size:
      clamp(
        10px,
        0.62cqw,
        12px
      );
  }
#halodoom-page-frame .game-info-actions,
  #halodoom-page-frame.is-info-compact .game-info-actions,
  #halodoom-page-frame.is-info-tight .game-info-actions {
    grid-template-columns:
      minmax(0, 1.25fr)
      minmax(0, 0.95fr);

    gap:
      clamp(
        9px,
        0.65cqw,
        13px
      );
  }
#halodoom-page-frame .game-info-action,
  #halodoom-page-frame.is-info-compact .game-info-action,
  #halodoom-page-frame.is-info-tight .game-info-action {
    min-height:
      clamp(
        40px,
        4.7cqh,
        48px
      );

    padding:
      0
      clamp(
        12px,
        0.78cqw,
        16px
      );

    gap:
      clamp(
        8px,
        0.55cqw,
        12px
      );

    font-size:
      clamp(
        9.5px,
        0.57cqw,
        11px
      );

    letter-spacing: 0.10em;
  }
#halodoom-page-frame .game-info-surface,
  #halodoom-page-frame .game-info-header,
  #halodoom-page-frame .game-info-logo,
  #halodoom-page-frame .game-info-kicker,
  #halodoom-page-frame .game-info-blurb,
  #halodoom-page-frame .game-info-feature,
  #halodoom-page-frame .game-info-feature-icon,
  #halodoom-page-frame .game-info-feature-copy strong,
  #halodoom-page-frame .game-info-feature-copy small,
  #halodoom-page-frame .game-info-fact,
  #halodoom-page-frame .game-info-fact span,
  #halodoom-page-frame .game-info-fact strong,
  #halodoom-page-frame .game-info-actions,
  #halodoom-page-frame .game-info-action {
    transition: none;
  }
#halodoom-page-frame .game-info-features {
    transition:
      opacity 190ms ease,
      transform 190ms ease;
  }
}

@media (min-width: 1401px){
#halodoom-page-frame .game-info-surface {
    align-content: start;

    grid-template-rows:
      auto
      auto
      auto
      auto
      auto;

    row-gap:
      clamp(
        8px,
        0.72cqh,
        14px
      );
  }
#halodoom-page-frame .game-info-features {
    align-content: start;

    min-height: 0;

    max-height: 180px;

    margin-block:
      clamp(
        2px,
        0.22cqh,
        5px
      );

    overflow: hidden;

    transition:
      opacity 190ms ease,
      transform 190ms ease,
      max-height 220ms ease,
      margin 220ms ease;
  }
#halodoom-page-frame
  .game-info-features.is-crowded,
  #halodoom-page-frame
  .game-info-features.is-structure-hidden {
    opacity: 0;

    max-height: 0;

    margin-block: 0;

    transform:
      translateY(-3px);

    pointer-events: none;
  }
#halodoom-page-frame.is-info-tight
  .game-info-features {
    opacity: 1;

    max-height: 180px;

    margin-block:
      clamp(
        1px,
        0.15cqh,
        4px
      );

    transform: none;

    pointer-events: auto;
  }
#halodoom-page-frame .game-info-header {
    margin-bottom:
      clamp(
        1px,
        0.18cqh,
        4px
      );
  }
#halodoom-page-frame .game-info-blurb {
    margin-bottom:
      clamp(
        2px,
        0.25cqh,
        5px
      );
  }
#halodoom-page-frame .game-info-facts {
    margin-top:
      clamp(
        2px,
        0.22cqh,
        5px
      );
  }
#halodoom-page-frame .game-info-actions {
    margin-top:
      clamp(
        1px,
        0.16cqh,
        4px
      );
  }
}

@media (min-width: 1401px){
#halodoom-page-frame .game-info-surface {
    --feature-zone-height: 118px;

    display: grid;

    grid-template-rows:
      auto
      var(--feature-zone-height)
      auto;

    align-content: center;

    row-gap:
      clamp(
        11px,
        1.25cqh,
        20px
      );

    padding:
      clamp(22px, 3.2cqh, 40px)
      clamp(20px, 1.65cqw, 34px)
      clamp(20px, 2.9cqh, 36px)
      clamp(22px, 1.8cqw, 38px);

    transition:
      grid-template-rows 230ms
      cubic-bezier(0.2, 0.78, 0.24, 1),
      row-gap 180ms ease,
      padding 180ms ease;
  }
#halodoom-page-frame.is-info-compact .game-info-surface,
  #halodoom-page-frame.is-info-tight .game-info-surface {
    grid-template-rows:
      auto
      var(--feature-zone-height)
      auto;

    align-content: center;
  }
#halodoom-page-frame .game-info-top-zone,
  #halodoom-page-frame .game-info-bottom-zone {
    min-width: 0;

    display: grid;

    align-content: start;
  }
#halodoom-page-frame .game-info-top-zone {
    row-gap:
      clamp(
        7px,
        0.68cqh,
        11px
      );
  }
#halodoom-page-frame .game-info-bottom-zone {
    row-gap:
      clamp(
        7px,
        0.62cqh,
        11px
      );
  }
#halodoom-page-frame .game-info-header,
  #halodoom-page-frame .game-info-blurb,
  #halodoom-page-frame .game-info-facts,
  #halodoom-page-frame .game-info-actions {
    margin-top: 0;
    margin-bottom: 0;
  }
#halodoom-page-frame .game-info-logo,
  #halodoom-page-frame.is-info-compact .game-info-logo,
  #halodoom-page-frame.is-info-tight .game-info-logo {
    width:
      clamp(
        280px,
        28cqw,
        405px
      );

    max-width: 60%;

    max-height:
      clamp(
        80px,
        10.5cqh,
        116px
      );
  }
#halodoom-page-frame .game-info-blurb,
  #halodoom-page-frame.is-info-compact .game-info-blurb,
  #halodoom-page-frame.is-info-tight .game-info-blurb {
    width:
      min(
        100%,
        74ch
      );

    max-width: 74ch;

    font-size:
      clamp(
        11.8px,
        0.72cqw,
        13.8px
      );

    line-height: 1.44;
  }
#halodoom-page-frame .game-info-features,
  #halodoom-page-frame.is-info-tight .game-info-features,
  #halodoom-page-frame
  .game-info-features.is-crowded {
    min-height: 0;
    height: 100%;
    max-height: none;

    margin: 0;

    align-content: center;

    overflow: hidden;

    opacity: 1;
    visibility: visible;
    transform: none;

    transition:
      opacity 170ms ease;
  }
#halodoom-page-frame
  .game-info-surface.is-features-collapsed
  .game-info-features {
    opacity: 0;

    pointer-events: none;
  }
#halodoom-page-frame .game-info-fact,
  #halodoom-page-frame.is-info-compact .game-info-fact,
  #halodoom-page-frame.is-info-tight .game-info-fact {
    padding:
      clamp(7px, 0.48cqw, 10px)
      clamp(7px, 0.56cqw, 11px);
  }
#halodoom-page-frame .game-info-action,
  #halodoom-page-frame.is-info-compact .game-info-action,
  #halodoom-page-frame.is-info-tight .game-info-action {
    min-height:
      clamp(
        40px,
        4.7cqh,
        48px
      );

    padding:
      0
      clamp(
        12px,
        0.78cqw,
        16px
      );

    font-size:
      clamp(
        9.5px,
        0.57cqw,
        11px
      );
  }
}

@media (min-width: 1401px){
#halodoom-page-frame .game-info-logo {
    width:
      clamp(
        285px,
        30cqw,
        500px
      );

    max-width: 63%;

    max-height:
      clamp(
        82px,
        11.5cqh,
        142px
      );
  }
#halodoom-page-frame .game-info-kicker {
    font-size:
      clamp(
        9px,
        0.66cqw,
        13px
      );

    letter-spacing:
      clamp(
        0.25em,
        0.28em,
        0.30em
      );
  }
#halodoom-page-frame .game-info-blurb {
    width:
      min(
        100%,
        76ch
      );

    max-width: 76ch;

    font-size:
      clamp(
        12px,
        0.78cqw,
        16.5px
      );

    line-height: 1.46;
  }
#halodoom-page-frame .game-info-feature {
    grid-template-columns:
      clamp(
        32px,
        2.2cqw,
        46px
      )
      minmax(0, 1fr);

    gap:
      clamp(
        7px,
        0.52cqw,
        11px
      );

    padding:
      clamp(
        5px,
        0.36cqw,
        8px
      )
      clamp(
        4px,
        0.3cqw,
        7px
      );
  }
#halodoom-page-frame .game-info-feature-icon {
    font-size:
      clamp(
        16px,
        1.1cqw,
        23px
      );
  }
#halodoom-page-frame .game-info-feature-copy strong {
    font-size:
      clamp(
        8px,
        0.56cqw,
        10.5px
      );
  }
#halodoom-page-frame .game-info-feature-copy small {
    font-size:
      clamp(
        7.5px,
        0.50cqw,
        9.5px
      );
  }
#halodoom-page-frame .game-info-fact span {
    font-size:
      clamp(
        8px,
        0.54cqw,
        10px
      );
  }
#halodoom-page-frame .game-info-fact strong {
    font-size:
      clamp(
        10px,
        0.68cqw,
        13px
      );
  }
#halodoom-page-frame .game-info-action {
    min-height:
      clamp(
        41px,
        5cqh,
        54px
      );

    padding:
      0
      clamp(
        13px,
        0.86cqw,
        19px
      );

    font-size:
      clamp(
        9.5px,
        0.62cqw,
        12px
      );
  }
#halodoom-page-frame .game-info-surface {
    row-gap:
      clamp(
        12px,
        1.45cqh,
        24px
      );

    padding:
      clamp(
        24px,
        3.5cqh,
        46px
      )
      clamp(
        22px,
        1.85cqw,
        38px
      )
      clamp(
        22px,
        3.2cqh,
        42px
      )
      clamp(
        24px,
        2cqw,
        42px
      );
  }
#halodoom-page-frame .game-info-surface {
    transition:
      grid-template-rows 260ms
      cubic-bezier(0.2, 0.78, 0.24, 1),
      row-gap 180ms ease,
      padding 180ms ease;
  }
}

@media (min-width: 1401px){
#halodoom-page-frame .game-info-logo {
    width:
      clamp(
        285px,
        36cqw,
        540px
      );

    max-width: 66%;

    max-height:
      clamp(
        82px,
        13cqh,
        150px
      );
  }
#halodoom-page-frame .game-info-kicker {
    font-size:
      clamp(
        9px,
        0.78cqw,
        13.5px
      );
  }
#halodoom-page-frame .game-info-blurb {
    max-width: 78ch;

    font-size:
      clamp(
        12px,
        0.98cqw,
        17px
      );

    line-height: 1.46;
  }
#halodoom-page-frame .game-info-feature {
    grid-template-columns:
      clamp(
        32px,
        2.65cqw,
        50px
      )
      minmax(0, 1fr);

    gap:
      clamp(
        7px,
        0.66cqw,
        12px
      );

    padding:
      clamp(
        5px,
        0.46cqw,
        9px
      )
      clamp(
        4px,
        0.38cqw,
        8px
      );
  }
#halodoom-page-frame .game-info-feature-icon {
    font-size:
      clamp(
        16px,
        1.35cqw,
        25px
      );
  }
#halodoom-page-frame .game-info-feature-copy strong {
    font-size:
      clamp(
        8px,
        0.68cqw,
        11px
      );
  }
#halodoom-page-frame .game-info-feature-copy small {
    font-size:
      clamp(
        7.5px,
        0.60cqw,
        10px
      );
  }
#halodoom-page-frame .game-info-fact span {
    font-size:
      clamp(
        8px,
        0.63cqw,
        10.5px
      );
  }
#halodoom-page-frame .game-info-fact strong {
    font-size:
      clamp(
        10px,
        0.78cqw,
        13.5px
      );
  }
#halodoom-page-frame .game-info-action {
    min-height:
      clamp(
        41px,
        5.8cqh,
        58px
      );

    padding:
      0
      clamp(
        13px,
        1.02cqw,
        21px
      );

    font-size:
      clamp(
        9.5px,
        0.75cqw,
        12.5px
      );
  }
#halodoom-page-frame .game-info-surface {
    row-gap:
      clamp(
        12px,
        1.7cqh,
        28px
      );

    padding:
      clamp(
        24px,
        4.1cqh,
        52px
      )
      clamp(
        22px,
        2.15cqw,
        44px
      )
      clamp(
        22px,
        3.7cqh,
        48px
      )
      clamp(
        24px,
        2.35cqw,
        48px
      );
  }
#halodoom-page-frame .game-info-top-zone {
    row-gap:
      clamp(
        7px,
        0.9cqh,
        13px
      );
  }
#halodoom-page-frame .game-info-bottom-zone {
    row-gap:
      clamp(
        7px,
        0.78cqh,
        13px
      );
  }
}

@media (min-width: 1900px){
#halodoom-page-frame .game-info-logo {
    max-width: 68%;
  }
#halodoom-page-frame .game-info-blurb {
    max-width: 80ch;
  }
#halodoom-page-frame .game-info-surface {
    padding-left:
      clamp(
        28px,
        2.55cqw,
        54px
      );

    padding-right:
      clamp(
        26px,
        2.35cqw,
        50px
      );
  }
}

@media (min-width: 1401px){
#halodoom-page-frame .game-info-blurb {
    width: 64ch;
    max-width: none;

    font-size:
      clamp(
        12px,
        0.98cqw,
        17px
      );

    line-height: 1.46;
  }
#halodoom-page-frame .game-info-top-zone {
    min-width: 0;
  }
#halodoom-page-frame .game-info-blurb {
    max-inline-size:
      min(
        64ch,
        calc(100cqw - 48px)
      );
  }
}

@media (min-width: 1401px){
#halodoom-page-frame .game-info-blurb {
    width: 64ch;

    max-inline-size:
      min(
        64ch,
        calc(100cqw - 40px)
      );

    font-size:
      clamp(
        11.4px,
        0.84cqw,
        17px
      );

    line-height: 1.45;
  }
#halodoom-page-frame .game-info-surface {
    row-gap:
      clamp(
        9px,
        min(
          1.65cqh,
          1.05cqw
        ),
        26px
      );

    padding-top:
      clamp(
        20px,
        min(
          3.8cqh,
          2.4cqw
        ),
        48px
      );

    padding-bottom:
      clamp(
        18px,
        min(
          3.4cqh,
          2.15cqw
        ),
        44px
      );
  }
#halodoom-page-frame .game-info-top-zone {
    row-gap:
      clamp(
        6px,
        min(
          0.85cqh,
          0.62cqw
        ),
        12px
      );
  }
#halodoom-page-frame .game-info-bottom-zone {
    row-gap:
      clamp(
        6px,
        min(
          0.74cqh,
          0.56cqw
        ),
        12px
      );
  }
}

@media (min-width: 1401px){
#halodoom-page-frame .game-info-logo {
    width:
      clamp(
        320px,
        31cqw,
        420px
      );

    max-width: 64%;

    max-height:
      clamp(
        92px,
        11.5cqh,
        122px
      );
  }
#halodoom-page-frame .game-info-blurb {
    font-size:
      clamp(
        10.8px,
        0.82cqw,
        16.5px
      );
  }
#halodoom-page-frame .game-info-kicker {
    font-size:
      clamp(
        8.5px,
        0.60cqw,
        12.5px
      );
  }
#halodoom-page-frame .game-info-fact span {
    font-size:
      clamp(
        7.5px,
        0.50cqw,
        10px
      );
  }
#halodoom-page-frame .game-info-fact strong {
    font-size:
      clamp(
        9.5px,
        0.64cqw,
        13px
      );
  }
}

@media (min-width: 1401px){
#halodoom-page-frame .game-info-logo {
    width:
      clamp(
        320px,
        31cqw,
        420px
      );
  }
}

@container (min-width: 980px){
#halodoom-page-frame .game-info-logo {
    width:
      clamp(
        390px,
        38cqw,
        520px
      );

    max-width: 68%;

    max-height:
      clamp(
        108px,
        13cqh,
        148px
      );
  }
}

@container (min-width: 1180px){
#halodoom-page-frame .game-info-logo {
    width:
      clamp(
        430px,
        40cqw,
        560px
      );

    max-width: 70%;
  }
}

@media (min-width: 1900px){
#halodoom-page-frame .game-info-logo {
    width:
      clamp(
        410px,
        23vw,
        520px
      );

    max-width: 68%;

    max-height:
      clamp(
        112px,
        12.5vh,
        148px
      );
  }
}

@media (min-width: 2200px){
#halodoom-page-frame .game-info-logo {
    width:
      clamp(
        470px,
        24vw,
        560px
      );

    max-width: 70%;

    max-height: 156px;
  }
}

@media (min-width: 1401px){
#halodoom-page-frame .game-info-logo {
    width:
      clamp(
        320px,
        calc(27.2vw - 118px),
        483px
      );

    max-width: 68%;

    max-height:
      clamp(
        92px,
        calc(7.8vw - 18px),
        140px
      );

    transition:
      width 140ms ease-out,
      max-height 140ms ease-out;
  }
}

@media (min-width: 1401px){
#halodoom-page-frame
  .game-info-surface.is-features-collapsed
  .game-info-logo {
    width:
      clamp(
        340px,
        calc(29.5vw - 122px),
        520px
      );

    max-width: 70%;

    max-height:
      clamp(
        100px,
        calc(8.6vw - 18px),
        150px
      );
  }
}

@media (min-width: 1401px){
#halodoom-page-frame
  .etherian-popout-glass-layer--1 {
    overflow: hidden;
  }
#halodoom-page-frame
  .etherian-popout-layer-image {
    position: absolute;

    top: 0;
    right: 0;

    height: 100%;
    width: auto;

    max-width: none;

    display: block;

    object-fit: contain;
    object-position: top right;

    pointer-events: none;

    
    opacity: 0.40;

    filter:
      saturate(0.92)
      contrast(0.96)
      brightness(0.88);
  }
#halodoom-page-frame
  .etherian-popout-glass-layer--1::before {
    content: "";

    position: absolute;
    inset: 0;

    z-index: 1;

    background:
      linear-gradient(
        110deg,
        rgba(18, 30, 34, 0.22),
        rgba(
          var(--page-accent-rgb),
          0.055
        ) 48%,
        rgba(10, 18, 22, 0.10)
      );

    pointer-events: none;
  }
#halodoom-page-frame
  .etherian-popout-layer-image {
    z-index: 0;
  }
}

@media (min-width: 1401px){
#halodoom-page-frame
  .etherian-popout-layer-image {
    
    -webkit-mask-image:
      radial-gradient(
        ellipse 78% 72%
        at 100% 0%,
        rgba(0, 0, 0, 1) 0%,
        rgba(0, 0, 0, 0.96) 30%,
        rgba(0, 0, 0, 0.72) 48%,
        rgba(0, 0, 0, 0.30) 66%,
        rgba(0, 0, 0, 0) 84%
      );

    mask-image:
      radial-gradient(
        ellipse 78% 72%
        at 100% 0%,
        rgba(0, 0, 0, 1) 0%,
        rgba(0, 0, 0, 0.96) 30%,
        rgba(0, 0, 0, 0.72) 48%,
        rgba(0, 0, 0, 0.30) 66%,
        rgba(0, 0, 0, 0) 84%
      );

    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;

    -webkit-mask-size: 100% 100%;
    mask-size: 100% 100%;
  }
}

@media (min-width: 1401px){
#halodoom-page-frame
  .etherian-popout-layer-image {
    opacity: 0.30;
  }
}

#halodoom-page-frame.is-layout-transitioning.is-secondary-open
.etherian-popout-layer-stack {
  opacity: 0 !important;
  transition-delay: 0ms !important;
}

@media (min-width: 1401px){
#halodoom-page-frame
  .desktop-secondary-panel-content {
    transition:
      opacity 650ms ease !important;
  }
#halodoom-page-frame.is-secondary-open
  .desktop-secondary-panel-content {
    transition:
      opacity 650ms ease !important;

    
    transition-delay:
      calc(
        var(--secondary-panel-duration) * 0.78
      ) !important;
  }
}

#halodoom-page-frame.is-layout-transitioning
.etherian-popout-layer-image {
  opacity: 0 !important;

  transition:
    opacity 220ms ease !important;

  transition-delay: 0ms !important;

  pointer-events: none !important;
}

#halodoom-page-frame.is-layout-transitioning
.etherian-popout-layer-stack {
  position: absolute;
  inset: 0;

  overflow: hidden;

  pointer-events: none;
}

#halodoom-page-frame.is-layout-transitioning
.etherian-popout-layer-image {
  position: absolute !important;

  top: 0 !important;
  right: 0 !important;

  height: 100% !important;
  width: auto !important;

  max-width: none !important;
  max-height: none !important;

  display: block !important;

  object-fit: contain !important;
  object-position: top right !important;

  z-index: 0 !important;

  opacity: 0 !important;

  filter:
    saturate(0.92)
    contrast(0.96)
    brightness(0.88) !important;

  -webkit-mask-image:
    radial-gradient(
      ellipse 78% 72%
      at 100% 0%,
      rgba(0, 0, 0, 1) 0%,
      rgba(0, 0, 0, 0.96) 30%,
      rgba(0, 0, 0, 0.72) 48%,
      rgba(0, 0, 0, 0.30) 66%,
      rgba(0, 0, 0, 0) 84%
    ) !important;

  mask-image:
    radial-gradient(
      ellipse 78% 72%
      at 100% 0%,
      rgba(0, 0, 0, 1) 0%,
      rgba(0, 0, 0, 0.96) 30%,
      rgba(0, 0, 0, 0.72) 48%,
      rgba(0, 0, 0, 0.30) 66%,
      rgba(0, 0, 0, 0) 84%
    ) !important;

  -webkit-mask-repeat: no-repeat !important;
  mask-repeat: no-repeat !important;

  -webkit-mask-size: 100% 100% !important;
  mask-size: 100% 100% !important;

  transition:
    opacity 220ms ease !important;

  transition-delay: 0ms !important;

  pointer-events: none !important;
}

@media (max-width: 1400px){
#halodoom-page-frame:not(.is-layout-transitioning)
  .desktop-secondary-panel
  .etherian-popout-layer-image {
    display: none !important;
  }
}

#halodoom-page-frame .game-info-background,
#halodoom-page-frame .game-info-layer--rear,
#halodoom-page-frame .game-info-layer--mid,
#halodoom-page-frame .game-info::after {
  display: none !important;
}

#halodoom-page-frame .desktop-secondary-panel-glass,
#halodoom-page-frame .etherian-popout-glass-layer,
#halodoom-page-frame .game-info-surface {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

/* =========================================================
   Media viewer — preserve selected image aspect ratio
   ========================================================= */

/*
  The old viewer was always 16:9. Images were already object-fit: contain,
  but the FRAME itself remained landscape.

  This keeps the same maximum 16:9 footprint while allowing the viewer
  shell to shrink to the selected image's real aspect ratio:
    - portrait/square images become narrower, not taller
    - very wide images become shorter, not wider
    - videos/YouTube remain 16:9
    - thumbnail strip width stays unchanged
*/
.media-viewer {
  --media-viewer-aspect-number:
    1.7777777778;

  width:
    min(
      var(--media-composition-width),
      calc(
        var(--media-composition-width)
        * 0.5625
        * var(--media-viewer-aspect-number)
      )
    );

  max-width: 100%;

  aspect-ratio:
    var(--media-viewer-aspect-number);

  transition:
    width 220ms ease,
    aspect-ratio 220ms ease;
}


.media-viewer-image {
  object-fit: contain !important;
  object-position: center center;
}


/* =========================================================
   BROBOTS — first-pass info styling aliases
   Uses the same established game-info template for now.
   ========================================================= */

#brobots-page-frame .desktop-secondary-panel-content {
    top: 3.5%;
    right: 4.5%;
    bottom: 3.5%;

    left:
      calc(
        var(--secondary-panel-overlap) +
        3%
      );

    overflow: visible;
  }

/* =========================================================
   SHARED GAME-INFO REFERENCE IMPLEMENTATION
   =========================================================
   Brobots is the canonical game-info presentation. Its accumulated, proven
   component rules below are shared by every game-frame page. Older per-game
   Etherian/Halodoom rules may remain earlier in the file for now, but these
   later shared rules win the cascade and define the final presentation.
   ========================================================= */

.prototype-page-frame[data-game-frame-page] .game-info {
    position: relative;

    width: 100%;
    height: 100%;

    min-width: 0;
    min-height: 0;

    color: rgba(244, 248, 250, 0.96);

    isolation: isolate;
  }

.prototype-page-frame[data-game-frame-page] .game-info-background {
    position: absolute;
    inset: 2% 0 4% 14%;

    z-index: 0;

    overflow: hidden;

    opacity: 0.33;

    clip-path:
      polygon(
        7% 0,
        100% 0,
        100% 90%,
        93% 100%,
        0 100%,
        0 8%
      );

    pointer-events: none;
  }

.prototype-page-frame[data-game-frame-page] .game-info-background-image {
    width: 100%;
    height: 100%;

    object-fit: cover;
    object-position: 58% 44%;

    filter:
      saturate(0.88)
      contrast(0.94)
      brightness(0.72);

    -webkit-mask-image:
      linear-gradient(
        105deg,
        transparent 0%,
        rgba(0, 0, 0, 0.16) 18%,
        rgba(0, 0, 0, 0.70) 54%,
        rgba(0, 0, 0, 0.92) 100%
      );

    mask-image:
      linear-gradient(
        105deg,
        transparent 0%,
        rgba(0, 0, 0, 0.16) 18%,
        rgba(0, 0, 0, 0.70) 54%,
        rgba(0, 0, 0, 0.92) 100%
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-layer {
    position: absolute;

    z-index: 1;

    pointer-events: none;

    border:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.17
      );

    background:
      rgba(
        var(--page-accent-rgb),
        0.025
      );

    clip-path:
      polygon(
        5% 0,
        100% 0,
        100% 91%,
        94% 100%,
        0 100%,
        0 7%
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-layer--rear {
    inset: 0.5% 1.5% 1.5% 5.5%;

    transform:
      translate(1.6%, -1.4%);

    opacity: 0.58;
  }

.prototype-page-frame[data-game-frame-page] .game-info-layer--mid {
    inset: 2.5% 3.5% 3% 2%;

    transform:
      translate(-0.8%, 0.7%);

    opacity: 0.78;
  }

.prototype-page-frame[data-game-frame-page] .game-info-surface {
    position: relative;

    z-index: 2;

    width: 100%;
    height: 100%;

    min-width: 0;
    min-height: 0;

    display: grid;

    grid-template-rows:
      auto
      auto
      minmax(0, 1fr)
      auto
      auto;

    align-content: center;

    gap:
      clamp(10px, 1.15vh, 18px);

    padding:
      clamp(22px, 2.15vw, 38px)
      clamp(22px, 2.25vw, 42px)
      clamp(20px, 2vw, 34px)
      clamp(24px, 2.4vw, 46px);

    border:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.26
      );

    background:
      linear-gradient(
        105deg,
        rgba(20, 29, 34, 0.72) 0%,
        rgba(22, 34, 40, 0.60) 48%,
        rgba(19, 31, 37, 0.40) 100%
      );

    backdrop-filter:
      blur(10px)
      saturate(112%);

    -webkit-backdrop-filter:
      blur(10px)
      saturate(112%);

    clip-path:
      polygon(
        5% 0,
        100% 0,
        100% 90%,
        94% 100%,
        0 100%,
        0 7%
      );

    box-shadow:
      inset 0 0 0 1px rgba(255, 255, 255, 0.035),
      inset 18px 0 42px rgba(255, 255, 255, 0.018);
  }

.prototype-page-frame[data-game-frame-page] .game-info-header {
    display: flex;
    flex-direction: column;

    align-items: flex-start;

    gap:
      clamp(5px, 0.65vh, 10px);

    min-width: 0;
  }

.prototype-page-frame[data-game-frame-page] .game-info-logo {
    display: block;

    width:
      min(
        68%,
        440px
      );

    max-height:
      clamp(70px, 12vh, 132px);

    object-fit: contain;
    object-position: left center;
  }

.prototype-page-frame[data-game-frame-page] .game-info-kicker {
    margin: 0;

    color:
      rgba(
        var(--page-accent-rgb),
        0.93
      );

    font-size:
      clamp(9px, 0.72vw, 13px);

    font-weight: 700;

    letter-spacing:
      0.34em;
  }

.prototype-page-frame[data-game-frame-page] .game-info-blurb {
    max-width: 94%;

    margin: 0;

    color:
      rgba(246, 249, 251, 0.92);

    font-size:
      clamp(12px, 0.86vw, 16px);

    line-height: 1.48;
  }

.prototype-page-frame[data-game-frame-page] .game-info-features {
    min-height: 0;

    display: grid;

    grid-template-columns:
      repeat(2, minmax(0, 1fr));

    align-content: center;

    gap:
      clamp(8px, 0.75vw, 14px);
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature {
    min-width: 0;

    display: grid;

    grid-template-columns:
      clamp(34px, 2.7vw, 48px)
      minmax(0, 1fr);

    align-items: center;

    gap:
      clamp(8px, 0.7vw, 13px);

    padding:
      clamp(7px, 0.65vw, 11px);

    border:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.20
      );

    background:
      linear-gradient(
        115deg,
        rgba(
          var(--page-accent-rgb),
          0.075
        ),
        rgba(16, 22, 26, 0.18)
      );

    clip-path:
      polygon(
        8px 0,
        100% 0,
        100% calc(100% - 8px),
        calc(100% - 8px) 100%,
        0 100%,
        0 8px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature-icon {
    display: grid;
    place-items: center;

    aspect-ratio: 1;

    color:
      rgba(
        var(--page-accent-rgb),
        0.96
      );

    border:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.45
      );

    font-size:
      clamp(18px, 1.5vw, 26px);

    line-height: 1;

    clip-path:
      polygon(
        25% 0,
        75% 0,
        100% 25%,
        100% 75%,
        75% 100%,
        25% 100%,
        0 75%,
        0 25%
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature-copy {
    min-width: 0;

    display: flex;
    flex-direction: column;

    gap: 3px;
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature-copy strong {
    color:
      rgba(
        var(--page-accent-rgb),
        0.96
      );

    font-size:
      clamp(8px, 0.61vw, 11px);

    letter-spacing:
      0.13em;
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature-copy small {
    overflow: hidden;

    color: rgba(232, 239, 243, 0.70);

    font-size:
      clamp(8px, 0.58vw, 10px);

    line-height: 1.25;

    white-space: nowrap;

    text-overflow: ellipsis;
  }

.prototype-page-frame[data-game-frame-page] .game-info-facts {
    display: grid;

    grid-template-columns:
      repeat(3, minmax(0, 1fr));

    border-top:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.28
      );

    border-bottom:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.18
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-fact {
    position: relative;

    min-width: 0;

    display: flex;
    flex-direction: column;

    gap: 4px;

    padding:
      clamp(9px, 0.75vw, 13px)
      clamp(8px, 0.8vw, 14px);
  }

.prototype-page-frame[data-game-frame-page]
  .game-info-fact +
  .game-info-fact::before {
    content: "";

    position: absolute;

    top: 22%;
    bottom: 22%;
    left: 0;

    width: 1px;

    background:
      rgba(
        var(--page-accent-rgb),
        0.24
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-fact span {
    color:
      rgba(
        var(--page-accent-rgb),
        0.78
      );

    font-size:
      clamp(8px, 0.58vw, 10px);

    letter-spacing:
      0.18em;
  }

.prototype-page-frame[data-game-frame-page] .game-info-fact strong {
    overflow: hidden;

    color: rgba(244, 248, 250, 0.92);

    font-size:
      clamp(10px, 0.72vw, 13px);

    font-weight: 500;

    white-space: nowrap;

    text-overflow: ellipsis;
  }

.prototype-page-frame[data-game-frame-page] .game-info-actions {
    display: grid;

    grid-template-columns:
      minmax(0, 1.35fr)
      minmax(0, 0.9fr);

    gap:
      clamp(10px, 0.85vw, 16px);
  }

.prototype-page-frame[data-game-frame-page] .game-info-action {
    min-width: 0;

    display: flex;

    align-items: center;
    justify-content: space-between;

    gap: 12px;

    padding:
      clamp(10px, 0.8vw, 14px)
      clamp(14px, 1vw, 18px);

    border:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.48
      );

    background:
      rgba(15, 21, 25, 0.42);

    color: rgba(248, 251, 252, 0.96);

    font: inherit;

    font-size:
      clamp(9px, 0.68vw, 12px);

    font-weight: 700;

    letter-spacing:
      0.11em;

    cursor: default;

    clip-path:
      polygon(
        10px 0,
        100% 0,
        100% calc(100% - 10px),
        calc(100% - 10px) 100%,
        0 100%,
        0 10px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-action--primary {
    background:
      linear-gradient(
        110deg,
        rgba(
          var(--page-accent-rgb),
          0.10
        ),
        rgba(
          var(--page-accent-rgb),
          0.10
        )
      );

    box-shadow:
      inset 0 0 0 1px
      rgba(
        var(--page-accent-rgb),
        0.10
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-surface {
    grid-template-rows:
      auto
      auto
      minmax(0, 0.78fr)
      auto
      auto;

    gap:
      clamp(12px, 1.35vh, 20px);

    padding-top:
      clamp(26px, 2.55vw, 44px);
  }

.prototype-page-frame[data-game-frame-page] .game-info-header {
    gap:
      clamp(7px, 0.8vh, 12px);
  }

.prototype-page-frame[data-game-frame-page] .game-info-logo {
    width:
      min(
        70%,
        460px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-blurb {
    max-width: 91%;

    line-height: 1.54;
  }

.prototype-page-frame[data-game-frame-page] .game-info-background {
    inset: 0.5% -0.5% 1.5% 9%;

    opacity: 0.47;
  }

.prototype-page-frame[data-game-frame-page] .game-info-background-image {
    object-position: 60% 42%;

    filter:
      saturate(0.94)
      contrast(0.96)
      brightness(0.78);

    -webkit-mask-image:
      linear-gradient(
        102deg,
        transparent 0%,
        rgba(0, 0, 0, 0.06) 13%,
        rgba(0, 0, 0, 0.36) 35%,
        rgba(0, 0, 0, 0.82) 66%,
        rgba(0, 0, 0, 0.96) 100%
      );

    mask-image:
      linear-gradient(
        102deg,
        transparent 0%,
        rgba(0, 0, 0, 0.06) 13%,
        rgba(0, 0, 0, 0.36) 35%,
        rgba(0, 0, 0, 0.82) 66%,
        rgba(0, 0, 0, 0.96) 100%
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-features {
    gap:
      clamp(6px, 0.55vw, 10px)
      clamp(14px, 1.05vw, 20px);

    padding:
      clamp(5px, 0.4vw, 8px)
      0;

    border-top:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.22
      );

    border-bottom:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.14
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature {
    grid-template-columns:
      clamp(30px, 2.35vw, 42px)
      minmax(0, 1fr);

    gap:
      clamp(8px, 0.65vw, 12px);

    padding:
      clamp(7px, 0.5vw, 9px)
      clamp(5px, 0.4vw, 8px);

    border: 0;

    background: transparent;

    clip-path: none;
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature-icon {
    border-color:
      rgba(
        var(--page-accent-rgb),
        0.34
      );

    background:
      rgba(
        var(--page-accent-rgb),
        0.045
      );

    font-size:
      clamp(16px, 1.25vw, 22px);
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature-copy strong {
    font-size:
      clamp(8px, 0.59vw, 10.5px);

    letter-spacing:
      0.14em;
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature-copy small {
    font-size:
      clamp(7.5px, 0.54vw, 9.5px);

    color:
      rgba(232, 239, 243, 0.64);
  }

.prototype-page-frame[data-game-frame-page] .game-info-facts {
    background:
      linear-gradient(
        90deg,
        rgba(
          var(--page-accent-rgb),
          0.035
        ),
        rgba(12, 18, 22, 0.08)
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-fact {
    padding-top:
      clamp(8px, 0.65vw, 11px);

    padding-bottom:
      clamp(8px, 0.65vw, 11px);
  }

.prototype-page-frame[data-game-frame-page] .game-info-action--primary {
    border-color:
      rgba(
        var(--page-accent-rgb),
        0.62
      );

    background:
      linear-gradient(
        110deg,
        rgba(
          var(--page-accent-rgb),
          0.34
        ),
        rgba(
          var(--page-accent-rgb),
          0.12
        )
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-action--secondary {
    border-color:
      rgba(
        var(--page-accent-rgb),
        0.28
      );

    color:
      rgba(238, 244, 247, 0.84);
  }

.prototype-page-frame[data-game-frame-page] .game-info-background {
    
    inset:
      -1.2%
      -0.8%
      8%
      31%;

    opacity: 0.54;

    overflow: hidden;

    border:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.16
      );

    background:
      rgba(
        var(--page-accent-rgb),
        0.028
      );

    clip-path:
      polygon(
        7% 0,
        100% 0,
        100% 86%,
        93% 100%,
        0 100%,
        0 10%
      );

    box-shadow:
      inset 0 0 0 1px rgba(255,255,255,0.018);
  }

.prototype-page-frame[data-game-frame-page] .game-info-background::after {
    content: "";

    position: absolute;
    inset: 0;

    pointer-events: none;

    background:
      linear-gradient(
        90deg,
        rgba(17, 27, 32, 0.92) 0%,
        rgba(17, 27, 32, 0.60) 27%,
        rgba(17, 27, 32, 0.22) 58%,
        rgba(17, 27, 32, 0.08) 100%
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-background-image {
    width: 112%;
    height: 112%;

    transform:
      translate(
        -4%,
        -5%
      );

    object-fit: cover;

    
    object-position: 69% 30%;

    filter:
      saturate(0.90)
      contrast(0.92)
      brightness(0.74);

    -webkit-mask-image: none;
    mask-image: none;
  }

.prototype-page-frame[data-game-frame-page] .game-info-layer--rear {
    inset:
      -1.3%
      0.4%
      0.8%
      6.8%;

    transform:
      translate(
        2.2%,
        -1.2%
      );

    opacity: 0.64;

    border-color:
      rgba(
        var(--page-accent-rgb),
        0.15
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-layer--mid {
    inset:
      1.4%
      2.3%
      2%
      1.2%;

    transform:
      translate(
        -0.5%,
        0.9%
      );

    opacity: 0.82;

    border-color:
      rgba(
        var(--page-accent-rgb),
        0.20
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info::after {
    content: "";

    position: absolute;

    z-index: 3;

    top: 18%;
    right: 0.35%;

    width: 2px;
    height: 28%;

    background:
      linear-gradient(
        to bottom,
        transparent,
        rgba(
          var(--page-accent-rgb),
          0.62
        ) 18%,
        rgba(
          var(--page-accent-rgb),
          0.28
        ) 76%,
        transparent
      );

    box-shadow:
      0 0 14px
      rgba(
        var(--page-accent-rgb),
        0.22
      );

    pointer-events: none;
  }

.prototype-page-frame[data-game-frame-page] .game-info-surface {
    grid-template-rows:
      auto
      auto
      minmax(0, 0.70fr)
      auto
      auto;

    gap:
      clamp(11px, 1.22vh, 18px);

    padding:
      clamp(26px, 2.35vw, 42px)
      clamp(24px, 2.2vw, 40px)
      clamp(22px, 1.9vw, 34px)
      clamp(28px, 2.55vw, 48px);

    background:
      linear-gradient(
        102deg,
        rgba(18, 27, 32, 0.80) 0%,
        rgba(20, 31, 36, 0.67) 43%,
        rgba(18, 30, 35, 0.47) 72%,
        rgba(18, 30, 35, 0.34) 100%
      );

    border-color:
      rgba(
        var(--page-accent-rgb),
        0.30
      );

    box-shadow:
      inset 0 0 0 1px rgba(255,255,255,0.032),
      inset 28px 0 56px rgba(255,255,255,0.012),
      inset -1px 0 0
      rgba(
        var(--page-accent-rgb),
        0.10
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-logo {
    width:
      min(
        67%,
        450px
      );

    margin-left:
      -0.6%;
  }

.prototype-page-frame[data-game-frame-page] .game-info-kicker {
    letter-spacing:
      0.31em;

    opacity: 0.94;
  }

.prototype-page-frame[data-game-frame-page] .game-info-blurb {
    max-width: 89%;

    font-size:
      clamp(12px, 0.84vw, 15px);

    line-height: 1.52;
  }

.prototype-page-frame[data-game-frame-page] .game-info-features {
    grid-template-columns:
      repeat(2, minmax(0, 1fr));

    column-gap:
      clamp(18px, 1.3vw, 24px);

    row-gap:
      clamp(7px, 0.6vw, 11px);

    padding:
      clamp(7px, 0.55vw, 10px)
      0;

    border-top-color:
      rgba(
        var(--page-accent-rgb),
        0.20
      );

    border-bottom-color:
      rgba(
        var(--page-accent-rgb),
        0.13
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature {
    position: relative;

    padding:
      clamp(6px, 0.48vw, 9px)
      clamp(4px, 0.3vw, 6px);
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature::after {
    content: "";

    position: absolute;

    right: 0;
    bottom: 0;

    width:
      clamp(18px, 1.8vw, 30px);

    height: 1px;

    background:
      rgba(
        var(--page-accent-rgb),
        0.13
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature-icon {
    background:
      linear-gradient(
        135deg,
        rgba(
          var(--page-accent-rgb),
          0.08
        ),
        rgba(12, 18, 22, 0.05)
      );

    box-shadow:
      inset 0 0 0 1px
      rgba(
        var(--page-accent-rgb),
        0.035
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature-copy strong {
    line-height: 1.15;
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature-copy small {
    line-height: 1.22;
  }

.prototype-page-frame[data-game-frame-page] .game-info-facts {
    border-top-color:
      rgba(
        var(--page-accent-rgb),
        0.24
      );

    border-bottom-color:
      rgba(
        var(--page-accent-rgb),
        0.16
      );

    background:
      linear-gradient(
        90deg,
        rgba(
          var(--page-accent-rgb),
          0.028
        ),
        rgba(12, 18, 22, 0.055)
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-fact span {
    font-size:
      clamp(7.5px, 0.54vw, 9.5px);

    letter-spacing:
      0.19em;
  }

.prototype-page-frame[data-game-frame-page] .game-info-fact strong {
    font-size:
      clamp(9.5px, 0.68vw, 12.5px);
  }

.prototype-page-frame[data-game-frame-page] .game-info-actions {
    grid-template-columns:
      minmax(0, 1.42fr)
      minmax(0, 0.88fr);

    gap:
      clamp(11px, 0.9vw, 17px);
  }

.prototype-page-frame[data-game-frame-page] .game-info-action {
    padding-top:
      clamp(10px, 0.72vw, 13px);

    padding-bottom:
      clamp(10px, 0.72vw, 13px);
  }

.prototype-page-frame[data-game-frame-page] .game-info-action--primary {
    box-shadow:
      inset 0 0 0 1px
      rgba(
        var(--page-accent-rgb),
        0.12
      ),
      0 0 18px
      rgba(
        var(--page-accent-rgb),
        0.055
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-background,
  .prototype-page-frame[data-game-frame-page] .game-info-layer--rear,
  .prototype-page-frame[data-game-frame-page] .game-info-layer--mid,
  .prototype-page-frame[data-game-frame-page] .game-info::after {
    display: none !important;
  }

.prototype-page-frame[data-game-frame-page] .game-info-surface {
    border: 0;

    background: transparent;

    backdrop-filter: none;
    -webkit-backdrop-filter: none;

    clip-path: none;

    box-shadow: none;
  }

#brobots-page-frame .etherian-popout-layer-stack {
    position: absolute;
    inset: 0;

    z-index: 1;

    overflow: hidden;

    
    clip-path:
      polygon(
        0 0,
        calc(
          100% -
          var(--etherian-stack-cut-run)
        ) 0,
        100%
        var(--etherian-stack-cut-rise),
        100%
        calc(
          100% -
          var(--etherian-stack-cut-rise)
        ),
        calc(
          100% -
          var(--etherian-stack-cut-run)
        ) 100%,
        0 100%
      );

    pointer-events: none;

    opacity: 0;

    transition:
      opacity 220ms ease;

    
  }

#brobots-page-frame.is-secondary-open
  .etherian-popout-layer-stack {
    opacity: 1;

    transition-delay:
      calc(
        var(--secondary-panel-duration) * 0.74
      );
  }

#brobots-page-frame .etherian-popout-glass-layer {
    position: absolute;

    
    --layer-cut-rise:
      clamp(44px, 4.8vw, 78px);

    --layer-cut-run:
      calc(
        var(--layer-cut-rise)
        *
        tan(
          var(--etherian-glass-angle)
        )
      );

    border:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.16
      );

    background:
      linear-gradient(
        115deg,
        rgba(255,255,255,0.022),
        rgba(
          var(--page-accent-rgb),
          0.034
        ) 45%,
        rgba(20,28,34,0.020)
      );

    box-shadow:
      inset 0 0 0 1px
      rgba(255,255,255,0.018);

    backdrop-filter:
      blur(2px)
      saturate(108%);

    -webkit-backdrop-filter:
      blur(2px)
      saturate(108%);
  }

#brobots-page-frame .etherian-popout-glass-layer--1 {
    z-index: 1;

    inset:
      2.5%
      1.7%
      5.5%
      0;

    --layer-cut-rise:
      clamp(54px, 5.4vw, 86px);

    clip-path:
      polygon(
        0 0,
        calc(
          100% -
          var(--layer-cut-run)
        ) 0,
        100%
        var(--layer-cut-rise),
        100%
        calc(
          100% -
          var(--layer-cut-rise)
        ),
        calc(
          100% -
          var(--layer-cut-run)
        ) 100%,
        0 100%
      );

    opacity: 0.42;

    border-color:
      rgba(
        220, 230, 242,
        0.18
      );
  }

#brobots-page-frame .etherian-popout-glass-layer--2 {
    z-index: 2;

    inset:
      7.5%
      6.2%
      8.5%
      0;

    --layer-cut-rise:
      clamp(62px, 6.1vw, 96px);

    clip-path:
      polygon(
        0 0,
        calc(
          100% -
          var(--layer-cut-run)
        ) 0,
        100%
        var(--layer-cut-rise),
        100%
        calc(
          100% -
          var(--layer-cut-rise) * 0.42
        ),
        calc(
          100% -
          var(--layer-cut-run) * 0.42
        ) 100%,
        0 100%
      );

    opacity: 0.50;

    border-color:
      rgba(
        var(--page-accent-rgb),
        0.18
      );

    background:
      linear-gradient(
        118deg,
        rgba(
          var(--page-accent-rgb),
          0.022
        ),
        rgba(255,255,255,0.018)
      );
  }

#brobots-page-frame .etherian-popout-glass-layer--3 {
    z-index: 3;

    inset:
      11.5%
      12.2%
      13.5%
      0;

    --layer-cut-rise:
      clamp(70px, 7vw, 110px);

    clip-path:
      polygon(
        0 0,
        calc(
          100% -
          var(--layer-cut-run)
        ) 0,
        100%
        var(--layer-cut-rise),
        100% 100%,
        0 100%
      );

    opacity: 0.58;

    border-color:
      rgba(
        var(--page-accent-rgb),
        0.22
      );

    background:
      linear-gradient(
        110deg,
        rgba(255,255,255,0.016),
        rgba(
          var(--page-accent-rgb),
          0.045
        )
      );
  }

#brobots-page-frame .etherian-popout-glass-layer--4 {
    z-index: 4;

    left: 0;
    right: 13.6%;
    top: 49%;
    bottom: 0;

    --layer-cut-rise:
      clamp(46px, 4.8vw, 76px);

    clip-path:
      polygon(
        0 0,
        calc(
          100% -
          var(--layer-cut-run)
        ) 0,
        100%
        var(--layer-cut-rise),
        100% 100%,
        0 100%
      );

    opacity: 0.66;

    border-color:
      rgba(
        var(--page-accent-rgb),
        0.24
      );

    background:
      linear-gradient(
        108deg,
        rgba(
          var(--page-accent-rgb),
          0.040
        ),
        rgba(255,255,255,0.018)
      );
  }

#brobots-page-frame .desktop-secondary-panel-content {
    z-index: 2;
  }

.prototype-page-frame[data-game-frame-page] .game-info {
    z-index: 2;
  }

#brobots-page-frame .etherian-popout-glass-layer {
    border-color:
      rgba(
        var(--page-accent-rgb),
        0.24
      );

    background:
      linear-gradient(
        115deg,
        rgba(255,255,255,0.055),
        rgba(
          var(--page-accent-rgb),
          0.085
        ) 44%,
        rgba(26,36,42,0.055)
      );

    box-shadow:
      inset 0 0 0 1px
      rgba(255,255,255,0.032);

    backdrop-filter:
      blur(4px)
      saturate(112%);

    -webkit-backdrop-filter:
      blur(4px)
      saturate(112%);
  }

#brobots-page-frame .etherian-popout-glass-layer--1 {
    opacity: 0.62;

    border-color:
      rgba(
        220, 230, 242,
        0.26
      );

    background:
      linear-gradient(
        116deg,
        rgba(255,255,255,0.060),
        rgba(177,202,216,0.065) 52%,
        rgba(28,36,42,0.040)
      );
  }

#brobots-page-frame .etherian-popout-glass-layer--2 {
    opacity: 0.70;

    border-color:
      rgba(
        var(--page-accent-rgb),
        0.28
      );

    background:
      linear-gradient(
        118deg,
        rgba(
          var(--page-accent-rgb),
          0.070
        ),
        rgba(255,255,255,0.050)
      );
  }

#brobots-page-frame .etherian-popout-glass-layer--3 {
    opacity: 0.76;

    border-color:
      rgba(
        var(--page-accent-rgb),
        0.32
      );

    background:
      linear-gradient(
        110deg,
        rgba(255,255,255,0.045),
        rgba(
          var(--page-accent-rgb),
          0.095
        )
      );
  }

#brobots-page-frame .etherian-popout-glass-layer--4 {
    opacity: 0.82;

    border-color:
      rgba(
        var(--page-accent-rgb),
        0.35
      );

    background:
      linear-gradient(
        108deg,
        rgba(
          var(--page-accent-rgb),
          0.105
        ),
        rgba(255,255,255,0.048)
      );
  }

#brobots-page-frame .etherian-popout-glass-layer--1 {
    opacity: 0.50;
  }

#brobots-page-frame .etherian-popout-glass-layer--2 {
    opacity: 0.58;
  }

#brobots-page-frame .etherian-popout-glass-layer--3 {
    opacity: 0.64;
  }

#brobots-page-frame .etherian-popout-glass-layer--4 {
    right: 20%;
    opacity: 0.70;
  }

#brobots-page-frame .etherian-popout-glass-layer {
    border-color: transparent !important;
    border-width: 0 !important;
  }

#brobots-page-frame .etherian-popout-glass-layer {
    box-shadow:
      inset 0 0 0 1px
      rgba(255, 255, 255, 0.018);
  }

#brobots-page-frame .etherian-popout-glass-layer--3 {
    clip-path:
      polygon(
        0 0,

        calc(
          100% -
          var(--layer-cut-run)
        ) 0,

        100%
        var(--layer-cut-rise),

        100%
        calc(
          100% -
          var(--layer-cut-rise) * 0.42
        ),

        calc(
          100% -
          var(--layer-cut-run) * 0.42
        ) 100%,

        0 100%
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-features {
    transition:
      opacity 120ms ease;
  }

.prototype-page-frame[data-game-frame-page]
  .game-info-features.is-crowded {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
  }

.prototype-page-frame[data-game-frame-page] .game-info-surface {
    align-content: stretch;

    grid-template-rows:
      auto
      auto
      minmax(0, 1fr)
      auto
      auto;
  }

.prototype-page-frame[data-game-frame-page] .game-info-header {
    align-self: start;
  }

.prototype-page-frame[data-game-frame-page] .game-info-logo {
    width:
      clamp(
        250px,
        30vw,
        430px
      );

    max-width: 62%;

    max-height:
      clamp(
        76px,
        11vh,
        126px
      );

    margin-left: 0;
  }

.prototype-page-frame[data-game-frame-page] .game-info-blurb {
    width: min(100%, 76ch);
    max-width: 76ch;
  }

.prototype-page-frame[data-game-frame-page].is-info-compact
  .game-info-surface {
    gap:
      clamp(8px, 0.9vh, 13px);

    padding:
      clamp(20px, 1.75vw, 30px)
      clamp(20px, 1.7vw, 30px)
      clamp(18px, 1.55vw, 27px)
      clamp(22px, 1.9vw, 34px);
  }

.prototype-page-frame[data-game-frame-page].is-info-compact
  .game-info-header {
    gap:
      clamp(4px, 0.5vh, 7px);
  }

.prototype-page-frame[data-game-frame-page].is-info-compact
  .game-info-logo {
    width:
      clamp(
        220px,
        25vw,
        350px
      );

    max-width: 58%;

    max-height:
      clamp(
        66px,
        9.5vh,
        104px
      );
  }

.prototype-page-frame[data-game-frame-page].is-info-compact
  .game-info-kicker {
    font-size:
      clamp(8px, 0.62vw, 11px);

    letter-spacing: 0.27em;
  }

.prototype-page-frame[data-game-frame-page].is-info-compact
  .game-info-blurb {
    width: min(100%, 70ch);
    max-width: 70ch;

    font-size:
      clamp(11px, 0.76vw, 13.5px);

    line-height: 1.43;
  }

.prototype-page-frame[data-game-frame-page].is-info-compact
  .game-info-features {
    column-gap:
      clamp(12px, 0.9vw, 18px);

    row-gap:
      clamp(5px, 0.42vw, 8px);

    padding:
      clamp(4px, 0.36vw, 7px)
      0;
  }

.prototype-page-frame[data-game-frame-page].is-info-compact
  .game-info-feature {
    grid-template-columns:
      clamp(27px, 2.15vw, 36px)
      minmax(0, 1fr);

    gap:
      clamp(6px, 0.5vw, 9px);

    padding:
      clamp(4px, 0.34vw, 6px)
      clamp(3px, 0.26vw, 5px);
  }

.prototype-page-frame[data-game-frame-page].is-info-compact
  .game-info-feature-icon {
    font-size:
      clamp(14px, 1.12vw, 20px);
  }

.prototype-page-frame[data-game-frame-page].is-info-compact
  .game-info-feature-copy strong {
    font-size:
      clamp(7.5px, 0.53vw, 9.5px);

    letter-spacing: 0.12em;
  }

.prototype-page-frame[data-game-frame-page].is-info-compact
  .game-info-feature-copy small {
    font-size:
      clamp(7px, 0.49vw, 8.8px);
  }

.prototype-page-frame[data-game-frame-page].is-info-compact
  .game-info-fact {
    gap: 2px;

    padding:
      clamp(6px, 0.48vw, 8px)
      clamp(6px, 0.58vw, 10px);
  }

.prototype-page-frame[data-game-frame-page].is-info-compact
  .game-info-actions {
    gap:
      clamp(8px, 0.62vw, 11px);
  }

.prototype-page-frame[data-game-frame-page].is-info-compact
  .game-info-action {
    padding:
      clamp(8px, 0.6vw, 10px)
      clamp(11px, 0.8vw, 14px);
  }

.prototype-page-frame[data-game-frame-page].is-info-tight
  .game-info-surface {
    gap:
      clamp(6px, 0.68vh, 9px);

    padding:
      clamp(16px, 1.35vw, 22px)
      clamp(17px, 1.4vw, 24px)
      clamp(15px, 1.25vw, 21px)
      clamp(18px, 1.55vw, 27px);
  }

.prototype-page-frame[data-game-frame-page].is-info-tight
  .game-info-logo {
    width:
      clamp(
        190px,
        21vw,
        290px
      );

    max-width: 54%;

    max-height:
      clamp(
        58px,
        8vh,
        86px
      );
  }

.prototype-page-frame[data-game-frame-page].is-info-tight
  .game-info-kicker {
    font-size:
      clamp(7.5px, 0.56vw, 9.5px);

    letter-spacing: 0.23em;
  }

.prototype-page-frame[data-game-frame-page].is-info-tight
  .game-info-blurb {
    width: min(100%, 64ch);
    max-width: 64ch;

    font-size:
      clamp(10.5px, 0.7vw, 12.5px);

    line-height: 1.38;
  }

.prototype-page-frame[data-game-frame-page].is-info-tight
  .game-info-features {
    column-gap:
      clamp(9px, 0.65vw, 13px);

    row-gap: 4px;

    padding: 3px 0;
  }

.prototype-page-frame[data-game-frame-page].is-info-tight
  .game-info-feature {
    grid-template-columns:
      clamp(24px, 1.85vw, 31px)
      minmax(0, 1fr);

    gap: 5px;

    padding: 3px 2px;
  }

.prototype-page-frame[data-game-frame-page].is-info-tight
  .game-info-feature-icon {
    font-size:
      clamp(12px, 0.92vw, 17px);
  }

.prototype-page-frame[data-game-frame-page].is-info-tight
  .game-info-feature-copy strong {
    font-size:
      clamp(7px, 0.48vw, 8.5px);

    letter-spacing: 0.10em;
  }

.prototype-page-frame[data-game-frame-page].is-info-tight
  .game-info-feature-copy small {
    font-size:
      clamp(6.7px, 0.45vw, 8px);
  }

.prototype-page-frame[data-game-frame-page].is-info-tight
  .game-info-fact {
    padding:
      5px
      clamp(5px, 0.46vw, 8px);
  }

.prototype-page-frame[data-game-frame-page].is-info-tight
  .game-info-fact span {
    font-size:
      clamp(7px, 0.48vw, 8.5px);

    letter-spacing: 0.15em;
  }

.prototype-page-frame[data-game-frame-page].is-info-tight
  .game-info-fact strong {
    font-size:
      clamp(9px, 0.6vw, 11px);
  }

.prototype-page-frame[data-game-frame-page].is-info-tight
  .game-info-action {
    padding:
      7px
      clamp(9px, 0.68vw, 12px);

    font-size:
      clamp(8px, 0.58vw, 10px);

    letter-spacing: 0.09em;
  }

.prototype-page-frame[data-game-frame-page]
  .game-info-features.is-crowded {
    transition:
      opacity 130ms ease;

    opacity: 0;
    visibility: hidden;
    pointer-events: none;
  }

.prototype-page-frame[data-game-frame-page] .game-info-surface,
  .prototype-page-frame[data-game-frame-page] .game-info-header,
  .prototype-page-frame[data-game-frame-page] .game-info-logo,
  .prototype-page-frame[data-game-frame-page] .game-info-kicker,
  .prototype-page-frame[data-game-frame-page] .game-info-blurb,
  .prototype-page-frame[data-game-frame-page] .game-info-features,
  .prototype-page-frame[data-game-frame-page] .game-info-feature,
  .prototype-page-frame[data-game-frame-page] .game-info-feature-icon,
  .prototype-page-frame[data-game-frame-page] .game-info-feature-copy strong,
  .prototype-page-frame[data-game-frame-page] .game-info-feature-copy small,
  .prototype-page-frame[data-game-frame-page] .game-info-fact,
  .prototype-page-frame[data-game-frame-page] .game-info-fact span,
  .prototype-page-frame[data-game-frame-page] .game-info-fact strong,
  .prototype-page-frame[data-game-frame-page] .game-info-actions,
  .prototype-page-frame[data-game-frame-page] .game-info-action {
    transition:
      width 210ms ease,
      max-width 210ms ease,
      max-height 210ms ease,
      padding 210ms ease,
      gap 210ms ease,
      font-size 210ms ease,
      line-height 210ms ease,
      letter-spacing 210ms ease,
      opacity 180ms ease,
      transform 180ms ease;
  }

.prototype-page-frame[data-game-frame-page] .game-info-surface {
    padding:
      clamp(16px, 1.65cqw, 34px)
      clamp(17px, 1.55cqw, 32px)
      clamp(15px, 1.45cqw, 29px)
      clamp(18px, 1.75cqw, 36px);

    gap:
      clamp(7px, 0.78cqh, 14px);
  }

.prototype-page-frame[data-game-frame-page] .game-info-logo {
    width:
      clamp(
        220px,
        27cqw,
        390px
      );

    max-width: 60%;

    max-height:
      clamp(
        66px,
        10cqh,
        112px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-kicker {
    font-size:
      clamp(8px, 0.60cqw, 11px);

    letter-spacing:
      clamp(0.22em, 0.26em, 0.28em);
  }

.prototype-page-frame[data-game-frame-page] .game-info-blurb {
    width:
      min(
        100%,
        clamp(
          58ch,
          67cqw,
          76ch
        )
      );

    max-width: 76ch;

    font-size:
      clamp(10.8px, 0.70cqw, 13.5px);

    line-height:
      clamp(1.38, 1.42, 1.46);
  }

.prototype-page-frame[data-game-frame-page] .game-info-features {
    column-gap:
      clamp(10px, 0.85cqw, 18px);

    row-gap:
      clamp(4px, 0.38cqw, 8px);

    padding:
      clamp(3px, 0.32cqw, 7px)
      0;
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature {
    grid-template-columns:
      clamp(25px, 2cqw, 36px)
      minmax(0, 1fr);

    gap:
      clamp(5px, 0.46cqw, 9px);

    padding:
      clamp(3px, 0.3cqw, 6px)
      clamp(2px, 0.24cqw, 5px);
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature-icon {
    font-size:
      clamp(13px, 1.02cqw, 20px);
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature-copy strong {
    font-size:
      clamp(7.3px, 0.50cqw, 9.5px);

    letter-spacing:
      clamp(0.10em, 0.115em, 0.12em);
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature-copy small {
    font-size:
      clamp(6.9px, 0.46cqw, 8.8px);
  }

.prototype-page-frame[data-game-frame-page] .game-info-fact {
    padding:
      clamp(5px, 0.44cqw, 8px)
      clamp(5px, 0.54cqw, 10px);
  }

.prototype-page-frame[data-game-frame-page] .game-info-action {
    padding:
      clamp(7px, 0.56cqw, 10px)
      clamp(9px, 0.74cqw, 14px);

    font-size:
      clamp(8px, 0.55cqw, 10px);
  }

.prototype-page-frame[data-game-frame-page].is-info-compact
  .game-info-logo {
    max-width: 57%;
  }

.prototype-page-frame[data-game-frame-page].is-info-compact
  .game-info-blurb {
    max-width: 70ch;
  }

.prototype-page-frame[data-game-frame-page].is-info-tight
  .game-info-features {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;

    transform:
      translateY(-4px);
  }

.prototype-page-frame[data-game-frame-page].is-info-tight
  .game-info-surface {
    grid-template-rows:
      auto
      auto
      minmax(0, 0.18fr)
      auto
      auto;
  }

.prototype-page-frame[data-game-frame-page]
  .game-info-features.is-crowded {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;

    transform:
      translateY(-4px);
  }

.prototype-page-frame[data-game-frame-page] .game-info-logo,
  .prototype-page-frame[data-game-frame-page].is-info-compact .game-info-logo,
  .prototype-page-frame[data-game-frame-page].is-info-tight .game-info-logo {
    width:
      clamp(
        270px,
        29cqw,
        410px
      );

    max-width: 61%;

    max-height:
      clamp(
        78px,
        10.5cqh,
        116px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-kicker,
  .prototype-page-frame[data-game-frame-page].is-info-compact .game-info-kicker,
  .prototype-page-frame[data-game-frame-page].is-info-tight .game-info-kicker {
    font-size:
      clamp(
        9px,
        0.60cqw,
        11px
      );

    letter-spacing: 0.27em;
  }

.prototype-page-frame[data-game-frame-page] .game-info-blurb,
  .prototype-page-frame[data-game-frame-page].is-info-compact .game-info-blurb,
  .prototype-page-frame[data-game-frame-page].is-info-tight .game-info-blurb {
    width:
      min(
        100%,
        clamp(
          62ch,
          68cqw,
          76ch
        )
      );

    max-width: 76ch;

    font-size:
      clamp(
        11.8px,
        0.72cqw,
        13.8px
      );

    line-height: 1.44;
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature,
  .prototype-page-frame[data-game-frame-page].is-info-compact .game-info-feature,
  .prototype-page-frame[data-game-frame-page].is-info-tight .game-info-feature {
    grid-template-columns:
      clamp(30px, 2.05cqw, 38px)
      minmax(0, 1fr);

    gap:
      clamp(6px, 0.46cqw, 9px);

    padding:
      clamp(4px, 0.32cqw, 7px)
      clamp(3px, 0.25cqw, 6px);
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature-icon,
  .prototype-page-frame[data-game-frame-page].is-info-compact .game-info-feature-icon,
  .prototype-page-frame[data-game-frame-page].is-info-tight .game-info-feature-icon {
    font-size:
      clamp(
        15px,
        1.02cqw,
        20px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature-copy strong,
  .prototype-page-frame[data-game-frame-page].is-info-compact .game-info-feature-copy strong,
  .prototype-page-frame[data-game-frame-page].is-info-tight .game-info-feature-copy strong {
    font-size:
      clamp(
        8px,
        0.51cqw,
        9.5px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature-copy small,
  .prototype-page-frame[data-game-frame-page].is-info-compact .game-info-feature-copy small,
  .prototype-page-frame[data-game-frame-page].is-info-tight .game-info-feature-copy small {
    font-size:
      clamp(
        7.5px,
        0.47cqw,
        8.8px
      );
  }

.prototype-page-frame[data-game-frame-page].is-info-tight .game-info-surface {
    grid-template-rows:
      auto
      auto
      minmax(0, 1fr)
      auto
      auto;
  }

.prototype-page-frame[data-game-frame-page].is-info-tight .game-info-features,
  .prototype-page-frame[data-game-frame-page] .game-info-features.is-crowded {
    opacity: 0;

    
    visibility: visible;

    pointer-events: none;

    transform:
      translateY(-3px);
  }

.prototype-page-frame[data-game-frame-page] .game-info-fact,
  .prototype-page-frame[data-game-frame-page].is-info-compact .game-info-fact,
  .prototype-page-frame[data-game-frame-page].is-info-tight .game-info-fact {
    padding:
      clamp(7px, 0.46cqw, 10px)
      clamp(7px, 0.55cqw, 11px);
  }

.prototype-page-frame[data-game-frame-page] .game-info-fact span,
  .prototype-page-frame[data-game-frame-page].is-info-compact .game-info-fact span,
  .prototype-page-frame[data-game-frame-page].is-info-tight .game-info-fact span {
    font-size:
      clamp(
        8px,
        0.49cqw,
        9.5px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-fact strong,
  .prototype-page-frame[data-game-frame-page].is-info-compact .game-info-fact strong,
  .prototype-page-frame[data-game-frame-page].is-info-tight .game-info-fact strong {
    font-size:
      clamp(
        10px,
        0.62cqw,
        12px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-actions,
  .prototype-page-frame[data-game-frame-page].is-info-compact .game-info-actions,
  .prototype-page-frame[data-game-frame-page].is-info-tight .game-info-actions {
    grid-template-columns:
      minmax(0, 1.25fr)
      minmax(0, 0.95fr);

    gap:
      clamp(
        9px,
        0.65cqw,
        13px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-action,
  .prototype-page-frame[data-game-frame-page].is-info-compact .game-info-action,
  .prototype-page-frame[data-game-frame-page].is-info-tight .game-info-action {
    min-height:
      clamp(
        40px,
        4.7cqh,
        48px
      );

    padding:
      0
      clamp(
        12px,
        0.78cqw,
        16px
      );

    gap:
      clamp(
        8px,
        0.55cqw,
        12px
      );

    font-size:
      clamp(
        9.5px,
        0.57cqw,
        11px
      );

    letter-spacing: 0.10em;
  }

.prototype-page-frame[data-game-frame-page] .game-info-surface,
  .prototype-page-frame[data-game-frame-page] .game-info-header,
  .prototype-page-frame[data-game-frame-page] .game-info-logo,
  .prototype-page-frame[data-game-frame-page] .game-info-kicker,
  .prototype-page-frame[data-game-frame-page] .game-info-blurb,
  .prototype-page-frame[data-game-frame-page] .game-info-feature,
  .prototype-page-frame[data-game-frame-page] .game-info-feature-icon,
  .prototype-page-frame[data-game-frame-page] .game-info-feature-copy strong,
  .prototype-page-frame[data-game-frame-page] .game-info-feature-copy small,
  .prototype-page-frame[data-game-frame-page] .game-info-fact,
  .prototype-page-frame[data-game-frame-page] .game-info-fact span,
  .prototype-page-frame[data-game-frame-page] .game-info-fact strong,
  .prototype-page-frame[data-game-frame-page] .game-info-actions,
  .prototype-page-frame[data-game-frame-page] .game-info-action {
    transition: none;
  }

.prototype-page-frame[data-game-frame-page] .game-info-features {
    transition:
      opacity 190ms ease,
      transform 190ms ease;
  }

.prototype-page-frame[data-game-frame-page] .game-info-surface {
    align-content: start;

    grid-template-rows:
      auto
      auto
      auto
      auto
      auto;

    row-gap:
      clamp(
        8px,
        0.72cqh,
        14px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-features {
    align-content: start;

    min-height: 0;

    max-height: 180px;

    margin-block:
      clamp(
        2px,
        0.22cqh,
        5px
      );

    overflow: hidden;

    transition:
      opacity 190ms ease,
      transform 190ms ease,
      max-height 220ms ease,
      margin 220ms ease;
  }

.prototype-page-frame[data-game-frame-page]
  .game-info-features.is-crowded,
  .prototype-page-frame[data-game-frame-page]
  .game-info-features.is-structure-hidden {
    opacity: 0;

    max-height: 0;

    margin-block: 0;

    transform:
      translateY(-3px);

    pointer-events: none;
  }

.prototype-page-frame[data-game-frame-page].is-info-tight
  .game-info-features {
    opacity: 1;

    max-height: 180px;

    margin-block:
      clamp(
        1px,
        0.15cqh,
        4px
      );

    transform: none;

    pointer-events: auto;
  }

.prototype-page-frame[data-game-frame-page] .game-info-header {
    margin-bottom:
      clamp(
        1px,
        0.18cqh,
        4px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-blurb {
    margin-bottom:
      clamp(
        2px,
        0.25cqh,
        5px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-facts {
    margin-top:
      clamp(
        2px,
        0.22cqh,
        5px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-actions {
    margin-top:
      clamp(
        1px,
        0.16cqh,
        4px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-surface {
    --feature-zone-height: 118px;

    display: grid;

    grid-template-rows:
      auto
      var(--feature-zone-height)
      auto;

    align-content: center;

    row-gap:
      clamp(
        11px,
        1.25cqh,
        20px
      );

    padding:
      clamp(22px, 3.2cqh, 40px)
      clamp(20px, 1.65cqw, 34px)
      clamp(20px, 2.9cqh, 36px)
      clamp(22px, 1.8cqw, 38px);

    transition:
      grid-template-rows 230ms
      cubic-bezier(0.2, 0.78, 0.24, 1),
      row-gap 180ms ease,
      padding 180ms ease;
  }

.prototype-page-frame[data-game-frame-page].is-info-compact .game-info-surface,
  .prototype-page-frame[data-game-frame-page].is-info-tight .game-info-surface {
    grid-template-rows:
      auto
      var(--feature-zone-height)
      auto;

    align-content: center;
  }

.prototype-page-frame[data-game-frame-page] .game-info-top-zone,
  .prototype-page-frame[data-game-frame-page] .game-info-bottom-zone {
    min-width: 0;

    display: grid;

    align-content: start;
  }

.prototype-page-frame[data-game-frame-page] .game-info-top-zone {
    row-gap:
      clamp(
        7px,
        0.68cqh,
        11px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-bottom-zone {
    row-gap:
      clamp(
        7px,
        0.62cqh,
        11px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-header,
  .prototype-page-frame[data-game-frame-page] .game-info-blurb,
  .prototype-page-frame[data-game-frame-page] .game-info-facts,
  .prototype-page-frame[data-game-frame-page] .game-info-actions {
    margin-top: 0;
    margin-bottom: 0;
  }

.prototype-page-frame[data-game-frame-page] .game-info-logo,
  .prototype-page-frame[data-game-frame-page].is-info-compact .game-info-logo,
  .prototype-page-frame[data-game-frame-page].is-info-tight .game-info-logo {
    width:
      clamp(
        280px,
        28cqw,
        405px
      );

    max-width: 60%;

    max-height:
      clamp(
        80px,
        10.5cqh,
        116px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-blurb,
  .prototype-page-frame[data-game-frame-page].is-info-compact .game-info-blurb,
  .prototype-page-frame[data-game-frame-page].is-info-tight .game-info-blurb {
    width:
      min(
        100%,
        74ch
      );

    max-width: 74ch;

    font-size:
      clamp(
        11.8px,
        0.72cqw,
        13.8px
      );

    line-height: 1.44;
  }

.prototype-page-frame[data-game-frame-page] .game-info-features,
  .prototype-page-frame[data-game-frame-page].is-info-tight .game-info-features,
  .prototype-page-frame[data-game-frame-page]
  .game-info-features.is-crowded {
    min-height: 0;
    height: 100%;
    max-height: none;

    margin: 0;

    align-content: center;

    overflow: hidden;

    opacity: 1;
    visibility: visible;
    transform: none;

    transition:
      opacity 170ms ease;
  }

.prototype-page-frame[data-game-frame-page]
  .game-info-surface.is-features-collapsed
  .game-info-features {
    opacity: 0;

    pointer-events: none;
  }

.prototype-page-frame[data-game-frame-page] .game-info-fact,
  .prototype-page-frame[data-game-frame-page].is-info-compact .game-info-fact,
  .prototype-page-frame[data-game-frame-page].is-info-tight .game-info-fact {
    padding:
      clamp(7px, 0.48cqw, 10px)
      clamp(7px, 0.56cqw, 11px);
  }

.prototype-page-frame[data-game-frame-page] .game-info-action,
  .prototype-page-frame[data-game-frame-page].is-info-compact .game-info-action,
  .prototype-page-frame[data-game-frame-page].is-info-tight .game-info-action {
    min-height:
      clamp(
        40px,
        4.7cqh,
        48px
      );

    padding:
      0
      clamp(
        12px,
        0.78cqw,
        16px
      );

    font-size:
      clamp(
        9.5px,
        0.57cqw,
        11px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-logo {
    width:
      clamp(
        285px,
        30cqw,
        500px
      );

    max-width: 63%;

    max-height:
      clamp(
        82px,
        11.5cqh,
        142px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-kicker {
    font-size:
      clamp(
        9px,
        0.66cqw,
        13px
      );

    letter-spacing:
      clamp(
        0.25em,
        0.28em,
        0.30em
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-blurb {
    width:
      min(
        100%,
        76ch
      );

    max-width: 76ch;

    font-size:
      clamp(
        12px,
        0.78cqw,
        16.5px
      );

    line-height: 1.46;
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature {
    grid-template-columns:
      clamp(
        32px,
        2.2cqw,
        46px
      )
      minmax(0, 1fr);

    gap:
      clamp(
        7px,
        0.52cqw,
        11px
      );

    padding:
      clamp(
        5px,
        0.36cqw,
        8px
      )
      clamp(
        4px,
        0.3cqw,
        7px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature-icon {
    font-size:
      clamp(
        16px,
        1.1cqw,
        23px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature-copy strong {
    font-size:
      clamp(
        8px,
        0.56cqw,
        10.5px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature-copy small {
    font-size:
      clamp(
        7.5px,
        0.50cqw,
        9.5px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-fact span {
    font-size:
      clamp(
        8px,
        0.54cqw,
        10px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-fact strong {
    font-size:
      clamp(
        10px,
        0.68cqw,
        13px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-action {
    min-height:
      clamp(
        41px,
        5cqh,
        54px
      );

    padding:
      0
      clamp(
        13px,
        0.86cqw,
        19px
      );

    font-size:
      clamp(
        9.5px,
        0.62cqw,
        12px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-surface {
    row-gap:
      clamp(
        12px,
        1.45cqh,
        24px
      );

    padding:
      clamp(
        24px,
        3.5cqh,
        46px
      )
      clamp(
        22px,
        1.85cqw,
        38px
      )
      clamp(
        22px,
        3.2cqh,
        42px
      )
      clamp(
        24px,
        2cqw,
        42px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-surface {
    transition:
      grid-template-rows 260ms
      cubic-bezier(0.2, 0.78, 0.24, 1),
      row-gap 180ms ease,
      padding 180ms ease;
  }

.prototype-page-frame[data-game-frame-page] .game-info-logo {
    width:
      clamp(
        285px,
        36cqw,
        540px
      );

    max-width: 66%;

    max-height:
      clamp(
        82px,
        13cqh,
        150px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-kicker {
    font-size:
      clamp(
        9px,
        0.78cqw,
        13.5px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-blurb {
    max-width: 78ch;

    font-size:
      clamp(
        12px,
        0.98cqw,
        17px
      );

    line-height: 1.46;
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature {
    grid-template-columns:
      clamp(
        32px,
        2.65cqw,
        50px
      )
      minmax(0, 1fr);

    gap:
      clamp(
        7px,
        0.66cqw,
        12px
      );

    padding:
      clamp(
        5px,
        0.46cqw,
        9px
      )
      clamp(
        4px,
        0.38cqw,
        8px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature-icon {
    font-size:
      clamp(
        16px,
        1.35cqw,
        25px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature-copy strong {
    font-size:
      clamp(
        8px,
        0.68cqw,
        11px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-feature-copy small {
    font-size:
      clamp(
        7.5px,
        0.60cqw,
        10px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-fact span {
    font-size:
      clamp(
        8px,
        0.63cqw,
        10.5px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-fact strong {
    font-size:
      clamp(
        10px,
        0.78cqw,
        13.5px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-action {
    min-height:
      clamp(
        41px,
        5.8cqh,
        58px
      );

    padding:
      0
      clamp(
        13px,
        1.02cqw,
        21px
      );

    font-size:
      clamp(
        9.5px,
        0.75cqw,
        12.5px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-surface {
    row-gap:
      clamp(
        12px,
        1.7cqh,
        28px
      );

    padding:
      clamp(
        24px,
        4.1cqh,
        52px
      )
      clamp(
        22px,
        2.15cqw,
        44px
      )
      clamp(
        22px,
        3.7cqh,
        48px
      )
      clamp(
        24px,
        2.35cqw,
        48px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-top-zone {
    row-gap:
      clamp(
        7px,
        0.9cqh,
        13px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-bottom-zone {
    row-gap:
      clamp(
        7px,
        0.78cqh,
        13px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-logo {
    max-width: 68%;
  }

.prototype-page-frame[data-game-frame-page] .game-info-blurb {
    max-width: 80ch;
  }

.prototype-page-frame[data-game-frame-page] .game-info-surface {
    padding-left:
      clamp(
        28px,
        2.55cqw,
        54px
      );

    padding-right:
      clamp(
        26px,
        2.35cqw,
        50px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-blurb {
    width: 64ch;
    max-width: none;

    font-size:
      clamp(
        12px,
        0.98cqw,
        17px
      );

    line-height: 1.46;
  }

.prototype-page-frame[data-game-frame-page] .game-info-top-zone {
    min-width: 0;
  }

.prototype-page-frame[data-game-frame-page] .game-info-blurb {
    max-inline-size:
      min(
        64ch,
        calc(100cqw - 48px)
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-blurb {
    width: 64ch;

    max-inline-size:
      min(
        64ch,
        calc(100cqw - 40px)
      );

    font-size:
      clamp(
        11.4px,
        0.84cqw,
        17px
      );

    line-height: 1.45;
  }

.prototype-page-frame[data-game-frame-page] .game-info-surface {
    row-gap:
      clamp(
        9px,
        min(
          1.65cqh,
          1.05cqw
        ),
        26px
      );

    padding-top:
      clamp(
        20px,
        min(
          3.8cqh,
          2.4cqw
        ),
        48px
      );

    padding-bottom:
      clamp(
        18px,
        min(
          3.4cqh,
          2.15cqw
        ),
        44px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-top-zone {
    row-gap:
      clamp(
        6px,
        min(
          0.85cqh,
          0.62cqw
        ),
        12px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-bottom-zone {
    row-gap:
      clamp(
        6px,
        min(
          0.74cqh,
          0.56cqw
        ),
        12px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-logo {
    width:
      clamp(
        320px,
        31cqw,
        420px
      );

    max-width: 64%;

    max-height:
      clamp(
        92px,
        11.5cqh,
        122px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-blurb {
    font-size:
      clamp(
        10.8px,
        0.82cqw,
        16.5px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-kicker {
    font-size:
      clamp(
        8.5px,
        0.60cqw,
        12.5px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-fact span {
    font-size:
      clamp(
        7.5px,
        0.50cqw,
        10px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-fact strong {
    font-size:
      clamp(
        9.5px,
        0.64cqw,
        13px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-logo {
    width:
      clamp(
        320px,
        31cqw,
        420px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-logo {
    width:
      clamp(
        390px,
        38cqw,
        520px
      );

    max-width: 68%;

    max-height:
      clamp(
        108px,
        13cqh,
        148px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-logo {
    width:
      clamp(
        430px,
        40cqw,
        560px
      );

    max-width: 70%;
  }

.prototype-page-frame[data-game-frame-page] .game-info-logo {
    width:
      clamp(
        410px,
        23vw,
        520px
      );

    max-width: 68%;

    max-height:
      clamp(
        112px,
        12.5vh,
        148px
      );
  }

.prototype-page-frame[data-game-frame-page] .game-info-logo {
    width:
      clamp(
        470px,
        24vw,
        560px
      );

    max-width: 70%;

    max-height: 156px;
  }

.prototype-page-frame[data-game-frame-page] .game-info-logo {
    width:
      clamp(
        320px,
        calc(27.2vw - 118px),
        483px
      );

    max-width: 68%;

    max-height:
      clamp(
        92px,
        calc(7.8vw - 18px),
        140px
      );

    transition:
      width 140ms ease-out,
      max-height 140ms ease-out;
  }

.prototype-page-frame[data-game-frame-page]
  .game-info-surface.is-features-collapsed
  .game-info-logo {
    width:
      clamp(
        340px,
        calc(29.5vw - 122px),
        520px
      );

    max-width: 70%;

    max-height:
      clamp(
        100px,
        calc(8.6vw - 18px),
        150px
      );
  }

#brobots-page-frame
  .etherian-popout-glass-layer--1 {
    overflow: hidden;
  }

#brobots-page-frame
  .etherian-popout-layer-image {
    position: absolute;

    top: 0;
    right: 0;

    height: 100%;
    width: auto;

    max-width: none;

    display: block;

    object-fit: contain;
    object-position: top right;

    pointer-events: none;

    
    opacity: 0.40;

    filter:
      saturate(0.92)
      contrast(0.96)
      brightness(0.88);
  }

#brobots-page-frame
  .etherian-popout-glass-layer--1::before {
    content: "";

    position: absolute;
    inset: 0;

    z-index: 1;

    background:
      linear-gradient(
        110deg,
        rgba(18, 30, 34, 0.22),
        rgba(
          var(--page-accent-rgb),
          0.055
        ) 48%,
        rgba(10, 18, 22, 0.10)
      );

    pointer-events: none;
  }

#brobots-page-frame
  .etherian-popout-layer-image {
    z-index: 0;
  }

#brobots-page-frame
  .etherian-popout-layer-image {
    
    -webkit-mask-image:
      radial-gradient(
        ellipse 78% 72%
        at 100% 0%,
        rgba(0, 0, 0, 1) 0%,
        rgba(0, 0, 0, 0.96) 30%,
        rgba(0, 0, 0, 0.72) 48%,
        rgba(0, 0, 0, 0.30) 66%,
        rgba(0, 0, 0, 0) 84%
      );

    mask-image:
      radial-gradient(
        ellipse 78% 72%
        at 100% 0%,
        rgba(0, 0, 0, 1) 0%,
        rgba(0, 0, 0, 0.96) 30%,
        rgba(0, 0, 0, 0.72) 48%,
        rgba(0, 0, 0, 0.30) 66%,
        rgba(0, 0, 0, 0) 84%
      );

    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;

    -webkit-mask-size: 100% 100%;
    mask-size: 100% 100%;
  }

#brobots-page-frame
  .etherian-popout-layer-image {
    opacity: 0.30;
  }

#brobots-page-frame.is-layout-transitioning.is-secondary-open
.etherian-popout-layer-stack {
  opacity: 0 !important;
  transition-delay: 0ms !important;
}

#brobots-page-frame
  .desktop-secondary-panel-content {
    transition:
      opacity 650ms ease !important;
  }

#brobots-page-frame.is-secondary-open
  .desktop-secondary-panel-content {
    transition:
      opacity 650ms ease !important;

    
    transition-delay:
      calc(
        var(--secondary-panel-duration) * 0.78
      ) !important;
  }

#brobots-page-frame.is-layout-transitioning
.etherian-popout-layer-image {
  opacity: 0 !important;

  transition:
    opacity 220ms ease !important;

  transition-delay: 0ms !important;

  pointer-events: none !important;
}

#brobots-page-frame.is-layout-transitioning
.etherian-popout-layer-stack {
  position: absolute;
  inset: 0;

  overflow: hidden;

  pointer-events: none;
}

#brobots-page-frame.is-layout-transitioning
.etherian-popout-layer-image {
  position: absolute !important;

  top: 0 !important;
  right: 0 !important;

  height: 100% !important;
  width: auto !important;

  max-width: none !important;
  max-height: none !important;

  display: block !important;

  object-fit: contain !important;
  object-position: top right !important;

  z-index: 0 !important;

  opacity: 0 !important;

  filter:
    saturate(0.92)
    contrast(0.96)
    brightness(0.88) !important;

  -webkit-mask-image:
    radial-gradient(
      ellipse 78% 72%
      at 100% 0%,
      rgba(0, 0, 0, 1) 0%,
      rgba(0, 0, 0, 0.96) 30%,
      rgba(0, 0, 0, 0.72) 48%,
      rgba(0, 0, 0, 0.30) 66%,
      rgba(0, 0, 0, 0) 84%
    ) !important;

  mask-image:
    radial-gradient(
      ellipse 78% 72%
      at 100% 0%,
      rgba(0, 0, 0, 1) 0%,
      rgba(0, 0, 0, 0.96) 30%,
      rgba(0, 0, 0, 0.72) 48%,
      rgba(0, 0, 0, 0.30) 66%,
      rgba(0, 0, 0, 0) 84%
    ) !important;

  -webkit-mask-repeat: no-repeat !important;
  mask-repeat: no-repeat !important;

  -webkit-mask-size: 100% 100% !important;
  mask-size: 100% 100% !important;

  transition:
    opacity 220ms ease !important;

  transition-delay: 0ms !important;

  pointer-events: none !important;
}


.prototype-page-frame[data-game-frame-page] .game-info-background,
.prototype-page-frame[data-game-frame-page] .game-info-layer--rear,
.prototype-page-frame[data-game-frame-page] .game-info-layer--mid,
.prototype-page-frame[data-game-frame-page] .game-info::after {
  display: none !important;
}

.prototype-page-frame[data-game-frame-page] .desktop-secondary-panel-glass,
.prototype-page-frame[data-game-frame-page] .etherian-popout-glass-layer,
.prototype-page-frame[data-game-frame-page] .game-info-surface {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

#brobots-page-frame .brobots-popout-layer-image {
  opacity: 0.30;
}


/* =========================================================
   Generic game-info layered-glass geometry tokens
   ========================================================= */

/*
  These geometry variables were originally scoped to the Etherian panel,
  then copied to Halodoom. Brobots exposed the flaw: its layered panes were
  present, but the shared stack clip was missing the angle/run variables,
  so the outer diagonal edge treatment became invalid.

  Define them on the generic secondary-panel container instead. Existing
  Etherian-prefixed variable names are retained as compatibility aliases for
  the current pane CSS; future cleanup can rename those structural classes
  without changing behavior.
*/
@media (min-width: 1401px) {
  .prototype-page-frame .desktop-secondary-panel {
    --game-info-glass-angle:
      calc(
        var(--button-shear-angle) * -1
      );

    --game-info-stack-cut-rise:
      clamp(42px, 4.1vw, 68px);

    --game-info-stack-cut-run:
      calc(
        var(--game-info-stack-cut-rise)
        *
        tan(
          var(--game-info-glass-angle)
        )
      );

    /* Compatibility aliases used by the current shared pane rules. */
    --etherian-glass-angle:
      var(--game-info-glass-angle);

    --etherian-stack-cut-rise:
      var(--game-info-stack-cut-rise);

    --etherian-stack-cut-run:
      var(--game-info-stack-cut-run);
  }
}


/* =========================================================
   Generic game-info decorative screenshot layer
   ========================================================= */

/*
  The decorative image itself was still styled only through page-scoped
  Etherian/Halodoom selectors. Brobots therefore had the <img> element but
  not the positioning, clipping/mask, z-index, or overflow rules that make
  it appear as atmosphere inside pane 1.

  Keep the current structural class names for compatibility, but make the
  actual behavior generic for every game page.
*/
@media (min-width: 1401px) {
  .prototype-page-frame
  .etherian-popout-glass-layer--1 {
    overflow: hidden;
  }


  .prototype-page-frame
  .etherian-popout-layer-image {
    position: absolute;

    top: 0;
    right: 0;

    height: 100%;
    width: auto;

    max-width: none;
    max-height: none;

    display: block;

    object-fit: contain;
    object-position: top right;

    z-index: 0;

    opacity: 0.30;

    filter:
      saturate(0.92)
      contrast(0.96)
      brightness(0.88);

    -webkit-mask-image:
      radial-gradient(
        ellipse 78% 72%
        at 100% 0%,
        rgba(0, 0, 0, 1) 0%,
        rgba(0, 0, 0, 0.96) 30%,
        rgba(0, 0, 0, 0.72) 48%,
        rgba(0, 0, 0, 0.30) 66%,
        rgba(0, 0, 0, 0) 84%
      );

    mask-image:
      radial-gradient(
        ellipse 78% 72%
        at 100% 0%,
        rgba(0, 0, 0, 1) 0%,
        rgba(0, 0, 0, 0.96) 30%,
        rgba(0, 0, 0, 0.72) 48%,
        rgba(0, 0, 0, 0.30) 66%,
        rgba(0, 0, 0, 0) 84%
      );

    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;

    -webkit-mask-size: 100% 100%;
    mask-size: 100% 100%;

    pointer-events: none;
  }


  /*
    Preserve a soft glass veil above the screenshot.
  */
  .prototype-page-frame
  .etherian-popout-glass-layer--1::before {
    content: "";

    position: absolute;
    inset: 0;

    z-index: 1;

    background:
      linear-gradient(
        110deg,
        rgba(18, 30, 34, 0.22),
        rgba(
          var(--page-accent-rgb),
          0.055
        ) 48%,
        rgba(10, 18, 22, 0.10)
      );

    pointer-events: none;
  }
}


/*
  Shared desktop -> tablet handoff behavior for the decorative screenshot.
*/
.prototype-page-frame.is-layout-transitioning
.etherian-popout-layer-image {
  position: absolute !important;

  top: 0 !important;
  right: 0 !important;

  height: 100% !important;
  width: auto !important;

  max-width: none !important;
  max-height: none !important;

  display: block !important;

  object-fit: contain !important;
  object-position: top right !important;

  z-index: 0 !important;

  opacity: 0 !important;

  pointer-events: none !important;

  transition:
    opacity 220ms ease !important;

  transition-delay: 0ms !important;
}


@media (max-width: 1400px) {
  .prototype-page-frame:not(.is-layout-transitioning)
  .desktop-secondary-panel
  .etherian-popout-layer-image {
    display: none !important;
  }
}


/* =========================================================
   Brobots decorative screenshot — correct responsive visibility
   ========================================================= */

/*
  IMPORTANT:
  A previous selector-cloning pass accidentally stripped the original
  @media (max-width: 1400px) wrapper and made this display:none rule global.
  That meant the image had the correct src and styling but was literally
  hidden on desktop.

  Desktop: show it.
  Tablet: hide it once the responsive handoff has completed.
*/
@media (min-width: 1401px) {
  #brobots-page-frame:not(.is-layout-transitioning)
  .brobots-popout-layer-image {
    display: block !important;
  }
}


@media (max-width: 1400px) {
  #brobots-page-frame:not(.is-layout-transitioning)
  .desktop-secondary-panel
  .brobots-popout-layer-image {
    display: none !important;
  }
}


/* =========================================================
   Game info — stronger background image + base glass test
   ========================================================= */

/*
  Dedicated info artwork is intentionally more visible for this pass.
  Previous final value was 0.30.
*/
@media (min-width: 1401px) {
  #etherian-page-frame .etherian-popout-layer-image,
  #halodoom-page-frame .etherian-popout-layer-image,
  #brobots-page-frame .etherian-popout-layer-image {
    opacity: 0.60;
  }
}


/*
  The ORIGINAL morphing popout glass sits behind the decorative pane stack.
  Previous final fill was rgba(105, 118, 138, 0.24).

  JS reads --secondary-panel-fill when it builds the morph keyframes, so
  changing this variable updates both the resting panel and the final frame
  of the open/close animation without any separate JS timing changes.
*/
#etherian-page-frame,
#halodoom-page-frame,
#brobots-page-frame {
  --secondary-panel-fill:
    rgba(105, 118, 138, 0.48);
}


/* =========================================================
   Game info — 2x secondary layered-glass opacity test
   ========================================================= */

/*
  Current final pane opacities were:
    Layer 1: 0.50
    Layer 2: 0.58
    Layer 3: 0.64
    Layer 4: 0.70

  Doubling those values would exceed CSS's maximum opacity of 1 for layers
  2–4, so this test clamps each result to 1. The pane fills themselves
  remain translucent gradients; this only removes the extra whole-element
  transparency that was being applied on top of those fills.
*/
@media (min-width: 1401px) {
  #etherian-page-frame .etherian-popout-glass-layer--1,
  #halodoom-page-frame .etherian-popout-glass-layer--1,
  #brobots-page-frame .etherian-popout-glass-layer--1 {
    opacity: 1;
  }


  #etherian-page-frame .etherian-popout-glass-layer--2,
  #halodoom-page-frame .etherian-popout-glass-layer--2,
  #brobots-page-frame .etherian-popout-glass-layer--2 {
    opacity: 1;
  }


  #etherian-page-frame .etherian-popout-glass-layer--3,
  #halodoom-page-frame .etherian-popout-glass-layer--3,
  #brobots-page-frame .etherian-popout-glass-layer--3 {
    opacity: 1;
  }


  #etherian-page-frame .etherian-popout-glass-layer--4,
  #halodoom-page-frame .etherian-popout-glass-layer--4,
  #brobots-page-frame .etherian-popout-glass-layer--4 {
    opacity: 1;
  }
}


/* =========================================================
   Site background video — generic two-buffer crossfade
   ========================================================= */

:root {
  --background-video-crossfade-duration: 700ms;
}


/*
  Both video buffers occupy the exact same existing background aperture.
  The old visual opacity (0.62) now belongs only to the active buffer.
*/
.site-background-video {
  opacity: 0;

  transition:
    opacity
    var(--background-video-crossfade-duration)
    ease;

  will-change: opacity;
}


.site-background-video.is-background-active {
  opacity: 0.62;
}


/*
  Keep both buffers under the existing neutral veil.
*/
.site-background-video--a,
.site-background-video--b {
  z-index: 0;
}


.site-background::after {
  z-index: 1;
}


/*
  Avoid an animated fade for users who request reduced motion.
  The existing reduced-motion rule still suppresses decorative video.
*/
@media (prefers-reduced-motion: reduce) {
  .site-background-video {
    transition: none;
  }
}


/* =========================================================
   BROBOTS INNER PAGE FRAME — fixed pieces only v1
   =========================================================
   New sizing model:
   - The Brobots raster art belongs to ONE shared inner-frame area.
   - That area fills the available game-page media region inside the
     existing SVG page frame.
   - The media browser lives INSIDE that border.
   - No spacer assets yet.
   - No desktop/tablet layout promotion. Existing page behavior stays intact.
   ========================================================= */

.prototype-page-frame[data-game-frame-page] .game-frame-area {
  position: relative;

  /*
    Fill the available media region inside the existing page-frame content.
    The outer SVG/page frame remains the owner of the page geometry.
  */
  width: 100%;
  height: 100%;

  min-width: 0;
  min-height: 0;

  box-sizing: border-box;

  display: grid;
  place-items: center;
}


/*
  Keep the existing generic media browser as the live content layer.
  It is now inset inside the Brobots raster border instead of determining
  the border's outer dimensions.
*/
.prototype-page-frame[data-game-frame-page] .game-frame-area > .media-browser {
  position: relative;
  z-index: 1;

  width: min(78%, var(--media-composition-width));
  max-width: 100%;

  /*
    Give the whole gallery room within the raster border.
    Height remains content-driven by the existing media system.
  */
  margin: auto;
}


/* Shared border-piece behavior */
.prototype-page-frame[data-game-frame-page] .game-frame-piece {
  position: absolute;
  z-index: 2;

  display: block;

  max-width: none;
  max-height: none;

  height: auto;

  pointer-events: none;
  user-select: none;
}


/* =========================================================
   Native design canvas
   Full original frame: 1164 × 1149

   All fixed pieces scale against THIS shared inner-frame box.
   That makes the entire raster treatment shrink/grow with the existing
   SVG/page frame instead of with the media viewer.
   ========================================================= */

/* ---------------- HERO REGION ---------------- */

/*
  Native full-frame vertical split:
    Hero: 796
    Separator: 3
    Thumbs: 350
    Total: 1149

  So hero region occupies the top 796/1149 of this shared canvas.
*/
.prototype-page-frame[data-game-frame-page] .game-frame-piece--hero-top-left {
  top: 0;
  left: 0;

  width:
    calc(
      816 / 1164 * 100%
    );
}


.prototype-page-frame[data-game-frame-page] .game-frame-piece--hero-top-right {
  top: 0;
  right: 0;

  width:
    calc(
      344 / 1164 * 100%
    );
}


.prototype-page-frame[data-game-frame-page] .game-frame-piece--hero-bottom-left {
  /*
    Native hero bottom sits at y = 796.
    Place this piece relative to the shared full frame.
  */
  top:
    calc(
      (796 - 185) / 1149 * 100%
    );

  left: 0;

  width:
    calc(
      606 / 1164 * 100%
    );
}


.prototype-page-frame[data-game-frame-page] .game-frame-piece--hero-bottom-right {
  top:
    calc(
      (796 - 185) / 1149 * 100%
    );

  right: 0;

  width:
    calc(
      554 / 1164 * 100%
    );
}


/* ---------------- THUMB REGION ---------------- */

/*
  Thumbnail region begins at y = 799
  (796 hero + 3 separator).
*/
.prototype-page-frame[data-game-frame-page] .game-frame-piece--thumb-top-left {
  top:
    calc(
      799 / 1149 * 100%
    );

  left: 0;

  width:
    calc(
      588 / 1164 * 100%
    );
}


.prototype-page-frame[data-game-frame-page] .game-frame-piece--thumb-top-right {
  top:
    calc(
      799 / 1149 * 100%
    );

  right: 0;

  width:
    calc(
      567 / 1164 * 100%
    );
}


.prototype-page-frame[data-game-frame-page] .game-frame-piece--thumb-bottom-left {
  bottom: 0;
  left: 0;

  width:
    calc(
      590 / 1164 * 100%
    );
}


.prototype-page-frame[data-game-frame-page] .game-frame-piece--thumb-bottom-right {
  right: 0;
  bottom: 0;

  width:
    calc(
      568 / 1164 * 100%
    );
}


/* =========================================================
   Desktop/tablet fit inside the existing SVG frame
   ========================================================= */

/*
  Let the inner Brobots border behave like a genuine second page border.
  On desktop it occupies the available left/media side.
*/
@media (min-width: 1401px) {
  .prototype-page-frame[data-game-frame-page] .game-frame-area {
    /*
      The desktop page still has its normal two-column game layout.
      This wrapper only fills the media column it already receives.
    */
    align-self: stretch;
  }
}


/*
  Tablet keeps the original stacked layout and SVG frame.
  The raster border simply scales with the full available content box.
*/
@media (max-width: 1400px) {
  .prototype-page-frame[data-game-frame-page] .game-frame-area {
    width: 100%;

    /*
      Give the border a responsive aspect based on its native full design.
      Cap it by available content height so it remains inside the SVG frame.
    */
    aspect-ratio: 1164 / 1149;

    height: auto;

    max-height: 100%;

    margin: auto;
  }


  .prototype-page-frame[data-game-frame-page] .game-frame-area > .media-browser {
    width: 72%;
  }
}


/*
  Mobile remains untouched for now.
*/
@media (max-width: 750px) {
  .prototype-page-frame[data-game-frame-page] .game-frame-area {
    display: contents;
  }

  .prototype-page-frame[data-game-frame-page] .game-frame-piece {
    display: none;
  }

  .prototype-page-frame[data-game-frame-page] .game-frame-area > .media-browser {
    width: auto;
  }
}


/* =========================================================
   BROBOTS INNER PAGE FRAME v2 — ONE uniformly scaled canvas
   =========================================================
   Key rule:
   the fixed border art is authored on a 1164 × 1149 canvas and that
   ENTIRE canvas scales as one object.

   scale = min(
     available inner-frame width  / 1164,
     available inner-frame height / 1149
   )

   Therefore height can become the limiting dimension just like width,
   and the fixed pieces can never run into/overlap one another merely
   because the page became shorter.
   ========================================================= */

.prototype-page-frame[data-game-frame-page] .game-frame-area {
  position: relative;

  width: 100%;
  height: 100%;

  min-width: 0;
  min-height: 0;

  overflow: hidden;

  /*
    JS writes this. Keeping a harmless default avoids a flash of giant
    native-size artwork before the first ResizeObserver pass.
  */
  --brobots-inner-frame-scale: 0.5;
}


/*
  This is the actual 1164 × 1149 design coordinate system.
  Nothing inside it is independently responsive.
*/
#brobots-page-frame .brobots-inner-frame-canvas {
  position: absolute;
  z-index: 2;

  left: 50%;
  top: 50%;

  width: 1164px;
  height: 1149px;

  transform:
    translate(-50%, -50%)
    scale(var(--brobots-inner-frame-scale));

  transform-origin: center center;

  pointer-events: none;
}


/*
  Override the earlier percentage-based piece sizing completely.
  Every piece now renders at its actual source pixel size inside the
  native canvas. The canvas transform scales ALL of them together.
*/
#brobots-page-frame
.brobots-inner-frame-canvas
.game-frame-piece {
  position: absolute;

  width: auto !important;
  height: auto !important;

  max-width: none !important;
  max-height: none !important;

  transform: none !important;
}


/* ---------------- HERO native positions ---------------- */

#brobots-page-frame
.brobots-inner-frame-canvas
.game-frame-piece--hero-top-left {
  left: 0 !important;
  right: auto !important;
  top: 0 !important;
  bottom: auto !important;

  width: 816px !important;
  height: 606px !important;
}


#brobots-page-frame
.brobots-inner-frame-canvas
.game-frame-piece--hero-top-right {
  left: auto !important;
  right: 0 !important;
  top: 0 !important;
  bottom: auto !important;

  width: 344px !important;
  height: 607px !important;
}


#brobots-page-frame
.brobots-inner-frame-canvas
.game-frame-piece--hero-bottom-left {
  left: 0 !important;
  right: auto !important;
  top: 611px !important;
  bottom: auto !important;

  width: 606px !important;
  height: 185px !important;
}


#brobots-page-frame
.brobots-inner-frame-canvas
.game-frame-piece--hero-bottom-right {
  left: auto !important;
  right: 0 !important;
  top: 611px !important;
  bottom: auto !important;

  width: 554px !important;
  height: 185px !important;
}


/* ---------------- THUMB native positions ---------------- */

#brobots-page-frame
.brobots-inner-frame-canvas
.game-frame-piece--thumb-top-left {
  left: 0 !important;
  right: auto !important;
  top: 799px !important;
  bottom: auto !important;

  width: 588px !important;
  height: 144px !important;
}


#brobots-page-frame
.brobots-inner-frame-canvas
.game-frame-piece--thumb-top-right {
  left: auto !important;
  right: 0 !important;
  top: 799px !important;
  bottom: auto !important;

  width: 567px !important;
  height: 144px !important;
}


#brobots-page-frame
.brobots-inner-frame-canvas
.game-frame-piece--thumb-bottom-left {
  left: 0 !important;
  right: auto !important;
  top: 946px !important;
  bottom: auto !important;

  width: 590px !important;
  height: 203px !important;
}


#brobots-page-frame
.brobots-inner-frame-canvas
.game-frame-piece--thumb-bottom-right {
  left: auto !important;
  right: 0 !important;
  top: 946px !important;
  bottom: auto !important;

  width: 568px !important;
  height: 203px !important;
}


/*
  The live gallery remains an independent content layer.
  We are deliberately NOT making its dimensions control the border.
*/
.prototype-page-frame[data-game-frame-page]
.game-frame-area > .media-browser {
  position: relative;
  z-index: 1;

  width: min(78%, var(--media-composition-width));
  max-width: 100%;

  margin: auto;
}


/*
  Critical correction to v1:
  tablet must NOT force the Brobots inner frame to the 1164:1149 aspect.
  It fills whatever interior rectangle the existing SVG/page layout gives
  it; the native canvas then uniformly contains itself inside that area.
*/
@media (max-width: 1400px) {
  .prototype-page-frame[data-game-frame-page] .game-frame-area {
    width: 100%;
    height: 100%;

    aspect-ratio: auto;

    margin: 0;
  }

  .prototype-page-frame[data-game-frame-page]
  .game-frame-area > .media-browser {
    width: 72%;
  }
}


@media (max-width: 750px) {
  #brobots-page-frame .brobots-inner-frame-canvas {
    display: none;
  }
}


/* =========================================================
   BROBOTS INNER PAGE FRAME v3 — uniformly scaled, edge pinned
   =========================================================

   This is the intended behavior:

   1. Determine ONE uniform art scale from whichever available dimension
      is tighter:
        scale = min(width / 1164, height / 1149)

   2. Scale every fixed raster piece by that same scale.

   3. DO NOT center a scaled 1164×1149 canvas.
      Instead, pin left pieces to the ACTUAL left edge and right pieces
      to the ACTUAL right edge of the available inner-frame area.

   Therefore:
   - if width is limiting, the pieces nearly meet as in the native art
   - if height is limiting, the pieces shrink but remain edge-pinned,
     intentionally creating large horizontal gaps for future spacers
   ========================================================= */

.prototype-page-frame[data-game-frame-page] .game-frame-area {
  --brobots-fixed-scale: 0.5;

  position: relative;

  width: 100%;
  height: 100%;

  min-width: 0;
  min-height: 0;

  overflow: hidden;
}


/*
  Kill the v2 native-canvas geometry if any stale selector remains earlier
  in the stylesheet. The v3 HTML no longer contains that element.
*/
#brobots-page-frame .brobots-inner-frame-canvas {
  display: none !important;
}


/* ---------------------------------------------------------
   Fixed pieces use the ONE shared art scale.
   Positioning is against the real inner-frame area.
   --------------------------------------------------------- */

.prototype-page-frame[data-game-frame-page]
.game-frame-area > .game-frame-piece {
  position: absolute;
  z-index: 2;

  display: block;

  max-width: none !important;
  max-height: none !important;

  margin: 0 !important;

  pointer-events: none;
  user-select: none;

  transform: none !important;
}


/* ---------------- HERO ---------------- */

.prototype-page-frame[data-game-frame-page]
.game-frame-piece--hero-top-left {
  left: 0 !important;
  right: auto !important;
  top: 0 !important;
  bottom: auto !important;

  width:
    calc(
      816px *
      var(--brobots-fixed-scale)
    ) !important;

  height:
    calc(
      606px *
      var(--brobots-fixed-scale)
    ) !important;
}


.prototype-page-frame[data-game-frame-page]
.game-frame-piece--hero-top-right {
  left: auto !important;
  right: 0 !important;
  top: 0 !important;
  bottom: auto !important;

  width:
    calc(
      344px *
      var(--brobots-fixed-scale)
    ) !important;

  height:
    calc(
      607px *
      var(--brobots-fixed-scale)
    ) !important;
}


.prototype-page-frame[data-game-frame-page]
.game-frame-piece--hero-bottom-left {
  left: 0 !important;
  right: auto !important;

  top:
    calc(
      611px *
      var(--brobots-fixed-scale)
    ) !important;

  bottom: auto !important;

  width:
    calc(
      606px *
      var(--brobots-fixed-scale)
    ) !important;

  height:
    calc(
      185px *
      var(--brobots-fixed-scale)
    ) !important;
}


.prototype-page-frame[data-game-frame-page]
.game-frame-piece--hero-bottom-right {
  left: auto !important;
  right: 0 !important;

  top:
    calc(
      611px *
      var(--brobots-fixed-scale)
    ) !important;

  bottom: auto !important;

  width:
    calc(
      554px *
      var(--brobots-fixed-scale)
    ) !important;

  height:
    calc(
      185px *
      var(--brobots-fixed-scale)
    ) !important;
}


/* ---------------- THUMBNAILS ---------------- */

.prototype-page-frame[data-game-frame-page]
.game-frame-piece--thumb-top-left {
  left: 0 !important;
  right: auto !important;

  top:
    calc(
      799px *
      var(--brobots-fixed-scale)
    ) !important;

  bottom: auto !important;

  width:
    calc(
      588px *
      var(--brobots-fixed-scale)
    ) !important;

  height:
    calc(
      144px *
      var(--brobots-fixed-scale)
    ) !important;
}


.prototype-page-frame[data-game-frame-page]
.game-frame-piece--thumb-top-right {
  left: auto !important;
  right: 0 !important;

  top:
    calc(
      799px *
      var(--brobots-fixed-scale)
    ) !important;

  bottom: auto !important;

  width:
    calc(
      567px *
      var(--brobots-fixed-scale)
    ) !important;

  height:
    calc(
      144px *
      var(--brobots-fixed-scale)
    ) !important;
}


.prototype-page-frame[data-game-frame-page]
.game-frame-piece--thumb-bottom-left {
  left: 0 !important;
  right: auto !important;

  top:
    calc(
      946px *
      var(--brobots-fixed-scale)
    ) !important;

  bottom: auto !important;

  width:
    calc(
      590px *
      var(--brobots-fixed-scale)
    ) !important;

  height:
    calc(
      203px *
      var(--brobots-fixed-scale)
    ) !important;
}


.prototype-page-frame[data-game-frame-page]
.game-frame-piece--thumb-bottom-right {
  left: auto !important;
  right: 0 !important;

  top:
    calc(
      946px *
      var(--brobots-fixed-scale)
    ) !important;

  bottom: auto !important;

  width:
    calc(
      568px *
      var(--brobots-fixed-scale)
    ) !important;

  height:
    calc(
      203px *
      var(--brobots-fixed-scale)
    ) !important;
}


/*
  Existing live gallery remains independent for this fixed-piece test.
*/
.prototype-page-frame[data-game-frame-page]
.game-frame-area > .media-browser {
  position: relative;
  z-index: 1;

  width: min(78%, var(--media-composition-width));
  max-width: 100%;

  margin: auto;
}


@media (max-width: 1400px) {
  .prototype-page-frame[data-game-frame-page] .game-frame-area {
    width: 100%;
    height: 100%;

    aspect-ratio: auto;

    margin: 0;
  }

  .prototype-page-frame[data-game-frame-page]
  .game-frame-area > .media-browser {
    width: 72%;
  }
}


@media (max-width: 750px) {
  .prototype-page-frame[data-game-frame-page]
  .game-frame-area > .game-frame-piece {
    display: none;
  }
}


/* =========================================================
   BROBOTS INNER PAGE FRAME v4 — pin vertically as well
   =========================================================

   Horizontal behavior from v3 stays exactly the same:
   left pieces hug the real left edge, right pieces hug the real right edge.

   Vertical behavior now follows the same idea:

   HERO REGION
     top pieces    -> pin to real top edge
     bottom pieces -> pin to the hero-region bottom anchor

   THUMB REGION
     top pieces    -> pin to the thumb-region top anchor
     bottom pieces -> pin to the real bottom edge

   The hero/thumb anchors preserve the original 1164×1149 design's
   vertical division, while every raster piece keeps the same uniform
   --brobots-fixed-scale.

   If extra height exists, it becomes empty vertical space BETWEEN pieces
   rather than moving the whole native composition upward.
   ========================================================= */

.prototype-page-frame[data-game-frame-page] .game-frame-area {
  /*
    Original native vertical landmarks:
      hero end:    796 / 1149
      thumb start: 799 / 1149

    These are positions within the ACTUAL available inner-frame height,
    not within a centered 1149px canvas.
  */
  --brobots-hero-end-y:
    calc(796 / 1149 * 100%);

  --brobots-thumb-start-y:
    calc(799 / 1149 * 100%);
}


/* ---------------- HERO TOP: real top edge ---------------- */

.prototype-page-frame[data-game-frame-page]
.game-frame-piece--hero-top-left,
.prototype-page-frame[data-game-frame-page]
.game-frame-piece--hero-top-right {
  top: 0 !important;
  bottom: auto !important;
}


/* ---------------- HERO BOTTOM: pin to hero split ---------------- */

.prototype-page-frame[data-game-frame-page]
.game-frame-piece--hero-bottom-left,
.prototype-page-frame[data-game-frame-page]
.game-frame-piece--hero-bottom-right {
  top:
    calc(
      var(--brobots-hero-end-y)
      -
      (
        185px *
        var(--brobots-fixed-scale)
      )
    ) !important;

  bottom: auto !important;
}


/* ---------------- THUMB TOP: pin to thumb split ---------------- */

.prototype-page-frame[data-game-frame-page]
.game-frame-piece--thumb-top-left,
.prototype-page-frame[data-game-frame-page]
.game-frame-piece--thumb-top-right {
  top:
    var(--brobots-thumb-start-y) !important;

  bottom: auto !important;
}


/* ---------------- THUMB BOTTOM: real bottom edge ---------------- */

.prototype-page-frame[data-game-frame-page]
.game-frame-piece--thumb-bottom-left,
.prototype-page-frame[data-game-frame-page]
.game-frame-piece--thumb-bottom-right {
  top: auto !important;
  bottom: 0 !important;
}


/* =========================================================
   BROBOTS INNER PAGE FRAME v5 — stretchers restored
   =========================================================

   This keeps the successful v4 model:
   - one uniform art scale
   - left/right fixed pieces pinned to real left/right edges
   - top/bottom fixed pieces pinned to their real vertical anchors

   The stretchers now simply occupy the EMPTY gaps between those pinned
   pieces. Their thickness uses the exact same --brobots-fixed-scale.
   Only their flexible axis is stretched.
   ========================================================= */

.prototype-page-frame[data-game-frame-page]
.game-frame-area > .game-frame-piece {
  z-index: 3;
}


.prototype-page-frame[data-game-frame-page] .game-frame-stretcher {
  position: absolute;
  z-index: 2;

  display: block;

  margin: 0;
  padding: 0;

  pointer-events: none;
  user-select: none;

  background-image: var(--brobots-stretcher-image);
  background-repeat: no-repeat;
  background-position: center;
  background-size: 100% 100%;
}


/* =========================================================
   HERO — horizontal stretchers
   ========================================================= */

.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--hero-top {
  top: 0;

  left:
    calc(
      816px *
      var(--brobots-fixed-scale)
    );

  right:
    calc(
      344px *
      var(--brobots-fixed-scale)
    );

  height:
    calc(
      125px *
      var(--brobots-fixed-scale)
    );
}


.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--hero-bottom {
  left:
    calc(
      606px *
      var(--brobots-fixed-scale)
    );

  right:
    calc(
      554px *
      var(--brobots-fixed-scale)
    );

  top:
    calc(
      var(--brobots-hero-end-y)
      -
      (
        37px *
        var(--brobots-fixed-scale)
      )
    );

  height:
    calc(
      37px *
      var(--brobots-fixed-scale)
    );
}


/* =========================================================
   HERO — vertical stretchers
   ========================================================= */

.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--hero-left {
  left: 0;

  top:
    calc(
      606px *
      var(--brobots-fixed-scale)
    );

  width:
    calc(
      145px *
      var(--brobots-fixed-scale)
    );

  height:
    calc(
      var(--brobots-hero-end-y)
      -
      (
        185px *
        var(--brobots-fixed-scale)
      )
      -
      (
        606px *
        var(--brobots-fixed-scale)
      )
    );
}


.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--hero-right {
  right: 0;

  top:
    calc(
      607px *
      var(--brobots-fixed-scale)
    );

  width:
    calc(
      145px *
      var(--brobots-fixed-scale)
    );

  height:
    calc(
      var(--brobots-hero-end-y)
      -
      (
        185px *
        var(--brobots-fixed-scale)
      )
      -
      (
        607px *
        var(--brobots-fixed-scale)
      )
    );
}


/* =========================================================
   THUMBNAILS — horizontal stretchers
   ========================================================= */

.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--thumb-top {
  left:
    calc(
      588px *
      var(--brobots-fixed-scale)
    );

  right:
    calc(
      567px *
      var(--brobots-fixed-scale)
    );

  top:
    var(--brobots-thumb-start-y);

  height:
    calc(
      51px *
      var(--brobots-fixed-scale)
    );
}


.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--thumb-bottom {
  left:
    calc(
      590px *
      var(--brobots-fixed-scale)
    );

  right:
    calc(
      568px *
      var(--brobots-fixed-scale)
    );

  bottom: 0;

  height:
    calc(
      105px *
      var(--brobots-fixed-scale)
    );
}


/* =========================================================
   THUMBNAILS — vertical stretchers
   ========================================================= */

.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--thumb-left {
  left: 0;

  top:
    calc(
      var(--brobots-thumb-start-y)
      +
      (
        144px *
        var(--brobots-fixed-scale)
      )
    );

  bottom:
    calc(
      203px *
      var(--brobots-fixed-scale)
    );

  width:
    calc(
      98px *
      var(--brobots-fixed-scale)
    );
}


.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--thumb-right {
  right: 0;

  top:
    calc(
      var(--brobots-thumb-start-y)
      +
      (
        144px *
        var(--brobots-fixed-scale)
      )
    );

  bottom:
    calc(
      203px *
      var(--brobots-fixed-scale)
    );

  width:
    calc(
      100px *
      var(--brobots-fixed-scale)
    );
}


/* =========================================================
   CENTER SEPARATOR
   ========================================================= */

.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--separator {
  left: 0;
  right: 0;

  top:
    calc(
      (
        var(--brobots-hero-end-y)
        +
        var(--brobots-thumb-start-y)
      )
      / 2
      -
      (
        1px *
        var(--brobots-fixed-scale)
      )
    );

  height:
    calc(
      2px *
      var(--brobots-fixed-scale)
    );
}


/* Hide the raster frame experiment on mobile exactly as before. */
@media (max-width: 750px) {
  .prototype-page-frame[data-game-frame-page] .game-frame-stretcher {
    display: none;
  }
}


/* =========================================================
   REUSABLE FRAME — LEGACY CASCADE BRIDGE
   =========================================================

   The v10-v15 rules below predate the final component checkpoint but still
   participate in the CURRENT frame: measured piece dimensions, fixed-piece
   pinning, stretcher flexible-axis geometry, repeat mode and separator fill.

   Brobots was still receiving these through #brobots-page-frame. The other
   game-frame instances were not, which is why their media aperture could be
   correct while the raster skin itself assembled at the wrong scale.

   Only selectors that target the current .game-frame-* DOM are shared here.
   Older abandoned .brobots-inner-frame-canvas experiments remain isolated.
   ========================================================= */

/* =========================================================
   BROBOTS INNER PAGE FRAME v10 — dynamic piece dimensions
   =========================================================
   Overall frame reference remains 1164 × 1149.

   Individual fixed-piece and stretcher dimensions are now supplied by JS
   from the ACTUAL raster files at runtime.

   This means adding/removing transparent padding around a cut asset no
   longer requires updating hardcoded CSS width/height values.
   ========================================================= */

/* Fixed pieces: JS writes width/height and some anchor dimensions. */
.prototype-page-frame[data-game-frame-page]
.game-frame-area > [data-game-frame-piece] {
  width: var(--brobots-piece-w, auto) !important;
  height: var(--brobots-piece-h, auto) !important;
}


/* Hero bottom rows use measured piece height for vertical pinning. */
.prototype-page-frame[data-game-frame-page]
.game-frame-piece--hero-bottom-left,
.prototype-page-frame[data-game-frame-page]
.game-frame-piece--hero-bottom-right {
  top:
    calc(
      var(--brobots-hero-end-y)
      -
      var(--brobots-piece-h)
    ) !important;
}


/* Thumb top rows still use the shared split anchor. */
.prototype-page-frame[data-game-frame-page]
.game-frame-piece--thumb-top-left,
.prototype-page-frame[data-game-frame-page]
.game-frame-piece--thumb-top-right {
  top:
    var(--brobots-thumb-start-y) !important;
}


/* Bottom thumb pieces stay pinned to the actual bottom edge. */
.prototype-page-frame[data-game-frame-page]
.game-frame-piece--thumb-bottom-left,
.prototype-page-frame[data-game-frame-page]
.game-frame-piece--thumb-bottom-right {
  top: auto !important;
  bottom: 0 !important;
}


/* =========================================================
   Stretchers use measured natural cross-axis dimensions.
   Their flexible axis is still defined entirely by pinned neighbors.
   ========================================================= */

.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--hero-top {
  left:
    var(--brobots-hero-top-left-w);

  right:
    var(--brobots-hero-top-right-w);

  height:
    var(--brobots-stretcher-h);
}


.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--hero-bottom {
  left:
    var(--brobots-hero-bottom-left-w);

  right:
    var(--brobots-hero-bottom-right-w);

  top:
    calc(
      var(--brobots-hero-end-y)
      -
      var(--brobots-stretcher-h)
    );

  height:
    var(--brobots-stretcher-h);
}


.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--hero-left {
  top:
    var(--brobots-hero-top-left-h);

  width:
    var(--brobots-stretcher-w);

  height:
    calc(
      var(--brobots-hero-end-y)
      -
      var(--brobots-hero-bottom-left-h)
      -
      var(--brobots-hero-top-left-h)
    );
}


.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--hero-right {
  top:
    var(--brobots-hero-top-right-h);

  width:
    var(--brobots-stretcher-w);

  height:
    calc(
      var(--brobots-hero-end-y)
      -
      var(--brobots-hero-bottom-right-h)
      -
      var(--brobots-hero-top-right-h)
    );
}


.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--thumb-top {
  left:
    var(--brobots-thumb-top-left-w);

  right:
    var(--brobots-thumb-top-right-w);

  top:
    var(--brobots-thumb-start-y);

  height:
    var(--brobots-stretcher-h);
}


.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--thumb-bottom {
  left:
    var(--brobots-thumb-bottom-left-w);

  right:
    var(--brobots-thumb-bottom-right-w);

  bottom: 0;

  height:
    var(--brobots-stretcher-h);
}


.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--thumb-left {
  top:
    calc(
      var(--brobots-thumb-start-y)
      +
      var(--brobots-thumb-top-left-h)
    );

  bottom:
    var(--brobots-thumb-bottom-left-h);

  width:
    var(--brobots-stretcher-w);
}


.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--thumb-right {
  top:
    calc(
      var(--brobots-thumb-start-y)
      +
      var(--brobots-thumb-top-right-h)
    );

  bottom:
    var(--brobots-thumb-bottom-right-h);

  width:
    var(--brobots-stretcher-w);
}


/* =========================================================
   BROBOTS INNER PAGE FRAME v11 — restore crisp stretchers
   =========================================================

   Keep v10's dynamic natural-size measurement.

   Restore ONLY the rendering change that fixed the blurry bars:
   - horizontal spacer samples repeat along X
   - vertical spacer samples repeat along Y
   - only their cross-axis thickness is scaled
   - do NOT stretch a 3px/5px sample across the entire flexible gap

   No seam overlap, phase anchoring, or pixel snapping is reintroduced.
   ========================================================= */


/* Horizontal stretcher samples */
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--hero-top,
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--hero-bottom,
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--thumb-top,
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--thumb-bottom {
  background-repeat: repeat-x !important;
  background-position: center !important;

  /*
    Natural source width remains unscaled by CSS.
    JS supplies the measured/scaled source HEIGHT through
    --brobots-stretcher-h.
  */
  background-size:
    auto
    var(--brobots-stretcher-h) !important;
}


/* Vertical stretcher samples */
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--hero-left,
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--hero-right,
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--thumb-left,
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--thumb-right {
  background-repeat: repeat-y !important;
  background-position: center !important;

  /*
    JS supplies the measured/scaled source WIDTH through
    --brobots-stretcher-w.
  */
  background-size:
    var(--brobots-stretcher-w)
    auto !important;
}


/*
  Separator is already a long source strip, so keep stretching it once.
*/
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--separator {
  background-repeat: no-repeat !important;
  background-position: center !important;
  background-size: 100% 100% !important;
}


/* =========================================================
   BROBOTS INNER PAGE FRAME v12 — full-width center separator
   =========================================================

   The separator source is already essentially the full native frame width.
   Treat it as one continuous strip and force its element to span the entire
   available Brobots inner-frame width.

   Its source image is stretched once to that width; no tiling.
   Its height comes from the runtime-measured natural image height.
   ========================================================= */

.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--separator {
  left: 0 !important;
  right: auto !important;

  width: 100% !important;

  height:
    var(--brobots-stretcher-h) !important;

  background-repeat: no-repeat !important;
  background-position: left center !important;
  background-size: 100% 100% !important;
}


/* =========================================================
   BROBOTS INNER PAGE FRAME v13 — separator actually measured
   =========================================================

   v12 referenced --brobots-stretcher-h on the center separator, but the
   separator was never included in the runtime-measured stretcher set.

   v13 adds it to that set in HTML and ensures it renders as the intended
   full-width stretch-separator.webp strip.
   ========================================================= */

.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--separator {
  left: 0 !important;
  right: auto !important;

  width: 100% !important;

  /*
    Now populated from stretch-separator.webp's real natural height.
  */
  height: var(--brobots-stretcher-h) !important;

  background-image:
    var(--brobots-stretcher-image) !important;

  background-repeat: no-repeat !important;
  background-position: left center !important;
  background-size: 100% 100% !important;

  /*
    Keep it visible above the surrounding fixed bars. The image itself
    supplies the visual seam; this does not alter its geometry.
  */
  z-index: 4 !important;
}


/* =========================================================
   BROBOTS INNER PAGE FRAME v14 — corrected native separator
   =========================================================

   stretch-separator.webp has now been corrected to the full native
   1164px frame width.

   Remove the previous compensation behavior. The separator now follows
   the same native-scale model as the rest of the frame:
     rendered width  = 1164px * --brobots-fixed-scale
     rendered height = naturalHeight * --brobots-fixed-scale

   Because the source itself matches the full-frame reference width,
   internal details keep their original X positions.
   ========================================================= */

.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--separator {
  left: 0 !important;
  right: auto !important;

  width:
    calc(
      1164px *
      var(--brobots-fixed-scale)
    ) !important;

  height:
    var(--brobots-stretcher-h) !important;

  background-image:
    var(--brobots-stretcher-image) !important;

  background-repeat: no-repeat !important;
  background-position: left center !important;
  background-size: 100% 100% !important;

  z-index: 4 !important;
}


/* =========================================================
   BROBOTS INNER PAGE FRAME v15 — separator fills its anchor gap
   =========================================================

   The two dark lines were not caused by the separator image height itself.

   Earlier versions still positioned the separator using the old 2px-source
   assumption:
      midpoint of the 3px native gap - 1px

   So changing the source image height could not remove the empty sliver(s).

   The separator is a true flexible bridge, so its BOX should span the exact
   vertical gap between the hero and thumbnail regions, then stretch the
   raster to fill that box.
   ========================================================= */

.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--separator {
  left: 0 !important;
  right: 0 !important;

  width: auto !important;

  top:
    var(--brobots-hero-end-y) !important;

  bottom:
    calc(
      100%
      -
      var(--brobots-thumb-start-y)
    ) !important;

  height: auto !important;

  background-image:
    var(--brobots-stretcher-image) !important;

  background-repeat: no-repeat !important;
  background-position: center !important;
  background-size: 100% 100% !important;

  z-index: 4 !important;
}

/* =========================================================
   BROBOTS — FINAL DESKTOP/TABLET MEDIA FRAME
/*
  MULTI-INSTANCE CONTRACT
  -----------------------
  Everything from this checkpoint onward belongs to the reusable raster-frame
  / tablet presentation component. Page-specific content and theme rules may
  still live elsewhere, but frame geometry/layout must never be scoped to one
  project id here.
*/

   Stable checkpoint before tablet integration
   =========================================================

   Architecture
   ------------
   - 17 raster pieces form the visible Brobots media frame.
   - JS reads source-image dimensions once.
   - CSS container units resize the raster frame continuously.
   - Hero + thumbnail apertures derive from the SAME frame geometry.
   - The old Simulacrum SVG page shell remains in the DOM as the hidden
     page/button + PC/tablet morph target.
   - Mobile keeps the generic gallery layout, except during the outgoing
     collapse handoff where the last tablet/desktop composition is frozen.
   ========================================================= */


/* ---------------------------------------------------------
   Frame area + layer ownership
   --------------------------------------------------------- */

.prototype-page-frame[data-game-frame-page] .game-frame-area {
  position: relative;

  width: 100%;
  height: 100%;

  min-width: 0;
  min-height: 0;

  overflow: hidden;

  container-type: size;
}


.prototype-page-frame[data-game-frame-page]
.game-frame-area > .media-browser {
  position: absolute;

  z-index: 1;

  inset: 0;

  width: 100% !important;
  height: 100% !important;

  max-width: none;

  margin: 0;
  padding: 0;

  display: block;

  overflow: visible;

  /*
    Generic thumbnail typography / small metrics still read this token.
    The actual Brobots rail geometry is controlled independently below.
  */
  --media-composition-width:
    var(
      --brobots-thumb-strip-width,
      520px
    );

  pointer-events: none;
}


.prototype-page-frame[data-game-frame-page] .game-frame-piece,
.prototype-page-frame[data-game-frame-page] .game-frame-stretcher {
  z-index: 3;
}


/* ---------------------------------------------------------
   Media zones
   --------------------------------------------------------- */

.prototype-page-frame[data-game-frame-page] .game-media-zone {
  position: absolute;

  display: grid;
  place-items: center;

  min-width: 0;
  min-height: 0;

  container-type: size;

  pointer-events: none;
}


/*
  Hero aperture = exact space between the four hero stretchers.
*/
.prototype-page-frame[data-game-frame-page] .game-media-zone--hero {
  left:
    var(
      --brobots-hero-left-rail-w,
      0px
    );

  right:
    var(
      --brobots-hero-right-rail-w,
      0px
    );

  top:
    var(
      --brobots-hero-top-bar-h,
      0px
    );

  bottom:
    calc(
      100%
      -
      var(--brobots-hero-end-y)
      +
      var(
        --brobots-hero-bottom-bar-h,
        0px
      )
    );

  width: auto;
  height: auto;
}


/*
  Thumbnail aperture = exact space between the four thumbnail stretchers.
*/
.prototype-page-frame[data-game-frame-page] .game-media-zone--thumbs {
  left:
    var(
      --brobots-thumb-left-rail-w,
      0px
    );

  right:
    var(
      --brobots-thumb-right-rail-w,
      0px
    );

  top:
    calc(
      var(--brobots-thumb-start-y)
      +
      var(
        --brobots-thumb-top-bar-h,
        0px
      )
    );

  bottom:
    var(
      --brobots-thumb-bottom-bar-h,
      0px
    );

  width: auto;
  height: auto;

  container-type: size;
  container-name: brobots-thumb-cavity;


  /*
    Arrow positions remain tied continuously to the current side-rail
    thicknesses rather than to viewport breakpoints.
  */
  --brobots-thumb-left-arrow-offset:
    max(
      8px,
      calc(
        var(
          --brobots-thumb-left-rail-w,
          0px
        )
        * 0.18
      )
    );

  --brobots-thumb-right-arrow-offset:
    max(
      8px,
      calc(
        var(
          --brobots-thumb-right-rail-w,
          0px
        )
        * 0.18
      )
    );

  --brobots-thumb-arrow-size:
    clamp(
      28px,
      min(
        5.2cqw,
        34cqh
      ),
      64px
    );

  --brobots-thumb-arrow-card-gap:
    clamp(
      10px,
      1.35cqw,
      24px
    );

  --brobots-thumb-card-gap:
    clamp(
      12px,
      1.45cqw,
      28px
    );
}


/* ---------------------------------------------------------
   Hero viewer
   --------------------------------------------------------- */

.prototype-page-frame[data-game-frame-page]
.game-media-zone--hero
.media-viewer {
  width: 100cqw !important;
  height: 100cqh !important;

  max-width: none;
  max-height: none;

  aspect-ratio: auto !important;

  margin: 0;

  justify-self: stretch;
  align-self: stretch;

  /*
    Small centered bleed hides antialiasing / measurement slivers beneath
    the raster artwork without changing the layout box itself.
  */
  transform:
    scale(1.04);

  transform-origin:
    50% 50%;

  clip-path: none !important;

  border-radius:
    clamp(
      28px,
      4.4cqw,
      48px
    );

  border:
    1px solid
    rgba(
      var(--page-accent-rgb),
      0.60
    );

  box-shadow:
    inset 0 0 0 1px
      rgba(255, 255, 255, 0.08);

  overflow: hidden;

  /*
    Resize must track the raster frame directly; generic gallery width /
    aspect easing would visibly lag during a fast drag.
  */
  transition: none !important;

  pointer-events: auto;
}


.prototype-page-frame[data-game-frame-page]
.game-media-zone--hero
.media-viewer-stage {
  position: absolute;

  inset: 0;

  display: block;

  border-radius: inherit;
}


.prototype-page-frame[data-game-frame-page]
.game-media-zone--hero
.media-viewer-image,
.prototype-page-frame[data-game-frame-page]
.game-media-zone--hero
.media-viewer-video {
  position: absolute;

  left: 50%;
  top: 50%;

  width: 100% !important;
  height: 100% !important;

  max-width: none;
  max-height: none;

  display: block;

  transform:
    translate(-50%, -50%);

  object-fit: cover !important;
  object-position: 50% 50% !important;

  border-radius: inherit;
}


/*
  YouTube equivalent of object-fit: cover.
*/
.prototype-page-frame[data-game-frame-page]
.game-media-zone--hero
.media-viewer-youtube {
  position: absolute;

  left: 50%;
  top: 50%;

  width:
    max(
      100%,
      calc(100cqh * 16 / 9)
    );

  height:
    max(
      100%,
      calc(100cqw * 9 / 16)
    );

  max-width: none;
  max-height: none;

  aspect-ratio: 16 / 9;

  transform:
    translate(-50%, -50%);

  border-radius: inherit;
}


.prototype-page-frame[data-game-frame-page]
.game-media-zone--hero
.media-youtube-local-fallback,
.prototype-page-frame[data-game-frame-page]
.game-media-zone--hero
.media-youtube-local-fallback-image {
  border-radius: inherit;
}


.prototype-page-frame[data-game-frame-page]
.game-media-zone--hero
.media-youtube-local-fallback-image {
  object-fit: cover;
  object-position: center center;
}


/* ---------------------------------------------------------
   Thumbnail composition
   --------------------------------------------------------- */

/*
  Full aperture becomes the thumbnail composition canvas.
*/
.prototype-page-frame[data-game-frame-page]
.game-media-zone--thumbs
.media-strip {
  position: absolute;

  inset: 0;

  width: 100% !important;
  height: 100%;

  max-width: none;

  display: block;

  margin: 0;

  transition: none !important;

  pointer-events: auto;
}


/*
  Arrows are fixed relative to the live aperture / side rails.
*/
.prototype-page-frame[data-game-frame-page]
.game-media-zone--thumbs
.media-arrow {
  position: absolute;

  z-index: 3;

  top: 50%;

  width:
    var(--brobots-thumb-arrow-size);

  height:
    var(--brobots-thumb-arrow-size);

  margin: 0;
  padding: 0;

  font-size:
    clamp(
      24px,
      min(
        3.6cqw,
        24cqh
      ),
      54px
    );

  line-height: 1;

  transform:
    translateY(-50%);

  pointer-events: auto;
}


.prototype-page-frame[data-game-frame-page]
.game-media-zone--thumbs
.media-arrow--previous {
  left:
    var(--brobots-thumb-left-arrow-offset);
}


.prototype-page-frame[data-game-frame-page]
.game-media-zone--thumbs
.media-arrow--next {
  right:
    var(--brobots-thumb-right-arrow-offset);
}


.prototype-page-frame[data-game-frame-page]
.game-media-zone--thumbs
.media-arrow:hover,
.prototype-page-frame[data-game-frame-page]
.game-media-zone--thumbs
.media-arrow:focus-visible {
  transform:
    translateY(-50%)
    scale(1.06);
}


/*
  Exactly three visible cards live continuously between the anchored arrows.
*/
.prototype-page-frame[data-game-frame-page]
.game-media-zone--thumbs
.media-thumbnails {
  position: absolute;

  top: 0;
  bottom: 0;

  left:
    calc(
      var(--brobots-thumb-left-arrow-offset)
      +
      var(--brobots-thumb-arrow-size)
      +
      var(--brobots-thumb-arrow-card-gap)
    );

  right:
    calc(
      var(--brobots-thumb-right-arrow-offset)
      +
      var(--brobots-thumb-arrow-size)
      +
      var(--brobots-thumb-arrow-card-gap)
    );

  width: auto;
  height: 100%;

  container-type: size;
  container-name: brobots-thumb-rail;

  grid-auto-columns:
    calc(
      (
        100%
        -
        (
          var(--brobots-thumb-card-gap)
          *
          2
        )
      )
      /
      3
    );

  gap:
    var(--brobots-thumb-card-gap);

  align-items: center;

  transition: none !important;
}


.prototype-page-frame[data-game-frame-page]
.game-media-zone--thumbs
.media-thumbnail {
  width: 100%;

  height:
    76cqh;

  max-height:
    calc(
      100cqh
      -
      8px
    );

  aspect-ratio: auto;

  padding:
    clamp(
      4px,
      0.55cqh,
      8px
    );

  clip-path: none !important;

  border-radius:
    clamp(
      7px,
      1.2cqw,
      12px
    );

  overflow: hidden;

  pointer-events: auto;
}


.prototype-page-frame[data-game-frame-page]
.game-media-zone--thumbs
.media-thumbnail-image,
.prototype-page-frame[data-game-frame-page]
.game-media-zone--thumbs
.media-thumbnail-local-video {
  width: 100%;
  height: 100%;

  object-fit: cover;
  object-position: 50% 50%;

  border-radius: inherit;
}


.prototype-page-frame[data-game-frame-page]
.game-media-zone--thumbs
.media-thumbnail-overlay {
  border-radius: inherit;
}


/* ---------------------------------------------------------
   Raster frame replaces visible Simulacrum shell
   --------------------------------------------------------- */

/*
  Keep the SVG shell alive as geometry / animation infrastructure.
*/
.prototype-page-frame[data-game-frame-page] .prototype-page-frame-shell {
  opacity: 0;
}


/*
  The visible raster frame reclaims almost all of the old SVG-border space.
*/
.prototype-page-frame[data-game-frame-page] .prototype-page-frame-content {
  top:
    clamp(
      6px,
      0.65cqw,
      12px
    );

  right:
    clamp(
      6px,
      0.65cqw,
      12px
    );

  bottom:
    clamp(
      6px,
      0.65cqw,
      12px
    );

  left:
    clamp(
      6px,
      0.65cqw,
      12px
    );
}


.prototype-page-frame[data-game-frame-page] .game-page--brobots,
.prototype-page-frame[data-game-frame-page] .game-frame-area {
  width: 100%;
  height: 100%;
}


/* ---------------------------------------------------------
   Desktop info-popout alignment
   --------------------------------------------------------- */

@media (min-width: 1401px) {
  .prototype-page-frame[data-game-frame-page] .desktop-secondary-panel {
    top: 7.75%;
    bottom: 7.75%;
  }
}


/*
  This MUST remain outside the desktop query: when PC -> tablet crosses the
  breakpoint, the outgoing popout is still alive for its reverse morph.
*/
.prototype-page-frame[data-game-frame-page].is-layout-transitioning
.desktop-secondary-panel {
  top: 7.75% !important;
  bottom: 7.75% !important;
}


/* ---------------------------------------------------------
   Mobile base layout
   --------------------------------------------------------- */

@media (max-width: 750px) {

  /*
    Mobile currently uses the generic gallery rather than the 17-piece
    raster frame.
  */
  .prototype-page-frame[data-game-frame-page] .prototype-page-frame-shell {
    opacity: 1;
  }


  .prototype-page-frame[data-game-frame-page] .prototype-page-frame-content {
    top:
      var(--page-content-top, 48px);

    right:
      var(--page-content-right, 48px);

    bottom:
      var(--page-content-bottom, 48px);

    left:
      var(--page-content-left, 48px);
  }


  .prototype-page-frame[data-game-frame-page]
  .game-frame-area > .media-browser {
    position: static;

    width: auto !important;
    height: auto !important;

    display: flex;

    padding:
      var(--media-browser-outer-padding);

    overflow: hidden;

    pointer-events: auto;
  }


  .prototype-page-frame[data-game-frame-page] .game-media-zone {
    position: static;

    display: contents;

    container-type: normal;
  }


  .prototype-page-frame[data-game-frame-page] .media-viewer {
    width:
      min(
        var(--media-composition-width),
        calc(
          var(--media-composition-width)
          * 0.5625
          * var(--media-viewer-aspect-number)
        )
      ) !important;

    height: auto !important;

    aspect-ratio:
      var(--media-viewer-aspect-number)
      !important;

    transform: none;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-media-zone--hero
  .media-viewer-stage {
    position: absolute;

    inset: 0;

    display: grid;
    place-items: center;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-media-zone--hero
  .media-viewer-image,
  .prototype-page-frame[data-game-frame-page]
  .game-media-zone--hero
  .media-viewer-video {
    position: static;

    width: 100% !important;
    height: 100% !important;

    transform: none;

    object-fit: contain !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-media-zone--hero
  .media-viewer-youtube {
    position: static;

    width: 100%;
    height: 100%;

    transform: none;
  }


  .prototype-page-frame[data-game-frame-page] .media-strip {
    width:
      var(--media-composition-width)
      !important;
  }
}


/* ---------------------------------------------------------
   Outgoing tablet/desktop -> mobile handoff hold — simplified
   --------------------------------------------------------- */

@media (max-width: 750px) {

  /*
    The old hold block reconstructed the entire desktop/tablet media browser
    (hero + thumbnail rail) for a few frames while ownership transferred to
    the mobile collapse animation.

    That media presentation is no longer part of the tablet landing design,
    so preserving it here only caused obsolete UI to flash before fading.

    Keep ONLY the outer frame/content geometry hold required by the page
    morph. The media browser is allowed to follow its normal mobile rules
    immediately instead of being rebuilt as the old tablet composition.
  */
  .prototype-page-frame[data-game-frame-page].is-mobile-collapse-hold
  .prototype-page-frame-shell {
    opacity: 0 !important;
  }


  .prototype-page-frame[data-game-frame-page].is-mobile-collapse-hold
  .prototype-page-frame-content {
    top:
      clamp(
        6px,
        0.65cqw,
        12px
      ) !important;

    right:
      clamp(
        6px,
        0.65cqw,
        12px
      ) !important;

    bottom:
      clamp(
        6px,
        0.65cqw,
        12px
      ) !important;

    left:
      clamp(
        6px,
        0.65cqw,
        12px
      ) !important;
  }
}


/* =========================================================
   BROBOTS TABLET INFO — CLEAN STEP 1 / VIRTUAL RESIZE
   =========================================================

   IMPORTANT:
   Desktop is intentionally untouched by this entire block.

   Normal frame sizing already works perfectly when the browser is resized:
     scale = min(frame width / native width, frame height / native height)

   Tablet-info simply feeds that SAME idea a deliberate virtual height:
     scale = min(
       frame width / native full-frame width,
       30% frame height / native HERO height
     )

   One 0->1 progress value blends from the proven normal resize result to
   that virtual-resize result. Every fixed piece, every stretcher thickness,
   every stretcher anchor and the separator use that SAME progress.
   ========================================================= */

@property --brobots-tablet-frame-progress {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}


@media (max-width: 1400px) {

  .prototype-page-frame[data-game-frame-page] .game-frame-area {
    --brobots-tablet-info-split-ratio:
      0.30;

    --brobots-tablet-info-hero-end-y:
      calc(
        100cqh
        *
        var(
          --brobots-tablet-info-split-ratio
        )
      );

    --brobots-tablet-info-thumb-start-y:
      calc(
        var(--brobots-tablet-info-hero-end-y)
        +
        max(
          var(
            --brobots-separator-h-info,
            0px
          ),
          2px
        )
      );

    --brobots-tablet-frame-progress:
      0;

    transition:
      --brobots-tablet-frame-progress
        720ms
        cubic-bezier(0.18, 0.78, 0.22, 1);


    /*
      Split position follows the same master progress as raster scale.
    */
    --brobots-hero-end-live-y:
      calc(
        var(--brobots-hero-end-base-y)
        +
        (
          var(--brobots-tablet-info-hero-end-y)
          -
          var(--brobots-hero-end-base-y)
        )
        *
        var(--brobots-tablet-frame-progress)
      );

    --brobots-thumb-start-live-y:
      calc(
        var(--brobots-thumb-start-base-y)
        +
        (
          var(--brobots-tablet-info-thumb-start-y)
          -
          var(--brobots-thumb-start-base-y)
        )
        *
        var(--brobots-tablet-frame-progress)
      );


    /* Fixed-piece anchor dimensions. */
    --brobots-hero-top-left-w-live:
      calc(var(--brobots-hero-top-left-w-base) + (var(--brobots-hero-top-left-w-info) - var(--brobots-hero-top-left-w-base)) * var(--brobots-tablet-frame-progress));
    --brobots-hero-top-left-h-live:
      calc(var(--brobots-hero-top-left-h-base) + (var(--brobots-hero-top-left-h-info) - var(--brobots-hero-top-left-h-base)) * var(--brobots-tablet-frame-progress));

    --brobots-hero-top-right-w-live:
      calc(var(--brobots-hero-top-right-w-base) + (var(--brobots-hero-top-right-w-info) - var(--brobots-hero-top-right-w-base)) * var(--brobots-tablet-frame-progress));
    --brobots-hero-top-right-h-live:
      calc(var(--brobots-hero-top-right-h-base) + (var(--brobots-hero-top-right-h-info) - var(--brobots-hero-top-right-h-base)) * var(--brobots-tablet-frame-progress));

    --brobots-hero-bottom-left-w-live:
      calc(var(--brobots-hero-bottom-left-w-base) + (var(--brobots-hero-bottom-left-w-info) - var(--brobots-hero-bottom-left-w-base)) * var(--brobots-tablet-frame-progress));
    --brobots-hero-bottom-left-h-live:
      calc(var(--brobots-hero-bottom-left-h-base) + (var(--brobots-hero-bottom-left-h-info) - var(--brobots-hero-bottom-left-h-base)) * var(--brobots-tablet-frame-progress));

    --brobots-hero-bottom-right-w-live:
      calc(var(--brobots-hero-bottom-right-w-base) + (var(--brobots-hero-bottom-right-w-info) - var(--brobots-hero-bottom-right-w-base)) * var(--brobots-tablet-frame-progress));
    --brobots-hero-bottom-right-h-live:
      calc(var(--brobots-hero-bottom-right-h-base) + (var(--brobots-hero-bottom-right-h-info) - var(--brobots-hero-bottom-right-h-base)) * var(--brobots-tablet-frame-progress));

    --brobots-thumb-top-left-w-live:
      calc(var(--brobots-thumb-top-left-w-base) + (var(--brobots-thumb-top-left-w-info) - var(--brobots-thumb-top-left-w-base)) * var(--brobots-tablet-frame-progress));
    --brobots-thumb-top-left-h-live:
      calc(var(--brobots-thumb-top-left-h-base) + (var(--brobots-thumb-top-left-h-info) - var(--brobots-thumb-top-left-h-base)) * var(--brobots-tablet-frame-progress));

    --brobots-thumb-top-right-w-live:
      calc(var(--brobots-thumb-top-right-w-base) + (var(--brobots-thumb-top-right-w-info) - var(--brobots-thumb-top-right-w-base)) * var(--brobots-tablet-frame-progress));
    --brobots-thumb-top-right-h-live:
      calc(var(--brobots-thumb-top-right-h-base) + (var(--brobots-thumb-top-right-h-info) - var(--brobots-thumb-top-right-h-base)) * var(--brobots-tablet-frame-progress));

    --brobots-thumb-bottom-left-w-live:
      calc(var(--brobots-thumb-bottom-left-w-base) + (var(--brobots-thumb-bottom-left-w-info) - var(--brobots-thumb-bottom-left-w-base)) * var(--brobots-tablet-frame-progress));
    --brobots-thumb-bottom-left-h-live:
      calc(var(--brobots-thumb-bottom-left-h-base) + (var(--brobots-thumb-bottom-left-h-info) - var(--brobots-thumb-bottom-left-h-base)) * var(--brobots-tablet-frame-progress));

    --brobots-thumb-bottom-right-w-live:
      calc(var(--brobots-thumb-bottom-right-w-base) + (var(--brobots-thumb-bottom-right-w-info) - var(--brobots-thumb-bottom-right-w-base)) * var(--brobots-tablet-frame-progress));
    --brobots-thumb-bottom-right-h-live:
      calc(var(--brobots-thumb-bottom-right-h-base) + (var(--brobots-thumb-bottom-right-h-info) - var(--brobots-thumb-bottom-right-h-base)) * var(--brobots-tablet-frame-progress));


    /* Aperture / frame thicknesses. */
    --brobots-hero-left-rail-w-live:
      calc(var(--brobots-hero-left-rail-w-base) + (var(--brobots-hero-left-rail-w-info) - var(--brobots-hero-left-rail-w-base)) * var(--brobots-tablet-frame-progress));
    --brobots-hero-right-rail-w-live:
      calc(var(--brobots-hero-right-rail-w-base) + (var(--brobots-hero-right-rail-w-info) - var(--brobots-hero-right-rail-w-base)) * var(--brobots-tablet-frame-progress));
    --brobots-hero-top-bar-h-live:
      calc(var(--brobots-hero-top-bar-h-base) + (var(--brobots-hero-top-bar-h-info) - var(--brobots-hero-top-bar-h-base)) * var(--brobots-tablet-frame-progress));
    --brobots-hero-bottom-bar-h-live:
      calc(var(--brobots-hero-bottom-bar-h-base) + (var(--brobots-hero-bottom-bar-h-info) - var(--brobots-hero-bottom-bar-h-base)) * var(--brobots-tablet-frame-progress));

    --brobots-thumb-left-rail-w-live:
      calc(var(--brobots-thumb-left-rail-w-base) + (var(--brobots-thumb-left-rail-w-info) - var(--brobots-thumb-left-rail-w-base)) * var(--brobots-tablet-frame-progress));
    --brobots-thumb-right-rail-w-live:
      calc(var(--brobots-thumb-right-rail-w-base) + (var(--brobots-thumb-right-rail-w-info) - var(--brobots-thumb-right-rail-w-base)) * var(--brobots-tablet-frame-progress));
    --brobots-thumb-top-bar-h-live:
      calc(var(--brobots-thumb-top-bar-h-base) + (var(--brobots-thumb-top-bar-h-info) - var(--brobots-thumb-top-bar-h-base)) * var(--brobots-tablet-frame-progress));
    --brobots-thumb-bottom-bar-h-live:
      calc(var(--brobots-thumb-bottom-bar-h-base) + (var(--brobots-thumb-bottom-bar-h-info) - var(--brobots-thumb-bottom-bar-h-base)) * var(--brobots-tablet-frame-progress));

    --brobots-separator-h-live:
      calc(var(--brobots-separator-h-base) + (var(--brobots-separator-h-info) - var(--brobots-separator-h-base)) * var(--brobots-tablet-frame-progress));
  }


  /*
    The actual raster pieces consume the SAME progress.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-frame-area > [data-game-frame-piece] {
    --brobots-piece-live-w:
      calc(
        var(--brobots-piece-base-w)
        +
        (
          var(--brobots-piece-info-w)
          -
          var(--brobots-piece-base-w)
        )
        *
        var(--brobots-tablet-frame-progress)
      );

    --brobots-piece-live-h:
      calc(
        var(--brobots-piece-base-h)
        +
        (
          var(--brobots-piece-info-h)
          -
          var(--brobots-piece-base-h)
        )
        *
        var(--brobots-tablet-frame-progress)
      );
  }


  .prototype-page-frame[data-game-frame-page]
  .game-frame-area > [data-game-frame-stretcher] {
    --brobots-stretcher-live-w:
      calc(
        var(--brobots-stretcher-base-w)
        +
        (
          var(--brobots-stretcher-info-w)
          -
          var(--brobots-stretcher-base-w)
        )
        *
        var(--brobots-tablet-frame-progress)
      );

    --brobots-stretcher-live-h:
      calc(
        var(--brobots-stretcher-base-h)
        +
        (
          var(--brobots-stretcher-info-h)
          -
          var(--brobots-stretcher-base-h)
        )
        *
        var(--brobots-tablet-frame-progress)
      );
  }


  /*
    Flexible axes remain the SAME proven v46 formulas:
      horizontal stretchers fill between current left/right anchors
      vertical stretchers fill between current top/bottom anchors
  */
  .prototype-page-frame[data-game-frame-page]
  .game-frame-stretcher--hero-top,
  .prototype-page-frame[data-game-frame-page]
  .game-frame-stretcher--hero-bottom,
  .prototype-page-frame[data-game-frame-page]
  .game-frame-stretcher--thumb-top,
  .prototype-page-frame[data-game-frame-page]
  .game-frame-stretcher--thumb-bottom {
    width: auto !important;
  }


  /*
    Thumb side stretchers are pinned by BOTH top and bottom, so auto height
    correctly fills that gap.

    Hero side stretchers are different: their proven v46 geometry uses
    top + an explicit calculated height. Forcing those to height:auto makes
    them zero-height (they have no bottom anchor/content), which is why the
    hero left/right rails disappeared in v52.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-frame-stretcher--thumb-left,
  .prototype-page-frame[data-game-frame-page]
  .game-frame-stretcher--thumb-right {
    height: auto !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-frame-stretcher--hero-left {
    height:
      calc(
        var(--brobots-hero-end-y)
        -
        var(--brobots-hero-bottom-left-h)
        -
        var(--brobots-hero-top-left-h)
      ) !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-frame-stretcher--hero-right {
    height:
      calc(
        var(--brobots-hero-end-y)
        -
        var(--brobots-hero-bottom-right-h)
        -
        var(--brobots-hero-top-right-h)
      ) !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-info-geometry {
    --brobots-tablet-frame-progress: 1;
  }




}


@media (max-width: 750px),
       (min-width: 1401px) {
}


/* =========================================================
   BROBOTS TABLET INFO — STEP 2a: MEDIA FADE HANDOFF
   =========================================================

   Geometry remains exactly as established in v53.

   The lower thumbnail UI now fades/scales away from the SAME master
   tablet-frame progress that drives the physical frame transformation.

   This keeps the visual handoff synchronized without adding a second JS
   animation timeline.
   ========================================================= */

@media (max-width: 1400px) {

  /*
    Use the existing master 0 -> 1 frame progress as the media handoff
    source of truth.

    Fade the thumbnails a little faster than the frame itself:
      progress 0.00 -> fully visible
      progress 0.62 -> effectively gone

    clamp() keeps the value valid through the full transition.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-media-zone--thumbs
  .media-strip {
    opacity:
      clamp(
        0,
        calc(
          1
          -
          (
            var(--brobots-tablet-frame-progress)
            /
            0.62
          )
        ),
        1
      );

    transform:
      scale(
        calc(
          1
          -
          (
            var(--brobots-tablet-frame-progress)
            *
            0.035
          )
        )
      );

    transform-origin:
      50% 50%;

    /*
      The values above already interpolate continuously because the shared
      progress variable is animated. Do not add another transition here.
    */
    transition: none !important;
  }


  /*
    Once the frame reaches its info state, the hidden thumbnail UI should
    not remain interactive underneath the future info surface.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-info-geometry
  .game-media-zone--thumbs
  .media-strip {
    pointer-events: none;
  }


  /*
    The temporary geometry-test arrow remains available for now so we can
    still click back to the media state while building this feature.

    It fades down substantially during the transition instead of vanishing
    completely. When wheel/touch navigation is added, this can become the
    final one-way attention arrow and disappear fully.
  */


  /*
    Preserve the existing up/down direction flip while keeping the new
    parent-level fade/scale independent.
  */
}


/* =========================================================
   BROBOTS TABLET INFO — STEP 2b: disable hidden media input
   =========================================================

   The site-wide open-page rules explicitly restore pointer-events:auto on
   thumbnails/arrows, so disabling only .media-strip was not sufficient:
   its descendants could still become hit targets.

   When tablet info geometry is active, disable the complete lower media
   interaction tree explicitly.
   ========================================================= */

@media (max-width: 1400px) {

  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-info-geometry
  .game-media-zone--thumbs,

  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-info-geometry
  .game-media-zone--thumbs
  .media-strip,

  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-info-geometry
  .game-media-zone--thumbs
  .media-thumbnails,

  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-info-geometry
  .game-media-zone--thumbs
  .media-thumbnail,

  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-info-geometry
  .game-media-zone--thumbs
  .media-arrow {
    pointer-events: none !important;
  }
}


/* =========================================================
   BROBOTS TABLET INFO — STEP 3: INFO SURFACE HANDOFF
   =========================================================

   The tablet info host lives INSIDE .game-frame-area, so it can
   use the exact same continuously-derived geometry as the raster frame.

   No desktop panel is moved or restyled.
   ========================================================= */

.prototype-page-frame[data-game-frame-page] .game-tablet-info-host {
  display: none;
}


@media (max-width: 1400px) {

  .prototype-page-frame[data-game-frame-page] .game-tablet-info-host {
    position: absolute;

    /*
      Occupy the exact lower INNER aperture:
        left/right  = current thumbnail side-rail thickness
        top         = current thumbnail start + top bar thickness
        bottom      = current bottom bar thickness
    */
    left:
      var(
        --brobots-thumb-left-rail-w,
        0px
      );

    right:
      var(
        --brobots-thumb-right-rail-w,
        0px
      );

    top:
      calc(
        var(--brobots-thumb-start-y)
        +
        var(
          --brobots-thumb-top-bar-h,
          0px
        )
      );

    bottom:
      var(
        --brobots-thumb-bottom-bar-h,
        0px
      );

    z-index: 2;

    display: block;

    min-width: 0;
    min-height: 0;

    overflow: hidden;

    /*
      Begin revealing after the thumbnail UI is mostly gone.
      progress ~= .52 -> starts
      progress = 1    -> fully visible
    */
    opacity:
      clamp(
        0,
        calc(
          (
            var(--brobots-tablet-frame-progress)
            -
            0.52
          )
          /
          0.48
        ),
        1
      );

    transform:
      translateY(
        calc(
          14px
          *
          (
            1
            -
            clamp(
              0,
              calc(
                (
                  var(--brobots-tablet-frame-progress)
                  -
                  0.52
                )
                /
                0.48
              ),
              1
            )
          )
        )
      );

    pointer-events: none;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-info-geometry
  .game-tablet-info-host {
    pointer-events: auto;
  }


  /*
    Reuse the existing game-info component, but remove the desktop popout's
    extra glass/decorative shell responsibilities. The Brobots raster frame
    is now the physical container.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-info {
    position: absolute;
    inset: 0;

    width: 100%;
    height: 100%;

    min-width: 0;
    min-height: 0;

    padding:
      clamp(
        16px,
        2.2cqw,
        30px
      );

    overflow: hidden;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-info-background,
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-info-layer {
    /*
      Keep the existing decorative background treatment available, but
      don't let it create a second physical border.
    */
    border: 0;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-info-surface {
    width: 100%;
    height: 100%;

    min-width: 0;
    min-height: 0;

    overflow: hidden;
  }


  /*
    Let the existing vertical feature-culling system continue to decide
    whether the highlights fit. This is only a tablet-specific sizing nudge,
    not a second info layout.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-info-logo {
    max-height:
      clamp(
        54px,
        8.5cqh,
        104px
      );
  }


}


/* Outside tablet mode the cloned surface does not participate at all. */
@media (min-width: 1401px) {
  .prototype-page-frame[data-game-frame-page] .game-tablet-info-host {
    display: none !important;
  }
}


/* =========================================================
   BROBOTS TABLET INFO — STEP 3b
   Shared crowding logic + layered glass motif
   ========================================================= */

@media (max-width: 1400px) {

  /*
    The tablet clone now runs through the exact same
    updateGameInfoFeatureCrowding() function as the desktop popout.

    These selectors only adapt the PRESENTATION of that same collapsed
    state to the tablet cavity; no separate culling decision is invented.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-info-surface.is-features-collapsed
  .game-info-features {
    opacity: 0;
    pointer-events: none;
  }


  /*
    Once the shared function collapses the middle feature zone, let the
    remaining top/bottom zones redistribute naturally through the cavity.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-info-surface.is-features-collapsed {
    grid-template-rows:
      auto
      0px
      auto;

    row-gap:
      clamp(
        10px,
        1.45cqh,
        20px
      );
  }


  /* -------------------------------------------------------
     Reuse the SAME four-layer glass stack as the PC popout.
     ------------------------------------------------------- */

  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack {
    position: absolute;
    inset:
      clamp(8px, 1.1cqh, 14px)
      clamp(8px, 1.0cqw, 16px);

    z-index: 1;

    display: block;

    overflow: hidden;

    pointer-events: none;

    /*
      The host itself already fades in from frame progress. Give the glass a
      slightly later/softer arrival so the content reads first.
    */
    opacity:
      clamp(
        0,
        calc(
          (
            var(--brobots-tablet-frame-progress)
            -
            0.60
          )
          /
          0.40
        ),
        1
      );

    clip-path: none;

    transition: none !important;
  }


  /*
    Override the desktop-only "secondary open" opacity contract.
    Inside the tablet host the stack is controlled entirely by tablet frame
    progress instead.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer {
    display: block;

    backdrop-filter:
      blur(3px)
      saturate(110%);

    -webkit-backdrop-filter:
      blur(3px)
      saturate(110%);
  }


  /*
    Adapt the existing motif to the broader/lower tablet cavity. These keep
    the same asymmetric layered language while avoiding a literal copy of
    the narrow desktop wedge.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--1 {
    inset:
      1.5%
      1.8%
      4.5%
      0;

    opacity: 0.56;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--2 {
    inset:
      6%
      6.5%
      8%
      1.5%;

    opacity: 0.48;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--3 {
    inset:
      11%
      12.5%
      13%
      3%;

    opacity: 0.44;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--4 {
    left: 2%;
    right: 17%;
    top: 52%;
    bottom: 1%;

    opacity: 0.52;
  }


  /*
    Keep the atmospheric Brobots background image in layer 1, but make it
    more restrained here because the tablet cavity is much larger.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .brobots-popout-layer-image {
    opacity: 0.22;

    object-position:
      right top;

    filter:
      saturate(0.88)
      contrast(0.94)
      brightness(0.82);
  }


  /*
    Content remains above the glass stack.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-info {
    z-index: 2;
  }
}


/* =========================================================
   BROBOTS TABLET INFO — STEP 3c
   Stronger glass + visible screenshot + rounded panes
   ========================================================= */

@media (max-width: 1400px) {

  /*
    The generic responsive rule hides decorative popout images below
    1400px. That is correct for the OLD desktop->tablet handoff, but the
    new tablet info host intentionally reuses that artwork.

    Re-enable the cloned image specifically inside the tablet host.
  */



  /*
    Make the tablet glass much closer in strength to the PC popout.
    The fills remain translucent; opacity:1 just stops stacking an extra
    whole-element transparency on top of them.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer {
    opacity: 1 !important;

    /*
      Tablet version uses softened Y2K glass cards rather than the sharper
      desktop wedge cuts.
    */
    border-radius:
      clamp(
        18px,
        2.5cqw,
        34px
      ) !important;

    clip-path: none !important;

    overflow: hidden;

    box-shadow:
      inset 0 0 0 1px
      rgba(255,255,255,0.055),

      0 8px 28px
      rgba(0,0,0,0.10);

    backdrop-filter:
      blur(5px)
      saturate(116%)
      !important;

    -webkit-backdrop-filter:
      blur(5px)
      saturate(116%)
      !important;
  }


  /*
    Give each sheet a slightly different radius so the layered stack feels
    intentional instead of like four identical rectangles.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--1 {
    border-radius:
      clamp(
        24px,
        3.1cqw,
        40px
      ) !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--2 {
    border-radius:
      clamp(
        20px,
        2.7cqw,
        36px
      ) !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--3 {
    border-radius:
      clamp(
        18px,
        2.35cqw,
        32px
      ) !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--4 {
    border-radius:
      clamp(
        16px,
        2.1cqw,
        28px
      ) !important;
  }


  /*
    Slightly stronger pane fills for this larger tablet cavity.
    These intentionally preserve the existing Brobots glass language.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--1 {
    background:
      linear-gradient(
        112deg,
        rgba(255,255,255,0.075),
        rgba(
          var(--page-accent-rgb),
          0.105
        ) 52%,
        rgba(22,32,40,0.18)
      ) !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--2 {
    background:
      linear-gradient(
        105deg,
        rgba(80,105,120,0.20),
        rgba(255,255,255,0.055)
      ) !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--3 {
    background:
      linear-gradient(
        115deg,
        rgba(
          var(--page-accent-rgb),
          0.09
        ),
        rgba(90,105,120,0.18)
      ) !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--4 {
    background:
      linear-gradient(
        108deg,
        rgba(255,255,255,0.065),
        rgba(
          var(--page-accent-rgb),
          0.12
        )
      ) !important;
  }
}


/* =========================================================
   BROBOTS TABLET INFO — STEP 3d
   Stabilize glass compositing through the fade
   =========================================================

   The glass stack was being faded independently INSIDE the already-fading
   tablet info host. With backdrop-filter on its child panes, Chrome can
   composite that nested translucent layer differently while opacity is
   animating, then rebuild it when the animation reaches 1. That produces
   the visible "blur changes when it settles" pop.

   Keep the physical glass stack at its final opacity for the ENTIRE
   transition. The existing host fade is already sufficient to reveal it.
   This means the glass has one visual treatment from first visible frame
   through the settled state.
   ========================================================= */

@media (max-width: 1400px) {

  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack {
    /*
      Do not independently animate opacity on a backdrop-filter container.
      The parent .game-tablet-info-host already performs the reveal.
    */
    opacity: 1 !important;

    transition: none !important;

    /*
      Keep Chrome on one compositing path during and after the host fade.
    */
    transform:
      translateZ(0);

    backface-visibility:
      hidden;

    will-change:
      transform;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer {
    /*
      These are the actual filtered surfaces. Their visual state should
      never change merely because the parent fade has completed.
    */
    opacity: 1 !important;

    transition: none !important;

    transform:
      translateZ(0);

    backface-visibility:
      hidden;

    will-change:
      backdrop-filter;
  }


  /*
    The screenshot is likewise held at its final visual treatment from the
    moment the host begins appearing. Only the host itself fades.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .etherian-popout-layer-image,
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .brobots-popout-layer-image {
    transition: none !important;

    transform:
      translateZ(0);

    backface-visibility:
      hidden;
  }
}


/* =========================================================
   BROBOTS TABLET INFO — STEP 3e
   Stable glass: remove real backdrop blur
   =========================================================

   New diagnosis from manual resize:
   this is NOT the fade timing. The visual shift also happens when the
   browser manually resizes the panel, which points to Chrome re-rasterizing
   backdrop-filter as the pane dimensions change.

   The desktop Brobots info treatment already avoids real backdrop blur.
   Match that architecture here too: keep the layered translucent panes,
   screenshot, gradients, highlights and borders, but remove
   backdrop-filter entirely from the tablet stack.

   This should make the glass appearance deterministic during:
   - arrow transition
   - manual resize
   - settled state
   ========================================================= */

@media (max-width: 1400px) {

  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;

    /*
      Keep the pane treatment itself unchanged and stable.
    */
    opacity: 1 !important;
    transition: none !important;

    transform: none !important;
    backface-visibility: visible !important;
    will-change: auto !important;
  }


  /*
    Also remove compositor-forcing hints from the stack/image. They were
    useful as a test, but can themselves encourage Chrome to promote/rebuild
    layers while resizing.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack,
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .etherian-popout-layer-image,
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .brobots-popout-layer-image {
    transform: none !important;
    backface-visibility: visible !important;
    will-change: auto !important;
  }
}


/* =========================================================
   BROBOTS TABLET LANDING — STEP 1
   Logo + "Scroll for more" replaces thumbnail rail
   ========================================================= */

.prototype-page-frame[data-game-frame-page] .game-tablet-landing-identity {
  display: none;
}


@media (max-width: 1400px) {

  /*
    The thumbnail area remains part of the physical frame geometry, but its
    CONTENT is no longer shown in the normal tablet landing state.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-media-zone--thumbs
  .media-strip {
    opacity: 0 !important;
    pointer-events: none !important;
  }




  /*
    Identity block occupies the lower frame aperture in the collapsed
    tablet state.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-landing-identity {
    position: absolute;

    left:
      var(
        --brobots-thumb-left-rail-w,
        0px
      );

    right:
      var(
        --brobots-thumb-right-rail-w,
        0px
      );

    top:
      calc(
        var(--brobots-thumb-start-y)
        +
        var(
          --brobots-thumb-top-bar-h,
          0px
        )
      );

    bottom:
      var(
        --brobots-thumb-bottom-bar-h,
        0px
      );

    z-index: 4;

    display: flex;
    flex-direction: column;

    align-items: center;
    justify-content: center;

    gap:
      clamp(
        10px,
        1.8cqh,
        20px
      );

    padding:
      clamp(
        12px,
        1.8cqw,
        24px
      );

    text-align: center;

    opacity:
      clamp(
        0,
        calc(
          1
          -
          (
            var(--brobots-tablet-frame-progress)
            /
            0.50
          )
        ),
        1
      );

    transform:
      translateY(
        calc(
          -8px
          *
          var(--brobots-tablet-frame-progress)
        )
      );

    pointer-events: auto;
  }


  /*
    Once info mode is active, the landing identity is visually gone and
    should no longer intercept input.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-info-geometry
  .game-tablet-landing-identity {
    pointer-events: none;
  }


  /*
    Reuse the authored Brobots logo. Keep it bold enough to immediately
    identify the page even when the current hero screenshot is ambiguous.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-landing-logo {
    /*
      Keep the larger visual weight from v65, but size it against the
      ACTUAL lower landing aperture rather than the full Brobots frame.

      Reserve enough vertical room for the "Scroll for more" cue, then let
      the logo consume the rest without ever crossing the aperture edges.
    */
    width:
      min(
        76cqw,
        560px
      );

    max-width: 88%;

    height: auto;

    max-height:
      calc(
        100%
        -
        clamp(
          64px,
          8cqh,
          92px
        )
      );

    object-fit: contain;

    margin: 0;

    flex: 0 1 auto;
  }


  /*
    The lower identity area is a hard visual aperture: nothing in the
    landing treatment should spill across the Brobots raster border.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-landing-identity {
    overflow: hidden;
  }


  /*
    Simple, readable interaction cue.
    No heavy card around it: the logo is the identity, this is just the hint.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-scroll-cue {
    display: inline-flex;
    flex-direction: column;

    align-items: center;
    justify-content: center;

    gap:
      clamp(
        2px,
        0.45cqh,
        5px
      );

    padding:
      clamp(
        4px,
        0.6cqh,
        7px
      )
      clamp(
        10px,
        1.4cqw,
        16px
      );

    border: 0;
    background: transparent;

    color:
      rgba(
        240,
        240,
        240,
        0.82
      );

    cursor: pointer;

    pointer-events: auto;

    font: inherit;
    text-align: center;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-scroll-cue-text {
    font-size:
      clamp(
        11px,
        1.25cqw,
        15px
      );

    font-weight: 600;

    letter-spacing:
      0.11em;

    text-transform: uppercase;

    text-shadow:
      0 1px 8px
      rgba(0,0,0,0.55);
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-scroll-cue-arrow {
    display: block;

    color:
      rgba(
        var(--page-accent-rgb),
        0.96
      );

    font-size:
      clamp(
        20px,
        2.8cqh,
        30px
      );

    line-height: 0.8;

    animation:
      game-tablet-scroll-cue-bob
      1.65s
      ease-in-out
      infinite;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-scroll-cue:hover,
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-scroll-cue:focus-visible {
    color:
      rgba(
        255,
        255,
        255,
        1
      );
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-scroll-cue:focus-visible {
    outline:
      2px solid
      rgba(
        var(--page-accent-rgb),
        0.82
      );

    outline-offset: 4px;

    border-radius: 10px;
  }
}


@keyframes game-tablet-scroll-cue-bob {
  0%,
  100% {
    transform:
      translateY(0);
  }

  50% {
    transform:
      translateY(5px);
  }
}


@media (prefers-reduced-motion: reduce) {
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-scroll-cue-arrow {
    animation: none;
  }
}


/* =========================================================
   BROBOTS TABLET LANDING — STEP 1c
   Scale the entire identity composition as one unit
   =========================================================

   v66 bounded the logo, but reserved a fixed-ish amount of vertical space
   for the cue. On a short tablet frame that reservation consumed nearly the
   whole lower aperture, so the logo collapsed while the cue stayed roughly
   the same size.

   Make the lower aperture its OWN size container instead. Logo, text, arrow,
   and spacing now all derive from the same available width/height, so the
   complete landing composition scales together during manual resize.
   ========================================================= */

@media (max-width: 1400px) {

  .prototype-page-frame[data-game-frame-page]
  .game-tablet-landing-identity {
    container-type: size;
    container-name: brobots-tablet-landing;

    /*
      Keep the whole composition truly centered in the live lower aperture.
      No child reserves a fixed pixel block anymore.
    */
    justify-content: center;

    gap:
      min(
        3.8cqh,
        18px
      );

    padding:
      min(
        4.5cqh,
        22px
      )
      min(
        3.2cqw,
        26px
      );

    overflow: hidden;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-landing-logo {
    /*
      Width is primarily driven by the landing aperture, while max-height
      gives the cue guaranteed proportional breathing room.

      Because cqw/cqh now resolve against .game-tablet-landing-identity,
      this stays centered and scales continuously with the actual panel.
    */
    width:
      min(
        84cqw,
        620px
      );

    max-width: 84cqw;

    height: auto;

    max-height:
      55cqh;

    object-fit: contain;

    flex:
      0 1 auto;

    margin: 0;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-scroll-cue {
    /*
      Cue sizing now follows the SAME lower aperture as the logo.
      Remove fixed clamp minimums that made it look detached at short sizes.
    */
    gap:
      min(
        1.2cqh,
        5px
      );

    padding:
      min(
        1.4cqh,
        7px
      )
      min(
        2.6cqw,
        16px
      );

    flex:
      0 0 auto;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-scroll-cue-text {
    font-size:
      min(
        5.2cqh,
        15px
      );

    letter-spacing:
      min(
        0.11em,
        0.9cqh
      );
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-scroll-cue-arrow {
    font-size:
      min(
        9cqh,
        30px
      );

    line-height:
      0.78;
  }
}


/* =========================================================
   BROBOTS TABLET LANDING — STEP 1d
   Clean isolated landing composition
   =========================================================

   The landing logo was cloned from .game-info-logo and still carried that
   class. Brobots has several generic/info compact sizing rules and even a
   width transition on .game-info-logo, so the landing logo was being driven
   by TWO systems. That explains both the off-centering and the "pop" after
   resize stopped.

   v68 removes that class in JS and gives the landing panel one simple,
   self-contained layout.
   ========================================================= */

@media (max-width: 1400px) {

  .prototype-page-frame[data-game-frame-page]
  .game-tablet-landing-identity {
    /*
      One plain centered column. No nested responsive reservation math.
    */
    display: flex;
    flex-direction: column;

    align-items: center;
    justify-content: center;

    gap:
      clamp(
        8px,
        2.0cqh,
        18px
      );

    padding:
      clamp(
        10px,
        2.2cqh,
        20px
      )
      clamp(
        16px,
        2.6cqw,
        28px
      );

    text-align: center;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-landing-logo {
    /*
      Large like the good v65 proportion, but bounded by BOTH dimensions of
      the actual lower aperture.

      Since this element no longer has .game-info-logo, no desktop/info
      width clamp or resize transition can override this.
    */
    display: block;

    width:
      min(
        78%,
        560px
      );

    height: auto;

    max-width: 78%;

    max-height: 58%;

    object-fit: contain;

    flex: 0 1 auto;

    margin: 0;

    transition: none !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-scroll-cue {
    /*
      Keep the cue visually attached to the logo, but preserve readability
      instead of shrinking it toward illegibility on short windows.
    */
    flex: 0 0 auto;

    gap:
      clamp(
        2px,
        0.55cqh,
        5px
      );

    padding:
      clamp(
        3px,
        0.6cqh,
        6px
      )
      clamp(
        8px,
        1.2cqw,
        14px
      );
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-scroll-cue-text {
    font-size:
      clamp(
        11px,
        min(
          1.35cqw,
          4.6cqh
        ),
        15px
      );

    letter-spacing:
      0.11em;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-scroll-cue-arrow {
    font-size:
      clamp(
        18px,
        min(
          2.4cqw,
          8cqh
        ),
        28px
      );
  }
}


/* =========================================================
   BROBOTS TABLET LANDING — STEP 1e
   Logo exits upward; cue fades independently
   =========================================================

   Keep the landing logo's SIZE independent of the expanding lower aperture.
   Previously max-height was a percentage of that live aperture, so the logo
   visibly grew as the info region expanded before fading.

   The logo now keeps a viewport-relative cap during the state transition,
   then physically travels upward and is clipped by the lower aperture.
   This reads like the page content is being pulled upward by the scroll.

   The "Scroll for more" cue remains in place and simply fades out.
   ========================================================= */

@media (max-width: 1400px) {

  .prototype-page-frame[data-game-frame-page]
  .game-tablet-landing-identity {
    /*
      Do NOT fade the whole group. The logo and cue now have separate exits.
    */
    opacity: 1 !important;

    transform: none !important;

    overflow: hidden;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-landing-logo {
    /*
      Crucial: this cap depends on the viewport, not on the live lower
      aperture height. Opening the info region therefore cannot make the
      logo suddenly grow.
    */
    width:
      min(
        78%,
        560px
      );

    max-width: 78%;

    height: auto;

    max-height:
      clamp(
        76px,
        10vh,
        126px
      );

    flex: 0 0 auto;

    /*
      JS measures the logo's collapsed centre against the hero viewer's
      centre immediately before entering info mode and stores that exact
      vertical delta here. The shared 0 -> 1 tablet progress then carries
      the logo to the hero centre instead of relying on a guessed multiple
      of the logo's own height.

      This deliberately remains a transform-only motion: the landing layout
      itself does not move, so the cue can keep fading independently.
    */
    transform:
      translateY(
        calc(
          var(
            --brobots-tablet-logo-target-y,
            -320px
          )
          *
          var(--brobots-tablet-frame-progress)
        )
      );

    /*
      The physical travel should normally tuck the logo fully behind the
      hero frame. Fade it as a safety net as well so unusual tablet/window
      proportions can never leave a visible sliver behind.

      Keep the first part of the motion readable, then finish the fade before
      the info surface is fully established.
    */
    opacity:
      clamp(
        0,
        calc(
          1
          -
          (
            var(--brobots-tablet-frame-progress)
            /
            0.72
          )
        ),
        1
      ) !important;

    transition: none !important;

    will-change:
      transform,
      opacity;
  }


  /*
    Keep the cue where it is; only fade it away.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-scroll-cue {
    opacity:
      clamp(
        0,
        calc(
          1
          -
          (
            var(--brobots-tablet-frame-progress)
            /
            0.42
          )
        ),
        1
      );

    transform: none !important;

    transition: none !important;
  }


  /*
    Once the info state has been selected, none of the old landing controls
    should remain interactive while visually leaving.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-info-geometry
  .game-tablet-scroll-cue {
    pointer-events: none;
  }
}


/* =========================================================
   BROBOTS MOBILE COLLAPSE — FINAL MEDIA OWNERSHIP CLEANUP
   =========================================================

   During .is-mobile-collapse-hold the outgoing real page only exists long
   enough to hand visual ownership to the fake hamburger-collapse morph.

   The media browser is not useful during that interval and was the source
   of the final hero-image flash. Remove it from layout/rendering entirely
   for those few frames rather than preserving or merely fading obsolete
   media UI.
   ========================================================= */

@media (max-width: 750px) {
  .prototype-page-frame[data-game-frame-page].is-mobile-collapse-hold
  .game-frame-area > .media-browser {
    display: none !important;
  }
}


/* =========================================================
   BROBOTS TABLET HERO — MEDIA NAVIGATION
   =========================================================

   The authored thumbnail buttons remain the one media-item data source and
   continue to drive desktop. JS creates this lightweight overlay from those
   same items, and the existing renderItem() controller drives both systems.

   On tablet, navigation is deliberately recessive:
   - the side hit areas are invisible at rest
   - approaching either side reveals a soft page-accent glow rather than a
     permanent arrow button
   - pagination dots float directly over the media with no backing pill

   Only Brobots tablet shows this overlay for now. Keeping the controls out of
   the raster frame markup means they can later be generalized for Etherian /
   Halodoom without duplicating the media list in HTML.
   ========================================================= */

.media-hero-navigation {
  display: none;
}


@media (max-width: 1400px) {

  .prototype-page-frame[data-game-frame-page]
  .game-media-zone--hero
  .media-hero-navigation {
    position: absolute;
    z-index: 2;

    inset: 0;

    display: block;

    pointer-events: none;
  }


  /* -------------------------------------------------------
     Invisible side hit areas + proximity glow
     ------------------------------------------------------- */

  .prototype-page-frame[data-game-frame-page]
  .media-hero-arrow {
    position: absolute;

    top: 0;
    bottom: 0;

    /*
      A generous transparent hit area makes the control respond as the cursor
      approaches the side of the hero instead of requiring a tiny target.
    */
    width:
      clamp(
        92px,
        20%,
        210px
      );

    height: auto;

    display: block;

    margin: 0;
    padding: 0;

    border: 0;
    background: transparent;

    /* Hide the authored ‹ / › glyph without changing the JS/HTML control. */
    color: transparent;
    font-size: 0;
    line-height: 0;

    cursor: pointer;

    opacity: 1;

    transform: none;

    pointer-events: auto;
  }


  /*
    The visible feedback is a soft accent wash that blooms in from the edge.
    It uses the page accent variable, so Brobots is gold now and future game
    pages can inherit their own theme without a new color rule.
  */
  .prototype-page-frame[data-game-frame-page]
  .media-hero-arrow::before {
    content: "";

    position: absolute;
    inset: 0;

    opacity: 0;

    pointer-events: none;

    transition:
      opacity 220ms ease;
  }


  .prototype-page-frame[data-game-frame-page]
  .media-hero-arrow--previous {
    left: 0;
  }


  .prototype-page-frame[data-game-frame-page]
  .media-hero-arrow--previous::before {
    background:
      linear-gradient(
        90deg,
        rgba(var(--page-accent-rgb), 0.30) 0%,
        rgba(var(--page-accent-rgb), 0.16) 30%,
        rgba(var(--page-accent-rgb), 0.07) 58%,
        rgba(var(--page-accent-rgb), 0.025) 78%,
        rgba(var(--page-accent-rgb), 0) 100%
      );
  }


  .prototype-page-frame[data-game-frame-page]
  .media-hero-arrow--next {
    right: 0;
  }


  .prototype-page-frame[data-game-frame-page]
  .media-hero-arrow--next::before {
    background:
      linear-gradient(
        270deg,
        rgba(var(--page-accent-rgb), 0.30) 0%,
        rgba(var(--page-accent-rgb), 0.16) 30%,
        rgba(var(--page-accent-rgb), 0.07) 58%,
        rgba(var(--page-accent-rgb), 0.025) 78%,
        rgba(var(--page-accent-rgb), 0) 100%
      );
  }


  .prototype-page-frame[data-game-frame-page]
  .media-hero-arrow:hover::before,
  .prototype-page-frame[data-game-frame-page]
  .media-hero-arrow:focus-visible::before {
    opacity: 1;
  }


  .prototype-page-frame[data-game-frame-page]
  .media-hero-arrow:focus-visible {
    outline: none;
  }


  .prototype-page-frame[data-game-frame-page]
  .media-hero-arrow:disabled {
    cursor: default;
    pointer-events: none;
  }


  .prototype-page-frame[data-game-frame-page]
  .media-hero-arrow:disabled::before {
    opacity: 0;
  }


  /* -------------------------------------------------------
     Minimal pagination dots
     ------------------------------------------------------- */

  .prototype-page-frame[data-game-frame-page]
  .media-hero-dots {
    position: absolute;

    left: 50%;
    bottom:
      clamp(
        9px,
        3.2cqh,
        16px
      );

    display: flex;
    align-items: center;
    justify-content: center;

    gap:
      clamp(
        6px,
        0.85cqw,
        10px
      );

    /*
      Keep a very restrained border/backplate around the dots for contrast,
      but hide the whole pagination treatment until the hero is engaged.
    */
    padding:
      5px
      8px;

    /*
      Restore the original v74 capsule-border visibility while keeping the
      newer lighter backplate + hover-only reveal behavior.
    */
    border:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.28
      );

    border-radius: 999px;

    background:
      rgba(10, 13, 16, 0.22);

    box-shadow:
      0 2px 8px
      rgba(0, 0, 0, 0.16);

    opacity: 0;

    transition:
      opacity 180ms ease;

    transform:
      translateX(-50%);

    pointer-events: none;
  }


  /*
    Pagination stays completely out of the artwork until the user actually
    enters the hero. focus-within preserves keyboard access once a dot is
    focused.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-media-zone--hero:hover
  .media-hero-dots,
  .prototype-page-frame[data-game-frame-page]
  .media-hero-navigation:has(:focus-visible)
  .media-hero-dots {
    opacity: 1;
    pointer-events: auto;
  }


  .prototype-page-frame[data-game-frame-page]
  .media-hero-dot {
    width:
      clamp(
        8px,
        min(1.15cqw, 4.8cqh),
        11px
      );

    height:
      clamp(
        8px,
        min(1.15cqw, 4.8cqh),
        11px
      );

    flex: 0 0 auto;

    margin: 0;
    padding: 0;

    border:
      1px solid
      rgba(255, 255, 255, 0.44);

    border-radius: 50%;

    background:
      rgba(240, 244, 247, 0.28);

    box-shadow:
      0 1px 4px
      rgba(0, 0, 0, 0.32);

    cursor: pointer;

    opacity: 1;

    transform: scale(1);

    transition:
      transform 150ms ease,
      border-color 150ms ease,
      background-color 150ms ease,
      box-shadow 150ms ease;
  }


  .prototype-page-frame[data-game-frame-page]
  .media-hero-dot:hover,
  .prototype-page-frame[data-game-frame-page]
  .media-hero-dot:focus-visible {
    border-color:
      rgba(
        var(--page-accent-rgb),
        0.88
      );

    background:
      rgba(
        var(--page-accent-rgb),
        0.54
      );

    transform:
      scale(1.18);
  }


  .prototype-page-frame[data-game-frame-page]
  .media-hero-dot:focus-visible {
    outline:
      1px solid
      rgba(
        var(--page-accent-rgb),
        0.68
      );

    outline-offset: 3px;
  }


  .prototype-page-frame[data-game-frame-page]
  .media-hero-dot.is-selected {
    opacity: 1;

    border-color:
      rgba(
        var(--page-accent-rgb),
        1
      );

    background:
      rgba(
        var(--page-accent-rgb),
        0.96
      );

    box-shadow:
      0 0 7px
      rgba(
        var(--page-accent-rgb),
        0.48
      );

    transform:
      scale(1.22);
  }
}


/* =========================================================
   Brobots tablet hero — resting media opacity
   =========================================================

   Keep the hero artwork slightly recessed at rest, then bring it to full
   strength when the pointer enters the hero zone. This intentionally lives on
   the READY media stage rather than .media-viewer itself so the frame/border
   and navigation overlay are not faded with the image/video.
*/
@media (max-width: 1400px) {
  .prototype-page-frame[data-game-frame-page]
  .game-media-zone--hero
  .media-viewer-stage.is-ready {
    opacity: 0.8;

    transition:
      opacity 220ms ease;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-media-zone--hero:hover
  .media-viewer-stage.is-ready {
    opacity: 1;
  }
}


/* =========================================================
   CLOSED PAGE FRAMES — HARD INTERACTION GATE
   =========================================================

   A hidden .prototype-page-frame previously relied on pointer-events:none
   only on the frame/content ancestors. Several descendants explicitly set
   pointer-events:auto (media viewers, arrows, local YouTube fallback links,
   desktop info content, etc.), which allows those invisible descendants to
   become hit targets even while their page frame is visually closed.

   This is the single source-of-truth gate: if the real page does not own
   .is-open, NOTHING inside its content surface may receive pointer input.
   Once .is-open is added, the existing open-page rules regain control.
   ========================================================= */

.prototype-page-frame:not(.is-open)
.prototype-page-frame-content,
.prototype-page-frame:not(.is-open)
.prototype-page-frame-content * {
  pointer-events: none !important;
}


/*
  Desktop secondary panels sit outside .prototype-page-frame-content, so give
  their complete hidden subtree the same protection. This also prevents an
  opacity-zero CTA/content layer from ever becoming an invisible hit target.
*/
.prototype-page-frame:not(.is-open)
.desktop-secondary-panel,
.prototype-page-frame:not(.is-open)
.desktop-secondary-panel * {
  pointer-events: none !important;
}


/* =========================================================
   BROBOTS DESKTOP <-> TABLET CONTENT HANDOFF
   =========================================================

   Crossing 1400px used to swap the desktop thumbnail rail and tablet
   landing identity in a single frame. Keep the physical Brobots frame on
   its existing responsive geometry, but animate the CONTENT handoff:

     desktop -> tablet
       thumbnails travel upward toward the hero and fade out
       landing logo / scroll cue fade in

     tablet -> desktop
       landing logo / scroll cue fade out
       thumbnails travel back down from the hero and fade in

   JS measures the actual hero-center -> thumbnail-center distance and
   writes --brobots-breakpoint-thumb-shift-y. That keeps the motion correct
   for unusual aspect ratios instead of relying on a guessed pixel offset.
   ========================================================= */

.prototype-page-frame[data-game-frame-page] .game-frame-area {
  --brobots-breakpoint-thumb-shift-y: -180px;
  --brobots-breakpoint-handoff-duration: 1240ms;
}


/* -------------------------
   Desktop -> tablet
   ------------------------- */

@media (max-width: 1400px) {
  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-breakpoint-entering
  .game-media-zone--thumbs
  .media-strip {
    opacity: 1 !important;

    transform:
      translateY(0)
      scale(1) !important;

    transition: none !important;

    pointer-events: none !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-breakpoint-entering
  .game-tablet-landing-identity {
    opacity: 0 !important;
    transition: none !important;
    pointer-events: none !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-breakpoint-entering.is-tablet-breakpoint-thumb-active
  .game-media-zone--thumbs
  .media-strip {
    opacity: 0 !important;

    transform:
      translateY(
        var(--brobots-breakpoint-thumb-shift-y)
      )
      scale(0.975) !important;

    transition:
      opacity 840ms ease,
      transform
        var(--brobots-breakpoint-handoff-duration)
        cubic-bezier(0.18, 0.78, 0.22, 1) !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-breakpoint-entering.is-tablet-breakpoint-handoff-active
  .game-tablet-landing-identity {
    opacity: 1 !important;

    transition:
      opacity 430ms ease 120ms !important;
  }
}


/* -------------------------
   Tablet -> desktop
   ------------------------- */

@media (min-width: 1401px) {
  /*
    Keep the outgoing tablet identity alive just long enough to fade away.
    Normally it is display:none outside tablet mode, so this transient class
    supplies the same lower-aperture placement while the handoff runs.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-breakpoint-leaving
  .game-tablet-landing-identity {
    position: absolute;

    left:
      var(--brobots-thumb-left-rail-w, 0px);

    right:
      var(--brobots-thumb-right-rail-w, 0px);

    top:
      calc(
        var(--brobots-thumb-start-y)
        +
        var(--brobots-thumb-top-bar-h, 0px)
      );

    bottom:
      var(--brobots-thumb-bottom-bar-h, 0px);

    z-index: 4;

    display: flex !important;
    flex-direction: column;
    align-items: center;
    justify-content: center;

    gap:
      var(
        --brobots-breakpoint-landing-gap,
        12px
      );

    padding-top:
      var(
        --brobots-breakpoint-landing-padding-top,
        12px
      );

    padding-right:
      var(
        --brobots-breakpoint-landing-padding-right,
        20px
      );

    padding-bottom:
      var(
        --brobots-breakpoint-landing-padding-bottom,
        12px
      );

    padding-left:
      var(
        --brobots-breakpoint-landing-padding-left,
        20px
      );

    overflow: hidden;

    text-align: center;

    opacity: 1 !important;
    transition: none !important;
    pointer-events: none !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-breakpoint-leaving
  .game-tablet-landing-logo {
    display: block;

    width:
      var(
        --brobots-breakpoint-landing-logo-width,
        min(78%, 560px)
      );

    height:
      var(
        --brobots-breakpoint-landing-logo-height,
        auto
      );

    max-width: none;
    max-height: none;

    object-fit: contain;

    flex: 0 1 auto;

    margin: 0;

    transition: none !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-breakpoint-leaving
  .game-tablet-scroll-cue {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;

    gap:
      var(
        --brobots-breakpoint-cue-gap,
        3px
      );

    padding-top:
      var(
        --brobots-breakpoint-cue-padding-top,
        4px
      );

    padding-right:
      var(
        --brobots-breakpoint-cue-padding-right,
        10px
      );

    padding-bottom:
      var(
        --brobots-breakpoint-cue-padding-bottom,
        4px
      );

    padding-left:
      var(
        --brobots-breakpoint-cue-padding-left,
        10px
      );

    border: 0;
    background: transparent;

    color: rgba(240, 240, 240, 0.82);

    font: inherit;
    text-align: center;

    flex: 0 0 auto;

    pointer-events: none !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-breakpoint-leaving
  .game-tablet-scroll-cue-text {
    font-size:
      var(
        --brobots-breakpoint-cue-text-size,
        13px
      );

    font-weight: 600;
    letter-spacing: 0.11em;
    text-transform: uppercase;

    text-shadow:
      0 1px 8px rgba(0, 0, 0, 0.55);
  }


  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-breakpoint-leaving
  .game-tablet-scroll-cue-arrow {
    display: block;

    color:
      rgba(var(--page-accent-rgb), 0.96);

    font-size:
      var(
        --brobots-breakpoint-cue-arrow-size,
        22px
      );

    line-height: 0.78;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-breakpoint-leaving
  .game-media-zone--thumbs
  .media-strip {
    opacity: 0 !important;

    transform:
      translateY(
        var(--brobots-breakpoint-thumb-shift-y)
      )
      scale(0.975) !important;

    transition: none !important;

    pointer-events: none !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-breakpoint-leaving.is-tablet-breakpoint-handoff-active
  .game-tablet-landing-identity {
    opacity: 0 !important;

    transition:
      opacity 360ms ease !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-breakpoint-leaving.is-tablet-breakpoint-thumb-active
  .game-media-zone--thumbs
  .media-strip {
    opacity: 1 !important;

    transform:
      translateY(0)
      scale(1) !important;

    transition:
      opacity 880ms ease 90ms,
      transform
        var(--brobots-breakpoint-handoff-duration)
        cubic-bezier(0.18, 0.78, 0.22, 1) !important;
  }
}


@media (prefers-reduced-motion: reduce) {
  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-breakpoint-entering
  .game-media-zone--thumbs
  .media-strip,

  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-breakpoint-entering
  .game-tablet-landing-identity,

  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-breakpoint-leaving
  .game-media-zone--thumbs
  .media-strip,

  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-breakpoint-leaving
  .game-tablet-landing-identity {
    transition-duration: 1ms !important;
  }
}

/* =========================================================
   BROBOTS — breakpoint handoff layering + desktop hero hover
   ========================================================= */

/*
  During the desktop <-> tablet content handoff the thumbnail strip travels
  upward into the hero aperture. Keep that moving strip BEHIND the hero
  media instead of allowing its later DOM position to paint on top.
*/
.prototype-page-frame[data-game-frame-page]
.game-frame-area.is-tablet-breakpoint-entering
.game-media-zone--hero,
.prototype-page-frame[data-game-frame-page]
.game-frame-area.is-tablet-breakpoint-leaving
.game-media-zone--hero {
  z-index: 2;
}

.prototype-page-frame[data-game-frame-page]
.game-frame-area.is-tablet-breakpoint-entering
.game-media-zone--thumbs,
.prototype-page-frame[data-game-frame-page]
.game-frame-area.is-tablet-breakpoint-leaving
.game-media-zone--thumbs {
  z-index: 1;
}


/*
  Use the same 80% -> 100% hero treatment on full desktop that tablet
  already uses. The opacity belongs to the ready media stage, not the
  viewer/frame itself, so raster chrome and controls remain full strength.
*/
@media (min-width: 1401px) {
  .prototype-page-frame[data-game-frame-page]
  .game-media-zone--hero
  .media-viewer-stage.is-ready {
    opacity: 0.8;

    transition:
      opacity 220ms ease;
  }

  .prototype-page-frame[data-game-frame-page]
  .game-media-zone--hero:hover
  .media-viewer-stage.is-ready {
    opacity: 1;
  }
}


/* =========================================================
   BROBOTS — tablet -> desktop handoff uses native tablet sizing
   =========================================================

   The landing identity already has a working responsive sizing system in
   tablet mode. The previous handoff experiments overrode that system with
   frozen pixel dimensions / JS transform scaling once the viewport crossed
   1400px, which is what caused the visible size jump.

   During the transient tablet -> desktop handoff, simply keep the identity
   as its own size container and continue using the SAME sizing formulas as
   the real tablet layout. No snapshot dimensions and no JS scale are needed.
   ========================================================= */

@media (min-width: 1401px) {

  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-breakpoint-leaving
  .game-tablet-landing-identity {
    container-type: size;
    container-name: brobots-tablet-landing;

    gap:
      clamp(
        8px,
        2cqh,
        18px
      );

    padding:
      clamp(
        10px,
        2.2cqh,
        20px
      )
      clamp(
        16px,
        2.6cqw,
        28px
      );

    /*
      Do not allow the old breakpoint-handoff scale experiment to affect
      this element. Its children now resize naturally from this aperture.
    */
    transform: none !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-breakpoint-leaving
  .game-tablet-landing-logo {
    display: block;

    width:
      min(
        78%,
        560px
      );

    max-width: 78%;

    height: auto;

    /*
      This is the same effective cap used by the normal tablet landing logo.
      It prevents the logo growing during the tablet info animation while
      still allowing width to follow the shrinking handoff aperture.
    */
    max-height:
      clamp(
        76px,
        10vh,
        126px
      );

    object-fit: contain;

    flex: 0 0 auto;

    margin: 0;

    transition: none !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-breakpoint-leaving
  .game-tablet-scroll-cue {
    gap:
      clamp(
        2px,
        0.55cqh,
        5px
      );

    padding:
      clamp(
        3px,
        0.6cqh,
        6px
      )
      clamp(
        8px,
        1.2cqw,
        14px
      );
  }


  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-breakpoint-leaving
  .game-tablet-scroll-cue-text {
    font-size:
      clamp(
        11px,
        min(
          1.35cqw,
          4.6cqh
        ),
        15px
      );

    letter-spacing: 0.11em;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-breakpoint-leaving
  .game-tablet-scroll-cue-arrow {
    font-size:
      clamp(
        18px,
        min(
          2.4cqw,
          8cqh
        ),
        28px
      );
  }
}


/* =========================================================
   BROBOTS TABLET INFO — GLOBAL PROGRESS SUBSTRATE
   =========================================================

   IMPORTANT FIX:
   The scroll-up event WAS already being called correctly.

   The snap happened because the animation machinery itself lived entirely
   inside @media (841px..1400px). The instant the viewport crossed 1400px,
   CSS discarded:
     - the --brobots-tablet-frame-progress transition
     - every *-live interpolation formula

   At that moment all JS-authored frame variables fell through their existing
   fallbacks straight to *-base, so there was literally nothing left for
   setBrobotsTabletGeometryState(false) to animate.

   These formulas are safe globally:
     progress = 0  -> exact existing base/desktop geometry
     progress = 1  -> tablet info geometry

   JS still only ENTERS the info state in tablet mode. The only reason this
   substrate remains available outside tablet is so an existing info state
   can animate cleanly back to 0 after crossing into desktop.
   ========================================================= */

.prototype-page-frame[data-game-frame-page] .game-frame-area {
  --brobots-tablet-info-split-ratio:
    0.30;

  --brobots-tablet-info-hero-end-y:
    calc(
      100cqh
      *
      var(--brobots-tablet-info-split-ratio)
    );

  --brobots-tablet-info-thumb-start-y:
    calc(
      var(--brobots-tablet-info-hero-end-y)
      +
      max(
        var(--brobots-separator-h-info, 0px),
        2px
      )
    );

  /*
    Outside an active info state this remains exactly zero, so all of the
    live formulas below resolve to the normal/base desktop geometry.
  */
  --brobots-tablet-frame-progress: 0;

  transition:
    --brobots-tablet-frame-progress
      720ms
      cubic-bezier(0.18, 0.78, 0.22, 1);

  --brobots-hero-end-live-y:
    calc(
      var(--brobots-hero-end-base-y)
      +
      (
        var(--brobots-tablet-info-hero-end-y)
        -
        var(--brobots-hero-end-base-y)
      )
      *
      var(--brobots-tablet-frame-progress)
    );

  --brobots-thumb-start-live-y:
    calc(
      var(--brobots-thumb-start-base-y)
      +
      (
        var(--brobots-tablet-info-thumb-start-y)
        -
        var(--brobots-thumb-start-base-y)
      )
      *
      var(--brobots-tablet-frame-progress)
    );

  --brobots-hero-top-left-w-live:
    calc(var(--brobots-hero-top-left-w-base) + (var(--brobots-hero-top-left-w-info) - var(--brobots-hero-top-left-w-base)) * var(--brobots-tablet-frame-progress));
  --brobots-hero-top-left-h-live:
    calc(var(--brobots-hero-top-left-h-base) + (var(--brobots-hero-top-left-h-info) - var(--brobots-hero-top-left-h-base)) * var(--brobots-tablet-frame-progress));

  --brobots-hero-top-right-w-live:
    calc(var(--brobots-hero-top-right-w-base) + (var(--brobots-hero-top-right-w-info) - var(--brobots-hero-top-right-w-base)) * var(--brobots-tablet-frame-progress));
  --brobots-hero-top-right-h-live:
    calc(var(--brobots-hero-top-right-h-base) + (var(--brobots-hero-top-right-h-info) - var(--brobots-hero-top-right-h-base)) * var(--brobots-tablet-frame-progress));

  --brobots-hero-bottom-left-w-live:
    calc(var(--brobots-hero-bottom-left-w-base) + (var(--brobots-hero-bottom-left-w-info) - var(--brobots-hero-bottom-left-w-base)) * var(--brobots-tablet-frame-progress));
  --brobots-hero-bottom-left-h-live:
    calc(var(--brobots-hero-bottom-left-h-base) + (var(--brobots-hero-bottom-left-h-info) - var(--brobots-hero-bottom-left-h-base)) * var(--brobots-tablet-frame-progress));

  --brobots-hero-bottom-right-w-live:
    calc(var(--brobots-hero-bottom-right-w-base) + (var(--brobots-hero-bottom-right-w-info) - var(--brobots-hero-bottom-right-w-base)) * var(--brobots-tablet-frame-progress));
  --brobots-hero-bottom-right-h-live:
    calc(var(--brobots-hero-bottom-right-h-base) + (var(--brobots-hero-bottom-right-h-info) - var(--brobots-hero-bottom-right-h-base)) * var(--brobots-tablet-frame-progress));

  --brobots-thumb-top-left-w-live:
    calc(var(--brobots-thumb-top-left-w-base) + (var(--brobots-thumb-top-left-w-info) - var(--brobots-thumb-top-left-w-base)) * var(--brobots-tablet-frame-progress));
  --brobots-thumb-top-left-h-live:
    calc(var(--brobots-thumb-top-left-h-base) + (var(--brobots-thumb-top-left-h-info) - var(--brobots-thumb-top-left-h-base)) * var(--brobots-tablet-frame-progress));

  --brobots-thumb-top-right-w-live:
    calc(var(--brobots-thumb-top-right-w-base) + (var(--brobots-thumb-top-right-w-info) - var(--brobots-thumb-top-right-w-base)) * var(--brobots-tablet-frame-progress));
  --brobots-thumb-top-right-h-live:
    calc(var(--brobots-thumb-top-right-h-base) + (var(--brobots-thumb-top-right-h-info) - var(--brobots-thumb-top-right-h-base)) * var(--brobots-tablet-frame-progress));

  --brobots-thumb-bottom-left-w-live:
    calc(var(--brobots-thumb-bottom-left-w-base) + (var(--brobots-thumb-bottom-left-w-info) - var(--brobots-thumb-bottom-left-w-base)) * var(--brobots-tablet-frame-progress));
  --brobots-thumb-bottom-left-h-live:
    calc(var(--brobots-thumb-bottom-left-h-base) + (var(--brobots-thumb-bottom-left-h-info) - var(--brobots-thumb-bottom-left-h-base)) * var(--brobots-tablet-frame-progress));

  --brobots-thumb-bottom-right-w-live:
    calc(var(--brobots-thumb-bottom-right-w-base) + (var(--brobots-thumb-bottom-right-w-info) - var(--brobots-thumb-bottom-right-w-base)) * var(--brobots-tablet-frame-progress));
  --brobots-thumb-bottom-right-h-live:
    calc(var(--brobots-thumb-bottom-right-h-base) + (var(--brobots-thumb-bottom-right-h-info) - var(--brobots-thumb-bottom-right-h-base)) * var(--brobots-tablet-frame-progress));

  --brobots-hero-left-rail-w-live:
    calc(var(--brobots-hero-left-rail-w-base) + (var(--brobots-hero-left-rail-w-info) - var(--brobots-hero-left-rail-w-base)) * var(--brobots-tablet-frame-progress));
  --brobots-hero-right-rail-w-live:
    calc(var(--brobots-hero-right-rail-w-base) + (var(--brobots-hero-right-rail-w-info) - var(--brobots-hero-right-rail-w-base)) * var(--brobots-tablet-frame-progress));
  --brobots-hero-top-bar-h-live:
    calc(var(--brobots-hero-top-bar-h-base) + (var(--brobots-hero-top-bar-h-info) - var(--brobots-hero-top-bar-h-base)) * var(--brobots-tablet-frame-progress));
  --brobots-hero-bottom-bar-h-live:
    calc(var(--brobots-hero-bottom-bar-h-base) + (var(--brobots-hero-bottom-bar-h-info) - var(--brobots-hero-bottom-bar-h-base)) * var(--brobots-tablet-frame-progress));

  --brobots-thumb-left-rail-w-live:
    calc(var(--brobots-thumb-left-rail-w-base) + (var(--brobots-thumb-left-rail-w-info) - var(--brobots-thumb-left-rail-w-base)) * var(--brobots-tablet-frame-progress));
  --brobots-thumb-right-rail-w-live:
    calc(var(--brobots-thumb-right-rail-w-base) + (var(--brobots-thumb-right-rail-w-info) - var(--brobots-thumb-right-rail-w-base)) * var(--brobots-tablet-frame-progress));
  --brobots-thumb-top-bar-h-live:
    calc(var(--brobots-thumb-top-bar-h-base) + (var(--brobots-thumb-top-bar-h-info) - var(--brobots-thumb-top-bar-h-base)) * var(--brobots-tablet-frame-progress));
  --brobots-thumb-bottom-bar-h-live:
    calc(var(--brobots-thumb-bottom-bar-h-base) + (var(--brobots-thumb-bottom-bar-h-info) - var(--brobots-thumb-bottom-bar-h-base)) * var(--brobots-tablet-frame-progress));

  --brobots-separator-h-live:
    calc(var(--brobots-separator-h-base) + (var(--brobots-separator-h-info) - var(--brobots-separator-h-base)) * var(--brobots-tablet-frame-progress));
}


/*
  Keep the existing state switch global as well. The JS tablet guard still
  prevents this state from being entered on desktop; this simply lets a state
  that ALREADY EXISTS survive the breakpoint long enough to animate out.
*/
.prototype-page-frame[data-game-frame-page]
.game-frame-area.is-tablet-info-geometry {
  --brobots-tablet-frame-progress: 1;
}


/*
  The raster pieces already consume these --*-live values through the
  JS-authored aliases. Keep their interpolation available outside the tablet
  media query for the same exit-only reason.
*/
.prototype-page-frame[data-game-frame-page]
.game-frame-area > [data-game-frame-piece] {
  --brobots-piece-live-w:
    calc(
      var(--brobots-piece-base-w)
      +
      (
        var(--brobots-piece-info-w)
        -
        var(--brobots-piece-base-w)
      )
      *
      var(--brobots-tablet-frame-progress)
    );

  --brobots-piece-live-h:
    calc(
      var(--brobots-piece-base-h)
      +
      (
        var(--brobots-piece-info-h)
        -
        var(--brobots-piece-base-h)
      )
      *
      var(--brobots-tablet-frame-progress)
    );
}


.prototype-page-frame[data-game-frame-page]
.game-frame-area > [data-game-frame-stretcher] {
  --brobots-stretcher-live-w:
    calc(
      var(--brobots-stretcher-base-w)
      +
      (
        var(--brobots-stretcher-info-w)
        -
        var(--brobots-stretcher-base-w)
      )
      *
      var(--brobots-tablet-frame-progress)
    );

  --brobots-stretcher-live-h:
    calc(
      var(--brobots-stretcher-base-h)
      +
      (
        var(--brobots-stretcher-info-h)
        -
        var(--brobots-stretcher-base-h)
      )
      *
      var(--brobots-tablet-frame-progress)
    );
}


/* =========================================================
   SHARED TABLET GLASS — BROBOTS INFO FORMATTING PRESERVED
   =========================================================

   The information layout above now comes from the real Brobots rules.
   This is only the glass/decorative layer that was confirmed working in
   the previous pass.
   ========================================================= */

@media (max-width: 1400px) {

  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack {
    position: absolute !important;
    inset: 0 !important;

    z-index: 1 !important;

    display: block !important;
    overflow: hidden !important;

    opacity: 1 !important;
    visibility: visible !important;

    pointer-events: none !important;

    transform: none !important;
    transition: none !important;
    clip-path: none !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer {
    display: block !important;
    position: absolute !important;

    opacity: 1 !important;
    visibility: visible !important;

    overflow: hidden !important;

    border:
      1px solid
      rgba(255,255,255,0.055) !important;

    box-shadow:
      inset 0 0 0 1px
      rgba(255,255,255,0.035),
      0 8px 28px
      rgba(0,0,0,0.10) !important;

    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;

    transform: none !important;
    transition: none !important;
    will-change: auto !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--1 {
    inset: 1.5% 1.8% 4.5% 0 !important;

    border-radius:
      clamp(24px, 3.1cqw, 40px) !important;

    background:
      linear-gradient(
        112deg,
        rgba(255,255,255,0.075),
        rgba(var(--page-accent-rgb),0.105) 52%,
        rgba(22,32,40,0.18)
      ) !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--2 {
    inset: 6% 6.5% 8% 1.5% !important;

    border-radius:
      clamp(20px, 2.7cqw, 36px) !important;

    background:
      linear-gradient(
        105deg,
        rgba(80,105,120,0.20),
        rgba(255,255,255,0.055)
      ) !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--3 {
    inset: 11% 12.5% 13% 3% !important;

    border-radius:
      clamp(18px, 2.35cqw, 32px) !important;

    background:
      linear-gradient(
        115deg,
        rgba(var(--page-accent-rgb),0.09),
        rgba(90,105,120,0.18)
      ) !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--4 {
    left: 2% !important;
    right: 17% !important;
    top: 52% !important;
    bottom: 1% !important;

    border-radius:
      clamp(16px, 2.1cqw, 28px) !important;

    background:
      linear-gradient(
        108deg,
        rgba(255,255,255,0.065),
        rgba(var(--page-accent-rgb),0.12)
      ) !important;
  }


}


/* =========================================================
   SHARED TABLET GLASS — TOP-RIGHT MASKED SCREENSHOT
   =========================================================

   Each game's authored desktop glass stack already contains its own image.
   The tablet controller clones that stack, so the image source stays entirely
   page-driven. The responsive "hide popout image" rules above are now scoped
   to .desktop-secondary-panel only, allowing the tablet clone to participate.
   ========================================================= */

@media (max-width: 1400px) {

  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--1 {
    overflow: hidden;
    isolation: isolate;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-layer-image {
    display: block;

    position: absolute;
    inset: 0;

    width: 100%;
    height: 100%;

    max-width: none;
    max-height: none;

    z-index: 0;

    object-fit: cover;
    object-position: right top;

    opacity: 0.58;

    filter:
      saturate(0.92)
      contrast(0.96)
      brightness(0.82);

    -webkit-mask-image:
      radial-gradient(
        ellipse 78% 72%
        at 100% 0%,
        rgba(0,0,0,1) 0%,
        rgba(0,0,0,0.96) 30%,
        rgba(0,0,0,0.72) 48%,
        rgba(0,0,0,0.30) 66%,
        rgba(0,0,0,0) 84%
      );

    mask-image:
      radial-gradient(
        ellipse 78% 72%
        at 100% 0%,
        rgba(0,0,0,1) 0%,
        rgba(0,0,0,0.96) 30%,
        rgba(0,0,0,0.72) 48%,
        rgba(0,0,0,0.30) 66%,
        rgba(0,0,0,0) 84%
      );

    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;

    -webkit-mask-size: 100% 100%;
    mask-size: 100% 100%;

    pointer-events: none;
  }

}


/* =========================================================
   SHARED TABLET GLASS SCREENSHOT — DESKTOP RULE, VERBATIM
   =========================================================

   This is intentionally NOT a tablet reinterpretation.

   The desktop popout's working screenshot geometry is:
     position:absolute;
     top:0;
     right:0;
     height:100%;
     width:auto;
     object-fit:contain;
     object-position:top right;

   The exact same geometry and radial mask are applied to the image cloned
   into the tablet glass stack. No inset:0, no width:100%, no alternate crop.
   ========================================================= */

@media (max-width: 1400px) {

  .prototype-page-frame[data-game-frame-page]:not(.is-layout-transitioning)
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-layer-image {
    position: absolute !important;

    top: 0 !important;
    right: 0 !important;
    left: auto !important;
    bottom: auto !important;

    height: 100% !important;
    width: auto !important;

    max-width: none !important;
    max-height: none !important;

    display: block !important;

    object-fit: contain !important;
    object-position: top right !important;

    z-index: 0 !important;

    opacity: 0.58 !important;

    filter:
      saturate(0.92)
      contrast(0.96)
      brightness(0.88)
      !important;

    -webkit-mask-image:
      radial-gradient(
        ellipse 78% 72%
        at 100% 0%,
        rgba(0, 0, 0, 1) 0%,
        rgba(0, 0, 0, 0.96) 30%,
        rgba(0, 0, 0, 0.72) 48%,
        rgba(0, 0, 0, 0.30) 66%,
        rgba(0, 0, 0, 0) 84%
      ) !important;

    mask-image:
      radial-gradient(
        ellipse 78% 72%
        at 100% 0%,
        rgba(0, 0, 0, 1) 0%,
        rgba(0, 0, 0, 0.96) 30%,
        rgba(0, 0, 0, 0.72) 48%,
        rgba(0, 0, 0, 0.30) 66%,
        rgba(0, 0, 0, 0) 84%
      ) !important;

    -webkit-mask-repeat: no-repeat !important;
    mask-repeat: no-repeat !important;

    -webkit-mask-size: 100% 100% !important;
    mask-size: 100% 100% !important;

    pointer-events: none !important;

    transform: none !important;
  }

}



/* =========================================================
   TABLET GLASS STACK — DESKTOP-STYLE CHAMFERED CORNERS
   =========================================================

   Replace the tablet's rounded pane corners with the same angular chamfer
   language used by the desktop popout glass.

   Unlike the desktop panes, the tablet version should chamfer ALL FOUR
   corners. The angle stays tied to the existing button/popout shear so the
   visual language remains consistent across the site.
   ========================================================= */

@media (max-width: 1400px) {

  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack {
    --tablet-glass-angle:
      calc(
        var(--button-shear-angle) * -1
      );
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer {
    border-radius: 0 !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer::before,
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer::after {
    border-radius: 0 !important;
    clip-path: inherit;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--1 {
    --tablet-pane-cut-rise:
      clamp(24px, 2.45cqw, 38px);

    --tablet-pane-cut-run:
      calc(
        var(--tablet-pane-cut-rise)
        *
        tan(
          var(--tablet-glass-angle)
        )
      );

    clip-path:
      polygon(
        var(--tablet-pane-cut-run) 0,
        calc(100% - var(--tablet-pane-cut-run)) 0,
        100% var(--tablet-pane-cut-rise),
        100% calc(100% - var(--tablet-pane-cut-rise)),
        calc(100% - var(--tablet-pane-cut-run)) 100%,
        var(--tablet-pane-cut-run) 100%,
        0 calc(100% - var(--tablet-pane-cut-rise)),
        0 var(--tablet-pane-cut-rise)
      ) !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--2 {
    --tablet-pane-cut-rise:
      clamp(20px, 2.05cqw, 32px);

    --tablet-pane-cut-run:
      calc(
        var(--tablet-pane-cut-rise)
        *
        tan(
          var(--tablet-glass-angle)
        )
      );

    clip-path:
      polygon(
        var(--tablet-pane-cut-run) 0,
        calc(100% - var(--tablet-pane-cut-run)) 0,
        100% var(--tablet-pane-cut-rise),
        100% calc(100% - var(--tablet-pane-cut-rise)),
        calc(100% - var(--tablet-pane-cut-run)) 100%,
        var(--tablet-pane-cut-run) 100%,
        0 calc(100% - var(--tablet-pane-cut-rise)),
        0 var(--tablet-pane-cut-rise)
      ) !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--3 {
    --tablet-pane-cut-rise:
      clamp(17px, 1.75cqw, 28px);

    --tablet-pane-cut-run:
      calc(
        var(--tablet-pane-cut-rise)
        *
        tan(
          var(--tablet-glass-angle)
        )
      );

    clip-path:
      polygon(
        var(--tablet-pane-cut-run) 0,
        calc(100% - var(--tablet-pane-cut-run)) 0,
        100% var(--tablet-pane-cut-rise),
        100% calc(100% - var(--tablet-pane-cut-rise)),
        calc(100% - var(--tablet-pane-cut-run)) 100%,
        var(--tablet-pane-cut-run) 100%,
        0 calc(100% - var(--tablet-pane-cut-rise)),
        0 var(--tablet-pane-cut-rise)
      ) !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--4 {
    --tablet-pane-cut-rise:
      clamp(15px, 1.55cqw, 24px);

    --tablet-pane-cut-run:
      calc(
        var(--tablet-pane-cut-rise)
        *
        tan(
          var(--tablet-glass-angle)
        )
      );

    clip-path:
      polygon(
        var(--tablet-pane-cut-run) 0,
        calc(100% - var(--tablet-pane-cut-run)) 0,
        100% var(--tablet-pane-cut-rise),
        100% calc(100% - var(--tablet-pane-cut-rise)),
        calc(100% - var(--tablet-pane-cut-run)) 100%,
        var(--tablet-pane-cut-run) 100%,
        0 calc(100% - var(--tablet-pane-cut-rise)),
        0 var(--tablet-pane-cut-rise)
      ) !important;
  }

}



/* =========================================================
   GAME FRAME — STRETCH FLEXIBLE BARS INSTEAD OF TILING
   =========================================================

   The original Brobots skin used tiny spacer samples and repeated them
   along the flexible axis. Etherian's spacer artwork is much larger and is
   authored as a continuous section, so repeating it is visibly incorrect.

   Keep the measured cross-axis thickness from JS, but stretch each source
   once across the flexible axis:
     horizontal bars -> width 100%, measured height
     vertical bars   -> measured width, height 100%

   Separator already uses one continuous stretched source.
   ========================================================= */

.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--hero-top,
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--hero-bottom,
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--thumb-top,
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--thumb-bottom {
  background-repeat: no-repeat !important;
  background-position: center !important;

  background-size:
    100%
    var(--brobots-stretcher-h)
    !important;
}


.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--hero-left,
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--hero-right,
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--thumb-left,
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--thumb-right {
  background-repeat: no-repeat !important;
  background-position: center !important;

  background-size:
    var(--brobots-stretcher-w)
    100%
    !important;
}



/* =========================================================
   GAME FRAME — THUMBNAIL RAILS TILE ON THEIR LONG AXIS
   =========================================================

   Hero rails remain stretched once, but the thumbnail section becomes very
   tall in tablet info mode. Stretching the side artwork across that entire
   cavity visibly smears the stone texture, so the thumbnail rails return to
   repeating on their flexible axis.

   Cross-axis thickness is still taken from the measured source artwork.
   ========================================================= */

/* Horizontal thumbnail rails: repeat left-to-right. */
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--thumb-top,
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--thumb-bottom {
  background-repeat: repeat-x !important;
  background-position: center !important;

  background-size:
    var(--brobots-stretcher-w)
    var(--brobots-stretcher-h)
    !important;
}


/* Vertical thumbnail rails: repeat top-to-bottom. */
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--thumb-left,
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--thumb-right {
  background-repeat: repeat-y !important;
  background-position: center !important;

  background-size:
    var(--brobots-stretcher-w)
    var(--brobots-stretcher-h)
    !important;
}



/* =========================================================
   GAME FRAME — CONSISTENT TEXEL DENSITY / TILE ALL RAILS
   =========================================================

   Final policy for the current raster skins:
   every flexible rail repeats on its long axis rather than stretching.

   This preserves the authored texel density and keeps the stone/material
   scale consistent between fixed corner pieces and flexible rails.

   Horizontal rails -> repeat-x
   Vertical rails   -> repeat-y
   Separator        -> repeat-x
   ========================================================= */

.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--hero-top,
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--hero-bottom,
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--thumb-top,
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--thumb-bottom,
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--separator {
  background-repeat: repeat-x !important;
  background-position: center !important;

  background-size:
    var(--brobots-stretcher-w)
    var(--brobots-stretcher-h)
    !important;
}


.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--hero-left,
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--hero-right,
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--thumb-left,
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--thumb-right {
  background-repeat: repeat-y !important;
  background-position: center !important;

  background-size:
    var(--brobots-stretcher-w)
    var(--brobots-stretcher-h)
    !important;
}



/* =========================================================
   GAME FRAME — CANONICAL CENTER SEPARATOR
   =========================================================

   The separator is NOT the same kind of stretcher as the four rails.

   Its source artwork is authored as a full-width strip spanning the entire
   frame. Older Brobots CSS has several historical separator implementations
   (including a hard-coded 1164px version), while v111 accidentally grouped
   the separator into the new repeat-x rail policy.

   That combination makes its phase / width disagree with the fixed frame
   pieces on every skin.

   Final rule:
     - span the exact gap between hero + thumbnail regions
     - use the whole separator image once
     - scale it to the separator box
     - never tile it
   ========================================================= */

.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--separator {
  left: 0 !important;
  right: 0 !important;

  width: auto !important;

  top:
    var(--brobots-hero-end-y) !important;

  bottom:
    calc(
      100%
      -
      var(--brobots-thumb-start-y)
    ) !important;

  height: auto !important;

  background-image:
    var(--brobots-stretcher-image) !important;

  background-repeat:
    no-repeat !important;

  background-position:
    center center !important;

  background-size:
    100% 100% !important;

  z-index: 4 !important;
}



/* =========================================================
   GAME FRAME — HYBRID RAIL POLICY
   =========================================================

   Back out of the three-slice experiment and use a pragmatic hybrid:

   STRETCH
   - hero-top
   - hero-left
   - hero-right

   TILE
   - hero-bottom
   - thumb-top
   - thumb-bottom
   - thumb-left
   - thumb-right

   KEEP SPECIAL
   - separator remains the canonical full-width separator from v112

   This matches the visible problem areas in Etherian while keeping the
   simpler authored/tiled behavior everywhere else.
   ========================================================= */

/* If any old three-slice spans exist during live reload, hide them. */
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher
.game-frame-slice {
  display: none !important;
}

/* ---------------------------
   Stretch the hero top rail
   --------------------------- */
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--hero-top {
  background-repeat: no-repeat !important;
  background-position: center !important;
  background-size:
    100%
    var(--brobots-stretcher-h)
    !important;
}

/* --------------------------------------
   Stretch the hero left / right sidebars
   -------------------------------------- */
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--hero-left,
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--hero-right {
  background-repeat: no-repeat !important;
  background-position: center !important;
  background-size:
    var(--brobots-stretcher-w)
    100%
    !important;
}

/* -----------------------
   Tile the hero bottom bar
   ----------------------- */
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--hero-bottom {
  background-repeat: repeat-x !important;
  background-position: center !important;
  background-size:
    var(--brobots-stretcher-w)
    var(--brobots-stretcher-h)
    !important;
}

/* -----------------------------------------
   Tile the thumbnail top / bottom / sidebars
   ----------------------------------------- */
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--thumb-top,
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--thumb-bottom {
  background-repeat: repeat-x !important;
  background-position: center !important;
  background-size:
    var(--brobots-stretcher-w)
    var(--brobots-stretcher-h)
    !important;
}

.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--thumb-left,
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--thumb-right {
  background-repeat: repeat-y !important;
  background-position: center !important;
  background-size:
    var(--brobots-stretcher-w)
    var(--brobots-stretcher-h)
    !important;
}



/* =========================================================
   GAME FRAME — 16-PIECE MODE (NO CENTER SEPARATOR)
   =========================================================

   The separator asset has been removed from every game frame. Hero and
   thumbnail regions now meet directly.

   Keep the old historical separator rules inert; there is no separator
   element in the DOM anymore. These variables collapse any remaining
   separator-era spacing assumptions to zero.
   ========================================================= */

.prototype-page-frame[data-game-frame-page] .game-frame-area {
  --brobots-separator-h-base: 0px;
  --brobots-separator-h-info: 0px;
  --brobots-separator-h-live: 0px;

  --brobots-tablet-info-thumb-start-y:
    var(--brobots-tablet-info-hero-end-y);
}

/*
  Defensive only: if an old cached/live-reload DOM still contains a separator,
  it contributes nothing.
*/
.prototype-page-frame[data-game-frame-page]
.game-frame-stretcher--separator {
  display: none !important;
}



/* =========================================================
   MOBILE PROTOTYPE — INHERIT TABLET GAME-PAGE COMPOSITION
   =========================================================
   Exploratory pass only.

   Phones now use the same raster-frame/media composition and the same
   media <-> info state machine as tablet. The old mobile gallery rules are
   left in place above for easy rollback, then neutralized here.

   We are intentionally NOT doing phone-specific formatting yet. The point
   of this checkpoint is to expose exactly what the tablet composition does
   when squeezed into a phone aspect ratio.
   ========================================================= */

@media (max-width: 750px) {

  /* Tablet/game raster frame becomes the visible page shell on mobile too. */
  .prototype-page-frame[data-game-frame-page]
  .prototype-page-frame-shell {
    opacity: 0;
  }


  .prototype-page-frame[data-game-frame-page]
  .prototype-page-frame-content {
    top:
      clamp(
        6px,
        0.65cqw,
        12px
      );

    right:
      clamp(
        6px,
        0.65cqw,
        12px
      );

    bottom:
      clamp(
        6px,
        0.65cqw,
        12px
      );

    left:
      clamp(
        6px,
        0.65cqw,
        12px
      );
  }


  .prototype-page-frame[data-game-frame-page]
  .game-frame-area {
    display: block !important;

    position: relative;

    width: 100%;
    height: 100%;

    aspect-ratio: auto;

    margin: 0;

    overflow: hidden;

    container-type: size;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-frame-area > .game-frame-piece,
  .prototype-page-frame[data-game-frame-page]
  .game-frame-area > .game-frame-stretcher {
    display: block !important;
  }


  /* Restore the shared frame-controlled media canvas. */
  .prototype-page-frame[data-game-frame-page]
  .game-frame-area > .media-browser {
    position: absolute !important;

    z-index: 1;

    inset: 0;

    width: 100% !important;
    height: 100% !important;

    max-width: none;

    margin: 0;
    padding: 0;

    display: block;

    overflow: visible;

    pointer-events: none;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-media-zone {
    position: absolute;

    display: grid;
    place-items: center;

    min-width: 0;
    min-height: 0;

    container-type: size;

    pointer-events: none;
  }


  /* Undo the former mobile "contained generic gallery" hero treatment. */
  .prototype-page-frame[data-game-frame-page]
  .game-media-zone--hero
  .media-viewer {
    width: 100cqw !important;
    height: 100cqh !important;

    max-width: none;
    max-height: none;

    aspect-ratio: auto !important;

    margin: 0;

    justify-self: stretch;
    align-self: stretch;

    transform:
      scale(1.04);

    transform-origin:
      50% 50%;

    pointer-events: auto;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-media-zone--hero
  .media-viewer-stage {
    position: absolute;

    inset: 0;

    display: block;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-media-zone--hero
  .media-viewer-image,
  .prototype-page-frame[data-game-frame-page]
  .game-media-zone--hero
  .media-viewer-video {
    position: absolute;

    left: 50%;
    top: 50%;

    width: 100% !important;
    height: 100% !important;

    transform:
      translate(-50%, -50%);

    object-fit: cover !important;
    object-position: 50% 50% !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-media-zone--hero
  .media-viewer-youtube {
    position: absolute;

    left: 50%;
    top: 50%;

    width:
      max(
        100%,
        calc(100cqh * 16 / 9)
      );

    height:
      max(
        100%,
        calc(100cqw * 9 / 16)
      );

    max-width: none;
    max-height: none;

    aspect-ratio: 16 / 9;

    transform:
      translate(-50%, -50%);
  }


  /* Restore the frame-controlled thumbnail aperture too. */
  .prototype-page-frame[data-game-frame-page]
  .game-media-zone--thumbs
  .media-strip {
    position: absolute;

    inset: 0;

    width: 100% !important;
    height: 100% !important;

    max-width: none;

    display: block;

    margin: 0;

    pointer-events: auto;
  }
}



/* =========================================================
   MOBILE PROTOTYPE — REAL PAGE FRAMES STAY ACTIVE
   =========================================================
   Older mobile CSS deliberately removed .prototype-page-frame entirely.
   Mobile now shares the tablet page internals, so the real frame must remain
   present and interactive below 750px.
   ========================================================= */

@media (max-width: 750px) {

  .prototype-page-frame {
    display: block !important;
  }


  /*
    Use the normal fixed page rectangle for this first functional prototype.
    Phone-specific proportions come next once we can actually inspect the
    shared tablet treatment on a live mobile page.
  */
  .prototype-page-frame[data-game-frame-page] {
    --page-frame-shift-y: 0px;

    --page-frame-side-padding:
      clamp(
        10px,
        3vw,
        18px
      );

    top:
      calc(
        clamp(82px, calc(64px + 3.9vw), 120px)
        +
        (clamp(6px, 0.7vw, 10px) * 2)
        +
        10px
      );

    right:
      var(--page-frame-side-padding);

    bottom:
      clamp(
        10px,
        3vw,
        18px
      );

    left:
      var(--page-frame-side-padding);
  }
}



/* =========================================================
   MOBILE PROTOTYPE — KEEP TABLET VERTICAL FRAME COMPOSITION
   =========================================================

   v121 gave mobile its own top/bottom rectangle. That changed the frame's
   vertical center exactly at 750px, which is the visible downward "pop"
   during tablet -> mobile resizing.

   Mobile can still use tighter horizontal side padding, but the vertical
   rectangle should remain continuous across the breakpoint.
   ========================================================= */

@media (max-width: 750px) {
  .prototype-page-frame[data-game-frame-page] {
    /*
      Match the shared tablet/desktop vertical composition.
      These override the exploratory v121 mobile values.
    */
    --page-frame-shift-y: -18px;

    top:
      calc(
        clamp(82px, calc(64px + 3.9vw), 120px)
        +
        (clamp(6px, 0.7vw, 10px) * 2)
        +
        20px
        +
        var(--page-frame-shift-y)
      );

    bottom:
      calc(
        clamp(18px, 2vw, 30px)
        -
        var(--page-frame-shift-y)
      );

    /*
      Keep the narrower mobile horizontal margins from v121.
    */
    --page-frame-side-padding:
      clamp(
        10px,
        3vw,
        18px
      );
  }
}



/* =========================================================
   MOBILE PROTOTYPE — CONTINUOUS HORIZONTAL FRAME WIDTH
   =========================================================

   The tablet frame reaches 840px with 28px side padding.
   v121/v122 switched immediately to an 18px mobile maximum, so crossing
   the breakpoint added ~20px of total frame width in one frame.

   Start mobile at the exact same 28px inset, then let it decrease smoothly
   with the viewport instead of stepping at 750px.
   ========================================================= */

@media (max-width: 750px) {
  .prototype-page-frame[data-game-frame-page] {
    --page-frame-side-padding:
      clamp(
        10px,
        3.333333vw,
        28px
      );
  }
}



/* =========================================================
   MOBILE — KEEP VERTICAL SWIPES INSIDE THE SITE
   =========================================================

   The game pages use deliberate swipe gestures rather than native document
   scrolling. Prevent the browser's root overscroll / pull-to-refresh gesture
   from competing with those interactions.

   JS also claims a clearly-vertical touchmove immediately, before the larger
   navigation threshold is reached. This CSS is the browser-level first line
   of defense; the JS handler is the fallback/interaction-level lock.
   ========================================================= */

@media (max-width: 750px) {
  html,
  body {
    overscroll-behavior-y: none;
  }

  .prototype-page-frame[data-game-frame-page].is-open {
    overscroll-behavior: none;
  }
}



/* =========================================================
   MOBILE MEDIA UX
   =========================================================
   - Hide tablet hover arrows + pagination dots on phones.
   - Hero media is changed by horizontal swipe instead.
   - Image-to-image changes use a directional soft-edge gradient wipe.
   ========================================================= */

@media (max-width: 750px) {

  .prototype-page-frame[data-game-frame-page]
  .media-hero-navigation {
    display: none !important;
  }


  /*
    Keep both outgoing and incoming screenshots stacked during a mobile wipe.
  */
  .prototype-page-frame[data-game-frame-page]
  .media-viewer-stage
  .media-viewer-image--outgoing,
  .prototype-page-frame[data-game-frame-page]
  .media-viewer-stage
  .media-viewer-image--incoming {
    position: absolute !important;
    inset: 0 !important;

    width: 100% !important;
    height: 100% !important;

    transform: none !important;

    object-fit: cover !important;
    object-position: 50% 50% !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .media-viewer-image--outgoing {
    z-index: 1;
  }


  .prototype-page-frame[data-game-frame-page]
  .media-viewer-image--incoming {
    z-index: 2;

    /*
      A feathered mask creates the "gradient wipe" rather than a hard clip.
      The whole mask is translated across the image in the swipe direction.
    */
    -webkit-mask-image:
      linear-gradient(
        90deg,
        transparent 0%,
        rgba(0, 0, 0, 0.10) 8%,
        #000 22%,
        #000 100%
      );

    mask-image:
      linear-gradient(
        90deg,
        transparent 0%,
        rgba(0, 0, 0, 0.10) 8%,
        #000 22%,
        #000 100%
      );

    -webkit-mask-size:
      160% 100%;

    mask-size:
      160% 100%;

    -webkit-mask-repeat:
      no-repeat;

    mask-repeat:
      no-repeat;

    will-change:
      -webkit-mask-position,
      mask-position,
      opacity;
  }


  .prototype-page-frame[data-game-frame-page]
  .media-viewer-stage.is-mobile-wipe-forward
  .media-viewer-image--incoming {
    animation:
      mobile-media-wipe-forward
      360ms
      cubic-bezier(0.22, 0.72, 0.24, 1)
      both;
  }


  .prototype-page-frame[data-game-frame-page]
  .media-viewer-stage.is-mobile-wipe-backward
  .media-viewer-image--incoming {
    transform: scaleX(-1) !important;

    animation:
      mobile-media-wipe-backward
      360ms
      cubic-bezier(0.22, 0.72, 0.24, 1)
      both;
  }


  @keyframes mobile-media-wipe-forward {
    from {
      -webkit-mask-position: 155% 0;
      mask-position: 155% 0;
      opacity: 0.92;
    }

    to {
      -webkit-mask-position: -55% 0;
      mask-position: -55% 0;
      opacity: 1;
    }
  }


  @keyframes mobile-media-wipe-backward {
    from {
      -webkit-mask-position: 155% 0;
      mask-position: 155% 0;
      opacity: 0.92;
    }

    to {
      -webkit-mask-position: -55% 0;
      mask-position: -55% 0;
      opacity: 1;
    }
  }
}



/* =========================================================
   MOBILE MEDIA WIPE — LOAD-SAFE DIRECTION FIX
   =========================================================

   v125 had two problems:
   1. the wipe animation could run before the incoming screenshot loaded;
   2. the reverse direction used scaleX(-1), which literally mirrored the
      screenshot.

   Keep both images normally oriented and use opposite gradient masks instead.
   JS now starts these animations only after the incoming image is ready.
   ========================================================= */

@media (max-width: 750px) {

  .prototype-page-frame[data-game-frame-page]
  .media-viewer-stage
  .media-viewer-image--incoming {
    transform: none !important;
    opacity: 1;
  }


  /* NEXT: reveal B from right -> left. */
  .prototype-page-frame[data-game-frame-page]
  .media-viewer-stage.is-mobile-wipe-forward
  .media-viewer-image--incoming {
    -webkit-mask-image:
      linear-gradient(
        90deg,
        #000 0%,
        #000 68%,
        rgba(0, 0, 0, 0.72) 78%,
        rgba(0, 0, 0, 0.18) 92%,
        transparent 100%
      ) !important;

    mask-image:
      linear-gradient(
        90deg,
        #000 0%,
        #000 68%,
        rgba(0, 0, 0, 0.72) 78%,
        rgba(0, 0, 0, 0.18) 92%,
        transparent 100%
      ) !important;

    -webkit-mask-size: 220% 100% !important;
    mask-size: 220% 100% !important;

    animation:
      mobile-media-reveal-from-right
      360ms
      cubic-bezier(0.22, 0.72, 0.24, 1)
      both !important;
  }


  /* PREVIOUS: reveal B from left -> right. */
  .prototype-page-frame[data-game-frame-page]
  .media-viewer-stage.is-mobile-wipe-backward
  .media-viewer-image--incoming {
    transform: none !important;

    -webkit-mask-image:
      linear-gradient(
        90deg,
        transparent 0%,
        rgba(0, 0, 0, 0.18) 8%,
        rgba(0, 0, 0, 0.72) 22%,
        #000 32%,
        #000 100%
      ) !important;

    mask-image:
      linear-gradient(
        90deg,
        transparent 0%,
        rgba(0, 0, 0, 0.18) 8%,
        rgba(0, 0, 0, 0.72) 22%,
        #000 32%,
        #000 100%
      ) !important;

    -webkit-mask-size: 220% 100% !important;
    mask-size: 220% 100% !important;

    animation:
      mobile-media-reveal-from-left
      360ms
      cubic-bezier(0.22, 0.72, 0.24, 1)
      both !important;
  }


  @keyframes mobile-media-reveal-from-right {
    from {
      -webkit-mask-position: -120% 0;
      mask-position: -120% 0;
    }

    to {
      -webkit-mask-position: 100% 0;
      mask-position: 100% 0;
    }
  }


  @keyframes mobile-media-reveal-from-left {
    from {
      -webkit-mask-position: 120% 0;
      mask-position: 120% 0;
    }

    to {
      -webkit-mask-position: -100% 0;
      mask-position: -100% 0;
    }
  }
}



/* =========================================================
   MOBILE MEDIA WIPE — DIRECT INCOMING-IMAGE ANIMATION
   =========================================================

   The previous implementation put the animation state on the stage. That
   made it too easy for the outgoing clone / inherited classes to participate
   in the wipe.

   This version is intentionally literal:
     A = static outgoing image underneath
     B = incoming image, hidden by its own mask BEFORE insertion
     B alone animates its mask across A
   ========================================================= */

@media (max-width: 750px) {

  .prototype-page-frame[data-game-frame-page]
  .media-viewer-image--outgoing {
    z-index: 1 !important;

    -webkit-mask-image: none !important;
    mask-image: none !important;

    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .media-viewer-image--incoming {
    z-index: 2 !important;

    animation: none !important;
    opacity: 1 !important;
    transform: none !important;

    -webkit-mask-repeat: no-repeat !important;
    mask-repeat: no-repeat !important;

    -webkit-mask-size: 220% 100% !important;
    mask-size: 220% 100% !important;
  }


  /* B starts completely hidden off the RIGHT and reveals right -> left. */
  .prototype-page-frame[data-game-frame-page]
  .media-viewer-image--incoming.is-wipe-forward {
    -webkit-mask-image:
      linear-gradient(
        90deg,
        #000 0%,
        #000 68%,
        rgba(0, 0, 0, 0.72) 78%,
        rgba(0, 0, 0, 0.18) 92%,
        transparent 100%
      ) !important;

    mask-image:
      linear-gradient(
        90deg,
        #000 0%,
        #000 68%,
        rgba(0, 0, 0, 0.72) 78%,
        rgba(0, 0, 0, 0.18) 92%,
        transparent 100%
      ) !important;

    -webkit-mask-position: -120% 0 !important;
    mask-position: -120% 0 !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .media-viewer-image--incoming.is-wipe-forward.is-wipe-running {
    animation:
      mobile-incoming-wipe-forward
      380ms
      cubic-bezier(0.22, 0.72, 0.24, 1)
      both !important;
  }


  /* B starts completely hidden off the LEFT and reveals left -> right. */
  .prototype-page-frame[data-game-frame-page]
  .media-viewer-image--incoming.is-wipe-backward {
    -webkit-mask-image:
      linear-gradient(
        90deg,
        transparent 0%,
        rgba(0, 0, 0, 0.18) 8%,
        rgba(0, 0, 0, 0.72) 22%,
        #000 32%,
        #000 100%
      ) !important;

    mask-image:
      linear-gradient(
        90deg,
        transparent 0%,
        rgba(0, 0, 0, 0.18) 8%,
        rgba(0, 0, 0, 0.72) 22%,
        #000 32%,
        #000 100%
      ) !important;

    -webkit-mask-position: 120% 0 !important;
    mask-position: 120% 0 !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .media-viewer-image--incoming.is-wipe-backward.is-wipe-running {
    animation:
      mobile-incoming-wipe-backward
      380ms
      cubic-bezier(0.22, 0.72, 0.24, 1)
      both !important;
  }


  @keyframes mobile-incoming-wipe-forward {
    from {
      -webkit-mask-position: -120% 0;
      mask-position: -120% 0;
    }

    to {
      -webkit-mask-position: 100% 0;
      mask-position: 100% 0;
    }
  }


  @keyframes mobile-incoming-wipe-backward {
    from {
      -webkit-mask-position: 120% 0;
      mask-position: 120% 0;
    }

    to {
      -webkit-mask-position: -100% 0;
      mask-position: -100% 0;
    }
  }
}



/* =========================================================
   MOBILE MEDIA WIPE — WIDTH REVEAL LAYER (FINAL OVERRIDE)
   =========================================================

   Previous mask-position versions were ambiguous: B could already be visible,
   then the moving mask exposed A again underneath.

   This renderer is geometrically simple:
     A stays static underneath.
     B sits full-size inside an overflow-hidden wrapper.
     The wrapper grows from 0% -> 100% width.
     A soft mask on the wrapper feathers ONLY the moving reveal edge.

   Neither image translates, mirrors, fades, or animates.
   ========================================================= */

@media (max-width: 750px) {

  .prototype-page-frame[data-game-frame-page]
  .mobile-media-wipe-layer {
    position: absolute;
    top: 0;
    bottom: 0;

    width: 0;

    overflow: hidden;

    z-index: 2;

    pointer-events: none;

    will-change: width;

    animation: none !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .mobile-media-wipe-layer > .media-viewer-image {
    position: absolute !important;

    top: 0 !important;
    bottom: 0 !important;

    width:
      var(
        --mobile-media-stage-width,
        100cqw
      ) !important;

    height: 100% !important;

    max-width: none !important;
    max-height: none !important;

    object-fit: cover !important;
    object-position: 50% 50% !important;

    transform: none !important;

    opacity: 1 !important;

    -webkit-mask-image: none !important;
    mask-image: none !important;

    animation: none !important;
  }


  /*
    NEXT / finger swipes left:
    B grows inward from the RIGHT edge.
    Its left reveal edge is softly feathered.
  */
  .prototype-page-frame[data-game-frame-page]
  .mobile-media-wipe-layer.is-wipe-forward {
    right: 0;
    left: auto;

    -webkit-mask-image:
      linear-gradient(
        90deg,
        transparent 0,
        rgba(0, 0, 0, 0.18) 12px,
        rgba(0, 0, 0, 0.72) 30px,
        #000 52px,
        #000 100%
      ) !important;

    mask-image:
      linear-gradient(
        90deg,
        transparent 0,
        rgba(0, 0, 0, 0.18) 12px,
        rgba(0, 0, 0, 0.72) 30px,
        #000 52px,
        #000 100%
      ) !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .mobile-media-wipe-layer.is-wipe-forward
  > .media-viewer-image {
    right: 0 !important;
    left: auto !important;
  }


  /*
    PREVIOUS / finger swipes right:
    B grows inward from the LEFT edge.
    Its right reveal edge is softly feathered.
  */
  .prototype-page-frame[data-game-frame-page]
  .mobile-media-wipe-layer.is-wipe-backward {
    left: 0;
    right: auto;

    -webkit-mask-image:
      linear-gradient(
        90deg,
        #000 0,
        #000 calc(100% - 52px),
        rgba(0, 0, 0, 0.72) calc(100% - 30px),
        rgba(0, 0, 0, 0.18) calc(100% - 12px),
        transparent 100%
      ) !important;

    mask-image:
      linear-gradient(
        90deg,
        #000 0,
        #000 calc(100% - 52px),
        rgba(0, 0, 0, 0.72) calc(100% - 30px),
        rgba(0, 0, 0, 0.18) calc(100% - 12px),
        transparent 100%
      ) !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .mobile-media-wipe-layer.is-wipe-backward
  > .media-viewer-image {
    left: 0 !important;
    right: auto !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .mobile-media-wipe-layer.is-wipe-running {
    animation:
      mobile-media-layer-reveal
      380ms
      cubic-bezier(0.22, 0.72, 0.24, 1)
      both !important;
  }


  @keyframes mobile-media-layer-reveal {
    from {
      width: 0;
    }

    to {
      width: 100%;
    }
  }
}



/* =========================================================
   MOBILE MEDIA WIPE — STABLE COMPLETION STATE
   =========================================================

   Keep the incoming image inside its reveal wrapper after the wipe finishes.
   This avoids the tiny end-of-animation position jump caused by reparenting
   the image back into the normal media stage.

   Once complete, the wrapper simply becomes a normal full-size unmasked
   layer until the next media render replaces the stage.
   ========================================================= */

@media (max-width: 750px) {

  .prototype-page-frame[data-game-frame-page]
  .mobile-media-wipe-layer.is-wipe-complete {
    width: 100% !important;

    -webkit-mask-image: none !important;
    mask-image: none !important;

    animation: none !important;
  }
}



/* =========================================================
   MOBILE MEDIA WIPE — PRESERVE OUTGOING WRAPPER GEOMETRY
   =========================================================

   After the first successful wipe, the visible screenshot intentionally lives
   inside .mobile-media-wipe-layer. On the next swipe, keep a clone of that
   entire layer as the outgoing A rather than extracting/reparenting the image.
   This keeps A in the exact same positioning context at swipe start.
   ========================================================= */

@media (max-width: 750px) {

  .prototype-page-frame[data-game-frame-page]
  .mobile-media-wipe-layer.is-wipe-outgoing {
    left: 0 !important;
    right: 0 !important;

    width: 100% !important;

    z-index: 1 !important;

    overflow: hidden !important;

    -webkit-mask-image: none !important;
    mask-image: none !important;

    animation: none !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .mobile-media-wipe-layer.is-wipe-outgoing
  > .media-viewer-image {
    left: 0 !important;
    right: auto !important;

    width: 100% !important;
    height: 100% !important;

    transform: none !important;

    -webkit-mask-image: none !important;
    mask-image: none !important;

    animation: none !important;
  }
}



/* =========================================================
   MOBILE MEDIA WIPE — ZERO-GEOMETRY-CHANGE OUTGOING SNAPSHOT
   =========================================================

   The start-of-swipe pop came from "normalizing" the outgoing clone:
   the visible completed layer could be right-anchored, then the outgoing
   override forced its child to left:0. That is a real geometry change.

   The outgoing snapshot must preserve the exact completed layer geometry.
   Only stacking / interactivity are changed here.
   ========================================================= */

@media (max-width: 750px) {

  .prototype-page-frame[data-game-frame-page]
  .mobile-media-wipe-layer.is-wipe-outgoing {
    z-index: 1 !important;

    pointer-events: none !important;

    animation: none !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .mobile-media-wipe-layer.is-wipe-outgoing
  > .media-viewer-image {
    animation: none !important;
  }
}



/* =========================================================
   MOBILE — DIRECTIONAL PAGE-COLOR SWIPE FEEDBACK
   =========================================================
   A soft horizontal light band travels with vertical swipe direction.

   Same-page media/info transitions:
     current page accent -> current page accent

   Page-to-page transitions:
     current accent -> incoming page accent

   The layer sits just beneath the real page frames so it reads as background
   illumination rather than another foreground UI element.
   ========================================================= */

.mobile-swipe-feedback {
  display: none;
}


@media (max-width: 750px) {
  .mobile-swipe-feedback {
    display: block;

    position: fixed;

    left: 0;
    right: 0;

    height:
      clamp(
        440px,
        88vw,
        720px
      );

    z-index: 19;

    pointer-events: none;

    opacity: 0;

    transform:
      translate3d(
        0,
        0,
        0
      );

    will-change:
      transform,
      opacity;

    filter:
      blur(10px);

    mix-blend-mode:
      screen;
  }


  /*
    Finger moving UP / navigating forward:
    the light enters from the bottom and travels toward the top.
  */
  .mobile-swipe-feedback.is-swipe-up {
    top: 100%;

    background:
      linear-gradient(
        to top,
        rgba(
          var(--mobile-swipe-to-rgb),
          0
        )
        0%,
        rgba(
          var(--mobile-swipe-to-rgb),
          0.10
        )
        18%,
        rgba(
          var(--mobile-swipe-to-rgb),
          0.31
        )
        42%,
        rgba(
          var(--mobile-swipe-from-rgb),
          0.41
        )
        58%,
        rgba(
          var(--mobile-swipe-from-rgb),
          0.10
        )
        82%,
        rgba(
          var(--mobile-swipe-from-rgb),
          0
        )
        100%
      );
  }


  .mobile-swipe-feedback.is-swipe-up.is-running {
    animation:
      mobile-swipe-light-up
      1280ms
      cubic-bezier(0.16, 0.76, 0.20, 1)
      both;
  }


  /*
    Finger moving DOWN / navigating backward:
    reverse both travel and the color ordering.
  */
  .mobile-swipe-feedback.is-swipe-down {
    bottom: 100%;

    background:
      linear-gradient(
        to bottom,
        rgba(
          var(--mobile-swipe-to-rgb),
          0
        )
        0%,
        rgba(
          var(--mobile-swipe-to-rgb),
          0.10
        )
        18%,
        rgba(
          var(--mobile-swipe-to-rgb),
          0.31
        )
        42%,
        rgba(
          var(--mobile-swipe-from-rgb),
          0.41
        )
        58%,
        rgba(
          var(--mobile-swipe-from-rgb),
          0.10
        )
        82%,
        rgba(
          var(--mobile-swipe-from-rgb),
          0
        )
        100%
      );
  }


  .mobile-swipe-feedback.is-swipe-down.is-running {
    animation:
      mobile-swipe-light-down
      1280ms
      cubic-bezier(0.16, 0.76, 0.20, 1)
      both;
  }


  @keyframes mobile-swipe-light-up {
    0% {
      opacity: 0;
      transform:
        translate3d(
          0,
          0,
          0
        );
    }

    14% {
      opacity: 0.92;
    }

    78% {
      opacity: 0.78;
    }

    100% {
      opacity: 0;
      transform:
        translate3d(
          0,
          calc(-100vh - 180px),
          0
        );
    }
  }


  @keyframes mobile-swipe-light-down {
    0% {
      opacity: 0;
      transform:
        translate3d(
          0,
          0,
          0
        );
    }

    14% {
      opacity: 0.92;
    }

    78% {
      opacity: 0.78;
    }

    100% {
      opacity: 0;
      transform:
        translate3d(
          0,
          calc(100vh + 180px),
          0
        );
    }
  }


  @media (prefers-reduced-motion: reduce) {
    .mobile-swipe-feedback.is-running {
      animation-duration: 1ms !important;
    }
  }
}



/* =========================================================
   MOBILE SWIPE FEEDBACK — CLIP TO BACKGROUND VIDEO OPENING
   =========================================================
   The swipe glow now lives inside a dedicated clipping layer that matches
   the background video's exact inset + inner corner radius. It can no longer
   wash across the opaque border/bezel around the video.
   ========================================================= */

@media (max-width: 750px) {

  .site-background
  .mobile-swipe-feedback-clip {
    position: absolute;

    top:
      var(--background-video-frame-width);

    right:
      var(--background-video-frame-width);

    bottom:
      var(--background-video-frame-width);

    left:
      var(--background-video-frame-width);

    overflow: hidden;

    border-radius:
      clamp(10px, 0.9vw, 16px);

    pointer-events: none;

    z-index: 1;
  }


  .site-background
  .mobile-swipe-feedback-clip
  .mobile-swipe-feedback {
    /*
      The clip wrapper is now the containing block, so the light sweep is
      positioned relative to the VIDEO opening instead of the whole viewport.
    */
    position: absolute;

    left: 0;
    right: 0;

    z-index: 1;
  }
}



/* =========================================================
   MOBILE SWIPE FEEDBACK — TRUE VIDEO-APERTURE TRAVEL
   =========================================================
   Clarification:
   - the dark color bezel is the OUTER boundary
   - the raster viewport-frame graphics sit above this effect naturally
   - the light should travel across the full VIDEO aperture, including any
     portions later covered by those raster frame graphics

   Animate through the clip's own height rather than 100vh. This keeps the
   1280ms timing perceptually consistent after moving the effect into the
   video aperture.
   ========================================================= */

@media (max-width: 750px) {

  .site-background
  .mobile-swipe-feedback-clip
  .mobile-swipe-feedback.is-swipe-up {
    top: 100%;
    bottom: auto;
  }


  .site-background
  .mobile-swipe-feedback-clip
  .mobile-swipe-feedback.is-swipe-up.is-running {
    animation:
      mobile-swipe-light-up-in-aperture
      2560ms
      cubic-bezier(0.16, 0.76, 0.20, 1)
      both;
  }


  .site-background
  .mobile-swipe-feedback-clip
  .mobile-swipe-feedback.is-swipe-down {
    top: auto;
    bottom: 100%;
  }


  .site-background
  .mobile-swipe-feedback-clip
  .mobile-swipe-feedback.is-swipe-down.is-running {
    animation:
      mobile-swipe-light-down-in-aperture
      2560ms
      cubic-bezier(0.16, 0.76, 0.20, 1)
      both;
  }


  @keyframes mobile-swipe-light-up-in-aperture {
    0% {
      opacity: 0;
      top: 100%;
      transform: none;
    }

    14% {
      opacity: 0.92;
    }

    78% {
      opacity: 0.78;
    }

    100% {
      opacity: 0;
      top: -360px;
      transform: none;
    }
  }


  @keyframes mobile-swipe-light-down-in-aperture {
    0% {
      opacity: 0;
      bottom: 100%;
      transform: none;
    }

    14% {
      opacity: 0.92;
    }

    78% {
      opacity: 0.78;
    }

    100% {
      opacity: 0;
      bottom: -360px;
      transform: none;
    }
  }
}



/* =========================================================
   MOBILE — HORIZONTAL PAGE-COLOR SWIPE FEEDBACK
   =========================================================
   Same visual language as the vertical sweep, but for hero media swipes.

   Swipe left  -> light enters from right and travels left.
   Swipe right -> light enters from left and travels right.

   Horizontal feedback always uses the currently-open page accent color.
   ========================================================= */

@media (max-width: 750px) {

  .site-background
  .mobile-swipe-feedback-clip
  .mobile-swipe-feedback.is-swipe-left,
  .site-background
  .mobile-swipe-feedback-clip
  .mobile-swipe-feedback.is-swipe-right {
    top: 0;
    bottom: 0;

    width:
      clamp(
        440px,
        88vw,
        720px
      );

    height: auto;

    filter:
      blur(18px);
  }


  .site-background
  .mobile-swipe-feedback-clip
  .mobile-swipe-feedback.is-swipe-left {
    left: 100%;
    right: auto;

    background:
      linear-gradient(
        to left,
        rgba(
          var(--mobile-swipe-from-rgb),
          0
        )
        0%,
        rgba(
          var(--mobile-swipe-from-rgb),
          0.10
        )
        18%,
        rgba(
          var(--mobile-swipe-from-rgb),
          0.31
        )
        42%,
        rgba(
          var(--mobile-swipe-to-rgb),
          0.41
        )
        58%,
        rgba(
          var(--mobile-swipe-to-rgb),
          0.11
        )
        82%,
        rgba(
          var(--mobile-swipe-to-rgb),
          0
        )
        100%
      );
  }


  .site-background
  .mobile-swipe-feedback-clip
  .mobile-swipe-feedback.is-swipe-left.is-running {
    animation:
      mobile-swipe-light-left-in-aperture
      2560ms
      cubic-bezier(0.16, 0.76, 0.20, 1)
      both;
  }


  .site-background
  .mobile-swipe-feedback-clip
  .mobile-swipe-feedback.is-swipe-right {
    left: auto;
    right: 100%;

    background:
      linear-gradient(
        to right,
        rgba(
          var(--mobile-swipe-from-rgb),
          0
        )
        0%,
        rgba(
          var(--mobile-swipe-from-rgb),
          0.10
        )
        18%,
        rgba(
          var(--mobile-swipe-from-rgb),
          0.31
        )
        42%,
        rgba(
          var(--mobile-swipe-to-rgb),
          0.41
        )
        58%,
        rgba(
          var(--mobile-swipe-to-rgb),
          0.11
        )
        82%,
        rgba(
          var(--mobile-swipe-to-rgb),
          0
        )
        100%
      );
  }


  .site-background
  .mobile-swipe-feedback-clip
  .mobile-swipe-feedback.is-swipe-right.is-running {
    animation:
      mobile-swipe-light-right-in-aperture
      2560ms
      cubic-bezier(0.16, 0.76, 0.20, 1)
      both;
  }


  @keyframes mobile-swipe-light-left-in-aperture {
    0% {
      opacity: 0;
      left: 100%;
      transform: none;
    }

    14% {
      opacity: 0.92;
    }

    78% {
      opacity: 0.78;
    }

    100% {
      opacity: 0;
      left: -720px;
      transform: none;
    }
  }


  @keyframes mobile-swipe-light-right-in-aperture {
    0% {
      opacity: 0;
      right: 100%;
      transform: none;
    }

    14% {
      opacity: 0.92;
    }

    78% {
      opacity: 0.78;
    }

    100% {
      opacity: 0;
      right: -720px;
      transform: none;
    }
  }
}



/* =========================================================
   MOBILE FRAME RASTER QUALITY — KEEP ALL 16 PIECES SHARP
   =========================================================
   Some mobile Chromium devices can cache small raster assets at an
   intermediate/composited resolution while the responsive frame settles.

   Keep every fixed corner piece and stretcher on the normal image raster
   path, and explicitly opt them out of transform / will-change hints that
   can encourage a stale low-resolution composited copy.

   Note: fixed <img> pieces already receive explicit live width + height from
   the shared measured frame geometry, so the safer part of the "explicit
   dimensions" fix is already present and does not need a second sizing system.
   ========================================================= */

@media (max-width: 750px) {

  .prototype-page-frame[data-game-frame-page]
  .game-frame-area > [data-game-frame-piece],

  .prototype-page-frame[data-game-frame-page]
  .game-frame-area > [data-game-frame-stretcher] {
    image-rendering: auto !important;

    transform: none !important;
    translate: none !important;
    scale: none !important;
    rotate: none !important;

    will-change: auto !important;

    backface-visibility: visible !important;
    -webkit-backface-visibility: visible !important;

    filter: none !important;

    /*
      Avoid giving Chromium an extra paint-containment boundary for these
      tiny raster assets. Let the browser rerasterize them at their final
      on-screen dimensions.
    */
    contain: none !important;
  }


  /*
    Fixed corner pieces are real <img> elements. Reassert both dimensions
    from the already-existing measured geometry so mobile Chromium has an
    explicit final raster target in both axes.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-frame-area > img[data-game-frame-piece] {
    width:
      var(
        --brobots-piece-w,
        auto
      )
      !important;

    height:
      var(
        --brobots-piece-h,
        auto
      )
      !important;

    max-width: none !important;
    max-height: none !important;

    object-fit: fill;

    /*
      Keep the browser's decoder/rasterizer in its normal high-quality mode.
    */
    image-rendering: auto !important;
  }
}



/* =========================================================
   MOBILE LANDSCAPE — PORTRAIT-ONLY GUARD
   =========================================================
   Browsers do not reliably allow an ordinary webpage to force portrait
   orientation. Instead, block interaction in phone-landscape and ask the
   user to rotate back to portrait.

   The coarse-pointer + short-height checks keep this aimed at phones rather
   than ordinary desktop windows.
   ========================================================= */

@media
  (orientation: landscape)
  and (pointer: coarse)
  and (max-height: 600px) {

  html,
  body {
    overflow: hidden !important;
    overscroll-behavior: none !important;
  }


  body > * {
    pointer-events: none !important;
    user-select: none !important;
  }


  body::before {
    content:
      "Please rotate your device to portrait";

    position: fixed;

    inset: 0;

    z-index: 2147483647;

    display: flex;

    align-items: center;
    justify-content: center;

    padding: 32px;

    box-sizing: border-box;

    background:
      rgba(
        10,
        10,
        10,
        0.94
      );

    color: #f0f0f0;

    font:
      600
      clamp(18px, 4vw, 28px)
      / 1.25
      system-ui,
      sans-serif;

    text-align: center;

    letter-spacing: 0.01em;

    pointer-events: auto;
  }
}



/* =========================================================
   MOBILE HERO IMAGE — CUSTOM GESTURE OWNERSHIP
   =========================================================
   The hero already has custom handlers for:
     - vertical page swipes
     - horizontal media swipes
     - stationary double-tap lightbox opening

   Give those handlers full ownership of gestures that begin on the hero
   instead of letting the browser claim the touch sequence first.
   ========================================================= */

@media (max-width: 750px) {

  .prototype-page-frame[data-game-frame-page]
  .media-viewer-image {
    touch-action: none;
  }
}



/* =========================================================
   MOBILE SAFARI — FIXED PIECES PAINTED ON THEIR OWN <img>
   =========================================================
   This preserves the original element's complete frame geometry and scaling.
   Only Safari's paint path changes.

   The WebP is painted as the element background; the normal replaced-image
   pixels are moved well outside the visible content box.
   ========================================================= */

@media (max-width: 750px) {

  html.is-mobile-safari-frame-renderer
  .prototype-page-frame[data-game-frame-page]
  .game-frame-area
  > img[data-game-frame-piece] {
    background-image:
      var(
        --safari-frame-piece-background
      ) !important;

    background-repeat:
      no-repeat !important;

    background-position:
      center !important;

    background-size:
      100% 100% !important;

    /*
      Preserve the <img> itself as the sizing/positioning object so all of the
      existing responsive frame interpolation continues to apply unchanged.
      Only its replaced pixels are moved out of view.
    */
    object-fit:
      none !important;

    object-position:
      100000px 100000px !important;
  }
}



/* =========================================================
   MOBILE HERO — RESTORE INTERACTION AFTER MEDIA WIPE
   =========================================================
   The completed wipe wrapper intentionally remains in place to avoid the
   1px end-of-transition snap. However, the base wrapper has
   pointer-events:none so it cannot interfere DURING the wipe.

   Once the wipe is complete, that same wrapper is now the permanent visible
   hero. Re-enable pointer events so its image can receive double-click /
   double-tap and open the lightbox normally.

   Outgoing transition snapshots remain non-interactive.
   ========================================================= */

@media (max-width: 750px) {

  .prototype-page-frame[data-game-frame-page]
  .mobile-media-wipe-layer.is-wipe-complete:not(.is-wipe-outgoing) {
    /*
      The completed wrapper is visual-only.

      Its retained geometry is intentionally optimized for a seamless wipe
      endpoint and can be larger than the visible hero cavity. Let the fixed
      .media-viewer-stage own all mobile touch interaction instead.
    */
    pointer-events: none !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .mobile-media-wipe-layer.is-wipe-complete:not(.is-wipe-outgoing)
  > .media-viewer-image {
    pointer-events: none !important;
    touch-action: none;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-media-zone--hero
  .media-viewer-stage {
    pointer-events: auto;
    touch-action: none;
  }
}



/* =========================================================
   GAME INFO BLURB — RESPONSIVE CENTERED TEXT BLOCK
   =========================================================
   The blurb used to hold a hard 64ch width so its line breaks would not jump
   while the game-info cavity resized. That kept transitions visually stable,
   but it becomes a liability once the cavity is genuinely narrower on mobile.

   Keep the useful part of that behavior:
     - desktop / roomy tablet: remain capped at 64ch, so wrapping stays stable
     - narrow tablet / mobile: shrink naturally with the available cavity
     - center the text BLOCK within the info surface
     - keep the text itself left-aligned for readability

   This means reflow only begins once the available space is actually smaller
   than the preferred 64ch measure, rather than continuously tracking every
   intermediate frame size.
   ========================================================= */

.prototype-page-frame[data-game-frame-page]
.game-info-blurb,
.prototype-page-frame[data-game-frame-page].is-info-compact
.game-info-blurb,
.prototype-page-frame[data-game-frame-page].is-info-tight
.game-info-blurb {
  inline-size:
    min(
      64ch,
      100%
    ) !important;

  width:
    min(
      64ch,
      100%
    ) !important;

  max-inline-size: 100% !important;
  max-width: 100% !important;

  margin-inline: auto !important;

  text-align: left;
}


/*
  Tablet/mobile clones have their own padded cavity. Use its actual content
  width rather than the page-level cqw fallback that previously let the 64ch
  block extend beyond the visible info frame.
*/
@media (max-width: 1400px) {

  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-info-blurb {
    inline-size:
      min(
        64ch,
        100%
      ) !important;

    width:
      min(
        64ch,
        100%
      ) !important;

    max-inline-size: 100% !important;
    max-width: 100% !important;

    margin-inline: auto !important;
  }
}



/* =========================================================
   GAME INFO BLURB — ONE SHARED FLUID MEASURE
   =========================================================
   Same rule at every scale:

     - left aligned with the rest of the info content
     - use all available width on narrow layouts
     - stop growing at a medium readable measure on wide layouts
     - JS may reduce font size only when the next section would be encroached

   76ch is intentionally between the old ~64ch block and the full-width
   treatment. No breakpoint-specific width behavior is required.
   ========================================================= */

.prototype-page-frame[data-game-frame-page]
.game-info-blurb,
.prototype-page-frame[data-game-frame-page].is-info-compact
.game-info-blurb,
.prototype-page-frame[data-game-frame-page].is-info-tight
.game-info-blurb,
.prototype-page-frame[data-game-frame-page]
.game-tablet-info-host
.game-info-blurb {
  inline-size:
    min(
      76ch,
      100%
    )
    !important;

  width:
    min(
      76ch,
      100%
    )
    !important;

  max-inline-size: 100% !important;
  max-width: 100% !important;

  margin-inline: 0 !important;

  --game-info-blurb-min-size: 9.5px;

  font-size:
    var(
      --game-info-blurb-fit-size,
      inherit
    )
    !important;

  text-align: left;
}


/*
  Do not clip the blurb itself. The fitter now uses the actual gap to the next
  visible section and reduces type before overlap can occur.
*/
.prototype-page-frame[data-game-frame-page]
.game-info-blurb {
  overflow: visible !important;
}



/* =========================================================
   MOBILE DIRECTIONAL PAGE SWITCH — MOTION GUARD
   =========================================================
   Page frames temporarily translate below the viewport during swipe-driven
   navigation. Keep that motion visually clipped to the site rather than
   creating transient document scrollbars.
   ========================================================= */

@media (max-width: 750px) {

  html,
  body {
    overflow: hidden;
  }


  .prototype-page-frame {
    will-change: auto;
  }
}



/* =========================================================
   MOBILE SWIPE-UP — OUTGOING INFO ACCENT WASH
   =========================================================
   As the outgoing page is compressed, its information cavity quickly washes
   into that page's accent color. By the half-height handoff it is fully
   covered, hiding copy before the responsive cavity becomes visually cramped.

   This is scoped ONLY to the swipe-up outgoing-page class.
   ========================================================= */

@media (max-width: 750px) {

  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host::after {
    content: "";

    position: absolute;
    inset: 0;

    z-index: 50;

    pointer-events: none;

    opacity: 0;

    background:
      radial-gradient(
        ellipse at 50% 42%,
        rgba(
          var(--page-accent-rgb),
          1
        )
        0%,
        rgba(
          var(--page-accent-rgb),
          0.96
        )
        58%,
        rgba(
          var(--page-accent-rgb),
          0.88
        )
        100%
      );

    box-shadow:
      inset 0 0 42px
      rgba(
        var(--page-accent-rgb),
        0.42
      );

    transition: none;

    will-change: opacity;
  }


  .prototype-page-frame[data-game-frame-page].is-mobile-outgoing-info-glow
  .game-tablet-info-host::after {
    opacity:
      var(
        --mobile-outgoing-info-glow-progress,
        0
      );
  }
}



/* =========================================================
   MOBILE SWIPE-UP — INFO -> TRANSLUCENT ACCENT PANEL
   =========================================================
   Refine the outgoing info treatment:
     - info content fades OUT
     - accent panel fades IN
     - final panel is only ~25% opaque
   ========================================================= */

@media (max-width: 750px) {

  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host::after {
    background:
      rgba(
        var(--page-accent-rgb),
        0.25
      )
      !important;

    box-shadow:
      inset 0 0 34px
      rgba(
        var(--page-accent-rgb),
        0.16
      )
      !important;
  }


  .prototype-page-frame[data-game-frame-page].is-mobile-outgoing-info-glow
  .game-tablet-info-host::after {
    opacity:
      var(
        --mobile-outgoing-info-glow-progress,
        0
      )
      !important;
  }


  /*
    Crossfade the authored info away at the same rate the translucent panel
    comes in. The host itself remains present so its geometry continues to
    resize normally during the push.
  */
  .prototype-page-frame[data-game-frame-page].is-mobile-outgoing-info-glow
  .game-tablet-info-host
  .game-info-surface {
    opacity:
      calc(
        1 -
        var(
          --mobile-outgoing-info-glow-progress,
          0
        )
      )
      !important;

    transition: none !important;
  }
}



/* =========================================================
   MOBILE LIGHTBOX — EDGE-TO-EDGE MEDIA
   =========================================================
   On mobile, the screenshot no longer reserves side gutters for the nav
   arrows. The image gets the full viewport width and the arrows overlap it.
   Vertical clearance for the close button remains unchanged.
   ========================================================= */

@media (max-width: 750px) {

  .media-lightbox {
    --media-lightbox-side-gutter: 0px;
  }


  .media-lightbox-image {
    max-width: 100vw;
  }


  /*
    Let navigation float over the image instead of consuming image width.
    Keep the controls comfortably reachable without pulling the media inward.
  */
  .media-lightbox-arrow {
    z-index: 2;

    /*
      Center on the lightbox's IMAGE AREA rather than the viewport.

      The image is centered inside the usable region between the top and
      bottom gutters, so this is its true vertical center even when the large
      close-button gutter makes that region asymmetrical.
    */
    top:
      calc(
        50% +
        (
          var(--media-lightbox-top-gutter) -
          var(--media-lightbox-bottom-gutter)
        ) / 2
      );

    width:
      clamp(44px, 12vw, 56px);

    height:
      clamp(60px, 16vw, 78px);
  }


  .media-lightbox-arrow--previous {
    left:
      max(
        4px,
        env(safe-area-inset-left)
      );
  }


  .media-lightbox-arrow--next {
    right:
      max(
        4px,
        env(safe-area-inset-right)
      );
  }
}



/* =========================================================
   TABLET / MOBILE LANDING IDENTITY — FIT + AMBIENT ACCENT GLOW
   =========================================================
   Collapsed game pages keep the existing composition:
     logo
     "Scroll for more"
     animated arrow

   The layout now treats the cue as a guaranteed bottom row and gives the logo
   only the remaining space. This prevents either piece from escaping the
   lower frame aperture on short / awkward viewport dimensions.

   A faint page-accent glow sits behind the complete identity treatment while
   collapsed. It disappears as soon as info mode is selected.
   ========================================================= */

@media (max-width: 1400px) {

  .prototype-page-frame[data-game-frame-page]
  .game-tablet-landing-identity {
    /*
      The lower aperture itself is already positioned correctly by the frame
      geometry. Grid makes the available height explicit:
        row 1 = logo, allowed to shrink
        row 2 = cue, always retained
    */
    display: grid !important;

    grid-template-columns:
      minmax(0, 1fr);

    grid-template-rows:
      minmax(0, 1fr)
      auto;

    align-items: center;
    justify-items: center;

    align-content: stretch;

    gap:
      clamp(
        4px,
        1.5cqh,
        14px
      );

    padding:
      clamp(
        6px,
        2.0cqh,
        18px
      )
      clamp(
        10px,
        2.4cqw,
        24px
      );

    min-width: 0;
    min-height: 0;

    isolation: isolate;
  }


  /*
    Soft colored atmosphere behind BOTH the logo and cue.

    Keep this deliberately restrained: it is not a solid panel, just a broad
    radial bloom using the current page accent.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-landing-identity::before {
    content: "";

    position: absolute;

    /*
      Fill the ENTIRE lower aperture instead of drawing a smaller bloom in the
      middle. Slight negative bleed avoids leaving a dark rim around the glow.
    */
    inset: -2% -1%;

    z-index: 0;

    pointer-events: none;

    border-radius:
      inherit;

    background:
      linear-gradient(
        90deg,
        rgba(
          var(--page-accent-rgb),
          0.20
        )
        0%,
        rgba(
          var(--page-accent-rgb),
          0.34
        )
        50%,
        rgba(
          var(--page-accent-rgb),
          0.20
        )
        100%
      );

    box-shadow:
      inset 0 0
      clamp(
        34px,
        9cqh,
        88px
      )
      rgba(
        var(--page-accent-rgb),
        0.24
      ),
      0 0
      clamp(
        20px,
        5cqh,
        56px
      )
      rgba(
        var(--page-accent-rgb),
        0.22
      );

    opacity: 0.86;

    transform: scale(0.992);

    animation:
      game-tablet-landing-glow-pulse
      2.6s
      ease-in-out
      infinite;

    will-change:
      opacity,
      transform,
      filter;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-landing-logo,
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-scroll-cue {
    position: relative;
    z-index: 1;
  }


  /*
    Info mode owns the lower aperture now, so the ambient landing glow should
    leave immediately with the identity state rather than lingering behind the
    info surface.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-frame-area.is-tablet-info-geometry
  .game-tablet-landing-identity::before {
    opacity: 0 !important;
    animation: none !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-landing-logo {
    /*
      The logo occupies ONLY row 1. height:100% + object-fit:contain means it
      can become smaller whenever the cue needs more room, while preserving the
      authored aspect ratio and existing centered placement.
    */
    grid-row: 1;

    align-self: center;
    justify-self: center;

    width:
      min(
        78%,
        560px
      );

    max-width: 78%;

    height: 100%;
    max-height: 100%;

    min-width: 0;
    min-height: 0;

    object-fit: contain;

    margin: 0;

    /*
      Keep the existing info-mode travel behavior from STEP 1e.
    */
    flex: none;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-scroll-cue {
    grid-row: 2;

    align-self: end;
    justify-self: center;

    min-width: 0;
    max-width: 100%;

    /*
      Remove hard minimums that can become too tall for very short apertures.
      cqh follows this exact lower landing area.
    */
    gap:
      clamp(
        1px,
        0.55cqh,
        5px
      );

    padding:
      clamp(
        2px,
        0.65cqh,
        6px
      )
      clamp(
        6px,
        1.4cqw,
        14px
      );
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-scroll-cue-text {
    font-size:
      clamp(
        9px,
        min(
          1.35cqw,
          4.4cqh
        ),
        15px
      );

    line-height: 1.08;

    white-space: nowrap;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-scroll-cue-arrow {
    font-size:
      clamp(
        14px,
        min(
          2.5cqw,
          7.5cqh
        ),
        28px
      );

    line-height: 0.72;
  }
}


@keyframes game-tablet-landing-glow-pulse {
  0%,
  100% {
    opacity: 0.72;
    transform: scale(0.992);
    filter: brightness(0.92) saturate(1.00);
  }

  50% {
    opacity: 1;
    transform: scale(1.006);
    filter: brightness(1.26) saturate(1.18);
  }
}


@media (prefers-reduced-motion: reduce) {
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-landing-identity::before {
    animation: none;
    opacity: 0.64;
    transform: none;
    filter: none;
  }
}



/* =========================================================
   TABLET / MOBILE LANDING IDENTITY — FRAME ABOVE PANEL
   =========================================================
   Keep the working v167 landing layout/glow exactly as-is, but move the
   complete landing identity underneath the raster frame artwork.

   Existing hierarchy:
     media content  = 1
     landing panel  = 4   <-- was incorrectly above the frame
     frame artwork  = 3

   New hierarchy:
     media content  = 1
     landing panel  = 2
     frame artwork  = 3

   This lets the real frame corners/bars naturally mask the glow at the edges
   without changing the glow's own internal stacking or clipping.
   ========================================================= */

@media (max-width: 1400px) {

  .prototype-page-frame[data-game-frame-page]
  .game-tablet-landing-identity {
    z-index: 2 !important;
  }


  /*
    Reassert the frame artwork above the landing panel. Keep this scoped to
    the direct frame assets so it does not disturb hero/media controls.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-frame-area > [data-game-frame-piece],

  .prototype-page-frame[data-game-frame-page]
  .game-frame-area > [data-game-frame-stretcher] {
    z-index: 3 !important;
  }
}



/* =========================================================
   ABOUT / CONTACT — SIMPLE COLORED GLASS STACK
   =========================================================
   These two non-game pages use one compact responsive treatment across
   desktop, tablet, and mobile. The authored content consumes the central
   ~90% of the page opening while the old structural page frame remains the
   morph/layout container.

   The glass intentionally carries more page accent than the game-info glass.
   ========================================================= */

.prototype-page-frame[data-page="about"]
.prototype-page-frame-shell,

.prototype-page-frame[data-page="contact"]
.prototype-page-frame-shell {
  /*
    About/Contact visually resolve into the glass stack rather than the
    detailed chrome page shell. Keep the SVG in DOM because the shared page
    geometry/morph system still measures this frame container.
  */
  opacity: 0;
}


.prototype-page-frame[data-page="about"]
.prototype-page-frame-content.simple-page-content,

.prototype-page-frame[data-page="contact"]
.prototype-page-frame-content.simple-page-content {
  display: grid;
  place-items: center;

  overflow: visible;

  padding:
    clamp(
      8px,
      min(1.8cqw, 1.8cqh),
      18px
    );
}


.simple-glass-page {
  position: relative;

  width: 90%;
  height: 90%;

  min-width: 0;
  min-height: 0;

  display: grid;
  place-items: center;

  container-type: size;
  container-name: simple-glass-page;

  isolation: isolate;
}


.simple-glass-layer {
  position: absolute;

  pointer-events: none;

  border:
    1px solid
    rgba(
      var(--page-accent-rgb),
      0.34
    );

  background:
    linear-gradient(
      145deg,
      rgba(
        var(--page-accent-rgb),
        0.24
      ),
      rgba(
        16,
        20,
        25,
        0.66
      )
      42%,
      rgba(
        var(--page-accent-rgb),
        0.16
      )
    );

  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.14),
    inset 0 0 44px
      rgba(
        var(--page-accent-rgb),
        0.09
      ),
    0 18px 48px rgba(0, 0, 0, 0.30),
    0 0 34px
      rgba(
        var(--page-accent-rgb),
        0.10
      );

  backdrop-filter:
    blur(14px)
    saturate(1.12);

  -webkit-backdrop-filter:
    blur(14px)
    saturate(1.12);

  clip-path:
    polygon(
      4% 0,
      100% 0,
      100% 92%,
      96% 100%,
      0 100%,
      0 8%
    );
}


.simple-glass-layer--back {
  inset: 5.5% 1.5% 0 5%;

  opacity: 0.54;

  transform:
    translate3d(
      -1.4%,
      1.8%,
      0
    );
}


.simple-glass-layer--middle {
  inset: 2.8% 3.2% 2.8% 2.5%;

  opacity: 0.70;

  transform:
    translate3d(
      1.2%,
      -0.8%,
      0
    );
}


.simple-glass-layer--front {
  inset: 0;

  opacity: 0.92;

  background:
    linear-gradient(
      150deg,
      rgba(
        var(--page-accent-rgb),
        0.29
      ),
      rgba(
        17,
        21,
        27,
        0.70
      )
      38%,
      rgba(
        var(--page-accent-rgb),
        0.19
      )
      100%
    );

  border-color:
    rgba(
      var(--page-accent-rgb),
      0.52
    );

  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.18),
    inset 0 0 52px
      rgba(
        var(--page-accent-rgb),
        0.12
      ),
    0 22px 58px rgba(0, 0, 0, 0.34),
    0 0 42px
      rgba(
        var(--page-accent-rgb),
        0.16
      );
}


.simple-glass-content {
  position: relative;
  z-index: 2;

  width:
    min(
      82%,
      760px
    );

  max-height: 82%;

  min-width: 0;
  min-height: 0;

  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;

  gap:
    clamp(
      8px,
      min(2.1cqw, 2.1cqh),
      20px
    );

  color: rgba(244, 247, 250, 0.94);
}


.simple-page-kicker {
  font-size:
    clamp(
      9px,
      min(1.6cqw, 2.0cqh),
      13px
    );

  line-height: 1;

  letter-spacing: 0.22em;

  font-weight: 700;

  color:
    rgba(
      var(--page-accent-rgb),
      0.90
    );
}


.simple-page-title {
  margin: 0;

  font-size:
    clamp(
      28px,
      min(7.5cqw, 9.0cqh),
      64px
    );

  line-height: 0.95;

  letter-spacing: -0.035em;

  font-weight: 800;

  text-wrap: balance;
}


.simple-page-pronunciation {
  display: inline-flex;
  align-items: center;

  max-width: 100%;

  padding:
    clamp(5px, 1.0cqh, 8px)
    clamp(9px, 1.8cqw, 14px);

  border:
    1px solid
    rgba(
      var(--page-accent-rgb),
      0.42
    );

  background:
    rgba(
      var(--page-accent-rgb),
      0.14
    );

  box-shadow:
    inset 0 0 18px
      rgba(
        var(--page-accent-rgb),
        0.08
      );

  clip-path:
    polygon(
      8px 0,
      100% 0,
      100% calc(100% - 8px),
      calc(100% - 8px) 100%,
      0 100%,
      0 8px
    );

  color: rgba(241, 245, 248, 0.80);

  font-size:
    clamp(
      10px,
      min(1.8cqw, 2.2cqh),
      14px
    );

  font-style: italic;

  letter-spacing: 0.05em;
}


.simple-page-blurb {
  margin: 0;

  max-width: 68ch;

  font-size:
    clamp(
      12px,
      min(2.5cqw, 3.0cqh),
      18px
    );

  line-height: 1.52;

  color: rgba(239, 243, 246, 0.82);

  text-wrap: pretty;
}


.simple-page-blurb strong {
  color:
    rgba(
      var(--page-accent-rgb),
      0.98
    );

  font-weight: 800;
}


.simple-page-facts {
  width: 100%;

  display: grid;
  grid-template-columns:
    repeat(
      3,
      minmax(
        0,
        1fr
      )
    );

  gap:
    clamp(
      6px,
      min(1.8cqw, 1.8cqh),
      14px
    );

  margin-top:
    clamp(
      2px,
      0.8cqh,
      8px
    );
}


.simple-page-fact {
  min-width: 0;

  padding:
    clamp(
      8px,
      1.8cqh,
      14px
    )
    clamp(
      8px,
      1.8cqw,
      14px
    );

  border-top:
    1px solid
    rgba(
      var(--page-accent-rgb),
      0.48
    );

  background:
    linear-gradient(
      180deg,
      rgba(
        var(--page-accent-rgb),
        0.10
      ),
      rgba(
        var(--page-accent-rgb),
        0.025
      )
    );
}


.simple-page-fact span,
.simple-page-fact strong {
  display: block;
}


.simple-page-fact span {
  margin-bottom:
    clamp(
      3px,
      0.8cqh,
      6px
    );

  color:
    rgba(
      var(--page-accent-rgb),
      0.78
    );

  font-size:
    clamp(
      8px,
      min(1.35cqw, 1.7cqh),
      11px
    );

  line-height: 1;

  letter-spacing: 0.16em;

  font-weight: 700;
}


.simple-page-fact strong {
  color: rgba(246, 248, 250, 0.92);

  font-size:
    clamp(
      10px,
      min(1.9cqw, 2.3cqh),
      14px
    );

  line-height: 1.25;

  font-weight: 650;
}


.simple-glass-content--contact {
  max-width: 620px;
}


/*
  Very narrow/short openings keep the same visual hierarchy but let the
  snapshot cards wrap so the prose never gets squeezed out.
*/
@container simple-glass-page (max-width: 560px) {
  .simple-glass-content {
    width: 84%;
  }


  .simple-page-facts {
    grid-template-columns:
      1fr;
  }
}


@container simple-glass-page (max-height: 500px) {
  .simple-glass-content {
    max-height: 88%;

    gap:
      clamp(
        5px,
        1.3cqh,
        10px
      );
  }


  .simple-page-pronunciation {
    padding:
      4px
      9px;
  }


  .simple-page-facts {
    gap: 5px;
  }


  .simple-page-fact {
    padding:
      6px
      9px;
  }
}



/* =========================================================
   ABOUT / CONTACT — FULL-WIDTH DESKTOP + LOCKED MASTER ANGLE
   ========================================================= */

/*
  Derive every glass chamfer from the SAME global angle used by the header,
  media viewer, and other Y2K geometry. Only the vertical rise changes with
  size; the slope itself never changes.
*/
.simple-glass-page {
  --simple-glass-corner-angle:
    calc(
      var(--button-shear-angle)
      * -1
    );

  --simple-glass-corner-rise:
    clamp(
      10px,
      min(2.5cqw, 2.5cqh),
      24px
    );

  --simple-glass-corner-run:
    calc(
      var(--simple-glass-corner-rise)
      *
      tan(
        var(--simple-glass-corner-angle)
      )
    );
}


.simple-glass-layer {
  clip-path:
    polygon(
      var(--simple-glass-corner-run) 0,
      100% 0,
      100%
        calc(
          100%
          -
          var(--simple-glass-corner-rise)
        ),
      calc(
        100%
        -
        var(--simple-glass-corner-run)
      )
        100%,
      0 100%,
      0
        var(--simple-glass-corner-rise)
    );
}


.simple-page-pronunciation {
  --simple-tag-corner-rise:
    clamp(
      5px,
      min(1.1cqw, 1.1cqh),
      9px
    );

  --simple-tag-corner-run:
    calc(
      var(--simple-tag-corner-rise)
      *
      tan(
        var(--simple-glass-corner-angle)
      )
    );

  clip-path:
    polygon(
      var(--simple-tag-corner-run) 0,
      100% 0,
      100%
        calc(
          100%
          -
          var(--simple-tag-corner-rise)
        ),
      calc(
        100%
        -
        var(--simple-tag-corner-run)
      )
        100%,
      0 100%,
      0
        var(--simple-tag-corner-rise)
    );
}


/*
  Desktop About / Contact do NOT use the game's left-frame + right-popout
  composition. They occupy the same broad central canvas as the smaller modes.
*/
@media (min-width: 1401px) {

  .prototype-page-frame[data-page="about"],
  .prototype-page-frame[data-page="contact"] {
    --simple-desktop-top:
      var(
        --desktop-page-area-top,
        calc(
          clamp(82px, calc(64px + 3.9vw), 120px)
          + (clamp(6px, 0.7vw, 10px) * 2)
          + 18px
        )
      );

    /*
      Use roughly 90% of the available viewport in BOTH axes, centered below
      the header. The inner glass then uses 90% of this page opening as before.
    */
    width: 90vw;

    height:
      calc(
        (
          100vh
          -
          var(--simple-desktop-top)
          -
          var(--desktop-page-gap)
        )
        * 0.90
      );

    max-width: none;

    left: 5vw;
    right: auto;

    top:
      calc(
        var(--simple-desktop-top)
        +
        (
          (
            100vh
            -
            var(--simple-desktop-top)
            -
            var(--desktop-page-gap)
          )
          -
          (
            (
              100vh
              -
              var(--simple-desktop-top)
              -
              var(--desktop-page-gap)
            )
            * 0.90
          )
        ) / 2
        +
        var(--page-frame-shift-y)
      );

    bottom: auto;
  }


  /*
    These pages are intentionally single-surface pages on desktop too.
    Keep the old shared popout markup inert so the game-page system remains
    untouched.
  */
  .prototype-page-frame[data-page="about"]
  .desktop-secondary-panel,

  .prototype-page-frame[data-page="contact"]
  .desktop-secondary-panel {
    display: none !important;
  }


  .prototype-page-frame[data-page="about"]
  .prototype-page-frame-content.simple-page-content,

  .prototype-page-frame[data-page="contact"]
  .prototype-page-frame-content.simple-page-content {
    /*
      With the SVG shell hidden, let the content use the full desktop page box
      instead of inheriting the old generated frame-window insets.
    */
    inset: 0;

    width: auto;
    height: auto;
  }
}



/* =========================================================
   ABOUT / CONTACT — GLASS FILLS THE ACTUAL MORPH TARGET
   =========================================================
   The shared page morph has always targeted the full .prototype-page-frame.
   The visible About/Contact glass was still inset inside that hidden frame,
   which is why the reverse morph appeared to "grab" a noticeably larger box.

   For these two simple pages, make the glass itself occupy that full target.
   The CONTENT inside remains comfortably inset, so this changes the visible
   surface size without turning the text into an edge-to-edge layout.
   ========================================================= */

.prototype-page-frame[data-page="about"]
.prototype-page-frame-content.simple-page-content,

.prototype-page-frame[data-page="contact"]
.prototype-page-frame-content.simple-page-content {
  /*
    Ignore the generated transparent-window offsets used by the old chrome
    shell. These pages no longer show that shell, so their glass should match
    the full rectangle that the morph system already targets.
  */
  inset: 0;

  width: auto;
  height: auto;

  padding:
    clamp(
      8px,
      min(1.4cqw, 1.4cqh),
      16px
    );
}


.prototype-page-frame[data-page="about"]
.simple-glass-page,

.prototype-page-frame[data-page="contact"]
.simple-glass-page {
  width: 100%;
  height: 100%;
}


/*
  Keep a small visual breathing room INSIDE the glass rather than shrinking
  the glass itself. This preserves the original comfortable composition while
  making the visible page and the morph target read as the same object.
*/
.prototype-page-frame[data-page="about"]
.simple-glass-content,

.prototype-page-frame[data-page="contact"]
.simple-glass-content {
  width:
    min(
      78%,
      860px
    );

  max-height: 82%;
}



/* =========================================================
   ABOUT / CONTACT — REMOVE BACKDROP-FILTER COMPOSITOR POP
   =========================================================
   The simple glass stack was fading as a child of the morphing/fading page
   while each layer also owned backdrop-filter. Browsers often promote that
   combination to a separate compositor surface only when the parent reaches
   its final opaque state, which creates the little "snap" after the visible
   fade has otherwise finished.

   Keep the exact translucent/tinted glass look, but make these particular
   layers purely painted glass. The background video still shows through the
   alpha; gradients, borders and inset highlights provide the depth without a
   late compositor handoff.
   ========================================================= */

.prototype-page-frame[data-page="about"]
.simple-glass-layer,

.prototype-page-frame[data-page="contact"]
.simple-glass-layer {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;

  /*
    Slightly strengthen the painted depth now that there is no live blur.
    These are static from frame one, so the parent page fade remains the only
    opacity animation involved.
  */
  background:
    linear-gradient(
      145deg,
      rgba(
        var(--page-accent-rgb),
        0.27
      ),
      rgba(
        16,
        20,
        25,
        0.69
      )
      42%,
      rgba(
        var(--page-accent-rgb),
        0.18
      )
    );

  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.15),
    inset 0 0 46px
      rgba(
        var(--page-accent-rgb),
        0.10
      ),
    0 18px 48px rgba(0, 0, 0, 0.30),
    0 0 34px
      rgba(
        var(--page-accent-rgb),
        0.11
      );
}


.prototype-page-frame[data-page="about"]
.simple-glass-layer--front,

.prototype-page-frame[data-page="contact"]
.simple-glass-layer--front {
  background:
    linear-gradient(
      150deg,
      rgba(
        var(--page-accent-rgb),
        0.31
      ),
      rgba(
        17,
        21,
        27,
        0.72
      )
      38%,
      rgba(
        var(--page-accent-rgb),
        0.21
      )
      100%
    );

  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.19),
    inset 0 0 54px
      rgba(
        var(--page-accent-rgb),
        0.13
      ),
    0 22px 58px rgba(0, 0, 0, 0.34),
    0 0 42px
      rgba(
        var(--page-accent-rgb),
        0.17
      );
}



/* =========================================================
   ABOUT / CONTACT — SYMMETRIC NESTED GLASS STACK
   =========================================================
   Replace the previous offset/parallax-style stack with five centered
   concentric panes. Each layer shares the exact same master-angle chamfer;
   only its inset, opacity, and tint strength change.
   ========================================================= */

.prototype-page-frame[data-page="about"]
.simple-glass-layer,

.prototype-page-frame[data-page="contact"]
.simple-glass-layer {
  transform: none;
  margin: 0;

  /*
    All layers remain perfectly centered. Individual variants only adjust
    inset symmetrically, so the stack reads as nested glass instead of cards
    slipping past one another.
  */
}


.prototype-page-frame[data-page="about"]
.simple-glass-layer--outer,

.prototype-page-frame[data-page="contact"]
.simple-glass-layer--outer {
  inset: 0;

  opacity: 0.38;

  background:
    linear-gradient(
      145deg,
      rgba(
        var(--page-accent-rgb),
        0.18
      ),
      rgba(14, 18, 23, 0.54) 48%,
      rgba(
        var(--page-accent-rgb),
        0.11
      )
    );

  border-color:
    rgba(
      var(--page-accent-rgb),
      0.30
    );

  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.09),
    0 16px 42px rgba(0, 0, 0, 0.22),
    0 0 28px
      rgba(
        var(--page-accent-rgb),
        0.08
      );
}


.prototype-page-frame[data-page="about"]
.simple-glass-layer--back,

.prototype-page-frame[data-page="contact"]
.simple-glass-layer--back {
  inset: 4%;

  opacity: 0.50;

  background:
    linear-gradient(
      145deg,
      rgba(
        var(--page-accent-rgb),
        0.22
      ),
      rgba(15, 19, 24, 0.60) 46%,
      rgba(
        var(--page-accent-rgb),
        0.14
      )
    );

  border-color:
    rgba(
      var(--page-accent-rgb),
      0.36
    );
}


.prototype-page-frame[data-page="about"]
.simple-glass-layer--middle,

.prototype-page-frame[data-page="contact"]
.simple-glass-layer--middle {
  inset: 8%;

  opacity: 0.62;

  background:
    linear-gradient(
      145deg,
      rgba(
        var(--page-accent-rgb),
        0.25
      ),
      rgba(16, 20, 25, 0.64) 44%,
      rgba(
        var(--page-accent-rgb),
        0.16
      )
    );

  border-color:
    rgba(
      var(--page-accent-rgb),
      0.42
    );
}


.prototype-page-frame[data-page="about"]
.simple-glass-layer--inner,

.prototype-page-frame[data-page="contact"]
.simple-glass-layer--inner {
  inset: 12%;

  opacity: 0.76;

  background:
    linear-gradient(
      145deg,
      rgba(
        var(--page-accent-rgb),
        0.28
      ),
      rgba(16, 20, 25, 0.68) 42%,
      rgba(
        var(--page-accent-rgb),
        0.18
      )
    );

  border-color:
    rgba(
      var(--page-accent-rgb),
      0.48
    );
}


.prototype-page-frame[data-page="about"]
.simple-glass-layer--front,

.prototype-page-frame[data-page="contact"]
.simple-glass-layer--front {
  inset: 16%;

  opacity: 0.94;

  background:
    linear-gradient(
      150deg,
      rgba(
        var(--page-accent-rgb),
        0.32
      ),
      rgba(17, 21, 27, 0.73) 38%,
      rgba(
        var(--page-accent-rgb),
        0.22
      )
      100%
    );

  border-color:
    rgba(
      var(--page-accent-rgb),
      0.56
    );

  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.18),
    inset 0 0 52px
      rgba(
        var(--page-accent-rgb),
        0.12
      ),
    0 18px 48px rgba(0, 0, 0, 0.26),
    0 0 38px
      rgba(
        var(--page-accent-rgb),
        0.15
      );
}


/*
  Keep the authored content comfortably inside the innermost pane.
  The pane nesting itself provides the visual interest, so the copy can stay
  relatively calm and centered within the composition.
*/
.prototype-page-frame[data-page="about"]
.simple-glass-content,

.prototype-page-frame[data-page="contact"]
.simple-glass-content {
  width:
    min(
      60%,
      760px
    );

  max-height: 62%;
}


@container simple-glass-page (max-width: 560px) {
  .prototype-page-frame[data-page="about"]
  .simple-glass-layer--back,

  .prototype-page-frame[data-page="contact"]
  .simple-glass-layer--back {
    inset: 3%;
  }


  .prototype-page-frame[data-page="about"]
  .simple-glass-layer--middle,

  .prototype-page-frame[data-page="contact"]
  .simple-glass-layer--middle {
    inset: 6%;
  }


  .prototype-page-frame[data-page="about"]
  .simple-glass-layer--inner,

  .prototype-page-frame[data-page="contact"]
  .simple-glass-layer--inner {
    inset: 9%;
  }


  .prototype-page-frame[data-page="about"]
  .simple-glass-layer--front,

  .prototype-page-frame[data-page="contact"]
  .simple-glass-layer--front {
    inset: 12%;
  }


  .prototype-page-frame[data-page="about"]
  .simple-glass-content,

  .prototype-page-frame[data-page="contact"]
  .simple-glass-content {
    width: 68%;
    max-height: 70%;
  }
}



/* =========================================================
   ABOUT / CONTACT — NESTED GLASS FORMATION / COLLAPSE
   =========================================================
   Closed / transitioning-away state:
     every pane occupies the full outer glass footprint.

   Open state:
     the four inner panes smoothly contract to their final nested sizes.

   Because this keys directly from the real page's .is-open class, the same
   transition automatically reverses when the page closes or hands off to the
   next page. No JS choreography is needed.
   ========================================================= */

.prototype-page-frame[data-page="about"]
.simple-glass-layer,

.prototype-page-frame[data-page="contact"]
.simple-glass-layer {
  /*
    Use one common physical footprint for every pane. Their final nesting is
    produced by scale rather than inset, so they can all begin/end at exactly
    the same outer boundary.
  */
  inset: 0;

  transform-origin: center center;

  transform:
    scale(1);

  transition:
    transform
    var(
      --prototype-page-frame-fade-duration,
      850ms
    )
    cubic-bezier(0.20, 0.72, 0.22, 1);
}


/*
  Outer pane is the reference/background footprint and therefore does not
  move. The remaining four panes contract concentrically.
*/
.prototype-page-frame[data-page="about"].is-open
.simple-glass-layer--outer,

.prototype-page-frame[data-page="contact"].is-open
.simple-glass-layer--outer {
  transform:
    scale(1);
}


.prototype-page-frame[data-page="about"].is-open
.simple-glass-layer--back,

.prototype-page-frame[data-page="contact"].is-open
.simple-glass-layer--back {
  transform:
    scale(0.92);
}


.prototype-page-frame[data-page="about"].is-open
.simple-glass-layer--middle,

.prototype-page-frame[data-page="contact"].is-open
.simple-glass-layer--middle {
  transform:
    scale(0.84);
}


.prototype-page-frame[data-page="about"].is-open
.simple-glass-layer--inner,

.prototype-page-frame[data-page="contact"].is-open
.simple-glass-layer--inner {
  transform:
    scale(0.76);
}


.prototype-page-frame[data-page="about"].is-open
.simple-glass-layer--front,

.prototype-page-frame[data-page="contact"].is-open
.simple-glass-layer--front {
  transform:
    scale(0.68);
}


/*
  The earlier narrow-container pass adjusted the final insets. Since nesting
  now comes from scale, use slightly gentler target scales on narrow layouts
  instead of changing physical offsets.
*/
@container simple-glass-page (max-width: 560px) {

  .prototype-page-frame[data-page="about"].is-open
  .simple-glass-layer--back,

  .prototype-page-frame[data-page="contact"].is-open
  .simple-glass-layer--back {
    transform:
      scale(0.94);
  }


  .prototype-page-frame[data-page="about"].is-open
  .simple-glass-layer--middle,

  .prototype-page-frame[data-page="contact"].is-open
  .simple-glass-layer--middle {
    transform:
      scale(0.88);
  }


  .prototype-page-frame[data-page="about"].is-open
  .simple-glass-layer--inner,

  .prototype-page-frame[data-page="contact"].is-open
  .simple-glass-layer--inner {
    transform:
      scale(0.82);
  }


  .prototype-page-frame[data-page="about"].is-open
  .simple-glass-layer--front,

  .prototype-page-frame[data-page="contact"].is-open
  .simple-glass-layer--front {
    transform:
      scale(0.76);
  }
}



/* =========================================================
   ABOUT / CONTACT — DENSER 8-PANE NEST + LARGE CHAMFERS
   =========================================================
   Three additional panes bring the stack to eight total. The overall depth
   remains almost identical to the previous five-pane version, but the scale
   steps are smaller so the panes sit much closer together.

   The glass chamfer is also 3x larger while still deriving its slope from the
   global --button-shear-angle.
   ========================================================= */

.simple-glass-page {
  --simple-glass-corner-rise:
    clamp(
      30px,
      min(7.5cqw, 7.5cqh),
      72px
    );
}


/*
  Intermediate pane styling. These intentionally interpolate between the
  neighboring authored panes rather than introducing a new visual language.
*/
.prototype-page-frame[data-page="about"]
.simple-glass-layer--ring-1,

.prototype-page-frame[data-page="contact"]
.simple-glass-layer--ring-1 {
  opacity: 0.44;

  background:
    linear-gradient(
      145deg,
      rgba(
        var(--page-accent-rgb),
        0.20
      ),
      rgba(15, 19, 24, 0.57) 47%,
      rgba(
        var(--page-accent-rgb),
        0.125
      )
    );

  border-color:
    rgba(
      var(--page-accent-rgb),
      0.33
    );
}


.prototype-page-frame[data-page="about"]
.simple-glass-layer--ring-2,

.prototype-page-frame[data-page="contact"]
.simple-glass-layer--ring-2 {
  opacity: 0.56;

  background:
    linear-gradient(
      145deg,
      rgba(
        var(--page-accent-rgb),
        0.235
      ),
      rgba(16, 20, 25, 0.62) 45%,
      rgba(
        var(--page-accent-rgb),
        0.15
      )
    );

  border-color:
    rgba(
      var(--page-accent-rgb),
      0.39
    );
}


.prototype-page-frame[data-page="about"]
.simple-glass-layer--ring-3,

.prototype-page-frame[data-page="contact"]
.simple-glass-layer--ring-3 {
  opacity: 0.69;

  background:
    linear-gradient(
      145deg,
      rgba(
        var(--page-accent-rgb),
        0.265
      ),
      rgba(16, 20, 25, 0.66) 43%,
      rgba(
        var(--page-accent-rgb),
        0.17
      )
    );

  border-color:
    rgba(
      var(--page-accent-rgb),
      0.45
    );
}


/*
  Eight evenly-spaced target scales. All panes still begin at scale(1), so
  the existing open/close formation effect remains intact.
*/
.prototype-page-frame[data-page="about"].is-open
.simple-glass-layer--outer,

.prototype-page-frame[data-page="contact"].is-open
.simple-glass-layer--outer {
  transform:
    scale(1);
}


.prototype-page-frame[data-page="about"].is-open
.simple-glass-layer--ring-1,

.prototype-page-frame[data-page="contact"].is-open
.simple-glass-layer--ring-1 {
  transform:
    scale(0.955);
}


.prototype-page-frame[data-page="about"].is-open
.simple-glass-layer--back,

.prototype-page-frame[data-page="contact"].is-open
.simple-glass-layer--back {
  transform:
    scale(0.91);
}


.prototype-page-frame[data-page="about"].is-open
.simple-glass-layer--ring-2,

.prototype-page-frame[data-page="contact"].is-open
.simple-glass-layer--ring-2 {
  transform:
    scale(0.865);
}


.prototype-page-frame[data-page="about"].is-open
.simple-glass-layer--middle,

.prototype-page-frame[data-page="contact"].is-open
.simple-glass-layer--middle {
  transform:
    scale(0.82);
}


.prototype-page-frame[data-page="about"].is-open
.simple-glass-layer--ring-3,

.prototype-page-frame[data-page="contact"].is-open
.simple-glass-layer--ring-3 {
  transform:
    scale(0.775);
}


.prototype-page-frame[data-page="about"].is-open
.simple-glass-layer--inner,

.prototype-page-frame[data-page="contact"].is-open
.simple-glass-layer--inner {
  transform:
    scale(0.73);
}


.prototype-page-frame[data-page="about"].is-open
.simple-glass-layer--front,

.prototype-page-frame[data-page="contact"].is-open
.simple-glass-layer--front {
  transform:
    scale(0.685);
}


/*
  On narrow layouts keep the same denser rhythm, just slightly shallower so
  the innermost pane leaves enough room for the copy.
*/
@container simple-glass-page (max-width: 560px) {

  .prototype-page-frame[data-page="about"].is-open
  .simple-glass-layer--ring-1,

  .prototype-page-frame[data-page="contact"].is-open
  .simple-glass-layer--ring-1 {
    transform:
      scale(0.96);
  }


  .prototype-page-frame[data-page="about"].is-open
  .simple-glass-layer--back,

  .prototype-page-frame[data-page="contact"].is-open
  .simple-glass-layer--back {
    transform:
      scale(0.92);
  }


  .prototype-page-frame[data-page="about"].is-open
  .simple-glass-layer--ring-2,

  .prototype-page-frame[data-page="contact"].is-open
  .simple-glass-layer--ring-2 {
    transform:
      scale(0.88);
  }


  .prototype-page-frame[data-page="about"].is-open
  .simple-glass-layer--middle,

  .prototype-page-frame[data-page="contact"].is-open
  .simple-glass-layer--middle {
    transform:
      scale(0.84);
  }


  .prototype-page-frame[data-page="about"].is-open
  .simple-glass-layer--ring-3,

  .prototype-page-frame[data-page="contact"].is-open
  .simple-glass-layer--ring-3 {
    transform:
      scale(0.80);
  }


  .prototype-page-frame[data-page="about"].is-open
  .simple-glass-layer--inner,

  .prototype-page-frame[data-page="contact"].is-open
  .simple-glass-layer--inner {
    transform:
      scale(0.76);
  }


  .prototype-page-frame[data-page="about"].is-open
  .simple-glass-layer--front,

  .prototype-page-frame[data-page="contact"].is-open
  .simple-glass-layer--front {
    transform:
      scale(0.72);
  }
}



/* =========================================================
   ABOUT / CONTACT — TIGHTER STACK + FASTER FORMATION
   =========================================================
   Halve the distance each pane travels away from scale(1), keeping the same
   eight-pane ordering but making the final nest roughly twice as tight.

   Also halve the existing formation/collapse duration so the pane movement
   resolves noticeably faster than the page fade.
   ========================================================= */

.prototype-page-frame[data-page="about"]
.simple-glass-layer,

.prototype-page-frame[data-page="contact"]
.simple-glass-layer {
  transition:
    transform
    calc(
      var(
        --prototype-page-frame-fade-duration,
        850ms
      )
      * 0.5
    )
    cubic-bezier(0.20, 0.72, 0.22, 1);
}


.prototype-page-frame[data-page="about"].is-open
.simple-glass-layer--outer,

.prototype-page-frame[data-page="contact"].is-open
.simple-glass-layer--outer {
  transform:
    scale(1);
}


.prototype-page-frame[data-page="about"].is-open
.simple-glass-layer--ring-1,

.prototype-page-frame[data-page="contact"].is-open
.simple-glass-layer--ring-1 {
  transform:
    scale(0.9775);
}


.prototype-page-frame[data-page="about"].is-open
.simple-glass-layer--back,

.prototype-page-frame[data-page="contact"].is-open
.simple-glass-layer--back {
  transform:
    scale(0.955);
}


.prototype-page-frame[data-page="about"].is-open
.simple-glass-layer--ring-2,

.prototype-page-frame[data-page="contact"].is-open
.simple-glass-layer--ring-2 {
  transform:
    scale(0.9325);
}


.prototype-page-frame[data-page="about"].is-open
.simple-glass-layer--middle,

.prototype-page-frame[data-page="contact"].is-open
.simple-glass-layer--middle {
  transform:
    scale(0.91);
}


.prototype-page-frame[data-page="about"].is-open
.simple-glass-layer--ring-3,

.prototype-page-frame[data-page="contact"].is-open
.simple-glass-layer--ring-3 {
  transform:
    scale(0.8875);
}


.prototype-page-frame[data-page="about"].is-open
.simple-glass-layer--inner,

.prototype-page-frame[data-page="contact"].is-open
.simple-glass-layer--inner {
  transform:
    scale(0.865);
}


.prototype-page-frame[data-page="about"].is-open
.simple-glass-layer--front,

.prototype-page-frame[data-page="contact"].is-open
.simple-glass-layer--front {
  transform:
    scale(0.8425);
}


@container simple-glass-page (max-width: 560px) {

  .prototype-page-frame[data-page="about"].is-open
  .simple-glass-layer--ring-1,

  .prototype-page-frame[data-page="contact"].is-open
  .simple-glass-layer--ring-1 {
    transform:
      scale(0.98);
  }


  .prototype-page-frame[data-page="about"].is-open
  .simple-glass-layer--back,

  .prototype-page-frame[data-page="contact"].is-open
  .simple-glass-layer--back {
    transform:
      scale(0.96);
  }


  .prototype-page-frame[data-page="about"].is-open
  .simple-glass-layer--ring-2,

  .prototype-page-frame[data-page="contact"].is-open
  .simple-glass-layer--ring-2 {
    transform:
      scale(0.94);
  }


  .prototype-page-frame[data-page="about"].is-open
  .simple-glass-layer--middle,

  .prototype-page-frame[data-page="contact"].is-open
  .simple-glass-layer--middle {
    transform:
      scale(0.92);
  }


  .prototype-page-frame[data-page="about"].is-open
  .simple-glass-layer--ring-3,

  .prototype-page-frame[data-page="contact"].is-open
  .simple-glass-layer--ring-3 {
    transform:
      scale(0.90);
  }


  .prototype-page-frame[data-page="about"].is-open
  .simple-glass-layer--inner,

  .prototype-page-frame[data-page="contact"].is-open
  .simple-glass-layer--inner {
    transform:
      scale(0.88);
  }


  .prototype-page-frame[data-page="about"].is-open
  .simple-glass-layer--front,

  .prototype-page-frame[data-page="contact"].is-open
  .simple-glass-layer--front {
    transform:
      scale(0.86);
  }
}



/* =========================================================
   ABOUT / CONTACT — RESTORE PREVIOUS DEPTH, KEEP FAST TIMING
   =========================================================
   v178's 0.5x duration felt right, but the pane spacing was too compressed.
   Restore the v177 target scales while leaving the faster transition intact.
   ========================================================= */

.prototype-page-frame[data-page="about"].is-open
.simple-glass-layer--outer,
.prototype-page-frame[data-page="contact"].is-open
.simple-glass-layer--outer {
  transform: scale(1);
}

.prototype-page-frame[data-page="about"].is-open
.simple-glass-layer--ring-1,
.prototype-page-frame[data-page="contact"].is-open
.simple-glass-layer--ring-1 {
  transform: scale(0.955);
}

.prototype-page-frame[data-page="about"].is-open
.simple-glass-layer--back,
.prototype-page-frame[data-page="contact"].is-open
.simple-glass-layer--back {
  transform: scale(0.91);
}

.prototype-page-frame[data-page="about"].is-open
.simple-glass-layer--ring-2,
.prototype-page-frame[data-page="contact"].is-open
.simple-glass-layer--ring-2 {
  transform: scale(0.865);
}

.prototype-page-frame[data-page="about"].is-open
.simple-glass-layer--middle,
.prototype-page-frame[data-page="contact"].is-open
.simple-glass-layer--middle {
  transform: scale(0.82);
}

.prototype-page-frame[data-page="about"].is-open
.simple-glass-layer--ring-3,
.prototype-page-frame[data-page="contact"].is-open
.simple-glass-layer--ring-3 {
  transform: scale(0.775);
}

.prototype-page-frame[data-page="about"].is-open
.simple-glass-layer--inner,
.prototype-page-frame[data-page="contact"].is-open
.simple-glass-layer--inner {
  transform: scale(0.73);
}

.prototype-page-frame[data-page="about"].is-open
.simple-glass-layer--front,
.prototype-page-frame[data-page="contact"].is-open
.simple-glass-layer--front {
  transform: scale(0.685);
}


@container simple-glass-page (max-width: 560px) {
  .prototype-page-frame[data-page="about"].is-open
  .simple-glass-layer--ring-1,
  .prototype-page-frame[data-page="contact"].is-open
  .simple-glass-layer--ring-1 {
    transform: scale(0.96);
  }

  .prototype-page-frame[data-page="about"].is-open
  .simple-glass-layer--back,
  .prototype-page-frame[data-page="contact"].is-open
  .simple-glass-layer--back {
    transform: scale(0.92);
  }

  .prototype-page-frame[data-page="about"].is-open
  .simple-glass-layer--ring-2,
  .prototype-page-frame[data-page="contact"].is-open
  .simple-glass-layer--ring-2 {
    transform: scale(0.88);
  }

  .prototype-page-frame[data-page="about"].is-open
  .simple-glass-layer--middle,
  .prototype-page-frame[data-page="contact"].is-open
  .simple-glass-layer--middle {
    transform: scale(0.84);
  }

  .prototype-page-frame[data-page="about"].is-open
  .simple-glass-layer--ring-3,
  .prototype-page-frame[data-page="contact"].is-open
  .simple-glass-layer--ring-3 {
    transform: scale(0.80);
  }

  .prototype-page-frame[data-page="about"].is-open
  .simple-glass-layer--inner,
  .prototype-page-frame[data-page="contact"].is-open
  .simple-glass-layer--inner {
    transform: scale(0.76);
  }

  .prototype-page-frame[data-page="about"].is-open
  .simple-glass-layer--front,
  .prototype-page-frame[data-page="contact"].is-open
  .simple-glass-layer--front {
    transform: scale(0.72);
  }
}


/* =========================================================
   MOBILE SIMPLE PAGES — FAST COPY EXIT
   =========================================================
   On About/Contact only, get the readable content out of the way almost
   immediately when a directional page transition begins. The glass itself
   continues its normal collapse/slide choreography.
   ========================================================= */

@media (max-width: 750px) {
  .prototype-page-frame[data-page="about"]
  .simple-glass-content,
  .prototype-page-frame[data-page="contact"]
  .simple-glass-content {
    opacity: 1;

    transition:
      opacity
      220ms
      ease-out;
  }


  .prototype-page-frame[data-page="about"].is-mobile-simple-page-exiting
  .simple-glass-content,
  .prototype-page-frame[data-page="contact"].is-mobile-simple-page-exiting
  .simple-glass-content {
    opacity: 0;
  }
}



/* =========================================================
   CONTACT PAGE — STANDARD CONTACT / SOCIAL LAYOUT
   ========================================================= */

.simple-glass-content--contact {
  width:
    min(
      62%,
      780px
    );

  max-height: 68%;
}


.contact-page-intro {
  max-width: 58ch;
}


.contact-email-card,
.contact-social-card {
  position: relative;

  width: 100%;

  display: grid;
  align-items: center;

  color: rgba(247, 249, 251, 0.94);
  text-decoration: none;

  border:
    1px solid
    rgba(
      var(--page-accent-rgb),
      0.34
    );

  background:
    linear-gradient(
      135deg,
      rgba(
        var(--page-accent-rgb),
        0.17
      ),
      rgba(13, 17, 22, 0.48)
    );

  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.08);

  transition:
    background-color 160ms ease,
    border-color 160ms ease,
    transform 160ms ease,
    box-shadow 160ms ease;
}


.contact-email-card {
  grid-template-columns:
    auto
    minmax(0, 1fr)
    auto;

  gap:
    clamp(
      10px,
      min(2.0cqw, 2.0cqh),
      18px
    );

  padding:
    clamp(
      12px,
      min(2.5cqw, 2.5cqh),
      20px
    )
    clamp(
      14px,
      min(3.0cqw, 3.0cqh),
      24px
    );

  /*
    Same slope as the rest of the site; only the cut size varies.
  */
  --contact-card-corner-rise:
    clamp(
      8px,
      min(1.6cqw, 1.6cqh),
      14px
    );

  --contact-card-corner-run:
    calc(
      var(--contact-card-corner-rise)
      *
      tan(
        calc(
          var(--button-shear-angle)
          * -1
        )
      )
    );

  clip-path:
    polygon(
      var(--contact-card-corner-run) 0,
      100% 0,
      100%
        calc(
          100%
          -
          var(--contact-card-corner-rise)
        ),
      calc(
        100%
        -
        var(--contact-card-corner-run)
      )
        100%,
      0 100%,
      0
        var(--contact-card-corner-rise)
    );
}


.contact-email-icon {
  display: grid;
  place-items: center;

  width:
    clamp(
      30px,
      min(5.5cqw, 6.2cqh),
      42px
    );

  aspect-ratio: 1;

  color:
    rgba(
      var(--page-accent-rgb),
      0.96
    );

  font-size:
    clamp(
      17px,
      min(3.4cqw, 3.8cqh),
      24px
    );

  line-height: 1;
}


.contact-email-copy,
.contact-social-copy {
  min-width: 0;

  display: flex;
  flex-direction: column;

  gap:
    clamp(
      3px,
      0.6cqh,
      6px
    );
}


.contact-email-copy small,
.contact-social-heading,
.contact-social-copy small {
  color:
    rgba(
      var(--page-accent-rgb),
      0.76
    );

  font-size:
    clamp(
      8px,
      min(1.35cqw, 1.7cqh),
      11px
    );

  line-height: 1.1;

  letter-spacing: 0.15em;

  font-weight: 700;
}


.contact-email-copy strong {
  overflow-wrap: anywhere;

  font-size:
    clamp(
      12px,
      min(2.35cqw, 2.8cqh),
      18px
    );

  line-height: 1.22;
}


.contact-link-arrow {
  color:
    rgba(
      var(--page-accent-rgb),
      0.90
    );

  font-size:
    clamp(
      22px,
      min(4.3cqw, 5cqh),
      32px
    );

  line-height: 1;

  transform: translateX(0);

  transition:
    transform 160ms ease;
}


.contact-social-section {
  width: 100%;

  display: flex;
  flex-direction: column;

  gap:
    clamp(
      7px,
      min(1.4cqw, 1.4cqh),
      12px
    );
}


.contact-social-heading {
  padding-left:
    clamp(
      2px,
      0.5cqw,
      5px
    );
}


.contact-social-grid {
  display: grid;

  grid-template-columns:
    repeat(
      3,
      minmax(
        0,
        1fr
      )
    );

  gap:
    clamp(
      7px,
      min(1.4cqw, 1.4cqh),
      12px
    );
}


.contact-social-card {
  grid-template-columns:
    auto
    minmax(0, 1fr)
    auto;

  gap:
    clamp(
      7px,
      min(1.1cqw, 1.1cqh),
      10px
    );

  min-width: 0;

  padding:
    clamp(
      9px,
      min(1.8cqw, 2.0cqh),
      14px
    );
}


.contact-social-icon {
  display: block;

  width:
    clamp(
      20px,
      min(3.8cqw, 4.2cqh),
      28px
    );

  aspect-ratio: 1;

  /*
    Simple Icons ships these as black SVGs. Invert them into the site's
    light-on-glass treatment while keeping the official silhouettes intact.
  */
  filter:
    invert(1)
    opacity(0.88);
}


.contact-social-copy strong {
  color: rgba(247, 249, 251, 0.94);

  font-size:
    clamp(
      10px,
      min(1.8cqw, 2.2cqh),
      14px
    );

  line-height: 1.1;
}


.contact-social-copy small {
  overflow: hidden;

  text-overflow: ellipsis;
  white-space: nowrap;

  letter-spacing: 0.02em;

  color: rgba(230, 235, 239, 0.58);
}


.contact-email-card:hover,
.contact-email-card:focus-visible,
.contact-social-card:hover,
.contact-social-card:focus-visible {
  outline: none;

  border-color:
    rgba(
      var(--page-accent-rgb),
      0.68
    );

  background:
    linear-gradient(
      135deg,
      rgba(
        var(--page-accent-rgb),
        0.27
      ),
      rgba(14, 18, 23, 0.58)
    );

  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.12),
    0 0 18px
      rgba(
        var(--page-accent-rgb),
        0.11
      );

  transform:
    translateY(-1px);
}


.contact-email-card:hover
.contact-link-arrow,
.contact-email-card:focus-visible
.contact-link-arrow,
.contact-social-card:hover
.contact-link-arrow,
.contact-social-card:focus-visible
.contact-link-arrow {
  transform:
    translateX(3px);
}


@container simple-glass-page (max-width: 750px) {
  .simple-glass-content--contact {
    width: 68%;
    max-height: 72%;
  }


  .contact-social-grid {
    grid-template-columns:
      1fr;
  }
}


@container simple-glass-page (max-height: 560px) {
  .simple-glass-content--contact {
    max-height: 76%;

    gap:
      clamp(
        5px,
        1.0cqh,
        9px
      );
  }


  .contact-email-card {
    padding:
      9px
      12px;
  }


  .contact-social-card {
    padding:
      7px
      9px;
  }
}



/* =========================================================
   GAME INFO GLASS — MOVE FOREGROUND PANE ABOVE LOGO
   =========================================================
   The fourth / foreground pane used to begin around the feature/facts area,
   putting its top edge directly through readable information.

   Keep the pane itself and its bottom/right geometry unchanged; simply move
   its top edge upward so the line sits above the game identity/logo instead.
   This is intentionally a fixed authored position rather than a measured one.
   ========================================================= */

/* Desktop popout info panels. */
@media (min-width: 1401px) {
  #brobots-page-frame
  .desktop-secondary-panel
  .etherian-popout-glass-layer--4,

  #etherian-page-frame
  .desktop-secondary-panel
  .etherian-popout-glass-layer--4,

  #halodoom-page-frame
  .desktop-secondary-panel
  .etherian-popout-glass-layer--4 {
    top: 12% !important;
  }
}


/* Tablet + mobile in-frame info panels. */
@media (max-width: 1400px) {
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--4 {
    top: 8% !important;
  }
}



/* =========================================================
   GAME INFO GLASS — LOWER FOREGROUND PANE SLIGHTLY ON DESKTOP
   =========================================================
   v182 moved the fourth pane high enough to clear the content, but on the
   desktop popout it now sits too close to the pane above and the two surfaces
   visually merge.

   Drop only the desktop popout version a little so the layer spacing reads
   clearly again. Tablet/mobile keep the v182 position.
   ========================================================= */

@media (min-width: 1401px) {
  #brobots-page-frame
  .desktop-secondary-panel
  .etherian-popout-glass-layer--4,

  #etherian-page-frame
  .desktop-secondary-panel
  .etherian-popout-glass-layer--4,

  #halodoom-page-frame
  .desktop-secondary-panel
  .etherian-popout-glass-layer--4 {
    top: 18% !important;
  }
}



/* =========================================================
   TABLET / MOBILE GAME INFO — CLEANER PANE RHYTHM
   =========================================================
   The in-frame stack had accumulated unrelated left/right/top offsets, so the
   sheets felt slightly accidental compared with the desktop popout.

   Give all four panes one clear nesting rule:
     - shared left edge
     - progressively larger top/right/bottom inset
     - even visual spacing between layers
     - foreground pane still begins above the game logo

   This affects only the tablet/mobile in-frame info stack.
   ========================================================= */

@media (max-width: 1400px) {

  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--1 {
    inset:
      0%
      1.5%
      2.5%
      0% !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--2 {
    inset:
      3%
      5%
      6%
      0% !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--3 {
    inset:
      6%
      9%
      9.5%
      0% !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--4 {
    left: 0% !important;
    right: 13% !important;
    top: 9% !important;
    bottom: 13% !important;
  }
}



/* =========================================================
   TABLET / MOBILE GAME INFO — LOOSEN THE PANE RHYTHM
   =========================================================
   v184 became a little too mathematically nested. Keep the cleaner overall
   flow, but reintroduce a small amount of asymmetry so the sheets feel layered
   rather than diagrammed.

   The offsets are still deliberate, just not perfectly incremental.
   ========================================================= */

@media (max-width: 1400px) {

  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--1 {
    inset:
      0%
      1.5%
      3%
      0% !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--2 {
    inset:
      4%
      5.5%
      5.5%
      1.2% !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--3 {
    inset:
      7%
      10.5%
      10%
      2.6% !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-tablet-glass-stack
  .etherian-popout-glass-layer--4 {
    left: 1.4% !important;
    right: 14.5% !important;
    top: 10% !important;
    bottom: 11.5% !important;
  }
}



/* =========================================================
   HEADER BANNER — INSET TO THE VIEWPORT FRAME STRETCH WIDTH
   =========================================================
   The viewport frame's straight stretch strips are authored at 21px when the
   banner/header reference height is 120px.

   Use that same ratio here so the banner always sits just INSIDE the outer
   viewport frame:
     - top buffer = outer stretch-strip thickness
     - left/right buffer = outer stretch-strip thickness
     - the fixed corner art can still overlap the banner naturally because the
       viewport frame is layered above the header
     - the straight stretch bars no longer sit on top of the banner

   Header content uses the exact same inset box, so logo + nav/hamburger move
   together with the banner instead of needing individual offsets.
   ========================================================= */

.site-header {
  --banner-frame-buffer:
    calc(
      var(--frame-height)
      * 21
      / 120
    );

  /*
    Keep the banner tight to its own lower edge; only the sides that touch the
    viewport's top/side frame need the stretch-width clearance.
  */
  padding:
    var(--banner-frame-buffer)
    var(--banner-frame-buffer)
    0;
}


.header-content {
  top:
    var(--banner-frame-buffer);

  right:
    var(--banner-frame-buffer);

  bottom:
    0;

  left:
    var(--banner-frame-buffer);
}


/*
  The <=485px header is uniformly scaled as one frozen composition. Because
  --banner-frame-buffer derives from the frozen --frame-height, it scales by
  exactly the same factor as the viewport-frame stretch strips without a
  second mobile-specific magic number.
*/
@media (max-width: 485px) {
  .site-header {
    --banner-frame-buffer:
      calc(
        var(--frame-height)
        * 21
        / 120
      );
  }
}



/* =========================================================
   HEADER BANNER — NUDGE UP INTO OUTER FRAME
   =========================================================
   Keep the stretch-width side buffers, but pull the whole banner/header
   content upward a few pixels so the top edge visually tucks under the
   viewport frame instead of leaving a hairline gap.
   ========================================================= */

.site-header {
  --banner-frame-overlap-y: 6px;

  padding-top:
    calc(
      var(--banner-frame-buffer)
      -
      var(--banner-frame-overlap-y)
    );
}


.header-content {
  top:
    calc(
      var(--banner-frame-buffer)
      -
      var(--banner-frame-overlap-y)
    );
}



/* =========================================================
   HEADER / MENU TYPOGRAPHY — MICHROMA TEST PASS
   =========================================================
   Use Michroma for the navigation labels so the UI picks up more of the
   wide, geometric Y2K character of the Simulacrum wordmark without changing
   any button geometry or spacing yet.
   ========================================================= */


.nav-button,
.mobile-menu-link {
  font-family:
    "Michroma",
    system-ui,
    sans-serif;
}



/* =========================================================
   HEADER / MENU TYPOGRAPHY — SLIGHTLY SMALLER MICHROMA
   =========================================================
   Reduce only the readable text by 2px. Keep the tablet icon glyphs and
   all button geometry unchanged.
   ========================================================= */

.nav-button .nav-label {
  font-size:
    clamp(
      8px,
      calc(0.68vw - 2px),
      12px
    );
}

.mobile-menu-link-text {
  font-size:
    clamp(
      15px,
      calc(3vw - 2px),
      20px
    );
}



/* =========================================================
   ABOUT / CONTACT — MICHROMA DISPLAY TYPOGRAPHY
   =========================================================
   Carry the header's Michroma treatment into the simple pages for their
   display/UI typography, while leaving paragraph copy in the existing body
   font for readability.
   ========================================================= */

.prototype-page-frame[data-page="about"] .simple-page-title,
.prototype-page-frame[data-page="contact"] .simple-page-title,
.prototype-page-frame[data-page="about"] .simple-page-kicker,
.prototype-page-frame[data-page="contact"] .simple-page-kicker,
.prototype-page-frame[data-page="about"] .simple-page-pronunciation,
.prototype-page-frame[data-page="about"] .simple-page-fact span,
.prototype-page-frame[data-page="about"] .simple-page-fact strong,
.prototype-page-frame[data-page="contact"] .contact-email-copy small,
.prototype-page-frame[data-page="contact"] .contact-email-copy strong,
.prototype-page-frame[data-page="contact"] .contact-social-heading,
.prototype-page-frame[data-page="contact"] .contact-social-copy strong,
.prototype-page-frame[data-page="contact"] .contact-social-copy small {
  font-family:
    "Michroma",
    system-ui,
    sans-serif;
}



/* =========================================================
   GAME INFO PAGES — MICHROMA ONLY ON SMALL HEADERS
   =========================================================
   Keep the game info layouts stable by limiting Michroma to:
     - the short descriptor directly under each game logo
     - the three fact headers above the action buttons

   Body copy, feature rows, fact values and buttons retain their existing
   typography and sizing.
   ========================================================= */

.prototype-page-frame[data-game-frame-page] .game-info-kicker,
.prototype-page-frame[data-game-frame-page] .game-info-fact span {
  font-family:
    "Michroma",
    system-ui,
    sans-serif;
}


/* =========================================================
   TABLET NAV ICONS — RASTER ASSETS
   =========================================================
   Use authored PNG icons from assets/header instead of the temporary
   inline-SVG approximations. Keep the existing .nav-icon wrapper so the
   tablet button layout and responsive behavior remain unchanged.
   ========================================================= */

.nav-icon {
  width: 2.4em;
  height: 2.4em;
}

.nav-icon-image {
  display: block;

  width: 100%;
  height: 100%;

  object-fit: contain;
  object-position: center;

  max-width: none;
  max-height: none;

  pointer-events: none;
  user-select: none;

  -webkit-user-drag: none;
}



/* =========================================================
   MOBILE MENU — USE PAGE ICON PNGS IN PLACE OF TRIANGLE MOTIFS
   =========================================================
   Reuse the same authored header icons as tablet nav. Keep the existing
   .mobile-menu-link-motif wrapper so menu spacing/alignment stays intact.
   ========================================================= */

.mobile-menu-link-motif {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.mobile-menu-link-icon-image {
  display: block;

  width: 2.1em;
  height: 2.1em;

  object-fit: contain;
  object-position: center;

  max-width: none;
  max-height: none;

  pointer-events: none;
  user-select: none;

  -webkit-user-drag: none;
}



/* =========================================================
   GAME INFO FEATURE DESCRIPTIONS — TWO-LINE WRAP
   =========================================================
   The feature descriptions were originally forced onto one line with an
   ellipsis. Allow the existing text area to use a second line instead,
   without changing the feature-grid proportions. This applies to every
   game info page that uses the shared game-info structure.
   ========================================================= */

.prototype-page-frame[data-game-frame-page]
.game-info-feature-copy small {
  overflow: visible;

  white-space: normal;

  text-overflow: clip;

  /*
    Reserve a consistent two-line text area so rows remain aligned even
    when one description happens to fit on a single line.
  */
  min-height: 2.44em;
}


/* =========================================================
   ETHERIAN + HALODOOM FEATURE DESCRIPTIONS — MATCH BROBOTS
   =========================================================
   Brobots already allows the mid-row description copy to breathe across
   two lines. Etherian and Halodoom still had stronger page-specific rules
   forcing a single-line ellipsis.

   Override those more specific rules directly so all game pages share the
   same behavior: same width/proportions, but description copy may wrap to
   a second line instead of being cut off.
   ========================================================= */

#brobots-page-frame .game-info-feature-copy small,
#etherian-page-frame .game-info-feature-copy small,
#etherian-page-frame.is-info-compact .game-info-feature-copy small,
#etherian-page-frame.is-info-tight .game-info-feature-copy small,
#halodoom-page-frame .game-info-feature-copy small,
#halodoom-page-frame.is-info-compact .game-info-feature-copy small,
#halodoom-page-frame.is-info-tight .game-info-feature-copy small,
.prototype-page-frame[data-game-frame-page] .game-info-feature-copy small {
  display: -webkit-box !important;
  -webkit-box-orient: vertical !important;
  -webkit-line-clamp: 2;
  line-clamp: 2;

  overflow: hidden !important;
  white-space: normal !important;
  text-overflow: clip !important;

  line-height: 1.22;
  min-height: calc(1.22em * 2);
}


/* =========================================================
   MOBILE GAME FACTS — FIT LONGER REAL CONTENT
   =========================================================
   The original metadata values were short placeholders, so the three-column
   row could afford larger type plus ellipsis. Real values such as
   "PC VR (Steam, Viveport)" and "Adventure / Platformer" need the type to
   scale down instead of being visibly chopped.
   ========================================================= */

@media (max-width: 750px) {

  .prototype-page-frame[data-game-frame-page]
  .game-info-fact span {
    font-size:
      clamp(
        6.5px,
        1.65cqw,
        8.5px
      ) !important;

    letter-spacing: 0.10em;

    white-space: normal;
    overflow-wrap: normal;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-info-fact strong {
    font-size:
      clamp(
        6.5px,
        1.70cqw,
        8.75px
      ) !important;

    line-height: 1.18;

    /*
      Real metadata values are not guaranteed to fit on one line.
      Let every game page use up to two lines here instead of shrinking
      Brobots differently or clipping longer values.
    */
    white-space: normal !important;
    overflow: visible !important;
    text-overflow: clip !important;

    overflow-wrap: normal;
    word-break: normal;

    min-height: calc(1.18em * 2);
  }
}


/* =========================================================
   MOBILE GAME FACTS — SECOND LINE WITHOUT RESERVING HEIGHT
   =========================================================
   Let long metadata values wrap, but keep the metadata row sized as though
   the value were one line tall. A second line is allowed to paint into the
   existing breathing room below instead of making the entire facts row taller.
   This is shared by Brobots, Etherian, and Halodoom.
   ========================================================= */

@media (max-width: 750px) {

  .prototype-page-frame[data-game-frame-page]
  .game-info-fact strong {
    min-height: 0 !important;
    height: 1.18em;

    white-space: normal !important;
    overflow: visible !important;
    text-overflow: clip !important;
  }


  /*
    Let the two action buttons get shallower as the phone gets narrower.
    Width/layout stays exactly the same; only their vertical footprint scales.
  */
  .prototype-page-frame[data-game-frame-page]
  .game-info-action {
    min-height:
      clamp(
        32px,
        8vw,
        46px
      ) !important;

    padding-top: 0 !important;
    padding-bottom: 0 !important;
  }
}



/* =========================================================
   MOBILE GAME BLURBS — SLIGHTLY SMALLER
   =========================================================
   The mobile blurb currently dominates the visual hierarchy a little too
   much compared with the feature rows, facts, and actions. Reduce it gently
   on all game pages while preserving the existing fitter behavior.
   ========================================================= */

@media (max-width: 750px) {

  .prototype-page-frame[data-game-frame-page]
  .game-info-blurb {
    font-size:
      clamp(
        7px,
        1.75vw,
        9px
      ) !important;

    line-height: 1.38;
  }
}



/* =========================================================
   MOBILE GAME BLURB — ACTUAL FITTER CEILING
   =========================================================
   The earlier mobile size tweak was being beaten by the higher-specificity
   shared fitter selector. Match that selector here so the JS fitter sees the
   smaller mobile size as its STARTING / MAXIMUM size, then can still shrink
   farther if the rest of the info panel needs room.
   ========================================================= */

@media (max-width: 750px) {

  .prototype-page-frame[data-game-frame-page]
  .game-info-blurb,
  .prototype-page-frame[data-game-frame-page].is-info-compact
  .game-info-blurb,
  .prototype-page-frame[data-game-frame-page].is-info-tight
  .game-info-blurb,
  .prototype-page-frame[data-game-frame-page]
  .game-tablet-info-host
  .game-info-blurb {
    --game-info-blurb-min-size: 8.5px;

    font-size:
      var(
        --game-info-blurb-fit-size,
        clamp(
          10px,
          2.35vw,
          12px
        )
      )
      !important;

    line-height: 1.40;
  }
}



/* =========================================================
   TABLET GAME INFO — LARGER FOUR-PART FEATURE STRIP
   =========================================================
   The four feature rows were reading much smaller than the rest of the
   tablet info panel. Increase only their icon/title/description typography;
   keep the existing two-column proportions and spacing intact.
   ========================================================= */

@media (min-width: 751px) and (max-width: 1400px) {

  .prototype-page-frame[data-game-frame-page]
  .game-info-feature-icon,
  .prototype-page-frame[data-game-frame-page].is-info-compact
  .game-info-feature-icon,
  .prototype-page-frame[data-game-frame-page].is-info-tight
  .game-info-feature-icon {
    font-size:
      clamp(
        17px,
        1.18cqw,
        23px
      ) !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-info-feature-copy strong,
  .prototype-page-frame[data-game-frame-page].is-info-compact
  .game-info-feature-copy strong,
  .prototype-page-frame[data-game-frame-page].is-info-tight
  .game-info-feature-copy strong {
    font-size:
      clamp(
        9.5px,
        0.64cqw,
        11.5px
      ) !important;

    line-height: 1.16;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-info-feature-copy small,
  .prototype-page-frame[data-game-frame-page].is-info-compact
  .game-info-feature-copy small,
  .prototype-page-frame[data-game-frame-page].is-info-tight
  .game-info-feature-copy small {
    font-size:
      clamp(
        8.5px,
        0.58cqw,
        10.5px
      ) !important;

    line-height: 1.25;
  }
}



/* =========================================================
   MOBILE GAME FEATURES — FIT LONG COPY INSTEAD OF CUTTING IT
   =========================================================
   The shared desktop/tablet rule intentionally caps feature descriptions
   at two lines. On phones the columns are much narrower, so some real copy
   needs a third line. Let the mobile feature copy use up to three lines and
   scale a little smaller as the viewport narrows instead of clipping it.
   ========================================================= */

@media (max-width: 750px) {

  .prototype-page-frame[data-game-frame-page]
  .game-info-feature-copy strong,
  .prototype-page-frame[data-game-frame-page].is-info-compact
  .game-info-feature-copy strong,
  .prototype-page-frame[data-game-frame-page].is-info-tight
  .game-info-feature-copy strong {
    font-size:
      clamp(
        7px,
        1.75vw,
        9px
      ) !important;

    line-height: 1.16;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-info-feature-copy small,
  .prototype-page-frame[data-game-frame-page].is-info-compact
  .game-info-feature-copy small,
  .prototype-page-frame[data-game-frame-page].is-info-tight
  .game-info-feature-copy small {
    display: -webkit-box !important;

    -webkit-box-orient: vertical !important;
    -webkit-line-clamp: 3 !important;
    line-clamp: 3;

    font-size:
      clamp(
        6.5px,
        1.55vw,
        8px
      ) !important;

    line-height: 1.18;

    min-height: 0 !important;

    overflow: hidden !important;
    white-space: normal !important;
    text-overflow: clip !important;
  }
}


/* =========================================================
   MOBILE LANDSCAPE GUARD — ALLOW AN OPEN LIGHTBOX THROUGH
   =========================================================
   Keep the existing portrait-only site lock. The one exception is the
   screenshot lightbox: if it is already open, rotating a phone/tablet may
   reveal and interact with the lightbox normally. Closing it in landscape
   returns immediately to the existing rotate-to-portrait guard.
   ========================================================= */

@media
  (orientation: landscape)
  and (pointer: coarse)
  and (max-height: 600px) {

  body:has(> .media-lightbox.is-open)::before,
  body:has(> .media-lightbox.is-closing)::before {
    content: none !important;
    display: none !important;
  }


  body:has(> .media-lightbox.is-open)
  > .media-lightbox,

  body:has(> .media-lightbox.is-closing)
  > .media-lightbox {
    pointer-events: auto !important;
    user-select: auto !important;
  }


  /*
    Landscape phones are often wider than the normal 840px mobile breakpoint.
    Keep the fullscreen image edge-to-edge anyway, with compact vertical
    gutters that suit the short landscape viewport.
  */
  .media-lightbox {
    --media-lightbox-side-gutter: 0px;
    --media-lightbox-top-gutter:
      clamp(54px, 13vh, 72px);
    --media-lightbox-bottom-gutter:
      clamp(10px, 3vh, 22px);
  }


  .media-lightbox-image {
    max-width: 100vw;
  }


  .media-lightbox-arrow {
    z-index: 2;

    top:
      calc(
        50% +
        (
          var(--media-lightbox-top-gutter) -
          var(--media-lightbox-bottom-gutter)
        ) / 2
      );
  }


  .media-lightbox-arrow--previous {
    left:
      max(
        4px,
        env(safe-area-inset-left)
      );
  }


  .media-lightbox-arrow--next {
    right:
      max(
        4px,
        env(safe-area-inset-right)
      );
  }
}


/* =========================================================
   TABLET / MOBILE LIGHTBOX — TOUCH GESTURE OWNERSHIP
   =========================================================
   Fullscreen screenshots now own direct touch gestures:
     swipe LEFT  -> next screenshot
     swipe RIGHT -> previous screenshot
     swipe UP/DOWN -> close lightbox
   ========================================================= */

@media (max-width: 1400px) {
  .media-lightbox.is-open {
    touch-action: none;
  }

  .media-lightbox-image {
    -webkit-user-drag: none;
    user-select: none;
  }
}


/* =========================================================
   TABLET / MOBILE LIGHTBOX — HERO-STYLE IMAGE WIPE
   =========================================================
   Horizontal lightbox swipes now use the same visual language as the mobile
   hero: the outgoing screenshot stays still while the incoming screenshot is
   revealed by a width-growing layer with a soft feathered leading edge.
   ========================================================= */

@media (max-width: 1400px) {

  .media-lightbox-wipe-layer {
    position: absolute;

    top:
      var(--media-lightbox-top-gutter);

    bottom:
      var(--media-lightbox-bottom-gutter);

    width: 0;

    overflow: hidden;

    z-index: 1;

    pointer-events: none;

    will-change: width;

    animation: none;
  }


  /*
    The inner canvas always retains the FULL safe lightbox width while the
    outer wrapper clips it. That keeps the incoming screenshot centered at
    its final geometry throughout the wipe instead of squashing/stretching.
  */
  .media-lightbox-wipe-canvas {
    position: absolute;

    top: 0;
    bottom: 0;

    width:
      calc(
        100vw -
        (var(--media-lightbox-side-gutter) * 2)
      );

    display: grid;
    place-items: center;

    pointer-events: none;
  }


  .media-lightbox-wipe-image {
    display: block;

    max-width: 100%;
    max-height: 100%;

    width: auto;
    height: auto;

    object-fit: contain;

    box-shadow:
      0 18px 60px
      rgba(0, 0, 0, 0.58);

    pointer-events: none;
    user-select: none;

    -webkit-user-drag: none;
  }


  /*
    NEXT / finger swipes left:
    reveal the incoming screenshot inward from the RIGHT edge.
  */
  .media-lightbox-wipe-layer.is-wipe-forward {
    right:
      var(--media-lightbox-side-gutter);

    left: auto;

    -webkit-mask-image:
      linear-gradient(
        90deg,
        transparent 0,
        rgba(0, 0, 0, 0.18) 12px,
        rgba(0, 0, 0, 0.72) 30px,
        #000 52px,
        #000 100%
      );

    mask-image:
      linear-gradient(
        90deg,
        transparent 0,
        rgba(0, 0, 0, 0.18) 12px,
        rgba(0, 0, 0, 0.72) 30px,
        #000 52px,
        #000 100%
      );
  }


  .media-lightbox-wipe-layer.is-wipe-forward
  .media-lightbox-wipe-canvas {
    right: 0;
    left: auto;
  }


  /*
    PREVIOUS / finger swipes right:
    reveal the incoming screenshot inward from the LEFT edge.
  */
  .media-lightbox-wipe-layer.is-wipe-backward {
    left:
      var(--media-lightbox-side-gutter);

    right: auto;

    -webkit-mask-image:
      linear-gradient(
        90deg,
        #000 0,
        #000 calc(100% - 52px),
        rgba(0, 0, 0, 0.72) calc(100% - 30px),
        rgba(0, 0, 0, 0.18) calc(100% - 12px),
        transparent 100%
      );

    mask-image:
      linear-gradient(
        90deg,
        #000 0,
        #000 calc(100% - 52px),
        rgba(0, 0, 0, 0.72) calc(100% - 30px),
        rgba(0, 0, 0, 0.18) calc(100% - 12px),
        transparent 100%
      );
  }


  .media-lightbox-wipe-layer.is-wipe-backward
  .media-lightbox-wipe-canvas {
    left: 0;
    right: auto;
  }


  .media-lightbox-wipe-layer.is-wipe-running {
    animation:
      media-lightbox-layer-reveal
      380ms
      cubic-bezier(0.22, 0.72, 0.24, 1)
      both;
  }


  @keyframes media-lightbox-layer-reveal {
    from {
      width: 0;
    }

    to {
      width:
        calc(
          100vw -
          (var(--media-lightbox-side-gutter) * 2)
        );
    }
  }
}


/* =========================================================
   GAME INFO ACTIONS — LIVE EXTERNAL LINKS + RESPONSIVE LABELS
   =========================================================
   Etherian / Halodoom actions are now real <a> elements. Desktop uses the
   explicit "Download on ..." wording, while tablet/mobile use the shorter
   "View on ..." label requested for the tighter layouts.
   ========================================================= */

.game-info-action[href] {
  text-decoration: none;
  cursor: pointer;
}

.game-info-action[href]:visited {
  color: inherit;
}

.game-info-action-label {
  min-width: 0;
}

.game-info-action-label--desktop {
  display: none;
}

.game-info-action-label--compact {
  display: inline;
}

@media (min-width: 1401px) {
  .game-info-action-label--desktop {
    display: inline;
  }

  .game-info-action-label--compact {
    display: none;
  }
}


/* =========================================================
   ABOUT — INTERNAL PAGE JUMP LINK
   =========================================================
   "Latest Release — Halodoom" behaves like the normal Halodoom nav button
   while retaining the visual treatment of the About facts.
   ========================================================= */

.simple-page-fact-link {
  color: inherit;
  text-decoration: none;

  cursor: pointer;

  transition:
    color 160ms ease,
    text-shadow 160ms ease;
}

.simple-page-fact-link:hover,
.simple-page-fact-link:focus-visible {
  color:
    rgb(
      var(--accent-halodoom-rgb)
    );

  text-shadow:
    0 0 8px
    rgba(
      var(--accent-halodoom-rgb),
      0.28
    );
}

.simple-page-fact-link:focus-visible {
  outline:
    1px solid
    rgba(
      var(--accent-halodoom-rgb),
      0.62
    );

  outline-offset: 3px;
}


/* =========================================================
   DESKTOP GAME INFO BUTTONS — HOVER / FOCUS RESPONSE
   =========================================================
   Give the live Etherian / Halodoom CTA links the same kind of responsive
   accent treatment as the main header buttons, while leaving tablet/mobile
   touch presentation untouched.
   ========================================================= */

@media (min-width: 1401px) {

  .prototype-page-frame[data-game-frame-page]
  .game-info-action[href] {
    transition:
      background-color 160ms ease,
      border-color 160ms ease,
      box-shadow 160ms ease,
      color 160ms ease,
      transform 160ms ease;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-info-action[href]:hover,

  .prototype-page-frame[data-game-frame-page]
  .game-info-action[href]:focus-visible {
    border-color:
      rgba(
        var(--page-accent-rgb),
        0.82
      );

    background:
      color-mix(
        in srgb,
        rgb(var(--page-accent-rgb)) 24%,
        rgba(15, 21, 25, 0.42)
      );

    box-shadow:
      inset 0 0 0 1px
      rgba(
        var(--page-accent-rgb),
        0.18
      ),
      0 0 16px
      rgba(
        var(--page-accent-rgb),
        0.12
      );

    color:
      rgba(
        255,
        255,
        255,
        0.98
      );

    transform:
      translateY(-1px);
  }


  .prototype-page-frame[data-game-frame-page]
  .game-info-action[href]:focus-visible {
    outline:
      2px solid
      rgba(
        var(--page-accent-rgb),
        0.70
      );

    outline-offset: 2px;
  }
}


/* =========================================================
   DESKTOP GAME INFO BUTTONS — MATCH CONTACT CARD HOVER
   =========================================================
   Refine the previous CTA hover pass so these use the same interaction
   language as the Contact-page cards: stronger accent border, diagonal
   accent-to-dark glass fill, subtle inner highlight/glow, 1px lift, and
   a small arrow nudge to the right.
   ========================================================= */

@media (min-width: 1401px) {

  .prototype-page-frame[data-game-frame-page]
  .game-info-action[href] {
    transition:
      background-color 160ms ease,
      border-color 160ms ease,
      transform 160ms ease,
      box-shadow 160ms ease;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-info-action[href] > span[aria-hidden="true"] {
    transform: translateX(0);

    transition:
      transform 160ms ease;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-info-action[href]:hover,

  .prototype-page-frame[data-game-frame-page]
  .game-info-action[href]:focus-visible {
    outline: none;

    border-color:
      rgba(
        var(--page-accent-rgb),
        0.68
      );

    background:
      linear-gradient(
        135deg,
        rgba(
          var(--page-accent-rgb),
          0.27
        ),
        rgba(14, 18, 23, 0.58)
      );

    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.12),
      0 0 18px
      rgba(
        var(--page-accent-rgb),
        0.11
      );

    transform:
      translateY(-1px);
  }


  .prototype-page-frame[data-game-frame-page]
  .game-info-action[href]:hover
  > span[aria-hidden="true"],

  .prototype-page-frame[data-game-frame-page]
  .game-info-action[href]:focus-visible
  > span[aria-hidden="true"] {
    transform:
      translateX(3px);
  }
}


/* =========================================================
   DESKTOP GAME INFO BUTTONS — CONTACT CARD HOVER, EXACT PASS
   =========================================================
   Match the Contact-page card interaction directly, but use each game's
   own --page-accent-rgb. Also override the older cursor: default rule so
   these live links show the normal pointer hand.
   ========================================================= */

@media (min-width: 1401px) {

  .prototype-page-frame[data-game-frame-page]
  .game-info-action[href] {
    cursor: pointer !important;
  }


  .prototype-page-frame[data-game-frame-page]
  .game-info-action[href]:hover,

  .prototype-page-frame[data-game-frame-page]
  .game-info-action[href]:focus-visible {
    background:
      linear-gradient(
        135deg,
        rgba(
          var(--page-accent-rgb),
          0.27
        ),
        rgba(
          255,
          255,
          255,
          0.18
        )
      ) !important;

    border-color:
      rgba(
        var(--page-accent-rgb),
        0.68
      ) !important;

    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.12),
      0 0 18px
      rgba(
        var(--page-accent-rgb),
        0.11
      ) !important;

    transform:
      translateY(-1px);
  }
}


/* =========================================================
   DESKTOP SECONDARY INFO BUTTONS — DARK-TO-WHITE HOVER
   =========================================================
   "Watch Trailer" starts from the quieter dark glass treatment, so keep
   that dark tone as the first side of its hover gradient rather than
   introducing the page accent color. The primary store/download button
   keeps the page-color -> white hover from the previous pass.
   ========================================================= */

@media (min-width: 1401px) {

  .prototype-page-frame[data-game-frame-page]
  .game-info-action--secondary[href]:hover,

  .prototype-page-frame[data-game-frame-page]
  .game-info-action--secondary[href]:focus-visible {
    background:
      linear-gradient(
        135deg,
        rgba(15, 21, 25, 0.42),
        rgba(
          255,
          255,
          255,
          0.18
        )
      ) !important;
  }
}


/* =========================================================
   INFO TEXT — BASIC DROP SHADOW
   =========================================================
   Apply a small, readable shadow to the text content on About, Contact,
   and all game info panels without affecting frame art, media, or icons.
   ========================================================= */

.simple-glass-content,
.prototype-page-frame[data-game-frame-page] .game-info-surface {
  text-shadow:
    0 2px 4px
    rgba(0, 0, 0, 0.72),
    0 0 2px
    rgba(0, 0, 0, 0.48);
}


/*
  A few nested elements define their own text rendering or are icon-like;
  keep the shadow on actual textual content while avoiding unnecessary
  glow on raster/SVG imagery.
*/
.simple-glass-content img,
.simple-glass-content svg,
.prototype-page-frame[data-game-frame-page] .game-info-surface img,
.prototype-page-frame[data-game-frame-page] .game-info-surface svg {
  text-shadow: none;
}


/* =========================================================
   RESPONSIVE NAV MODE — AUTHORITATIVE FINAL HANDOFF
   =========================================================
   Phones use the hamburger at <=750px.
   Tablet/compact desktop use the five icon buttons at >=751px.
   These final rules intentionally own visibility so older header rules
   cannot accidentally keep the hamburger active in tablet widths.
   ========================================================= */

@media (max-width: 750px) {
  .main-nav {
    opacity: 0 !important;
    pointer-events: none !important;
  }

  .menu-toggle {
    opacity: 1 !important;
    pointer-events: auto !important;
  }
}

@media (min-width: 751px) {
  .main-nav {
    opacity: 1 !important;
    pointer-events: auto !important;
  }

  .menu-toggle {
    opacity: 0 !important;
    pointer-events: none !important;
  }

  .mobile-menu {
    display: none !important;
  }
}


/* =========================================================
   STARTUP PRELOADER
   =========================================================
   Covers the site while critical UI/frame artwork is warming the browser
   cache. The main page initializes normally underneath it, so removing the
   loader does not introduce another responsive/layout handoff.
   ========================================================= */

.site-preloader {
  position: fixed;
  inset: 0;

  z-index: 10000;

  display: grid;
  place-items: center;

  padding:
    clamp(24px, 6vw, 72px);

  background:
    radial-gradient(
      circle at 50% 42%,
      rgba(71, 72, 71, 0.72),
      rgba(20, 21, 21, 0.96) 58%,
      rgba(8, 9, 9, 1) 100%
    );

  opacity: 1;
  visibility: visible;

  pointer-events: auto;

  transition:
    opacity 420ms ease,
    visibility 0s linear 420ms;
}


.site-preloader.is-preloader-leaving {
  opacity: 0;
  visibility: hidden;

  pointer-events: none;
}


.site-preloader-inner {
  width:
    min(
      82vw,
      420px
    );

  display: grid;

  grid-template-columns:
    1fr
    auto;

  align-items: end;

  gap:
    8px
    12px;
}


.site-preloader-logo {
  grid-column: 1 / -1;

  display: block;

  width:
    min(
      76%,
      310px
    );

  height: auto;

  margin:
    0
    auto
    clamp(14px, 3vh, 28px);

  object-fit: contain;

  filter:
    drop-shadow(
      0 5px 14px
      rgba(0, 0, 0, 0.52)
    );
}


.site-preloader-label {
  grid-column: 1 / -1;

  color:
    rgba(240, 240, 240, 0.82);

  font-family:
    "Michroma",
    system-ui,
    sans-serif;

  font-size:
    clamp(8px, 1.55vw, 11px);

  letter-spacing:
    0.28em;

  text-align: center;
}


.site-preloader-track {
  grid-column: 1 / -1;

  position: relative;

  height:
    clamp(4px, 0.7vw, 6px);

  overflow: hidden;

  border:
    1px solid
    rgba(240, 240, 240, 0.17);

  background:
    rgba(240, 240, 240, 0.055);

  box-shadow:
    inset 0 0 8px
    rgba(0, 0, 0, 0.44);

  clip-path:
    polygon(
      8px 0,
      100% 0,
      calc(100% - 8px) 100%,
      0 100%
    );
}


.site-preloader-fill {
  width:
    var(--site-preloader-progress, 0%);

  height: 100%;

  background:
    linear-gradient(
      90deg,
      rgba(255, 114, 2, 0.56),
      rgba(255, 114, 2, 1),
      rgba(255, 255, 255, 0.82)
    );

  box-shadow:
    0 0 12px
    rgba(255, 114, 2, 0.38);

  transition:
    width 140ms ease-out;
}


.site-preloader-meta {
  grid-column: 1 / -1;

  display: flex;

  justify-content: space-between;
  align-items: center;

  gap: 16px;

  color:
    rgba(240, 240, 240, 0.58);

  font-family:
    "Michroma",
    system-ui,
    sans-serif;

  font-size:
    clamp(7px, 1.25vw, 9px);

  letter-spacing:
    0.10em;
}


.site-preloader-percent {
  color:
    rgba(255, 114, 2, 0.90);

  min-width: 4ch;

  text-align: right;
}


/*
  On especially small phones, keep the loader compact and entirely inside
  the same minimum-width assumptions as the rest of the site.
*/
@media (max-width: 485px) {
  .site-preloader-inner {
    width:
      min(
        82vw,
        330px
      );
  }

  .site-preloader-logo {
    width: 72%;
  }
}


/* =========================================================
   VIEWPORT SIDE CHEVRONS — PASSIVE PAGE PROGRESS INDICATOR
   =========================================================
   The two existing side-center frame ornaments now double as a visual
   "scroll position" marker. They remain decorative / non-interactive;
   JS only updates --viewport-page-progress-y when page intent changes.

   About    -> 18%
   Brobots  -> 34%
   Etherian -> 50%
   Halodoom -> 66%
   Contact  -> 82%
   ========================================================= */

.viewport-frame {
  --viewport-page-progress-y: 18%;
}


.viewport-frame-piece--left-center,
.viewport-frame-piece--right-center {
  top:
    var(
      --viewport-page-progress-y,
      50%
    );

  /*
    The global structural-frame rule intentionally disables transitions on
    .viewport-frame-piece with !important. These two ornaments are the one
    exception now that they act as the passive page-position indicator.
  */
  transition:
    top
    420ms
    cubic-bezier(
      0.20,
      0.72,
      0.22,
      1
    ) !important;
}


/*
  Respect reduced-motion without changing the indicator's final position.
*/
@media (prefers-reduced-motion: reduce) {
  .viewport-frame-piece--left-center,
  .viewport-frame-piece--right-center {
    transition: none !important;
  }
}


/* =========================================================
   LIVE GAME ACTIONS — CLEAN CLIPPED EDGES
   =========================================================
   Native CSS borders do not follow the chamfered clip-path diagonals, which
   leaves the store / trailer buttons looking like their outline is missing
   pieces. The live CTAs read more cleanly without that partial perimeter.
   Keep their fills, hover gradients, lift and glow behavior unchanged.
   ========================================================= */

.prototype-page-frame[data-game-frame-page]
.game-info-action[href] {
  border: 0 !important;
}


.prototype-page-frame[data-game-frame-page]
.game-info-action[href]:hover,

.prototype-page-frame[data-game-frame-page]
.game-info-action[href]:focus-visible {
  border: 0 !important;
}


/* =========================================================
   BROBOTS STATUS BLOCKS — ROUNDED RECTANGLES
   =========================================================
   These are informational status blocks rather than live links. Keep the
   real Etherian / Halodoom CTAs in their existing chamfered style, and only
   simplify the two Brobots placeholders.
   ========================================================= */

#brobots-page-frame
.game-info-action:not([href]) {
  clip-path: none !important;

  border: 0 !important;

  border-radius:
    clamp(
      8px,
      0.7cqw,
      12px
    ) !important;

  overflow: hidden;
}


/* =========================================================
   GAME INFO ACTIONS — UNIVERSAL ROUNDED RECTANGLE TREATMENT
   =========================================================
   Apply the same rounded-rectangle silhouette to all game info action
   blocks and links:
   - Brobots placeholders
   - Etherian store/trailer buttons
   - Halodoom store/trailer buttons

   Keep the existing fills, hover gradients, lift, glow, and text treatment.
   ========================================================= */

.prototype-page-frame[data-game-frame-page]
.game-info-action {
  clip-path: none !important;
  border: 0 !important;
  border-radius:
    clamp(
      8px,
      0.7cqw,
      12px
    ) !important;
  overflow: hidden;
}

.prototype-page-frame[data-game-frame-page]
.game-info-action:hover,

.prototype-page-frame[data-game-frame-page]
.game-info-action:focus-visible {
  border: 0 !important;
  border-radius:
    clamp(
      8px,
      0.7cqw,
      12px
    ) !important;
}

