/* ran-morph.css · "The Audit" hero stage. Placed and sized by ran-morph.js; every motion style comes from seek(t). */

/* The stage is its own paint layer, so its frames never repaint the hero. It is never scaled itself
   (the camera scales .rm-world inside it), so its text still rasterises crisp at every zoom. */
.ran-morph {
  position: absolute;
  z-index: 3;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  opacity: 0;
  contain: layout paint;
  will-change: transform;
}

/* Flow layout: sized by the page (5:4 if unset), the pause toggle inside the frame. See INSTALL.md. */
.ran-morph:where([data-layout="flow"]) {
  width: 100%;
  height: 100%;
  aspect-ratio: 5 / 4;
}

.ran-morph[data-layout="flow"] {
  position: relative;
  box-sizing: border-box;
  overflow: hidden;
  border: 1px solid transparent;
  border-radius: 20px;
  opacity: 1;
}

.ran-morph[data-layout="flow"]:where(.is-mounted) {
  border-color: #34383c;
  background: #12161a;
}

.ran-morph[data-layout="flow"] .rm-stage {
  opacity: 0;
}

.ran-morph-caption {
  margin: 12px 2px 0;
  color: rgba(241, 242, 239, 0.56);
  font: 500 0.66rem/1.3 "IBM Plex Mono", ui-monospace, monospace;
  text-transform: uppercase;
}

:where(.ran-morph[data-layout="flow"]:not(.is-mounted)) ~ .ran-morph-caption {
  visibility: hidden;
}

.ran-morph-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.ran-morph .rm-stage {
  position: absolute;
  inset: 0;
  display: block;
  overflow: hidden;
  color: #090b0d; /* beats the site's body.lux-site a { color: inherit } */
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}

/* The site resets letter-spacing on every element; let the stage's own tracking reach its spans. */
.rm-stage * {
  letter-spacing: inherit;
}

/* The site's faint 88 px grid, aligned to the hero's by the script, fading out toward the stage edges. */
.rm-grid,
.ran-morph[data-layout="flow"]::before {
  position: absolute;
  inset: 0;
  background-image: linear-gradient(rgba(255, 255, 255, 0.036) 1px, transparent 1px), linear-gradient(90deg, rgba(255, 255, 255, 0.036) 1px, transparent 1px);
  background-size: 88px 88px;
  -webkit-mask-image: radial-gradient(closest-side, #000 45%, transparent);
  mask-image: radial-gradient(closest-side, #000 45%, transparent);
}

.ran-morph[data-layout="flow"]::before {
  background-position: 50% 50%;
}

.ran-morph[data-layout="flow"]:where(.is-mounted)::before {
  content: "";
}

.ran-morph[data-layout="flow"] .rm-grid {
  display: none;
}

.rm-world,
.rm-world > *,
.rm-g > *,
.rm-cursor {
  position: absolute;
  top: 0;
  left: 0;
}

.rm-world {
  transform-origin: 0 0;
}

.rm-g {
  transform-origin: 0 0;
}

/* Shape pieces: 1 px rects and 100 px discs, scaled into a rounded rect of any size and radius. */
.rm-shape > *,
.rm-px {
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
  transform-origin: 0 0;
}

.rm-shape > .rm-o,
.rm-knob,
.rm-ind {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  transform-origin: 0 0;
}

.rm-paper > *,
.rm-knob,
.rm-knobm,
.rm-cover {
  background: #f1f2ef;
}

.rm-ind,
.rm-indm,
.rm-fill,
.rm-track.rm-on {
  background: #090b0d;
}

/* Ink surfaces on the ink stage: the site's ink-soft, with a 1 px ring like its glass pills. */
.rm-inked > * {
  background: #12161a;
}

.rm-ring > * {
  background: #34383c;
}

/* Type: Manrope for UI, IBM Plex Mono for labels and numbers, one Bricolage number. */
.rm-t {
  color: #090b0d;
  font: 600 14px/1.2 "Manrope", Arial, sans-serif;
  white-space: nowrap;
}

.rm-m {
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.rm-mute {
  color: rgba(9, 11, 13, 0.55);
}

.rm-inv {
  color: #f1f2ef;
}

.rm-small {
  font-size: 13px;
}

.rm-big {
  font: 700 30px/1 "Bricolage Grotesque", Arial, sans-serif;
}

.rm-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  color: #090b0d;
  font-family: "Manrope", Arial, sans-serif;
  white-space: nowrap;
}

.rm-pill span:last-child {
  display: inline-block;
}

.rm-reel {
  display: inline-block;
  height: 1.2em;
  overflow: hidden;
  font-variant-numeric: tabular-nums;
  vertical-align: top;
}

.rm-strip {
  display: block;
  line-height: 1.2em;
  text-align: center;
  white-space: pre;
}

.rm-lead .rm-strip {
  text-align: right;
}

.rm-svg,
.rm-svg svg {
  display: block;
}

.rm-track {
  width: 34px;
  height: 20px;
  border-radius: 10px;
  background: rgba(9, 11, 13, 0.24);
}

.rm-bar {
  height: 8px;
  border-radius: 4px;
  background: rgba(9, 11, 13, 0.12);
}

.rm-handle {
  box-sizing: border-box;
  width: 16px;
  height: 16px;
  border: 1.5px solid #090b0d;
  border-radius: 50%;
  background: #f1f2ef;
}

.rm-rule {
  background: rgba(9, 11, 13, 0.08);
}

.rm-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #ff4e45;
}

.rm-tip {
  display: flex;
  align-items: center;
  padding: 6px 10px;
  border-radius: 8px;
  background: #ff4e45;
  color: #090b0d;
  font: 600 12px/1.2 "Manrope", Arial, sans-serif;
  white-space: nowrap;
}

.rm-caret {
  position: absolute;
  top: 50%;
  right: -4px;
  width: 9px;
  height: 9px;
  margin-top: -4.5px;
  background: #ff4e45;
  transform: rotate(45deg);
}

.rm-tip span {
  position: relative;
}

.rm-redrow {
  height: 44px;
  border-radius: 12px;
  background: #ff4e45;
}

.rm-rowdot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(9, 11, 13, 0.4);
}

