/* The spin screen: the machine, the reels, the bets, the Spin button and the spin counter.
   index.html loads the stylesheets in a fixed order (Game/docs/ui-style.md, "Stylesheets"). */

/* ---------------------------------------------------------------------------
   The spin screen (reference: planning/marketing/stills/football/3-spin.png)
   --------------------------------------------------------------------------- */
/* The spin screen is as tall as the shell. The machine keeps its height, and the part above it (.rj-spin__upper) takes
   what is left and scrolls on its own when its content does not fit, so the machine never covers an event bar and the
   Spin button stays on screen. When everything fits, the machine follows the event bars and the free height stays below
   it, so no empty band separates the bars from the machine. */
.rj-spin {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    height: calc(100% - 1rem);
}

.rj-spin > .rj-topbar,
.rj-spin > .rj-machine {
    flex: none;
}

.rj-spin__upper {
    display: flex;
    flex: 0 1 auto;
    flex-direction: column;
    gap: 1rem;
    /* At least most of one event bar stays in sight on the shortest screen. */
    min-height: min(3.25rem, 100%);
    overflow-y: auto;
    overscroll-behavior: contain;
}

/* With no madness, no event and no offer the part takes no height and adds no gap. */
.rj-spin__upper:not(:has(*)) { display: none; }

/* At zero spins the Spin button is disabled and the out-of-spins offer's buy button is the screen's main action. The
   screen then takes the height of its content, the part above the machine takes the height it needs and does not scroll
   on its own, and the shell scrolls the whole screen, so the player sees the offer and its buy button first. */
.rj-spin.rj-spin--offer { height: auto; }

.rj-spin--offer > .rj-spin__upper {
    flex: none;
    min-height: 0;
    overflow-y: visible;
}

/* The top bar's Home and Shop: small ghost GameButtons with an icon. On the light themes a dark ghost face looks muddy, so
   they take the secondary colours there. */
.rj-spin__nav {
    gap: 0.3rem;
    padding-inline: 0.6rem 0.8rem;
}

[data-theme="cats"] .rj-spin__nav,
[data-theme="allotment"] .rj-spin__nav {
    --gb-light: var(--ui-secondary-light);
    --gb-face:  var(--ui-secondary);
    --gb-dark:  var(--ui-secondary-dark);
    --gb-ink:   var(--ui-on-secondary);
}

[data-theme="cats"] .rj-spin__nav::before,
[data-theme="allotment"] .rj-spin__nav::before { opacity: 1; }

.rj-spin__nav .rj-icon {
    width: 1.35rem;
    height: 1.35rem;
    flex: none;
}

/* The pending attack and raid row is the machine's top bar (Spin.razor): one chunky button per kind with the symbol art
   and a count badge, side by side. */
.rj-pending {
    display: flex;
    justify-content: center;
    gap: 0.5rem;
    width: 100%;
}

.rj-pending__item {
    position: relative;
    flex: 1 1 0;
    min-width: 0;
    max-width: 13rem;
    animation: rj-ui-pop 0.4s var(--ui-pop) both;
}

.rj-spin .rj-pending__go {
    width: 100%;
    padding: 0.2rem 0.6rem calc(0.2rem + var(--ui-edge)) 2.75rem;
    font-size: 0.95rem;
}

.rj-spin .rj-pending__go .rj-gbtn__text { min-width: 0; }

/* The symbol art and its count badge over the left end of the button. They take no taps, so a tap reaches the button. */
.rj-badge {
    position: absolute;
    z-index: 1;
    top: calc(50% - var(--ui-edge) / 2);
    left: 0.35rem;
    display: inline-flex;
    transform: translateY(-50%);
    pointer-events: none;
}

.rj-badge__icon {
    width: 2.2rem;
    height: 2.2rem;
    object-fit: contain;
    filter: drop-shadow(0 2px 0 rgba(0, 0, 0, 0.35));
}

.rj-badge__icon--blank {
    width: 1.6rem;
    height: 1.6rem;
    border: 2px solid var(--ui-outline);
    border-radius: 50%;
    background: var(--ui-danger-light);
}

