/* ===========================================================================
   STYLING.CSS  -  read this first
   ===========================================================================

   HOW THIS FILE IS BUILT
   ----------------------
   It is not one flat stylesheet. It is a stack of LAYERS, each appended below
   the last and each deliberately overriding the one above it, as the look of
   the game moved from its original styling through RuneScape Classic and on to
   the 2004 beta.

   That is why a selector like #combatBarHud is defined several times and why there
   are ~300 !important declarations. They are not accidents: a later layer has
   to beat an earlier one, and CSS decides that by source order and specificity.

   THE ONE RULE FOR EDITING THIS FILE
   ----------------------------------
   THE LAST DEFINITION WINS. If a change appears to do nothing, something
   further DOWN the file is overriding it. Search for the selector, take the
   final occurrence, and edit that one. Do not add another override at the
   bottom unless you are adding a genuinely new layer.

   LAYOUT GEOMETRY LIVES IN VARIABLES
   ----------------------------------
   Do not hand-position HUD elements. The bottom-left column is a LANE system:
   each element gets a fixed lane height and stacks upward from the chat box.
   Adding a readout means adding a lane, not guessing a `bottom` value - that
   guesswork is what previously left five elements overlapping each other.

     --rs-col     right sidebar width      --hud-x       shared left edge
     --rs-bar     bottom control bar       --hud-gutter  gap between lanes
     --rs-chat    chat parchment height    --hud-base    first lane's baseline
     --rs-mini    minimap diameter         --lane-*      each lane's height

   THE FRAME IS 512 x 346
   ----------------------
   That is the real 2001 client's applet size and everything is authored to it,
   then scaled up to the window with --rsc-zoom. Any new overlay must fit those
   coordinates or it will be clipped. Verified clear at time of writing: no
   overlaps, nothing off-screen.

   LAYER MAP
   ---------
     line 897   RUNESCAPE CLASSIC (2001-2003) RESKIN  — overrides above
     line 980   512x346 FIT LAYER  — appended last so it wins over everything ab
     line 1139  RUNESCAPE 2004-05 BETA HUD — fitted to the true 512x346 applet.
     line 1334  HUD TEXT PLACEMENT FIX (512x346) — appended last, wins.
     line 1355  NPC-HINT vs STAT-BAR FIX (appended last, wins).
     line 1372  RIGHT-CLICK CONTEXT MENU — styled to match the OSRS "Choose Opti
     line 1568  RS2-BETA INTERFACE SKIN (appended last, wins)
     line 1707  RS2-BETA LAYOUT MATCH (appended after the skin, wins)
     line 1839  TRANSITIONS
     line 1901  BOTTOM-LEFT HUD STACK - single source of truth

   =========================================================================== */

/* 1. Embed the provided RuneScape TrueType Font */
  @font-face {
    font-family: 'basic';
    src: url('/runescape.ttf') format('truetype');
    font-weight: normal;
    font-style: normal;
  }
  
  @font-face {
    font-family: 'quil';
    src: url('/quil.ttf') format('truetype');
    font-weight: normal;
    font-style: normal;
  }

  :root {
    --gold: #ffff00;
    --gold-dark: #aaaa00;
    --ink: #ffffff;
    
    /* RSC HUD Theme Colors */
    --rsc-cyan: #00ffff;
    --rsc-teal-dark: #002b2b;
    --rsc-teal-bright: #005f5f;
    --rsc-border: #555555;
    --rsc-border-light: #888888;
  }
  
  * { box-sizing: border-box; }

  html, body {
    margin: 0; padding: 0;
    width: 100%; height: 100%;
    background: #000;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    
    font-family: 'basic', monospace;
    font-size: 16px;
    image-rendering: pixelated;
    
    color: var(--ink);
    -webkit-user-select: none; user-select: none;
  }

  #page-layout { 
    width: 512px;
    height: 346px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #000;
    position: relative;
    transform-origin: center center;
    flex-shrink: 0;
  }

  .rsc-frame {
    width: 100%;
    height: 100%;
  }

  /* --- CLASSIC 2001 RSC LOGIN UI OVERLAY --- */
  #login-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: #000000;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    z-index: 9999;
  }

  .rsc-login-logo-container {
    width: min(90%, 380px);
    height: clamp(70px, 30vh, 140px);
    background-color: black;
    margin-bottom: clamp(10px, 3vh, 25px);
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    overflow: hidden;
  }

  .rsc-logo-fallback-text {
    width: 100%;
    height: 100%;
    font-size: 42px;
    color: #8c8c8c;
    font-weight: bold;
    text-shadow: 3px 3px 0px #000000;
    letter-spacing: 4px;
    text-transform: uppercase;
  }

  .rsc-login-prompt {
    color: #ffffff;
    font-size: clamp(14px, 4vw, 22px);
    margin-bottom: clamp(12px, 3vh, 25px);
    text-align: center;
    letter-spacing: 0.5px;
    font-family: 'basic';
    font-weight: bold;
  }
  
  .rsc-login-notice {
    color: #ffffff;
    font-size: clamp(10px, 2.5vw, 15px);
    margin-bottom: clamp(12px, 3vh, 25px);
    text-align: center;
    letter-spacing: 0.5px;
    font-family: 'basic';
  }

  /* Screens */
  .rsc-login-screen {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
  }

  .hidden {
    display: none !important;
  }

  .rsc-button-container-horizontal {
    display: flex;
    gap: clamp(16px, 5vw, 45px);
    justify-content: center;
    align-items: center;
  }

  .rsc-classic-btn {
    background: linear-gradient(to right, #5d75a8, #384359);
    border: 2px solid #000000;
    color: #ffffff;
    font-family: 'quil', monospace;
    font-size: clamp(12px, 3vw, 16px);
    padding: clamp(6px, 1.5vh, 10px) clamp(14px, 4vw, 24px);
    min-width: clamp(90px, 25vw, 140px);
    cursor: default;
    box-shadow: inset 2px 2px 0px #6b7587, inset -2px -2px 0px #2d323b;
    text-align: center;
  }

  .rsc-classic-btn:active {
    box-shadow: inset -2px -2px 0px #6b7587, inset 2px 2px 0px #2d323b;
  }

  /* Credentials input container styling */
  .rsc-credentials-box {
    display: flex;
    flex-direction: column;
    gap: clamp(8px, 2vh, 16px);
    width: min(80%, 290px);
    margin-bottom: clamp(10px, 2vh, 20px);
  }

  .rsc-credentials-box .input-group {
    display: flex;
    flex-direction: column;
    gap: 4px;
  }

  .rsc-credentials-box label {
    font-size: clamp(11px, 3vw, 16px);
    color: var(--gold);
    text-transform: lowercase;
  }

  .rsc-credentials-box input {
    width: 100%;
    padding: clamp(4px, 1vh, 6px);
    background-color: #000000;
    color: #ffffff;
    border: 2px solid #5c5c5c;
    font-family: inherit;
    font-size: clamp(11px, 3vw, 16px);
  }
  /* ----------------------------------------- */

  /* Character select screen */
  .rsc-charselect-grid {
    display: flex;
    gap: clamp(8px, 2vw, 18px);
    justify-content: center;
    align-items: center;
    margin-bottom: clamp(12px, 3vh, 22px);
    flex-wrap: wrap;
    max-width: 90%;
  }

  .rsc-char-thumb {
    width: clamp(48px, 15vw, 84px);
    height: clamp(48px, 15vw, 84px);
    background: #000000;
    border: 2px solid #5c5c5c;
    box-shadow: inset 2px 2px 0px #333, inset -2px -2px 0px #000;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: default;
  }

  .rsc-char-thumb img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    image-rendering: pixelated;
  }

  .rsc-char-thumb.selected {
    border-color: var(--gold);
    box-shadow: 0 0 0 2px var(--gold), inset 2px 2px 0px #333, inset -2px -2px 0px #000;
  }
  /* ----------------------------------------- */

  /* INTEGRATED LAYOUT — full-bleed viewport, everything else floats over it */
  #gameUI {
    width: 100%;
    height: 100%;
    background: #000; 
    overflow: hidden; 
    position: relative;
  }

  /* THE VIEWPORT NOW FILLS THE ENTIRE 875x650 FRAME */
  #mainViewport {
    position: relative;
    width: 100%;
    height: 100%;
    overflow: hidden;
    background: #000;
  }

  /* CANVAS FILLS THE FULL VIEWPORT */
  #canvasWrap {
    position: absolute;
    inset: 0;
    z-index: 1;
    border: none;
  }

  #canvasWrap canvas {
    display: block;
    width: 100% !important;
    height: 100% !important;
    cursor: default;
    image-rendering: pixelated;
  }

  /* --- UPDATED TAB ROW TO MATCH SCREENSHOT --- */
  /* --- TRANSPARENT WHITE STYLE WITH LIGHT GRAY BORDERS --- */
#tabBtnsRow { 
  position: absolute;
  top: 4px; 
  right: 4px;
  display: grid; 
  grid-template-columns: repeat(6, 46px);
  background: transparent; /* Allows the underlying UI to show through the gaps */
  border: none;
  gap: 2px; /* Small spacing to separate the light gray borders cleanly */
  z-index: 36;
}

#tabBtnsRow button {
  padding: 0; 
  background: rgb(128, 128, 128); /* Translucent white background */
  border: 2px solid #d3d3d3; /* Solid light gray border */
  display: flex; 
  align-items: center; 
  justify-content: center;
  height: 46px;
  width: 46px;
  cursor: default;
  box-shadow: none; /* Removed the old 3D stone bevel shadow */
  transition: background 0.15s ease;
  
  /* --- FIXES TO CLIP THE OVERFLOWING IMAGE --- */
  overflow: hidden;        /* Crops the image to the button's borders */
  box-sizing: border-box;  /* Forces the 2px border to stay inside the 46px limit */
}

#tabBtnsRow button:hover {
  background: rgba(255, 255, 255, 0.4); /* Slightly brighter on hover */
}

#tabBtnsRow button.active { 
  background: rgba(255, 255, 255, 0.55); /* Noticeably solid/opaque when active */
  border-color: #ffffff; /* Turns white when active to highlight selection */
}

