/* ============================================================
   Sedal PWA — dark minimalist coin economy
   Palette carried over from the Scriptable widget.
   ============================================================ */

:root {
  --bg:            #0a0a0a;
  --bg-elev:       #111111;
  --bg-elev-2:     #1a1a1a;
  --bg-danger:     #241212;
  --border:        #1f1f1f;
  --text:          #e6e6e6;
  --text-dim:      #aaaaaa;
  --text-faint:    #666666;
  --text-ghost:    #333333;

  --coin:          #ffd166;
  --ok:            #80ed99;
  --danger:        #ff6b6b;
  --info:          #bbddff;

  /* rarity */
  --trash:         #8a8a8a;
  --common:        #ffffff;
  --uncommon:      #80ed99;
  --rare:          #4cc9f0;
  --epic:          #9d4edd;
  --legendary:     #ffd166;
  --mythical:      #f15bb5;
  --none:          #ff6b6b;

  --tab-h: 64px;

  /* Emoji font chain — appended to both font variables so glyphs fall back
     gracefully across platforms. Each platform's browser picks the first
     installed emoji font for each character:
       iOS / macOS Safari  → Apple Color Emoji  (rich, varied)
       Windows / Edge      → Segoe UI Emoji     (Microsoft's set)
       Android / Chrome    → Noto Color Emoji   (Google's set)
       Linux Firefox       → Twemoji Mozilla / Noto Color Emoji
     The chain only activates for characters the body font can't render, so
     it doesn't affect Latin text — only emoji. */
  --font-emoji: 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', 'Twemoji Mozilla', 'EmojiOne Color', 'Android Emoji';

  --font-mono: ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace, var(--font-emoji);
  --font-body: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif, var(--font-emoji);
}

* { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }

html, body {
  height: 100%;
  overflow: hidden;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
  user-select: none;
  -webkit-user-select: none;
  overscroll-behavior: none;
}

#app {
  display: flex;
  flex-direction: column;
  height: 100dvh;
  max-width: 560px;
  margin: 0 auto;
  position: relative;
  padding-top: env(safe-area-inset-top);
  padding-left: env(safe-area-inset-left);
  padding-right: env(safe-area-inset-right);
}

/* ============ SCREENS ============ */
.screen {
  display: none;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  padding-bottom: calc(var(--tab-h) + env(safe-area-inset-bottom));
  animation: fadeIn .18s ease;
}
.screen.active { display: flex; }

@keyframes fadeIn {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ============ TOP BAR (home) ============ */
.top-bar {
  display: flex;
  gap: 6px;
  padding: 12px 14px 10px;
  flex-wrap: wrap;
  align-items: center;
}

.pill {
  display: inline-flex;
  align-items: center;
  padding: 5px 10px;
  background: rgba(0,0,0,0.45);
  border: 1px solid var(--border);
  border-radius: 10px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.2px;
}
.pill-brand   { color: var(--text); }
.pill-weather { color: var(--text-dim); font-weight: 500; font-size: 10px; }
.pill-coins   { color: var(--coin); font-family: var(--font-mono); }

/* ============ HOME STAGE ============ */
.home-stage {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 16px 14px;
  min-height: 0;
}

/* Moon — appears only at night/dusk in the top-left of the sky. The
   emoji content is set by JS (renderHome) based on the current phase.
   Visibility is controlled by the time-of-day class on cast-area.
   Full moon gets a soft glow; new moon has no glow (and is barely visible
   against the dark sky, which feels right). */
.cast-moon {
  position: absolute;
  top: 6%;
  left: 14%;
  font-size: 26px;
  opacity: 0;
  pointer-events: none;
  z-index: 2;
  transition: opacity 1.2s ease, font-size 1.2s ease;
  filter: drop-shadow(0 0 6px rgba(255, 245, 200, 0.5));
}
.cast-area.time-night .cast-moon,
.cast-area.time-dusk  .cast-moon { opacity: 1; }
/* Pulse for full moon on its boost night — the moon throbs gently so the
   player notices the lit-up sky. Class set by JS when phase is full. */
.cast-moon.full-glow {
  font-size: 34px;
  animation: moonGlow 4s ease-in-out infinite;
  filter: drop-shadow(0 0 16px rgba(255, 240, 180, 0.85));
}
@keyframes moonGlow {
  0%, 100% { filter: drop-shadow(0 0 14px rgba(255, 240, 180, 0.7)); }
  50%      { filter: drop-shadow(0 0 22px rgba(255, 240, 180, 1)); }
}

/* Daytime weather emoji — same spot as the moon, but shown only in daytime
   tods (the moon owns night/dusk). Reflects the live weather. */
.cast-weather-sky {
  position: absolute;
  top: 6%;
  left: 14%;
  font-size: 30px;
  opacity: 0;
  pointer-events: none;
  z-index: 2;
  transition: opacity 1.2s ease;
  filter: drop-shadow(0 0 8px rgba(255, 255, 255, 0.25));
  animation: skyWxBob 6s ease-in-out infinite;
}
.cast-area.time-dawn    .cast-weather-sky,
.cast-area.time-morning .cast-weather-sky,
.cast-area.time-midday  .cast-weather-sky,
.cast-area.time-sunset  .cast-weather-sky { opacity: 1; }
.cast-weather-sky.is-storm { animation: skyWxStorm 1.8s ease-in-out infinite; }
@keyframes skyWxBob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-4px); }
}
@keyframes skyWxStorm {
  0%, 100% { filter: drop-shadow(0 0 8px rgba(180,200,255,0.3)); transform: translateY(0); }
  50%      { filter: drop-shadow(0 0 16px rgba(180,200,255,0.7)); transform: translateY(-3px); }
}

/* Stars — scattered dots in the sky band. Multiple radial-gradient
   backgrounds give the appearance of dozens of stars without needing a
   DOM child for each. Visible only at night, with a faint twinkle. */
.cast-stars {
  position: absolute;
  inset: 0 0 auto 0;
  height: 40%;
  pointer-events: none;
  z-index: 1;
  opacity: 0;
  transition: opacity 1.5s ease;
  background-image:
    radial-gradient(1px 1px at 8%  18%, rgba(255,255,255,0.85), transparent 60%),
    radial-gradient(1px 1px at 22% 32%, rgba(255,255,255,0.7),  transparent 60%),
    radial-gradient(1.5px 1.5px at 36% 12%, rgba(255,255,255,0.9), transparent 65%),
    radial-gradient(1px 1px at 47% 44%, rgba(255,255,255,0.6),  transparent 60%),
    radial-gradient(1px 1px at 58% 22%, rgba(255,255,255,0.8),  transparent 60%),
    radial-gradient(1.5px 1.5px at 68% 38%, rgba(255,255,255,0.9), transparent 65%),
    radial-gradient(1px 1px at 78% 14%, rgba(255,255,255,0.7),  transparent 60%),
    radial-gradient(1px 1px at 88% 30%, rgba(255,255,255,0.85), transparent 60%),
    radial-gradient(1px 1px at 14% 50%, rgba(255,255,255,0.55), transparent 60%),
    radial-gradient(1.5px 1.5px at 40% 60%, rgba(255,255,255,0.7), transparent 65%),
    radial-gradient(1px 1px at 65% 55%, rgba(255,255,255,0.6),  transparent 60%),
    radial-gradient(1px 1px at 90% 60%, rgba(255,255,255,0.7),  transparent 60%);
  animation: starsTwinkle 5s ease-in-out infinite;
}
@keyframes starsTwinkle {
  0%, 100% { opacity: 0; }
}
.cast-area.time-night .cast-stars { animation: starsTwinkleNight 5s ease-in-out infinite; }
@keyframes starsTwinkleNight {
  0%, 100% { opacity: 0.85; }
  50%      { opacity: 1; }
}
.cast-area.time-dusk .cast-stars { opacity: 0.35; }

/* Moon-blessed catch popup — toast overlay that floats up briefly when a
   rare+ catch landed during full/new moon. */
/* Workshop craft burst — sparkle/hammer flash at the row center when a
   material-cost tier upgrade succeeds. Fixed-position emoji that scales
   up and fades out over 900ms. */
.craft-burst {
  position: fixed;
  font-size: 32px;
  transform: translate(-50%, -50%) scale(0.5);
  opacity: 0;
  pointer-events: none;
  z-index: 300;
  filter: drop-shadow(0 0 10px rgba(255, 220, 130, 0.8));
  animation: craftBurst 900ms cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}
@keyframes craftBurst {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(0.5); }
  25%  { opacity: 1; transform: translate(-50%, -50%) scale(1.2); }
  70%  { opacity: 1; transform: translate(-50%, -50%) scale(1.0); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(0.85); }
}

.moon-blessed-toast {
  position: fixed;
  top: 14%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0.9);
  z-index: 280;
  background: linear-gradient(135deg, rgba(40, 30, 60, 0.95), rgba(20, 20, 40, 0.95));
  border: 1.5px solid rgba(255, 240, 180, 0.6);
  border-radius: 14px;
  padding: 14px 22px;
  font-size: 16px;
  font-weight: 700;
  color: #fff5c4;
  letter-spacing: 0.4px;
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.7);
  box-shadow: 0 0 28px rgba(255, 240, 180, 0.3);
  pointer-events: none;
  white-space: nowrap;
  animation: moonBlessedFloat 2.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}
@keyframes moonBlessedFloat {
  0%   { opacity: 0; transform: translate(-50%, -10%) scale(0.7); }
  15%  { opacity: 1; transform: translate(-50%, -50%) scale(1.05); }
  80%  { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -120%) scale(1); }
}

/* Shooting Star streak — a brief diagonal flash across the sky when the
   meteor event triggers. Animated by adding .shooting-star-flash to
   cast-area; auto-removes via animation end. */
.cast-area .meteor-streak {
  position: absolute;
  top: 5%;
  left: -10%;
  width: 120px;
  height: 2px;
  background: linear-gradient(90deg, transparent, #ffeeaa, transparent);
  box-shadow: 0 0 16px 2px rgba(255, 238, 170, 0.7);
  transform: rotate(15deg);
  pointer-events: none;
  z-index: 4;
  animation: meteorStreak 1.4s ease-out forwards;
}
@keyframes meteorStreak {
  0%   { left: -20%; top: 4%;  opacity: 0; }
  10%  { opacity: 1; }
  100% { left: 110%; top: 30%; opacity: 0; }
}

.cast-area {
  flex: 1;
  min-height: 220px;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Water depth gradient — the cast-area is the water. The sky div covers the
     top ~40%, so the water reads from the horizon (40%) downward. Light, sunlit
     turquoise just under the surface fading through ocean blue into near-black
     at the floor — light gets absorbed with depth, selling the "we can see into
     the deep" feel where the hook drops. */
  background: linear-gradient(180deg,
    rgba(22, 68, 102, 1)  40%,   /* sunlit surface just below the horizon */
    rgba(13, 46, 80, 1)   58%,
    rgba(7, 26, 54, 1)    76%,
    rgba(3, 13, 32, 1)    90%,
    rgba(1, 6, 18, 1)     100%   /* near-black abyss at the floor */
  );
  border: 1px solid var(--border);
  border-radius: 16px;
  position: relative;
  overflow: hidden;
}

/* Sky band — real div, not a pseudo, so it can stack alongside the boat
   ripple effects (if we ever re-add them) without one rule eating another.
   Occupies the top 40% of the cast-area; the SVG wave below carves the
   visible horizon shape so it feels less rigid than a flat rectangle. */
.cast-sky {
  position: absolute;
  inset: 0 0 auto 0;
  height: 40%;
  pointer-events: none;
  z-index: 0;
  /* Default — bright midday in case the JS class fails to apply */
  background: linear-gradient(180deg,
    #5fb0e0 0%,
    #82c4e8 60%,
    #b5dceb 100%);
  transition: background 1.5s ease;
}

/* Time-of-day variants set by JS on .cast-area. Each is a vertical
   gradient that lands warm/dark near the horizon so the colour where sky
   meets water transitions visibly between the two. */
.cast-area.time-night     .cast-sky { background: linear-gradient(180deg, #060a24 0%, #0e1438 55%, #1b2255 100%); }
.cast-area.time-dawn      .cast-sky { background: linear-gradient(180deg, #2a2966 0%, #845080 45%, #f0a880 100%); }
.cast-area.time-morning   .cast-sky { background: linear-gradient(180deg, #7eb6dc 0%, #b7d9ec 55%, #f0e6c8 100%); }
.cast-area.time-midday    .cast-sky { background: linear-gradient(180deg, #4fa8e0 0%, #82c2e8 55%, #c0e0ee 100%); }
.cast-area.time-sunset    .cast-sky { background: linear-gradient(180deg, #3a2e6e 0%, #d56838 50%, #f8a060 100%); }
.cast-area.time-dusk      .cast-sky { background: linear-gradient(180deg, #14163e 0%, #4a3070 50%, #7a4a78 100%); }

/* Weather effects layer — sits above the sky, below the wave. Each
   weather class enables a different effect (clouds, rain, fog, sun glow).
   The fx layer is the same height as the sky so its effects only show in
   the sky portion. */
.cast-weather-fx {
  position: absolute;
  inset: 0 0 auto 0;
  height: 40%;
  pointer-events: none;
  /* Above the moon/sun (z-index 2) so clouds always pass IN FRONT of them —
     a cloud drifting behind the moon looked wrong. Still below meteors (4). */
  z-index: 3;
  overflow: hidden;
}

/* ===== Weather mood: sky + water darken with worse weather =====
   A translucent overlay sits over the sky and the water, intensity rising
   from cloudy → rain → storm. Layered ON TOP of the time-of-day colour so
   it stays coherent at any hour. Medium-marked: clearly felt, not oppressive. */
.cast-sky::after,
.cast-area::before {
  content: '';
  position: absolute;
  pointer-events: none;
  opacity: 0;
  transition: opacity 1.6s ease, background 1.6s ease;
}
.cast-sky::after {
  inset: 0;
  z-index: 1;
  background: linear-gradient(180deg, rgba(40,48,62,0.55), rgba(30,38,52,0.35));
}
.cast-area::before {
  inset: 40% 0 0 0;   /* water portion only (below the horizon) */
  z-index: 0;
  background: linear-gradient(180deg, rgba(10,18,32,0.5), rgba(4,10,22,0.6));
}
.cast-area.weather-cloudy .cast-sky::after,
.cast-area.weather-overcast .cast-sky::after,
.cast-area.weather-windy  .cast-sky::after { opacity: 0.45; }
.cast-area.weather-cloudy::before,
.cast-area.weather-overcast::before,
.cast-area.weather-windy::before { opacity: 0.35; }
.cast-area.weather-rain .cast-sky::after { opacity: 0.7; }
.cast-area.weather-cold .cast-sky::after { opacity: 0.6; }
.cast-area.weather-rain::before { opacity: 0.55; }
.cast-area.weather-storm .cast-sky::after { opacity: 0.85; }
.cast-area.weather-storm::before { opacity: 0.7; }
.cast-area.weather-foggy .cast-sky::after {
  opacity: 0.5;
  background: linear-gradient(180deg, rgba(200,208,218,0.5), rgba(180,192,206,0.3));
}

/* Foggy — semi-transparent grey veil with a slow drift */
.cast-area.weather-foggy .cast-weather-fx {
  background: linear-gradient(180deg,
    rgba(220, 225, 232, 0.0) 0%,
    rgba(200, 210, 220, 0.35) 60%,
    rgba(180, 195, 210, 0.55) 100%);
  filter: blur(1px);
}

/* Sunny — bright glow centered above the boat */
.cast-area.weather-sunny .cast-weather-fx {
  background: radial-gradient(ellipse at 50% 100%,
    rgba(255, 220, 150, 0.35) 0%,
    rgba(255, 200, 120, 0.15) 30%,
    transparent 60%);
}

/* Cloudy / windy — puffy clouds drifting across the sky. Each "cloud" is a
   cluster of several overlapping circles of varied size (a real cloud is
   lumpy), rather than one big soft ellipse. Tighter colour stops keep a
   defined body with soft edges. */
.cast-area.weather-cloudy .cast-weather-fx,
.cast-area.weather-overcast .cast-weather-fx,
.cast-area.weather-windy  .cast-weather-fx {
  background:
    /* cloud A (left) — 3 puffs */
    radial-gradient(ellipse 8% 14% at 12% 36%, rgba(246,249,253,0.55), transparent 65%),
    radial-gradient(ellipse 11% 19% at 19% 33%, rgba(246,249,253,0.55), transparent 66%),
    radial-gradient(ellipse 7% 13% at 26% 37%, rgba(240,244,250,0.5), transparent 65%),
    /* cloud B (centre) — 3 puffs, a bit larger */
    radial-gradient(ellipse 9% 16% at 44% 50%, rgba(242,246,251,0.5), transparent 65%),
    radial-gradient(ellipse 13% 22% at 52% 47%, rgba(244,247,252,0.52), transparent 66%),
    radial-gradient(ellipse 8% 15% at 60% 51%, rgba(238,242,248,0.46), transparent 65%),
    /* cloud C (right) — 2 puffs */
    radial-gradient(ellipse 10% 17% at 80% 34%, rgba(245,248,252,0.5), transparent 65%),
    radial-gradient(ellipse 7% 13% at 88% 37%, rgba(238,242,248,0.46), transparent 65%);
  background-repeat: no-repeat;
  background-size: 200% 100%;
  animation: cloudDrift 38s linear infinite;
}
@keyframes cloudDrift {
  0%   { background-position: 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%; }
  100% { background-position: 100% 0%, 100% 0%, 100% 0%, 100% 0%, 100% 0%, 100% 0%, 100% 0%, 100% 0%; }
}

/* Rain / Storm sky mood — keep this as atmosphere only.
   Actual falling drops live in .cast-precip and are clipped to the sky,
   so rain never continues into the water. */
.cast-area.weather-rain .cast-weather-fx {
  background:
    linear-gradient(180deg,
      rgba(120, 150, 185, 0.12) 0%,
      rgba(150, 185, 215, 0.08) 58%,
      rgba(210, 230, 245, 0.05) 100%);
}

/* Storm — darker sky veil, no hatch wallpaper */
.cast-area.weather-storm .cast-weather-fx {
  background:
    linear-gradient(180deg,
      rgba(18, 24, 52, 0.50) 0%,
      rgba(18, 28, 48, 0.34) 60%,
      rgba(120, 145, 170, 0.08) 100%);
}

/* Cold — pale icy tint */
.cast-area.weather-cold .cast-weather-fx {
  background: linear-gradient(180deg,
    rgba(220, 235, 245, 0.18) 0%,
    rgba(195, 220, 235, 0.10) 100%);
}

/* SVG wave horizon — sits at sky/water boundary. The path is set by JS
   from a sine function, and the amplitude responds to the active weather
   (calm = nearly flat, storm = big swells). Two stacked paths give a
   parallax feel: a brighter foreground line and a dimmer back line. */
.cast-wave-svg {
  position: absolute;
  left: 0;
  right: 0;
  /* Position at the bottom of the sky band, with the wave's vertical
     amplitude extending slightly above and below the horizon line. */
  top: calc(40% - 28px);
  width: 100%;
  height: 56px;
  pointer-events: none;
  z-index: 2;
}

/* Boat — slightly above the SVG wave so it appears to float on it. */
.cast-boat {
  position: absolute;
  /* Park the boat ON the horizon. The SVG wave's midline is at 40% of the
     cast-area, so we anchor the boat there and lift it by ~70% of its own
     height with translateY so the hull sits ON the line, not below it.
     This is screen-height-agnostic — the boat tracks the horizon at any
     cast-area size. */
  top: 40%;
  left: 50%;
  --boat-lift: 75%;
  --boat-scale: 1;
  transform: translate(-50%, calc(-1 * var(--boat-lift))) scale(var(--boat-scale));
  font-size: 36px;
  animation: castBoatFloat 3s ease-in-out infinite;
  pointer-events: none;
  z-index: 3;
}
@keyframes castBoatFloat {
  0%, 100% { transform: translate(-50%, calc(-1 * var(--boat-lift))) scale(var(--boat-scale)) rotate(-2deg); }
  50%      { transform: translate(-50%, calc(-1 * var(--boat-lift) - 4px)) scale(var(--boat-scale)) rotate(2deg); }
}

/* "Tap Cast to Fish!" prompt — visible only when idle */
.cast-idle-prompt {
  position: absolute;
  bottom: 22%;
  left: 50%;
  transform: translateX(-50%);
  text-align: center;
  font-size: 13px;
  color: rgba(187, 221, 255, 0.85);
  pointer-events: none;
}
.cast-idle-prompt .big {
  font-size: 28px;
  margin-bottom: 6px;
}
/* Hide the idle prompt during a minigame run + when cooldown is active */
.cast-area.minigame .cast-idle-prompt,
.cast-area.cooldown-state .cast-idle-prompt {
  display: none;
}

/* Cooldown state — boat stays on the surface as always, slightly dimmed
   to suggest "resting between casts". Never moved below the water line. */
.cast-area.cooldown-state .cast-boat {
  opacity: 0.75;
}

/* ============================================================
   CAST MINIGAME — hook, silhouette, bite indicator
   The minigame phases are controlled by .phase-* classes on .cast-area
   ============================================================ */

/* Hook — starts hidden, drops in from above */
.cast-hook {
  position: absolute;
  /* Resting position is under the boat at the same depth as the active
     bobbing animation. The drop-in animation overrides this on its way
     down; the .bobbing/.shake states match this. This way a moment of
     class toggling (drop-in removed before bobbing applied) doesn't leave
     the hook stuck in the sky at the old 18% value. */
  top: 65%;
  left: 50%;
  transform: translateX(-50%);
  font-size: 30px;
  pointer-events: none;
  z-index: 2;
  /* Subtle silver glint via drop-shadow */
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.6));
}
.cast-hook.bait-glow-common {
  filter: drop-shadow(0 0 4px rgba(255,255,255,.9)) drop-shadow(0 0 10px rgba(255,255,255,.45));
}
.cast-hook.bait-glow-uncommon {
  filter: drop-shadow(0 0 5px rgba(128,237,153,.95)) drop-shadow(0 0 12px rgba(128,237,153,.55));
}
.cast-hook.bait-glow-rare {
  filter: drop-shadow(0 0 5px rgba(76,201,240,.95)) drop-shadow(0 0 13px rgba(76,201,240,.55));
}
.cast-hook.bait-glow-epic {
  filter: drop-shadow(0 0 5px rgba(157,78,221,.98)) drop-shadow(0 0 14px rgba(157,78,221,.6));
}
.cast-hook.bait-glow-legendary {
  filter: drop-shadow(0 0 5px rgba(255,209,102,.98)) drop-shadow(0 0 15px rgba(255,209,102,.65));
}
.cast-hook.bait-glow-shiny {
  filter: drop-shadow(0 0 6px rgba(255,255,210,1)) drop-shadow(0 0 18px rgba(255,224,102,.75));
}
.cast-hook.bait-glow-mythical {
  filter: drop-shadow(0 0 6px rgba(241,91,181,1)) drop-shadow(0 0 20px rgba(157,78,221,.85));
}
/* Drop-in: hook plunges from the boat down to mid-water. The boat sits
   on the horizon at 40% of the cast-area, so the hook starts there (not
   up at 8% in the sky). */
.cast-hook.drop-in {
  animation: castHookDrop 700ms cubic-bezier(0.5, 0, 0.7, 0.7) forwards;
}
@keyframes castHookDrop {
  from { top: 40%; opacity: 0.6; }
  to   { top: 65%; opacity: 1; }
}
/* Bobbing: gentle vertical movement while waiting */
.cast-hook.bobbing {
  top: 65%;
  animation: castHookBob 1.6s ease-in-out infinite;
}
@keyframes castHookBob {
  0%, 100% { transform: translateX(-50%) translateY(0); }
  50%      { transform: translateX(-50%) translateY(5px); }
}
/* Shake: hook trembles when a fish has bitten */
.cast-hook.shake {
  top: 65%;
  animation: castHookShake 0.18s ease-in-out infinite;
}
@keyframes castHookShake {
  0%, 100% { transform: translateX(-50%) translateY(0) rotate(-4deg); }
  50%      { transform: translateX(-50%) translateY(2px) rotate(4deg); }
}
/* Reel up: hook returns to the boat (at the horizon, not into the sky) */
.cast-hook.reel-up {
  animation: castHookReel 700ms cubic-bezier(0.3, 0.7, 0.4, 1) forwards;
}
@keyframes castHookReel {
  from { top: 65%; }
  to   { top: 40%; opacity: 0.3; }
}
/* Pull out: hook leaves slowly after a miss / no-bite */
.cast-hook.pull-out {
  animation: castHookReel 1000ms ease-in-out forwards;
}

/* Fish silhouette — a dark shadow that swims in from a side, then is "hooked" */
.cast-fish-shadow {
  position: absolute;
  top: 70%;
  left: 0%;
  font-size: 28px;
  /* True black silhouette: brightness(0) zeroes out all emoji colours.
     Drop-shadow then paints a separate rarity-coloured glow around it. */
  filter: brightness(0) drop-shadow(0 1px 3px rgba(0, 0, 0, 0.45));
  opacity: 0.78;
  pointer-events: none;
}
.cast-fish-shadow.approach {
  animation: castShadowApproach 1.4s cubic-bezier(0.45, 0, 0.55, 1) forwards;
}
/* Default approach: swims in from the LEFT side, moving right toward the
   hook. The base 🐟 glyph faces left, so we flip it horizontally to face
   the direction of travel (right). */
.cast-area.fish-from-left .cast-fish-shadow {
  transform: scaleX(-1);
}
.cast-area.fish-from-left .cast-fish-shadow.approach {
  animation: castShadowApproachLeft 1.4s cubic-bezier(0.45, 0, 0.55, 1) forwards;
}
.cast-area.fish-from-right .cast-fish-shadow.approach {
  animation: castShadowApproachRight 1.4s cubic-bezier(0.45, 0, 0.55, 1) forwards;
}
@keyframes castShadowApproach {
  0%   { left: -15%; opacity: 0; }
  20%  { opacity: 0.55; }
  100% { left: 46%; opacity: 0.9; }
}
@keyframes castShadowApproachLeft {
  0%   { left: -15%; opacity: 0; }
  20%  { opacity: 0.55; }
  100% { left: 46%; opacity: 0.9; }
}
@keyframes castShadowApproachRight {
  0%   { left: 115%; opacity: 0; }
  20%  { opacity: 0.55; }
  100% { left: 46%; opacity: 0.9; }
}
/* Hooked: stays attached to the hook position, small wiggle */
.cast-fish-shadow.hooked {
  left: 46%;
  animation: castShadowWiggle 0.22s ease-in-out infinite;
}
@keyframes castShadowWiggle {
  0%, 100% { transform: rotate(-6deg); }
  50%      { transform: rotate(6deg); }
}
/* Same wiggle but for fish that came from the left — keep them flipped */
.cast-area.fish-from-left .cast-fish-shadow.hooked {
  animation: castShadowWiggleFlipped 0.22s ease-in-out infinite;
}
@keyframes castShadowWiggleFlipped {
  0%, 100% { transform: scaleX(-1) rotate(-6deg); }
  50%      { transform: scaleX(-1) rotate(6deg); }
}
/* Reel up alongside the hook — fades and rises */
.cast-fish-shadow.reel-up {
  animation: castShadowReelUp 700ms cubic-bezier(0.3, 0.7, 0.4, 1) forwards;
}
@keyframes castShadowReelUp {
  from { top: 60%; left: 46%; opacity: 0.9; }
  to   { top: 12%; left: 46%; opacity: 0; filter: brightness(1); }
}
.cast-area.fish-from-left .cast-fish-shadow.reel-up {
  animation: castShadowReelUpFlipped 700ms cubic-bezier(0.3, 0.7, 0.4, 1) forwards;
}
@keyframes castShadowReelUpFlipped {
  from { top: 60%; left: 46%; opacity: 0.9; transform: scaleX(-1); }
  to   { top: 12%; left: 46%; opacity: 0; filter: brightness(1); transform: scaleX(-1); }
}
/* Escape: shadow swims off opposite to the side it came from.
   The fish turns around to flee, so its facing direction flips too. */
.cast-area.fish-from-right .cast-fish-shadow.escape {
  /* Came from the right swimming left; now flees back to the right.
     Now-facing-right means we mirror the default left-facing glyph. */
  animation: castShadowEscapeRight 1.1s cubic-bezier(0.6, 0, 0.7, 1) forwards;
}
.cast-area.fish-from-left .cast-fish-shadow.escape {
  /* Came from the left swimming right (flipped via scaleX); now flees back
     to the left, so it returns to the default orientation (no flip). */
  animation: castShadowEscapeLeft 1.1s cubic-bezier(0.6, 0, 0.7, 1) forwards;
}
@keyframes castShadowEscapeRight {
  0%   { left: 46%; opacity: 0.9; transform: scaleX(-1); }
  100% { left: 115%; opacity: 0; transform: scaleX(-1); }
}
@keyframes castShadowEscapeLeft {
  0%   { left: 46%; opacity: 0.9; }
  100% { left: -15%; opacity: 0; }
}

/* Rarity tint on the silhouette — the shape stays pure black; only the
   glow colour around it hints at how rare the catch is. */
.cast-fish-shadow.r-rare      { filter: brightness(0) drop-shadow(0 0 6px rgba(76, 201, 240, 0.70)); }
.cast-fish-shadow.r-epic      { filter: brightness(0) drop-shadow(0 0 8px rgba(157, 78, 221, 0.75)); }
.cast-fish-shadow.r-legendary { filter: brightness(0) drop-shadow(0 0 10px rgba(255, 209, 102, 0.80)); }
.cast-fish-shadow.r-mythical  { filter: brightness(0) drop-shadow(0 0 12px rgba(241, 91, 181, 0.85)); }

/* Bite indicator — yellow ❗ that pops in next to the hook.
   The pop animation is triggered by the .bite-pop class so it can be
   re-applied between taps on multi-tap catches. */
.cast-bite-indicator {
  position: absolute;
  top: 52%;
  left: 56%;
  font-size: 28px;
  filter: drop-shadow(0 0 8px rgba(255, 209, 102, 0.7));
  pointer-events: none;
  /* Default state for visible indicator (no animation): full-size, opaque */
  transform: scale(1);
  opacity: 1;
}
.cast-bite-indicator.bite-pop {
  animation: castBitePop 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes castBitePop {
  0%   { transform: scale(0.4); opacity: 0.3; }
  60%  { transform: scale(1.25); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}

/* Tap hint — pulsing text at the bottom telling the player to tap */
.cast-tap-hint {
  position: absolute;
  bottom: 12%;
  left: 50%;
  transform: translateX(-50%);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 1.5px;
  color: #ffd166;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.7);
  animation: castTapPulse 0.8s ease-in-out infinite;
  pointer-events: none;
}
@keyframes castTapPulse {
  0%, 100% { opacity: 0.7; transform: translateX(-50%) scale(1); }
  50%      { opacity: 1;   transform: translateX(-50%) scale(1.06); }
}

/* "Got away!" / "Nothing biting…" message */
.cast-message {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 16px;
  font-weight: 700;
  color: rgba(255, 130, 130, 0.95);
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.7);
  /* forwards = hold the final keyframe (opacity:0) so the message stays
     invisible after the animation completes. Otherwise the browser reverts
     to the rule's resting opacity:1 between animation-end and the JS hide,
     which reads as a brief re-flash of the text. */
  animation: castMessageFade 1.1s ease-out forwards;
  pointer-events: none;
}
@keyframes castMessageFade {
  0%   { opacity: 0; transform: translate(-50%, -40%); }
  20%  { opacity: 1; transform: translate(-50%, -50%); }
  80%  { opacity: 1; }
  100% { opacity: 0; }
}

/* During bite phase, the whole area has a subtle yellow vignette to draw attention */
.cast-area.phase-bite {
  box-shadow: inset 0 0 40px rgba(255, 209, 102, 0.18);
}
.cast-area.phase-bite .cast-tap-hint {
  cursor: pointer;
}
/* The whole stage is clickable during bite phase so the player can tap anywhere */
.cast-area.phase-bite { cursor: pointer; }

/* ============ LATEST CATCH ============ */
.latest-catch {
  margin-top: 14px;
}
.latest-label {
  font-size: 10px;
  color: var(--text-faint);
  text-transform: uppercase;
  letter-spacing: 1px;
  margin-bottom: 6px;
}
.latest-body {
  background: rgba(0,0,0,0.45);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 10px 12px;
  min-height: 56px;
  display: flex;
  align-items: center;
}
.latest-empty {
  color: var(--text-faint);
  font-size: 12px;
}
.latest-catch-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
}
.latest-catch-item .emoji { font-size: 22px; }
.latest-catch-item .info { flex: 1; min-width: 0; }
.latest-catch-item .name { font-weight: 700; font-size: 14px; }
.latest-catch-item .detail { font-size: 11px; color: var(--text-dim); font-family: var(--font-mono); }
.latest-catch-item .record {
  font-size: 9px;
  color: var(--coin);
  font-weight: 700;
  letter-spacing: 0.5px;
  margin-top: 2px;
}
.latest-catch-item .miss-text {
  color: var(--danger);
  font-size: 13px;
}
.latest-catch-item .multi-badge {
  background: rgba(255, 209, 102, 0.15);
  color: var(--coin);
  padding: 2px 7px;
  border-radius: 6px;
  font-size: 10px;
  font-weight: 700;
  font-family: var(--font-mono);
}

/* ============ CAST CONTROLS ============ */
.cast-controls {
  padding: 6px 14px 8px;
  display: flex;
  gap: 10px;
  align-items: center;
}
.cast-btn {
  flex: 1;
  padding: 14px;
  font-size: 15px;
  font-weight: 700;
  background: #1a7a4a;
  color: white;
  border: none;
  border-radius: 12px;
  cursor: pointer;
  /* Only animate transform + background — explicit so the press doesn't
     transition the color via the catch-all 'all' (which let the darker
     green :active state read as a flash on release). */
  transition: transform 0.12s ease, background 0.18s ease;
  font-family: inherit;
  letter-spacing: 0.3px;
}
.cast-btn:active:not(:disabled) {
  /* Just a scale press — no color change. The button stays green until the
     cooldown actually flips it to the disabled grey style. */
  transform: scale(0.96);
}
/* JS-triggered: .pressed plays the bounce animation for 220ms. The .casting
   class keeps the grey "I'm busy" look on the button for the entire duration
   of the cast minigame, so the player gets immediate feedback that the press
   registered and that the button is now inert. */
.cast-btn.pressed:not(:disabled) {
  animation: castBtnPress 0.22s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.cast-btn.casting:not(:disabled) {
  background: #333;
  color: var(--text-faint);
}
@keyframes castBtnPress {
  0%   { transform: scale(1); }
  35%  { transform: scale(0.92); }
  100% { transform: scale(1); }
}
.cast-btn:disabled {
  background: #333;
  color: var(--text-faint);
  cursor: not-allowed;
}
.timer {
  font-family: var(--font-mono);
  font-size: 14px;
  font-weight: 700;
  color: var(--text-dim);
  min-width: 64px;
  text-align: center;
}
.timer.ready { color: var(--ok); }

.inv-count-row {
  padding: 0 14px 10px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
}
.inv-count-pill {
  font-size: 11px;
  padding: 4px 10px;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-family: var(--font-mono);
  color: var(--text-dim);
}

/* ============ SCREEN HEADER (non-home) ============ */
.screen-header {
  padding: 14px 16px 10px;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  border-bottom: 1px solid var(--border);
}
.screen-title { font-size: 18px; font-weight: 700; letter-spacing: 0.2px; }
.screen-sub   { font-size: 13px; color: var(--coin); font-family: var(--font-mono); font-weight: 600; }

.screen-body {
  flex: 1;
  overflow-y: auto;
  padding: 8px 14px 16px;
  -webkit-overflow-scrolling: touch;
}

/* ============ SECTION HEADER inside screen ============ */
.section-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--text-faint);
  padding: 14px 4px 6px;
}

.hint {
  font-size: 11px;
  color: var(--text-dim);
  padding: 10px 4px;
  font-style: italic;
}

/* ============ INVENTORY ROW ============ */
.inv-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 10px;
  margin-bottom: 6px;
}
.inv-row .emoji { font-size: 20px; min-width: 24px; text-align: center; }
.inv-row .info { flex: 1; min-width: 0; }
.inv-row .inv-actions { display: flex; gap: 6px; align-items: center; }
.inv-row .name { font-weight: 700; font-size: 13px; }
.inv-row .detail { font-size: 10px; color: var(--text-dim); font-family: var(--font-mono); margin-top: 1px; }
.inv-row .keep-btn {
  background: rgba(76, 201, 240, 0.10);
  color: var(--rare);
  border: 1px solid rgba(76, 201, 240, 0.25);
  padding: 6px 9px;
  border-radius: 8px;
  font-size: 12px;
  font-weight: 700;
  font-family: var(--font-mono);
  cursor: pointer;
  transition: all 0.15s;
}
.inv-row .keep-btn:active { transform: scale(0.95); background: rgba(76, 201, 240, 0.18); }

.inv-row .recycle-btn {
  background: rgba(150, 200, 130, 0.12);
  color: #a8d97a;
  border: 1px solid rgba(150, 200, 130, 0.28);
  padding: 6px 9px;
  border-radius: 8px;
  font-size: 12px;
  font-weight: 700;
  font-family: var(--font-mono);
  cursor: pointer;
  transition: all 0.15s;
}
.inv-row .recycle-btn:active { transform: scale(0.95); background: rgba(150, 200, 130, 0.22); }

.inv-row .open-btn {
  background: linear-gradient(180deg, rgba(255, 200, 90, 0.18), rgba(180, 130, 40, 0.10));
  color: #ffd97a;
  border: 1px solid rgba(255, 200, 90, 0.45);
  padding: 6px 9px;
  border-radius: 8px;
  font-size: 12px;
  font-weight: 700;
  font-family: var(--font-mono);
  cursor: pointer;
  transition: all 0.15s;
  box-shadow: 0 0 8px rgba(255, 200, 90, 0.12);
}
.inv-row .open-btn:active { transform: scale(0.95); background: rgba(255, 200, 90, 0.30); }
.inv-row .open-btn.disabled {
  background: rgba(80, 80, 80, 0.15);
  color: var(--text-ghost);
  border-color: rgba(255, 255, 255, 0.08);
  box-shadow: none;
  cursor: not-allowed;
  opacity: 0.55;
}
.chest-loot-line.pirate-drop {
  border-top: 1px dashed rgba(255, 200, 90, 0.25);
  padding-top: 6px;
  margin-top: 2px;
}

.inv-row .sell-btn {
  background: rgba(128, 237, 153, 0.1);
  color: var(--ok);
  border: 1px solid rgba(128, 237, 153, 0.25);
  padding: 6px 10px;
  border-radius: 8px;
  font-size: 12px;
  font-weight: 700;
  font-family: var(--font-mono);
  cursor: pointer;
  transition: all 0.15s;
}
.inv-row .sell-btn:active { transform: scale(0.95); background: rgba(128, 237, 153, 0.2); }

.sell-all-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 12px;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 10px;
  margin-bottom: 6px;
  cursor: pointer;
  transition: background 0.15s;
}
.sell-all-row:active { background: var(--bg-elev-2); }
.sell-all-row .left { font-size: 12px; font-weight: 600; }
.sell-all-row .right { font-size: 12px; color: var(--ok); font-family: var(--font-mono); font-weight: 700; }

/* Recycle-all-row — recycle-tinted variant of sell-all-row */
.sell-all-row.recycle-all-row {
  border-color: rgba(150, 200, 130, 0.32);
  background: linear-gradient(180deg, rgba(150, 200, 130, 0.06), rgba(150, 200, 130, 0.02));
}
.sell-all-row.recycle-all-row .left { color: #a8d97a; }
.sell-all-row.recycle-all-row .right { color: #a8d97a; font-style: italic; font-weight: 600; }

.empty-state {
  text-align: center;
  padding: 48px 20px;
  color: var(--text-faint);
  font-size: 14px;
}

/* ============ SHOP ============ */
.shop-section {
  margin-bottom: 16px;
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
  background: var(--bg-elev);
}
.shop-section-title {
  padding: 13px 14px;
  font-size: 15px;
  font-weight: 800;
  background: var(--bg-elev-2);
  border-bottom: 1px solid var(--border);
  letter-spacing: 0.2px;
}
.shop-current {
  padding: 11px 14px;
  font-size: 13px;
  color: var(--ok);
  border-bottom: 1px solid var(--border);
}
.shop-current .tag { color: var(--text-faint); font-size: 11px; margin-left: 5px; }
.shop-next {
  padding: 15px 14px;
  display: flex;
  flex-direction: column;
  gap: 11px;
}
.shop-next.affordable { cursor: pointer; }

/* Upgrade name + price on one line, both prominent */
.shop-next .up-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.shop-next .up-name {
  font-size: 16px;
  font-weight: 800;
  color: var(--coin);
}
.shop-next.locked .up-name { color: var(--text-faint); }
.shop-next .up-price {
  font-family: var(--font-mono);
  font-size: 17px;
  font-weight: 800;
  color: var(--coin);
  text-shadow: 0 0 10px rgba(255, 209, 102, 0.25);
  white-space: nowrap;
}
.shop-next.locked .up-price {
  color: var(--danger);
  text-shadow: 0 0 8px rgba(255, 107, 107, 0.18);
}

/* Casual benefit line — the "why you'd buy this" */
.shop-next .up-benefit {
  font-size: 13.5px;
  color: var(--fg);
  line-height: 1.5;
  opacity: 0.92;
}
.shop-next.locked .up-benefit { color: var(--text-dim); opacity: 0.8; }

/* Material cost line (workshop) */
.shop-next .up-materials {
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 700;
  color: var(--coin);
}
.shop-next.locked .up-materials { color: var(--danger); }

.shop-next .buy-btn {
  width: 100%;
  background: linear-gradient(180deg, rgba(128, 237, 153, 0.18), rgba(128, 237, 153, 0.1));
  color: var(--ok);
  border: 1px solid rgba(128, 237, 153, 0.4);
  padding: 12px 16px;
  border-radius: 10px;
  font-weight: 800;
  font-size: 14px;
  letter-spacing: 0.5px;
  cursor: pointer;
  transition: all 0.15s;
  font-family: inherit;
  margin-top: 2px;
}
.shop-next .buy-btn:active { transform: scale(0.97); }
.shop-next .up-cant-afford {
  font-size: 12px;
  color: var(--text-faint);
  text-align: center;
  padding: 4px 0;
  font-style: italic;
}
/* Compact MAX label — no longer takes up a full section row. */
.shop-max {
  padding: 6px 12px;
  text-align: center;
  color: var(--coin);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.6px;
  opacity: 0.7;
}

/* Compact section — used when an upgrade is at MAX. Shows just the title
   and a tidy "✅ Name · MAX" tag, on one line. */
.shop-section.shop-section-compact {
  margin-bottom: 8px;
}
.shop-compact-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 12px;
  gap: 10px;
  flex-wrap: wrap;
}
.shop-compact-title {
  font-size: 12px;
  font-weight: 700;
  color: var(--text-dim);
  min-width: 0;
  flex: 1;
}
.shop-compact-max {
  font-size: 11px;
  font-weight: 700;
  color: var(--ok);
  background: rgba(128, 237, 153, 0.10);
  border: 1px solid rgba(128, 237, 153, 0.25);
  border-radius: 999px;
  padding: 3px 10px;
  letter-spacing: 0.4px;
  white-space: nowrap;
}


/* ============ AQUARIUM ============ */
.aquarium-card {
  background: linear-gradient(180deg, rgba(5, 35, 52, 0.92), rgba(2, 12, 20, 0.95));
  border: 1px solid rgba(76, 201, 240, 0.22);
  border-radius: 16px;
  padding: 12px;
  margin: 6px 0 14px;
  box-shadow: 0 12px 30px rgba(0,0,0,0.25), inset 0 0 28px rgba(76,201,240,0.05);
}
.aquarium-head {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  align-items: flex-start;
  margin-bottom: 10px;
}
.aquarium-title {
  font-weight: 800;
  font-size: 14px;
  letter-spacing: 0.4px;
}
.aquarium-sub {
  font-size: 10px;
  color: rgba(187,221,255,0.62);
  margin-top: 2px;
}
.aquarium-capacity {
  font-family: var(--font-mono);
  font-weight: 800;
  color: var(--info);
  font-size: 12px;
  padding: 4px 8px;
  border-radius: 999px;
  background: rgba(76,201,240,0.10);
  border: 1px solid rgba(76,201,240,0.20);
}
.aquarium-tank {
  position: relative;
  /* Fill the remaining viewport height so the tank stretches down to just
     above the tab bar instead of stopping at a fixed 210px. The 360px
     subtracted accounts for the screen header + aquarium head + info card +
     actions + tab bar + small margins. min/max keep small and large phones
     in a comfortable range. */
  height: calc(100vh - 360px);
  min-height: 260px;
  max-height: 520px;
  overflow: hidden;
  border-radius: 14px;
  /* iOS Safari can let the background/blended layers bleed past the rounded
     corner (isolation + mix-blend-mode break the corner clip). A matching
     mask forces the whole tank — background included — to clip to the radius. */
  -webkit-mask-image: -webkit-radial-gradient(white, black);
  -webkit-mask-image: radial-gradient(white, black);
  border: 1px solid rgba(187,221,255,0.10);
  background:
    radial-gradient(circle at 20% 20%, rgba(76,201,240,0.15), transparent 32%),
    radial-gradient(circle at 80% 75%, rgba(157,78,221,0.12), transparent 32%),
    linear-gradient(180deg, #06384b 0%, #031a2a 52%, #010810 100%);
  isolation: isolate;
}
.aquarium-depth {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: linear-gradient(180deg,
    rgba(8,24,44,0) 0%,
    rgba(6,18,36,0.16) 54%,
    rgba(3,12,26,0.50) 100%);
}
.aquarium-godrays {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  overflow: hidden;
  mix-blend-mode: screen;
}
.aquarium-godrays .godray {
  position: absolute;
  top: -10%;
  left: var(--ray-x, 30%);
  width: var(--ray-w, 70px);
  height: 120%;
  transform: skewX(-14deg);
  transform-origin: top center;
  background: linear-gradient(180deg,
    rgba(150,225,255,0.16) 0%,
    rgba(130,210,255,0.09) 42%,
    rgba(120,200,255,0.0) 80%);
  filter: blur(6px);
  opacity: 0.5;
  animation: aquariumGodray var(--ray-dur, 12s) ease-in-out infinite;
  animation-delay: var(--ray-delay, 0s);
}
@keyframes aquariumGodray {
  0%,100% { opacity: 0.28; transform: skewX(-14deg) translateX(0); }
  50%     { opacity: 0.58; transform: skewX(-11deg) translateX(10px); }
}
.aquarium-empty {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(187,221,255,0.46);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.4px;
}

/* Rising bubbles — ambient detail. Each bubble rises from the tank floor
   to the surface, shrinking and fading as it climbs, then loops. Sits
   behind the fish (z-index 1 vs fish 10+). */
.aquarium-bubbles {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  overflow: hidden;
}

/* Swaying seaweed at the tank floor. Each blade is anchored at the bottom
   and sways from its base. Behind the fish (z-index 2), above bubbles. */
.aquarium-plants {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  overflow: hidden;
}
.aq-plant {
  position: absolute;
  bottom: -2px;
  width: 14px;
  height: var(--plant-h, 60px);
  border-radius: 48% 48% 6px 6px;
  transform-origin: bottom center;
  background: linear-gradient(
    180deg,
    hsla(var(--plant-hue, 150), 70%, 55%, 0.30),
    hsla(var(--plant-hue, 150), 75%, 38%, 0.55) 60%,
    hsla(var(--plant-hue, 150), 80%, 28%, 0.70)
  );
  box-shadow: 0 0 8px hsla(var(--plant-hue, 150), 70%, 45%, 0.25);
  animation: aqPlantSway 5.5s ease-in-out infinite;
  animation-delay: var(--plant-delay, 0s);
}
/* A second narrower frond offset to one side for a fuller look */
.aq-plant::before {
  content: '';
  position: absolute;
  bottom: 0;
  left: -8px;
  width: 10px;
  height: 72%;
  border-radius: 48% 48% 6px 6px;
  transform-origin: bottom center;
  background: linear-gradient(
    180deg,
    hsla(var(--plant-hue, 150), 65%, 50%, 0.22),
    hsla(var(--plant-hue, 150), 72%, 34%, 0.50)
  );
  animation: aqPlantSwayAlt 6.5s ease-in-out infinite;
  animation-delay: var(--plant-delay, 0s);
}
@keyframes aqPlantSway {
  0%,100% { transform: rotate(-5deg) scaleY(1); }
  50%     { transform: rotate(6deg) scaleY(1.03); }
}
@keyframes aqPlantSwayAlt {
  0%,100% { transform: rotate(7deg); }
  50%     { transform: rotate(-4deg); }
}
.aq-bubble {
  position: absolute;
  bottom: -20px;
  width: var(--bubble-size, 10px);
  height: var(--bubble-size, 10px);
  border-radius: 50%;
  background:
    radial-gradient(circle at 35% 30%, rgba(255,255,255,0.55), rgba(187,221,255,0.12) 60%, transparent 75%);
  border: 1px solid rgba(255,255,255,0.18);
  opacity: 0;
  /* linear (not ease-in) so the rise is constant-speed — ease-in made
     bubbles appear to stall near the bottom then jump. */
  animation: aqBubbleRise var(--bubble-dur, 8s) linear infinite;
  animation-delay: var(--bubble-delay, 0s);
  will-change: transform, opacity;
}
@keyframes aqBubbleRise {
  0%   { transform: translate(0, 0) scale(1);                          opacity: 0; }
  8%   { opacity: 0.7; }
  50%  { transform: translate(var(--bubble-drift, 0), -280px) scale(0.7); opacity: 0.5; }
  92%  { opacity: 0.12; }
  100% { transform: translate(0, -560px) scale(0.2);                  opacity: 0; }
}
.aquarium-fish {
  position: absolute;
  top: var(--fish-cell-y, var(--fish-top, 50%));
  left: var(--fish-cell-x, var(--fish-left, 50%));
  z-index: var(--fish-z);
  font-size: 25px;
  border: 0;
  background: transparent;
  padding: 10px;
  cursor: pointer;
  outline: none;
  -webkit-tap-highlight-color: transparent;
  filter:
    drop-shadow(0 0 5px rgba(187,221,255,0.20))
    drop-shadow(0 2px 6px rgba(0,0,0,0.55));
  transform: translate(-50%, -50%);
  animation: var(--fish-wander, none) var(--fish-dur, 12s) ease-in-out infinite;
  animation-delay: var(--fish-delay, 0s);
  will-change: transform;
}
.aquarium-fish:focus,
.aquarium-fish:focus-visible,
.aquarium-fish:active {
  outline: none !important;
  box-shadow: none !important;
  border: 0 !important;
}
.aquarium-emoji {
  display: inline-block;
  transform: scale(var(--fish-scale));
  transform-origin: center;
  opacity: var(--fish-opacity, 1);
}
/* Bottom dwellers — absolutely static. */
.aquarium-fish.bottom {
  animation: none;
  /* Anchor by the bottom of the element so a 1.8× scaled crown doesn't
     hang outside the tank. translate(-50%, -100%) centers horizontally and
     places the BOTTOM edge of the item at the `top` coordinate. */
  transform: translate(-50%, -100%) rotate(var(--fish-rotate, 0deg));
}
.aquarium-fish.bottom .aquarium-emoji {
  transform: scale(var(--fish-scale));
}
/* Maelstrom Spirit — fixed position, just spins. */
.aquarium-fish.spirit {
  animation: aquariumSpiritSpin 12s linear infinite;
}
.aquarium-fish.r-rare,
.aquarium-fish.r-epic,
.aquarium-fish.r-legendary,
.aquarium-fish.r-mythical,
.aquarium-fish.r-anomaly,
.aquarium-fish.r-cosmic,
.aquarium-fish.r-eldritch {
  filter:
    drop-shadow(0 0 7px currentColor)
    drop-shadow(0 0 16px currentColor)
    drop-shadow(0 2px 6px rgba(0,0,0,0.55));
}
.aquarium-fish.r-rare { color: var(--rare); }
.aquarium-fish.r-epic { color: var(--epic); }
.aquarium-fish.r-legendary { color: var(--legendary); }
.aquarium-fish.r-mythical { color: var(--mythical); }
.aquarium-fish.r-anomaly,
.aquarium-fish.r-cosmic,
.aquarium-fish.r-eldritch { color: #b78cff; }

.shiny-orbit {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0;
  height: 0;
  pointer-events: none;
  z-index: 6;
  font-size: 16px;
}
.shiny-orbit::before {
  content: '✨';
  position: absolute;
  left: -16px;
  top: -14px;
  font-size: 14px;
  transform: translate(-50%, -50%);
  transform-origin: center center;
  filter:
    drop-shadow(0 0 5px rgba(255,245,150,0.98))
    drop-shadow(0 0 12px rgba(255,190,70,0.70));
  animation: shinySparklePulse 2.6s ease-in-out infinite;
  will-change: transform, opacity;
}
/* Continuous left -> right -> left arc. No midpoint transform jumps. */
@keyframes shinySparklePulse {
  0%, 100% { transform: translate(-50%, -50%) scale(0.7);  opacity: 0.55; }
  50%      { transform: translate(-50%, -50%) scale(1.15); opacity: 1; }
}

/* Favourite "Add to Favourites" button inside the aquarium inspect box.
   Same shape as the existing aq-return button but with gold tint to read
   as the "favourite" action distinct from inventory return. */
.aq-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 6px;
}
.aq-actions .aq-return {
  flex: 1 1 auto;
  margin-top: 0;
}
.aq-return.aq-fav-add {
  background: rgba(255, 220, 90, 0.10);
  border-color: rgba(255, 220, 90, 0.45);
  color: #ffd97a;
}
.aq-return.aq-fav-add:active {
  background: rgba(255, 220, 90, 0.22);
}
.aq-return.aq-fav-add.disabled {
  background: rgba(80, 80, 80, 0.15);
  color: var(--text-ghost);
  border-color: rgba(255, 255, 255, 0.08);
  cursor: not-allowed;
  opacity: 0.55;
}

/* Favourites card — 5-slot trophy showcase sitting below the aquarium.
   Same visual language as the aquarium card but with a gold accent
   instead of cyan, signaling "premium display". */
.favourites-card {
  background: linear-gradient(180deg, rgba(40, 30, 8, 0.88), rgba(15, 10, 2, 0.95));
  border: 1px solid rgba(255, 220, 90, 0.25);
  border-radius: 16px;
  padding: 12px;
  margin: 6px 0 14px;
  box-shadow: 0 12px 30px rgba(0,0,0,0.25), inset 0 0 28px rgba(255, 220, 90, 0.05);
}
.favourites-head {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  align-items: flex-start;
  margin-bottom: 12px;
}
.favourites-title {
  font-weight: 800;
  font-size: 14px;
  letter-spacing: 0.4px;
}
.favourites-sub {
  font-size: 10px;
  color: rgba(255, 230, 160, 0.62);
  margin-top: 2px;
}
.favourites-capacity {
  font-family: var(--font-mono);
  font-weight: 800;
  color: rgba(255, 220, 90, 0.95);
  font-size: 12px;
  padding: 4px 8px;
  border-radius: 999px;
  border: 1px solid rgba(255, 220, 90, 0.40);
  background: rgba(255, 220, 90, 0.08);
}
.favourites-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 8px;
}
.fav-slot {
  aspect-ratio: 1 / 1;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  background: rgba(255, 255, 255, 0.03);
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  padding: 0;
  cursor: pointer;
  font-size: 22px;
  color: rgba(255, 255, 255, 0.18);
  transition: transform 0.12s;
  outline: none;
  -webkit-tap-highlight-color: transparent;
}
.fav-slot:focus,
.fav-slot:focus-visible {
  outline: none;
}
.fav-slot.empty {
  cursor: default;
  /* placeholder ⭐ at low opacity */
}
.fav-slot.filled {
  background:
    radial-gradient(circle at 50% 60%, rgba(0,0,0,0.30), transparent 70%),
    linear-gradient(180deg, rgba(20, 18, 8, 0.85), rgba(10, 8, 2, 0.95));
  color: inherit;
}
/* Rarity-coloured glow on the pedestal. Uses the same r-{rarity} hues
   defined elsewhere — but instead of text color it drives the box glow. */
.fav-slot.filled.r-common    { border-color: rgba(180, 180, 180, 0.45); box-shadow: 0 0 12px rgba(180, 180, 180, 0.20), inset 0 0 18px rgba(180, 180, 180, 0.08); }
.fav-slot.filled.r-uncommon  { border-color: rgba(125, 215, 110, 0.55); box-shadow: 0 0 14px rgba(125, 215, 110, 0.28), inset 0 0 20px rgba(125, 215, 110, 0.10); }
.fav-slot.filled.r-rare      { border-color: rgba(78, 165, 245, 0.60);  box-shadow: 0 0 16px rgba(78, 165, 245, 0.35),  inset 0 0 22px rgba(78, 165, 245, 0.12); }
.fav-slot.filled.r-epic      { border-color: rgba(178, 120, 255, 0.65); box-shadow: 0 0 18px rgba(178, 120, 255, 0.40), inset 0 0 24px rgba(178, 120, 255, 0.14); }
.fav-slot.filled.r-legendary { border-color: rgba(255, 200, 80, 0.70);  box-shadow: 0 0 20px rgba(255, 200, 80, 0.50),  inset 0 0 26px rgba(255, 200, 80, 0.18); }
.fav-slot.filled.r-mythical  { border-color: rgba(255, 100, 200, 0.75); box-shadow: 0 0 24px rgba(255, 100, 200, 0.55), inset 0 0 28px rgba(255, 100, 200, 0.22); }
.fav-slot.filled.r-trash     { border-color: rgba(160, 130, 100, 0.45); box-shadow: 0 0 10px rgba(160, 130, 100, 0.20), inset 0 0 16px rgba(160, 130, 100, 0.08); }
.fav-slot.filled:active { transform: scale(0.94); }

/* Shiny favourites — rarity colour stays ON THE BORDER (from the base
   .r-* rules); shiny adds a layered GLOW only: rarity hue outer ring +
   warm gold halo. Pulses so the gold breathes. The border is NOT
   overridden, so you can still read the tier at a glance. */
.fav-slot.filled.shiny {
  animation: favShinyPulse 2.2s ease-in-out infinite;
}
/* Per-rarity outer-glow colour fed into the pulse keyframe. */
.fav-slot.filled.shiny.r-common    { --rarity-glow: 180, 180, 180; }
.fav-slot.filled.shiny.r-uncommon  { --rarity-glow: 125, 215, 110; }
.fav-slot.filled.shiny.r-rare      { --rarity-glow: 78, 165, 245; }
.fav-slot.filled.shiny.r-epic      { --rarity-glow: 178, 120, 255; }
.fav-slot.filled.shiny.r-legendary { --rarity-glow: 255, 200, 80; }
.fav-slot.filled.shiny.r-mythical  { --rarity-glow: 255, 100, 200; }
.fav-slot.filled.shiny.r-trash     { --rarity-glow: 160, 130, 100; }
@keyframes favShinyPulse {
  0%,100% {
    box-shadow:
      0 0 14px rgba(var(--rarity-glow, 255,215,0), 0.40),
      0 0 10px rgba(255, 215, 0, 0.45),
      inset 0 0 18px rgba(255, 215, 0, 0.15);
  }
  50% {
    box-shadow:
      0 0 22px rgba(var(--rarity-glow, 255,215,0), 0.60),
      0 0 18px rgba(255, 215, 0, 0.75),
      inset 0 0 22px rgba(255, 215, 0, 0.28);
  }
}
.fav-emoji {
  font-size: 30px;
  filter: drop-shadow(0 2px 6px rgba(0,0,0,0.55));
}
.fav-sparkle {
  position: absolute;
  top: 2px;
  right: 4px;
  font-size: 12px;
  filter: drop-shadow(0 0 6px rgba(255,215,0,0.85));
  animation: aquariumSparkleOrbit 1.9s ease-in-out infinite;
}

@keyframes aquariumSparkleOrbit {
  0%,100% { opacity: .45; transform: translate(-50%,-50%) rotate(0deg) translateX(16px) scale(.8); }
  50%     { opacity: 1;   transform: translate(-50%,-50%) rotate(180deg) translateX(20px) scale(1.15); }
}

/* Wide-traveling wander animations.
   Each fish has a deterministic y-row but travels widely across the tank
   horizontally. Two variants per movement style (A/B) so adjacent fish
   in the same row don't move identically. Flip (scaleX(-1)) at the
   direction change so the fish "faces" where it's swimming. */

/* Small fish (common/uncommon/rare) — gentle drift variant A. */
@keyframes aquariumWideDriftA {
  0%   { transform: translate(-50%, -50%) translate(0,     0) scaleX(1); }
  20%  { transform: translate(-50%, -50%) translate(13vw,  calc(var(--fish-vamp,5px) * -1)) scaleX(1); }
  48%  { transform: translate(-50%, -50%) translate(11vw,  var(--fish-vamp,5px)) scaleX(1); }
  50%  { transform: translate(-50%, -50%) translate(11vw,  var(--fish-vamp,5px)) scaleX(-1); }
  72%  { transform: translate(-50%, -50%) translate(4vw,   calc(var(--fish-vamp,5px) * -0.7)) scaleX(-1); }
  98%  { transform: translate(-50%, -50%) translate(-9vw,  var(--fish-vamp,5px)) scaleX(-1); }
  100% { transform: translate(-50%, -50%) translate(0,     0) scaleX(1); }
}

@keyframes aquariumWideDriftB {
  0%   { transform: translate(-50%, -50%) translate(0,     0) scaleX(-1); }
  18%  { transform: translate(-50%, -50%) translate(-11vw, var(--fish-vamp,5px)) scaleX(-1); }
  44%  { transform: translate(-50%, -50%) translate(-15vw, calc(var(--fish-vamp,5px) * -1)) scaleX(-1); }
  50%  { transform: translate(-50%, -50%) translate(-15vw, calc(var(--fish-vamp,5px) * -1)) scaleX(1); }
  68%  { transform: translate(-50%, -50%) translate(-5vw,  var(--fish-vamp,5px)) scaleX(1); }
  96%  { transform: translate(-50%, -50%) translate(11vw,  calc(var(--fish-vamp,5px) * -0.7)) scaleX(1); }
  100% { transform: translate(-50%, -50%) translate(0,     0) scaleX(-1); }
}

@keyframes aquariumWideDriftC {
  0%   { transform: translate(-50%, -50%) translate(0,     0) scaleX(1); }
  22%  { transform: translate(-50%, -50%) translate(8vw,   var(--fish-vamp,5px)) scaleX(1); }
  46%  { transform: translate(-50%, -50%) translate(13vw,  calc(var(--fish-vamp,5px) * 1.5)) scaleX(1); }
  50%  { transform: translate(-50%, -50%) translate(13vw,  calc(var(--fish-vamp,5px) * 1.5)) scaleX(-1); }
  74%  { transform: translate(-50%, -50%) translate(-2vw,  calc(var(--fish-vamp,5px) * -1.2)) scaleX(-1); }
  100% { transform: translate(-50%, -50%) translate(0,     0) scaleX(1); }
}

@keyframes aquariumWideZigzagA {
  0%   { transform: translate(-50%, -50%) translate(0,     0) scaleX(1); }
  15%  { transform: translate(-50%, -50%) translate(9vw,   calc(var(--fish-vamp,5px) * -1)) scaleX(1); }
  30%  { transform: translate(-50%, -50%) translate(14vw,  var(--fish-vamp,5px)) scaleX(1); }
  35%  { transform: translate(-50%, -50%) translate(14vw,  var(--fish-vamp,5px)) scaleX(-1); }
  55%  { transform: translate(-50%, -50%) translate(3vw,   calc(var(--fish-vamp,5px) * -1.2)) scaleX(-1); }
  75%  { transform: translate(-50%, -50%) translate(-11vw, var(--fish-vamp,5px)) scaleX(-1); }
  85%  { transform: translate(-50%, -50%) translate(-11vw, var(--fish-vamp,5px)) scaleX(1); }
  100% { transform: translate(-50%, -50%) translate(0,     0) scaleX(1); }
}

@keyframes aquariumWideZigzagB {
  0%   { transform: translate(-50%, -50%) translate(0,     0) scaleX(-1); }
  20%  { transform: translate(-50%, -50%) translate(-13vw, var(--fish-vamp,5px)) scaleX(-1); }
  35%  { transform: translate(-50%, -50%) translate(-13vw, var(--fish-vamp,5px)) scaleX(1); }
  55%  { transform: translate(-50%, -50%) translate(-2vw,  calc(var(--fish-vamp,5px) * -1.3)) scaleX(1); }
  72%  { transform: translate(-50%, -50%) translate(12vw,  var(--fish-vamp,5px)) scaleX(1); }
  85%  { transform: translate(-50%, -50%) translate(12vw,  var(--fish-vamp,5px)) scaleX(-1); }
  100% { transform: translate(-50%, -50%) translate(0,     0) scaleX(-1); }
}

@keyframes aquariumWideZigzagC {
  0%   { transform: translate(-50%, -50%) translate(0,     0) scaleX(1); }
  18%  { transform: translate(-50%, -50%) translate(10vw,  calc(var(--fish-vamp,5px) * 1.3)) scaleX(1); }
  33%  { transform: translate(-50%, -50%) translate(13vw,  calc(var(--fish-vamp,5px) * -1.3)) scaleX(1); }
  38%  { transform: translate(-50%, -50%) translate(13vw,  calc(var(--fish-vamp,5px) * -1.3)) scaleX(-1); }
  60%  { transform: translate(-50%, -50%) translate(-4vw,  calc(var(--fish-vamp,5px) * 1.1)) scaleX(-1); }
  82%  { transform: translate(-50%, -50%) translate(-12vw, calc(var(--fish-vamp,5px) * -1)) scaleX(-1); }
  100% { transform: translate(-50%, -50%) translate(0,     0) scaleX(1); }
}

/* Float bob — light items (driftwood, sparkle, gem) gently rise and fall
   like flotsam in slow water. No flip (these are symmetric objects). */
@keyframes aquariumFloatBob {
  0%,100% { transform: translate(-50%, -50%) translate(0,                            0); }
  25%     { transform: translate(-50%, -50%) translate(1vw,                          calc(var(--fish-wiggle) * -1)); }
  50%     { transform: translate(-50%, -50%) translate(0,                            var(--fish-wiggle)); }
  75%     { transform: translate(-50%, -50%) translate(-1vw,                         calc(var(--fish-wiggle) * -1)); }
}

/* Maelstrom Spirit: slow continuous rotation, fixed position. */
@keyframes aquariumSpiritSpin {
  from { transform: translate(-50%, -50%) rotate(0deg); }
  to   { transform: translate(-50%, -50%) rotate(360deg); }
}

/* Shiny fish: movement stays on .aquarium-fish; sparkle lives on child layer.
   This fixes shiny catches not swimming because glow animation fought movement. */
.aquarium-fish.shiny {
  background: transparent;
}
.aquarium-fish.shiny .aquarium-emoji {
  filter:
    drop-shadow(0 0 5px rgba(255,215,0,0.75))
    drop-shadow(0 0 14px rgba(255,215,0,0.35));
}

.aquarium-info {
  margin-top: 10px;
  min-height: 52px;
  padding: 10px 12px;
  border-radius: 12px;
  background: rgba(0,0,0,0.28);
  border: 1px solid rgba(255,255,255,0.07);
  color: rgba(230,230,230,0.70);
  font-size: 11px;
}
.aquarium-info .aq-name {
  font-size: 14px;
  font-weight: 800;
  margin-bottom: 3px;
}
.aquarium-info .aq-detail {
  font-family: var(--font-mono);
  color: var(--text-dim);
  font-size: 10px;
}
.aquarium-info .aq-return {
  margin-top: 8px;
  background: rgba(255,255,255,0.06);
  color: var(--text);
  border: 1px solid rgba(255,255,255,0.12);
  padding: 6px 10px;
  border-radius: 8px;
  font-size: 11px;
  font-weight: 700;
}
.aquarium-actions { margin-top: 10px; }
.save-tool-btn.disabled { opacity: 0.45; cursor: not-allowed; }

.aquarium-fly {
  position: fixed;
  z-index: 9999;
  pointer-events: none;
  font-size: 28px;
  transform: translate(-50%, -50%);
  transition: transform 0.65s cubic-bezier(.2,.8,.2,1), opacity 0.65s;
}

/* ============ TROPHIES ============ */
.trophy-section {
  margin-bottom: 16px;
}
.trophy-section .label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1.5px;
  padding: 8px 4px;
}
.trophy-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 10px;
  margin-bottom: 4px;
}
.trophy-row .emoji { font-size: 18px; min-width: 22px; text-align: center; }
.trophy-row .info { flex: 1; min-width: 0; }
.trophy-row .name { font-weight: 700; font-size: 13px; }
.trophy-row .detail { font-size: 10px; color: var(--text-dim); font-family: var(--font-mono); margin-top: 1px; }
.trophy-row.empty .emoji { opacity: 0.3; }
.trophy-row.empty .name { color: var(--text-ghost); font-weight: 500; }
.trophy-row.empty .detail { color: var(--text-ghost); font-style: italic; }

/* Special Catches section — event-only catches, distinct visual treatment
   from the regular rarity-tier Trophy Wall. Gold-tinted border + faint
   gradient backdrop reads as "rare event collection". */
.special-catches-section {
  border: 1px solid rgba(255, 215, 130, 0.25);
  border-radius: 12px;
  padding: 6px 8px;
  background: linear-gradient(180deg, rgba(255, 215, 130, 0.04), rgba(255, 215, 130, 0.01));
}
.special-row { border-left: 2px solid rgba(255, 215, 130, 0.4); }
.special-row.empty { border-left-color: rgba(255, 215, 130, 0.15); }

/* Pirate Trophies — chest-exclusive collection. Rust/amber tint distinct
   from the lighter gold used for Special Catches. */
.pirate-trophies-section {
  border: 1px solid rgba(200, 130, 60, 0.30);
  border-radius: 12px;
  padding: 6px 8px;
  background: linear-gradient(180deg, rgba(200, 130, 60, 0.06), rgba(140, 80, 40, 0.02));
}
.pirate-row { border-left: 2px solid rgba(220, 150, 80, 0.5); }
.pirate-row.empty { border-left-color: rgba(220, 150, 80, 0.18); }

.reset-btn-row {
  padding: 12px;
  background: var(--bg-danger);
  border: 1px solid rgba(255, 107, 107, 0.3);
  border-radius: 10px;
  margin: 8px 0 20px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  cursor: pointer;
  transition: background 0.15s;
}
.reset-btn-row:active { background: #311717; }
.reset-btn-row .t { color: var(--danger); font-weight: 700; font-size: 13px; }
.reset-btn-row .s { color: #d7a0a0; font-size: 10px; }

/* ============ TAB BAR ============ */
.tab-bar {
  position: absolute;
  left: 0; right: 0;
  bottom: 0;
  height: calc(var(--tab-h) + env(safe-area-inset-bottom));
  padding-bottom: env(safe-area-inset-bottom);
  background: rgba(10,10,10,0.92);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-top: 1px solid var(--border);
  display: flex;
  z-index: 50;
}
.tab {
  flex: 1;
  background: none;
  border: none;
  color: var(--text-faint);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  cursor: pointer;
  font-family: inherit;
  transition: color 0.15s;
}
.tab-icon { font-size: 20px; }
.tab-label { font-size: 10px; font-weight: 600; letter-spacing: 0.3px; }
.tab.active { color: var(--text); }
.tab.active .tab-icon { transform: scale(1.08); }

/* ============ CATCH POPUP ============ */
.catch-popup {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0,0,0,0.7);
  z-index: 100;
  animation: popupBg 0.2s ease;
  padding: 20px;
}
.catch-popup.hidden { display: none; }
@keyframes popupBg {
  from { background: rgba(0,0,0,0); }
  to   { background: rgba(0,0,0,0.7); }
}

.catch-popup-inner {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 24px 20px;
  max-width: 320px;
  width: 100%;
  text-align: center;
  animation: popupPop 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes popupPop {
  from { transform: scale(0.7); opacity: 0; }
  to   { transform: scale(1); opacity: 1; }
}

.popup-header {
  font-size: 11px;
  color: var(--text-faint);
  text-transform: uppercase;
  letter-spacing: 1.5px;
  margin-bottom: 14px;
}
.popup-catch {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 12px;
  background: var(--bg);
  border-radius: 10px;
  margin-bottom: 6px;
  text-align: left;
}
.popup-catch .emoji { font-size: 30px; position: relative; }
.popup-catch .name { font-weight: 700; font-size: 16px; }
.popup-catch .detail { font-size: 11px; color: var(--text-dim); font-family: var(--font-mono); margin-top: 2px; }
.popup-catch .rarity-tag {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 1px;
  margin-top: 3px;
}
.popup-catch .record {
  position: absolute;
  top: -6px;
  right: -6px;
  background: var(--coin);
  color: #000;
  font-size: 9px;
  font-weight: 800;
  padding: 2px 6px;
  border-radius: 6px;
}
.popup-catch { position: relative; }

/* Skill Cast Perfect bonus indicators per catch */
.catch-bonus-badge {
  display: inline-block;
  font-size: 10px;
  font-weight: 800;
  padding: 2px 6px;
  border-radius: 6px;
  vertical-align: middle;
  margin-left: 4px;
  letter-spacing: 0.5px;
}
.catch-bonus-badge.multi-extra {
  background: var(--coin);
  color: #000;
  position: absolute;
  top: -4px;
  right: -8px;
  font-size: 11px;
  padding: 2px 5px;
  box-shadow: 0 0 8px rgba(255, 220, 90, 0.6);
}
.catch-bonus-badge.rarity-upgrade {
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid currentColor;
  /* color comes from the r-{rarity} class on the same span */
  text-shadow: 0 0 4px currentColor;
  padding: 2px 7px;
  font-size: 9px;
}
/* Doubled-coin price: golden glow + pulse so the bonus is unmistakable */
.catch-price.coin-doubled,
.price.coin-doubled {
  color: var(--coin);
  font-weight: 800;
  text-shadow: 0 0 6px rgba(255, 220, 90, 0.85);
  animation: coinDoubledPulse 1.2s ease-in-out infinite;
}
@keyframes coinDoubledPulse {
  0%, 100% { text-shadow: 0 0 6px rgba(255, 220, 90, 0.85); }
  50%      { text-shadow: 0 0 12px rgba(255, 220, 90, 1), 0 0 20px rgba(255, 220, 90, 0.6); }
}

.popup-miss {
  padding: 32px 20px;
  font-size: 16px;
  color: var(--danger);
  font-weight: 600;
}
.popup-close {
  margin-top: 20px;
  width: 100%;
  background: rgba(128, 237, 153, 0.15);
  color: var(--ok);
  border: 1px solid rgba(128, 237, 153, 0.45);
  padding: 16px 20px;
  border-radius: 12px;
  font-weight: 800;
  font-size: 16px;
  cursor: pointer;
  font-family: inherit;
}
.popup-close:active { transform: scale(0.98); background: rgba(128, 237, 153, 0.25); }

/* When tinted by rarity, the button border + background follow the rarity
   text color (set by the r-* class), matching the popup frame glow. */
.popup-close.nice-rarity {
  border-color: currentColor;
  background: rgba(255, 255, 255, 0.06); /* fallback for old browsers */
  background: color-mix(in srgb, currentColor 14%, transparent);
}
.popup-close.nice-rarity:active {
  background: rgba(255, 255, 255, 0.12); /* fallback */
  background: color-mix(in srgb, currentColor 26%, transparent);
}

/* ============ MODAL ============ */
.modal {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.75);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
  padding: 20px;
}
.modal.hidden { display: none; }
.modal-inner {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 24px 20px;
  max-width: 340px;
  width: 100%;
  text-align: center;
}
.modal-title {
  font-size: 17px;
  font-weight: 700;
  color: var(--danger);
  margin-bottom: 8px;
}
.modal-sub {
  font-size: 12px;
  color: var(--text-dim);
  margin-bottom: 18px;
  line-height: 1.5;
}
.modal-btn {
  display: block;
  width: 100%;
  padding: 12px;
  font-size: 13px;
  font-weight: 700;
  border: none;
  border-radius: 10px;
  cursor: pointer;
  margin-bottom: 8px;
  font-family: inherit;
}
.modal-btn:active { transform: scale(0.98); }
.modal-btn-danger {
  background: rgba(255, 107, 107, 0.15);
  color: var(--danger);
  border: 1px solid rgba(255, 107, 107, 0.4);
}
.modal-btn-cancel {
  background: rgba(128, 237, 153, 0.1);
  color: var(--ok);
  border: 1px solid rgba(128, 237, 153, 0.25);
}

/* ============ RARITY COLORS ============ */
.r-trash     { color: var(--trash); }
.r-common    { color: var(--common); }
.r-uncommon  { color: var(--uncommon); }
.r-rare      { color: var(--rare); }
.r-epic      { color: var(--epic); }
.r-legendary { color: var(--legendary); }
.r-mythical  { color: var(--mythical); }
.r-none      { color: var(--none); }

.hidden { display: none !important; }

/* ============================================================
   SKILL CAST — second button, streak pill, mini-game overlay
   ============================================================ */

/* Two-button cast row with two timer cells beneath */
.cast-controls.dual {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px 10px;
  align-items: stretch;
}
.cast-controls.dual .timer-cell {
  display: flex;
  justify-content: center;
  align-items: center;
  margin-top: 2px;
  min-height: 20px;
}
.timer.skill { color: #c89bff; }
.timer.skill.ready { color: var(--ok); }

.skill-btn {
  padding: 14px;
  font-size: 15px;
  font-weight: 700;
  background: linear-gradient(135deg, #4a1f7a 0%, #6a2fa0 100%);
  color: white;
  border: none;
  border-radius: 12px;
  cursor: pointer;
  transition: all 0.15s ease;
  font-family: inherit;
  letter-spacing: 0.3px;
  position: relative;
  overflow: hidden;
}
.skill-btn:active:not(:disabled) {
  transform: scale(0.98);
  background: linear-gradient(135deg, #3a1864 0%, #5a268a 100%);
}
.skill-btn:disabled {
  background: #2a2a2a;
  color: var(--text-faint);
  cursor: not-allowed;
}
.skill-btn.locked {
  background: #1a1a1a;
  border: 1px dashed #333;
  color: var(--text-faint);
}
/* Silhouette state — early game, still building catches toward unlock */
.skill-btn.silhouette {
  background: repeating-linear-gradient(
    135deg,
    #161616 0px, #161616 8px,
    #1a1a1a 8px, #1a1a1a 16px
  );
  border: 1px dashed #2c2c2c;
  color: #555;
  letter-spacing: 1px;
}
/* "Buy in Shop" prompt — catches met, draw the eye to the shop tab */
.skill-btn.prompt-shop {
  background: linear-gradient(135deg, #2a2a1a 0%, #3a3a20 100%);
  border: 1px solid rgba(255, 209, 102, 0.4);
  color: var(--coin);
  letter-spacing: 0.5px;
  animation: skillPromptPulse 2.5s ease-in-out infinite;
}
@keyframes skillPromptPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255, 209, 102, 0); }
  50%      { box-shadow: 0 0 16px 2px rgba(255, 209, 102, 0.18); }
}
/* 🔓 Freshly unlocked Skill Cast — lit and glowing to invite the first tap.
   The padlock "pops" off (handled in JS by clearing skillCastSeen). */
.skill-btn.just-unlocked {
  background: linear-gradient(135deg, #1d3a24 0%, #245c30 100%);
  border: 1px solid rgba(128, 237, 153, 0.7);
  color: #aaffc0;
  letter-spacing: 0.5px;
  animation: skillUnlockGlow 1.5s ease-in-out infinite;
}
@keyframes skillUnlockGlow {
  0%, 100% { box-shadow: 0 0 0 0 rgba(128, 237, 153, 0); }
  50%      { box-shadow: 0 0 20px 3px rgba(128, 237, 153, 0.45); }
}
/* Padlock "drops off" the button on the first tap after unlocking. A 🔓
   pseudo-element tumbles down and fades while the button flashes bright. */
.skill-btn.lock-dropping {
  position: relative;
  background: linear-gradient(135deg, #245c30 0%, #2f7a40 100%);
  border: 1px solid rgba(128, 237, 153, 0.9);
  color: #aaffc0;
  overflow: visible;
  animation: skillLockFlash 0.6s ease-out forwards;
}
.skill-btn.lock-dropping::after {
  content: '🔓';
  position: absolute;
  top: 50%;
  left: 50%;
  font-size: 22px;
  pointer-events: none;
  animation: padlockDrop 0.6s cubic-bezier(0.4, 0.1, 0.7, 1) forwards;
}
@keyframes skillLockFlash {
  0%   { box-shadow: 0 0 24px 4px rgba(128, 237, 153, 0.6); }
  100% { box-shadow: 0 0 0 0 rgba(128, 237, 153, 0); }
}
@keyframes padlockDrop {
  0%   { transform: translate(-50%, -50%) rotate(0deg);    opacity: 1; }
  20%  { transform: translate(-50%, -60%) rotate(-8deg);   opacity: 1; }
  100% { transform: translate(-50%, 90px) rotate(45deg);   opacity: 0; }
}

/* Streak pill on home top bar */
.pill-streak {
  background: linear-gradient(135deg, rgba(255, 107, 107, 0.2) 0%, rgba(255, 209, 102, 0.2) 100%);
  border: 1px solid rgba(255, 153, 51, 0.4);
  color: #ffaa55;
  font-family: var(--font-mono);
  animation: streakPulse 2s ease-in-out infinite;
}
@keyframes streakPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255, 153, 51, 0); }
  50%      { box-shadow: 0 0 12px 0 rgba(255, 153, 51, 0.4); }
}

/* Daily ✅ pill — shown after the daily reward is claimed.
   Replaces the home-screen Daily card for the rest of the day. */
.pill-daily-done {
  background: rgba(128, 237, 153, 0.10);
  border: 1px solid rgba(128, 237, 153, 0.35);
  color: var(--ok);
  font-family: var(--font-mono);
  font-weight: 700;
  letter-spacing: 0.3px;
  animation: dailyDonePopIn 600ms ease-out;
}
.pill-buff {
  background: linear-gradient(135deg, rgba(255, 209, 102, 0.18) 0%, rgba(120, 200, 255, 0.18) 100%);
  border: 1px solid rgba(255, 209, 102, 0.45);
  color: #ffd87a;
  font-family: var(--font-mono);
  font-weight: 700;
  letter-spacing: 0.3px;
  animation: buffBeacon 2.4s ease-in-out infinite;
}
@keyframes buffBeacon {
  0%,100% { box-shadow: 0 0 0 0 rgba(255, 209, 102, 0); }
  50%     { box-shadow: 0 0 10px 1px rgba(255, 209, 102, 0.45); }
}
@keyframes dailyDonePopIn {
  0%   { transform: scale(0.4); opacity: 0; }
  60%  { transform: scale(1.15); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}

/* ============================================================
   MINI-GAME OVERLAY
   ============================================================ */
.skill-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.92);
  z-index: 200;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: calc(20px + env(safe-area-inset-top)) calc(20px + env(safe-area-inset-right)) calc(20px + env(safe-area-inset-bottom)) calc(20px + env(safe-area-inset-left));
  animation: fadeIn 0.2s ease;
}
.skill-overlay.hidden { display: none; }

.skill-overlay .header {
  text-align: center;
  margin-bottom: 24px;
}
.skill-overlay .title {
  font-size: 12px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 8px;
}
.skill-overlay .streak-display {
  font-size: 14px;
  color: #ffaa55;
  font-family: var(--font-mono);
  font-weight: 700;
}
.skill-overlay .streak-display .label { color: var(--text-faint); font-weight: 500; }

.skill-wheel {
  width: min(280px, 75vw);
  height: min(280px, 75vw);
  position: relative;
  margin-bottom: 32px;
}

.skill-wheel svg {
  width: 100%;
  height: 100%;
  overflow: visible;
}

/* Wheel pointer (fixed at top) */
.skill-pointer {
  position: absolute;
  top: -12px;
  left: 50%;
  transform: translateX(-50%);
  width: 0;
  height: 0;
  border-left: 12px solid transparent;
  border-right: 12px solid transparent;
  border-top: 18px solid #ffd166;
  filter: drop-shadow(0 2px 4px rgba(255, 209, 102, 0.5));
}

.skill-tap-btn {
  padding: 16px 48px;
  font-size: 18px;
  font-weight: 800;
  letter-spacing: 1px;
  background: linear-gradient(135deg, #4a1f7a 0%, #6a2fa0 100%);
  color: white;
  border: none;
  border-radius: 14px;
  cursor: pointer;
  font-family: inherit;
  box-shadow: 0 4px 24px rgba(106, 47, 160, 0.4);
  transition: transform 0.1s;
}
.skill-tap-btn:active {
  transform: scale(0.96);
}

.skill-cancel {
  margin-top: 16px;
  background: none;
  border: none;
  color: var(--text-faint);
  font-size: 12px;
  cursor: pointer;
  font-family: inherit;
  padding: 8px 16px;
}

/* Result flash after tap */
.skill-result-flash {
  position: absolute;
  font-size: 48px;
  font-weight: 800;
  letter-spacing: 2px;
  animation: flashOut 0.9s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
  pointer-events: none;
  text-shadow: 0 4px 24px currentColor;
}
/* Pinned to where the player tapped (clientX/Y are viewport coords). Uses its
   own keyframe so the scale animation keeps the -50%/-50% centering (otherwise
   the scale transform would knock it off the tap point). */
.skill-result-flash.at-tap {
  position: fixed;
  z-index: 10000;
  white-space: nowrap;
  animation: flashOutTap 0.9s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}
@keyframes flashOutTap {
  0%   { transform: translate(-50%, -50%) scale(0.3); opacity: 0; }
  30%  { transform: translate(-50%, -50%) scale(1.2); opacity: 1; }
  70%  { transform: translate(-50%, -50%) scale(1);   opacity: 1; }
  100% { transform: translate(-50%, -50%) scale(1.4); opacity: 0; }
}
.skill-result-flash.perfect { color: var(--coin); }
.skill-result-flash.good { color: var(--ok); }
.skill-result-flash.miss { color: var(--danger); }

@keyframes flashOut {
  0%   { transform: scale(0.3); opacity: 0; }
  30%  { transform: scale(1.2); opacity: 1; }
  70%  { transform: scale(1); opacity: 1; }
  100% { transform: scale(1.4); opacity: 0; }
}

/* ============================================================
   PERFECT BONUS ANIMATIONS
   ============================================================ */
.bonus-particles {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 250;
  overflow: hidden;
}
.bonus-particle {
  position: absolute;
  font-size: 28px;
  animation: floatUp 1.6s ease-out forwards;
  opacity: 0;
}
@keyframes floatUp {
  0%   { transform: translateY(40vh) scale(0.5); opacity: 0; }
  20%  { opacity: 1; }
  100% { transform: translateY(-20vh) scale(1.2) rotate(20deg); opacity: 0; }
}

/* Wheel-anchored variant: particles spawn at the wheel's center (positioned
   via inline left/top) and fan outward along a per-particle direction vector
   (--dx, --dy in inline style). They start hidden BEHIND the visible wheel
   ring center, scale up as they emerge, then fade. Z-index is just under
   the wheel itself so they appear to come from behind. */
.bonus-particles.from-wheel { z-index: 218; /* skill-overlay is ~230 */ }
.bonus-particles.from-wheel .bonus-particle {
  /* Start at the wheel center, scaled small (behind the wheel art) */
  transform: translate(-50%, -50%) scale(0.3);
  animation: bonusBurstOut 1.5s cubic-bezier(0.22, 1, 0.36, 1) forwards;
}
@keyframes bonusBurstOut {
  0%   { transform: translate(-50%, -50%) scale(0.3) rotate(0deg);   opacity: 0; }
  15%  { transform: translate(-50%, -50%) scale(1.0) rotate(0deg);   opacity: 1; }
  100% {
    /* Move outward using the per-particle --dx/--dy direction. The translate
       chain (-50% then dx/dy) keeps the visual origin at the particle's
       fixed left/top while the second translate moves it outward. */
    transform: translate(calc(-50% + var(--dx, 0px)), calc(-50% + var(--dy, 0px))) scale(1.3) rotate(35deg);
    opacity: 0;
  }
}

.bonus-label {
  position: fixed;
  top: 30%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 22px;
  font-weight: 800;
  letter-spacing: 1px;
  z-index: 260;
  pointer-events: none;
  padding: 12px 24px;
  border-radius: 12px;
  background: rgba(0, 0, 0, 0.85);
  border: 2px solid currentColor;
  animation: bonusLabel 1.6s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}
/* Over-wheel variant: positioned via inline left/top at the wheel center.
   The top:30% rule above is overridden by the inline style; we just need
   to make sure the centering transform still applies during the anim. */
.bonus-label.over-wheel {
  top: auto; /* let inline 'top: <px>' take effect */
  animation: bonusLabelOverWheel 1.6s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}
@keyframes bonusLabelOverWheel {
  0%   { transform: translate(-50%, -50%) scale(0.5); opacity: 0; }
  20%  { transform: translate(-50%, -50%) scale(1.15); opacity: 1; }
  80%  { transform: translate(-50%, -50%) scale(1); opacity: 1; }
  100% { transform: translate(-50%, -120%) scale(1); opacity: 0; }
}
.bonus-label.coin   { color: var(--coin); }
.bonus-label.multi  { color: var(--ok); }
.bonus-label.rarity { color: var(--rare); }
@keyframes bonusLabel {
  0%   { transform: translate(-50%, -50%) scale(0.5); opacity: 0; }
  20%  { transform: translate(-50%, -50%) scale(1.1); opacity: 1; }
  80%  { transform: translate(-50%, -50%) scale(1); opacity: 1; }
  100% { transform: translate(-50%, -65%) scale(1); opacity: 0; }
}

/* ============================================================
   SKILL WHEEL — outcome pulse on the entire ring
   ============================================================ */
.skill-wheel {
  transition: filter 0.1s;
}
.skill-wheel.pulse-perfect {
  animation: pulsePerfect 0.9s ease-out;
}
.skill-wheel.pulse-good {
  animation: pulseGood 0.9s ease-out;
}
.skill-wheel.pulse-miss {
  animation: pulseMiss 0.9s ease-out;
}
@keyframes pulsePerfect {
  0%   { filter: drop-shadow(0 0 0 #ffd166); transform: scale(1); }
  20%  { filter: drop-shadow(0 0 40px #ffd166) drop-shadow(0 0 20px #ffd166); transform: scale(1.05); }
  100% { filter: drop-shadow(0 0 0 #ffd166); transform: scale(1); }
}
@keyframes pulseGood {
  0%   { filter: drop-shadow(0 0 0 #80ed99); transform: scale(1); }
  20%  { filter: drop-shadow(0 0 30px #80ed99); transform: scale(1.03); }
  100% { filter: drop-shadow(0 0 0 #80ed99); transform: scale(1); }
}
@keyframes pulseMiss {
  0%   { filter: drop-shadow(0 0 0 #ff6b6b); transform: scale(1) rotate(0deg); }
  10%  { transform: scale(1) rotate(-1deg); }
  20%  { filter: drop-shadow(0 0 30px #ff6b6b); transform: scale(0.98) rotate(1deg); }
  30%  { transform: scale(1) rotate(-1deg); }
  40%  { transform: scale(1) rotate(0deg); }
  100% { filter: drop-shadow(0 0 0 #ff6b6b); transform: scale(1); }
}

/* ============================================================
   SHOP — haptic toggle (special non-tier row)
   ============================================================ */
.shop-toggle-section {
  margin-bottom: 16px;
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
  background: var(--bg-elev);
}
.shop-toggle-row {
  padding: 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  cursor: pointer;
}
.shop-toggle-row .stats { flex: 1; min-width: 0; }
.shop-toggle-row .toggle-name { font-size: 13px; font-weight: 700; }
.shop-toggle-row .toggle-desc { font-size: 10px; color: var(--text-dim); margin-top: 2px; }

/* iOS-style toggle switch */
.toggle-switch {
  position: relative;
  width: 48px;
  height: 28px;
  background: #2a2a2a;
  border-radius: 14px;
  transition: background 0.2s;
  flex-shrink: 0;
}
.toggle-switch.on { background: #1a7a4a; }
.toggle-switch::after {
  content: '';
  position: absolute;
  top: 3px;
  left: 3px;
  width: 22px;
  height: 22px;
  background: white;
  border-radius: 50%;
  transition: transform 0.2s;
  box-shadow: 0 1px 3px rgba(0,0,0,0.3);
}
.toggle-switch.on::after { transform: translateX(20px); }

/* ============================================================
   SAVE TOOLS — Export / Import buttons + modals
   ============================================================ */
.save-tools-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin: 8px 0 12px;
}
.save-tool-btn {
  padding: 12px;
  font-size: 12px;
  font-weight: 700;
  background: var(--bg-elev);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 10px;
  cursor: pointer;
  font-family: inherit;
  transition: all 0.15s;
}
.save-tool-btn:active {
  transform: scale(0.97);
  background: var(--bg-elev-2);
}

.save-textarea {
  width: 100%;
  min-height: 120px;
  max-height: 240px;
  padding: 10px;
  margin-bottom: 12px;
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-family: var(--font-mono);
  font-size: 10px;
  resize: vertical;
  box-sizing: border-box;
  -webkit-user-select: text;
  user-select: text;
}

.modal-btn-primary {
  background: rgba(128, 237, 153, 0.15);
  color: var(--ok);
  border: 1px solid rgba(128, 237, 153, 0.4);
}

.import-error {
  color: var(--danger);
  font-size: 11px;
  padding: 8px;
  margin-bottom: 10px;
  background: rgba(255, 107, 107, 0.1);
  border: 1px solid rgba(255, 107, 107, 0.3);
  border-radius: 8px;
  text-align: left;
}

/* ============================================================
   COIN FLY PARTICLES
   ============================================================ */
.coin-particle {
  position: fixed;
  font-family: var(--font-mono);
  font-weight: 800;
  font-size: 24px;
  pointer-events: none;
  z-index: 355;
  transform: translate(-50%, -50%);
  will-change: transform, opacity;
  /* Subtle glow drop-shadow that works with emoji */
  filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.6));
}

/* Sell — curves UP toward the coin pill at the top */
.coin-particle.sell {
  animation: coinFlySell 700ms cubic-bezier(0.4, 0, 0.6, 1) forwards;
}
@keyframes coinFlySell {
  0% {
    left: var(--start-x);
    top: var(--start-y);
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.5);
  }
  15% {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1.1);
  }
  50% {
    left: var(--mid-x);
    top: var(--mid-y);
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
  }
  90% {
    opacity: 0.9;
  }
  100% {
    left: var(--end-x);
    top: var(--end-y);
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.6);
  }
}

/* Material reward — larger, slower arc so the emoji is readable */
.coin-particle.material-particle {
  font-size: 32px;
  /* Use the SAME flight as the cast→inventory catch animation (the reference)
     so Harbor payouts look identical: same keyframe, duration and easing. */
  animation: fishFly 750ms cubic-bezier(0.32, 0.04, 0.45, 1) forwards;
  z-index: 9999;
}

/* Buy — curves DOWN from the coin pill to the buy button */
.coin-particle.buy {
  animation: coinFlyBuy 500ms cubic-bezier(0.4, 0, 0.6, 1) forwards;
}
@keyframes coinFlyBuy {
  0% {
    left: var(--start-x);
    top: var(--start-y);
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.6);
  }
  15% {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
  }
  50% {
    left: var(--mid-x);
    top: var(--mid-y);
    opacity: 1;
  }
  100% {
    left: var(--end-x);
    top: var(--end-y);
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.5);
  }
}

/* Coin pill pulse — green glow + bounce on sell, red shrink on spend */
.pill-pulse-gain {
  animation: pillPulseGain 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes pillPulseGain {
  0%   { transform: scale(1); text-shadow: none; }
  40%  { transform: scale(1.18); color: var(--ok); text-shadow: 0 0 6px rgba(128, 237, 153, 0.85), 0 0 12px rgba(128, 237, 153, 0.45); }
  100% { transform: scale(1); text-shadow: none; }
}

.pill-pulse-spend {
  animation: pillPulseSpend 0.4s ease;
}
@keyframes pillPulseSpend {
  0%   { transform: scale(1); }
  50%  { transform: scale(0.92); color: var(--danger); }
  100% { transform: scale(1); }
}

/* Trophy Wall version footer */
.version-footer {
  text-align: center;
  padding: 16px 0 8px;
  font-size: 10px;
  letter-spacing: 1.5px;
  color: var(--text-ghost);
  font-family: var(--font-mono);
  text-transform: uppercase;
}


.skill-screen-hint {
  padding: 14px 22px;
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 1.8px;
  color: rgba(255, 255, 255, 0.78);
  text-transform: uppercase;
  pointer-events: none;
  animation: hintPulse 1.2s ease-in-out infinite;
}
@keyframes hintPulse {
  0%, 100% { opacity: 0.55; transform: scale(1); }
  50% { opacity: 1; transform: scale(1.03); }
}
.skill-overlay {
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  touch-action: manipulation;
}

/* ============================================================
   DIVE SCREEN (tab) — ready/cooldown/start screen
   ============================================================ */
.dive-ready {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 32px 20px;
  text-align: center;
}
.dive-icon-big {
  font-size: 72px;
  margin-bottom: 12px;
  filter: drop-shadow(0 4px 20px rgba(76, 201, 240, 0.4));
}
.dive-tagline {
  font-size: 13px;
  color: var(--text-dim);
  margin-bottom: 24px;
  line-height: 1.5;
  max-width: 280px;
}
.dive-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  width: 100%;
  max-width: 320px;
  margin-bottom: 24px;
}
.dive-stat {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px;
  text-align: center;
}
.dive-stat .label {
  font-size: 10px;
  color: var(--text-faint);
  text-transform: uppercase;
  letter-spacing: 1px;
  margin-bottom: 4px;
}
.dive-stat .value {
  font-size: 18px;
  font-weight: 700;
  color: var(--rare);
}
.dive-start-btn {
  width: 100%;
  max-width: 320px;
  padding: 18px;
  font-size: 16px;
  font-weight: 800;
  letter-spacing: 1px;
  background: linear-gradient(135deg, #1f5c7a 0%, #2f7fa0 100%);
  color: white;
  border: none;
  border-radius: 14px;
  cursor: pointer;
  font-family: inherit;
  box-shadow: 0 4px 24px rgba(47, 127, 160, 0.3);
}
.dive-start-btn:active:not(:disabled) {
  transform: scale(0.98);
}
.dive-start-btn:disabled {
  background: #2a2a2a;
  color: var(--text-faint);
  cursor: not-allowed;
  box-shadow: none;
}
.dive-locked-msg {
  background: rgba(255, 209, 102, 0.08);
  border: 1px solid rgba(255, 209, 102, 0.25);
  color: var(--coin);
  padding: 14px;
  border-radius: 10px;
  font-size: 12px;
  text-align: center;
  max-width: 320px;
  line-height: 1.5;
  margin-top: 8px;
}

/* ============================================================
   DIVE FULLSCREEN OVERLAY — gameplay area
   ============================================================ */
.dive-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  --dive-darkness: 0;
  --dive-depth-progress: 0;
  --dive-haze: 0.16;
  --dive-top: #188faf;
  --dive-mid: #095c7f;
  --dive-bottom: #031a2b;
  background:
    linear-gradient(180deg, var(--dive-top) 0%, var(--dive-mid) 50%, var(--dive-bottom) 100%);
  overflow: hidden;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
}
.dive-overlay.hidden { display: none; }

/* Treasure chest target — pulses a golden glow via the filter property only,
   so positioning (via transform) is untouched. The chest already moves on its
   own velocity vector; we don't need a bob animation here. */
.dive-target.chest {
  filter:
    drop-shadow(0 0 10px rgba(255, 215, 100, 0.95))
    drop-shadow(0 0 24px rgba(255, 175, 50, 0.70))
    drop-shadow(0 2px 8px rgba(0, 0, 0, 0.5));
  animation: chestGlowPulse 1.1s ease-in-out infinite;
}
@keyframes chestGlowPulse {
  0%, 100% {
    filter:
      drop-shadow(0 0 8px  rgba(255, 215, 100, 0.85))
      drop-shadow(0 0 18px rgba(255, 175, 50, 0.55))
      drop-shadow(0 2px 8px rgba(0, 0, 0, 0.5));
  }
  50% {
    filter:
      drop-shadow(0 0 14px rgba(255, 230, 130, 1))
      drop-shadow(0 0 34px rgba(255, 175, 50, 0.85))
      drop-shadow(0 0 50px rgba(255, 215, 100, 0.40))
      drop-shadow(0 2px 8px rgba(0, 0, 0, 0.5));
  }
}
.dive-target.chest.collected.chest-collected {
  /* Gold burst on pickup */
  animation: chestBurst 0.6s ease-out forwards;
}
@keyframes chestBurst {
  0%   { opacity: 1; filter: brightness(1); }
  40%  { opacity: 1; filter: brightness(1.8) drop-shadow(0 0 30px rgba(255, 220, 100, 1)); }
  100% { opacity: 0; filter: brightness(2); }
}

/* Treasure chest popup — golden card that appears between the dive end and
   the regular catch-results popup. Higher z-index than the catch popup so
   it sits on top. */
.chest-modal {
  position: fixed;
  inset: 0;
  z-index: 350; /* above dive-overlay (200) and catch popup (~300) */
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.65);
  opacity: 0;
  transition: opacity 0.25s ease;
  padding: 24px;
}
.chest-modal.show { opacity: 1; }
.chest-modal-card {
  background: linear-gradient(160deg, #2a1f0c 0%, #1a1207 100%);
  border: 1px solid rgba(255, 200, 90, 0.35);
  border-radius: 20px;
  padding: 28px 24px 20px;
  max-width: 320px;
  width: 100%;
  text-align: center;
  box-shadow:
    0 12px 40px rgba(0, 0, 0, 0.7),
    0 0 0 1px rgba(255, 210, 120, 0.08),
    inset 0 1px 0 rgba(255, 220, 140, 0.12);
  transform: scale(0.92);
  transition: transform 0.32s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.chest-modal.show .chest-modal-card { transform: scale(1); }
.chest-modal-icon {
  font-size: 56px;
  line-height: 1;
  margin-bottom: 8px;
  filter: drop-shadow(0 0 18px rgba(255, 200, 80, 0.55));
}
.chest-modal-title {
  font-family: var(--font-display, var(--font-mono));
  font-size: 26px;
  font-weight: 700;
  color: #ffd97a;
  letter-spacing: 0.4px;
  margin-bottom: 4px;
}
.chest-modal-sub {
  font-family: var(--font-mono);
  font-size: 12px;
  color: rgba(255, 220, 160, 0.7);
  margin-bottom: 18px;
}
.chest-modal-sub strong {
  color: #ffd97a;
  font-weight: 700;
}
.chest-loot-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 20px;
  padding: 12px;
  border-radius: 12px;
  background: rgba(0, 0, 0, 0.35);
  border: 1px solid rgba(255, 200, 90, 0.12);
}
.chest-loot-line {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-mono);
  font-size: 14px;
  color: rgba(255, 245, 220, 0.94);
}
.chest-loot-emoji { font-size: 20px; line-height: 1; }
.chest-loot-name { flex: 1; text-align: left; font-weight: 500; }
.chest-loot-qty { font-weight: 700; color: #ffd97a; }
.chest-modal-close {
  width: 100%;
  padding: 12px 16px;
  border-radius: 12px;
  border: 1px solid rgba(255, 200, 90, 0.45);
  background: linear-gradient(180deg, #5a3d10 0%, #3a2708 100%);
  color: #fff5d4;
  font-family: var(--font-display, var(--font-mono));
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.5px;
  cursor: pointer;
  transition: transform 0.1s ease, background 0.2s ease;
}
.chest-modal-close:active {
  transform: scale(0.97);
  background: linear-gradient(180deg, #4a3208 0%, #2a1c04 100%);
}

/* Sell-confirm modal: variant of chest-modal with two side-by-side buttons.
   The Cancel button is a quiet grey; the Sell button picks up the rarity
   colour so the player can SEE which tier they're about to dump. */
.sell-confirm-modal .chest-modal-card { max-width: 360px; }
.sell-confirm-row {
  display: flex;
  gap: 10px;
  margin-top: 14px;
}
.sell-confirm-cancel,
.sell-confirm-ok {
  flex: 1;
  padding: 12px 16px;
  border-radius: 12px;
  font-family: var(--font-display, var(--font-mono));
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.5px;
  cursor: pointer;
  transition: transform 0.1s ease, background 0.2s ease, border-color 0.2s ease;
}
.sell-confirm-cancel {
  border: 1px solid rgba(255, 255, 255, 0.15);
  background: rgba(40, 40, 50, 0.7);
  color: var(--text-dim);
}
.sell-confirm-cancel:active {
  transform: scale(0.97);
  background: rgba(30, 30, 40, 0.85);
}
/* Default Sell button tint — neutral. Rarity classes override below. */
.sell-confirm-ok {
  border: 1px solid rgba(120, 200, 130, 0.45);
  background: linear-gradient(180deg, #2e6e3d 0%, #1a4226 100%);
  color: #e8ffeb;
}
.sell-confirm-ok:active { transform: scale(0.97); }
/* Rarity-tinted variants — the colour signals what the player is about to
   commit to. Trash/common are subtle; mythical is a loud warning. */
.sell-confirm-ok.r-trash     { background: linear-gradient(180deg, #4a4a4a 0%, #2c2c2c 100%); border-color: rgba(170,170,170,0.4); color: #ddd; }
.sell-confirm-ok.r-common    { background: linear-gradient(180deg, #355e7a 0%, #1d3a4c 100%); border-color: rgba(110,180,225,0.4); color: #e3f1fb; }
.sell-confirm-ok.r-uncommon  { background: linear-gradient(180deg, #2e7a4e 0%, #144229 100%); border-color: rgba(128,237,153,0.45); color: #ddffe3; }
.sell-confirm-ok.r-rare      { background: linear-gradient(180deg, #3a5fb0 0%, #1d2f63 100%); border-color: rgba(115,160,255,0.5); color: #e5edff; }
.sell-confirm-ok.r-epic      { background: linear-gradient(180deg, #6e3aa0 0%, #3a1d63 100%); border-color: rgba(190,130,255,0.5); color: #f3e8ff; }
.sell-confirm-ok.r-legendary { background: linear-gradient(180deg, #8a5a14 0%, #4d3008 100%); border-color: rgba(255,200,90,0.55); color: #fff5d4; }
.sell-confirm-ok.r-mythical  { background: linear-gradient(180deg, #a82a8e 0%, #5a1448 100%); border-color: rgba(255,120,210,0.6); color: #ffe6f7; }
/* Recycle confirm button — green/earthy, distinct from sell variants */
.sell-confirm-ok.recycle-confirm-ok {
  background: linear-gradient(180deg, #5a8a3a 0%, #2e4a1d 100%);
  border-color: rgba(168, 217, 122, 0.5);
  color: #e8ffd4;
}
/* Visit Shop confirm button — friendly cyan, signals "go somewhere" rather
   than "delete things". Used by the Aquarium-full modal. */
.sell-confirm-ok.visit-shop-ok {
  background: linear-gradient(180deg, #2a6a9f 0%, #15375a 100%);
  border-color: rgba(110, 180, 225, 0.55);
  color: #e3f1fb;
}

.dive-hud {
  position: absolute;
  top: 0; left: 0; right: 0;
  padding: env(safe-area-inset-top) 12px 8px;
  z-index: 210;
  pointer-events: none; /* let touches pass through to the dive field */
}
.dive-hud-corner-tr {
  position: absolute;
  top: calc(env(safe-area-inset-top, 0px) + 8px);
  right: 0;
  /* Sits left of the quit × button. Push our pill far enough inward so they
     never overlap on narrow phones. */
  padding-right: 50px;
  display: flex;
  gap: 5px;
}
.dive-hud-pill {
  background: rgba(0, 0, 0, 0.42);
  border: 1px solid rgba(255, 255, 255, 0.08);
  color: var(--text);
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 12px;
  padding: 5px 10px;
  border-radius: 8px;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  letter-spacing: 0.3px;
}

/* Big, prominent depth display below the pill row */
.dive-depth-display {
  text-align: center;
  margin-top: 8px;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 22px;
  letter-spacing: 2px;
  color: rgba(187, 221, 255, 0.85);
  text-shadow: 0 0 18px rgba(76, 201, 240, 0.35);
}

.dive-hud-hint {
  /* Sit near the BOTTOM of the screen, above the home-indicator strip.
     The depth pill owns the top of the dive overlay; pushing the hint down
     gives the player a clean horizon and points at the area they'll soon
     be touching anyway. */
  position: absolute;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 60px);
  left: 50%;
  transform: translateX(-50%);
  text-align: center;
  font-size: 11px;
  font-weight: 700;
  color: rgba(255, 255, 255, 0.95);
  letter-spacing: 2.5px;
  text-transform: uppercase;
  white-space: nowrap;
  text-shadow:
    0 1px 2px rgba(0, 0, 0, 0.85),
    0 0 8px rgba(0, 30, 60, 0.7);
  animation: divePulse 2.5s ease-in-out infinite;
  z-index: 212;
  pointer-events: none;
}
@keyframes divePulse {
  0%, 100% { opacity: 0.65; }
  50%      { opacity: 1; }
}

/* Lives pill shake when a heart is lost */
.dive-hud-pill.heart-shake {
  animation: heartShake 0.55s cubic-bezier(0.36, 0.07, 0.19, 0.97);
}
@keyframes heartShake {
  0%   { transform: translateX(0); }
  10%  { transform: translateX(-6px) rotate(-3deg); }
  20%  { transform: translateX( 6px) rotate( 3deg); }
  30%  { transform: translateX(-5px) rotate(-2deg); }
  40%  { transform: translateX( 5px) rotate( 2deg); }
  50%  { transform: translateX(-3px) rotate(-1deg); }
  60%  { transform: translateX( 3px) rotate( 1deg); }
  70%  { transform: translateX(-2px); }
  80%  { transform: translateX( 2px); }
  100% { transform: translateX(0); }
}

/* Always-visible depth meter in the centre of the screen. */
.dive-depth-center {
  position: absolute;
  left: 50%;
  top: calc(env(safe-area-inset-top) + 60px);
  transform: translateX(-50%);
  z-index: 211;
  pointer-events: none;
  text-align: center;
  padding: 8px 18px 9px;
  border-radius: 18px;
  background: rgba(0, 12, 22, 0.22);
  border: 1px solid rgba(120, 220, 255, 0.10);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  min-width: 140px;
}
/* Depth value — the dominant element, big mono numerals, like v1.5.4 had it.
   This is the number the player checks constantly during a dive. */
.dive-depth-value {
  font-family: var(--font-mono);
  font-size: clamp(24px, 8vw, 40px);
  line-height: 1;
  font-weight: 900;
  color: rgba(235, 248, 255, 0.94);
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.72), 0 0 22px rgba(76, 201, 240, 0.42);
  letter-spacing: 0.5px;
}
/* Zone name — small subtitle under the depth. Same readable mono so it reads
   like a unit/label on the depth number, not a competing headline. */
.dive-zone-name {
  margin-top: 4px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.8px;
  color: rgba(190, 230, 255, 0.62);
  /* Smooth out the cross-fade between zones. */
  transition: color 0.6s ease;
}

.dive-field {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse at 50% -12%, rgba(165, 240, 255, calc(0.22 - var(--dive-depth-progress, 0) * 0.16)) 0%, rgba(110, 210, 255, calc(0.10 - var(--dive-depth-progress, 0) * 0.07)) 28%, transparent 58%),
    radial-gradient(circle at 18% 35%, rgba(76, 201, 240, calc(0.10 - var(--dive-depth-progress, 0) * 0.055)) 0%, transparent 34%),
    radial-gradient(circle at 82% 74%, rgba(100, 85, 255, calc(0.08 + var(--dive-depth-progress, 0) * 0.04)) 0%, transparent 38%),
    linear-gradient(180deg, rgba(255,255,255,0.055) 0%, transparent 18%, rgba(0,0,0,0.08) 100%);
}
.dive-field::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: calc(0.18 + var(--dive-depth-progress, 0) * 0.18);
  background-image:
    radial-gradient(circle at 24% 20%, rgba(255,255,255,0.12) 0 1px, transparent 2px),
    radial-gradient(circle at 76% 32%, rgba(255,255,255,0.08) 0 1px, transparent 2px),
    radial-gradient(circle at 46% 82%, rgba(255,255,255,0.07) 0 1px, transparent 2px);
  background-size: 160px 220px, 210px 260px, 180px 240px;
  animation: diveWaterSpecks 18s linear infinite;
}
@keyframes diveWaterSpecks {
  from { background-position: 0 0, 0 0, 0 0; }
  to   { background-position: 0 -220px, 0 -260px, 0 -240px; }
}
.dive-overlay::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 205;
  background:
    radial-gradient(ellipse at 50% 10%, rgba(150, 235, 255, calc(0.13 - var(--dive-depth-progress, 0) * 0.09)) 0%, transparent 44%),
    radial-gradient(circle at 50% 52%, transparent 0%, rgba(0, 0, 0, calc(0.12 + var(--dive-darkness, 0) * 0.40)) 82%),
    linear-gradient(180deg,
      rgba(255,255,255, calc(0.045 - var(--dive-depth-progress, 0) * 0.03)) 0%,
      rgba(0,0,0, calc(var(--dive-darkness, 0) * 0.18)) 58%,
      rgba(0,0,0, calc(var(--dive-darkness, 0) * 0.44)) 100%);
}

.dive-target {
  position: absolute;
  font-size: 30px;
  pointer-events: none;
  transform: translate(-50%, -50%);
  filter:
    drop-shadow(0 0 5px rgba(var(--rarity-rgb, 235,245,255), 0.45))
    drop-shadow(0 0 12px rgba(var(--rarity-rgb, 235,245,255), 0.20))
    drop-shadow(0 2px 8px rgba(0, 0, 0, 0.5));
  will-change: transform, opacity;
}
.dive-target.rarity-epic, .dive-target.rarity-legendary, .dive-target.rarity-mythical {
  animation: rarityGlow 1s ease-in-out infinite;
}
.dive-target.rarity-legendary { --glow-scale: 1.18; }
.dive-target.rarity-mythical { --glow-scale: 1.32; }
.dive-target.bomb {
  filter: drop-shadow(0 0 10px rgba(255,60,60,0.45)) drop-shadow(0 2px 8px rgba(0,0,0,0.65));
}
/* Oxygen bubble — soft cyan halo, gentle bob */
.dive-target.bubble {
  filter: drop-shadow(0 0 8px rgba(80,200,255,0.55)) drop-shadow(0 0 16px rgba(80,200,255,0.28));
  animation: bubbleBob 1.8s ease-in-out infinite;
}
@keyframes bubbleBob {
  0%, 100% { transform: translate(-50%, -50%) scale(1); }
  50%      { transform: translate(-50%, -50%) scale(1.08); }
}
/* "+3s" text that drifts up from a collected bubble */
.dive-bubble-floater {
  position: fixed;
  transform: translate(-50%, -50%);
  pointer-events: none;
  font-family: var(--font-mono);
  font-weight: 800;
  font-size: 18px;
  color: #80ed99;
  text-shadow: 0 1px 4px rgba(0,0,0,0.7), 0 0 10px rgba(128,237,153,0.55);
  z-index: 230;
  animation: bubbleFloat 0.9s ease-out forwards;
}
@keyframes bubbleFloat {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(0.5); }
  20%  { opacity: 1; transform: translate(-50%, -100%) scale(1.1); }
  100% { opacity: 0; transform: translate(-50%, -180%) scale(1); }
}
@keyframes rarityGlow {
  0%, 100% { filter: drop-shadow(0 0 6px rgba(var(--rarity-rgb), 0.55)) drop-shadow(0 0 14px rgba(var(--rarity-rgb), 0.26)) drop-shadow(0 2px 8px rgba(0,0,0,0.5)); }
  50%      { filter: drop-shadow(0 0 9px rgba(var(--rarity-rgb), 0.80)) drop-shadow(0 0 22px rgba(var(--rarity-rgb), 0.46)) drop-shadow(0 2px 8px rgba(0,0,0,0.5)); }
}
.dive-target.collected {
  animation: diveCollect 0.4s ease-out forwards;
}
@keyframes diveCollect {
  0%   { transform: translate(-50%, -50%) scale(1); opacity: 1; }
  100% { transform: translate(-50%, -50%) scale(1.8); opacity: 0; }
}
.dive-target.exploded {
  animation: diveExplode 0.4s ease-out forwards;
}
@keyframes diveExplode {
  0%   { transform: translate(-50%, -50%) scale(1) rotate(0deg); opacity: 1; }
  100% { transform: translate(-50%, -50%) scale(2.2) rotate(180deg); opacity: 0; }
}

/* Thumb-following catch circle. It is again a blue filled circle with a bright blue edge.
   The oxygen/stamina gauge is a compact BOTW-style bar attached to its upper-right. */
.dive-hitbox {
  position: fixed;
  width: 72px;
  height: 72px;
  transform: translate(-50%, -50%);
  pointer-events: none;
  z-index: 220;
  transition: opacity 0.15s;
}
.dive-hitbox.hidden { opacity: 0; }
/* Lifted state: hide the lantern + stamina pill, but KEEP the heart row
   visible so the heart-loss shake animation has somewhere to play after
   the player has let go. Once the brief animation finishes, JS adds
   .lift-done which fades the hearts out too. */
.dive-hitbox.lift .dive-hitbox-core { opacity: 0; }
.dive-hitbox.lift .dive-stamina-mini { opacity: 0; }
.dive-hitbox.lift .dive-hitbox-core,
.dive-hitbox.lift .dive-stamina-mini {
  transition: opacity 0.18s ease;
}
.dive-hitbox.lift.lift-done .dive-hitbox-lives { opacity: 0; transition: opacity 0.25s ease; }
.dive-hitbox-core {
  position: absolute;
  inset: 0;
  border-radius: 999px;
  background:
    radial-gradient(circle at 38% 34%, rgba(170, 240, 255, 0.22) 0%, rgba(28, 170, 255, 0.10) 35%, rgba(4, 23, 42, 0.30) 72%);
  border: 3px solid rgba(78, 205, 255, 0.95);
  box-shadow:
    inset 0 0 18px rgba(76, 201, 240, 0.22),
    0 0 0 1px rgba(210, 245, 255, 0.22),
    0 0 18px rgba(76, 201, 240, 0.62),
    0 6px 20px rgba(0, 0, 0, 0.38);
}
/* Lantern effect: a soft expanding halo around the hitbox lights up nearby
   targets so the player can see fish and bombs even in deep dark water.
   Pseudo-element is OUTSIDE the hitbox visually (negative inset) but stays
   centred on it. Pointer-events none so it never blocks gestures.
   `mix-blend-mode: screen` makes the gradient actually BRIGHTEN whatever is
   underneath instead of compositing as an opaque overlay — so dark water
   under the halo reveals fish and bombs that would otherwise be invisible. */
.dive-hitbox-core::before {
  content: '';
  position: absolute;
  inset: -140px;
  border-radius: 50%;
  pointer-events: none;
  background: radial-gradient(
    circle,
    rgba(200, 240, 255, 0.55) 0%,
    rgba(140, 210, 255, 0.32) 22%,
    rgba(100, 180, 240, 0.18) 42%,
    rgba(60, 130, 200, 0.08) 65%,
    transparent 88%
  );
  mix-blend-mode: screen;
  /* Subtle slow pulse so the light feels alive without being distracting */
  animation: diveLanternPulse 3.6s ease-in-out infinite;
}
@keyframes diveLanternPulse {
  0%, 100% { transform: scale(1);    opacity: 1; }
  50%      { transform: scale(1.07); opacity: 0.85; }
}
/* Mini lives row — sits just above the stamina bar around the hitbox. Tiny
   hearts so they don't draw attention away from gameplay; they're context, not
   a primary HUD element. The whole stack (lives + stamina) is centered above
   the player's thumb. */
.dive-hitbox-lives {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 44px); /* clears the stamina pill (~22px tall) + healthy gap */
  transform: translateX(-50%);
  font-size: 13px;
  letter-spacing: 2px;
  white-space: nowrap;
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.7));
  pointer-events: none;
  user-select: none;
}
.dive-hitbox-lives.heart-shake {
  animation: heartShakeMini 0.45s ease-in-out;
}
@keyframes heartShakeMini {
  0%, 100% { transform: translateX(-50%) translateY(0); }
  25%      { transform: translateX(-50%) translateY(-2px) rotate(-3deg); }
  50%      { transform: translateX(-50%) translateY(0) rotate(3deg); }
  75%      { transform: translateX(-50%) translateY(-1px) rotate(-2deg); }
}

/* Stamina bar — sits centered ABOVE the hitbox so it's always visible without
   being obscured by the player's finger. Labeled "O2" so it's unambiguous. */
.dive-stamina-mini {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 8px);
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 3px 7px 3px 4px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.18);
  box-shadow: 0 2px 7px rgba(0,0,0,0.45);
  white-space: nowrap;
}
.dive-stamina-label {
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.6px;
  color: rgba(220, 240, 255, 0.85);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
}
.dive-stamina-track {
  width: 56px;
  height: 8px;
  padding: 1px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.10);
}
.dive-stamina-fill {
  height: 100%;
  width: 100%;
  border-radius: 999px;
  background: #80ed99;
  transition: width 0.12s linear, background 0.2s ease;
  box-shadow: 0 0 8px rgba(128,237,153,0.5);
}
.dive-stamina-fill.full { background: #80ed99; box-shadow: 0 0 8px rgba(128,237,153,0.55); }
.dive-stamina-fill.warn { background: #ffd166; box-shadow: 0 0 8px rgba(255,209,102,0.55); }
.dive-stamina-fill.crit {
  background: #ff6b6b;
  box-shadow: 0 0 10px rgba(255,107,107,0.65);
  animation: divePulseCrit 0.9s ease-in-out infinite;
}
/* Damage flash overlay when bomb is hit */
.dive-overlay.damage-flash::before {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(255, 80, 80, 0.4);
  animation: diveDamageFlash 0.3s ease-out;
  pointer-events: none;
  z-index: 215;
}

/* Drowning / penalty state — applied when the player has lifted their finger.
   A pulsing red vignette around the edges + faster-draining oxygen makes it
   clear they need to touch again. Doesn't end the dive. */
.dive-overlay.drowning {
  animation: diveDrowningPulse 0.9s ease-in-out infinite;
}
.dive-overlay.drowning::after {
  /* Strengthen the radial darken that the dive-overlay::after already paints
     into a pulsing red vignette so the visual warning is unmistakable. */
  background:
    radial-gradient(circle at 50% 50%, transparent 30%, rgba(255, 60, 60, 0.35) 100%),
    linear-gradient(180deg, transparent 0%, rgba(0,0,0, 0.25) 100%);
}
@keyframes diveDrowningPulse {
  0%, 100% { box-shadow: inset 0 0 0 0 rgba(255, 60, 60, 0); }
  50%      { box-shadow: inset 0 0 60px 8px rgba(255, 60, 60, 0.30); }
}
@keyframes diveDamageFlash {
  0%   { opacity: 1; }
  100% { opacity: 0; }
}

/* ============================================================
   FULL CATCH LIST MODAL
   ============================================================ */
.catch-list-inner {
  max-width: 380px;
  width: 100%;
  max-height: 80vh;
  display: flex;
  flex-direction: column;
  padding: 20px 16px 16px;
}
.catch-list-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  margin: 12px 0;
  padding: 0 2px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.catch-list-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  text-align: left;
}
.catch-list-item .emoji { font-size: 22px; flex-shrink: 0; }
.catch-list-item .info { flex: 1; min-width: 0; }
.catch-list-item .name { font-size: 13px; font-weight: 700; }
.catch-list-item .detail {
  font-size: 10px;
  color: var(--text-dim);
  font-family: var(--font-mono);
  margin-top: 1px;
}
.catch-list-item .price {
  font-size: 12px;
  font-weight: 700;
  color: var(--coin);
  font-family: var(--font-mono);
}
.catch-list-item .record {
  background: var(--coin);
  color: #000;
  font-size: 8px;
  font-weight: 800;
  letter-spacing: 0.5px;
  padding: 1px 5px;
  border-radius: 4px;
  margin-left: 4px;
}
.catch-list-summary {
  font-size: 11px;
  color: var(--text-dim);
  text-align: center;
  margin-bottom: 4px;
  font-family: var(--font-mono);
}

/* See-all button inside catch popup */
.popup-see-all {
  margin-top: 10px;
  margin-bottom: 0;
  background: none;
  color: var(--text-dim);
  border: 1px solid var(--border);
  padding: 8px 14px;
  border-radius: 9px;
  font-weight: 600;
  font-size: 12px;
  cursor: pointer;
  font-family: inherit;
}
.popup-see-all:active { transform: scale(0.98); }

/* "+N more" subtle text inside popup */
.popup-more {
  font-size: 11px;
  color: var(--text-faint);
  text-align: center;
  padding: 6px;
  font-style: italic;
}

/* Make the home-screen Latest Catch box clickable feeling */
.latest-body.clickable {
  cursor: pointer;
  transition: background 0.15s;
}
.latest-body.clickable:active {
  background: rgba(0, 0, 0, 0.6);
}

/* ============================================================
   LEADERBOARD SCREEN
   ============================================================ */
.lb-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 4px 12px;
  gap: 10px;
}
.lb-myname {
  font-size: 12px;
  color: var(--text-dim);
}
.lb-myname b { color: var(--coin); font-weight: 700; }
.lb-refresh-btn {
  background: rgba(76, 201, 240, 0.15);
  color: var(--rare);
  border: 1px solid rgba(76, 201, 240, 0.35);
  padding: 6px 12px;
  border-radius: 8px;
  font-size: 11px;
  font-weight: 700;
  cursor: pointer;
  font-family: inherit;
}
.lb-refresh-btn:active { transform: scale(0.96); }
.lb-edit-name-btn {
  background: none;
  border: none;
  color: var(--rare);
  font-size: 11px;
  cursor: pointer;
  font-family: inherit;
  text-decoration: underline;
  padding: 0;
}

.lb-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 10px;
  margin-bottom: 6px;
}
.lb-row.me {
  background: rgba(255, 209, 102, 0.08);
  border-color: rgba(255, 209, 102, 0.4);
}
.lb-rank {
  font-family: var(--font-mono);
  font-weight: 800;
  font-size: 16px;
  color: var(--text-faint);
  min-width: 32px;
  text-align: center;
}
.lb-row.me .lb-rank { color: var(--coin); }
.lb-rank.medal-1 { color: #ffd166; }
.lb-rank.medal-2 { color: #c8c8c8; }
.lb-rank.medal-3 { color: #cd7f32; }
.lb-name-block { flex: 1; min-width: 0; }
.lb-name {
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.lb-meta {
  font-size: 10px;
  color: var(--text-dim);
  font-family: var(--font-mono);
  margin-top: 1px;
}
.lb-rarest {
  font-size: 18px;
  text-align: center;
  min-width: 28px;
}
.lb-points {
  font-family: var(--font-mono);
  font-weight: 800;
  font-size: 14px;
  color: var(--coin);
  text-align: right;
  min-width: 50px;
}

.lb-empty {
  text-align: center;
  padding: 32px 20px;
  color: var(--text-faint);
  font-size: 13px;
}
.lb-loading {
  text-align: center;
  padding: 32px 20px;
  color: var(--text-dim);
  font-size: 12px;
}
.lb-error {
  background: rgba(255, 107, 107, 0.1);
  border: 1px solid rgba(255, 107, 107, 0.3);
  color: var(--danger);
  padding: 12px;
  border-radius: 10px;
  font-size: 11px;
  margin: 8px 0;
}
.lb-join-cta {
  background: rgba(255, 209, 102, 0.08);
  border: 1px solid rgba(255, 209, 102, 0.3);
  padding: 16px;
  border-radius: 10px;
  text-align: center;
  margin-bottom: 12px;
}
.lb-join-cta .title { font-size: 14px; font-weight: 700; color: var(--coin); margin-bottom: 4px; }
.lb-join-cta .sub { font-size: 11px; color: var(--text-dim); margin-bottom: 10px; }
.lb-join-cta button {
  background: var(--coin);
  color: #000;
  border: none;
  padding: 10px 20px;
  border-radius: 8px;
  font-weight: 700;
  font-size: 12px;
  cursor: pointer;
  font-family: inherit;
}

/* Username input modal */
.username-input {
  width: 100%;
  padding: 12px;
  margin-bottom: 12px;
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-family: inherit;
  font-size: 14px;
  box-sizing: border-box;
  -webkit-user-select: text;
  user-select: text;
}
.username-input:focus {
  outline: none;
  border-color: var(--coin);
}

/* ============================================================
   LEADERBOARD — Inline expand detail
   ============================================================ */

/* Wrapper holds row + detail; gives the whole unit a single border */
.lb-row-wrap {
  margin-bottom: 6px;
  border-radius: 10px;
  overflow: hidden;
  transition: background 0.2s;
}
.lb-row-wrap.expanded {
  background: var(--bg-elev);
  border: 1px solid var(--rare);
  margin-bottom: 10px;
}
.lb-row-wrap.expanded .lb-row {
  background: transparent;
  border: none;
  margin: 0;
}

/* Tappable row hint */
.lb-row {
  cursor: pointer;
  transition: background 0.15s;
}
.lb-row:active {
  background: var(--bg-elev-2);
}

/* Chevron indicator */
.lb-chevron {
  color: var(--text-faint);
  font-size: 12px;
  margin-left: 4px;
  min-width: 14px;
  text-align: center;
  transition: transform 0.2s, color 0.2s;
}
.lb-row.is-expanded .lb-chevron {
  color: var(--rare);
}

/* Detail panel */
.lb-detail {
  padding: 4px 12px 14px;
  animation: lbDetailIn 0.2s ease-out;
}
@keyframes lbDetailIn {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Rarest catch big card */
.lb-rarest-card {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  margin-bottom: 10px;
}
.lb-rarest-emoji {
  font-size: 36px;
}
.lb-rarest-info {
  flex: 1;
}
.lb-rarest-label {
  font-size: 9px;
  color: var(--text-faint);
  letter-spacing: 1.2px;
  text-transform: uppercase;
}
.lb-rarest-name {
  font-size: 16px;
  font-weight: 700;
  margin-top: 2px;
}
.lb-rarest-rarity {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 1px;
  margin-top: 2px;
}

/* Favourites strip in expanded leaderboard row */
.lb-favourites-strip {
  background: var(--bg);
  border: 1px solid rgba(255, 220, 90, 0.22);
  border-radius: 8px;
  padding: 8px 10px;
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.lb-favourites-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.5px;
  color: rgba(255, 220, 90, 0.85);
  text-transform: uppercase;
  flex-shrink: 0;
}
.lb-favourites-emojis {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
}
.lb-fav-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.10);
  font-size: 18px;
  line-height: 1;
  position: relative;
  transition: transform 0.15s;
}
/* Rarity-coloured glow on each chip. Same hues as .fav-slot.filled.r-* */
.lb-fav-chip.r-common    { border-color: rgba(180, 180, 180, 0.45); box-shadow: 0 0 8px rgba(180, 180, 180, 0.20); }
.lb-fav-chip.r-uncommon  { border-color: rgba(125, 215, 110, 0.55); box-shadow: 0 0 9px rgba(125, 215, 110, 0.28); }
.lb-fav-chip.r-rare      { border-color: rgba(78, 165, 245, 0.60);  box-shadow: 0 0 10px rgba(78, 165, 245, 0.35); }
.lb-fav-chip.r-epic      { border-color: rgba(178, 120, 255, 0.65); box-shadow: 0 0 11px rgba(178, 120, 255, 0.40); }
.lb-fav-chip.r-legendary { border-color: rgba(255, 200, 80, 0.70);  box-shadow: 0 0 12px rgba(255, 200, 80, 0.50); }
.lb-fav-chip.r-mythical  { border-color: rgba(255, 100, 200, 0.75); box-shadow: 0 0 14px rgba(255, 100, 200, 0.55); }
.lb-fav-chip.r-trash     { border-color: rgba(160, 130, 100, 0.45); box-shadow: 0 0 7px rgba(160, 130, 100, 0.20); }
/* Shiny chip — extra warm gold halo + a corner sparkle indicator */
.lb-fav-chip.shiny {
  box-shadow:
    0 0 8px rgba(255, 215, 0, 0.55),
    0 0 14px rgba(255, 215, 0, 0.35),
    inset 0 0 6px rgba(255, 215, 0, 0.20);
  animation: shinyChipPulse 2.2s ease-in-out infinite;
}
.lb-fav-sparkle {
  position: absolute;
  top: -3px;
  right: -3px;
  font-size: 9px;
  pointer-events: none;
  filter: drop-shadow(0 0 4px rgba(255, 215, 0, 0.9));
  animation: lbSparkleTwinkle 1.6s ease-in-out infinite;
}
@keyframes lbSparkleTwinkle {
  0%,100% { opacity: .5; transform: scale(.85); }
  50%     { opacity: 1;  transform: scale(1.1); }
}
@keyframes shinyChipPulse {
  0%,100% { box-shadow: 0 0 8px rgba(255, 215, 0, 0.55), 0 0 14px rgba(255, 215, 0, 0.35), inset 0 0 6px rgba(255, 215, 0, 0.20); }
  50%     { box-shadow: 0 0 12px rgba(255, 215, 0, 0.85), 0 0 22px rgba(255, 215, 0, 0.55), inset 0 0 8px rgba(255, 215, 0, 0.30); }
}

/* Stats grid */
.lb-stats-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
  margin-bottom: 8px;
}
.lb-stat {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px;
  text-align: center;
}
.lb-stat-label {
  font-size: 9px;
  color: var(--text-faint);
  letter-spacing: 0.8px;
  text-transform: uppercase;
  margin-bottom: 2px;
}
.lb-stat-val {
  font-size: 14px;
  font-weight: 700;
  font-family: var(--font-mono);
  color: var(--rare);
}
.lb-stat-empty {
  grid-column: 1 / -1;
  padding: 16px;
  text-align: center;
  background: var(--bg);
  border: 1px dashed var(--border);
  border-radius: 8px;
  font-size: 11px;
  color: var(--text-faint);
  font-style: italic;
}

/* Footer with timestamp */
.lb-detail-footer {
  font-size: 10px;
  color: var(--text-faint);
  text-align: center;
  padding: 4px 0;
  font-family: var(--font-mono);
}

/* Own actions */
.lb-own-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
}
.lb-action-btn {
  padding: 10px 8px;
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 11px;
  font-weight: 700;
  cursor: pointer;
  font-family: inherit;
  transition: all 0.15s;
}
.lb-action-btn:active {
  transform: scale(0.97);
  background: var(--bg-elev-2);
}
.lb-action-danger {
  background: rgba(255, 107, 107, 0.08);
  color: var(--danger);
  border-color: rgba(255, 107, 107, 0.3);
}

/* Section heading shown above each shop group ("💰 Coin Shop", etc).
   Rounded pill so it visually matches the rest of the UI. Compact too —
   it just labels the group, doesn't dominate the screen.
   The pill is inline-flex; the parent .shop-group-* uses text-align:center
   to put it visually in the middle of the group. */
.shop-section-title.major {
  display: inline-flex;
  align-items: center;
  margin: 12px 0 10px;
  padding: 6px 14px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--bg-elev-2);
  background-clip: padding-box;
}

/* Group-coloured backgrounds + headings.
   Each `.shop-group-*` div wraps the section blocks of one shop category.
   The colours are subtle so the dark theme isn't overwhelmed. */
.shop-group-coin,
.shop-group-workshop,
.shop-group-merchant {
  padding: 4px 0 2px;
  border-radius: 14px;
  margin-bottom: 14px;
  /* Centers the inline-flex .shop-section-title.major pill in the group */
  text-align: center;
}
.shop-group-pirate {
  padding: 4px 0 2px;
  border-radius: 14px;
  margin-bottom: 14px;
  text-align: center;
}
.pirate-corner {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  padding: 16px; margin: 8px auto 0; max-width: 340px;
  border-radius: 14px; border: 1px solid rgba(255,255,255,0.08);
  background: rgba(255,255,255,0.03);
}
.pirate-corner-icon { font-size: 40px; }
.pirate-corner-text { font-size: 13px; color: var(--text-faint); line-height: 1.4; }
.pirate-corner.locked { opacity: 0.85; }
.pirate-corner.locked .pirate-corner-icon { filter: grayscale(0.6) blur(0.5px); }
.pirate-corner-btn {
  width: 100%; padding: 14px; font-size: 15px; font-weight: 800; letter-spacing: 1px;
  border-radius: 12px; cursor: pointer; font-family: inherit;
  background: linear-gradient(135deg, #6b4a1f 0%, #a07a2f 100%);
  color: #ffe9b8; border: 1px solid rgba(255,209,102,0.35);
}
.pirate-corner-btn:active:not(:disabled) { transform: scale(0.98); }
.pirate-corner-btn:disabled {
  background: #2a2a2a; color: var(--text-faint); cursor: not-allowed; border-color: rgba(255,255,255,0.08);
}
/* The pill is centered, but the rest of the group's content should stay
   in its normal left-aligned flow. */
.shop-group-coin > .shop-section,
.shop-group-workshop > .shop-section,
.shop-group-merchant > .shop-section {
  text-align: left;
}
.shop-group-coin {
  /* Soft yellow — money */
  background: linear-gradient(180deg, rgba(255, 209, 102, 0.05) 0%, rgba(255, 209, 102, 0.02) 100%);
  border: 1px solid rgba(255, 209, 102, 0.10);
}
.shop-group-coin .shop-section-title.major {
  background: rgba(255, 209, 102, 0.10);
  border-color: rgba(255, 209, 102, 0.30);
  color: #ffd166;
}
.shop-group-workshop {
  /* Soft warm brown — wood / crafting */
  background: linear-gradient(180deg, rgba(176, 130, 90, 0.06) 0%, rgba(176, 130, 90, 0.02) 100%);
  border: 1px solid rgba(176, 130, 90, 0.12);
}
.shop-group-workshop .shop-section-title.major {
  background: rgba(176, 130, 90, 0.14);
  border-color: rgba(176, 130, 90, 0.35);
  color: #d2a578;
}
.shop-group-merchant {
  /* Soft green — exchange / trade */
  background: linear-gradient(180deg, rgba(128, 237, 153, 0.05) 0%, rgba(128, 237, 153, 0.02) 100%);
  border: 1px solid rgba(128, 237, 153, 0.12);
}
.shop-group-merchant .shop-section-title.major {
  background: rgba(128, 237, 153, 0.10);
  border-color: rgba(128, 237, 153, 0.30);
  color: var(--ok);
}
/* Inside a coloured group, the section cards drop their dark backgrounds
   slightly so the group tint shows through. */
.shop-group-coin .shop-section,
.shop-group-workshop .shop-section,
.shop-group-merchant .shop-section {
  margin-left: 10px;
  margin-right: 10px;
  margin-bottom: 10px;
}

/* Material wallet — shows what you've gathered so far */
.material-wallet .mat-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 10px 12px 12px;
}
.mat-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 6px 10px;
  border-radius: 999px;
  background: rgba(255,255,255,0.06);
  border: 1px solid rgba(255,255,255,0.1);
  font-size: 12px;
  font-family: var(--font-mono);
  font-weight: 600;
  white-space: nowrap;
}
.mat-chip .mat-count {
  color: var(--text);
}
.mat-chip.zero {
  opacity: 0.4;
}

/* Cost row inside Workshop upgrades — shows what you need to spend.
   Items here render as block-level chips that wrap nicely instead of
   pushing the buy button off the row. */
.material-cost {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  font-family: var(--font-mono);
}
.material-cost .cost-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  border-radius: 6px;
  background: rgba(255,209,102,0.08);
  border: 1px solid rgba(255,209,102,0.18);
  font-size: 11px;
  font-weight: 700;
  color: var(--coin);
  white-space: nowrap;
}
.material-cost .cost-chip.insufficient {
  background: rgba(255,107,107,0.08);
  border-color: rgba(255,107,107,0.25);
  color: var(--danger);
}
.name.r-material,.rarity-tag.r-material,.label.r-material{color:#78ffdc}
.dive-target.rarity-material::before{box-shadow:0 0 18px rgba(var(--rarity-rgb),.45)}


/* ===== SHINY VARIANT ===== */
/* Pokemon-style alt catches: extremely rare (1/256 in Hadal, 1/4096 in Cast),
   capped to one per dive. Marked by a ✨ prefix in the item name and this
   pulsing gold glow on the UI element. */
@keyframes shinyPulse {
  0%, 100% {
    box-shadow:
      0 0 0 1px rgba(255, 215, 0, 0.35),
      0 0 12px rgba(255, 215, 0, 0.25),
      inset 0 0 18px rgba(255, 215, 0, 0.08);
  }
  50% {
    box-shadow:
      0 0 0 1px rgba(255, 215, 0, 0.6),
      0 0 24px rgba(255, 215, 0, 0.55),
      inset 0 0 22px rgba(255, 215, 0, 0.18);
  }
}
@keyframes shinyEmojiSparkle {
  0%, 100% { filter: drop-shadow(0 0 4px rgba(255, 215, 0, 0.5)); }
  50%      { filter: drop-shadow(0 0 12px rgba(255, 215, 0, 0.9)); }
}
/* Scoped .shiny pulse — only on contexts that actually want the gold
   border-glow rectangle (inventory rows, popup catches, trophies).
   The aquarium uses its own .aquarium-fish.shiny rule which only glows
   the emoji's filter, not the button outline. Without this scoping the
   beaver / any shiny aquarium fish would inherit a yellow rounded-rect. */
.inv-row.shiny,
.popup-catch.shiny,
.catch-list-item.shiny,
.trophy-row.shiny {
  animation: shinyPulse 2s ease-in-out infinite;
  position: relative;
  border-radius: 12px;
}
.inv-row.shiny .emoji,
.popup-catch.shiny .emoji,
.catch-list-item.shiny .emoji,
.trophy-row.shiny .emoji {
  animation: shinyEmojiSparkle 2s ease-in-out infinite;
}

/* Cloud Save */
.cloud-save-card {
  margin: 12px 0 14px;
  padding: 14px;
  border: 1px solid rgba(94, 207, 255, 0.28);
  background: linear-gradient(180deg, rgba(94,207,255,0.08), rgba(255,255,255,0.025));
  border-radius: 18px;
}
.cloud-title {
  font-weight: 900;
  font-size: 16px;
  margin-bottom: 8px;
  color: var(--fg);
}
.cloud-line {
  color: var(--muted);
  margin: 4px 0;
  font-size: 14px;
}
.cloud-line b { color: var(--coin); }
.cloud-code {
  letter-spacing: 0.12em;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.cloud-hint {
  margin-top: 8px;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.35;
}
.cloud-actions { margin-top: 10px; }
.cloud-status {
  margin-top: 8px;
  min-height: 18px;
  color: var(--muted);
  font-size: 12px;
}
.cloud-status.ok { color: var(--ok); }
.cloud-status.err { color: var(--bad); }
.cloud-input {
  width: 100%;
  padding: 12px 14px;
  margin: 8px 0;
  border-radius: 14px;
  border: 1px solid rgba(255,255,255,0.15);
  background: rgba(255,255,255,0.06);
  color: var(--fg);
  font-size: 16px;
  outline: none;
}
.cloud-input:focus { border-color: rgba(94,207,255,0.65); }

/* ============================================================
   DAILY CHALLENGE — home card + modal
   ============================================================ */
.daily-card {
  margin-top: 12px;
  padding: 10px 12px;
  /* Match the top "Daily 🎯" pill 1:1 — same green bg, border, and text. */
  background: rgba(128, 237, 153, 0.10);
  border: 1px solid rgba(128, 237, 153, 0.35);
  border-radius: 10px;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}
.daily-card:active {
  background: rgba(128, 237, 153, 0.18);
}
.daily-card.done {
  border-color: rgba(128, 237, 153, 0.4);
  background: linear-gradient(180deg, rgba(128,237,153,0.06) 0%, var(--bg-elev) 100%);
}
.daily-card.claimable {
  border-color: var(--coin);
  background: linear-gradient(180deg, rgba(255,209,102,0.10) 0%, var(--bg-elev) 100%);
  animation: dailyPulse 2.5s ease-in-out infinite;
}
@keyframes dailyPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255,209,102,0); }
  50%      { box-shadow: 0 0 14px 1px rgba(255,209,102,0.18); }
}
.daily-card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 4px;
}
.daily-card-title {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
  font-family: var(--font-mono);
  color: var(--ok);
}
.daily-card-status {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 700;
  color: var(--coin);
}
.daily-card.done .daily-card-status { color: var(--ok); }
.daily-card-label {
  font-size: 13px;
  color: var(--text);
  margin-bottom: 8px;
  line-height: 1.3;
}
.daily-card-bar {
  height: 6px;
  background: var(--bg);
  border-radius: 4px;
  overflow: hidden;
  border: 1px solid var(--border);
}
.daily-card-bar-fill {
  height: 100%;
  background: var(--coin);
  transition: width 0.3s ease-out;
}
.daily-card.done .daily-card-bar-fill { background: var(--ok); }

/* Modal */
.daily-modal-inner {
  max-width: 380px;
  width: 100%;
  padding: 20px 18px 16px;
}
.daily-modal-label {
  font-size: 15px;
  text-align: center;
  margin: 8px 0 16px;
  line-height: 1.4;
}
.daily-modal-bar {
  position: relative;
  height: 22px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 11px;
  overflow: hidden;
  margin-bottom: 16px;
}
.daily-modal-bar-fill {
  position: absolute;
  inset: 0 auto 0 0;
  background: var(--coin);
  transition: width 0.3s ease-out;
}
.daily-modal-bar-text {
  position: relative;
  text-align: center;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 12px;
  line-height: 22px;
  color: var(--bg);
  mix-blend-mode: difference;
}
.daily-modal-rewards {
  padding: 12px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  margin-bottom: 12px;
}
.daily-modal-rewards-label {
  font-size: 10px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 6px;
  text-align: center;
}
.daily-modal-rewards-items {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: 14px;
  font-weight: 700;
  color: var(--coin);
}
.daily-modal-rewards-items .reward-mat {
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 4px 10px;
  font-size: 13px;
  color: var(--text);
}
.daily-modal-reset {
  font-size: 10px;
  text-align: center;
  color: var(--text-faint);
  letter-spacing: 0.5px;
  margin-bottom: 14px;
}

/* ============================================================
   MERCHANT — material trade shop section
   ============================================================ */
/* Merchant — compact one-row trades. The whole section is denser than
   Workshop because there's a lot of them and they're all the same shape. */
.merchant-section {
  /* Slightly tighter padding so 5 trades fit on screen with less scroll */
  padding: 0;
}
.merchant-trade {
  padding: 7px 10px;
  display: flex;
  align-items: center;
  gap: 6px;
  border-bottom: 1px solid var(--border);
}
.merchant-trade:last-child { border-bottom: none; }
.merchant-trade-side {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
  min-width: 0;
}
.merchant-trade-side.give { justify-content: flex-end; flex: 1; }
.merchant-trade-side.receive { flex: 0 0 auto; }
.merchant-trade-side .merchant-chip {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 3px 7px;
  border-radius: 5px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--border);
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
}
.merchant-trade-side.give .merchant-chip.insufficient {
  background: rgba(255, 107, 107, 0.08);
  border-color: rgba(255, 107, 107, 0.25);
  color: var(--danger);
}
.merchant-trade-side .merchant-chip.receive {
  background: rgba(128, 237, 153, 0.08);
  border-color: rgba(128, 237, 153, 0.25);
  color: var(--ok);
}
.merchant-trade-arrow {
  color: var(--text-faint);
  font-size: 13px;
  flex-shrink: 0;
}
.merchant-trade-btn {
  background: rgba(128, 237, 153, 0.12);
  color: var(--ok);
  border: 1px solid rgba(128, 237, 153, 0.3);
  /* Wider now that it says "Trade" instead of an icon. Min-width keeps the
     button column visually aligned across rows even when the label changes. */
  padding: 5px 14px;
  min-width: 64px;
  border-radius: 7px;
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.4px;
  cursor: pointer;
  font-family: inherit;
  flex-shrink: 0;
}
.merchant-trade-btn:disabled {
  background: rgba(255, 255, 255, 0.03);
  color: var(--text-faint);
  border-color: var(--border);
  cursor: not-allowed;
}
.merchant-trade-btn:not(:disabled):active { transform: scale(0.92); }

/* Tier badge on the left of each trade row — a glanceable progression marker.
   Higher tiers = rarer materials, so the colour ramps from cool blue to gold. */
.merchant-trade-tier {
  flex-shrink: 0;
  width: 36px;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.5px;
  padding: 3px 0;
  border-radius: 5px;
  border: 1px solid;
}
.merchant-trade-tier.tier-1 {
  color: #4cc9f0;
  border-color: rgba(76, 201, 240, 0.30);
  background: rgba(76, 201, 240, 0.06);
}
.merchant-trade-tier.tier-2 {
  color: #80ed99;
  border-color: rgba(128, 237, 153, 0.30);
  background: rgba(128, 237, 153, 0.06);
}
.merchant-trade-tier.tier-3 {
  color: #c084fc;
  border-color: rgba(192, 132, 252, 0.30);
  background: rgba(192, 132, 252, 0.06);
}
.merchant-trade-tier.tier-4 {
  color: #ffd166;
  border-color: rgba(255, 209, 102, 0.35);
  background: rgba(255, 209, 102, 0.08);
}

/* Short helper text under the Merchant title — quick orientation for new players */
.merchant-intro {
  font-size: 11px;
  color: var(--text-dim);
  text-align: center;
  padding: 0 14px 10px;
  line-height: 1.45;
  font-style: italic;
}

/* ============================================================
   STICKY SHOP WALLET — always-visible material counts
   ============================================================ */
.shop-wallet {
  background: var(--bg-elev);
  border-bottom: 1px solid var(--border);
  padding: 8px 12px;
  position: relative;
  z-index: 5;
}
.shop-wallet .mat-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  justify-content: center;
}
.shop-wallet .mat-chip {
  /* Slightly tighter than the in-shop variant */
  padding: 4px 8px;
  font-size: 11px;
}

/* The shop screen needs to ensure the wallet sits between the header and
   the scrolling body. We can't use `#screen-shop` directly because that
   beats `.screen { display:none }` and the screen stays visible on other tabs.
   Scoping to `.active` so the `display:none` from the parent rule still wins
   when shop isn't the current tab. */
#screen-shop.active {
  flex-direction: column;
}
#screen-shop > .screen-body {
  flex: 1;
  min-height: 0;
}

/* Trade animation — a chip particle that flies between two anchor points.
   Same scaffolding as coin/material particles but uses the merchant chip look. */
.merchant-particle {
  position: fixed;
  pointer-events: none;
  transform: translate(-50%, -50%);
  font-family: var(--font-mono);
  font-size: 18px;
  font-weight: 700;
  padding: 4px 9px;
  border-radius: 999px;
  background: rgba(128, 237, 153, 0.18);
  border: 1px solid rgba(128, 237, 153, 0.45);
  color: var(--ok);
  z-index: 9999;
  white-space: nowrap;
  box-shadow: 0 0 12px rgba(128, 237, 153, 0.35);
  animation: merchantFly 700ms cubic-bezier(0.4, 0, 0.6, 1) forwards;
}
.merchant-particle.give {
  /* Outgoing (wallet → merchant) — yellow/coin colour */
  background: rgba(255, 209, 102, 0.18);
  border-color: rgba(255, 209, 102, 0.45);
  color: var(--coin);
  box-shadow: 0 0 12px rgba(255, 209, 102, 0.35);
}
@keyframes merchantFly {
  0% {
    left: var(--start-x);
    top: var(--start-y);
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.4);
  }
  18% {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1.1);
  }
  55% {
    left: var(--mid-x);
    top: var(--mid-y);
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
  }
  100% {
    left: var(--end-x);
    top: var(--end-y);
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.6);
  }
}

/* Pulse the receiver chip when a material arrives. */
.mat-chip.bump {
  animation: matChipBump 0.5s ease-out;
}
@keyframes matChipBump {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.25); background: rgba(128, 237, 153, 0.35); }
  100% { transform: scale(1); }
}

/* ============================================================
   CATCH → INVENTORY ANIMATION
   When the player taps "Nice!", every catch becomes a flying emoji
   that arcs from the popup to the Inventory tab in the bottom bar.
   ============================================================ */
.fish-particle {
  position: fixed;
  transform: translate(-50%, -50%);
  pointer-events: none;
  font-size: 32px;
  z-index: 9999;
  /* Subtle glow makes a swarm of fish read as "shiny things flying" */
  filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.4));
  animation: fishFly 750ms cubic-bezier(0.32, 0.04, 0.45, 1) forwards;
}
/* Rarer fish leave a brighter trail */
.fish-particle.r-rare      { filter: drop-shadow(0 0 8px rgba(76, 201, 240, 0.55)) drop-shadow(0 2px 6px rgba(0,0,0,0.4)); }
.fish-particle.r-epic      { filter: drop-shadow(0 0 9px rgba(157, 78, 221, 0.6))  drop-shadow(0 2px 6px rgba(0,0,0,0.4)); }
.fish-particle.r-legendary { filter: drop-shadow(0 0 10px rgba(255, 209, 102, 0.7)) drop-shadow(0 2px 6px rgba(0,0,0,0.4)); }
.fish-particle.r-mythical  { filter: drop-shadow(0 0 12px rgba(241, 91, 181, 0.7))  drop-shadow(0 2px 6px rgba(0,0,0,0.4)); }
@keyframes fishFly {
  0% {
    left: var(--start-x);
    top: var(--start-y);
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.4) rotate(-15deg);
  }
  18% {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1.05) rotate(0deg);
  }
  55% {
    left: var(--mid-x);
    top: var(--mid-y);
    opacity: 1;
    transform: translate(-50%, -50%) scale(0.95) rotate(20deg);
  }
  100% {
    left: var(--end-x);
    top: var(--end-y);
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.5) rotate(40deg);
  }
}

/* Popup gracefully fades + shrinks once the player hits Nice — the popup
   is "deflating" as its fish escape toward the inventory. */
.catch-popup.flying-away .catch-popup-inner {
  animation: catchPopupFlyAway 280ms ease-in forwards;
  pointer-events: none;
}
@keyframes catchPopupFlyAway {
  0%   { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(0.85); }
}

/* Inventory tab pulse — when the catch swarm arrives, briefly highlight
   the destination so the player knows where their fish went. */
.tab.tab-pulse {
  animation: tabPulse 700ms ease-out;
}
@keyframes tabPulse {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.18); filter: drop-shadow(0 0 12px rgba(128, 237, 153, 0.8)); }
  100% { transform: scale(1); filter: none; }
}

/* ============================================================
   POPUP RARITY GLOW
   The catch popup gets a glow around its border in the colour of the
   player's best catch. Intensity scales with rarity — a common haul is
   subtle, a mythical pulses spectacularly.
   ============================================================ */

/* Common and trash: no glow — keeps everyday catches calm. */

/* Uncommon: soft green halo, no animation. */
.catch-popup.glow-uncommon .catch-popup-inner {
  border-color: rgba(128, 237, 153, 0.55);
  box-shadow:
    0 0 24px rgba(128, 237, 153, 0.30),
    0 0 0 1px rgba(128, 237, 153, 0.18);
}

/* Rare: cyan, slow pulse */
.catch-popup.glow-rare .catch-popup-inner {
  border-color: rgba(76, 201, 240, 0.65);
  animation: popupPop 0.35s cubic-bezier(0.34, 1.56, 0.64, 1),
             glowRare 2s ease-in-out infinite 0.35s;
}
@keyframes glowRare {
  0%, 100% { box-shadow: 0 0 24px rgba(76, 201, 240, 0.35), 0 0 0 1px rgba(76, 201, 240, 0.22); }
  50%      { box-shadow: 0 0 36px rgba(76, 201, 240, 0.55), 0 0 0 1px rgba(76, 201, 240, 0.35); }
}

/* Epic: purple, deeper pulse */
.catch-popup.glow-epic .catch-popup-inner {
  border-color: rgba(157, 78, 221, 0.7);
  animation: popupPop 0.35s cubic-bezier(0.34, 1.56, 0.64, 1),
             glowEpic 1.7s ease-in-out infinite 0.35s;
}
@keyframes glowEpic {
  0%, 100% { box-shadow: 0 0 28px rgba(157, 78, 221, 0.40), 0 0 0 1px rgba(157, 78, 221, 0.25); }
  50%      { box-shadow: 0 0 44px rgba(157, 78, 221, 0.65), 0 0 0 2px rgba(157, 78, 221, 0.45); }
}

/* Legendary: gold, rich double-layer shadow */
.catch-popup.glow-legendary .catch-popup-inner {
  border-color: rgba(255, 209, 102, 0.85);
  animation: popupPop 0.35s cubic-bezier(0.34, 1.56, 0.64, 1),
             glowLegendary 1.4s ease-in-out infinite 0.35s;
}
@keyframes glowLegendary {
  0%, 100% {
    box-shadow:
      0 0 30px rgba(255, 209, 102, 0.45),
      0 0 60px rgba(255, 209, 102, 0.25),
      0 0 0 1px rgba(255, 209, 102, 0.40);
  }
  50% {
    box-shadow:
      0 0 50px rgba(255, 209, 102, 0.75),
      0 0 90px rgba(255, 209, 102, 0.45),
      0 0 0 2px rgba(255, 209, 102, 0.65);
  }
}

/* Mythical: pink, the loudest celebration. Adds a rotating outer glow
   via a ::before pseudo-element so the popup looks like it's spinning
   in a halo. */
.catch-popup.glow-mythical .catch-popup-inner {
  position: relative;
  border-color: rgba(241, 91, 181, 0.95);
  animation: popupPop 0.35s cubic-bezier(0.34, 1.56, 0.64, 1),
             glowMythical 1s ease-in-out infinite 0.35s;
}
.catch-popup.glow-mythical .catch-popup-inner::before {
  content: '';
  position: absolute;
  inset: -8px;
  border-radius: 20px;
  background: conic-gradient(
    from 0deg,
    rgba(241, 91, 181, 0.0) 0%,
    rgba(241, 91, 181, 0.55) 25%,
    rgba(255, 209, 102, 0.40) 50%,
    rgba(241, 91, 181, 0.55) 75%,
    rgba(241, 91, 181, 0.0) 100%
  );
  filter: blur(14px);
  z-index: -1;
  animation: mythicalSpin 3.5s linear infinite;
}
@keyframes glowMythical {
  0%, 100% {
    box-shadow:
      0 0 38px rgba(241, 91, 181, 0.55),
      0 0 80px rgba(241, 91, 181, 0.30),
      0 0 0 2px rgba(241, 91, 181, 0.55);
  }
  50% {
    box-shadow:
      0 0 60px rgba(241, 91, 181, 0.85),
      0 0 120px rgba(241, 91, 181, 0.50),
      0 0 0 3px rgba(241, 91, 181, 0.80);
  }
}
@keyframes mythicalSpin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* ============ INVENTORY SETTINGS PILL ============ */
.inventory-settings-pill {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 10px 12px;
  margin: 4px 0 10px;
  border-radius: 999px;
  background: rgba(255,255,255,0.055);
  border: 1px solid rgba(255,255,255,0.12);
  color: var(--text);
  font-size: 12px;
  font-weight: 800;
  cursor: pointer;
}
.settings-pill-sub {
  color: var(--text-dim);
  font-size: 10px;
  font-weight: 600;
  font-family: var(--font-mono);
}
.inventory-settings-panel {
  background: rgba(0,0,0,0.52);
  border: 1px solid rgba(255,255,255,0.10);
  border-radius: 16px;
  padding: 12px;
  margin: 0 0 12px;
}
.settings-panel-head {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  align-items: flex-start;
  margin-bottom: 10px;
}
.settings-panel-title {
  font-weight: 900;
  font-size: 15px;
}
.settings-panel-sub {
  color: var(--text-dim);
  font-size: 10px;
  margin-top: 2px;
}
.settings-panel-close {
  background: rgba(255,255,255,0.08);
  color: var(--text);
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 9px;
  width: 32px;
  height: 32px;
  font-weight: 900;
}
.inventory-cloud-card {
  margin: 8px 0 10px;
}
.aquarium-shop-hint {
  color: rgba(187,221,255,0.55);
  font-size: 10px;
  font-family: var(--font-mono);
  padding: 2px 2px 0;
}

/* Moby Dick — strong white glow so the legendary white whale is instantly
   distinct from the other 🐳 (Beluga, Sperm Whale). Applied everywhere the
   emoji renders via the emojiHTML() helper. */
.moby-glow {
  display: inline-block;
  filter:
    brightness(1.15)
    drop-shadow(0 0 4px rgba(255, 255, 255, 0.95))
    drop-shadow(0 0 10px rgba(235, 245, 255, 0.85))
    drop-shadow(0 0 18px rgba(200, 230, 255, 0.65));
  animation: mobyGlowPulse 2.6s ease-in-out infinite;
}
@keyframes mobyGlowPulse {
  0%,100% {
    filter:
      brightness(1.15)
      drop-shadow(0 0 4px rgba(255, 255, 255, 0.95))
      drop-shadow(0 0 10px rgba(235, 245, 255, 0.85))
      drop-shadow(0 0 18px rgba(200, 230, 255, 0.65));
  }
  50% {
    filter:
      brightness(1.25)
      drop-shadow(0 0 6px rgba(255, 255, 255, 1))
      drop-shadow(0 0 16px rgba(235, 245, 255, 0.95))
      drop-shadow(0 0 26px rgba(200, 230, 255, 0.80));
  }
}
.cosmic-koi {
  display: inline-block;
  position: relative;
  filter: drop-shadow(0 0 6px rgba(180,130,255,0.7)) drop-shadow(0 0 12px rgba(120,180,255,0.5));
  animation: cosmicKoiGlow 3s ease-in-out infinite;
}
.cosmic-koi::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 1.55em;
  height: 0.62em;
  margin: -0.31em 0 0 -0.775em;
  border-radius: 50%;
  border: 0.1em solid rgba(190,150,255,0.85);
  border-top-color: rgba(150,190,255,0.35);
  border-bottom-color: rgba(220,180,255,0.95);
  box-shadow: 0 0 8px rgba(180,140,255,0.55);
  pointer-events: none;
  transform: rotateX(72deg) rotateZ(0deg);
  animation: cosmicKoiRing 6s linear infinite;
}
@keyframes cosmicKoiGlow {
  0%,100% { filter: drop-shadow(0 0 6px rgba(180,130,255,0.7)) drop-shadow(0 0 12px rgba(120,180,255,0.5)); }
  50%     { filter: drop-shadow(0 0 10px rgba(200,150,255,0.9)) drop-shadow(0 0 20px rgba(140,200,255,0.7)); }
}
@keyframes cosmicKoiRing {
  0%   { transform: rotateX(72deg) rotateZ(0deg); }
  100% { transform: rotateX(72deg) rotateZ(360deg); }
}

/* ===== Mythical species animations (shown in trophy/favourites/leaderboard) ===== */
.myth-anim {
  display: inline-block;
  position: relative;
}
/* Living creatures — slow swimming sway */
.myth-swim { animation: mythSwim 3.4s ease-in-out infinite; }
@keyframes mythSwim {
  0%,100% { transform: translateX(-2px) rotate(-4deg); }
  50%     { transform: translateX(2px) rotate(4deg); }
}
/* Whirlpools — continuous spin */
.myth-spin { animation: mythSpin 4s linear infinite; }
@keyframes mythSpin {
  0%   { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}
/* Cosmic — pulsing aura glow */
.myth-aura { animation: mythAura 2.8s ease-in-out infinite; }
@keyframes mythAura {
  0%,100% { filter: drop-shadow(0 0 4px rgba(150,120,255,0.55)); transform: scale(1); }
  50%     { filter: drop-shadow(0 0 12px rgba(180,150,255,0.95)); transform: scale(1.08); }
}
/* Living relics — heartbeat (double-thump) */
.myth-beat { animation: mythBeat 1.5s ease-in-out infinite; }
@keyframes mythBeat {
  0%, 40%, 100% { transform: scale(1); }
  15%  { transform: scale(1.18); }
  28%  { transform: scale(1.02); }
  35%  { transform: scale(1.12); }
}
/* Ancient artifacts — gentle float + shimmer */
.myth-relic { animation: mythRelic 3.6s ease-in-out infinite; }
@keyframes mythRelic {
  0%,100% { transform: translateY(0); filter: drop-shadow(0 0 3px rgba(255,220,150,0.4)); }
  50%     { transform: translateY(-3px); filter: drop-shadow(0 0 9px rgba(255,225,160,0.85)); }
}
/* Eldritch / kaiju — tiny symbols flicker in and out around the emoji.
   The symbol stays small so the main emoji is always readable. */
.myth-cthulhu, .myth-godzilla {
  filter: drop-shadow(0 0 5px rgba(120,200,140,0.5));
}
.myth-godzilla{ opacity:1 !important; z-index:0; }
.myth-cthulhu::before, .myth-cthulhu::after,
.myth-godzilla::before, .myth-godzilla::after {
  position: absolute;
  font-size: 0.38em;
  pointer-events: none;
  opacity: 0;
}
.myth-cthulhu::before { content: '❓'; top: -0.1em; right: -0.2em; animation: mythFlickerA 2.4s ease-in-out infinite; }
.myth-cthulhu::after  { content: '❓'; bottom: 0; left: -0.2em;     animation: mythFlickerB 2.4s ease-in-out infinite; }
.myth-godzilla::before {
  content: '☢️';
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
  font-size: 1.05em;
  opacity: 0.28;
  filter: blur(0.5px);
  z-index: -1;                /* sits BEHIND Godzilla, not on top */
  animation: godzillaRadiationSpin 8s linear infinite;
}
.myth-godzilla::after { content:''; display:none; }

/* Water spirit (Undine) — gentle bob + soft blue aura, with sparkle + droplet
   rising and fading above her. Symbols stay small so she's always readable. */
.myth-undine {
  animation: mythUndineFloat 3.8s ease-in-out infinite;
  filter: drop-shadow(0 0 6px rgba(120,200,255,0.6));
}
@keyframes mythUndineFloat {
  0%,100% { transform: translateY(0) rotate(-3deg); }
  50%     { transform: translateY(-4px) rotate(3deg); }
}
.myth-undine::before {
  content: '✨';
  position: absolute;
  top: -0.2em; right: -0.1em;
  font-size: 0.4em;
  pointer-events: none;
  opacity: 0;
  animation: undineSparkle 2.6s ease-in-out infinite;
}
@keyframes undineSparkle {
  0%, 100% { opacity: 0; transform: translateY(0) scale(0.5); }
  30%      { opacity: 1; transform: translateY(-0.3em) scale(1); }
  60%      { opacity: 0; transform: translateY(-0.7em) scale(0.6); }
}

@keyframes godzillaRadiationSpin {
  from { transform: translate(-50%,-50%) rotate(0deg); }
  to { transform: translate(-50%,-50%) rotate(360deg); }
}
@keyframes mythFlickerA {
  0%, 100% { opacity: 0; transform: scale(0.6); }
  15%      { opacity: 1; transform: scale(1); }
  30%      { opacity: 0; transform: scale(0.6); }
}
@keyframes mythFlickerB {
  0%, 50%, 100% { opacity: 0; transform: scale(0.6); }
  65%           { opacity: 1; transform: scale(1); }
  80%           { opacity: 0; transform: scale(0.6); }
}


/* Pirate Sunken Chest */
.chest-modal.sunken-pirate-modal {
  background:
    radial-gradient(circle at 50% 28%, rgba(90, 70, 45, 0.35), transparent 34%),
    radial-gradient(circle at 50% 80%, rgba(0, 0, 0, 0.88), rgba(0, 0, 0, 0.94)),
    linear-gradient(180deg, rgba(12,18,22,0.92), rgba(2,5,8,0.98));
}

.sunken-pirate-modal .chest-modal-card {
  border-color: rgba(255, 195, 95, 0.22);
  background:
    linear-gradient(180deg, rgba(44, 31, 20, 0.96), rgba(10, 8, 8, 0.98));
  box-shadow:
    0 0 0 1px rgba(255, 195, 95, 0.08),
    0 24px 80px rgba(0,0,0,0.70),
    inset 0 0 34px rgba(255, 170, 55, 0.05);
}

.sunken-pirate-modal .chest-modal-icon {
  font-size: 54px;
  filter:
    drop-shadow(0 0 10px rgba(255, 190, 80, 0.35))
    drop-shadow(0 5px 18px rgba(0,0,0,0.75));
}

.sunken-pirate-modal .chest-modal-title {
  color: #ffd166;
}

.sunken-pirate-modal .chest-modal-sub {
  color: rgba(230, 210, 175, 0.72);
}

.sunken-ominous {
  margin: 12px 0 10px;
  padding: 10px 12px;
  border-radius: 14px;
  background:
    linear-gradient(180deg, rgba(80, 55, 35, 0.34), rgba(0,0,0,0.22));
  border: 1px solid rgba(255, 195, 95, 0.14);
  color: rgba(255, 235, 200, 0.86);
  font-size: 12px;
  font-weight: 700;
  line-height: 1.35;
}

/* Ghost Ship Event */
#ghost-ship-overlay{
  position:fixed;
  inset:0;
  z-index:99999;
  background:
    radial-gradient(circle at center, rgba(40,40,60,.55), rgba(0,0,0,.92)),
    linear-gradient(180deg, rgba(15,25,35,.88), rgba(0,0,0,.95));
  backdrop-filter: blur(8px);
  display:flex;
  align-items:center;
  justify-content:center;
  padding:20px;
}

.ghost-ship-modal{
  width:min(92vw,420px);
  border-radius:24px;
  padding:26px 22px;
  background:linear-gradient(180deg, rgba(20,25,35,.96), rgba(4,6,10,.98));
  border:1px solid rgba(255,255,255,.08);
  text-align:center;
  animation:ghostFloat 4s ease-in-out infinite;
}

@keyframes ghostFloat{
  0%,100%{ transform:translateY(0px); }
  50%{ transform:translateY(-6px); }
}

.ghost-fog{ font-size:42px; margin-bottom:8px; }
.ghost-title{ font-size:24px; font-weight:900; margin-bottom:10px; line-height:1.1; }
.duel-draw-title{ color:#ffd166; text-shadow:0 0 18px rgba(255,209,102,0.45); }
.ghost-sub{ color:rgba(255,255,255,.72); margin-bottom:18px; }
.ghost-captain{ font-size:58px; margin:10px 0 18px; }
.ghost-dialogue{ font-style:italic; line-height:1.5; margin-bottom:20px; }

.ghost-play-btn{
  width:100%;
  border:none;
  border-radius:16px;
  padding:14px 16px;
  font-weight:800;
  background:linear-gradient(180deg, #ffd166, #ffb703);
  color:#1a1200;
}

/* ===== Slot Machine ===== */
.slot-modal .slot-balance{
  font-size:15px;
  color:rgba(255,255,255,.8);
  margin-bottom:16px;
}
.slot-modal .slot-balance b{ color:#ffd166; }
.slot-reels{
  display:flex;
  justify-content:center;
  gap:10px;
  margin:6px 0 16px;
}
.slot-reel{
  width:74px;
  height:84px;
  border-radius:14px;
  display:flex;
  align-items:center;
  justify-content:center;
  font-size:42px;
  background:linear-gradient(180deg, rgba(255,255,255,.06), rgba(0,0,0,.25));
  border:1px solid rgba(255,255,255,.1);
  box-shadow:inset 0 2px 8px rgba(0,0,0,.4);
}
.slot-reel.spinning{
  animation:slotReelShake .18s linear infinite;
  filter:blur(0.4px);
}
.slot-reel.locked{
  animation:slotReelLock .28s ease-out;
  border-color:rgba(255,255,255,.14);
  box-shadow:inset 0 2px 8px rgba(0,0,0,.4);
}
@keyframes slotReelShake{
  0%,100%{ transform:translateY(-2px); }
  50%{ transform:translateY(2px); }
}
@keyframes slotReelLock{
  0%{ transform:scale(1.18); }
  60%{ transform:scale(0.94); }
  100%{ transform:scale(1); }
}
.slot-result{
  min-height:22px;
  font-weight:800;
  line-height:1.4;
  margin-bottom:16px;
  color:rgba(255,255,255,.85);
}
.slot-result.win{ color:#7CFC9B; }
.slot-result.chips{ color:#c08a3a; text-shadow:0 0 12px rgba(180,122,42,.38); }
.slot-result.miss{ color:rgba(255,255,255,.5); }
.slot-result.boom{ color:#ff6b6b; text-shadow:0 0 12px rgba(255,80,80,.5); }
.slot-result.jackpot{
  color:#ffd166;
  text-shadow:0 0 16px rgba(255,209,102,.7);
  animation:slotJackpot .6s ease-in-out infinite;
}
@keyframes slotJackpot{
  0%,100%{ transform:scale(1); }
  50%{ transform:scale(1.06); }
}
.slot-btn{
  background:linear-gradient(180deg, #b388ff, #7c4dff) !important;
  color:#fff !important;
}

/* ===== Bait chip + popover (bottom-right, next to fish count) ===== */
.bait-chip-cell{
  position:relative;
  display:inline-flex;
}
.bait-chip{
  position:relative;
  display:inline-flex;
  align-items:center;
  gap:4px;
  font-size:11px;
  padding:4px 10px;
  background:var(--bg-elev);
  border:1px solid var(--border);
  border-radius:8px;
  font-family:var(--font-mono);
  color:var(--text-dim);
  cursor:pointer;
  line-height:1;
}
.bait-chip:active{ transform:scale(.95); }
.bait-chip-count{ font-variant-numeric:tabular-nums; }
.bait-chip.active{
  color:#fff;
  border-width:1.5px;
  background:rgba(255,255,255,.06);
}
.bait-chip.active.r-common{
  border-color:rgba(255,255,255,.72);
  box-shadow:0 0 8px rgba(255,255,255,.22);
}
.bait-chip.active.r-uncommon{
  border-color:var(--uncommon);
  box-shadow:0 0 9px color-mix(in srgb, var(--uncommon) 45%, transparent);
}
.bait-chip.active.r-rare{
  border-color:var(--rare);
  box-shadow:0 0 9px color-mix(in srgb, var(--rare) 45%, transparent);
}
.bait-chip.active.r-epic{
  border-color:var(--epic);
  box-shadow:0 0 9px color-mix(in srgb, var(--epic) 45%, transparent);
}
.bait-chip.active.r-legendary{
  border-color:var(--legendary);
  box-shadow:0 0 9px color-mix(in srgb, var(--legendary) 45%, transparent);
}
.bait-chip.active.r-shiny{
  border-color:#ffe066;
  box-shadow:0 0 10px rgba(255,224,102,.42);
}
.bait-chip.active.r-mythical{
  border-color:var(--mythical);
  box-shadow:0 0 10px color-mix(in srgb, var(--mythical) 50%, transparent);
}
.bait-toggle-dot{
  position:absolute;
  top:-2px;
  right:-2px;
  width:8px;
  height:8px;
  border-radius:50%;
  background:#ffd166;
  box-shadow:0 0 6px rgba(255,209,102,.8);
}
.bait-popover{
  position:absolute;
  bottom:calc(100% + 8px);
  left:0;
  z-index:40;
  background:linear-gradient(180deg, rgba(24,28,38,.98), rgba(10,12,18,.99));
  border:1px solid rgba(255,255,255,.12);
  border-radius:14px;
  padding:12px;
  box-shadow:0 8px 24px rgba(0,0,0,.5);
  animation:baitPopIn .16s ease-out;
}
@keyframes baitPopIn{
  0%{ opacity:0; transform:translateY(6px) scale(.96); }
  100%{ opacity:1; transform:translateY(0) scale(1); }
}
.bait-popover-close{
  position:absolute;
  top:-8px;
  right:-8px;
  width:22px;
  height:22px;
  border-radius:50%;
  border:1px solid rgba(255,255,255,.15);
  background:rgba(30,34,44,.98);
  color:rgba(255,255,255,.7);
  font-size:12px;
  line-height:1;
  cursor:pointer;
  display:flex;
  align-items:center;
  justify-content:center;
}
.bait-popover-close:active{ transform:scale(.9); }
.bait-popover-pills{
  display:grid;
  grid-template-columns:repeat(3, auto);
  gap:8px;
  justify-items:stretch;
}
.bait-pill{
  position:relative;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:3px;
  padding:5px 9px;
  border-radius:999px;
  font-size:15px;
  line-height:1;
  background:rgba(255,255,255,.05);
  border:1.5px solid rgba(255,255,255,.18);
  color:#fff;
  cursor:pointer;
  transition:transform .12s ease, box-shadow .12s ease, border-color .12s ease;
}
.bait-pill:active{ transform:scale(.94); }
.bait-pill-count{
  font-size:11px;
  font-weight:800;
  color:rgba(255,255,255,.7);
  font-variant-numeric:tabular-nums;
}
.bait-pill.r-common    { border-color:rgba(255,255,255,.4); }
.bait-pill.r-uncommon  { border-color:var(--uncommon); }
.bait-pill.r-rare      { border-color:var(--rare); }
.bait-pill.r-epic      { border-color:var(--epic); }
.bait-pill.r-legendary { border-color:var(--legendary); }
.bait-pill.r-shiny     { border-color:#ffe066; }
.bait-pill.r-mythical  { border-color:var(--mythical); }
.bait-pill.armed{
  background:rgba(255,255,255,.10);
  box-shadow:0 0 10px currentColor;
  transform:translateY(-1px);
}
.bait-pill.r-common.armed    { color:rgba(255,255,255,.85); }
.bait-pill.r-uncommon.armed  { color:var(--uncommon); }
.bait-pill.r-rare.armed      { color:var(--rare); }
.bait-pill.r-epic.armed      { color:var(--epic); }
.bait-pill.r-legendary.armed { color:var(--legendary); }
.bait-pill.r-shiny.armed     { color:#ffe066; }
.bait-pill.r-mythical.armed  { color:var(--mythical); }
.bait-pill.armed .bait-pill-count{ color:currentColor; }



/* Pirate Dice minigame */
.pirate-score {
  color: #ffd166;
  font-weight: 900;
  margin: 8px 0 2px;
  letter-spacing: .5px;
}
.pirate-round {
  color: rgba(255,255,255,.52);
  font-size: 12px;
  margin-bottom: 12px;
}
.pirate-table {
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
  margin: 14px 0;
}
.pirate-side {
  padding: 12px;
  border-radius: 16px;
  background: linear-gradient(180deg, rgba(255,255,255,.06), rgba(0,0,0,.18));
  border: 1px solid rgba(255,255,255,.08);
}
.pirate-side.captain {
  background: linear-gradient(180deg, rgba(100,70,45,.16), rgba(0,0,0,.25));
  border-color: rgba(255, 209, 102, .12);
}
.pirate-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 1.6px;
  color: rgba(255,255,255,.56);
  margin-bottom: 8px;
}
.pirate-dice-row {
  display: flex;
  justify-content: center;
  gap: 7px;
  min-height: 40px;
}
.pirate-die {
  font-size: 32px;
  line-height: 1;
  display: inline-block;
  filter: drop-shadow(0 3px 4px rgba(0,0,0,.55));
}
.pirate-side.captain .pirate-die {
  filter:
    drop-shadow(0 3px 4px rgba(0,0,0,.65))
    drop-shadow(0 0 7px rgba(255, 209, 102, .18));
}
.pirate-hand {
  margin-top: 8px;
  color: rgba(255,255,255,.78);
  font-size: 12px;
  font-weight: 800;
}
#pirate-dice-panel.rolling .pirate-die {
  animation: pirateDiceShake .18s linear infinite;
}
@keyframes pirateDiceShake {
  0% { transform: translate(0,0) rotate(0deg); }
  25% { transform: translate(1px,-2px) rotate(8deg); }
  50% { transform: translate(-1px,1px) rotate(-7deg); }
  75% { transform: translate(2px,1px) rotate(5deg); }
  100% { transform: translate(0,0) rotate(0deg); }
}
.pirate-final-list {
  display: grid;
  gap: 9px;
  margin: 18px 0;
}
.pirate-final-row {
  padding: 11px 12px;
  border-radius: 14px;
  font-weight: 900;
  background: rgba(255,255,255,.06);
  border: 1px solid rgba(255,255,255,.08);
  transition: transform .45s ease, opacity .45s ease;
}
.pirate-final-row.gain {
  color: #ffd166;
  background: rgba(255,209,102,.10);
  border-color: rgba(255,209,102,.20);
  animation: pirateRewardPop .65s ease both;
}
.pirate-reward-rarity {
  display: inline-block; margin-left: 6px; font-size: 10px; font-weight: 800;
  letter-spacing: 1px; text-transform: uppercase; opacity: 0.7; vertical-align: middle;
}
.pirate-final-row.gain.rarity-legendary { color: #ffb347; }
.pirate-final-row.gain.rarity-mythical  { color: #ff6ad5; }
.pirate-final-row.gain.rarity-epic      { color: #c98bff; }
.pirate-final-row.loss {
  color: #ff8a8a;
  background: rgba(255, 70, 70, .08);
  border-color: rgba(255, 70, 70, .18);
}
.pirate-final-row.loss.take {
  transform: translateX(18px) scale(.96);
  opacity: .45;
}
@keyframes pirateRewardPop {
  0% { transform: scale(.86); opacity: 0; }
  70% { transform: scale(1.04); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
.cursed-claim {
  background: linear-gradient(180deg, #ff8a8a, #8c1f1f) !important;
  color: white !important;
}



/* Cursed pirate chest visual rework */
.chest-modal.sunken-pirate-modal {
  background:
    radial-gradient(circle at 50% 15%, rgba(60,50,45,.18), transparent 28%),
    radial-gradient(circle at 50% 90%, rgba(0,0,0,.96), rgba(0,0,0,.99)),
    linear-gradient(180deg, rgba(14,14,16,.96), rgba(3,3,5,.99));
}

.sunken-pirate-modal .chest-modal-card {
  background:
    linear-gradient(180deg,
      rgba(38,28,20,.98),
      rgba(18,14,12,.99)
    );
  border:
    1px solid rgba(120,95,70,.28);
  box-shadow:
    0 24px 80px rgba(0,0,0,.78),
    inset 0 0 24px rgba(255,255,255,.02),
    inset 0 -12px 28px rgba(0,0,0,.42);
  position: relative;
  overflow: hidden;
}

.sunken-pirate-modal .chest-modal-card::before {
  content: '';
  position: absolute;
  inset: 0;
  background:
    repeating-linear-gradient(
      90deg,
      rgba(255,255,255,.015) 0px,
      rgba(255,255,255,.015) 2px,
      transparent 2px,
      transparent 34px
    );
  opacity: .55;
  pointer-events: none;
}

.sunken-pirate-modal .chest-modal-card::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 36%;
  height: 2px;
  background: rgba(120,95,70,.22);
  box-shadow: 0 1px 0 rgba(0,0,0,.55);
}

.sunken-pirate-modal .chest-modal-icon {
  font-size: 50px;
  filter:
    drop-shadow(0 6px 14px rgba(0,0,0,.72));
  opacity: .92;
}

.sunken-pirate-modal .chest-modal-title {
  color: rgba(220,210,190,.88);
  text-shadow:
    0 2px 10px rgba(0,0,0,.45);
  letter-spacing: .4px;
}

.sunken-pirate-modal .chest-modal-sub {
  color: rgba(185,175,160,.62);
}

.sunken-ominous {
  margin: 14px 0 12px;
  padding: 12px 14px;
  border-radius: 14px;
  background:
    linear-gradient(180deg,
      rgba(255,255,255,.03),
      rgba(0,0,0,.18)
    );
  border:
    1px solid rgba(255,255,255,.05);
  color:
    rgba(210,210,210,.74);
  font-size: 12px;
  line-height: 1.45;
  font-style: italic;
  letter-spacing: .2px;
}

.sunken-pirate-modal .chest-loot-list {
  background:
    linear-gradient(180deg,
      rgba(0,0,0,.14),
      rgba(0,0,0,.28)
    );
  border:
    1px solid rgba(255,255,255,.04);
}

.sunken-pirate-modal .chest-modal-close {
  background:
    linear-gradient(180deg,
      rgba(70,60,55,.95),
      rgba(28,24,22,.98)
    );
  color:
    rgba(230,225,215,.82);
  border:
    1px solid rgba(255,255,255,.06);
}



/* UI polish fixes */
.sunken-pirate-modal .chest-modal-card::after {
  top: 31% !important;
  opacity: .45;
}

.sunken-pirate-modal .chest-modal-sub {
  position: relative;
  z-index: 2;
  line-height: 1.45;
}

.sunken-pirate-modal .chest-modal-title {
  position: relative;
  z-index: 2;
  margin-bottom: 6px;
}



/* Pirate Dice interactive layout polish */
.pirate-table.interactive {
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
}
.pirate-versus {
  font-size: 12px;
  font-weight: 900;
  letter-spacing: .8px;
  color: rgba(255,255,255,.58);
  text-transform: uppercase;
  padding: 2px 0;
}
.pirate-side.player {
  background: linear-gradient(180deg, rgba(80,140,180,.12), rgba(0,0,0,.18));
  border-color: rgba(120,210,255,.12);
}
.pirate-die-btn {
  border: 0;
  background: rgba(255,255,255,.045);
  border: 1px solid rgba(255,255,255,.08);
  border-radius: 12px;
  padding: 5px 6px;
  min-width: 42px;
  min-height: 42px;
  display: grid;
  place-items: center;
  transition: transform .12s ease, background .12s ease, border-color .12s ease;
}
.pirate-die-btn:not(:disabled):active {
  transform: scale(.92);
}
.pirate-die-btn.held {
  background: rgba(255,209,102,.14);
  border-color: rgba(255,209,102,.42);
  box-shadow: 0 0 0 1px rgba(255,209,102,.08), 0 0 14px rgba(255,209,102,.13);
}
.pirate-die-btn:disabled {
  opacity: .88;
}
.pirate-die-btn .pirate-die {
  pointer-events: none;
}
.ghost-close-btn.pirate-lock-btn {
  margin-top: 8px;
  background: rgba(255,255,255,.07);
  color: rgba(255,255,255,.76);
  border: 1px solid rgba(255,255,255,.09);
}
.pirate-final-row.gain.claimable {
  transform: translateY(-2px);
  box-shadow: 0 0 18px rgba(255,209,102,.16);
}
.pirate-final-row.claimed {
  transform: translateY(-20px) scale(.92);
  opacity: 0;
}
.pirate-final-row.loss.claimed {
  transform: translateX(24px) scale(.90);
  opacity: 0;
}
.pirate-final-row.taken {
  transform: translateX(40px) scale(.85) rotate(4deg);
  opacity: 0;
  transition: transform .5s cubic-bezier(.5,0,.75,0), opacity .5s ease;
}



/* Fix: old chest plank divider must not cross the Sunken Pirate Chest title */
.sunken-pirate-modal .chest-modal-card::after {
  top: 39% !important;
  height: 1px !important;
  opacity: .28 !important;
  z-index: 0 !important;
}

.sunken-pirate-modal .chest-modal-icon,
.sunken-pirate-modal .chest-modal-title,
.sunken-pirate-modal .chest-modal-sub,
.sunken-pirate-modal .sunken-ominous,
.sunken-pirate-modal .chest-loot-list,
.sunken-pirate-modal .chest-modal-close {
  position: relative;
  z-index: 2;
}

.sunken-pirate-modal .chest-modal-title {
  margin-bottom: 10px !important;
  line-height: 1.12 !important;
}



.dive-start-btn.cursed {
  background: linear-gradient(180deg, rgba(120, 35, 35, 0.95), rgba(45, 12, 16, 0.98)) !important;
  border: 1px solid rgba(255, 95, 95, 0.28) !important;
  color: rgba(255, 220, 220, 0.95) !important;
  box-shadow: 0 0 18px rgba(255, 50, 50, 0.12) !important;
}



/* Pirate Dice UX fixes */
.ghost-close-btn.pirate-lock-btn,
.pirate-lock-btn {
  display: block !important;
  width: 100% !important;
  margin-top: 10px !important;
  padding: 13px 16px !important;
  border-radius: 16px !important;
  border: 1px solid rgba(255,255,255,.12) !important;
  background: linear-gradient(180deg, rgba(255,255,255,.09), rgba(255,255,255,.045)) !important;
  color: rgba(255,255,255,.86) !important;
  font-size: 15px !important;
  font-weight: 900 !important;
  letter-spacing: .3px !important;
  text-align: center !important;
}

.pirate-stolen-list {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  justify-content: center;
  padding: 10px;
  border-radius: 14px;
  background: rgba(0,0,0,.20);
  border: 1px solid rgba(255,80,80,.12);
}

.pirate-stolen-list.empty {
  color: rgba(255,255,255,.55);
  font-size: 12px;
  font-style: italic;
}

.pirate-stolen-chip {
  padding: 6px 8px;
  border-radius: 999px;
  background: rgba(255,255,255,.06);
  border: 1px solid rgba(255,255,255,.08);
  font-size: 11px;
  font-weight: 800;
  max-width: 100%;
}



/* Pirate Dice Duel replacement */
.duel-header {
  text-align: center;
  margin-bottom: 12px;
}
.duel-title {
  font-size: 26px;
  font-weight: 950;
  letter-spacing: .2px;
}
.duel-round {
  display: inline-block;
  margin-top: 6px;
  padding: 3px 12px;
  font-size: 11px;
  font-weight: 900;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: #ffd166;
  background: rgba(255,209,102,.10);
  border: 1px solid rgba(255,209,102,.25);
  border-radius: 999px;
}
.duel-sub {
  margin-top: 5px;
  font-size: 11px;
  color: rgba(255,255,255,.58);
  font-weight: 800;
}
.duel-board {
  display: grid;
  gap: 10px;
}
.duel-hp {
  padding: 8px 10px;
  border-radius: 14px;
  background: rgba(255,255,255,.045);
  border: 1px solid rgba(255,255,255,.07);
}
.duel-hp-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 1.4px;
  color: rgba(255,255,255,.55);
  margin-bottom: 3px;
}
.duel-hearts {
  font-size: 16px;
  letter-spacing: 1px;
  color: #ff7474;
  text-shadow: 0 0 8px rgba(255,60,60,.18);
}
.duel-heart { display: inline-block; transition: color 0.2s; }
.duel-heart.filled { color: #ff7474; }
.duel-heart.empty  { color: rgba(255,116,116,0.22); }
.duel-heart.just-lost {
  color: #ff3030;
  animation: duelHeartLost 0.85s ease-out;
}
@keyframes duelHeartLost {
  0%   { transform: scale(1.5) translateY(0); color: #fff; text-shadow: 0 0 14px rgba(255,40,40,0.95); opacity: 1; }
  35%  { transform: scale(1.7) translateY(-3px); color: #ff3030; }
  100% { transform: scale(0.6) translateY(10px) rotate(25deg); opacity: 0.15; }
}
.duel-heart.just-gained {
  animation: duelHeartGained 0.9s ease-out;
}
@keyframes duelHeartGained {
  0%   { transform: scale(0.2); color: #ffd166; text-shadow: 0 0 16px rgba(255,209,102,1); opacity: 0; }
  40%  { transform: scale(1.6); color: #ffe9a8; opacity: 1; }
  70%  { transform: scale(1.2); color: #ffd166; }
  100% { transform: scale(1); color: #ff7474; text-shadow: 0 0 8px rgba(255,60,60,.18); }
}
.duel-shields {
  margin-top: 4px;
  font-size: 13px;
  color: #80d8ff;
}
.duel-enemy {
  font-size: 54px;
  line-height: 1;
  filter:
    drop-shadow(0 8px 12px rgba(0,0,0,.55))
    drop-shadow(0 0 12px rgba(255,209,102,.10));
}
.duel-status {
  min-height: 20px;
  color: rgba(255,255,255,.78);
  font-size: 13px;
  font-weight: 850;
  line-height: 1.35;
}
.duel-dice-row {
  display: flex;
  justify-content: center;
  gap: 8px;
  flex-wrap: nowrap;
}
.duel-die {
  position: relative;
  width: 48px;
  height: 56px;
  border-radius: 14px;
  border: 1px solid rgba(255,255,255,.09);
  background:
    linear-gradient(180deg, rgba(255,255,255,.08), rgba(0,0,0,.18));
  display: grid;
  place-items: center;
  transition: transform .14s ease, border-color .14s ease, box-shadow .14s ease, background .14s ease;
}
.duel-die:not(:disabled):active {
  transform: scale(.92);
}
.duel-die.skull-live {
  animation: duelSkullPulse 1.4s ease-in-out infinite;
}
@keyframes duelSkullPulse {
  0%,100% { box-shadow: 0 0 0 1px rgba(190,70,255,.10), 0 0 16px rgba(190,70,255,.20); }
  50%     { box-shadow: 0 0 0 1px rgba(190,70,255,.30), 0 0 26px rgba(190,70,255,.45); }
}
.duel-round-summary {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: center;
  margin: 8px 0;
  padding: 8px;
  border-radius: 10px;
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.08);
}
.duel-round-summary .duel-dmg,
.duel-round-summary .duel-block {
  font-size: 12px;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: 6px;
}
.duel-die.tumbling {
  animation: duelDieTumble 0.5s cubic-bezier(.45,.05,.55,.95) infinite;
  animation-delay: calc(var(--spin, 0) * -4ms);
  z-index: 5;
}
.duel-die.tumbling .duel-die-icon {
  animation: duelIconWobble 0.5s ease-in-out infinite;
  animation-delay: calc(var(--spin, 0) * -4ms);
}
@keyframes duelDieTumble {
  0%   { transform: translateY(0) rotate(0deg) scale(1.04); }
  25%  { transform: translateY(-22px) rotate(110deg) scale(1.1); }
  50%  { transform: translateY(-30px) rotate(200deg) scale(1.12); }
  75%  { transform: translateY(-18px) rotate(290deg) scale(1.08); }
  100% { transform: translateY(0) rotate(360deg) scale(1.04); }
}
@keyframes duelIconWobble {
  0%,100% { transform: rotate(0deg); }
  50%     { transform: rotate(-26deg); }
}
.duel-die.landed {
  animation: duelDieLand 0.42s cubic-bezier(.16,1.7,.35,1);
  z-index: 6;
}
@keyframes duelDieLand {
  0%   { transform: translateY(-26px) scale(1.18, 0.84) rotate(10deg); box-shadow: 0 0 0 rgba(255,255,255,0); }
  40%  { transform: translateY(0) scale(1.28, 0.6); box-shadow: 0 6px 22px rgba(0,0,0,0.5), 0 0 18px rgba(255,255,255,0.45); }
  62%  { transform: translateY(-5px) scale(0.86, 1.2) rotate(-2deg); }
  82%  { transform: translateY(0) scale(1.06, 0.95); }
  100% { transform: translateY(0) scale(1, 1) rotate(0deg); box-shadow: 0 2px 8px rgba(0,0,0,0.3); }
}
.duel-die-icon {
  font-size: 27px;
  line-height: 1;
  filter: drop-shadow(0 3px 4px rgba(0,0,0,.48));
}
.duel-die.sword {
  border-color: rgba(255,255,255,.12);
}
.duel-die.shield {
  border-color: rgba(120,210,255,.18);
}
.duel-die.skull,
.duel-die.locked {
  border-color: rgba(190,70,255,.34);
  box-shadow:
    0 0 0 1px rgba(190,70,255,.08),
    0 0 18px rgba(190,70,255,.20);
  background:
    radial-gradient(circle at 50% 40%, rgba(190,70,255,.18), transparent 58%),
    linear-gradient(180deg, rgba(70,20,85,.42), rgba(0,0,0,.32));
}
.duel-die.held {
  border-color: rgba(255,209,102,.55);
  box-shadow:
    0 0 0 1px rgba(255,209,102,.12),
    0 0 18px rgba(255,209,102,.18);
}
.duel-lock {
  position: absolute;
  top: -8px;
  right: -7px;
  font-size: 14px;
}
.duel-kept {
  position: absolute;
  bottom: -8px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 8px;
  font-weight: 950;
  letter-spacing: .6px;
  color: #ffd166;
  background: rgba(0,0,0,.72);
  border: 1px solid rgba(255,209,102,.25);
  border-radius: 999px;
  padding: 2px 5px;
}
.duel-dice-placeholder {
  padding: 18px;
  color: rgba(255,255,255,.30);
  border: 1px dashed rgba(255,255,255,.09);
  border-radius: 14px;
  font-weight: 850;
}
.duel-stats {
  font-size: 12px;
  color: rgba(255,255,255,.62);
  font-weight: 900;
}
.duel-stats.rolling {
  color: rgba(255,255,255,.28);
  letter-spacing: 1px;
}
.duel-die.bust-stuck {
  border: 2px solid #ff4444;
  box-shadow: 0 0 0 1px rgba(255,68,68,.4), 0 0 14px rgba(255,68,68,.55);
  animation: duelBustStuck 0.9s ease-in-out infinite;
}
@keyframes duelBustStuck {
  0%,100% { box-shadow: 0 0 0 1px rgba(255,68,68,.4), 0 0 12px rgba(255,68,68,.45); }
  50%     { box-shadow: 0 0 0 2px rgba(255,68,68,.7), 0 0 20px rgba(255,68,68,.75); }
}
.duel-die.reroll-target {
  animation: duelRerollHint 1.1s ease-in-out infinite;
}
@keyframes duelRerollHint {
  0%,100% { transform: translateY(0); box-shadow: 0 0 0 1px rgba(190,120,255,.25), 0 0 10px rgba(190,120,255,.30); }
  50%     { transform: translateY(-3px); box-shadow: 0 0 0 1px rgba(190,120,255,.5), 0 0 18px rgba(190,120,255,.55); }
}
.duel-hearts.duel-slash {
  position: relative;
  animation: duelSlashShake 0.4s ease;
}
.duel-hearts.duel-slash::after {
  content: '';
  position: absolute;
  inset: -6px -10px;
  background: linear-gradient(115deg, transparent 40%, rgba(255,80,80,0.85) 50%, transparent 60%);
  pointer-events: none;
  animation: duelSlashSweep 0.45s ease-out;
}
@keyframes duelSlashSweep {
  0%   { transform: translateX(-120%); opacity: 0; }
  40%  { opacity: 1; }
  100% { transform: translateX(120%); opacity: 0; }
}
@keyframes duelSlashShake {
  0%,100% { transform: translateX(0); }
  25%     { transform: translateX(-4px); }
  75%     { transform: translateX(4px); }
}
.duel-hearts.duel-victory-pulse {
  animation: duelVictoryPulse 0.8s ease;
}
@keyframes duelVictoryPulse {
  0%,100% { filter: none; transform: scale(1); }
  35%     { filter: drop-shadow(0 0 10px rgba(120,255,160,0.9)); transform: scale(1.12); }
}
#ghost-cancel-btn,
.ghost-close-btn:not(.pirate-lock-btn) {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  margin: 10px auto 0;
  padding: 11px 22px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 700;
  color: rgba(255,255,255,.72);
  background: rgba(255,255,255,.05);
  border: 1px solid rgba(255,255,255,.12);
  border-radius: 12px;
  cursor: pointer;
}
#ghost-cancel-btn:active,
.ghost-close-btn:not(.pirate-lock-btn):active {
  transform: scale(.97);
  background: rgba(255,255,255,.08);
}
.duel-divider {
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.10), transparent);
  margin: 2px 0;
}
.duel-actions {
  margin-top: 12px;
}
#pirate-dice-panel.duel-rolling .duel-die:not(.held):not(.locked) .duel-die-icon {
  animation: duelSlotSpin .16s linear infinite;
}
@keyframes duelSlotSpin {
  0% { transform: translateY(-2px) scale(.95); opacity: .60; }
  50% { transform: translateY(2px) scale(1.08); opacity: 1; }
  100% { transform: translateY(-1px) scale(.98); opacity: .75; }
}
#pirate-dice-panel.duel-hit {
  animation: duelHitShake .35s ease;
}
#pirate-dice-panel.duel-critical {
  animation: duelCriticalShake .55s ease;
}
@keyframes duelHitShake {
  0%,100% { transform: translateY(0); }
  30% { transform: translateX(-4px); }
  60% { transform: translateX(4px); }
}
@keyframes duelCriticalShake {
  0%,100% { transform: translateY(0) scale(1); }
  20% { transform: translateX(-8px) scale(1.01); }
  40% { transform: translateX(8px) scale(1.015); }
  60% { transform: translateX(-6px) scale(1.01); }
  80% { transform: translateX(5px) scale(1); }
}



/* Blind Pirate Dice Duel tweaks */
.duel-die.hidden {
  border-color: rgba(255,255,255,.10);
  background:
    linear-gradient(180deg, rgba(255,255,255,.06), rgba(0,0,0,.28));
}
.duel-die.hidden .duel-die-icon {
  opacity: .55;
  filter: blur(.2px) drop-shadow(0 3px 4px rgba(0,0,0,.55));
}
.duel-combat-flash {
  min-height: 34px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: center;
  align-items: center;
}
.duel-dmg,
.duel-block {
  display: inline-block;
  padding: 6px 9px;
  border-radius: 999px;
  font-weight: 950;
  font-size: 12px;
  animation: duelCombatPop .7s ease both;
}
.duel-dmg {
  color: #ffd0d0;
  background: rgba(255,70,70,.16);
  border: 1px solid rgba(255,70,70,.24);
}
.duel-block {
  color: #d5f1ff;
  background: rgba(90,190,255,.12);
  border: 1px solid rgba(90,190,255,.22);
}
@keyframes duelCombatPop {
  0% { opacity: 0; transform: translateY(8px) scale(.86); }
  60% { opacity: 1; transform: translateY(-2px) scale(1.06); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}
.duel-actions .ghost-play-btn:disabled,
.duel-actions .ghost-close-btn:disabled {
  opacity: .42;
  filter: grayscale(.5);
}


/* Harbor / Tavern additions */
.tavern-balance-row {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  align-items: center;
  width: 100%;
  padding: 9px 10px;
  border-radius: 14px;
  background: rgba(255,255,255,0.06);
  color: var(--text);
  font-size: 13px;
}
.tavern-balance-row.subtle { opacity: 0.9; }
.tavern-action-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  width: 100%;
}
.pirate-corner-btn.small {
  padding: 9px 8px;
  font-size: 12px;
}

/* Tavern money micro-animations */
.pirate-corner-btn.small.muted {
  opacity: 0.86;
  background: rgba(255,255,255,0.06);
}
.pirate-corner-btn.muted {
  opacity: 0.86;
  background: rgba(255,255,255,0.06);
  margin-top: 6px;
}
.tavern-value-float {
  position: fixed;
  z-index: 360;
  pointer-events: none;
  transform: translate(-50%, -50%);
  font-family: var(--font-mono);
  font-weight: 900;
  font-size: 13px;
  letter-spacing: 0.2px;
  padding: 5px 9px;
  border-radius: 999px;
  background: rgba(10,10,10,0.72);
  border: 1px solid rgba(255,255,255,0.18);
  box-shadow: 0 8px 24px rgba(0,0,0,0.4);
  animation: tavernFloatUp 850ms cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
}
.tavern-value-float.gain { color: var(--ok); }
.tavern-value-float.spend { color: var(--danger); }
.tavern-value-float.bad { color: var(--warn); }
@keyframes tavernFloatUp {
  0% { opacity: 0; transform: translate(-50%, -35%) scale(0.86); }
  18% { opacity: 1; transform: translate(-50%, -70%) scale(1.06); }
  100% { opacity: 0; transform: translate(-50%, -145%) scale(0.96); }
}
.tavern-flash-gain {
  animation: tavernFlashGain 560ms ease;
}
.tavern-flash-spend {
  animation: tavernFlashSpend 560ms ease;
}
.tavern-flash-bet {
  animation: tavernFlashBet 520ms ease;
}
@keyframes tavernFlashGain {
  0% { transform: scale(1); box-shadow: 0 0 0 rgba(128,237,153,0); }
  38% { transform: scale(1.025); box-shadow: 0 0 18px rgba(128,237,153,0.42); background: rgba(128,237,153,0.13); }
  100% { transform: scale(1); box-shadow: 0 0 0 rgba(128,237,153,0); }
}
@keyframes tavernFlashSpend {
  0% { transform: scale(1); box-shadow: 0 0 0 rgba(255,107,107,0); }
  38% { transform: scale(0.985); box-shadow: 0 0 16px rgba(255,107,107,0.35); background: rgba(255,107,107,0.11); }
  100% { transform: scale(1); box-shadow: 0 0 0 rgba(255,107,107,0); }
}
@keyframes tavernFlashBet {
  0% { transform: scale(1); }
  45% { transform: scale(1.025); background: rgba(255,209,102,0.13); box-shadow: 0 0 16px rgba(255,209,102,0.25); }
  100% { transform: scale(1); }
}
.tavern-shake {
  animation: tavernShake 380ms ease;
}
@keyframes tavernShake {
  0%,100% { transform: translateX(0); }
  20% { transform: translateX(-5px); }
  40% { transform: translateX(5px); }
  60% { transform: translateX(-3px); }
  80% { transform: translateX(3px); }
}

/* ===== Harbor shop card grid (functional; visual polish later) ===== */
.harbor-grid{
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:10px;
  padding:0 0 14px;
}
.harbor-card{
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap:6px;
  padding:22px 14px;
  border-radius:16px;
  background:var(--bg-elev);
  border:1px solid var(--border);
  color:var(--text);
  text-align:center;
  cursor:pointer;
  transition:transform .12s ease, border-color .12s ease, background .12s ease;
}
.harbor-card:active{ transform:scale(.97); }
.harbor-card.open{
  border-color:#4cc9f0;
  background:rgba(76,201,240,.08);
}
/* Affordable-upgrade highlight — draws the eye to shops with something to buy */
.harbor-card.has-upgrade{
  border-color:rgba(128,237,153,.55);
  background:rgba(128,237,153,.06);
  animation:harborCardGlow 2.2s ease-in-out infinite;
}
.harbor-card.has-upgrade.open{
  border-color:#4cc9f0;
  background:rgba(76,201,240,.08);
  animation:none;
}
@keyframes harborCardGlow{
  0%,100%{ box-shadow:0 0 0 rgba(128,237,153,0); }
  50%    { box-shadow:0 0 16px rgba(128,237,153,.35); }
}
.harbor-card-emoji{ font-size:40px; line-height:1; margin-bottom:2px; }
.harbor-card-name{ font-weight:800; font-size:17px; }
.harbor-card-divider{
  width:40px;
  height:1px;
  background:rgba(255,255,255,.14);
  margin:1px 0;
}
.harbor-card-status{ font-size:11px; color:var(--text-dim); line-height:1.5; }

/* ===== Shop cards — Harbor-style, calm and uniform ===== */
.shop-card{
  position:relative;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap:6px;
  width:100%;
  padding:22px 14px;
  margin:0 0 12px;
  border-radius:16px;
  background:var(--bg-elev);
  border:1px solid var(--border);
  color:var(--text);
  text-align:center;
  font:inherit;
}
/* Affordable → green glowing border, clickable (rendered as a <button>) */
.shop-card.affordable{
  cursor:pointer;
  border-color:rgba(128,237,153,.55);
  background:rgba(128,237,153,.06);
  animation:harborCardGlow 2.2s ease-in-out infinite;
}
.shop-card.affordable:active{ transform:scale(.97); }
/* Armed for confirmation (first tap) — stronger, steady glow + brighter border
   so it clearly stands apart from the gentle "affordable" pulse. */
.shop-card.armed{
  animation:none;
  border-color:rgba(128,237,153,.95);
  background:rgba(128,237,153,.16);
  box-shadow:0 0 22px 4px rgba(128,237,153,.5);
}
.shop-card.armed .shop-card-sub{ color:var(--ok); font-weight:700; }
/* While the buy animation plays, the freshly re-rendered card keeps its frame
   but hides its (new) content, so the old ghost values and the new price never
   overlap. Content fades back in once the ghost/ring finish. */
.shop-card.buy-settling > *{ opacity:0; }
.shop-card:not(.buy-settling) > *{ transition:opacity .25s ease-in; }
/* Locked / maxed → quiet grey, not interactive */
.shop-card.locked, .shop-card.maxed{
  cursor:default;
  border-color:var(--border);
  opacity:.85;
}
.shop-card-emoji{ font-size:40px; line-height:1; margin-bottom:2px; }
.shop-card-name{ font-weight:800; font-size:17px; }
.shop-card-divider{
  width:40px; height:1px;
  background:rgba(255,255,255,.14);
  margin:1px 0;
}
.shop-card-sub{ font-size:11px; color:var(--text-dim); line-height:1.5; max-width:90%; }
.shop-card-price{
  margin-top:4px;
  font-family:var(--font-mono);
  font-weight:700;
  font-size:15px;
  color:var(--coin);
}
.shop-card-price.cant{ color:var(--text-dim); }
/* Corner level badge — universal "4/6" progress, or "MAX LVL" */
.shop-card-level{
  position:absolute;
  top:10px; right:12px;
  font-family:var(--font-mono);
  font-size:11px;
  font-weight:700;
  color:var(--text-dim);
  letter-spacing:.5px;
}
.shop-card.maxed .shop-card-level{ color:var(--ok); }

/* Purchase confirmation — a ghost clone of the bought card flashes green and
   pops, since the real card re-renders away the instant you buy. */
.shop-card-ghost{
  position:fixed;
  z-index:9998;
  margin:0;
  pointer-events:none;
  border-color:rgba(128,237,153,.9);
  background:rgba(128,237,153,.14);
  animation:shopBuyPop .5s cubic-bezier(0.34,1.56,0.64,1) forwards;
}
@keyframes shopBuyPop{
  0%   { transform:scale(1);    box-shadow:0 0 0 0 rgba(128,237,153,.55); opacity:1; }
  35%  { transform:scale(1.05); box-shadow:0 0 26px 6px rgba(128,237,153,.5); opacity:1; }
  100% { transform:scale(.96);  box-shadow:0 0 0 0 rgba(128,237,153,0);    opacity:0; }
}
/* Expanding green ring that radiates out from the bought card — a clean,
   satisfying confirmation with no text/emoji. */
.shop-buy-ring{
  position:fixed;
  z-index:9999;
  width:60px; height:60px;
  margin:-30px 0 0 -30px;
  border-radius:50%;
  border:3px solid rgba(128,237,153,.85);
  pointer-events:none;
  animation:shopBuyRing .55s cubic-bezier(0.22,0.61,0.36,1) forwards;
}
@keyframes shopBuyRing{
  0%   { transform:scale(.3); opacity:.9; border-width:3px; }
  100% { transform:scale(2.6); opacity:0; border-width:1px; }
}
.harbor-hint{
  text-align:center;
  color:var(--text-dim);
  font-size:13px;
  padding:20px 0;
}

/* ===== Harbor full-screen shop view ===== */
.harbor-shop-view{ animation:harborShopIn .2s ease-out; }
@keyframes harborShopIn{
  0%{ opacity:0; transform:translateX(8px); }
  100%{ opacity:1; transform:translateX(0); }
}
.harbor-back-btn{
  display:inline-flex;
  align-items:center;
  gap:4px;
  padding:8px 14px;
  margin-bottom:10px;
  border-radius:999px;
  background:var(--bg-elev);
  border:1px solid var(--border);
  color:var(--text);
  font-size:14px;
  font-weight:600;
  cursor:pointer;
}
.harbor-back-btn:active{ transform:scale(.96); }
.harbor-shop-title{
  font-size:20px;
  font-weight:800;
  margin-bottom:12px;
}

/* ===== Harbor town-square scene (time-of-day) ===== */
.harbor-scene{
  position:relative;
  border-radius:18px;
  overflow:hidden;
  padding:0;
  margin-bottom:6px;
  min-height:420px;
  isolation:isolate;
}
.harbor-sky, .harbor-water, .harbor-silhouette, .harbor-stars{
  position:absolute; left:0; right:0; pointer-events:none; z-index:0;
}
.harbor-sky{ top:0; height:55%; }
.harbor-water{ bottom:0; height:45%; }
/* Sky palettes mirror the Fish screen for continuity */
.harbor-scene.time-night   .harbor-sky { background:linear-gradient(180deg,#060a24,#0e1438 55%,#1b2255); }
.harbor-scene.time-dawn    .harbor-sky { background:linear-gradient(180deg,#2a2966,#845080 45%,#f0a880); }
.harbor-scene.time-morning .harbor-sky { background:linear-gradient(180deg,#7eb6dc,#b7d9ec 55%,#f0e6c8); }
.harbor-scene.time-midday  .harbor-sky { background:linear-gradient(180deg,#4fa8e0,#82c2e8 55%,#c0e0ee); }
.harbor-scene.time-sunset  .harbor-sky { background:linear-gradient(180deg,#3a2e6e,#d56838 50%,#f8a060); }
.harbor-scene.time-dusk    .harbor-sky { background:linear-gradient(180deg,#14163e,#4a3070 50%,#7a4a78); }
/* Water — darker reflection of the sky mood */
.harbor-scene.time-night   .harbor-water { background:linear-gradient(180deg,#0a1238,#060a1e); }
.harbor-scene.time-dawn    .harbor-water { background:linear-gradient(180deg,#5a4a70,#1c1c40); }
.harbor-scene.time-morning .harbor-water { background:linear-gradient(180deg,#6aa6cc,#2e5a7a); }
.harbor-scene.time-midday  .harbor-water { background:linear-gradient(180deg,#3f90c8,#1e5882); }
.harbor-scene.time-sunset  .harbor-water { background:linear-gradient(180deg,#a85838,#3a2050); }
.harbor-scene.time-dusk    .harbor-water { background:linear-gradient(180deg,#3a2858,#14132e); }
/* Pier + house silhouette sitting on the horizon (between sky and water) */
.harbor-silhouette{
  bottom:43%;
  height:64px;
  background:
    /* little houses with peaked roofs, as layered conic/linear gradients */
    linear-gradient(180deg, transparent 40%, rgba(0,0,0,.55) 40%) 0 0/100% 100%,
    repeating-linear-gradient(90deg, transparent 0 26px, rgba(0,0,0,.4) 26px 30px);
  -webkit-mask:linear-gradient(180deg, transparent 0, #000 60%);
          mask:linear-gradient(180deg, transparent 0, #000 60%);
  opacity:.6;
}
.harbor-scene.time-midday .harbor-silhouette,
.harbor-scene.time-morning .harbor-silhouette{ opacity:.32; }
/* Stars — only at night/dusk, faint dots */
.harbor-stars{ top:0; height:50%; opacity:0; }
.harbor-scene.time-night .harbor-stars,
.harbor-scene.time-dusk  .harbor-stars{
  opacity:.7;
  background-image:
    radial-gradient(1px 1px at 20% 30%, #fff, transparent),
    radial-gradient(1px 1px at 60% 20%, #fff, transparent),
    radial-gradient(1px 1px at 80% 40%, #fff, transparent),
    radial-gradient(1px 1px at 35% 55%, #fff, transparent),
    radial-gradient(1px 1px at 75% 65%, #fff, transparent),
    radial-gradient(1px 1px at 48% 18%, #fff, transparent);
  animation:harborStars 5s ease-in-out infinite;
}
@keyframes harborStars{ 0%,100%{opacity:.45;} 50%{opacity:.8;} }
/* The grid sits above the scene with padding */
.harbor-scene .harbor-grid{
  position:relative;
  z-index:1;
  padding:16px;
  margin:0;
}
/* Cards become glassy "buildings" standing in the scene */
.harbor-scene .harbor-card{
  background:rgba(18,22,32,.72);
  backdrop-filter:blur(4px);
  -webkit-backdrop-filter:blur(4px);
  border:1px solid rgba(255,255,255,.14);
  box-shadow:0 6px 16px rgba(0,0,0,.4);
}

/* ===== Harbor header subtitle ===== */
#screen-shop .screen-header{ align-items:flex-start; }
.harbor-title-block{ display:flex; flex-direction:column; gap:2px; }
.harbor-subtitle{
  font-size:12px;
  color:var(--text-dim);
  font-weight:500;
}

/* ===== Tavern room (chips currency, tavern vibe) ===== */
.tavern-room{
  background:
    radial-gradient(120% 80% at 50% 0%, rgba(120,72,30,.22), transparent 60%),
    linear-gradient(180deg, rgba(40,28,16,.55), rgba(20,14,8,.7));
  border:1px solid rgba(190,140,70,.28);
  border-radius:18px;
  padding:20px 16px;
  display:flex;
  flex-direction:column;
  gap:14px;
}
.tavern-room-head{ text-align:center; }
.tavern-room-sign{ font-size:38px; line-height:1; }
.tavern-room-flavour{ font-size:12px; color:rgba(255,225,180,.6); margin-top:6px; line-height:1.5; }
.tavern-balance-card{
  display:flex;
  align-items:center;
  justify-content:space-between;
  padding:14px 18px;
  border-radius:14px;
  background:rgba(255,209,102,.08);
  border:1px solid rgba(255,209,102,.3);
}
.tavern-balance-label{ font-size:14px; color:rgba(255,225,180,.8); }
.tavern-balance-big{ font-size:24px; font-weight:800; color:#ffd166; font-variant-numeric:tabular-nums; }
.tavern-room-actions{ display:flex; gap:10px; }
.tavern-btn{
  flex:1;
  border:none;
  border-radius:14px;
  padding:13px 14px;
  font-weight:700;
  font-size:15px;
  cursor:pointer;
  transition:transform .12s ease, filter .12s ease;
}
.tavern-btn:active{ transform:scale(.97); }
.tavern-btn:disabled{ opacity:.4; cursor:default; }
.tavern-btn.ghost{
  background:rgba(255,255,255,.06);
  border:1px solid rgba(255,209,102,.35);
  color:#ffe1b4;
}
.tavern-btn.play{ width:100%; flex:none; padding:15px; font-size:16px; color:#1a1200; }
.tavern-btn.play.dice{ background:linear-gradient(180deg,#ffd166,#e6a52e); }
.tavern-btn.play.slot{ background:linear-gradient(180deg,#b388ff,#7c4dff); color:#fff; }
.tavern-game-note{ font-size:11px; color:rgba(255,225,180,.5); text-align:center; margin-top:-6px; }
.tavern-bet-block{ display:flex; flex-direction:column; gap:8px; }
.tavern-bet-label{ font-size:13px; color:rgba(255,225,180,.75); font-weight:600; }
.tavern-bet-chips{ display:flex; gap:8px; }
.tavern-bet-chip{
  flex:1;
  border:1px solid rgba(255,209,102,.3);
  background:rgba(255,255,255,.04);
  color:#ffe1b4;
  border-radius:12px;
  padding:11px 0;
  font-weight:800;
  font-size:15px;
  cursor:pointer;
  transition:transform .1s ease, background .12s ease, border-color .12s ease;
}
.tavern-bet-chip:active{ transform:scale(.95); }
.tavern-bet-chip.active{
  background:rgba(255,209,102,.2);
  border-color:#ffd166;
  color:#ffd166;
  box-shadow:0 0 10px rgba(255,209,102,.35);
}
/* Header chip balance (shown only inside the Tavern) */
.header-chips{
  display:block;
  font-size:13px;
  color:#ffd166;
  font-weight:700;
  margin-top:2px;
  transform-origin:right center;
}
/* Add Chips popup */
.add-chips-overlay{
  position:fixed; inset:0; z-index:200;
  background:rgba(0,0,0,.6);
  display:flex; align-items:center; justify-content:center;
  padding:24px;
}
.add-chips-modal{
  width:100%; max-width:320px;
  background:linear-gradient(180deg, rgba(34,26,16,.98), rgba(18,12,6,.99));
  border:1px solid rgba(190,140,70,.4);
  border-radius:18px;
  padding:20px;
  text-align:center;
}
.add-chips-title{ font-size:20px; font-weight:800; color:#ffd166; }
.add-chips-sub{ font-size:12px; color:rgba(255,225,180,.6); margin:4px 0 16px; }
.add-chips-grid{ display:grid; grid-template-columns:1fr 1fr; gap:10px; margin-bottom:16px; }
.add-chips-opt{
  display:flex; flex-direction:column; gap:3px;
  padding:14px 10px;
  border-radius:12px;
  background:rgba(255,209,102,.1);
  border:1px solid rgba(255,209,102,.3);
  color:#fff;
  cursor:pointer;
  transition:transform .1s ease;
}
.add-chips-opt:active{ transform:scale(.95); }
.add-chips-opt.disabled{ opacity:.4; }
.add-chips-amt{ font-size:18px; font-weight:800; color:#ffd166; }
.add-chips-cost{ font-size:12px; color:rgba(255,255,255,.6); }
.add-chips-close{
  width:100%;
  padding:12px;
  border-radius:12px;
  border:1px solid rgba(255,255,255,.15);
  background:rgba(255,255,255,.06);
  color:#fff;
  font-weight:700;
  cursor:pointer;
}

/* ===== Harbor back-to-town link (in header, replaces subtitle) ===== */
.harbor-back-link{
  background:none;
  border:none;
  padding:0;
  font-size:12px;
  font-weight:600;
  color:#4cc9f0;
  cursor:pointer;
  display:inline-flex;
  align-items:center;
  gap:3px;
}
.harbor-back-link:active{ opacity:.6; }

/* ===== Add Chips: selected state + fly animation ===== */
.add-chips-opt.selected{
  border-color:#ffd166;
  background:rgba(255,209,102,.22);
  box-shadow:0 0 12px rgba(255,209,102,.45);
  transform:translateY(-1px);
}
.add-chips-close.ready{
  background:linear-gradient(180deg,#ffd166,#e6a52e);
  color:#1a1200;
  border-color:transparent;
  font-weight:800;
}
.chip-fly{
  position:fixed;
  z-index:300;
  font-size:30px;
  pointer-events:none;
  transform:translate(0,0);
  will-change:transform,opacity;
  filter:drop-shadow(0 2px 6px rgba(255,209,102,.6));
}
.header-chips.chip-bump{
  animation:chipBump .22s ease-out;
}
@keyframes chipBump{
  0%{ transform:scale(1); }
  45%{ transform:scale(1.35); color:#fff; }
  100%{ transform:scale(1); }
}

/* ===== Slot powder-keg explosion ===== */
.slot-reels.slot-boom{ animation:slotBoomShake .5s ease-in-out; }
@keyframes slotBoomShake{
  0%,100%{ transform:translateX(0); }
  15%{ transform:translateX(-8px) rotate(-2deg); }
  30%{ transform:translateX(8px) rotate(2deg); }
  45%{ transform:translateX(-6px); }
  60%{ transform:translateX(6px); }
  75%{ transform:translateX(-3px); }
}
.slot-explosion{
  position:absolute;
  top:50%; left:50%;
  transform:translate(-50%,-50%) scale(0.3);
  font-size:80px;
  pointer-events:none;
  z-index:5;
  animation:slotExplode .85s ease-out forwards;
}
@keyframes slotExplode{
  0%{ transform:translate(-50%,-50%) scale(0.3); opacity:0; }
  25%{ transform:translate(-50%,-50%) scale(1.3); opacity:1; }
  60%{ transform:translate(-50%,-50%) scale(1.1); opacity:1; }
  100%{ transform:translate(-50%,-50%) scale(1.5); opacity:0; }
}
.slot-reels{ position:relative; }

/* Slot won-bait name keeps its inline rarity colour, just bolder */
.slot-bait-name{ font-weight:800; }

/* ===== Slot panel (window) edge glow on outcome ===== */
#slot-panel{ transition:box-shadow .25s ease, border-color .25s ease; }
#slot-panel.glow-win{
  border-color:var(--slot-glow, #8ecae6);
  box-shadow:0 0 26px 5px color-mix(in srgb, var(--slot-glow, #8ecae6) 70%, transparent);
}
#slot-panel.glow-jackpot{
  border-color:var(--slot-glow, #f15bb5);
  animation:slotGlowJackpot 1.2s ease-in-out infinite;
}
#slot-panel.glow-loss{
  border-color:#ff5252;
  box-shadow:0 0 26px 5px rgba(255,82,82,.62);
}
@keyframes slotGlowJackpot{
  0%,100%{ box-shadow:0 0 24px 4px color-mix(in srgb, var(--slot-glow, #f15bb5) 65%, transparent); }
  50%{ box-shadow:0 0 42px 10px color-mix(in srgb, var(--slot-glow, #f15bb5) 90%, transparent); }
}

/* ===== Slot machine cabinet + pull lever ===== */
 .slot-machine-cabinet{
  position:relative;
  margin:10px auto 16px;
  padding:18px 18px 36px;
  max-width:310px;
  border-radius:22px;
  background:
    radial-gradient(circle at 50% 0%, rgba(255,209,102,.18), transparent 45%),
    linear-gradient(180deg, rgba(35,24,14,.92), rgba(15,11,9,.96));
  border:1px solid rgba(180,122,42,.62);
  box-shadow:inset 0 2px 0 rgba(255,255,255,.08), inset 0 -10px 24px rgba(0,0,0,.28), 0 14px 32px rgba(0,0,0,.34);
  overflow:visible;
}
.slot-cabinet-lights{
  position:absolute;
  top:7px;
  left:50%;
  transform:translateX(-50%);
  font-size:11px;
  letter-spacing:9px;
  color:rgba(255,209,102,.55);
  pointer-events:none;
  white-space:nowrap;
}
.slot-machine-cabinet .slot-reels{
  margin:14px 0 10px;
}
.slot-cost-pill{
  position:absolute;
  left:50%;
  bottom:9px;
  transform:translateX(-50%);
  padding:4px 10px;
  border-radius:999px;
  background:rgba(0,0,0,.28);
  border:1px solid rgba(255,255,255,.08);
  color:rgba(255,255,255,.72);
  font-size:12px;
  font-weight:800;
  white-space:nowrap;
}
.slot-lever{
  position:absolute;
  right:-31px;
  top:50%;
  width:58px;
  height:142px;
  transform:translateY(-50%);
  background:transparent;
  border:0;
  padding:0;
  cursor:pointer;
  touch-action:none;
  -webkit-tap-highlight-color:transparent;
  overflow:visible;
  z-index:3;
}
.slot-lever::before{
  content:"";
  position:absolute;
  left:25px;
  top:18px;
  width:8px;
  height:58px;
  border-radius:999px;
  background:linear-gradient(180deg, rgba(255,226,137,.95), rgba(156,97,32,.94));
  box-shadow:inset 0 0 5px rgba(0,0,0,.38), 0 0 10px rgba(255,209,102,.18);
  transform-origin:50% 0%;
  transform:translateY(var(--rod-y,0px));
  transition:transform .18s cubic-bezier(.2,.9,.28,1.18);
}
.slot-lever::after{
  content:"";
  position:absolute;
  left:18px;
  top:64px;
  width:23px;
  height:23px;
  border-radius:999px;
  background:linear-gradient(180deg, rgba(255,255,255,.16), rgba(0,0,0,.08)), #3a2615;
  border:1px solid rgba(255,209,102,.48);
  box-shadow:inset 0 2px 5px rgba(255,255,255,.08), 0 0 12px rgba(0,0,0,.38);
}
.slot-lever-knob{
  position:absolute;
  left:16px;
  top:0px;
  width:28px;
  height:28px;
  border-radius:999px;
  background:radial-gradient(circle at 35% 28%, rgba(255,255,255,.45), rgba(255,82,82,.92) 28%, rgba(140,18,28,.98) 72%);
  border:1px solid rgba(255,180,180,.62);
  box-shadow:inset 0 2px 6px rgba(255,255,255,.2), 0 0 13px rgba(255,82,82,.36), 0 4px 10px rgba(0,0,0,.38);
  transform-origin:50% 0%;
  transform:translateY(var(--knob-y,0px));
  transition:transform .18s cubic-bezier(.2,.9,.28,1.18), filter .18s ease;
}
.slot-lever.grabbing .slot-lever-knob,
.slot-lever.grabbing::before{
  transition:none;
}
.slot-lever.pulled .slot-lever-knob{
  transform:translateY(123px);
}
.slot-lever.pulled::before{
  transform:translateY(58px);
}
.slot-lever:disabled{
  opacity:.42;
  cursor:not-allowed;
  filter:grayscale(.35);
}
.slot-lever:disabled .slot-lever-knob{
  filter:none;
}
.slot-leave-link{
  margin-top:6px;
}
@media (max-width:380px){
  .slot-reel{ width:64px; height:76px; font-size:38px; }
  .slot-lever{ right:-26px; transform:translateY(-50%) scale(.92); }
}


/* Active bait glow on fishing hook button */
/* Active bait no longer glows the Cast/Skill Cast buttons.
   The glow is applied only to the animated hook while it is in the water. */

/* Merchant 2.0 — tabs + bait trade sink */
.merchant-tabs {
  display: flex;
  gap: 8px;
  padding: 0 0 10px;
}
.merchant-tab {
  flex: 1;
  border: 1px solid var(--border);
  background: rgba(255,255,255,.04);
  color: var(--text-dim);
  border-radius: 10px;
  padding: 9px 10px;
  font-family: inherit;
  font-weight: 800;
  letter-spacing: .3px;
  cursor: pointer;
}
.merchant-tab.active {
  color: #80ed99;
  border-color: rgba(128,237,153,.38);
  background: rgba(128,237,153,.10);
  box-shadow: 0 0 18px rgba(128,237,153,.08);
}
.merchant-tab:active { transform: scale(.97); }

.merchant-have {
  color: var(--text-faint);
  font-size: 10px;
  font-family: var(--font-mono);
  align-self: center;
  white-space: nowrap;
}
.merchant-note {
  color: var(--text-faint);
  font-size: 10px;
  text-align: center;
  padding: 10px 12px 12px;
  border-top: 1px solid var(--border);
  line-height: 1.35;
}
.merchant-trade.bait-trade .merchant-chip.bait-give {
  border-color: rgba(255,255,255,.18);
}
.merchant-trade.bait-trade .merchant-chip.bait-give.r-common { color: #e8edf2; }
.merchant-trade.bait-trade .merchant-chip.bait-give.r-uncommon { color: #80ed99; border-color: rgba(128,237,153,.30); background: rgba(128,237,153,.07); }
.merchant-trade.bait-trade .merchant-chip.bait-give.r-rare { color: #4cc9f0; border-color: rgba(76,201,240,.30); background: rgba(76,201,240,.07); }
.merchant-trade.bait-trade .merchant-chip.bait-give.r-epic { color: #c084fc; border-color: rgba(192,132,252,.30); background: rgba(192,132,252,.07); }
.merchant-trade.bait-trade .merchant-chip.bait-give.r-legendary { color: #ffd166; border-color: rgba(255,209,102,.36); background: rgba(255,209,102,.08); }
.merchant-trade.bait-trade .merchant-chip.bait-give.r-shiny { color: #fff7b0; border-color: rgba(255,247,176,.40); background: rgba(255,247,176,.09); }
.merchant-trade.bait-trade .merchant-chip.bait-give.insufficient {
  color: var(--danger);
  background: rgba(255,107,107,.08);
  border-color: rgba(255,107,107,.24);
}
.merchant-trade-tier.tier-5 {
  color: #fff7b0;
  border-color: rgba(255,247,176,.45);
  background: rgba(255,247,176,.08);
  box-shadow: 0 0 12px rgba(255,247,176,.08);
}


/* Merchant 2.1 — bait buy/sell switch */
.merchant-bait-switch {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin: -2px 0 10px;
}
.merchant-bait-switch-btn {
  border: 1px solid var(--border);
  background: rgba(255,255,255,.04);
  color: var(--text-dim);
  border-radius: 12px;
  padding: 9px 10px;
  font-family: inherit;
  font-weight: 900;
  letter-spacing: .3px;
  cursor: pointer;
}
.merchant-bait-switch-btn.active {
  color: #ffd166;
  border-color: rgba(255,209,102,.42);
  background: rgba(255,209,102,.10);
  box-shadow: 0 0 18px rgba(255,209,102,.08);
}
.merchant-bait-switch-btn:active { transform: scale(.97); }
.bait-trade-section.buy-mode .merchant-trade-btn {
  color: #ffd166;
  border-color: rgba(255,209,102,.42);
  background: rgba(255,209,102,.10);
}
.bait-trade-section.buy-mode .merchant-trade-btn:disabled {
  color: var(--text-faint);
  border-color: rgba(255,255,255,.10);
  background: rgba(255,255,255,.04);
}

/* ===== The Lighthouse — keeper's guides ===== */
.lighthouse{ display:flex; flex-direction:column; gap:16px; }
.lh-greeting{
  background:linear-gradient(180deg, rgba(40,52,68,.5), rgba(20,28,40,.6));
  border:1px solid rgba(140,180,220,.22);
  border-radius:14px;
  padding:16px 18px;
}
.lh-greeting p{ margin:0 0 8px; font-size:13px; color:var(--text-dim); }
.lh-greeting p:last-child{ margin-bottom:0; }
.lh-greeting-quote{ font-style:italic; color:var(--text) !important; line-height:1.6; }
.lh-topic-list{ display:flex; flex-direction:column; gap:8px; }
.lh-topic{
  display:flex;
  align-items:center;
  gap:12px;
  width:100%;
  padding:14px 16px;
  border-radius:12px;
  background:var(--bg-elev);
  border:1px solid var(--border);
  color:var(--text);
  cursor:pointer;
  text-align:left;
  transition:transform .1s ease, border-color .12s ease;
}
.lh-topic:active{ transform:scale(.98); }
.lh-topic-icon{ font-size:22px; }
.lh-topic-title{ flex:1; font-weight:700; font-size:15px; }
.lh-topic-arrow{ color:var(--text-dim); font-size:20px; }
.lh-back{
  align-self:flex-start;
  background:none;
  border:none;
  color:#4cc9f0;
  font-size:13px;
  font-weight:600;
  cursor:pointer;
  padding:0;
}
.lh-back:active{ opacity:.6; }
.lh-article-title{ font-size:20px; font-weight:800; margin:4px 0 12px; }
.lh-keeper-voice .lh-para{
  margin:0 0 12px;
  font-size:14px;
  line-height:1.65;
  color:var(--text);
}
.lh-keeper-voice .lh-para:last-child{ margin-bottom:0; }

/* Lighthouse: faintly glowing themed words in the keeper's prose */
.lh-c{
  color:var(--lh-c, #fff);
  font-weight:600;
  opacity:.92;
  text-shadow:0 0 6px var(--lh-c);            /* fallback: full-strength glow */
  text-shadow:0 0 6px color-mix(in srgb, var(--lh-c) 45%, transparent);
}

/* ===== Lighthouse 2.0 — Morse Signals ===== */
.lh-main-grid{display:grid;grid-template-columns:1fr;gap:10px;}
.lh-mode-card{display:flex;align-items:center;gap:12px;width:100%;padding:14px 16px;border-radius:14px;background:linear-gradient(180deg,rgba(30,42,58,.72),rgba(14,20,32,.78));border:1px solid rgba(140,180,220,.22);color:var(--text);text-align:left;cursor:pointer;transition:transform .1s ease,border-color .12s ease,box-shadow .12s ease;}
.lh-mode-card:active{transform:scale(.985);}
.lh-mode-card:hover{border-color:rgba(76,201,240,.35);box-shadow:0 0 18px rgba(76,201,240,.08);}
.lh-mode-card span{font-size:24px;width:32px;text-align:center;flex:0 0 32px;}
.lh-mode-card strong{display:block;font-size:15px;}
.lh-mode-card small{display:block;color:var(--text-dim);font-size:12px;line-height:1.35;margin-top:2px;}
.lh-signal-panel,.lh-logbook{background:linear-gradient(180deg,rgba(40,52,68,.50),rgba(20,28,40,.64));border:1px solid rgba(140,180,220,.24);border-radius:16px;padding:16px;box-shadow:0 14px 40px rgba(0,0,0,.18);}
.lh-signal-kicker{font-size:11px;text-transform:uppercase;letter-spacing:.12em;color:#9ad0ec;font-weight:800;margin-bottom:8px;}
.lh-morse-code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:28px;font-weight:900;line-height:1.2;letter-spacing:.05em;text-align:center;color:#fff;text-shadow:0 0 14px rgba(76,201,240,.35);padding:18px 10px;border-radius:14px;background:rgba(0,0,0,.22);border:1px solid rgba(255,255,255,.08);overflow-wrap:break-word;word-break:break-word;white-space:normal;max-width:100%;box-sizing:border-box;-webkit-user-select:none;user-select:none;-webkit-touch-callout:none;}
.lh-send-word{text-align:center;font-size:28px;font-weight:900;letter-spacing:.08em;color:#ffd166;text-shadow:0 0 14px rgba(255,209,102,.28);padding:16px 10px;border-radius:14px;background:rgba(0,0,0,.22);border:1px solid rgba(255,209,102,.16);}
.lh-signal-desc{font-size:12px;color:var(--text-dim);text-align:center;margin:10px 0 14px;}
.lh-answer-grid{display:grid;grid-template-columns:1fr;gap:8px;}
.lh-answer,.lh-primary,.lh-secondary{border:1px solid rgba(255,255,255,.12);border-radius:12px;background:rgba(255,255,255,.06);color:var(--text);font-weight:800;padding:11px 12px;cursor:pointer;}
.lh-answer:active,.lh-primary:active,.lh-secondary:active,.lh-morse-key:active{transform:scale(.98);}
.lh-primary{width:100%;background:linear-gradient(180deg,#ffd166,#b98526);color:#211704;border-color:rgba(255,209,102,.55);box-shadow:0 0 18px rgba(255,209,102,.16);margin-top:10px;}
.lh-secondary{font-size:12px;color:var(--text-dim);}
.lh-feedback{margin-top:12px;padding:10px 12px;border-radius:12px;background:rgba(76,201,240,.10);border:1px solid rgba(76,201,240,.22);font-size:13px;line-height:1.4;color:var(--text);}
.lh-send-input{min-height:44px;display:flex;align-items:center;justify-content:center;text-align:center;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:20px;font-weight:900;letter-spacing:.06em;color:#fff;border-radius:12px;background:rgba(0,0,0,.25);border:1px solid rgba(255,255,255,.10);padding:10px;margin:10px 0;word-break:break-word;}
.lh-empty{color:var(--text-faint);font-family:inherit;font-size:14px;font-weight:700;}
.lh-morse-key{display:flex;align-items:center;justify-content:center;width:88px;height:88px;margin:10px auto;border-radius:50%;border:1px solid rgba(76,201,240,.42);background:radial-gradient(circle at 35% 30%,rgba(154,208,236,.35),rgba(76,201,240,.12) 45%,rgba(12,20,32,.9));font-size:34px;box-shadow:0 0 28px rgba(76,201,240,.16);color:#fff;touch-action:none;}
.lh-morse-key.pressed{transform:scale(.94);box-shadow:0 0 34px rgba(255,209,102,.22);border-color:rgba(255,209,102,.55);}
.lh-send-actions{display:grid;grid-template-columns:repeat(4,1fr);gap:6px;margin:8px 0;}
.lh-expected{font-size:11px;color:var(--text-faint);text-align:center;margin-top:8px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;}
.lh-active-buff{display:grid;grid-template-columns:auto 1fr;gap:3px 10px;align-items:center;padding:12px 14px;border-radius:14px;background:linear-gradient(180deg,rgba(255,209,102,.12),rgba(76,201,240,.07));border:1px solid rgba(255,209,102,.25);}
.lh-active-buff span{font-size:11px;text-transform:uppercase;letter-spacing:.12em;color:var(--text-dim);grid-column:1/-1;}
.lh-active-buff strong{font-size:18px;color:#ffd166;}
.lh-active-buff em{font-style:normal;color:var(--text);font-size:12px;}
.lh-log-stat{font-size:12px;color:var(--text-dim);margin-bottom:12px;}
.lh-letter-grid{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:14px;}
.lh-letter{font-size:11px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;padding:5px 7px;border-radius:999px;background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.08);color:var(--text-faint);}
.lh-letter.known{color:#fff;border-color:rgba(76,201,240,.35);background:rgba(76,201,240,.10);}
.lh-log-list{display:flex;flex-direction:column;gap:7px;}
.lh-log-row{display:grid;grid-template-columns:74px 1fr;gap:2px 10px;align-items:center;padding:10px 11px;border-radius:12px;background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.08);}
.lh-log-row b{font-size:13px;color:var(--text-faint);}
.lh-log-row span{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;color:var(--text-dim);}
.lh-log-row em{grid-column:2;font-style:normal;font-size:11px;color:var(--text-faint);}
.lh-log-row.known{border-color:rgba(76,201,240,.20);background:rgba(76,201,240,.06);}
.lh-log-row.known b{color:#fff;}

/* ===== Lighthouse charge meter + activate ===== */
.lh-charge{
  background:linear-gradient(180deg, rgba(30,40,55,.6), rgba(18,24,34,.7));
  border:1px solid rgba(140,180,220,.22);
  border-radius:14px;
  padding:14px 16px;
  display:flex; flex-direction:column; gap:10px;
}
.lh-charge-head{ display:flex; justify-content:space-between; font-size:13px; color:rgba(200,220,240,.85); font-weight:600; }
.lh-charge-pct{ font-family:var(--font-mono); color:#ffd87a; }
.lh-charge-bar{ height:10px; border-radius:6px; background:rgba(255,255,255,.08); overflow:hidden; }
.lh-charge-fill{ height:100%; border-radius:6px; background:linear-gradient(90deg,#4cc9f0,#80ed99); transition:width .4s ease; }
.lh-charge-fill.full{ background:linear-gradient(90deg,#ffd166,#ffe066); animation:lhChargeGlow 1.4s ease-in-out infinite; }
@keyframes lhChargeGlow{ 0%,100%{ filter:brightness(1); } 50%{ filter:brightness(1.3); } }
.lh-activate{
  border:none; border-radius:12px; padding:12px; font-weight:800; font-size:15px; cursor:pointer;
  background:rgba(255,255,255,.06); color:rgba(200,220,240,.5);
}
.lh-activate.ready{ background:linear-gradient(180deg,#ffd166,#e6a52e); color:#1a1200; animation:lhChargeGlow 1.4s ease-in-out infinite; }
.lh-activate:active.ready{ transform:scale(.97); }

/* ===== Decode: slots + Wordle keypad ===== */
.lh-decode-slots{ display:flex; gap:8px; justify-content:center; margin:10px 0; flex-wrap:wrap; }
.lh-slot{
  width:34px; height:42px; border-radius:8px; display:flex; align-items:center; justify-content:center;
  font-size:20px; font-weight:800; font-family:var(--font-mono);
  background:rgba(255,255,255,.05); border:1px solid rgba(255,255,255,.12); color:rgba(255,255,255,.3);
}
.lh-slot.filled{ background:rgba(128,237,153,.15); border-color:#80ed99; color:#80ed99; }
.lh-keyboard{ display:grid; grid-template-columns:repeat(7,1fr); gap:5px; margin-top:8px; }
.lh-key{
  padding:10px 0; border-radius:8px; font-weight:700; font-size:14px; font-family:var(--font-mono); cursor:pointer;
  background:rgba(255,255,255,.08); border:1px solid rgba(255,255,255,.14); color:#fff;
  -webkit-user-select:none; user-select:none; -webkit-touch-callout:none;
}
.lh-key:active{ transform:scale(.92); }
.lh-key.correct{ background:rgba(128,237,153,.22); border-color:#80ed99; color:#80ed99; }
.lh-key.wrong{ background:rgba(40,44,52,.6); border-color:rgba(255,255,255,.06); color:rgba(255,255,255,.2); }
.lh-key:disabled{ cursor:default; }
.lh-feedback.ok{ color:#80ed99; font-weight:700; }

/* Decode: active cursor slot + per-letter morse highlight */
.lh-slot.active{ border-color:#ffd166; box-shadow:0 0 8px rgba(255,209,102,.4); color:rgba(255,209,102,.6); }
.lh-morse-code .lh-mc{ opacity:.4; transition:opacity .2s; }
.lh-morse-code .lh-mc.active{ opacity:1; color:#ffd166; font-weight:800; }
.lh-morse-code .lh-mc-sep{ opacity:.25; margin:0 6px; }

/* ===== Lighthouse Learn mode ===== */
.lh-learn-lesson{
  display:flex; flex-direction:column; align-items:center; gap:6px;
  background:rgba(255,209,102,.08); border:1px solid rgba(255,209,102,.3);
  border-radius:14px; padding:18px; margin:6px 0 14px;
}
.lh-learn-letter{ font-size:48px; font-weight:800; color:#ffd87a; line-height:1; }
.lh-learn-morse{ font-family:var(--font-mono); font-size:26px; letter-spacing:4px; color:#ffe066; }
.lh-learn-prog{ font-size:12px; color:rgba(200,220,240,.7); font-family:var(--font-mono); }
.lh-learn-q{ text-align:center; font-size:14px; color:rgba(200,220,240,.85); margin-bottom:8px; }
.lh-learn-keys{ grid-template-columns:repeat(4,1fr); }
.lh-learn-opt{ padding:14px 0; font-size:18px; }

/* Learn: hidden lesson (recall phase) + reveal button */
.lh-learn-lesson.hidden-lesson{ background:rgba(255,255,255,.04); border-color:rgba(255,255,255,.12); }
.lh-learn-lesson.hidden-lesson .lh-learn-letter{ color:rgba(255,255,255,.25); }
.lh-learn-lesson.hidden-lesson .lh-learn-morse{ color:rgba(255,255,255,.2); letter-spacing:6px; }
.lh-reveal{ margin-top:8px; font-size:12px; padding:6px 12px; }

/* ===== Lighthouse Logbook — per-letter level cards ===== */
.lh-letter-cards{
  display:grid; grid-template-columns:repeat(4,1fr); gap:8px; margin:12px 0;
}
.lh-letter-card{
  display:flex; flex-direction:column; align-items:center; gap:5px;
  padding:10px 4px; border-radius:10px;
  background:rgba(255,255,255,.04); border:1px solid rgba(255,255,255,.1);
}
.lh-letter-card.locked{ opacity:.4; }
.lh-letter-card.learning{ border-color:rgba(76,201,240,.4); background:rgba(76,201,240,.08); }
.lh-letter-card.recall{ border-color:rgba(255,209,102,.45); background:rgba(255,209,102,.08); }
.lh-letter-card.mastered{ border-color:rgba(128,237,153,.5); background:rgba(128,237,153,.1); }
.lh-lc-letter{ font-size:22px; font-weight:800; line-height:1; }
.lh-letter-card.mastered .lh-lc-letter{ color:#80ed99; }
.lh-letter-card.recall .lh-lc-letter{ color:#ffd87a; }
.lh-letter-card.learning .lh-lc-letter{ color:#7ad0f0; }
.lh-lc-morse{ font-family:var(--font-mono); font-size:13px; letter-spacing:2px; color:rgba(255,255,255,.6); min-height:16px; }
.lh-lc-pips{ display:flex; gap:3px; }
.lh-pip{ width:9px; height:9px; border-radius:50%; background:rgba(255,255,255,.12); border:1.5px solid transparent; box-sizing:border-box; }
.lh-pip.on{ background:#ffd166; }
.lh-pip.ring{ border-color:#4cc9f0; }
.lh-letter-card.mastered .lh-pip.on{ background:#80ed99; }
.lh-letter-card.mastered .lh-pip.ring{ border-color:#80ed99; }
.lh-log-legend{ display:flex; flex-wrap:wrap; gap:10px; justify-content:center; font-size:11px; color:rgba(200,220,240,.7); margin:8px 0; }
.lh-log-legend span{ display:inline-flex; align-items:center; gap:4px; }
.lh-dot{ width:8px; height:8px; border-radius:50%; }
.lh-dot.mastered{ background:#80ed99; } .lh-dot.recall{ background:#ffd166; }
.lh-dot.learning{ background:#4cc9f0; } .lh-dot.locked{ background:rgba(255,255,255,.2); }
.lh-log-subtitle{ font-size:13px; font-weight:700; color:rgba(200,220,240,.85); margin:12px 0 6px; }
.lh-log-words{ display:flex; flex-wrap:wrap; gap:6px; }
.lh-log-word{ font-family:var(--font-mono); font-size:12px; padding:4px 8px; border-radius:6px; background:rgba(128,237,153,.12); color:#80ed99; }
.lh-log-empty{ font-size:12px; color:rgba(255,255,255,.4); }

/* Decode: post-solve "New signal" — centred, green, glowing call to action */
.lh-new-signal-ready{
  display:block;
  margin:14px auto 0;
  padding:13px 28px;
  border-radius:12px;
  font-weight:800;
  font-size:15px;
  cursor:pointer;
  color:#0c1f12;
  background:linear-gradient(180deg,#80ed99,#4caf6a);
  border:1px solid rgba(128,237,153,.6);
  box-shadow:0 0 16px rgba(128,237,153,.45);
  animation:lhNewSignalGlow 1.4s ease-in-out infinite;
}
.lh-new-signal-ready:active{ transform:scale(.97); }
@keyframes lhNewSignalGlow{
  0%,100%{ box-shadow:0 0 12px rgba(128,237,153,.35); }
  50%    { box-shadow:0 0 22px rgba(128,237,153,.65); }
}

/* Learn keying drill — the letter to tap out */
.lh-learn-target{
  font-size:52px; font-weight:800; text-align:center; color:#ffd87a;
  margin:6px 0 10px; letter-spacing:2px;
}

/* Recognition drill progress line (no lesson card to avoid revealing the answer) */
.lh-learn-prog-top{ text-align:center; font-size:12px; color:rgba(200,220,240,.7); font-family:var(--font-mono); margin-bottom:10px; }

/* Trophy: ever-caught-shiny gets a glowing border + ✨ corner mark */
.trophy-row.shiny-trophy{
  position: relative;
  border: 1px solid rgba(255,224,102,0.55);
  box-shadow: 0 0 12px rgba(255,224,102,0.30), inset 0 0 14px rgba(255,224,102,0.08);
  border-radius: 12px;
}
.trophy-shiny-mark{
  margin-left: auto;
  flex: 0 0 auto;
  align-self: center;
  padding-left: 8px;
  font-size: 14px;
  z-index: 3;
  filter: drop-shadow(0 0 5px rgba(255,224,102,0.95));
  animation: trophyShinyPulse 2.6s ease-in-out infinite;
}
@keyframes trophyShinyPulse {
  0%, 100% { transform: scale(0.8);  opacity: 0.6; }
  50%      { transform: scale(1.15); opacity: 1; }
}
/* Ensure mythical emoji animations run inside fav/leaderboard chips too */
.fav-emoji .myth-anim, .lb-fav-chip .myth-anim{ display:inline-block; }
/* Shiny tiles must NOT stop the mythical emoji's own animation. */
.fav-slot.shiny .myth-beat, .lb-fav-chip.shiny .myth-beat,
.fav-slot.shiny .myth-anim, .lb-fav-chip.shiny .myth-anim{
  animation-play-state: running !important;
}
.fav-slot.shiny .myth-beat, .lb-fav-chip.shiny .myth-beat{
  animation: mythBeat 1.5s ease-in-out infinite !important;
}

/* Mythical animations must survive shiny parent/glow animations in every view. */
.aquarium-fish.shiny .myth-anim,
.fav-slot.shiny .myth-anim,
.lb-fav-chip.shiny .myth-anim,
.trophy-row.shiny-trophy .myth-anim{
  display:inline-block !important;
  animation-play-state: running !important;
}
.aquarium-fish.shiny .myth-beat,
.fav-slot.shiny .myth-beat,
.lb-fav-chip.shiny .myth-beat,
.trophy-row.shiny-trophy .myth-beat{
  animation: mythBeat 1.5s ease-in-out infinite !important;
}


/* Great Whirlpool — diagonal oval orbit with depth
   Scales with the surrounding emoji size so it matches Trophy/Favourites/Leaderboard rows. */
.whirlpool-wrap{
  position:relative;
  display:inline-grid;
  place-items:center;
  width:1.35em;
  height:1.35em;
  line-height:1;
  vertical-align:middle;
  overflow:visible;
  isolation:isolate;
}
.whirlpool-core{
  position:absolute;
  inset:0;
  display:grid;
  place-items:center;
  font-size:1em;
  z-index:3;
  animation:whirlpoolDrift 4s ease-in-out infinite;
  will-change:transform;
}
.whirlpool-orbit{
  position:absolute;
  left:50%;
  top:50%;
  font-size:.42em;
  line-height:1;
  transform-origin:0 0;
  animation:whirlpoolOval 5s linear infinite;
  will-change:transform, opacity;
  pointer-events:none;
}
.whirlpool-orbit.jelly{animation-delay:-2.5s}
@keyframes whirlpoolDrift{
  0%,100%{transform:translateX(-.06em)}
  50%{transform:translateX(.06em)}
}
@keyframes whirlpoolOval{
  0%{
    transform:translate(.48em,-.48em) scale(.75);
    z-index:1;
    opacity:.62;
  }
  25%{
    transform:translate(0em,-.22em) scale(.9);
    z-index:2;
    opacity:.86;
  }
  49%{z-index:4}
  50%{
    transform:translate(-.48em,.48em) scale(1.12);
    z-index:5;
    opacity:1;
  }
  75%{
    transform:translate(0em,.22em) scale(.9);
    z-index:2;
    opacity:.86;
  }
  100%{
    transform:translate(.48em,-.48em) scale(.75);
    z-index:1;
    opacity:.62;
  }
}

/* Listen mode — hear-only Morse identification */
.lh-listen-play{
  display:block;
  width:100%;
  margin:6px auto 14px;
  padding:18px;
  border-radius:14px;
  font-size:18px;
  font-weight:800;
  cursor:pointer;
  color:#0b1f2e;
  background:linear-gradient(180deg,#7fd7ff,#4cc9f0);
  border:1px solid rgba(124,215,255,.6);
  box-shadow:0 0 18px rgba(76,201,240,.4);
  transition:transform .12s;
}
.lh-listen-play:active{ transform:scale(.97); }
.lh-listen-soundoff{
  margin:4px 0 12px;
  padding:10px 12px;
  border-radius:10px;
  font-size:12.5px;
  color:#ffd87a;
  background:rgba(255,200,80,.08);
  border:1px solid rgba(255,200,80,.25);
  text-align:center;
}

/* Beacon charge shown in the header while in the Lighthouse */
.header-beacon{
  font-family: var(--font-mono);
  font-size: 14px;
  font-weight: 800;
  color: #7fd7ff;
  white-space: nowrap;
}
.header-beacon.ready{
  display: inline-block;
  padding: 5px 11px;
  border-radius: 9px;
  color: #07210f;
  background: linear-gradient(180deg,#80ed99,#46b96a);
  border: 1px solid rgba(128,237,153,.6);
  box-shadow: 0 0 12px rgba(128,237,153,.5);
  cursor: pointer;
  animation: harborBadgePulse 1.6s ease-in-out infinite;
}
.header-beacon.ready:active{ transform: scale(.96); }

/* Buff pill is tappable; its emoji pops upward when tapped */
.pill-buff{ cursor: pointer; }
.buff-pop{
  position: fixed;
  transform: translate(-50%, 0);
  font-size: 22px;
  pointer-events: none;
  z-index: 9999;
  animation: buffPop 0.9s ease-out forwards;
  will-change: transform, opacity;
}
@keyframes buffPop {
  0%   { transform: translate(-50%, 0) scale(0.6);   opacity: 0; }
  25%  { transform: translate(-50%, -10px) scale(1.25); opacity: 1; }
  100% { transform: translate(-50%, -64px) scale(1);  opacity: 0; }
}

/* Harbor card upgrade badge — green bubble with the affordable-upgrade count */
.harbor-card{ position: relative; }
.harbor-card-badge{
  position: absolute;
  top: 10px; right: 10px;
  min-width: 24px; height: 24px;
  padding: 0 6px;
  border-radius: 12px;
  background: linear-gradient(180deg,#80ed99,#46b96a);
  color: #07210f;
  font-size: 13px;
  font-weight: 800;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 0 12px rgba(128,237,153,.6);
  z-index: 5;
  animation: harborBadgePulse 2s ease-in-out infinite;
}

@keyframes harborBadgePulse {
  0%,100% { transform: scale(1);    box-shadow: 0 0 8px rgba(128,237,153,.5); }
  50%     { transform: scale(1.12); box-shadow: 0 0 14px rgba(128,237,153,.85); }
}

/* Send / Learn keying — big square tap keys for dot & dash */
.lh-tap-pad{
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:12px;
  margin:12px 0;
}
.lh-tap-key{
  aspect-ratio:1 / 1;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap:6px;
  font-size:44px;
  font-weight:800;
  color:#7fd7ff;
  background:linear-gradient(180deg,rgba(124,215,255,.14),rgba(76,201,240,.06));
  border:1px solid rgba(124,215,255,.4);
  border-radius:18px;
  cursor:pointer;
  transition:transform .1s;
}
.lh-tap-key span{ font-size:14px; font-weight:700; color:var(--text-dim); letter-spacing:.06em; }
.lh-tap-key:active{ transform:scale(.95); background:rgba(124,215,255,.22); }
.lh-tap-clear{ width:100%; margin-bottom:4px; }
.lh-send-actions-2{ grid-template-columns:1fr 1fr; }

/* Header active-signal as small text under the charge */
.header-beacon-wrap{
  display:flex;
  flex-direction:column;
  align-items:flex-end;
  gap:2px;
  line-height:1.15;
}
.header-signal-text{
  font-size:10.5px;
  font-weight:600;
  color:#ffd166;
  white-space:nowrap;
  max-width:60vw;
  overflow:hidden;
  text-overflow:ellipsis;
}

/* Learn keying — compact tap keys so the Check button stays on-screen */
.lh-tap-pad-compact .lh-tap-key{
  aspect-ratio:auto;
  min-height:64px;
  font-size:32px;
  flex-direction:row;
  gap:10px;
}
.lh-tap-pad-compact .lh-tap-key span{ font-size:13px; }

/* Send mode — single press-and-hold Morse key (live straight key) */
.lh-key-press{
  width:100%;
  min-height:140px;
  margin:14px 0;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap:8px;
  border-radius:22px;
  cursor:pointer;
  color:#7fd7ff;
  background:radial-gradient(circle at 50% 40%,rgba(124,215,255,.18),rgba(76,201,240,.06));
  border:2px solid rgba(124,215,255,.4);
  user-select:none;
  -webkit-user-select:none;
  -webkit-touch-callout:none;
  touch-action:none;
  transition:transform .08s,background .08s,border-color .08s,box-shadow .08s;
}
.lh-key-press-icon{ font-size:56px; line-height:1; }
.lh-key-press-hint{ font-size:13px; font-weight:700; color:var(--text-dim); letter-spacing:.06em; }
.lh-key-press.pressing{
  transform:scale(.98);
  background:radial-gradient(circle at 50% 40%,rgba(124,215,255,.4),rgba(76,201,240,.15));
  border-color:rgba(124,215,255,.8);
  box-shadow:0 0 26px rgba(124,215,255,.5);
}
/* Once the hold crosses into dash territory, shift colour to gold so you can
   feel the dot→dash boundary while still pressing. */
.lh-key-press.is-dash{
  color:#ffd166;
  background:radial-gradient(circle at 50% 40%,rgba(255,209,102,.42),rgba(255,180,80,.16));
  border-color:rgba(255,209,102,.85);
  box-shadow:0 0 30px rgba(255,209,102,.55);
}

/* ============ REEF SHOP — boat skins (clean surf-shop vibe) ============ */
.reef-shop{ padding:4px 2px 8px; }
.reef-header{
  text-align:center;
  padding:10px 0 16px;
}
.reef-kicker{
  font-family:var(--font-mono);
  font-size:13px;
  font-weight:800;
  letter-spacing:.22em;
  color:#5ed3c4;
}
.reef-tagline{
  margin-top:5px;
  font-size:14px;
  color:var(--text-dim);
  font-style:italic;
}
.reef-section-label{
  font-size:12px;
  font-weight:800;
  letter-spacing:.06em;
  color:var(--text-dim);
  text-transform:uppercase;
  margin:6px 2px 10px;
}
.reef-grid{
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:12px;
}
.reef-card{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:8px;
  padding:18px 10px 14px;
  border-radius:18px;
  background:linear-gradient(180deg,rgba(94,211,196,.07),rgba(94,211,196,.02));
  border:1px solid rgba(94,211,196,.18);
  transition:border-color .15s,background .15s;
}
.reef-card.active{
  border-color:rgba(94,211,196,.6);
  background:linear-gradient(180deg,rgba(94,211,196,.16),rgba(94,211,196,.05));
  box-shadow:0 0 18px rgba(94,211,196,.2);
}
.reef-emoji{ font-size:52px; line-height:1; }
.reef-name{ font-size:14px; font-weight:700; color:var(--text); }
.reef-buy,.reef-use,.reef-equipped{
  width:100%;
  padding:9px;
  border-radius:11px;
  font-size:14px;
  font-weight:800;
  text-align:center;
  cursor:pointer;
}
.reef-buy{
  font-family:var(--font-mono);
  color:#07271f;
  background:linear-gradient(180deg,#6fe0cf,#3fb5a3);
  border:1px solid rgba(94,211,196,.5);
}
.reef-buy.cant{
  color:var(--text-dim);
  background:rgba(255,255,255,.04);
  border:1px solid rgba(255,255,255,.1);
  cursor:not-allowed;
}
.reef-buy:active:not(.cant){ transform:scale(.97); }
.reef-use{
  color:#5ed3c4;
  background:rgba(94,211,196,.1);
  border:1px solid rgba(94,211,196,.4);
}
.reef-use:active{ transform:scale(.97); }
.reef-equipped{
  color:#5ed3c4;
  background:transparent;
  border:1px solid transparent;
  cursor:default;
}

/* Reef shop — tank expansion block (matches the surf-shop vibe) */
.reef-tank-card{
  padding:16px;
  border-radius:18px;
  background:linear-gradient(180deg,rgba(94,211,196,.09),rgba(94,211,196,.03));
  border:1px solid rgba(94,211,196,.22);
  margin-bottom:18px;
}
.reef-tank-row{
  display:flex;
  align-items:baseline;
  gap:10px;
  margin-bottom:12px;
}
.reef-tank-count{
  font-family:var(--font-mono);
  font-size:26px;
  font-weight:800;
  color:#5ed3c4;
}
.reef-tank-label{ font-size:13px; color:var(--text-dim); }
.reef-tank-buy{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:10px;
}
.reef-tank-price{ font-family:var(--font-mono); }
.reef-tank-max{
  text-align:center;
  font-size:14px;
  font-weight:700;
  color:#5ed3c4;
  padding:6px;
}
.reef-section-boats{ margin-top:4px; }

/* Reef tagline shown under the coins in the header */
.reef-tagline-header{
  color:#5ed3c4 !important;
  font-style:italic;
  font-weight:600;
}

/* ===== Aquarium-style godrays in the water — sunshine / full moon =====
   These are intentionally soft, underwater-looking beams. The light source is
   on the upper-left, so the beams travel diagonally down-right into the water.
   They should be felt more than "read" as hard stripes. */
.cast-godrays {
  position: absolute;
  inset: 38% 0 0 0;          /* water only, starting just under the horizon */
  z-index: 1;
  pointer-events: none;
  overflow: hidden;
  opacity: 0;
  transition: opacity 1.8s ease;
  mix-blend-mode: screen;
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 8%, #000 70%, transparent 100%);
  mask-image: linear-gradient(180deg, transparent 0%, #000 8%, #000 70%, transparent 100%);
}
.cast-area.godray-sun .cast-godrays { opacity: .46; }
.cast-area.godray-moon .cast-godrays { opacity: .24; }

.cast-godray {
  position: absolute;
  top: -10%;
  left: var(--ray-x, 30%);
  width: var(--ray-w, 70px);
  height: 120%;
  /* Sun sits upper-left, so shafts fan down-and-to-the-right (top toward the
     sun, bottom away) — same direction as the boat shadow below. */
  transform: skewX(14deg);
  transform-origin: top center;
  filter: blur(6px);
  opacity: 0.5;
  animation: castGodraySway var(--ray-dur, 12s) ease-in-out infinite;
  animation-delay: var(--ray-delay, 0s);
}

/* Warm gold underwater shafts for sunshine / sunset */
.cast-area.godray-sun .cast-godray {
  background: linear-gradient(180deg,
    rgba(255,228,160,0.18) 0%,
    rgba(255,212,135,0.10) 42%,
    rgba(255,200,110,0.0) 80%);
}

/* Cool silver underwater shafts for the full moon */
.cast-area.godray-moon .cast-godray {
  background: linear-gradient(180deg,
    rgba(205,225,255,0.15) 0%,
    rgba(185,210,250,0.085) 42%,
    rgba(170,200,250,0.0) 80%);
}

@keyframes castGodraySway {
  0%,100% { opacity: 0.28; transform: skewX(14deg) translateX(0); }
  50%     { opacity: 0.58; transform: skewX(11deg) translateX(10px); }
}

/* Soft boat shadow in the water. This is separate from the screen-blended
   light rays because dark colours vanish in screen blend. The shadow leans
   down-right from the boat, matching the upper-left sun/moon direction. */
.cast-boat-shadow {
  position: absolute;
  top: 40%;
  left: 49.5%;
  width: 72px;
  height: 54%;
  transform: rotate(24deg) skewX(-8deg);
  transform-origin: top center;
  background: linear-gradient(180deg,
    rgba(0, 8, 22, 0.18) 0%,
    rgba(0, 8, 22, 0.095) 34%,
    rgba(0, 6, 18, 0.035) 66%,
    rgba(0, 5, 15, 0.0) 100%);
  border-radius: 999px;
  filter: blur(12px);
  opacity: 0;
  pointer-events: none;
  z-index: 2;
  transition: opacity 1.8s ease;
  animation: castBoatShadowDrift 7.5s ease-in-out infinite;
  will-change: transform, opacity;
}
.cast-area.godray-sun .cast-boat-shadow { opacity: .48; }
.cast-area.godray-moon .cast-boat-shadow { opacity: .22; }

@keyframes castBoatShadowDrift {
  0%, 100% { transform: rotate(23deg) skewX(-8deg) translateX(-2px); }
  50%      { transform: rotate(25deg) skewX(-8deg) translateX(2px); }
}

/* ===== Precipitation layer — rain / snow =====
   Rain is clipped to the sky band only; it stops at the horizon. */
.cast-precip {
  position: absolute;
  inset: 0 0 auto 0;
  height: 40%;
  z-index: 2;
  pointer-events: none;
  overflow: hidden;
  opacity: 0;
  transition: opacity 1.2s ease;
  mask-image: linear-gradient(180deg, #000 0%, #000 82%, transparent 100%);
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 82%, transparent 100%);
}
/* Rain: short separated drops, not a full-scene hatch pattern */
.cast-area.weather-rain .cast-precip {
  opacity: .92;
  background-image:
    linear-gradient(112deg, transparent 0 48%, rgba(205,230,255,.34) 48% 52%, transparent 52% 100%),
    linear-gradient(112deg, transparent 0 49%, rgba(205,230,255,.24) 49% 52%, transparent 52% 100%),
    linear-gradient(112deg, transparent 0 49%, rgba(205,230,255,.18) 49% 51%, transparent 51% 100%);
  background-size: 38px 62px, 54px 78px, 72px 92px;
  background-position: 0 0, 18px 0, -28px 0;
  animation: rainFallSky .62s linear infinite;
  filter: blur(.15px);
}
/* Storm: denser, faster drops, still clipped to the sky */
.cast-area.weather-storm .cast-precip {
  opacity: 1;
  background-image:
    linear-gradient(112deg, transparent 0 47%, rgba(220,238,255,.46) 47% 53%, transparent 53% 100%),
    linear-gradient(112deg, transparent 0 49%, rgba(205,226,250,.34) 49% 53%, transparent 53% 100%),
    linear-gradient(112deg, transparent 0 49%, rgba(205,226,250,.24) 49% 52%, transparent 52% 100%);
  background-size: 34px 58px, 48px 70px, 64px 82px;
  background-position: 0 0, 14px 0, -24px 0;
  animation: rainFallStorm .42s linear infinite;
  filter: blur(.1px);
}
/* Seamless loops: every layer shifts by EXACTLY one of its own tiles per
   cycle (x by tile-width leftward, y by tile-height downward), so the loop
   restart is invisible — no more choppy jump. Different tile heights give a
   natural parallax between the three layers. */
@keyframes rainFallSky {
  0%   { background-position: 0 0, 18px 0, -28px 0; }
  100% { background-position: -38px 62px, -36px 78px, -100px 92px; }
}
@keyframes rainFallStorm {
  0%   { background-position: 0 0, 14px 0, -24px 0; }
  100% { background-position: -34px 58px, -34px 70px, -88px 82px; }
}
/* Snow: slow drifting flecks (two layers for depth) */
.cast-area.weather-cold .cast-precip {
  opacity: 1;
  background-image:
    radial-gradient(2px 2px at 20% 10%, rgba(255,255,255,0.9), transparent 60%),
    radial-gradient(2px 2px at 60% 30%, rgba(255,255,255,0.8), transparent 60%),
    radial-gradient(1.5px 1.5px at 40% 50%, rgba(255,255,255,0.85), transparent 60%),
    radial-gradient(2px 2px at 80% 70%, rgba(255,255,255,0.75), transparent 60%),
    radial-gradient(1.5px 1.5px at 10% 80%, rgba(255,255,255,0.8), transparent 60%),
    radial-gradient(2px 2px at 90% 40%, rgba(255,255,255,0.85), transparent 60%);
  background-size: 100% 200%;
  animation: snowFall 8s linear infinite;
}
@keyframes snowFall {
  /* Percentage Y on a 200%-tall image inverts direction (offset = -h × p),
     so falling DOWN needs -200%: one full pattern period per loop, seamless. */
  0%   { background-position: 0 0; }
  100% { background-position: 6px -200%; }
}

/* ===== Lightning flash — occasional during storms ===== */
.cast-lightning {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  opacity: 0;
  background: linear-gradient(180deg, rgba(220,232,255,0.85), rgba(180,200,255,0.2) 60%, transparent);
}
.cast-area.weather-storm .cast-lightning {
  animation: lightningFlash 7s linear infinite;
}
@keyframes lightningFlash {
  0%, 100%   { opacity: 0; }
  1%         { opacity: 0.9; }
  3%         { opacity: 0.1; }
  5%         { opacity: 0.7; }
  8%         { opacity: 0; }
  /* one quick double-flash near the start of each ~7s cycle, dark the rest */
}

/* Gentle whole-frame flash when a fish bites */
.cast-area.bite-flash {
  animation: biteFlash 0.6s ease-out;
}
@keyframes biteFlash {
  0%   { box-shadow: inset 0 0 0 0 rgba(120,195,255,0); border-color: var(--border); }
  30%  { box-shadow: inset 0 0 30px 4px rgba(120,195,255,0.6); border-color: rgba(140,205,255,0.95); }
  100% { box-shadow: inset 0 0 0 0 rgba(120,195,255,0); border-color: var(--border); }
}

/* Workshop material chips — green when you already hold enough of that material */
.up-materials .cost-chip,
.cost-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  border-radius: 6px;
  background: rgba(255,209,102,0.08);
  border: 1px solid rgba(255,209,102,0.18);
  font-size: 11px;
  font-weight: 700;
  color: var(--coin);
  white-space: nowrap;
  margin-right: 5px;
}
.cost-chip.enough {
  background: rgba(128,237,153,0.10);
  border-color: rgba(128,237,153,0.35);
  color: #80ed99;
}
.cost-chip.insufficient {
  background: rgba(255,107,107,0.08);
  border-color: rgba(255,107,107,0.25);
  color: var(--danger);
}

/* Materials stock bar atop the Workshop */
.materials-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 10px 12px;
  margin-bottom: 12px;
  border-radius: 12px;
  background: rgba(255,255,255,0.03);
  border: 1px solid var(--border);
}
.mat-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 700;
  color: var(--text);
}
.mat-chip.mat-zero { opacity: 0.4; }

/* Workshop materials shown in the header (in place of coins) */
.header-mats {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  gap: 3px 8px;
  max-width: 64vw;
  line-height: 1.3;
}
.header-mat {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 700;
  color: var(--text);
  white-space: nowrap;
  padding: 2px 6px;
  border-radius: 7px;
  background: rgba(255,255,255,0.04);
}
.header-mat b { color: var(--text-dim); font-weight: 700; }
.header-mat.mat-zero { opacity: 0.32; }

/* Single Sell All button in the inventory (opens the rarity popup) */
.sell-all-button {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  margin-bottom: 12px;
  border-radius: 14px;
  background: linear-gradient(180deg, rgba(255,209,102,0.10), rgba(255,209,102,0.04));
  border: 1px solid rgba(255,209,102,0.22);
  cursor: pointer;
  transition: transform .1s, background .15s;
}
.sell-all-button:active { transform: scale(.98); }
.sell-all-icon { font-size: 22px; }
.sell-all-label { font-size: 16px; font-weight: 800; color: var(--coin); }
.sell-all-sub { margin-left: auto; font-size: 12px; color: var(--text-dim); }

/* Sell All popup card */
.sellall-card { max-width: 360px; width: 88vw; }
.sellall-rows { margin: 14px 0; display: flex; flex-direction: column; gap: 8px; }
.sellall-rows .sell-all-row { margin: 0; cursor: pointer; }
.sell-all-empty { padding: 20px; color: var(--text-dim); font-size: 14px; text-align: center; }

/* The Sell All popup keeps a near-transparent backdrop so the coin-fly (to the
   money counter up top) and material-fly (to the Harbor tab) stay visible
   behind/around the card. The card itself is centred and short, leaving the
   top money display and bottom tab bar uncovered. */
.sellall-popup { background: rgba(0, 0, 0, 0.18); }

/* ===== Anglerfish — glowing lure dangling in front of the head ===== */
.anglerfish {
  position: relative;
  display: inline-block;
  line-height: 1;
}
.anglerfish .angler-body {
  display: inline-block;
  /* Lit only while the lure glows; goes black in the dark phase. Synced to
     the lure by sharing the same 4s cycle and keyframe timing. */
  animation: anglerBodyFlicker 4s ease-in-out infinite;
}
/* The lure: smaller than the fish, upside-down, hanging off the upper-left
   (in front of the leftward-facing 🐟 head). */
.anglerfish .angler-lure {
  position: absolute;
  left: -0.42em;
  top: -0.34em;
  font-size: 0.55em;          /* smaller than the fish */
  transform: rotate(180deg);   /* hang upside down */
  transform-origin: center;
  animation: anglerLureFlicker 4s ease-in-out infinite;
}
/* The line connecting the fish's head to the lure. A thin rotated bar from
   the head (upper-left of the body) reaching up to the lure. */
.anglerfish .angler-lure::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 100%;                   /* from the lure (which is flipped) toward head */
  width: 1.5px;
  height: 0.5em;
  background: linear-gradient(to bottom, rgba(255,235,150,0.9), rgba(255,235,150,0.3));
  transform: translateX(-50%);
}
/* Lure: glows bright, then goes dark — like a deep-sea lure flashing on and
   off. brightness(0) makes the emoji a black silhouette in the dark phase. */
@keyframes anglerLureFlicker {
  0%, 12%   { filter: brightness(0) drop-shadow(0 0 0 transparent); }      /* off / black */
  22%       { filter: brightness(1.3) drop-shadow(0 0 7px rgba(255,235,150,1)); } /* flash on */
  30%       { filter: brightness(1) drop-shadow(0 0 4px rgba(255,235,150,0.8)); }
  55%       { filter: brightness(1.2) drop-shadow(0 0 9px rgba(255,235,150,1)); }  /* steady glow */
  68%, 100% { filter: brightness(0) drop-shadow(0 0 0 transparent); }      /* fades to black */
}
/* Fish: dark when the lure is off, lit (by the lure) when it glows. Same
   timing as the lure so they breathe together. */
@keyframes anglerBodyFlicker {
  0%, 12%   { filter: brightness(0.06); }                                   /* black in the dark */
  22%       { filter: brightness(1) drop-shadow(0 0 5px rgba(255,235,150,0.5)); }
  55%       { filter: brightness(1) drop-shadow(0 0 4px rgba(255,235,150,0.4)); }
  68%, 100% { filter: brightness(0.06); }                                   /* back to black */
}

/* ===== Ancient Urn event modal ===== */
.urn-card {
  max-width: 380px;
  width: 90vw;
  text-align: center;
  background: linear-gradient(165deg, #1a1230 0%, #0f0a1f 100%);
  border: 1px solid rgba(190, 150, 255, 0.25);
}
.urn-stage {
  position: relative;
  height: 180px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 8px 0 4px;
}
.urn-emoji {
  font-size: 90px;
  line-height: 1;
  user-select: none;
  -webkit-user-select: none;
  cursor: grab;
  touch-action: none;       /* let us track finger drags without scrolling */
  filter: drop-shadow(0 0 16px rgba(190, 150, 255, 0.35));
  transition: transform 0.08s ease;
}
.urn-emoji:active { cursor: grabbing; }
.urn-text {
  font-size: 16px;
  color: #d8c8ff;
  font-style: italic;
  margin: 6px 0 16px;
  min-height: 1.3em;
}
.urn-progress-wrap {
  height: 8px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  overflow: hidden;
  margin: 0 auto 18px;
  max-width: 240px;
}
.urn-progress-bar {
  height: 100%;
  width: 0%;
  border-radius: 999px;
  background: linear-gradient(90deg, #9d7bff, #c9a8ff);
  transition: width 0.12s ease;
}

/* Urn rub → genie reveal */
.urn-puff {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%) scale(0.3);
  font-size: 110px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease, transform 0.5s ease;
}
.urn-puff.show {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1.4);
}
.urn-emoji.urn-burst {
  animation: urnBurst 0.5s ease forwards;
}
@keyframes urnBurst {
  0%   { transform: scale(1); opacity: 1; }
  60%  { transform: scale(1.3) rotate(8deg); opacity: 0.5; }
  100% { transform: scale(0.2); opacity: 0; }
}
.urn-emoji.urn-genie-in {
  animation: urnGenieIn 0.6s cubic-bezier(0.2, 1.4, 0.4, 1) forwards;
  cursor: default;
}
@keyframes urnGenieIn {
  0%   { transform: translateY(20px) scale(0.4); opacity: 0; }
  100% { transform: translateY(0) scale(1); opacity: 1; }
}
.urn-text.urn-greet {
  animation: urnGreetIn 0.5s ease forwards;
  color: #e8dcff;
  font-style: normal;
  font-size: 15px;
  line-height: 1.4;
}
@keyframes urnGreetIn {
  0%   { opacity: 0; transform: translateY(6px); }
  100% { opacity: 1; transform: translateY(0); }
}

/* Urn trivia */
.urn-trivia { margin: 6px 0 16px; }
.urn-q-progress {
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #9d7bff;
  margin-bottom: 8px;
}
.urn-q {
  font-size: 16px;
  color: #f0e8ff;
  font-weight: 600;
  margin-bottom: 14px;
  line-height: 1.35;
}
.urn-answers { display: flex; flex-direction: column; gap: 8px; }
.urn-answer {
  padding: 13px 14px;
  border-radius: 12px;
  border: 1px solid rgba(190, 150, 255, 0.25);
  background: rgba(255, 255, 255, 0.04);
  color: #e8dcff;
  font-size: 15px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}
.urn-answer:active { transform: scale(0.98); }
.urn-answer.locked { pointer-events: none; }
.urn-answer.correct {
  background: rgba(128, 237, 153, 0.18);
  border-color: #80ed99;
  color: #c8ffd6;
}
.urn-answer.wrong {
  background: rgba(241, 91, 181, 0.16);
  border-color: #f15bb5;
  color: #ffc8e6;
}
.urn-score {
  font-size: 14px;
  color: #d8c8ff;
  margin-bottom: 10px;
}
.urn-reward {
  font-size: 19px;
  font-weight: 800;
  color: #ffd166;
  padding: 14px;
  border-radius: 14px;
  background: rgba(255, 209, 102, 0.08);
  border: 1px solid rgba(255, 209, 102, 0.3);
  margin-bottom: 6px;
}
.urn-genie-celebrate { animation: urnGenieCelebrate 1.6s ease-in-out infinite; }
@keyframes urnGenieCelebrate {
  0%, 100% { transform: translateY(0) scale(1); }
  50%      { transform: translateY(-6px) scale(1.06); }
}

.urn-collect { margin-top: 14px; }

/* Reward coloured by its rarity */
.urn-reward.r-epic      { color: var(--epic);      border-color: rgba(157, 78, 221, 0.4);  background: rgba(157, 78, 221, 0.10); }
.urn-reward.r-legendary { color: var(--legendary); border-color: rgba(255, 209, 102, 0.4); background: rgba(255, 209, 102, 0.10); }
.urn-reward.r-mythical  { color: var(--mythical);  border-color: rgba(241, 91, 181, 0.45); background: rgba(241, 91, 181, 0.12); }
.urn-reward-coins { color: var(--coin); }

/* Collect celebration */
.urn-reward-pop { animation: urnRewardPop 0.6s cubic-bezier(0.2, 1.6, 0.4, 1); }
@keyframes urnRewardPop {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.18); }
  100% { transform: scale(1); }
}
.urn-collect-cheer { animation: urnCollectCheer 0.6s ease; }
@keyframes urnCollectCheer {
  0%   { transform: translateY(0) scale(1) rotate(0); }
  35%  { transform: translateY(-12px) scale(1.15) rotate(-6deg); }
  70%  { transform: translateY(-4px) scale(1.05) rotate(5deg); }
  100% { transform: translateY(0) scale(1) rotate(0); }
}
.urn-collect.collecting { opacity: 0.6; }
.urn-sparkle {
  position: fixed;
  font-size: 22px;
  pointer-events: none;
  z-index: 400;
  transform: translate(-50%, -50%);
  animation: urnSparkleFly 0.8s ease-out forwards;
}
@keyframes urnSparkleFly {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(0.3); }
  30%  { opacity: 1; }
  100% { opacity: 0; transform: translate(calc(-50% + var(--sx)), calc(-50% + var(--sy))) scale(1.1); }
}

/* Bait landing pop when a reward bait flies into the tab */
.bait-chip-pop { animation: baitChipPop 0.5s ease; }
@keyframes baitChipPop {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.25); }
}

/* ===== New Voyage (prestige) ===== */
.new-voyage-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  width: 100%;
  padding: 18px 16px;
  margin: 4px 0 18px;
  border-radius: 16px;
  border: 1px solid rgba(255, 209, 102, 0.4);
  background: linear-gradient(160deg, rgba(255,209,102,0.12), rgba(157,78,221,0.10));
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.2s ease;
  animation: voyageGlow 3s ease-in-out infinite;
}
.new-voyage-btn:active { transform: scale(0.98); }
.new-voyage-btn .nv-icon { font-size: 30px; line-height: 1; }
.new-voyage-btn .nv-label {
  font-size: 19px; font-weight: 800; letter-spacing: 0.02em;
  color: #ffd166;
}
.new-voyage-btn .nv-sub { font-size: 12px; color: var(--text-dim); }
@keyframes voyageGlow {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255, 209, 102, 0.0); }
  50%      { box-shadow: 0 0 22px 2px rgba(255, 209, 102, 0.25); }
}

/* Prestige rank badge colours (P1→P5 by rarity) */
.prestige-badge { font-weight: 800; }
.prestige-badge.p1 { color: var(--uncommon); }
.prestige-badge.p2 { color: var(--rare); }
.prestige-badge.p3 { color: var(--epic); }
.prestige-badge.p4 { color: var(--legendary); }
.prestige-badge.p5 { color: var(--mythical); }

/* New Voyage confirmation modal */
.voyage-card { max-width: 400px; width: 92vw; text-align: center; background: linear-gradient(165deg, #0e1a2e 0%, #0a1220 100%); border: 1px solid rgba(120, 195, 255, 0.3); }
.voyage-icon { font-size: 54px; line-height: 1; margin: 4px 0; }
.voyage-title { font-size: 24px; font-weight: 800; color: #ffd166; letter-spacing: 0.02em; margin-bottom: 12px; }
.voyage-desc { font-size: 14px; line-height: 1.6; color: #cfe0f5; margin-bottom: 18px; }
.voyage-desc em { color: #9bd0ff; font-style: italic; }
.voyage-cols { display: flex; gap: 10px; margin-bottom: 16px; }
.voyage-col { flex: 1; padding: 12px; border-radius: 12px; text-align: left; }
.voyage-lose { background: rgba(241, 91, 181, 0.08); border: 1px solid rgba(241, 91, 181, 0.25); }
.voyage-keep { background: rgba(128, 237, 153, 0.08); border: 1px solid rgba(128, 237, 153, 0.25); }
.voyage-col-h { font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 6px; font-weight: 700; }
.voyage-lose .voyage-col-h { color: #f15bb5; }
.voyage-keep .voyage-col-h { color: #80ed99; }
.voyage-col-list { font-size: 12px; line-height: 1.7; color: #c8d4e4; }
.voyage-reward { font-size: 14px; color: #e8dcff; margin-bottom: 16px; padding: 10px; border-radius: 10px; background: rgba(255,209,102,0.08); }
.voyage-confirm-btn { width: 100%; padding: 15px; border-radius: 14px; border: none; background: linear-gradient(135deg, #ffd166, #f4a93c); color: #1a1208; font-size: 17px; font-weight: 800; cursor: pointer; margin-bottom: 8px; transition: transform 0.1s ease; }
.voyage-confirm-btn:active { transform: scale(0.98); }

/* Prestige badge colours reused in the modal/toast */
.voyage-reward b.p1, .voyage-toast-icon.p1 { color: var(--uncommon); }
.voyage-reward b.p2, .voyage-toast-icon.p2 { color: var(--rare); }
.voyage-reward b.p3, .voyage-toast-icon.p3 { color: var(--epic); }
.voyage-reward b.p4, .voyage-toast-icon.p4 { color: var(--legendary); }
.voyage-reward b.p5, .voyage-toast-icon.p5 { color: var(--mythical); }

/* New Voyage toast */
.voyage-toast { position: fixed; top: 18%; left: 50%; transform: translateX(-50%) translateY(-20px); z-index: 400; background: rgba(10, 18, 32, 0.95); border: 1px solid rgba(120,195,255,0.35); border-radius: 16px; padding: 20px 28px; text-align: center; color: #cfe0f5; font-size: 15px; opacity: 0; transition: opacity 0.4s ease, transform 0.4s ease; pointer-events: none; }
.voyage-toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
.voyage-toast-icon { font-size: 40px; font-weight: 800; margin-bottom: 6px; }

/* Rarity glow on upgrade tier rows (Shop + Workshop) — left accent + soft halo
   in the tier's rarity colour, so each upgrade row reads common→mythical. */
.tier-glow { border-left: 2px solid transparent; }
.tier-glow.r-common    { border-left-color: rgba(255,255,255,0.35); box-shadow: -3px 0 12px -6px rgba(255,255,255,0.40); }
.tier-glow.r-uncommon  { border-left-color: var(--uncommon);  box-shadow: -3px 0 14px -6px rgba(128,237,153,0.55); }
.tier-glow.r-rare      { border-left-color: var(--rare);      box-shadow: -3px 0 14px -6px rgba(76,201,240,0.55); }
.tier-glow.r-epic      { border-left-color: var(--epic);      box-shadow: -3px 0 16px -6px rgba(157,78,221,0.60); }
.tier-glow.r-legendary { border-left-color: var(--legendary); box-shadow: -3px 0 18px -5px rgba(255,209,102,0.65); }
.tier-glow.r-mythical  { border-left-color: var(--mythical);  box-shadow: -3px 0 20px -5px rgba(241,91,181,0.70); }

/* ===== Tier re-select strip (collapsed behind "Change gear") ===== */
.tier-selector { margin-top: 8px; }
.gear-toggle {
  background: none; border: none; padding: 4px 2px; cursor: pointer;
  font-size: 12px; color: var(--text-dim); letter-spacing: 0.02em;
  display: inline-flex; align-items: center; gap: 5px;
}
.gear-toggle:active { transform: scale(0.97); }
.gear-toggle.open { color: var(--text); }
.gear-chevron { font-size: 10px; opacity: 0.8; }
/* Pills are always in the DOM; the wrap collapses via CSS for a smooth toggle */
.tier-pills-wrap { max-height: 0; opacity: 0; overflow: hidden; transition: max-height 0.28s ease, opacity 0.2s ease; }
.tier-selector.open .tier-pills-wrap { max-height: 260px; opacity: 1; }
.tier-pills { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; padding-top: 8px; border-top: 1px dashed rgba(255,255,255,0.08); }
.tier-pill {
  font-size: 12px; font-weight: 600; padding: 6px 10px; border-radius: 999px;
  border: 1px solid rgba(255,255,255,0.14); background: rgba(255,255,255,0.04);
  color: var(--text-dim); cursor: pointer; transition: transform 0.1s ease, background 0.15s ease, border-color 0.15s ease;
}
.tier-pill:active { transform: scale(0.96); }
/* Inactive pills tint their text by rarity (subtle) */
.tier-pill.r-common    { color: rgba(255,255,255,0.7); }
.tier-pill.r-uncommon  { color: var(--uncommon); }
.tier-pill.r-rare      { color: var(--rare); }
.tier-pill.r-epic      { color: var(--epic); }
.tier-pill.r-legendary { color: var(--legendary); }
.tier-pill.r-mythical  { color: var(--mythical); }
/* Active pill: filled with its rarity colour + glow */
.tier-pill.active { color: #0a1018; font-weight: 800; border-color: transparent; }
.tier-pill.active.r-common    { background: #e8eef5; }
.tier-pill.active.r-uncommon  { background: var(--uncommon); box-shadow: 0 0 12px -2px rgba(128,237,153,0.6); }
.tier-pill.active.r-rare      { background: var(--rare);      box-shadow: 0 0 12px -2px rgba(76,201,240,0.6); }
.tier-pill.active.r-epic      { background: var(--epic);      box-shadow: 0 0 12px -2px rgba(157,78,221,0.6); color: #fff; }
.tier-pill.active.r-legendary { background: var(--legendary); box-shadow: 0 0 12px -2px rgba(255,209,102,0.65); }
.tier-pill.active.r-mythical  { background: var(--mythical);  box-shadow: 0 0 12px -2px rgba(241,91,181,0.65); color: #fff; }

/* New Voyage card: requirement progress + locked/ready states */
.new-voyage-btn .nv-target { font-size: 14px; opacity: 0.85; }
.new-voyage-btn .nv-reqs { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 14px; margin-top: 8px; }
.new-voyage-btn .nv-req {
  font-size: 12px; color: var(--text-dim);
  font-variant-numeric: tabular-nums; padding: 2px 8px; border-radius: 999px;
  background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.08);
}
.new-voyage-btn .nv-req.met { color: var(--uncommon); border-color: rgba(128,237,153,0.35); background: rgba(128,237,153,0.08); }
/* Locked: dimmed, no glow, not inviting a tap */
.new-voyage-btn.locked { animation: none; opacity: 0.82; cursor: default; border-color: rgba(255,255,255,0.1); background: rgba(255,255,255,0.03); }
.new-voyage-btn.locked .nv-label { color: var(--text); }
/* Ready: keep the gold glow from the base rule */
.new-voyage-btn.ready { }

/* Requirement line inside the confirm modal */
.voyage-req-line { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-bottom: 14px; }
.voyage-req-line .nv-req { font-size: 12px; color: var(--uncommon); padding: 3px 10px; border-radius: 999px; background: rgba(128,237,153,0.08); border: 1px solid rgba(128,237,153,0.3); font-variant-numeric: tabular-nums; }

/* Challenger Deep mythical — giant, slow, radiant aura */
.dive-target.challenger-mythical {
  filter: drop-shadow(0 0 14px rgba(var(--rarity-rgb,241,91,181), 0.9))
          drop-shadow(0 0 34px rgba(var(--rarity-rgb,241,91,181), 0.6));
  animation: challengerPulse 2.4s ease-in-out infinite;
  z-index: 5;
}
/* The pink halo BACKGROUND disc — same treatment mythicals get elsewhere.
   A real radial background (not a filter) so iOS renders it reliably even
   while the species animation runs on the inner span. */
.dive-target.challenger-mythical::before {
  content: '';
  position: absolute;
  inset: -38%;
  border-radius: 50%;
  background: radial-gradient(circle,
    rgba(241,91,181,0.50) 0%,
    rgba(241,91,181,0.26) 42%,
    rgba(241,91,181,0.10) 62%,
    transparent 72%);
  z-index: -1;
  animation: challengerHalo 2.4s ease-in-out infinite;
  pointer-events: none;
}
@keyframes challengerHalo {
  0%, 100% { opacity: 0.75; transform: scale(1); }
  50%      { opacity: 1;    transform: scale(1.16); }
}
@keyframes challengerPulse {
  0%, 100% { filter: drop-shadow(0 0 14px rgba(var(--rarity-rgb,241,91,181), 0.85)) drop-shadow(0 0 30px rgba(var(--rarity-rgb,241,91,181), 0.5)); }
  50%      { filter: drop-shadow(0 0 22px rgba(var(--rarity-rgb,241,91,181), 1)) drop-shadow(0 0 50px rgba(var(--rarity-rgb,241,91,181), 0.75)); }
}
/* Bomb that fizzles out on its own (no damage) — gentle puff, not a red blast */
.dive-target.fizzled { animation: bombFizzle 0.36s ease-out forwards; }
@keyframes bombFizzle {
  0%   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.4); }
}

/* Challenger Deep victory banner (shown 4s before rewards) */
.dive-success-banner {
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%) scale(0.9);
  text-align: center; z-index: 30; pointer-events: none;
  opacity: 0; transition: opacity 0.5s ease, transform 0.5s ease;
  width: 86%; max-width: 420px;
}
.dive-success-banner.show { opacity: 1; transform: translate(-50%, -50%) scale(1); }
.dive-success-banner .dsb-title {
  font-size: 24px; font-weight: 800; color: #f15bb5;
  text-shadow: 0 0 18px rgba(241,91,181,0.7); margin-bottom: 10px; letter-spacing: 0.02em;
}
.dive-success-banner .dsb-sub { font-size: 14px; line-height: 1.6; color: #cfe0f5; }

/* ===== 🎬 Dive Transition (Start Dive → submerge; dive end → surface) ===== */
/* Fullscreen sweep layer (above the dive overlay's z-index:200, below popups) */
.dive-transition {
  position: fixed; inset: 0; z-index: 400;
  pointer-events: none; opacity: 0;
  transition: opacity 0.6s ease-in-out;
  background-size: 100% 130%;
  background-repeat: no-repeat;
}
.dive-transition.show { opacity: 1; }
/* The gradient drifts vertically while visible, so the sweep feels like
   moving THROUGH water rather than a flat fade. */
.dive-transition.submerge {
  background-image: linear-gradient(180deg, rgba(14,125,160,0.25) 0%, #085f80 38%, #06182f 72%, #030c1c 100%);
}
.dive-transition.submerge.show { animation: dtDriftDown 1.7s ease-in-out forwards; }
.dive-transition.surface {
  background-image: linear-gradient(0deg, rgba(3,12,28,0.9) 0%, rgba(26,163,200,0.55) 55%, rgba(235,250,255,0.35) 100%);
}
.dive-transition.surface.show { animation: dtDriftUp 1.7s ease-in-out forwards; }
@keyframes dtDriftDown {
  from { background-position: 50% -14%; }
  to   { background-position: 50% 114%; }
}
@keyframes dtDriftUp {
  from { background-position: 50% 114%; }
  to   { background-position: 50% -14%; }
}
.dt-bubble {
  position: absolute; bottom: -36px;
  opacity: 0;
  animation: dtBubbleRise 1.6s cubic-bezier(.3,.1,.4,1) forwards;
  filter: drop-shadow(0 0 6px rgba(180,230,255,0.5));
}
@keyframes dtBubbleRise {
  0%   { transform: translateY(0) translateX(0) scale(0.8); opacity: 0; }
  14%  { opacity: 0.9; }
  55%  { transform: translateY(-44vh) translateX(7px) scale(1.05); }
  100% { transform: translateY(-82vh) translateX(-5px) scale(1.18); opacity: 0; }
}

/* 🎬 Ripple submerge: the dive grows out of the Start Dive button as a fast
   expanding circle. Opacity snaps on; the reveal is the clip-path itself. */
.dive-transition.ripple {
  transition: clip-path 0.55s cubic-bezier(.3,0,.25,1), opacity 0.45s ease;
  background-size: 100% 100%;
}
.dive-transition.ripple.show { opacity: 1; }

/* 🎬 HUD entrance after the ripple: staggered slide+fade in. The depth gauge
   and hint are centered via translateX(-50%), so the keyframes must keep it. */
.dive-overlay.hud-enter .dive-hud-corner-tr { animation: hudIn 0.45s cubic-bezier(.2,.7,.3,1) 0.35s backwards; }
.dive-overlay.hud-enter .dive-depth-center  { animation: hudInCentered 0.45s cubic-bezier(.2,.7,.3,1) 0.5s backwards; }
.dive-overlay.hud-enter .dive-hud-hint      { animation: hudInUpCentered 0.45s cubic-bezier(.2,.7,.3,1) 0.65s backwards; }
@keyframes hudIn {
  from { opacity: 0; transform: translateY(-10px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes hudInCentered {
  from { opacity: 0; transform: translateX(-50%) translateY(-10px); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0); }
}
@keyframes hudInUpCentered {
  from { opacity: 0; transform: translateX(-50%) translateY(12px); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0); }
}

/* Sell All: sold-out rows stay in place (fixed layout) — dimmed, inert */
.sell-all-row.sold-out {
  opacity: 0.38;
  pointer-events: none;
  filter: saturate(0.4);
}
.sell-all-row.sold-out .right { color: var(--uncommon); font-size: 12px; }

/* 🖐 Dive handedness toggle (below Start Dive) */
.dive-hand-toggle {
  display: block; margin: 10px auto 0; padding: 6px 14px;
  background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.12);
  border-radius: 999px; color: var(--text-dim); font-size: 12px; cursor: pointer;
}
.dive-hand-toggle b { color: var(--text); }
.dive-hand-toggle:active { transform: scale(0.97); }
.dive-hand-hint { display: block; font-size: 10px; opacity: 0.7; margin-top: 2px; }

/* 🕸️ Net pill states */
.pill-net { cursor: pointer; font-variant-numeric: tabular-nums; }
.pill-net.idle { opacity: 0.55; }
.pill-net.full { color: var(--uncommon); border-color: rgba(128,237,153,0.4); animation: netFullPulse 1.4s ease-in-out infinite; }
.pill-net.warn { color: #ffb347; border-color: rgba(255,179,71,0.4); }
@keyframes netFullPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(128,237,153,0); }
  50%      { box-shadow: 0 0 10px 1px rgba(128,237,153,0.35); }
}
/* 🕸️ Net modals — NOT the treasure chest. They follow the game's core
   neutral surface language (same tokens as .modal-inner / .modal-title /
   .modal-sub): --bg-elev card, --border, body font, --text/--text-dim.
   Rows step up the game's own elevation ladder (bg-elev → bg-elev-2). */
.net-deploy-row { cursor: pointer; }
.net-modal .chest-modal-card {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.7);
}
.net-modal .chest-modal-title {
  font-family: var(--font-body);
  font-size: 19px;
  color: var(--text);
  letter-spacing: 0;
}
.net-modal .chest-modal-sub {
  font-family: var(--font-body);
  font-size: 12px;
  color: var(--text-dim);
  line-height: 1.5;
}
.net-modal .sell-all-row { background: var(--bg-elev-2); }

/* 🌦️ Test weather row value */
.weather-test-value { font-size: 12px; color: var(--text-dim); font-family: var(--font-mono); white-space: nowrap; }

/* 🕸️ Net haul chips — itemised rewards that fly to their destination */
.net-haul-grid {
  display: flex; flex-wrap: wrap; gap: 6px;
  justify-content: center; margin: 4px 0 14px;
  max-height: 40vh; overflow-y: auto;
}
/* Chips use the same neutral tokens as inventory rows: --bg-elev-2 surface,
   --border edge; materials keep the game's --ok green, trash dims. */
.net-haul-chip {
  display: flex; align-items: center; gap: 6px;
  padding: 6px 10px; border-radius: 999px;
  background: var(--bg-elev-2);
  border: 1px solid var(--border);
  font-size: 12px;
}
.net-haul-chip.is-trash { opacity: 0.7; }
.net-haul-chip.is-material { border-color: rgba(128, 237, 153, 0.3); }
.net-haul-chip .chip-emoji { font-size: 16px; }
.net-haul-chip .chip-name { color: var(--text); font-weight: 600; }
.net-haul-chip .chip-count { color: var(--text-dim); font-weight: 700; font-family: var(--font-mono); }

/* ===== 📡 Ranks switch + feed list ===== */
.ranks-switch {
  display: flex; gap: 8px; padding: 10px 16px 6px;
}
.ranks-tab {
  flex: 1; padding: 9px 0; border-radius: 10px;
  background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.08);
  color: var(--text-dim); font-size: 13px; font-weight: 600; cursor: pointer;
  font-family: inherit; transition: background 0.2s ease, color 0.2s ease;
}
.ranks-tab.active {
  background: linear-gradient(135deg, #1f5c7a 0%, #2f7fa0 100%);
  color: #fff; border-color: rgba(120,195,255,0.35);
}
.feed-list { display: flex; flex-direction: column; gap: 8px; padding-top: 4px; }
.feed-row {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 11px 12px; border-radius: 12px;
  background: rgba(255,255,255,0.035);
  border: 1px solid rgba(255,255,255,0.07);
}
/* Feed borders by news type — each rarity reads at a glance */
.feed-row.feed-record {
  border-color: rgba(255,255,255,0.1);
}
.feed-row.feed-legendary {
  border-color: rgba(255,190,40,0.7);
  box-shadow: 0 0 10px rgba(255,190,40,0.25);
}
.feed-row.feed-mythical {
  border-color: rgba(200,90,230,0.75);
  box-shadow: 0 0 12px rgba(200,90,230,0.3);
}
.feed-row.feed-prestige {
  border-color: rgba(120,195,255,0.6);
  box-shadow: 0 0 8px rgba(120,195,255,0.18);
}
/* Daily — same green palette as the "Daily 🎯" pill, for a consistent look. */
.feed-row.feed-daily {
  background: rgba(128, 237, 153, 0.10);
  border-color: rgba(128, 237, 153, 0.35);
}
/* Shiny — pulsing yellow */
.feed-row.feed-shiny {
  border-color: rgba(255,225,90,0.7);
  animation: feedShinyPulse 1.8s ease-in-out infinite;
}
@keyframes feedShinyPulse {
  0%, 100% { border-color: rgba(255,225,90,0.4); box-shadow: 0 0 5px rgba(255,225,90,0.2); }
  50%      { border-color: rgba(255,235,140,0.95); box-shadow: 0 0 16px rgba(255,225,90,0.55); }
}
.feed-icon { font-size: 18px; line-height: 1.3; }
.feed-main { flex: 1; min-width: 0; }
.feed-line { font-size: 13px; line-height: 1.45; color: var(--text); }
.feed-line b { color: #fff; }
.feed-sub { font-size: 11px; color: var(--text-dim); margin-top: 2px; }
.feed-time { font-size: 10px; color: var(--text-dim); font-family: var(--font-mono); white-space: nowrap; padding-top: 2px; }

/* 📡 Feed reactions */
.feed-react-bar { display: flex; gap: 6px; margin-top: 7px; }
.feed-react {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 3px 8px; border-radius: 999px;
  background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.08);
  font-size: 13px; cursor: pointer; font-family: inherit;
  transition: transform 0.12s ease, border-color 0.2s ease;
}
.feed-react:active { transform: scale(1.15); }
.feed-react.mine {
  border-color: rgba(120,195,255,0.55);
  background: rgba(47,127,160,0.25);
}
.feed-react-n { font-size: 11px; color: var(--text-dim); font-family: var(--font-mono); }
.feed-react.mine .feed-react-n { color: #bfe3ff; }

/* 📡 Feed v2: "+" opener, labelled picker, who-reacted expand, shiny text */
.feed-react-add { color: var(--text-dim); font-weight: 700; min-width: 30px; justify-content: center; }
.feed-picker {
  display: flex; flex-direction: column; gap: 4px;
  margin-top: 6px; padding: 8px;
  background: rgba(10, 18, 32, 0.92);
  border: 1px solid rgba(120,195,255,0.25); border-radius: 12px;
}
.feed-picker-row {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 10px; border-radius: 8px; text-align: left;
  background: transparent; border: none; cursor: pointer;
  color: var(--text); font-size: 14px; font-family: inherit;
}
.feed-picker-row span { font-size: 12px; color: var(--text-dim); }
.feed-picker-row:active, .feed-picker-row.mine { background: rgba(47,127,160,0.3); }
.feed-who {
  margin-top: 7px; padding: 8px 10px;
  background: rgba(255,255,255,0.03);
  border-left: 2px solid rgba(120,195,255,0.3); border-radius: 0 8px 8px 0;
}
.feed-who-line { font-size: 12px; color: var(--text); line-height: 1.6; }
.feed-who-line b { color: var(--text-dim); font-weight: 600; font-size: 11px; }
.feed-who-line.dim { color: var(--text-dim); }
.feed-shiny { color: #bfe9ff; text-shadow: 0 0 6px rgba(150,220,255,0.6); }
.feed-row { cursor: pointer; }

/* 🕸️ Net pill "new feature" glow — idle or full (actionable), white */
.pill-net.net-glow {
  border-color: rgba(255,255,255,0.35);
  box-shadow: 0 0 5px rgba(255,255,255,0.3);
}
.pill-net.net-glow.net-new {
  animation: netNewGlow 1.6s ease-in-out infinite;
}
@keyframes netNewGlow {
  0%, 100% { box-shadow: 0 0 4px 0 rgba(255,255,255,0.45); border-color: rgba(255,255,255,0.5); }
  50%      { box-shadow: 0 0 14px 2px rgba(255,255,255,0.85); border-color: rgba(255,255,255,0.95); }
}


/* 🔥 Streak bonus celebration — streak line + stacked-bonus row */
.bonus-label .bonus-streak {
  font-size: 13px; font-weight: 800; letter-spacing: 1px;
  color: #ffb347; text-shadow: 0 0 8px rgba(255,140,60,0.7);
  margin-bottom: 2px;
}
.bonus-label .bonus-main { font-size: inherit; }
.bonus-label .bonus-stack {
  font-size: 14px; margin-top: 4px; letter-spacing: 2px;
  color: #fff; text-shadow: 0 0 6px rgba(255,255,255,0.5);
}
/* All three stacked — make it ERUPT */
.bonus-label.bonus-label-max {
  animation: bonusMaxPop 0.5s cubic-bezier(.2,1.4,.4,1) both;
}
.bonus-label.bonus-label-max .bonus-streak {
  color: #ffd166; text-shadow: 0 0 14px rgba(255,200,60,0.95);
}
@keyframes bonusMaxPop {
  0%   { transform: translate(-50%, -50%) scale(0.4); opacity: 0; }
  60%  { transform: translate(-50%, -50%) scale(1.25); opacity: 1; }
  100% { transform: translate(-50%, -50%) scale(1); opacity: 1; }
}

/* 📡 Ranks pull-to-refresh hint */
.ranks-refresh-hint {
  text-align: center;
  font-size: 11px;
  color: var(--text-dim);
  padding: 8px 0 4px;
  font-family: var(--font-mono);
  opacity: 0.8;
}

/* 🗼 Beacon fully charged but locked — a buff is still live, use it up first */
.header-beacon.charged-locked {
  opacity: 0.55;
  font-style: italic;
}

/* 🛸 Unknown Craft — UFO abducting a tiny cow in a tractor beam */
.ufo-craft {
  position: relative;
  display: inline-block;
}
.ufo-body {
  display: inline-block;
  animation: ufoHover 2.2s ease-in-out infinite;
}
.ufo-cow {
  position: absolute;
  left: 50%;
  top: 92%;
  transform: translateX(-50%);
  font-size: 0.36em;            /* small — beamed from afar */
  filter: drop-shadow(0 0 4px rgba(120,235,170,0.9));
  animation: ufoBeamCow 2.2s ease-in-out infinite;
}
/* The tractor beam glow between saucer and cow */
.ufo-cow::before {
  content: '';
  position: absolute;
  left: 50%;
  bottom: 100%;
  transform: translateX(-50%);
  width: 0; height: 0;
  border-left: 0.7em solid transparent;
  border-right: 0.7em solid transparent;
  border-bottom: 1.4em solid rgba(140,240,180,0.22);
  animation: ufoBeamPulse 2.2s ease-in-out infinite;
}
@keyframes ufoHover {
  0%, 100% { transform: translateY(0) rotate(-2deg); }
  50%      { transform: translateY(-4px) rotate(2deg); }
}
@keyframes ufoBeamCow {
  0%, 100% { transform: translateX(-50%) translateY(0); opacity: 0.9; }
  50%      { transform: translateX(-50%) translateY(-3px); opacity: 1; }
}
@keyframes ufoBeamPulse {
  0%, 100% { opacity: 0.5; }
  50%      { opacity: 0.85; }
}

/* 🦑 Kraken — a tiny ship above being dragged down into the deep */
.kraken-myth {
  position: relative;
  display: inline-block;
}
.kraken-body {
  display: inline-block;
}
.kraken-ship {
  position: absolute;
  left: 50%;
  bottom: 86%;
  transform: translateX(-50%);
  font-size: 0.34em;            /* small — a doomed little boat */
  filter: drop-shadow(0 0 3px rgba(0,0,0,0.4));
  animation: krakenDragShip 2.6s ease-in-out infinite;
}
@keyframes krakenDragShip {
  0%      { transform: translateX(-50%) translateY(-2px) rotate(-12deg); opacity: 1; }
  50%     { transform: translateX(-50%) translateY(3px) rotate(10deg); opacity: 0.95; }
  100%    { transform: translateX(-50%) translateY(-2px) rotate(-12deg); opacity: 1; }
}

/* 🧽 Square Sponge — little bubbles rising around it (SpongeBob nod) */
.sponge-myth {
  position: relative;
  display: inline-block;
}
.sponge-body { display: inline-block; }
.sponge-bubble {
  position: absolute;
  font-size: 0.3em;
  opacity: 0;
  pointer-events: none;
  bottom: 40%;
}
.sponge-bubble.b1 { left: 8%;  animation: spongeBubble 2.4s ease-in infinite; }
.sponge-bubble.b2 { left: 62%; animation: spongeBubble 2.8s ease-in 0.7s infinite; }
.sponge-bubble.b3 { left: 38%; animation: spongeBubble 2.2s ease-in 1.4s infinite; }
@keyframes spongeBubble {
  0%   { transform: translateY(0) scale(0.6); opacity: 0; }
  20%  { opacity: 0.9; }
  100% { transform: translateY(-140%) scale(1); opacity: 0; }
}

/* 👻 Ghost Captain — a ghost, so it phases between solid and translucent */
.ghost-phase {
  display: inline-block;
  animation: ghostPhase 3.2s ease-in-out infinite;
}
@keyframes ghostPhase {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.3; }
}

/* 🕸️ Soaking net pill — the BORDER fills clockwise with time (--net-fill deg).
   A conic-gradient ring drawn via a mask so only the border area shows. */
.pill-net.soaking {
  position: relative;
  border-color: transparent;
}
.pill-net.soaking::after {
  content: '';
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  padding: 1.5px;
  background: conic-gradient(
    rgba(128,237,153,0.95) var(--net-fill, 0deg),
    rgba(255,255,255,0.12) var(--net-fill, 0deg)
  );
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  pointer-events: none;
}

/* 🫧 Dive oxygen readout flashes red when air is running low (≤8s) */
#dive-lives.low-air { color: #ff6b6b; animation: lowAirPulse 0.9s ease-in-out infinite; }
@keyframes lowAirPulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }

/* ===== 🏆 Achievement unlock pop-up (slides down from top, auto-dismisses) ===== */
.achievement-popup {
  position: fixed; top: 0; left: 50%;
  transform: translate(-50%, -160%);
  z-index: 2000;
  display: flex; align-items: center; gap: 12px;
  background: linear-gradient(135deg, #1a2740, #0f1822);
  border: 1px solid rgba(128,237,153,0.4);
  border-radius: 14px;
  padding: 12px 18px;
  /* push below the status bar / notch (safe-area), with a comfortable gap */
  margin-top: calc(env(safe-area-inset-top, 0px) + 54px);
  box-shadow: 0 12px 40px rgba(0,0,0,0.55), 0 0 22px rgba(128,237,153,0.25);
  max-width: 88vw;
  opacity: 0;
  transition: transform 0.45s cubic-bezier(0.2,0.9,0.3,1.2), opacity 0.45s ease;
  pointer-events: none;
}
.achievement-popup.show { transform: translate(-50%, 0); opacity: 1; }
.achievement-popup.anti { border-color: rgba(241,91,181,0.45); box-shadow: 0 12px 40px rgba(0,0,0,0.55), 0 0 22px rgba(241,91,181,0.25); }
.ach-pop-icon { font-size: 30px; line-height: 1; }
.ach-pop-text { display: flex; flex-direction: column; gap: 2px; }
.ach-pop-label { font-size: 11px; color: #80ed99; font-family: ui-monospace, monospace; text-transform: uppercase; letter-spacing: 0.5px; }
.achievement-popup.anti .ach-pop-label { color: #f15bb5; }
.ach-pop-name { font-size: 15px; font-weight: 700; color: #eaf2f8; }

/* ===== 🎖️ Trophies sub-switch (Trophy Wall ↔ Achievements) ===== */
.trophy-switch { display: flex; gap: 8px; padding: 4px 0 10px; }
.trophy-tab {
  flex: 1; padding: 9px 0; border-radius: 10px;
  background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.08);
  color: var(--text-dim); font-size: 13px; font-weight: 600; cursor: pointer;
  font-family: inherit; transition: background 0.2s ease, color 0.2s ease;
}
.trophy-tab.active {
  background: linear-gradient(135deg, #8a6d1f 0%, #b8902f 100%);
  color: #fff; border-color: rgba(255,210,120,0.35);
}

/* ===== Achievements list ===== */
.ach-progress { text-align: center; font-family: ui-monospace, monospace; font-size: 13px; color: #cfe0ec; font-weight: 700; padding: 6px 0 12px; }
.ach-empty { text-align: center; color: var(--text-dim); padding: 30px; }
.ach-cat { margin-bottom: 18px; }
.ach-cat-head { font-size: 13px; font-weight: 700; color: #eaf2f8; margin-bottom: 8px; display: flex; align-items: center; gap: 6px; }
.ach-cat-icon { font-size: 15px; }
.ach-cat-count { margin-left: auto; font-family: ui-monospace, monospace; font-size: 12px; color: var(--text-dim); font-weight: 600; }
.ach-grid { display: flex; flex-direction: column; gap: 8px; }
.ach-item {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 13px; border-radius: 12px;
  background: rgba(255,255,255,0.035);
  border: 1px solid rgba(255,255,255,0.06);
  position: relative;
}
.ach-item.got { border-color: rgba(255,210,120,0.30); background: rgba(184,144,47,0.10); }
.ach-item.got.anti { border-color: rgba(241,91,181,0.35); background: rgba(241,91,181,0.08); }
.ach-item.locked { opacity: 0.55; }
.ach-item-icon { font-size: 24px; line-height: 1; width: 30px; text-align: center; }
.ach-item.locked .ach-item-icon { filter: grayscale(1); opacity: 0.7; }
.ach-item-text { flex: 1; min-width: 0; }
.ach-item-name { font-size: 14px; font-weight: 700; color: #eaf2f8; }
.ach-item-desc { font-size: 12px; color: var(--text-dim); margin-top: 2px; }
.ach-item-check { color: #ffd278; font-size: 16px; font-weight: 800; }
.ach-item.anti .ach-item-check { color: #f15bb5; }

/* 🚫 iOS: never show the text magnifier/loupe or selection on tappable controls.
   The loupe pops on long-press (e.g. holding the Morse key, dive hold) — kill it
   globally on buttons and the interactive game surfaces. */
button, .lh-key-press, .dive-hitbox, .dive-overlay, .tab, [data-recycle-idx], [role="button"] {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}

/* ===== 🐳 Ambient wildlife in the cast-area water (decorative, no interaction) ===== */
/* Sits below the boat/UI but over the water gradient. Silhouettes = darkened
   emoji with depth-based opacity (deeper = fainter). */
.cast-wildlife {
  position: absolute; left: 0; right: 0; top: 0; bottom: 0;
  overflow: hidden; pointer-events: none; z-index: 2;
}
.wl-creature {
  position: absolute;
  /* Silhouette: crush the emoji to a dark shape. The container opacity sets
     how visible it is by depth. */
  filter: brightness(0) saturate(0);
  will-change: transform;
  user-select: none; -webkit-user-select: none;
}
/* Flip horizontally when swimming right-to-left so it never faces "backwards". */
.wl-creature.wl-flip { transform: scaleX(-1); }

/* Cross-swimmers (whale, octopus, dolphin) drift fully across and out. The
   translateX distances are generous so they fully clear the panel edges. */
/* Emoji sea creatures face LEFT by default. So a creature moving RIGHT (LTR)
   must be flipped to face right; one moving LEFT (RTL) stays as-is. */
@keyframes wlSwimLTR {
  from { transform: translateX(-18vw) scaleX(-1); }
  to   { transform: translateX(118vw) scaleX(-1); }
}
@keyframes wlSwimRTL {
  from { transform: translateX(118vw); }
  to   { transform: translateX(-18vw); }
}

/* Floaters (jellyfish, octopus) don't cross — they hover in place, gently
   bobbing, then fade out. Max opacity rides on --wl-op so depth-fade is kept. */
@keyframes wlDriftJelly {
  0%   { opacity: 0;             transform: translateY(0); }
  15%  { opacity: var(--wl-op);  transform: translateY(-7px); }
  40%  { opacity: var(--wl-op);  transform: translateY(5px); }
  65%  { opacity: var(--wl-op);  transform: translateY(-5px); }
  85%  { opacity: var(--wl-op);  transform: translateY(3px); }
  100% { opacity: 0;             transform: translateY(-9px); }
}
@keyframes wlDriftOcto {
  0%   { opacity: 0;             transform: translateY(0) scale(1); }
  18%  { opacity: var(--wl-op);  transform: translateY(-4px) scale(1.04); }
  50%  { opacity: var(--wl-op);  transform: translateY(3px) scale(0.98); }
  82%  { opacity: var(--wl-op);  transform: translateY(-3px) scale(1.03); }
  100% { opacity: 0;             transform: translateY(5px) scale(1); }
}

/* 🪼✨ Night bioluminescence: at dusk/night, jellyfish glow faint blue in the
   water (like real life). The silhouette lightens slightly so the glow reads,
   and a soft blue drop-shadow pulses gently. */
.cast-area.time-night .wl-jelly,
.cast-area.time-dusk .wl-jelly {
  /* Full natural colour at night (NO brightness(0)/saturate(0) silhouette,
     unlike the fish) with a small static glow. Static = cheap (animating the
     blur lagged on mobile). */
  filter: drop-shadow(0 0 5px rgba(130, 225, 255, 0.80))
          drop-shadow(0 0 11px rgba(70, 170, 255, 0.45));
}

/* ===== 🔦 Morse Daily Word banner (lighthouse home) ===== */
.lh-daily {
  display: flex; align-items: center; gap: 12px;
  margin: 4px 0 14px; padding: 12px 14px;
  border-radius: 14px;
  background: linear-gradient(135deg, rgba(124,215,255,0.10), rgba(76,201,240,0.04));
  border: 1px solid rgba(124,215,255,0.30);
}
.lh-daily.done {
  background: linear-gradient(135deg, rgba(128,237,153,0.12), rgba(76,201,240,0.05));
  border-color: rgba(128,237,153,0.40);
}
.lh-daily-left { flex: 1; min-width: 0; }
.lh-daily-kicker { font-size: 11px; font-weight: 700; letter-spacing: 0.4px; color: #7fd7ff; text-transform: uppercase; }
.lh-daily.done .lh-daily-kicker { color: #80ed99; }
.lh-daily-word {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 26px; font-weight: 900; letter-spacing: 0.12em; color: #fff;
  margin: 2px 0; text-shadow: 0 0 12px rgba(124,215,255,0.35);
}
.lh-daily-hint { font-size: 11px; color: var(--text-dim); }
.lh-daily-btn {
  flex-shrink: 0; padding: 10px 16px; border-radius: 10px;
  background: linear-gradient(135deg, #1f5c7a, #2f7fa0);
  border: 1px solid rgba(124,215,255,0.35); color: #fff;
  font-weight: 700; font-size: 13px; font-family: inherit; cursor: pointer;
}
.lh-daily.done .lh-daily-btn {
  background: rgba(255,255,255,0.06); border-color: rgba(255,255,255,0.12);
}

/* 🌍 Morse Daily Word — global reset countdown line */
.lh-daily-reset {
  font-size: 10px;
  color: var(--text-dim);
  opacity: 0.75;
  margin-top: 3px;
  letter-spacing: 0.2px;
}

/* ⚓ Prestige name styling on the leaderboard. White fill stays legible, with a
   prestige-coloured OUTLINE around the letters plus a supporting glow. Higher
   prestige = thicker outline + brighter glow. paint-order keeps the stroke
   behind the fill so the white interior stays readable. Static = cheap. */
.lb-name-text {
  color: #fff;
  paint-order: stroke fill;
}
.lb-name-text.pg1 {
  -webkit-text-stroke: 0.6px rgba(128, 237, 153, 0.85);
  text-shadow: 0 0 2px rgba(128, 237, 153, 0.45);
}
.lb-name-text.pg2 {
  -webkit-text-stroke: 0.7px rgba(120, 195, 255, 0.90);
  text-shadow: 0 0 2px rgba(120, 195, 255, 0.50);
}
.lb-name-text.pg3 {
  -webkit-text-stroke: 0.8px rgba(199, 125, 255, 0.92);
  text-shadow: 0 0 3px rgba(199, 125, 255, 0.55);
}
.lb-name-text.pg4 {
  -webkit-text-stroke: 0.9px rgba(255, 199, 80, 0.95);
  text-shadow: 0 0 3px rgba(255, 209, 102, 0.60);
}
.lb-name-text.pg5 {
  -webkit-text-stroke: 1px rgba(241, 130, 230, 1);
  text-shadow: 0 0 3px rgba(241, 130, 230, 0.65), 0 0 6px rgba(199, 125, 255, 0.40);
}

/* Inventory row "collapse" — when you sell / recycle / move-to-aquarium, a
   fixed-position clone of the row shrinks toward the tap point and fades while
   the reward particles already fly out. --collapse-origin (set inline) points
   the shrink toward the finger. */
.inv-row.row-collapsing,
.aq-slot.row-collapsing {
  animation: rowCollapse 0.5s cubic-bezier(0.25, 0.1, 0.25, 1) forwards;
  pointer-events: none;
  transform-origin: var(--collapse-origin, center);
  box-sizing: border-box;
  will-change: transform, opacity;
}
@keyframes rowCollapse {
  0%   { transform: scale(1);    opacity: 1; }
  100% { transform: scale(0.05); opacity: 0; }
}

/* 🔦 Lighthouse harbor card glows while a beacon buff is active — a gently
   pulsing warm beacon border. Two tiers: base glow for any active buff, and a
   STRONGER glow when the Morse Daily Word is also done that day. */
.harbor-card.buff-active {
  border-color: rgba(255, 209, 102, 0.7);
  animation: harborBuffGlow 2.4s ease-in-out infinite;
}
@keyframes harborBuffGlow {
  0%, 100% {
    border-color: rgba(255, 209, 102, 0.55);
    box-shadow: 0 0 6px rgba(255, 209, 102, 0.35), inset 0 0 8px rgba(255, 209, 102, 0.12);
  }
  50% {
    border-color: rgba(255, 224, 150, 0.95);
    box-shadow: 0 0 14px rgba(255, 209, 102, 0.65), inset 0 0 12px rgba(255, 209, 102, 0.20);
  }
}
/* Stronger beacon: brighter, wider halo + faster pulse when daily is also done. */
.harbor-card.buff-active.buff-strong {
  animation: harborBuffGlowStrong 1.7s ease-in-out infinite;
}
@keyframes harborBuffGlowStrong {
  0%, 100% {
    border-color: rgba(255, 224, 150, 0.85);
    box-shadow: 0 0 12px rgba(255, 215, 120, 0.6), 0 0 22px rgba(255, 200, 90, 0.3), inset 0 0 12px rgba(255, 215, 120, 0.22);
  }
  50% {
    border-color: rgba(255, 240, 190, 1);
    box-shadow: 0 0 20px rgba(255, 224, 150, 0.9), 0 0 36px rgba(255, 200, 90, 0.5), inset 0 0 16px rgba(255, 224, 150, 0.32);
  }
}

/* Catch-list modal: white title (not the danger-red default) + a blue
   "back to fishing" button instead of the generic cancel pill. */
#catch-list-title { color: #fff; }
#catch-list-close {
  color: #7fd7ff;
  border-color: rgba(124, 215, 255, 0.55);
  background: rgba(124, 215, 255, 0.08);
}
/* Daily modal: green title (unified Daily look) + the same blue
   "Back to fishing" button as the catch-list modal. */
#daily-modal-title { color: var(--ok); }
#daily-close-btn {
  color: #7fd7ff;
  border-color: rgba(124, 215, 255, 0.55);
  background: rgba(124, 215, 255, 0.08);
}

/* ============================================================
   👋 ONBOARDING — first-launch intro (3 cards)
   ============================================================ */
.onboarding-overlay {
  position: fixed;
  inset: 0;
  z-index: 9000;
  background: rgba(8, 8, 8, 0.97);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: calc(24px + env(safe-area-inset-top)) calc(24px + env(safe-area-inset-right)) calc(24px + env(safe-area-inset-bottom)) calc(24px + env(safe-area-inset-left));
  animation: fadeIn 0.25s ease;
}
.onboarding-overlay.hidden { display: none; }
.onboarding-card {
  width: 100%;
  max-width: 360px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
.onboarding-step {
  display: flex;
  flex-direction: column;
  align-items: center;
  animation: fadeIn 0.25s ease;
}
.onboarding-step.hidden { display: none; }
.onboarding-emoji {
  font-size: 64px;
  line-height: 1;
  margin-bottom: 22px;
}
.onboarding-title {
  font-size: 24px;
  font-weight: 800;
  margin: 0 0 12px;
  color: var(--text);
}
.onboarding-text {
  font-size: 15px;
  line-height: 1.6;
  color: var(--text-dim);
  margin: 0;
  max-width: 300px;
}
.onboarding-text strong { color: var(--text); font-weight: 700; }
.onboarding-dots {
  display: flex;
  gap: 8px;
  margin: 32px 0 24px;
}
.onboarding-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.18);
  transition: background 0.25s ease, transform 0.25s ease;
}
.onboarding-dot.active {
  background: var(--ok);
  transform: scale(1.25);
}
.onboarding-actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  width: 100%;
}
.onboarding-next {
  width: 100%;
  max-width: 280px;
  padding: 15px 20px;
  border-radius: 14px;
  border: 1px solid rgba(128, 237, 153, 0.55);
  background: rgba(128, 237, 153, 0.10);
  color: var(--ok);
  font-size: 16px;
  font-weight: 700;
  cursor: pointer;
  font-family: inherit;
}
.onboarding-next:active { transform: scale(0.98); }
.onboarding-skip {
  background: none;
  border: none;
  color: var(--text-faint);
  font-size: 13px;
  cursor: pointer;
  padding: 6px 12px;
  font-family: inherit;
}

/* Privacy policy link at the bottom of the settings panel */
.settings-privacy-link {
  display: block;
  text-align: center;
  margin-top: 16px;
  padding: 8px;
  color: var(--text-faint);
  font-size: 12px;
  text-decoration: underline;
}

/* ============================================================
   ⚖️ MERCHANT — trade cards (Harbor-style grid)
   ============================================================ */
.shop-group-merchant-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
/* Compact trade cards — smaller than the single-column shop cards so all
   5-6 fit on one screen in a 2-up grid without scrolling. */
.trade-card {
  padding: 12px 10px;
  margin: 0;
  gap: 3px;
  border-radius: 14px;
}
.trade-card .shop-card-emoji { font-size: 30px; margin-bottom: 0; }
.trade-card .shop-card-name { font-size: 14px; line-height: 1.2; }
.trade-card .shop-card-divider { margin: 3px 0; }
.trade-card .shop-card-level { top: 7px; right: 9px; font-size: 10px; }
.trade-card .trade-cost { min-height: 18px; margin-top: 3px; }
.trade-cost-chip { font-size: 12px; padding: 1px 7px; }
.trade-card .trade-cost {
  margin-top: 6px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: center;
  align-items: center;
  min-height: 22px;
}
.trade-cost-chip {
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 700;
  color: var(--text-dim);
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 2px 8px;
}
.trade-cost-chip.short { color: var(--danger); border-color: rgba(255, 107, 107, 0.4); }
.trade-card.armed .trade-cost { color: var(--ok); font-weight: 700; }
/* Tier badge in the corner — colored by tier, reusing the level-badge slot */
.trade-tier { font-weight: 800; }
.trade-tier.tier-1 { color: #7fd7ff; }
.trade-tier.tier-2 { color: var(--ok); }
.trade-tier.tier-3 { color: var(--epic); }
.trade-tier.tier-4 { color: var(--coin); }

/* Bait trade cards — "have / cap" line under the cost */
.trade-have {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-faint);
  margin-top: 3px;
}
.trade-have.full { color: var(--danger); }
.bait-card .shop-card-name { font-size: 13px; }