.rj-badge--raid .rj-badge__icon--blank { background: var(--ui-primary-light); }

.rj-badge .rj-count-badge {
    top: -0.35rem;
    right: -0.45rem;
}

/* The pressed button moves down, so the icon moves with it. */
.rj-pending__item:has(.rj-gbtn:active) .rj-badge { transform: translateY(calc(-50% + var(--ui-press))); }

/* The machine: a framed card in the theme's panel colours, with a soft light behind the slot art. */
.rj-machine {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.65rem;
    padding: 0.9rem 0.8rem 1rem;
    border: 3px solid var(--ui-panel-border);
    border-radius: calc(var(--ui-radius-panel) + 0.4rem);
    background:
        radial-gradient(ellipse 70% 40% at 50% 28%, color-mix(in srgb, var(--ui-primary-light) 30%, transparent), transparent 70%),
        linear-gradient(180deg, var(--ui-panel-light) 0%, var(--ui-panel) 45%);
    box-shadow:
        inset 0 2px 0 rgba(255, 255, 255, 0.28),
        inset 0 0 0 2px color-mix(in srgb, var(--ui-panel-border) 35%, transparent),
        0 0 0 2px var(--ui-outline),
        0 6px 0 2px color-mix(in srgb, var(--ui-outline) 55%, transparent),
        0 12px 24px var(--ui-shadow);
    color: var(--ui-panel-ink);
}

/* On a short screen (760 px or less, such as 360 × 640) the machine uses smaller gaps, a smaller frame and a lower Spin
   button, so the part above it keeps more height and the spin counter under the button stays on screen. */
@media (max-height: 760px) {
    .rj-machine { gap: 0.45rem; padding: 0.55rem 0.55rem 0.7rem; }
    .rj-machine .rj-machine__frame { width: min(100%, 30vh); }
    .rj-spin { gap: 0.6rem; }
    .rj-machine .rj-spin__button { min-height: 3.3rem; font-size: 1.55rem; }
    .rj-spin .rj-pending__go { min-height: 2.75rem; }
    .rj-machine .rj-spin__result { min-height: 1.6rem; font-size: 1.2rem; }
    .rj-machine .rj-spin__result--big { font-size: 1.6rem; }
    .rj-spin:has(.rj-progress, .rj-madness) .rj-machine .rj-machine__frame { width: min(100%, 25vh); }
}

/* The slot frame art with a reel in each of its windows. MachineFrames.cs gives the box its aspect ratio and each reel
   its window in percent. We give the frame art a higher z-index than the reels, so the browser draws the frame over the
   reels and the player sees each reel only through its window. We cap the box's width by the screen height too, so the
   machine fits a short screen. */
.rj-machine__frame {
    position: relative;
    width: min(100%, 38vh);
    margin: -0.4rem 0 -0.2rem;
}

/* While a madness banner or an event bar stands above the machine, the frame is smaller, so the bars stay in sight. */
.rj-spin:has(.rj-progress, .rj-madness) .rj-machine__frame { width: min(100%, 31vh); }

.rj-machine__frame-art {
    position: absolute;
    inset: 0;
    z-index: 2;
    width: 100%;
    height: 100%;
    pointer-events: none;
}

.rj-reels {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.4rem;
    width: 100%;
    padding: 0.5rem;
    border-radius: var(--r-card);
    background: color-mix(in srgb, var(--theme-background, black) 50%, black);
}

.rj-reel {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    min-height: 7.5rem;
    padding: 0.5rem 0.25rem;
    border-radius: var(--r-panel);
    /* We draw the reel face in the theme's text colour and the symbol names in its background colour, so the face
       contrasts with the machine in a dark theme and in a light one. */
    background: linear-gradient(180deg, var(--theme-text, var(--ink)), color-mix(in srgb, var(--theme-text, var(--ink)) 82%, var(--theme-background, var(--ground))));
    color: var(--theme-background, var(--ground));
    text-align: center;
    overflow: hidden;
}

