/* ==========================================================================
   Wilderness Reborn.

   AdventureQuest bones: a wide battle stage with the player on the left and
   whatever found them on the right, gold-plated status bars beneath, and the
   panels under that. Colours lean on the site's own tokens so the page still
   reads as pawsoffury.net.
   ========================================================================== */

.wildy-main {
    max-width: 1060px;
    margin: 0 auto;
    padding: 0 1rem 3rem;
}

.wildy-state {
    text-align: center;
    color: var(--muted, #a0a2ab);
    padding: 3rem 0;
}

/* ----- the intro --------------------------------------------------------- */
.wildy-hero {
    max-width: 34rem;
    margin: 3rem auto;
    text-align: center;
    display: grid;
    gap: 1rem;
    justify-items: center;
}

.wildy-hero h1 { font-size: 2rem; }

/* ----- the stage --------------------------------------------------------- */
/* The stage breaks out of the reading column and runs the full width of the
   window, because the backgrounds are wide scenes and a 1060px letterbox
   wasted most of them. The height follows the viewport so the whole thing is
   in view at once without the panels below being pushed off the fold.

   body.wildy-page carries overflow-x: clip for this -- 100vw counts the
   scrollbar and would otherwise leave a few pixels of horizontal scroll.
   `clip` rather than `hidden` so the sticky topline keeps working. */
.wildy-stage {
    position: relative;
    height: clamp(330px, 62vh, 620px);
    width: 100vw;
    margin-left: calc(50% - 50vw);
    border-radius: 0;
    border-block: 1px solid var(--line, #262a33);
    background: #10131a center / cover no-repeat;
    overflow: hidden;
}

.wildy-place {
    position: absolute;
    top: 0.6rem;
    left: 50%;
    transform: translateX(-50%);
    padding: 0.25rem 0.8rem;
    border-radius: 999px;
    background: rgba(10, 12, 16, 0.72);
    border: 1px solid var(--line, #262a33);
    font-size: 0.8rem;
    font-weight: 700;
    white-space: nowrap;
}

.wildy-place.is-danger { border-color: #b3372f; color: #ffb4a8; }

.wildy-fighter {
    position: absolute;
    /* On top of the ground the scene draws, not on the edge of the stage. */
    bottom: calc(var(--wground, 0px) - 4px);
    z-index: 1;
    display: grid;
    justify-items: center;
    transition: transform 0.1s ease;
}

/* Character art keeps its whole 768px canvas (packed to 512) so equipment
   overlays can align on it pixel-perfect. That canvas leaves 62 of its 768
   empty below the feet, so the figure is pulled down by that same share of
   whatever height it happens to be drawn at -- a fixed offset was right at
   one size only, and left the feet hovering once the stage could grow. */
/* Three times the 128-pixel canvas the art is drawn on, so every pixel of
   it is a clean 3x3 square. A figure sized to the viewport landed on
   fractions of a pixel and the browser smoothed the difference, which is
   what made a crisp sprite look painted. Two on a short screen; still
   whole. */
.wildy-stage { --wchar: 384px; --wground: 120px; }
@media (max-height: 760px) {
    .wildy-stage { --wchar: 256px; --wground: 80px; }
}

/* The scene itself: drawn small and blown up by a whole number, so its
   pixels are the size of the sprites' pixels. Behind everything, and not
   something a reader needs announced. */
.wildy-scene {
    position: absolute;
    inset: 0;
    z-index: 0;
    width: 100%;
    height: 100%;
    image-rendering: pixelated;
    pointer-events: none;
}

.wildy-player {
    left: max(8%, calc(50% - 30rem));
    bottom: calc(var(--wground, 0px) - var(--wchar) * 0.0574);
}
.wildy-npc { right: max(10%, calc(50% - 30rem)); }

.wildy-player img#player-img {
    height: var(--wchar);
    width: auto;
    image-rendering: pixelated;
}
/* The NPC sprite is the south-west view, so it already faces the player --
   it used to be the east view flipped, which is why it needed mirroring.
   Every monster is drawn on a canvas of its own size, so the whole-number
   scale is worked out per sprite as it loads (crispNpc) and set here. */
.wildy-npc img {
    height: 300px;
    width: auto;
    image-rendering: pixelated;
}

/* Worn equipment, layered over the base on the same canvas. Drawn art at
   characters/overlay-<slot>-<slug>.png appears here by existing. */
.wildy-overlay {
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    height: var(--wchar);
    width: auto;
    image-rendering: pixelated;
    pointer-events: none;
}

/* The equipped weapon, held at an angle by the base character's lowered
   hand. The stand-in for a weapon with no overlay art yet. */
#hand-item {
    position: absolute;
    bottom: 107px;
    right: 84px;
    width: 84px;
    height: 84px;
    object-fit: contain;
    image-rendering: pixelated;
    transform: rotate(-38deg);
    filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.5));
    pointer-events: none;
    z-index: 2;
}

.wildy-fighter.is-hit { transform: translateX(0); animation: wildy-shake 0.28s; }

@keyframes wildy-shake {
    20% { transform: translateX(-7px); }
    50% { transform: translateX(6px); }
    80% { transform: translateX(-3px); }
}

/* ----- combat motion ------------------------------------------------------ */
/* The lunge: a step into the strike and back. The player faces right, the
   NPC faces left, so each lunges towards the other. */
.wildy-fighter.is-lunge-r { animation: wildy-lunge-r 0.26s ease-out; }
.wildy-fighter.is-lunge-l { animation: wildy-lunge-l 0.26s ease-out; }

@keyframes wildy-lunge-r {
    35% { transform: translateX(52px); }
    70% { transform: translateX(38px); }
}

@keyframes wildy-lunge-l {
    35% { transform: translateX(-52px); }
    70% { transform: translateX(-38px); }
}

/* Stab is a straight thrust; crush is an overhead smash. Each stance moves
   the way the weapon actually would, and the NPC mirrors it leftwards. */
.wildy-fighter.is-thrust-r { animation: wildy-thrust-r 0.22s ease-out; }
.wildy-fighter.is-thrust-l { animation: wildy-thrust-l 0.22s ease-out; }

@keyframes wildy-thrust-r { 40% { transform: translateX(66px); } }
@keyframes wildy-thrust-l { 40% { transform: translateX(-66px); } }

.wildy-fighter.is-crush-r { animation: wildy-crush-r 0.3s ease-in; }
.wildy-fighter.is-crush-l { animation: wildy-crush-l 0.3s ease-in; }

@keyframes wildy-crush-r {
    30% { transform: translate(8px, -24px) rotate(-7deg); }
    70% { transform: translate(46px, 4px) rotate(8deg); }
}

@keyframes wildy-crush-l {
    30% { transform: translate(-8px, -24px) rotate(7deg); }
    70% { transform: translate(-46px, 4px) rotate(-8deg); }
}

/* Staggered by a special: a reel, not a flinch. */
.wildy-fighter.is-stagger { animation: wildy-stagger 0.65s ease; }

@keyframes wildy-stagger {
    25% { transform: rotate(-9deg) translateX(-9px); }
    60% { transform: rotate(6deg) translateX(6px); }
}

/* The weapon swings up and through during a melee strike. */
#hand-item.is-swing { animation: wildy-swing 0.26s ease-in-out; }

@keyframes wildy-swing {
    30% { transform: rotate(-110deg) translateY(-8px); }
    65% { transform: rotate(12deg); }
    100% { transform: rotate(-38deg); }
}

/* Projectiles: spawned at the attacker's chest height, flown across the
   stage with a transition on transform. */
.wildy-proj {
    position: absolute;
    bottom: 150px;
    pointer-events: none;
    z-index: 3;
    transition: transform 0.28s linear, opacity 0.28s linear;
}

.wildy-proj.from-player { left: 16%; }
.wildy-proj.from-npc { right: 16%; }
.wildy-proj.from-player.is-flying { transform: translateX(min(58vw, 560px)); }
.wildy-proj.from-npc.is-flying { transform: translateX(max(-58vw, -560px)); }