#tabBtnsRow button img { 
  width: 100%;
  height: 100%;
  object-fit: cover;
  image-rendering: pixelated; 
  display: block; /* Prevents any inline baseline gaps under the image */
}

  /* THE DROPDOWN PANEL - shows on hover, floats under the tab row like the real client */
  #tabDropdown {
    position: absolute;
    top: 32px; right: 4px;
    width: 205px;
    max-height: 420px;
    display: none;
    flex-direction: column;
    background: #5c5c5c;
    border: 2px solid #000;
    z-index: 35;
    box-shadow: 0 4px 14px rgba(0,0,0,.6);
  }
  #tabDropdown.open { display: flex; }

  #tabContent { flex: 1; overflow-y: auto; padding: 4px; background: #5c5c5c; max-height: 420px; }

  /* BOTTOMBAR - compact overlay, bottom-right, above the classic link bar */
    
  /* CLASSIC FIXED TOP-LEFT ACTION TEXT (not a cursor tooltip) */
  #npcHint {
    position: absolute; 
    top: 4px; left: 4px;
    max-width: 320px;
    z-index: 32; 
    padding: 3px 6px; 
    font-size: 15px; 
    color: #ffffff;
    background: none; 
    border: none;
    display: block; 
    pointer-events: none;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    text-shadow: 1px 1px 0px #000;
  }

  /* AUTO-APPEARING COMBAT STYLE MENU, replaces/augments the action text while fighting */
  #combatStyleOverlay {
    position: absolute;
    top: 28px; left: 4px;
    width: 190px;
    z-index: 33;
    display: none;
    box-shadow: 0 4px 14px rgba(0,0,0,.6);
  }

  /* WAVE COUNTDOWN. The "Select combat style" box also lives in this corner
     (top:28px, left:4px) and can be visible at the same time if the player is
     fighting a critter/dummy between waves - pushed down below its full
     height (~170-180px) to clear it. Hidden between waves by main-boot.js. */
  /* FPS READOUT. Now the sole occupant of this corner: the wilderness depth
     percentage that used to sit here reported the same thing as the skull's
     wilderness level, just in different units. */
  #fpsDisplay {
    position: absolute;
    top: 189px; left: 4px;
    color: #ffffff;
    pointer-events: none;
    z-index: 10;
    opacity: 0.95;
    line-height: 1.4;
    font-size: 15px;
    font-weight: normal;
    font-family: 'quil', monospace;
  }

  .clickMarker {
    position: absolute; width: 16px; height: 16px; border: 2px solid #ff0000;
    transform: translate(-50%,-50%); pointer-events: none; z-index: 26;
    animation: clickPing .4s steps(4) forwards;
  }
  @keyframes clickPing {
    0% { opacity: 1; transform: translate(-50%,-50%) scale(0.6); border-color: #ff0000; }
    50% { border-color: #ffff00; }
    100% { opacity: 0; transform: translate(-50%,-50%) scale(1.4); }
  }

  #blockIndicator {
    position: absolute; 
    top: 50%; 
    left: 50%; 
    transform: translate(-50%, -50%);
    width: 70px; 
    height: 70px; 
    border: 2px dashed #ff0000; 
    z-index: 21;
    opacity: 0 ; 
    pointer-events: none;
  }

  #blockIndicator.active { opacity: 0.8; }

  h1, h2, h3, .rs-title { margin: 0; color: var(--gold); font-weight: bold; text-transform: lowercase; }

  .rs-panel { 
    background: #5c5c5c; 
    border: 2px solid #000000;
  }
  
  .rs-parchment { 
    font-family: 'quil', monospace;
    background: transparent; 
    color: #fff;
    border: none;
  }
  
  .rs-btn {
    font-family: 'basic', monospace;
    background: #444444; 
    border: 2px solid #222222;
    color: #fff; padding: 4px 10px; cursor: default; font-size: 14px;
    box-shadow: inset 1px 1px 0 #6b6b6b, inset -1px -1px 0 #1a1a1a;
  }
  .rs-btn:active {
    box-shadow: inset -1px -1px 0 #6b6b6b, inset 1px 1px 0 #1a1a1a;
  }

  ::-webkit-scrollbar { width: 14px; background: #111111; border-left: 1px solid var(--rsc-border); }
  ::-webkit-scrollbar-thumb { background: #333333; border: 1px solid var(--rsc-border-light); }

  /* FLOATING STAT BAR */
  .stat { font-size: 14px; color: var(--gold); display: flex; align-items: center; gap: 4px; flex-shrink: 0; }
  .stat b { color: #fff; }
  .stat .icon { font-size: 14px; display: flex; align-items: center; }
  .stat .icon img { max-height: 14px; }

  #lvlbar { width: 50px; height: 8px; background: #000; border: 1px solid var(--rsc-border); overflow: hidden; display: inline-block; }
  #lvlbarFill { height: 100%; background: #00ff00; width: 0%; }

  /* EXTRA TAB (formerly a persistent panel, now its own tab - see .rscExtraBlock below) */
  .hud-btn-toggle {
    cursor: default;
    text-align: center;
    padding: 2px;
    border: 1px solid #222;
    border-radius: 3px;
    background: #333;
    margin-bottom: 6px;
    box-shadow: inset 1px 1px 0 #555, inset -1px -1px 0 #111;
  }
  .hud-btn-toggle:hover { color: var(--gold); background: #444; }
  .hud-btn-toggle:active { box-shadow: inset -1px -1px 0 #555, inset 1px 1px 0 #111; }

  /* FLOATING CHAT LOG WINDOW */
  #log {
    position: absolute; left: 2px; bottom: 1px; width: 50%; height: 50px; z-index: 20;
    padding: 1px; font-size: 16px; overflow-y: auto; text-align: left;
    background: transparent; border: none;
    text-shadow: 1px 1px 0px #000;
    color: #ffffff; 
    pointer-events: none;
  }
  #log .g { color: #ffffff; }
  #log .r { color: #ffffff; }
  #log .b { color: #ffffff; }
  #log .p { color: #ffffff; }
  #log .c { color: #ffffff; }
  #log .v { color: #ffffff; }

  /* OSRS-STYLE CHAT FILTER BAR */
  .rsc-tabs { 
    position: absolute; left: 0; bottom: 0; width: 100%; height: 26px; 
    display: flex; z-index: 35; 
    background: linear-gradient(#1a3a6b, #0d2547); 
    padding: 0; opacity: 0;
    border-top: 1px solid #2a4d80; cursor: default;
  }
  .rsc-tabs span {
    flex: 1; text-align: center; padding-top: 6px; 
    color: var(--rsc-cyan); 
    cursor: default; background: transparent; border-right: 1px solid #2a4d80;
    font-size: 13px; white-space: nowrap; text-transform: none; 
    text-shadow: 1px 1px 0 #000;
  }
  .rsc-tabs span:last-child { 
    border-right: none; 
    background: #7a0b00; 
    color: #ffffff; 
  }
  
  #waveBanner {
    position: absolute; top: 25%; left: 50%; transform: translate(-50%,-50%);
    z-index: 25; padding: 10px 20px; text-align: center; opacity: 0; pointer-events: none;
    border: 1px solid #fff; background: #000;
  }
  #waveBanner.show { opacity: 1; }

  /* Low-hitpoints vignette - opacity/animation driven by updateLowHpVignette()
     in main-boot.js. Sits above the 3d canvas, below all HUD/menu chrome. */
  #lowHpVignette {
    position: absolute; inset: 0; z-index: 20; pointer-events: none;
    opacity: 0;
    background: radial-gradient(ellipse at center, rgba(180,0,0,0) 55%, rgba(180,0,0,0.55) 100%);
    animation: lowHpPulse 1.6s ease-in-out infinite;
  }
  @keyframes lowHpPulse {
    0%, 100% { filter: brightness(1); }
    50% { filter: brightness(1.35); }
  }

  /* --- Classic RSC sleeping screen --- */
  #sleepScreen {
    position: absolute; inset: 0; z-index: 90;
    background: #000;
    display: none;
    align-items: center; justify-content: center;
    text-align: center;
  }
  #sleepScreen.show { display: flex; }
  #sleepScreen .sleepInner { position: relative; z-index: 2; max-width: 480px; padding: 0 20px; }
  #sleepScreen h1 { color: #ffe066; font-size: 26px; margin: 0 0 6px; text-shadow: 1px 1px 0 #000; }
  #sleepScreen h2 { color: #ffe066; font-size: 18px; margin: 0 0 18px; text-shadow: 1px 1px 0 #000; }
  #sleepScreen p { color: #fff; font-size: 13px; line-height: 1.5; margin: 0 0 10px; }
  #sleepScreen .sleepRerollLine { font-size: 12px; color: #ccc; }
  #sleepScreen .sleepRerollLine a { color: #ffe066; text-decoration: none; cursor: default; }
  #sleepScreen .sleepRerollLine a:hover { color: #fff; }

  .sleepWord {
    font-size: 26px; font-weight: bold; color: #e8e8e8; margin: 10px auto 14px;
    letter-spacing: 3px; user-select: none;
  }
  .sleepWord span { display: inline-block; }

  #sleepWordInput {
    display: block; margin: 0 auto 14px; width: 220px;
    background: #000; border: 2px solid #fff; color: #fff;
    font-family: inherit; font-size: 16px; text-align: center; padding: 5px;
    outline: none;
  }

  .sleepZ {
    position: absolute; font-weight: bold; font-size: 22px; z-index: 1;
    text-shadow: 1px 1px 0 #000; user-select: none; opacity: 0.9;
  }
  .z1 { top: 8%;  left: 6%;  color: #33ff33; transform: rotate(-12deg); font-size: 20px; }
  .z2 { top: 20%; left: 16%; color: #ff4444; transform: rotate(8deg);  font-size: 16px; }
  .z3 { top: 42%; left: 4%;  color: #6699ff; transform: rotate(-6deg); font-size: 24px; }
  .z4 { top: 70%; left: 10%; color: #cc66ff; transform: rotate(10deg); font-size: 18px; }
  .z5 { top: 10%; right: 6%; color: #33ff33; transform: rotate(14deg); font-size: 22px; }
  .z6 { top: 34%; right: 14%; color: #ffee44; transform: rotate(-10deg); font-size: 17px; }
  .z7 { top: 58%; right: 5%; color: #ff8844; transform: rotate(6deg);  font-size: 20px; }
  .z8 { top: 80%; right: 16%; color: #66ccff; transform: rotate(-8deg); font-size: 16px; }

  #modalWrap { position: absolute; inset: 0; background: rgba(0,0,0,0.8); z-index: 50; display: none; align-items: center; justify-content: center; }

  #modalBox {
    position: relative;
    display: flex;
    flex-direction: column;
    width: 420px;
    max-width: 92%;
    max-height: 500px;
    overflow: hidden;
    text-align: center;
    border: 2px solid #000;
    background: #4a4a4a;
  }

  #modalTitleBar {
    display: flex; align-items: center; justify-content: space-between;
    padding: 6px 10px;
    background: linear-gradient(#2a4d80, #0d2547);
    border-bottom: 2px solid #000;
  }
  #modalTitleBar #modalTitle { margin: 0; font-size: 14px; color: #fff; text-align: left; }
  #modalBtn {
    cursor: default; font-size: 12px; color: #fff; white-space: nowrap; padding-left: 10px;
  }
  #modalBtn:hover { color: var(--rsc-gold); }

  #modalSubBar {
    display: none;
    justify-content: space-between;
    padding: 4px 10px;
    background: #12345c;
    border-bottom: 2px solid #000;
    font-size: 11px;
  }
  #modalSubBar.show { display: flex; }
  #modalSubLeft { color: #55ff55; }
  #modalSubRight { color: #6699ff; }

  #modalBodyScroll { flex: 1; overflow-y: auto; padding: 14px 18px; }

  #modalFooterHint {
    display: none;
    padding: 6px 10px;
    text-align: center;
    color: #ffe066;
    font-size: 12px;
    background: #2a2a2a;
    border-top: 2px solid #000;
    text-shadow: 1px 1px 0 #000;
  }
  #modalFooterHint.show { display: block; }

  #loadScreen { position: absolute; inset: 0; background: #000; z-index: 100; display: flex; align-items: center; justify-content: center; }
  .loading-bar-container {
    width: 250px; height: 30px; background: black; border: 2px solid #730000; position: relative; overflow: hidden;
    display: flex; align-items: center; justify-content: center;
  }
  #loadingBarFill { position: absolute; left: 0; top: 0; bottom: 0; width: 0%; background: #d60000; z-index: 0; }
  #loadScreen p { color: #00ffff; font-size: 12px; font-family: Arial, sans-serif; margin: 0; position: relative; z-index: 1; pointer-events: none; }

  .damageFloat { position: absolute; z-index: 26; font-size: 18px; pointer-events: none; text-shadow: 1px 1px 0px #000; }

  .invGrid { 
    display: grid; 
    grid-template-columns: repeat(5, 1fr); 
    gap: 0px; 
    border-top: 2px solid #000;
    border-left: 2px solid #000;
    background: #000;
    margin-bottom: 8px; 
  }
  .invSlot {
    position: relative; 
    background: #5c5c5c; 
    border-right: 2px solid #000;
    border-bottom: 2px solid #000;
    aspect-ratio: 1/1; display: flex; align-items: center; justify-content: center;
    box-shadow: inset 1px 1px 0 #7a7a7a, inset -1px -1px 0 #2a2a2a;
    cursor: default;
  }
  .invSlot:hover { background: #6c6c6c; box-shadow: inset 0 0 0 2px #7a6a00; }
  .invSlot.selected { background: #444444; box-shadow: inset 0 0 0 2px #ffcc33; }
  .invSlot .qty { position: absolute; top: 2px; left: 2px; font-size: 14px; color: var(--gold); font-weight: bold; text-shadow: 1px 1px 0px #000;}

  /* Bank window: same beveled slot-grid look as the inventory, but denser
     (7 columns, like the reference RSC bank screen) and with two quantity
     badges per slot instead of one - how many of that item sit in the bank
     (green, bottom-left) and how many the player is currently carrying
     (blue, top-right), matching the color legend already set by
     setModalSubBar()/#modalSubLeft/#modalSubRight above the grid. */
  .bankGrid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 0px;
    border-top: 2px solid #000;
    border-left: 2px solid #000;
    background: #000;
    margin-bottom: 8px;
  }
  .bankSlot {
    position: relative;
    background: #5c5c5c;
    border-right: 2px solid #000;
    border-bottom: 2px solid #000;
    aspect-ratio: 1/1; display: flex; align-items: center; justify-content: center;
    box-shadow: inset 1px 1px 0 #7a7a7a, inset -1px -1px 0 #2a2a2a;
    cursor: pointer;
  }
  .bankSlot:hover { background: #6c6c6c; box-shadow: inset 0 0 0 2px #7a6a00; }
  .bankSlot.selected { background: #444444; box-shadow: inset 0 0 0 2px #ffcc33; }
  .bankSlot img { max-width: 78%; max-height: 78%; }
  .bankSlot .qtyBank { position: absolute; bottom: 1px; left: 2px; font-size: 11px; color: #55ff55; font-weight: bold; text-shadow: 1px 1px 0px #000; }
  .bankSlot .qtyHeld { position: absolute; top: 1px; right: 2px; font-size: 11px; color: #6699ff; font-weight: bold; text-shadow: 1px 1px 0px #000; }

  /* Deposit/withdraw panel that appears under the grid once an item is
     selected - was completely unstyled before (raw browser default block
     text), which is why it read as broken next to the grid above it. */
  .invActionBox {
    border: 2px solid #000; background: #4a4a4a; padding: 8px 10px; text-align: left;
    box-shadow: inset 1px 1px 0 #6b6b6b, inset -1px -1px 0 #1a1a1a;
  }
  .iaName { color: var(--rsc-gold); font-weight: bold; font-size: 13px; margin-bottom: 3px; }
  .iaDesc { color: #ddd; font-size: 11px; margin-bottom: 6px; }
  .iaBtns { display: flex; flex-wrap: wrap; gap: 5px; }

  /* Gold variant: withdraw / buy actions get a warm brass look so they read
     as distinct from the plain-grey deposit actions at a glance. */
  .rs-btn.gold {
    background: linear-gradient(#6b5522, #3a2e10);
    border-color: #1a1400;
    color: #ffe066;
    box-shadow: inset 1px 1px 0 #a4883c, inset -1px -1px 0 #1a1400;
  }
  .rs-btn.gold:active { box-shadow: inset -1px -1px 0 #a4883c, inset 1px 1px 0 #1a1400; }
  .rs-btn:disabled { opacity: 0.5; cursor: default; }

  .achRow, .bestRow, .merchRow, .satchelRow, .skillRow, .craftRow { 
    border: 2px solid #000; margin-bottom: 4px; background: #4a4a4a; padding: 5px; text-align: left;
  }

  .csHeader {
    background: #1a1a1a;
    color: var(--gold);
    font-size: 13px;
    font-weight: bold;
    text-transform: none;
    padding: 4px 6px;
    border: 2px solid #000;
    border-bottom: none;
  }
  .combatStylePanel {
    display: flex;
    flex-direction: column;
    margin-bottom: 10px;
    border: 2px solid #000;
  }
  .csRow {
    background: #2b2b2b;
    color: #ffffff;
    font-size: 13px;
    padding: 6px 8px;
    cursor: default;
    border-top: 1px solid #444;
  }
  .csRow:first-child { border-top: none; }
  .csRow:hover { background: #3a3a3a; color: var(--gold); }
  .csRow.selected {
    background: #7a0000;
    color: #ffffff;
    font-weight: bold;
    box-shadow: inset 0 0 0 1px #ff5555;
  }
  
#gearBar, #slayerTracker {
  position: absolute; left: 0px; z-index: 21; width: 150px;
  background: rgba(0,0,0,.85); border: 2px solid #000; padding: 6px;
}

/* CLASSIC RSC/RS2-BETA WILDERNESS SKULL. Overlaid on the 3D view,
   directly under the wilderness percentage line, in normal document flow (no
   absolute positioning needed - it just stacks below the text above it).
   Only shown while the player is both past the first wilderness tier AND
   actively in combat (toggled in main-boot.js) - matching the real client,
   where the indicator never appears outside a fight. */
/* Overlaid on the bottom-right of the 3D view, as in the 2004 client, rather
   than stacked under the sidebar depth readout. */
#wildernessLevelIndicator {
  display: none;
  position: absolute;
  right: calc(var(--rs-col) + 14px);
  bottom: 92px;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  z-index: 30;
  pointer-events: none;
}
#wildernessSkullIcon {
  /* waveactive.png is 24x24 - drawn at native size so the pixels land 1:1. */
  width: 24px;
  height: 24px;
  image-rendering: pixelated;
  filter: drop-shadow(0 1px 1px rgba(0,0,0,.9));
}
#wildernessLevelText {
  font-family: 'quil', serif;
  font-size: 14px;
  font-weight: bold;
  color: #ffd700;
  text-shadow: 1px 1px 0 #000, -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000;
  white-space: nowrap;
}
#gearBar { bottom: 250px; font-size: 13px; }
#slayerTracker { bottom: 310px; font-size: 13px; color: #fff; }


  
  /* Container for the background slideshow */
.login-slideshow {
  position: relative;
  width: 100%;        /* Fills .rsc-login-logo-container, which is now responsive */
  height: 100%;
  overflow: hidden;
  border: 1px solid lightgray;
}

/* Layer images directly on top of each other */
.login-slideshow img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  /* Use a linear timing function for a smoother cross-dissolve blend */
  animation: rscDissolveLonger 20s linear infinite;
}

/* Stagger start times by 5 seconds each */
.login-slideshow img:nth-child(1) { animation-delay: 0s; }
.login-slideshow img:nth-child(2) { animation-delay: 5s; }
.login-slideshow img:nth-child(3) { animation-delay: 10s; }

/* 20-second dissolve loop timeline with a 2.5-second transition */
@keyframes rscDissolveLonger {
  0% {
    opacity: 1;
  }
  /* Takes 2.5 seconds (12.5% of 20s) to fade in completely */
  12.5% {
    opacity: 1;
  }
  /* Stays fully visible until the 5-second mark (25% of 20s) */
  37.5% {
    opacity: 1;
  }
  100% {
    opacity: 1;
  }
}
/* ============================================================
   RUNESCAPE CLASSIC (2001-2003) RESKIN  — overrides above
   ============================================================ */
:root{
  --rsc-panel: rgba(60,60,60,0.88);      /* translucent gray tab panels */
  --rsc-panel-lite: rgba(90,90,90,0.88);
  --rsc-slot:#2b2b2b;
  --rsc-gold:#ffdd33;
}

/* --- Classic dark palette for the HUD deck & panels --- */
#gameUI, .rs-panel { 
  background: var(--rsc-panel) !important; 
}

/* --- UPDATED TAB ROW & BUTTON CONTAINER STYLING --- */
#tabBtnsRow {
  position: absolute;
  top: 4px; right: 4px;
  display: grid; 
  grid-template-columns: repeat(3, 46px); /* 3 across, 2 rows */
  background: transparent !important;    /* Keeps background clear */
  border: none !important;
  gap: 2px !important;
  z-index: 36;
}

#tabBtnsRow button {
  padding: 0 !important; 
  background: rgba(80, 80, 80, 0.9) !important; /* SLIGHTLY LIGHTER GRAY BACKGROUND */
  border: 2px solid #d3d3d3 !important;         /* Solid light gray border */
  display: flex !important; 
  align-items: center !important; 
  justify-content: center !important;
  height: 46px !important;
  width: 46px !important;
  cursor: default;
  box-shadow: none !important;
  transition: background 0.15s ease;
}

#tabBtnsRow button:hover {
  background: rgba(100, 100, 100, 0.95) !important; /* Lighter highlight on hover */
}

#tabBtnsRow button.active {
  background: rgba(55, 55, 55, 0.95) !important;   /* Distinct darker active state */
  border-color: #ffffff !important;                /* Bright white highlight border */
  box-shadow: none !important;
}

#tabBtnsRow button img { 
  width: 100% !important;
  height: 100% !important;
  object-fit: cover !important;
  image-rendering: pixelated !important; 
}

/* --- MATCHING SLIGHTLY LIGHTER GRAY DROPDOWN PANEL STYLING --- */
#tabDropdown {
  position: absolute;
  top: 54px !important; /* Lowered from 32px to clear the new taller 46px buttons */
  right: 4px;
  width: 286px; /* Matches the total width of the 6 button columns + gaps */
  background: rgba(80, 80, 80, 0.9) !important; /* MATCHING SLIGHTLY LIGHTER GRAY BACKGROUND */
  border: 2px solid #d3d3d3 !important;         /* Solid light gray matching border */
  box-shadow: 0 4px 14px rgba(0,0,0,.6) !important;
}

#tabContent {
  background: transparent !important; /* Allows the dropdown's background to show through */
}

/* Header text inside the box styled to fit the new theme */
#tabDropdown::before {
  display: block; padding: 3px 0 2px; margin: 2px 2px 0;
  text-align: center; font-size: 12px; font-weight: bold; letter-spacing: 1px;
  color: var(--rsc-gold); /* Yellow gold looks beautiful over the gray background */
  background: rgba(0, 0, 0, 0.3) !important;
  border: 1px solid #777777 !important;
  text-shadow: 1px 1px 0px #000000 !important;
  content: "INVENTORY";
}
/* ============================================================
   512x346 FIT LAYER  — appended last so it wins over everything above.
   The frame stays a true 512x346 RSC applet internally (so nothing has to
   be re-authored), but every piece of chrome is re-sized to the proportions
   the real 2001 client used at that resolution, and the whole frame is then
   scaled up to the window with --rsc-zoom. Text is re-rasterized at the
   zoomed size (crisp), and the 3D canvas gets a matching pixel ratio from
   the fit script in index.html, so it is bigger without being blockier.
   ============================================================ */
:root{
  --rsc-zoom: 1;              /* set by rscFitFrame() in index.html */
  --rsc-tab: 27px;            /* tab icon size (was 46px) */
  --rsc-panel-w: 168px;       /* right-hand panel width (was 286px) */
  --rsc-font: 11px;
}

/* Scale the whole applet to the window, from the centre. */
#page-layout{
  width: 512px;
  height: 346px;
  transform: scale(var(--rsc-zoom));
  transform-origin: center center;
  image-rendering: auto;
}

/* Body/base type: RSC used a ~11-12px face at this resolution. */
html, body{ font-size: var(--rsc-font); }

/* Nearest-neighbour, not smooth. The buffer is now a true 512x346 and the
   page scales it up, exactly as the applet was blown up in a browser window -
   so the upscale must not interpolate or the whole point is lost. */
#canvasWrap canvas{
  image-rendering: pixelated;
  image-rendering: crisp-edges;   /* Firefox spells it differently */
}

/* --- Tab icons: 6 across the top-right in 167px instead of 286px --- */
#tabBtnsRow{
  top: 3px !important; right: 3px !important;
  grid-template-columns: repeat(3, var(--rsc-tab)) !important;   /* 3 on top, 3 below */
  gap: 1px !important;
}
#tabBtnsRow button{
  width: var(--rsc-tab) !important;
  height: var(--rsc-tab) !important;
  border-width: 1px !important;
}

