/* The attack screen (target picker, target site, result) and the raid screen (header card, dig spots, dig bubbles,
   result). Both screens use the casual-game look of Game/docs/ui-style.md: the --ui-* tokens of the theme, GameButton,
   Ribbon, the panel frame and the tooltip bubble. index.html loads the stylesheets in a fixed order
   (Game/docs/ui-style.md, "Stylesheets"), and this file comes after menus.css, so its rules win a tie. */

/* ---------------------------------------------------------------------------
   Shared by both screens
   --------------------------------------------------------------------------- */
.rj-attack,
.rj-raid {
    gap: 0.6rem;
}

/* Home: a small ghost GameButton with the home icon, at the top left. */
.rj-topbar__home {
    align-self: flex-start;
    margin-left: -0.2rem;
}

.rj-topbar__home .rj-icon {
    width: 1.25rem;
    height: 1.25rem;
}

/* A chip with the attacks or raids left: the symbol art over its left edge and display text. */
.rj-raid-chip {
    position: relative;
    align-self: center;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    box-sizing: border-box;
    max-width: 100%;
    min-height: 2.1rem;
    margin: 0 0 0 0.9rem;
    padding: 0.2rem 0.9rem 0.25rem 1.7rem;
    border: var(--ui-border) solid var(--ui-outline);
    border-radius: 999px;
    background: var(--ui-pill-bg);
    box-shadow: inset 0 0 0 1.5px var(--ui-pill-rim), 0 2px 0 var(--ui-outline);
    color: var(--ui-pill-ink);
    font-family: var(--ui-font-display);
    font-size: 0.98rem;
    font-weight: 400;
    line-height: 1.15;
    text-align: center;
}

.rj-raid-chip__icon {
    position: absolute;
    left: -0.95rem;
    top: 50%;
    width: 2.4rem;
    height: 2.4rem;
    object-fit: contain;
    transform: translateY(-50%) rotate(-8deg);
    filter: drop-shadow(0 2px 0 var(--ui-outline));
}

.rj-raid-chip.is-none {
    font-family: var(--font-body);
    font-weight: 800;
    font-size: 0.9rem;
}

/* A portrait in a thick round frame, with the FRIEND tag over its lower edge. */
.rj-raid__frame {
    position: relative;
    flex: none;
    display: inline-grid;
    place-items: center;
    padding: 3px;
    border-radius: 50%;
    background: linear-gradient(180deg, var(--ui-primary-light), var(--ui-primary-dark));
    box-shadow: 0 0 0 var(--ui-border) var(--ui-outline), 0 3px 0 var(--ui-border) var(--ui-outline);
}

.rj-raid__frame .rj-portrait {
    background: color-mix(in srgb, var(--ui-panel) 70%, white);
}

.rj-raid__friend {
    position: absolute;
    left: 50%;
    bottom: -0.55rem;
    padding: 0.05rem 0.4rem 0.1rem;
    border: 2px solid var(--ui-outline);
    border-radius: 0.45rem;
    background: linear-gradient(180deg, var(--ui-secondary-light), var(--ui-secondary));
    color: #ffffff;
    font-family: var(--ui-font-display);
    font-size: 0.68rem;
    font-weight: 400;
    letter-spacing: 0.04em;
    line-height: 1.1;
    white-space: nowrap;
    -webkit-text-stroke: 0.2em var(--ui-outline);
    paint-order: stroke fill;
    transform: translateX(-50%);
}

/* The light secondary face (putki's white) takes dark text with no outline. */
[data-theme="putki"] .rj-raid__friend {
    color: var(--ui-on-secondary);
    -webkit-text-stroke: 0;
}

.rj-raid__searching::after,
.rj-attack__searching::after {
    content: "";
    display: inline-block;
    width: 0.9rem;
    height: 0.9rem;
    margin-left: 0.5rem;
    border: 3px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: rj-spin-around 0.8s linear infinite;
    vertical-align: middle;
}

@keyframes rj-spin-around {
    to { transform: rotate(360deg); }
}

/* An error under the screen: a red bubble with white display text. */
.rj-attack__message,
.rj-raid__message {
    align-self: center;
    margin: 0;
    padding: 0.5rem 0.9rem;
    border: var(--ui-border) solid var(--ui-outline);
    border-radius: 0.9rem;
    background: linear-gradient(180deg, var(--ui-danger-light), var(--ui-danger) 55%);
    box-shadow: 0 3px 0 var(--ui-outline);
    color: #ffffff;
    font-family: var(--ui-font-display);
    font-size: 1rem;
    font-weight: 400;
    text-align: center;
    -webkit-text-stroke: 0.18em var(--ui-danger-dark);
    paint-order: stroke fill;
    animation: rj-ui-pop 0.35s var(--ui-pop) both;
}

/* Sun rays behind a reward: a slow turning ring of light wedges. */
.rj-raid__rays,
.rj-attack__rays {
    position: absolute;
    z-index: 0;
    left: 50%;
    top: 50%;
    width: 15rem;
    height: 15rem;
    margin: -7.5rem 0 0 -7.5rem;
    border-radius: 50%;
    background: repeating-conic-gradient(from 0deg, rgba(255, 236, 150, 0.55) 0deg 10deg, transparent 10deg 30deg);
    -webkit-mask-image: radial-gradient(circle, black 25%, transparent 70%);
    mask-image: radial-gradient(circle, black 25%, transparent 70%);
    pointer-events: none;
    animation: rj-ra-rays 12s linear infinite;
}

