/* ============================================================================
 *  KAMPUNG BUGS — features.css
 *  Everything added by phases 1-7: the shutter, energy, bosses, restoration,
 *  the profile, the Lepak Corner, settings, and the rank-up beetle.
 * ==========================================================================*/

/* ---------------------------------------------------------- ART SIZING */
.bug-art{ display:block; }
.gear-art{ display:block; }
.bugchip{ padding:2px; }
.bugchip.is-boss{ box-shadow:0 0 0 1px var(--accent) inset; }
.bugchip.is-titan{ box-shadow:0 0 0 1px var(--hot) inset; }
.bugchip.is-shiny,.bugchip.is-prismatic{ box-shadow:0 0 0 1px #7fd8e8 inset; }

.card-icon{ display:grid; place-items:center; width:44px; height:44px; flex:0 0 auto;
  border-radius:10px; background:rgba(255,255,255,.05); border:1px solid var(--line); }
.card header{ align-items:center; gap:10px; }
.card-head-text{ display:flex; flex-direction:column; gap:3px; min-width:0; flex:1 1 auto; }
.card-head-text h4{ margin:0; }
.card-head-text .price{ align-self:flex-start; }

.tinytag{ font-size:.6rem; font-weight:800; letter-spacing:.1em; text-transform:uppercase;
  padding:1px 5px; border-radius:4px; background:rgba(255,255,255,.08); color:var(--dim);
  vertical-align:middle; }
.tinytag.boss{ background:rgba(243,182,74,.18); color:var(--accent); }
.tinytag.titan{ background:rgba(226,87,76,.18); color:var(--hot); }
.shinytick{ color:#7fd8e8; font-weight:700; }
.shinytick.prism{ color:#e0a3ff; }

/* --------------------------------------------------------- TOP BAR ADD */
.tval.energy{ display:inline-flex; align-items:center; gap:5px; }
.tval.energy .ui-svg{ color:var(--good); }
.tval.energy i{ font-style:normal; color:var(--dimmer); font-weight:500; font-size:.82rem; }
.tval.energy.is-empty .ui-svg{ color:var(--bad); }
.place-clock .flip{ font-style:normal; color:var(--dimmer); font-size:.78rem;
  margin-left:6px; padding-left:8px; border-left:1px solid var(--line2); }
.place-rain em{ font-style:normal; font-size:.66rem; text-transform:uppercase;
  letter-spacing:.1em; opacity:.75; }

/* ---------------------------------------------------------- SLOT ICONS */
.slot-row{ display:flex; align-items:center; gap:8px; }
.slot-icon{ display:grid; place-items:center; width:38px; height:38px; flex:0 0 auto;
  border-radius:8px; background:rgba(0,0,0,.28); border:1px solid var(--line); }
.slot-row select{ flex:1 1 auto; min-width:0; }

/* -------------------------------------------------------------- ENERGY */
/* ------------------------------------------------------------- SHUTTER */
.shutter{
  position:relative; display:block; width:100%; border:0; cursor:pointer;
  padding:24px 18px; border-radius:var(--radius); overflow:hidden;
  background:radial-gradient(circle at 50% 36%, #2c4d43, #142c26 72%);
  border:1px solid var(--line2); color:var(--text); margin-bottom:14px; transition:.2s;
}
.shutter:hover:not(:disabled){ border-color:var(--accent); transform:translateY(-2px);
  box-shadow:0 12px 30px rgba(243,182,74,.16); }
.shutter.is-disabled,.shutter:disabled{ opacity:.55; cursor:not-allowed; }
.shutter.is-field{ background:radial-gradient(circle at 50% 36%, #3a4258, #171f2e 72%); }
.shutter-ring{ position:absolute; inset:50% auto auto 50%; width:120px; height:120px;
  margin:-60px 0 0 -60px; border-radius:50%; border:2px solid rgba(243,182,74,.45);
  opacity:0; pointer-events:none; }
.shutter-flash{ position:absolute; inset:0; background:#fff; opacity:0; pointer-events:none; }
.shutter.is-shooting .shutter-ring{ animation:sring 780ms ease-out 1; }
.shutter.is-shooting .shutter-flash{ animation:sflash 780ms ease-out 1; }
.shutter.is-shooting .shutter-brackets i{ animation:sbracket 780ms cubic-bezier(.3,.8,.3,1) 1; }
@keyframes sring{ 0%{ transform:scale(.5); opacity:.9; } 100%{ transform:scale(2.4); opacity:0; } }
@keyframes sflash{ 0%,58%{ opacity:0; } 64%{ opacity:.68; } 100%{ opacity:0; } }
.shutter-face{ position:relative; display:flex; flex-direction:column;
  align-items:center; gap:6px; }
.shutter-face .ui-svg{ color:var(--accent); }
.shutter-face b{ font-size:1.12rem; font-weight:800; letter-spacing:.05em; }
.shutter-face i{ font-style:normal; font-size:.8rem; color:var(--dim); }
.shutter-brackets{ position:absolute; inset:-10px -14px; pointer-events:none; }
.shutter-brackets i{ position:absolute; width:16px; height:16px;
  border:2px solid rgba(243,182,74,.5); }
.shutter-brackets i:nth-child(1){ top:0; left:0; border-right:0; border-bottom:0; }
.shutter-brackets i:nth-child(2){ top:0; right:0; border-left:0; border-bottom:0; }
.shutter-brackets i:nth-child(3){ bottom:0; left:0; border-right:0; border-top:0; }
.shutter-brackets i:nth-child(4){ bottom:0; right:0; border-left:0; border-top:0; }
@keyframes sbracket{ 0%{ transform:scale(1.5); opacity:0; } 40%{ opacity:1; }
  62%{ transform:scale(.86); } 100%{ transform:scale(1); opacity:1; } }

/* ------------------------------------------------------- RESULT ADDONS */
.res-tag.var{ background:#7fd8e8; color:#06222a; margin-left:5px; }
.result.is-shiny{ box-shadow:0 0 0 1px rgba(127,216,232,.45) inset; }
.result.is-prismatic{ box-shadow:0 0 0 1px rgba(224,163,255,.55) inset; }
.j-shiny{ display:inline-block; font-size:.62rem; font-weight:800; letter-spacing:.12em;
  background:#7fd8e8; color:#06222a; padding:1px 6px; border-radius:4px; margin-right:5px; }
.j-shiny.prism{ background:#e0a3ff; color:#2a0a3a; }
.j-boss{ display:inline-block; font-size:.62rem; font-weight:800; letter-spacing:.12em;
  background:var(--accent); color:#1a1305; padding:1px 6px; border-radius:4px; margin-right:5px; }
.j-titan{ display:inline-block; font-size:.62rem; font-weight:800; letter-spacing:.12em;
  background:var(--hot); color:#fff; padding:1px 6px; border-radius:4px; margin-right:5px; }
.j-restore{ border-left-color:#c9873f; }

/* ------------------------------------------------- BOSS / TITAN STRIPS */
.bossstrip,.titanstrip{ display:flex; align-items:center; gap:14px;
  background:linear-gradient(100deg, rgba(243,182,74,.10), rgba(0,0,0,.2));
  border:1px solid rgba(243,182,74,.3); border-radius:var(--radius);
  padding:12px 16px; margin-bottom:16px; }
.titanstrip{ background:linear-gradient(100deg, rgba(226,87,76,.10), rgba(0,0,0,.2));
  border-color:rgba(226,87,76,.3); }
.bossstrip.is-due{ border-color:var(--accent); box-shadow:0 0 22px rgba(243,182,74,.16); }
.titanstrip.is-live{ border-color:var(--hot); box-shadow:0 0 22px rgba(226,87,76,.16); }
/* Last thing in the setup panel now -- under the type chart, which is the
   chart it is asking you to get right -- so its own bottom margin would be
   padding the panel twice. */
.setup-panel .bossstrip{ margin:14px 0 0; }
.boss-art{ flex:0 0 auto; display:grid; place-items:center; width:52px; height:52px;
  border-radius:12px; background:rgba(0,0,0,.3); border:1px solid var(--line); }
.boss-body{ flex:1 1 auto; min-width:0; }
.boss-label{ display:inline-flex; align-items:center; gap:5px; font-size:.66rem;
  font-weight:800; letter-spacing:.13em; text-transform:uppercase; color:var(--accent); }
.titanstrip .boss-label{ color:var(--hot); }
.boss-label em{ font-style:normal; color:var(--good); letter-spacing:.04em; }
.boss-body b{ display:block; font-size:1rem; margin:2px 0 5px; }
.boss-body small{ color:var(--dim); font-size:.79rem; }
.boss-bar{ height:5px; border-radius:99px; background:rgba(255,255,255,.08);
  overflow:hidden; margin-bottom:5px; max-width:340px; }
.boss-bar i{ display:block; height:100%; border-radius:99px;
  background:linear-gradient(90deg,var(--accent),var(--accent2)); transition:width .4s ease; }
/* ------------------------------------------- ATTRACTION HOVER CARD */
/* A heading that carries a control needs a row of its own — .panel h3 is
   already a flex box, but putting the pip inside it would put a <table>
   inside an <h3>. */
.panel-head{ position:relative; display:flex; align-items:center; gap:8px;
  margin:0 0 .4em; }
.panel-head h3{ margin:0; }

/* Stretched to the full height of the heading row on purpose: the card
   hangs off the row's bottom edge, and a pointer travelling from the pip
   down to the card has to stay inside .headpop the whole way or the hover
   ends halfway. */
.headpop{ align-self:stretch; display:inline-flex; align-items:center; }
.headpop-btn{ position:relative; display:grid; place-items:center; width:26px; height:26px;
  padding:0; border-radius:50%; cursor:pointer; color:var(--dimmer); transition:.16s;
  border:1px solid var(--line2); background:rgba(0,0,0,.24); }
.headpop-btn .ui-svg{ display:block; }
/* The card hangs off the panel's left edge, not off this button, so without
   a notch there is nothing tying the two together. It sits in the 10px
   bridge below the pip, tip against the card's top edge. */
.headpop-btn::after{ content:''; position:absolute; top:calc(100% + 5px); left:50%;
  margin-left:-6px; border:6px solid transparent; border-top-width:0;
  border-bottom-color:var(--line2); opacity:0; transition:opacity .14s ease; }
.headpop:hover .headpop-btn::after,.headpop:focus-within .headpop-btn::after,
.headpop.is-open .headpop-btn::after{ opacity:1; }
.headpop:hover .headpop-btn,.headpop.is-open .headpop-btn{
  color:var(--accent); border-color:var(--accent); background:rgba(243,182,74,.12); }
.headpop-btn:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }

/* Anchored to the whole heading row rather than to the pip: the card is far
   wider than a 26px button, and the panel's own left edge is the one
   position that does not move when the heading text changes length.
   padding-top is the bridge the pointer crosses on the way down — a plain
   margin there would be a gap, and a gap is a mouseout. */
.headpop-card{ position:absolute; top:100%; left:0; z-index:20; padding-top:10px;
  opacity:0; visibility:hidden; transform:translateY(-4px);
  transition:opacity .14s ease, transform .14s ease, visibility 0s .14s; }
.headpop:hover .headpop-card,.headpop:focus-within .headpop-card,
.headpop.is-open .headpop-card{
  opacity:1; visibility:visible; transform:none; transition-delay:0s; }
/* Two widths. The spawn table is seven columns and wants 820 — at 720 the
   species name wrapped and every row went two lines tall, halving how much
   of it you can see. The type chart is three columns and would just be a
   lot of air at that width.
   Both fall back by subtracting the page gutter AND the panel's own
   padding on both sides: a card starts at the panel's content edge, so a
   width of just "viewport minus gutters" runs off the right of a phone by
   exactly that inset. */
.headpop-inner{ width:min(480px,
    calc(100vw - 2 * var(--shell-gutter) - 2 * clamp(14px,2vw,20px)));
  background:linear-gradient(170deg, var(--panel), var(--bg2));
  border:1px solid var(--line2); border-radius:var(--radius);
  box-shadow:0 18px 44px rgba(0,0,0,.55); padding:13px; }
.headpop-card.is-wide .headpop-inner{ width:min(820px,
    calc(100vw - 2 * var(--shell-gutter) - 2 * clamp(14px,2vw,20px))); }
.headpop-title{ display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  margin-bottom:10px; font-size:.98rem; font-weight:700; }
.headpop-title .ui-svg{ color:var(--accent); flex:0 0 auto; }
.headpop-title i{ font-style:normal; font-weight:400; font-size:.8rem; color:var(--dimmer); }
.headpop-card .dex-table{ font-size:.85rem; }
.headpop-card .c-name b,.headpop-card .c-name em{ white-space:nowrap; }

/* The catch dialog on a phone. .result stretches to fill its parent in the
   shot panel; in a modal there is nothing to fill, so it is pinned back to
   its own height. */
.catchpop{ margin-bottom:14px; }
/* The empty-frame card leads with its own "Empty frame" heading, which the
   dialog title has already said two lines above. The escape and catch
   cards head with the species instead, so they keep theirs. */
.catchpop .result.empty h4{ display:none; }
.catchpop .result{ flex:0 0 auto; }
.catchpop .result.catch{ background:linear-gradient(140deg,
    color-mix(in srgb, var(--fc) 16%, transparent), rgba(0,0,0,.25)); }
/* Capped so the card still ends above the fold when the camp is at scroll
   zero and the location panel has pushed the heading a long way down the
   page. Past that the table scrolls inside itself, under the pointer. */
.headpop-card .tablewrap{ max-height:min(44vh, 360px); overflow-y:auto; }

.ins-row.is-boss .c-name b{ color:var(--accent2); }
.ins-row.is-titan .c-name b{ color:#ff9d92; }
.splist li.boss .sp-name{ color:var(--accent2); }
.ad-meta .titan{ color:var(--hot); border-color:rgba(226,87,76,.4); }

/* --------------------------------------------------------- RESTORATION */
.track-hero{ border-left:4px solid var(--ac); }
.card.site{ border-left:3px solid var(--tc); }
.card.site.is-done{ border-color:rgba(95,208,138,.42); }
.site-place{ font-size:.75rem !important; color:var(--dimmer) !important;
  text-transform:uppercase; letter-spacing:.09em; font-weight:600; margin:0 !important; }
.stages{ list-style:none; margin:0; padding:0; display:grid; gap:4px; }
.stage{ display:grid; grid-template-columns:22px 1fr auto; gap:9px; align-items:center;
  padding:6px 8px; border-radius:7px; background:rgba(0,0,0,.2); font-size:.8rem; }
.stage-n{ display:grid; place-items:center; width:20px; height:20px; border-radius:50%;
  background:rgba(255,255,255,.07); font-size:.68rem; font-weight:700; color:var(--dimmer); }
.stage-body{ min-width:0; }
.stage-body b{ display:block; font-weight:600; }
.stage-body i{ font-style:normal; font-size:.73rem; color:var(--dimmer); }
.stage-cost{ font-size:.75rem; color:var(--accent2); font-variant-numeric:tabular-nums; }
.stage.is-done{ opacity:.62; }
.stage.is-done .stage-n{ background:rgba(95,208,138,.22); color:var(--good); }
.stage.is-done .stage-n::after{ content:'\2713'; }
.stage.is-done .stage-n{ font-size:.7rem; }
.stage.is-next{ background:rgba(243,182,74,.08); box-shadow:inset 0 0 0 1px rgba(243,182,74,.24); }
.stage.is-later{ opacity:.5; }
.site-stage{ font:700 6px var(--font); fill:#fff; pointer-events:none; }
.site{ cursor:pointer; }
.site .site-dot{ transition:.18s; }
.site:hover .site-dot{ fill-opacity:.9; filter:drop-shadow(0 0 6px currentColor); }
.site.is-dim{ opacity:.3; }
.site.is-picked .site-dot{ stroke-width:3; }
.site:focus{ outline:none; }
.site:focus .site-dot{ stroke:#fff; stroke-width:3; }

/* ------------------------------------------------------------- PROFILE */
.hunter-card{ background:linear-gradient(140deg, rgba(243,182,74,.10), var(--bg2) 60%);
  border-color:rgba(243,182,74,.28); }
.hc-top{ display:flex; align-items:center; gap:16px; flex-wrap:wrap; }
.hc-badge{ position:relative; display:grid; place-items:center; width:66px; height:66px;
  border-radius:16px; flex:0 0 auto; color:#1a1305;
  background:linear-gradient(140deg,var(--accent2),var(--accent));
  box-shadow:0 6px 18px rgba(243,182,74,.28); }
.hc-badge span{ position:absolute; bottom:6px; right:8px; font-size:.72rem; font-weight:800; }
.hc-id{ flex:1 1 12rem; min-width:0; }
.hc-id h2{ margin-bottom:2px; }
.hc-code{ font-size:.78rem; color:var(--dimmer); margin:4px 0 0; }
.hc-code b{ font-family:ui-monospace,Menlo,Consolas,monospace; color:var(--text);
  letter-spacing:.08em; }
/* Sits on the code it copies rather than in the card header, so the button is
   read as belonging to that one string. */
.hc-copy{ display:inline-grid; place-items:center; width:24px; height:24px;
  margin-left:6px; vertical-align:-7px; border-radius:7px; cursor:pointer;
  color:var(--dimmer); border:1px solid var(--line); background:rgba(0,0,0,.24);
  transition:.16s; }
.hc-copy:hover{ color:var(--text); border-color:var(--accent); }
.hc-copy:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }
.hc-stats{ display:grid; grid-template-columns:repeat(auto-fit,minmax(88px,1fr));
  gap:8px; margin-top:16px; }
.hc-stats div{ background:rgba(0,0,0,.24); border:1px solid var(--line);
  border-radius:10px; padding:10px 8px; text-align:center; }
.hc-stats b{ display:block; font-size:1.15rem; font-variant-numeric:tabular-nums; }
.hc-stats span{ font-size:.68rem; text-transform:uppercase; letter-spacing:.1em;
  color:var(--dimmer); }

.showcase{ display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:10px; }
.show-slot{ position:relative; display:flex; flex-direction:column; align-items:center;
  gap:5px; padding:14px 10px; border-radius:var(--radius-s); cursor:pointer;
  border:1px solid var(--line); background:rgba(0,0,0,.22); color:var(--text);
  font-family:var(--font); transition:.16s; text-align:center; }
.show-slot:hover{ border-color:var(--fc,var(--accent)); transform:translateY(-2px); }
.show-slot b{ font-size:.86rem; line-height:1.25; }
.show-slot i{ font-style:normal; font-size:.72rem; color:var(--dimmer); }
.show-slot .slot-art{ color:var(--fc); }
.show-slot.is-empty{ border-style:dashed; color:var(--dimmer); min-height:132px;
  justify-content:center; }
.slot-plus{ font-size:1.8rem; line-height:1; color:var(--dimmer); }
.slot-lbl{ font-size:.74rem; }
.slot-var{ position:absolute; top:6px; right:6px; font-size:.58rem; font-weight:800;
  letter-spacing:.09em; text-transform:uppercase; padding:2px 5px; border-radius:4px;
  background:#7fd8e8; color:#06222a; }
.slot-var.prismatic{ background:#e0a3ff; color:#2a0a3a; }
.slot-var.boss{ background:var(--accent); color:#1a1305; }
.slot-var.titan{ background:var(--hot); color:#fff; }
.bestrec{ display:flex; align-items:center; gap:14px; }
.bestrec b{ display:block; font-size:1rem; }
.bestrec span{ font-size:.82rem; color:var(--dimmer); }

.pickgrid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(116px,1fr));
  gap:8px; max-height:52vh; overflow-y:auto; margin-bottom:12px; }
.pick{ display:flex; flex-direction:column; align-items:center; gap:3px; padding:9px 6px;
  border-radius:9px; border:1px solid var(--line); background:rgba(0,0,0,.22);
  color:var(--text); cursor:pointer; font-family:var(--font); transition:.14s;
  text-align:center; }
.pick:hover{ border-color:var(--fc); }
.pick.is-on{ border-color:var(--fc); background:color-mix(in srgb, var(--fc) 18%, transparent); }
.pick b{ font-size:.74rem; line-height:1.2; }
.pick i{ font-style:normal; font-size:.68rem; color:var(--dimmer); }

/* -------------------------------------------------------- LEPAK CORNER */
.sim-banner{ display:flex; gap:14px; align-items:flex-start;
  border-left:3px solid var(--hot); background:rgba(226,87,76,.08); }
.sim-banner .ui-svg{ color:var(--hot); flex:0 0 auto; margin-top:2px; }
.sim-banner b{ display:block; margin-bottom:4px; }
.sim-banner p{ color:var(--dim); font-size:.88rem; margin:0; max-width:76ch; }
.lepak-grid{ display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:16px;
  align-items:start; }
@media(max-width:940px){ .lepak-grid{ grid-template-columns:1fr; } }
.mecard b{ font-size:1.05rem; }
.mecard i{ display:block; font-style:normal; color:var(--dim); font-size:.84rem; }
.party-panel.is-live{ border-color:rgba(226,87,76,.4); }
.party{ display:grid; gap:6px; margin-bottom:10px; }
.pmember{ display:flex; align-items:center; gap:9px; padding:8px 10px; border-radius:8px;
  background:rgba(0,0,0,.22); font-size:.87rem; }
.pmember .ui-svg{ color:var(--accent); flex:0 0 auto; }
.pmember i{ font-style:normal; color:var(--dimmer); font-size:.76rem; margin-left:auto; }
.pmember.is-me{ box-shadow:inset 0 0 0 1px rgba(243,182,74,.3); }
.titan-note{ display:flex; gap:9px; align-items:flex-start; margin-top:10px; padding:10px 12px;
  border-radius:8px; background:rgba(0,0,0,.24); font-size:.82rem; color:var(--dim); }
.titan-note .ui-svg{ color:var(--dimmer); flex:0 0 auto; }
.titan-note.is-live{ background:rgba(226,87,76,.1); color:var(--text); }
.titan-note.is-live .ui-svg{ color:var(--hot); }

.addfriend{ display:flex; gap:7px; margin-bottom:10px; }
.addfriend input,.chatform input{ flex:1 1 auto; min-width:0; padding:9px 11px;
  border-radius:8px; border:1px solid var(--line2); background:var(--panel2);
  color:var(--text); font:500 .88rem var(--font); }
.suggestions{ display:flex; flex-wrap:wrap; gap:6px; margin-bottom:12px; }
.sug{ display:flex; flex-direction:column; align-items:flex-start; padding:6px 10px;
  border-radius:7px; border:1px dashed var(--line2); background:transparent;
  color:var(--text); cursor:pointer; font-family:var(--font); transition:.14s; }
.sug:hover{ border-style:solid; border-color:var(--accent); }
.sug b{ font-size:.8rem; }
.sug i{ font-style:normal; font-size:.68rem; color:var(--dimmer);
  font-family:ui-monospace,Menlo,Consolas,monospace; }
.friendlist{ display:grid; gap:5px; }
.friend{ display:flex; align-items:center; gap:9px; padding:8px 10px; border-radius:8px;
  background:rgba(0,0,0,.2); }
.presence{ width:8px; height:8px; border-radius:50%; background:var(--lock); flex:0 0 auto; }
.friend.is-online .presence{ background:var(--good); box-shadow:0 0 8px rgba(95,208,138,.7); }
.friend-body{ flex:1 1 auto; min-width:0; }
.friend-body b{ display:block; font-size:.88rem; }
.friend-body i{ font-style:normal; font-size:.74rem; color:var(--dimmer); }

.chat-panel{ display:flex; flex-direction:column; min-height:420px; }
.chatlog{ flex:1 1 auto; overflow-y:auto; max-height:400px; display:flex;
  flex-direction:column; gap:6px; padding:4px 2px 10px; }
.msg{ max-width:86%; padding:7px 11px; border-radius:12px; font-size:.86rem;
  background:rgba(255,255,255,.05); border:1px solid var(--line); align-self:flex-start; }
.msg.is-mine{ align-self:flex-end; background:rgba(243,182,74,.13);
  border-color:rgba(243,182,74,.28); }
.msg.is-system{ align-self:center; background:transparent; border:0; color:var(--dimmer);
  font-size:.76rem; font-style:italic; }
.msg-who{ display:block; font-size:.68rem; font-weight:700; letter-spacing:.06em;
  text-transform:uppercase; color:var(--dimmer); margin-bottom:2px; }
.msg.is-mine .msg-who{ color:var(--accent); }
.chatform{ display:flex; gap:7px; margin-top:8px; }
.chatfoot{ display:flex; align-items:center; gap:10px; margin-top:8px; flex-wrap:wrap; }
.chatfoot .dim{ font-size:.74rem; flex:1 1 14rem; }

/* ---------------------------------------------- LEPAK CORNER, LIVE [0010] */
/* The green twin of .sim-banner. They say opposite things and are never on
   screen together: one means these hunters are invented, the other means
   they can read what you type. */
.live-banner{ display:flex; gap:14px; align-items:flex-start;
  border-left:3px solid var(--good); background:rgba(95,208,138,.07); }
.live-banner .ui-svg{ color:var(--good); flex:0 0 auto; margin-top:2px; }
.live-banner b{ display:block; margin-bottom:4px; }
.live-banner p{ color:var(--dim); font-size:.88rem; margin:0; max-width:76ch; }
.live-banner p.warn{ margin-top:6px; }

.tiny-note{ font-size:.74rem; line-height:1.5; margin:6px 0 0; max-width:60ch; }
.cornercount{ display:flex; align-items:center; gap:7px; margin:10px 0 0;
  font-size:.8rem; color:var(--dim); }
.cornercount .ui-svg{ color:var(--dimmer); flex:0 0 auto; }
.cornercount b{ color:var(--good); }

/* Something is waiting on an answer, so it is not a panel to slide past. */
.req-panel{ border-color:rgba(243,182,74,.4); background:rgba(243,182,74,.05); }
.req-panel .friend{ background:rgba(0,0,0,.18); }

.tinytag.lead{ background:rgba(243,182,74,.18); color:var(--accent); }
.pmember .tinytag,.pmember .btn{ flex:0 0 auto; margin-left:6px; }
.pmember i{ flex:1 1 auto; text-align:right; }
.pmember.is-pending{ opacity:.62; border:1px dashed var(--line2); background:transparent; }
.friend .tinytag{ flex:0 0 auto; }

.sug-label{ font-size:.72rem; color:var(--dimmer); margin:0 0 5px;
  text-transform:uppercase; letter-spacing:.08em; font-weight:700; }
.sug b{ display:flex; align-items:center; gap:5px; }
.dot-on{ width:6px; height:6px; border-radius:50%; background:var(--good);
  display:inline-block; box-shadow:0 0 6px rgba(95,208,138,.7); }

.sentlist{ display:grid; gap:4px; margin-bottom:10px; }
.sentrow{ display:flex; align-items:center; gap:8px; padding:6px 10px; border-radius:7px;
  border:1px dashed var(--line2); font-size:.78rem; color:var(--dim); }
.sentrow span{ flex:1 1 auto; min-width:0; }
.sentrow b{ color:var(--text); }

.blocklist{ display:flex; align-items:center; gap:6px; flex-wrap:wrap; margin-top:8px;
  font-size:.74rem; }

/* Report and Block hide until the message is under the pointer — they are
   for the rare bad message, not decoration on every good one. Always visible
   to the keyboard, though, which cannot hover. */
.msg{ position:relative; }
.msg-acts{ position:absolute; top:-9px; right:6px; display:flex; gap:4px; opacity:0;
  transition:opacity .14s; pointer-events:none; }
.msg:hover .msg-acts,.msg-acts:focus-within{ opacity:1; pointer-events:auto; }
.msg-acts button{ font:700 .62rem var(--font); letter-spacing:.05em; text-transform:uppercase;
  padding:2px 6px; border-radius:5px; cursor:pointer; color:var(--dimmer);
  border:1px solid var(--line2); background:var(--panel2); }
.msg-acts button:hover{ color:var(--hot); border-color:var(--hot); }
.msg-acts button:focus-visible{ outline:2px solid var(--accent); outline-offset:1px; }
.msg-who em{ font-style:normal; font-weight:500; letter-spacing:0; text-transform:none;
  color:var(--dimmer); margin-left:6px; }
/* On its way to the server. It is in the log because waiting a round trip to
   see your own sentence feels broken; the fade says it is not landed yet. */
.msg.is-pending{ opacity:.55; }

/* ------------------------------------------------------------ SETTINGS */
.opts{ display:grid; grid-template-columns:repeat(auto-fit,minmax(200px,1fr)); gap:8px; }
.opt{ display:flex; gap:9px; align-items:flex-start; padding:11px 13px; cursor:pointer;
  border-radius:var(--radius-s); border:1px solid var(--line); background:rgba(0,0,0,.2);
  transition:.16s; }
.opt:hover{ border-color:var(--line2); }
.opt.is-on{ border-color:var(--accent); background:rgba(243,182,74,.09); }
.opt input{ margin-top:3px; accent-color:var(--accent); flex:0 0 auto; }
.opt-body b{ display:block; font-size:.9rem; }
.opt-body i{ font-style:normal; font-size:.76rem; color:var(--dimmer); line-height:1.45; }
.rung-cap{ font-size:.74rem; color:var(--dimmer); font-variant-numeric:tabular-nums; }
.rung{ grid-template-columns:34px 1fr auto auto; }

/* ------------------------------------------------- RANK-UP BEETLE  [17] */
.rankup{ position:fixed; inset:0; z-index:120; display:none; align-items:center;
  justify-content:center; padding:20px; overflow-y:auto;
  background:radial-gradient(circle at 50% 40%, rgba(20,44,38,.94), rgba(4,10,9,.96));
  backdrop-filter:blur(6px); }
.rankup.is-open{ display:flex; }
.ru-box{ display:flex; flex-direction:column; align-items:center; gap:6px; text-align:center;
  margin:auto; }
.ru-beetle{ overflow:visible; }
.ru-beetle *{ transform-box:view-box; }
.ru-abdomen{ fill:#3a2a15; stroke:#150e05; stroke-width:2; }
.ru-thorax{ fill:#a86f22; stroke:#150e05; stroke-width:2.6; }
.ru-head{ fill:#8d5b1a; stroke:#150e05; stroke-width:2.6; }
.ru-horn{ fill:#c08a2e; stroke:#150e05; stroke-width:2.4; stroke-linejoin:round; }
.ru-ant{ fill:none; stroke:#150e05; stroke-width:3; stroke-linecap:round; }
.ru-elytra path{ fill:#d09330; stroke:#150e05; stroke-width:2.6; stroke-linejoin:round; }
.ru-elytra-r path{ fill:#c1852a; }
.ru-hind path{ fill:rgba(210,235,255,.5); stroke:rgba(255,255,255,.35); stroke-width:1.4; }

.ru-elytra,.ru-hind,.ru-plate{ transform-origin:100px 70px; }
.ru-hind{ transform:scale(.06) rotate(0deg); opacity:0; }
.ru-plate{ opacity:0; transform:scale(.7); transform-origin:100px 132px; }
.ru-plate circle{ fill:#1d3630; stroke:var(--accent); stroke-width:3; }
.ru-num{ fill:var(--accent2); font:800 34px var(--font); }

.rankup.is-playing .ru-elytra-l{ animation:ruElyL 900ms cubic-bezier(.22,.9,.3,1) 260ms both; }
.rankup.is-playing .ru-elytra-r{ animation:ruElyR 900ms cubic-bezier(.22,.9,.3,1) 260ms both; }
.rankup.is-playing .ru-hind-l{ animation:ruHindL 780ms cubic-bezier(.22,.9,.3,1) 520ms both; }
.rankup.is-playing .ru-hind-r{ animation:ruHindR 780ms cubic-bezier(.22,.9,.3,1) 520ms both; }
.rankup.is-playing .ru-plate{ animation:ruPlate 620ms cubic-bezier(.2,.9,.3,1.3) 780ms both; }
.rankup.is-playing .ru-copy{ animation:ruCopy 620ms ease 980ms both; }
.rankup.is-playing .ru-beetle{ animation:ruRise 700ms cubic-bezier(.2,.9,.3,1.1) both; }

@keyframes ruRise{ from{ opacity:0; transform:translateY(26px) scale(.9); }
                   to{ opacity:1; transform:none; } }
@keyframes ruElyL{ to{ transform:rotate(-62deg) translateY(-6px); } }
@keyframes ruElyR{ to{ transform:rotate(62deg) translateY(-6px); } }
@keyframes ruHindL{ from{ transform:scale(.06); opacity:0; }
                    to{ transform:scale(1) rotate(-8deg); opacity:1; } }
@keyframes ruHindR{ from{ transform:scale(.06); opacity:0; }
                    to{ transform:scale(1) rotate(8deg); opacity:1; } }
@keyframes ruPlate{ from{ opacity:0; transform:scale(.6); } to{ opacity:1; transform:scale(1); } }
@keyframes ruCopy{ from{ opacity:0; transform:translateY(12px); } to{ opacity:1; transform:none; } }

.ru-copy{ max-width:30rem; }
.ru-kicker{ display:block; font-size:.7rem; font-weight:800; letter-spacing:.24em;
  text-transform:uppercase; color:var(--accent); margin-bottom:4px; }
.ru-name{ font-size:clamp(1.7rem,5vw,2.5rem); font-weight:800; letter-spacing:-.02em;
  margin-bottom:6px; }
.ru-sub{ color:var(--dim); font-size:.92rem; margin-bottom:14px; }

/* reduced motion: no wing choreography, just a clean reveal */
.ru-box.is-reduced .ru-elytra-l{ transform:rotate(-62deg) translateY(-6px); }
.ru-box.is-reduced .ru-elytra-r{ transform:rotate(62deg) translateY(-6px); }
.ru-box.is-reduced .ru-hind{ transform:scale(1); opacity:1; }
.ru-box.is-reduced .ru-plate{ opacity:1; transform:scale(1); }
.rankup.is-playing .ru-box.is-reduced *{ animation:none !important; }
.ru-box.is-reduced{ animation:ruCopy 260ms ease both; }

/* The motion setting is gone and full motion is the default, so there is
   no data-motion attribute to key off any more — only the OS preference,
   which these named rules kill outright rather than leaving to the
   blanket animation-duration:.01ms in style.css. */
@media (prefers-reduced-motion: reduce){
  .shutter.is-shooting .shutter-ring,
  .shutter.is-shooting .shutter-flash,
  .shutter.is-shooting .shutter-brackets i,
  .town-pulse{ animation:none !important; }
}

/* ------------------------------------------------- RANK LADDER PAGE  [18] */
/* Rank reads as a sub-line under the hunter's name, not a chip of its own,
   so it is sized down and tinted rather than given a .tlabel of its own. */
.ranksub{
  display:block; margin:1px 0 0; padding:0; border:0; background:none;
  font:inherit; font-size:.78rem; font-weight:700; line-height:1.2;
  color:var(--accent); text-align:left; cursor:pointer;
  text-decoration:underline; text-decoration-color:rgba(243,182,74,.35);
  text-underline-offset:3px; border-radius:4px;
}
.ranksub:hover{ text-decoration-color:var(--accent); }
.ranksub:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }

.rankladder{ display:grid; gap:10px; }
.rankrung{
  border-radius:12px; padding:13px 15px;
  background:var(--panel); border:1px solid rgba(255,255,255,.06);
}
.rankrung.is-done{ opacity:.72; }
.rankrung.is-cur{ border-color:var(--accent); background:rgba(243,182,74,.08); }

.rankrung-h{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.rankrung-h .rung-name{ font-weight:700; font-size:1rem; }
.rankrung.is-cur .rung-n{ background:var(--accent); color:#1a1305; }
.rankrung.is-done .rung-n{ background:rgba(95,208,138,.2); color:var(--good); }

.rung-tag{
  margin-left:auto; font-size:.66rem; font-weight:700; letter-spacing:.07em;
  text-transform:uppercase; color:var(--accent);
  border:1px solid rgba(243,182,74,.4); border-radius:99px; padding:2px 9px;
}
.rung-tag.done{ color:var(--good); border-color:rgba(95,208,138,.35); }

/* A rung's unlocks read straight down: block under block, and inside a shop
   block, category under category. Nothing sits in a second column, so the eye
   only ever travels one direction. */
.rung-body{ display:grid; gap:8px; margin-top:11px; grid-template-columns:1fr; }
.rung-body:empty{ display:none; }
.unlock-block{ border:1px solid var(--line); border-radius:10px;
  background:rgba(0,0,0,.18); padding:9px 11px 10px;
  border-left:3px solid var(--sc,var(--line2)); }
.unlock-h{ display:flex; align-items:center; gap:6px; margin:0 0 7px;
  font-size:.74rem; font-weight:800; letter-spacing:.06em; text-transform:uppercase;
  color:var(--sc,var(--dim)); }
.unlock-h .ui-svg{ flex:0 0 auto; }

/* One supermarket inside the Supermarkets block: its own name, then its own
   categories. Indented and rule-marked so the nesting is visible without a
   second card border inside a card. */
.shop-group{ margin:8px 0 0; padding-left:10px;
  border-left:2px solid color-mix(in srgb, var(--sc,#8c8c8c) 55%, transparent); }
.shop-group:first-of-type{ margin-top:4px; }
.shop-name{ display:flex; align-items:baseline; gap:8px; flex-wrap:wrap; margin:0;
  font-size:.8rem; font-weight:700; color:var(--sc,var(--text)); }
.unlock-sub{ font-size:.66rem; font-weight:500; letter-spacing:.02em;
  text-transform:none; color:var(--dimmer); }

/* Fixed label column, so every category name in the rung starts at the same
   x and the lists all begin at the same x under them. */
.unlock-kind{ display:grid; grid-template-columns:7.5rem minmax(0,1fr);
  gap:3px 10px; align-items:baseline; margin-top:5px; }
.kind-lbl{ font-size:.68rem; text-transform:uppercase; letter-spacing:.08em;
  color:var(--dimmer); line-height:1.5; }

/* The list is the grid and each row is display:contents, which is what makes
   name / tag / price line up down the block instead of each row packing
   itself. Rows always emit all three cells; see row() in ui/rank.js. */
.unlock-list{ margin:0; padding:0; list-style:none; display:grid;
  grid-template-columns:minmax(0,1fr) auto auto; gap:3px 8px; align-items:baseline; }
.unlock-list li{ display:contents; }
.unlock-list .u-name{ font-size:.82rem; line-height:1.5; min-width:0;
  overflow-wrap:anywhere; }
.unlock-list b{ font-weight:600; }
.u-type{ justify-self:start; font-size:.62rem; text-transform:uppercase;
  letter-spacing:.07em; padding:1px 6px; border-radius:99px;
  color:var(--tc,var(--dimmer)); white-space:nowrap;
  border:1px solid color-mix(in srgb, var(--tc,#8c8c8c) 40%, transparent); }
.u-type.is-blank{ border:0; padding:0; }
.u-cost{ justify-self:end; font-size:.72rem; color:var(--dimmer);
  font-variant-numeric:tabular-nums; white-space:nowrap; }
.u-need{ grid-column:1 / -1; font-size:.68rem; color:var(--accent2); }

/* Show more / show less */
.rung-toggle{ display:inline-flex; align-items:center; gap:5px; cursor:pointer;
  padding:3px 9px; border-radius:99px; font-family:var(--font);
  font-size:.68rem; font-weight:700; letter-spacing:.06em; text-transform:uppercase;
  color:var(--dim); background:transparent; border:1px solid var(--line2);
  transition:.16s; }
.rankrung-h .rung-tag{ margin-left:0; }
.rankrung-h .rung-toggle{ margin-left:auto; }
.rung-toggle:hover{ color:var(--text); border-color:var(--accent); }
.rung-toggle:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }
.rung-toggle .ui-svg{ transition:transform .18s; }
.rankrung.is-open .rung-toggle .ui-svg{ transform:rotate(180deg); }
.rung-summary{ margin:8px 0 0; font-size:.78rem; color:var(--dimmer); }
.rankrung:not(.is-open) .rung-body{ display:none; }
.rankrung.is-open .rung-summary{ display:none; }
@media (prefers-reduced-motion:reduce){ .rung-toggle .ui-svg{ transition:none; } }

/* ------------------------------------------------ HUNTER ACCOUNT MENU [19] */
/* The hunter name in the header is the account menu: Profile, Settings and
   Log out. Opens on hover for pointers, on :focus-within for keyboards, and
   on .is-open which main.js toggles for touch, where hover never fires. */
.tstat-menu{ position:relative; display:flex; flex-direction:column;
  align-items:flex-start; }
.tstat-trigger{
  display:flex; flex-direction:column; align-items:flex-start;
  border:0; background:none; padding:0; margin:0; font:inherit; color:inherit;
  text-align:left; cursor:pointer; border-radius:6px;
}
.tstat-trigger:focus-visible{ outline:2px solid var(--accent); outline-offset:3px; }
.tcaret{ font-size:.62em; margin-left:5px; color:var(--dimmer); vertical-align:middle; }
.tstat-menu:hover .tval, .tstat-menu:focus-within .tval{ color:var(--accent); }
.tstat-menu:hover .tcaret, .tstat-menu:focus-within .tcaret{ color:var(--accent); }

.tmenu{
  position:absolute; top:100%; left:0; z-index:60; margin-top:8px;
  min-width:172px; padding:6px; display:none;
  background:var(--panel); border:1px solid rgba(255,255,255,.1);
  border-radius:10px; box-shadow:0 14px 34px rgba(0,0,0,.5);
}
/* A hover-opened menu needs an unbroken hit area between trigger and panel,
   or the 8px gap closes it as the pointer crosses. */
.tmenu::before{ content:''; position:absolute; left:0; right:0; top:-8px; height:8px; }
.tstat-menu:hover .tmenu,
.tstat-menu:focus-within .tmenu,
.tstat-menu.is-open .tmenu{ display:block; }

.tmenu-item{
  display:block; width:100%; text-align:left; cursor:pointer;
  padding:8px 11px; border:0; border-radius:7px; background:none;
  color:var(--text); font:inherit; font-size:.86rem; font-weight:600;
}
.tmenu-item:hover, .tmenu-item:focus-visible{ background:rgba(255,255,255,.07); outline:none; }
.tmenu-item.is-danger{ color:var(--bad); }
.tmenu-item.is-danger:hover{ background:rgba(233,90,90,.12); }

/* --------------------------------------------------- BUG INVENTORY  [20] */
.bugctls{ display:flex; flex-wrap:wrap; gap:12px; align-items:flex-end; margin-top:12px; }
.bugctl{ display:flex; flex-direction:column; gap:4px; font-size:.7rem;
  text-transform:uppercase; letter-spacing:.09em; color:var(--dimmer); font-weight:700; }
.bugctl select{
  background:rgba(0,0,0,.3); color:var(--text); font:inherit; font-size:.86rem;
  font-weight:500; text-transform:none; letter-spacing:0;
  border:1px solid rgba(255,255,255,.12); border-radius:8px; padding:7px 10px;
}
.bugctl select:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }

/* ------------------------------------------------------------- METRICS */
/* The dex table with two extra habits: any cell may carry a quiet second
   line, and the row that is you is marked so you do not read your own
   break-glass figures as somebody's real ones. */
.metrics-table{ min-width:940px; }
.metrics-table td em{ display:block; margin-top:2px; font-style:normal;
  font-size:.72rem; color:var(--dimmer); }
.metrics-table tr.is-me{ background:rgba(243,182,74,.07); }
.metrics-table tr.is-me td:first-child{ box-shadow:inset 3px 0 0 var(--accent); }
.metrics-table .tinytag{ margin-left:6px; }
.bugcount{ margin-left:auto; font-size:.78rem; color:var(--dimmer);
  font-variant-numeric:tabular-nums; }

.buggrid{
  display:grid; gap:12px; margin-top:14px;
  grid-template-columns:repeat(auto-fill, minmax(178px, 1fr));
}
.bugcard{
  position:relative; padding:12px; border-radius:12px;
  background:var(--panel); border:1px solid rgba(255,255,255,.07);
  border-top:3px solid var(--fc);
}
.bugcard.is-shiny{ box-shadow:0 0 0 1px rgba(243,182,74,.35); }
.bugcard.is-prismatic{ box-shadow:0 0 0 1px rgba(233,90,90,.45); }
.bugcard-top{ display:flex; align-items:flex-start; justify-content:space-between; }
.bugcard-art{ display:block; }
.bugcard h4{ margin:6px 0 1px; font-size:.9rem; line-height:1.25; }
.bugcard-fam{ margin:0; font-size:.7rem; color:var(--fc); font-weight:600;
  text-transform:uppercase; letter-spacing:.06em; }

/* Grade is the fastest read on the card, so it gets the strongest contrast. */
.buggrade{
  display:grid; place-items:center; width:25px; height:25px; flex:0 0 auto;
  border-radius:7px; font-size:.76rem; font-weight:800;
  background:rgba(255,255,255,.08); color:var(--dim);
}
.buggrade.g-C{ background:rgba(126,168,74,.22); color:#9fce62; }
.buggrade.g-B{ background:rgba(76,134,216,.22); color:#7fb0f0; }
.buggrade.g-A{ background:rgba(177,137,216,.24); color:#c9a6f0; }
.buggrade.g-S{ background:var(--accent); color:#1a1305; }

.bugstats{ display:grid; gap:3px; margin-top:9px; }
.bugstat{ display:flex; align-items:baseline; gap:6px; font-size:.72rem;
  color:var(--dimmer); text-transform:uppercase; letter-spacing:.05em; font-weight:600; }
.bugstat b{ margin-left:auto; font-size:.88rem; color:var(--text);
  font-variant-numeric:tabular-nums; letter-spacing:0; }
.bugstat b small{ font-size:.7em; color:var(--dimmer); font-weight:600; }
.bugstat i{ font-style:normal; font-size:.7rem; font-weight:700; letter-spacing:0;
  min-width:38px; text-align:right; }
.bugstat i.up{ color:var(--good); }
.bugstat i.down{ color:var(--bad); }

.bugvar{
  position:absolute; top:10px; left:10px;
  font-size:.6rem; font-weight:800; letter-spacing:.07em; text-transform:uppercase;
  padding:2px 7px; border-radius:99px;
}
.bugvar.shiny{ background:rgba(243,182,74,.9); color:#1a1305; }
.bugvar.prismatic{ background:linear-gradient(90deg,#f3b64a,#e95a5a,#7fb0f0); color:#120a0a; }

.bugcard-foot{ margin-top:9px; padding-top:8px; font-size:.7rem; color:var(--dimmer);
  border-top:1px solid rgba(255,255,255,.06); }

/* ------------------------------------------------- PAINTED SPECIES ART [21] */
/* Hand-painted icons sit where a generated SVG normally would, so they have to
   match its box exactly: same square, transparent ground, no baseline gap. */
.bugphoto{
  display:block; object-fit:contain; cursor:pointer;
  filter:drop-shadow(0 2px 4px rgba(0,0,0,.45));
  transition:transform .16s ease;
}
.bugphoto:hover{ transform:scale(1.07); }
/* The parametric art rotates hue for variants; this is the CSS equivalent, so
   a shiny painted species still reads as shiny. */
.bugphoto.is-shiny{ filter:drop-shadow(0 0 6px rgba(243,182,74,.65)) hue-rotate(35deg) saturate(1.4); }
.bugphoto.is-prismatic{ filter:drop-shadow(0 0 7px rgba(233,90,90,.7)) hue-rotate(155deg) saturate(1.9); }

.fullart{
  display:block; width:100%; height:auto; margin:4px 0 12px;
  border-radius:10px; border:1px solid var(--line);
}

/* ---------------------------------------------------- ICON PEEK  [22] */
/* Magnified preview floated on hover. pointer-events:none matters: without
   it the panel sits under the cursor it just appeared beneath, swallowing
   the click and flickering as the pointer enters and leaves it. */
.artpeek{
  position:fixed; z-index:200; display:none; pointer-events:none;
  padding:12px; border-radius:14px; text-align:center;
  background:linear-gradient(170deg, var(--panel), var(--bg2));
  border:1px solid var(--line2); box-shadow:0 20px 48px rgba(0,0,0,.62);
  animation:peekIn .13s ease-out;
}
.artpeek.is-on{ display:block; }
.artpeek img{
  /* 224 CSS px is exactly 448 device px on a 2x screen — a 1:1 match with
     the preview file, so it never has to invent pixels. */
  display:block; width:224px; height:224px; object-fit:contain;
  filter:drop-shadow(0 3px 8px rgba(0,0,0,.5));
}
.artpeek b{ display:block; margin-top:8px; font-size:.92rem; }
.artpeek i{ display:block; font-style:normal; font-size:.71rem; color:var(--dimmer);
  text-transform:uppercase; letter-spacing:.07em; font-weight:600; margin-top:2px; }

@keyframes peekIn{ from{ opacity:0; transform:translateY(4px) scale(.97); }
                   to{ opacity:1; transform:none; } }
@media (prefers-reduced-motion:reduce){ .artpeek{ animation:none; } }

/* Hovering already grows the icon slightly; keep that as the cue that it is
   interactive, but drop it on touch where the preview never appears. */
@media (hover:none){ .bugphoto:hover{ transform:none; } }

/* ------------------------------------------------------- SHOT LOG  [23] */
/* #resultSlot used to hold one card; it is now the whole log, newest first.
   Capped and scrollable so a long session cannot push the bait profile and
   the rest of the page off the bottom. */
.huntlog{
  max-height:min(56vh, 520px); overflow-y:auto; overscroll-behavior:contain;
  display:grid; gap:8px; padding-right:4px;
}
.huntlog::-webkit-scrollbar{ width:8px; }
.huntlog::-webkit-scrollbar-thumb{ background:rgba(255,255,255,.12); border-radius:99px; }
.huntlog::-webkit-scrollbar-track{ background:transparent; }

.logrow{ position:relative; }
.logtime{
  position:absolute; top:8px; right:10px;
  font-size:.68rem; color:var(--dimmer); font-variant-numeric:tabular-nums;
  pointer-events:none;
}

/* Rows that are not a catch or an escape — travel, rank-ups, purchases.
   Deliberately quieter than a result card so hunting stays the loud thing. */
.result.note{
  display:flex; align-items:baseline; gap:10px; flex-wrap:wrap;
  padding:9px 74px 9px 12px; border-radius:10px;
  background:rgba(255,255,255,.028); border:1px solid var(--line);
  font-size:.84rem; color:var(--dim);
}
.result.note .jtext{ flex:1 1 auto; min-width:0; }
.result.note .jplace{ font-size:.72rem; color:var(--dimmer); white-space:nowrap; }
.result.note.j-rank{ border-color:rgba(243,182,74,.35); color:var(--text); }
.result.note.j-warn{ border-color:rgba(239,106,95,.35); }
/* An empty frame is a miss too, and it is the ONLY miss that comes back to
   the log as a one-line note rather than a card — nothing turned up, so
   there is no animal to draw. It gets the same red as the escape card so
   the log reads the same way whichever kind of miss it was. */
.result.note.j-empty{ border-color:rgba(239,106,95,.42);
  background:rgba(239,106,95,.07); color:var(--dim); }

/* The oldest rows fade back, so the eye lands on the newest without the list
   turning into a wall of equally-loud cards. */
.huntlog .logrow:nth-child(n+6){ opacity:.72; }
.huntlog .logrow:nth-child(n+12){ opacity:.55; }

/* ----------------------------------------------------- HISCORE  [27] */
.hisearch-panel .addfriend{ margin-bottom:0; }
.hitable td{ padding:10px 11px; }
.hi-pos{ width:56px; font-variant-numeric:tabular-nums; color:var(--dimmer); }
.hi-pos b{ font-size:.95rem; }
.hi-name b{ display:inline; font-weight:600; }
.hi-name em{ display:block; font-size:.74rem; color:var(--dimmer); font-style:normal; }
.hi-name .tinytag{ margin-left:6px; }
.hi-gain{ color:var(--good); font-weight:700; }

/* The top three are the reason anyone opens a board, so they are the only
   rows that get a colour of their own. Everything below is a list. */
.hirow.is-gold   .hi-pos b{ color:#f3b64a; }
.hirow.is-silver .hi-pos b{ color:#cfd8dc; }
.hirow.is-bronze .hi-pos b{ color:#d08a52; }
.hirow.is-gold   { background:rgba(243,182,74,.07); }
.hirow.is-silver { background:rgba(207,216,220,.05); }
.hirow.is-bronze { background:rgba(208,138,82,.05); }
/* Your own row, wherever it lands — the one you were looking for. */
.hirow.is-me{ box-shadow:inset 3px 0 0 var(--accent); background:rgba(243,182,74,.10); }

.hipager{ display:flex; align-items:center; justify-content:space-between;
  gap:12px; margin-top:14px; flex-wrap:wrap; }
.hipage-at{ font-size:.82rem; color:var(--dim); text-align:center;
  font-variant-numeric:tabular-nums; }
.hipage-at i{ display:block; font-style:normal; font-size:.72rem; color:var(--dimmer); }

/* ---------------------------------------------- AISLE / SHELF TABS [26] */
/* Second row of tabs under the supermarket branches, and the only row in
   the bag. Four or five kinds stacked in one scroll buried the weapons
   under fifty bait cards. */
.kindtabs{ display:flex; gap:6px; overflow-x:auto; scrollbar-width:none;
  margin:0 0 14px; padding-bottom:2px; }
.kindtabs::-webkit-scrollbar{ display:none; }
.kindtab{ display:inline-flex; align-items:center; gap:7px; flex:0 0 auto;
  padding:8px 14px; border-radius:99px; border:1px solid var(--line);
  background:rgba(0,0,0,.2); color:var(--dim); font:600 .86rem/1 var(--font);
  cursor:pointer; transition:.16s; }
.kindtab:hover{ color:var(--text); border-color:var(--line2); }
.kindtab .ui-svg{ color:var(--dimmer); flex:0 0 auto; transition:.16s; }
.kindtab:hover .ui-svg{ color:var(--accent); }
.kindtab.is-on{ color:#12211d; background:linear-gradient(140deg,var(--accent2),var(--accent));
  border-color:transparent; box-shadow:0 4px 14px rgba(243,182,74,.22); }
.kindtab.is-on .ui-svg{ color:#3a2c0d; }
.kindtab:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }
/* An empty aisle is still worth showing — it says the branch does not
   stock them, which is a fact about the shop. */
.kindtab.is-empty{ opacity:.5; }
.tabcount{ font-size:.7rem; font-weight:800; padding:1px 6px; border-radius:99px;
  background:rgba(255,255,255,.09); color:var(--dimmer); }
.kindtab.is-on .tabcount{ background:rgba(0,0,0,.18); color:#3a2c0d; }

/* Bought, or fitted. A card that has already been paid for is a receipt,
   not a button — the four slots in camp are where gear is changed. */
.boughttag{ display:inline-flex; align-items:center; gap:6px; align-self:flex-start;
  padding:5px 11px; border-radius:99px; font-size:.76rem; font-weight:700;
  color:var(--good); background:rgba(95,208,138,.12);
  border:1px solid rgba(95,208,138,.34); }
.boughttag .ui-svg{ color:var(--good); }
.boughttag.is-on{ color:var(--accent); background:rgba(243,182,74,.12);
  border-color:rgba(243,182,74,.36); }
.boughttag.is-on .ui-svg{ color:var(--accent); }

/* ------------------------------------------------- CORNER TABS  [26] */
.cornertabs{ display:flex; gap:6px; margin:0 0 12px; }
.cornertab{ display:inline-flex; align-items:center; gap:7px; flex:0 0 auto;
  padding:7px 13px; border-radius:99px; border:1px solid var(--line);
  background:rgba(0,0,0,.2); color:var(--dim); font:600 .84rem/1 var(--font);
  cursor:pointer; transition:.16s; }
.cornertab:hover{ color:var(--text); border-color:var(--line2); }
.cornertab .ui-svg{ color:var(--dimmer); flex:0 0 auto; }
.cornertab.is-on{ color:#12211d; background:linear-gradient(140deg,var(--accent2),var(--accent));
  border-color:transparent; }
.cornertab.is-on .ui-svg{ color:#3a2c0d; }
.cornertab.is-on .tabcount{ background:rgba(0,0,0,.18); color:#3a2c0d; }
.cornertab:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }

.party-tab{ display:flex; flex-direction:column; gap:10px; }
.party-name{ display:flex; align-items:center; gap:9px; flex-wrap:wrap;
  padding:9px 12px; border-radius:10px; background:rgba(243,182,74,.08);
  border:1px solid rgba(243,182,74,.28); }
.party-name .ui-svg{ color:var(--accent); flex:0 0 auto; }
.party-name b{ font-size:1rem; flex:1 1 auto; min-width:0; }
.party-tab.is-live .party-name{ border-color:var(--accent); }
/* Nothing to show yet, so say what a party is for rather than "none". */
.party-empty{ display:flex; flex-direction:column; align-items:center; text-align:center;
  gap:8px; padding:22px 16px; border-radius:var(--radius);
  border:1px dashed var(--line2); background:rgba(0,0,0,.18); }
.party-empty .ui-svg{ color:var(--dimmer); }
.party-empty b{ font-size:1rem; }
.party-empty p{ margin:0; font-size:.84rem; color:var(--dim); max-width:44ch; }

/* Public or private, said on the party itself rather than buried in a
   settings sheet — it decides who can walk in. */
.doortag{ font-size:.62rem; font-weight:800; letter-spacing:.1em; text-transform:uppercase;
  padding:2px 8px; border-radius:99px; flex:0 0 auto;
  color:var(--dimmer); background:rgba(255,255,255,.07); }
.doortag.is-public{ color:var(--good); background:rgba(95,208,138,.14); }
.doorpick{ margin:14px 0; }

/* Invitations and open parties are the same row: a name, who is in it,
   and the answer. */
.invitebox,.openbox{ display:grid; gap:6px; padding:11px 12px; border-radius:var(--radius-s);
  background:rgba(0,0,0,.2); border:1px solid var(--line); }
.invitebox{ border-color:rgba(243,182,74,.4); background:rgba(243,182,74,.06); }
.invitebox-h{ display:flex; align-items:center; gap:7px; font-size:.68rem; font-weight:800;
  letter-spacing:.09em; text-transform:uppercase; color:var(--dimmer); }
.invitebox .invitebox-h{ color:var(--accent); }
.invitebox-h .ui-svg{ flex:0 0 auto; }
.inviterow{ display:flex; align-items:center; gap:8px; padding:7px 10px; border-radius:8px;
  background:rgba(0,0,0,.24); }
.inviterow-body{ flex:1 1 auto; min-width:0; }
.inviterow-body b{ display:block; font-size:.88rem; }
.inviterow-body i{ font-style:normal; font-size:.74rem; color:var(--dimmer); }

/* A miss gets the same dialog as a catch on a phone, so the heading is
   what tells you which it was before you read anything else. */
.modal-title.is-miss{ color:var(--bad); }

/* ------------------------------------------------------ MARKETPLACE  [24] */
.bzwallet{ display:flex; align-items:center; gap:20px; flex-wrap:wrap; margin-top:10px; }
.bzstat{ display:flex; flex-direction:column; }
.bzstat span{ font-size:.68rem; text-transform:uppercase; letter-spacing:.09em;
  color:var(--dimmer); font-weight:600; }
.bzstat b{ font-size:1.1rem; }

.bzform{ display:flex; align-items:flex-end; gap:12px; flex-wrap:wrap; margin-top:10px; }
.bzform label{ display:flex; flex-direction:column; gap:4px; font-size:.68rem;
  text-transform:uppercase; letter-spacing:.09em; color:var(--dimmer); font-weight:700; }
.bzform select,.bzform input{
  background:rgba(0,0,0,.3); color:var(--text); font:inherit; font-size:.88rem;
  font-weight:500; text-transform:none; letter-spacing:0;
  border:1px solid rgba(255,255,255,.12); border-radius:8px; padding:7px 10px;
}
.bzform input[type=number]{ width:120px; font-variant-numeric:tabular-nums; }
.bzform select:focus-visible,.bzform input:focus-visible{
  outline:2px solid var(--accent); outline-offset:2px; }

/* The tariff is the one thing a seller must not be surprised by, so it is
   stated before the form and quoted again under it. */
.bztariff{
  display:flex; align-items:center; gap:8px; margin:10px 0 0;
  padding:9px 12px; border-radius:9px; font-size:.82rem; color:var(--text);
  background:rgba(243,182,74,.09); border:1px solid rgba(243,182,74,.3);
}
.bztariff .ui-svg{ color:var(--accent); flex:0 0 auto; }
.bzquote{ margin:10px 0 0; font-size:.88rem; color:var(--dim); }
.bzquote b{ color:var(--text); font-variant-numeric:tabular-nums; }

.bztag{ font-size:.6rem; font-weight:800; letter-spacing:.07em; text-transform:uppercase;
  color:var(--accent); border:1px solid rgba(243,182,74,.4);
  border-radius:99px; padding:1px 7px; margin-left:6px; }
.dex-table tr.is-mine{ background:rgba(243,182,74,.06); }

/* ---------------------------------------------------- PREMIUM SHOP  [25] */
.pstatus{
  display:flex; align-items:center; gap:8px; margin:10px 0 0;
  padding:10px 13px; border-radius:10px; font-size:.86rem;
  background:rgba(243,182,74,.1); border:1px solid rgba(243,182,74,.32);
}
.pstatus .ui-svg{ color:var(--accent); flex:0 0 auto; }

.pgrid{ display:grid; gap:14px; grid-template-columns:repeat(auto-fit, minmax(300px, 1fr)); }
.pcard{
  padding:18px; border-radius:14px;
  background:linear-gradient(165deg, var(--panel2), var(--bg2));
  border:1px solid rgba(243,182,74,.28);
}
.pcard.is-owned{ border-color:rgba(95,208,138,.4); }
.pcard-h{ display:flex; align-items:flex-start; justify-content:space-between; gap:14px; }
.pcard-h h4{ margin:0; font-size:1.12rem; }
.pcard-cad{ font-size:.68rem; text-transform:uppercase; letter-spacing:.09em;
  color:var(--dimmer); font-weight:700; }
.pcard-price{ font-size:1.25rem; font-weight:800; color:var(--accent);
  white-space:nowrap; }
.pcard-blurb{ margin:12px 0 0; font-size:.88rem; color:var(--dim); }
.pcard-perks{ margin:12px 0 0; padding:0 0 0 18px; display:grid; gap:5px; }
.pcard-perks li{ font-size:.85rem; line-height:1.5; }
.pcard-perks li::marker{ color:var(--accent); }

/* The concrete before/after does more selling than any adjective. */
.pcard-now{
  margin:14px 0 0; padding:10px 12px; border-radius:9px; font-size:.85rem;
  background:rgba(0,0,0,.24); color:var(--dim);
}
.pcard-now b{ color:var(--text); font-variant-numeric:tabular-nums; }
.pcard-now b.up{ color:var(--good); }
.pcard-owned{
  display:flex; align-items:center; gap:8px; margin-top:14px;
  font-size:.88rem; font-weight:700; color:var(--good);
}
.pcard-owned .ui-svg{ color:var(--good); }

/* Checkout is honest about stopping short, so it is styled as a notice
   rather than dressed up to look like a working payment step. */
.cknote{
  margin:14px 0; padding:13px 15px; border-radius:10px;
  background:rgba(239,106,95,.09); border:1px solid rgba(239,106,95,.3);
}
.cknote b{ display:block; margin-bottom:6px; color:var(--bad); }
.cknote p{ margin:0 0 .5em; font-size:.86rem; color:var(--dim); }
.cknote code{ font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:.82em;
  background:rgba(0,0,0,.3); padding:1px 5px; border-radius:4px; color:var(--text); }

/* ------------------------------------------------------------ TUTORIAL */
/* z-index 110 sits above the page and the modal (90) but deliberately BELOW
   the rank-up overlay (120). A first catch can clear 150 points, and a
   rank-up trapped under the masks would be a rank-up nobody could dismiss. */
.tut{ position:fixed; inset:0; z-index:110; display:none; }
.tut.is-on{ display:block; }

/* Four opaque panels around the target rather than one panel with a hole:
   a panel can swallow the clicks that must not reach the page, and the gap
   between them leaves the real control underneath genuinely clickable. */
.tut-mask{ position:fixed; background:rgba(4,10,9,.8); }

.tut-ring{ position:fixed; border-radius:12px; pointer-events:none;
  box-shadow:0 0 0 2px var(--accent), 0 0 0 6px rgba(243,182,74,.16),
             0 0 26px rgba(243,182,74,.4);
  transition:left .2s, top .2s, width .2s, height .2s; }
.tut-ring.is-nudge{ animation:tutNudge .45s ease-out; }
@keyframes tutNudge{
  50%{ box-shadow:0 0 0 4px var(--accent2), 0 0 0 10px rgba(243,182,74,.3),
                  0 0 36px rgba(243,182,74,.75); } }

.tut-card{ position:fixed; width:min(346px, calc(100vw - 24px));
  background:var(--panel); border:1px solid var(--line2); border-radius:var(--radius-s);
  box-shadow:0 18px 44px rgba(0,0,0,.55); padding:15px 16px 13px; }
.tut-card.is-centred{ left:50%; top:50%; transform:translate(-50%,-50%); }
.tut-step{ margin:0 0 5px; font-size:.66rem; font-weight:800; letter-spacing:.1em;
  text-transform:uppercase; color:var(--dimmer); }
.tut-card h3{ margin:0 0 7px; font-size:1.02rem; color:var(--accent2); }
.tut-body{ margin:0; font-size:.85rem; line-height:1.5; color:var(--text); }
.tut-cta{ margin:10px 0 0; font-size:.78rem; font-weight:700; color:var(--accent); }

.tut-actions{ display:flex; align-items:center; gap:10px; margin-top:14px; }
.tut-skip{ font-family:var(--font); font-size:.76rem; color:var(--dimmer);
  background:none; border:0; padding:4px 2px; cursor:pointer; text-decoration:underline; }
.tut-skip:hover{ color:var(--text); }
.tut-next{ margin-left:auto; font-family:var(--font); font-size:.8rem; font-weight:700;
  color:#1a1305; background:var(--accent); border:0; border-radius:99px;
  padding:7px 16px; cursor:pointer; }
.tut-next:hover{ background:var(--accent2); }
.tut-skip:focus-visible, .tut-next:focus-visible{ outline:2px solid var(--accent2);
  outline-offset:2px; }
.tut-bar{ margin-top:12px; height:3px; border-radius:99px; background:rgba(255,255,255,.09); }
.tut-bar i{ display:block; height:100%; border-radius:99px; background:var(--accent);
  transition:width .2s; }

/* The hover peek renders at z-index 200 and would float over the overlay. */
.tut-open .artpeek{ display:none !important; }
@media (prefers-reduced-motion:reduce){
  .tut-ring{ transition:none; }
  .tut-ring.is-nudge{ animation:none; }
}