/* A reel inside a frame window: Spin.razor sets its position. The frame art contains the window's border, so we draw the
   reel as a plain light face slightly larger than the window. */
.rj-reel--framed {
    position: absolute;
    z-index: 1;
    min-height: 0;
    padding: 0;
    margin: -0.5%;
    border-radius: 0;
    background: linear-gradient(180deg, #fffdf6, #e9e3d3 55%, #fffdf6);
    box-sizing: content-box;
}

.rj-reel__art {
    display: block;
    width: 3.4rem;
    max-width: 92%;
    height: auto;
    aspect-ratio: 1;
    object-fit: contain;
}

.rj-reel--framed .rj-reel__art {
    width: 90%;
    max-width: none;
}

.rj-reel__blank {
    width: 3rem;
    height: 3rem;
    border-radius: 50%;
    background: var(--theme-accent, var(--gold));
    box-shadow: inset 0 -0.3rem 0 rgba(0, 0, 0, 0.18);
}

.rj-reel__name {
    font-size: 0.72rem;
    font-weight: 800;
    line-height: 1.15;
    overflow-wrap: anywhere;
}

/* A spinning reel shows a strip of every symbol twice and moves it up by half its height, so the loop has no seam. */
.rj-reel__strip {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.3rem;
    width: 100%;
    animation: rj-reel-spin 0.45s linear infinite;
    filter: blur(1.5px);
}

.rj-reel.is-spinning {
    justify-content: flex-start;
}

.rj-reel.is-spinning .rj-reel__name {
    visibility: hidden;
}

.rj-reel.is-landed .rj-reel__art,
.rj-reel.is-landed .rj-reel__blank {
    animation: rj-reel-land var(--t-slow) var(--ease-spring, var(--ease));
}

@keyframes rj-reel-spin {
    from { transform: translateY(0); }
    to   { transform: translateY(-50%); }
}

@keyframes rj-reel-land {
    from { transform: translateY(-40%) scale(0.9); }
    to   { transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .rj-reel__strip { animation: none; }
    .rj-reel.is-landed .rj-reel__art,
    .rj-reel.is-landed .rj-reel__blank { animation: none; }
}

/* The coin burst of a coin win: coins fly up from the win line and fall away once, five for a small win and ten for a big
   one (.rj-burst--big flies higher). The machine is the burst's containing block, because it is positioned. */
.rj-burst {
    position: absolute;
    inset: 0;
    z-index: 6;
    overflow: hidden;
    pointer-events: none;
}

.rj-burst__coin {
    position: absolute;
    /* The coins spread evenly across the machine, whatever their number (--coins). */
    left: calc(50% - 1.1rem + (var(--coin) - (var(--coins) - 1) / 2) * (84% / var(--coins)));
    bottom: 40%;
    width: 2.2rem;
    height: 2.2rem;
    border-radius: 50%;
    background: var(--ui-primary);
    animation: rj-burst 1.1s var(--ease) both;
    animation-delay: calc(var(--coin) * 45ms);
}

.rj-burst--big .rj-burst__coin { animation: rj-burst-big 1.3s var(--ease) both; animation-delay: calc(var(--coin) * 45ms); }

.rj-burst__coin:has(img) { background: none; }

.rj-burst__coin img { width: 100%; height: 100%; object-fit: contain; }

@keyframes rj-burst {
    0%   { transform: translateY(0) scale(0.4); opacity: 0; }
    15%  { opacity: 1; }
    55%  { transform: translateY(-5rem) rotate(160deg) scale(0.9); opacity: 1; }
    100% { transform: translateY(-2rem) rotate(300deg) scale(0.7); opacity: 0; }
}

@keyframes rj-burst-big {
    0%   { transform: translateY(0) scale(0.4); opacity: 0; }
    15%  { opacity: 1; }
    55%  { transform: translateY(-9rem) rotate(200deg) scale(1); opacity: 1; }
    100% { transform: translateY(-4rem) rotate(360deg) scale(0.8); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
    .rj-burst { display: none; }
}

/* The win line: display text with a dark outline. It pops in when the reels stop, and its number counts up
   (NumberCountUp). While the reels spin, it keeps its height and hides the counter at 0. */
.rj-spin__result {
    min-height: 1.9rem;
    margin: 0;
    font-family: var(--ui-font-display);
    font-size: 1.35rem;
    font-weight: 400;
    line-height: 1.15;
    letter-spacing: 0.01em;
    text-align: center;
    color: var(--ui-primary-light);
    -webkit-text-stroke: 0.2em var(--ui-outline);
    paint-order: stroke fill;
    text-shadow: 0 0.09em 0 var(--ui-outline), 0 0.2em 0.4em rgba(0, 0, 0, 0.3);
}

.rj-spin__result.is-waiting { visibility: hidden; }

.rj-spin__result.is-shown { animation: rj-ui-pop 0.4s var(--ui-pop) both; }

.rj-spin__result-number { font-variant-numeric: tabular-nums; }

.rj-spin__result--big {
    font-size: 2rem;
    line-height: 1.05;
    color: #ffffff;
}

.rj-spin__result--big.is-shown { animation: rj-big-win 0.6s var(--ui-pop) both; }

@keyframes rj-big-win {
    0%   { transform: scale(0.4); opacity: 0; }
    60%  { transform: scale(1.15); opacity: 1; }
    100% { transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .rj-spin__result.is-shown,
    .rj-spin__result--big.is-shown,
    .rj-pending__item { animation: none; }
}

/* The bet selector: chunky chips in a dark tray, with "Bet" on a tab over the tray's top edge. The selected chip has the
   primary colours and stands a little higher. */
.rj-bets {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 100%;
    padding-top: 0.55rem;
}

.rj-bets__label {
    position: absolute;
    z-index: 1;
    top: 0;
    padding: 0 0.6rem;
    border: 2px solid var(--ui-outline);
    border-radius: 0.5rem;
    background: var(--ui-secondary-dark);
    font-family: var(--ui-font-display);
    font-size: 0.75rem;
    font-weight: 400;
    line-height: 1.25;
    color: #ffffff;
    letter-spacing: 0.03em;
}

.rj-bets__tray {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.25rem;
    box-sizing: border-box;
    max-width: 100%;
    padding: 0.55rem 0.35rem 0.4rem;
    border: 2px solid var(--ui-outline);
    border-radius: 1rem;
    background: color-mix(in srgb, var(--ui-outline) 32%, transparent);
    box-shadow: inset 0 3px 6px color-mix(in srgb, var(--ui-outline) 40%, transparent), 0 1px 0 rgba(255, 255, 255, 0.2);
}

.rj-bets__option {
    position: relative;
    min-width: 2.75rem;
    min-height: 2.75rem;
    padding: 0 0.35rem;
    border: 2px solid var(--ui-outline);
    border-radius: 0.8rem;
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.3) 0%, rgba(255, 255, 255, 0.12) 50%, rgba(255, 255, 255, 0.06) 100%), var(--ui-nav);
    box-shadow: inset 0 -3px 0 rgba(0, 0, 0, 0.25), 0 2px 0 var(--ui-outline);
    color: #ffffff;
    font-family: var(--ui-font-display);
    font-size: 1.05rem;
    font-weight: 400;
    line-height: 1;
    -webkit-text-stroke: 0.16em var(--ui-outline);
    paint-order: stroke fill;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: transform var(--t-fast) ease-out;
}

/* In cats the bar colour is the primary orange, so an unselected chip is a light face with dark text instead. */
[data-theme="cats"] .rj-bets__option:not(.is-selected) {
    background: linear-gradient(180deg, #ffffff 0%, var(--ui-panel) 100%);
    color: var(--ui-panel-ink);
    -webkit-text-stroke: 0;
}

/* Seven bets or more (a madness event's extra bet): narrower chips, still 44 px high, so the row fits at 360 px. */
.rj-bets--many .rj-bets__tray { gap: 0.15rem; padding-inline: 0.15rem; }

.rj-bets--many .rj-bets__option {
    min-width: 2.4rem;
    padding: 0 0.1rem;
    font-size: 0.9rem;
}

.rj-bets__option.is-selected {
    background: linear-gradient(180deg, var(--ui-primary-light) 0%, var(--ui-primary) 55%, color-mix(in srgb, var(--ui-primary) 80%, var(--ui-primary-dark)) 100%);
    box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.45), inset 0 -3px 0 var(--ui-primary-dark), 0 3px 0 var(--ui-outline);
    color: var(--ui-on-primary);
    transform: translateY(-2px);
}

.rj-bets__option:active:not(:disabled) { transform: translateY(1px); }

.rj-bets__option:focus-visible { outline: 3px solid #ffffff; outline-offset: 1px; }

.rj-bets__option:disabled { opacity: var(--disabled-opacity); cursor: default; }

/* The Spin button: the large primary GameButton, wider and taller, with the label over the cost chip. A light sweep runs
   over the face while the button can spin; the sweep moves inside the button, so the button itself does not move and
   Playwright can tap it. */
.rj-spin__button {
    flex-direction: column;
    gap: 0.1rem;
    width: min(86%, 17rem);
    min-height: 4rem;
    margin-bottom: calc(var(--ui-edge) + 0.1rem);
    padding: 0.3rem 1rem 0.35rem;
    border-radius: 1.4rem;
    overflow: hidden;
    font-size: 2rem;
    line-height: 1;
    letter-spacing: 0.03em;
}

.rj-spin__button::after {
    content: "";
    position: absolute;
    z-index: -1;
    top: 0;
    bottom: 0;
    left: -40%;
    width: 30%;
    background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.45), transparent);
    transform: skewX(-18deg);
    pointer-events: none;
    animation: rj-spin-shine 2.8s ease-in-out infinite;
}

.rj-spin__button:disabled::after { display: none; }

@keyframes rj-spin-shine {
    0%, 55% { left: -40%; }
    100%    { left: 120%; }
}

.rj-spin__button-label { display: block; }

.rj-spin__cost {
    display: inline-flex;
    align-items: center;
    gap: 0.15rem;
    padding: 0.05rem 0.5rem 0.05rem 0.2rem;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.3);
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.35);
    font-size: 0.85rem;
    letter-spacing: 0;
    -webkit-text-stroke: 0.14em var(--ui-outline);
    font-variant-numeric: tabular-nums;
}