/* --- Right-hand panel: fits under the icons inside 346px of height --- */
#tabDropdown{
  top: calc(var(--rsc-tab) + 5px) !important;
  right: 3px !important;
  width: var(--rsc-panel-w) !important;
  max-height: 296px !important;
  border-width: 1px !important;
}
#tabContent{
  max-height: 276px !important;
  padding: 3px !important;
  font-size: var(--rsc-font);
}
#tabDropdown::before{
  padding: 1px 0 !important;
  margin: 1px 1px 0 !important;
  font-size: 9px !important;
  letter-spacing: 0 !important;
}

/* Panel innards */
.rs-btn{ font-size: 10px; padding: 2px 5px; border-width: 1px; }
.rs-btn.small{ font-size: 9px; padding: 1px 4px; }
.achRow, .bestRow, .merchRow, .satchelRow, .skillRow, .craftRow{
  border-width: 1px; margin-bottom: 2px; padding: 3px; font-size: 10px;
}
.invGrid{ border-top-width: 1px; border-left-width: 1px; margin-bottom: 4px; }
.invSlot{ border-right-width: 1px; border-bottom-width: 1px; }
.invSlot img{ max-width: 82%; max-height: 82%; }
.invSlot .qty{ font-size: 9px; top: 0; left: 1px; }
.bankGrid{ border-top-width: 1px; border-left-width: 1px; margin-bottom: 4px; grid-template-columns: repeat(6, 1fr); }
.bankSlot{ border-right-width: 1px; border-bottom-width: 1px; }
.bankSlot .qtyBank, .bankSlot .qtyHeld{ font-size: 9px; }
.invActionBox{ padding: 5px 6px; border-width: 1px; }
.iaName{ font-size: 10px; }
.iaDesc{ font-size: 9px; margin-bottom: 4px; }
.csHeader{ font-size: 10px; padding: 2px 4px; border-width: 1px; }
.csRow{ font-size: 10px; padding: 3px 5px; }
::-webkit-scrollbar{ width: 7px; }

/* --- Action text / combat style overlay --- */
#npcHint{
  font-size: 11px; padding: 1px 3px; max-width: 200px; top: 2px; left: 2px;
}
#combatStyleOverlay{ top: 18px; left: 2px; width: 120px; }

/* --- Left column: HP/prayer, gear, slayer. Stacked bottom-up so all three
       stay inside 346px instead of running off the top. --- */
#gearBar, #slayerTracker{
  width: 104px; padding: 3px; border-width: 1px; font-size: 10px;
}
#gearBar{ bottom: 132px; font-size: 9px; }
#slayerTracker{ bottom: 186px; font-size: 9px; }

/* --- Chat log: classic 5 lines along the bottom-left --- */
#log{
  left: 2px; bottom: 2px; width: 62%; height: 62px;
  font-size: 11px; line-height: 1.15;
}

/* The button was still using the general .rs-btn border (2px) + .rs-btn.small
   padding (1px 4px), which left only ~14px of interior room in this 26px-wide
   shell - too small for the 16px icon below, so it spilled outside the
   button's edges instead of sitting inside it. Slimmed to match the
   container's own 1px border and centered properly. */

/* --- Modals: must live inside 512x346 --- */
#modalBox{ width: 320px !important; max-width: 94% !important; max-height: 280px !important; }
#modalTitleBar{ padding: 3px 6px; border-bottom-width: 1px; }
#modalTitleBar #modalTitle{ font-size: 11px; }
#modalBtn{ font-size: 10px; }
#modalSubBar{ padding: 2px 6px; font-size: 9px; }
#modalBodyScroll{ padding: 6px 8px; font-size: 10px; }
#modalText{ font-size: 10px; margin: 0 0 6px; }
#modalFooterHint{ padding: 3px 6px; font-size: 9px; }
.mn{ font-size: 10px; }
.md, .mc{ font-size: 9px; }
.mIcon img{ width: 14px !important; height: 14px !important; }

/* --- Wave banner / load screen / sleep screen --- */
#waveBanner{ padding: 4px 10px; }
#waveBanner h2{ font-size: 14px; }
#waveBanner p{ font-size: 10px; margin: 2px 0 0; }
.loading-bar-container{ width: 180px; height: 20px; }
#loadScreen p{ font-size: 10px; }
#sleepScreen .sleepInner{ max-width: 340px; padding: 0 10px; }
#sleepScreen h1{ font-size: 16px; margin-bottom: 3px; }
#sleepScreen h2{ font-size: 12px; margin-bottom: 8px; }
#sleepScreen p{ font-size: 10px; margin-bottom: 5px; }
.sleepWord{ font-size: 17px; letter-spacing: 2px; margin: 5px auto 7px; }
#sleepWordInput{ width: 150px; font-size: 11px; padding: 2px; border-width: 1px; }
.sleepZ{ font-size: 14px !important; }
.damageFloat{ font-size: 12px; }
.stat{ font-size: 10px; }
.stat .icon img{ max-height: 10px; }

/* --- Login overlay: the 512x346 frame is scaled, the login screen is not,
       so give it its own sensible ceiling. --- */
#login-overlay{ font-size: 12px; }

/* ============================================================
   RUNESCAPE 2004-05 BETA HUD — fitted to the true 512x346 applet.
   (appended last — wins over everything above; delete to revert.)
   Sidebar/frame use the game's own stone textures (darkened so light text
   stays readable). Every coordinate is sized so the whole HUD lands inside
   512x346; the applet is then scaled up by --rsc-zoom.
   ============================================================ */
:root{
  --rs-col: 156px;         /* right column width */
  --rs-mini: 106px;        /* round minimap size */
  --rs-tab: 25px;          /* tab icon size (6 across the 156px column) */
  --rs-chat: 76px;         /* parchment chat height */
  --rs-bar: 16px;          /* bottom chat-control bar height */
  --rs-parch: #d9caa2;     /* aged chat parchment */
  --rs-gold2: #ffdd44;
  /* Darkening overlays laid over the stone texture so the panels aren't too
     light for white/gold text. */
  --rs-tint:   linear-gradient(rgba(28,24,18,0.56), rgba(28,24,18,0.56));
  --rs-tint-d: linear-gradient(rgba(16,13,9,0.72), rgba(16,13,9,0.72));
}

/* Stone frame backdrop (the border area around the view/panel/chat). */
#gameUI, #mainViewport{
  background: var(--rs-tint-d), url('textures/rock.jpg') !important;
  background-size: 96px 96px !important;
  image-rendering: pixelated;
}
#mainViewport{ box-shadow: inset 0 0 0 1px #17130d, inset 0 0 16px rgba(0,0,0,0.6); }

/* --- 3D VIEW: framed block, top-left --- */
#canvasWrap{
  top: 3px !important; left: 3px !important;
  right: calc(var(--rs-col) + 8px) !important;
  bottom: calc(var(--rs-chat) + var(--rs-bar) + 7px) !important;
  border: 2px solid #14110b !important;
}

/* --- ROUND MINIMAP: centred at the top of the right column --- */
#hudMinimap{
  position: absolute; top: 3px;
  right: calc((var(--rs-col) - var(--rs-mini))/2 + 3px);
  width: var(--rs-mini); height: var(--rs-mini);
  border-radius: 50%;
  background: #223018;
  border: 2px solid #14110b;
  box-shadow: inset 0 0 0 3px #2c2820, 0 0 0 1px #6a6252;
  /* Was overflow:hidden, which clipped the compass to the round map. The
     canvas carries its own border-radius so the map is still a clean circle,
     and the compass is now free to sit proud of the edge like the real client. */
  overflow: visible; z-index: 34;
}
#hudMinimapCanvas{ width: 100%; height: 100%; display: block; border-radius: 50%; image-rendering: pixelated; }
/* Compass: sits over the top-left of the minimap and is rotated every frame by
   updateHudCompass() so its needle holds true north. */
#hudCompass{
  position: absolute; top: -7px; left: -7px;
  width: 30px; height: 30px;
  z-index: 36; cursor: pointer;
  transform-origin: 50% 50%;
  /* No CSS transition: the rotation is already smoothed by the camera's own
     easing, and a transition on top of a per-frame update just adds lag. */
  filter: drop-shadow(0 1px 1px rgba(0,0,0,0.8));
}
#hudCompass img{ width: 100%; height: 100%; display: block; image-rendering: pixelated; pointer-events: none; }
#hudCompass:hover{ filter: drop-shadow(0 0 3px #ffd98a); }
/* Fallback needle, shown only if compass.png is missing (see the img onerror
   in playgame.html) so the control is never invisible or broken-looking. */
#hudCompass.noCompassImg{
  background: radial-gradient(circle, #cfc6ac 0 46%, #6a6252 47% 100%);
  border-radius: 50%; border: 1px solid #14110b;
}
#hudCompass.noCompassImg::after{
  content: ''; position: absolute; left: 50%; top: 3px;
  width: 0; height: 0; transform: translateX(-50%);
  border-left: 5px solid transparent; border-right: 5px solid transparent;
  border-bottom: 11px solid #d64b2a;
}

/* --- TAB ROW: directly below the minimap, 6 stone tabs across the column --- */
#tabBtnsRow{
  top: calc(var(--rs-mini) + 6px) !important;
  right: 3px !important;
  grid-template-columns: repeat(3, var(--rs-tab)) !important;   /* 3 on top, 3 below */
  gap: 1px !important;
}
#tabBtnsRow button{
  width: var(--rs-tab) !important; height: var(--rs-tab) !important;
  background: var(--rs-tint), url('textures/stone2.jpg') !important;
  background-size: 48px 48px !important;
  border: 1px solid #14110b !important;
  box-shadow: inset 1px 1px 0 #7a725e, inset -1px -1px 0 #322e28 !important;
  image-rendering: pixelated;
}
#tabBtnsRow button.active{
  background: var(--rs-tint-d), url('textures/stone2.jpg') !important;
  background-size: 48px 48px !important;
  border-color: var(--rs-gold2) !important;
  box-shadow: inset -1px -1px 0 #7a725e, inset 1px 1px 0 #322e28 !important;
}

/* --- PANEL: stone-textured, always open, below the tab row --- */
#tabDropdown{
  display: flex !important;
  top: calc(var(--rs-mini) + var(--rs-tab) + 10px) !important;
  right: 3px !important;
  bottom: calc(var(--rs-bar) + 3px) !important;
  width: var(--rs-col) !important;
  max-height: none !important;
  background: var(--rs-tint), url('textures/totemwood.png') !important;
  background-size: 64px 64px !important;
  border: 2px solid #14110b !important;
  box-shadow: inset 1px 1px 0 #7a725e, inset -1px -1px 0 #322e28 !important;
  image-rendering: pixelated;
}
#tabContent{ max-height: none !important; flex: 1 1 auto; overflow-y: auto; background: transparent !important; padding: 4px !important; }
#tabDropdown::before{ color: var(--rs-gold2) !important; background: rgba(0,0,0,0.3) !important; border-color: #6a6252 !important; }

/* --- INVENTORY: borderless slots so items sit right on the stone --- */
.invGrid{ border: none !important; background: transparent !important; gap: 1px !important; }
.invSlot{ background: transparent !important; border: none !important; box-shadow: none !important; }
.invSlot:hover{ background: rgba(255,255,255,0.08) !important; box-shadow: none !important; }
.invSlot.selected{ background: rgba(255,220,80,0.16) !important; box-shadow: inset 0 0 0 1px var(--rs-gold2) !important; }
.invSlot .qty{ color: var(--rs-gold2) !important; }