@keyframes rj-ra-rays {
    to { transform: rotate(360deg); }
}

/* ---------------------------------------------------------------------------
   The attack screen
   --------------------------------------------------------------------------- */
.rj-attack__title {
    align-self: center;
    max-width: calc(100% - 2rem);
    margin: 0.35rem 0 0.15rem;
    font-size: clamp(1rem, 4.6vw, 1.2rem);
    white-space: normal;
}

/* The tabs: a recessed track with three chunky tabs; the chosen tab is raised in the main colour. */
.rj-tabs {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.35rem;
    padding: 0.3rem;
    border: var(--ui-border) solid var(--ui-outline);
    border-radius: 1.05rem;
    background: color-mix(in srgb, var(--ui-outline) 55%, transparent);
    box-shadow: inset 0 3px 6px rgba(0, 0, 0, 0.35), 0 2px 0 rgba(255, 255, 255, 0.12);
}

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

.rj-tabs__tab:not(.is-selected) { filter: saturate(0.75) brightness(0.92); }

.rj-tabs__tab:active:not(:disabled) {
    transform: translateY(2px);
    box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.25), 0 1px 0 var(--ui-outline);
}

.rj-tabs__tab.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);
}

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

.rj-tabs__count { top: -0.55rem; right: -0.35rem; }

.rj-attack__panel {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0.6rem;
    padding: 0.8rem;
}

.rj-attack__panel > .rj-attack__mascot { align-self: center; }

.rj-attack__empty {
    margin: 0;
    color: var(--ui-panel-ink);
    font-weight: 800;
    text-align: center;
}

/* A row of the Revenge or Friends tab: a small framed card with the portrait, the name and an action chip. */
.rj-attack__pick {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    box-sizing: border-box;
    width: 100%;
    min-height: 3.5rem;
    margin: 0 0 3px;
    padding: 0.35rem 0.55rem;
    border: var(--ui-border) solid var(--ui-outline);
    border-radius: 0.9rem;
    background: linear-gradient(180deg, var(--ui-panel-light), var(--ui-panel));
    box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.2), 0 3px 0 var(--ui-outline);
    color: var(--ui-panel-ink);
    font: inherit;
    text-align: left;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: transform var(--t-fast) ease-out;
}

.rj-attack__pick:active:not(:disabled) { transform: translateY(2px); }
.rj-attack__pick:disabled { cursor: default; }

.rj-attack__pick .rj-attack__portrait {
    box-shadow: 0 0 0 2.5px var(--ui-outline);
    background: color-mix(in srgb, var(--ui-panel) 70%, white);
}

/* A greyed friend: the portrait and the site fade, and the name and the reason stay readable. */
.rj-attack__pick.is-greyed > * { opacity: 0.45; filter: grayscale(1); }
.rj-attack__pick.is-greyed > .rj-attack__pick-name { opacity: 1; filter: none; }

.rj-attack__pick-name {
    flex: 1;
    min-width: 0;
    font-family: var(--ui-font-display);
    font-size: 1.1rem;
    font-weight: 400;
    line-height: 1.15;
    overflow-wrap: anywhere;
}

/* Why a greyed friend takes no attack. */
.rj-attack__pick-reason {
    display: block;
    font-family: var(--font-body);
    font-size: 0.8rem;
    font-weight: 800;
    color: var(--ui-panel-ink-2);
}

.rj-attack__pick-action {
    flex: none;
    padding: 0.2rem 0.6rem 0.25rem;
    border: 2px solid var(--ui-outline);
    border-radius: 0.6rem;
    background: linear-gradient(180deg, var(--ui-secondary-light), var(--ui-secondary) 60%);
    box-shadow: 0 2px 0 var(--ui-outline);
    color: var(--ui-on-secondary);
    font-family: var(--ui-font-display);
    font-size: 0.9rem;
    font-weight: 400;
    white-space: nowrap;
}

.rj-attack__pick-action--revenge {
    background: linear-gradient(180deg, var(--ui-danger-light), var(--ui-danger) 60%);
    color: #ffffff;
    -webkit-text-stroke: 0.18em var(--ui-outline);
    paint-order: stroke fill;
}

.rj-attack__find {
    align-self: center;
    min-width: min(16rem, 100%);
}

.rj-attack__searching {
    margin: 0;
    padding: 1.2rem 0;
    color: var(--ui-panel-ink);
    font-family: var(--ui-font-display);
    font-size: 1.15rem;
    font-weight: 400;
    text-align: center;
}

/* The target: the framed portrait, the name in display text and the coins on a pill. */
.rj-target {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    gap: 0.55rem;
}