/* An arrow: shaft, head and fletching drawn as one bar. */
.wildy-proj.is-arrow {
    width: 46px;
    height: 3px;
    background: linear-gradient(90deg, #c9cdd6 0 12%, #8a6b43 12% 88%, #e8e9ec 88%);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
}

.wildy-proj.is-arrow.from-npc { transform: scaleX(-1); }
.wildy-proj.is-arrow.from-npc.is-flying { transform: scaleX(-1) translateX(min(58vw, 560px)); }

/* A spell bolt, and necromancy's paler cousin. */
.wildy-proj.is-orb,
.wildy-proj.is-skull {
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: radial-gradient(circle at 35% 35%, #bfe7ff, #3fa4e8 55%, rgba(63, 164, 232, 0));
    filter: drop-shadow(0 0 8px rgba(87, 178, 224, 0.9));
}

.wildy-proj.is-skull {
    background: radial-gradient(circle at 35% 35%, #d8ffd8, #4ec06a 55%, rgba(78, 192, 106, 0));
    filter: drop-shadow(0 0 8px rgba(110, 220, 130, 0.9));
}

/* Damage splats: the RS red star, blue for a miss, green for a heal. */
.wildy-splat {
    position: absolute;
    left: 50%;
    top: 34%;
    transform: translate(-50%, 0);
    min-width: 34px;
    padding: 0.3rem 0.4rem;
    text-align: center;
    border-radius: 50% 45% 55% 48%;
    background: radial-gradient(#e0473a, #8e1f16);
    color: #fff;
    font-weight: 900;
    font-size: 0.95rem;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.7);
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5);
    animation: wildy-splat-pop 0.8s ease-out forwards;
    pointer-events: none;
    z-index: 4;
}

.wildy-splat.is-zero { background: radial-gradient(#3f65b0, #1d3466); }
.wildy-splat.is-heal { background: radial-gradient(#4ec06a, #1f6e35); }

@keyframes wildy-splat-pop {
    0% { opacity: 0; transform: translate(-50%, 8px) scale(0.5); }
    18% { opacity: 1; transform: translate(-50%, 0) scale(1.12); }
    30% { transform: translate(-50%, 0) scale(1); }
    75% { opacity: 1; }
    100% { opacity: 0; transform: translate(-50%, -16px) scale(0.95); }
}

/* Entrances and deaths. The NPC strides in from the right; the fallen keel
   over and fade where they stand. */
.wildy-fighter.is-enter { animation: wildy-enter 0.45s ease-out; }

@keyframes wildy-enter {
    0% { opacity: 0; transform: translateX(130px); }
    100% { opacity: 1; transform: translateX(0); }
}

.wildy-fighter.is-dead { animation: wildy-fall 0.75s ease-in forwards; }

@keyframes wildy-fall {
    30% { transform: rotate(8deg); }
    100% { opacity: 0; transform: rotate(84deg) translateY(26px); }
}

/* The red wash when you go down. */
.wildy-flash {
    position: absolute;
    inset: 0;
    background: radial-gradient(rgba(160, 20, 10, 0.12), rgba(120, 10, 5, 0.55));
    animation: wildy-flash-in 0.85s ease-out forwards;
    pointer-events: none;
    z-index: 5;
}

@keyframes wildy-flash-in {
    0% { opacity: 0; }
    25% { opacity: 1; }
    100% { opacity: 0; }
}

/* ----- special attacks ---------------------------------------------------- */
/* The whole stage jolts under a smash. */
#stage.is-quake { animation: wildy-quake 0.45s; }

@keyframes wildy-quake {
    20% { transform: translate(-5px, 3px); }
    40% { transform: translate(5px, -3px); }
    60% { transform: translate(-4px, 2px); }
    80% { transform: translate(3px, -2px); }
}

/* The flare when a special fires, coloured by its school. */
.wildy-aura {
    position: absolute;
    inset: -10px;
    border-radius: 50%;
    pointer-events: none;
    z-index: 2;
    background: radial-gradient(circle, rgba(255, 214, 90, 0.55), transparent 65%);
    animation: wildy-aura-pulse 0.45s ease-out forwards;
}

.wildy-aura.is-drain { background: radial-gradient(circle, rgba(205, 45, 45, 0.55), transparent 65%); }
.wildy-aura.is-beam { background: radial-gradient(circle, rgba(90, 170, 255, 0.55), transparent 65%); }
.wildy-aura.is-burst { background: radial-gradient(circle, rgba(150, 220, 120, 0.5), transparent 65%); }

@keyframes wildy-aura-pulse {
    0% { opacity: 0; transform: scale(0.6); }
    40% { opacity: 1; }
    100% { opacity: 0; transform: scale(1.3); }
}

/* A ward going up: a cool blue shell around the fighter. */
.wildy-guard-flash {
    position: absolute;
    inset: -6px;
    z-index: 3;
    pointer-events: none;
    border: 2px solid rgba(150, 210, 255, 0.75);
    border-radius: 14px;
    background: radial-gradient(circle, rgba(120, 200, 255, 0.4), transparent 70%);
    animation: wildy-aura-pulse 0.5s ease-out forwards;
}

/* The ⚡ buttons carry the gold of the thing they spend. */
button.wspec {
    border-color: #d9a441;
    color: #ffd977;
    min-height: 2.4rem;
}

button.wspec:disabled { opacity: 0.55; }

/* The combat buttons read as what they are. */
#btn-attack { border-color: #b3372f; }
#btn-flee { border-color: #7a5c2e; color: #e8c988; }

/* ----- the plates -------------------------------------------------------- */
.wildy-plates {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
    margin-top: 0.8rem;
}

.wildy-plate {
    border: 1px solid #7a5c2e;
    border-radius: 12px;
    background: linear-gradient(#1d1a12, #14120c);
    padding: 0.55rem 0.85rem;
    display: grid;
    gap: 0.35rem;
    box-shadow: inset 0 0 0 1px rgba(217, 164, 65, 0.15);
}

.wp-name {
    font-weight: 800;
    letter-spacing: 0.02em;
    color: #e8c988;
    border-bottom: 1px solid rgba(217, 164, 65, 0.25);
    padding-bottom: 0.25rem;
}

.wp-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.85rem;
}

.wp-sub { color: var(--muted, #a0a2ab); margin-left: auto; font-size: 0.78rem; }

.wp-bar {
    position: relative;
    flex: 1;
    height: 16px;
    border-radius: 8px;
    background: #0c0e12;
    border: 1px solid #3a3325;
    overflow: hidden;
}

.wp-fill {
    height: 100%;
    border-radius: 8px 0 0 8px;
    transition: width 0.25s ease;
}

.wp-fill.hp { background: linear-gradient(#e05545, #9c2f22); }
.wp-fill.npc { background: linear-gradient(#57b2e0, #2d6f9c); }

.wp-num {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    font-size: 0.72rem;
    font-weight: 800;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
}

/* ----- the actions ------------------------------------------------------- */
.wildy-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.8rem;
}

.wildy-actions button { min-height: 2.4rem; }

.wl-level {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.85rem;
    color: var(--muted, #a0a2ab);
}

.wl-level input { width: 4.2rem; }

body.is-busy .wildy-actions button { opacity: 0.6; pointer-events: none; }

/* ----- the log ----------------------------------------------------------- */
.wildy-log {
    list-style: none;
    margin: 0.8rem 0 0;
    padding: 0.6rem 0.85rem;
    border: 1px solid var(--line, #262a33);
    border-radius: 12px;
    background: var(--panel, #14161c);
    max-height: 220px;
    overflow-y: auto;
    font-size: 0.84rem;
    display: grid;
    gap: 0.2rem;
}

.wildy-log li.is-error { color: #ff9b8e; }
.wildy-log li.is-note { color: #e8c988; }

/* ----- tabs and panels --------------------------------------------------- */
.wildy-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    margin-top: 1rem;
}

.wtab {
    border: 1px solid var(--line, #262a33);
    border-bottom: none;
    border-radius: 10px 10px 0 0;
    background: transparent;
    padding: 0.45rem 0.9rem;
    cursor: pointer;
    color: var(--muted, #a0a2ab);
}

.wtab.is-here {
    background: var(--panel, #14161c);
    color: var(--text, #e8e9ec);
    font-weight: 700;
}

.wildy-panel {
    border: 1px solid var(--line, #262a33);
    border-radius: 0 12px 12px 12px;
    background: var(--panel, #14161c);
    padding: 0.8rem;
    display: grid;
    gap: 0.3rem;
    min-height: 160px;
}

.wi-row {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.3rem 0.4rem;
    border-radius: 8px;
}

.wi-row:hover { background: rgba(255, 255, 255, 0.04); }

.wi-icon {
    width: 34px;
    height: 34px;
    display: grid;
    place-items: center;
    flex: none;
}

.wi-img { max-width: 34px; max-height: 34px; }
.wi-fallback { color: var(--muted, #a0a2ab); }
.wi-name { flex: 1; font-size: 0.9rem; }
.wi-qty { color: var(--muted, #a0a2ab); font-size: 0.82rem; }
.wi-price { color: #e8c988; font-size: 0.82rem; margin-right: 0.4rem; }

.wi-actions { display: flex; gap: 0.3rem; }

.wi-actions button {
    font-size: 0.75rem;
    padding: 0.25rem 0.6rem;
    min-height: 0;
}

.wi-coins {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.4rem;
    border-bottom: 1px solid var(--line, #262a33);
    margin-bottom: 0.3rem;
}

/* Bestiary rows: a summary line that opens into the drop table. */
.wn-row {
    border: 1px solid var(--line, #262a33);
    border-radius: 10px;
    padding: 0.3rem 0.6rem;
}

.wn-row summary {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    cursor: pointer;
    list-style: none;
}

.wn-row summary small { color: var(--muted, #a0a2ab); margin-left: auto; }
.wn-body { padding: 0.5rem 0.4rem 0.3rem; font-size: 0.85rem; }
.wn-body ul { margin: 0.2rem 0 0.6rem 1.2rem; }

.wildy-stats ul { margin: 0.2rem 0 0.6rem 1.2rem; }

button.danger { border-color: #b3372f; color: #ffb4a8; }

.wildy-footnote {
    text-align: center;
    color: var(--muted, #a0a2ab);
    font-size: 0.8rem;
    padding-bottom: 2rem;
}

/* Only the game page: the stage above is deliberately wider than the column
   it sits in, and 100vw includes the scrollbar. */
body.wildy-page { overflow-x: clip; }

/* ===== Fullscreen stage, icon rail, floating nameplates ================== */
/* The stage is the game. It runs the full width of the viewport with the
   icon rail sitting against its right edge, and the HP bars ride above each
   fighter instead of in plates below. */
.wildy-world {
    position: relative;
    width: 100vw;
    margin-left: calc(50% - 50vw);
}

.wildy-world .wildy-stage {
    height: clamp(420px, 78vh, 900px);
    width: 100%;
    margin-left: 0;
}

/* ----- the icon rail ----------------------------------------------------- */
.wildy-rail {
    position: absolute;
    top: 50%;
    right: clamp(0.4rem, 1.5vw, 1.2rem);
    transform: translateY(-50%);
    display: grid;
    grid-template-columns: repeat(2, auto);
    gap: 0.3rem;
    padding: 0.4rem;
    border-radius: 12px;
    background: rgba(10, 12, 16, 0.72);
    border: 1px solid #7a5c2e;
    box-shadow: inset 0 0 0 1px rgba(217, 164, 65, 0.15);
    z-index: 3;
}

.wildy-rail .wtab {
    position: relative;
    display: grid;
    place-items: center;
    width: 46px;
    height: 46px;
    padding: 0;
    border: 1px solid transparent;
    border-radius: 9px;
    background: rgba(30, 26, 18, 0.6);
    cursor: pointer;
}

.wildy-rail .wtab img {
    /* Every icon is trimmed to its own subject, so they are all different
       shapes -- a tall slayer skull, a wide set of scales. Fixing both sides
       stretched each one into a square; these are limits, and contain keeps
       the proportions. */
    max-width: 34px;
    max-height: 34px;
    width: auto;
    height: auto;
    object-fit: contain;
    image-rendering: pixelated;
}

.wildy-rail .wtab:hover {
    border-color: #7a5c2e;
    background: rgba(60, 48, 26, 0.75);
    /* The rail is two columns, so a name reading rightwards crosses the icon
       beside it. Later siblings paint over earlier ones, so the hovered one
       has to come up or its tip sits behind the next icon along. */
    z-index: 6;
}

.wildy-rail .wtab.is-here {
    border-color: #d9a441;
    background: rgba(90, 68, 26, 0.9);
    box-shadow: 0 0 0 1px rgba(217, 164, 65, 0.35);
}

/* Bank and shop exist only in the safe zone. */
.wildy-rail .wtab[disabled] { opacity: 0.34; cursor: not-allowed; filter: grayscale(0.7); }

.wtab-tip {
    position: absolute;
    /* The rail is down the left, so the name reads outwards from it. */
    left: calc(100% + 0.45rem);
    top: 50%;
    transform: translateY(-50%);
    padding: 0.15rem 0.5rem;
    border-radius: 6px;
    background: rgba(10, 12, 16, 0.92);
    border: 1px solid var(--line, #262a33);
    font-size: 0.72rem;
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.12s;
    z-index: 6;
}

.wildy-rail .wtab:hover .wtab-tip { opacity: 1; }

.wtab-slots {
    grid-column: 1 / -1;
    text-align: center;
    font-size: 0.7rem;
    color: var(--muted, #a0a2ab);
    padding-top: 0.1rem;
}

/* ----- nameplates that ride above the fighters --------------------------- */
.wildy-nameplate {
    position: absolute;
    bottom: 100%;
    left: 50%;
    transform: translateX(-50%);
    margin-bottom: 0.35rem;
    display: grid;
    justify-items: center;
    gap: 0.15rem;
    padding: 0.28rem 0.5rem;
    border-radius: 9px;
    background: rgba(10, 12, 16, 0.78);
    border: 1px solid #7a5c2e;
    white-space: nowrap;
    pointer-events: none;
}

.np-name { font-size: 0.76rem; font-weight: 700; }
.np-sub { font-size: 0.68rem; color: var(--muted, #a0a2ab); }

.np-bar {
    position: relative;
    display: block;
    width: clamp(96px, 12vw, 150px);
    height: 13px;
    border-radius: 999px;
    background: #2a1c17;
    border: 1px solid #0c0e12;
    overflow: hidden;
}

.np-fill {
    display: block;
    height: 100%;
    width: 100%;
    transition: width 0.25s ease;
}

.np-fill.hp { background: linear-gradient(#e05545, #9c2f22); }
.np-fill.npc { background: linear-gradient(#57b2e0, #2d6f9c); }

.np-num {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    font-size: 0.66rem;
    font-weight: 700;
    text-shadow: 0 1px 2px #000;
}

/* ----- the HUD across the foot of the stage ------------------------------ */
.wildy-hud {
    position: absolute;
    left: 50%;
    bottom: 0.7rem;
    transform: translateX(-50%);
    display: grid;
    justify-items: center;
    gap: 0.4rem;
    width: min(100%, 62rem);
    padding: 0 0.6rem;
    z-index: 2;
}

.hud-purse {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.22rem 0.7rem;
    border-radius: 999px;
    background: rgba(10, 12, 16, 0.78);
    border: 1px solid #7a5c2e;
    font-size: 0.8rem;
}

.hud-style { color: var(--muted, #a0a2ab); font-size: 0.74rem; }

.wildy-hud .wildy-actions {
    justify-content: center;
    margin-top: 0;
    padding: 0.45rem 0.6rem;
    border-radius: 12px;
    background: rgba(10, 12, 16, 0.78);
    border: 1px solid #7a5c2e;
}

/* Panels sit under the stage, and the rail owns the tab strip now. */
.wildy-panel { border-radius: 12px; margin-top: 0.8rem; }

@media (max-width: 780px) {
    .wildy-rail {
        position: static;
        transform: none;
        grid-template-columns: repeat(6, auto);
        justify-content: center;
        margin: 0.6rem auto 0;
        width: max-content;
    }
    .wildy-hud { position: static; transform: none; width: 100%; margin-top: 0.6rem; }
    .wildy-world .wildy-stage { height: clamp(300px, 46vh, 460px); }
}

.wildy-soon { display: grid; gap: 0.35rem; padding: 0.6rem 0.2rem; }
.wildy-soon h3 { margin: 0; font-size: 1rem; }

/* ===== The rail, and the window that pops out beside it ================== */
/* The icons live down the left of the stage and a panel opens immediately to
   their right, over the scene -- a small window sized to its contents, not a
   column that shoves the game aside. */
.wildy-world { position: relative; }

.wildy-world .wildy-rail {
    top: 50%;
    left: clamp(0.4rem, 1.2vw, 1rem);
    right: auto;
    transform: translateY(-50%);
}

.wildy-drawer {
    position: absolute;
    top: 50%;
    left: calc(clamp(0.4rem, 1.2vw, 1rem) + 108px);
    transform: translateY(-50%);
    z-index: 4;
    display: none;
    grid-template-rows: auto 1fr;
    max-height: calc(100% - 1.6rem);
    max-width: calc(100% - 10rem);
    border: 2px solid #7a5c2e;
    border-radius: 12px;
    background: linear-gradient(#241c12, #17120c);
    box-shadow: inset 0 0 0 1px rgba(217, 164, 65, 0.18),
                0 10px 30px rgba(0, 0, 0, 0.55);
    overflow: hidden;
}

body.panel-open .wildy-drawer { display: grid; }

.wd-head {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.35rem 0.5rem;
    border-bottom: 2px solid #7a5c2e;
    background: linear-gradient(#3a2c19, #241a0f);
    font-size: 0.82rem;
    font-weight: 700;
}

.wd-head img {
    max-width: 20px;
    max-height: 20px;
    width: auto;
    height: auto;
    object-fit: contain;
    image-rendering: pixelated;
}
.wd-head .wd-sub { margin-left: auto; font-weight: 400; font-size: 0.72rem;
                   color: var(--muted, #a0a2ab); }

.wd-close {
    border: 1px solid #7a5c2e;
    background: rgba(0, 0, 0, 0.35);
    color: #e8c988;
    border-radius: 6px;
    width: 20px;
    height: 20px;
    font-size: 0.7rem;
    line-height: 1;
    cursor: pointer;
    padding: 0;
}

.wildy-panel {
    border: 0;
    border-radius: 0;
    background: transparent;
    margin: 0;
    padding: 0.5rem;
    min-height: 0;
    overflow-y: auto;
    display: block;
}

/* ----- slot grids -------------------------------------------------------- */
/* A slot is a fixed size, so a window is only ever as wide as its grid --
   which is what keeps the inventory the shape of an inventory. */
:root { --wslot: 46px; }

/* A grid with no shape named fits as many slots across as it has room
   for. The named ones below say exactly how many, because an inventory
   that reflows is not an inventory. */
.wgrid { display: grid; gap: 3px;
         grid-template-columns: repeat(auto-fill, var(--wslot)); }
.wgrid.inv   { grid-template-columns: repeat(4, var(--wslot)); }
.wgrid.bank  { grid-template-columns: repeat(8, var(--wslot)); }
.wgrid.shop  { grid-template-columns: repeat(5, var(--wslot)); }

.wslot {
    position: relative;
    width: var(--wslot);
    height: var(--wslot);
    background: url('/games/wildernessreborn/art/ui/slot.png') center / 100% 100% no-repeat;
    display: grid;
    place-items: center;
}

.wslot.is-empty { opacity: 0.5; }
.wslot.has-item { cursor: pointer; }
.wslot.has-item:hover { filter: brightness(1.3); }

.wslot img {
    width: 66%;
    height: 66%;
    object-fit: contain;
    image-rendering: pixelated;
    pointer-events: none;
}

.wslot .ws-qty {
    position: absolute;
    top: 3px;
    left: 5px;
    font-size: 0.6rem;
    font-weight: 700;
    color: #ffe08a;
    text-shadow: 0 1px 2px #000, 0 0 3px #000;
    pointer-events: none;
}

.wslot .ws-price {
    position: absolute;
    bottom: 2px;
    left: 0;
    right: 0;
    text-align: center;
    font-size: 0.55rem;
    color: #ffe08a;
    text-shadow: 0 1px 2px #000;
    pointer-events: none;
}

.wslot .ws-label {
    position: absolute;
    bottom: 3px;
    left: 0;
    right: 0;
    text-align: center;
    font-size: 0.56rem;
    letter-spacing: 0.01em;
    color: #b3a481;
    text-shadow: 0 1px 2px #000;
    pointer-events: none;
}

/* ----- the equipment paperdoll ------------------------------------------- */
.wequip {
    display: grid;
    grid-template-columns: repeat(3, var(--wslot));
    gap: 3px;
    justify-content: center;
    /* RuneScape's paperdoll, with the two ammo slots moved up to sit beside
       the helm: head at the top, the neck and back below it, hands out to the
       sides of the chest, then legs and feet. */
    grid-template-areas:
        ".      helm    ammo"
        "cape   amulet  ammo2"
        "main   body    off"
        ".      legs    ."
        "gloves boots   ring";
}

.wequip .wslot[data-slot="helm"]     { grid-area: helm; }
.wequip .wslot[data-slot="cape"]     { grid-area: cape; }
.wequip .wslot[data-slot="amulet"]   { grid-area: amulet; }
.wequip .wslot[data-slot="body"]     { grid-area: body; }
.wequip .wslot[data-slot="ammo"]     { grid-area: ammo; }
.wequip .wslot[data-slot="mainhand"] { grid-area: main; }
.wequip .wslot[data-slot="offhand"]  { grid-area: off; }
.wequip .wslot[data-slot="gloves"]   { grid-area: gloves; }
.wequip .wslot[data-slot="legs"]     { grid-area: legs; }
.wequip .wslot[data-slot="boots"]    { grid-area: boots; }
.wequip .wslot[data-slot="ring"]     { grid-area: ring; }
.wequip .wslot[data-slot="ammo2"]    { grid-area: ammo2; }

/* ----- the strip under a picked slot ------------------------------------- */
.wpicked {
    display: grid;
    gap: 0.3rem;
    margin-top: 0.5rem;
    padding: 0.4rem 0.5rem;
    border: 1px solid #7a5c2e;
    border-radius: 8px;
    background: rgba(0, 0, 0, 0.32);
    font-size: 0.78rem;
}

.wpicked .wp-title { font-weight: 700; }
.wpicked .wp-acts { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.wpicked button { font-size: 0.72rem; padding: 0.2rem 0.5rem; }

.wbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3rem;
    margin-bottom: 0.45rem;
    font-size: 0.78rem;
}

.wbar button { font-size: 0.7rem; padding: 0.2rem 0.45rem; }

.wildy-soon { display: grid; gap: 0.3rem; padding: 0.4rem 0.2rem; max-width: 17rem; }
.wildy-soon h3 { margin: 0; font-size: 0.92rem; }
.wildy-soon p { font-size: 0.76rem; margin: 0; }

@media (max-width: 780px) {
    .wildy-drawer {
        position: static;
        transform: none;
        max-width: 100%;
        max-height: none;
        margin: 0.6rem auto 0;
        width: max-content;
    }
}

/* ----- the right-click menu ---------------------------------------------- */
/* Sits on the page rather than inside the panel, so a menu opened on a slot
   near the edge is not clipped by the window it came from -- and above the
   hover card, which opens at the same cursor and would otherwise cover the
   very list that was asked for. */
.wmenu {
    position: fixed;
    z-index: 70;
    min-width: 10rem;
    padding: 0 0 2px;
    border: 2px solid #7a5c2e;
    border-radius: 8px;
    background: linear-gradient(#241c12, #17120c);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.6),
                inset 0 0 0 1px rgba(217, 164, 65, 0.18);
    font-size: 0.8rem;
    overflow: hidden;
}

.wm-head {
    padding: 0.3rem 0.6rem;
    background: linear-gradient(#3a2c19, #241a0f);
    border-bottom: 1px solid #7a5c2e;
    font-weight: 700;
    color: #ffe08a;
    white-space: nowrap;
}

.wm-item {
    display: block;
    width: 100%;
    text-align: left;
    padding: 0.28rem 0.6rem;
    border: 0;
    background: transparent;
    color: var(--text, #e8e9ec);
    font: inherit;
    cursor: pointer;
    white-space: nowrap;
}

.wm-item:hover { background: rgba(217, 164, 65, 0.22); color: #fff3d0; }
/* The first line is what a left click already does. */
.wm-item:first-of-type { color: #ffe08a; }

/* ----- the action bar clears the fighters -------------------------------- */
/* The buttons sat over the player's legs and across the NPC. The bar keeps the
   foot of the stage and everybody stands above it. */
.wildy-world .wildy-stage .wildy-fighter { bottom: 3.9rem; }

.wildy-world .wildy-stage .wildy-player {
    bottom: calc(3.9rem + clamp(296px, 46vh, 440px) * -0.0574);
}

.wildy-hud { bottom: 0.45rem; }

.wildy-hud .wildy-actions {
    background: linear-gradient(rgba(36, 28, 18, 0.94), rgba(23, 18, 12, 0.94));
    border: 2px solid #7a5c2e;
    border-radius: 12px;
    box-shadow: inset 0 0 0 1px rgba(217, 164, 65, 0.18),
                0 6px 18px rgba(0, 0, 0, 0.5);
}

/* ----- the combat log ---------------------------------------------------- */
/* Framed like every other panel, so the tale of a fight belongs to the same
   game as the windows above it. */
.wildy-logbox {
    max-width: 62rem;
    margin: 0.9rem auto 0;
    border: 2px solid #7a5c2e;
    border-radius: 12px;
    background: linear-gradient(#241c12, #17120c);
    box-shadow: inset 0 0 0 1px rgba(217, 164, 65, 0.18),
                0 6px 18px rgba(0, 0, 0, 0.4);
    overflow: hidden;
}

.wl-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.35rem 0.7rem;
    background: linear-gradient(#3a2c19, #241a0f);
    border-bottom: 2px solid #7a5c2e;
    font-size: 0.82rem;
    font-weight: 700;
    color: #ffe08a;
}

.wl-rule {
    height: 16px;
    width: auto;
    max-width: 40px;
    object-fit: contain;
    image-rendering: pixelated;
    opacity: 0.9;
}

.wildy-logbox .wildy-log {
    margin: 0;
    padding: 0.5rem 0.8rem;
    max-height: 13rem;
    overflow-y: auto;
    background: transparent;
    border: 0;
    border-radius: 0;
}

/* An outfit sprite carries its own padding, so it needs none of the canvas
   correction the old 768px character art did. */
.wildy-world .wildy-stage .wildy-player.is-outfit { bottom: 3.9rem; }
.wildy-player.is-outfit img#player-img { height: clamp(230px, 38vh, 380px); }

/* ===== The action bar, in the same timber as everything else ============== */
/* These were the site's own buttons sitting inside a medieval frame, which is
   what made the bar read as a web page laid over a game. */
.wildy-hud .wildy-actions button,
.wildy-hud .wildy-actions select {
    border: 2px solid #7a5c2e;
    border-radius: 9px;
    background: linear-gradient(#3a2c19, #241a0f);
    box-shadow: inset 0 1px 0 rgba(217, 164, 65, 0.22),
                0 2px 0 rgba(0, 0, 0, 0.5);
    color: #e8c988;
    font-weight: 700;
    letter-spacing: 0.01em;
    padding: 0.4rem 0.8rem;
    min-height: 2.2rem;
    cursor: pointer;
    transition: filter 0.12s, transform 0.06s;
}

.wildy-hud .wildy-actions button:hover:not(:disabled),
.wildy-hud .wildy-actions select:hover { filter: brightness(1.22); }
.wildy-hud .wildy-actions button:active:not(:disabled) { transform: translateY(1px); }
.wildy-hud .wildy-actions button:disabled { opacity: 0.45; cursor: not-allowed; }

/* Whatever the bar is mainly for: venture, fight, swing. Struck gold. */
.wildy-hud .wildy-actions button.primary {
    background: linear-gradient(#e0b45a, #a8781f);
    border-color: #f0d089;
    color: #2a1d08;
    text-shadow: 0 1px 0 rgba(255, 240, 200, 0.35);
}

/* The swing itself, in blood and iron. */
.wildy-hud .wildy-actions button.attack {
    background: linear-gradient(#a8382c, #5e1c16);
    border-color: #d4614f;
    color: #ffdcd4;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
}

/* Running away is not a proud button. */
.wildy-hud .wildy-actions button.flee {
    background: linear-gradient(#2f2a22, #1b1712);
    border-color: #6b5a3a;
    color: #cdbb92;
}

/* A weapon's special: it should look like it costs something. */
.wildy-hud .wildy-actions .wspec {
    background: linear-gradient(#4a2f5e, #2a1838);
    border-color: #9d6fc4;
    color: #efd9ff;
}

.wl-level {
    color: #cdbb92;
    font-weight: 700;
    font-size: 0.82rem;
}

/* The level box reads as carved into the bar rather than sat on it. */
.wl-level input {
    width: 3.6rem;
    padding: 0.32rem 0.45rem;
    border: 2px solid #7a5c2e;
    border-radius: 8px;
    background: #120e09;
    box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.65);
    color: #ffe08a;
    font: inherit;
    font-weight: 700;
    text-align: center;
}

.wl-level input:focus-visible { outline: 2px solid #d9a441; outline-offset: 1px; }
.wildy-hud .wildy-actions select { padding-right: 1.6rem; }
.wildy-hud .wildy-actions select option { background: #241a0f; color: #e8c988; }

/* The purse and stance pill above the bar, in the same timber. */
.hud-purse {
    background: linear-gradient(rgba(58, 44, 25, 0.94), rgba(23, 18, 12, 0.94));
    border: 2px solid #7a5c2e;
    box-shadow: inset 0 1px 0 rgba(217, 164, 65, 0.2);
    color: #ffe08a;
    font-weight: 700;
}

.hud-purse .hud-style { color: #b3a481; font-weight: 400; }

/* The nameplates over each fighter, matched to the bar. */
.wildy-nameplate {
    border-color: #7a5c2e;
    background: linear-gradient(rgba(36, 28, 18, 0.92), rgba(17, 13, 9, 0.92));
    box-shadow: inset 0 1px 0 rgba(217, 164, 65, 0.18);
}

.np-name { color: #ffe08a; }

/* ----- what just happened, where you are looking ------------------------- */
/* The log is a panel now, so anything said while it is shut would otherwise go
   unread -- including every refusal from the server. */
.wildy-toast {
    position: absolute;
    top: 3.1rem;
    left: 50%;
    transform: translateX(-50%);
    z-index: 5;
    margin: 0;
    max-width: min(40rem, 80%);
    padding: 0.42rem 0.9rem;
    border: 2px solid #7a5c2e;
    border-radius: 10px;
    background: linear-gradient(rgba(36, 28, 18, 0.96), rgba(17, 13, 9, 0.96));
    box-shadow: inset 0 1px 0 rgba(217, 164, 65, 0.2),
                0 6px 18px rgba(0, 0, 0, 0.5);
    color: #ffe08a;
    font-size: 0.85rem;
    font-weight: 700;
    text-align: center;
    pointer-events: none;
}

.wildy-toast.is-error { border-color: #b3372f; color: #ffb4a8; }

/* ===== The six systems =================================================== */
/* Slayer, the exchange, crafting, presets, alchemy and trading. Cards for a
   thing with a decision attached, rows for a long list. */
.wildy-panel .wh {
    margin: 0.7rem 0 0.35rem;
    font-size: 0.78rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: #b3a481;
}

.wildy-panel .wh:first-child { margin-top: 0; }

.wcard {
    display: grid;
    gap: 0.3rem;
    margin-bottom: 0.45rem;
    padding: 0.5rem 0.6rem;
    border: 1px solid #7a5c2e;
    border-radius: 9px;
    background: rgba(0, 0, 0, 0.3);
}

.wc-title { font-weight: 700; color: #ffe08a; font-size: 0.84rem; }
.wc-sub { font-size: 0.76rem; color: var(--muted, #a0a2ab); }
.wc-acts { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-top: 0.15rem; }

.wc-mats {
    margin: 0.15rem 0 0;
    padding-left: 1rem;
    font-size: 0.74rem;
    color: #cdbb92;
}

/* A material you are short of is the reason the button is off. */
.wc-mats .is-short { color: #ff9b8e; }

.wrow {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.3rem 0.4rem;
    border-bottom: 1px solid rgba(217, 164, 65, 0.14);
    font-size: 0.8rem;
}

.wrow:last-child { border-bottom: 0; }
.wrow > span:nth-of-type(2) { flex: 1; min-width: 0; }
.wrow small { display: block; color: var(--muted, #a0a2ab); font-size: 0.7rem; }
.wrow em { color: #8fbf7a; font-size: 0.74rem; }

.wr-icon img { width: 26px; height: 26px; object-fit: contain; image-rendering: pixelated; }

.wildy-panel button {
    border: 1px solid #7a5c2e;
    border-radius: 7px;
    background: linear-gradient(#3a2c19, #241a0f);
    color: #e8c988;
    font: inherit;
    font-size: 0.72rem;
    font-weight: 700;
    padding: 0.25rem 0.5rem;
    cursor: pointer;
}

.wildy-panel button.primary {
    background: linear-gradient(#e0b45a, #a8781f);
    border-color: #f0d089;
    color: #2a1d08;
}

.wildy-panel button:hover:not(:disabled) { filter: brightness(1.2); }
.wildy-panel button:disabled { opacity: 0.4; cursor: not-allowed; }

/* The exchange is long, so it gets a search and a scroll of its own. */
.wfind {
    width: 100%;
    margin-bottom: 0.4rem;
    padding: 0.32rem 0.5rem;
    border: 2px solid #7a5c2e;
    border-radius: 8px;
    background: #120e09;
    box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.6);
    color: #ffe08a;
    font: inherit;
    font-size: 0.78rem;
}

.wlist { max-height: 24rem; overflow-y: auto; }

/* These panels are lists rather than grids, so they want a readable width. */
body.panel-open .wildy-drawer { min-width: 15rem; }


/* ---------------------------------------------------------------------------
   The exchange

   Eight slots on a board, and one of them opened full width to set an offer up
   or look at one standing. The slots are buttons, so they undo the panel's
   ordinary button styling and dress themselves.
   --------------------------------------------------------------------------- */

.wge-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 0.35rem;
}

.wildy-panel .wge-slot {
    display: grid;
    gap: 0.2rem;
    align-content: start;
    justify-items: center;
    min-height: 7.4rem;
    padding: 0.4rem 0.3rem;
    border: 2px solid #7a5c2e;
    border-radius: 9px;
    background: linear-gradient(#33261544, #1a120a);
    box-shadow: inset 0 1px 0 rgba(255, 224, 138, 0.12);
    text-align: center;
    font-size: 0.68rem;
    line-height: 1.2;
}

.wildy-panel .wge-slot.is-empty { color: #8a7a5e; }
.wildy-panel .wge-slot.is-buy   { border-color: #6f8f4e; }
.wildy-panel .wge-slot.is-sell  { border-color: #a8683a; }
.wildy-panel .wge-slot.is-done  { box-shadow: 0 0 0 1px #ffe08a inset; }

.wge-kind {
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: #ffe08a;
    font-size: 0.62rem;
}
.wge-slot.is-empty .wge-kind { color: #6f6247; }

.wge-mid { display: grid; justify-items: center; gap: 0.1rem; min-height: 3.1rem; }
.wge-mid img { width: 30px; height: 30px; object-fit: contain; image-rendering: pixelated; }

.wge-name {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
    color: #e8c988;
}

.wge-qty { color: #cdbb92; font-size: 0.64rem; }

.wge-plus {
    display: grid;
    place-items: center;
    width: 30px;
    height: 30px;
    border: 1px dashed #5d4a2c;
    border-radius: 6px;
    color: #6f6247;
    font-size: 1rem;
}

/* How much of the offer has gone through. */
.wge-bar {
    display: block;
    width: 100%;
    height: 6px;
    border: 1px solid #5d4a2c;
    border-radius: 4px;
    background: #120e09;
    overflow: hidden;
}
.wge-bar.big { height: 10px; }
.wge-bar > i { display: block; height: 100%; background: linear-gradient(#e0b45a, #a8781f); }
.wge-slot.is-buy  .wge-bar > i { background: linear-gradient(#9fd06a, #5c8a33); }
.wge-slot.is-sell .wge-bar > i { background: linear-gradient(#f0b27a, #b5642c); }

.wge-foot { color: #a0956f; font-size: 0.62rem; }

/* The set-up sheet: two big numbers with their own rows of buttons. */
.wge-num {
    padding: 0.3rem 0.5rem;
    border: 2px solid #7a5c2e;
    border-radius: 8px;
    background: #120e09;
    box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.6);
    color: #ffe08a;
    font-size: 1rem;
    font-weight: 700;
    text-align: center;
}

.wge-total { font-size: 0.8rem; color: #cdbb92; margin: 0.2rem 0 0; }
.wge-total b { color: #ffe08a; }
.wge-why { font-size: 0.74rem; color: #ff9b8e; margin: 0; }
.wge-hold { font-size: 0.78rem; color: #9fd06a; margin: 0; }

/* Buy or sell, before anything else is decided. */
.wtoggle { display: flex; gap: 0.3rem; margin-bottom: 0.4rem; }
.wildy-panel .wtoggle button { flex: 1; }
.wildy-panel .wtoggle button.is-on {
    background: linear-gradient(#e0b45a, #a8781f);
    border-color: #f0d089;
    color: #2a1d08;
}

/* ---------------------------------------------------------------------------
   Odds and ends: the auto-alch list, a preset's two columns, and how much of
   something you are holding.
   --------------------------------------------------------------------------- */

.wchips { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-bottom: 0.4rem; }

.wildy-panel .wchip {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.2rem 0.45rem;
    font-size: 0.7rem;
}
.wildy-panel .wchip img {
    width: 18px; height: 18px; object-fit: contain; image-rendering: pixelated;
}
.wildy-panel .wchip i { color: #ff9b8e; font-style: normal; font-weight: 700; }

.wc-cols {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.6rem;
    align-items: start;
}
/* Grid children refuse to shrink below their content unless told to, which is
   how one long column pushes a card open. */
.wc-col { min-width: 0; }

.wc-h {
    margin: 0 0 0.2rem;
    color: #a0956f;
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}
.wc-h small { color: #6f6247; font-weight: 400; letter-spacing: 0; text-transform: none; }

/* A preset is a picture of a loadout, not somewhere to click, so its slots are
   drawn small enough that both halves fit side by side. */

/* How many you have of the thing being broken down. */
.wc-held {
    margin-left: 0.4rem;
    color: #9fd06a;
    font-size: 0.68rem;
    font-weight: 400;
}
.wc-held.is-short { color: #ff9b8e; }

@media (max-width: 700px) {
    .wge-grid { grid-template-columns: repeat(2, 1fr); }
    .wc-cols { grid-template-columns: 1fr; }
}


/* ---------------------------------------------------------------------------
   What an item does

   One card, moved to wherever the cursor is. Cut from the same timber as the
   panels: the same border, the same gold, the same inset shadow.
   --------------------------------------------------------------------------- */

.witip {
    position: fixed;
    z-index: 60;
    max-width: 17rem;
    padding: 0.45rem 0.55rem;
    border: 2px solid #7a5c2e;
    border-radius: 9px;
    background: linear-gradient(#241a0f, #140e08);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.6),
                inset 0 1px 0 rgba(255, 224, 138, 0.14);
    color: #e8c988;
    font-size: 0.74rem;
    line-height: 1.35;
    pointer-events: none;
}

.wt-head { display: flex; align-items: center; gap: 0.4rem; }
.wt-head img {
    width: 28px; height: 28px; object-fit: contain; image-rendering: pixelated;
}
.wt-head b { color: #ffe08a; font-size: 0.8rem; }
.wt-head small {
    display: block;
    color: #a0956f;
    font-size: 0.66rem;
    text-transform: capitalize;
}

.wt-line { margin: 0.3rem 0 0; }
.wt-line.muted { color: #a0956f; font-size: 0.68rem; }

.wt-group { margin-top: 0.35rem; }
.wt-group h6 {
    margin: 0 0 0.15rem;
    color: #a0956f;
    font-size: 0.62rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

/* Two to a line, so a full set of bonuses stays a glance rather than a list. */
.wt-stat {
    display: inline-block;
    width: 48%;
    color: #cdbb92;
    font-size: 0.7rem;
}
.wt-stat b { color: #9fd06a; }
.wt-stat.is-bad b { color: #ff9b8e; }

/* ----- presets, two to a row ---------------------------------------------- */
.wpresets {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(19rem, 1fr));
    gap: 0.45rem;
}
.wpresets .wcard { margin-bottom: 0; }

/* A preset's cells are buttons rather than plain squares, since every one of
   them is somewhere to click -- so they have to shed the panel's button
   styling and wear the slot frame instead. */
.wildy-panel .wpresets .wslot {
    padding: 0;
    border: 0;
    border-radius: 0;
    background: url('/games/wildernessreborn/art/ui/slot.png') center / 100% 100% no-repeat;
    cursor: pointer;
}
.wildy-panel .wpresets .wslot:hover:not(:disabled) { filter: brightness(1.4); }

.wequip.mini, .wgrid.inv.mini { --wslot: 30px; }
.wequip.mini { grid-template-columns: repeat(3, var(--wslot)); }
.wgrid.inv.mini { grid-template-columns: repeat(4, var(--wslot)); }
.wequip.mini .wslot, .wgrid.inv.mini .wslot { width: 30px; height: 30px; }
/* At thirty pixels a slot name does not fit, and one that does not fit runs
   over its neighbour. The paperdoll's own shape says which slot is which --
   head at the top, boots at the bottom -- and hovering says it in words. */
.wequip.mini .ws-label { display: none; }
.wequip.mini .ws-qty, .wgrid.inv.mini .ws-qty { font-size: 0.55rem; }


/* ---------------------------------------------------------------------------
   How many
   ---------------------------------------------------------------------------
   The stack sizes, in the colours the game this borrows from uses: yellow up
   to a hundred thousand, then white thousands, green millions and blue
   billions. Only the drawing is rounded -- hovering says the real number.
   Last in the file on purpose, so these beat the plain .ws-qty above them. */

.wq { font-weight: 700; color: #ffe08a; }
.ws-qty.is-k, .wq.is-k, .wi-qty.is-k { color: #fff; }
.ws-qty.is-m, .wq.is-m, .wi-qty.is-m { color: #5ede63; }
.ws-qty.is-b, .wq.is-b, .wi-qty.is-b { color: #6cb6ff; }
.wslot .ws-qty.is-k { color: #fff; }
.wslot .ws-qty.is-m { color: #5ede63; }
.wslot .ws-qty.is-b { color: #6cb6ff; }

/* The exact count, at the top of the hovering card. */
.wt-have {
    margin: 0.25rem 0 0;
    font-size: 0.78rem;
    color: #cfd2da;
}
.wt-have b { color: #ffe08a; }

/* The quantity on an offer being set up: rounded like everything else, with
   the real number under it once it is large enough to have been rounded. */
.wge-num small {
    display: block;
    font-size: 0.6rem;
    font-weight: 400;
    color: var(--muted, #a0a2ab);
}


/* ---------------------------------------------------------------------------
   The bank's tabs
   --------------------------------------------------------------------------- */

.wbank-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
    margin: 0.4rem 0 0.5rem;
}

.wbank-tabwrap { position: relative; display: inline-flex; }

.wbank-tab {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.2rem 0.5rem;
    border: 1px solid #4a3c25;
    border-radius: 4px;
    background: #241d13;
    color: #cdbb92;
    font: inherit;
    font-size: 0.72rem;
    text-transform: lowercase;
    cursor: pointer;
}

.wbank-tab:hover { border-color: #7a6339; color: #ffe08a; }
.wbank-tab.is-on { background: #3b2f1c; border-color: #a2854c; color: #ffe08a; }
.wbank-tab.is-new { color: #8d7f66; }
.wbank-tab i { font-style: normal; font-size: 0.6rem; opacity: 0.65; }

/* What a drop would land on. */
.wbank-tab.is-dropping,
.wslot.is-dropping { outline: 2px solid #ffe08a; outline-offset: -2px; }
.wslot.is-dragging { opacity: 0.35; }
.wslot[draggable="true"] { cursor: grab; }

.wbank-x {
    margin-left: 0.15rem;
    padding: 0 0.3rem;
    border: 1px solid #4a3c25;
    border-left: 0;
    border-radius: 0 4px 4px 0;
    background: #241d13;
    color: #8d7f66;
    font: inherit;
    font-size: 0.7rem;
    cursor: pointer;
}
.wbank-x:hover { color: #ff9b8e; }

/* Sets mode: a heading over each family, and nothing else changed. */
.wbank-set { margin-bottom: 0.6rem; }

.wbank-set h5 {
    margin: 0 0 0.25rem;
    font-size: 0.72rem;
    font-weight: 700;
    color: #cdbb92;
    letter-spacing: 0.02em;
}

/* ---------------------------------------------------------------------------
   Asking something
   ---------------------------------------------------------------------------
   What the browser's own prompt and confirm used to do, in the game's own
   furniture: over the stage, in the same wood and gold as everything else. */

.wask-veil {
    position: fixed;
    inset: 0;
    z-index: 60;
    display: grid;
    place-items: center;
    background: rgba(8, 6, 4, 0.62);
    backdrop-filter: blur(2px);
}

.wask {
    width: min(23rem, calc(100vw - 2rem));
    padding: 0.9rem 1rem 0.85rem;
    border: 1px solid #6b5326;
    border-radius: 10px;
    background: linear-gradient(#2b2216, #1d1710);
    box-shadow: 0 14px 40px rgba(0, 0, 0, 0.6);
    color: #efe3cb;
}

.wask h4 {
    margin: 0 0 0.35rem;
    font-size: 0.98rem;
    color: #ffe08a;
}

.wask-body {
    margin: 0 0 0.6rem;
    font-size: 0.8rem;
    line-height: 1.45;
    color: #cfc3ab;
}

.wask-in {
    width: 100%;
    padding: 0.4rem 0.5rem;
    border: 1px solid #56421f;
    border-radius: 6px;
    background: #14100a;
    color: #ffe08a;
    font: inherit;
    font-size: 0.95rem;
}

.wask-in:focus { outline: none; border-color: #d9a441; }

.wask-acts {
    display: flex;
    justify-content: flex-end;
    gap: 0.4rem;
    margin-top: 0.75rem;
}

.wask-acts button {
    padding: 0.32rem 0.8rem;
    border: 1px solid #56421f;
    border-radius: 6px;
    background: #241d13;
    color: #cdbb92;
    font: inherit;
    font-size: 0.82rem;
    cursor: pointer;
}

.wask-acts button:hover { border-color: #a2854c; color: #ffe08a; }

.wask-acts .primary {
    background: #3b2f1c;
    border-color: #a2854c;
    color: #ffe08a;
}

/* Something that cannot be undone is not the same colour as something that
   can. */
.wask.is-danger h4 { color: #ff9b8e; }
.wask.is-danger .wask-acts .primary {
    background: #4a1f1a;
    border-color: #b4453a;
    color: #ffd9d3;
}

/* ---------------------------------------------------------------------------
   Searching the bank, and what is on the floor
   --------------------------------------------------------------------------- */

.wbank-find {
    width: 100%;
    margin: 0.45rem 0 0.1rem;
    padding: 0.35rem 0.55rem;
    border: 1px solid #4a3c25;
    border-radius: 6px;
    background: #16120c;
    color: #ffe08a;
    font: inherit;
    font-size: 0.82rem;
}

.wbank-find:focus { outline: none; border-color: #d9a441; }

/* A pile appears because something is in it, so the floor has as many slots
   as there are piles and not one more. */
.wgrid.ground { grid-template-columns: repeat(8, var(--wslot)); }

.wslot .ws-note {
    position: absolute;
    bottom: 1px;
    left: 0;
    right: 0;
    text-align: center;
    font-size: 0.52rem;
    color: #cfc3ab;
    text-shadow: 0 1px 2px #000;
    pointer-events: none;
}


/* The worn bonuses, in the hovering card's own groups. Two columns, since
   the paperdoll above them is narrow and a single column of twelve rows
   would be taller than the figure it belongs to. */
.wequip-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
    gap: 0.4rem;
    margin-top: 0.7rem;
}

.wequip-stats .wt-group { margin: 0; }

/* On the card two stats share a line, because a card is narrow and its
   list is short. Here each group is its own column already, so a stat gets
   the whole width and the numbers line up down the side. */
.wequip-stats .wt-stat {
    display: flex;
    justify-content: space-between;
    width: 100%;
    padding: 0.04rem 0;
}


/* ---------------------------------------------------------------------------
   Building a trade, and reading a beast
   --------------------------------------------------------------------------- */

.wtrade-to { margin-bottom: 0.5rem; }
.wtrade-to .wc-title { display: flex; align-items: center; gap: 0.4rem; }
.wtrade-to .wc-title img { width: 22px; height: 22px; object-fit: contain; }

/* The bestiary: a row you can read at a glance, opening onto the numbers. */
.wn-list { display: flex; flex-direction: column; gap: 0.3rem; }

.wn-row {
    border: 1px solid #322a1c;
    border-radius: 8px;
    background: rgba(24, 20, 14, 0.6);
    overflow: hidden;
}

.wn-row > summary {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.35rem 0.5rem;
    cursor: pointer;
    list-style: none;
}
.wn-row > summary::-webkit-details-marker { display: none; }
.wn-row[open] > summary { border-bottom: 1px solid #322a1c; }
.wn-row > summary:hover { background: rgba(60, 48, 26, 0.5); }

.wn-face {
    width: 44px;
    height: 44px;
    display: grid;
    place-items: center;
    flex: 0 0 auto;
}
.wn-face img {
    max-width: 44px;
    max-height: 44px;
    object-fit: contain;
    image-rendering: pixelated;
}

.wn-head { display: flex; flex-direction: column; line-height: 1.3; }
.wn-head b { color: #ffe08a; font-size: 0.9rem; }
.wn-head small { color: var(--muted, #a0a2ab); font-size: 0.7rem; }

.wn-body { padding: 0.5rem 0.6rem 0.6rem; }

.wn-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
    gap: 0.4rem;
    margin-bottom: 0.5rem;
}
.wn-stats .wt-group { margin: 0; }
.wn-stats .wt-stat {
    display: flex;
    justify-content: space-between;
    width: 100%;
}

.wn-drops { margin-top: 0.5rem; }
.wn-drops h6 {
    margin: 0 0 0.2rem;
    color: #a0956f;
    font-size: 0.62rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.wn-drop {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.12rem 0.2rem;
    border-radius: 5px;
}
.wn-drop:hover { background: rgba(60, 48, 26, 0.45); }

.wn-icon { width: 24px; height: 24px; display: grid; place-items: center; }
.wn-icon img {
    max-width: 24px; max-height: 24px;
    object-fit: contain; image-rendering: pixelated;
}
.wn-name { flex: 1; font-size: 0.8rem; color: #cdbb92; }
.wn-name small { color: var(--muted, #a0a2ab); }
.wn-odds { font-size: 0.72rem; color: #9fd06a; white-space: nowrap; }


/* ---------------------------------------------------------------------------
   The keeper's panel

   A roster and a record, in the same list and grid furniture as the rest of
   the game -- it is the same game, seen from the other side of it.
   --------------------------------------------------------------------------- */

.wildy-notice {
    margin: 0 0 .5rem;
    padding: .45rem .7rem;
    border: 1px solid rgba(255, 196, 88, .45);
    border-radius: .4rem;
    background: rgba(255, 196, 88, .12);
    color: #ffe2a8;
    font-size: .85rem;
    text-align: center;
}

.wa-row {
    display: grid;
    grid-template-columns: 1.6rem minmax(0, 1fr) auto auto 4.2rem;
    align-items: center;
    gap: .5rem;
    text-align: left;
}

/* The initial is the floor and the picture is the ceiling: one is always
   showing, so a face that will not load is still a face. */
.wa-face {
    position: relative;
    display: grid;
    place-items: center;
    width: 1.6rem;
    height: 1.6rem;
    flex: none;
    border-radius: 50%;
    background: rgba(255, 255, 255, .1);
    font-size: .7rem;
    font-weight: 700;
    overflow: hidden;
}

.wa-face img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.wa-name { display: grid; min-width: 0; }
.wa-name b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wa-name small { font-size: .72rem; opacity: .75; }
.wa-name small.is-bad { color: #ff9a8a; opacity: 1; }
.wa-name small.is-danger { color: #ffb96a; opacity: 1; }

.wa-cell { font-size: .75rem; opacity: .85; white-space: nowrap; }
.wa-when { text-align: right; }
.wa-when.is-here { color: #7fe0a0; opacity: 1; }

.wa-head {
    display: flex;
    align-items: center;
    gap: .6rem;
    margin: .4rem 0 .6rem;
}

.wa-head .wa-face { width: 2.4rem; height: 2.4rem; }

.wa-sums {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
    margin-bottom: .6rem;
}

.wa-acts {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
    margin-bottom: .5rem;
}

.wa-acts button { font-size: .78rem; }
.wa-acts button.is-danger { border-color: rgba(255, 120, 100, .5); color: #ff9a8a; }

.wa-notice {
    display: block;
    margin: 0 0 .6rem;
    color: #ffb96a;
}

.wa-log {
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: .75rem;
    line-height: 1.6;
}

.wa-log li {
    display: flex;
    gap: .4rem;
    padding: .15rem 0;
    border-bottom: 1px solid rgba(255, 255, 255, .05);
}

.wa-log .wa-when { width: 4.2rem; flex: none; text-align: left; opacity: .6; }


/* The keeper's sections, and the rows only they see. */

.wa-tabs { margin-bottom: .5rem; }

.wildy-notice.is-watching {
    border-color: rgba(160, 200, 255, .5);
    background: rgba(120, 170, 255, .14);
    color: #cfe2ff;
}

.wildy-notice button {
    margin-left: .5rem;
    font-size: .75rem;
    padding: .1rem .5rem;
}

.wa-alerts { margin-bottom: .6rem; }

.wa-alert {
    display: flex;
    align-items: center;
    gap: .5rem;
    text-align: left;
    font-size: .8rem;
}

.wa-alert-kind {
    flex: none;
    padding: .05rem .4rem;
    border-radius: .25rem;
    background: rgba(255, 196, 88, .18);
    color: #ffd48a;
    font-size: .68rem;
    text-transform: uppercase;
    letter-spacing: .04em;
}

.wa-drop, .wa-order, .wa-patch, .wa-save {
    display: grid;
    align-items: center;
    gap: .5rem;
    text-align: left;
    font-size: .78rem;
}

.wa-drop { grid-template-columns: 1.6rem minmax(0, 1fr) auto auto 3.4rem; }
.wa-order { grid-template-columns: 1.6rem minmax(0, 1fr) auto auto auto; }
.wa-patch, .wa-save { grid-template-columns: minmax(0, 1fr) auto auto; }

.wa-drop .wa-cell.is-bad { color: #ff9a8a; font-weight: 700; }

.wa-note {
    display: block;
    margin: -.2rem 0 .6rem;
    color: #cfe2ff;
}

.wa-fight {
    max-height: 14rem;
    overflow-y: auto;
    margin-bottom: .6rem;
}


/* A monster that belongs to the clan, read by somebody who is not in it. */

.wn-row.is-locked > summary { opacity: .72; }

.wn-locked {
    align-self: center;
    padding: .05rem .4rem;
    border-radius: .25rem;
    background: rgba(255, 196, 88, .16);
    color: #ffd48a;
    font-size: .66rem;
    text-transform: uppercase;
    letter-spacing: .04em;
    white-space: nowrap;
}

.wn-join {
    display: block;
    margin: 0 0 .5rem;
    color: #ffd48a;
}


/* ===========================================================================
   On a phone
   ===========================================================================
   The game is one screen: a stage with the fight on it, the buttons across
   the foot of it, and the icons under those. Everything here is inside a
   width query, so none of it reaches the desktop layout it is overriding.

   What was wrong: the rail and the buttons were told to go back into the
   normal flow at this width, and both of them live *inside* the stage --
   which is a positioned box with `overflow: hidden` and nothing else in flow.
   So the icons landed in a heap over the cat's face and the buttons fell out
   of the bottom of the stage and were clipped away entirely.
   =========================================================================== */
@media (max-width: 780px) {
    /* The stage is the game, so it gets the screen. dvh rather than vh: on a
       phone the address bar comes and goes, and vh is measured against the
       tallest the viewport ever gets. */
    .wildy-main { padding: 0 0 1rem; }
    .wildy-world .wildy-stage { height: min(66vh, 540px); }
    .wildy-world .wildy-stage { height: min(66dvh, 540px); }
    .wildy-notice { margin: 0 .6rem .4rem; }

    /* Two fighters at desktop size are wider together than a phone is, so
       they meet in the middle of each other. Smaller, and pushed out to the
       edges. The ground stays where it is, so the scene behind them is still
       laid out at the same scale and still lands on whole pixels -- only the
       two of them are drawn at three quarters. */
    .wildy-world .wildy-stage { --wchar: 192px; --wground: 80px; }
    .wildy-player { left: 1%; }
    .wildy-npc { right: 1%; }
    .wildy-nameplate { font-size: .68rem; }

    /* ----- the icons, along the foot ------------------------------------ */
    /* A strip rather than a block: fifteen icons will not fit across a phone,
       so they scroll, which is a thing thumbs are good at. */
    .wildy-world .wildy-rail {
        position: absolute;
        top: auto;
        right: 0;
        bottom: 0;
        left: 0;
        transform: none;
        display: flex;
        flex-wrap: nowrap;
        justify-content: flex-start;
        width: 100%;
        margin: 0;
        gap: .25rem;
        padding: .3rem .4rem;
        padding-bottom: calc(.3rem + env(safe-area-inset-bottom, 0px));
        border-radius: 0;
        border-inline: 0;
        border-bottom: 0;
        background: rgba(10, 12, 16, .92);
        overflow-x: auto;
        overscroll-behavior-x: contain;
        scrollbar-width: none;
    }

    .wildy-world .wildy-rail::-webkit-scrollbar { display: none; }

    .wildy-rail .wtab { flex: none; width: 42px; height: 42px; }
    .wildy-rail .wtab img { max-width: 30px; max-height: 30px; }

    /* A name that only appears on hover is a name nobody here will ever see,
       and on a touch screen it appears stuck to the tap instead. */
    .wtab-tip { display: none; }

    .wtab-slots { flex: none; align-self: center; padding: 0 .5rem; }

    /* ----- the buttons, just above them --------------------------------- */
    .wildy-hud {
        position: absolute;
        left: 50%;
        right: auto;
        bottom: calc(3.6rem + env(safe-area-inset-bottom, 0px));
        transform: translateX(-50%);
        width: 100%;
        margin: 0;
        padding: 0 .4rem;
        gap: .3rem;
    }

    .wildy-hud .wildy-actions {
        flex-wrap: wrap;
        justify-content: center;
        gap: .3rem;
        padding: .4rem;
    }

    /* Big enough to hit with a thumb. */
    .wildy-hud .wildy-actions button,
    .wildy-hud .wildy-actions select,
    .wildy-hud .wildy-actions input {
        min-height: 38px;
        font-size: .82rem;
    }

    .hud-purse { font-size: .74rem; padding: .18rem .55rem; }

    /* ----- the panel, as a sheet ---------------------------------------- */
    /* Beside the rail there is no room for a window, so it comes up from the
       bottom over the game and goes away again. Fixed rather than absolute:
       it should cover the screen, not the stage it happens to sit in.  */
    .wildy-drawer {
        position: fixed;
        top: auto;
        right: 0;
        bottom: 0;
        left: 0;
        transform: none;
        width: auto;
        max-width: none;
        max-height: 82vh;
        max-height: 82dvh;
        margin: 0;
        border-inline: 0;
        border-bottom: 0;
        border-radius: 14px 14px 0 0;
        z-index: 30;
        padding-bottom: env(safe-area-inset-bottom, 0px);
    }

    .wd-head { padding: .5rem .6rem; font-size: .88rem; }
    .wd-close { width: 28px; height: 28px; font-size: .8rem; }
    .wildy-panel { padding: .6rem; }

    /* The bank is eight slots across, which is wider than a phone. As many as
       fit, and the rest wrap -- the bank is a store, not a shape. */
    .wgrid.bank, .wgrid.ground {
        grid-template-columns: repeat(auto-fill, var(--wslot));
        justify-content: center;
    }

    /* Rows that were laid out for a wide window get their columns back. */
    .wa-row { grid-template-columns: 1.6rem minmax(0, 1fr) auto; }
    .wa-row .wa-cell:nth-of-type(2) { display: none; }
    .wa-drop, .wa-order { grid-template-columns: 1.6rem minmax(0, 1fr) auto; }
    .wa-drop .wa-cell:first-of-type, .wa-order .wa-cell:last-of-type { display: none; }
    .wn-drop { font-size: .74rem; }
}


/* ---------------------------------------------------------------------------
   Holding a slot down

   A right-click is what opens the option list, and a touch screen has no
   second button -- so a held press does it instead, and the browser's own
   idea of a long press has to get out of the way first: iOS offers to save
   the icon as a picture, and both offer to select the text under the finger.

   Keyed on there being no hover rather than on the width of the window,
   because that is the actual question. A mouse is unaffected either way.
   --------------------------------------------------------------------------- */
@media (hover: none) {
    .wslot, .wslot * {
        -webkit-touch-callout: none;
        -webkit-user-select: none;
        user-select: none;
    }
}