/* --- EQUIPMENT DIAMOND (buildEquipmentHTML) --- */
.eqDiamond{ display:flex; flex-direction:column; align-items:center; gap:3px; margin:3px 0 5px; }
.eqRow{ display:flex; gap:12px; justify-content:center; }
.eqCell{
  width:30px; height:30px; display:flex; align-items:center; justify-content:center;
  background: var(--rs-tint-d), url('textures/stone2.jpg'); background-size:48px 48px;
  border:1px solid #14110b; box-shadow: inset 1px 1px 0 #6a6252, inset -1px -1px 0 #2a2620;
  position:relative; image-rendering:pixelated;
}
.eqCell.empty{ visibility:hidden; }
.eqCell img{ max-width:80%; max-height:80%; image-rendering:pixelated; }
.eqCell .eqLbl{ font-size:6px; color:#c6beae; text-align:center; line-height:1; }
.eqCell.filled{ box-shadow: inset 0 0 0 1px var(--rs-gold2), inset 1px 1px 0 #6a6252; }
.eqStats{
  margin:4px 2px; padding:3px 5px; background:rgba(9,32,16,0.85); border:1px solid #14110b;
  font-size:9px; color:#55dd55; display:grid; grid-template-columns:1fr 1fr; gap:1px 8px;
}
.eqStats span{ color:#9fe89f; }
.eqStats b{ color:#fff; float:right; }

/* --- CORE STAT BAR: compact, top-left over the view --- */
#npcHint{ top:18px !important; max-width: calc(100% - var(--rs-col) - 20px) !important; }
#combatStyleOverlay{ top:32px !important; }

/* --- FEWER FLOATERS --- */
#gearBar, #slayerTracker{ display:none !important; }

/* --- PARCHMENT CHAT --- */
#log{
  top:auto !important; left:3px !important;
  right: calc(var(--rs-col) + 8px) !important;
  bottom: calc(var(--rs-bar) + 2px) !important;
  width:auto !important; height: var(--rs-chat) !important;
  padding:3px 7px !important;
  /* Real parchment sheet; --rs-parch is the fallback colour if the image is missing. */
  background: var(--rs-parch) url('textures/parchment.jpg') center/cover !important;
  border:2px solid #14110b !important;
  font-size:11px !important; line-height:1.22 !important;
  pointer-events:auto !important; overflow-y:auto !important;
}
#log, #log .g, #log .r, #log .b, #log .p, #log .c, #log .v{ color:#6a1c08 !important; text-shadow:none !important; }

/* --- BOTTOM CHAT-CONTROL BAR --- */
.rsc-tabs{
  display:flex !important; left:0 !important; bottom:0 !important;
  width:100% !important; height: var(--rs-bar) !important;
  background: var(--rs-tint-d), url('textures/stone2.jpg') !important;
  background-size: 64px 64px !important;
  border-top:1px solid #14110b !important; opacity:1 !important; z-index:40 !important;
  align-items:center; image-rendering:pixelated;
}
.rsc-tabs span{
  flex:1; text-align:center; font-size:9px; color:#cfc6b0 !important;
  border-right:1px solid #14110b; padding:0 !important; background:transparent !important;
  white-space:nowrap;
}
.rsc-tabs span:last-child{ border-right:none; color:#fff !important; }
.rsc-tabs .on{ color:#33dd33; }
.rsc-tabs a{ color:inherit; text-decoration:none; }

/* ============================================================
   HUD TEXT PLACEMENT FIX (512x346) — appended last, wins.
   Keep the next-wave countdown and FPS readout from overlapping the stat bar,
   action text, combat menu, HP panel, chat or the sidebar.
   ============================================================ */
/* FPS takes the top-left slot the wilderness percentage used to occupy, just
   under the action text. */
#fpsDisplay{
  top: 32px !important; left: 4px !important;
  right: auto !important; bottom: auto !important;
  text-align: left !important;
}
/* Wilderness skull: this used to shrink it to 16px because it sat in normal
   flow in the sidebar HUD. It is now an overlay on the 3D view
   instead, and waveactive.png is a 24x24 pixel-art icon - forcing 16px scaled
   it by a non-integer factor, which blurs pixel art no matter what
   image-rendering says. Drawn 1:1 at its native size so it stays crisp. */
#wildernessSkullIcon{ width:24px !important; height:24px !important; }
#wildernessLevelText{ font-size:12px !important; }
#fpsDisplay{ font-size: 10px !important; line-height: 1.2 !important; }

/* ============================================================
   NPC-HINT vs STAT-BAR FIX (appended last, wins).
   Give the stat bar a fixed compact height, drop the action text to a clear
   row just beneath it, and put the action text ABOVE the bar in z-order so it
   can never render behind the bar. The next-wave/combat rows shift down to
   match. All still inside 512x346.
   ============================================================ */
#npcHint{ top: 19px !important; z-index: 36 !important; }
/* Tucked against the left edge, on the row BELOW #combatStyleOverlay
   (y 34-74) rather than beside it. Sharing that row meant pushing the counter
   130px inward to clear the combat menu, which left it stranded in the middle
   of the view; dropping a row keeps it hard against the side and clear of the
   menu at the same time. */
#fpsDisplay{ top: 78px !important; left: 4px !important; }
#combatStyleOverlay{ top: 34px !important; }

/* ============================================================
   RIGHT-CLICK CONTEXT MENU — styled to match the OSRS "Choose Option" box.
   Solid black panel with a thin light border; a grey "Choose Option" header
   over a divider; rows show a WHITE action verb + a CYAN object name. On hover
   only the verb turns YELLOW (no row highlight), exactly like the client.
   Positioned in the frame's own coordinate space by openContextMenuAt().
   ============================================================ */
#rsContextMenu{
  position: absolute;
  z-index: 200;
  min-width: 96px;
  max-width: 280px;
  padding: 0 0 2px 0;
  background: #000;
  border: 1px solid #5a5a5a;         /* light outer edge like the client box */
  box-shadow: 0 1px 3px rgba(0,0,0,0.7);
  font-size: 12px;
  line-height: 1.18;
  font-weight: bold;
  color: #ffffff;
  text-transform: none !important;    /* the game lowercases chat; this box is proper-case */
  user-select: none;
  display: none;
}
#rsContextMenu .rsCtxHeader{
  padding: 2px 5px 3px 5px;
  margin-bottom: 1px;
  background: #000;
  color: #b0b0b0;                     /* grey header text */
  font-weight: bold;
  border-bottom: 1px solid #5a5a5a;   /* divider under the header */
  white-space: nowrap;
  text-transform: none !important;
}
#rsContextMenu .rsCtxRow{
  padding: 0 5px;
  white-space: nowrap;
  cursor: pointer;
  background: #53504A;
  text-transform: none !important;
}
/* Action verb = white; object name = cyan. */
#rsContextMenu .rsCtxAct{ color: #ffffff; }
#rsContextMenu .rsCtxObj{ color: #00ffff; }
/* Hover: only the verb turns yellow; the object stays cyan, no row highlight. */
#rsContextMenu .rsCtxRow:hover .rsCtxAct{ color: #ffff00; }
#rsContextMenu .rsCtxRow:hover .rsCtxObj{ color: #00ffff; }
/* --- 2004 LEVEL-UP DIALOGUE ------------------------------------------------
   The moment everything stops and the chat area is taken over by the skill
   icon and two centred lines, until you click to continue. Sits directly over
   #log (same corner, same parchment font) so it reads as the chat box being
   commandeered, exactly as the 2004 client did it - rather than as a modern
   toast floating somewhere else on screen. */
/* Same footprint as #log and the NPC panel (left:2px, bottom:2px, 62% x 62px).
   It was 50% x 50px, which left chat text visible around its edges, and the
   translucent wash let more show through underneath - both of which read as a
   box floating on the chat rather than replacing it. */
#levelUpPanel{
  /* Exactly the geometry of #log's authoritative rule (the !important
     "PARCHMENT CHAT" block further up), so this sheet lands pixel-for-pixel on
     top of the chat box and hides it completely - which is what the real client
     did: the dialogue REPLACES the chat area for as long as it's open.
     Previously these used left:2px/62%/62px, taken from an earlier #log rule
     that the parchment block overrides, so they covered only part of it and the
     log showed around the edges. Same parchment texture and border too, so the
     swap reads as the chat box changing contents rather than a panel landing on
     top of it. */
  position: absolute;
  left: 3px;
  right: calc(var(--rs-col) + 8px);
  bottom: calc(var(--rs-bar) + 2px);
  width: auto; height: var(--rs-chat);
  box-sizing: border-box;
  background: var(--rs-parch) url('textures/parchment.jpg') center/cover;
  border: 2px solid #14110b;
  text-shadow: none;
  overflow: hidden;
  z-index: 40;                 /* above #log (20) so it covers the chat text */
  display: none;
  align-items: center; gap: 10px;
  padding: 3px 7px;
  font-family: 'quil', monospace;
  text-align: center;
  color: #000080;              /* the classic navy dialogue text */
  cursor: pointer;
}
#levelUpPanel.show{ display: flex; }
#levelUpPanel .luIcon{ flex: 0 0 auto; }
#levelUpPanel .luIcon img{
  width: 36px; height: 36px; display: block;
  image-rendering: pixelated;
}
#levelUpPanel .luText{ flex: 1 1 auto; line-height: 1.25; }
#levelUpPanel .luLine1{ font-size: 13px; }
#levelUpPanel .luLine2{ font-size: 13px; color: #000000; }
#levelUpPanel .luMore{ font-size: 12px; color: #000080; margin-top: 2px; }
#levelUpPanel:hover .luMore{ text-decoration: underline; }

/* --- 2004 NPC CHAT HEAD ----------------------------------------------------
   Parchment panel with a portrait, the speaker's name in red, their line in
   black, and "Click here to continue" in blue.

   The portrait SIDE encodes who is talking: NPCs sit on the left, the player's
   own head on the right. That alternation is most of what makes an exchange
   read as a conversation instead of a wall of text with a picture attached, and
   it's how the real client did it. Markup order never changes - the head is
   always written first - and .side-right just reverses the flex row. */
/* Footprint matches #log (left:2px, bottom:2px, 62% x 62px) exactly. It was
   50% x 50px, so the chat log poked out to the right of it and above it - the
   panel is meant to take the chat area OVER, not sit on part of it. Fully
   opaque for the same reason. */
#npcDialoguePanel{
  /* Exactly the geometry of #log's authoritative rule (the !important
     "PARCHMENT CHAT" block further up), so this sheet lands pixel-for-pixel on
     top of the chat box and hides it completely - which is what the real client
     did: the dialogue REPLACES the chat area for as long as it's open.
     Previously these used left:2px/62%/62px, taken from an earlier #log rule
     that the parchment block overrides, so they covered only part of it and the
     log showed around the edges. Same parchment texture and border too, so the
     swap reads as the chat box changing contents rather than a panel landing on
     top of it. */
  position: absolute;
  left: 3px;
  right: calc(var(--rs-col) + 8px);
  bottom: calc(var(--rs-bar) + 2px);
  width: auto; height: var(--rs-chat);
  box-sizing: border-box;
  background: var(--rs-parch) url('textures/parchment.jpg') center/cover;
  border: 2px solid #14110b;
  text-shadow: none;
  overflow: hidden;
  z-index: 41;                 /* above #log (20) and the level-up sheet (40) */
  display: none;
  align-items: center; gap: 8px;
  padding: 3px 7px;
  font-family: 'quil', monospace;
  cursor: pointer;
}
#npcDialoguePanel.show{ display: flex; }
#npcDialoguePanel.side-left{  flex-direction: row; }
#npcDialoguePanel.side-right{ flex-direction: row-reverse; }
/* Chat head cropped from the full-body world sprite. Every sprite in sprimg is
   39px wide, so the numbers below are fixed rather than proportional:
   render at 96px (~2.5x native), pull left by (96-44)/2 to centre the figure,
   and pull up 4px to trim the empty pixels above the scalp. The 44px box then
   frames the head and shoulders.

   This replaced `width:46px; transform:scale(2.2); transform-origin:50% 20%`,
   which compounded a 1.18x fit with a 2.2x transform into ~2.6x and cropped to
   roughly an 18x18 patch of the source - a fragment of the face blown up until
   it was unrecognisable, which is the grey block in the screenshot. */
#npcDialoguePanel .npcHead{
  flex: 0 0 auto; width: 44px; height: 44px;
  overflow: hidden;
}
#npcDialoguePanel .npcHead img{
  display: block;
  width: 96px; height: auto;
  margin-left: -26px;
  margin-top: -4px;
  image-rendering: pixelated;
}
#npcDialoguePanel .npcSay{ flex: 1 1 auto; text-align: center; line-height: 1.2; min-width: 0; }
#npcDialoguePanel .npcName{ font-size: 13px; color: #b02020; }
#npcDialoguePanel .npcLine{
  font-size: 13px; color: #000000;
  /* Long lines wrap and centre, as in the reference - they never clip. */
  overflow-wrap: break-word;
}
#npcDialoguePanel .npcMore{ font-size: 12px; color: #0000c0; margin-top: 2px; }
#npcDialoguePanel:hover .npcMore{ text-decoration: underline; }

/* --- RUN TOGGLE ------------------------------------------------------------
   Beside the minimap where the real client kept it. */
#runToggle{
  position: absolute;
  top: calc(var(--rs-mini) + 4px);
  right: calc((var(--rs-col) - var(--rs-mini))/2 + 3px);
  display: flex; align-items: center; gap: 3px;
  padding: 1px 5px;
  font-family: 'basic', monospace; font-size: 11px;
  color: #e8dfc8;
  background: var(--rs-tint), url('textures/stone2.jpg');
  background-size: 48px 48px;
  border: 1px solid #14110b;
  box-shadow: inset 1px 1px 0 #7a725e, inset -1px -1px 0 #322e28;
  cursor: pointer; z-index: 35; user-select: none;
}
#runToggle #runToggleIcon{ color: #6b6353; font-size: 9px; }
#runToggle.running #runToggleIcon{ color: #4ddb4d; }
#runToggle.spent   #runToggleIcon{ color: #d64b2a; }
#runToggle.spent   #runToggleText{ color: #d64b2a; }
#runToggle:hover{ filter: brightness(1.25); }
/* The tab row sits below the minimap; nudge it down to clear the toggle. */
#tabBtnsRow{ top: calc(var(--rs-mini) + 22px) !important; }

/* ============================================================
   RS2-BETA INTERFACE SKIN (appended last, wins)
   Matched against the beta bank / shop / treasure-trail screens. What the
   modals had before was the RSC palette: a blue gradient title bar and a flat
   grey body. The beta dropped both - its windows are a single dark warm-brown
   sheet with a bevelled edge, an AMBER title centred across the top, and
   "Close Window" as plain text in the corner rather than a button. Item counts
   are yellow, hint lines at the foot are orange, and any action buttons are
   maroon. Those five things are most of the look.
   ============================================================ */
:root{
  /* The body is a TINT over the stone texture rather than a colour blended
     into it. `background-blend-mode: multiply` was darkening #3f3a32 by the
     texture's own value, so the result landed far darker than the swatch
     suggested and nothing here was predictable. An rgba layer over the image
     lands exactly where it says it will. */
  --rs2-panel:      #665f4e;   /* window body / fallback if uibg.jpg is absent */
  --rs2-panel-dark: #4e4940;   /* recessed areas: item grids, scroll troughs */
  --rs2-border:     #bfb394;   /* SOLID frame - deliberately lighter than the body */
  --rs2-bevel-lo:   #4e4940;   /* retained for the few rules still naming it */
  --rs2-amber:      #ff9040;   /* titles */
  --rs2-orange:     #ff8020;   /* footer hints */
  --rs2-yellow:     #ffff00;   /* item quantities */
  --rs2-btn:        #7d2626;   /* maroon buttons */
  --rs2-btn-hi:     #9a3434;
}
#modalBox{
  /* textures/uibg.jpg is the window sheet. background-COLOR is set separately
     from background-image on purpose: if the file is missing the colour alone
     still renders a proper opaque panel, whereas a shorthand would leave the
     tint layer floating over the 3D scene behind it.
     The wash over the top is deliberately light and quite transparent so
     whatever art goes in reads mostly as drawn - it is there to stop a dark
     source image dragging the panel back down, not to recolour it. */
  background-color: var(--rs2-panel) !important;
  background-image:
    linear-gradient(rgba(45,38,28,0.20), rgba(45,38,28,0.20)),
    url('textures/uibg.jpg') !important;
  /* Tiled at the image's own size rather than stretched to `cover`. `auto`
     respects whatever you author - a 64px tile and a 256px tile both repeat at
     the size you drew them, instead of being scaled to the panel and losing
     their pixel grid. Swap to a fixed `64px 64px` if you'd rather pin it. */
  background-size: auto, auto !important;
  background-position: top left !important;
  background-repeat: repeat, repeat !important;
  /* A single solid frame, lighter than the body it surrounds - no black outline
     and no bevel shadows, which were reading as a second darker border just
     inside the first. */
  border: 2px solid var(--rs2-border) !important;
  box-shadow: none !important;
}
/* No coloured title bar in the beta - the title sits directly on the sheet,
   centred, with the close text pinned to the corner beside it. */
