/* The Daily Drawing is the hero's attraction, not a small plaque inside a
   full-width empty cabinet. This sheet is intentionally separate from the
   at-capacity app.css and owns only the cabinet's responsive identity pass. */

body.layout-basic .jackpot-hero__machine {
  --jp-board-size: clamp(15rem, 68cqi, 28rem);
  --jp-foil-size: clamp(2.75rem, 11.8cqi, 5.65rem);
  --jp-side-gap: clamp(0.2rem, 0.85cqi, 0.42rem);
  --jp-stage-top: 3.18rem;
  --jp-action-width: min(var(--jp-board-size), 18rem);
  --jp-chainlink-size: clamp(2.3rem, 7.6cqi, 2.9rem);
  --jp-chainlink-gap: clamp(1.15rem, 4.2cqi, 1.8rem);
  width: min(100%, 48rem);
  margin-inline: auto;
  padding: 0.24rem 0.34rem 0.38rem;
  /* The plate is built in fab order, bottom up: bare laminate, the woven glass
     of the substrate, the bitmap that carries the frame and its mounting
     screws, the copper, then the white ink. Two lighting layers finish it — a
     warm source above the title, and a vignette that takes the corners down so
     the cabinet has a middle and an edge instead of one even wash. Everything
     here sits below every child, so the board, sockets and LED key are unaffected.
     The copper and silkscreen sheets stretch with the box; both are authored
     against the measured desktop AND phone hardware positions, so no route or
     legend lands on a part in either layout. */
  background:
    radial-gradient(62% 18% at 50% 2%, rgba(205, 164, 72, 0.055), transparent 72%),
    radial-gradient(48% 72% at 50% 47%, rgba(33, 112, 72, 0.045), transparent 76%),
    radial-gradient(118% 58% at 50% -6%, rgba(255, 226, 163, 0.05), transparent 62%),
    radial-gradient(128% 118% at 50% 46%, transparent 54%, rgba(0, 0, 0, 0.52) 100%),
    url('/app/assets/jackpot/daily-drawing-board-silkscreen-v3.svg') center / 100% 100% no-repeat,
    url('/app/assets/jackpot/daily-drawing-board-routing-v9.svg') center / 100% 100% no-repeat,
    repeating-linear-gradient(45deg, rgba(216, 232, 220, 0.013) 0 1px, transparent 1px 5px),
    repeating-linear-gradient(-45deg, rgba(0, 0, 0, 0.17) 0 1px, transparent 1px 5px),
    url('/app/assets/jackpot/daily-drawing-backplate-v9.webp') center / 100% 100% no-repeat,
    #03100b;
}

/* One permanent cabinet fitting owns the lower-left circle. Ineligible players
   see the untouched board through a faint placement ring and a small keyed
   motherboard-style port; eligibility replaces it with the red ALL IN key. */
body.layout-basic .jackpot-hero__machine > app-all-in-machine-control {
  position: absolute;
  z-index: 8;
  left: calc(50% - (var(--jp-action-width) / 2) - var(--jp-chainlink-gap) - var(--jp-chainlink-size));
  bottom: var(--jp-chainlink-size);
  display: grid;
  width: var(--jp-chainlink-size);
  aspect-ratio: 1;
  place-items: stretch;
  border-radius: 50%;
  pointer-events: none;
}

body.layout-basic .jackpot-hero__machine .jackpot-all-in-socket,
body.layout-basic .jackpot-hero__machine .jackpot-all-in-button {
  box-sizing: border-box;
  display: grid;
  width: 100%;
  height: 100%;
  grid-area: 1 / 1;
  place-items: center;
  border-radius: 50%;
}

body.layout-basic .jackpot-hero__machine .jackpot-all-in-socket {
  position: relative;
  border: 1px solid rgba(235, 229, 201, 0.2);
  background: rgba(255, 255, 255, 0.012);
  box-shadow:
    inset 0 0 0 1px rgba(3, 7, 5, 0.24),
    0 0 6px rgba(222, 202, 139, 0.035);
  pointer-events: none;
}

/* Component designator printed inside the empty fitting, just below its 4-pin
   header. It disappears with the socket when the earned red control replaces
   this state. */
body.layout-basic .jackpot-hero__machine .jackpot-all-in-socket__label {
  position: absolute;
  top: 81%;
  left: 50%;
  color: rgba(207, 217, 209, 0.15);
  font: 700 clamp(0.3rem, 1.05cqi, 0.4rem)/1 ui-monospace, "SFMono-Regular", Menlo, Consolas, "DejaVu Sans Mono", monospace;
  letter-spacing: 0.067em;
  text-indent: 0.067em;
  transform: translate(-50%, -50%);
  white-space: nowrap;
}

body.layout-basic .jackpot-hero__machine .jackpot-all-in-socket__port {
  position: relative;
  display: grid;
  width: 34%;
  aspect-ratio: 1;
  place-items: center;
  border: 1px solid #404343;
  border-radius: 13%;
  background: linear-gradient(145deg, #202323, #050606 68%);
  box-shadow:
    inset 1px 1px 2px rgba(255, 255, 255, 0.09),
    inset -2px -2px 3px #000,
    0 0 0 1px rgba(116, 113, 102, 0.25),
    0 1px 2px rgba(0, 0, 0, 0.72);
}

body.layout-basic .jackpot-hero__machine .jackpot-all-in-socket__pins {
  display: grid;
  width: 72%;
  height: 72%;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-template-rows: repeat(2, minmax(0, 1fr));
  gap: 8%;
}

body.layout-basic .jackpot-hero__machine .jackpot-all-in-socket__pin {
  min-width: 0;
  min-height: 0;
  border: 1px solid rgba(101, 103, 99, 0.66);
  border-radius: 16%;
  background:
    radial-gradient(circle at 48% 50%,
      #c1a55f 0 12%, #71633e 16%, #090a0a 23% 57%, #3a3d3b 64% 100%);
  box-shadow: inset 0 0 2px rgba(0, 0, 0, 0.9);
}

body.layout-basic .jackpot-hero__machine .jackpot-all-in-socket__pin:nth-child(2),
body.layout-basic .jackpot-hero__machine .jackpot-all-in-socket__pin:nth-child(3) {
  clip-path: polygon(22% 0, 78% 0, 100% 22%, 100% 100%, 0 100%, 0 22%);
}

body.layout-basic .jackpot-hero__machine .jackpot-all-in-socket__port::after {
  position: absolute;
  top: 28%;
  right: -13%;
  width: 13%;
  height: 44%;
  border-radius: 0 2px 2px 0;
  background: #090a0a;
  box-shadow: inset -1px 0 rgba(255, 255, 255, 0.08), 1px 0 1px rgba(0, 0, 0, 0.7);
  content: "";
}

body.layout-basic .jackpot-hero__machine .jackpot-all-in-button {
  appearance: none;
  padding: 0;
  border: 0;
  background: transparent;
  filter: none;
  pointer-events: auto;
  cursor: pointer;
  transition: filter 130ms ease;
}

body.layout-basic .jackpot-hero__machine .jackpot-all-in-button img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  pointer-events: none;
}

body.layout-basic .jackpot-hero__machine .jackpot-all-in-button:hover:not(:disabled),
body.layout-basic .jackpot-hero__machine .jackpot-all-in-button:focus-visible:not(:disabled) {
  outline: none;
  filter:
    drop-shadow(0 0 4px rgba(255, 74, 74, 0.88))
    drop-shadow(0 0 9px rgba(239, 38, 38, 0.58));
}

body.layout-basic .jackpot-hero__machine .jackpot-all-in-button:focus-visible {
  box-shadow: 0 0 0 2px #fff7d6, 0 0 0 4px rgba(239, 68, 68, 0.72);
}

body.layout-basic .jackpot-hero__machine .jackpot-all-in-button:active:not(:disabled) {
  filter: brightness(0.88) drop-shadow(0 0 4px rgba(239, 38, 38, 0.42));
}

body.layout-basic .jackpot-hero__machine .jackpot-all-in-button:disabled {
  cursor: default;
  filter: grayscale(0.45) brightness(0.72) drop-shadow(0 2px 3px rgba(0, 0, 0, 0.62));
}

body.layout-basic .jackpot-hero__machine .jackpot-all-in-button.is-cued {
  animation: jackpot-all-in-cue 0.25s ease-out both;
}

body.layout-basic .jackpot-hero__machine :is(.jackpot-all-in-socket, .jackpot-all-in-button)[hidden] {
  display: none !important;
}

@keyframes jackpot-all-in-cue {
  0%, 100% { filter: brightness(1) drop-shadow(0 3px 4px rgba(0, 0, 0, 0.72)); }
  38% { filter: brightness(1.48) drop-shadow(0 0 8px rgba(255, 221, 123, 0.76)); }
}

@media (prefers-reduced-motion: reduce) {
  body.layout-basic .jackpot-hero__machine .jackpot-all-in-button {
    transition: none;
  }
  body.layout-basic .jackpot-hero__machine .jackpot-all-in-button.is-cued {
    animation: none;
  }
}

/* The live board-current layer mirrors only the four copper traces that leave
   the LED key and terminate beneath the draw widget. It stays page-owned and
   inline so the rolling state and reduced-motion preference can control the
   packets directly; no isolated SVG document is left animating after a roll.
   Every path is authored key-first, so a decreasing dash offset sends current
   upward from the button into the board. */
body.layout-basic .jackpot-hero__machine > .jackpot-board-current {
  position: absolute;
  z-index: 1;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  filter: drop-shadow(0 0 2px rgba(111, 168, 255, 0.24));
  opacity: 0;
  pointer-events: none;
  transition: opacity 160ms ease;
}

body.layout-basic .jackpot-hero__machine > .jackpot-board-current use {
  fill: none;
  stroke-linecap: square;
  stroke-linejoin: miter;
  vector-effect: non-scaling-stroke;
}

body.layout-basic .jackpot-hero__machine > .jackpot-board-current .jackpot-board-current__rail {
  opacity: 0.24;
}

body.layout-basic .jackpot-hero__machine > .jackpot-board-current .jackpot-board-current__rail use {
  stroke-width: 2.1;
}

body.layout-basic .jackpot-hero__machine > .jackpot-board-current .jackpot-board-current__packet use {
  stroke-width: 2.6;
  stroke-opacity: 0.92;
  stroke-dasharray: 7 27;
}

body.layout-basic .jackpot-hero__machine:has(
  replay-panel .replay-reveal-btn.is-spinning
) > .jackpot-board-current {
  opacity: 0.62;
}

body.layout-basic .jackpot-hero__machine:has(
  replay-panel .replay-reveal-btn.is-spinning
) > .jackpot-board-current .jackpot-board-current__packet use {
  animation: jackpot-board-current-flow 1.44s linear infinite;
}

body.layout-basic .jackpot-hero__machine > .jackpot-board-current .jackpot-board-current__packet use:nth-child(2) {
  animation-delay: -90ms;
}
body.layout-basic .jackpot-hero__machine > .jackpot-board-current .jackpot-board-current__packet use:nth-child(3) {
  animation-delay: -180ms;
}
body.layout-basic .jackpot-hero__machine > .jackpot-board-current .jackpot-board-current__packet use:nth-child(4) {
  animation-delay: -270ms;
}

@keyframes jackpot-board-current-flow {
  to { stroke-dashoffset: -34; }
}

/* The board is a ticket lying on the machine, so it needs contact with it: a
   hard dark rim, a warm bounce off the plate, and a shadow under its lower
   edge. Colour inside the quadrants is game state and is left alone. */
body.layout-basic .jackpot-hero__machine replay-panel .replay-ticket {
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.85),
    0 0 0 3px rgba(120, 88, 32, 0.2),
    0 12px 22px -12px rgba(0, 0, 0, 0.95);
}