.rj-spin__cost-icon {
    width: 1.3rem;
    height: 1.3rem;
    object-fit: contain;
}

.rj-spin__counter-icon {
    position: absolute;
    left: -0.7rem;
    top: 50%;
    width: 2.1rem;
    height: 2.1rem;
    object-fit: contain;
    transform: translateY(-50%);
    filter: drop-shadow(0 2px 0 var(--ui-outline)) drop-shadow(0 2px 3px rgba(0, 0, 0, 0.35));
}

.rj-spin__cost-icon--blank {
    display: inline-block;
    width: 0.9rem;
    height: 0.9rem;
    border: 2px solid var(--ui-outline);
    border-radius: 50%;
    background: var(--ui-primary-light);
}

.rj-spin__counter-icon--blank {
    width: 1.5rem;
    height: 1.5rem;
    border: 2px solid var(--ui-outline);
    border-radius: 50%;
    background: var(--ui-primary);
}

/* The spin counter under the Spin button: a currency pill with the spins icon over its left edge, "35 / 50" in display
   text, and the time to the next spin (or "Full") on a dark chip. The "−{bet}" float rises from the pill and fades; it
   takes no pointer events. */
.rj-spin__counter {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    min-height: 2rem;
    margin: -0.3rem 0 0;
    padding: 0.1rem 0.25rem 0.1rem 1.7rem;
    border: var(--ui-border) solid var(--ui-outline);
    border-radius: 0.8rem;
    background: var(--ui-pill-bg);
    box-shadow: inset 0 0 0 1.5px var(--ui-pill-rim), inset 0 -3px 0 rgba(0, 0, 0, 0.18), 0 2px 0 var(--ui-outline);
    font-variant-numeric: tabular-nums;
}