#modalTitleBar{
  background: transparent !important;
  border-bottom: none !important;
  position: relative !important;
  justify-content: center !important;
  padding: 5px 8px 3px !important;
}
#modalTitleBar #modalTitle{
  color: var(--rs2-amber) !important;
  text-align: center !important;
  font-size: 13px !important;
  /* Full outline rather than a single offset shadow. The amber only had 1.7:1
     contrast once the panel was lightened, and since uibg.jpg is user-supplied
     the background brightness isn't knowable - an outline reads on either. */
  text-shadow: 1px 1px 0 #2a2118, -1px 1px 0 #2a2118,
               1px -1px 0 #2a2118, -1px -1px 0 #2a2118 !important;
  letter-spacing: 0.3px;
}
#modalBtn{
  position: absolute !important; right: 6px; top: 5px;
  padding-left: 0 !important;
  color: #ffffff !important; font-size: 10px !important;
  text-shadow: 1px 1px 0 #1a1610 !important;
  cursor: pointer !important;
}
#modalBtn:hover{ color: #ffe9a8 !important; }
/* Sub bar / footer hints: orange centred text on the sheet, no blue strip. */
#modalSubBar{
  background: transparent !important;
  color: var(--rs2-orange) !important;
  border-bottom: 1px solid var(--rs2-border) !important;
  font-size: 10px !important;
}
#modalSubLeft, #modalSubRight{
  color: var(--rs2-orange) !important;
  text-shadow: 1px 1px 0 #2a2118, -1px -1px 0 #2a2118 !important;
}
#modalFooterHint{
  color: var(--rs2-orange) !important;
  text-align: center !important;
  font-size: 10px !important;
  text-shadow: 1px 1px 0 #2a2118, -1px -1px 0 #2a2118 !important;
}
/* Item grids sit in a recessed well, like the beta's bank and shop panes. */
/* .bankGrid is a class, not an id (modals-ui.js sets className='bankGrid'), and
   the merchant is a LIST not a grid - there is no #shopGrid or .shopSlot in
   this codebase, so those selectors are gone rather than left dangling. */
.bankGrid, .invGrid, .merchList{
  background: var(--rs2-panel-dark);
  border: 1px solid var(--rs2-border);
  box-shadow: none;
}
/* Quantities: yellow, top-left, hard black shadow - the beta's single most
   recognisable inventory detail. */
.invSlot .qty, .bankSlot .qtyBank{
  color: var(--rs2-yellow) !important;
  text-shadow: 1px 1px 0 #000 !important;
}
/* Maroon buttons ("Swap / Insert", "Item / Note"). */
#modalBox .rs-btn, #modalBox button{
  background: var(--rs2-btn) !important;
  border: 1px solid var(--rs2-border) !important;
  box-shadow: none !important;
  color: #f0e6d2 !important;
  font-family: 'basic', monospace !important;
}
#modalBox .rs-btn:hover, #modalBox button:hover{ background: var(--rs2-btn-hi) !important; }
#modalBox .rs-btn:disabled, #modalBox button:disabled{
  background: #5f584a !important; color: #9a9080 !important;
  border-color: #7d7362 !important;
  box-shadow: none !important;
}
/* Chunky beta scrollbar rather than the thin dark one. */
/* Merchant rows: alternating tint inside the well so a long list stays
   readable, matching the beta's banded shop panes. */
.merchRow{ background: transparent; border-bottom: none; }
.merchRow:nth-child(even){ background: rgba(255,255,255,0.03); }
.merchRow .mn{ color: var(--rs2-amber) !important; }
.merchRow .mc{ color: var(--rs2-yellow) !important; text-shadow: 1px 1px 0 #000; }

#modalBodyScroll::-webkit-scrollbar{ width: 12px; background: var(--rs2-panel-dark); }
#modalBodyScroll::-webkit-scrollbar-thumb{
  background: #8a7c62; border: 1px solid var(--rs2-border);
  box-shadow: none;
}

/* ============================================================
   RS2-BETA LAYOUT MATCH (appended after the skin, wins)
   The skin above got the colours right; this gets the SHAPE right. Measured
   against the bank and shop screenshots: eight columns, borderless cells over
   one continuous recessed well, a single yellow count per item sitting at the
   top-left, and a centred amber title with an orange instruction line at the
   foot of the pane.
   ============================================================ */

/* ---- BANK: eight columns, like the beta's bank pane ---- */
.bankGrid{
  grid-template-columns: repeat(8, 1fr) !important;
  gap: 0 !important;
  border: none !important;
  padding: 3px !important;
  margin-bottom: 5px !important;
  background: var(--rs2-panel-dark) !important;
  border: 1px solid var(--rs2-border) !important;
  box-shadow: none !important;
}
/* Cells are invisible in the beta - items float on one continuous well rather
   than sitting in a chequerboard of bordered boxes. */
.bankSlot{
  border: none !important;
  background: transparent !important;
  aspect-ratio: 1 / 1;
  padding: 1px !important;
}
.bankSlot:hover{
  background: rgba(255,255,255,0.07) !important;
  box-shadow: none !important;
}
.bankSlot.selected{
  background: rgba(255,204,51,0.16) !important;
  box-shadow: inset 0 0 0 1px #ffcc33 !important;
}
.bankSlot img{ max-width: 88% !important; max-height: 88% !important; }
/* The banked amount is THE number in the beta: yellow, top-left, hard shadow.
   The carried count stays but recedes to a dim corner figure so the pane reads
   as one quantity per item the way the screenshots do, without losing the
   information the sub-bar promises. */
.bankSlot .qtyBank{
  top: 0 !important; left: 1px !important; bottom: auto !important;
  color: var(--rs2-yellow) !important;
  font-size: 9px !important;
}
.bankSlot .qtyHeld{
  top: auto !important; bottom: 0 !important; right: 1px !important;
  /* The carried-count figure: 8px and a dim warm grey against the recessed
     well, which was the least legible thing in the interface. */
  color: #ffffff !important;
  text-shadow: 1px 1px 0 #1a1610, -1px -1px 0 #1a1610 !important;
  font-size: 8px !important;
}

/* ---- MERCHANT: a shop GRID, not a list of rows ---- */
.merchList{
  display: grid !important;
  grid-template-columns: repeat(6, 1fr) !important;
  gap: 0 !important;
  padding: 3px !important;
  background: var(--rs2-panel-dark);
  border: 1px solid var(--rs2-border);
  box-shadow: none;
}
.merchRow{
  display: flex !important;
  flex-direction: column !important;
  align-items: center !important;
  justify-content: flex-start !important;
  position: relative;
  padding: 2px 1px !important;
  border: none !important;
  background: transparent !important;
  text-align: center;
  min-height: 0 !important;
}
.merchRow:nth-child(even){ background: transparent !important; }
.merchRow:hover{ background: rgba(255,255,255,0.07) !important; }
.merchRow .mIcon img{ height: 26px !important; width: auto !important; }
/* Price sits over the icon in yellow, exactly where the beta puts stock counts. */
.merchRow .mc{
  position: absolute; top: 0; left: 2px;
  color: var(--rs2-yellow) !important;
  font-size: 9px !important; font-weight: bold;
  text-shadow: 1px 1px 0 #000;
}
.merchRow .mn{ font-size: 8px !important; color: #ffffff !important; line-height: 1.1;
  text-shadow: 1px 1px 0 #1a1610, -1px -1px 0 #1a1610 !important; }
/* Descriptions don't exist in the beta shop - the item name and price are the
   whole cell. Hidden rather than deleted so the tooltip text stays available. */
.merchRow .md{ display: none !important; }
.merchRow .mi{ display: flex; flex-direction: column; align-items: center; }

/* ---- Title / footer, matched to the screenshots ---- */
#modalTitleBar #modalTitle{ font-size: 12px !important; }
#modalText{
  color: #ffffff !important;
  text-shadow: 1px 1px 0 #1a1610 !important;
  font-size: 9px !important;
  text-align: center !important;
}

/* Buy buttons are hidden, not removed - see renderMerchantModal. The cell is
   the click target, as in the beta. */
.merchRow > .rs-btn{ display: none !important; }
.merchRow{ cursor: pointer; }
.merchRow.cantAfford{ opacity: 0.45; cursor: default; }
.merchRow.cantAfford:hover{ background: transparent !important; }

/* Eight columns need more width than the 320px the modal was capped at - the
   beta's bank pane fills most of the frame. */
#modalBox{ width: 420px !important; max-width: 96% !important; max-height: 300px !important; }

/* Body copy inside modals. These lines used to carry inline `color:#ccc` /
   `color:#fff` in modals-ui.js, which beats every stylesheet rule - so they sat
   outside all the theming work and stayed dim no matter what the panel did.
   Moved to a class so they follow the theme like everything else. */
#modalBox .modalBodyText,
#modalBox .modalBodyText *{
  color: #ffffff !important;
  text-shadow: 1px 1px 0 #1a1610 !important;
  font-size: 10px !important;
}
#modalBox .modalBodyText b{ color: var(--rs2-yellow) !important; }
/* Strengthened outline on the headline body line: uibg.jpg is user-supplied, so
   a single-offset shadow can vanish against a mid-tone tile. */
#modalText{
  text-shadow: 1px 1px 0 #1a1610, -1px 1px 0 #1a1610,
               1px -1px 0 #1a1610, -1px -1px 0 #1a1610 !important;
}

/* ============================================================
   TRANSITIONS
   Nothing in the interface moved: modals, dialogue sheets and the level-up
   panel all snapped between display:none and visible, which is the single
   biggest thing that makes an interface read as unfinished. These are short -
   90-140ms - because RuneScape's UI was snappy, not floaty; the point is to
   remove the hard cut, not to animate for its own sake.
   ============================================================ */
/* Buttons and slots acknowledge the press instead of only the hover. */
.rs-btn, #modalBox button, .bankSlot, .merchRow, .invSlot{
  transition: background-color 90ms ease-out, filter 90ms ease-out, opacity 90ms ease-out;
}
.rs-btn:active:not(:disabled), #modalBox button:active:not(:disabled){
  filter: brightness(0.85);
  transform: translateY(1px);
}
.bankSlot:active, .merchRow:active:not(.cantAfford), .invSlot:active{
  filter: brightness(1.2);
}
/* The compass and run toggle are clickable but gave no press feedback. */
#hudCompass:active{ filter: brightness(1.3); }
#runToggle:active{ filter: brightness(0.85); }
/* Respect a system-level request for reduced motion. */
@media (prefers-reduced-motion: reduce){
  .rs-btn, #modalBox button, .bankSlot, .merchRow, .invSlot{ transition: none !important; }
}

/* --- THE DELVE ------------------------------------------------------------
   Resolve readout, bottom-left of the 3D view above the health panel. Hidden
   entirely in town (delve.js sets display), because a meter sitting at zero is
   noise - it should only ever appear when there is a run to lose. */
#delveHud{
  position: absolute; left: 6px;
  bottom: calc(var(--rs-chat) + var(--rs-bar) + 40px);
  width: 130px; display: none; z-index: 30;
  font-family: 'basic', monospace; pointer-events: none;
  color: #ffd98a; text-shadow: 1px 1px 0 #000;
}
#delveHud .delveTop{ font-size: 10px; letter-spacing: 0.4px; }
#delveHud .delveTop b{ color: #ffb347; font-size: 12px; }
#delveHud .delveBarWrap{
  height: 5px; margin: 2px 0 1px;
  background: #1a1610; border: 1px solid #6a6252;
}
#delveHud .delveBar{ height: 100%; background: linear-gradient(#ffcc66, #d98a1f); }
#delveHud .delveSub{ font-size: 8px; color: #cbbfa2; }

/* --- ADVENTURER RANK BANNER -------------------------------------------------
   A passive, always-on readout (rank-title.js) - total skill level and a
   rank title, nothing more. Sits top-center, clear of the action-text corner
   (left) and the minimap/tab row (right). Kept small - one row of text, a
   thin bar, one caption - so it reads at a glance without competing with the
   viewport for attention. */
#rankBanner{
  position: absolute; top: 4px; left: 50%; transform: translateX(-50%);
  width: 178px; z-index: 32; cursor: pointer;
  background: rgba(10,9,6,0.85);
  border: 1px solid #6a6252;
  box-shadow: inset 0 0 0 1px #17130d, 0 1px 3px rgba(0,0,0,0.6);
  padding: 2px 6px 3px;
  font-family: 'basic', monospace;
  pointer-events: auto;
}
#rankBanner:hover{ border-color: #ffd98a; }
#rankBanner .rkRow{
  display: flex; align-items: baseline; justify-content: center; gap: 5px;
  white-space: nowrap; overflow: hidden;
}
#rankBanner .rkKind{
  font-size: 7px; letter-spacing: 0.5px; text-transform: uppercase;
  color: #a89e8a; flex: none;
}
#rankBanner .rkTitle{
  font-size: 11px; color: #ffd98a; text-shadow: 1px 1px 0 #000;
  line-height: 1.15; overflow: hidden; text-overflow: ellipsis;
  min-width: 0; flex: 1 1 auto;
}
#rankBanner .rkBarWrap{
  height: 4px; margin: 2px 0 1px;
  background: #1a1610; border: 1px solid #6a6252;
}
#rankBanner .rkBar{ height: 100%; background: linear-gradient(#ffcc66, #d98a1f); }
#rankBanner .rkProg{ font-size: 7px; color: #a89e8a; text-align: center; }
/* Max rank gets a gold frame instead of the usual neutral one. */
#rankBanner.rkMaxed{ border-color: #d9a628; }
#rankBanner.rkMaxed .rkTitle{ color: #fff2c0; }


/* ============================================================
   BOTTOM-LEFT HUD STACK - single source of truth
   ------------------------------------------------------------
   Six elements share this column and each had been positioned independently,
   by eye, at whatever moment it was added. Measured, four pairs genuinely
   overlapped - the attack-style buttons sat underneath the hitpoints panel,
   and the delve meter, gear bar and hitpoints panel were all in one another's
   space.

   The cause is that every one of them used a hand-picked `bottom` with no
   knowledge of its neighbours, so each addition silently landed on the last.
   This block replaces all of that with explicit LANES derived from one
   variable each, stacked upward from the top edge of the chat parchment with a
   fixed gutter, so adding another readout later means adding a lane rather
   than guessing an offset again.

   Lane heights are fixed rather than automatic on purpose: an element whose
   content grows (a long slayer task, a three-digit hitpoint value) would
   otherwise silently push into the lane above.
   ============================================================ */
