/* ==========================================================================
   meadow.css — The Meadow, golden-hour 3D showpiece (Robinhood Chain)
   Warm daylight HUD chrome (cream glass, dark ink, amber-gold accent) over
   the scene; the slide-in station panel uses the equity-reference crisp
   dark-mono treatment on purpose (spec-locked colors) for contrast.
   Fonts match the site: Instrument Sans (ui), Instrument Serif (display),
   IBM Plex Mono (mono).
   ========================================================================== */

:root{
  --m-canvas:#cfe0ea;
  --m-panel:rgba(255,251,242,0.62);
  --m-panel-solid:#fbf5e8;
  --m-ink:#2a2115;
  --m-ink-muted:#6b5c44;
  /* DESIGN PERFECTION PASS: was #93866c (3.3:1 on the ivory HUD chips --
     fails WCAG AA 4.5:1 for the small mono/label text it's used on: brand
     sub-label, FPS badge, settings label/hint, station-num). Darkened to
     land at ~4.6:1 against --m-panel-solid while keeping the same warm-brown
     hue and staying visibly one step lighter than --m-ink-muted. */
  --m-ink-faint:#7a6e58;
  --m-border:rgba(42,33,21,0.14);
  --m-accent:#b9822f;
  --m-accent-hover:#8f631f;

  /* spec-locked panel palette (station 1 / station 2 slide-in) */
  --m-panel-dark:#17140e;
  /* MARKET LIGHTER ticket (owner: "make the color of the market lighter its
     kinda dark"): a mid-warm parchment, used ONLY by .market-sheet /
     .collection-sheet / .collection-detail-card below (My Cards shares the
     same overlay family the owner was looking at) -- every OTHER dark
     surface (chat, oracle, confirm-chip, card-panel, station panels...)
     keeps --m-panel-dark untouched, so this never bleeds into the two
     recently-shipped surfaces (chat/oracle) the ticket says not to touch.
     --m-panel-dark-ink/-muted still clear >=4.5:1 against it (ivory ~12.6:1,
     muted ivory ~6.7:1) so no text-color changes were needed alongside it. */
  --m-panel-mid:#2e2820;
  --m-panel-dark-border:rgba(201,165,88,0.22); /* gold hairline, replaces the old boxed brown border */
  --m-panel-dark-ink:#efe9dc; /* ivory, >=4.5:1 on the dark panel */
  --m-panel-dark-muted:#b9ae98; /* muted ivory floor, >=4.5:1 on the dark panel */
  --m-gold:#d9a84e;
  --m-hairline:rgba(201,165,88,0.22);
  --m-hairline-strong:rgba(201,165,88,0.35);

  --font-ui:'Instrument Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  --font-serif:'Instrument Serif',Georgia,serif;
  --font-mono:'IBM Plex Mono',monospace;
}

*{box-sizing:border-box;}

html,body{
  margin:0;padding:0;width:100%;height:100%;overflow:hidden;
  background:var(--m-canvas);color:var(--m-ink);
  font-family:var(--font-ui);
  -webkit-font-smoothing:antialiased;
}

.mono{font-family:var(--font-mono);font-variant-numeric:tabular-nums;}

/* BUG FIX (owner: "the chat in the trade the dropdown color selection i cant
   see shit") -- the trade tab's <select> elements (and the market sort
   <select>) only ever styled the closed control; the native <option> popup
   list had zero explicit color/background anywhere in this file. Chromium
   inherits a <select>'s `color` into its option popup while leaving the
   popup's own background at the OS default (usually white), so the ivory
   --m-panel-dark-ink text rendered as near-white-on-white in the open
   dropdown -- unreadable, exactly the reported symptom. Shared class so
   every native select in the app (trade YOUR CARD/ASK FOR + market sort)
   gets identical treatment: explicit dark background + ivory text + visible
   gold-hairline border on the control, and explicit dark background + ivory
   text on every <option> (#efe9dc on #1c1914 = ~14.5:1 contrast, well past
   the 4.5:1 floor). 44px min-height unconditionally (not just the
   pointer:coarse media query below) per the 44px touch-target spec. Safari
   ignores <option> style rules entirely and renders its own native list --
   acceptable per spec; the closed control still reads correctly there. */
.native-select{
  background:var(--m-panel-dark);color:var(--m-panel-dark-ink);
  border:1px solid var(--m-panel-dark-border);min-height:44px;
}
.native-select option{
  background:#1c1914;color:var(--m-panel-dark-ink);
}

/* ================= DESIGN PERFECTION PASS: focus-visible =================
   One rule for every native focusable control on the page (HUD buttons,
   panel/overlay buttons, form inputs, links) -- keyboard-only, never shown
   on mouse/touch activation. 2px gold ring, offset so it never collides with
   a hairline border. Elements that are div/role="button" (e.g. #walk-chip)
   aren't natively focusable and are out of scope here (would need a
   tabindex attribute added at element-creation time in meadow.js, outside
   this pass's DOM-string-template write scope). */
button:focus-visible, a:focus-visible, input:focus-visible, select:focus-visible{
  outline:2px solid var(--m-gold);
  outline-offset:2px;
}

/* ================= DESIGN PERFECTION PASS: reduced motion =================
   prefers-reduced-motion:reduce collapses every animation/transition to
   effectively instant (hover lifts, panel slides, chip enter/exit, the
   coin-hud insufficient-funds shake, oracle cursor blink) EXCEPT the toast/
   float family, which keeps a short opacity-only fade -- their transform
   component (translate/scale) is dropped so nothing moves, but they still
   fade in/out instead of hard-cutting. */
@media (prefers-reduced-motion: reduce){
  *, *::before, *::after{
    animation-duration:0.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:0.01ms !important;
    scroll-behavior:auto !important;
  }
  .confirm-chip, .walk-chip, .rotate-chip, .install-chip, .sound-on-toast,
  .skill-toast, .walk-hint-toast, #inspect-chip, .coin-float, .coin-fly, .dolos-speech, .chat-panel,
  .onboarding-overlay, #focus-scrim{
    transition-duration:.25s !important;
    transition-property:opacity !important;
  }
}

/* ================= DESIGN PERFECTION PASS: documented z-index scale =================
   5   #vignette
   6   #grain
   8   #focus-scrim (card-focus dim)
   10  #hud (17 on mobile while a bottom-sheet panel is open -- see the
       max-width:720px block below for why) -- #hint-card lives inside this
       stacking context (no z-index of its own), which is exactly why its
       `bottom` offset now has to stay strictly clear of every z19 element
       below (see the HUD ZONE MAP comment above #meadow-canvas): being
       inside #hud, it can never out-paint them by z-index alone, only by
       not overlapping them spatially in the first place.
   15  #station-panel (permanently [hidden] -- item 1, dead DOM, kept for
       plumbing only, see meadow.js)
   16  #card-panel
   18  .dolos-speech, .walk-chip ("Press E" proximity chip)
   19  .walk-joystick, .chat-toggle, .chat-panel, .meadow-presence-chip,
       .meadow-presence-list
   20  #fallback (no-WebGL screen)
   21  .confirm-chip, .rotate-chip, .install-chip
   22  #inspect-chip
   23  .coin-fly, .coin-float, .sound-on-toast, .skill-toast, .walk-hint-toast,
       .sound-off-chip
   24  .rarity-gallery, .summon-panel
   25  .onboarding-overlay, .simple-card-viewer
   26  .market-overlay
   27  .collection-overlay
   28  .collection-detail
   29  .oracle-overlay (REBUILD: was an in-world billboard plane, not a DOM
       layer at all -- see meadow.js activateOracleTerminal)
   Each tier is a distinct feature layer; nothing here shares a value with
   an unrelated element on purpose. See the mobile-breakpoint comment on
   #hud below for the one place two layers legitimately fight for the top
   (bottom-sheet panels vs. the HUD they'd otherwise bury). */

/* ================= HUD ZONE MAP =================
   Owner: "map out each thing so they are well placed" / "these things are
   hiding instructions and placed in a not user friendly position". Every
   fixed/absolute HUD element below is assigned to exactly ONE of these
   reserved regions -- nothing floats free of a zone, and nothing anchors
   off a raw pixel guess when a dynamic CSS var already exists for its
   corner (see the --meadow-* clearance vars, computed in meadow.js).

   TOP-LEFT      brand          .meadow-brand (#hud-top, flex start)
   TOP-RIGHT     status+controls #fps-badge, .wallet-pill, .mode-pill,
                                  .coin-hud, .collection-hud-btn, #sound-toggle,
                                  fullscreen .icon-btn, #settings-toggle
                                  (.meadow-top-right, flex end, wraps under
                                  the brand on overflow -- #hud-top's own
                                  flex-wrap) -> #settings-popover docks
                                  directly under the gear icon; .sound-off-chip
                                  docks near #sound-toggle, one corner over,
                                  and yields to #settings-popover on open
                                  (see the settingsToggle click handler)
   TOP-CENTER    transient toasts .skill-toast, .walk-hint-toast, .rotate-chip,
                                  .install-chip (stacked, never overlap each
                                  other -- see their own top: offsets)
   BOTTOM-CENTER station nav     #station-nav / .walk-nav-row (+ .walk-toggle-btn,
                                  .traveler-chip) -- never relocated by this
                                  pass, self-aligned, own horizontal-scroll
   BOTTOM-LEFT   comms stack     one column, bottom-to-top:
                                    .chat-toggle / .chat-panel   (floor: --meadow-chat-clear,
                                                                  the station-nav's own measured
                                                                  clearance)
                                    .meadow-presence-chip        (--meadow-presence-chip-clear:
                                                                  floor + chat block height + gap)
                                    .meadow-presence-list        (--meadow-presence-list-clear:
                                                                  chip clearance + chip height + gap)
                                    #hint-card                   (--meadow-hint-card-clear:
                                                                  list clearance + list height + gap)
                                  All four vars are recomputed live in
                                  meadow.js (updateChatNavClearance +
                                  updateCommsStackClearance) whenever the
                                  chat panel opens/closes or the presence
                                  chip/list show/hide, so the column can
                                  never overlap itself regardless of which
                                  piece is tallest at the moment -- this is
                                  the fix for the named "chat covers the
                                  presence chip / hint card" collision.
   BOTTOM-RIGHT  actions        .cast-btn (56px, touch/walk only) --
                                  .walk-toggle-btn/.traveler-chip stay in the
                                  BOTTOM-CENTER nav row (they fit there at
                                  every supported width), not duplicated here
   LEFT-MID      joystick (walk) .walk-joystick-move (touch + WALK only,
                                  <=768px) -- the comms stack's <=768px `left`
                                  offset (132px / 44px-collapsed) is the dodge
                                  that keeps it clear of this zone
   RIGHT-MID     joystick (walk) .walk-joystick-look (touch + WALK only,
                                  <=768px)
   FLOATING      transient chips .confirm-chip / .walk-chip ("Press E") /
                  (bottom-center)  .sound-on-toast / #inspect-chip -- centered,
                                  never persistent alongside comms-stack
                                  content; .walk-chip left-anchors instead of
                                  centering under ~480px so it clears the
                                  LEFT-MID joystick zone (see that rule below)
   ================================================================== */

#meadow-canvas{
  position:fixed;inset:0;width:100%;height:100%;display:block;background:var(--m-canvas);
  touch-action:none;
}

/* ================= atmosphere overlays ================= */
#vignette{
  position:fixed;inset:0;z-index:5;pointer-events:none;
  background:radial-gradient(ellipse at 50% 58%, rgba(0,0,0,0) 46%, rgba(20,14,4,0.32) 100%);
}
/* SUMMON COMBAT V3 ticket item 3: brief radial flash on a nearby skill
   impact (triggerScreenFlash in meadow.js) -- skipped entirely under
   prefers-reduced-motion (guarded in JS; this class is simply never added
   then, so the base #vignette rule above stands untouched). */
#vignette.impact-flash{ animation: meadow-impact-flash 0.26s ease-out; }
@keyframes meadow-impact-flash{
  0%{ background: radial-gradient(ellipse at 50% 50%, rgba(255,230,180,var(--flash-strength,0.32)) 0%, rgba(20,14,4,0.32) 100%); }
  100%{ background: radial-gradient(ellipse at 50% 58%, rgba(0,0,0,0) 46%, rgba(20,14,4,0.32) 100%); }
}
#grain{
  position:fixed;inset:0;z-index:6;pointer-events:none;
  opacity:0.045;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120' height='120'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  background-size:180px 180px;
}

/* ================= HUD shell ================= */
#hud{
  position:fixed;inset:0;pointer-events:none;
  display:flex;flex-direction:column;justify-content:space-between;
  padding:20px 22px;
  z-index:10;
}
#hud a, #hud button, #hud input{pointer-events:auto;}

#hud-top{
  display:flex;align-items:flex-start;justify-content:space-between;
  /* OWNER FEEDBACK item 3: this row has no width ceiling -- brand lockup +
     FPS badge + DEMO pill + coin HUD + My Cards + Connect wallet + sound +
     fullscreen + settings can exceed the viewport well before 480px (the
     only narrow-width condensing rule today is wallet-pill's text hiding).
     flex-wrap here (plus the matching wrap on .meadow-top-right below)
     lets the cluster fold onto extra lines under the brand instead of
     overflowing past the edge or overlapping the canvas title. */
  flex-wrap:wrap;row-gap:8px;
}
.meadow-brand{
  pointer-events:auto;
  display:flex;flex-direction:column;gap:2px;
  text-decoration:none;
  opacity:0.94;
}
.meadow-brand-name{
  font-family:var(--font-serif);font-style:italic;font-size:20px;color:var(--m-ink);
  letter-spacing:-0.01em;line-height:1;
  text-shadow:0 1px 8px rgba(255,255,255,0.4);
}
.meadow-brand-sub{
  font-size:9.5px;font-weight:500;color:var(--m-ink-faint);
  letter-spacing:.08em;text-transform:uppercase;
}
.meadow-brand:hover .meadow-brand-name{color:var(--m-accent);}

.meadow-top-right{display:flex;align-items:center;gap:10px;flex-wrap:wrap;justify-content:flex-end;row-gap:8px;}

#fps-badge{
  font-size:10.5px;color:var(--m-ink-faint);
  background:var(--m-panel);border:1px solid var(--m-border);
  /* DESIGN PERFECTION PASS: was 5px 10px -- vertical padding now matches
     the rest of the #hud-top pill family (wallet-pill/mode-pill/coin-hud
     all sit at 8px top/bottom) so the row reads as one consistent chip
     set instead of each pill having its own height. */
  border-radius:999px;padding:8px 12px;backdrop-filter:blur(10px);
  letter-spacing:.04em;
}

.wallet-pill{
  display:flex;align-items:center;gap:7px;
  font-size:11px;font-weight:600;letter-spacing:.03em;
  color:var(--m-ink);background:var(--m-panel);border:1px solid var(--m-border);
  border-radius:999px;padding:8px 14px;backdrop-filter:blur(10px);
  /* WALLET-MODE TICKET: was cursor:default (decorative, unwired) -- the pill
     is now a real connect button / account chip, see meadow.js
     updateWalletChipUI(). */
  cursor:pointer;transition:border-color .15s ease;
}
.wallet-pill.wallet-connected{border-color:rgba(185,130,47,0.4);}
/* dim = not connected (default); .wallet-dot-connected (added by JS once a
   live account exists) swaps to the gold accent -- the dot is now literally
   the "is a wallet connected" signal, never just decoration. */
.wallet-dot{width:6px;height:6px;border-radius:999px;background:var(--m-ink-faint);display:inline-block;}
.wallet-dot-connected{background:var(--m-accent);box-shadow:0 0 6px rgba(185,130,47,0.55);}

/* ---- wallet account popover (item 2: connected wallet mini-panel) ----
   Appended to document.body like confirm-chip/skill-toast above it in
   meadow.js, so it gets its own z-index tier -- extending the documented
   scale near the top of this file: 30 .wallet-popover. Position (top/right)
   is set inline by meadow.js's positionWalletPopover(), anchored to the
   wallet pill's live bounding rect so it tracks correctly through the
   #hud-top row's flex-wrap. */