.rj-spin__counter-value {
    font-family: var(--ui-font-display);
    font-size: 1.1rem;
    font-weight: 400;
    line-height: 1.1;
    color: var(--ui-pill-ink);
    -webkit-text-stroke: 0.18em var(--ui-pill-stroke);
    paint-order: stroke fill;
}

.rj-spin__counter-regen {
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.35);
    color: #ffffff;
    font-size: 0.78rem;
    font-weight: 800;
    white-space: nowrap;
}

.rj-spin__counter[data-full="true"] .rj-spin__counter-regen {
    background: linear-gradient(180deg, var(--ui-plus-light), var(--ui-plus));
    color: #ffffff;
    -webkit-text-stroke: 0.15em var(--ui-outline);
    paint-order: stroke fill;
}

.rj-spin__spent {
    position: absolute;
    left: 50%;
    top: 0;
    font-family: var(--ui-font-display);
    font-size: 1.3rem;
    font-weight: 400;
    color: var(--ui-danger-light);
    -webkit-text-stroke: 0.2em var(--ui-outline);
    paint-order: stroke fill;
    text-shadow: 0 0.09em 0 var(--ui-outline);
    white-space: nowrap;
    pointer-events: none;
    opacity: 0;
    animation: rj-spin-spent 0.9s ease-out;
}