.rm-key {
  font-size: 15px;
}

.rm-hint {
  padding: 3px 6px;
  border: 1px solid rgba(241, 242, 239, 0.3);
  border-radius: 6px;
}

.rm-type {
  font: 500 15px/1.2 "Manrope", Arial, sans-serif;
  white-space: pre;
}

.rm-caretbar {
  background: #f1f2ef;
}

.rm-matchbg {
  height: 34px;
  border-radius: 10px;
  background: #ff4e45;
}

.rm-chip {
  padding: 6px 9px;
  border: 1px solid rgba(241, 242, 239, 0.3);
  border-radius: 999px;
  color: #f1f2ef;
  transform-origin: 50% 50%;
}

.rm-now {
  border-color: #ff4e45;
  background: #ff4e45;
  color: #090b0d;
}

/* Windows keys: ink-soft caps with a 1 px ring and a bottom edge. */
.rm-kc {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  min-width: 28px;
  height: 28px;
  padding: 0 8px;
  border-radius: 7px;
  background: #12161a;
  box-shadow: 0 0 0 1px #34383c, inset 0 -2px #34383c;
  color: #f1f2ef;
  font-size: 11px;
}

.rm-kcl {
  min-width: 56px;
  height: 56px;
  padding: 0 16px;
  border-radius: 14px;
  font-size: 15px;
}

/* Structure: the campaign table, its selection and the bulk bar. */
.rm-tint {
  height: 34px;
  border-radius: 10px;
  background: rgba(9, 11, 13, 0.05);
}

.rm-cb,
.rm-cbon {
  box-sizing: border-box;
  width: 16px;
  height: 16px;
  border-radius: 4px;
}

.rm-cb {
  border: 1.5px solid rgba(9, 11, 13, 0.32);
}

.rm-cbon {
  background: #090b0d;
  color: #f1f2ef;
}

.rm-code {
  font-size: 11px;
}

.rm-stat {
  color: rgba(9, 11, 13, 0.55);
}

.rm-off {
  color: rgba(9, 11, 13, 0.38);
}

.rm-dup {
  padding: 3px 7px;
  border-radius: 999px;
  background: #ff4e45;
  color: #090b0d;
}

.rm-bulk {
  height: 44px;
  border-radius: 12px;
  background: #090b0d;
}

.rm-act {
  color: rgba(241, 242, 239, 0.78);
  font-size: 13px;
}

.rm-tok {
  padding: 4px 7px;
  border: 1px solid rgba(241, 242, 239, 0.3);
  border-radius: 6px;
}

.rm-btn {
  padding: 6px 12px;
  border-radius: 999px;
  background: #f1f2ef;
  font-size: 12.5px;
}

/* Spend: donuts, legends, reallocation bars. */
.rm-sl.rm-red {
  fill: #ff4e45;
}

.rm-sl.rm-ink {
  fill: #090b0d;
}

.rm-sl.rm-ink55 {
  fill: #6f7275;
}

.rm-sl.rm-ink30 {
  fill: #c3c5c2;
}

.rm-legdot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
}

.rm-red {
  background: #ff4e45;
}

.rm-ink {
  background: #090b0d;
}

.rm-ink55 {
  background: #6f7275;
}

.rm-ink30 {
  background: #c3c5c2;
}