.wallet-popover{
  position:fixed;z-index:30;width:230px;padding:14px 16px 16px;
  background:var(--m-panel-solid);border:1px solid var(--m-border);
  border-radius:14px;box-shadow:0 20px 40px rgba(42,33,21,0.18);
  pointer-events:auto;
  opacity:0;transform:translateY(-4px);
  transition:opacity .15s ease, transform .15s ease;
}
.wallet-popover.visible{opacity:1;transform:translateY(0);}
.wallet-popover-address{
  margin:0 0 10px;font-size:10.5px;color:var(--m-ink-muted);
  word-break:break-all;letter-spacing:.02em;line-height:1.4;
}
.wallet-popover-mode{
  margin:10px 0 8px;font-size:10px;font-weight:600;letter-spacing:.06em;
  color:var(--m-ink-faint);text-transform:uppercase;
}
.wallet-popover-copy,.wallet-popover-disconnect{
  width:100%;padding:8px 10px;border-radius:8px;
  font-size:11px;font-weight:600;letter-spacing:.03em;
  background:var(--m-panel);border:1px solid var(--m-border);color:var(--m-ink);
  cursor:pointer;transition:color .15s ease, border-color .15s ease;
}
.wallet-popover-copy{margin-bottom:6px;}
.wallet-popover-copy:hover{color:var(--m-accent);border-color:rgba(185,130,47,0.4);}
.wallet-popover-disconnect{color:#b0503a;}
.wallet-popover-disconnect:hover{border-color:rgba(176,80,58,0.4);}

.icon-btn{
  pointer-events:auto;
  width:32px;height:32px;border-radius:999px;
  display:flex;align-items:center;justify-content:center;
  background:var(--m-panel);border:1px solid var(--m-border);
  color:var(--m-ink-muted);cursor:pointer;backdrop-filter:blur(10px);
  transition:color .15s ease, border-color .15s ease;
}
.icon-btn:hover{color:var(--m-accent);border-color:rgba(185,130,47,0.4);}

/* ================= settings popover ================= */
#settings-popover{
  position:absolute;top:64px;right:22px;
  width:220px;padding:14px 16px 16px;
  background:var(--m-panel-solid);border:1px solid var(--m-border);
  border-radius:14px;box-shadow:0 20px 40px rgba(42,33,21,0.18);
  pointer-events:auto;
}
.settings-label{
  margin:0 0 8px;font-size:10px;font-weight:600;text-transform:uppercase;
  letter-spacing:.08em;color:var(--m-ink-faint);
  /* FIX ITEM (UI EASE SWEEP, owner: "make the ui easier" -- group rows with
     tiny mono section labels): was inheriting the UI sans font -- every
     other tiny uppercase tag in the popover family (settings-hint, market
     tabs, chip labels) already reads in mono, this was the one outlier. */
  font-family:var(--font-mono);
}
/* FIX ITEM (UI EASE SWEEP): "DATA" section header above the reset-demo
   link -- the only row in the popover with no group label at all before
   this pass (Render Resolution/Sound volume/Traveler each already had
   one). Reuses .settings-label's own top-border-adjacent spacing; the
   reset link keeps its own border-top divider immediately below it. */
.settings-label-data{
  margin:14px 0 8px;padding-top:10px;border-top:1px solid var(--m-border);
}
#res-scale{width:100%;accent-color:var(--m-accent);}
.settings-row{display:flex;align-items:center;justify-content:space-between;margin-top:6px;}
#res-scale-value{font-size:12px;color:var(--m-ink);}
.settings-hint{font-size:9.5px;color:var(--m-ink-faint);letter-spacing:.03em;}

/* ================= keyboard hint card ================= */
/* ZONE MAP FIX (owner: "hiding instructions ... not user friendly
   position"): bottom was a static 96px, unrelated to the station-nav's
   real measured height OR the chat-toggle sitting at the exact same 22px
   left inset directly below it -- on most viewports the two boxes
   overlapped (chat-toggle's top edge landed ~20-30px above hint-card's own
   bottom edge). Now anchored off --meadow-hint-card-clear (meadow.js
   updateCommsStackClearance), the top slot of the bottom-left comms-stack
   column -- see the HUD ZONE MAP comment near the top of this file. */
#hint-card{
  position:absolute;left:22px;bottom:var(--meadow-hint-card-clear, 156px);
  display:flex;flex-direction:column;gap:8px;
  background:var(--m-panel);border:1px solid var(--m-border);
  border-radius:14px;padding:12px 16px;backdrop-filter:blur(14px);
  pointer-events:auto;
}
.hint-row{display:flex;align-items:center;gap:8px;}
.key{
  min-width:20px;height:20px;padding:0 6px;
  display:inline-flex;align-items:center;justify-content:center;
  font-family:var(--font-mono);font-size:10px;font-weight:600;
  color:var(--m-ink-muted);background:rgba(255,255,255,0.55);
  border:1px solid var(--m-border);border-radius:5px;
}
.key-wide{min-width:32px;padding:0 8px;}
.hint-label{font-size:11px;color:var(--m-ink-muted);letter-spacing:.01em;}

/* ================= station switcher ================= */
#station-nav{
  align-self:center;
  display:flex;gap:2px;
  background:var(--m-panel);border:1px solid var(--m-border);
  border-radius:999px;padding:4px;backdrop-filter:blur(14px);
  pointer-events:auto;
}
/* OWNER FEEDBACK (1074px screenshot: pills overflow right, only 00-04
   visible, no scroll cue): pills are compact numbers ("00".."07", 44px
   min touch target) by default so the full row fits without needing
   every station's full name on screen at once. Only the ACTIVE pill
   expands to show its name ("00 OVERVIEW") via .station-label's
   max-width transition (200ms ease, no bounce); inactive pills reveal
   their name as a hover/focus tooltip instead (below) -- CSS only,
   never shifts layout since the tooltip is absolutely positioned. */
.station-btn{
  display:inline-flex;align-items:center;justify-content:center;
  position:relative;flex:none;
  font-family:var(--font-mono);font-size:11px;font-weight:600;
  text-transform:uppercase;letter-spacing:.06em;
  color:var(--m-ink-muted);background:none;border:none;
  min-width:44px;min-height:44px;
  padding:0 11px;border-radius:999px;cursor:pointer;
  transition:color .15s ease, background .15s ease;
  white-space:nowrap;
}
.station-num{
  font-size:9.5px;color:var(--m-ink-faint);
  transition:color .15s ease;
}
.station-label{
  display:inline-block;max-width:0;margin-left:0;opacity:0;overflow:hidden;
  transition:max-width .2s ease, margin-left .2s ease, opacity .2s ease;
  vertical-align:middle;
}
.station-btn:hover{color:var(--m-ink);}
/* DESIGN PERFECTION PASS: was color:#fbf6ea (near-white) on the solid
   --m-accent fill -- measures ~3.1:1, fails the 4.5:1 floor for this
   11px label (a mid-tone gold-brown contrasts better with dark ink than
   with white here). Switched to --m-ink, which lands ~4.7:1. */
.station-btn.active{color:var(--m-ink);background:var(--m-accent);}
.station-btn.active .station-num{color:var(--m-ink);}
.station-btn.active .station-label{max-width:150px;margin-left:8px;opacity:1;}

/* hover/focus tooltip for the compact (inactive) pills -- gated to real
   hover+fine-pointer so a tap on touch never leaves a phantom label
   stuck open; absolutely positioned so it can never shift the row. */
@media (hover:hover) and (pointer:fine){
  .station-btn:not(.active):hover::after,
  .station-btn:not(.active):focus-visible::after{
    content:attr(data-name);
    position:absolute;left:50%;bottom:calc(100% + 8px);
    transform:translateX(-50%);
    background:var(--m-panel-dark);color:var(--m-panel-dark-ink);
    border:1px solid var(--m-gold);border-radius:6px;
    padding:5px 9px;font-family:var(--font-ui);font-size:10.5px;
    font-weight:600;text-transform:none;letter-spacing:normal;
    white-space:nowrap;pointer-events:none;
    box-shadow:0 8px 20px rgba(0,0,0,0.3);
  }
}

/* ================= slide-in station panel (spec-locked dark) ================= */
#station-panel{
  position:fixed;top:0;right:0;bottom:0;
  width:400px;max-width:92vw;
  background:var(--m-panel-dark);
  border-left:1px solid var(--m-panel-dark-border);
  color:var(--m-panel-dark-ink);
  font-family:var(--font-mono);
  z-index:15;
  display:flex;flex-direction:column;
  padding:22px 22px 26px;
  overflow-y:auto;
  box-shadow:-30px 0 60px rgba(0,0,0,0.35);
  transform:translateX(0);
  transition:transform .4s cubic-bezier(.16,1,.3,1);
}
#station-panel[hidden]{display:none;}
#station-panel.entering{transform:translateX(100%);}

/* thin gold-tinted scrollbar, transparent track (both panels) */
#station-panel, #card-panel{
  scrollbar-width:thin;
  scrollbar-color:var(--m-hairline-strong) transparent;
}
#station-panel::-webkit-scrollbar, #card-panel::-webkit-scrollbar{width:6px;height:6px;}
#station-panel::-webkit-scrollbar-track, #card-panel::-webkit-scrollbar-track{background:transparent;}
#station-panel::-webkit-scrollbar-thumb, #card-panel::-webkit-scrollbar-thumb{
  background:var(--m-hairline-strong);border-radius:999px;
}

.panel-head{
  display:flex;align-items:flex-start;justify-content:space-between;
  margin-bottom:18px;padding-bottom:16px;
  border-bottom:1px solid var(--m-panel-dark-border);
}
.panel-eyebrow{
  margin:0 0 6px;font-size:10px;font-weight:600;text-transform:uppercase;
  letter-spacing:.14em;color:var(--m-gold);
}
#panel-title{
  position:relative;
  margin:0;padding-bottom:11px;font-family:var(--font-serif);font-weight:400;font-size:21px;
  letter-spacing:normal;color:var(--m-panel-dark-ink);
}
#panel-title::after{
  content:'';position:absolute;left:0;bottom:0;width:48px;height:1px;
  background:var(--m-hairline-strong);
}
#station-panel .icon-btn{
  background:rgba(255,255,255,0.05);border-color:var(--m-panel-dark-border);
  color:var(--m-panel-dark-muted);
}
#station-panel .icon-btn:hover{color:var(--m-gold);border-color:var(--m-gold);}

#panel-content{font-size:12px;line-height:1.5;}

/* -- pack tiers -- */
.tier-row{
  border:none;border-radius:0;border-bottom:1px solid var(--m-hairline);
  padding:15px 0;margin-bottom:0;
  display:flex;align-items:baseline;justify-content:space-between;gap:14px;
}
.tier-row:last-child{border-bottom:none;}
.tier-row.tier-disabled{opacity:0.45;}
.tier-name{font-family:var(--font-serif);font-weight:400;font-size:16px;color:var(--m-panel-dark-ink);margin:0 0 4px;}
.tier-desc{font-family:var(--font-mono);font-size:11px;color:var(--m-panel-dark-muted);margin:0;}
.tier-price{font-family:var(--font-mono);font-size:12.5px;font-weight:600;color:var(--m-gold);white-space:nowrap;align-self:baseline;}

.panel-subhead{
  margin:18px 0 8px;font-size:10px;font-weight:600;text-transform:uppercase;
  letter-spacing:.1em;color:var(--m-panel-dark-muted);
}

.odds-table{width:100%;border-collapse:collapse;margin-bottom:16px;}
.odds-table th{
  text-align:left;font-size:9px;text-transform:uppercase;letter-spacing:.08em;
  color:var(--m-panel-dark-muted);font-weight:600;padding:0 0 6px;
  border-bottom:1px solid var(--m-panel-dark-border);
}
.odds-table td{padding:11px 0;font-size:11px;border-bottom:1px solid var(--m-hairline);}
.odds-table td:last-child{text-align:right;color:var(--m-gold);}