@keyframes rj-spin-spent {
    0%   { opacity: 0; transform: translate(-50%, 0) scale(0.7); }
    20%  { opacity: 1; transform: translate(-50%, -40%) scale(1.15); }
    100% { opacity: 0; transform: translate(-50%, -180%) scale(1); }
}

@media (prefers-reduced-motion: reduce) {
    .rj-spin__spent,
    .rj-spin__button::after { animation: none; }
    .rj-spin__button::after { display: none; }
}

/* A refusal under the Spin button: white text on a red bubble. */
.rj-spin__message {
    margin: 0;
    padding: 0.35rem 0.8rem;
    border: 2px solid var(--ui-outline);
    border-radius: 0.8rem;
    background: var(--ui-danger);
    color: #ffffff;
    font-weight: 800;
    text-align: center;
}

.rj-spin .rj-spin__shop { align-self: center; }

.rj-spin__shop .rj-icon {
    width: 1.5rem;
    height: 1.5rem;
}

/* The out-of-spins line above the Shop button: a light bubble, a plain statement and not an error. */
.rj-spin__empty {
    margin: 0;
    padding: 0.45rem 0.8rem;
    border-radius: 0.9rem;
    background: var(--ui-bubble);
    color: var(--ui-bubble-ink);
    font-weight: 800;
    text-align: center;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
}

/* ---------------------------------------------------------------------------
   The part above the machine on the spin screen: the out-of-spins offer, the madness banner and the event bars. These
   rules start with .rj-spin, so they win over the shop's and the events screen's rules for the same components in
   menus.css, which index.html loads later.
   --------------------------------------------------------------------------- */

/* The out-of-spins offer: a framed card with the heading on a ribbon-coloured band, the offer's art beside its name and
   contents, and the buy button under them. */
.rj-spin .rj-spin__offer {
    display: flex;
    flex-direction: column;
    gap: 0;
    overflow: hidden;
    border: 3px solid var(--ui-panel-border);
    border-radius: var(--ui-radius-panel);
    background: linear-gradient(180deg, var(--ui-panel-light) 0%, var(--ui-panel) 38%);
    box-shadow:
        inset 0 2px 0 rgba(255, 255, 255, 0.28),
        0 0 0 2px var(--ui-outline),
        0 6px 0 2px color-mix(in srgb, var(--ui-outline) 55%, transparent),
        0 12px 24px var(--ui-shadow);
    color: var(--ui-panel-ink);
}

