@font-face { font-family: 'RS-Plain'; src: url('fonts/RuneScape-Plain-12.otf') format('opentype'); }
@font-face { font-family: 'RS-Bold';  src: url('fonts/RuneScape-Bold-12.otf')  format('opentype'); }
@font-face { font-family: 'RS-Quill'; src: url('fonts/RuneScape-Quill-8.otf')  format('opentype'); }

:root {
    --bg:      #1c1c1a;
    --panel:   #1a1a1a;
    --well:    #0f0f0c;
    --gold:    #8b6914;
    --gold-hi: #c9a03a;
    --gold-lo: #4a3708;
    --text:    #f0e68c;
    --dim:     #9c9376;
    --line:    #33322c;
    --ink:     #2b2600;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: 'RS-Plain', 'Trebuchet MS', sans-serif;
    font-size: 16px;
    -webkit-font-smoothing: none;          /* 2004 never antialiased its text */
}

/* ------------------------------------------------------------------ chrome
   A stack of centred rows, not one flex line. Each row wraps on its own and
   stays centred, so nothing can ride over anything else at any window width -
   which is exactly what brand + label + purse on one line did the moment the
   window narrowed.
   ======================================================================== */
header {
    display: flex; flex-direction: column; align-items: center; gap: 9px;
    padding: 16px 20px 13px;
    background:
        linear-gradient(180deg, #00000073, #000000a6),
        url('img/panel.jpg') repeat;
    background-size: auto, 128px;
    border-bottom: 2px solid var(--gold);
    box-shadow: inset 0 -1px 0 #000, 0 2px 6px #0009;
    text-align: center;
}
.brand {
    display: flex; align-items: center; justify-content: center;
    gap: 14px; flex-wrap: wrap;
}
.brand img {
    width: 58px; height: 58px; image-rendering: pixelated;
    filter: drop-shadow(0 0 6px #000);
}
h1 {
    margin: 0; font-family: 'RS-Bold'; font-size: 34px; letter-spacing: 3px;
    text-transform: uppercase; line-height: 1;
    color: var(--text);
    -webkit-text-stroke: 1.4px var(--ink); paint-order: stroke fill;
    text-shadow: 2px 2px 0 #000;
}
.set-label {
    font-size: 13px; color: var(--dim); letter-spacing: .4px;
}
.spacer { flex: 1; }

/* the purse reads as a row of stone tabs, the way a 2004 interface would have
   punched numbers into the frame rather than floating them over it */
.purse {
    display: flex; gap: 8px; align-items: center; justify-content: center;
    flex-wrap: wrap;
    font-family: 'RS-Bold'; font-size: 14px;
}
.purse .coin, .purse .who {
    padding: 4px 11px; border-radius: 2px;
    background: #00000059;
    border: 1px solid #0009;
    box-shadow: inset 0 1px 0 #ffffff14;
    color: var(--dim);
}
.purse .who { color: #ffefb0; }
.purse b { color: #ffd44d; margin-left: 4px; }

nav {
    display: flex; gap: 3px; padding: 0 16px; justify-content: center;
    flex-wrap: wrap;
    background: #00000038;
    border-bottom: 2px solid var(--gold-lo);
}
nav button {
    font-family: 'RS-Bold'; font-size: 14px;
    background: transparent; color: var(--dim);
    border: 0; border-bottom: 3px solid transparent;
    padding: 9px 18px; cursor: pointer;
}
nav button:hover { color: var(--text); }
nav button[aria-selected='true'] { color: var(--text); border-bottom-color: var(--gold); }

main { padding: 20px; max-width: 1500px; margin: 0 auto; }

/* ------------------------------------------------------------------ controls */
.controls { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin-bottom: 16px; }
input[type=text], select {
    font-family: 'RS-Plain'; font-size: 15px;
    background: var(--well); color: var(--text);
    border: 2px inset var(--gold-lo); border-radius: 2px; padding: 6px 9px;
}
input[type=text] { min-width: 210px; }
button.act {
    font-family: 'RS-Bold'; font-size: 14px; cursor: pointer;
    background: url('img/panel.jpg') repeat; background-size: cover;
    color: var(--text);
    border: 2px outset var(--gold); border-radius: 2px; padding: 7px 15px;
    text-shadow: 1px 1px 2px #000c;
}
button.act:hover { filter: brightness(1.18); }
button.act:active { border-style: inset; transform: translateY(1px); }
button.act:disabled { opacity: .4; cursor: default; border-style: solid; }

/* The chips are the bottom of the filter block, so they own the gap down to the
   grid. Without it the first row of cards sat straight on them, and a gilded
   card's glow bled up over the buttons. */
.tier-filters {
    display: flex; gap: 6px; flex-wrap: wrap;
    margin: 0 0 22px;
    padding-bottom: 16px;
    border-bottom: 1px solid var(--line);
}
.tier-chip {
    font-family: 'RS-Bold'; font-size: 12px; cursor: pointer; user-select: none;
    padding: 5px 10px; border-radius: 2px;
    border: 2px solid currentColor; background: transparent; opacity: .45;
}
.tier-chip[aria-pressed='true'] { opacity: 1; background: color-mix(in srgb, currentColor 18%, transparent); }
.count { color: var(--dim); font-size: 13px; }

/* ================================================================== THE CARD
   Built like a 2004 interface panel: black keyline, gold bevel, tiled stone,
   and every inner element sunk with an inset border. No soft shadows, no
   gradients that Andrew couldn't have drawn with a 2px border.
   ========================================================================= */
.grid {
    display: grid; gap: 16px;
    grid-template-columns: repeat(auto-fill, minmax(182px, 1fr));
    align-items: start;
}

.card {
    position: relative;
    /* the tier colour washes the whole card, not just the trim, so rarity is
       readable at a glance across a full grid */
    background:
        linear-gradient(180deg,
            color-mix(in srgb, var(--tier) 26%, transparent) 0%,
            color-mix(in srgb, var(--tier) 10%, transparent) 45%,
            transparent 100%),
        url('img/panel.jpg') repeat;
    background-size: auto, 128px;
    border: 2px outset var(--gold);
    outline: 1px solid #000;
    border-radius: 2px;
    padding: 5px;
    cursor: pointer;
    display: flex; flex-direction: column; gap: 4px;
}
.card:hover { filter: brightness(1.14); }
.card:active { border-style: inset; }


/* tier is a chiselled rule under the nameplate plus the ribbon at the foot,
   so every card still reads as the same 2004 furniture */
.card .name {
    font-family: 'RS-Bold'; font-size: 13px; line-height: 1.1;
    text-align: center; min-height: 30px;
    display: flex; align-items: center; justify-content: center;
    padding: 3px 4px;
    color: #ffefb0;
    background: #00000059;
    border: 1px solid #0009;
    border-bottom: 2px solid var(--tier);
    -webkit-text-stroke: 1px var(--ink); paint-order: stroke fill;
}

.card .well {
    height: 132px;
    background:
        radial-gradient(ellipse at 50% 45%,
            color-mix(in srgb, var(--tier) 26%, #23221b) 0%,
            color-mix(in srgb, var(--tier) 7%, var(--well)) 78%);
    border: 2px inset #0e0e0a;
    display: flex; align-items: center; justify-content: center;
    overflow: hidden;
}
/* The art is now rendered at 128px (items) and 192px (npcs) rather than being
   an upscaled 32px sprite, so let the browser resample it smoothly. */
.card .well img { image-rendering: auto; }
.card .well img.obj { width: 124px; height: 124px; }
.card .well img.npc { width: 132px; height: 132px; }
.card .well .glyph { font-family: 'RS-Bold'; font-size: 38px; color: var(--tier); opacity: .45; }

.card .examine {
    font-family: 'RS-Plain'; font-size: 12px; line-height: 1.28;
    color: #e2d7b4; text-align: center;
    -webkit-text-stroke: .8px #14120a; paint-order: stroke fill;
    min-height: 46px; padding: 3px 4px;
    display: flex; align-items: center; justify-content: center;
    background: #00000047; border: 1px solid #0009;
}

.card .foot {
    display: flex; justify-content: space-between; align-items: center;
    font-family: 'RS-Bold'; font-size: 10px; letter-spacing: .6px;
    padding: 2px 2px 0;
    -webkit-text-stroke: .9px #14120a; paint-order: stroke fill;
}
.card .foot .tier { color: var(--tier); text-transform: uppercase;
    text-shadow: 1px 1px 0 #000; }
.card .foot .tier::before {
    content: ''; display: inline-block; width: 7px; height: 7px;
    background: var(--tier); margin-right: 5px;
    border: 1px solid #0008; transform: rotate(45deg);
}
.card .foot .set { color: #7a7059; }

.card.dupe::after {
    content: 'x' attr(data-count);
    position: absolute; top: 4px; right: 5px;
    font-family: 'RS-Bold'; font-size: 12px; color: #0d0d0b;
    background: var(--tier); border: 1px solid #0008; border-radius: 2px; padding: 0 4px;
}
.card.locked { filter: grayscale(1) brightness(.4); }
.card.locked:hover { filter: grayscale(1) brightness(.55); }

/* ------------------------------------------------------------------ detail */
/* Deliberately no stats. This is a collecting game, not a battler - a card is
   a picture and a line of examine text, the way it reads in game. */
dialog {
    background: url('img/panel.jpg') repeat; background-size: 128px;
    color: var(--text);
    border: 2px outset var(--gold); outline: 1px solid #000;
    border-radius: 2px; padding: 6px; max-width: 340px; width: 88vw;
}
dialog::backdrop { background: #000b; }
dialog .name {
    font-family: 'RS-Bold'; font-size: 18px; text-align: center;
    padding: 8px 6px; color: #ffefb0;
    background: #00000059; border: 1px solid #0009;
    border-bottom: 2px solid var(--tier);
    -webkit-text-stroke: 1.1px var(--ink); paint-order: stroke fill;
}
dialog .well {
    height: 244px; margin-top: 5px;
    background:
        radial-gradient(ellipse at 50% 45%,
            color-mix(in srgb, var(--tier) 30%, #23221b) 0%,
            color-mix(in srgb, var(--tier) 8%, var(--well)) 78%);
    border: 2px inset #0e0e0a;
    display: flex; align-items: center; justify-content: center;
}
dialog .well img { image-rendering: auto; }
dialog .well img.obj { width: 208px; height: 208px; }
dialog .well img.npc { width: 224px; height: 224px; }
dialog .well .glyph { font-family: 'RS-Bold'; font-size: 90px; color: var(--tier); opacity: .45; }
dialog .examine {
    font-family: 'RS-Quill'; font-size: 19px; line-height: 1.35;
    color: #e7dcbb; text-align: center; padding: 12px 10px;
    -webkit-text-stroke: .9px #14120a; paint-order: stroke fill;
    background: #00000047; border: 1px solid #0009; margin-top: 5px;
}
dialog .foot {
    display: flex; justify-content: space-between; align-items: center;
    font-family: 'RS-Bold'; font-size: 11px; letter-spacing: .6px;
    padding: 7px 3px 3px;
    -webkit-text-stroke: .9px #14120a; paint-order: stroke fill;
}
dialog .foot .tier { color: var(--tier); text-transform: uppercase; }
dialog .foot .set { color: #7a7059; }

/* ------------------------------------------------------------------ packs */
.pack-row { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 20px; }
.pack {
    background: url('img/panel.jpg') repeat; background-size: 128px;
    border: 2px outset var(--gold); outline: 1px solid #000;
    border-radius: 2px; padding: 11px 13px; min-width: 168px; cursor: pointer;
    color: var(--text); text-align: left;
}
.pack:hover { filter: brightness(1.2); }
.pack:active { border-style: inset; }
.pack:disabled { opacity: .35; cursor: default; filter: none; }
.pack .pname { font-family: 'RS-Bold'; font-size: 14px; text-shadow: 1px 1px 0 #000; }
.pack .pmeta { font-size: 12px; color: var(--dim); margin-top: 3px; }
.pack .pcost { font-family: 'RS-Bold'; font-size: 13px; color: #ffd44d; margin-top: 5px; }

.reveal { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(182px, 1fr)); }
.reveal .card { animation: flip .42s cubic-bezier(.2,.8,.3,1) backwards; }
.reveal .card:nth-child(1) { animation-delay: 0s }
.reveal .card:nth-child(2) { animation-delay: .12s }
.reveal .card:nth-child(3) { animation-delay: .24s }
.reveal .card:nth-child(4) { animation-delay: .36s }
.reveal .card:nth-child(5) { animation-delay: .48s }
@keyframes flip { from { transform: rotateY(90deg) scale(.92); opacity: 0 } to { transform: none; opacity: 1 } }
@media (prefers-reduced-motion: reduce) { .reveal .card { animation: none } }

/* ------------------------------------------------------------------ panels */
.panel {
    background:
        linear-gradient(180deg, #00000042, #00000080),
        url('img/panel.jpg') repeat;
    background-size: auto, 128px;
    border: 2px outset var(--gold-lo);
    outline: 1px solid #000;
    border-radius: 2px;
    padding: 15px 18px 17px; margin-bottom: 20px;
}
/* the heading sits on a chiselled rule, like every panel title in 2004 */
.panel h3 {
    margin: 0 0 12px; padding-bottom: 8px;
    font-family: 'RS-Bold'; font-size: 15px; letter-spacing: 1.4px;
    text-transform: uppercase; color: #ffefb0;
    text-shadow: 1px 1px 0 #000;
    border-bottom: 1px solid #0009;
    box-shadow: 0 1px 0 #ffffff0f;
}
.panel p { margin: 0 0 9px; font-size: 15px; color: #b9b09a; line-height: 1.5; }
.panel .note { font-size: 13px; color: #948c78; line-height: 1.5; }
.panel code { font-family: ui-monospace, monospace; font-size: 12px; color: var(--text); }

.stat-row { display: flex; gap: 26px; flex-wrap: wrap; margin: 6px 0 14px; }
.stat { min-width: 92px; }
.stat .v { font-family: 'RS-Bold'; font-size: 24px; color: #ffefb0; }
.stat .l { font-size: 11px; color: var(--dim); text-transform: uppercase; letter-spacing: .6px; }

.tierbar { display: flex; height: 22px; border: 2px inset #0e0e0a; overflow: hidden; }
.tierbar div { height: 100%; }
.tierbar-legend { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 8px; font-size: 12px; }
.tierbar-legend span::before {
    content: ''; display: inline-block; width: 9px; height: 9px;
    background: currentColor; margin-right: 5px; transform: rotate(45deg);
}

.skills { display: grid; gap: 8px; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }
.skillrow { display: flex; align-items: center; gap: 9px; font-size: 13px; }
.skillrow .sn { flex: 0 0 92px; color: var(--dim); }
.skillrow .sb { flex: 1; height: 10px; background: var(--well); border: 1px inset #0e0e0a; }
.skillrow .sb i { display: block; height: 100%; background: var(--gold); }
.skillrow .sv { font-family: 'RS-Bold'; font-size: 12px; color: #ffd44d; min-width: 54px; text-align: right; }

.empty { color: var(--dim); font-size: 14px; padding: 40px 0; text-align: center; }

/* ============================================================== CARD BACK
   Built like a piece of 2004 interface furniture: stone panel, heavy gold
   bevel, rivets at the corners, a lozenge plate for the mark, banner at the
   foot. Nothing on the back may hint at what is on the front.
   ======================================================================== */
.flipper { perspective: 1000px; aspect-ratio: 182 / 268; cursor: pointer; }
.flip-inner {
    position: relative; width: 100%; height: 100%;
    transform-style: preserve-3d;
    transition: transform .55s cubic-bezier(.3,.75,.35,1);
}
.flipper.turned .flip-inner { transform: rotateY(180deg); }

.flipper .face {
    position: absolute; inset: 0;
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
}
.flipper .face.front { transform: rotateY(180deg); }

/* Belt and braces. backface-visibility alone is unreliable once a child sets
   a filter or overflow, and a card whose art shows through before it is turned
   ruins the whole point of a pack. */
.flipper:not(.turned) .face.front { visibility: hidden; }
.flipper .face.front { transition: visibility 0s linear .27s; }

/* A face-down card glows in the tier it is hiding - the only place the glow
   appears, because it exists to tease what is about to be turned over. The
   colour sits on the flipper, so the back itself never knows what it covers. */
.flipper .card.back { transition: box-shadow .12s, border-color .12s, filter .12s; }
.flipper:not(.turned):hover .card.back {
    filter: brightness(1.2);
    box-shadow: 0 0 18px -1px var(--glow), 0 0 6px 0 var(--tier);
    border-color: var(--glow);
}

.card.back { padding: 4px; overflow: hidden; background: #17160f; }
.back-frame {
    position: relative; flex: 1;
    border: 2px outset var(--gold);
    outline: 1px solid #000;
    background: url('img/panel.jpg') repeat; background-size: 110px;
    display: flex; flex-direction: column;
    align-items: center; justify-content: center; gap: 12px;
    overflow: hidden;
}
/* faint diagonal weave, the hatch RS used on its stone panels */
.back-hatch {
    position: absolute; inset: 0; opacity: .15; pointer-events: none;
    background-image:
        repeating-linear-gradient( 45deg, transparent 0 5px, #000 5px 6px),
        repeating-linear-gradient(-45deg, transparent 0 5px, #d8ab3f 5px 6px);
}
.rivet {
    position: absolute; width: 7px; height: 7px; border-radius: 50%;
    background: radial-gradient(circle at 35% 30%, #e6c06a 0 40%, #6d5210 70%, #2a2008 100%);
    box-shadow: 0 0 0 1px #0009;
}
.rivet.tl { left: 5px;  top: 5px; }
.rivet.tr { right: 5px; top: 5px; }
.rivet.bl { left: 5px;  bottom: 5px; }
.rivet.br { right: 5px; bottom: 5px; }

.back-plate {
    position: relative;
    padding: 12px;
    background: #100f0980;
    border: 2px inset #0e0e0a;
}
.back-lozenge {
    width: 66px; height: 66px;
    display: flex; align-items: center; justify-content: center;
    background: linear-gradient(145deg, #2a2412 0%, #14120b 100%);
    border: 2px outset var(--gold);
    transform: rotate(45deg);
    box-shadow: inset 0 0 10px -3px #e6c06a66;
}
.back-lozenge img {
    width: 42px; height: 42px;
    image-rendering: pixelated;
    transform: rotate(-45deg);
}
.back-banner {
    position: relative; width: 88%; text-align: center; padding: 3px 0;
    background: linear-gradient(180deg, #3a2f13 0%, #1d1809 100%);
    border-top: 1px solid #d8ab3f55;
    border-bottom: 1px solid #000;
}
.back-banner span {
    font-family: 'RS-Bold'; font-size: 11px; letter-spacing: 3px;
    color: #e6c06a;
    -webkit-text-stroke: 1px #14120a; paint-order: stroke fill;
}

/* ============================================================ PRINT FINISHES
   Two per-copy finishes, rolled independently of tier.

   The rule that makes these read as print rather than as a CSS filter: the
   finish goes BEHIND the art, never over it. Every icon is a transparent PNG,
   so a pattern painted into the well shows through exactly where a real holo
   sheet would - around the subject, never across its face. The art itself is
   left completely alone.

   And a foil is flat until it catches the light, so the sweep sits still for
   most of its cycle and passes once, rather than a shine strip on a permanent
   loop.
   ======================================================================== */

.card.foil, .card.gilded { contain: paint; }

/* the sweep: one pass, then a long rest */
@keyframes tilt {
    0%, 62%  { transform: translateX(-130%) }
    100%     { transform: translateX(330%) }
}

.card.foil .well::before,
.card.gilded .well::before {
    content: ''; position: absolute; z-index: 0; pointer-events: none;
    top: -30%; bottom: -30%; left: 0; width: 42%;
    transform: translateX(-130%);
    animation: tilt 6.5s cubic-bezier(.45,0,.55,1) infinite;
    will-change: transform;
}

/* ---------------------------------------------------------------- foil
   Cold silver. A woven diamond lattice behind the subject - close to the
   cross-hatch a 2004 interface would have dithered - lit by a white pass. */
.card.foil {
    border-color: #c3cedb;
    box-shadow: 0 0 0 1px #000, 0 0 12px -4px #c3cedb;
}
.card.foil .name {
    border-bottom-color: #c3cedb;
    color: #eef4ff;
    background: linear-gradient(180deg, #33404d99, #00000059);
}
.card.foil .well {
    background:
        /* Silver ripple: fine concentric rings struck from behind the subject.
           Deliberately the same idea as the gilded rays and deliberately not
           the same geometry - rings read as cold and gold rays read as warm, so
           the two are told apart at a glance across a grid. Diagonal rakes and
           cross-hatches were both tried here and both read as cloth. */
        repeating-radial-gradient(circle at 50% 46%,
            #cfe6ff1a 0 1px, transparent 1px 7px),
        repeating-radial-gradient(circle at 50% 46%,
            #ffffff0f 0 1px, transparent 1px 23px),
        radial-gradient(ellipse at 50% 44%, #a8cff036 0%, transparent 66%),
        radial-gradient(ellipse at 50% 45%,
            color-mix(in srgb, var(--tier) 34%, #191d22) 0%,
            color-mix(in srgb, var(--tier) 12%, #0c0f12) 80%);
    border-color: #0b0e12;
}
.card.foil .well::before {
    background: linear-gradient(100deg,
        transparent, #ffffff0f 34%, #eaf6ff4d 50%, #ffffff0f 66%, transparent);
}
.card.foil .foot .pts { color: #dceaff; }

/* --------------------------------------------------------------- gilded
   Warm gold leaf, and rarer than foil, so it is allowed to be louder: rays out
   of the centre like a stamped medallion, a heavier frame, a quicker and more
   saturated pass. */
.card.gilded {
    border-color: #e8c24a;
    box-shadow:
        0 0 0 1px #000,
        inset 0 0 0 1px #7d5c10,
        0 0 18px -4px #e8c24ae0;
}
.card.gilded .name {
    border-bottom-color: #e8c24a;
    color: #fff2c4;
    background: linear-gradient(180deg, #574212a8, #00000059);
}
.card.gilded .well {
    background:
        /* the rays are struck from the centre and fade out before the rim, so
           the card reads as a stamped medallion rather than a sunburst poster */
        radial-gradient(ellipse at 50% 46%,
            transparent 0 34%, #0d0a04b8 82%),
        repeating-conic-gradient(from 6deg at 50% 46%,
            #ffdd8a17 0deg 4deg, transparent 4deg 11deg),
        radial-gradient(ellipse at 50% 44%, #ffd77a38 0%, transparent 64%),
        radial-gradient(ellipse at 50% 45%,
            color-mix(in srgb, var(--tier) 34%, #241f13) 0%,
            color-mix(in srgb, var(--tier) 12%, #0f0c06) 80%);
    border-color: #120e05;
}
.card.gilded .well::before {
    width: 34%;
    animation-duration: 4.6s;
    background: linear-gradient(100deg,
        transparent, #ffe9a824 32%, #fff4cc80 50%, #ffe9a824 68%, transparent);
}
.card.gilded .foot .pts { color: #ffe9a8; }

/* -------------------------------------------------------------- the tag
   A chiselled plate in the finish's own metal, riveted into the top-left
   corner the way a 2004 interface would have labelled something. */
.finish-tag {
    position: absolute; z-index: 4; left: 5px; top: 4px;
    font-family: 'RS-Bold'; font-size: 9px; letter-spacing: 1px;
    padding: 1px 6px; border-radius: 1px;
    text-transform: uppercase; color: #12100a;
    border: 1px solid #00000099;
    box-shadow: inset 0 1px 0 #ffffff8c, 0 1px 2px #000000a6;
}
.card.foil   .finish-tag { background: linear-gradient(180deg, #eef4ff, #93a4b8); }
.card.gilded .finish-tag { background: linear-gradient(180deg, #ffe9a8, #b8892a); }

/* ------------------------------------------------------- on the big card
   Same idea at detail size: pattern behind the art, one slow pass. */
/* No `position` here. A modal <dialog> is laid out in the top layer, and the UA
   sheet gives it `position: absolute` to centre it there. Overriding that with
   `position: relative` drops it back into normal flow at the top of the
   document, and showModal's focus then scrolls the page up to find it - which
   is why opening a foil or gilded card threw you back to the top of the binder
   and opening a plain one did not. */
dialog.foil { border-color: #c3cedb; }
dialog.gilded { border-color: #e8c24a; box-shadow: inset 0 0 0 1px #7d5c10; }
dialog.foil .well {
    background:
        repeating-radial-gradient(circle at 50% 46%, #cfe6ff1a 0 1px, transparent 1px 11px),
        repeating-radial-gradient(circle at 50% 46%, #ffffff0f 0 1px, transparent 1px 37px),
        radial-gradient(ellipse at 50% 44%, #a8cff036 0%, transparent 66%),
        radial-gradient(ellipse at 50% 45%,
            color-mix(in srgb, var(--tier) 34%, #191d22) 0%,
            color-mix(in srgb, var(--tier) 12%, #0c0f12) 80%);
}
dialog.gilded .well {
    background:
        radial-gradient(ellipse at 50% 46%, transparent 0 34%, #0d0a04b8 84%),
        repeating-conic-gradient(from 6deg at 50% 46%,
            #ffdd8a17 0deg 3deg, transparent 3deg 9deg),
        radial-gradient(ellipse at 50% 44%, #ffd77a38 0%, transparent 64%),
        radial-gradient(ellipse at 50% 45%,
            color-mix(in srgb, var(--tier) 34%, #241f13) 0%,
            color-mix(in srgb, var(--tier) 12%, #0f0c06) 80%);
}
dialog.foil .well::before, dialog.gilded .well::before {
    content: ''; position: absolute; z-index: 0; pointer-events: none;
    top: -30%; bottom: -30%; left: 0; width: 40%;
    transform: translateX(-130%);
    animation: tilt 6.5s cubic-bezier(.45,0,.55,1) infinite;
    will-change: transform;
}
dialog.foil .well::before {
    background: linear-gradient(100deg,
        transparent, #ffffff0f 34%, #eaf6ff4d 50%, #ffffff0f 66%, transparent);
}
dialog.gilded .well::before {
    animation-duration: 4.6s;
    background: linear-gradient(100deg,
        transparent, #ffe9a824 32%, #fff4cc80 50%, #ffe9a824 68%, transparent);
}

/* the well is the stage for all of this, and the art sits above it */
.card .well, dialog .well { position: relative; overflow: hidden; }
.card .well img, .card .well .glyph,
dialog .well img, dialog .well .glyph { position: relative; z-index: 1; }

.foil-word   { color: #cfd6dd; }
.gilded-word { color: #e8c24a; }

/* discontinued: gold leaf, the rarest thing on the board */
.card[data-tier='discontinued'] { border-color: #e6cc80; }
.card[data-tier='discontinued'] .name { border-bottom-color: #e6cc80; color: #fff0c4; }

/* tint the detail dialog to match its tier as well */
dialog {
    background:
        linear-gradient(180deg,
            color-mix(in srgb, var(--tier) 22%, transparent) 0%,
            transparent 55%),
        url('img/panel.jpg') repeat;
    background-size: auto, 128px;
}

.reveal-bar {
    display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
    margin-bottom: 14px; padding: 10px 12px;
    background: var(--panel); border: 2px solid var(--gold-lo); border-radius: 2px;
}
/* every reveal mode fills the same grid, so the layout never jumps */
#reveal { min-height: 0; }
.flipper .card { will-change: transform; }

@media (prefers-reduced-motion: reduce) {
    .card.foil .well::before, .card.gilded .well::before,
    dialog.foil .well::before, dialog.gilded .well::before { animation: none; }
}

/* ================================================================== RARITY
   A reference page, so it is laid out as a ledger: one row per rung, the tier's
   own colour carrying the row, numbers right-aligned so they can be compared
   down the column.
   ======================================================================== */
.rarity-table { display: flex; flex-direction: column; gap: 4px; }
.rarity-row {
    display: grid;
    grid-template-columns: 18px minmax(120px, 1.1fr) minmax(96px, .8fr) minmax(100px, .8fr) minmax(120px, 1.4fr);
    gap: 12px; align-items: center;
    padding: 10px 12px;
    background: #00000038;
    border: 1px solid #0009;
    border-left: 4px solid var(--rt, var(--gold));
    border-radius: 2px;
    font-size: 15px;
}
.rarity-row.head {
    background: transparent; border-color: transparent;
    border-left-color: transparent;
    font-family: 'RS-Bold'; font-size: 12px; letter-spacing: 1px;
    text-transform: uppercase; color: var(--dim);
    padding-bottom: 2px;
}
.rarity-row .pip-tier {
    width: 11px; height: 11px; background: var(--rt);
    border: 1px solid #0008; transform: rotate(45deg);
}
.rarity-row .rname {
    font-family: 'RS-Bold'; font-size: 16px; color: var(--rt);
    text-shadow: 1px 1px 0 #000;
}
.rarity-row .rnum { font-family: 'RS-Bold'; font-size: 15px; color: #ffd44d; }
.rarity-row .rnote { color: #b9b09a; font-size: 14px; }
.rarity-row.head .rname, .rarity-row.head .rnum,
.rarity-row.head .rnote { color: inherit; font-size: 12px; text-shadow: none; }

.rule-list { display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); }
.rule {
    padding: 11px 13px;
    background: #00000038; border: 1px solid #0009; border-radius: 2px;
    border-top: 2px solid var(--gold-lo);
}
.rule b {
    display: block; margin-bottom: 5px;
    font-family: 'RS-Bold'; font-size: 13px; color: #ffefb0;
    text-shadow: 1px 1px 0 #000;
}
.rule b { font-size: 14px; }
.rule p { margin: 0; font-size: 14px; color: #b9b09a; line-height: 1.5; }

/* ================================================================ TOASTS
   Every action says whether it worked. Signing in used to change one line of
   grey text at the bottom of a panel, which is indistinguishable from nothing
   happening - and getting the key wrong looked exactly the same as getting it
   right.
   ======================================================================== */
.toasts {
    position: fixed; z-index: 60; right: 16px; bottom: 16px;
    display: flex; flex-direction: column-reverse; gap: 8px;
    max-width: min(380px, calc(100vw - 32px));
    pointer-events: none;
}
.toast {
    pointer-events: auto;
    background:
        linear-gradient(180deg, #00000047, #00000085),
        url('img/panel.jpg') repeat;
    background-size: auto, 128px;
    border: 2px outset var(--gold);
    border-left: 5px solid var(--gold-hi);
    outline: 1px solid #000;
    border-radius: 2px;
    padding: 11px 14px;
    box-shadow: 0 4px 14px #000a;
    animation: toast-in .22s cubic-bezier(.2,.9,.3,1);
}
.toast.out { animation: toast-out .25s ease forwards; }
.toast b {
    display: block; font-family: 'RS-Bold'; font-size: 15px; color: #ffefb0;
    text-shadow: 1px 1px 0 #000; margin-bottom: 2px;
}
.toast span { display: block; font-size: 14px; color: #c9bfa4; line-height: 1.45; }
.toast.good { border-left-color: #7fc04a; }
.toast.good b { color: #d6f2b4; }
.toast.bad  { border-left-color: #d05a3c; border-color: #8a3a28; }
.toast.bad b { color: #ffc8b6; }
@keyframes toast-in  { from { transform: translateY(14px); opacity: 0 } }
@keyframes toast-out { to { transform: translateY(8px); opacity: 0 } }
@media (prefers-reduced-motion: reduce) {
    .toast, .toast.out { animation: none; }
}

/* ------------------------------------------------------- who you are, at a glance */
.who-panel { border-color: var(--gold); }
.who-head {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    padding-bottom: 11px; margin-bottom: 12px;
    border-bottom: 1px solid #0009; box-shadow: 0 1px 0 #ffffff0f;
}
.who-name {
    font-family: 'RS-Bold'; font-size: 25px; letter-spacing: 1px; color: #ffefb0;
    text-shadow: 2px 2px 0 #000;
}
.badges { display: flex; gap: 6px; flex-wrap: wrap; }
.badge {
    font-family: 'RS-Bold'; font-size: 11px; letter-spacing: .8px;
    text-transform: uppercase; padding: 3px 9px; border-radius: 2px;
    border: 1px solid #0009; box-shadow: inset 0 1px 0 #ffffff1f;
    background: #00000059; color: var(--dim);
}
.badge.on  { background: linear-gradient(180deg, #3f6a24, #244014); color: #d6f2b4; border-color: #5c8f36; }
.badge.off { background: linear-gradient(180deg, #4a3812, #2a1f0a); color: #e8c98a; border-color: #7a5a1e; }
.next-step {
    margin-top: 12px; padding: 11px 13px;
    font-size: 15px; line-height: 1.5; color: #efe4bd;
    background: #00000047; border: 1px solid #0009;
    border-left: 4px solid var(--gold-hi); border-radius: 2px;
}

/* ============================================================== THE ALARM
   Above the views, not inside a tab, because an account being taken is not a
   thing you should have to go looking for. Red is the only place on the site
   that uses it, so it cannot be mistaken for decoration.
   ======================================================================== */
.alarm {
    background: linear-gradient(180deg, #4a1410, #2a0c0a);
    border-bottom: 2px solid #b6432c;
    box-shadow: inset 0 -1px 0 #000, 0 2px 8px #000a;
}
.alarm-body { max-width: 1500px; margin: 0 auto; padding: 14px 20px 16px; }
.alarm b {
    display: block; font-family: 'RS-Bold'; font-size: 17px; letter-spacing: .5px;
    color: #ffd0c2; text-shadow: 1px 1px 0 #000;
}
.alarm span { display: block; font-size: 14px; color: #e8a894; margin-top: 3px; }
.alarm p { margin: 8px 0 11px; font-size: 14px; color: #d6b3a8; line-height: 1.5; max-width: 78ch; }
button.act.danger {
    border-color: #b6432c;
    background: linear-gradient(180deg, #5d1c15, #38100c);
    color: #ffd0c2;
}
button.act.danger:hover { filter: brightness(1.25); }

/* the three steps of the challenge, so it reads as a task and not a wall */
.steps { display: grid; gap: 8px; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); margin: 4px 0 12px; }
.step {
    display: flex; align-items: baseline; gap: 9px;
    padding: 9px 12px; font-size: 14px; color: #cfc4a0;
    background: #00000038; border: 1px solid #0009; border-radius: 2px;
}
.step b {
    font-family: 'RS-Bold'; font-size: 15px; color: #12100a;
    background: var(--gold-hi); border: 1px solid #0009; border-radius: 2px;
    min-width: 20px; text-align: center; padding: 0 5px;
}
.step em { color: #ffefb0; font-style: normal; }

/* waiting to exist is a state, not an error */
.challenge.waiting { border-left-color: #6f9a4e; }
.challenge.waiting .ch-line b { color: #b6e08a; }

.ch-warn {
    margin-top: 9px; padding: 9px 11px;
    font-size: 13px; line-height: 1.5; color: #e8c9a0;
    background: #3a230c99; border: 1px solid #7a5a1e; border-radius: 2px;
}

/* ================================================ SYNC AND THE XP CHALLENGE */
.formula {
    font-family: ui-monospace, 'Consolas', monospace;
    font-size: 14px; color: #ffd44d;
    background: var(--well); border: 2px inset var(--gold-lo);
    padding: 10px 12px; margin: 0 0 10px;
    overflow-x: auto; white-space: nowrap;
}

.challenge {
    background: #00000047; border: 1px solid #0009;
    border-left: 4px solid var(--gold);
    border-radius: 2px; padding: 13px 15px; margin: 4px 0 10px;
}
.ch-line { font-size: 17px; color: #efe4bd; line-height: 1.5; }
.ch-line b { color: #ffd44d; }
.ch-note { font-size: 13px; color: #948c78; margin-top: 6px; line-height: 1.5; }
.ch-progress { font-family: 'RS-Bold'; font-size: 14px; color: #ffd44d; min-height: 18px; }

/* the unverified route is deliberately behind a fold - it is the lesser option */
.fold { margin: 6px 0 4px; }
.fold summary {
    cursor: pointer; font-size: 14px; color: var(--dim);
    padding: 5px 0; user-select: none;
}
.fold summary:hover { color: var(--text); }
.fold[open] summary { color: #ffefb0; }

/* ------------------------------------------------------------ wordmark */
/* Quill, matching the mark on the back of every card */
h1, .back-banner span {
    font-family: 'RS-Quill', 'RS-Bold', serif;
    text-transform: none;
    letter-spacing: 1px;
}
h1 { font-size: 40px; line-height: .9; }
.back-banner span { font-size: 17px; letter-spacing: .5px; }

.purse .who {
    font-family: 'RS-Bold'; color: #cfc4a0;
    border: 2px inset var(--gold-lo); border-radius: 2px;
    padding: 3px 9px; background: #00000047;
}
label.check { font-size: 13px; color: var(--dim); display: inline-flex; align-items: center; gap: 5px; }
button.act.small { font-size: 12px; padding: 4px 9px; }

.keybox {
    font-family: ui-monospace, monospace; font-size: 15px; letter-spacing: 1px;
    background: var(--well); border: 2px inset var(--gold-lo);
    padding: 10px 12px; word-break: break-all; color: #ffe9a8;
}
.accrow {
    display: flex; align-items: center; gap: 10px;
    padding: 8px 10px; margin-bottom: 6px;
    background: #00000038; border: 1px solid #0009;
}
.accname { font-family: 'RS-Bold'; font-size: 15px; color: #ffefb0; flex: 1; }

/* ------------------------------------------------------------ trade */
.trade {
    background: var(--panel); border: 2px solid var(--gold-lo); border-radius: 2px;
    margin-bottom: 14px;
}
.trade-head {
    display: flex; gap: 12px; align-items: baseline; flex-wrap: wrap;
    padding: 9px 12px; border-bottom: 1px solid var(--line);
    background: #00000038;
}
.trade-head .trader { font-family: 'RS-Bold'; font-size: 15px; color: #ffefb0; }
.trade-head .wants { font-size: 13px; color: var(--dim); }
.trade-body { display: flex; gap: 18px; padding: 14px; align-items: flex-start; flex-wrap: wrap; }
.trade-side { width: 182px; }
.trade-side.grow { flex: 1; min-width: 260px; width: auto; }
.trade-label {
    font-family: 'RS-Bold'; font-size: 11px; letter-spacing: 1px;
    text-transform: uppercase; color: var(--dim); margin-bottom: 6px;
}
.trade-offers { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 10px; }
.trade-offer { width: 182px; }
.trade-who { font-size: 12px; color: var(--dim); text-align: center; margin: 4px 0; }

dialog .held {
    font-family: 'RS-Bold'; font-size: 12px; text-align: center;
    color: #cfc4a0; padding: 7px 6px; margin-top: 5px;
    background: #00000047; border: 1px solid #0009;
}

/* ------------------------------------------------------------ trade board */
.trade-head .spacer { flex: 1; }
.badge-you {
    font-family: 'RS-Bold'; font-size: 10px; letter-spacing: 1px;
    text-transform: uppercase; color: #12100a; background: var(--gold-hi);
    border: 1px solid #0009; border-radius: 2px; padding: 1px 5px;
}
.trade-arrow {
    align-self: center; font-size: 26px; color: var(--gold-hi);
    text-shadow: 1px 1px 0 #000; padding: 0 2px;
}
.trade-offer { display: flex; flex-direction: column; gap: 4px; }
.trade-offer .act.accept { background: #2f4a1e; border-color: #6f9a4e; }
.empty.small { padding: 18px 0; font-size: 13px; }
