/* ==========================================================================
   NoBS OSRS — stylesheet
   Palette is built off the game's own interface: bistre-warm charcoal for the
   reading surface, RuneScape gold as the single accent, jade for "ready",
   and blood red reserved exclusively for the Wilderness (where you can
   actually lose your items). Colour carries information, not decoration.
   ========================================================================== */

:root{
  /* Where the top-right buttons start, below the header. Below 1280px the
     title row stacks, 98px, plus the page's 18px of padding. */
  --actions-top:116px;
  /* Quick setup: the height above and below its two rows of pictures. Here,
     at the top, so the width-specific values further down can override it.
     Below 1280px the title row stacks: 174px down to the gear chart, plus
     the 12px gap between the rows and 14px under the bottom one. */
  --qs-chrome:200px;
  /* surfaces — warm, not blue-black */
  --ink:#14110d;
  --surface:#1b1712;
  --raised:#241f18;
  --hover:#2e281e;
  --active:#3a3223;
  --line:#3b3325;
  --line-soft:#2a241b;

  /* text */
  --text:#f0e8d8;
  --text-2:#b3a48c;
  --text-3:#8b7d69;

  /* accents */
  --gold:#e8ab35;
  --gold-dim:#8a6620;
  --gold-soft:rgba(232,171,53,.12);
  --jade:#74b45c;
  --jade-soft:rgba(116,180,92,.12);
  --blood:#d4544a;
  --blood-dim:#6b2c28;
  --blood-soft:rgba(212,84,74,.12);
  /* Solid fill for step one. The regular blood red measures 4.1:1 behind white
     text — short of 4.5 — so the button sits a shade deeper. */
  --blood-deep:#b3372d;
  /* The height kept free around the Full guide player: header, title, tabs
     and the closed description box. The player takes whatever is left, so the
     description can be read without scrolling. See .guide-grid. */
  --guide-reserve:340px;

  --font:"Archivo","Archivo Fallback",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  --r:10px;
  --r-sm:7px;
  --header-h:58px;
  --sidebar-w:268px;
  --ease:cubic-bezier(.2,.7,.3,1);
}

*,*::before,*::after{box-sizing:border-box;}

html{ -webkit-text-size-adjust:100%; }

body{
  margin:0;
  min-height:100vh;
  background:var(--ink);
  color:var(--text);
  font-family:var(--font);
  font-size:14px;
  line-height:1.5;
  font-variant-numeric:tabular-nums;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}

h1,h2,h3{ margin:0; font-weight:700; letter-spacing:-.02em; line-height:1.15; }

button{ font:inherit; color:inherit; }
a{ color:inherit; }

:focus-visible{ outline:2px solid var(--gold); outline-offset:2px; border-radius:3px; }
:focus:not(:focus-visible){ outline:none; }
/* The content area can hold focus — tabindex="-1" lets navigation hand focus
   to it for screen readers, and it also takes focus whenever someone clicks
   empty space inside it. A ring round the whole content area is never useful,
   and browsers draw one after the next key press: that was the gold line that
   appeared along the top and left of the page, seemingly out of nowhere. */
#main:focus, #main:focus-visible{ outline:none; }

::selection{ background:var(--gold); color:var(--ink); }