:root{
  --hud-x:      6px;    /* every lane shares one left edge */
  --hud-gutter: 4px;    /* breathing room between lanes */
  --hud-base:   calc(var(--rs-chat) + var(--rs-bar) + 4px);  /* just above the chat */
  /* Attack styles + the special attack bar. 38px, not the 16px this started
     as: that figure was sized for a single row of style buttons, and the spec
     label and bar added two more rows underneath. The lane was never resized,
     so 21px of it hung down over the chat log. Measured content is 37px. */
  --lane-combat: 38px;
  /* --lane-hp is gone with the hitpoints panel: health now shows over the
     player's head in combat and in the skills tab otherwise. */
  --lane-delve:  30px;  /* resolve meter */
  --lane-gear:   14px;
  --lane-slayer: 14px;
}
#combatBarHud,
#delveHud,
#gearBar,
#slayerTracker{
  position: absolute !important;
  left: var(--hud-x) !important;
  right: auto !important;
  top: auto !important;
  z-index: 31 !important;   /* above the chat (20), below the modal layer */
}
/* Lane 1 - attack styles, closest to the chat: it changes most often and is
   the thing you look at mid-fight. */
/* Lane 1 - attack styles and the special attack bar, closest to the chat
   because it is what you watch mid-fight. Its height must match the content:
   see --lane-combat. */
#combatBarHud{
  bottom: var(--hud-base) !important;
  height: var(--lane-combat) !important;
  align-items: center;
}
/* Lane 2 - hitpoints and prayer. */
/* Lane 3 - the delve meter. Hidden in town, but it still owns its lane so the
   lanes above don't shift when a run starts and it appears. */
#delveHud{
  bottom: calc(var(--hud-base) + var(--lane-combat) ) !important;
  height: var(--lane-delve) !important;
  width: 130px !important;
}
/* Lane 4 - gear summary. */
#gearBar{
  bottom: calc(var(--hud-base) + var(--lane-combat) + var(--lane-delve) + var(--hud-gutter)*3) !important;
  height: var(--lane-gear) !important;
  overflow: hidden;
}
/* Lane 5 - slayer task, topmost and least urgent. */
#slayerTracker{
  bottom: calc(var(--hud-base) + var(--lane-combat) + var(--lane-delve) + var(--lane-gear) + var(--hud-gutter)*4) !important;
  height: var(--lane-slayer) !important;
  overflow: hidden;
  white-space: nowrap; text-overflow: ellipsis;
}
/* The hitpoints panel's labels were inline-styled at 13px, which overflowed the
   44px lane on its own. Sized here so the lane maths holds. */

/* The skull's `bottom: 92px` was measured against an older chat height and now
   clips the top of the parchment. Pinned to the same --hud-base as the
   left-hand stack so both sides of the screen sit on one baseline, and so it
   follows automatically if the chat is ever resized. */
#wildernessLevelIndicator{
  bottom: var(--hud-base) !important;
}





/* --- WILDERNESS COMBAT BAR ------------------------------------------------
   Attack styles and the special attack bar, in the lane the strike bar used
   so the bottom-left stack keeps its geometry. */
#combatBarHud{
  width:170px; display:none;
  /* Contains its own overflow. If this ever grows past --lane-combat again it
     will clip inside its own box rather than bleeding down over the chat log -
     a contained failure you can see, instead of one that corrupts a neighbour. */
  overflow:hidden;
  font-family:'basic',monospace; font-size:9px;
  color:#cbbfa2; text-shadow:1px 1px 0 #000; pointer-events:none;
}
#combatBarHud .cbStyles{ display:flex; gap:2px; margin-bottom:2px }
#combatBarHud .cbStyle{
  flex:1 1 0; padding:1px 2px; text-align:center;
  background:rgba(20,17,11,0.75); border:1px solid #4a4438; color:#9a9080;
}
#combatBarHud .cbStyle b{ color:#cbbfa2; margin-right:2px }
#combatBarHud .cbOn{ background:rgba(60,50,30,0.92); border-color:#cbbfa2; color:#ffe9a8 }
#combatBarHud .cbStrong{ color:#7fdc7f; border-color:#7fdc7f }
#combatBarHud .cbWeak{ color:#e08a8a }
#combatBarHud .cbOff{ opacity:0.4 }
#combatBarHud .cbSpecRow{ display:flex; justify-content:space-between; line-height:1 }
#combatBarHud .cbKey{ color:#ffe9a8 }
#combatBarHud .cbSpecWrap{
  position:relative; height:6px; margin-top:2px;
  background:#14110b; border:1px solid #4a4438;
}
#combatBarHud .cbSpec{ height:100%; background:#5a7fa8; transition:width 120ms linear }
/* Turns gold the moment you can actually afford to fire it. */
#combatBarHud .cbReady{ background:#ffcc33 }
/* The notch showing what this weapon's spec costs. */
#combatBarHud .cbSpecMark{
  position:absolute; top:-1px; width:1px; height:8px; background:#cbbfa2;
}

/* --- CONTACT PRESSURE BAR -------------------------------------------------
   Rises while you stand in a creature's reach, falls while you are out. Red at
   the top is the only warning this mechanic needs. Shares the combat lane. */

/* --- SPELLBOOK / PRAYER BOOK GRIDS ----------------------------------------
   Five columns, matching the RS2 books' proportions inside this panel's width.
   Cells below your level stay VISIBLE but dimmed: the greyed-out rows are a
   ladder you can see yourself climbing, which a list of five text rows can
   never convey. */
.bkGrid{
  display:grid; grid-template-columns:repeat(5,1fr);
  gap:1px; padding:2px;
}
.bkCell{
  position:relative; aspect-ratio:1/1;
  display:flex; align-items:center; justify-content:center;
  cursor:pointer; border:1px solid transparent;
}
.bkCell img{ width:88%; height:88%; object-fit:contain; image-rendering:pixelated; }
/* Shown only when the icon file is missing, so the book works with no art. */
.bkCell .bkFallback{
  display:none; position:absolute; inset:2px;
  align-items:center; justify-content:center;
  background:rgba(0,0,0,0.35); border:1px solid #4a4438;
  font-family:'basic',monospace; font-size:8px; color:#cbbfa2;
  text-shadow:1px 1px 0 #000;
}
.bkCell:hover{ background:rgba(255,255,255,0.08); border-color:#6a6252 }
/* Below your level: dimmed and desaturated, but still there. */
.bkLocked{ opacity:0.28; filter:grayscale(1); cursor:default }
.bkLocked:hover{ background:transparent; border-color:transparent }
/* Burning / selected. */
.bkOn{
  background:rgba(255,204,51,0.18);
  border-color:#ffcc33;
  box-shadow:inset 0 0 6px rgba(255,204,51,0.35);
}
.bkFoot{
  display:flex; justify-content:space-between;
  margin-top:3px; padding:2px 4px;
  font-family:'basic',monospace; font-size:9px;
  color:#cbbfa2; text-shadow:1px 1px 0 #000;
  border-top:1px solid #4a4438;
}
.bkFoot b{ color:#ffcc33 }

/* --- PRAYER + MAGIC TABS --------------------------------------------------
   Eight tabs now, not six. Kept to ONE row and the icons shrunk rather than
   wrapping to a second: a second row would push #tabDropdown down 26px and
   invalidate the panel geometry that everything below it is measured against.
   17px is small but it is what the real client used at this resolution. */
/* The one-row, eight-across layout that used to live here is gone - it forced
   17px buttons, and it is superseded by the two-row block further down. */
#tabBtnsRow button .tabIcon{ width:100%; height:100%; display:flex; align-items:center; justify-content:center }
#tabBtnsRow button .tabIcon img{ max-width:100%; max-height:100%; }
/* Letter fallback while the tab art is missing, so no tab is ever blank. */
#tabBtnsRow button .tabIcon.tabNoImg::after{
  content:attr(data-letter);
  font-family:'basic',monospace; font-size:10px; color:#cbbfa2;
  text-shadow:1px 1px 0 #000;
}
/* The panel's top was calculated from --rs-tab (25px), so shrinking the tabs
   would have left an 8px gap between the row and the panel. Locked to the size
   the tabs actually are, so the two can never drift apart again. */
/* (an older #tabDropdown top rule lived here; it referenced --rs-tab-sm,
   which no longer exists. The live one is in the tab-row block below.) */


/* --- WORLD MAP ------------------------------------------------------------
   A full chart of the island, over everything. Deliberately styled like the
   game's own modals - amber title on stone, "Close Window" as plain text - so
   it reads as part of the client rather than a browser overlay. */
#worldMapWrap{
  position:absolute; inset:0; z-index:60;
  display:none; align-items:center; justify-content:center;
  background:rgba(0,0,0,0.72);
}
#worldMapPanel{
  background-color:var(--rs2-panel);
  background-image:url('textures/uibg.jpg');
  background-repeat:repeat;
  border:2px solid var(--rs2-border);
  padding:4px 6px 6px;
}
#worldMapBar{
  position:relative; text-align:center; padding:2px 0 4px;
  font-family:'basic',monospace;
}
#worldMapTitle{
  color:var(--rs2-amber); font-size:13px;
  text-shadow:1px 1px 0 #1a1610,-1px -1px 0 #1a1610;
}
#worldMapClose{
  position:absolute; right:2px; top:2px;
  color:#fff; font-size:10px; cursor:pointer;
  text-shadow:1px 1px 0 #1a1610;
}
#worldMapClose:hover{ color:var(--rs2-yellow) }
#worldMapCanvas{
  display:block; border:1px solid #14110b;
  cursor:grab; image-rendering:pixelated;
}
#worldMapCanvas:active{ cursor:grabbing }
#worldMapInfo{
  display:flex; justify-content:space-between;
  margin-top:3px; padding:2px 4px;
  font-family:'basic',monospace; font-size:10px;
  color:#fff; text-shadow:1px 1px 0 #1a1610;
}
#worldMapInfo b{ color:var(--rs2-amber) }
#worldMapHint{
  text-align:center; margin-top:1px;
  font-family:'basic',monospace; font-size:8px;
  color:#cbbfa2; text-shadow:1px 1px 0 #1a1610;
}

/* ============================================================
   IFRAME CONTAINMENT (appended last, wins)
   ------------------------------------------------------------
   The game is authored to the real 2001 applet size, 512 x 346, and is meant to
   drop straight into an iframe of exactly that. These rules make that a
   guarantee rather than an expectation: nothing may spill outside the frame, no
   scrollbar may ever appear, and no future overlay can quietly grow past the
   edge without being clipped where you can see it.
   ============================================================ */
/* 100% rather than a hard 512x346. In an iframe of exactly that size these are
   identical - but forcing the pixel values would have broken standalone use,
   where the frame is meant to SCALE UP to a larger window via --rsc-zoom. A
   hard-sized body would have clipped the scaled frame instead of showing it. */
html, body{
  width:100%; height:100%;
  margin:0; padding:0;
  overflow:hidden !important;
  background:#000;
}
/* The frame itself. `overflow:hidden` here is the hard stop: an overlay that
   grows past 512x346 gets clipped at the edge instead of producing a scrollbar
   or bleeding outside the embed. */
#page-layout{
  position:relative;
  width:512px; height:346px;
  overflow:hidden;
  margin:0 auto;
}
/* Overlays fall into two groups, and they must be treated differently.

   INSIDE the scaled frame (#worldMapWrap, #modalWrap): fill their parent with
   inset:0 and let the transform scale them along with everything else. No
   pixel size - a fixed 512x346 would fight the parent's own box.

   OUTSIDE it (#login-overlay is a SIBLING of #page-layout, not a child): it has
   to cover the VIEWPORT, because there is no scaled frame around it to fill.
   Giving it absolute + 512x346 pinned it to the top-left of the window at
   unscaled size while the game grew around it - which is exactly what
   fullscreen looked like before login. */
#worldMapWrap, #modalWrap{
  position:absolute !important;
  inset:0 !important;
}
#login-overlay{
  position:fixed !important;
  inset:0 !important;
  width:100% !important; height:100% !important;
  /* Left at the 9999 the original rule sets. #page-layout is transformed, which
     makes it a stacking context, so anything inside it is trapped there - but
     the login screen must sit above the whole page regardless, and there is no
     reason to lower a value that was already correct. */
}
/* Anything that opens over the game must fit inside it, whatever it contains. */
#worldMapPanel, #modalBox{
  max-width:496px !important;
  max-height:330px !important;
  overflow:hidden;
}
/* Long text is the only thing that realistically forces a layout wider - a
   creature name, a chat line, an item label. Wrapping those is enough; a
   blanket rule on every descendant would constrain absolutely-positioned
   overlays against the wrong containing block. */
#log, #npcHint, .tabSub, .iaName, .merchRow .mn,
#modalText, #modalTitle, #worldMapInfo{
  overflow-wrap:break-word; word-break:normal;
}

/* --- CENTRING THE SCALED FRAME --------------------------------------------
   #page-layout scales from its own centre (transform-origin: center center),
   and `margin: 0 auto` only centres it HORIZONTALLY. Sitting at the top of the
   page, a 3x scale therefore threw the upper half off the top of the screen -
   in a 1920x1080 fullscreen the frame landed at y -346 to 692, cutting off
   everything above the chat.

   Making the body a centring flex container fixes it for every zoom at once:
   the box sits in the middle of the viewport before it scales, so it grows
   evenly in all four directions and letterboxes cleanly. */
body{
  display:flex !important;
  align-items:center;
  justify-content:center;
}
#page-layout{
  margin:0 !important;
  flex:0 0 auto;
}

/* ============================================================
   TAB ROW + PANEL - single source of truth (appended last, wins)
   ------------------------------------------------------------
   These two overlapped by 12px because their positions were computed from
   DIFFERENT things: the row's top was a hardcoded `--rs-mini + 22px`, while the
   panel's top was `--rs-mini + <tab size> + 10px`. Shrinking the tabs to fit
   eight across therefore moved the panel UP without moving the row, and the
   panel's heading rendered underneath the buttons.

   Everything below is derived from three variables, so the row and the panel
   can no longer disagree. Change --rs-tab-big and both follow.

   Eight tabs across a 156px column meant 17px buttons, which were too small to
   read. Two rows fixed that.
   
   It is THREE across now, not four. There are six tabs left - quests went, and
   prayer folded into the spellbook - and six into four rows as 4 + 2, which
   looks like a row that ran out rather than a designed block. Three and three
   is even, and it makes each button wider into the bargain.
   ============================================================ */
:root{
  --rs-tab-big:  30px;   /* button size */
  --rs-tab-gap:   1px;
  --rs-tab-top:  calc(var(--rs-mini) + 5px);                                   /* row starts here */
  --rs-tab-rows: calc(var(--rs-tab-big) * 2 + var(--rs-tab-gap));              /* two rows tall */
}
/* The row spans the FULL column, exactly like the panel beneath it. Fixed-width
   columns left the tabs 123px wide in a 156px column, so a third of the column
   sat empty on the left and the row didn't line up with the panel's edge.
   1fr columns divide whatever the column is, so the two always agree. */
#tabBtnsRow{
  top: var(--rs-tab-top) !important;
  right: 3px !important;
  left: auto !important;
  display: grid !important;
  grid-template-columns: repeat(3, 1fr) !important;   /* 3 on top, 3 on the bottom */
  gap: var(--rs-tab-gap) !important;
  width: var(--rs-col) !important;
  height: var(--rs-tab-rows) !important;
}
/* Buttons fill their cell rather than being sized themselves, so the row stays
   flush whatever the column width is. */
#tabBtnsRow button{
  width: 100% !important;
  height: var(--rs-tab-big) !important;
  padding: 0 !important;
}
#tabBtnsRow button .tabIcon{
  width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
}
/* `object-fit: cover` CROPS to fill its box - fine when the button was square,
   but the cells are 38x30 now, so it was cutting the top and bottom off every
   icon. `contain` letterboxes instead, so the whole icon is visible whatever
   shape the cell is. All three need !important because an earlier rule sets
   width/height/object-fit with !important and would otherwise win. */
#tabBtnsRow button .tabIcon img,
#tabBtnsRow button > img{
  width: auto !important;
  height: auto !important;
  max-width: 84% !important;
  max-height: 84% !important;
  object-fit: contain !important;
  display: block;
}
/* The panel begins BELOW the row, measured from the row itself rather than from
   a separate guess at the tab size. This is the line that was wrong. */
