/*
 * The Monster skin: `skin: monster` in a note's frontmatter.
 * lib/skins.ts, components/skins/MonsterSkin.tsx, docs/DECISIONS.md #234.
 *
 * ONE NOTE'S OWN LOOK, and the site's design rules stop at its edge on
 * purpose: red, a second typeface, full-bleed pictures, motion everywhere.
 * The owner asked for exactly that, for this page.
 *
 * What keeps it from leaking:
 * - This file is in `public/`, not imported: only a skinned page links it.
 * - EVERY selector names `[data-skin="monster"]`, and no keyframe shares a
 *   name with the site's (scripts/skins.test.mjs). A rule that could match
 *   another page is a failed test, not a surprise.
 * - It is plain CSS: no Tailwind, no PostCSS, served as written.
 *
 * THE LOOK IS A DARK ROOM. The page is black from top to bottom, and
 * everything on it is something lit: a screen, a photograph, a word. Nothing
 * meets anything else along a hard line, because nothing touches; each thing
 * falls off into the dark and the next one comes up out of it. Three colours:
 * black #030303, red #ff2a12, white #f6f1ee.
 *
 * The note stays ordinary Markdown, grouped by `<section class="mx-plate">`:
 *   .mx-plate                    words and pictures on the dark
 *   .mx-plate.mx-screen.mx-red   a lit red screen, black type
 *   .mx-plate.mx-screen.mx-white a lit white screen, red type
 *   .mx-plate.mx-end             sources and credits
 * Inside one, `##` is the headline, `>` a statement, a headerless two-column
 * table a stack of big figures, a list a roster, an image embed a picture. A
 * picture directly followed by a `##` or a `>` takes it in: the words stand
 * in the photograph (`.mx-frame`, composed by the driver). The ink of those
 * words follows the picture's file name: `…-bw.*` red, `…-red.*` white.
 *
 * Motion is opt-in twice over: the driver sets `data-mx="live"` only when it
 * is running and the reader has not asked for reduced motion, and everything
 * that waits to be revealed is hidden under that attribute alone. Without it
 * the page is the same room, standing still. What waits carries `.mx-hold`,
 * which the driver gives only to what is still below the window when it
 * starts, and trades for `.mx-in` when the thing is scrolled to.
 *
 * AN ENTRANCE FILLS `backwards`, NEVER `both` OR `forwards`. A finished
 * animation that still fills forwards keeps its element a surface of its own
 * on the graphics card, for good. Every paragraph, every word of every
 * headline and both copies of every photograph stayed one: 134 surfaces by
 * the foot of the page, 3.4 GB of them on a 5K screen against 1.7 on a
 * laptop's, which is where the page lagged and froze and the laptop did not.
 * Every entrance here ends on the element's own resting style, so letting go
 * at the end changes nothing that can be seen. Only what the scroll drives
 * and the opening (hidden once it has played) fill forwards
 * (scripts/skins.test.mjs).
 */

/* Sofia Sans Extra Condensed Black (SIL OFL 1.1, public/skins/OFL.txt). Two
   subsets, because every note is also in Ukrainian. */