.rj-target__who {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.4rem 0.7rem;
    padding: 0.5rem 0.7rem 0.7rem;
    border: var(--ui-border) solid var(--ui-outline);
    border-radius: var(--ui-radius-panel);
    background: linear-gradient(180deg, var(--ui-panel-light) 0%, var(--ui-panel) 45%);
    box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.22), 0 0 0 2px var(--ui-panel-border) inset, 0 4px 0 var(--ui-outline), 0 8px 16px var(--ui-shadow);
}

.rj-target__portrait { width: 3rem; height: 3rem; }

/* The name over the coins pill, beside the portrait. */
.rj-target__info {
    display: flex;
    flex: 1;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.35rem;
    min-width: 0;
}

.rj-target__name {
    max-width: 100%;
    font-family: var(--ui-font-display);
    font-size: clamp(1.05rem, 5vw, 1.3rem);
    font-weight: 400;
    line-height: 1.1;
    color: #ffffff;
    -webkit-text-stroke: 0.2em var(--ui-outline);
    paint-order: stroke fill;
    text-shadow: 0 0.09em 0 var(--ui-outline);
    overflow-wrap: break-word;
}

.rj-target__coins {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    margin-left: 0.5rem;
    padding: 0.2rem 0.7rem 0.2rem 1.6rem;
    border: 2px solid var(--ui-outline);
    border-radius: 999px;
    background: var(--ui-pill-bg);
    box-shadow: inset 0 0 0 1.5px var(--ui-pill-rim);
    color: var(--ui-pill-ink);
    font-family: var(--ui-font-display);
    font-size: 0.95rem;
    font-weight: 400;
    font-variant-numeric: tabular-nums;
}

.rj-target__coin {
    position: absolute;
    left: -0.5rem;
    top: 50%;
    width: 1.9rem;
    height: 1.9rem;
    object-fit: contain;
    transform: translateY(-50%);
    filter: drop-shadow(0 2px 0 var(--ui-outline));
}

.rj-target__hint {
    align-self: center;
    margin-bottom: 0.15rem;
}

.rj-target__hint.is-sending::after { display: none; }

/* A structure the player can attack shows a red crosshair that pulses; a structure the player cannot attack is greyed. */
.rj-target .rj-structure:not(:disabled) { cursor: crosshair; }