#tabDropdown{
  /* No gap: the tabs sit directly ON the panel in the real client, and a 4px
     strip of background between them read as a seam. */
  top: calc(var(--rs-tab-top) + var(--rs-tab-rows)) !important;
}

/* --- IMAGES MUST NOT CROP -------------------------------------------------
   Any rule that forces both width and height on an <img> will squash or crop it
   unless object-fit says otherwise. The tab icons were being cropped by an
   `object-fit: cover`; these are the others that forced both dimensions with no
   object-fit at all, which stretches a non-square source to fit.

   `contain` on all of them: the whole image is always visible and its aspect
   ratio is preserved, whatever shape the box is. The login slideshow keeps
   `cover` on purpose - a background is meant to fill its frame. */
.mIcon img,
.merchRow .mIcon img,
#hudCompass img,
#levelUpPanel .luIcon img,
#npcDialoguePanel .npcHead img{
  object-fit: contain;
}

/* --- BOTTOM BAR ------------------------------------------------------------
   The cosmetic chat filters are gone - there is nobody else to filter or report
   in a single-player game - and the sound toggle has taken their place. It used
   to be a floating cluster overlapping the bottom-right corner of the side
   panel; living in the bar it has nothing to collide with.

   With the mute cluster gone the panel can also reach its full height again. */
#tabDropdown{ bottom: calc(var(--rs-bar) + 3px) !important; }

.rsc-tabs #soundToggle{
  display:inline-flex; align-items:center; gap:5px;
  cursor:pointer; user-select:none;
}
.rsc-tabs #soundToggle:hover{ filter:brightness(1.3) }
.rsc-tabs #soundToggle img{
  width:12px; height:12px; object-fit:contain;
  image-rendering:pixelated; vertical-align:middle;
}
.rsc-tabs .off{ color:#d64b2a }

/* ============================================================
   SMITHING / CRAFTING WINDOWS  (2004 style)
   ------------------------------------------------------------
   These were borrowing the merchant's grid, which hides .md - and .md is where
   the ore requirements live, so the smelting window could not tell you what
   anything needed. They have their own class now.

   Laid out as the 2004 client laid out a making-interface: a vertical list of
   rows, each an icon, a name, and what it costs you, with a hard rule between
   them. Not a modern card grid - the row IS the unit, and you read straight
   down it. What you cannot make yet stays visible and dims, because the list
   doubles as the thing that tells you what to work toward.
   ============================================================ */
.craftList{
  background: var(--rs2-panel-dark);
  border: 1px solid var(--rs2-border);
  max-height: 176px; overflow-y: auto;
}
.craftRow{
  display: flex; align-items: center; gap: 7px;
  padding: 3px 5px;
  border-bottom: 1px solid rgba(0,0,0,0.45);
  cursor: default;
}
.craftRow:last-child{ border-bottom: none }
.craftRow:nth-child(even){ background: rgba(255,255,255,0.035) }
.craftRow:hover{ background: rgba(255,204,51,0.10) }

.craftRow .mIcon{
  flex: 0 0 34px; height: 34px;
  display: flex; align-items: center; justify-content: center;
}
.craftRow .mIcon img{
  max-width: 32px !important; max-height: 32px !important;
  width: auto !important; height: auto !important;
  object-fit: contain !important;
  image-rendering: pixelated;
}
.craftRow .mi{ flex: 1 1 auto; min-width: 0; line-height: 1.25 }
/* Name in amber, the way every heading in this interface is. */
.craftRow .mn{
  font-size: 11px !important; color: var(--rs2-amber) !important;
  text-shadow: 1px 1px 0 #1a1610;
}
/* What it costs. Shown - this is the line the shop grid was hiding. */
.craftRow .md{
  display: block !important;
  font-size: 9px !important; color: #ffffff !important;
  text-shadow: 1px 1px 0 #1a1610;
  overflow-wrap: break-word;
}
/* Experience, in the yellow this interface uses for every number. */
.craftRow .mc{
  position: static !important;
  font-size: 9px !important; color: var(--rs2-yellow) !important;
  text-shadow: 1px 1px 0 #1a1610;
}
.craftRow > .rs-btn{
  display: inline-block !important;
  flex: 0 0 auto; align-self: center;
  font-size: 9px !important; padding: 2px 8px !important;
}
/* Too low a level, or not enough ore: dimmed but still listed, so the window
   shows you the whole ladder rather than only the rung you are on. */
.craftRow:has(.rs-btn:disabled){ opacity: 0.45 }
.craftRow.equipped{
  background: rgba(255,204,51,0.16);
  box-shadow: inset 2px 0 0 var(--rs2-yellow);
}

/* Tab strip inside the smithing window (Smelt Bars / Craft Gear) and the
   equipment-slot picker. Flat stone tabs sitting ON the list, as the client
   drew them - not pill buttons floating above it. */
.villagerTabs{
  display:flex; gap:1px; margin-bottom:0;
}
.villagerTabs .rs-btn{
  flex:1 1 0;
  font-size:10px !important; padding:3px 0 !important;
  background:var(--rs2-panel-dark) !important;
  border:1px solid var(--rs2-border) !important;
  border-bottom:none !important;
  color:#cbbfa2 !important;
  box-shadow:none !important;
}
.villagerTabs .rs-btn.active{
  background:var(--rs2-panel) !important;
  color:var(--rs2-amber) !important;
  text-shadow:1px 1px 0 #1a1610;
}
.villagerTabs .rs-btn:hover{ filter:brightness(1.2) }
/* The blurb above the list: white, small, and out of the way of the amber
   heading rather than competing with it. */
#modalText{ font-size:9px !important; line-height:1.3 !important; }

/* ============================================================
   SKILLS GRID  (OSRS stats panel)
   ------------------------------------------------------------
   Three columns of cells, each an icon beside a current/maximum pair split by
   a diagonal rule, then a four-figure footer. The old panel was two columns of
   "Attack: 5/5" text rows - readable, but you had to read it. A grid of icons
   is scannable: your eye lands on the skill you want without parsing words.
   ============================================================ */
.skGrid{
  display:grid; grid-template-columns:repeat(3,1fr);
  gap:1px; padding:1px;
}
.skCell{
  position:relative;
  display:flex; align-items:center; gap:2px;
  height:22px; padding:0 2px;
  background:var(--rs2-panel-dark);
  border:1px solid var(--rs2-border);
  font-family:'basic',monospace;
  cursor:default;
}
/* Skills this game does not simulate yet: shown so the panel keeps the shape
   of the real thing, but dimmed so they cannot be mistaken for trainable. */
.skDim{ opacity:0.35 }
.skCell .skIcon{
  flex:0 0 15px; height:15px;
  display:flex; align-items:center; justify-content:center;
}
.skCell .skIcon img{
  max-width:15px; max-height:15px;
  width:auto; height:auto; object-fit:contain;
  image-rendering:pixelated;
}
/* Fallback initials, shown only when the icon file is absent. */
.skCell .skIcon i{ display:none; font-style:normal; font-size:7px; color:#cbbfa2 }
.skCell .skIcon.skNoImg i{ display:block }

/* The current/maximum pair. The diagonal is what makes the OSRS cell read at a
   glance - two numbers stacked with a rule between them, rather than "5/5" in
   a line you have to parse. */
.skCell .skNums{
  position:relative; flex:1 1 auto; height:100%;
}
.skCell .skNums b,
.skCell .skNums em{
  position:absolute; font-style:normal; font-weight:normal;
  font-size:9px; color:var(--rs2-yellow);
  text-shadow:1px 1px 0 #000;
}
.skCell .skNums b { top:1px;  left:4px; }    /* current */
.skCell .skNums em{ bottom:1px; right:2px; } /* maximum */
.skCell .skNums::after{
  content:''; position:absolute;
  left:2px; right:2px; top:50%;
  height:1px; background:#cbbfa2;
  transform:rotate(-24deg);
  opacity:0.65;
}
.skFoot{
  display:grid; grid-template-columns:1fr 1fr;
  gap:0 4px; margin-top:2px; padding:2px 4px;
  background:var(--rs2-panel-dark);
  border:1px solid var(--rs2-border);
  font-family:'basic',monospace; font-size:9px;
  color:#cbbfa2; text-shadow:1px 1px 0 #000;
}
.skFoot b{ color:var(--rs2-yellow) }

/* ============================================================
   RUN TOGGLE — DEDICATED BAND (appended last, wins)
   ------------------------------------------------------------
   The run toggle sat at `--rs-mini + 4px` while the tab row sat at
   `--rs-mini + 5px`, so the pill had no band of its own: it was pinned to the
   bottom edge of the round minimap and its ~17px body dropped straight onto
   the first row of tabs. Reading as "the minimap is on top of the run button."

   Fix: carve out a real strip between the minimap and the tabs. The run toggle
   gets a fixed height and lives in that strip; the tab row (and the panel,
   which is measured from --rs-tab-top) both shift down by exactly the strip
   height, so nothing else has to be touched and nothing can overlap again.
   ============================================================ */
:root{
  --rs-run-h:   15px;                                  /* run toggle body height */
  --rs-run-gap:  3px;                                  /* clearance above + below it */
  /* Tabs now start below the minimap AND the run strip. Overrides the earlier
     --rs-tab-top; the panel derives from this var so it follows automatically. */
  --rs-tab-top: calc(var(--rs-mini) + var(--rs-run-gap) + var(--rs-run-h) + var(--rs-run-gap));
}
#runToggle{
  /* Just below the minimap, inside its own strip. */
  top: calc(var(--rs-mini) + var(--rs-run-gap)) !important;
  height: var(--rs-run-h) !important;
  box-sizing: border-box !important;
  padding: 0 6px !important;
  justify-content: center !important;
  /* Centred on the minimap's centre line instead of clinging to its right edge,
     so the lone pill reads as an intentional row rather than a stray tag. */
  left: auto !important;
  right: calc((var(--rs-col) - var(--rs-mini))/2 + 3px + var(--rs-mini)/2) !important;
  transform: translateX(50%) !important;
}
#runToggle:active{ transform: translateX(50%) !important; filter: brightness(0.85); }

/* Progressive tab-unlock styles removed - every sidebar tab is available
   from the start. */

/* ============================================================
   FIRST-PERSON + SURVIVAL TRIAL HUD (fps-mode.js / wave-survival.js)
   ============================================================ */
/* Dead-centre crosshair, shown only while the mouse is captured. */
#fpsCrosshair{
  position: absolute; top: 50%; left: 50%;
  width: 3px; height: 3px; margin: -1.5px 0 0 -1.5px;
  z-index: 40; pointer-events: none;
  background: rgba(255,255,255,0.85);
  border-radius: 50%;
  box-shadow: 0 0 0 1px rgba(0,0,0,0.6),
              0 -7px 0 -1px rgba(255,255,255,0.7), 0 7px 0 -1px rgba(255,255,255,0.7),
              -7px 0 0 -1px rgba(255,255,255,0.7), 7px 0 0 -1px rgba(255,255,255,0.7);
}
/* "Click to look" prompt when first-person is on but the mouse is free. */
#fpsLockHint{
  position: absolute; bottom: 6px; left: 50%; transform: translateX(-50%);
  z-index: 40; pointer-events: none;
  padding: 4px 10px;
  font-family: 'basic', monospace; font-size: 9px; color: #f0e6cc;
  background: rgba(10,8,5,0.72); border: 1px solid #14110b; border-radius: 3px;
  text-shadow: 1px 1px 0 #000; white-space: nowrap;
}


/* ===========================================================================
   HUB OVERLAY (hub-menu.js)  —  RuneScape 2 beta main-menu skin
   ---------------------------------------------------------------------------
   Skinned after the 2004 RuneScape 2 beta interface: the whole board sits in a
   WOOD-GRAIN frame (border-image from the bundle's own textures/wood.jpg) over
   a dark-brown interior, with the RS2 ORANGE (#ff9040) headers, CREAM body
   text and 1px black shadows the era rendered its font with. The clickable
   sub-panels - menu tiles, bounty cards, the contract notice, shop rows - are
   PARCHMENT (textures/parchment.jpg) with dark ink text, the way RS2 pinned
   notices and journal pages inside its wooden panels, each framed by a raised
   dark-wood bevel that inverts on :active so it presses in when clicked.

   Only the LOOK changes - every size, grid, max-height and the 420px stacking
   breakpoint carry over untouched - so the markup in playgame.html and the
   logic in hub-menu.js need no edits. Texture URLs are relative to THIS file
   (styling.css lives beside the textures/ folder), so they resolve the same
   way in-game as the rest of the stylesheet's assets.

   Positioned exactly like #login-overlay: a FIXED, full-viewport sibling of
   #page-layout, outside the 512x346 scaled-frame rules. #hubReopenBtn and
   #contractHud are fixed the same way (and, being siblings of #hub-overlay
   rather than children, spell their colours out literally rather than
   inheriting the --rs2m-* custom properties defined on the overlay).
   =========================================================================== */
#hub-overlay{
  position: fixed; top: 0; left: 0; width: 100%; height: 100%;
  background: #0d0a06;
  display: flex; align-items: center; justify-content: center;
  z-index: 9998; /* just under #login-overlay's 9999 - the two never show together */
  font-family: 'basic', monospace;

  /* RS2 beta palette. Scoped to the overlay so every descendant (including the
     shop's shared .merchRow rows) inherits it. */
  --rs2m-parch:  #e8dc99;   /* parchment ink-panel fill (falls back if img fails) */
  --rs2m-wood-hi:#8a6a34;   /* wood bevel highlight (top-left)                    */
  --rs2m-wood-lo:#1a1108;   /* wood bevel shadow    (bottom-right)                */
  --rs2m-ink:    #2c1a0a;   /* dark ink text on parchment                         */
  --rs2m-ink2:   #57401f;   /* lighter ink / descriptions on parchment            */
  --rs2m-link:   #123a8f;   /* RS2 journal "click here" blue on parchment         */
  --rs2m-well:   #140d06;   /* recessed icon slot                                 */
  --rs2m-orange: #ff9040;   /* RS2 header orange                                  */
  --rs2m-yellow: #ffff00;
  --rs2m-cream:  #e8dcc0;
  --rs2m-green:  #3fbf3f;
  --rs2m-red:    #a11f1f;
}