/* The space under the offer card leaves room for the guide's arrow over the event bar below it, so the arrow does not
   cover the buy button. */
.rj-spin--offer .rj-spin__offer { margin-bottom: 0.75rem; }

.rj-spin__offer-heading {
    margin: 0;
    padding: 0.4rem 0.7rem 0.45rem;
    border-bottom: 2px solid var(--ui-outline);
    background: linear-gradient(180deg, var(--ui-ribbon-light) 0%, var(--ui-ribbon) 60%, color-mix(in srgb, var(--ui-ribbon) 75%, var(--ui-ribbon-dark)) 100%);
    box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.3), inset 0 -3px 0 var(--ui-ribbon-dark);
    font-family: var(--ui-font-display);
    font-size: 1.05rem;
    font-weight: 400;
    line-height: 1.15;
    text-align: center;
    color: #ffffff;
    -webkit-text-stroke: 0.18em var(--ui-outline);
    paint-order: stroke fill;
    text-shadow: 0 0.08em 0 var(--ui-outline);
}

.rj-spin .rj-spin__offer .rj-offer {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas: "art name" "art contents" "buy buy";
    align-items: center;
    gap: 0.15rem 0.7rem;
    padding: 0.6rem 0.8rem 0.8rem;
    border: 0;
    border-radius: 0;
    background: none;
    color: inherit;
}

.rj-spin .rj-spin__offer .rj-offer__art-box {
    grid-area: art;
    width: 5.2rem;
}

.rj-spin .rj-spin__offer .rj-offer__name {
    grid-area: name;
    align-self: end;
    font-family: var(--ui-font-display);
    font-size: 1.35rem;
    font-weight: 400;
    line-height: 1.1;
    color: var(--ui-panel-ink);
}

.rj-spin .rj-spin__offer .rj-offer__contents {
    grid-area: contents;
    align-self: start;
    font-size: 1.05rem;
    font-weight: 800;
    color: var(--ui-panel-ink);
}

.rj-spin .rj-spin__offer .rj-offer__buy,
.rj-spin .rj-spin__offer .rj-offer__sold-out {
    grid-area: buy;
    margin-top: 0.5rem;
}

/* The madness banner: a hot banner in the primary colours (the danger colours for an attack madness), the name in display
   text, and the countdown on a dark chip. */
.rj-spin .rj-spin__upper .rj-madness__item {
    align-items: center;
    gap: 0.15rem 0.5rem;
    padding: 0.45rem 0.7rem;
    border: var(--ui-border) solid var(--ui-outline);
    border-radius: 0.9rem;
    background: linear-gradient(180deg, var(--ui-primary-light) 0%, var(--ui-primary) 55%, var(--ui-primary-dark) 100%);
    box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.4), inset 0 -3px 0 rgba(0, 0, 0, 0.2), 0 3px 0 var(--ui-outline);
    color: #ffffff;
}

.rj-spin .rj-spin__upper .rj-madness__item--attack {
    background: linear-gradient(180deg, var(--ui-danger-light) 0%, var(--ui-danger) 55%, var(--ui-danger-dark) 100%);
}

.rj-spin .rj-spin__upper .rj-madness__name,
.rj-spin .rj-spin__upper .rj-madness__effect {
    font-family: var(--ui-font-display);
    font-weight: 400;
    font-size: 1.05rem;
    line-height: 1.1;
    -webkit-text-stroke: 0.18em var(--ui-outline);
    paint-order: stroke fill;
    text-shadow: 0 0.08em 0 var(--ui-outline);
}

.rj-spin .rj-spin__upper .rj-madness__effect { color: #fff6c2; }

.rj-spin .rj-spin__upper .rj-madness__bets {
    font-size: 0.85rem;
    font-weight: 800;
    text-shadow: 0 1px 0 var(--ui-outline);
}

.rj-spin .rj-spin__upper .rj-madness__timer {
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.35);
    color: #ffffff;
    font-size: 0.78rem;
    font-weight: 800;
}