.rm-num {
  font: 500 17px/1 "IBM Plex Mono", ui-monospace, monospace;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}

.rm-redtxt {
  color: #ff4e45;
}

.rm-track2 {
  height: 10px;
  border-radius: 2px;
  background: rgba(9, 11, 13, 0.07);
}

/* Result */
.rm-mark {
  width: 0;
  border-left: 1.5px dashed rgba(9, 11, 13, 0.32);
}

.rm-inkdot {
  background: #090b0d;
}

.rm-inktip {
  padding: 5px 8px;
  border-radius: 7px;
  background: #090b0d;
  transform-origin: 100% 50%;
}

.rm-roassub {
  font-size: 11.5px;
}

.rm-upchip {
  padding: 4px 8px;
  border-radius: 999px;
  background: #090b0d;
  color: #f1f2ef;
  transform-origin: 100% 50%;
}

/* Kinetic type: paper words on ink; the highlighted ones sit on the morphing shape in ink. */
.rm-line {
  color: #f1f2ef;
  font: 700 34px/1.12 "Manrope", Arial, sans-serif;
  letter-spacing: -0.03em;
  word-spacing: 0.12em;
  white-space: nowrap;
}

.rm-w {
  display: inline-block;
  overflow: hidden;
  padding-bottom: 0.1em;
  margin-bottom: -0.1em;
  vertical-align: top;
}

.rm-w > span {
  display: inline-block;
}

.rm-hl > span {
  color: #090b0d;
}

/* The cursor moves on almost every frame: its own layer, so it never repaints the UI under it.
   Safe: the camera never scales it and it holds no text. */
.rm-cursor {
  width: 20px;
  height: 26px;
  pointer-events: none;
  transform-origin: 2px 2px;
  will-change: transform;
}

/* Pause toggle (WCAG 2.2.2): right edge on the container, placed by the script. */
.ran-morph-toggle {
  position: absolute;
  z-index: 3;
  top: 0;
  left: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-width: 44px;
  min-height: 44px;
  margin: 0;
  padding: 0 16px 0 15px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 999px;
  background: rgba(16, 20, 24, 0.62);
  box-shadow: inset 0 1px rgba(255, 255, 255, 0.12);
  color: #f1f2ef;
  font: 500 0.66rem/1 "IBM Plex Mono", ui-monospace, monospace;
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
  transform: translateX(-100%);
}

.ran-morph-toggle:hover {
  border-color: rgba(255, 255, 255, 0.55);
}

.ran-morph-toggle[aria-pressed="true"] {
  border-color: #f1f2ef;
  background: #f1f2ef;
  color: #090b0d;
}

/* Pause bars while the motion runs; a play triangle once it is paused (the icon shows what a press will do, as on the
   site's own pause toggle). The name stays "Pause motion", with aria-pressed. */
.ran-morph-toggle-icon {
  box-sizing: border-box;
  width: 8px;
  height: 10px;
  border-inline: 2px solid currentColor;
}

.ran-morph-toggle[aria-pressed="true"] .ran-morph-toggle-icon {
  width: 9px;
  border: 0;
  background: currentColor;
  clip-path: polygon(0 0, 100% 50%, 0 100%);
}

.ran-morph-toggle.is-compact {
  padding: 0;
}

.ran-morph-toggle.is-compact[aria-pressed="true"] .ran-morph-toggle-icon {
  margin-left: 2px; /* optical centre of the triangle */
}

/* Flow: inside the frame, 12 px from its top-right corner (the ring is 1 px), or its bottom-right corner in narrow
   or short frames without a caption (.is-low, set by the script; see CONFIG.toggleLow). Solid ink-soft with the
   frame's ring, so the icon reads the same over any content that passes under it. Pressed, it keeps the ink-soft fill
   and takes a paper ring: a paper disc would merge with the paper cards that pass under it. */
.ran-morph[data-layout="flow"] > .ran-morph-toggle {
  top: 11px;
  right: 11px;
  left: auto;
  box-sizing: border-box;
  width: 44px;
  height: 44px;
  border-color: #34383c;
  background: #12161a;
  transform: none;
}

/* Low specificity: reduced motion (below) still hides it, and a page's :focus-visible ring (often a box-shadow) still
   shows. No inset highlight. */
:where(.ran-morph[data-layout="flow"]) > .ran-morph-toggle {
  display: flex;
  box-shadow: none;
}

.ran-morph[data-layout="flow"] > .ran-morph-toggle.is-low {
  top: auto;
  bottom: 11px;
}

.ran-morph[data-layout="flow"] > .ran-morph-toggle:hover {
  border-color: rgba(255, 255, 255, 0.55);
}

.ran-morph[data-layout="flow"] > .ran-morph-toggle[aria-pressed="true"] {
  border-color: #f1f2ef;
  background: #12161a;
  color: #f1f2ef;
}