/* The board: a wooden-framed panel over a dark-brown interior. */
.hub-panel{
  width: min(92%, 480px);
  max-height: 90vh;
  overflow-y: auto;
  background: linear-gradient(#251a0e, #160f07);
  border: 16px solid #2a1d0f;
  border-image: url('textures/wood.jpg') 60 round;
  box-shadow: inset 0 0 0 2px #140d05, 0 0 0 2px #0d0a06, 0 6px 26px rgba(0,0,0,0.7);
  padding: 14px 16px 16px;
  color: var(--rs2m-cream);
  text-shadow: 1px 1px 0 #000;
}
.hub-titlebar{ display: flex; align-items: center; justify-content: center; gap: 10px; margin-bottom: 4px; }
.hub-crest{ width: 26px; height: 26px; image-rendering: pixelated; }
.hub-title{ font-size: clamp(20px, 5vw, 28px); color: var(--rs2m-orange); text-shadow: 2px 2px 0 #000; letter-spacing: 1px; }
/* Carved groove dividers: dark line with a warm-tan glint beneath. */
.hub-substatus{
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 11px; color: var(--rs2m-cream);
  border-bottom: 2px solid #140d05; box-shadow: 0 1px 0 #6b5228;
  padding-bottom: 8px; margin-bottom: 10px;
}
.hub-rankline{ color: var(--rs2m-yellow); }

.hub-screen.hidden{ display: none !important; }
.hub-screen-head{
  display: flex; align-items: center; justify-content: space-between;
  border-bottom: 2px solid #140d05; box-shadow: 0 1px 0 #6b5228;
  padding-bottom: 6px; margin-bottom: 8px;
}
.hub-screen-title{ font-size: 16px; color: var(--rs2m-orange); text-shadow: 1px 1px 0 #000; }
.hub-screen-sub{ font-size: 11px; color: var(--rs2m-cream); margin-bottom: 8px; }

/* --- Main menu tiles: parchment notices with a raised dark-wood bevel --- */
.hub-tilegrid{ display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
@media (max-width: 420px){ .hub-tilegrid{ grid-template-columns: 1fr; } }
.hub-tile{
  display: flex; gap: 10px; align-items: flex-start;
  background: var(--rs2m-parch) url('textures/parchment.jpg'); background-size: cover;
  border: 2px solid #140d05;
  box-shadow: inset 2px 2px 0 var(--rs2m-wood-hi), inset -2px -2px 0 var(--rs2m-wood-lo);
  padding: 10px; cursor: pointer;
  text-shadow: none;
}
.hub-tile:hover{ filter: brightness(1.06); }
.hub-tile:active{ box-shadow: inset -2px -2px 0 var(--rs2m-wood-hi), inset 2px 2px 0 var(--rs2m-wood-lo); }
/* Icon slot: a recessed dark well so the light sprites still read on parchment. */
.hub-tile-icon{
  width: 40px; height: 40px; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: var(--rs2m-well); border: 2px solid #140d05;
  box-shadow: inset 2px 2px 0 #000, inset -2px -2px 0 #4a3921;
}
.hub-tile-icon img{ width: 100%; height: 100%; object-fit: contain; image-rendering: pixelated; }
.hub-tile-title{ color: var(--rs2m-ink); font-size: 13px; font-weight: bold; margin-bottom: 2px; }
.hub-tile-desc{ font-size: 10px; color: var(--rs2m-ink2); line-height: 1.3; margin-bottom: 4px; }
.hub-tile-link{ font-size: 10px; color: var(--rs2m-link); font-weight: bold; }
.hub-footer-row{ display: flex; justify-content: flex-end; gap: 10px; margin-top: 12px; }

/* --- Bounty Board grid: smaller parchment notices --- */
.hub-bounty-grid{
  display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: 8px;
  max-height: 56vh; overflow-y: auto; padding-right: 2px;
}
.hub-bounty-card{
  display: flex; flex-direction: column; align-items: center; text-align: center; gap: 3px;
  background: var(--rs2m-parch) url('textures/parchment.jpg'); background-size: cover;
  border: 2px solid #140d05;
  box-shadow: inset 2px 2px 0 var(--rs2m-wood-hi), inset -2px -2px 0 var(--rs2m-wood-lo);
  padding: 8px 4px; cursor: pointer; text-shadow: none;
}
.hub-bounty-card:hover{ filter: brightness(1.06); }
.hub-bounty-card:active{ box-shadow: inset -2px -2px 0 var(--rs2m-wood-hi), inset 2px 2px 0 var(--rs2m-wood-lo); }
.hub-bounty-card.locked{ opacity: 0.5; cursor: default; filter: grayscale(0.5); }
.hub-bounty-card.locked:hover{ filter: grayscale(0.5); }
.hbc-icon{ width: 32px; height: 32px; display: flex; align-items: center; justify-content: center;
  background: var(--rs2m-well); border: 1px solid #140d05; }
.hbc-icon img{ max-width: 100%; max-height: 100%; image-rendering: pixelated; }
.hbc-name{ font-size: 9px; color: var(--rs2m-ink); text-transform: capitalize; font-weight: bold; }
.hbc-level{ font-size: 8px; color: var(--rs2m-ink2); }
.hbc-lock{ font-size: 8px; color: var(--rs2m-red); }
.hbc-link{ font-size: 8px; color: var(--rs2m-link); font-weight: bold; }

/* --- Contract confirm: a pinned parchment notice --- */
.hub-contract-card{
  background: var(--rs2m-parch) url('textures/parchment.jpg'); background-size: cover;
  border: 2px solid #140d05;
  box-shadow: inset 2px 2px 0 var(--rs2m-wood-hi), inset -2px -2px 0 var(--rs2m-wood-lo);
  padding: 10px; text-shadow: none;
}
.cc-target{ display: flex; align-items: center; gap: 10px; padding-bottom: 8px; border-bottom: 2px solid #8a6a34; margin-bottom: 8px; }
.cc-target img{ width: 40px; height: 40px; object-fit: contain; image-rendering: pixelated;
  background: var(--rs2m-well); border: 2px solid #140d05; }
.cc-name{ font-size: 13px; color: var(--rs2m-ink); text-transform: capitalize; font-weight: bold; }
.cc-lvl{ font-size: 10px; color: var(--rs2m-ink2); }
.cc-count{ font-size: 10px; color: var(--rs2m-ink2); }
.cc-mod{ margin-bottom: 8px; }
.cc-mod-name{ font-size: 12px; color: #9a3b12; font-weight: bold; }
.cc-mod-desc{ font-size: 10px; color: var(--rs2m-ink2); }
.cc-rewards{ font-size: 10px; color: #1d6a1d; display: flex; flex-direction: column; gap: 2px; font-weight: bold; }

/* --- Shop: the shared .merchRow rows, reskinned to parchment strips --- */
.hub-shoplist{ max-height: 50vh; overflow-y: auto; }
.hub-shoplist .merchRow{
  background: var(--rs2m-parch) url('textures/parchment.jpg') !important; background-size: cover !important;
  border: 2px solid #140d05 !important;
  box-shadow: inset 1px 1px 0 var(--rs2m-wood-hi), inset -1px -1px 0 var(--rs2m-wood-lo);
  margin-bottom: 6px; text-shadow: none;
}
.hub-shoplist .merchRow:nth-child(even){ background: var(--rs2m-parch) url('textures/parchment.jpg') !important; }
.hub-shoplist .merchRow:hover{ filter: brightness(1.06); }
.hub-shoplist .merchRow:active:not(.cantAfford){ box-shadow: inset -1px -1px 0 var(--rs2m-wood-hi), inset 1px 1px 0 var(--rs2m-wood-lo); }
.hub-shoplist .merchRow.cantAfford{ filter: grayscale(0.5); }
.hub-shoplist .merchRow .mn{ color: var(--rs2m-ink) !important; text-shadow: none !important; }
.hub-shoplist .merchRow .mc{ color: #1d6a1d !important; text-shadow: none !important; font-weight: bold; }

/* --- Rankings: engraved rows on the dark board, RS2 orange names --- */
.hub-rankings-list{ display: flex; flex-direction: column; max-height: 56vh; overflow-y: auto; }
.hub-rank-row{
  display: grid; grid-template-columns: 28px 1fr 100px 60px 50px; gap: 6px; align-items: center;
  font-size: 10px; padding: 4px 4px;
  border-bottom: 1px solid #140d05; box-shadow: 0 1px 0 rgba(139,106,52,0.4);
  color: var(--rs2m-cream);
}
.hub-rank-row.me{ background: rgba(255,144,64,0.16); }
.hrPos{ color: var(--rs2m-cream); }
.hrName{ color: var(--rs2m-orange); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hrTitle{ color: var(--rs2m-cream); }
.hrTotal{ color: var(--rs2m-yellow); text-align: right; }
.hrGold{ color: var(--rs2m-green); text-align: right; }
.hub-rank-empty{ font-size: 11px; color: var(--rs2m-cream); padding: 10px 0; }

/* Hub buttons: wooden RS2 versions of the shared login button, scoped to the
   hub so the login screen's blue-grey .rsc-classic-btn is left untouched. */
#hub-overlay .rsc-classic-btn{
  background: #4a3921 url('textures/wood.jpg'); background-size: cover;
  border: 2px solid #140d05; color: var(--rs2m-cream);
  box-shadow: inset 2px 2px 0 #8a6a34, inset -2px -2px 0 #1a1108;
  text-shadow: 1px 1px 0 #000;
}
#hub-overlay .rsc-classic-btn:hover{ filter: brightness(1.08); }
#hub-overlay .rsc-classic-btn:active{ box-shadow: inset -2px -2px 0 #8a6a34, inset 2px 2px 0 #1a1108; }
.rsc-classic-btn.small{ min-width: auto; padding: 4px 10px; font-size: 11px; }

/* --- Reopen button + contract tracker: fixed, viewport-relative overlays.
   Siblings of #hub-overlay, so the RS2 wood colours are written literally
   here rather than pulled from the --rs2m-* custom properties. --- */
#hubReopenBtn{
  position: fixed; top: 8px; left: 8px; z-index: 40;
  display: none; align-items: center; justify-content: center;
  background: #4a3921 url('textures/wood.jpg'); background-size: cover;
  border: 2px solid #140d05; color: #e8dcc0;
  font-family: 'basic', monospace; font-size: 11px;
  padding: 4px 10px; cursor: pointer; text-shadow: 1px 1px 0 #000;
  box-shadow: inset 2px 2px 0 #8a6a34, inset -2px -2px 0 #1a1108;
}
#hubReopenBtn:hover{ filter: brightness(1.08); }
#hubReopenBtn:active{ box-shadow: inset -2px -2px 0 #8a6a34, inset 2px 2px 0 #1a1108; }
#contractHud{
  position: fixed; top: 40px; left: 8px; z-index: 39; display: none;
  width: 170px; font-family: 'basic', monospace;
  background: linear-gradient(#251a0e, #160f07); border: 2px solid #140d05;
  box-shadow: inset 2px 2px 0 #6b5228, inset -2px -2px 0 #140d05;
  padding: 4px 8px 5px; color: #ffb000; text-shadow: 1px 1px 0 #000;
}
#contractHud .chTop{ font-size: 10px; letter-spacing: 0.3px; color: #ff9040; }
#contractHud .chSub{ font-size: 9px; color: #e8dcc0; }

/* ===========================================================================
   POINT-AND-CLICK CONTROLS
   The camera pad and the shield replace the arrow keys and Space. Both are
   styled from the same stone-and-bevel parts as #runToggle so they read as
   part of the client rather than bolted on.
   =========================================================================== */
/* Moved up into the run strip, beside the run toggle.
   It used to sit at minimap + 86px, which was fine when the tab row was one
   line - but the row is two rows tall (61px), so the panel below now begins at
   minimap + 82px and the shield button was floating on top of the panel's
   contents. The run strip is the only band in this column not already spoken
   for, and a toggle belongs next to the other toggle anyway. */
#shieldToggle{
  position: absolute;
  top: calc(var(--rs-mini) + var(--rs-run-gap)) !important;
  height: var(--rs-run-h) !important;
  box-sizing: border-box !important;
  /* Hard right of the column. The run toggle is centred on the minimap, so the
     two share the strip without meeting. */
  left: auto !important;
  right: 3px !important;
  display: flex; align-items: center; justify-content: center; gap: 2px;
  padding: 0 4px;
  font-family: 'basic', monospace; font-size: 9px;
  color: #e8dfc8;
  background: var(--rs-tint), url('textures/stone2.jpg');
  background-size: 48px 48px;
  border: 1px solid #14110b;
  box-shadow: inset 1px 1px 0 #7a725e, inset -1px -1px 0 #322e28;
  cursor: pointer; z-index: 35; user-select: none;
}
#shieldToggle #shieldIcon{ color: #6b6353; font-size: 10px; }
#shieldToggle.up{ box-shadow: inset -1px -1px 0 #7a725e, inset 1px 1px 0 #322e28; }
#shieldToggle.up #shieldIcon{ color: #8fd0ff; }
#shieldToggle.up #shieldText{ color: #8fd0ff; }
/* No shield equipped: the block does nothing, so say so rather than lie. */
#shieldToggle.noShield{ opacity: .5; cursor: default; }
#shieldToggle:hover{ filter: brightness(1.25); }

/* The weapon chips in the combat HUD are the control for switching weapon now,
   so they have to look pressable. */
.cbStyle{ cursor: pointer; }
.cbStyle:hover{ filter: brightness(1.35); }
.cbStyle:focus-visible{ outline: 1px solid var(--gold); outline-offset: 1px; }
.cbStyle.cbOff{ cursor: default; }
.cbStyle.cbOff:hover{ filter: none; }

/* Active home-cooking buffs, under the weapon chips in the combat HUD. */
.cbFed{
  font-family: 'basic', monospace; font-size: 10px;
  color: #9fe89f; margin-top: 2px;
  text-shadow: 1px 1px 0 #000;
}

/* ===========================================================================
   YOUR DUNGEON panel
   A vertical list of rooms: details on the left, Build/Upgrade on the right.
   This deliberately does NOT reuse .merchList/.merchRow - that pair is a
   six-column grid of shop icons with the price absolutely positioned over the
   picture, which turned this list into overlapping columns of text.
   =========================================================================== */
.dgnList, .cookList{
  display: flex;
  flex-direction: column;
  gap: 3px;
  text-align: left;
  padding: 3px;
  background: var(--rs2-panel-dark);
  border: 1px solid var(--rs2-border);
}
.dgnRow, .cookRow{
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 6px;
  background: rgba(0,0,0,0.18);
  border: 1px solid #14110b;
  box-shadow: inset 1px 1px 0 rgba(122,114,94,0.35);
}
.dgnRow:hover, .cookRow:hover{ background: rgba(255,255,255,0.06); }
/* min-width:0 lets the text column shrink instead of forcing the row wider than
   the modal, which is what pushes a flex child out past its container. */
.dgnInfo{ flex: 1 1 auto; min-width: 0; }
.dgnName{
  font-family: 'basic', monospace;
  color: var(--rs2-amber);
  font-size: 12px;
  line-height: 1.25;
}
.dgnLv{ color: #ffcc66; }
.dgnBlurb{
  color: #cfc6ae;
  font-size: 10px;
  line-height: 1.3;
  margin: 2px 0 0;
}
.dgnGives{
  color: #9fd89f;
  font-size: 10px;
  line-height: 1.3;
  margin: 2px 0 0;
}
.dgnCost{
  color: var(--rs2-yellow);
  font-size: 10px;
  line-height: 1.3;
  margin: 1px 0 0;
  text-shadow: 1px 1px 0 #000;
}
.dgnBtn{
  flex: 0 0 auto;
  align-self: center;
  min-width: 62px;
}
.dgnBtn:disabled{ opacity: 0.45; cursor: default; }

/* The panel is taller than the shop grid it replaced, so give the modal room
   to breathe before #modalBodyScroll starts scrolling. */
#modalBox:has(.dgnList){ width: 470px; }

/* The kitchen list is the same list-of-rows shape as the dungeon panel, with a
   food icon in front. Same reason for existing: it was also built on .merchList,
   so its recipes were being forced into the shop's six-column icon grid with the
   "Needs:" line absolutely positioned on top of the picture. */
.cookRow .mIcon{
  flex: 0 0 auto;
  width: 40px;
  display: flex; align-items: center; justify-content: center;
}
.cookRow .mIcon img{ max-height: 36px; width: auto; object-fit: contain; }

/* Plain block wrapper for the admin console - it styles its own children inline. */
.adminConsoleWrap{ text-align: left; }

/* Section headings inside the combined Spellbook tab, so the two grids read as
   two lists rather than one long run of icons. */
.bkSection{
  font-family: 'basic', monospace;
  font-size: 11px;
  letter-spacing: .06em;
  color: var(--rs2-amber);
  text-transform: uppercase;
  padding: 6px 4px 3px;
  border-bottom: 1px solid var(--rs2-border);
  margin-bottom: 4px;
}
.bkSection:not(:first-child){ margin-top: 10px; }

/* Item icon in a shop row, in front of the name and price. */
.shopIcon{
  flex: 0 0 auto;
  width: 30px; height: 30px;
  display: flex; align-items: center; justify-content: center;
}
.shopIcon img{
  max-width: 26px; max-height: 26px;
  object-fit: contain;
  image-rendering: pixelated;
}