/* An owned gold board keeps its own gold announcement; it only gains the
   seating shadow underneath. */
body.layout-basic .jackpot-hero__machine replay-panel .replay-ticket.replay-ticket--has-owned-gold {
  box-shadow:
    0 0 0 2px rgba(255, 233, 163, 0.22),
    0 0 30px rgba(212, 175, 55, 0.42),
    0 12px 22px -12px rgba(0, 0, 0, 0.95);
}

body.layout-basic .jackpot-hero__draw-title {
  display: flex;
  flex-direction: row;
  width: min(35rem, 94%);
  height: 2.72rem;
  flex-basis: 2.72rem;
  gap: 0.42rem;
  align-items: center;
  justify-content: center;
  margin: 0.05rem auto -0.02rem;
  padding: 0.22rem 0.72rem;
  text-align: center;
}

body.layout-basic .jackpot-hero__draw-title::before,
body.layout-basic .jackpot-hero__draw-title::after {
  position: static;
  z-index: 0;
  inset: auto;
  width: auto;
  height: 1px;
  flex: 1 1 2rem;
  clip-path: none;
  background: linear-gradient(90deg, transparent, rgba(174, 135, 55, 0.5));
  box-shadow: none;
  content: '';
}
body.layout-basic .jackpot-hero__draw-title::after {
  background: linear-gradient(90deg, rgba(174, 135, 55, 0.5), transparent);
}

body.layout-basic .jackpot-hero__draw-mark {
  z-index: 1;
  width: 0.92rem;
  height: 1.32rem;
  flex: 0 0 auto;
  object-fit: contain;
  filter: sepia(0.28) saturate(0.7) drop-shadow(0 0 4px rgba(93, 234, 147, 0.18));
}

body.layout-basic .jackpot-hero__draw-title > strong {
  z-index: 1;
  min-width: 0;
  color: #dccb95;
  background: none;
  background-clip: border-box;
  -webkit-background-clip: border-box;
  -webkit-text-fill-color: currentColor;
  font-size: clamp(0.64rem, 2.85cqi, 0.96rem);
  line-height: 1;
  letter-spacing: 0.14em;
  white-space: nowrap;
  text-shadow: 0 1px 0 #020705;
  filter: drop-shadow(0 0 4px rgba(115, 229, 157, 0.08));
}

body.layout-basic .jackpot-hero__machine replay-panel .panel {
  padding-top: 0.12rem;
  padding-bottom: 0.38rem;
}

/* A real, opaque arcade key lives on the PCB. The bezel never changes; its
   three-colour LED bank lights when it is actionable or carrying information. */