.pity-wrap{margin-bottom:18px;}
.pity-label{display:flex;justify-content:space-between;font-size:10px;color:var(--m-panel-dark-muted);margin-bottom:6px;}
.pity-bar{height:6px;border-radius:999px;background:rgba(255,255,255,0.06);overflow:hidden;}
.pity-fill{height:100%;background:linear-gradient(90deg, var(--m-gold), #f3cd83);}

.wallet-cta{
  width:100%;padding:12px 16px;margin-top:4px;
  background:rgba(217,168,78,0.14);border:1px solid var(--m-panel-dark-border);
  color:var(--m-panel-dark-muted);border-radius:6px;
  font-family:var(--font-mono);font-size:11.5px;font-weight:600;
  text-transform:uppercase;letter-spacing:.08em;cursor:not-allowed;
}

.panel-footnote{
  font-size:10.5px;line-height:1.55;color:var(--m-panel-dark-muted);margin:14px 0 0;
}

/* -- obelisk live ticker feed (station 03) -- */
.ticker-list{display:flex;flex-direction:column;gap:2px;margin:8px 0 4px;}
.ticker-row{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:13px 0;border-bottom:1px solid var(--m-hairline);
}
.ticker-row:last-child{border-bottom:none;}
.ticker-name{font-size:12.5px;font-weight:600;letter-spacing:.02em;color:var(--m-panel-dark-ink);}
.ticker-price{font-size:11px;color:var(--m-panel-dark-muted);}
.ticker-pct{font-size:11px;font-weight:600;min-width:56px;text-align:right;color:var(--m-panel-dark-muted);}
.ticker-pct.up{color:#5be3a8;}
.ticker-pct.down{color:#ff8f7d;}

/* -- strongbox holdings (station 05) -- */
.holdings-list{display:flex;flex-direction:column;gap:0;margin:8px 0 16px;}
.holdings-row{
  display:flex;align-items:baseline;justify-content:space-between;gap:14px;
  padding:15px 0;border-bottom:1px solid var(--m-hairline);
}
.holdings-row:last-child{border-bottom:none;}
.holdings-name{font-family:var(--font-serif);font-size:16px;font-weight:400;color:var(--m-panel-dark-ink);margin:0 0 3px;}
.holdings-qty{font-size:11px;color:var(--m-panel-dark-muted);margin:0;}
.holdings-value{font-family:var(--font-mono);font-size:12px;font-weight:600;color:var(--m-gold);white-space:nowrap;align-self:baseline;}

/* -- oracle terminal (station 06) -- */
.oracle-terminal{
  background:#0a0f0b;border:1px solid var(--m-panel-dark-border);border-radius:10px;
  padding:14px 14px 16px;margin:8px 0 4px;
}
/* DESIGN PERFECTION PASS: alpha was 0.55 -- ~4.13:1 on the terminal's near-
   black background, under the 4.5:1 floor for this 10.5px legend text.
   Bumped to 0.62 (~4.97:1); the brighter <span> keywords are untouched. */
.oracle-cmds{font-size:10.5px;color:rgba(127,219,160,0.62);line-height:1.8;margin:0 0 12px;letter-spacing:.02em;}
.oracle-cmds span{color:#8fe8b4;}
.oracle-prompt-row{display:flex;align-items:center;gap:6px;font-size:12px;color:#8fe8b4;min-height:16px;}
.oracle-caret{color:#c98b3a;}
.oracle-input{min-width:2px;color:#c9f7d8;outline:none;}
.oracle-cursor{display:inline-block;color:#8fe8b4;animation:oracle-blink 1s step-end infinite;}
@keyframes oracle-blink{50%{opacity:0;}}
/* FIX ITEM (UI EASE SWEEP): 11px -> 13px -- the oracle's actual reply text,
   meant to be read, not a chip/tag; the terminal panel is full station-panel
   width, not a tight bubble. */
.oracle-response{margin:10px 0 0;font-size:13px;color:var(--m-gold);min-height:14px;}

/* -- trading post listings (station 07) -- */
.listing-list{display:flex;flex-direction:column;gap:0;margin:8px 0 16px;}
.listing-row{
  display:flex;align-items:baseline;justify-content:space-between;gap:14px;
  border:none;border-radius:0;border-bottom:1px solid var(--m-hairline);padding:15px 0;
}
.listing-row:last-child{border-bottom:none;}
.listing-name{font-family:var(--font-serif);font-size:16px;font-weight:400;color:var(--m-panel-dark-ink);margin:0 0 3px;}
.listing-seller{font-family:var(--font-mono);font-size:10.5px;color:var(--m-panel-dark-muted);margin:0;}
.listing-price{font-family:var(--font-mono);font-size:12px;font-weight:600;color:var(--m-gold);white-space:nowrap;align-self:baseline;}
.ladder-line{font-size:13px;font-weight:600;color:var(--m-gold);margin:0 0 16px;}

/* -- collection grid -- */
.collection-grid{
  display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-top:4px;
}
.slot{
  aspect-ratio:3/4;border-radius:4px;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  border:1px solid var(--m-panel-dark-border);
  font-size:10px;text-align:center;padding:6px;
  position:relative;overflow:hidden;
}
.slot-filled{
  background-color:rgba(217,168,78,0.1);
  background-image:linear-gradient(160deg, rgba(217,168,78,0.16), rgba(217,168,78,0.02));
  background-size:cover;background-position:center;background-repeat:no-repeat;
  color:var(--m-gold);font-weight:600;
  /* hairline FULL border in the rarity color -- no left-stripe accent (banned pattern) */
  border:1px solid var(--m-gold);
  padding:0;align-items:stretch;justify-content:flex-end;
}
.slot-filled .slot-name{
  padding:16px 6px 6px;
  background:linear-gradient(to top, rgba(10,8,5,0.94), rgba(10,8,5,0));
  color:#fff;font-size:10px;line-height:1.25;
}
/* real manifest rarity tiers on the collection grid (station 02) */
.slot-filled.rarity-epic{border-color:#c9d3da;}
.slot-filled.rarity-rare{border-color:#b8794a;}
.slot-filled.rarity-common{border-color:var(--m-panel-dark-muted);}
.slot-empty{
  color:var(--m-panel-dark-muted);
  background:repeating-linear-gradient(135deg, rgba(255,255,255,0.02) 0 6px, transparent 6px 12px);
}

/* ================= card focus: scrim + detail panel ================= */
#focus-scrim{
  position:fixed;inset:0;z-index:8;pointer-events:none;
  background:#0a0805;opacity:0;
  transition:opacity .45s cubic-bezier(.16,1,.3,1);
}
#focus-scrim.active{opacity:.3;}

#card-panel{
  position:fixed;top:0;right:0;bottom:0;
  width:400px;max-width:92vw;
  background:var(--m-panel-dark);
  border-left:1px solid var(--m-panel-dark-border);
  color:var(--m-panel-dark-ink);
  font-family:var(--font-mono);
  z-index:16;
  display:flex;flex-direction:column;gap:2px;
  padding:26px 22px 24px;
  overflow-y:auto;
  box-shadow:-30px 0 60px rgba(0,0,0,0.35);
  transform:translateX(100%);
  transition:transform .45s cubic-bezier(.16,1,.3,1);
  pointer-events:none;
}
#card-panel.open{transform:translateX(0);pointer-events:auto;}
/* bug fix (Escape/card-focus audit): #card-panel sets its own `display:flex`
   above, which (author specificity beats the UA [hidden]{display:none}
   default) silently defeats the native `hidden` attribute -- exactly why
   #station-panel needs the same override just above. meadow.js now toggles
   `hidden` on close (see hidePanel() in meadow.js), so this has to be here
   for that to actually take the panel out of layout/the a11y tree instead
   of leaving it sitting fully-sized just offscreen. */
#card-panel[hidden]{display:none;}

.card-panel-ticker{
  margin:6px 0 0;font-size:30px;font-weight:700;letter-spacing:-0.01em;
  color:var(--m-panel-dark-ink);
}
.card-panel-name{
  margin:2px 0 10px;font-family:var(--font-ui);font-size:14.5px;
  color:var(--m-panel-dark-muted);
}
.card-panel-meta{display:flex;align-items:center;gap:10px;margin-bottom:16px;}
.rarity-chip{
  font-family:var(--font-mono);font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;
  padding:4px 10px;border-radius:3px;
  border:1px solid var(--m-panel-dark-border);color:var(--m-panel-dark-muted);background:transparent;
}
.rarity-chip.rarity-gold{color:var(--m-gold);background:transparent;border-color:var(--m-gold);}
.rarity-chip.rarity-epic{color:#c9d3da;background:transparent;border-color:#c9d3da;}
.rarity-chip.rarity-rare{color:#d99b6c;background:transparent;border-color:#d99b6c;}
.card-panel-num{font-size:10.5px;color:var(--m-panel-dark-muted);}

.stat-list{display:flex;flex-direction:column;gap:11px;margin-bottom:16px;}
.stat-row-head{display:flex;justify-content:space-between;font-size:10.5px;margin-bottom:5px;
  text-transform:uppercase;letter-spacing:.06em;color:var(--m-panel-dark-muted);}
.stat-bar{height:5px;border-radius:999px;background:rgba(255,255,255,0.06);overflow:hidden;}
.stat-fill{height:100%;background:linear-gradient(90deg, var(--m-gold), #f3cd83);}

.card-divider{border:none;border-top:1px solid var(--m-panel-dark-border);margin:2px 0 14px;}

.price-row{display:flex;justify-content:space-between;align-items:center;margin-bottom:14px;}
.price-label{font-size:10px;text-transform:uppercase;letter-spacing:.08em;color:var(--m-panel-dark-muted);}
.price-value{font-size:15px;font-weight:700;color:var(--m-gold);}

/* SIGNATURE SKILLS ticket: small gold line on the card panel + My Cards
   detail viewer, foreshadowing the perk system ("Skill: Starfall"). */
.card-panel-skill{
  margin:0 0 14px;font-family:var(--font-mono);font-size:11px;letter-spacing:.04em;
  color:var(--m-gold);
}
.card-panel-skill[hidden]{display:none;}

/* text-with-hairline-underline, not a boxed button -- avoids stacking a
   second border box under the primary .wallet-cta */
.ghost-btn{
  align-self:center;width:auto;padding:4px 1px 6px;margin-top:10px;
  background:transparent;border:none;border-bottom:1px solid var(--m-hairline-strong);
  color:var(--m-panel-dark-ink);border-radius:0;
  font-family:var(--font-mono);font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.08em;
  cursor:pointer;transition:border-color .15s ease, color .15s ease;
}
.ghost-btn:hover{border-color:var(--m-gold);color:var(--m-gold);}

/* FEATURE A: "Sell" button in the focused card panel -- only visible when
   the focused persona is owned (see updateSellButtonFor in meadow.js),
   gold when the vault is unlocked, dimmed (still visible, still readable)
   while it's disabled so the player understands why nothing happens yet. */
#card-panel-sell{border-color:var(--m-gold);color:var(--m-gold);}
#card-panel-sell:disabled{border-color:var(--m-panel-dark-border);color:var(--m-panel-dark-muted);cursor:not-allowed;}
#card-panel-sell[hidden]{display:none;}

.card-step-row{display:flex;justify-content:center;gap:6px;margin-top:2px;flex:none;}
.step-btn{
  width:34px;height:34px;border-radius:999px;
  display:flex;align-items:center;justify-content:center;
  background:rgba(255,255,255,0.05);border:1px solid var(--m-panel-dark-border);
  color:var(--m-panel-dark-muted);font-size:17px;line-height:1;cursor:pointer;
  transition:color .15s ease, border-color .15s ease;
}
.step-btn:hover{color:var(--m-gold);border-color:var(--m-gold);}

/* ITEM 2: compact card-panel layout -- header row (id + step buttons),
   collapsed-behind-a-tap stats. Desktop always shows the full stat list
   (.stats-toggle stays display:none); the <=720px chip-bar layout below
   flips that: stats hidden until .stats-open is toggled on. */
.card-panel-head-row{
  display:flex;align-items:flex-start;justify-content:space-between;gap:12px;
  padding-right:36px; /* clears the absolutely-positioned .panel-collapse-btn */
}
.card-panel-id{min-width:0;}
.card-panel-head-row .card-step-row{margin-top:2px;}
.stats-toggle{
  display:none;width:100%;align-items:center;justify-content:center;gap:4px;
  margin:2px 0 12px;padding:9px 4px;
  background:none;border:none;border-top:1px solid var(--m-hairline);border-bottom:1px solid var(--m-hairline);
  color:var(--m-panel-dark-muted);font-family:var(--font-mono);font-size:10.5px;font-weight:600;
  text-transform:uppercase;letter-spacing:.08em;cursor:pointer;
}
.stats-toggle-chevron{display:inline-block;transition:transform .2s ease;}
.stats-toggle[aria-expanded="true"] .stats-toggle-chevron{transform:rotate(90deg);}
.card-panel-actions{display:flex;align-items:center;gap:10px;margin-top:4px;}
.card-panel-actions .wallet-cta{flex:1;margin-top:0;}
.card-panel-actions .ghost-btn{flex:none;align-self:center;margin-top:0;}

@media (max-width:720px){
  /* ITEM 2: slim bottom chip bar -- stats collapsed behind the tap toggle,
     everything else tightened for a max-30vh strip (see #card-panel in the
     injected #meadow-panel-overrides, meadow.js) */
  .stats-toggle{display:flex;}
  .stat-list{display:none;}
  .stat-list.stats-open{display:flex;}
  .card-panel-head-row{align-items:center;}
  .card-panel-ticker{font-size:22px;margin-top:0;}
  .card-panel-name{margin-bottom:4px;}
  .card-panel-meta{margin-bottom:8px;}
  .price-row{margin-bottom:8px;}
  .card-divider{margin:0 0 10px;}
}

/* mobile #card-panel sizing/position is owned entirely by the injected
   #meadow-panel-overrides <style> (meadow.js) -- no duplicate rule here. */

/* ================= DOLOS character speech panel ================= */
.dolos-speech{
  position:fixed;z-index:18;width:260px;
  background:var(--m-panel-dark);border:1px solid var(--m-panel-dark-border);
  border-radius:12px;padding:14px 16px 16px;
  box-shadow:0 20px 50px rgba(0,0,0,0.4);
  pointer-events:none;
  opacity:0;transform:translateY(6px);
  transition:opacity .3s ease, transform .3s ease;
}
.dolos-speech[hidden]{display:none;}
.dolos-speech.visible{opacity:1;transform:translateY(0);pointer-events:auto;}
.dolos-speech-name{
  margin:0 0 6px;font-family:var(--font-serif);font-style:italic;font-weight:400;
  font-size:17px;letter-spacing:.02em;color:var(--m-gold);
}
.dolos-speech-line{
  /* FIX ITEM (UI EASE SWEEP): 11.5px -> 13px -- this is DOLOS's actual
     dialogue line, meant to be read, not a chip/tag; 260px bubble width and
     1.55 line-height both have plenty of headroom for the extra 1.5px. */
  margin:0;font-size:13px;line-height:1.55;color:var(--m-panel-dark-ink);
}

/* ================= item 5: first-visit onboarding overlay ================= */
.onboarding-overlay{
  position:fixed;inset:0;z-index:25;
  display:flex;align-items:center;justify-content:center;
  padding:24px;
  background:rgba(10,8,5,0.62);
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  opacity:1;transition:opacity .4s ease;
}
.onboarding-overlay.onboarding-hide{opacity:0;pointer-events:none;}
.onboarding-card{
  max-width:420px;width:100%;
  background:var(--m-panel-dark);
  border:1px solid var(--m-panel-dark-border);
  border-radius:16px;
  padding:34px 30px 28px;
  text-align:center;
  box-shadow:0 30px 70px rgba(0,0,0,0.45);
}
.onboarding-title{
  margin:0 0 20px;font-family:var(--font-serif);font-weight:400;font-style:italic;
  font-size:26px;letter-spacing:-0.01em;color:var(--m-panel-dark-ink);
}
.onboarding-line{
  /* FIX ITEM (UI EASE SWEEP): 11.5px -> 13px -- the first-visit orientation
     copy is body prose meant to be read once, not a chip/tag; 420px card
     width has room. */
  margin:0 0 12px;font-size:13px;line-height:1.6;color:var(--m-panel-dark-muted);
  letter-spacing:.01em;
}
.onboarding-line:last-of-type{margin-bottom:24px;}
.onboarding-btn{
  width:100%;padding:13px 16px;
  background:rgba(217,168,78,0.14);border:1px solid var(--m-gold);
  color:var(--m-gold);border-radius:6px;
  font-size:11.5px;font-weight:600;text-transform:uppercase;letter-spacing:.08em;
  cursor:pointer;transition:background .15s ease, color .15s ease;
}
.onboarding-btn:hover{background:rgba(217,168,78,0.26);}

/* ================= fallback (no WebGL) ================= */
#fallback[hidden]{display:none}
#fallback{
  position:fixed;inset:0;z-index:20;
  display:flex;align-items:center;justify-content:center;
  background:
    radial-gradient(60% 50% at 50% 0%, rgba(185,130,47,0.10), transparent 70%),
    var(--m-canvas);
  padding:24px;
}
.fallback-inner{max-width:560px;text-align:center;}
.fallback-eyebrow{
  font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.1em;
  color:var(--m-accent);margin:0 0 14px;
}
#fallback h1{
  font-family:var(--font-serif);font-weight:400;font-size:34px;line-height:1.15;
  letter-spacing:-0.01em;color:var(--m-ink);margin:0 0 14px;
}
.fallback-copy{color:var(--m-ink-muted);font-size:14.5px;line-height:1.6;margin:0 0 26px;}
.fallback-links{display:flex;flex-wrap:wrap;gap:22px;justify-content:center;}
.meadow-link{
  display:inline-flex;align-items:center;gap:6px;
  font-family:var(--font-mono);font-size:11.5px;font-weight:600;
  text-transform:uppercase;letter-spacing:.08em;
  color:var(--m-accent);text-decoration:none;
  border-bottom:1px solid rgba(185,130,47,0.35);padding-bottom:2px;
  transition:color .15s ease, border-color .15s ease, gap .15s ease;
}
.meadow-link:hover{color:var(--m-accent-hover);border-color:var(--m-accent-hover);gap:9px;}

@media (max-width:768px){
  /* ZONE MAP FIX (owner: "hiding instructions ... not user friendly
     position"): was `display:none` -- mobile players had zero access to
     the keyboard/controls legend. Collapses to a 44px "?" chip instead
     (same touch-target floor as every other icon-chip in the file) that
     expands on tap via .hint-expanded (toggled in meadow.js, right next to
     the hint-card's existing JS-built rows). left:132px matches the same
     joystick-clearance dock .chat-toggle/.meadow-presence-chip already use
     at this breakpoint (see LEFT-MID zone, top of file) so the collapsed
     chip can never sit under the WALK-mode move joystick either. bottom
     stays on the same dynamic stack var as the expanded desktop card. */
  #hint-card{
    left:132px;bottom:var(--meadow-hint-card-clear, 156px);
    width:44px;height:44px;padding:0;gap:0;
    align-items:center;justify-content:center;
    border-radius:999px;overflow:hidden;cursor:pointer;
  }
  #hint-card .hint-row{display:none;}
  #hint-card::before{
    content:'?';font-family:var(--font-mono);font-size:15px;font-weight:700;
    color:var(--m-ink-muted);
  }
  #hint-card.hint-expanded{
    width:auto;height:auto;padding:12px 16px;border-radius:14px;
    align-items:stretch;justify-content:flex-start;
  }
  #hint-card.hint-expanded::before{display:none;}
  #hint-card.hint-expanded .hint-row{display:flex;}
}
@media (max-width:720px){
  /* station-btn is compact-by-default (numbers only) from the base rule
     above now, so no override is needed here anymore -- station-num used
     to be hidden and the full label shown at this breakpoint, which is
     exactly backwards from the redesign (numbers primary, full name only
     on the active pill / hover tooltip). See the OWNER FEEDBACK comment
     on .station-btn above. */
  /* #station-panel sizing/position is owned entirely by the injected
     #meadow-panel-overrides <style> (meadow.js) -- no duplicate rule here. */
  /* bug fix (mobile 390px nav audit): at this breakpoint #station-panel
     (z-index 15) and #card-panel (z-index 16) become bottom sheets (see
     #meadow-panel-overrides in meadow.js), stacking bottom:0 up to 45vh
     tall -- and #station-nav lives inside #hud (z-index 10), pinned to the
     bottom of the screen by #hud's flex layout. #hud is `position:fixed`
     with its own z-index, so it's a stacking context: no z-index on
     #station-nav itself can ever lift it above a sheet outside that
     context. Whenever a station/card panel is open, its higher z-index
     sheet silently sits on top of the nav pills and swallows their clicks
     -- lifting #hud as a whole above both sheets (but still under the
     onboarding overlay at 25 / no-WebGL fallback at 20) fixes it here,
     scoped to the bottom-sheet breakpoint only. Desktop is untouched: there
     the panel deliberately covers the top-right HUD icons (wallet/settings)
     while open, and #station-nav isn't anywhere near it. */
  #hud{ z-index:17; padding-bottom:calc(20px + env(safe-area-inset-bottom)); }
}
@media (max-width:480px){
  .wallet-pill span:not(.wallet-dot){display:none;}
  /* OWNER FEEDBACK item 2: even 8 compact 44px number pills (8*44 + 7*2
     gap + 8 container padding =~374px) can be a touch wider than the
     available row at 390/360px viewports. #station-nav already scrolls
     (overflow-x:auto, scroll-snap, see below) -- this adds the visible
     fade-edge affordance the ticket calls for instead of the old hard,
     invisible clip (only 00-04 showing with no cue there was more). */
  #station-nav{
    -webkit-mask-image:linear-gradient(to right, transparent 0, #000 14px, #000 calc(100% - 14px), transparent 100%);
    mask-image:linear-gradient(to right, transparent 0, #000 14px, #000 calc(100% - 14px), transparent 100%);
  }
}

/* ================= station nav: horizontal-scroll on narrow viewports ================= */
#station-nav{
  max-width:calc(100vw - 32px);
  overflow-x:auto;
  overflow-y:hidden;
  scroll-snap-type:x proximity;
  -webkit-overflow-scrolling:touch;
  scrollbar-width:none;
  touch-action:pan-x;
}
#station-nav::-webkit-scrollbar{display:none;}
.station-btn{scroll-snap-align:center;}

/* hover-lift is a mouse/trackpad affordance only -- keep touch taps flat
   (no phantom :hover state stuck on after a tap) */
@media (hover:hover) and (pointer:fine){
  .station-btn:hover{transform:translateY(-1px);}
  .icon-btn:hover{transform:translateY(-1px);}
  .walk-toggle-btn:hover{transform:translateY(-1px);}
}

/* ================= walk mode (adventure) ================= */
/* wraps the WALK/TOUR pill and #station-nav side by side, replacing
   #station-nav as the direct flex child of #hud (see meadow.js) */
.walk-nav-row{
  display:flex;align-items:center;gap:10px;
  align-self:center;max-width:calc(100vw - 32px);
}
.walk-toggle-btn{
  display:flex;align-items:center;justify-content:center;flex:none;
  font-family:var(--font-mono);font-size:11px;font-weight:700;
  text-transform:uppercase;letter-spacing:.08em;
  color:var(--m-accent);background:var(--m-panel);
  border:1px solid var(--m-accent);border-radius:999px;
  padding:10px 16px;cursor:pointer;white-space:nowrap;
  backdrop-filter:blur(14px);
  transition:color .15s ease, background .15s ease, border-color .15s ease;
}
.walk-toggle-btn:hover{background:rgba(185,130,47,0.12);}
/* DESIGN PERFECTION PASS: same contrast fix as .station-btn.active above --
   near-white text on the solid --m-accent fill measured ~3.1:1. */
.walk-toggle-btn.active{color:var(--m-ink);background:var(--m-accent);}

/* ================= FIX ITEM 8: Traveler avatar chip beside WALK pill ================= */
.traveler-chip{
  display:flex;align-items:center;gap:0;flex:none;
  width:38px;height:38px;padding:0;overflow:hidden;
  background:var(--m-panel);border:1px solid var(--m-accent);border-radius:999px;
  cursor:pointer;backdrop-filter:blur(14px);
  transition:width .25s ease, background .15s ease;
}
.traveler-chip-glyph{width:20px;height:20px;flex:none;margin:0 9px;display:block;}
.traveler-chip-label{
  font-size:10px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--m-accent);white-space:nowrap;opacity:0;
  transition:opacity .2s ease;padding-right:0;
}
.traveler-chip:hover{background:rgba(185,130,47,0.12);}
.traveler-chip.show-label{width:auto;padding-right:2px;}
.traveler-chip.show-label .traveler-chip-label{opacity:1;padding-right:12px;}

/* "Press E -- <Station>" proximity chip, bottom-center */
.walk-chip{
  position:fixed;left:50%;bottom:104px;z-index:18;
  transform:translate(-50%,6px);
  background:var(--m-panel-dark);border:1px solid var(--m-gold);
  color:var(--m-gold);border-radius:999px;
  padding:9px 18px;font-size:11px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;
  cursor:pointer;pointer-events:auto;
  opacity:0;transition:opacity .25s ease, transform .25s ease;
  box-shadow:0 12px 30px rgba(0,0,0,0.32);
}
.walk-chip[hidden]{display:none;}
.walk-chip.visible{opacity:1;transform:translate(-50%,0);}

/* mobile move/look joystick pair -- transparent circles + thumb, WALK only,
   <=768px (also hard-gated closed >=769px below regardless of JS state) */
.walk-joystick{
  position:fixed;bottom:26px;width:96px;height:96px;border-radius:999px;
  background:rgba(23,20,14,0.28);border:1px solid rgba(255,255,255,0.28);
  z-index:19;touch-action:none;
}
.walk-joystick[hidden]{display:none;}
.walk-joystick-move{left:22px;}
.walk-joystick-look{right:22px;}
.walk-joystick-thumb{
  position:absolute;top:50%;left:50%;width:40px;height:40px;margin:-20px 0 0 -20px;
  border-radius:999px;background:rgba(255,255,255,0.42);border:1px solid rgba(255,255,255,0.55);
  pointer-events:none;
}
@media (min-width:769px){
  .walk-joystick{display:none;}
}
@media (max-width:720px){
  .walk-nav-row{flex-wrap:wrap;justify-content:center;}
}
@media (max-width:480px){
  .walk-chip{bottom:88px;font-size:10px;padding:8px 14px;}
  /* ZONE MAP FIX (LEFT-MID joystick collision, owner-flagged suspect): the
     base rule centers this chip at left:50% -- at 390/360px widths its own
     text width ("Press E -- <station>", length varies) pushes the left
     edge into the move-joystick's 22-118px column whenever WALK mode has
     both on screen together (~8-40px overlap depending on station name
     length). Left-anchored instead of centered here, clear of the
     joystick -- same technique the mobile-landscape block below already
     uses for the identical collision against .walk-joystick-look. */
  .walk-chip{
    left:calc(130px + env(safe-area-inset-left));
    transform:translate(0,6px);
  }
  .walk-chip.visible{transform:translate(0,0);}
}

/* ================= ITEM 4: mobile touch/nav polish =================
   Coarse-pointer or <=820px (same gate as the ITEM 3 quality tier) gets
   every HUD tap target bumped to >=44px -- 48px on the station pills/WALK
   toggle specifically, 56px on the walk-chip. #station-nav's horizontal
   scroll + momentum (-webkit-overflow-scrolling:touch, scroll-snap-type:x)
   and its max-width:calc(100vw - 32px) clamp already exist above, so this
   only touches sizing, not layout -- placed last so it wins the cascade
   over the earlier 480px/720px rules for the same properties. */
@media (max-width:820px), (pointer:coarse){
  .station-btn{min-height:48px;}
  .walk-toggle-btn{min-height:48px;}
  .icon-btn{width:44px;height:44px;}
  .step-btn{width:44px;height:44px;}
  .panel-collapse-btn{width:44px;height:44px;}
  .wallet-cta{padding:14px 16px;}
  .ghost-btn{padding:14px 4px;}
  .stats-toggle{min-height:44px;}
  .walk-chip{
    min-height:56px;display:flex;align-items:center;justify-content:center;
    padding:10px 22px;
  }
}

/* ================= DESIGN PERFECTION PASS: touch-target completion =================
   Same gate as ITEM 4 above (coarse-pointer or <=820px), extended to every
   remaining tappable control under 44px that ITEM 4 didn't reach: the
   overlay/panel close pills, the market/chat tabs, the buy/cancel/send/post
   buttons, the toast action buttons, and the two small HUD icon chips
   (My Cards, Traveler). Each gets min-height:44px (min-width too on the
   fixed-size icon chips) plus inline-flex centering wherever the base rule
   didn't already declare a display -- text stays visually where it was,
   only the hit target grows. Left-aligned settings-popover rows
   (.traveler-skin-btn/.settings-reset-link) center vertically only, keeping
   their text-align:left. Form fields (.chat-input and friends) get the same
   min-height so typing/tapping into them is no harder to land than any
   button beside them. */
@media (max-width:820px), (pointer:coarse){
  .wallet-pill{min-height:44px;}
  .mode-pill{min-height:44px;}
  .traveler-chip{min-width:44px;min-height:44px;justify-content:center;}
  .collection-hud-btn{width:44px;height:44px;}
  .market-close, .collection-close, .rarity-gallery-close, .summon-panel-close,
  .chat-panel-close, .simple-card-viewer-close, .collection-detail-close,
  .market-buy-btn, .market-cancel-btn, .sound-on-toast button,
  .chat-send-btn, .chat-trade-submit, .chat-tab, .market-tab{
    display:inline-flex;align-items:center;justify-content:center;min-height:44px;
  }
  .rotate-chip-close, .install-chip-close{
    display:inline-flex;align-items:center;justify-content:center;
    min-width:44px;min-height:44px;
  }
  .confirm-btn{display:flex;align-items:center;justify-content:center;min-height:44px;}
  .traveler-skin-btn, .settings-reset-link{
    display:flex;align-items:center;min-height:44px;
  }
  .chat-input, .chat-trade-select, .chat-trade-input{min-height:44px;}
  /* DESIGN PERFECTION PASS: market overlay's sort <select> was missed by
     the sweep above -- 4px vertical padding at 11px type measures ~21px
     tall, well under the 44px floor. */
  .market-sort select{min-height:44px;}
}

/* ================= ITEM 6: DEMO / REAL mode pill ================= */
.mode-pill{
  display:flex;align-items:center;justify-content:center;
  font-family:var(--font-mono);font-size:10.5px;font-weight:700;letter-spacing:.06em;
  color:var(--m-accent);background:var(--m-panel);border:1px solid var(--m-accent);
  border-radius:999px;padding:8px 14px;backdrop-filter:blur(10px); /* DESIGN PERFECTION PASS: 13->14, matches wallet-pill's horizontal padding */
  cursor:pointer;transition:color .15s ease, background .15s ease, border-color .15s ease;
}
.mode-pill:hover{background:rgba(185,130,47,0.12);}
/* DESIGN PERFECTION PASS: #5be3a8 (the same bright mint used for
   .ticker-pct.up etc. against the DARK station panel, ~9:1 there) was
   reused here against the LIGHT --m-panel HUD chip -- ~1.5:1, effectively
   unreadable. Swapped for a deep forest green (on-brand, matches the
   dark-panel accent family) that measures ~5.9:1 on the ivory chip. */
.mode-pill.mode-real{color:#1e6b4f;border-color:#1e6b4f;}
.mode-pill.mode-real:hover{background:rgba(30,107,79,0.12);}

/* ================= ITEM 5/7: shared confirm chip (pack ceremony + market buy) ================= */
.confirm-chip{
  position:fixed;left:50%;bottom:104px;z-index:21;
  transform:translate(-50%,8px);
  width:min(360px, calc(100vw - 32px));
  background:var(--m-panel-dark);border:1px solid var(--m-gold);
  color:var(--m-panel-dark-ink);border-radius:14px;
  padding:16px 18px 18px;box-shadow:0 20px 50px rgba(0,0,0,0.4);
  pointer-events:auto;
  opacity:0;transition:opacity .25s ease, transform .25s ease;
}
.confirm-chip[hidden]{display:none;}
.confirm-chip.visible{opacity:1;transform:translate(-50%,0);}
.confirm-title{margin:0 0 4px;font-family:var(--font-serif);font-size:16px;color:var(--m-gold);}
.confirm-sub{margin:0 0 4px;font-family:var(--font-mono);font-size:10.5px;color:var(--m-panel-dark-muted);}
.confirm-actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px;}
.confirm-btn{
  flex:1;min-width:96px;padding:11px 12px;
  background:rgba(217,168,78,0.16);border:1px solid var(--m-gold);color:var(--m-gold);
  border-radius:6px;font-family:var(--font-mono);font-size:10.5px;font-weight:600;
  text-transform:uppercase;letter-spacing:.06em;cursor:pointer;
  transition:background .15s ease;
}
.confirm-btn:hover{background:rgba(217,168,78,0.28);}
.confirm-btn-ghost{
  background:transparent;border-color:var(--m-panel-dark-border);color:var(--m-panel-dark-muted);
}
.confirm-btn-ghost:hover{border-color:var(--m-gold);color:var(--m-gold);background:transparent;}

/* ================= ITEM 3: card-panel "chip bar" enter/exit ================= */
@keyframes chip-enter{
  from{opacity:0;transform:translateY(8px);}
  to{opacity:1;transform:translateY(0);}
}
@keyframes chip-exit{
  from{opacity:1;transform:translateY(0);}
  to{opacity:0;transform:translateY(8px);}
}
.card-panel-meta.chip-anim-in, .price-row.chip-anim-in{
  animation:chip-enter 240ms cubic-bezier(.16,1,.3,1) both;
}
.card-panel-meta.chip-anim-out, .price-row.chip-anim-out{
  animation:chip-exit 240ms ease both;
}

/* ================= ITEM 7: settings popover reset-demo link ================= */
.settings-reset-link{
  /* FIX ITEM (UI EASE SWEEP): border-top/margin-top removed -- the new
     .settings-label-data header directly above this link now carries the
     section divider, so this row follows it exactly like sound-vol-slider
     follows its own SOUND label (no second border stacking immediately
     under the first). */
  width:100%;padding:0;
  background:none;border:none;
  color:var(--m-ink-faint);font-family:var(--font-mono);font-size:9.5px;
  text-transform:uppercase;letter-spacing:.06em;cursor:pointer;text-align:left;
  transition:color .15s ease;
}
.settings-reset-link:hover{color:var(--m-accent);}

/* ================= POLISH TICKET item 1: INSPECT mode =================
   Esc-back chip sits outside #hud (appended straight to <body>, same
   pattern #walk-chip already uses) so it's exempt from the dim rule below.
   ------------------------------------------------------------------- */
#inspect-chip{
  position:fixed;left:50%;top:26px;z-index:22;
  transform:translate(-50%,-6px);
  background:var(--m-panel-dark);border:1px solid var(--m-gold);
  color:var(--m-gold);border-radius:999px;
  padding:9px 18px;font-size:11px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;
  cursor:pointer;pointer-events:auto;
  opacity:0;transition:opacity .25s ease, transform .25s ease;
  box-shadow:0 12px 30px rgba(0,0,0,0.32);
}
#inspect-chip[hidden]{display:none;}
#inspect-chip.visible{opacity:1;transform:translate(-50%,0);}

/* everything ELSE in the HUD dims + stops swallowing clicks while
   INSPECTing -- #inspect-chip (above) is the one exception, being outside
   #hud entirely. */
body.meadow-inspecting #hud{
  opacity:0.16;transition:opacity .3s ease;
}
body.meadow-inspecting #hud a,
body.meadow-inspecting #hud button,
body.meadow-inspecting #hud input{
  pointer-events:none;
}
body.meadow-inspecting #walk-chip,
body.meadow-inspecting .confirm-chip{
  opacity:0!important;pointer-events:none;
}

/* REBUILD (ORACLE): the terminal's <input>/quick-chips used to live here as
   standalone fixed-position elements (hidden off-screen input + a
   bottom-docked chip row) -- both replaced by #oracle-overlay, a proper DOM
   modal declared with .market-overlay/.collection-overlay below. See that
   block for .oracle-input/.oracle-quick-btn. */

/* ================= POLISH TICKET item 4: traveler skin picker =================
   Same settings-popover group styling as the reset-demo link above. */
.traveler-skin-group{display:flex;flex-direction:column;gap:4px;margin-bottom:2px;}
.traveler-skin-btn{
  width:100%;text-align:left;padding:7px 9px;
  background:transparent;border:1px solid var(--m-border);border-radius:7px;
  color:var(--m-ink-muted);font-family:var(--font-mono);font-size:10.5px;
  cursor:pointer;transition:color .15s ease, border-color .15s ease, background .15s ease;
}
.traveler-skin-btn:hover{color:var(--m-ink);border-color:rgba(185,130,47,0.4);}
.traveler-skin-btn.active{color:#fbf6ea;background:var(--m-accent);border-color:var(--m-accent);}

/* ================= OWNER ADDITION: demo wallet coin HUD ================= */
.coin-hud{
  display:flex;align-items:center;gap:6px;
  font-size:11px;font-weight:600;letter-spacing:.02em;
  color:var(--m-ink);background:var(--m-panel);border:1px solid var(--m-border);
  /* DESIGN PERFECTION PASS: 6px top/bottom -> 8px, matching the rest of the
     #hud-top pill family; horizontal stays asymmetric (icon hugs the left
     edge) by design. */
  border-radius:999px;padding:8px 12px 8px 8px;backdrop-filter:blur(10px);
}
.coin-hud[hidden]{display:none;}
.coin-hud-icon{width:18px;height:18px;display:block;}
.coin-hud-balance{font-variant-numeric:tabular-nums;}

/* ================= REAL-MODE RAIL: token balance chip =================
   Reuses .coin-hud's pill/blur/border chrome (same #hud-top pill family)
   but with symmetric padding (no icon to hug the left edge -- text-only)
   and the same forest-green accent .mode-real already uses for the REAL
   badge, so the two read as one system: "REAL" pill + real-token-balance
   pill, distinct from the gold .coin-hud that only ever shows in DEMO. */
.wallet-token-chip{
  padding:8px 12px;
  color:#1e6b4f;border-color:#1e6b4f;
  font-variant-numeric:tabular-nums;
}

/* ================= FIX ITEM 4: insufficient-coins shake ================= */
@keyframes coin-hud-shake{
  0%,100%{transform:translateX(0);}
  20%{transform:translateX(-5px);}
  40%{transform:translateX(4px);}
  60%{transform:translateX(-3px);}
  80%{transform:translateX(2px);}
}
.coin-hud.shake{
  animation:coin-hud-shake 400ms ease-in-out;
  border-color:#c1441e;
}

/* ================= FIX ITEM 7: rarity gallery (odds rows) ================= */
.rarity-gallery{
  position:fixed;left:0;right:0;bottom:0;height:30vh;min-height:220px;z-index:24;
  background:var(--m-panel-dark);border-top:1px solid var(--m-gold);
  box-shadow:0 -20px 50px rgba(0,0,0,0.45);
  display:flex;flex-direction:column;
  opacity:0;transform:translateY(16px);
  transition:opacity .3s ease, transform .3s ease;
  pointer-events:auto;
}
.rarity-gallery[hidden]{display:none;}
.rarity-gallery.visible{opacity:1;transform:translateY(0);}
.rarity-gallery-head{
  display:flex;align-items:center;justify-content:space-between;
  padding:14px 20px;border-bottom:1px solid var(--m-panel-dark-border);flex:none;
}
.rarity-gallery-title{color:var(--m-gold);font-size:13px;font-weight:700;letter-spacing:.05em;}
.rarity-gallery-close{
  background:transparent;border:1px solid var(--m-panel-dark-border);color:var(--m-panel-dark-muted);
  border-radius:999px;padding:7px 14px;font-family:var(--font-mono);font-size:10px;
  text-transform:uppercase;letter-spacing:.06em;cursor:pointer;transition:color .15s ease, border-color .15s ease;
}
.rarity-gallery-close:hover{color:var(--m-gold);border-color:var(--m-gold);}
.rarity-gallery-strip{
  flex:1;display:flex;gap:12px;padding:16px 20px 20px;overflow-x:auto;overflow-y:hidden;
  -webkit-overflow-scrolling:touch;
}
.rarity-thumb{
  flex:none;width:120px;height:100%;border-radius:8px;border:1px solid var(--m-panel-dark-border);
  background-color:#1c1811;background-size:cover;background-position:center;
  position:relative;overflow:hidden;cursor:pointer;padding:0;
  transition:border-color .15s ease, transform .15s ease;
}
.rarity-thumb:hover{border-color:var(--m-gold);transform:translateY(-2px);}
.rarity-thumb-fade{
  position:absolute;left:0;right:0;bottom:0;padding:8px 8px 9px;
  background:linear-gradient(to top, rgba(10,8,5,0.94), rgba(10,8,5,0));
  display:flex;flex-direction:column;gap:2px;text-align:left;
}
.rarity-thumb-name{display:block;font-family:var(--font-serif);font-size:12px;color:#fff;line-height:1.2;}
.rarity-thumb-price{display:block;font-family:var(--font-mono);font-size:10px;color:var(--m-gold);}
@media (max-width:600px){
  .rarity-gallery{height:34vh;}
  .rarity-thumb{width:96px;}
}

/* ================= FIX ITEM 7: simple centered card viewer fallback ================= */
.simple-card-viewer{
  position:fixed;inset:0;z-index:25;display:flex;align-items:center;justify-content:center;
  opacity:0;transition:opacity .25s ease;pointer-events:auto;
}
.simple-card-viewer[hidden]{display:none;}
.simple-card-viewer.visible{opacity:1;}
.simple-card-viewer-backdrop{position:absolute;inset:0;background:rgba(8,6,3,0.72);}
.simple-card-viewer-card{
  position:relative;width:min(300px, 82vw);background:var(--m-panel-dark);
  border:1px solid var(--m-gold);border-radius:14px;padding:18px;
  display:flex;flex-direction:column;gap:10px;box-shadow:0 30px 70px rgba(0,0,0,0.5);
  transform:translateY(0);
}
.simple-card-viewer-art{
  width:100%;aspect-ratio:340/480;border-radius:10px;background-size:cover;background-position:center;
  background-color:#1c1811;border:1px solid var(--m-panel-dark-border);
}
.simple-card-viewer-name{margin:0;font-family:var(--font-serif);font-size:18px;color:var(--m-panel-dark-ink);text-align:center;}
.simple-card-viewer-price{margin:0;font-family:var(--font-mono);font-size:12px;color:var(--m-gold);text-align:center;}
.simple-card-viewer-close{
  align-self:flex-end;background:transparent;border:1px solid var(--m-panel-dark-border);color:var(--m-panel-dark-muted);
  border-radius:999px;padding:6px 12px;font-family:var(--font-mono);font-size:10px;
  text-transform:uppercase;letter-spacing:.05em;cursor:pointer;
}
.simple-card-viewer-close:hover{color:var(--m-gold);border-color:var(--m-gold);}

/* ================= ITEM 9: THE ARENA -- summon panel ================= */
.summon-panel{
  position:fixed;left:0;right:0;bottom:0;height:30vh;min-height:220px;z-index:24;
  background:var(--m-panel-dark);border-top:1px solid var(--m-gold);
  box-shadow:0 -20px 50px rgba(0,0,0,0.45);
  display:flex;flex-direction:column;
  opacity:0;transform:translateY(16px);
  transition:opacity .3s ease, transform .3s ease;
  pointer-events:auto;
}
.summon-panel[hidden]{display:none;}
.summon-panel.visible{opacity:1;transform:translateY(0);}
.summon-panel-head{
  display:flex;align-items:center;justify-content:space-between;
  padding:14px 20px;border-bottom:1px solid var(--m-panel-dark-border);flex:none;
}
.summon-panel-title{color:var(--m-gold);font-size:13px;font-weight:700;letter-spacing:.05em;}
.summon-panel-close{
  background:transparent;border:1px solid var(--m-panel-dark-border);color:var(--m-panel-dark-muted);
  border-radius:999px;padding:7px 14px;font-family:var(--font-mono);font-size:10px;
  text-transform:uppercase;letter-spacing:.06em;cursor:pointer;transition:color .15s ease, border-color .15s ease;
}
.summon-panel-close:hover{color:var(--m-gold);border-color:var(--m-gold);}
.summon-panel-empty{
  flex:1;display:flex;align-items:center;justify-content:center;margin:0;
  color:var(--m-panel-dark-muted);font-size:12px;text-align:center;padding:0 24px;
}
/* SUMMON COMBAT V3 ticket item 1: "Follow me"/"Guard arena" toggle row */
.summon-panel-follow-row{padding:0 20px;flex:none;}
.summon-follow-toggle{
  margin-top:12px;
  background:transparent;border:1px solid var(--m-gold);color:var(--m-gold);
  border-radius:999px;padding:8px 16px;font-size:11px;font-weight:600;
  text-transform:uppercase;letter-spacing:.05em;cursor:pointer;
  transition:background .15s ease, color .15s ease;
}
.summon-follow-toggle:hover{background:rgba(217,168,78,0.14);}
.summon-follow-toggle[aria-pressed="true"]{background:var(--m-gold);color:var(--m-panel-dark);}
.summon-panel-strip{
  flex:1;display:flex;gap:12px;padding:16px 20px 20px;overflow-x:auto;overflow-y:hidden;
  -webkit-overflow-scrolling:touch;
}
.summon-thumb{
  flex:none;width:120px;height:100%;border-radius:8px;border:1px solid var(--m-gold);
  background-color:#1c1811;background-size:cover;background-position:center;
  position:relative;overflow:hidden;cursor:pointer;padding:0;
  transition:transform .15s ease, box-shadow .15s ease;
}
.summon-thumb:hover{transform:translateY(-2px);box-shadow:0 8px 20px rgba(217,168,78,0.3);}
.summon-thumb-fade{
  position:absolute;left:0;right:0;bottom:0;padding:8px 8px 9px;
  background:linear-gradient(to top, rgba(10,8,5,0.94), rgba(10,8,5,0));
  display:block;text-align:left;
}
.summon-thumb-name{display:block;font-family:var(--font-serif);font-size:12px;color:#fff;line-height:1.2;}
@media (max-width:600px){
  .summon-panel{height:34vh;}
  .summon-thumb{width:96px;}
}

/* small DOM sprites, fly from the coin-HUD chip to/from a purchase point --
   ease-out only transition (no bounce), per house style */
.coin-fly{
  position:fixed;width:11px;height:11px;border-radius:999px;z-index:23;
  background:radial-gradient(circle at 35% 30%, #f6dfa0, #d9a84e 55%, #a97a2e 100%);
  box-shadow:0 2px 6px rgba(90,58,18,0.4);
  pointer-events:none;
  transform:translate(0,0) scale(1);opacity:1;
  transition:transform .55s cubic-bezier(0,0,.2,1), opacity .55s ease;
  margin:-5.5px 0 0 -5.5px;
}

/* ================= OWNER ADDITION: audio system ================= */
#sound-toggle.active{color:var(--m-accent);border-color:rgba(185,130,47,0.4);}
#sound-vol{width:100%;accent-color:var(--m-accent);margin-top:2px;}

.onboarding-audio-hint{
  margin:-2px 0 20px;font-size:10px;color:var(--m-gold);
  letter-spacing:.04em;opacity:0.85;
}

/* ================= FEATURE B: Full Market overlay (obelisk) =================
   Full-width bottom sheet, same fixed-inset/backdrop/slide pattern as
   .summon-panel above, but capped at max-height:62vh per spec rather than a
   fixed vh, and a paper-grain dark texture over var(--m-panel-dark) (same
   inline feTurbulence data-URI technique meadow.js's #meadow-panel-overrides
   already uses for the card/station panels) instead of a flat fill. */
.market-overlay{
  position:fixed;inset:0;z-index:26;display:flex;align-items:flex-end;justify-content:center;
  opacity:0;pointer-events:none;transition:opacity .25s ease;
}
.market-overlay[hidden]{display:none;}
.market-overlay.visible{opacity:1;pointer-events:auto;}
.market-overlay-backdrop{position:absolute;inset:0;background:rgba(8,6,3,0.6);}
.market-sheet{
  position:relative;width:100%;max-height:62vh;
  background-color:var(--m-panel-mid); /* MARKET LIGHTER: was --m-panel-dark, see the token comment above */
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='g'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix type='matrix' values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.05 0'/></filter><rect width='100%25' height='100%25' filter='url(%23g)'/></svg>");
  background-repeat:repeat;background-size:140px 140px;
  border-top:1px solid var(--m-gold); /* thin gold hairline, per spec */
  box-shadow:0 -20px 50px rgba(0,0,0,0.45);
  border-radius:16px 16px 0 0;
  display:flex;flex-direction:column;
  transform:translateY(16px);transition:transform .3s ease;
}
.market-overlay.visible .market-sheet{transform:translateY(0);}
.market-sheet-head{
  display:flex;align-items:flex-start;justify-content:space-between;
  padding:16px 20px 10px;flex:none;border-bottom:1px solid var(--m-panel-dark-border);
}
.market-eyebrow{margin:0;font-family:var(--font-mono);font-size:10px;letter-spacing:.14em;color:var(--m-gold);text-transform:uppercase;}
.market-title{margin:2px 0 0;font-family:var(--font-serif);font-weight:400;font-size:22px;color:var(--m-panel-dark-ink);}
.market-close{
  background:transparent;border:1px solid var(--m-panel-dark-border);color:var(--m-panel-dark-muted);
  border-radius:999px;padding:7px 14px;font-family:var(--font-mono);font-size:10px;
  text-transform:uppercase;letter-spacing:.06em;cursor:pointer;transition:color .15s ease, border-color .15s ease;
  flex:none;
}
.market-close:hover{color:var(--m-gold);border-color:var(--m-gold);}
.market-tabs{
  display:flex;gap:6px;padding:12px 20px 0;flex:none;overflow-x:auto;-webkit-overflow-scrolling:touch;
}
.market-tab{
  background:transparent;border:1px solid var(--m-panel-dark-border);color:var(--m-panel-dark-muted);
  border-radius:999px;padding:6px 14px;font-family:var(--font-mono);font-size:10.5px;
  text-transform:uppercase;letter-spacing:.06em;cursor:pointer;white-space:nowrap;flex:none;
  transition:color .15s ease, border-color .15s ease, background .15s ease;
}
.market-tab:hover{color:var(--m-gold);border-color:var(--m-gold);}
.market-tab.active{background:rgba(217,168,78,0.16);border-color:var(--m-gold);color:var(--m-gold);}
.market-toolbar{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:10px 20px;flex:none;
}
.market-mode-note{font-size:10.5px;color:var(--m-panel-dark-muted);}
.market-sort{display:flex;align-items:center;gap:6px;font-size:10.5px;color:var(--m-panel-dark-muted);text-transform:uppercase;letter-spacing:.05em;}
.market-sort select{
  background:var(--m-panel-mid);border:1px solid var(--m-panel-dark-border);color:var(--m-panel-dark-ink);
  border-radius:6px;padding:4px 8px;font-family:var(--font-mono);font-size:11px;
}
.market-grid{
  flex:1;min-height:0;overflow-y:auto;padding:6px 20px 20px;
  display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:14px;
}
.market-empty{grid-column:1/-1;text-align:center;color:var(--m-panel-dark-muted);font-size:12px;padding:30px 0;}
.market-subhead{grid-column:1/-1;margin:8px 0 0;font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--m-gold);}
.market-card{
  background:rgba(255,255,255,0.03);border:1px solid var(--m-panel-dark-border);border-radius:10px;
  padding:10px;display:flex;flex-direction:column;gap:6px;
}
.market-card-art{
  width:100%;aspect-ratio:340/480;border-radius:6px;background-size:cover;background-position:center;
  background-color:#1c1811;border:1px solid var(--m-panel-dark-border);
}
.market-card-name{margin:0;font-family:var(--font-serif);font-size:14px;color:var(--m-panel-dark-ink);}
.market-card-meta{display:flex;align-items:center;justify-content:space-between;gap:6px;}
.market-yours{
  font-family:var(--font-mono);font-size:9px;letter-spacing:.08em;color:var(--m-gold);
  border:1px solid var(--m-gold);border-radius:999px;padding:2px 7px;flex:none;
}
.market-qty{font-size:10px;color:var(--m-panel-dark-muted);}
.market-card-foot{display:flex;align-items:center;justify-content:space-between;gap:8px;}
.market-card-price{font-size:12px;font-weight:600;color:var(--m-gold);}
.market-buy-btn, .market-cancel-btn{
  background:rgba(217,168,78,0.16);border:1px solid var(--m-gold);color:var(--m-gold);
  border-radius:999px;padding:5px 12px;font-family:var(--font-mono);font-size:10px;
  text-transform:uppercase;letter-spacing:.06em;cursor:pointer;transition:background .15s ease;flex:none;
}
.market-buy-btn:hover, .market-cancel-btn:hover{background:rgba(217,168,78,0.28);}
.market-cancel-btn{background:transparent;border-color:var(--m-panel-dark-border);color:var(--m-panel-dark-muted);}
.market-cancel-btn:hover{border-color:var(--m-gold);color:var(--m-gold);background:transparent;}

/* ================= INLINE BUY/SELL ticket =================
   Owner: "i can buy nothing in the market" / "when you in the chest you can
   sell and the market as well not after closing the market". Root cause was
   the shared #confirm-chip rendering BEHIND the market/collection overlay's
   own backdrop (z-index 21 vs 26/27) -- its Confirm button was visually and
   functionally unreachable the whole time an overlay was open. Buy/List now
   confirm INLINE, replacing a row's own foot with a price + Confirm/Cancel
   strip -- the overlay never closes, never touches the chip. Full-width
   flex-wrapped row so both buttons clear the 44px tap-target floor even in
   the narrowest (120px) grid column. */
.market-inline-confirm, .market-inline-list{
  display:flex;flex-wrap:wrap;align-items:center;gap:6px;width:100%;
}
.market-inline-price{font-size:12px;font-weight:600;color:var(--m-gold);flex:1 0 100%;}
.market-inline-error{font-size:11px;font-weight:600;color:#e07a5f;flex:1 0 100%;text-align:center;padding:11px 0;}
.market-inline-btn{
  flex:1;min-width:64px;min-height:44px;padding:6px 10px;
  background:rgba(217,168,78,0.16);border:1px solid var(--m-gold);color:var(--m-gold);
  border-radius:8px;font-family:var(--font-mono);font-size:10px;font-weight:600;
  text-transform:uppercase;letter-spacing:.05em;cursor:pointer;transition:background .15s ease;
}
.market-inline-btn:hover{background:rgba(217,168,78,0.28);}
.market-inline-cancel-btn{background:transparent;border-color:var(--m-panel-dark-border);color:var(--m-panel-dark-muted);}
.market-inline-cancel-btn:hover{border-color:var(--m-gold);color:var(--m-gold);background:transparent;}
.market-inline-list .market-inline-btn{min-width:100%;flex-basis:100%;}

@media (max-width:600px){
  .market-sheet{max-height:70vh;}
  .market-grid{grid-template-columns:repeat(auto-fill,minmax(120px,1fr));}
  .market-toolbar{flex-wrap:wrap;}
}

/* ================= POLISH TICKET item 2: My Collection viewer ================= */
.collection-hud-btn{
  display:flex;align-items:center;justify-content:center;
  width:30px;height:30px;padding:0;
  color:var(--m-ink);background:var(--m-panel);border:1px solid var(--m-border);
  border-radius:999px;backdrop-filter:blur(10px);cursor:pointer;
  transition:border-color .15s ease, transform .15s ease;
}
.collection-hud-btn:hover{border-color:var(--m-accent);transform:translateY(-1px);}
.collection-hud-icon{width:18px;height:18px;display:block;}

/* full-width bottom sheet, same fixed-inset/backdrop/slide/paper-grain
   pattern as .market-overlay/.market-sheet above, capped at max-height:70vh
   (per spec) rather than 62vh. */
.collection-overlay{
  position:fixed;inset:0;z-index:27;display:flex;align-items:flex-end;justify-content:center;
  opacity:0;pointer-events:none;transition:opacity .25s ease;
}
.collection-overlay[hidden]{display:none;}
.collection-overlay.visible{opacity:1;pointer-events:auto;}
.collection-overlay-backdrop{position:absolute;inset:0;background:rgba(8,6,3,0.6);}
.collection-sheet{
  position:relative;width:100%;max-height:70vh;
  background-color:var(--m-panel-mid); /* MARKET LIGHTER: same treatment as .market-sheet -- shares the overlay pattern */
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='g'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix type='matrix' values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.05 0'/></filter><rect width='100%25' height='100%25' filter='url(%23g)'/></svg>");
  background-repeat:repeat;background-size:140px 140px;
  border-top:1px solid var(--m-gold);
  box-shadow:0 -20px 50px rgba(0,0,0,0.45);
  border-radius:16px 16px 0 0;
  display:flex;flex-direction:column;
  transform:translateY(16px);transition:transform .3s ease;
}
.collection-overlay.visible .collection-sheet{transform:translateY(0);}
.collection-sheet-head{
  display:flex;align-items:flex-start;justify-content:space-between;
  padding:16px 20px 10px;flex:none;border-bottom:1px solid var(--m-panel-dark-border);
}
.collection-eyebrow{margin:0;font-family:var(--font-mono);font-size:10px;letter-spacing:.14em;color:var(--m-gold);text-transform:uppercase;}
.collection-title{margin:2px 0 0;font-family:var(--font-serif);font-weight:400;font-size:22px;color:var(--m-panel-dark-ink);}
.collection-close{
  background:transparent;border:1px solid var(--m-panel-dark-border);color:var(--m-panel-dark-muted);
  border-radius:999px;padding:7px 14px;font-family:var(--font-mono);font-size:10px;
  text-transform:uppercase;letter-spacing:.06em;cursor:pointer;transition:color .15s ease, border-color .15s ease;
  flex:none;
}
.collection-close:hover{color:var(--m-gold);border-color:var(--m-gold);}
.collection-summary{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:10px 20px;flex:none;font-size:11px;color:var(--m-panel-dark-muted);
}
.collection-vault-value{color:var(--m-gold);}
.collection-grid{
  flex:1;min-height:0;overflow-y:auto;padding:6px 20px 20px;
  display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:14px;
}
.collection-empty{grid-column:1/-1;text-align:center;color:var(--m-panel-dark-muted);font-size:12px;padding:30px 0;}
.collection-card{
  /* DESIGN PERFECTION PASS: border was 2px, the only non-hairline border in
     the file (.market-card, the sibling grid-item pattern, is 1px) */
  background:rgba(255,255,255,0.03);border:1px solid var(--m-panel-dark-border);border-radius:10px;
  padding:8px;display:flex;flex-direction:column;gap:6px;cursor:pointer;
  transition:transform .15s ease, background .15s ease;
}
.collection-card:hover{transform:translateY(-2px);background:rgba(255,255,255,0.06);}
.collection-card-art-wrap{position:relative;display:block;width:100%;}
.collection-card-art{
  width:100%;aspect-ratio:340/480;border-radius:6px;object-fit:cover;display:block;
  background-color:#1c1811;
}
.collection-qty-badge{
  position:absolute;right:5px;bottom:5px;
  background:rgba(8,6,3,0.82);color:var(--m-gold);border:1px solid var(--m-gold);
  border-radius:999px;padding:2px 7px;font-family:var(--font-mono);font-size:10px;font-weight:600;
}
.collection-card-name{margin:0;font-family:var(--font-serif);font-size:13px;color:var(--m-panel-dark-ink);text-align:left;}

/* centered detail viewer, layered ON TOP of .collection-overlay -- same
   fixed/centered/backdrop pattern as .simple-card-viewer above, extended
   with rarity + value + Sell/Summon actions. */
.collection-detail{
  position:fixed;inset:0;z-index:28;display:flex;align-items:center;justify-content:center;
  opacity:0;transition:opacity .25s ease;pointer-events:auto;
}
.collection-detail[hidden]{display:none;}
.collection-detail.visible{opacity:1;}
.collection-detail-backdrop{position:absolute;inset:0;background:rgba(8,6,3,0.78);}
.collection-detail-card{
  position:relative;width:min(320px, 84vw);background:var(--m-panel-mid); /* MARKET LIGHTER: same treatment -- this is the sell/detail popup inside My Cards */
  border:1px solid var(--m-gold);border-radius:14px;padding:18px;
  display:flex;flex-direction:column;align-items:center;gap:8px;
  box-shadow:0 30px 70px rgba(0,0,0,0.5);
}
.collection-detail-art{
  width:100%;aspect-ratio:340/480;border-radius:10px;background-size:cover;background-position:center;
  background-color:#1c1811;border:1px solid var(--m-panel-dark-border);
}
.collection-detail-name{margin:6px 0 0;font-family:var(--font-serif);font-size:19px;color:var(--m-panel-dark-ink);text-align:center;}
.collection-detail-value{margin:0;font-family:var(--font-mono);font-size:11px;color:var(--m-panel-dark-muted);text-align:center;}
/* SIGNATURE SKILLS ticket: gold "Skill: <name>" line, matching .card-panel-skill */
.collection-detail-skill{margin:0;font-family:var(--font-mono);font-size:11px;letter-spacing:.04em;color:var(--m-gold);text-align:center;}
.collection-detail-skill[hidden]{display:none;}
.collection-detail-actions{width:100%;}
/* same "disabled while the vault is locked" treatment as #card-panel-sell above */
#collection-detail-sell-btn:disabled{border-color:var(--m-panel-dark-border);color:var(--m-panel-dark-muted);cursor:not-allowed;background:transparent;}
/* INLINE BUY/SELL: My Cards' own inline sell confirm, swapped in for
   .collection-detail-actions -- see the JS comment above
   collectionDetailSellConfirmEl for why (z-index 28, above the chip). */
.collection-detail-sell-confirm{width:100%;text-align:center;}
.collection-detail-sell-confirm[hidden]{display:none;}
.collection-detail-sell-confirm .confirm-actions{margin-top:8px;}
.collection-detail-close{
  align-self:flex-end;background:transparent;border:1px solid var(--m-panel-dark-border);color:var(--m-panel-dark-muted);
  border-radius:999px;padding:6px 12px;font-family:var(--font-mono);font-size:10px;
  text-transform:uppercase;letter-spacing:.05em;cursor:pointer;
}
.collection-detail-close:hover{color:var(--m-gold);border-color:var(--m-gold);}
@media (max-width:600px){
  .collection-grid{grid-template-columns:repeat(auto-fill,minmax(104px,1fr));}
}

/* ================= REBUILD (owner: "the oracle ui is bugging a lot") =====
   ================= Oracle Terminal overlay =================
   Centered parchment/terminal modal (not a bottom sheet like .market-sheet/
   .collection-sheet -- ~680px max-width per spec, floats over whichever
   station the camera is framing) -- same fixed-inset/backdrop/paper-grain
   technique as those two, Esc/close-button/backdrop-click all close it (see
   meadow.js activateOracleTerminal/deactivateOracleTerminal). The log below
   keeps the dark-near-black/phosphor-green terminal look the old in-world
   canvas used (that part always read fine) -- the bug was the canvas plane
   itself (truncated text, disconnected prompt, leaking into other
   stations), not this palette. */
.oracle-overlay{
  position:fixed;inset:0;z-index:29;display:flex;align-items:center;justify-content:center;
  padding:20px;opacity:0;pointer-events:none;transition:opacity .25s ease;
}
.oracle-overlay[hidden]{display:none;}
.oracle-overlay.visible{opacity:1;pointer-events:auto;}
.oracle-overlay-backdrop{position:absolute;inset:0;background:rgba(8,6,3,0.72);}
.oracle-sheet{
  position:relative;width:100%;max-width:680px;max-height:82vh;
  background-color:var(--m-panel-dark);
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='g'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix type='matrix' values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.05 0'/></filter><rect width='100%25' height='100%25' filter='url(%23g)'/></svg>");
  background-repeat:repeat;background-size:140px 140px;
  border:1px solid var(--m-gold);
  box-shadow:0 30px 70px rgba(0,0,0,0.5);
  border-radius:14px;
  display:flex;flex-direction:column;min-height:0;
  transform:translateY(10px) scale(.98);transition:transform .25s ease;
}
.oracle-overlay.visible .oracle-sheet{transform:translateY(0) scale(1);}
.oracle-sheet-head{
  display:flex;align-items:flex-start;justify-content:space-between;
  padding:16px 20px 10px;flex:none;border-bottom:1px solid var(--m-panel-dark-border);
}
.oracle-eyebrow{margin:0;font-family:var(--font-mono);font-size:10px;letter-spacing:.14em;color:var(--m-gold);text-transform:uppercase;}
.oracle-title{margin:2px 0 0;font-family:var(--font-serif);font-weight:400;font-size:22px;color:var(--m-panel-dark-ink);}
.oracle-close{
  background:transparent;border:1px solid var(--m-panel-dark-border);color:var(--m-panel-dark-muted);
  border-radius:999px;padding:7px 14px;font-family:var(--font-mono);font-size:10px;
  text-transform:uppercase;letter-spacing:.06em;cursor:pointer;transition:color .15s ease, border-color .15s ease;
  flex:none;
}
.oracle-close:hover{color:var(--m-gold);border-color:var(--m-gold);}
/* carved-style command menu, always visible above the scrolling log --
   ORACLE_TERM_MENU_LABEL (meadow.js) is built straight off
   ORACLE_REAL_COMMANDS, the exact list runOracleCommand's switch handles, so
   this can never list a command the parser doesn't accept. */
.oracle-menu-line{
  margin:0;padding:10px 20px 0;font-family:var(--font-mono);font-size:9.5px;
  letter-spacing:.08em;color:rgba(143,232,180,0.55);text-transform:uppercase;flex:none;
}
/* the scrolling output log -- dark-near-black/phosphor-green, same look the
   old canvas terminal had, minus the truncation: white-space:pre-wrap on
   .oracle-line keeps the parser's own hand-padded table spacing (odds/
   collection/holdings) intact while still wrapping long lines instead of
   clipping at an edge, and the log scrolls (slim scrollbar) once content
   overflows instead of losing anything. */
.oracle-log{
  flex:1;min-height:160px;max-height:44vh;overflow-y:auto;
  margin:10px 20px 0;padding:14px 16px;
  background:linear-gradient(180deg,#12180f,#0a0f0b);
  border:1px solid rgba(143,232,180,0.18);border-radius:8px;
  font-family:var(--font-mono);font-size:12.5px;line-height:1.55;
  scrollbar-width:thin;scrollbar-color:rgba(143,232,180,0.35) transparent;
}
.oracle-log::-webkit-scrollbar{width:6px;}
.oracle-log::-webkit-scrollbar-track{background:transparent;}
.oracle-log::-webkit-scrollbar-thumb{background:rgba(143,232,180,0.35);border-radius:999px;}
.oracle-line{margin:0 0 4px;white-space:pre-wrap;word-break:break-word;}
.oracle-line:last-child{margin-bottom:0;}
/* real, visible input row -- ">" prompt + a real <input>, replacing the old
   off-screen hidden input the canvas plane drew a fake caret on top of. */
.oracle-input-row{
  display:flex;align-items:center;gap:8px;flex:none;
  margin:10px 20px 0;padding:9px 12px;
  background:#0a0f0b;border:1px solid rgba(143,232,180,0.25);border-radius:8px;
}
.oracle-prompt{color:#c98b3a;font-family:var(--font-mono);font-size:14px;font-weight:600;flex:none;}
.oracle-input{
  flex:1;min-width:0;background:transparent;border:none;outline:none;
  color:#c9f7d8;font-family:var(--font-mono);font-size:13px;caret-color:#8fe8b4;
}
.oracle-input::placeholder{color:rgba(143,232,180,0.4);}
/* quick-command chips, moved inside the overlay (used to float as a
   standalone fixed-position row docked above the HUD) -- same
   ORACLE_QUICK_COMMANDS source list as the menu line above. */
.oracle-quick-cmds{
  display:flex;flex-wrap:wrap;gap:8px;flex:none;
  margin:12px 20px 20px;
}
.oracle-quick-btn{
  min-width:44px;min-height:44px;padding:0 14px;
  display:inline-flex;align-items:center;justify-content:center;
  background:transparent;border:1px solid var(--m-gold);
  color:var(--m-gold);border-radius:999px;
  font-family:var(--font-mono);font-size:10.5px;font-weight:600;letter-spacing:.06em;
  cursor:pointer;transition:background .15s ease, color .15s ease;
}
.oracle-quick-btn:hover{background:rgba(217,168,78,0.16);}
@media (max-width:600px){
  .oracle-sheet{max-width:92vw;max-height:86vh;}
  .oracle-log{max-height:36vh;}
  /* 16px floor -- iOS Safari zooms the whole page on focusing any input
     under 16px, which would fight the modal's own transform/backdrop. */
  .oracle-input{font-size:16px;}
  .oracle-quick-btn{padding:0 11px;font-size:10px;}
}

/* ================= ITEM 1 addendum: friendly sell/buy confirm sheets =================
   Both .sell-sheet (openSellConfirm) and .buy-sheet (openPostBuyConfirm /
   openMarketBuyConfirm) share this exact layout -- art thumbnail left, name
   + big gold amount + rate/wallet note right -- inside the existing
   .confirm-chip shell, so no new positioning/backdrop rules are needed. */
.sell-sheet, .buy-sheet{
  display:flex;align-items:center;gap:12px;margin-bottom:2px;
}
.sell-sheet-art, .buy-sheet-art{
  flex:none;width:56px;height:78px;border-radius:6px;background-size:cover;background-position:center;
  background-color:#1c1811;border:1px solid var(--m-panel-dark-border);
}
.sell-sheet-info, .buy-sheet-info{min-width:0;flex:1;}
.sell-sheet-amount{
  margin:2px 0 3px;font-size:20px;font-weight:700;color:var(--m-gold);letter-spacing:-0.01em;
}
.sell-sheet-unit{font-size:12px;font-weight:600;opacity:0.75;}
.buy-sheet-amount{margin:2px 0 3px;font-size:18px;font-weight:700;color:var(--m-gold);}
.confirm-btn-big{flex:1 1 100%;padding:13px 12px;font-size:11.5px;}

/* "+N $DOLOS" / "-N $DOLOS" float, rises from the coin-HUD chip and fades --
   ease-out only, no bounce, matching .coin-fly's own easing curve. */
.coin-float{
  position:fixed;z-index:23;transform:translate(-50%,0);
  font-size:13px;font-weight:700;white-space:nowrap;pointer-events:none;
  opacity:0;transition:transform .9s cubic-bezier(0,0,.2,1), opacity .9s ease;
}
.coin-float.rise{transform:translate(-50%,-34px);opacity:0;}
.coin-float:not(.rise){opacity:1;}
.coin-float-earn{color:#5be3a8;}
.coin-float-spend{color:#ff8f7d;}

/* ================= ITEM 3: sold-out market listings ================= */
.market-card-soldout{opacity:0.62;}
.market-card-soldout-label{
  font-size:10px;letter-spacing:.04em;color:var(--m-panel-dark-muted);text-align:right;flex:1;
}

/* ================= ITEM 5: chat panel + trade UI =================
   Bottom-left, collapsible, mono/paper-grain (same inline feTurbulence
   data-URI technique as .market-sheet/.collection-sheet above), capped at
   max 30vh per spec. */
.chat-toggle{
  /* FIX ITEM (CHAT REBUILD): bottom was a static 22px, which the station-nav
     row (variable height -- 2-line wrap under 720px, safe-area padding)
     directly overlapped at several widths (owner screenshot: "panel
     overlapping nav pills"). --meadow-chat-clear is measured live off the
     real nav box in meadow.js (updateChatNavClearance) and always lands
     >= nav height + 12px; the 76px fallback only ever applies for the one
     frame before that JS runs. */
  position:fixed;left:22px;bottom:var(--meadow-chat-clear, 76px);z-index:19;
  display:flex;align-items:center;gap:7px;min-height:44px;/* FIX ITEM (CHAT): touch target */
  font-family:var(--font-mono);font-size:10.5px;font-weight:700;letter-spacing:.06em;
  color:var(--m-accent);background:var(--m-panel);border:1px solid var(--m-accent);
  border-radius:999px;padding:9px 15px;cursor:pointer;backdrop-filter:blur(14px);
  transition:background .15s ease;
}
.chat-toggle:hover{background:rgba(185,130,47,0.12);}
/* DESIGN PERFECTION PASS: dock right of the WALK-mode left joystick zone
   (22px inset + 96px circle + 14px clearance) -- previously sat directly on
   top of it at the shared bottom-left corner whenever WALK mode was active
   on a phone (same breakpoint the joystick itself uses to appear at all,
   see @media (min-width:769px){.walk-joystick{display:none;}} above). The
   <=600px and landscape blocks further down carry matching left offsets
   instead of resetting back to the corner. */
@media (max-width:768px){
  .chat-toggle{left:132px;}
}
.chat-unread-dot{
  width:7px;height:7px;border-radius:999px;background:#ff8f7d;
  box-shadow:0 0 0 2px rgba(255,143,125,0.25);
}
.chat-unread-dot[hidden]{display:none;}
.chat-panel{
  /* FIX ITEM (CHAT REBUILD): "log squashed to a sliver" -- max-height:30vh
     let the panel shrink to whatever tiny box the flex layout left it on a
     short/wide viewport, with the message log (flex:1 below) absorbing all
     of that squeeze. Fixed sane height instead: min 320px desktop (ticket
     spec), capped so it never blows past the viewport. See the <=600px
     block below for the 45vh mobile height. bottom uses the same nav-clear
     var as .chat-toggle above -- they dock at the same corner. */
  position:fixed;left:22px;bottom:var(--meadow-chat-clear, 76px);z-index:19;
  width:min(340px, calc(100vw - 44px));height:min(420px, 60vh);min-height:320px;
  background-color:var(--m-panel-dark);
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='g'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix type='matrix' values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.05 0'/></filter><rect width='100%25' height='100%25' filter='url(%23g)'/></svg>");
  background-repeat:repeat;background-size:140px 140px;
  /* CHAT POLISH (panel chrome): 14px -> 12px -- one consistent radius across
     the whole chat/presence chrome cluster (see .meadow-presence-list
     below, same value) instead of an arbitrary one-off. Shadow stays the
     single 0 20px 50px rgba(0,0,0,0.4) level already shared with that same
     cluster -- nothing here stacks a second shadow on top of it. */
  border:1px solid var(--m-gold);border-radius:12px;
  box-shadow:0 20px 50px rgba(0,0,0,0.4);
  display:flex;flex-direction:column;
  opacity:0;transform:translateY(10px);pointer-events:none;
  transition:opacity .22s ease, transform .22s ease;
}
.chat-panel[hidden]{display:none;}
.chat-panel.visible{opacity:1;transform:translateY(0);pointer-events:auto;}
.chat-panel-head{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:11px 12px;border-bottom:1px solid var(--m-panel-dark-border);flex:none;
  /* CHAT POLISH / responsive sweep: title + online dot + 2 tabs + close all
     share this one row -- at the panel's own min width (340px desktop, or
     the <=600px auto-width block below on a narrow phone) that's tight even
     before the online dot ever shows. flex-wrap (same "fold onto an extra
     line instead of overflow/clip" fix #hud-top already uses above) lets
     the online badge drop to its own line rather than forcing an overlap. */
  flex-wrap:wrap;row-gap:4px;
}
.chat-panel-title{font-size:10.5px;font-weight:700;letter-spacing:.08em;color:var(--m-gold);}
/* CHAT POLISH: online-count dot, mirrors meadow-presence-chip's own count
   (see renderPresenceChip in meadow.js) -- hidden until a real remote
   player is reported, same "never implies multiplayer that isn't there"
   gate as every other presence-driven element in this file. */
.chat-panel-online{
  display:flex;align-items:center;gap:5px;font-size:9.5px;color:var(--m-panel-dark-muted);flex:none;
}
.chat-panel-online[hidden]{display:none;}
.chat-panel-online-dot{width:6px;height:6px;border-radius:999px;background:#8fbf8a;box-shadow:0 0 0 2px rgba(143,191,138,0.22);}
.chat-tabs{display:flex;gap:4px;}
.chat-tab{
  background:transparent;border:1px solid var(--m-panel-dark-border);color:var(--m-panel-dark-muted);
  border-radius:999px;padding:4px 11px;font-family:var(--font-mono);font-size:10px;
  min-height:44px;display:inline-flex;align-items:center;/* FIX ITEM (CHAT): touch target */
  cursor:pointer;transition:color .15s ease, border-color .15s ease, background .15s ease;
}
.chat-tab.active{background:rgba(217,168,78,0.16);border-color:var(--m-gold);color:var(--m-gold);}
.chat-panel-close{
  background:transparent;border:none;color:var(--m-panel-dark-muted);font-size:18px;line-height:1;
  min-width:44px;min-height:44px;display:inline-flex;align-items:center;justify-content:center;/* FIX ITEM (CHAT): touch target */
  cursor:pointer;padding:0 2px;transition:color .15s ease;
}
.chat-panel-close:hover{color:var(--m-gold);}
/* CHAT POLISH: position:relative so .chat-new-pill (below) can dock inside
   this box (just above the input row) without any extra wrapper markup. */
.chat-body{display:flex;flex-direction:column;min-height:0;flex:1;position:relative;}
/* FIX ITEM (CHAT REBUILD): root cause of "OFFER A TRADE form bleeding into
   the Talk tab" -- setChatTab() (meadow.js) toggles the `hidden` attribute
   on both .chat-body and .chat-trade, but neither selector had a matching
   [hidden]{display:none} override, so the class's own `display:flex`
   (author-origin) simply outranked the UA default [hidden] rule and BOTH
   tab bodies rendered stacked on top of each other regardless of which tab
   was active. Explicit overrides, same pattern every other overlay in this
   file already uses ([hidden]{display:none} right after its base rule). */
.chat-body[hidden]{display:none;}
.chat-log{
  flex:1;min-height:0;overflow-y:auto;padding:10px 12px;
  display:flex;flex-direction:column;gap:8px;
  /* FIX ITEM (CHAT REBUILD): "native scrollbars" -- thin gold-tinted
     scrollbar matching the #station-panel/#card-panel treatment above,
     instead of the browser's default chrome. */
  scrollbar-width:thin;scrollbar-color:var(--m-hairline-strong) transparent;
}
.chat-log::-webkit-scrollbar{width:6px;}
.chat-log::-webkit-scrollbar-track{background:transparent;}
.chat-log::-webkit-scrollbar-thumb{background:var(--m-hairline-strong);border-radius:999px;}
/* FIX ITEM (CHAT): message bubbles -- own vs DOLOS vs NPC read from
   BACKGROUND TINT (never a border-left stripe). Own messages align right
   (max 82% width) the way a normal messaging UI reads at a glance; DOLOS/
   ambient stay left. */
.chat-row{
  /* DESIGN PERFECTION PASS: 1.4 -> 1.5 -- typography-rhythm floor for
     wrapping copy; a multi-line message now gets normal reading rhythm.
     FIX ITEM (CHAT REBUILD): 11.5px -> 14px floor per spec. */
  font-size:14px;line-height:1.5;
  padding:7px 10px;border-radius:10px;max-width:82%;
  /* CHAT POLISH: entry animation -- fade+translateY, 150ms. Collapses to
     effectively instant under prefers-reduced-motion automatically via this
     file's own blanket `*{transition-duration:0.01ms}` override above, so
     no separate reduced-motion rule is needed here. */
  opacity:1;transform:translateY(0);
  transition:opacity .15s ease, transform .15s ease;
}
.chat-row.chat-row-enter{opacity:0;transform:translateY(6px);}
/* CHAT POLISH: consecutive same-sender rows cluster -- the grouped row skips
   its own .chat-row-head entirely (see appendChatRow in meadow.js), so it
   just needs a tighter top margin to read as part of the same run instead
   of a lone bubble with its own default flex gap. */
.chat-row.chat-row-grouped{margin-top:-4px;}
/* CHAT POLISH: was justify-content:space-between, which only ever worked
   with exactly 2 children (name, time). The glass mark (below) is now a
   3rd child before the name -- space-between would spread all 3 evenly
   instead of grouping mark+name on the left, so this switches to a plain
   gap + .chat-time's own margin-left:auto, which pushes the time to the
   right regardless of how many siblings precede it. */
.chat-row-head{display:flex;align-items:baseline;gap:6px;margin-bottom:2px;}
.chat-time{font-size:9px;font-weight:400;color:var(--m-panel-dark-muted);opacity:0.7;flex:none;margin-left:auto;}
.chat-name{font-weight:700;margin-right:5px;}
.chat-row-player{align-self:flex-end;background:rgba(217,168,78,0.16);}
.chat-row-player .chat-name{color:var(--m-panel-dark-ink);}
.chat-row-player .chat-text{color:var(--m-panel-dark-muted);}
.chat-row-dolos{align-self:flex-start;background:rgba(255,255,255,0.05);}
.chat-row-dolos .chat-name{color:var(--m-gold);}
.chat-row-dolos .chat-text{color:var(--m-panel-dark-ink);}
/* CHAT POLISH: small glass mark next to DOLOS's own name (never remote
   players, see the strict cls check in appendChatRow) -- same dot+halo
   language as .wallet-dot/.chat-unread-dot/.meadow-presence-dot elsewhere
   in this HUD, not a border-left stripe. */
.chat-dolos-mark{
  display:inline-block;width:6px;height:6px;border-radius:999px;margin-right:5px;
  background:var(--m-gold);box-shadow:0 0 0 3px rgba(217,168,78,0.18);
  vertical-align:middle;
}
/* DESIGN PERFECTION PASS: remote/other-player rows (window.DolosNet.renderRemoteChat
   stamps 'chat-row-dolos chat-row-other' together) previously had no rule of
   their own and silently fell back to the DOLOS treatment -- same white-ish
   tint, same gold name. Own tier now: a faint sage-green wash (distinct from
   DOLOS's white tint and the player's gold tint) with a sage name color,
   same bubble shape, background tint only -- no border-left stripe. Source
   order after .chat-row-dolos so it wins the shared background/name-color
   declarations at equal specificity. */
.chat-row-other{background:rgba(106,158,106,0.14);}
.chat-row-other .chat-name{color:#8fbf8a;}
.chat-row-ambient{align-self:flex-start;background:rgba(255,255,255,0.02);opacity:0.68;}
.chat-row-ambient .chat-name{color:#c9d3da;font-style:italic;}
.chat-row-ambient .chat-text{color:var(--m-panel-dark-muted);font-style:italic;}
/* CHAT POLISH: "new messages" pill -- only surfaces when the log is
   scrolled up and a message lands below the fold (see isChatLogNearBottom/
   showChatNewPill in meadow.js); docked just above the input row, inside
   .chat-body's own box (position:relative, above) so no new fixed-position
   element or z-index-scale entry is needed. */
.chat-new-pill{
  position:absolute;left:50%;bottom:64px;z-index:2;
  transform:translate(-50%,6px);
  background:var(--m-panel-dark);border:1px solid var(--m-gold);color:var(--m-gold);
  border-radius:999px;padding:6px 14px;font-family:var(--font-mono);font-size:10px;font-weight:600;
  letter-spacing:.04em;cursor:pointer;box-shadow:0 10px 24px rgba(0,0,0,0.35);
  opacity:0;transition:opacity .2s ease, transform .2s ease;pointer-events:none;
}
.chat-new-pill[hidden]{display:none;}
.chat-new-pill.visible{opacity:1;transform:translate(-50%,0);pointer-events:auto;}
.chat-input-row{display:flex;align-items:center;gap:8px;padding:10px 12px;border-top:1px solid var(--m-panel-dark-border);flex:none;}
.chat-input{
  flex:1;min-width:0;min-height:44px;background:rgba(255,255,255,0.04);border:1px solid var(--m-panel-dark-border);
  border-radius:8px;padding:8px 10px;color:var(--m-panel-dark-ink);font-size:14px;/* FIX ITEM (CHAT REBUILD): 11.5px -> 14px floor */
  transition:border-color .15s ease, box-shadow .15s ease;
}
/* FIX ITEM (CHAT): explicit gold focus ring, not just the border-color swap */
.chat-input:focus{outline:none;border-color:var(--m-gold);box-shadow:0 0 0 3px rgba(217,168,78,0.25);}
/* CHAT POLISH: character counter -- hidden until the message gets close to
   the 400-char limit (see the chat-input 'input' listener in meadow.js). */
.chat-char-count{font-size:9px;color:var(--m-panel-dark-muted);flex:none;white-space:nowrap;}
.chat-char-count[hidden]{display:none;}
.chat-char-count.chat-char-count-warn{color:#ff8f7d;}
.chat-send-btn{
  background:rgba(217,168,78,0.16);border:1px solid var(--m-gold);color:var(--m-gold);
  border-radius:8px;padding:8px 14px;font-family:var(--font-mono);font-size:14px;font-weight:600;/* FIX ITEM (CHAT REBUILD): 10.5px -> 14px floor */
  min-height:44px;flex:none;/* FIX ITEM (CHAT): touch target; flex:none -- CHAT POLISH: also reused as the trade row Accept/Cancel button, never wants to shrink */
  cursor:pointer;transition:background .15s ease;
}
.chat-send-btn:hover{background:rgba(217,168,78,0.28);}
.chat-trade{flex:1;min-height:0;display:flex;flex-direction:column;padding:12px;gap:10px;overflow-y:auto;}
.chat-trade[hidden]{display:none;} /* FIX ITEM (CHAT REBUILD): see .chat-body[hidden] comment above -- same root cause, same fix */
.chat-trade{scrollbar-width:thin;scrollbar-color:var(--m-hairline-strong) transparent;}
.chat-trade::-webkit-scrollbar{width:6px;}
.chat-trade::-webkit-scrollbar-track{background:transparent;}
.chat-trade::-webkit-scrollbar-thumb{background:var(--m-hairline-strong);border-radius:999px;}
.chat-trade-form{display:flex;flex-direction:column;gap:8px;}
.chat-trade-label{font-size:10px;text-transform:uppercase;letter-spacing:.08em;color:var(--m-panel-dark-muted);}
.chat-trade-select, .chat-trade-input{
  background:rgba(255,255,255,0.04);border:1px solid var(--m-panel-dark-border);border-radius:8px;
  padding:8px 10px;color:var(--m-panel-dark-ink);font-family:var(--font-mono);font-size:14px;width:100%;/* FIX ITEM (CHAT REBUILD): 11px -> 14px floor */
}
.chat-trade-select:focus, .chat-trade-input:focus{outline:none;border-color:var(--m-gold);}
.chat-trade-submit{
  background:rgba(217,168,78,0.16);border:1px solid var(--m-gold);color:var(--m-gold);
  border-radius:8px;padding:9px 12px;font-family:var(--font-mono);font-size:14px;font-weight:600;/* FIX ITEM (CHAT REBUILD): 10.5px -> 14px floor */
  min-height:44px;/* FIX ITEM (CHAT): touch target */
  text-transform:uppercase;letter-spacing:.06em;cursor:pointer;transition:background .15s ease;
}
.chat-trade-submit:hover{background:rgba(217,168,78,0.28);}
.chat-trade-submit:disabled{opacity:0.4;cursor:not-allowed;}
.chat-trade-note{margin:0;font-size:10px;color:var(--m-panel-dark-muted);line-height:1.5;}
.chat-trade-list{display:flex;flex-direction:column;gap:6px;}
/* CHAT POLISH: each row now carries a real card-art thumbnail (same
   background-image:url('assets/cards/...') pattern as .market-card-art/
   .buy-sheet-art/.sell-sheet-art elsewhere in this file) plus a poster
   handle, wrapped in .chat-trade-offer-body so the give/want/poster text
   stacks under the art instead of one long wrapping line. */
.chat-trade-offer{
  display:flex;align-items:center;gap:8px;
  background:rgba(255,255,255,0.03);border:1px solid var(--m-panel-dark-border);border-radius:8px;
  padding:8px 10px;font-size:14px;/* FIX ITEM (CHAT REBUILD): 10.5px -> 14px floor */
}
.chat-trade-offer-art{
  flex:none;width:32px;height:32px;border-radius:6px;background-size:cover;background-position:center;
  background-color:rgba(255,255,255,0.04);border:1px solid var(--m-panel-dark-border);
}
.chat-trade-offer-body{flex:1;min-width:0;display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 6px;}
.chat-trade-offer-give{color:var(--m-panel-dark-ink);font-weight:600;}
.chat-trade-offer-arrow{color:var(--m-gold);}
.chat-trade-offer-want{color:var(--m-panel-dark-muted);}
.chat-trade-offer-poster{flex-basis:100%;font-size:9.5px;color:var(--m-panel-dark-muted);opacity:0.7;text-transform:uppercase;letter-spacing:.04em;}
.chat-trade-empty{margin:4px 0;font-size:11px;color:var(--m-panel-dark-muted);}
@media (max-width:600px){
  .chat-toggle{padding:8px 13px;} /* left stays docked right of the joystick, set above; bottom stays the dynamic --meadow-chat-clear var */
  /* FIX ITEM (CHAT REBUILD): 45vh mobile height per spec (was max-height:38vh,
     same "shrinks to a sliver" issue as the desktop max-height:30vh above). */
  .chat-panel{left:14px;right:14px;width:auto;height:45vh;min-height:0;}
}

/* ================= MULTIPLAYER: presence chip + roster list =================
   Docked directly above .chat-toggle (same left inset, same z-tier 19 --
   see the documented z-index scale above) so it reads as part of the same
   "network" UI cluster. Hidden by default and only ever un-hidden by
   window.DolosNet.applyPresenceState() in meadow.js the first time a REAL
   remote player is reported by Supabase presence -- never shown
   speculatively, so an offline/local-only session never implies
   multiplayer that isn't there. Background-tint rows, 44px touch targets,
   same conventions as the chat panel above -- no border-left stripes. */
.meadow-presence-chip{
  /* ZONE MAP FIX (owner: "the chat open ... interferes"): docked above the
     chat block via --meadow-presence-chip-clear (meadow.js
     updateCommsStackClearance), which measures the REAL rendered height of
     whichever chat element is currently showing -- the 44px .chat-toggle
     pill when closed, or the full .chat-panel (320-420px) when open -- so
     this chip shifts up above the panel instead of sitting underneath it
     the moment chat opens. The calc() fallback reproduces the old fixed
     +52px delta for the one frame before meadow.js's first layout pass. */
  position:fixed;left:22px;bottom:var(--meadow-presence-chip-clear, calc(var(--meadow-chat-clear, 76px) + 52px));z-index:19;
  display:flex;align-items:center;gap:7px;min-height:44px;
  font-family:var(--font-mono);font-size:10.5px;font-weight:700;letter-spacing:.06em;
  color:var(--m-accent);background:var(--m-panel);border:1px solid var(--m-accent);
  border-radius:999px;padding:9px 15px;cursor:pointer;backdrop-filter:blur(14px);
  transition:background .15s ease;
}
.meadow-presence-chip:hover{background:rgba(185,130,47,0.12);}
.meadow-presence-chip[hidden]{display:none;}
.meadow-presence-dot{
  width:7px;height:7px;border-radius:999px;background:#8fbf8a;
  box-shadow:0 0 0 2px rgba(143,191,138,0.25);
}
.meadow-presence-list{
  /* ZONE MAP FIX: same dynamic-measurement treatment as .meadow-presence-chip
     above, stacked one slot higher via --meadow-presence-list-clear (chip
     clearance + the chip's own real height + gap) -- this is what keeps the
     expanded roster list clear of an open .chat-panel too, not just the
     collapsed chip. */
  position:fixed;left:22px;bottom:var(--meadow-presence-list-clear, calc(var(--meadow-chat-clear, 76px) + 100px));z-index:19;
  width:min(240px, calc(100vw - 44px));max-height:26vh;overflow-y:auto;
  background-color:var(--m-panel-dark);
  /* CHAT POLISH (panel chrome): 14px -> 12px, matching .chat-panel's own
     radius above -- one consistent value across the whole chat/presence
     chrome cluster. */
  border:1px solid var(--m-gold);border-radius:12px;
  box-shadow:0 20px 50px rgba(0,0,0,0.4);
  padding:6px;display:flex;flex-direction:column;gap:4px;
}
.meadow-presence-list[hidden]{display:none;}
.meadow-presence-row{
  display:flex;align-items:center;justify-content:space-between;gap:8px;
  min-height:44px;padding:0 10px;border-radius:8px;
  font-family:var(--font-mono);font-size:11px;
  background:rgba(255,255,255,0.03);
}
.meadow-presence-handle{color:var(--m-panel-dark-ink);}
.meadow-presence-you{color:var(--m-panel-dark-muted);font-size:9.5px;letter-spacing:.06em;text-transform:uppercase;}
@media (max-width:768px){
  .meadow-presence-chip{left:132px;} /* same joystick-clearance dock as .chat-toggle above */
  .meadow-presence-list{left:132px;}
}
@media (max-width:600px){
  .meadow-presence-chip{padding:8px 13px;} /* bottom stays the dynamic calc() set above -- old static 66px(=14+52) preserved as the same +52px delta */
  .meadow-presence-list{left:14px;right:14px;width:auto;} /* bottom stays the dynamic calc() set above -- old static 114px(=14+100) preserved as the same +100px delta */
}

/* ================= ITEM 6: "Sound on?" toast =================
   One-time, shown after 3+ actions while muted (see noteMutedAction in
   meadow.js) -- offers to unmute right from the toast, no settings-popover
   detour required. */
.sound-on-toast{
  position:fixed;left:50%;bottom:104px;z-index:23;
  transform:translate(-50%,8px);
  display:flex;align-items:center;gap:12px;
  background:var(--m-panel-dark);border:1px solid var(--m-gold);color:var(--m-panel-dark-ink);
  border-radius:999px;padding:10px 12px 10px 18px;box-shadow:0 20px 50px rgba(0,0,0,0.4);
  font-family:var(--font-mono);font-size:11px;
  opacity:0;transition:opacity .25s ease, transform .25s ease;
  pointer-events:auto;
}
.sound-on-toast.visible{opacity:1;transform:translate(-50%,0);}
.sound-on-toast button{
  background:rgba(217,168,78,0.16);border:1px solid var(--m-gold);color:var(--m-gold);
  border-radius:999px;padding:7px 14px;font-family:var(--font-mono);font-size:10px;font-weight:600;
  text-transform:uppercase;letter-spacing:.06em;cursor:pointer;white-space:nowrap;
  transition:background .15s ease;
}
.sound-on-toast button:hover{background:rgba(217,168,78,0.28);}

/* ================= POLISH TICKET: sound-off boot nudge =================
   One-time-per-SESSION chip when a RETURNING visitor's saved preference is
   muted (see maybeShowSoundOffNudge in meadow.js) -- clarifies "no audio"
   is a remembered choice, not a bug (owner: muted audio read as broken).
   Docked top-right, near #sound-toggle -- same chip family/shape as
   .sound-on-toast above, just its own corner so the two (different trigger,
   different timing) can never collide. */
.sound-off-chip{
  position:fixed;top:calc(76px + env(safe-area-inset-top));right:calc(22px + env(safe-area-inset-right));z-index:23;
  transform:translateY(-8px);
  background:var(--m-panel-dark);border:1px solid var(--m-gold);color:var(--m-panel-dark-ink);
  border-radius:999px;padding:10px 16px;box-shadow:0 20px 50px rgba(0,0,0,0.4);
  font-family:var(--font-mono);font-size:11px;min-height:44px;display:flex;align-items:center;
  opacity:0;transition:opacity .25s ease, transform .25s ease;
  pointer-events:auto;cursor:pointer;max-width:calc(100vw - 32px);
}
.sound-off-chip.visible{opacity:1;transform:translateY(0);}
@media (max-width:600px){
  .sound-off-chip{right:14px;font-size:10px;padding:9px 14px;}
}

/* ================= FIX ITEM (SKILLS): skill-fired toast =================
   Fires alongside the in-world nameplate flash (meadow.js flashNameplateSkill)
   every time a summon's signature skill actually launches -- top-center,
   pointer-events:none (purely informational, never blocks a follow-up click),
   same shape family as .sound-on-toast/.rotate-chip/.install-chip but its own
   position so it can never stack with either. Text only, no icon. */
.skill-toast{
  position:fixed;left:50%;top:calc(176px + env(safe-area-inset-top));z-index:23;
  transform:translate(-50%,-8px);
  background:var(--m-panel-dark);border:1px solid var(--m-gold);color:var(--m-gold);
  border-radius:999px;padding:9px 18px;box-shadow:0 20px 50px rgba(0,0,0,0.4);
  font-family:var(--font-mono);font-size:11px;font-weight:600;letter-spacing:.04em;
  white-space:nowrap;opacity:0;pointer-events:none;
  transition:opacity .25s ease, transform .25s ease;
}
.skill-toast[hidden]{display:none;}
.skill-toast.visible{opacity:1;transform:translate(-50%,0);}
@media (max-width:600px){
  .skill-toast{top:calc(140px + env(safe-area-inset-top));font-size:10px;padding:8px 14px;}
}

/* FIX ITEM (UI EASE SWEEP): first-visit "WASD move . E interact . Q cast"
   toast, shown once when WALK mode is first entered (meadow.js
   maybeShowWalkHint). Same shape/family as .skill-toast directly above --
   its own `top` offset (below .skill-toast's own stack slot) so the two can
   never overlap on the rare frame both would be eligible at once. */
.walk-hint-toast{
  position:fixed;left:50%;top:calc(226px + env(safe-area-inset-top));z-index:23;
  transform:translate(-50%,-8px);
  background:var(--m-panel-dark);border:1px solid var(--m-gold);color:var(--m-gold);
  border-radius:999px;padding:9px 18px;box-shadow:0 20px 50px rgba(0,0,0,0.4);
  font-family:var(--font-mono);font-size:11px;font-weight:600;letter-spacing:.04em;
  white-space:nowrap;opacity:0;pointer-events:none;
  transition:opacity .25s ease, transform .25s ease;
}
.walk-hint-toast[hidden]{display:none;}
.walk-hint-toast.visible{opacity:1;transform:translate(-50%,0);}
@media (max-width:600px){
  .walk-hint-toast{top:calc(190px + env(safe-area-inset-top));font-size:10px;padding:8px 14px;white-space:normal;text-align:center;max-width:calc(100vw - 32px);}
}

/* ================= HOTKEY CAST ticket item 2: on-screen cast button =================
   56px, bottom-right, touch devices / walk mode only (JS gates [hidden] --
   see updateCastButton in meadow.js). A conic-gradient wedge (.cast-btn-
   sweep) sweeps away as the cooldown clears; .on-cooldown desaturates the
   whole button so "not ready" reads at a glance without reading the sweep. */
.cast-btn{
  position:fixed;right:calc(20px + env(safe-area-inset-right));bottom:calc(96px + env(safe-area-inset-bottom));
  z-index:19;width:56px;height:56px;border-radius:999px;padding:0;
  display:flex;align-items:center;justify-content:center;
  background:var(--m-panel-dark);border:2px solid var(--m-gold);color:var(--m-gold);
  cursor:pointer;overflow:hidden;box-shadow:0 12px 30px rgba(0,0,0,0.35);
  transition:filter .15s ease, transform .15s ease;
}
.cast-btn[hidden]{display:none;}
.cast-btn:active{transform:scale(0.94);}
.cast-btn-sweep{position:absolute;inset:0;border-radius:999px;pointer-events:none;}
.cast-btn-label{
  position:relative;z-index:1;font-size:8.5px;font-weight:700;text-transform:uppercase;
  letter-spacing:.03em;text-align:center;line-height:1.15;padding:0 6px;
}
.cast-btn.cast-btn-empty{opacity:0.4;border-color:var(--m-panel-dark-muted);color:var(--m-panel-dark-muted);cursor:default;}
.cast-btn.on-cooldown{filter:grayscale(0.7) brightness(0.75);}

/* ================= PWA TICKET: fullscreen + rotate/install chips =================
   Item 2 (rotate/fullscreen suggestion) and item 4 (home-screen install
   prompt) share one toast shape/position family with .sound-on-toast above,
   just docked to the top of the HUD instead of the bottom. */
.rotate-chip, .install-chip{
  position:fixed;left:50%;top:calc(76px + env(safe-area-inset-top));z-index:21;
  transform:translate(-50%,-8px);
  display:flex;align-items:center;gap:10px;
  background:var(--m-panel-dark);border:1px solid var(--m-gold);color:var(--m-panel-dark-ink);
  border-radius:999px;padding:9px 8px 9px 16px;box-shadow:0 20px 50px rgba(0,0,0,0.4);
  font-family:var(--font-mono);font-size:11px;
  opacity:0;transition:opacity .25s ease, transform .25s ease;
  pointer-events:auto;cursor:pointer;max-width:calc(100vw - 32px);
}
.rotate-chip[hidden], .install-chip[hidden]{display:none;}
.rotate-chip.visible, .install-chip.visible{opacity:1;transform:translate(-50%,0);}
.install-chip{top:calc(126px + env(safe-area-inset-top));} /* stacks below the rotate chip if both are ever visible */
.rotate-chip-close, .install-chip-close{
  background:transparent;border:none;color:var(--m-panel-dark-muted);font-size:16px;line-height:1;
  cursor:pointer;padding:4px 6px;transition:color .15s ease;flex:none;
}
.rotate-chip-close:hover, .install-chip-close:hover{color:var(--m-gold);}
@media (max-width:480px){
  .rotate-chip, .install-chip{font-size:10px;padding:8px 6px 8px 13px;}
}

/* ================= PWA TICKET item 3: mobile landscape layout =================
   Gated to (orientation:landscape) and (max-height:500px) -- a phone
   actually turned sideways, never a landscape tablet/desktop. Portrait is
   completely untouched by every rule in this block. Appended last in the
   file so it wins cascade ties against the earlier max-width breakpoints
   above on any device narrow enough to match both (e.g. a small phone in
   landscape, where landscape width can still be <720px). #station-panel /
   #card-panel's own landscape override lives inside the JS-injected
   #meadow-panel-overrides stylesheet instead (meadow.js) -- it's appended
   to <head> after this stylesheet loads, so an override here would lose
   that cascade tie; see the matching comment there. */
@media (orientation: landscape) and (max-height: 500px){
  /* HUD top bar: slimmer padding, smaller brand lockup, safe-area on all sides */
  #hud{
    padding:calc(8px + env(safe-area-inset-top)) calc(14px + env(safe-area-inset-right))
            calc(8px + env(safe-area-inset-bottom)) calc(14px + env(safe-area-inset-left));
  }
  .meadow-brand-name{font-size:15px;}
  .meadow-brand-sub{display:none;}
  #fps-badge{padding:4px 8px;font-size:9px;}
  .wallet-pill{padding:6px 10px;}
  .wallet-pill span:not(.wallet-dot){display:none;}
  .icon-btn{width:28px;height:28px;}
  #settings-popover{top:54px;right:calc(14px + env(safe-area-inset-right));}

  /* keyboard hint card: ZONE MAP FIX (owner: "hiding instructions") -- was
     `display:none`, same as the old <=768px portrait rule. Same 44px "?"
     collapse as that rule now gives it, just resized to this block's
     smaller 40px icon-btn scale and left-anchored at the same 124px dock
     .chat-toggle/.walk-chip already use here to dodge the move-joystick
     (this query can fire above 768px width -- e.g. 844x390 -- so it needs
     its own copy of the treatment rather than inheriting the portrait one). */
  #hint-card{
    left:calc(124px + env(safe-area-inset-left));
    bottom:var(--meadow-hint-card-clear, 120px);
    width:40px;height:40px;padding:0;gap:0;
    align-items:center;justify-content:center;
    border-radius:999px;overflow:hidden;cursor:pointer;
  }
  #hint-card .hint-row{display:none;}
  #hint-card::before{
    content:'?';font-family:var(--font-mono);font-size:14px;font-weight:700;
    color:var(--m-ink-muted);
  }
  #hint-card.hint-expanded{
    width:auto;height:auto;max-height:70vh;overflow-y:auto;
    padding:10px 14px;border-radius:12px;
    align-items:stretch;justify-content:flex-start;
  }
  #hint-card.hint-expanded::before{display:none;}
  #hint-card.hint-expanded .hint-row{display:flex;}

  /* station nav: numbers only, compact 40px square pills. font-size:0 on
     the button collapses the bare "Pack Table" text node (there's no span
     to target -- only .station-num is wrapped) to zero width; the number
     span resets its own font-size back up so it stays legible. */
  .station-btn{
    font-size:0; padding:0; width:40px; height:40px;
    display:flex;align-items:center;justify-content:center;
  }
  .station-btn .station-num{font-size:11px;}
  .walk-nav-row{gap:6px;}
  .walk-toggle-btn{padding:0 10px;min-height:36px;}
  .traveler-chip{width:32px;height:32px;}

  /* joysticks: move stays anchored bottom-left; look becomes a wide
     right-half touch zone instead of a small circle, so a look-drag can
     start anywhere over there (still clamps to the same WALK_JOY_RADIUS
     around wherever the touch lands -- see walkJoyStart in meadow.js) */
  .walk-joystick{bottom:calc(14px + env(safe-area-inset-bottom));}
  .walk-joystick-move{left:calc(14px + env(safe-area-inset-left));}
  .walk-joystick-look{
    right:0;left:50%;top:8%;bottom:18%;width:auto;height:auto;
    border-radius:16px;background:rgba(23,20,14,0.12);border-color:rgba(255,255,255,0.14);
  }
  /* DESIGN PERFECTION PASS (mobile-landscape collision audit): the base
     rule centers this chip at left:50% -- which is exactly the left edge
     of .walk-joystick-look right above (left:50%, top 8% to bottom 18%,
     i.e. most of the screen height on the right half). Centered, the chip
     sits inside that look-zone's bounds, and walk-chip is z-index 18 vs
     the joystick's 19 (documented scale, not touched here), so taps in the
     overlap would land on the invisible look-drag zone instead of the
     "Press E" chip. Left-anchored instead, clear of the look-zone and
     matching the same left offset .chat-toggle already uses in this block
     to dodge the move-joystick (14px inset + 96px circle + 14px gap). */
  .walk-chip{
    bottom:calc(70px + env(safe-area-inset-bottom));
    left:calc(124px + env(safe-area-inset-left));
    transform:translate(0,6px);
  }
  .walk-chip.visible{transform:translate(0,0);}

  /* bottom-sheet panels currently at a fixed 30vh: side-docked right:300px,
     70vh tall instead, freeing up the scene. Reuses each component's own
     existing sizing property (height for summon-panel/rarity-gallery,
     max-height for chat-panel) rather than switching techniques. */
  .summon-panel, .rarity-gallery{
    left:auto;right:env(safe-area-inset-right);top:auto;bottom:0;
    width:300px;max-width:80vw;height:70vh;min-height:0;
    border-top:none;border-left:1px solid var(--m-gold);border-radius:14px 0 0 0;
  }
  .chat-toggle{
    /* DESIGN PERFECTION PASS: was left:14px, same corner as
       .walk-joystick-move here (also 14px + safe-area) -- docked right of
       the 96px joystick circle instead, same fix as the portrait rule
       above. FIX ITEM (CHAT REBUILD): bottom switched to the same
       --meadow-chat-clear var as the portrait rule -- the static
       14px + safe-area here had the identical nav-overlap bug at this
       breakpoint. */
    left:calc(124px + env(safe-area-inset-left));bottom:var(--meadow-chat-clear, 76px);
  }
  .chat-panel{
    left:auto;right:calc(0px + env(safe-area-inset-right));bottom:var(--meadow-chat-clear, 76px);
    width:300px;max-width:80vw;height:70vh;min-height:0;max-height:70vh;
  }

  .rotate-chip, .install-chip{top:calc(56px + env(safe-area-inset-top));}
  .install-chip{top:calc(100px + env(safe-area-inset-top));}
  /* CHAT/SOUND responsive sweep: landscape HUD chrome is slimmer (8px
     padding, 28px icon-btns -- see the #hud/.icon-btn rules earlier in this
     same block) than portrait's, so the portrait-tuned 76px top offset sits
     lower than it needs to here; tightened to match the same delta
     .rotate-chip/.install-chip already use in this block. */
  .sound-off-chip{top:calc(50px + env(safe-area-inset-top));right:calc(14px + env(safe-area-inset-right));}
}