/* scrollbars */
::-webkit-scrollbar{ width:11px; height:11px; }
::-webkit-scrollbar-track{ background:transparent; }
::-webkit-scrollbar-thumb{ background:#3a3225; border-radius:8px; border:3px solid var(--surface); }
::-webkit-scrollbar-thumb:hover{ background:#4c4130; }

.skip-link{
  position:absolute; left:8px; top:-60px; z-index:300;
  background:var(--gold); color:var(--ink); font-weight:700;
  padding:9px 16px; border-radius:var(--r-sm); text-decoration:none;
  transition:top .15s var(--ease);
}
.skip-link:focus{ top:8px; }

.vh{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

/* ==========================================================================
   Shell
   ========================================================================== */

#app{ display:flex; flex-direction:column; height:100vh; height:100dvh; }

.header{
  height:var(--header-h); flex:none; display:flex; align-items:center; gap:12px;
  padding:0 14px; background:var(--surface);
  border-bottom:1px solid var(--line);
}
/* The site's own controls: logo, search, letters. */
.site-nav{ display:flex; align-items:center; gap:12px; flex:0 1 auto; min-width:0; margin-left:auto; }
/* Holds a monster page's title row on a screen wide enough — see below. */
.header-page{ display:none; }

/* The buttons, all one size: Copy URL, Watch on YouTube, Support, DPS. */
.btn-support .heart{ color:#ff5a8f; }
.btn-support:hover .heart{ color:#ff7aa5; }
.btn-dps .calc{ color:var(--gold); }
.btn-dps .yt{ margin-left:1px; }

.icon-btn{
  display:none; align-items:center; justify-content:center;
  width:34px; height:34px; flex:none;
  background:none; border:1px solid var(--line); border-radius:var(--r-sm);
  color:var(--text-2); cursor:pointer;
}
.icon-btn:hover{ background:var(--hover); color:var(--text); }

/* Home: the logo alone, always the first thing at the top left. */
.brand{
  display:flex; align-items:center; flex:none;
  text-decoration:none; padding:3px; margin:-3px; border-radius:var(--r-sm);
  transition:transform .13s var(--ease), filter .13s var(--ease);
}
.brand img{ height:44px; width:auto; display:block; }
.brand:hover{ transform:scale(1.05); filter:brightness(1.08); }

/* header search — opens the command palette */
.search-trigger{
  flex:1 1 300px; max-width:400px; min-width:0;
  display:flex; align-items:center; gap:9px;
  height:34px; padding:0 9px 0 11px;
  background:var(--ink); border:1px solid var(--line); border-radius:var(--r-sm);
  color:var(--text-3); cursor:pointer; text-align:left;
  transition:border-color .13s var(--ease), color .13s var(--ease);
}
.search-trigger:hover{ border-color:var(--gold-dim); color:var(--text-2); }
/* Only the label flexes. This was `.search-trigger span`, which matched every
   descendant span — including .kbd and the modifier span inside it. .kbd sets
   flex:none, but `.search-trigger span` is more specific and won, so the
   shortcut hint stretched across the bar and pushed "Ctrl" away from "K". */
.search-trigger > .search-label{
  flex:1 1 auto; min-width:0; font-size:13px;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
/* The narrow-screen wording is a second element, shown by swapping display —
   not the same element with font-size:0 and a ::before. That trick broke on
   any phone with a minimum font size set: the browser floored the 0 back up to
   the minimum and the real label rendered next to the replacement, reading
   "SearchSearch ...". display:none cannot be overridden that way. */
.search-trigger > .search-label-sm{ display:none; }
.search-trigger svg{ flex:none; }
.kbd{
  flex:none; display:inline-flex; align-items:center; gap:3px; white-space:nowrap;
  font-size:10.5px; font-weight:600; color:var(--text-3);
  background:var(--raised); border:1px solid var(--line-soft);
  border-radius:5px; padding:2px 6px; line-height:1.4;
}

/* ==========================================================================
   Layout / sidebar
   ========================================================================== */

.layout{ flex:1; display:flex; min-height:0; }

/* Only ever a drawer now. On a wide screen the list is the row of letters in
   the header, so there is no column down the side of the page; below that
   width it slides in over the page from the menu button. Hidden from the Tab
   order while it is closed — otherwise a keyboard user on a laptop would tab
   through every monster in a list they cannot see. */
.sidebar{
  position:fixed; top:var(--header-h); bottom:0; left:0; z-index:120;
  width:var(--sidebar-w); min-height:0;
  background:var(--surface); border-right:1px solid var(--line);
  display:flex; flex-direction:column;
  transform:translateX(-100%); visibility:hidden;
  transition:transform .2s var(--ease), visibility 0s linear .2s;
  box-shadow:10px 0 30px rgba(0,0,0,.5);
}
.sidebar.open{
  transform:none; visibility:visible;
  transition:transform .2s var(--ease), visibility 0s linear 0s;
}

/* app.js replaces this wrapper's innerHTML on every render, so it has to sit
   between .sidebar and the list. Left unstyled it was a plain block with
   min-height:auto, which grew to the full height of the monster list — so
   .sidebar-list's flex:1 and overflow-y:auto applied to nothing, the sidebar
   never scrolled on its own, and the whole page scrolled instead. Making the
   wrapper part of the flex column is what gives the list a bounded height. */
#sidebar-inner{ flex:1; min-height:0; display:flex; flex-direction:column; }

.sidebar-filter{
  flex:none; padding:10px 12px; border-bottom:1px solid var(--line-soft);
  display:flex; align-items:center; gap:8px;
}
.filter-label{ flex:1; min-width:0; font-size:12px; color:var(--text-2); }
.filter-label b{ color:var(--text); font-weight:600; }

/* ------------------------------------------------------ header letters */

/* The monster list as a row of letters beside the search. Shown from 1280px,
   the width at which the row, the search and the banner all fit on one line;
   app.js switches at the same point. */
.topnav{ display:none; align-items:center; gap:10px; flex:none; }
.az-row{ display:flex; align-items:center; gap:2px; }
.az-letter{
  position:relative; flex:none; width:24px; height:28px; padding:0;
  background:none; border:none; border-radius:var(--r-sm); cursor:pointer;
  font:inherit; font-size:12.5px; font-weight:650; color:var(--text-2);
  display:flex; align-items:center; justify-content:center;
  transition:background .1s var(--ease), color .1s var(--ease);
}
.az-letter:hover,
.az-letter[aria-expanded="true"]{ background:var(--hover); color:var(--text); }
/* The letter of the page you are on: the same gold marker the list uses for
   the current page, turned to sit under the letter instead of beside it. */
.az-letter.active{ background:var(--gold-soft); color:var(--gold); }
.az-letter.active::after{
  content:""; position:absolute; left:6px; right:6px; bottom:-5px;
  height:2px; border-radius:2px; background:var(--gold);
}

/* The flyout is a single shared element outside the header, positioned with
   fixed coordinates measured from its letter at open time — so no ancestor's
   overflow or transform can clip it or shift what "fixed" means. */
.az-flyout{
  position:fixed; z-index:130; display:none;
  min-width:190px; max-width:290px; overflow-y:auto; overscroll-behavior:contain;
  padding:6px 8px 8px; background:var(--raised);
  border:1px solid var(--line); border-radius:var(--r);
  box-shadow:0 14px 34px rgba(0,0,0,.55);
}
.az-flyout.open{ display:block; }
.az-flyout .mon-link{ white-space:nowrap; }
.flyout-head{
  padding:2px 9px 6px; font-size:11px; font-weight:700;
  color:var(--text-3); letter-spacing:.04em;
}

/* honest switch: hide monsters that have no guide filmed yet */
.switch{
  position:relative; flex:none; width:36px; height:20px;
  background:var(--raised); border:1px solid var(--line); border-radius:20px;
  cursor:pointer; padding:0; transition:background .15s var(--ease), border-color .15s var(--ease);
}
.switch::after{
  content:""; position:absolute; top:2px; left:2px; width:14px; height:14px;
  border-radius:50%; background:var(--text-3); transition:transform .15s var(--ease), background .15s var(--ease);
}
.switch[aria-checked="true"]{ background:var(--gold-soft); border-color:var(--gold-dim); }
.switch[aria-checked="true"]::after{ transform:translateX(16px); background:var(--gold); }

.sidebar-list{ flex:1; overflow-y:auto; overscroll-behavior:contain; padding:6px 8px 24px; }

.letter-head{
  position:sticky; top:0; z-index:1;
  padding:7px 10px 4px; font-size:11px; font-weight:700; color:var(--text-3);
  background:linear-gradient(var(--surface) 72%,transparent);
  letter-spacing:.04em;
}

.mon-link{
  display:flex; align-items:center; gap:8px;
  padding:6px 9px; border-radius:var(--r-sm);
  font-size:13px; color:var(--text-2); text-decoration:none;
  position:relative; transition:background .1s var(--ease), color .1s var(--ease);
}
.mon-link:hover{ background:var(--hover); color:var(--text); }
.mon-link[aria-current="page"]{ background:var(--gold-soft); color:var(--text); font-weight:600; }
.mon-link[aria-current="page"]::before{
  content:""; position:absolute; left:-8px; top:5px; bottom:5px;
  width:3px; border-radius:0 3px 3px 0; background:var(--gold);
}
.mon-name{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.mon-link.pending{ color:var(--text-3); }
.mon-link.pending .mon-name{ opacity:.8; }

/* status dot: filled jade = guide is live, hollow = not filmed yet */
.dot{ flex:none; width:6px; height:6px; border-radius:50%; background:var(--jade); }
.pending .dot{ background:none; box-shadow:inset 0 0 0 1.5px var(--text-3); }
.crown{ flex:none; color:var(--gold); opacity:.75; }
.pending .crown{ color:var(--text-3); opacity:.6; }

.side-empty{ padding:20px 12px; font-size:12.5px; color:var(--text-3); line-height:1.6; }

.scrim{
  display:block; position:fixed; top:var(--header-h); inset:0 0 0 0; z-index:110;
  background:rgba(10,8,6,.6); opacity:0; pointer-events:none;
  transition:opacity .2s var(--ease);
}
.scrim.open{ opacity:1; pointer-events:auto; }

/* Wide enough for the row of letters: the list lives in the header, and the
   drawer and its button are not needed. */
@media (min-width:1280px){
  .topnav{ display:flex; }
  .sidebar,
  .scrim{ display:none; }
  .search-trigger{ min-width:120px; }
}
/* Too narrow for the row: the menu button opens the list as a drawer, and
   there are no letters for a menu to hang from. */
@media (max-width:1279px){
  .icon-btn{ display:flex; }
  .az-flyout{ display:none !important; }
}

/* ==========================================================================
   Main
   ========================================================================== */

/* The scrollbar's space is always kept, whether or not a page scrolls. A
   monster page that fits the screen has none and the long homepage has one;
   without this the page's right edge — and the top-right buttons on it —
   moved sideways by a scrollbar's width going from one to the other. */
.main{ flex:1; min-width:0; overflow-y:auto; overscroll-behavior:contain; scrollbar-gutter:stable; }

/* --------------------------------------------------------------- home */

.home{ max-width:1180px; margin:0 auto; padding:56px 28px 80px; }

.hero{ margin-bottom:30px; }
.hero h1{
  font-size:clamp(34px,5.4vw,60px); font-weight:800; font-stretch:82%;
  letter-spacing:-.035em; margin-bottom:24px;
}
.hero p{
  margin:0 0 26px; font-size:16px; color:var(--text-2);
  max-width:56ch; line-height:1.55;
}
.hero p b{ color:var(--text); font-weight:600; }
.hero p code{
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  font-size:.88em; color:var(--gold);
  background:var(--gold-soft); border:1px solid var(--line);
  padding:1px 6px; border-radius:5px; white-space:nowrap;
}

.hero-search{ position:relative; max-width:620px; }
.hero-search svg{
  position:absolute; left:16px; top:50%; transform:translateY(-50%);
  color:var(--text-3); pointer-events:none;
}
.hero-search input{
  width:100%; height:56px; padding:0 92px 0 46px;
  background:var(--surface); border:1px solid var(--line); border-radius:12px;
  color:var(--text); font-family:inherit; font-size:16px;
  transition:border-color .14s var(--ease), background .14s var(--ease);
}
.hero-search input::placeholder{ color:var(--text-3); }
.hero-search input:focus{ outline:none; border-color:var(--gold); background:var(--raised); }
.hero-search input::-webkit-search-cancel-button{ cursor:pointer; }
.hero-search .kbd{ position:absolute; right:14px; top:50%; transform:translateY(-50%); }

/* live count line under the search */
.result-line{
  margin-top:12px; font-size:13px; color:var(--text-3); min-height:20px;
}
.result-line b{ color:var(--text-2); font-weight:600; }
.result-line em{ font-style:normal; color:var(--gold); }

/* Text for screen readers only. */
.sr-only{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

/* A one-line tip for first-time visitors. Quiet enough that a regular stops
   seeing it, and it fades out properly the first time a letter key is used.
   It fades with visibility, never display, so its line is always kept and the
   heading, search box and letters stay exactly where they are. */
.key-hint{
  display:flex; align-items:center; gap:5px;
  height:20px; margin:0 0 7px 2px;
  font-size:12.5px; color:var(--text-3);
  transition:opacity .4s var(--ease), visibility 0s linear 0s;
}
.key-hint.used{
  opacity:0; visibility:hidden;
  transition:opacity .4s var(--ease), visibility 0s linear .4s;
}
.key-hint kbd{
  display:inline-grid; place-items:center;
  min-width:18px; height:18px; padding:0 4px;
  border:1px solid var(--line); border-bottom-width:2px; border-radius:4px;
  background:var(--surface); color:var(--text-2);
  font:650 10.5px/1 ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}

/* The browse bar under the search box: the sort menu, then the letters with
   the tip sitting over them. A clear gap above it keeps the tip from reading as
   part of the search box. */
.browse{
  display:flex; align-items:flex-start; gap:10px; flex-wrap:wrap;
  margin-top:24px; transition:opacity .15s var(--ease);
}
.letter-area{ flex:1; min-width:0; }

/* The reset reads Esc where there is a keyboard to press it on, and All where
   there is not. */
.all-touch{ display:none; }

/* No keyboard, no tip, no Esc — decided once by the device, never by anything
   the reader does, so none of it can shift the page. */
@media (hover:none), (pointer:coarse){
  .key-hint{ display:none; }
  .browse{ margin-top:20px; }
  .sort{ margin-top:0 !important; }
  .all-key{ display:none; }
  .all-touch{ display:inline; }
}
/* While a search is running the letters and sort do nothing, so they step
   back. Picking a letter still works — it clears the search. */
.browse.searching{ opacity:.45; }

/* Shaped like YouTube's "Latest" chip. A native select underneath, so on a
   phone it opens the system picker. */
/* Pushed down by the tip's line — 20px, plus the 7px under it — so the menu
   sits level with the letter buttons rather than with the tip. */
.sort{ flex:none; margin-top:27px; }
.sort select{
  -webkit-appearance:none; appearance:none;
  height:34px; padding:0 32px 0 13px; border-radius:8px;
  border:1px solid var(--line); background-color:var(--raised); color:var(--text);
  font:inherit; font-size:13.5px; font-weight:700; cursor:pointer;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23f0e8d8' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 11px center;
}
.sort select:hover{ border-color:var(--gold-dim); }
.sort select:focus-visible{ outline:2px solid var(--gold); outline-offset:2px; }
.sort option{ background:var(--surface); color:var(--text); }

.letters{ display:flex; flex-wrap:wrap; gap:6px; flex:1; min-width:0; }
.letter-btn{
  min-width:34px; height:34px; padding:0 9px; border-radius:8px;
  border:1px solid var(--line); background:var(--surface); color:var(--text-2);
  font:inherit; font-size:13.5px; font-weight:700; cursor:pointer;
  transition:color .12s var(--ease), border-color .12s var(--ease), background .12s var(--ease);
}
.letter-btn:hover{ color:var(--text); border-color:var(--gold-dim); background:var(--raised); }
.letter-btn[aria-pressed="true"]{ background:var(--gold); border-color:var(--gold); color:var(--ink); }
.letter-btn:focus-visible{ outline:2px solid var(--gold); outline-offset:2px; }

/* A second section — Bosses under Slayer monsters — needs the same room above
   it that the first gets from the browse bar. */
#home-results .grid + .section-head{ margin-top:34px; }

/* On a phone the letters get their own line under the sort menu and wrap
   across the full width, rather than squeezing into a column beside it. */
@media (max-width:560px){
  .letter-area{ flex-basis:100%; }
}

.section-head{
  display:flex; align-items:baseline; gap:10px; flex-wrap:wrap;
  margin:0 0 16px; padding-top:8px;
}
.section-head h2{ font-size:17px; font-weight:700; font-stretch:92%; }
.section-head .count{ font-size:13px; color:var(--text-3); }
.section-head .spacer{ flex:1; }


.grid{
  display:grid; gap:14px;
  grid-template-columns:repeat(auto-fill,minmax(216px,1fr));
}

/* Spans the whole row so the cards below it always start a fresh line — the
   grid would otherwise flow the heading into a card slot. Same letters as the
   sidebar, so the two read as one list seen two ways. */
.grid-letter{
  grid-column:1 / -1;
  display:flex; align-items:center; gap:11px;
  margin:14px 0 0; font-size:13px; font-weight:700;
  color:var(--gold); letter-spacing:.06em;
}
.grid-letter:first-child{ margin-top:0; }
.grid-letter::after{
  content:""; flex:1; height:1px; background:var(--line);
}

.card{
  display:flex; flex-direction:column;
  background:var(--surface); border:1px solid var(--line); border-radius:var(--r);
  overflow:hidden; text-decoration:none; color:inherit;
  transition:border-color .14s var(--ease), transform .14s var(--ease);
}
.card:hover{ border-color:var(--gold-dim); transform:translateY(-2px); }
.card:hover .card-title{ color:var(--gold); }

.card-thumb{
  position:relative; aspect-ratio:16/9; background:var(--raised);
  border-bottom:1px solid var(--line-soft); overflow:hidden;
}
.card-thumb img{
  width:100%; height:100%; object-fit:cover; display:block;
  opacity:.92; transition:opacity .14s var(--ease), transform .3s var(--ease);
}
.card:hover .card-thumb img{ opacity:1; transform:scale(1.03); }

.card-thumb.empty{
  display:flex; align-items:center; justify-content:center;
  color:#453b2a;
  background:repeating-linear-gradient(-45deg,var(--raised) 0 8px,#201b14 8px 16px);
}

.card-body{ padding:11px 13px 13px; display:flex; flex-direction:column; gap:5px; flex:1; }
.card-title{
  font-size:14px; font-weight:650; letter-spacing:-.01em;
  display:flex; align-items:center; gap:6px;
  transition:color .13s var(--ease);
}
.card-title .crown{ font-size:11px; }
.card-meta{ font-size:12px; color:var(--text-3); line-height:1.45; margin-top:auto; }
/* The two questions the line answers are kept apart: where it lives, then what
   to wear. Block rather than a dot separator so a long location count never
   drags the gear count onto a ragged third line. */
.card-meta .meta-where,
.card-meta .meta-gear{ display:block; }
.card-meta .meta-gear{ color:var(--text-3); opacity:.8; }
.card-meta .wild-flag{ color:var(--blood); }

.card.pending{ opacity:.62; }
.card.pending:hover{ opacity:.85; }
.card.pending .card-title{ color:var(--text-2); }

.tag{
  display:inline-block; font-size:10.5px; font-weight:700; letter-spacing:.03em;
  padding:2px 7px; border-radius:5px; vertical-align:1px;
}
.tag-wild{ background:var(--blood-soft); color:var(--blood); box-shadow:inset 0 0 0 1px var(--blood-dim); }
.tag-soon{ background:var(--raised); color:var(--text-3); box-shadow:inset 0 0 0 1px var(--line); }

.no-results{
  grid-column:1/-1; padding:44px 20px; text-align:center;
  border:1px dashed var(--line); border-radius:var(--r); color:var(--text-3);
}
.no-results b{ display:block; color:var(--text-2); font-size:15px; margin-bottom:5px; font-weight:600; }

.home-foot{
  margin-top:52px; padding-top:22px; border-top:1px solid var(--line-soft);
  font-size:12.5px; color:var(--text-3); line-height:1.7;
}
.home-foot a{ color:var(--text-2); }

/* --------------------------------------------------------------- detail */

.detail{ padding:0; }

.detail-head{
  padding:16px 26px 0; display:flex; align-items:flex-start; gap:14px; flex-wrap:wrap;
}
/* Sized to be recognised at a glance, now it has the line to itself. */
.detail-head h1{
  display:flex; align-items:center; gap:10px;
  font-size:clamp(26px, 2.3vw, 36px); font-weight:800; line-height:1.1;
  letter-spacing:-.01em;
}
.boss-mark{ display:inline-flex; color:var(--gold); }
.boss-mark .crown{ width:.62em; height:.62em; }
/* Copy URL, Watch on YouTube, Support, DPS calculator: top right of the page,
   under the letters. They wrap onto a second line rather than shrink. */
/* The row fills from the right: DPS calculator at the far end, then Support,
   Watch on YouTube, Copy URL. When there is not room for all four, it is the
   leftmost that drops to a second line — so Support and the DPS calculator
   always sit at the top right, in the same spot on every page, including the
   homepage where they are the only two. Done with order, not by reordering the
   markup, so keyboard and screen-reader order still read left to right. */
.page-actions{ display:flex; flex-direction:row-reverse; flex-wrap:wrap; justify-content:flex-start; gap:8px; }
.page-actions > :nth-last-child(1){ order:1; }
.page-actions > :nth-last-child(2){ order:2; }
.page-actions > :nth-last-child(3){ order:3; }
.page-actions > :nth-last-child(4){ order:4; }

/* The homepage's Support and DPS calculator, placed exactly where a monster
   page's top-right buttons are. The wrapper takes no height, so the homepage
   below is untouched; --actions-top is how far down the page those buttons
   start in each layout — below the title row, where it is still in the page. */
.home-actions{ position:relative; height:0; }
.home-actions .page-actions{ position:absolute; top:var(--actions-top); right:26px; z-index:2; }

/* Full guide: the player and chapters on the left at their usual size, the
   buttons in the space to their right, level with the top of the chapters
   box. The right column never drops below 270px — room for Support and the
   DPS calculator side by side, so they stay in their usual spot — and on a
   tight screen the player gives up that much width. */
:root{ --guide-w:max(calc((100vh - var(--guide-reserve)) * 4 / 3 + 368px), 808px); }
.guide-wrap{
  display:grid; gap:16px; align-items:start;
  grid-template-columns:minmax(0, min(var(--guide-w), calc(100% - 286px))) minmax(270px, 1fr);
}
.guide-wrap > .guide-grid{ grid-column:1; grid-row:1; }
.guide-wrap > .page-actions{ grid-column:2; grid-row:1; }

/* On a wide screen the name, the tabs and the two buttons share one line, and
   the line the name used to have to itself goes. display:contents lets the
   name and buttons sit in the same row as the tabs without moving them in the
   HTML, so a phone still gets them stacked. The row carries the baseline the
   selected tab opens through. */
/* From 1680px a monster's name and tabs fit on the header line, beside the
   home button, with the switch, letters and search on the right. The page's
   title row goes, and everything below it moves up. The four buttons are not
   in the header at all — they sit at the page's top right. Must match
   TITLE_IN_HEADER in build.js and TITLE_WIDE in app.js. */
@media (min-width:1680px){
  .header-page{ display:flex; align-self:stretch; align-items:stretch; min-width:0; flex:0 1 auto; }
  .header-page .detail-top{ padding:0; margin:0; box-shadow:none; gap:16px; align-items:flex-end; }
  .header-page .detail-head h1{ font-size:30px; }
  .header-page .name-wrap{ align-self:center; }
  /* The selected tab sits on the header's bottom edge and opens through it
     into the page, as it did through the old title row's line. */
  .header-page .tabs-row{ margin-bottom:-1px; position:relative; z-index:1; }
}

@media (min-width:1280px){
  /* The title row is 56px shorter up here, so the Full guide player takes
     that back — the description box still lands 17px above the fold. */
  :root{ --guide-reserve:284px; --qs-chrome:153px; --actions-top:69px; }
  .detail-top{
    display:flex; align-items:flex-end; gap:18px;
    padding:12px 26px 0; margin-bottom:-1px;
    box-shadow:inset 0 -1px 0 var(--line);
  }
  .detail-top .detail-head{ display:contents; }
  .detail-top .detail-head h1{ align-self:center; flex:none; padding-bottom:2px; }
  .detail-top .tabs-row{ order:1; flex:none; padding:0; margin:0; box-shadow:none; }
}

/* After the 1280px block on purpose: both apply on a wide screen, and the
   later rule wins. The title row has left the page up here, so the Full guide
   player takes that height too. */
@media (min-width:1680px){
  :root{ --guide-reserve:229px; --qs-chrome:102px; --actions-top:18px; }
}

.btn{
  display:inline-flex; align-items:center; gap:7px;
  padding:6px 12px; border-radius:var(--r-sm);
  background:var(--surface); border:1px solid var(--line);
  color:var(--text-2); font-size:12.5px; font-weight:600; cursor:pointer;
  text-decoration:none; white-space:nowrap;
  transition:border-color .13s var(--ease), color .13s var(--ease);
}
.btn:hover{ border-color:var(--gold-dim); color:var(--text); }
.btn.done{ color:var(--jade); border-color:var(--jade); }

/* tabs */
/* The row holds the how-to button and the tabs. It carries the baseline, as an
   inset shadow so the selected tab can cover it and it stays full width when
   the tabs scroll sideways on a narrow screen. The popover is positioned
   against the row, outside the scrolling tablist, so the overflow cannot clip
   it. */
.tabs-row{
  position:relative; display:flex; align-items:flex-end; gap:10px;
  padding:14px 26px 0; margin-bottom:-1px;
  box-shadow:inset 0 -1px 0 var(--line);
}
.tabs{
  display:flex; gap:5px; flex:1; min-width:0;
  overflow-x:auto; scrollbar-width:none;
}
.tabs::-webkit-scrollbar{ display:none; }

/* Folder tabs. Each is its own raised shape; the selected one takes the page
   colour and drops its bottom edge so it opens into the content below. */
.tab{
  display:flex; align-items:center; gap:9px;
  padding:9px 15px 10px; cursor:pointer; white-space:nowrap;
  background:var(--surface); color:var(--text-2);
  border:1px solid var(--line); border-bottom:none;
  border-radius:var(--r-sm) var(--r-sm) 0 0;
  box-shadow:inset 0 -1px 0 var(--line);
  font-size:13.5px; font-weight:650;
  transition:color .12s var(--ease), background .12s var(--ease);
}
.tab:hover{ color:var(--text); background:var(--raised); }
.tab[aria-selected="true"]{
  background:var(--ink); color:var(--gold);
  box-shadow:inset 0 2px 0 var(--gold);
}

/* The number that opens the tab. A keycap rather than a superscript so it
   reads as "press this", not as a count. Hidden where there is no keyboard. */
.tab-key{
  display:inline-grid; place-items:center;
  min-width:19px; height:19px; padding:0 5px;
  border:1px solid var(--line); border-bottom-width:2px; border-radius:4px;
  background:var(--raised); color:var(--text-3);
  font:650 11px/1 ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}
.tab[aria-selected="true"] .tab-key{ color:var(--gold); border-color:var(--gold-dim); background:var(--surface); }
@media (hover:none), (pointer:coarse){
  .tab-key,
  .help-list .kb-only{ display:none; }
}

/* The name, with the how-to button at its top right like a footnote mark:
   small and a little faded so a regular reader passes over it, still the
   universal blue-disc sign so a new one knows what it is. */
.name-wrap{ position:relative; display:flex; align-items:flex-start; gap:3px; min-width:0; }
.info-btn{
  flex:none; width:20px; height:20px; padding:0; margin-top:-3px;
  display:grid; place-items:center;
  border:0; border-radius:50%; background:none; cursor:pointer;
  color:#0f6ce8; opacity:.7;
  transition:opacity .12s var(--ease), color .12s var(--ease), box-shadow .12s var(--ease);
}
.info-btn:hover{ opacity:1; color:#3b87f2; }
.info-btn:focus-visible{ opacity:1; outline:2px solid #fff; outline-offset:2px; }
.info-btn[aria-expanded="true"]{ opacity:1; color:#3b87f2; box-shadow:0 0 0 3px rgba(15,108,232,.35); }

/* Drops from the button, opening rightward, where there is room. */
.help-pop{
  position:absolute; top:calc(100% + 9px); left:calc(100% - 20px); z-index:140;
  width:min(340px, calc(100vw - 32px));
  padding:14px 16px 12px; border-radius:12px;
  background:var(--raised); border:1px solid var(--line);
  box-shadow:0 14px 36px rgba(0,0,0,.55);
}
.help-pop[hidden]{ display:none; }
/* A small pointer back up at the button it came from. */
.help-pop::before{
  content:""; position:absolute; top:-6px; left:5px;
  width:10px; height:10px; transform:rotate(45deg);
  background:var(--raised); border-left:1px solid var(--line); border-top:1px solid var(--line);
}
.help-title{ margin:0 0 8px; font-size:13.5px; font-weight:700; color:var(--text); }
.help-list{ margin:0; padding:0 0 0 17px; font-size:13px; line-height:1.6; color:var(--text-2); }
.help-list li{ margin-bottom:5px; }
.help-list li::marker{ color:var(--gold); }
.help-list b{ color:var(--text); font-weight:650; }
.help-list kbd{
  display:inline-block; min-width:17px; padding:0 5px;
  border:1px solid var(--line); border-bottom-width:2px; border-radius:4px;
  background:var(--surface); color:var(--text);
  font:650 11px/17px ui-monospace, "SF Mono", Menlo, Consolas, monospace; text-align:center;
}

.panel{ padding:18px 26px 40px; }

/* location chips */
.chips{ display:flex; gap:7px; flex-wrap:wrap; margin-bottom:16px; }
.chip{
  display:inline-flex; align-items:center; gap:7px;
  padding:6px 13px; border-radius:20px; cursor:pointer;
  background:var(--surface); border:1px solid var(--line);
  color:var(--text-2); font-size:12.5px; font-weight:600;
  transition:border-color .12s var(--ease), color .12s var(--ease);
}
.chip:hover{ border-color:var(--gold-dim); color:var(--text); }
.chip[aria-pressed="true"]{ background:var(--gold-soft); border-color:var(--gold-dim); color:var(--gold); }
.chip.wild[aria-pressed="true"]{ background:var(--blood-soft); border-color:var(--blood-dim); color:var(--blood); }
.chip .wild-tag{
  font-size:9.5px; font-weight:700; letter-spacing:.04em;
  color:var(--blood); background:var(--blood-soft);
  padding:1px 5px; border-radius:4px;
}

/* The first thing to do on Quick setup, so it is sized to be seen rather than
   read only if you were already looking. */
.chips-label{
  font-size:15px; font-weight:700; color:var(--text);
  margin:0 0 10px; display:flex; align-items:center; gap:8px;
}
.chips-label::before{
  content:""; flex:none; width:3px; height:15px;
  border-radius:2px; background:var(--gold);
}

/* Quick setup: the controls in one bar, then the gear chart, then prayers and
   settings with the inventory beside them.

   Two equal columns spanning 80% of the panel. With three pictures sharing a
   row each got about a third of the width, too small to read without zooming;
   calc(80% - 10px) makes each column exactly 1.2 times what one of the three
   was — (width - 32px) / 3 * 1.2, twice, plus the 16px gap — at every screen
   width. Keeping the pair side by side, rather than stacking all three, is
   what keeps the page short. */
/* Every picture as large as the screen allows with all three in view: two
   rows of 16:9, so a column is (height left over) x 8/9 wide — or half the
   width, if that is less. --qs-chrome is what sits above and below the two
   rows: the header, the title row where it is still in the page, the padding
   and the gap. Measured per layout, below. A 4K screen gets very large
   pictures and a 1080p one smaller, and none is cut off at the bottom. */

/* A third column takes whatever width the two picture columns leave. It is
   empty under the inventory, but the buttons and choices beside the gear
   chart spread into it: on a shorter screen, where the pictures are limited
   by height and there is width to spare, that keeps the bubbles on fewer
   lines, so they stay shorter than the gear chart and never push the second
   row off the bottom. It also puts them right under the search bar. */
.qs-grid{
  --qs-w:max(300px, min(calc((100vh - var(--qs-chrome)) * 8 / 9), calc((100% - 32px) / 2)));
  display:grid; gap:12px 16px; align-items:start;
  grid-template-columns:var(--qs-w) var(--qs-w) minmax(0, 1fr);
}
/* Beside the gear chart, above the inventory. The four buttons stay at the
   top right, under the letters, where they are on the Full guide too. The
   location and gear choices sit below them, against the gear chart: each
   label, then its bubbles, the labels lined up in a column. */
.qs-aside{
  grid-column:2 / -1; grid-row:1; min-width:0;
  display:flex; flex-direction:column; align-items:stretch; gap:16px;
}
.qs-controls{
  display:grid; grid-template-columns:max-content minmax(0,1fr);
  align-items:start; gap:10px 14px;
}
.qs-ctl{ display:contents; }
.qs-ctl .chips,
.qs-ctl .qs-styles{ justify-content:flex-start; margin:0; }
.qs-ctl .qs-styles{ min-height:32px; align-items:center; }
.qs-ctl .chips-label{ margin:0; min-height:32px; }
.qs-col{ min-width:0; display:flex; flex-direction:column; gap:7px; }
.qs-gear{ grid-column:1; grid-row:1; }
/* Row two, filling from the left: a monster with an inventory shot but no
   prayers shot puts it under the gear rather than leaving a gap. */
.qs-shot{ grid-row:2; }
/* Every picture is a 16:9 screenshot, so each frame holds that shape before
   its picture arrives. Without it a frame was zero-high while loading: choose
   Ranged and the prayers and inventory jumped up into the gear chart's place,
   then fell back down when it loaded. Now nothing below can move. A picture
   of another shape is shown whole inside the frame rather than cropped. */
.qs-col .frame{ aspect-ratio:16 / 9; }
.qs-col .frame img.shot{ width:100%; height:100%; max-height:none; object-fit:contain; }

.qs-styles{ display:flex; gap:5px; flex-wrap:wrap; }
.style-btn{
  padding:3px 10px; border-radius:14px; cursor:pointer;
  background:none; border:1px solid var(--line-soft);
  color:var(--text-3); font-size:11.5px; font-weight:600;
  transition:border-color .12s var(--ease), color .12s var(--ease);
}
.style-btn:hover{ color:var(--text-2); border-color:var(--line); }
.style-btn[aria-pressed="true"]{ background:var(--gold-soft); border-color:var(--gold-dim); color:var(--gold); }
/* In the bar they sit under the location chips, so they match them in size. */
.qs-ctl .style-btn{ padding:6px 13px; border-radius:20px; font-size:12.5px; border-color:var(--line); color:var(--text-2); }

/* media frames */
.frame{
  position:relative; border:1px solid var(--line); border-radius:var(--r);
  background:#100d09; overflow:hidden;
}
.frame img.shot{
  display:block; width:100%; height:auto;
  max-height:calc(100vh - 260px); object-fit:contain; cursor:zoom-in;
  background:#100d09;
}
.zoom-btn{
  position:absolute; top:9px; right:9px; z-index:2;
  width:30px; height:30px; border-radius:50%;
  background:rgba(20,17,13,.82); border:1px solid var(--line);
  color:var(--text-2); cursor:zoom-in;
  display:flex; align-items:center; justify-content:center;
  opacity:0; transition:opacity .13s var(--ease);
}
.frame:hover .zoom-btn,.zoom-btn:focus-visible{ opacity:1; }
.zoom-btn:hover{ background:var(--hover); color:var(--text); }

/* A screenshot that could not be loaded — the image host is down, or the file
   was removed. Hold the frame open at a sensible size, hide the broken image
   and the zoom control, and say what happened and where else to look. The
   location badge stays, so the reader still knows which shot this was. */
.frame.shot-failed{
  min-height:180px; display:flex; align-items:center; justify-content:center;
  border-style:dashed; background:var(--raised);
}
.frame.shot-failed img.shot,
.frame.shot-failed .zoom-btn{ display:none; }
.frame.shot-failed::after{
  content:"Image temporarily unavailable \A The Full guide video shows this setup";
  white-space:pre-line; text-align:center;
  font-size:13px; line-height:1.6; color:var(--text-3); padding:40px 18px 18px;
}

.frame-tag{
  position:absolute; top:9px; left:9px; z-index:2; pointer-events:none;
  display:inline-flex; align-items:center; gap:6px;
  padding:4px 11px; border-radius:16px;
  background:rgba(20,17,13,.86); border:1px solid var(--line);
  font-size:12px; font-weight:600; color:var(--text);
  backdrop-filter:blur(3px);
}

/* video facade — nothing from YouTube loads until this is clicked */
.facade{
  position:relative; display:block; width:100%; padding:0; border:0;
  aspect-ratio:16/9; background:#0d0b08; cursor:pointer; overflow:hidden;
}
.facade img{
  width:100%; height:100%; object-fit:cover; display:block;
  opacity:.72; transition:opacity .16s var(--ease);
}
.facade:hover img{ opacity:.92; }
.facade-play{
  position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
  flex-direction:column; gap:10px; pointer-events:none;
}
.facade-play .disc{
  width:58px; height:58px; border-radius:50%;
  background:rgba(232,171,53,.94); color:#14110d;
  display:flex; align-items:center; justify-content:center;
  box-shadow:0 6px 22px rgba(0,0,0,.5);
  transition:transform .16s var(--ease);
}
.facade:hover .disc{ transform:scale(1.08); }
.facade-play .lbl{
  font-size:12px; font-weight:600; color:var(--text);
  background:rgba(20,17,13,.82); padding:3px 11px; border-radius:14px;
}
.frame iframe{ display:block; width:100%; aspect-ratio:16/9; border:0; }

/* The Full guide player is deliberately 4:3, not 16:9. A 16:9 video letterboxes
   inside a 4:3 box, so YouTube's title bar along the top and its scrubber along
   the bottom land on the black bars instead of over the footage.

   The shape lives on the container rather than on whatever is inside it. That
   matters because clicking swaps the poster for an empty <div>, which the
   YouTube API then replaces with an iframe — and an empty div has no height, so
   the box used to collapse to a thin strip for as long as the API took to load.
   Now the container holds the shape and every child just fills it.

   Width is whichever is smaller: the column, or what will fit above the fold.
   Without the second term a 4:3 box is tall enough to run off the bottom of a
   laptop screen. */
#guide-frame{
  position:relative;
  width:100%;              /* .guide-grid's max-width is what caps this now */
  aspect-ratio:4/3;
  background:#000;
}
#guide-frame > *{ position:absolute; inset:0; width:100%; height:100%; }
#guide-frame .facade,
#guide-frame iframe{ aspect-ratio:auto; }
#guide-frame .facade img{ object-fit:contain; }

/* full guide: chapters beside the player */
/* The chapters column and its type were scaled up ~20% — at 296px with
   12.5px labels the list was hard to read. The player is 1fr, so it gives
   back exactly the width this takes. */
.guide-grid{
  display:grid; grid-template-columns:1fr 356px; gap:12px; align-items:stretch;
  /* Cap the whole grid, not just the player inside it. The player is limited by
     viewport height, so on a wide monitor its 1fr column was far wider than the
     player could ever be and simply centred it — leaving a 250px hole between
     the video and the chapter list. Capping the grid makes the column exactly
     the player's width, so the list sits against it. 368px = the 356px column
     plus the 12px gap. */
  /* The floor keeps the video watchable on very short screens, where the
     description then needs a short scroll rather than the player shrinking to
     a postage stamp. 808px = a 440px-wide player plus the 368px column — the
     smallest size at which a 1366x768 laptop still shows the whole box. */
  max-width:max(calc((100vh - var(--guide-reserve)) * 4 / 3 + 368px), 808px);
}
.chapters{
  border:1px solid var(--line); border-radius:var(--r);
  background:var(--ink); overflow:hidden;
  display:flex; flex-direction:column;
  /* Sits level with the player, top and bottom, instead of hanging below it.
     height:0 keeps the list out of the row-height calculation, so the row is
     sized by the 4:3 player alone; min-height:100% then fills that row. */
  height:0; min-height:100%;
}

/* The chapter box reads top to bottom as three levels of emphasis, loudest
   first: step one is a solid button, step two a tinted callout, and each
   location a card with its name up front. */

/* Step one. The strongest thing in the box, because it comes first. */
.chapters-note{
  flex:none; display:flex; align-items:center; gap:12px; width:100%;
  text-align:left; border:0; font:inherit; cursor:pointer;
  padding:13px 15px; background:var(--blood-deep); color:#fff;
  transition:background .12s var(--ease);
}
.chapters-note:hover{ background:#c4443a; }
.chapters-note:focus-visible{ outline:2px solid #fff; outline-offset:-5px; }
.note-play{
  flex:none; width:32px; height:32px; border-radius:50%;
  display:grid; place-items:center; background:rgba(255,255,255,.2);
}
.note-play svg{ margin-left:2px; }
.note-text b{ display:block; font-size:16.5px; font-weight:800; line-height:1.2; color:#fff; }
.note-text span{ display:block; margin-top:2px; font-size:13px; color:rgba(255,255,255,.86); }

.chapters-scroll{ overflow-y:auto; flex:1; min-height:0; padding-bottom:10px; }

/* Step two. Tinted and dashed rather than solid, so it reads as the next
   instruction without competing with step one — and not as a button. */
.chapters-next{
  display:flex; align-items:center; justify-content:center; text-align:center;
  margin:12px 10px 0; padding:9px 12px;
  border:1px dashed var(--gold-dim); border-radius:8px;
  background:var(--gold-soft); color:var(--gold);
  font-size:13.5px; font-weight:700;
  cursor:default; user-select:none;
}

/* One card per location: the name first, then its three chapters. */
.ch-loc{
  margin:10px 10px 0;
  border:1px solid var(--line); border-radius:10px;
  background:var(--surface);
}
.ch-group{
  display:flex; align-items:center; gap:9px; width:100%;
  text-align:left; border:0; cursor:pointer; font:inherit;
  padding:10px 11px 10px 12px; border-radius:9px 9px 0 0;
  background:var(--raised); color:var(--text);
  border-bottom:1px solid var(--line);
  font-size:15px; font-weight:750; line-height:1.25;
  /* Sticks within its own card, so while its chapters are on screen the name
     stays visible above them, and the next card pushes it out. */
  position:sticky; top:0; z-index:1;
  transition:color .12s var(--ease);
}
.ch-pin{ flex:none; color:var(--gold); }
.ch-group-name{ flex:1; min-width:0; }
.ch-group .wild-tag{
  flex:none; padding:2px 6px; border-radius:4px;
  background:var(--blood-soft); color:var(--blood);
  font-size:10.5px; font-weight:800; letter-spacing:.04em;
}
.ch-group-go{
  flex:none; width:24px; height:24px; border-radius:50%;
  display:grid; place-items:center;
  border:1px solid var(--line); background:var(--surface); color:var(--text-3);
  transition:background .12s var(--ease), color .12s var(--ease), border-color .12s var(--ease);
}
.ch-group-go svg{ margin-left:1px; }
.ch-group:hover{ color:var(--gold); }
.ch-group:hover .ch-group-go{ background:var(--gold); border-color:var(--gold); color:var(--ink); }

.ch-row{
  display:flex; align-items:center; gap:10px; width:100%;
  padding:9px 15px; border:0; background:none; cursor:pointer; text-align:left;
  color:var(--text-2); border-bottom:1px solid var(--line-soft);
  transition:background .1s var(--ease), color .1s var(--ease);
}
.ch-loc .ch-row{ padding-left:14px; }
.ch-loc .ch-row:last-child{ border-bottom:0; border-radius:0 0 9px 9px; }
.ch-row:hover{ background:var(--hover); color:var(--text); }
.ch-row[aria-current="true"]{ background:var(--gold-soft); color:var(--text); box-shadow:inset 3px 0 0 var(--gold); }

/* Step one as a card: the red button and its three chapters inside one red
   outline, the same shape as each location's card below — not a red header
   with rows hanging off it. Pinned: it stays at the top while the locations
   scroll. */
.ch-intro{
  flex:none; margin:10px 10px 0;
  border:1px solid var(--blood); border-radius:10px; overflow:hidden;
}
.ch-intro .ch-row.key{ border-left:0; padding-left:14px; }
.ch-intro .ch-row.key:last-child{ border-bottom:0; }

/* The intro chapters belong to step one: same red, attached underneath. */
.ch-row.key{ background:var(--blood-soft); border-left:3px solid var(--blood); padding-left:13px; }
.ch-row.key:hover{ background:rgba(212,84,74,.2); }
.ch-row.key[aria-current="true"]{ background:rgba(212,84,74,.28); box-shadow:none; }

.ch-time{
  flex:none; width:44px; font-size:13.5px; font-weight:650; color:var(--gold);
  font-variant-numeric:tabular-nums;
}
.ch-label{ font-size:14.5px; font-weight:600; line-height:1.3; }

/* empty / pending states */
.empty{
  border:1px dashed var(--line); border-radius:var(--r);
  background:var(--surface); padding:52px 24px; text-align:center;
}
.empty svg{ color:#453b2a; margin-bottom:12px; }
.empty b{ display:block; font-size:15px; font-weight:650; color:var(--text-2); margin-bottom:6px; }
.empty p{ margin:0 auto; max-width:44ch; font-size:13px; color:var(--text-3); line-height:1.6; }
.empty .btn{ margin-top:18px; }

/* The description box, shaped like YouTube's: the facts on the first lines,
   the rest behind "...more". */
.desc{
  margin-top:26px; max-width:880px;
  border-radius:12px; background:var(--raised);
  font-size:13.5px; line-height:1.6; color:var(--text-2);
}
.desc summary{
  display:block; list-style:none; cursor:pointer;
  padding:12px 15px 11px; border-radius:12px;
}
.desc summary::-webkit-details-marker{ display:none; }
.desc:not([open]) summary:hover{ background:var(--hover); }
.desc summary:focus-visible{ outline:2px solid var(--gold); outline-offset:2px; }
.desc-line{ display:block; }
/* Closed, each line stays on one line and trails off — as YouTube's does — so
   the box is the same height for every monster. Nine locations would
   otherwise wrap to three lines and push "...more" below the fold on exactly
   the guides that have the most to show. Opening it lets every line wrap. */
.desc:not([open]) .desc-line{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.desc-line b{ color:var(--text); font-weight:650; }
.desc-more{ display:block; margin-top:3px; font-weight:700; color:var(--text); }
.desc[open] .desc-more{ display:none; }
.desc-body{ padding:0 15px 13px; }
.desc-body p{ margin:0 0 10px; color:var(--text-2); }
.desc-less{
  padding:0; border:0; background:none; cursor:pointer;
  font:inherit; font-weight:700; color:var(--text);
}
.desc-less:hover{ text-decoration:underline; }

/* ==========================================================================
   Command palette
   ========================================================================== */

.palette-backdrop{
  position:fixed; inset:0; z-index:210; display:none;
  background:rgba(10,8,6,.72); backdrop-filter:blur(3px);
  align-items:flex-start; justify-content:center; padding:11vh 18px 18px;
}
.palette-backdrop.open{ display:flex; }

.palette{
  width:100%; max-width:620px; max-height:72vh;
  background:var(--surface); border:1px solid var(--line); border-radius:14px;
  box-shadow:0 24px 70px rgba(0,0,0,.6); overflow:hidden;
  display:flex; flex-direction:column;
}
.palette-input-row{
  display:flex; align-items:center; gap:11px;
  padding:14px 16px; border-bottom:1px solid var(--line);
}
.palette-input-row svg{ flex:none; color:var(--text-3); }
.palette-input-row input{
  flex:1; min-width:0; background:none; border:0; outline:none;
  color:var(--text); font-family:inherit; font-size:15.5px;
}
.palette-input-row input::placeholder{ color:var(--text-3); }

.palette-results{ overflow-y:auto; flex:1; padding:6px; }
.p-group{
  padding:9px 11px 5px; font-size:11px; font-weight:700;
  color:var(--text-3); letter-spacing:.03em;
}
.p-item{
  display:flex; align-items:center; gap:10px; width:100%;
  padding:8px 11px; border-radius:var(--r-sm); border:0; background:none;
  cursor:pointer; text-align:left; color:var(--text-2); text-decoration:none;
}
.p-item[data-active="true"]{ background:var(--gold-soft); color:var(--text); }
.p-item .dot{ margin:0; }
.dot.hollow{ background:none; box-shadow:inset 0 0 0 1.5px var(--text-3); }
.p-name{ flex:1; min-width:0; font-size:13.5px; font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.p-name mark{ background:none; color:var(--gold); font-weight:750; }
.p-hint{ flex:none; font-size:11.5px; color:var(--text-3); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:46%; }
.p-empty{ padding:34px 16px; text-align:center; color:var(--text-3); font-size:13px; line-height:1.6; }
.palette-foot{
  flex:none; display:flex; gap:14px; align-items:center; flex-wrap:wrap;
  padding:9px 15px; border-top:1px solid var(--line-soft);
  background:var(--ink); font-size:11.5px; color:var(--text-3);
}
.palette-foot span{ display:inline-flex; align-items:center; gap:5px; }

/* ==========================================================================
   Lightbox
   ========================================================================== */

.lightbox{
  position:fixed; inset:0; z-index:220; display:none;
  background:rgba(8,6,4,.95); align-items:center; justify-content:center; padding:24px;
}
.lightbox.open{ display:flex; }
.lightbox img{
  max-width:96vw; max-height:92vh; object-fit:contain; border-radius:8px;
  box-shadow:0 20px 60px rgba(0,0,0,.7);
}
.lightbox-close{
  position:absolute; top:16px; right:18px; width:40px; height:40px; border-radius:50%;
  background:var(--raised); border:1px solid var(--line); color:var(--text);
  cursor:pointer; display:flex; align-items:center; justify-content:center;
}
.lightbox-close:hover{ background:var(--hover); }
.lightbox-cap{
  position:absolute; bottom:20px; left:50%; transform:translateX(-50%);
  font-size:12.5px; color:var(--text-2); background:var(--surface);
  border:1px solid var(--line); padding:6px 14px; border-radius:16px;
  max-width:80vw; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}

/* toast */
.toast{
  position:fixed; bottom:22px; left:50%; transform:translate(-50%,14px);
  z-index:240; padding:9px 18px; border-radius:22px;
  background:var(--raised); border:1px solid var(--jade); color:var(--text);
  font-size:13px; font-weight:600; opacity:0; pointer-events:none;
  transition:opacity .18s var(--ease), transform .18s var(--ease);
}
.toast.show{ opacity:1; transform:translate(-50%,0); }

/* ==========================================================================
   Responsive
   ========================================================================== */

@media (max-width:1080px){
  .guide-grid{ grid-template-columns:1fr; max-width:none; }

  /* Stacked, the chapter list has no player beside it to take its height from.
     The wide layout gives it height:0 + min-height:100% so the 4:3 player alone
     sizes the row — here that resolved to zero and the box vanished, rows and
     all. Underneath the video it just takes the height of its own content and
     the page scrolls, rather than nesting a scroll area inside a scroll area on
     a touch screen. */
  .chapters{ height:auto; min-height:0; }
  /* flex:1 gives a zero basis and grows to fill the parent — but here the
     parent is sized by its content, so the two never resolve and the list is
     clipped. flex:none makes the list its own height and the box follows. */
  .chapters-scroll{ flex:none; overflow:visible; }
  /* Was max-height:320px, from when the stacked list was a short scroll area.
     It now sits under the video at its own height and the page scrolls, so a
     cap would just hide the later locations behind a nested scrollbar. */
  .chapters{ max-height:none; }
}

@media (max-width:840px){
  .promo,
  .page-actions .btn-dps{ display:none; }

  .home{ padding:34px 18px 60px; }
  .detail-head,.tabs-row,.panel{ padding-left:16px; padding-right:16px; }
  .help-pop{ left:10px; }
  .grid{ grid-template-columns:repeat(auto-fill,minmax(150px,1fr)); gap:11px; }
  .frame img.shot{ max-height:none; }
  .palette-backdrop{ padding:6vh 12px 12px; }
  .palette-foot{ display:none; }
}

@media (max-width:900px){
  /* One column: the buttons and choices first, then the three pictures, full
     width. The choices read the usual way round again, label first. */
  .qs-grid{ grid-template-columns:minmax(0,1fr); }
  .qs-aside,
  .qs-gear,
  .qs-shot{ grid-column:1; grid-row:auto; }
  .page-actions{ justify-content:flex-end; }
  /* No room to line these up with a monster page's buttons, so the
     homepage's go; Support is a tap away on every guide. */
  .home-actions{ display:none; }
}
/* Below 1280px there is no spare width beside the player, so the buttons take
   a line above it, still right-aligned — the height the homepage puts its own
   Support and DPS at in this layout. */
@media (max-width:1279px){
  .guide-wrap{ grid-template-columns:minmax(0,1fr); }
  .guide-wrap > .page-actions{ grid-column:1; grid-row:1; }
  .guide-wrap > .guide-grid{ grid-row:2; }
}
@media (max-width:560px){
  .qs-controls{ grid-template-columns:minmax(0,1fr); gap:8px; }
  /* A long name wraps on a phone, so opening from its end would run off the
     screen. Open from its start instead; the pointer is dropped, since it
     would no longer line up with the button. */
  .name-wrap .help-pop{ left:0; }
  .name-wrap .help-pop::before{ display:none; }
}

@media (max-width:520px){
  /* The header has no room at this width, so the control moves into the page:
     .detail-head is a wrapping flex row, and margin-left:auto puts it at the
     top right, level with the monster name and under the search bar. */
  .donate{ display:none; }
  /* Even without the shortcut hint there is only room for about two thirds of
     "Search monsters or locations" on a phone, so swap in wording that fits
     rather than ellipsizing it. The button's aria-label is unchanged. */
  .search-trigger > .search-label{ display:none; }
  .search-trigger > .search-label-sm{
    display:block; flex:1 1 auto; min-width:0; font-size:13px;
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  }
}

@media (max-width:460px){
  .hero-search input{ height:50px; font-size:15px; padding-right:16px; }
  .hero-search .kbd{ display:none; }
  .page-actions{ justify-content:flex-end; }
}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important; animation-iteration-count:1 !important;
    transition-duration:.01ms !important; scroll-behavior:auto !important;
  }
  .card:hover{ transform:none; }
  .card:hover .card-thumb img{ transform:none; }
}

@media print{
  .header,.sidebar,.az-flyout,.tabs-row,.page-actions,.zoom-btn,.desc-more,.desc-less{ display:none !important; }
  body{ background:#fff; color:#000; }
}