body.layout-basic .jackpot-hero__machine replay-panel .replay-controls {
  position: relative;
  box-sizing: border-box;
  width: var(--jp-action-width);
  height: 3.24rem;
  min-height: 3.24rem;
  flex: 0 0 3.24rem;
  padding: 0.31rem;
  border: 1px solid #616864;
  border-radius: 5px;
  outline: 1px solid rgba(160, 119, 45, 0.42);
  outline-offset: 1px;
  background: linear-gradient(180deg, #343936 0%, #171b19 19%, #080a09 58%, #1a1e1b 100%);
  box-shadow:
    inset 0 1px 0 rgba(225, 232, 228, 0.18),
    inset 0 -1px 0 #010201,
    inset 0 0 0 2px #090b0a,
    0 0 0 1px rgba(0, 0, 0, 0.9),
    0 2px 8px rgba(0, 0, 0, 0.52);
}

/* app.css makes the warming/loading board inert so stale scratch cards cannot
   be touched. The shared action row has two deliberate exceptions:
   - a visible Day Summary still belongs to the already-completed day and must
     remain usable while replay data refreshes behind it;
   - once the resolver arms Mine FLIP, the player advances that still-pending
     pipeline with it.
   Without these overrides the buttons look enabled while their parent
   discards every pointer event. */
body.layout-basic .jackpot-hero replay-panel[data-day-warming] .panel > .replay-controls:has(
  > .ldj-results-cta:not([hidden])
),
body.layout-basic .jackpot-hero replay-panel[data-day-loading] .panel > .replay-controls:has(
  > .ldj-results-cta:not([hidden])
),
body.layout-basic .jackpot-hero replay-panel[data-day-warming] .panel > .replay-controls:has(
  > .replay-reveal-btn[data-replay-action='mine-flip']:not(:disabled)
),
body.layout-basic .jackpot-hero replay-panel[data-day-loading] .panel > .replay-controls:has(
  > .replay-reveal-btn[data-replay-action='mine-flip']:not(:disabled)
) {
  pointer-events: auto;
}

body.layout-basic .jackpot-hero__machine replay-panel .replay-reveal-btn.is-processing[
  data-replay-action='mine-flip'
]:not(:disabled) {
  cursor: pointer;
}

/* One enlarged VRF instrument sits at the circuit board's lower-right edge.
   It IS the Chainlink mark, not a ring of lamps that approximates one: the
   hexagon is masked from the same
   /symbols/crypto_05_chainlink_blue.svg the board prints when Chainlink is a
   drawn trait, so the silhouette is the brand geometry rather than six bars
   guessed into a hex. Brand first — the instrument reads as the mark at rest
   and only modulates its brightness to report VRF state.

   The mark is one unbroken ring (::before). The six addressable cells are the
   six SIDES of that same masked ring, so the instrument reports the VRF wait as
   a chain assembling itself one link at a time. Height bands were the earlier
   attempt and they failed as progress: a band lights the part of the ring the
   fill gradient is darkest in, so two lit read as six lit. Glow lives on the
   parent, whose filter composites AFTER each child has been masked. */
body.layout-basic .jackpot-hero__machine replay-panel .jackpot-chainlink {
  position: absolute;
  z-index: 4;
  isolation: isolate;
  top: 50%;
  display: none;
  box-sizing: border-box;
  width: var(--jp-chainlink-size);
  height: var(--jp-chainlink-size);
  border: 1px solid #2a312e;
  border-radius: 7px;
  /* A smooth satin-plastic face, not another UI tile. One very soft lift at
     the upper edge describes the shell without turning its top into a glossy
     hotspot. It stays opaque because the routed copper terminates under the
     package. */
  background:
    radial-gradient(110% 38% at 22% -18%, rgba(255, 255, 255, 0.04), transparent 72%),
    linear-gradient(155deg, #151816 0%, #090c0b 48%, #020303 100%);
  box-shadow:
    inset 0 1px 0 rgba(240, 248, 244, 0.055),
    inset 1px 0 0 rgba(223, 233, 228, 0.02),
    inset 0 -1px 0 rgba(0, 0, 0, 0.95),
    inset 0 0 0 2px rgba(0, 0, 0, 0.34),
    0 0 0 1px rgba(0, 0, 0, 0.72),
    0 3px 6px -2px rgba(0, 0, 0, 0.92);
  pointer-events: none;
  filter: none;
  transform: translateY(-50%);
  transition: border-color 180ms ease, filter 220ms ease;
}

/* Short gunmetal solder contacts mount the package without drawing an orange
   sunburst around the logo. A shared metal ramp makes them catch the same light
   as one physical lead frame instead of reading as flat grey tabs. Two contacts
   per edge are enough at phone scale; the left pair lands on the source-to-key
   nets. */
body.layout-basic .jackpot-hero__machine replay-panel .jackpot-chainlink__pins {
  position: absolute;
  z-index: -1;
  inset: -0.11rem;
  background: linear-gradient(145deg, #8a948f 0%, #46504b 38%, #171d1a 100%);
  -webkit-mask:
    repeating-linear-gradient(90deg, transparent 0 18%, #000 18% 27%, transparent 27% 50%) top / 100% 0.13rem no-repeat,
    repeating-linear-gradient(90deg, transparent 0 18%, #000 18% 27%, transparent 27% 50%) bottom / 100% 0.13rem no-repeat,
    repeating-linear-gradient(180deg, transparent 0 18%, #000 18% 27%, transparent 27% 50%) left / 0.13rem 100% no-repeat,
    repeating-linear-gradient(180deg, transparent 0 18%, #000 18% 27%, transparent 27% 50%) right / 0.13rem 100% no-repeat;
  mask:
    repeating-linear-gradient(90deg, transparent 0 18%, #000 18% 27%, transparent 27% 50%) top / 100% 0.13rem no-repeat,
    repeating-linear-gradient(90deg, transparent 0 18%, #000 18% 27%, transparent 27% 50%) bottom / 100% 0.13rem no-repeat,
    repeating-linear-gradient(180deg, transparent 0 18%, #000 18% 27%, transparent 27% 50%) left / 0.13rem 100% no-repeat,
    repeating-linear-gradient(180deg, transparent 0 18%, #000 18% 27%, transparent 27% 50%) right / 0.13rem 100% no-repeat;
  filter: drop-shadow(0 1px 0 rgba(0, 0, 0, 0.78));
  opacity: 0.68;
  pointer-events: none;
  transition: filter 180ms ease, opacity 180ms ease;
}

/* Exactly two dot-free PCB traces span the exposed gap between the devices.
   This component-relative pair replaces the old fixed-coordinate SVG feed,
   which drifted away from the module at narrow widths and left two orphaned
   stubs beside the button. The colour, opacity and quiet halo are copied from
   the rest of the board copper. Both traces disappear beneath the opaque
   housings between the module's square mounting contacts rather than plugging
   visibly into those contacts or crossing the button face. */
body.layout-basic .jackpot-hero__machine replay-panel .jackpot-chainlink__lead {
  position: absolute;
  z-index: -2;
  right: 100%;
  width: var(--jp-chainlink-gap);
  height: 1px;
  background: #b98a38;
  box-shadow: 0 0 3px rgba(208, 163, 76, 0.05);
  opacity: 0.27;
  pointer-events: none;
  transform: translateY(-50%);
  transition: filter 180ms ease, background-color 180ms ease, opacity 180ms ease;
}

body.layout-basic .jackpot-hero__machine replay-panel .jackpot-chainlink__lead--top {
  top: 38%;
}

body.layout-basic .jackpot-hero__machine replay-panel .jackpot-chainlink__lead--bottom {
  top: 62%;
}

/* Waiting for VRF is dormant copper. Only the live roll energises this pair:
   one blue-white packet travels from the right-hand Chainlink package toward
   the key, with a soft tail that reads as current rather than marching dots. */
body.layout-basic .jackpot-hero__machine replay-panel .replay-controls:has(
  > .replay-reveal-btn.is-spinning
) .jackpot-chainlink__lead {
  background:
    repeating-linear-gradient(
      90deg,
      rgba(52, 79, 137, 0.46) 0 8px,
      rgba(96, 148, 255, 0.72) 8px 12px,
      #eef5ff 12px 14px,
      #8bb5ff 14px 18px,
      rgba(52, 79, 137, 0.46) 18px 28px
    ) 0 0 / 28px 1px;
  filter: drop-shadow(0 0 1.8px rgba(126, 170, 255, 0.54));
  opacity: 0.82;
  animation: jackpot-chainlink-lead-flow 720ms linear infinite;
}

body.layout-basic .jackpot-hero__machine replay-panel .replay-controls:has(
  > .replay-reveal-btn.is-spinning
) .jackpot-chainlink__lead--bottom {
  animation-delay: -180ms;
}

@keyframes jackpot-chainlink-lead-flow {
  to { background-position: -28px 0; }
}

/* The standby mark: the whole hexagon, dim, always legible as the logo. */
body.layout-basic .jackpot-hero__machine replay-panel .jackpot-chainlink::before {
  position: absolute;
  inset: 5%;
  /* Flat, for the same reason the lit cells are. A top-to-bottom ramp made the
     upper sides of the resting mark about four times brighter than the lower
     ones, which is more spread than lit-vs-dim itself carries, so an unlit top
     face outshone a lit bottom one and progress became unreadable. */
  background: #1a294d;
  content: '';
  -webkit-mask: url('/symbols/crypto_05_chainlink_blue.svg') center / contain no-repeat;
  mask: url('/symbols/crypto_05_chainlink_blue.svg') center / contain no-repeat;
  opacity: 0.68;
  filter:
    drop-shadow(0 -1px 0 rgba(0, 0, 0, 0.88))
    drop-shadow(0 1px 0 rgba(77, 105, 166, 0.14));
}

/* The letters themselves are the module's white LED — no badge or white disc
   behind them. They stay invisible at rest and while the key is merely
   processing tickets. Only the live jackpot draw energises this VRF legend. */
body.layout-basic .jackpot-hero__machine replay-panel .jackpot-chainlink__core {
  position: absolute;
  z-index: 3;
  inset: 34% 19%;
  display: grid;
  place-items: center;
  border: 0;
  background: transparent;
  color: transparent;
  box-shadow: none;
  font: 950 clamp(0.3rem, 0.95cqi, 0.42rem)/1 var(--font-display, "Inter", system-ui, sans-serif);
  letter-spacing: 0.08em;
  text-indent: 0.08em;
  opacity: 0;
  text-shadow: none;
  transition: color 160ms ease, filter 160ms ease, opacity 160ms ease, text-shadow 160ms ease;
}

body.layout-basic .jackpot-hero__machine replay-panel[single-button] .jackpot-chainlink {
  display: block;
}

body.layout-basic .jackpot-hero__machine replay-panel .jackpot-chainlink--right {
  left: calc(100% + var(--jp-chainlink-gap));
}

/* Each cell is the full mark, narrowed to the wedge that owns one side of the
   hexagon. The wedges are measured off the artwork, not guessed: inside the
   -18..18 viewBox the ring's centre lands at 49.82% / 49.64% and its six
   vertices sit at 30-degree intervals on a 38.85% radius, so a side occupies a
   60-degree sector about that centre. The sectors BUTT: no narrowing, no
   engraved joints. Brightness alone segments the mark, so at any step it reads
   as one clean Chainlink logo part lit and part dim, and fully lit it is the
   unbroken canonical mark.

   The wedge is a SECOND MASK LAYER, not a clip-path, and that is the fix for
   the corner the fill kept overhanging. clip-path is a path in the element's
   own box while the artwork is a rasterised mask image, and Chrome snaps the
   mask raster to whole pixels while it does not snap the path. This module is
   positioned off a fluid, container-query-sized row, so its box lands on a
   FRACTIONAL x (531.42px at 1440 wide), and the two disagreed by however much
   that fraction was: measured across a range of sub-pixel offsets the cut
   wandered from 1.50% of the box short of the vertex to 0.30% past it, a swing
   of about 0.58px. Past the vertex is the direction that reads broken, and no
   constant angle can correct an error that changes with the layout. Composing
   the sector INTO the mask puts both in the same coordinate space, so they
   snap together: across the same offsets the seam does not move at all.

   Each wedge is the intersection of TWO HALF-PLANES with the artwork, and the
   half-planes are linear gradients rather than one conic sector on purpose. A
   conic sector's edges must both pass through its centre, so biasing an edge
   can only ROTATE it — which tilts a seam off the corner miter it is supposed
   to run along. On the two vertical seams that tilt was visible as a
   stair-step: a 250px edge leaning 0.75 degrees drifts about 0.7px sideways,
   crosses a pixel boundary partway down, and rasterises with a notch in it. A
   half-plane boundary can be moved PARALLEL to itself, so the bias is now an
   inward offset and every cut stays exactly on its 60-degree meridian. The
   vertical seams get gradient angles of exactly 90 and 270 degrees, whose
   iso-lines are exactly vertical, and a straight edge cannot step.
   The offset is also better geometry than the rotation was: the ring's inner
   and outer vertices sit on the same radial, so the corner miter IS that
   meridian. A parallel cut stays parallel to the miter and surrenders a
   constant-width sliver; a rotated one opened into a wedge that gave back more
   the further out it went.

   Seam overlap is DIRECTIONAL, and that is the other half. A symmetric overrun
   put a lit sliver past the vertex on the LEADING edge too, so the frontier of
   a part-filled ring overhung its corner. Overlap now goes only into the
   neighbour that is ALREADY LIT when a link fires, where it is lit-on-lit and
   can never print: those edges are pushed 2% of the box OUTWARD. Every EXPOSED
   edge is pulled 0.45% of the box INWARD. At 28-38px a whole corner of the ring
   is two or three device pixels, so an edge sitting exactly on the miter still
   antialiases into the first pixel of the dark face; short cannot make that
   mistake. The dim standby ring sits under every cell, so an undershoot
   surrenders a sliver of lit back to dim and still reads as a corner, while an
   overshoot reads as broken. Outward beats inward by 2.00 to 0.45, which is
   what guarantees the closed ring carries no dim seam anywhere.
   The fill is flat so a link reads equally bright wherever it sits. */
body.layout-basic .jackpot-hero__machine replay-panel .jackpot-chainlink__cell {
  position: absolute;
  inset: 5%;
  box-sizing: border-box;
  width: auto;
  height: auto;
  border: 0;
  border-radius: 0;
  /* The per-link rules below supply all four of these; the test pins all six
     links. These defaults exist only so a link that ever lost them degrades to
     an unsegmented mark — visibly wrong and obvious — rather than to a blue
     square (no mask) or to nothing at all (two half-planes that miss). */
  --jp-link-a-angle: 270deg;
  --jp-link-a-stop: 100%;
  --jp-link-b-angle: 90deg;
  --jp-link-b-stop: 100%;
  /* Chrome does NOT antialias a gradient hard stop here, so the four diagonal
     seams came out as a bare 1px staircase. This is the smallest feather that
     resolves that staircase while leaving the two VERTICAL seams a single
     crisp transition pixel — measured at 10x, 0.15px smears the cut into a
     three-pixel ramp and stops reading as an edge, 0.06px does not. It is
     symmetric about the stop, so the 50% crossing stays exactly on the biased
     line and the edge cannot creep past its corner. In px, so it stays
     sub-pixel at real size and only resolves once someone zooms in. */
  --jp-link-feather: 0.06px;
  /* Flat, not graded. The mark's own modelling used to fight the segmentation:
     a lit link on a dark face read dimmer than an unlit link on a light face,
     so a part-filled ring looked broken rather than part-filled. Lit is one
     LED blue everywhere, dim is one dim blue everywhere, and the only thing
     that varies across the instrument is whether a link is on. */
  background: #6f9bf2;
  box-shadow: none;
  -webkit-mask:
    url('/symbols/crypto_05_chainlink_blue.svg') center / contain no-repeat,
    linear-gradient(
      var(--jp-link-a-angle),
      #000 calc(var(--jp-link-a-stop) - var(--jp-link-feather)),
      transparent calc(var(--jp-link-a-stop) + var(--jp-link-feather))
    ) center / 100% 100% no-repeat,
    linear-gradient(
      var(--jp-link-b-angle),
      #000 calc(var(--jp-link-b-stop) - var(--jp-link-feather)),
      transparent calc(var(--jp-link-b-stop) + var(--jp-link-feather))
    ) center / 100% 100% no-repeat;
  mask:
    url('/symbols/crypto_05_chainlink_blue.svg') center / contain no-repeat,
    linear-gradient(
      var(--jp-link-a-angle),
      #000 calc(var(--jp-link-a-stop) - var(--jp-link-feather)),
      transparent calc(var(--jp-link-a-stop) + var(--jp-link-feather))
    ) center / 100% 100% no-repeat,
    linear-gradient(
      var(--jp-link-b-angle),
      #000 calc(var(--jp-link-b-stop) - var(--jp-link-feather)),
      transparent calc(var(--jp-link-b-stop) + var(--jp-link-feather))
    ) center / 100% 100% no-repeat;
  /* Must follow the shorthands: `mask` resets the compositing operator, and
     without the intersect the three layers ADD and every link is the whole
     mark. Each layer intersects the accumulated result below it, so this is the
     artwork AND half-plane A AND half-plane B. */
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
  opacity: 0;
  transform: none;
  transition: opacity 260ms ease;
}

/* The chain runs LIKE A CLOCK: link 1 starts at the top vertex, 12 o'clock,
   and each later link is the next side clockwise, so the lit region is always
   ONE arc sweeping the way a hand sweeps. Link 6 closes the ring back onto the
   top vertex, so the mark completes where it started.

   `a` is the trailing edge, `b` is the leading edge. Each is a gradient angle
   plus the stop where that gradient turns off, which together place a straight
   boundary at a chosen angle AND a chosen distance. The angles are all whole
   multiples of 30 because every cut lies exactly on a vertex meridian — that
   exactness is the anti-jag property, and the test asserts it rather than
   trusting the numbers below. 90deg and 270deg are the two vertical seams.
   The stops are not readable by eye; they are generated (BIAS 0.45% inward on
   an exposed edge, OVERLAP 2% outward on an edge that lands on lit material)
   and the test recovers both back out of the pair.
   Link 1 has nothing lit behind it, so BOTH its edges are exposed. Link 6
   lands on lit material at both ends and is the only link that overruns twice.
   Note the artwork itself is not quite regular: its outer bottom vertex sits
   at local x 19.0 where every other landmark centres on 18.9, so the seam at
   6 o'clock sits a further 0.18% of the box to the short side. */
body.layout-basic .jackpot-hero__machine replay-panel .jackpot-chainlink__cell--1 {
  --jp-link-a-angle: 270deg;
  --jp-link-a-stop: 49.73%;
  --jp-link-b-angle: 150deg;
  --jp-link-b-stop: 49.3765%;
}
body.layout-basic .jackpot-hero__machine replay-panel .jackpot-chainlink__cell--2 {
  --jp-link-a-angle: 330deg;
  --jp-link-a-stop: 51.7582%;
  --jp-link-b-angle: 210deg;
  --jp-link-b-stop: 49.5082%;
}
body.layout-basic .jackpot-hero__machine replay-panel .jackpot-chainlink__cell--3 {
  --jp-link-a-angle: 30deg;
  --jp-link-a-stop: 51.6264%;
  --jp-link-b-angle: 270deg;
  --jp-link-b-stop: 49.73%;
}
body.layout-basic .jackpot-hero__machine replay-panel .jackpot-chainlink__cell--4 {
  --jp-link-a-angle: 90deg;
  --jp-link-a-stop: 51.82%;
  --jp-link-b-angle: 330deg;
  --jp-link-b-stop: 49.9647%;
}
body.layout-basic .jackpot-hero__machine replay-panel .jackpot-chainlink__cell--5 {
  --jp-link-a-angle: 150deg;
  --jp-link-a-stop: 51.17%;
  --jp-link-b-angle: 30deg;
  --jp-link-b-stop: 49.8329%;
}
body.layout-basic .jackpot-hero__machine replay-panel .jackpot-chainlink__cell--6 {
  --jp-link-a-angle: 210deg;
  --jp-link-a-stop: 51.3018%;
  --jp-link-b-angle: 90deg;
  --jp-link-b-stop: 51.82%;
}

/* Restore the original pending-RNG fill: a real request assembles five sides
   once, in clockwise order, across the expected confirmation window. Each
   completed side stays on; this is elapsed-wait progress, not an endless
   spinner. The sixth side belongs to the arrival event and cannot be filled
   merely because more time passed. */
body.layout-basic .jackpot-hero__machine replay-panel .replay-controls:has(
  > .replay-reveal-btn.is-processing[data-jp-rng-requested][data-jp-stage='rng']
) .jackpot-chainlink__cell--1 { animation: jackpot-chainlink-cell-charge 240ms ease-out 0s both; }
body.layout-basic .jackpot-hero__machine replay-panel .replay-controls:has(
  > .replay-reveal-btn.is-processing[data-jp-rng-requested][data-jp-stage='rng']
) .jackpot-chainlink__cell--2 { animation: jackpot-chainlink-cell-charge 240ms ease-out 4s both; }
body.layout-basic .jackpot-hero__machine replay-panel .replay-controls:has(
  > .replay-reveal-btn.is-processing[data-jp-rng-requested][data-jp-stage='rng']
) .jackpot-chainlink__cell--3 { animation: jackpot-chainlink-cell-charge 240ms ease-out 8s both; }
body.layout-basic .jackpot-hero__machine replay-panel .replay-controls:has(
  > .replay-reveal-btn.is-processing[data-jp-rng-requested][data-jp-stage='rng']
) .jackpot-chainlink__cell--4 { animation: jackpot-chainlink-cell-charge 240ms ease-out 12s both; }
body.layout-basic .jackpot-hero__machine replay-panel .replay-controls:has(
  > .replay-reveal-btn.is-processing[data-jp-rng-requested][data-jp-stage='rng']
) .jackpot-chainlink__cell--5 { animation: jackpot-chainlink-cell-charge 240ms ease-out 16s both; }

/* Arrival closes the sixth side. While the resolved word is being consumed,
   the logo remains fully lit beside the white VRF legend; motion belongs to
   the two outbound leads and the board routes, not to another ring spinner. */
body.layout-basic .jackpot-hero__machine replay-panel .replay-controls:has(
  > .replay-reveal-btn.is-processing[data-jp-stage='rng-arrived']
) .jackpot-chainlink__cell,
body.layout-basic .jackpot-hero__machine replay-panel .replay-controls:has(
  > .replay-reveal-btn.is-spinning
) .jackpot-chainlink__cell {
  background: radial-gradient(circle at 49.82% 49.64%, #a8c2fb 0%, #4d75df 62%, #24499f 100%);
  opacity: 1;
  filter: none;
  animation: none;
}

body.layout-basic .jackpot-hero__machine replay-panel .replay-controls:has(
  > .replay-reveal-btn.is-spinning
) .jackpot-chainlink {
  border-color: #506058;
  filter: none;
}

body.layout-basic .jackpot-hero__machine replay-panel .replay-controls:has(
  > .replay-reveal-btn.is-spinning
) .jackpot-chainlink__pins {
  filter: drop-shadow(0 0 1.5px rgba(111, 155, 242, 0.38));
  opacity: 0.86;
}

body.layout-basic .jackpot-hero__machine replay-panel .replay-controls:has(
  > .replay-reveal-btn.is-spinning
) .jackpot-chainlink__core {
  color: #fff;
  opacity: 1;
  text-shadow:
    0 0 2px #fff,
    0 0 6px rgba(255, 255, 255, 0.96),
    0 0 12px rgba(92, 143, 255, 0.9);
  animation: jackpot-vrf-core 1.44s cubic-bezier(0.2, 0.72, 0.26, 1) infinite;
}

/* The response closes the pending fill with one restrained acknowledgement.
   The processing stage holds this state briefly, then removes it as the
   pipeline moves on, so this cannot turn into another ambient loop. */
body.layout-basic .jackpot-hero__machine replay-panel .replay-controls:has(
  > .replay-reveal-btn.is-processing[data-jp-stage='rng-arrived']
) .jackpot-chainlink {
  animation: jackpot-chainlink-closed 720ms cubic-bezier(0.2, 1.4, 0.34, 1) both;
}

/* While the reels are actually turning, this module is the board's power
   source, not a request status light. Its shell answers on the same 1.44s
   clock as the white VRF core and the four upward board routes while the
   completed blue mark itself stays steadily lit.
   The old pair used to BLOOM: a 30px halo on the plate plus a 5px drop-shadow, pulsing
   on a 1.05s clock. During a draw that is the brightest thing on the board and
   it competes with the reels and the SPIN key for the eye, which is backwards —
   the module is the supply, not the event. What is left is a slight pulse on
   a slow clock: the mark itself breathes, the plate around it does not light
   up. The power CURRENT leaving the module is unchanged; only the module's own
   glow is tamed. */
body.layout-basic .jackpot-hero__machine replay-panel .replay-controls:has(
  > .replay-reveal-btn.is-spinning
) .jackpot-chainlink {
  box-shadow:
    inset 0 1px 0 rgba(240, 248, 244, 0.055),
    inset 1px 0 0 rgba(223, 233, 228, 0.02),
    inset 0 -1px 0 rgba(0, 0, 0, 0.95),
    inset 0 0 0 2px rgba(0, 0, 0, 0.34),
    0 0 0 1px rgba(0, 0, 0, 0.72),
    0 3px 6px -2px rgba(0, 0, 0, 0.92);
  filter: none;
  animation: jackpot-chainlink-source 1.44s ease-in-out infinite;
}

@keyframes jackpot-chainlink-cell-charge {
  0% { opacity: 0; }
  55% { opacity: 1; filter: brightness(1.5); }
  100% { opacity: 1; filter: brightness(1); }
}

@keyframes jackpot-chainlink-closed {
  0% { filter: brightness(1); }
  45% {
    filter: brightness(1.18) drop-shadow(0 0 3px rgba(104, 151, 239, 0.38));
  }
  100% { filter: brightness(1); }
}

/* A breath, not a beacon: the mark lifts about a tenth in brightness and the
   halo stays inside 3px, so the module reads as live without ever becoming the
   brightest thing on a board that is mid-draw. No box-shadow in here at all —
   animating it was what put light on the plate. */
@keyframes jackpot-chainlink-source {
  0%, 100% {
    filter: brightness(1);
  }
  18% {
    filter: brightness(1.1);
  }
  46% {
    filter: brightness(1.03);
  }
}

@keyframes jackpot-vrf-core {
  0%, 100% {
    opacity: 0.58;
    filter: brightness(0.9);
  }
  16% {
    opacity: 1;
    filter: brightness(1.32);
    text-shadow:
      0 0 3px #fff,
      0 0 8px #fff,
      0 0 16px rgba(92, 143, 255, 0.98);
  }
  44% {
    opacity: 0.76;
    filter: brightness(1.04);
  }
}

body.layout-basic .jackpot-hero__machine replay-panel .replay-controls > .replay-reveal-btn,
body.layout-basic .jackpot-hero__machine replay-panel .replay-controls > .ldj-results-cta {
  --jp-led-a: 255, 63, 122;
  --jp-led-b: 255, 201, 79;
  --jp-led-c: 75, 225, 255;
  box-sizing: border-box;
  height: 100%;
  min-height: 0;
  border: 1px solid #353237;
  border-radius: 7px;
  background:
    radial-gradient(90% 170% at 50% 50%, rgba(111, 104, 113, 0.045), transparent 72%),
    linear-gradient(180deg, #111014 0%, #070609 100%);
  background-color: #070609;
  color: #68636b;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.045),
    inset 0 0 0 1px #030204,
    inset 0 0 13px #000;
  clip-path: none;
  font-family: var(--font-display, "Inter", system-ui, sans-serif);
  font-variant-numeric: tabular-nums;
  font-weight: 950;
  font-size: clamp(0.69rem, 2.7cqi, 0.82rem);
  letter-spacing: 0.105em;
  text-shadow: none;
  opacity: 1;
  transition: box-shadow 140ms ease, color 140ms ease, filter 140ms ease;
}

/* Author-level display:flex/grid rules otherwise beat the browser's built-in
   [hidden] stylesheet. The physical LED key can have exactly one owner. */
body.layout-basic .jackpot-hero__machine replay-panel .replay-controls > .replay-reveal-btn[hidden],
body.layout-basic .jackpot-hero__machine replay-panel .replay-controls > .ldj-results-cta[hidden] {
  display: none !important;
}

body.layout-basic .jackpot-hero__machine replay-panel .replay-reveal-btn::before {
  width: 1.18rem;
  height: 0.46rem;
  border: 0;
  border-radius: 999px;
  background:
    radial-gradient(circle at 12% 50%, #39353b 0 0.13rem, transparent 0.15rem),
    radial-gradient(circle at 50% 50%, #39353b 0 0.13rem, transparent 0.15rem),
    radial-gradient(circle at 88% 50%, #39353b 0 0.13rem, transparent 0.15rem);
  box-shadow: none;
  filter: none;
  -webkit-mask: none;
  mask: none;
}

body.layout-basic .jackpot-hero__machine replay-panel .replay-reveal-btn:not(:disabled),
body.layout-basic .jackpot-hero__machine replay-panel .replay-reveal-btn.is-processing,
body.layout-basic .jackpot-hero__machine replay-panel .replay-reveal-btn.is-spinning,
body.layout-basic .jackpot-hero__machine replay-panel .replay-controls > .ldj-results-cta {
  border-color: transparent;
  background:
    radial-gradient(circle at 8% 40%, rgba(var(--jp-led-a), 0.42), transparent 34%) padding-box,
    radial-gradient(circle at 91% 55%, rgba(var(--jp-led-c), 0.36), transparent 37%) padding-box,
    linear-gradient(105deg, rgba(43, 5, 31, 0.98), rgba(52, 25, 8, 0.96) 49%, rgba(3, 29, 38, 0.98)) padding-box,
    linear-gradient(102deg, rgb(var(--jp-led-a)), rgb(var(--jp-led-b)) 48%, rgb(var(--jp-led-c))) border-box;
  background-color: transparent;
  color: #fffaf0;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.2),
    inset 0 -2px 0 rgba(0, 0, 0, 0.5),
    0 0 9px rgba(var(--jp-led-a), 0.28),
    0 0 17px rgba(var(--jp-led-c), 0.16);
  text-shadow:
    0 0 5px rgba(var(--jp-led-b), 0.72),
    -2px 0 10px rgba(var(--jp-led-a), 0.32),
    2px 0 10px rgba(var(--jp-led-c), 0.3);
  opacity: 1;
}

body.layout-basic .jackpot-hero__machine replay-panel .replay-reveal-btn:not(:disabled)::before,
body.layout-basic .jackpot-hero__machine replay-panel .replay-reveal-btn.is-processing::before,
body.layout-basic .jackpot-hero__machine replay-panel .replay-reveal-btn.is-spinning::before {
  border-color: transparent;
  background:
    radial-gradient(circle at 12% 50%, rgb(var(--jp-led-a)) 0 0.13rem, transparent 0.15rem),
    radial-gradient(circle at 50% 50%, rgb(var(--jp-led-b)) 0 0.13rem, transparent 0.15rem),
    radial-gradient(circle at 88% 50%, rgb(var(--jp-led-c)) 0 0.13rem, transparent 0.15rem);
  box-shadow: none;
  filter:
    drop-shadow(-0.18rem 0 4px rgba(var(--jp-led-a), 0.62))
    drop-shadow(0.18rem 0 4px rgba(var(--jp-led-c), 0.58));
}

/* A key waiting for the player runs the cabinet's attract loop. Three LED
   colours are always visible at once, while the halo hands emphasis from the
   warm side to the cool side and a soft rainbow glint crosses the face.
   Processing and spinning keep their steady panes. */
body.layout-basic .jackpot-hero__machine replay-panel .replay-controls
  > .replay-reveal-btn:not(:disabled):not(.is-processing):not(.is-spinning),
body.layout-basic .jackpot-hero__machine replay-panel .replay-controls > .ldj-results-cta {
  position: relative;
  overflow: hidden;
  animation: jackpot-key-attract 2.8s ease-in-out infinite;
}

body.layout-basic .jackpot-hero__machine replay-panel .replay-reveal-btn.is-bonus {
  --jp-led-a: 244, 114, 182;
  --jp-led-b: 255, 214, 92;
  --jp-led-c: 167, 139, 250;
}

@keyframes jackpot-key-attract {
  0%, 100% {
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.2),
      inset 0 -2px 0 rgba(0, 0, 0, 0.5),
      0 0 9px rgba(var(--jp-led-a), 0.28),
      0 0 17px rgba(var(--jp-led-c), 0.12);
  }
  50% {
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.25),
      inset 0 -2px 0 rgba(0, 0, 0, 0.45),
      0 0 12px rgba(var(--jp-led-b), 0.34),
      0 0 22px rgba(var(--jp-led-c), 0.24);
  }
}

/* Move a painted glint layer instead of repainting its background each frame.
   The layer is 2.6 times the face width: -80% and 18.461538% put it at the
   same offsets as the old 130% and -30% background positions. Its resting
   position stays off the face for reduced motion and hover. */
body.layout-basic .jackpot-hero__machine replay-panel .replay-controls
  > .replay-reveal-btn:not(:disabled):not(.is-processing):not(.is-spinning)::after,
body.layout-basic .jackpot-hero__machine replay-panel .replay-controls > .ldj-results-cta::after {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 260%;
  border-radius: 1px;
  background:
    linear-gradient(112deg,
      transparent 0 36%,
      rgba(var(--jp-led-a), 0.16) 44%,
      rgba(var(--jp-led-b), 0.24) 49%,
      rgba(255, 255, 255, 0.22) 51%,
      rgba(var(--jp-led-c), 0.18) 56%,
      transparent 64% 100%)
    0 0 / 100% 100% no-repeat;
  transform: translateX(-80%);
  animation: jackpot-key-sheen 2.8s ease-in-out infinite;
  pointer-events: none;
}

@keyframes jackpot-key-sheen {
  0%, 18% { transform: translateX(-80%); }
  62%, 100% { transform: translateX(18.461538%); }
}

/* Under the pointer the key answers steadily: the attract loop yields to the
   hover glow so the player's own focus is never argued with. */
body.layout-basic .jackpot-hero__machine replay-panel .replay-reveal-btn:hover:not(:disabled),
body.layout-basic .jackpot-hero__machine replay-panel .replay-reveal-btn:focus-visible,
body.layout-basic .jackpot-hero__machine replay-panel .ldj-results-cta:hover,
body.layout-basic .jackpot-hero__machine replay-panel .ldj-results-cta:focus-visible,
body.layout-basic .jackpot-hero__machine replay-panel .replay-reveal-btn:hover:not(:disabled)::after,
body.layout-basic .jackpot-hero__machine replay-panel .replay-reveal-btn:focus-visible::after,
body.layout-basic .jackpot-hero__machine replay-panel .ldj-results-cta:hover::after,
body.layout-basic .jackpot-hero__machine replay-panel .ldj-results-cta:focus-visible::after {
  /* The armed rule includes three :not() states, giving it more specificity
     than hover/focus. These interaction states must still stop the loop. */
  animation: none !important;
}

/* While the key is naming the crank, its indicator is a pickaxe.
   The glyph is otherwise keyed off data-jp-stage, and those stage rules paint
   full-colour picture icons into this socket — the coinflip stage puts an ETH
   coin face there, which is what a player reads next to MINE FLIP. This is a
   mask, not a background image, so the mark takes the LED bank's bright middle
   colour rather than arriving as a separate picture badge.

   SPECIFICITY IS LOAD-BEARING: jackpot-processing.css loads AFTER this sheet
   and its `[data-jp-stage="…"]::before` rules are (0,5,3). The extra
   `.replay-controls >` here makes this (0,6,3) so it wins outright instead of
   depending on source order, and `content` is restated because the RNG stages
   set `content: none` and would otherwise delete the element entirely. */
body.layout-basic .jackpot-hero__machine replay-panel .replay-controls
  > .replay-reveal-btn.is-processing[data-jp-action="mine-flip"]::before {
  content: "";
  width: 0.95rem;
  height: 0.95rem;
  border: 0;
  border-radius: 0;
  background: rgb(var(--jp-led-b));
  -webkit-mask: url('/app/assets/jackpot-stage-mine.svg') center / contain no-repeat;
  mask: url('/app/assets/jackpot-stage-mine.svg') center / contain no-repeat;
  /* box-shadow would trace the element box straight through the mask, so the
     glow has to be a drop-shadow of the masked shape. */
  box-shadow: none;
  filter: drop-shadow(0 0 4px rgba(var(--jp-led-b), 0.62));
}

body.layout-basic .jackpot-hero__machine replay-panel .replay-reveal-btn:hover:not(:disabled),
body.layout-basic .jackpot-hero__machine replay-panel .replay-reveal-btn:focus-visible,
body.layout-basic .jackpot-hero__machine replay-panel .ldj-results-cta:hover,
body.layout-basic .jackpot-hero__machine replay-panel .ldj-results-cta:focus-visible {
  border-color: transparent;
  filter: brightness(1.11) saturate(1.1);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.28),
    inset 0 -2px 0 rgba(0, 0, 0, 0.42),
    0 0 13px rgba(var(--jp-led-a), 0.35),
    0 0 22px rgba(var(--jp-led-c), 0.24);
  transform: none !important;
}

/* Pressing the key dips the LED bank and pushes the face into the bezel. */
body.layout-basic .jackpot-hero__machine replay-panel .replay-controls > .replay-reveal-btn:active:not(:disabled),
body.layout-basic .jackpot-hero__machine replay-panel .replay-controls > .ldj-results-cta:active {
  border-color: transparent;
  filter: brightness(0.74) saturate(0.9);
  box-shadow:
    inset 0 3px 8px rgba(0, 0, 0, 0.95),
    inset 0 0 20px rgba(0, 0, 0, 0.88),
    0 0 4px rgba(var(--jp-led-b), 0.14);
  transform: none !important;
}

/* Keyboard focus takes the cool LED colour; hover glows without drawing a
   ring, so the two states stay tellable apart. */
body.layout-basic .jackpot-hero__machine replay-panel .replay-controls > .replay-reveal-btn:focus-visible,
body.layout-basic .jackpot-hero__machine replay-panel .replay-controls > .ldj-results-cta:focus-visible {
  outline: 2px solid rgba(var(--jp-led-c), 0.92);
  outline-offset: 2px;
}

body.layout-basic .jackpot-hero__machine replay-panel .replay-reveal-btn.is-bonus {
  --jp-led-a: 244, 114, 182;
  --jp-led-b: 255, 214, 92;
  --jp-led-c: 167, 139, 250;
}

body.layout-basic .jackpot-hero__machine replay-panel .replay-reveal-btn.is-coinflip {
  --jp-led-a: 34, 211, 238;
  --jp-led-b: 52, 211, 153;
  --jp-led-c: 129, 140, 248;
}

body.layout-basic .jackpot-hero__machine replay-panel .replay-reveal-btn.is-craps {
  --jp-led-a: 52, 211, 153;
  --jp-led-b: 255, 214, 92;
  --jp-led-c: 16, 185, 129;
}

body.layout-basic .jackpot-hero__machine replay-panel .replay-reveal-btn.is-decimator {
  --jp-led-a: 255, 70, 95;
  --jp-led-b: 255, 189, 54;
  --jp-led-c: 94, 234, 212;
}

body.layout-basic .jackpot-hero__machine replay-panel .replay-reveal-btn:disabled:not(.is-processing):not(.is-spinning) {
  border-color: #353237;
  background:
    radial-gradient(90% 170% at 50% 50%, rgba(111, 104, 113, 0.045), transparent 72%),
    linear-gradient(180deg, #111014 0%, #070609 100%);
  background-color: #070609;
  color: #68636b;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.045),
    inset 0 0 0 1px #030204,
    inset 0 0 13px #000;
  text-shadow: none;
  opacity: 1;
}

/* The routing layer is locked to the same measured grid as the four live
   sockets. Four traces enter every socket—one for each foil quadrant—running
   clean into the socket edge. Every exposed route ends on a real part: the
   outer feeds bond to the perimeter ground rail at a plated via, the inner
   feeds tap the processor bus. No lane runs to the cabinet edge. */
body.layout-basic .jackpot-hero__machine .ldj-foil-machine-bank {
  background: url('/app/assets/jackpot/daily-drawing-foil-routing-v5.svg') center / 100% 100% no-repeat;
}

/* The bank's current sheet: the same sixteen feeds as the copper above it,
   inline in the bank so the page owns them (the markup carries why it is not a
   background like every other sheet). It is stretched over exactly the box the
   copper is stretched over — same element, same 1372x1000 viewBox, same
   non-uniform stretch — so a lit lane lands on its own trace in both layouts.

   It paints after the sockets on purpose. No lane enters a socket: each one
   terminates on the socket edge, and the sockets are opaque, so the only thing
   this puts over a seated card is the last pixel or two of glow at the rim,
   which is the arrival it exists to show. */
body.layout-basic .jackpot-hero__machine .ldj-foil-machine-current {
  position: absolute;
  z-index: 4;
  inset: 0;
  width: 100%;
  height: 100%;
  filter: drop-shadow(0 0 2px rgba(103, 232, 249, 0.1));
  opacity: 0;
  pointer-events: none;
  transition: opacity 200ms ease;
}

/* The whole sheet is dark until the machine is under load. The drawing is the
   one moment the bank is being fed, and it draws on the same beat as the board
   and never louder: the board sheet drives at 0.82-1.0, this at 0.5-0.7, so the
   seated hardware reads as something the machine is powering rather than as a
   second headline beside the board and the SPIN key. */
body.layout-basic .jackpot-hero__machine:has(replay-panel .replay-reveal-btn.is-spinning)
  .ldj-foil-machine-current {
  opacity: 0.4;
  animation: jackpot-foil-current-drive 1.9s ease-in-out infinite;
}

@keyframes jackpot-foil-current-drive {
  0%, 100% { opacity: 0.32; filter: drop-shadow(0 0 2px rgba(103, 232, 249, 0.1)); }
  50% { opacity: 0.44; filter: drop-shadow(0 0 3px rgba(120, 172, 255, 0.18)); }
}

/* A socket's four feeds carry current only while a ticket is seated in it. An
   empty bay's lanes are dead copper in every state, so a spinning bank reports
   what the player actually holds instead of lighting a symmetrical decoration.

   The socket order is the grid placement in app.css, not a guess: nth-child(1)
   is column 1 row 1 (upper left), (2) column 1 row 2 (lower left), (3) column 5
   row 1 (upper right), (4) column 5 row 2 (lower right). The four lane groups
   are authored in that same order, which is also the order the copper sheet
   authors its sockets in. */
body.layout-basic .jackpot-hero__machine .ldj-foil-lane {
  fill: none;
  opacity: 0;
  transition: opacity 200ms ease;
}

body.layout-basic .jackpot-hero__machine .ldj-foil-lane path {
  stroke-width: 2.8;
  stroke-opacity: 0.78;
  stroke-linecap: square;
  stroke-linejoin: miter;
  /* The bank stretches non-uniformly, so a scaled stroke would render the
     horizontal stubs at a different weight from the vertical runs. This is the
     same effect the copper sheet uses, for the same reason. */
  vector-effect: non-scaling-stroke;
  /* 30px of period in 1.05s is 28.5 px/s — the same travel rate as the board
     sheet's 62px in 2.2s, so the two halves of the flow system move as one. The
     period is shorter than the board's because these lanes are only ~50px long
     on screen; at the board's 16/46 a foil lane would be empty most of the
     time. Every path is authored source-first, leaving the draw processor's own
     edge and ending on a socket edge, and the offset only ever decreases — so
     the flow is always board -> socket, and nothing here travels away from a
     seated card or in from the frame. */
  stroke-dasharray: 9 21;
  animation: ldj-foil-lane-flow 1.05s linear infinite;
  /* Occupied sockets retain their lanes between drawings, when the entire
     current sheet has opacity 0. Pause unless BOTH the socket is occupied and
     the drawing is running; invisible stroke animation still costs main-thread
     style work every frame. ambient-motion.js also parks an offscreen sheet. */
  animation-play-state: paused;
}

@keyframes ldj-foil-lane-flow {
  to { stroke-dashoffset: -30; }
}

body.layout-basic .jackpot-hero__machine
  .ldj-foil-machine-bank:has(.ldj-foil-machine-slot:nth-child(1).is-loaded) .ldj-foil-lane--1,
body.layout-basic .jackpot-hero__machine
  .ldj-foil-machine-bank:has(.ldj-foil-machine-slot:nth-child(2).is-loaded) .ldj-foil-lane--2,
body.layout-basic .jackpot-hero__machine
  .ldj-foil-machine-bank:has(.ldj-foil-machine-slot:nth-child(3).is-loaded) .ldj-foil-lane--3,
body.layout-basic .jackpot-hero__machine
  .ldj-foil-machine-bank:has(.ldj-foil-machine-slot:nth-child(4).is-loaded) .ldj-foil-lane--4 {
  opacity: 1;
}

body.layout-basic .jackpot-hero__machine:has(replay-panel .replay-reveal-btn.is-spinning)
  .ldj-foil-machine-bank:has(.ldj-foil-machine-slot:nth-child(1).is-loaded) .ldj-foil-lane--1 path,
body.layout-basic .jackpot-hero__machine:has(replay-panel .replay-reveal-btn.is-spinning)
  .ldj-foil-machine-bank:has(.ldj-foil-machine-slot:nth-child(2).is-loaded) .ldj-foil-lane--2 path,
body.layout-basic .jackpot-hero__machine:has(replay-panel .replay-reveal-btn.is-spinning)
  .ldj-foil-machine-bank:has(.ldj-foil-machine-slot:nth-child(3).is-loaded) .ldj-foil-lane--3 path,
body.layout-basic .jackpot-hero__machine:has(replay-panel .replay-reveal-btn.is-spinning)
  .ldj-foil-machine-bank:has(.ldj-foil-machine-slot:nth-child(4).is-loaded) .ldj-foil-lane--4 path {
  animation-play-state: running;
}

body.layout-basic .jackpot-hero__machine replay-panel .replay-controls > .ldj-results-cta::before,
body.layout-basic .jackpot-hero__machine replay-panel .replay-controls > .ldj-results-cta::after {
  content: none;
}

body.layout-basic .jackpot-hero__machine replay-panel .replay-hint {
  width: min(var(--jp-board-size, 18.75rem), 18rem);
  height: 1rem;
  min-height: 1rem;
  flex-basis: 1rem;
  margin: 0.12rem 0 0.08rem;
  color: #82958a;
  font: 700 clamp(0.54rem, 1.9cqi, 0.62rem)/1 ui-monospace, "SFMono-Regular", Consolas, monospace;
  letter-spacing: 0.11em;
  text-transform: uppercase;
}

body.layout-basic .jackpot-hero__machine replay-panel .replay-hint:empty {
  visibility: hidden;
}

body.layout-basic .jackpot-hero__machine replay-panel .replay-no-bonus {
  color: #718078;
  font: 700 clamp(0.52rem, 1.8cqi, 0.6rem)/1 ui-monospace, "SFMono-Regular", Consolas, monospace;
  font-style: normal;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* Foil tickets sit in actual machine sockets here. Their final background
   layer is deliberately opaque: the backplate's gold traces can route into a
   socket, but can never remain visible beneath the recessed hardware. Empty
   sockets stay empty; owned tickets keep their real foil face inside a neutral
   silver chassis. */
/* An empty socket says one thing: a ticket-shaped processor drops in here. It
   is a plain dull-silver bay — machined, lit from above, but flat and quiet,
   with no bright frame competing with the seated card that replaces it. Three
   things and nothing else: the body, the printed ticket silhouette, and the
   blank centre seal.

   Empty is the common state — most players are looking at four of these — so
   the bay is board furniture, not a feature. It is pitched to sit just above
   the laminate rather than on top of it: the dull silver is taken down to
   where an unlit machined part actually sits in this cabinet's light, and the
   rim highlights that were drawing the eye to an empty fitting are pulled to a
   whisper. Squint and the sockets go back into the board; look for one and it
   is still a bay with a lead-in chamfer and a seal. */
/* An empty bay is a hole in the plate, not a part. It gets no more attention
   than the bare laminate around it: the body sits at the board's own value
   with a green cast rather than a lighter neutral grey, and the chamfer, the
   top catch-light and the outer edge line are all taken down to where you have
   to look for the socket to find it. A seated ticket is the only thing in this
   bank allowed to be seen from across the room. */
body.layout-basic .jackpot-hero__machine .ldj-foil-machine-slot {
  justify-self: center;
  border-color: rgba(168, 173, 178, 0.04);
  border-radius: 6px;
  background:
    linear-gradient(180deg, rgba(226, 230, 234, 0.014), rgba(226, 230, 234, 0)) top / 100% 0.2rem no-repeat,
    radial-gradient(120% 62% at 50% 108%, rgba(226, 230, 234, 0.014), transparent 70%),
    linear-gradient(180deg, #080b0a 0%, #0b0e0d 58%, #0d100f 100%);
  box-shadow:
    inset 0 4px 9px rgba(0, 0, 0, 0.5),
    inset 0 -2px 5px rgba(0, 0, 0, 0.2),
    inset 0 0 0 2px rgba(9, 12, 11, 0.42),
    0 1px 0 rgba(198, 203, 208, 0.012);
}

/* The centre seal: a blank seated plate on the cavity floor. It carries no
   mark — the diamond alone is the register point where the seated ticket's own
   centre diamond will land. The house flame stays on the board silkscreen. */
body.layout-basic .jackpot-hero__machine .ldj-foil-machine-slot:not(.is-loaded)::after {
  position: absolute;
  z-index: 2;
  width: 22%;
  height: 22%;
  box-sizing: border-box;
  border: 1px solid rgba(198, 203, 209, 0.06);
  border-radius: 2px;
  background: linear-gradient(145deg, rgba(96, 101, 106, 0.08), rgba(14, 17, 16, 0.9));
  box-shadow: inset 0 0 0 1px rgba(226, 230, 234, 0.012), 0 1px 3px rgba(0, 0, 0, 0.5);
  content: '';
  transform: rotate(45deg);
}

/* The printed ticket silhouette: a stamped guide showing what fits here. Its
   outline and quadrant cross are the four-quadrant foil ticket at the exact
   footprint one occupies, so a seated card lands on its own printed shadow.
   Faint — a guide mark on the floor, never a lit element. */
body.layout-basic .jackpot-hero__machine .ldj-foil-machine-slot:not(.is-loaded)::before {
  position: absolute;
  z-index: 1;
  display: block;
  box-sizing: border-box;
  width: 76%;
  height: 76%;
  border: 1px solid rgba(214, 220, 226, 0.014);
  border-radius: 3px;
  background:
    linear-gradient(90deg, transparent calc(50% - 0.5px), rgba(214, 220, 226, 0.026) calc(50% - 0.5px), rgba(214, 220, 226, 0.026) calc(50% + 0.5px), transparent calc(50% + 0.5px)),
    linear-gradient(180deg, transparent calc(50% - 0.5px), rgba(214, 220, 226, 0.026) calc(50% - 0.5px), rgba(214, 220, 226, 0.026) calc(50% + 0.5px), transparent calc(50% + 0.5px));
  content: '';
  filter: none;
  -webkit-mask: none;
  mask: none;
}

/* Occupied: the chassis is the same dull silver as the empty bay, dropped into
   shadow by the card. It carries no signal of its own. The engaged gold strip
   is gone — every seated socket lit it, so it announced "occupied" on four
   sockets at once and said nothing about the draw. The ticket is the signal
   now, and it earns its light from the board. */
body.layout-basic .jackpot-hero__machine .ldj-foil-machine-slot.is-loaded {
  border-color: rgba(150, 156, 162, 0.5);
  background:
    linear-gradient(180deg, rgba(226, 230, 234, 0.14), rgba(226, 230, 234, 0)) top / 100% 0.16rem no-repeat,
    linear-gradient(145deg, #383b3e 0%, #16181a 56%, #2b2e30 100%);
  box-shadow:
    inset 0 2px 7px rgba(0, 0, 0, 0.72),
    inset 0 0 0 1px rgba(190, 195, 200, 0.13),
    0 1px 0 rgba(190, 195, 200, 0.12);
  transition: border-color 240ms ease, box-shadow 240ms ease;
}

/* The card itself carries no match state. Each quadrant has two independently
   readable layers instead: its metal background and its badge. That lets the
   live jackpot reels express the scoring rule directly — symbol match wakes
   only the badge; symbol + color wakes both the badge and quadrant metal.

   Every seated face starts dormant. A dark pseudo-layer holds the metal down
   without filtering the child badge; symbol and exact match classes then lift
   only the layers they earn. This separation is load-bearing: putting the
   grayscale on the cell would also grayscale its badge, making a badge-only
   lamp impossible. */
body.layout-basic .jackpot-hero__machine .ldj-foil-machine-slot.is-loaded .ldj-foil-machine-ticket {
  filter: none;
  opacity: 1;
}

body.layout-basic .jackpot-hero__machine .ldj-foil-machine-slot.is-loaded .ldj-foil-machine-cell {
  isolation: isolate;
  filter: none;
  opacity: 1;
}

body.layout-basic .jackpot-hero__machine .ldj-foil-machine-slot.is-loaded
  .ldj-foil-machine-cell::after {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: rgba(2, 5, 7, 0.76);
  box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.78);
  content: '';
  pointer-events: none;
  transition: background 180ms ease, box-shadow 180ms ease;
}

body.layout-basic .jackpot-hero__machine .ldj-foil-machine-slot.is-loaded
  .ldj-foil-machine-cell:is(.is-no-match, .is-symbol-match)::after {
  background: rgba(2, 5, 7, 0.76);
  box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.78);
}

body.layout-basic .jackpot-hero__machine .ldj-foil-machine-slot.is-loaded
  .ldj-foil-machine-cell img {
  z-index: 2;
  opacity: 0.36;
  filter: grayscale(0.86) saturate(0.26) brightness(0.56);
  transition: filter 180ms ease, opacity 180ms ease, transform 180ms ease;
}

body.layout-basic .jackpot-hero__machine .ldj-foil-machine-slot.is-loaded
  .ldj-foil-machine-cell.is-no-match img {
  opacity: 0.36;
  filter: grayscale(0.86) saturate(0.26) brightness(0.56);
}

/* +1: the symbol badge is the only lamp. The quadrant metal stays under the
   same dormant mask as a miss, so the player can read what matched at a glance. */
body.layout-basic .jackpot-hero__machine .ldj-foil-machine-slot.is-loaded
  .ldj-foil-machine-cell.is-symbol-match img {
  opacity: 1;
  filter:
    brightness(1.26)
    saturate(1.32)
    drop-shadow(0 0 2px rgba(219, 234, 254, 1))
    drop-shadow(0 0 7px rgba(96, 165, 250, 0.98));
}

/* +2: the same badge lamp plus the quadrant's own foil-metal colour proves the
   color match. The ticket already supplies the trait-specific metal variables;
   lifting the dormant mask reveals that exact surface instead of repainting
   every full match green. */
body.layout-basic .jackpot-hero__machine .ldj-foil-machine-slot.is-loaded
  .ldj-foil-machine-cell.is-color-match::after {
  background: radial-gradient(circle at 50% 48%, rgba(255, 255, 255, 0.16), transparent 68%);
  box-shadow:
    inset 0 0 0 2px var(--foil-metal-bright, #dfe7ed),
    inset 0 0 12px var(--foil-metal-glow, rgba(226, 232, 240, 0.3)),
    0 0 4px var(--foil-metal-bright, #dfe7ed),
    0 0 10px var(--foil-metal-glow, rgba(226, 232, 240, 0.3));
}
body.layout-basic .jackpot-hero__machine .ldj-foil-machine-slot.is-loaded
  .ldj-foil-machine-cell.is-color-match img {
  opacity: 1;
  filter:
    brightness(1.3)
    saturate(1.3)
    drop-shadow(0 0 2px var(--foil-metal-pale, #fff))
    drop-shadow(0 0 8px var(--foil-metal-bright, #dfe7ed));
}

/* Progress follows every painted jackpot frame. A reel stop starts this short
   lock-on pop; clearing the class leaves the durable symbol/full match state
   illuminated for the rest of the spin and settle. */
body.layout-basic .jackpot-hero__machine .ldj-foil-machine-slot.is-loaded
  .ldj-foil-machine-cell.is-match-flash img {
  animation: ldj-foil-badge-lock 640ms cubic-bezier(0.2, 0.82, 0.24, 1) both;
}
body.layout-basic .jackpot-hero__machine .ldj-foil-machine-slot.is-loaded
  .ldj-foil-machine-cell.is-color-match.is-match-flash::after {
  animation: ldj-foil-quadrant-lock 640ms ease-out both;
}

@keyframes ldj-foil-badge-lock {
  0% { transform: scale(0.78); }
  48% { transform: scale(1.13); }
  100% { transform: scale(1); }
}
@keyframes ldj-foil-quadrant-lock {
  0% { opacity: 0.22; filter: brightness(1.8); }
  56% { opacity: 1; filter: brightness(1.28); }
  100% { opacity: 1; filter: none; }
}

/* A paying, unclaimed tuple is an action—not just another grading state. The
   socket gets a warm claim-ready halo while its quadrants continue to show
   only the main draw's durable score. That distinction matters for a
   bonus-only payout: the ticket can honestly invite a claim without locking
   Roll 2's faces into the cabinet. */
body.layout-basic .jackpot-hero__machine .ldj-foil-machine-slot.is-claimable {
  pointer-events: auto;
  border-color: rgba(253, 224, 71, 0.94);
  box-shadow:
    inset 0 0 0 1px rgba(254, 249, 195, 0.3),
    inset 0 0 12px rgba(34, 197, 94, 0.2),
    0 0 7px rgba(74, 222, 128, 0.7),
    0 0 19px rgba(250, 204, 21, 0.5);
  animation: ldj-foil-claim-ready 1.25s ease-in-out infinite alternate;
}

body.layout-basic .jackpot-hero__machine
  .ldj-foil-machine-slot.is-match.is-claimable::after {
  right: auto;
  left: -0.28rem;
}

body.layout-basic .jackpot-hero__machine
  .ldj-foil-machine-ticket--claimable {
  position: relative;
  appearance: none;
  margin: 0;
  padding: 0;
  color: inherit;
  font: inherit;
  cursor: pointer;
  pointer-events: auto;
  filter:
    brightness(1.08)
    drop-shadow(0 0 5px rgba(74, 222, 128, 0.5))
    drop-shadow(0 0 9px rgba(250, 204, 21, 0.32));
  transition: filter 150ms ease, transform 150ms ease;
}

body.layout-basic .jackpot-hero__machine
  .ldj-foil-machine-ticket--claimable:hover,
body.layout-basic .jackpot-hero__machine
  .ldj-foil-machine-ticket--claimable:focus-visible {
  filter:
    brightness(1.18)
    drop-shadow(0 0 7px rgba(74, 222, 128, 0.72))
    drop-shadow(0 0 13px rgba(250, 204, 21, 0.48));
  transform: scale(1.025);
}

body.layout-basic .jackpot-hero__machine
  .ldj-foil-machine-ticket--claimable:focus-visible {
  outline: 2px solid rgba(253, 224, 71, 0.96);
  outline-offset: 2px;
}

/* Reuse the game's quest waypoint so claimable foil work reads like every
   other actionable objective. The ticket clips its foil quadrants, so the
   marker is a sibling button on the overflow-visible socket; both controls
   invoke the exact same immutable claim tuple. */
body.layout-basic .jackpot-hero__machine .ldj-foil-claim-marker {
  position: absolute;
  z-index: 7;
  top: -0.52rem;
  right: -0.48rem;
  display: block;
  width: 1.12rem;
  height: 1.12rem;
  appearance: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: url('/app/assets/quest-objective-tail-bottom-left.svg') center / contain no-repeat;
  cursor: pointer;
  filter: drop-shadow(0 0 5px rgba(250, 204, 21, 0.78));
  pointer-events: auto;
  animation: ldj-foil-claim-marker 0.92s ease-in-out infinite alternate;
}

body.layout-basic .jackpot-hero__machine .ldj-foil-claim-marker:focus-visible {
  outline: 2px solid rgba(253, 224, 71, 0.96);
  outline-offset: 2px;
}

body.layout-basic .jackpot-hero__machine .ldj-foil-machine-slot.is-claim-busy {
  cursor: wait;
  animation: none;
}

body.layout-basic .jackpot-hero__machine
  .ldj-foil-machine-slot.is-claim-busy .ldj-foil-machine-ticket--claimable {
  cursor: wait;
  opacity: 0.72;
  transform: none;
}

body.layout-basic .jackpot-hero__machine
  .ldj-foil-machine-slot.is-claim-busy .ldj-foil-claim-marker {
  opacity: 0.64;
  filter: grayscale(0.35) drop-shadow(0 0 3px rgba(250, 204, 21, 0.5));
  animation: none;
}

@keyframes ldj-foil-claim-ready {
  from { filter: brightness(0.98); }
  to { filter: brightness(1.12); }
}

@keyframes ldj-foil-claim-marker {
  from { transform: translateY(0) scale(0.96); }
  to { transform: translateY(-1px) scale(1.05); }
}

/* The centre never comes up with a hit. The quadrant is the claim; the centre
   is structure. It used to inherit the card's group fade and therefore rose
   with the card, putting a second bright object dead centre announcing the
   same hit the lit quadrant had already announced. It now states its own
   muting unconditionally — no :has(), no match state — so it is the same
   object on a card that hit nothing and on a card that hit four times.

   OPACITY IS DELIBERATELY NOT PART OF THAT MUTING, for the same reason the
   cells above are opaque: the four cells meet UNDER the centre, so a
   translucent centre lets the lit foil at that junction come up through the
   diamond and the centre stops reading as an object at all. It stays fully
   opaque, dark against the material around it, and its 1px #59616a rim — the
   same dark silver as the quadrant cross struck through the card — is what
   the bright foil stops against. That hairline is the ticket's own structure,
   so a lit quadrant ends at the centre's edge instead of crowding into it. */
body.layout-basic .jackpot-hero__machine .ldj-foil-machine-slot.is-loaded .ldj-foil-machine-center {
  filter: grayscale(0.86) saturate(0.26) brightness(0.46);
  opacity: 1;
}

body.layout-basic .jackpot-hero__machine .ldj-foil-machine-ticket {
  box-sizing: border-box;
  width: calc(100% - 0.36rem);
  height: calc(100% - 0.36rem);
  place-self: center;
  border: 1px solid #59616a;
  /* Concentric with the socket rim: the chassis is 6px over a 1px wall, so its
     inner edge turns on 5px, and the card now turns on the same 5px inside its
     own 1px wall. At 5px the card's corner read tighter than the frame it sits
     in and the quadrant art printed a hard square corner against a curve. */
  border-radius: 6px;
  box-shadow:
    inset 0 0 0 1px rgba(207, 214, 222, 0.08),
    0 1px 4px rgba(0, 0, 0, 0.68);
}

body.layout-basic .jackpot-hero__machine .ldj-foil-machine-cell {
  display: flex;
  align-items: center;
  justify-content: center;
}

/* The four corner quadrants carry the chassis corner themselves rather than
   relying on the card's overflow alone. Foil art is drawn square and oversized
   (108%), so a corner quadrant that is not clipped puts a hard square corner of
   bright foil where the frame is turning. Each cell already clips its own art,
   so giving the corner cells the card's own inner radius makes the clip
   explicit and state-proof: it holds for a plain card, a graded one and a
   winning one, and it never touches the quadrant cross lines, which are struck
   from the centre. */
body.layout-basic .jackpot-hero__machine .ldj-foil-machine-cell:nth-child(1) {
  border-top-left-radius: 5px;
}
body.layout-basic .jackpot-hero__machine .ldj-foil-machine-cell:nth-child(2) {
  border-top-right-radius: 5px;
}
body.layout-basic .jackpot-hero__machine .ldj-foil-machine-cell:nth-child(3) {
  border-bottom-left-radius: 5px;
}
body.layout-basic .jackpot-hero__machine .ldj-foil-machine-cell:nth-child(4) {
  border-bottom-right-radius: 5px;
}

body.layout-basic .jackpot-hero__machine .ldj-foil-machine-cell img {
  position: relative;
  inset: auto;
  width: 108%;
  height: 108%;
  object-position: 50% 50%;
  transform: none;
}

body.layout-basic .jackpot-hero__machine .ldj-foil-machine-ticket::before,
body.layout-basic .jackpot-hero__machine .ldj-foil-machine-ticket::after {
  background: #59616a;
  box-shadow: none;
}
body.layout-basic .jackpot-hero__machine .ldj-foil-machine-ticket::before { width: 1px; }
body.layout-basic .jackpot-hero__machine .ldj-foil-machine-ticket::after { height: 1px; }

/* The seated card keeps the ticket's real foil centre: the canonical gold face
   and the inverted flame, untouched. Only the structural LINE is the socket's,
   the same dark silver as the chassis and the quadrant cross above it. The
   per-ticket accent belongs to a full-size card, where it is a hairline around
   a wide diamond; at this scale the 2px accent ring was most of the object, so
   a red-accented ticket printed a red lozenge with a flame trapped inside it
   instead of a ticket centre. */
body.layout-basic .jackpot-hero__machine .ldj-foil-machine-center {
  width: 20%;
  height: 20%;
  border-width: 1px;
  border-color: #59616a;
  /* The gold face, its hairline and the flame are the canonical ones. Two
     things come off at this size. The canonical OUTER bloom: a card resting in
     a socket that already blooms has nothing left to say when it lights. And
     the canonical 4px white inset, which is a soft modelling highlight on a
     wide face but floods most of a 13px one — it washed the lower half of the
     diamond pale and left the flame with nothing to read against. */
  box-shadow:
    inset 0 0 0 1px rgba(111, 73, 4, 0.5),
    inset 0 1px 2px rgba(255, 255, 255, 0.6);
}

/* The centre never lights. A multi-hit card used to bloom its centre gold on
   top of everything else, which put a second, brighter claim on a card whose
   matched quadrants already say it plainly at their own normal presence. The
   seated centre is the ticket's centre in every state and nothing else. */

body.layout-basic .jackpot-hero__machine .ldj-foil-machine-center img {
  display: block;
  width: 95%;
  height: 95%;
  max-width: none;
  max-height: none;
  margin: 0;
  object-fit: contain;
  object-position: center;
  transform: rotate(-45deg);
  transform-origin: center;
}

/* Seat a newly opened foil pack only after the fullscreen reveal queue has
   drained. Each card drops into its processor socket with a short stagger;
   reduced-motion users still receive the final seated state immediately. */
body.layout-basic .jackpot-hero__machine .ldj-foil-machine-slot.is-slotting .ldj-foil-machine-ticket {
  animation: ldj-foil-ticket-slot 0.62s cubic-bezier(0.2, 0.82, 0.24, 1) both;
  animation-delay: calc(var(--foil-slot-index, 0) * 85ms);
  transform-origin: 50% 50%;
}

@keyframes ldj-foil-ticket-slot {
  0% { opacity: 0; transform: translate3d(0, -22%, 0) scale(0.82); }
  68% { transform: translate3d(0, 2.5%, 0) scale(1.025); }
  100% { transform: translate3d(0, 0, 0) scale(1); }
}

body.layout-basic .jackpot-hero__machine .ldj-foil-machine-slot.is-loaded.is-match {
  border-color: #d8dee5;
  box-shadow:
    inset 0 0 0 1px rgba(247, 250, 252, 0.18),
    0 0 6px rgba(74, 222, 128, 0.78),
    0 0 16px rgba(34, 197, 94, 0.42);
}

@media (max-width: 430px) {
  body.layout-basic .jackpot-hero__draw-title {
    width: 97%;
    gap: 0.28rem;
    padding-inline: 0.32rem;
  }
  body.layout-basic .jackpot-hero__draw-title::before,
  body.layout-basic .jackpot-hero__draw-title::after { flex-basis: 0.5rem; }
  body.layout-basic .jackpot-hero__draw-mark { width: 0.8rem; height: 1.14rem; }
  body.layout-basic .jackpot-hero__draw-title > strong { letter-spacing: 0.075em; }
}

@media (prefers-reduced-motion: reduce) {
  body.layout-basic .jackpot-hero__machine > .jackpot-board-current .jackpot-board-current__packet use {
    stroke-dasharray: none;
    animation: none !important;
  }
  /* Which sockets are being fed is state, not decoration, so the occupied
     lanes stay lit at full strength. Only the motion goes: the sheet stops
     breathing and the dashes close up into solid traces. This is exactly why
     the sheet is inline — as a background-image none of the three declarations
     below could reach it, and Chrome does not hand the preference to an SVG
     image either. */
  body.layout-basic .jackpot-hero__machine .ldj-foil-machine-current {
    animation: none !important;
  }
  body.layout-basic .jackpot-hero__machine .ldj-foil-machine-cell.is-match-flash img,
  body.layout-basic .jackpot-hero__machine
    .ldj-foil-machine-cell.is-color-match.is-match-flash::after { animation: none; }
  body.layout-basic .jackpot-hero__machine .ldj-foil-machine-cell::after {
    transition: none !important;
  }
  body.layout-basic .jackpot-hero__machine .ldj-foil-machine-cell img {
    transition: none !important;
  }
  body.layout-basic .jackpot-hero__machine .ldj-foil-machine-slot.is-claimable,
  body.layout-basic .jackpot-hero__machine .ldj-foil-claim-marker {
    animation: none !important;
  }
  body.layout-basic .jackpot-hero__machine .ldj-foil-machine-ticket--claimable {
    transition: none !important;
  }
  body.layout-basic .jackpot-hero__machine .ldj-foil-lane path {
    stroke-dasharray: none;
    animation: none;
  }
  /* Keep active state visible without travelling packets or staged fades. */
  body.layout-basic .jackpot-hero__machine replay-panel .jackpot-chainlink__lead {
    animation: none !important;
  }
  body.layout-basic .jackpot-hero__machine replay-panel .replay-controls:has(
    > .replay-reveal-btn.is-processing[data-jp-rng-requested][data-jp-stage='rng']
  ) .jackpot-chainlink__cell,
  body.layout-basic .jackpot-hero__machine replay-panel .replay-controls:has(
    > .replay-reveal-btn.is-processing[data-jp-stage='rng-arrived']
  ) .jackpot-chainlink__cell,
  body.layout-basic .jackpot-hero__machine replay-panel .replay-controls:has(
    > .replay-reveal-btn.is-spinning
  ) .jackpot-chainlink__cell {
    animation: none !important;
    opacity: 1;
    filter: none;
  }
  body.layout-basic .jackpot-hero__machine replay-panel .jackpot-chainlink__cell {
    transition: none !important;
  }
  /* The source pulse is atmosphere, not state: the module stays lit, the
     breathing stops. */
  body.layout-basic .jackpot-hero__machine replay-panel .jackpot-chainlink {
    animation: none !important;
  }
  body.layout-basic .jackpot-hero__machine replay-panel .jackpot-chainlink__core {
    animation: none !important;
  }
  /* The armed key's attract loop is invitation, not state: the LED bank stays
     lit in its action palette and the sheen parks off the face. */
  body.layout-basic .jackpot-hero__machine replay-panel .replay-controls
    > .replay-reveal-btn:not(:disabled):not(.is-processing):not(.is-spinning),
  body.layout-basic .jackpot-hero__machine replay-panel .replay-controls
    > .replay-reveal-btn:not(:disabled):not(.is-processing):not(.is-spinning)::after,
  body.layout-basic .jackpot-hero__machine replay-panel .replay-controls > .ldj-results-cta,
  body.layout-basic .jackpot-hero__machine replay-panel .replay-controls > .ldj-results-cta::after {
    animation: none;
  }
  body.layout-basic .jackpot-hero__draw-mark { filter: none; }
  body.layout-basic .jackpot-hero__machine .ldj-foil-machine-slot.is-slotting .ldj-foil-machine-ticket {
    animation: none;
  }
}

@media (forced-colors: active) {
  body.layout-basic .jackpot-hero__draw-title > strong { color: CanvasText; background: none; filter: none; }
}