@font-face {
  font-family: "MX Display";
  src: url("/skins/sofia-sans-xc-900-latin.woff2") format("woff2");
  font-weight: 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
    U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "MX Display";
  src: url("/skins/sofia-sans-xc-900-cyrillic.woff2") format("woff2");
  font-weight: 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

/* ------------------------------------------------------------------------
   The site around the note
   ------------------------------------------------------------------------ */

/* The site's own tokens, for as long as this page is open: the breadcrumb
   bar, the drawer, the palette and every other piece of chrome reads these,
   so they turn black and red with the page and turn back when it is left.
   One set for light and dark and for both colour families; the skin has no
   light mode. */
html:has(.page[data-skin="monster"]) {
  --bg: #030303;
  --bg-sidebar: #080808;
  --bg-hover: #26100c;
  --surface: #150a08;
  --text: #f6f1ee;
  --text-secondary: #cfc7c3;
  --text-tertiary: #8d827e;
  --text-caption: #b9afab;
  --border: #2e1713;
  --code-bg: #150a08;
  --chrome-bg: color-mix(in srgb, #130806 78%, transparent);
  --chrome-ring: color-mix(in srgb, #ff2a12 38%, transparent);
  color-scheme: dark;
  scrollbar-color: #7a1408 #030303;
  background: #030303;
}

/* The site's grain is colour noise at 3%. Turned up it would be confetti;
   the page below carries its own, in one tone. */
html:has(.page[data-skin="monster"]) body::after {
  display: none;
}

.page[data-skin="monster"] {
  --mx-black: #030303;
  --mx-red: #ff2a12;
  --mx-white: #f6f1ee;
  --mx-display: "MX Display", Impact, "Haettenschweiler", "Arial Narrow", sans-serif;
  --mx-sans: "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
  --mx-gutter: clamp(1.25rem, 4.5vw, 4rem);
  --mx-snap: cubic-bezier(0.16, 0.84, 0.24, 1);
  --mx-cut: cubic-bezier(0.7, 0, 0.12, 1);
  /* The smear on big type: the word again, fainter, a little above and a
     little below, the way it ghosts on a frame that was moving. NO BLUR in
     any of them, and that is the whole point. A blurred text-shadow on
     letters this size was measured as the one thing making the page slow:
     with it the scroll ran at about 40 frames a second with hitches of a
     third of a second, without it at 59 with none. An unblurred shadow is
     only the glyphs drawn once more. The glow itself is light BEHIND the
     word (a gradient, under Headlines below), never around each letter. */
  --mx-ghost:
    0 -0.014em 0 rgb(255 42 18 / 0.3), 0 0.014em 0 rgb(255 42 18 / 0.3), 0 -0.03em 0 rgb(255 42 18 / 0.2),
    0 0.03em 0 rgb(255 42 18 / 0.2), 0 -0.05em 0 rgb(255 42 18 / 0.12), 0 0.05em 0 rgb(255 42 18 / 0.12),
    0 -0.074em 0 rgb(255 42 18 / 0.07), 0 0.074em 0 rgb(255 42 18 / 0.07);
  /* How long the opening holds the page back; set from the beat count below. */
  --mx-wait: 0s;

  position: relative;
  max-width: none;
  padding: 0;
  overflow-x: clip;
  background: var(--mx-black);
  color: var(--mx-white);
  font-family: var(--mx-sans);
}

.page[data-skin="monster"] ::selection {
  background: var(--mx-red);
  color: var(--mx-black);
}

.page[data-skin="monster"] .mx-red ::selection {
  background: var(--mx-black);
  color: var(--mx-red);
}

/* The site fades every page in on `<main>`, and that fade fills forwards, so
   `<main>` stays a surface of its own for good. Here it would be a second
   sheet the height of the whole note under everything else, and the opening
   already covers the arrival. */
main:has(> .page[data-skin="monster"]) {
  animation: none;
}

/* The reading bar is the one line of the site's chrome that lives inside the
   page, so it is painted here. */
.page[data-skin="monster"] .reading-progress-fill,
.page[data-skin="monster"] .reading-progress-head {
  background: var(--mx-red);
  box-shadow: 0 0 10px 1px rgb(255 42 18 / 0.7);
}

/* The contents rail is placed against a 39rem column that this page does not
   have. The pill takes over at every width instead. */
.page[data-skin="monster"] .toc-rail {
  display: none;
}

@media (min-width: 1168px) {
  .page[data-skin="monster"] .toc-bar {
    display: flex;
  }

  .page[data-skin="monster"] .toc-sheet,
  .page[data-skin="monster"] .toc-sheet-backdrop {
    display: block;
  }
}

/* ------------------------------------------------------------------------
   The opening
   ------------------------------------------------------------------------ */

/* One word, one screen: red, then white, then the dark. Each is a lit
   rectangle with its light falling off toward the corners, never a flat
   field to the edge of the glass. Then the last word is pulled out into
   vertical streaks and the whole thing lets go. */
.page[data-skin="monster"] .mx-intro {
  --mx-beat: 0.44s;
  position: fixed;
  inset: 0;
  z-index: 45;
  pointer-events: none;
  background: var(--mx-black);
  animation:
    mx-out 0.5s ease-out calc(var(--mx-wait) - 0.42s) forwards,
    mx-gone 0.01s linear calc(var(--mx-wait) + 0.1s) forwards;
}

@keyframes mx-out {
  to {
    opacity: 0;
  }
}

/* Both ends hidden, so the fill holds whatever the last frame rounds to: a
   lone `to` is only reached at progress 1, and a delay made of `calc()` can
   finish at 0.99999999. */
@keyframes mx-gone {
  from,
  to {
    visibility: hidden;
  }
}

.page[data-skin="monster"] .mx-beat {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  overflow: hidden;
  background: radial-gradient(ellipse 62% 58% at 50% 50%, #2b0502 0, #0a0100 55%, var(--mx-black) 100%);
  color: var(--mx-red);
  opacity: 0;
  animation: mx-beat-on 0.01s linear calc(var(--i) * var(--mx-beat)) forwards;
}

.page[data-skin="monster"] .mx-beat:nth-last-child(2) {
  background: radial-gradient(ellipse 74% 70% at 50% 50%, #fff 0, #f3e9e5 38%, #b98f86 70%, #3d0a04 92%, #0a0100 100%);
}

.page[data-skin="monster"] .mx-beat:nth-last-child(3) {
  background: radial-gradient(ellipse 74% 70% at 50% 50%, #ff3a1e 0, #ee230d 40%, #8c0c02 76%, #1c0200 96%);
  color: var(--mx-black);
}

.page[data-skin="monster"] .mx-beat:nth-last-child(4) {
  color: var(--mx-white);
}

@keyframes mx-beat-on {
  to {
    opacity: 1;
  }
}

.page[data-skin="monster"] .mx-beat b {
  font: 900 min(44vw, 74vh) / 0.8 var(--mx-display);
  text-transform: uppercase;
  white-space: nowrap;
}

/* The word lands on the inner element and the last word is pulled out on
   the outer one. Two transform animations on ONE element cannot run on the
   compositor; they ran on the main thread, and a word the height of the
   window was drawn again, sharp, at every size on its way to twenty times
   its height. */
.page[data-skin="monster"] .mx-beat b > span {
  display: inline-block;
  animation: mx-beat-word 0.44s var(--mx-snap) calc(var(--i) * var(--mx-beat)) both;
}

.page[data-skin="monster"] .mx-beat:last-child b {
  text-shadow: var(--mx-ghost);
  animation: mx-streak-out 0.5s var(--mx-cut) calc(var(--mx-wait) - 0.5s) forwards;
}

/* Lands stretched and smeared, the way a word looks on the frame it arrives. */
@keyframes mx-beat-word {
  0% {
    transform: scale(0.9, 3.4);
  }
  38% {
    transform: scale(1.02, 0.95);
  }
  100% {
    transform: scale(1.06, 1.03);
  }
}

/* A scale and nothing else: the compositor stretches the word it already
   has, and a texture stretched twenty times IS the smear. On top of where
   the word landed (1.06 by 1.03, on the element inside), which is why this
   stops a little short of 1.5 by 22. */
@keyframes mx-streak-out {
  to {
    transform: scale(1.415, 21.36);
    opacity: 0;
  }
}

/* How long the page waits behind the opening: the beats, then the pull. */
.page[data-skin="monster"]:has(.mx-intro[data-n="1"]) {
  --mx-wait: 1.04s;
}

.page[data-skin="monster"]:has(.mx-intro[data-n="2"]) {
  --mx-wait: 1.48s;
}

.page[data-skin="monster"]:has(.mx-intro[data-n="3"]) {
  --mx-wait: 1.92s;
}

.page[data-skin="monster"]:has(.mx-intro[data-n="4"]) {
  --mx-wait: 2.36s;
}

/* ------------------------------------------------------------------------
   The hero: smoke, the title, the can in front of it
   ------------------------------------------------------------------------ */

.page[data-skin="monster"] .mx-hero,
.page[data-skin="monster"] .mx-can {
  position: absolute;
  inset: 0 0 auto;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
}

/* THE HERO IS DRAWN ONCE, BEHIND THE OPENING, AND THEN ONLY MOVED. Nothing in
   it makes an entrance: the title, the can and the line under them are all
   standing there when the dark lifts. The title used to slam in half a
   second after the can, stretched to three times its height, and the can
   came forward from 1.3 times its size; the owner saw a can with no words,
   then tall dim words, each held for a moment, and asked for the title to
   simply be there. An entrance is also a thing drawn again at every size it
   passes through and once more when it lets go.

   Three things move when the hero is LEFT, each ONE layer with nothing but a
   transform and an opacity on it:

   - the smoke's corners and floor are in its shader, not a sheet over it,
     and the scroll moves the canvas, not the box round it;
   - the can's shadow, mask and light are on `.mx-lit`, a box that stands
     still INSIDE the one the scroll moves;
   - the title has no animation of its own; the flicker is on the block
     round it.

   A filter, a mask or a blend on the moving thing itself is worked out
   again by the graphics card for every frame of the move, and two layers
   under one fading parent are first drawn to a target the size of the
   window. An element with two animations on one property gets neither on
   the compositor: it is re-drawn from scratch, every frame, at whatever
   size it has reached. scripts/skins.test.mjs holds the one-animation rule
   and the hero's stillness. */
.page[data-skin="monster"] .mx-hero {
  z-index: 0;
  /* The smoke sinks out of this box as the hero is left; nothing clips it. */
  overflow: visible;
  background: var(--mx-black);
}

.page[data-skin="monster"] .mx-smoke {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* THE CAN IS IN FRONT OF THE TITLE. It is a cut-out with an alpha channel
   (scripts/skin-grade.mjs --key white), in a layer of its own above the
   header, so the words pass behind it the way a figure walks in front of a
   title in a film. */
.page[data-skin="monster"] .mx-can {
  z-index: 2;
  pointer-events: none;
}

/* The stand is the can's own box, at the can's own shape (`--mx-ar`, set by
   the driver from the file's size), so a second layer can be laid exactly
   over it. */
.page[data-skin="monster"] .mx-stand {
  position: absolute;
  top: 50%;
  left: 50%;
  height: min(92vh, 190vw);
  aspect-ratio: var(--mx-ar, 0.45);
  translate: -50% -50%;
}

/* What the can wears, on a box of its own inside the stand (see "The hero is
   drawn once" above). */
.page[data-skin="monster"] .mx-lit {
  position: absolute;
  inset: 0;
  /* The shadow is what puts the can in front of the letters. One, and tight:
     a second, wide one for the glow cost more than everything else in the
     hero put together, and the smoke behind already does that job. */
  filter: drop-shadow(0 0 0.9vw rgb(0 0 0 / 0.9));
  /* Top and foot go into the dark: the room has no floor and no ceiling. */
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 17%, #000 58%, transparent 95%);
  mask-image: linear-gradient(to bottom, transparent 0, #000 17%, #000 58%, transparent 95%);
}

.page[data-skin="monster"] .mx-art {
  display: block;
  width: 100%;
  max-width: none;
  height: 100%;
}

/* The room's light on it: full in the middle, falling to dark red round the
   sides the way a cylinder does, cut to the can's own outline so none of it
   lands on the air. A product picture is lit evenly from everywhere, which
   is exactly what a thing standing in a dark room is not. */
.page[data-skin="monster"] .mx-lit::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(
      90deg,
      rgb(34 0 0 / 0.9) 0,
      rgb(110 14 6 / 0.42) 13%,
      transparent 34%,
      transparent 64%,
      rgb(110 14 6 / 0.48) 86%,
      rgb(34 0 0 / 0.92) 100%
    ),
    linear-gradient(to bottom, rgb(20 0 0 / 0.55) 0, transparent 26%, transparent 60%, rgb(12 0 0 / 0.8) 92%);
  mix-blend-mode: multiply;
  /* `--mx-art` is the file the browser chose for the can, named by the driver
     once it has loaded. Until then the mask is empty and there is no light,
     which is the can as photographed; without the fallback there would be no
     mask at all, and the light would be a dark rectangle round the can. */
  -webkit-mask: var(--mx-art, linear-gradient(transparent, transparent)) center / 100% 100% no-repeat;
  mask: var(--mx-art, linear-gradient(transparent, transparent)) center / 100% 100% no-repeat;
}

.page[data-skin="monster"] > header {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 100vh;
  min-height: 100svh;
  padding: 6rem var(--mx-gutter) clamp(2.25rem, 7vh, 4.5rem);
}

/* On a phone the can is most of the window, so the title stands in front of
   it, at its foot. */
.page[data-skin="monster"] .page-title {
  position: relative;
  z-index: 3;
  margin: 0;
  font: 900 clamp(5rem, 27vw, 13rem) / 0.78 var(--mx-display);
  letter-spacing: -0.012em;
  text-transform: uppercase;
  /* Each word its own line, without touching the markup React owns. */
  word-spacing: 100vw;
  color: var(--mx-red);
  /* Out of focus and lit, as the owner drew it. The letters have no ink of
     their own: what shows is their shadows, so the edge itself is soft. On
     top the word twice over (once is thin at the rim), under it a dim smear
     straight up and straight down, and a halo. Nothing is slipped sideways:
     a darker copy to the right read as letters cut in 3D, and the owner
     turned it down. These are BLURRED shadows, the one place on the page
     that has them (see `--mx-ghost`): the title makes no entrance and has no
     animation of its own, so it is drawn once and after that only moved. It
     was an SVG filter before that, drawn off the graphics card and the first
     thing to go missing. */
  color: transparent;
  text-shadow:
    0 0 0.012em #ff3a1c,
    0 0 0.012em #ff3a1c,
    0 0.05em 0.035em rgb(190 20 8 / 0.42),
    0 -0.05em 0.035em rgb(190 20 8 / 0.3),
    0 0.11em 0.06em rgb(150 12 4 / 0.22),
    0 -0.1em 0.06em rgb(150 12 4 / 0.14),
    0 0 0.07em rgb(255 42 18 / 0.28);
}

/* The lamp's flicker is on the block round the title, not on the title, so
   the title and the line under it dip together and the header that fades
   out as the hero is left holds one layer. */
.page[data-skin="monster"] .note-header-text {
  animation: mx-flicker 9s linear calc(var(--mx-wait) + 2s) infinite;
}

@media (max-width: 599px), (max-aspect-ratio: 1/1) {
  .page[data-skin="monster"] > header {
    z-index: 3;
  }
}

/* A lamp that never quite settles: two short dips in nine seconds. */
@keyframes mx-flicker {
  0%,
  41%,
  43.5%,
  45%,
  82%,
  83.2%,
  100% {
    opacity: 1;
  }
  42%,
  44.2% {
    opacity: 0.62;
  }
  82.6% {
    opacity: 0.78;
  }
}

/* "Copy as Markdown" hangs off the title's left edge on hover. At this size
   it would hang off the window; ⌘K still offers it. */
.page[data-skin="monster"] .page-title .copy-md {
  display: none;
}

.page[data-skin="monster"] .entry-meta {
  position: relative;
  z-index: 3;
  margin-top: 1.25rem;
  font: 600 0.8125rem / 1.4 var(--mx-sans);
  letter-spacing: -0.01em;
  color: rgb(246 241 238 / 0.62);
}

@keyframes mx-rise {
  from {
    opacity: 0;
    transform: translateY(1rem);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* With room to work in, the title is ONE line across the whole window, drawn
   tall, and the can stands in the gap between its two words with a letter
   tucked behind each shoulder. Below the rules it overrides: a media query
   adds no specificity.

   The numbers are this title's. "MONSTER" sets 3.07em wide and "ENERGY"
   2.62em, so at 13vw with a 20.8vw gap the line is 94.8vw and the middle of
   the gap falls at 53% of the window, which is where the can stands; and the
   can is never wider than 23.6vw, so it covers the gap and the edge of one
   letter either side and no more. */
@media (min-width: 600px) and (min-aspect-ratio: 1/1) {
  .page[data-skin="monster"] > header {
    justify-content: center;
    align-items: center;
    padding: 0;
  }

  /* The block round the title fills the header and centres the title
     itself, so that the date line, which is placed against a corner of the
     window, is placed against THIS box. Placed against the header, it sat
     outside the block that flickers, on a layer of its own, and a block that
     fades with two layers in it is first drawn to a target of its own on
     every frame. */
  .page[data-skin="monster"] .note-header-text {
    position: relative;
    display: flex;
    flex: 1;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    align-self: stretch;
  }

  .page[data-skin="monster"] .page-title {
    font-size: 13vw;
    line-height: 1;
    white-space: nowrap;
    /* The gap, less the space character that is already there. */
    word-spacing: 18.2vw;
    scale: 1 1.75;
    transform-origin: 50% 58%;
  }

  .page[data-skin="monster"] .mx-stand {
    top: 52%;
    left: 52.4%;
    height: min(86vh, 52.5vw);
  }

  .page[data-skin="monster"] .entry-meta {
    position: absolute;
    left: var(--mx-gutter);
    bottom: clamp(1.5rem, 5vh, 3rem);
    margin: 0;
  }
}

/* Leaving the hero, each layer goes at its own speed: the smoke sinks, the
   can comes toward you, the title falls behind. */
@supports (animation-timeline: scroll()) {
  .page[data-skin="monster"][data-mx="live"] .mx-smoke {
    animation: mx-sink linear both;
    animation-timeline: scroll(root);
    animation-range: 0 100vh;
  }

  .page[data-skin="monster"][data-mx="live"] .mx-can {
    animation: mx-near linear both;
    animation-timeline: scroll(root);
    animation-range: 0 100vh;
  }

  .page[data-skin="monster"][data-mx="live"] > header {
    animation: mx-far linear both;
    animation-timeline: scroll(root);
    animation-range: 0 70vh;
  }

  @keyframes mx-sink {
    to {
      transform: translateY(26vh);
      opacity: 0;
    }
  }

  @keyframes mx-near {
    to {
      transform: translateY(8vh) scale(1.16);
      opacity: 0;
    }
  }

  @keyframes mx-far {
    to {
      transform: translateY(10vh);
      opacity: 0;
    }
  }
}

/* ------------------------------------------------------------------------
   Over the whole window: scanlines, and the vignette
   ------------------------------------------------------------------------ */

.page[data-skin="monster"] .mx-fx {
  position: fixed;
  inset: 0;
  z-index: 25;
  overflow: hidden;
  pointer-events: none;
  background:
    repeating-linear-gradient(to bottom, rgb(0 0 0 / 0.1) 0 1px, transparent 1px 3px),
    radial-gradient(ellipse 118% 104% at 50% 50%, transparent 46%, rgb(0 0 0 / 0.42) 78%, rgb(0 0 0 / 0.86) 100%);
}

/* Film grain, one tone, over the window. A sheet a little bigger than the
   glass, shifted in steps: only a transform changes, so the compositor moves
   a picture it already has and nothing is ever repainted. (It was first a
   layer the whole height of the page with an animated background-position,
   which repainted fifteen thousand pixels of it eight times a second.) */
.page[data-skin="monster"] .mx-fx::after {
  content: "";
  position: absolute;
  inset: -120px;
  opacity: 0.17;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='g' x='0' y='0' width='100%25' height='100%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.92' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 2.6 -1.05'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23g)'/%3E%3C/svg%3E");
}

.page[data-skin="monster"][data-mx="live"] .mx-fx::after {
  animation: mx-grain 0.7s steps(1) infinite;
}

@keyframes mx-grain {
  0% {
    transform: none;
  }
  17% {
    transform: translate(-61px, 37px);
  }
  33% {
    transform: translate(83px, -19px);
  }
  50% {
    transform: translate(-29px, -97px);
  }
  67% {
    transform: translate(41px, 71px);
  }
  83% {
    transform: translate(-103px, 13px);
  }
}

/* A phone is all edge: the same vignette there would sit on the text. */
@media (max-width: 699px) {
  .page[data-skin="monster"] .mx-fx {
    background:
      repeating-linear-gradient(to bottom, rgb(0 0 0 / 0.1) 0 1px, transparent 1px 3px),
      radial-gradient(ellipse 150% 100% at 50% 50%, transparent 55%, rgb(0 0 0 / 0.7) 100%);
  }
}

/* ------------------------------------------------------------------------
   The note body
   ------------------------------------------------------------------------ */

.page[data-skin="monster"] .prose {
  position: relative;
  z-index: 3;
  margin-top: 0;
  font-size: clamp(1.125rem, 0.95rem + 0.62vw, 1.5rem);
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: -0.014em;
  color: inherit;
}

/* A plate: a stretch of the dark with things in it. The column is a grid so
   that a headline, a picture and a paragraph can each take a different width
   without a wrapper apiece. */
.page[data-skin="monster"] .mx-plate {
  --mx-ground: var(--mx-black);
  --mx-ink: var(--mx-white);
  --mx-hot: var(--mx-red);
  position: relative;
  display: grid;
  grid-template-columns:
    [full-start] minmax(var(--mx-gutter), 1fr)
    [wide-start] minmax(0, 37rem) [mid] minmax(0, 37rem)
    [wide-end] minmax(var(--mx-gutter), 1fr) [full-end];
  padding-block: clamp(4rem, 12vh, 9rem);
  color: var(--mx-ink);
  /* The site's text tokens, re-pointed at this plate. The page-wide set above
     is for a black page; left alone, every site rule that paints with
     `--text` (a table cell, a list marker) would draw white on a white
     screen. */
  --text: var(--mx-ink);
  --text-secondary: var(--mx-ink);
  --text-tertiary: color-mix(in srgb, var(--mx-ink) 62%, var(--mx-ground));
  --text-caption: var(--mx-ink);
  --border: color-mix(in srgb, var(--mx-ink) 30%, transparent);
}

.page[data-skin="monster"] .mx-plate > * {
  grid-column: wide;
  min-width: 0;
}

/* A plate that opens or closes on a picture gives up its own air there:
   the picture already fades into the dark, and two fades and two paddings
   in a row were a third of a screen of nothing. */
.page[data-skin="monster"] .mx-plate:has(> figure:first-child) {
  padding-top: 0;
}

.page[data-skin="monster"] .mx-plate:has(> figure:last-child) {
  padding-bottom: 0;
}

/* Running text keeps to the left half once there is a right half to leave
   dark. */
@media (min-width: 1100px) {
  .page[data-skin="monster"] .mx-plate > p {
    grid-column: wide-start / mid;
  }
}

/* ---- A lit screen ---- */

/* A rectangle of light in the room, held off the edges of the window, bright
   in the middle and going dark toward its own corners, with what it throws
   on the air around it. It never runs to the edge of the glass, so it never
   has an edge to be cut along. */
.page[data-skin="monster"] .mx-screen {
  margin: clamp(2.5rem, 9vh, 6rem) clamp(0.75rem, 3.2vw, 3.25rem);
  padding-block: clamp(4rem, 13vh, 9.5rem);
  border-radius: 6px;
}

.page[data-skin="monster"] .mx-red {
  --mx-ground: #e2200b;
  --mx-ink: #060000;
  --mx-hot: #060000;
  --mx-spill: rgb(255 42 18 / 0.34);
  background: radial-gradient(ellipse 86% 78% at 50% 44%, #ff3d21 0, #ee250e 36%, #b01103 68%, #4a0500 92%, #220200 100%);
}

.page[data-skin="monster"] .mx-white {
  --mx-ground: #efe6e2;
  --mx-ink: #0a0403;
  --mx-hot: var(--mx-red);
  --mx-spill: rgb(255 120 90 / 0.3);
  background: radial-gradient(ellipse 86% 78% at 50% 44%, #fff 0, #f6eeeb 38%, #d9c4be 68%, #7c4038 92%, #3d120c 100%);
}

/* What the screen throws on the room. A gradient, which costs nothing to
   draw; the same light as three stacked box-shadows with a 26vw blur was a
   texture several screens across for every screen on the page. */
.page[data-skin="monster"] .mx-screen {
  isolation: isolate;
}

.page[data-skin="monster"] .mx-screen::before {
  content: "";
  position: absolute;
  inset: -7vw -3vw;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(closest-side, var(--mx-spill), transparent);
}

/* Coming up, a screen is switched on, once. */
.page[data-skin="monster"][data-mx="live"] .mx-screen.mx-hold {
  opacity: 0.12;
}

.page[data-skin="monster"][data-mx="live"] .mx-screen.mx-in {
  animation: mx-switch-on 0.7s var(--mx-snap) backwards;
}

@keyframes mx-switch-on {
  0% {
    opacity: 0.12;
    transform: scale(0.965);
  }
  22% {
    opacity: 0.85;
  }
  34% {
    opacity: 0.4;
  }
  100% {
    opacity: 1;
    transform: none;
  }
}

/* ---- Headlines ---- */

.page[data-skin="monster"] .prose h2 {
  margin: 0 0 0.34em;
  font: 900 clamp(4.25rem, 17vw, 15.5rem) / 0.78 var(--mx-display);
  letter-spacing: -0.012em;
  text-transform: uppercase;
  text-wrap: balance;
  color: var(--mx-hot);
  text-shadow: var(--mx-ghost);
  scroll-margin-top: 6rem;
}

/* The light a headline gives off: a soft field BEHIND the whole word, drawn
   as a gradient. Around each letter it would be a blurred shadow, and see
   `--mx-ghost` for what that costs. */
.page[data-skin="monster"] .mx-plate:not(.mx-screen, .mx-end) > h2,
.page[data-skin="monster"] .mx-frame > :is(h2, blockquote) {
  isolation: isolate;
}

.page[data-skin="monster"] .mx-plate:not(.mx-screen, .mx-end) > h2::before,
.page[data-skin="monster"] .mx-frame > :is(h2, blockquote)::before {
  content: "";
  position: absolute;
  inset: -40% -6%;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(closest-side, rgb(255 34 10 / 0.2), rgb(255 34 10 / 0.06) 62%, transparent);
}

.page[data-skin="monster"] .mx-plate:not(.mx-screen, .mx-end) > h2 {
  position: relative;
}

/* On a lit screen the type is ink, and ink ghosts in its own colour. */
.page[data-skin="monster"] .mx-red h2 {
  text-shadow:
    0 -0.014em 0 rgb(6 0 0 / 0.3), 0 0.014em 0 rgb(6 0 0 / 0.3), 0 -0.03em 0 rgb(6 0 0 / 0.2),
    0 0.03em 0 rgb(6 0 0 / 0.2), 0 -0.05em 0 rgb(6 0 0 / 0.12), 0 0.05em 0 rgb(6 0 0 / 0.12),
    0 -0.074em 0 rgb(6 0 0 / 0.07), 0 0.074em 0 rgb(6 0 0 / 0.07);
}

/* The site clips a heading that stands directly over a headerless table (an
   "At a glance" over its facts). Here that heading is the plate's headline. */
.page[data-skin="monster"] .prose h2.fact-heading {
  position: static;
  width: auto;
  height: auto;
  overflow: visible;
  clip-path: none;
  white-space: normal;
}

.page[data-skin="monster"] .prose h2 .heading-anchor {
  display: none;
}

.page[data-skin="monster"] .mx-w,
.page[data-skin="monster"] .mx-w > span {
  display: inline-block;
}

.page[data-skin="monster"] .mx-w > span {
  transform-origin: 50% 100%;
}

.page[data-skin="monster"][data-mx="live"] .prose :is(h2, blockquote).mx-hold .mx-w > span {
  opacity: 0;
}

.page[data-skin="monster"][data-mx="live"] .prose :is(h2, blockquote).mx-in .mx-w > span {
  animation: mx-slam 0.62s var(--mx-snap) calc(var(--i) * 110ms) backwards;
}

@keyframes mx-slam {
  0% {
    opacity: 0;
    transform: translateY(0.3em) scaleY(3.4);
  }
  40% {
    opacity: 1;
    transform: translateY(-0.02em) scaleY(0.9);
  }
  100% {
    opacity: 1;
    transform: none;
  }
}

/* ---- Running text ---- */

.page[data-skin="monster"] .prose p {
  max-width: 34rem;
  margin: 0 0 1.1em;
  text-wrap: pretty;
}

.page[data-skin="monster"] .prose strong {
  font-weight: 800;
  color: var(--mx-red);
}

/* White on this red is 3:1, too thin for running text. On a red screen the
   emphasis is a black bar instead. */
.page[data-skin="monster"] .mx-red p strong {
  padding: 0.02em 0.28em 0.06em;
  background: #060000;
  color: var(--mx-white);
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

.page[data-skin="monster"] .prose a {
  color: inherit;
  font-weight: 700;
  text-decoration: underline;
  text-decoration-color: var(--mx-red);
  text-decoration-thickness: 2px;
  text-underline-offset: 0.18em;
}

.page[data-skin="monster"] .prose a:hover {
  color: var(--mx-red);
}

/* The first paragraph of the note is the lede: it speaks at title volume. */
.page[data-skin="monster"] .prose .mx-plate:first-child {
  padding-block: clamp(1rem, 4vh, 3rem) clamp(3rem, 9vh, 6rem);
}

.page[data-skin="monster"] .prose .mx-plate:first-child > p:first-child {
  grid-column: wide;
  max-width: 21ch;
  padding-left: 0;
  font-size: clamp(1.9rem, 1rem + 4vw, 4.75rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.04em;
  text-wrap: balance;
}

.page[data-skin="monster"][data-mx="live"] .prose :is(p, li).mx-hold {
  opacity: 0;
  transform: translateY(1.4rem);
}

.page[data-skin="monster"][data-mx="live"] .prose :is(p, li).mx-in {
  animation: mx-rise 0.75s var(--mx-snap) 0.08s backwards;
}

/* ---- Pictures ---- */

/* A picture is a window in the dark, not a block on the page: its top and
   foot dissolve and its corners go black. */
.page[data-skin="monster"] .prose figure {
  --mx-over: var(--mx-red);
  grid-column: full;
  position: relative;
  height: clamp(62vh, 64vw, 92vh);
  margin: clamp(1rem, 4vh, 2.5rem) 0;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 9%, #000 89%, transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0, #000 9%, #000 89%, transparent 100%);
}

/* The ink of the words set into a picture follows the picture's look, which
   is the last word of its file name (scripts/skin-grade.mjs). */
.page[data-skin="monster"] .prose figure:has(img[src*="-red."]) {
  --mx-over: var(--mx-white);
}

/* White words on a red picture want dark behind them, not more red: the
   picture is already as bright as they are. */
.page[data-skin="monster"] .prose figure:has(img[src*="-red."]) > :is(h2, blockquote)::before {
  background: radial-gradient(closest-side, rgb(3 3 3 / 0.72), rgb(3 3 3 / 0.34) 60%, transparent);
}

.page[data-skin="monster"] .prose figure:has(img[src*="-red."]) > h2,
.page[data-skin="monster"] .prose figure:has(img[src*="-red."]) > blockquote p {
  text-shadow: none;
}

.page[data-skin="monster"] .prose figure img,
.page[data-skin="monster"] .prose figure img:hover,
.page[data-skin="monster"] .mx-fore {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  margin: 0;
  border: 0;
  border-radius: 0;
  object-fit: cover;
  box-shadow: none;
  translate: none;
  background-size: cover;
  background-position: center;
}

/* The corners of the frame. */
.page[data-skin="monster"] .prose figure::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: radial-gradient(ellipse 80% 78% at 50% 50%, transparent 32%, rgb(3 3 3 / 0.62) 74%, rgb(3 3 3 / 0.95) 100%);
}

.page[data-skin="monster"] .prose figcaption {
  position: absolute;
  z-index: 4;
  left: var(--mx-gutter);
  bottom: 14%;
  max-width: min(72%, 30rem);
  margin: 0;
  color: rgb(246 241 238 / 0.6);
  font: 500 0.75rem / 1.35 var(--mx-sans);
  letter-spacing: -0.005em;
  text-align: left;
}

/* Words in the picture. Set by the driver (`composeFrames`): the heading is
   a child of the figure, drawn over the photograph and under a second copy
   of the photograph's bottom band, so the letters stand behind the ground. */
.page[data-skin="monster"] .mx-frame {
  /* Where the words stand, up from the picture's foot, and how big they are.
     No floor in rem on the size: the longest word here ("СПОНСОРУВАТИ") has
     to fit a phone, and only a size tied to the window's width promises
     that. */
  --mx-foot: 15%;
  --mx-type: min(15.5vw, 15rem);
}

.page[data-skin="monster"] .mx-frame > :is(h2, blockquote) {
  position: absolute;
  z-index: 2;
  inset: auto var(--mx-gutter) var(--mx-foot);
  margin: 0;
  padding: 0;
  border: 0;
  text-align: center;
  color: var(--mx-over);
}

.page[data-skin="monster"] .mx-frame > h2,
.page[data-skin="monster"] .mx-frame > blockquote p {
  font-size: var(--mx-type);
  color: var(--mx-over);
  text-shadow: var(--mx-ghost);
}

/* The band is measured in the TYPE's size, up from where the words stand: it
   takes the letters' feet and no more. It was a share of the picture's
   height, which was right on a wide window only; on a phone, where the type
   is a quarter the size in a frame as tall, it lay over the whole last line
   ("ВСЕ" could not be read). */
.page[data-skin="monster"] .mx-fore {
  --mx-band: linear-gradient(
    to top,
    #000 0,
    #000 calc(var(--mx-foot) + 0.08 * var(--mx-type)),
    transparent calc(var(--mx-foot) + 0.45 * var(--mx-type))
  );
  z-index: 3;
  pointer-events: none;
  -webkit-mask-image: var(--mx-band);
  mask-image: var(--mx-band);
}

/* The credit sits just above where the picture's foot starts to dissolve
   (the last 11% of the frame) and under the words. Lower, it dissolved with
   the picture and could not be read. */
.page[data-skin="monster"] .mx-frame figcaption {
  bottom: 11.5%;
}

/* A phone's frame is tall and narrow: the words stand higher in it, clear of
   the credit. */
@media (max-width: 699px) {
  .page[data-skin="monster"] .mx-frame {
    --mx-foot: 19%;
  }

  .page[data-skin="monster"] .prose figcaption {
    right: var(--mx-gutter);
    max-width: none;
    font-size: 0.6875rem;
  }
}

/* One reveal, when it arrives: the picture comes up out of black and settles.
   Opacity and scale only, so the compositor does it with what it already
   holds. Hidden by opacity until then, never by a clip: an element clipped to
   nothing does not intersect the viewport, so the observer that should reveal
   it never fires and its lazy image never loads.

   It used to be tied to the scroll instead, under-exposed on the way in and
   on the way out, through an animated `filter: brightness()`. That left every
   picture nearly black for most of its time on screen, and repainted two
   masked full-window layers on every scrolled frame. */
.page[data-skin="monster"][data-mx="live"] .prose figure.mx-hold > :is(img, .mx-fore) {
  opacity: 0;
}

.page[data-skin="monster"][data-mx="live"] .prose figure.mx-in > :is(img, .mx-fore) {
  animation: mx-expose 1.1s var(--mx-snap) backwards;
}

@keyframes mx-expose {
  from {
    opacity: 0;
    transform: scale(1.1);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* The words in a picture travel a little slower than it does. A translate,
   which is all the scroll is allowed to drive.

   Not in a large window on a dense screen. A heading that moves is a surface
   of its own, and so then is everything drawn over it and the mask round the
   lot: about 170 MB a picture at 5120px across, for a movement of a few
   dozen pixels. There the words stand still in the picture. A wide window at
   one pixel a point keeps it, and so does a laptop. */
@supports (animation-timeline: view()) {
  @media (max-width: 1800px), (max-resolution: 1.49dppx) {
    .page[data-skin="monster"][data-mx="live"] .prose figure {
      view-timeline: --mx-shot block;
    }

    .page[data-skin="monster"][data-mx="live"] .mx-frame > :is(h2, blockquote) {
      animation: mx-drift linear both;
      animation-timeline: --mx-shot;
      animation-range: cover 0% cover 100%;
    }
  }

  @keyframes mx-drift {
    from {
      translate: 0 16%;
    }
    to {
      translate: 0 -16%;
    }
  }
}

/* ---- A statement: `> …` ---- */

.page[data-skin="monster"] .prose blockquote {
  grid-column: full;
  margin: clamp(2rem, 8vh, 5rem) 0;
  padding: 0 var(--mx-gutter);
  border: 0;
  text-align: center;
  color: var(--mx-hot);
}

.page[data-skin="monster"] .prose blockquote p,
.page[data-skin="monster"][data-mx="live"] .prose blockquote p {
  max-width: none;
  margin: 0;
  font: 900 clamp(3.75rem, 17vw, 16rem) / 0.78 var(--mx-display);
  font-style: normal;
  letter-spacing: -0.012em;
  text-transform: uppercase;
  text-wrap: balance;
  text-shadow: var(--mx-ghost);
  opacity: 1;
  transform: none;
  animation: none;
}

/* ---- Figures: a headerless two-column table ---- */

/* One figure a line, as big as the line will take, its name beside it in
   ordinary type. A stack of facts, not a dashboard of tiles. */
.page[data-skin="monster"] .prose table {
  display: block;
  width: auto;
  margin: clamp(1rem, 4vh, 3rem) 0 clamp(2rem, 6vh, 4rem);
  border: 0;
  border-radius: 0;
  overflow: visible;
  font-size: inherit;
}

.page[data-skin="monster"] .prose thead {
  display: none;
}

.page[data-skin="monster"] .prose tbody {
  display: block;
}

.page[data-skin="monster"] .prose tr {
  display: flex;
  flex-direction: row-reverse;
  justify-content: flex-end;
  align-items: baseline;
  gap: 0 clamp(0.75rem, 2vw, 1.75rem);
  flex-wrap: wrap;
  padding: 0.1em 0 0.04em;
  border-bottom: 1px solid color-mix(in srgb, currentColor 24%, transparent);
}

.page[data-skin="monster"] .prose tr:last-child {
  border-bottom: 0;
}

.page[data-skin="monster"] .prose td {
  display: block;
  padding: 0;
  border: 0;
  color: inherit;
}

.page[data-skin="monster"] .prose td:first-child {
  max-width: 13rem;
  font-size: clamp(0.9375rem, 0.85rem + 0.3vw, 1.125rem);
  font-weight: 700;
  line-height: 1.15;
}

.page[data-skin="monster"] .prose td:last-child {
  font: 900 clamp(4.5rem, 16vw, 13.5rem) / 0.84 var(--mx-display);
  letter-spacing: -0.012em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  color: var(--mx-hot);
}

.page[data-skin="monster"] .mx-plate:not(.mx-screen) td:last-child {
  text-shadow: var(--mx-ghost);
}

/* On a phone every figure stands over its name; side by side, the long
   names wrapped above their figures and the short ones did not. */
@media (max-width: 699px) {
  .page[data-skin="monster"] .prose tr {
    flex-direction: column-reverse;
    align-items: flex-start;
    padding-bottom: 0.5rem;
  }

  .page[data-skin="monster"] .prose td:first-child {
    max-width: none;
  }
}

.page[data-skin="monster"][data-mx="live"] .prose table.mx-hold tr {
  opacity: 0;
}

.page[data-skin="monster"][data-mx="live"] .prose table.mx-in tr {
  transform-origin: 0 100%;
  animation: mx-row 0.7s var(--mx-snap) backwards;
}

.page[data-skin="monster"][data-mx="live"] .prose table.mx-in tr:nth-child(2) {
  animation-delay: 0.12s;
}

.page[data-skin="monster"][data-mx="live"] .prose table.mx-in tr:nth-child(3) {
  animation-delay: 0.24s;
}

.page[data-skin="monster"][data-mx="live"] .prose table.mx-in tr:nth-child(4) {
  animation-delay: 0.36s;
}

@keyframes mx-row {
  0% {
    opacity: 0;
    transform: translateX(-5%) scaleY(2.4);
  }
  45% {
    opacity: 1;
    transform: scaleY(0.93);
  }
  100% {
    opacity: 1;
    transform: none;
  }
}

/* ---- A roster: a list whose items open on a bold name ---- */

.page[data-skin="monster"] .prose ul {
  margin: clamp(1.5rem, 5vh, 3.5rem) 0;
  padding: 0;
  list-style: none;
}

.page[data-skin="monster"] .prose ul > li {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-items: baseline;
  gap: 0.1rem 2rem;
  margin: 0;
  padding: 0.5rem 0 0.7rem;
  border-bottom: 1px solid rgb(246 241 238 / 0.16);
}

.page[data-skin="monster"] .prose ul > li > strong:first-child {
  font: 900 clamp(2.75rem, 7.4vw, 6.5rem) / 0.86 var(--mx-display);
  letter-spacing: -0.008em;
  text-transform: uppercase;
  text-shadow: var(--mx-ghost);
}

@media (min-width: 700px) {
  .page[data-skin="monster"] .prose ul > li:has(> strong:first-child) {
    grid-template-columns: minmax(14rem, 1fr) minmax(0, 1fr);
  }
}

/* ---- The end matter: sources and credits ---- */

.page[data-skin="monster"] .mx-end {
  padding-block: clamp(4rem, 10vh, 7rem);
}

/* A measure, not half the grid: `wide-start / mid` is the left half of the
   column at any width, and on a phone that set every source in a strip 170px
   wide. */
.page[data-skin="monster"] .mx-end > * {
  max-width: 37rem;
}

.page[data-skin="monster"] .mx-end h2 {
  margin-top: 1.6em;
  font-size: clamp(2rem, 4vw, 3.25rem);
  text-shadow: none;
  scale: none;
}

.page[data-skin="monster"] .mx-end h2:first-child {
  margin-top: 0;
}

.page[data-skin="monster"] .prose .mx-end p,
.page[data-skin="monster"] .prose .mx-end ul {
  margin: 0 0 1rem;
  padding-left: 0;
  font-size: 0.9375rem;
  line-height: 1.45;
  color: rgb(246 241 238 / 0.72);
}

.page[data-skin="monster"] .prose .mx-end ul > li {
  display: block;
  padding: 0.55rem 0 0.6rem;
  border-bottom-color: rgb(246 241 238 / 0.12);
}

.page[data-skin="monster"] .prose .mx-end a {
  font-weight: 600;
  text-decoration-thickness: 1px;
  text-decoration-color: rgb(255 42 18 / 0.7);
}

/* ---- Previous / next ---- */

.page[data-skin="monster"] .entry-siblings {
  position: relative;
  z-index: 3;
  margin: 0;
  padding: 2.5rem var(--mx-gutter) 5rem;
  border-top: 1px solid rgb(246 241 238 / 0.12);
  background: var(--mx-black);
  font-family: var(--mx-sans);
}

/* ------------------------------------------------------------------------
   Reduced motion, and paper
   ------------------------------------------------------------------------ */

/* The driver never sets `data-mx` here, so nothing above waits to be
   revealed. What is left to switch off is the motion that runs on its own. */
@media (prefers-reduced-motion: reduce) {
  .page[data-skin="monster"] {
    --mx-wait: 0s !important;
  }

  .page[data-skin="monster"] .mx-intro {
    display: none;
  }

  .page[data-skin="monster"] .note-header-text {
    animation: none;
  }
}

@media print {
  .page[data-skin="monster"] .mx-intro,
  .page[data-skin="monster"] .mx-fx,
  .page[data-skin="monster"] .mx-smoke {
    display: none;
  }
}