.rj-target .rj-structure:not(:disabled)::after {
    content: "";
    position: absolute;
    z-index: 3;
    left: 50%;
    top: 50%;
    width: max(2.4rem, 55%);
    aspect-ratio: 1;
    background: var(--ui-danger);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cg fill='none' stroke='black' stroke-width='9' stroke-linecap='round'%3E%3Ccircle cx='50' cy='50' r='30'/%3E%3Cpath d='M50 6v22M50 72v22M6 50h22M72 50h22'/%3E%3C/g%3E%3Ccircle cx='50' cy='50' r='7' fill='black'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cg fill='none' stroke='black' stroke-width='9' stroke-linecap='round'%3E%3Ccircle cx='50' cy='50' r='30'/%3E%3Cpath d='M50 6v22M50 72v22M6 50h22M72 50h22'/%3E%3C/g%3E%3Ccircle cx='50' cy='50' r='7' fill='black'/%3E%3C/svg%3E") center / contain no-repeat;
    filter: drop-shadow(0 0 2px #ffffff) drop-shadow(0 0 1px #ffffff) drop-shadow(0 2px 0 var(--ui-outline));
    transform: translate(-50%, -50%);
    pointer-events: none;
    animation: rj-ra-aim 1.4s ease-in-out infinite;
}

@keyframes rj-ra-aim {
    0%, 100% { transform: translate(-50%, -50%) scale(1); }
    50%      { transform: translate(-50%, -50%) scale(0.86); }
}

.rj-target .rj-structure:disabled .rj-structure__art { filter: grayscale(0.8) brightness(0.75); }

/* The attack result: a framed card with the title ribbon, the art popping in front of rays, and the coins counting up. */
.rj-attack__result {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.6rem;
    text-align: center;
}

.rj-attack__result-stage {
    position: relative;
    display: grid;
    place-items: center;
    width: 100%;
    min-height: 7rem;
}

.rj-attack__result.is-blocked .rj-attack__rays {
    background: repeating-conic-gradient(from 0deg, rgba(190, 220, 255, 0.5) 0deg 10deg, transparent 10deg 30deg);
}

.rj-attack__result-art {
    position: relative;
    z-index: 1;
    width: min(45%, 9.5rem);
    max-height: 22vh;
    object-fit: contain;
    height: auto;
    filter: drop-shadow(0 6px 8px rgba(0, 0, 0, 0.35));
    animation: rj-ra-pop-in 0.5s var(--ui-pop) both;
}

.rj-attack__result-coins {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    margin: 0;
}

.rj-attack__count,
.rj-raid__result-count {
    font-family: var(--ui-font-display);
    font-size: 2.4rem;
    font-weight: 400;
    font-variant-numeric: tabular-nums;
    line-height: 1;
    color: #ffffff;
    -webkit-text-stroke: 0.16em var(--ui-outline);
    paint-order: stroke fill;
    text-shadow: 0 0.07em 0 var(--ui-outline), 0 0.15em 0.3em rgba(0, 0, 0, 0.3);
}

.rj-attack__coin,
.rj-raid__result-coin {
    width: 2.6rem;
    height: 2.6rem;
    object-fit: contain;
    filter: drop-shadow(0 2px 0 var(--ui-outline));
    animation: rj-ra-coin-spin 0.8s ease-out both;
}

@keyframes rj-ra-coin-spin {
    from { transform: rotateY(540deg) scale(0.4); }
    to   { transform: rotateY(0) scale(1); }
}

@keyframes rj-ra-pop-in {
    0%   { transform: scale(0.3) rotate(-8deg); opacity: 0; }
    100% { transform: scale(1) rotate(0); opacity: 1; }
}

.rj-attack__result-text,
.rj-raid__result-text {
    margin: 0;
    color: var(--ui-panel-ink);
    font-size: 1.05rem;
    font-weight: 800;
}

.rj-attack__again,
.rj-raid__again {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: flex-end;
    gap: 0.6rem 0.8rem;
    margin-top: 0.2rem;
}

/* ---------------------------------------------------------------------------
   The raid screen
   --------------------------------------------------------------------------- */
/* While the player digs, the header card names the raid, so the chip with the raids left hides. */
.rj-raid[data-state="digging"] .rj-raid__pending,
.rj-raid[data-state="revealing"] .rj-raid__pending,
.rj-raid[data-state="taking"] .rj-raid__pending { display: none; }

.rj-raid__searching {
    align-self: center;
    margin: 1.5rem 0 0;
    padding: 0.6rem 1.1rem;
    border: var(--ui-border) solid var(--ui-outline);
    border-radius: 1rem;
    background: var(--ui-bubble);
    box-shadow: 0 4px 0 var(--ui-outline);
    color: var(--ui-bubble-ink);
    font-family: var(--ui-font-display);
    font-size: 1.15rem;
    font-weight: 400;
}

.rj-raid__start {
    align-self: center;
    margin-top: 1rem;
}

.rj-raid__target {
    position: relative;
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    gap: 0.5rem;
}

/* The header card: the ribbon banner straddles its top edge, and under it the framed portrait, the name and the stash. */
.rj-raid__head {
    margin-top: 1.05rem;
    padding: 0.45rem 0.75rem 0.65rem;
}

.rj-raid__head > .rj-ribbon:first-child,
.rj-raid__result > .rj-ribbon:first-child {
    max-width: calc(100% - 2.2rem);
    white-space: normal;
}

.rj-raid__head > .rj-ribbon:first-child {
    position: relative;
    left: auto;
    top: auto;
    display: flex;
    width: fit-content;
    margin: -1.55rem auto 0.4rem;
    transform: none;
    font-size: clamp(0.92rem, 4.2vw, 1.12rem);
}

.rj-raid__who {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
}

.rj-raid__portrait { width: 3.2rem; height: 3.2rem; }

.rj-raid__info {
    display: flex;
    flex-direction: column;
    gap: 0.05rem;
    min-width: 0;
}

.rj-raid__name {
    font-family: var(--ui-font-display);
    font-size: 1.15rem;
    font-weight: 400;
    line-height: 1.1;
    color: var(--ui-panel-ink);
    overflow-wrap: anywhere;
}

/* The stash: the coin art and the amount as a big number, and the "hidden here" line beside it. */
.rj-raid__stash {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0 0.35rem;
    margin: 0;
}

.rj-raid__stash-art {
    width: 2.1rem;
    height: 2.1rem;
    object-fit: contain;
    filter: drop-shadow(0 2px 0 var(--ui-outline));
}

.rj-raid__stash-shape {
    width: 1.7rem;
    height: 1.7rem;
    border: 2px solid var(--ui-outline);
    border-radius: 50%;
    background: radial-gradient(circle at 35% 35%, var(--ui-primary-light) 0 22%, var(--ui-primary) 23% 70%, var(--ui-primary-dark) 71%);
}

.rj-raid__stash-amount {
    font-family: var(--ui-font-display);
    font-size: 1.75rem;
    font-weight: 400;
    font-variant-numeric: tabular-nums;
    line-height: 1.05;
    color: #ffffff;
    -webkit-text-stroke: 0.18em var(--ui-outline);
    paint-order: stroke fill;
    text-shadow: 0 0.08em 0 var(--ui-outline);
}

.rj-raid__stash-label {
    color: var(--ui-panel-ink-2);
    font-size: 0.85rem;
    font-weight: 800;
    line-height: 1.1;
}

/* The row under the card: the shovels for the digs left with the line, and the pill with the coins found so far. Both are
   on screen from the start and stay on one line, so the board under them never moves while the player taps. */
.rj-raid__status {
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    justify-content: center;
    gap: 0.4rem 0.6rem;
}

.rj-raid__hint {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    margin: 0;
    padding: 0.15rem 0.7rem 0.15rem 0.35rem;
    border: var(--ui-border) solid var(--ui-outline);
    border-radius: 999px;
    background: var(--ui-pill-bg);
    box-shadow: inset 0 0 0 1.5px var(--ui-pill-rim), 0 2px 0 var(--ui-outline);
    color: var(--ui-pill-ink);
    font-family: var(--ui-font-display);
    font-size: 1rem;
    font-weight: 400;
    white-space: nowrap;
}

.rj-raid__hint[data-line="lastdig"] {
    background: linear-gradient(180deg, var(--ui-danger-light), var(--ui-danger) 60%);
    color: #ffffff;
    -webkit-text-stroke: 0.18em var(--ui-outline);
    paint-order: stroke fill;
    animation: rj-ra-throb 1.2s ease-in-out infinite;
}

@keyframes rj-ra-throb {
    0%, 100% { transform: scale(1); }
    50%      { transform: scale(1.06); }
}

.rj-raid__tools {
    display: inline-flex;
    gap: 0.05rem;
}

.rj-raid__tool {
    width: 1.55rem;
    height: 1.55rem;
    overflow: visible;
    stroke: var(--ui-outline);
    stroke-width: 1.5;
    stroke-linejoin: round;
    filter: drop-shadow(0 1.5px 0 var(--ui-outline));
    transition: opacity 0.3s, filter 0.3s, transform 0.3s var(--ui-pop);
}

.rj-raid__tool.is-used {
    opacity: 0.35;
    filter: grayscale(1);
    transform: scale(0.8);
}

/* The coins found so far: the number counts up and bounces at each find (NumberCountUp). Before the first find the pill
   shows 0 a little faded. */
.rj-raid__found {
    position: relative;
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    min-width: 4.2rem;
    justify-content: center;
    margin: 0 0 0 0.7rem;
    padding: 0.2rem 0.75rem 0.2rem 1.45rem;
    border: var(--ui-border) solid var(--ui-outline);
    border-radius: 999px;
    background: linear-gradient(180deg, var(--ui-primary-light), var(--ui-primary) 60%);
    box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.45), 0 2px 0 var(--ui-outline);
    color: #ffffff;
    font-family: var(--ui-font-display);
    font-size: 0.98rem;
    font-weight: 400;
    font-variant-numeric: tabular-nums;
    -webkit-text-stroke: 0.18em var(--ui-outline);
    paint-order: stroke fill;
}