/* Flow, narrow or short frames with a caption (.is-out, set by the script): under the frame, at the right end of the
   caption row, which the page lays out (INSTALL.md: the figure as a two-column grid). Without that layout it sits on
   its own line under the caption, at the right. Ink-soft with the frame's ring, like the frame; paper when pressed, as
   nothing passes under it here. The display and box-shadow rule has the specificity of one class, so the reduced-motion
   rule below still hides it and a page's :focus-visible ring still shows. */
.ran-morph[data-layout="flow"] ~ .ran-morph-toggle {
  position: relative;
  top: auto;
  left: auto;
  box-sizing: border-box;
  width: 44px;
  height: 44px;
  border-color: #34383c;
  background: #12161a;
  transform: none;
}

:where(.ran-morph[data-layout="flow"]) ~ .ran-morph-toggle {
  display: flex;
  margin: 8px 0 0 auto;
  box-shadow: none;
}

.ran-morph[data-layout="flow"] ~ .ran-morph-toggle:hover {
  border-color: rgba(255, 255, 255, 0.55);
}

.ran-morph[data-layout="flow"] ~ .ran-morph-toggle[aria-pressed="true"] {
  border-color: #f1f2ef;
  background: #f1f2ef;
}

/* A paper disc on the page's ink: a paper ring with an ink gap shows focus (a paper band would only merge with the
   disc, and an ink outline with the page). */
.ran-morph[data-layout="flow"] ~ .ran-morph-toggle[aria-pressed="true"]:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 2px #090b0d, 0 0 0 4px #f1f2ef;
}

.ran-morph-toggle.is-compact .ran-morph-toggle-label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}

/* One pause for the whole hero, including the site's own looping bits. */
html[data-motion="paused"] .lux-scroll-cue span::after,
html[data-motion="paused"] .lux-ticker > div {
  animation-play-state: paused;
}

@media (prefers-reduced-motion: reduce) {
  .ran-morph-toggle {
    display: none;
  }
}

@media (forced-colors: active) {
  .ran-morph,
  .ran-morph-toggle,
  .ran-morph-caption {
    display: none;
  }
}

/* Fill (phone portrait frames; the script sets .is-fill on the host, see CONFIG.fillMax): the audit UI at phone-UI
   sizes, one notch up, since the camera holds cards at 1:1 instead of zooming them. Same families, weights and colours.
   The order of these rules mirrors the base rules above (.rm-small and .rm-code after .rm-m). Where the cards play
   scaled down (a 320 px phone, the table on the shortest screens), the script sets --rm-floor, the size that lands at
   10.5 px on screen, and the four smallest sizes take it (max(): a frame at 1:1 has no floor and keeps its own). */
.ran-morph.is-fill .rm-t {
  font-size: 15px;
}

.ran-morph.is-fill .rm-m {
  font-size: max(11.5px, var(--rm-floor, 0px));
}

.ran-morph.is-fill .rm-small {
  font-size: 14px;
}

.ran-morph.is-fill .rm-code {
  font-size: max(12px, var(--rm-floor, 0px));
}

.ran-morph.is-fill .rm-act {
  font-size: 14px;
}

.ran-morph.is-fill .rm-btn {
  font-size: 13.5px;
}

.ran-morph.is-fill .rm-big {
  font-size: 38px;
}

.ran-morph.is-fill .rm-roassub {
  font-size: max(12px, var(--rm-floor, 0px));
}

.ran-morph.is-fill .rm-tip {
  font-size: 13px;
}

.ran-morph.is-fill .rm-kc {
  font-size: max(12px, var(--rm-floor, 0px));
}

.ran-morph.is-fill .rm-kcl {
  font-size: 16px;
}

.ran-morph.is-fill .rm-type,
.ran-morph.is-fill .rm-key {
  font-size: 16px;
}

/* Fill: the Ctrl+K act's ink surfaces fill the frame, so they drop their ring (ran-morph.js) and sit one step lighter
   than the frame, a raised sheet on its ink (paper text on it: 14:1). The Ctrl key matches the K key, the shape. */
.ran-morph.is-fill .rm-inked > *,
.ran-morph.is-fill .rm-kcl {
  background: #1e2327;
}

.ran-morph.is-fill .rm-kcl {
  box-shadow: none;
}

/* Fill: the poster's rows need air, so a highlight block never meets the row above while its words rise. */
.ran-morph.is-fill .rm-line {
  line-height: 1.36;
}

/* Fill: a mask ends where its row does (the 1.36 line box already holds the glyphs), so a word rising in the row above
   a highlight block comes out of the block's edge instead of from behind it. */
.ran-morph.is-fill .rm-w {
  padding-bottom: 0.04em;
  margin-bottom: -0.04em;
}