/* An event bar: the event's name on a ribbon tag, a thick outlined bar with a glossy fill, and the next reward's icon at
   the bar's end (a trophy with a count badge while a reward waits for its claim). */
.rj-spin .rj-spin__upper .rj-progress { gap: 0.5rem; }

.rj-spin .rj-spin__upper .rj-progress__event {
    display: grid;
    grid-template-columns: minmax(0, auto) minmax(0, 1fr);
    align-items: center;
    gap: 0.25rem 0.5rem;
    padding: 0.45rem 0.6rem 0.4rem;
    border: var(--ui-border) solid var(--ui-outline);
    border-radius: 0.9rem;
    background: linear-gradient(180deg, var(--ui-panel-light) 0%, var(--ui-panel) 60%);
    box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.25), inset 0 0 0 2px color-mix(in srgb, var(--ui-panel-border) 40%, transparent), 0 3px 0 var(--ui-outline);
    color: var(--ui-panel-ink);
}

.rj-spin .rj-spin__upper .rj-progress__name {
    max-width: 8.5rem;
    overflow: hidden;
    padding: 0.05rem 0.55rem 0.1rem;
    border: 2px solid var(--ui-outline);
    border-radius: 0.45rem;
    background: linear-gradient(180deg, var(--ui-ribbon-light) 0%, var(--ui-ribbon) 60%, var(--ui-ribbon-dark) 100%);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.35);
    color: #ffffff;
    font-family: var(--ui-font-display);
    font-size: 0.95rem;
    font-weight: 400;
    line-height: 1.2;
    text-overflow: ellipsis;
    white-space: nowrap;
    -webkit-text-stroke: 0.18em var(--ui-outline);
    paint-order: stroke fill;
}

.rj-progress__track {
    display: flex;
    align-items: center;
    min-width: 0;
    padding-right: 0.4rem;
}

.rj-spin .rj-spin__upper .rj-progress__bar {
    position: relative;
    flex: 1;
    height: 1rem;
    margin-right: -0.6rem;
    border: 2px solid var(--ui-outline);
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.4);
    box-shadow: inset 0 2px 3px rgba(0, 0, 0, 0.45);
    overflow: hidden;
}

.rj-spin .rj-spin__upper .rj-progress__fill {
    display: block;
    height: 100%;
    border-radius: 999px;
    background:
        linear-gradient(180deg, rgba(255, 255, 255, 0.55) 0 35%, transparent 36%),
        linear-gradient(180deg, var(--ui-plus-light), var(--ui-plus) 60%, var(--ui-plus-dark));
    box-shadow: inset -2px 0 0 rgba(0, 0, 0, 0.2);
}

.rj-progress__reward {
    position: relative;
    z-index: 1;
    display: grid;
    place-items: center;
    flex: none;
    width: 2.1rem;
    height: 2.1rem;
    border: 2px solid var(--ui-outline);
    border-radius: 50%;
    background: radial-gradient(circle at 50% 35%, #ffffff, color-mix(in srgb, var(--ui-primary-light) 70%, white) 70%);
    box-shadow: 0 2px 0 var(--ui-outline);
}

.rj-progress__reward img,
.rj-progress__reward .rj-icon {
    width: 1.6rem;
    height: 1.6rem;
    object-fit: contain;
}

.rj-progress__reward-blank {
    width: 1.1rem;
    height: 1.1rem;
    border-radius: 50%;
    background: var(--ui-primary);
}

.rj-progress__reward.is-ready {
    background: radial-gradient(circle at 50% 35%, var(--ui-primary-light), var(--ui-primary) 75%);
}

.rj-progress__reward .rj-count-badge {
    top: -0.4rem;
    right: -0.5rem;
}

.rj-spin .rj-spin__upper .rj-progress__text {
    grid-column: 1 / -1;
    font-size: 0.8rem;
    font-weight: 800;
    color: var(--ui-panel-ink-2);
}

.rj-shell__loading {
    min-height: calc(100% - 1rem);
}