.rj-raid__found:not(.has-coins) { filter: saturate(0.6); }

.rj-raid__found-value { display: inline-block; }

/* On a narrow screen the row keeps to one line with smaller shovels and text. */
@media (max-width: 380px) {
    .rj-raid__status { gap: 0.4rem; }
    .rj-raid__hint { font-size: 0.92rem; padding-right: 0.55rem; }
    .rj-raid__tool { width: 1.3rem; height: 1.3rem; }
    .rj-raid__found { margin-left: 0.6rem; font-size: 0.92rem; padding-left: 1.3rem; }
}

.rj-raid__found-coin {
    position: absolute;
    left: -0.75rem;
    top: 50%;
    width: 1.9rem;
    height: 1.9rem;
    object-fit: contain;
    transform: translateY(-50%);
    filter: drop-shadow(0 2px 0 var(--ui-outline));
}

/* --- Dig spots (Components/Site/DigSpot.razor) ---------------------------------------------------------------------
   A dig spot draws in front of every structure (a structure's stacking order is at most 1000, its vertical position
   times ten), so a tap on the spot reaches the spot (known issue K4). The raid screen's structures take no tap. A spot
   is at least 44 × 44 px around its centre, because a short raid screen draws the site small; the art grows with it.
   The button never moves, so a tap lands where the player aimed; only its body inside shakes and bobs. */
.rj-dig {
    position: absolute;
    z-index: 2000;
    display: block;
    min-width: 2.75rem;
    min-height: 2.75rem;
    padding: 0;
    border: 0;
    background: none;
    transform: translate(-50%, -50%);
    cursor: pointer;
    font: inherit;
    color: inherit;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    user-select: none;
}

/* app-base.css fades every disabled button and scales every pressed one. A spot the player cannot tap (a dug spot, or any
   spot while no dig is left) stays at full strength, and a press keeps the spot's centring transform. */
.rj-dig:disabled { cursor: default; opacity: 1; }
.rj-dig:active:not(:disabled) { transform: translate(-50%, -50%); }

/* The raid screen's structures take no tap, so they are disabled; they are the target's base, so they keep full colour. */
.rj-raid .rj-structure:disabled { opacity: 1; }

.rj-dig__body {
    position: relative;
    display: block;
}

/* A spot the player can dig glows and bobs now and then, so the player sees what to tap. */
.rj-dig.is-closed:not(:disabled) { filter: drop-shadow(0 0 0.45rem var(--ui-primary-light)) drop-shadow(0 0 0.15rem #ffffff); }
.rj-dig.is-closed:not(:disabled):not(.is-tapped) .rj-dig__body { animation: rj-ra-bob 2.4s ease-in-out infinite; }
.rj-dig.is-closed:not(:disabled):nth-child(odd):not(.is-tapped) .rj-dig__body { animation-delay: 0.6s; }

@keyframes rj-ra-bob {
    0%, 70%, 100% { transform: translateY(0) rotate(0); }
    78%           { transform: translateY(-8%) rotate(-5deg); }
    86%           { transform: translateY(0) rotate(4deg); }
    93%           { transform: translateY(-3%) rotate(-2deg); }
}

/* A tap shakes the body. The two classes play the same shake, so the browser starts it again at each tap. */
.rj-dig__body.is-shake-a { animation: rj-ra-shake-a 0.32s ease-out; }
.rj-dig__body.is-shake-b { animation: rj-ra-shake-b 0.32s ease-out; }

@keyframes rj-ra-shake-a {
    0%   { transform: translate(0, 0) rotate(0) scale(1); }
    20%  { transform: translate(-6%, 3%) rotate(-6deg) scale(0.92); }
    45%  { transform: translate(5%, -2%) rotate(5deg) scale(1.04); }
    70%  { transform: translate(-3%, 1%) rotate(-2deg) scale(0.99); }
    100% { transform: translate(0, 0) rotate(0) scale(1); }
}

@keyframes rj-ra-shake-b {
    0%   { transform: translate(0, 0) rotate(0) scale(1); }
    20%  { transform: translate(6%, 3%) rotate(6deg) scale(0.92); }
    45%  { transform: translate(-5%, -2%) rotate(-5deg) scale(1.04); }
    70%  { transform: translate(3%, 1%) rotate(2deg) scale(0.99); }
    100% { transform: translate(0, 0) rotate(0) scale(1); }
}

/* While the dig waits for the server, the spot keeps digging. */
.rj-dig.is-pending .rj-dig__body { animation: rj-ra-digging 0.22s linear infinite; }

@keyframes rj-ra-digging {
    0%, 100% { transform: translate(0, 0) rotate(0); }
    25%      { transform: translate(-3%, 2%) rotate(-3deg); }
    75%      { transform: translate(3%, -1%) rotate(3deg); }
}

/* The spot pops open when the server reveals it; the loot glows. */
.rj-dig.is-loot .rj-dig__body,
.rj-dig.is-open .rj-dig__body { animation: rj-ra-open 0.5s var(--ui-pop) both; }
.rj-dig.is-loot { filter: drop-shadow(0 0 0.5rem #ffe27a); }
.rj-dig.is-open:not(.is-loot) .rj-dig__art { filter: saturate(0.7) brightness(0.92); }

@keyframes rj-ra-open {
    0%   { transform: scale(0.7); }
    55%  { transform: scale(1.18); }
    100% { transform: scale(1); }
}

.rj-dig__art {
    display: block;
    width: 100%;
    height: auto;
}

.rj-dig__art--placeholder {
    aspect-ratio: 1;
    border-radius: 50%;
    background:
        radial-gradient(circle, color-mix(in srgb, var(--ui-outline) 70%, transparent) 0 30%, transparent 31%),
        radial-gradient(circle, var(--ui-primary-dark) 0 60%, transparent 61%);
    border: 3px dashed var(--ui-primary);
}

.rj-dig.is-loot .rj-dig__art--placeholder,
.rj-dig.is-open .rj-dig__art--placeholder { border-style: solid; }

/* The cracks over a spot the player is tapping: one more set of cracks per tap. */
.rj-dig__cracks {
    position: absolute;
    inset: 6% 10% 14%;
    width: 80%;
    height: 80%;
    overflow: visible;
    pointer-events: none;
}

.rj-dig__crack {
    fill: none;
    stroke: #2b1708;
    stroke-width: 5;
    stroke-linecap: round;
    stroke-linejoin: round;
    filter: drop-shadow(0 1px 0 rgba(255, 255, 255, 0.55));
}

.rj-dig__cracks.is-stage-1 .rj-dig__crack--2,
.rj-dig__cracks.is-stage-1 .rj-dig__crack--3,
.rj-dig__cracks.is-stage-2 .rj-dig__crack--3 { display: none; }

/* The dust of a tap: five puffs that fly out from the spot's centre and fade. */
.rj-dig__dust {
    position: absolute;
    left: 50%;
    top: 55%;
    width: 0;
    height: 0;
    pointer-events: none;
}

.rj-dig__dust i {
    position: absolute;
    width: 0.65rem;
    height: 0.65rem;
    margin: -0.325rem;
    border-radius: 50%;
    background: radial-gradient(circle at 35% 35%, #fff3d6, #c9a77a 70%);
    opacity: 0;
    animation: rj-ra-dust 0.55s ease-out forwards;
}

.rj-dig__dust i:nth-child(1) { --dx: -1.6rem; --dy: -1.1rem; }
.rj-dig__dust i:nth-child(2) { --dx: 1.5rem;  --dy: -1.3rem; animation-delay: 0.02s; }
.rj-dig__dust i:nth-child(3) { --dx: -1.9rem; --dy: 0.3rem;  animation-delay: 0.04s; }
.rj-dig__dust i:nth-child(4) { --dx: 1.8rem;  --dy: 0.2rem; }
.rj-dig__dust i:nth-child(5) { --dx: 0.2rem;  --dy: -1.8rem; animation-delay: 0.03s; }

@keyframes rj-ra-dust {
    0%   { opacity: 0.95; transform: translate(0, 0) scale(0.5); }
    100% { opacity: 0;    transform: translate(var(--dx), var(--dy)) scale(1.4); }
}

/* The taps so far as pips under the spot. */
.rj-dig__pips {
    position: absolute;
    left: 50%;
    bottom: -0.45rem;
    display: flex;
    gap: 0.15rem;
    padding: 0.12rem 0.2rem;
    border: 2px solid var(--ui-outline);
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.55);
    transform: translateX(-50%);
    pointer-events: none;
}

.rj-dig__pips i {
    width: 0.45rem;
    height: 0.45rem;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.3);
}

.rj-dig__pips i.is-on {
    background: radial-gradient(circle at 35% 35%, var(--ui-primary-light), var(--ui-primary) 70%);
    animation: rj-ui-pop 0.3s var(--ui-pop) both;
}

/* --- Dig bubbles (Raid.razor, DigFeedback.PlaceCallout) -------------------------------------------------------------
   A tooltip bubble (.rj-tip) next to a dig spot: the line while the player taps, and what the spot held when the server
   reveals it. The page places it on one side of the spot in percent of the site and sets its width (--tip-w, the width
   PlaceCallout assumes for its text), and --tip-shift moves it off its anchor to that side. With pointer-events: none, the
   browser sends a tap on a bubble to the spot under it. */
.rj-dig-tip {
    --tip-shift: translate(-50%, -100%);
    position: absolute;
    z-index: 2500;
    box-sizing: border-box;
    width: var(--tip-w, 46cqw);
    /* The page's width is an estimate; a word never breaks out of the bubble. */
    min-width: min-content;
    /* The side padding and the type size follow the site's width, so the bubble is as wide as DigFeedback.PlaceCallout
       assumes on the smallest site (237 px at 360 × 640) too. */
    padding: 0.3rem clamp(0.25rem, 2cqw, 0.5rem) 0.35rem;
    border: var(--ui-border) solid var(--ui-outline);
    border-radius: 0.8rem;
    box-shadow: 0 3px 0 var(--ui-outline), 0 6px 14px rgba(0, 0, 0, 0.3);
    font-family: var(--ui-font-display);
    font-size: clamp(0.66rem, 4.6cqw, 1.1rem);
    font-weight: 400;
    line-height: 1.1;
    pointer-events: none;
    transform: var(--tip-shift);
    animation: rj-ra-tip 0.3s var(--ui-pop) both;
}

.rj-dig-tip--above { --tip-shift: translate(-50%, -100%); transform-origin: var(--tail-x, 50%) 100%; }
.rj-dig-tip--below { --tip-shift: translate(-50%, 0);     transform-origin: var(--tail-x, 50%) 0; }
.rj-dig-tip--right { --tip-shift: translate(0, -50%);     transform-origin: 0 50%; }
.rj-dig-tip--left  { --tip-shift: translate(-100%, -50%); transform-origin: 100% 50%; }

@keyframes rj-ra-tip {
    0%   { transform: var(--tip-shift) scale(0.4); opacity: 0; }
    100% { transform: var(--tip-shift) scale(1);   opacity: 1; }
}

/* The tail: a square turned 45°, with the outline on its two outer sides. */
.rj-dig-tip::after {
    width: 0.75rem;
    height: 0.75rem;
    border: var(--ui-border) solid var(--ui-outline);
    box-sizing: border-box;
}

.rj-dig-tip.rj-tip--tail-bottom::after { bottom: -0.45rem; border-top: 0; border-left: 0; }
.rj-dig-tip.rj-tip--tail-top::after    { top: -0.45rem; border-bottom: 0; border-right: 0; }

.rj-dig-tip.rj-tip--tail-left::after {
    left: -0.45rem;
    top: 50%;
    border-top: 0;
    border-right: 0;
    transform: translateY(-50%) rotate(45deg);
}

.rj-dig-tip.rj-tip--tail-right::after {
    right: -0.45rem;
    left: auto;
    top: 50%;
    border-bottom: 0;
    border-left: 0;
    transform: translateY(-50%) rotate(45deg);
}

.rj-dig-tip__main,
.rj-dig-tip__next {
    display: block;
}

.rj-dig-tip__next {
    margin-top: 0.1rem;
    font-size: 0.82em;
}

/* What a spot held: the coins in big white display text on the main colour, or a quiet grey bubble for an empty spot. */
.rj-raid__callout.is-loot {
    background: linear-gradient(180deg, var(--ui-primary-light), var(--ui-primary) 60%);
    color: #ffffff;
    -webkit-text-stroke: 0.18em var(--ui-outline);
    paint-order: stroke fill;
}

.rj-raid__callout.is-loot .rj-raid__callout-main { font-size: 1.35em; }

.rj-raid__callout.is-empty {
    background: #eef1f4;
    color: #2d3540;
}

/* The bubble fades after a moment; the page then takes it away. */
.rj-raid__callout {
    animation: rj-ra-tip 0.3s var(--ui-pop) both, rj-ra-tip-out 0.3s ease-in 1.3s forwards;
}

@keyframes rj-ra-tip-out {
    to { opacity: 0; }
}

/* --- The raid result ------------------------------------------------------------------------------------------------- */
.rj-raid__result {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.6rem;
    overflow: visible;
    text-align: center;
}

.rj-raid__result.is-refused { --ui-panel-border: var(--ui-danger); }

.rj-raid__result > :not(.rj-raid__rays):not(.rj-raid__sparkles):not(.rj-ribbon) { position: relative; z-index: 1; }

.rj-raid__result .rj-raid__rays { top: 9.5rem; }

.rj-raid__who--result { gap: 0.6rem; }

.rj-raid__result-coins {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    margin: 0;
    animation: rj-ra-pop-in 0.5s var(--ui-pop) both;
}

.rj-raid__result.is-haul-big .rj-raid__result-count { font-size: 2.8rem; }

/* Sparkles around a big haul. */
.rj-raid__sparkles {
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
}

.rj-raid__sparkles i {
    position: absolute;
    width: 1rem;
    height: 1rem;
    background: #fff4a8;
    clip-path: polygon(50% 0, 62% 38%, 100% 50%, 62% 62%, 50% 100%, 38% 62%, 0 50%, 38% 38%);
    filter: drop-shadow(0 0 4px #ffd84d);
    animation: rj-ra-twinkle 1.6s ease-in-out infinite;
}

.rj-raid__sparkles i:nth-child(1) { left: 12%; top: 18%; }
.rj-raid__sparkles i:nth-child(2) { left: 84%; top: 22%; animation-delay: 0.4s; width: 0.8rem; height: 0.8rem; }
.rj-raid__sparkles i:nth-child(3) { left: 20%; top: 46%; animation-delay: 0.8s; }
.rj-raid__sparkles i:nth-child(4) { left: 78%; top: 50%; animation-delay: 0.2s; width: 1.2rem; height: 1.2rem; }
.rj-raid__sparkles i:nth-child(5) { left: 8%;  top: 70%; animation-delay: 1s; width: 0.7rem; height: 0.7rem; }
.rj-raid__sparkles i:nth-child(6) { left: 90%; top: 76%; animation-delay: 0.6s; }

@keyframes rj-ra-twinkle {
    0%, 100% { transform: scale(0.3) rotate(0); opacity: 0.2; }
    50%      { transform: scale(1) rotate(45deg); opacity: 1; }
}

/* The four spots as small tiles: the dug ones in the main colour, the one the player left faded. */
.rj-raid__spots {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0.4rem;
    width: 100%;
    margin: 0;
    padding: 0;
    list-style: none;
}

.rj-raid__spot {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.1rem;
    padding: 0.3rem 0.15rem;
    border: 2px solid var(--ui-outline);
    border-radius: 0.7rem;
    background: color-mix(in srgb, var(--ui-outline) 35%, transparent);
    box-shadow: 0 2px 0 var(--ui-outline);
    color: var(--ui-panel-ink);
    font-family: var(--ui-font-display);
    font-size: 0.85rem;
    font-weight: 400;
    font-variant-numeric: tabular-nums;
    animation: rj-ra-pop-in 0.4s var(--ui-pop) both;
    animation-delay: calc(var(--i, 1) * 0.08s);
}

.rj-raid__spot-art { width: min(100%, 2.6rem); height: auto; }

.rj-raid__spot.is-dug {
    background: linear-gradient(180deg, var(--ui-primary-light), var(--ui-primary) 60%);
    color: #ffffff;
    -webkit-text-stroke: 0.18em var(--ui-outline);
    paint-order: stroke fill;
}

/* A spot that held nothing reads as empty, whether the player dug it or not. */
.rj-raid__spot.is-empty {
    background: #d9dee3;
    color: #3a424c;
    -webkit-text-stroke: 0;
}

/* A spot the player did not dig shows the loot the player left behind, struck through and faded, so the tiles the player
   dug are the ones that add up to the coins taken. */
.rj-raid__spot.is-hidden { opacity: 0.6; }
.rj-raid__spot.is-hidden .rj-raid__spot-coins { text-decoration: line-through; }

.rj-raid__spot-note {
    font-family: var(--font-body);
    font-size: 0.66rem;
    font-weight: 800;
    -webkit-text-stroke: 0;
}

/* ---------------------------------------------------------------------------
   Reduced motion: no shake, bob, pop, rays or sparkles.
   --------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    .rj-raid__rays,
    .rj-attack__rays,
    .rj-raid__sparkles i,
    .rj-raid__searching::after,
    .rj-attack__searching::after,
    .rj-attack__message,
    .rj-raid__message,
    .rj-attack__result-art,
    .rj-attack__coin,
    .rj-raid__result-coin,
    .rj-raid__result-coins,
    .rj-raid__spot,
    .rj-raid__hint[data-line="lastdig"],
    .rj-raid__found,
    .rj-dig__body,
    .rj-dig__body.is-shake-a,
    .rj-dig__body.is-shake-b,
    .rj-dig.is-pending .rj-dig__body,
    .rj-dig.is-closed:not(:disabled):not(.is-tapped) .rj-dig__body,
    .rj-dig.is-loot .rj-dig__body,
    .rj-dig.is-open .rj-dig__body,
    .rj-dig__dust i,
    .rj-dig__pips i.is-on,
    .rj-dig-tip,
    .rj-raid__callout,
    .rj-target .rj-structure:not(:disabled)::after { animation: none; }

    .rj-dig__dust { display: none; }
    .rj-raid__tool { transition: none; }
}
