/* ==========================================================================
   Mealborne — Components (CSS)
   ==========================================================================
   Reusable element classes that consume design tokens. Loaded AFTER
   tokens.css so var(--c-*), var(--frame-*), var(--t-*), etc. are in scope.

   Naming convention: every Mealborne-system class is prefixed `.mb-`.
   This avoids collision with the existing prototype classes (.screen,
   .gold-title, .card, .btn) which Wave 3+ will replace incrementally.
   The legacy classes stay live until a screen is retheemed.

   Wave 2 (2026-04-25): seeded with what title-screen.js needs.
   ========================================================================== */

/* ===== PIXEL SPRITE · canonical render rule for all Squire/monster pixel art =====
   Apply to any <img> rendering pixel art at non-native sizes. Without it, browser
   bilinear filtering blurs the pixel grid and our crisp 8-bit edges become mushy.
   Use everywhere Squire sprites render: hub-town party-card, squire-den portrait,
   species-picker cards, squire-evolution ceremony, plus future monster/biome assets.
   First wired in: hub-town.js party-card avatar (Phase 6b, 2026-04-25). */
.mb-pixel-sprite {
  image-rendering: pixelated;
  image-rendering: crisp-edges;  /* Firefox fallback */
  object-fit: contain;
}


/* ============ SCREEN CONTAINERS =========================================== */

/* Full-bleed dark screen ground. Use for title, ceremony, hero contexts.
   Composes a Plum→Onyx radial vignette over flat Deep Onyx. */
.mb-screen {
  position: fixed;
  inset: 0;
  background:
    radial-gradient(ellipse at 50% 40%, var(--c-plum) 0%, var(--c-onyx) 70%),
    var(--c-onyx);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  font-family: var(--font-ui);
  color: var(--c-bone);
  z-index: var(--z-modal);
}

.mb-screen-tap { cursor: pointer; }


/* ============ EMBER PARTICLES =============================================
   Ambient warmth for hero / title contexts. Replaces the FitQuest gold-star
   twinkle. Each ember is a small dot that drifts upward and fades. */

.mb-ember {
  position: absolute;
  border-radius: 50%;
  background: var(--c-amber);
  pointer-events: none;
  opacity: 0;
  animation: mb-ember-drift 6s var(--ease-in-out) infinite;
  filter: drop-shadow(0 0 4px rgba(232, 147, 26, 0.5));
}

@keyframes mb-ember-drift {
  0%   { opacity: 0;    transform: translateY(0)    scale(0.6); }
  20%  { opacity: 0.6;  transform: translateY(-12px) scale(1.0); }
  100% { opacity: 0;    transform: translateY(-60px) scale(1.2); }
}


/* ============ WORDMARK · The locked Mealborne logo ========================
   Forum + Aged Bronze gradient + 8px inscriptional tracking. Uses
   background-clip:text so the gradient fills the glyphs. The drop-shadow
   simulates the incised depth from the locked v2 spec. */

.mb-wordmark {
  font-family: var(--font-display);
  font-weight: 400;                  /* Forum is single-weight */
  font-size: clamp(40px, 12vw, 64px);
  letter-spacing: var(--ls-inscription);
  line-height: 1.1;
  text-align: center;

  /* Aged Bronze, applied via background-clip:text */
  color: transparent;
  background-image: var(--bronze-gradient-aged);
  -webkit-background-clip: text;
  background-clip: text;

  /* Inscribed depth — subtle bottom shadow simulates carve */
  filter: drop-shadow(0 1px 0 rgba(0, 0, 0, 0.85));

  margin: var(--s-3) 0;
  user-select: none;
}


/* ============ INSCRIPTION RULES ===========================================
   The plaque-style hairline rules that frame the wordmark. Used above
   ("--top" alone) and below ("--rule" with center dot) per the locked
   primary master composition. */

.mb-rule-top {
  width: clamp(120px, 32vw, 200px);
  height: 1px;
  background: var(--c-bronze-mid);
  opacity: 0.35;
  margin: 0 auto var(--s-2);
}

.mb-rule {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  margin-top: var(--s-2);
}

.mb-rule-line {
  height: 1px;
  width: clamp(56px, 14vw, 92px);
  background: var(--c-bronze-mid);
  opacity: 0.55;
}

/* Square pixel dot — matches the inscription aesthetic (not round). */
.mb-rule-dot {
  width: 4px;
  height: 4px;
  background: var(--c-bronze-top);
  opacity: 0.85;
  flex: none;
}


/* ============ TAP PROMPT (title screen affordance) ======================== */

.mb-tap-prompt {
  position: absolute;
  bottom: clamp(64px, 14vh, 104px);
  font-family: var(--font-display);
  font-size: var(--t-sm);
  letter-spacing: var(--ls-wide);
  color: var(--c-bronze-mid);
  text-transform: uppercase;
  user-select: none;
  animation:
    mb-tap-pulse 2.4s var(--ease-in-out) infinite,
    mb-fade-in   2s   var(--ease-out) 0.4s both;
}

/* Variant when prompt is nested inside another absolutely-positioned block
   (e.g. the welcome-back group) — drops the absolute positioning. */
.mb-tap-prompt--inline {
  position: static;
  bottom: auto;
}

@keyframes mb-tap-pulse {
  0%, 100% { opacity: 0.30; }
  50%      { opacity: 0.85; }
}


/* ============ WELCOME-BACK BLOCK (returning player) ======================= */

.mb-welcome {
  position: absolute;
  bottom: clamp(64px, 14vh, 104px);
  text-align: center;
  animation: mb-fade-in 2s var(--ease-out) 0.6s both;
}

.mb-welcome-eyebrow {
  font-family: var(--font-display);
  font-size: var(--t-xs);
  letter-spacing: var(--ls-wide);
  color: var(--c-bronze-mid);
  text-transform: uppercase;
  opacity: 0.75;
  margin-bottom: var(--s-1);
}

.mb-welcome-name {
  font-family: var(--font-display);
  font-size: var(--t-lg);
  letter-spacing: var(--ls-normal);
  color: var(--c-bronze-top);
  margin-bottom: var(--s-2);
}


/* ============ VERSION / CREDIT TAG ======================================== */

.mb-version-tag {
  position: absolute;
  bottom: var(--s-4);
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  letter-spacing: var(--ls-tight);
  color: var(--c-bronze-mid);
  opacity: 0.35;
  user-select: none;
}


/* ============ ENTRANCE ANIMATIONS ========================================= */

.mb-title-reveal {
  position: relative;
  z-index: 1;
  animation: mb-title-fade-in 1.6s var(--ease-out) both;
}

@keyframes mb-title-fade-in {
  0%   { opacity: 0; transform: translateY(16px); }
  100% { opacity: 1; transform: translateY(0);    }
}

@keyframes mb-fade-in {
  0%   { opacity: 0; transform: translateY(8px); }
  100% { opacity: 1; transform: translateY(0);   }
}


/* ============ COMPACT WORDMARK (header contexts) ==========================
   Smaller variant for screens that are not the title hero — auth-gate,
   onboarding flow, in-app screens that need a brand mark in the header. */

.mb-wordmark--sm {
  font-size: clamp(20px, 5.5vw, 28px);
  letter-spacing: var(--ls-wide);
  margin: var(--s-2) 0 0;
}


/* ============ PAGE-STYLE SCREEN (forms, settings, lists) ==================
   For screens that scroll and have content stacked vertically. Uses the
   on-brand onyx ground without the full vignette of .mb-screen.
   Replaces the legacy .screen class incrementally — Wave 3+ migrates more
   screens. */

.mb-screen-page {
  min-height: 100vh;
  padding: var(--s-6) var(--s-5);
  background:
    radial-gradient(ellipse at 50% 0%, var(--c-plum) 0%, var(--c-onyx) 65%),
    var(--c-onyx);
  display: flex;
  flex-direction: column;
  font-family: var(--font-ui);
  color: var(--c-bone);
}


/* ============ BUTTON · primary + secondary ================================
   Bronze-frame button that grammatically matches the locked logo system.
   Matches the .btn pattern in the design system v2 spec. */

.mb-btn {
  display: inline-block;
  width: 100%;
  min-height: 44px;
  padding: var(--s-3) var(--s-5);
  background: rgba(138, 125, 58, 0.15);
  border: var(--rule-thin) solid var(--c-bronze-top);
  border-radius: var(--r-card);
  font-family: var(--font-display);
  font-size: var(--t-md);
  letter-spacing: var(--ls-normal);
  color: var(--c-bronze-top);
  text-align: center;
  cursor: pointer;
  text-transform: uppercase;
  transition: background var(--motion-snap) var(--ease-out),
              color      var(--motion-snap) var(--ease-out),
              border-color var(--motion-snap) var(--ease-out);
  user-select: none;
}

.mb-btn:hover {
  background: rgba(242, 184, 56, 0.22);
  color: var(--c-bone);
}

.mb-btn:active {
  background: rgba(242, 184, 56, 0.30);
}

.mb-btn:disabled,
.mb-btn[aria-disabled="true"] {
  opacity: 0.35;
  cursor: not-allowed;
}

.mb-btn--secondary {
  background: transparent;
  border-color: var(--c-bronze-mid);
  color: var(--c-bronze-mid);
}

.mb-btn--secondary:hover {
  background: rgba(138, 125, 58, 0.10);
  border-color: var(--c-bronze-top);
  color: var(--c-bone);
}


/* ============ TAB ROW · segmented control =================================
   Used in auth-gate, future settings, anywhere two-or-three-way switching
   is needed. */

.mb-tab-row {
  display: flex;
  gap: 0;
  border: var(--rule-thin) solid rgba(138, 125, 58, 0.30);
  border-radius: var(--r-card);
  overflow: hidden;
  background: rgba(26, 20, 32, 0.55);
}

.mb-tab {
  flex: 1;
  padding: var(--s-3) var(--s-2);
  background: transparent;
  border: none;
  border-bottom: var(--rule-med) solid transparent;
  font-family: var(--font-display);
  font-size: var(--t-sm);
  letter-spacing: var(--ls-normal);
  color: var(--c-bronze-mid);
  text-transform: uppercase;
  cursor: pointer;
  transition: background var(--motion-snap), color var(--motion-snap), border-color var(--motion-snap);
}

.mb-tab:hover {
  color: var(--c-bone);
  background: rgba(138, 125, 58, 0.06);
}

.mb-tab--active {
  background: rgba(242, 184, 56, 0.10);
  color: var(--c-bronze-top);
  border-bottom-color: var(--c-bronze-top);
}


/* ============ DIVIDER · "or" between sections ============================= */

.mb-divider-or {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin: var(--s-5) 0;
}

.mb-divider-or-line {
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg,
    transparent,
    rgba(138, 125, 58, 0.35),
    transparent);
}

.mb-divider-or-text {
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  color: var(--c-bronze-mid);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  opacity: 0.6;
}


/* ============ FINE PRINT (footers, legal, version notes) ================== */

.mb-fine-print {
  text-align: center;
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  color: var(--c-bronze-mid);
  opacity: 0.45;
  line-height: 1.6;
  padding: var(--s-4) 0;
}


/* ============ HEADER BLOCK (centered title + optional subtitle) =========== */

.mb-page-header {
  text-align: center;
  margin-bottom: var(--s-8);
  animation: mb-fade-in 1.2s var(--ease-out) both;
}


/* ============ SCREEN TITLE (secondary heading, below wordmark) ============
   For screens that have their own identity beyond the brand wordmark —
   "GUILD ENTRY", "DAILY DEBRIEF", "TROPHY HALL". Forum caps, bronze,
   tracked. Sits below the wordmark in the page header. */

.mb-screen-title {
  font-family: var(--font-display);
  font-size: var(--t-lg);
  letter-spacing: var(--ls-wide);
  color: var(--c-bronze-top);
  text-transform: uppercase;
  text-align: center;
  margin: var(--s-3) 0 var(--s-2);
}

/* Italic flavor caption beneath a screen title — diegetic / NPC voice. */
.mb-flavor {
  font-family: var(--font-script);
  font-style: italic;
  font-size: var(--t-base);
  color: var(--c-bronze-mid);
  text-align: center;
  line-height: 1.55;
  max-width: 32ch;
  margin: 0 auto var(--s-5);
  opacity: 0.85;
}


/* ============ INPUT (text, date, email, password) =========================
   Token-driven input style. Replaces the inline-styled inputs in age-gate,
   inputGroup() helpers, and any other form across the prototype.
   Wave 3 will migrate inputGroup() in components.js to use .mb-input. */

.mb-input {
  width: 100%;
  min-height: 44px;
  padding: var(--s-3) var(--s-4);
  background: rgba(26, 20, 32, 0.55);
  border: var(--rule-thin) solid rgba(138, 125, 58, 0.35);
  border-radius: var(--r-card);
  font-family: var(--font-ui);
  font-size: var(--t-md);
  color: var(--c-bone);
  letter-spacing: var(--ls-tight);
  transition: border-color var(--motion-snap), background var(--motion-snap);
}

.mb-input::placeholder {
  color: var(--c-bronze-mid);
  opacity: 0.55;
}

.mb-input:focus {
  outline: none;
  border-color: var(--c-bronze-top);
  background: rgba(26, 20, 32, 0.75);
}

.mb-input-label {
  display: block;
  font-family: var(--font-display);
  font-size: var(--t-xs);
  letter-spacing: var(--ls-wide);
  color: var(--c-bronze-mid);
  text-transform: uppercase;
  margin-bottom: var(--s-1);
}

.mb-input-help {
  font-family: var(--font-ui);
  font-size: var(--t-xs);
  color: var(--c-bronze-mid);
  opacity: 0.7;
  margin-top: var(--s-2);
  line-height: 1.55;
}

.mb-input-error {
  display: none;
  font-family: var(--font-ui);
  font-size: var(--t-xs);
  color: var(--c-ember);
  margin-top: var(--s-2);
}

.mb-input-error[data-visible="true"] {
  display: block;
}


/* ============ PROSE (readable body copy inside cards / sections) ==========
   For the warm, narrative-heavy content blocks — age-gate rejection,
   guild registration intro, etc. */

.mb-prose {
  font-family: var(--font-ui);
  font-size: var(--t-base);
  line-height: 1.7;
  color: var(--c-bone);
  text-align: center;
}

.mb-prose strong {
  color: var(--c-bronze-top);
  font-weight: 600;
}

.mb-prose-muted {
  color: var(--c-bronze-mid);
  opacity: 0.75;
}


/* ============ FRAME · D2 Double-Rule Plaque ===============================
   The canonical Mealborne UI surface — wordmark monogram lineage. Used
   wherever "this is the game speaking" needs to read: ceremony moments,
   modal hero contexts, plaque-style emphasis. Has top corner accent
   pixels (Harvest Gold dots) at the outer rule. .mb-frame-inner adds the
   second hairline rule for full D2 grammar; omit for a lighter chrome. */

.mb-frame {
  position: relative;
  background: var(--frame-bg);
  border: var(--frame-outer-weight) solid var(--frame-outer-color);
  border-radius: var(--frame-radius);
  padding: var(--frame-padding);
}

.mb-frame::before,
.mb-frame::after {
  content: "";
  position: absolute;
  width: var(--frame-corner-size);
  height: var(--frame-corner-size);
  background: var(--frame-corner-color);
  pointer-events: none;
}
.mb-frame::before { top: calc(var(--frame-corner-size) / -2); left: calc(var(--frame-corner-size) / -2); }
.mb-frame::after  { top: calc(var(--frame-corner-size) / -2); right: calc(var(--frame-corner-size) / -2); }

.mb-frame-inner {
  border: var(--frame-inner-weight) solid var(--frame-inner-color);
  border-radius: calc(var(--frame-radius) - 1px);
  padding: var(--s-4) var(--s-5);
}


/* ============ CARD · content surface =====================================
   Lighter than .mb-frame — for content blocks within a screen. Single
   rule + top corner accents. No inner rule. Used for damage breakdown,
   stat blocks, list entries, secondary panels. */

.mb-card {
  position: relative;
  background: rgba(26, 20, 32, 0.55);
  border: var(--rule-thin) solid var(--c-bronze-mid);
  border-radius: var(--r-card);
  padding: var(--s-4) var(--s-5);
  margin-bottom: var(--s-3);
}

.mb-card::before,
.mb-card::after {
  content: "";
  position: absolute;
  width: 4px;
  height: 4px;
  background: var(--frame-corner-color);
  pointer-events: none;
}
.mb-card::before { top: -2px; left: -2px; }
.mb-card::after  { top: -2px; right: -2px; }

.mb-card-title {
  font-family: var(--font-display);
  font-size: var(--t-md);
  letter-spacing: var(--ls-normal);
  color: var(--c-bronze-top);
  text-transform: uppercase;
  margin-bottom: var(--s-3);
}

.mb-card-subtitle {
  font-family: var(--font-script);
  font-style: italic;
  font-size: var(--t-sm);
  color: var(--c-bronze-mid);
  margin-bottom: var(--s-3);
  line-height: 1.5;
}


/* ============ INSIGHT BOX · accented callout =============================
   For Squire insights, level-ups, ability activations, critical hits —
   content blocks that need a colored emphasis stripe. Consume an
   `--accent` custom property via inline style for affinity / status color.
   Default accent is bronze-mid. */

.mb-insight {
  --accent: var(--c-bronze-mid);
  position: relative;
  background: rgba(26, 20, 32, 0.45);
  border-left: 3px solid var(--accent);
  border-top: var(--rule-hair) solid rgba(138, 125, 58, 0.18);
  border-right: var(--rule-hair) solid rgba(138, 125, 58, 0.18);
  border-bottom: var(--rule-hair) solid rgba(138, 125, 58, 0.18);
  border-radius: 0 var(--r-card) var(--r-card) 0;
  padding: var(--s-3) var(--s-4);
  margin-bottom: var(--s-3);
  font-family: var(--font-ui);
  font-size: var(--t-base);
  color: var(--c-bone);
  line-height: 1.55;
}

.mb-insight strong {
  color: var(--accent);
  font-weight: 600;
}

.mb-insight-line {
  font-size: var(--t-sm);
  color: #b8b0c0;
  margin-top: var(--s-1);
}

.mb-insight-meta {
  font-family: var(--font-script);
  font-style: italic;
  font-size: var(--t-xs);
  color: var(--c-bronze-mid);
  margin-top: var(--s-1);
  opacity: 0.85;
}


/* ============ STACKED BAR · damage breakdown =============================
   Horizontal bar with multiple colored segments. Used for the macro
   contribution display in battle-debrief. Each segment width is set
   inline (proportional to contribution); colors set inline (per-macro
   accuracy). */

.mb-stacked-bar {
  display: flex;
  width: 100%;
  height: 26px;
  background: rgba(26, 20, 32, 0.6);
  border: var(--rule-thin) solid var(--c-bronze-mid);
  border-radius: var(--r-card);
  overflow: hidden;
  margin-bottom: var(--s-3);
}

.mb-stacked-seg {
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  color: var(--c-onyx);
  font-weight: 700;
  text-shadow: 0 0 1px rgba(255, 255, 255, 0.4);
  transition: width var(--motion-smooth) var(--ease-out);
  border-right: 1px solid rgba(26, 20, 32, 0.4);
}
.mb-stacked-seg:last-child { border-right: none; }


/* ============ STAT ROW · accuracy / macro indicator strip ================ */

.mb-stat-row {
  display: flex;
  justify-content: space-between;
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  color: var(--c-bronze-mid);
  margin-top: var(--s-3);
  letter-spacing: var(--ls-tight);
}

.mb-stat-row > span {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}


/* ============ NOTE · tiny inline annotation =============================
   Below cards, for tiny status notes (affix, variety, etc.). */

.mb-note {
  font-family: var(--font-ui);
  font-size: var(--t-xs);
  color: var(--c-bronze-mid);
  margin-top: var(--s-2);
  line-height: 1.5;
}

.mb-note-warm {
  color: var(--c-amber);
}


/* ============ PROGRESS BAR · configurable accent + width =================
   Used for Bond XP, HP, day progress, training rings, encounter HP, etc.
   Set width inline (`width: N%`); set accent inline via CSS var
   (`--accent: <color>`) when caller wants a non-default color (e.g. squire
   species color, affinity color). Default accent is bronze. */

.mb-progress {
  --accent: var(--c-bronze-top);
  height: 10px;
  background: rgba(255, 255, 255, 0.06);
  border: var(--rule-thin) solid rgba(138, 125, 58, 0.25);
  border-radius: var(--r-card);
  overflow: hidden;
  margin: var(--s-2) 0;
}

.mb-progress-fill {
  height: 100%;
  background: linear-gradient(90deg, color-mix(in srgb, var(--accent) 60%, transparent), var(--accent));
  border-radius: inherit;
  transition: width var(--motion-smooth) var(--ease-out);
}

.mb-progress-meta {
  display: flex;
  justify-content: space-between;
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  color: var(--c-bronze-mid);
  letter-spacing: var(--ls-tight);
}


/* ============ BADGE · small label chip ===================================
   For rarity tags, "equipped" indicators, level pills. Default is bronze
   tone; consume `--accent` for squire/affinity color via inline style. */

.mb-badge {
  --accent: var(--c-bronze-top);
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border: var(--rule-thin) solid color-mix(in srgb, var(--accent) 40%, transparent);
  border-radius: var(--r-pill);
  font-family: var(--font-display);
  font-size: var(--t-xs);
  letter-spacing: var(--ls-normal);
  color: var(--accent);
  text-transform: uppercase;
}

.mb-badge-strong {
  background: color-mix(in srgb, var(--accent) 22%, transparent);
  border-color: var(--accent);
}


/* ============ SPEECH BUBBLE · NPC / Squire dialogue ======================
   Cormorant italic body inside a soft squire-tinted bubble with a top-left
   speech triangle. Set `--accent` inline for the squire color. */

.mb-bubble {
  --accent: var(--c-bronze-mid);
  position: relative;
  margin: var(--s-3) 0 var(--s-4);
  padding: var(--s-3) var(--s-4);
  border-radius: var(--r-modal);
  background: color-mix(in srgb, var(--accent) 6%, transparent);
  border: var(--rule-thin) solid color-mix(in srgb, var(--accent) 22%, transparent);
}

.mb-bubble::before {
  content: "";
  position: absolute;
  top: -8px;
  left: var(--s-8);
  width: 0;
  height: 0;
  border-left: 8px solid transparent;
  border-right: 8px solid transparent;
  border-bottom: 8px solid color-mix(in srgb, var(--accent) 22%, transparent);
}

.mb-bubble-text {
  font-family: var(--font-script);
  font-style: italic;
  font-size: var(--t-base);
  color: var(--accent);
  line-height: 1.55;
}

.mb-bubble-eyebrow {
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  color: var(--c-bronze-mid);
  letter-spacing: var(--ls-normal);
  text-transform: uppercase;
  margin-bottom: 4px;
  opacity: 0.7;
}

.mb-bubble-dashed {
  border-style: dashed;
  background: rgba(26, 20, 32, 0.45);
}


/* ============ PORTRAIT RING · circular character avatar frame ============
   Used for Squire portrait, party-card portraits, Hub squire selector.
   Consumes `--accent` for the ring color (species/affinity hex). */

.mb-portrait-ring {
  --accent: var(--c-bronze-top);
  width: 96px;
  height: 96px;
  border-radius: 50%;
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--accent) 14%, transparent),
    color-mix(in srgb, var(--accent) 4%, transparent));
  border: 3px solid color-mix(in srgb, var(--accent) 50%, transparent);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 48px;
  position: relative;
  box-shadow: 0 0 24px color-mix(in srgb, var(--accent) 14%, transparent);
}

.mb-portrait-status {
  position: absolute;
  bottom: -4px;
  right: -4px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--c-onyx);
  border: 2px solid var(--c-bronze-mid);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
}


/* ============ TILE GRID · 2-col grid of accessory / item tiles =========== */

.mb-tile-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--s-2);
}

.mb-tile {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-3);
  background: rgba(255, 255, 255, 0.03);
  border: var(--rule-thin) solid rgba(138, 125, 58, 0.2);
  border-radius: var(--r-card);
  cursor: pointer;
  transition: border-color var(--motion-snap), background var(--motion-snap);
}

.mb-tile:hover {
  background: rgba(138, 125, 58, 0.06);
  border-color: var(--c-bronze-mid);
}

.mb-tile-icon {
  font-size: 20px;
  flex-shrink: 0;
}

.mb-tile-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.mb-tile-name {
  font-family: var(--font-ui);
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--c-bone);
}

.mb-tile-desc {
  font-family: var(--font-ui);
  font-size: var(--t-xs);
  color: var(--c-bronze-mid);
  line-height: 1.4;
}


/* ============ EQUIPPED CHIP · clickable removable accessory =============
   Squire-color tinted chip with the accessory icon + name + remove "x". */

.mb-eq-chip {
  --accent: var(--c-bronze-top);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  border: var(--rule-thin) solid color-mix(in srgb, var(--accent) 25%, transparent);
  border-radius: var(--r-card);
  cursor: pointer;
  transition: background var(--motion-snap);
}

.mb-eq-chip:hover {
  background: color-mix(in srgb, var(--accent) 18%, transparent);
}

.mb-eq-chip-name {
  font-family: var(--font-ui);
  font-size: var(--t-sm);
  color: var(--accent);
}

.mb-eq-chip-remove {
  font-family: var(--font-ui);
  font-size: var(--t-sm);
  color: var(--c-bronze-mid);
  margin-left: 2px;
}


/* ============ LIST ROW · ability rows, milestone rows ==================== */

.mb-list-row {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-2) 0;
}

.mb-list-row-icon {
  width: 32px;
  height: 32px;
  border-radius: var(--r-card);
  background: rgba(255, 255, 255, 0.03);
  border: var(--rule-thin) solid rgba(138, 125, 58, 0.18);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  flex-shrink: 0;
}

.mb-list-row-icon[data-unlocked="true"] {
  --accent: var(--c-bronze-top);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  border-color: color-mix(in srgb, var(--accent) 35%, transparent);
}

.mb-list-row-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}

.mb-list-row-name {
  display: flex;
  align-items: baseline;
  gap: var(--s-2);
  font-family: var(--font-ui);
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--c-bone);
}

.mb-list-row-meta {
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  color: var(--c-bronze-mid);
  letter-spacing: var(--ls-tight);
}

.mb-list-row-desc {
  font-family: var(--font-ui);
  font-size: var(--t-xs);
  color: var(--c-bronze-mid);
  line-height: 1.5;
}

.mb-list-row[data-locked="true"] {
  opacity: 0.4;
}


/* ============ MILESTONE TIMELINE · linear dots for level / phase progress
   Used for Bond level milestones (1-10) and similar linear progressions. */

.mb-milestone-row {
  display: flex;
  justify-content: space-between;
  margin-top: var(--s-3);
  padding: 0 var(--s-1);
}

.mb-milestone {
  --accent: var(--c-bronze-top);
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.06);
  border: var(--rule-thin) solid rgba(138, 125, 58, 0.18);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 700;
  color: var(--c-bronze-mid);
  transition: all var(--motion-smooth);
}

.mb-milestone[data-state="reached"] {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--c-onyx);
}

.mb-milestone[data-state="current"] {
  background: var(--accent);
  border: 2px solid var(--c-bronze-top);
  color: var(--c-onyx);
  box-shadow: 0 0 8px color-mix(in srgb, var(--accent) 50%, transparent);
}


/* ============ BACK LINK · subtle text-only "←" navigation ================
   Use this in screens that want a quiet back affordance instead of a full
   button. Replaces inline-styled `<button>` patterns. */

.mb-back-link {
  background: transparent;
  border: none;
  color: var(--c-bronze-mid);
  font-family: var(--font-ui);
  font-size: var(--t-sm);
  letter-spacing: var(--ls-tight);
  cursor: pointer;
  padding: 4px 0;
  margin-bottom: var(--s-3);
  text-align: left;
  transition: color var(--motion-snap);
}

.mb-back-link:hover {
  color: var(--c-bronze-top);
}


/* ============ SECTION HEADER · in-card row title + meta ================== */

.mb-section-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--s-3);
}

.mb-section-row-title {
  font-family: var(--font-display);
  font-size: var(--t-md);
  letter-spacing: var(--ls-normal);
  color: var(--c-bone);
  text-transform: uppercase;
}

.mb-section-row-meta {
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  color: var(--c-bronze-mid);
  letter-spacing: var(--ls-tight);
}


/* ============ HUD STRIP · top bar with currency + level + settings =======
   Used at the top of Hub Town and other in-game screens. Sticky-ish row
   showing player resources + level + settings entry. */

.mb-hud-strip {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  padding: var(--s-2) 0;
  margin-bottom: var(--s-4);
  font-family: var(--font-mono);
  font-size: var(--t-sm);
  color: var(--c-bone);
}

.mb-hud-strip-left,
.mb-hud-strip-right {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
}

/* Currency readout (Gold ingot, Soul Gems) — compact pill in the HUD strip. */
.mb-currency-pill {
  --accent: var(--c-bronze-top);
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: var(--font-mono);
  font-size: var(--t-sm);
  color: var(--c-bone);
  letter-spacing: var(--ls-tight);
}

.mb-currency-pill-glyph {
  font-size: 14px;
  color: var(--accent);
}

/* Icon-only button (gear, close, X) — bronze-mid by default, brighter on hover. */
.mb-icon-btn {
  background: transparent;
  border: none;
  color: var(--c-bronze-mid);
  font-size: 18px;
  cursor: pointer;
  padding: 4px;
  border-radius: var(--r-subtle);
  transition: color var(--motion-snap), background var(--motion-snap);
  line-height: 1;
}

.mb-icon-btn:hover {
  color: var(--c-bronze-top);
  background: rgba(242, 184, 56, 0.06);
}


/* ============ BANNER · status rows (momentum / streak / weather / etc) ===
   Centered-text row with --accent-driven background tint + border. Used for
   single-line status indicators above the main content. */

.mb-banner {
  --accent: var(--c-bronze-mid);
  text-align: center;
  padding: var(--s-2) var(--s-3);
  margin-bottom: var(--s-2);
  border-radius: var(--r-card);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  border: var(--rule-thin) solid color-mix(in srgb, var(--accent) 25%, transparent);
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  color: var(--accent);
  letter-spacing: var(--ls-tight);
  font-weight: 700;
}


/* ============ HUB TILE GRID + HUB TILE ===================================
   The 2-column navigable tile grid at the heart of Hub Town. Each tile is
   a square-ish card with icon + label + sub. State variants:
     [data-state="pulse"]   — pulsing accent (Scale tile prompting weigh-in)
     [data-state="ready"]   — glow ring (Chronicle with new tier, etc.)
     [data-state="dim"]     — disabled / locked (encounter done, missing data)
   `--accent` custom property drives state colors. Default bronze. */

.mb-hub-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-2);
  margin-bottom: var(--s-4);
}

.mb-hub-tile {
  --accent: var(--c-bronze-top);
  position: relative;
  background: rgba(26, 20, 32, 0.55);
  border: var(--rule-thin) solid var(--c-bronze-mid);
  border-radius: var(--r-card);
  padding: var(--s-3);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  text-align: center;
  cursor: pointer;
  min-height: 96px;
  transition: border-color var(--motion-snap), background var(--motion-snap);
}

/* Top-corner accent pixels (matches `.mb-card` grammar). */
.mb-hub-tile::before,
.mb-hub-tile::after {
  content: "";
  position: absolute;
  width: 3px;
  height: 3px;
  background: var(--c-bronze-top);
  pointer-events: none;
}
.mb-hub-tile::before { top: -1.5px; left: -1.5px; }
.mb-hub-tile::after  { top: -1.5px; right: -1.5px; }

.mb-hub-tile:hover {
  background: rgba(138, 125, 58, 0.10);
  border-color: var(--c-bronze-top);
}

.mb-hub-tile[data-state="pulse"] {
  border-color: color-mix(in srgb, var(--accent) 50%, transparent);
  box-shadow: 0 0 12px color-mix(in srgb, var(--accent) 25%, transparent);
  animation: pulseAmber 2s ease-in-out infinite;
}

.mb-hub-tile[data-state="ready"] {
  border-color: color-mix(in srgb, var(--accent) 50%, transparent);
  box-shadow: 0 0 12px color-mix(in srgb, var(--accent) 25%, transparent);
}

.mb-hub-tile[data-state="dim"] {
  opacity: 0.35;
  cursor: default;
}

.mb-hub-tile-icon {
  font-size: 24px;
  line-height: 1;
  margin-bottom: 2px;
}

.mb-hub-tile-label {
  font-family: var(--font-display);
  font-size: var(--t-sm);
  letter-spacing: var(--ls-normal);
  color: var(--c-bone);
  text-transform: uppercase;
}

.mb-hub-tile-sub {
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  color: var(--c-bronze-mid);
  letter-spacing: var(--ls-tight);
  line-height: 1.3;
}

/* "NEW" sash for freshly unlocked tiles (used by `_applyNewPulse`). */
.mb-hub-tile-sash {
  position: absolute;
  top: 4px;
  right: 4px;
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.5px;
  padding: 2px 6px;
  border-radius: var(--r-subtle);
  background: var(--c-amber);
  color: var(--c-onyx);
  pointer-events: none;
}


/* ============ PARTY CARD · Squire portrait + identity ====================
   The big squire identity card on Hub Town. Avatar (squircle, not circle —
   distinguishes from `.mb-portrait-ring` in squire-den) + name + evolution
   title + bond level + affinity chip + cosmetics + bond progress bar.
   Driven by `--accent` for squire color. */

.mb-party-card {
  --accent: var(--c-bronze-top);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: var(--s-4) var(--s-3);
  margin-bottom: var(--s-4);
  background: rgba(255, 255, 255, 0.03);
  border: var(--rule-thin) solid rgba(138, 125, 58, 0.25);
  border-radius: var(--r-modal);
}

.mb-party-avatar {
  --accent: var(--c-bronze-top);
  width: 72px;
  height: 72px;
  border-radius: var(--r-modal);
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--accent) 14%, transparent),
    color-mix(in srgb, var(--accent) 4%, transparent));
  border: 2px solid color-mix(in srgb, var(--accent) 40%, transparent);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: 32px;
  position: relative;
}

.mb-party-avatar[data-stage="champion"] {
  border-color: color-mix(in srgb, var(--accent) 50%, transparent);
  box-shadow: 0 0 12px color-mix(in srgb, var(--accent) 30%, transparent);
}

.mb-party-name {
  font-family: var(--font-display);
  font-size: var(--t-base);
  letter-spacing: var(--ls-normal);
  color: var(--accent);
}

.mb-party-evo-title {
  font-family: var(--font-script);
  font-style: italic;
  font-size: var(--t-xs);
  color: var(--accent);
  opacity: 0.85;
}

.mb-party-bond-line {
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  color: var(--c-bronze-mid);
  letter-spacing: var(--ls-tight);
  text-transform: uppercase;
}


/* ============ AFFINITY CHIP (compact, inline pill) =======================
   The squire's emergent affinity displayed on the party card. Different
   from the in-game frame chip — this is a small pill with the affinity
   emoji + "the {titlePhrase}" label, color-tinted per affinity. */

.mb-aff-chip {
  --accent: var(--c-aff-wandering);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
  padding: 4px 10px;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  border: var(--rule-thin) solid color-mix(in srgb, var(--accent) 40%, transparent);
}

.mb-aff-chip-emoji {
  font-size: 14px;
  line-height: 1;
}

.mb-aff-chip-name {
  font-family: var(--font-display);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: var(--ls-tight);
  color: var(--accent);
  text-transform: lowercase;
}


/* ============ KEYFRAMES · pulse for tiles ================================ */

@keyframes pulseAmber {
  0%, 100% { box-shadow: 0 0 12px color-mix(in srgb, var(--accent, var(--c-bronze-top)) 25%, transparent); }
  50%      { box-shadow: 0 0 18px color-mix(in srgb, var(--accent, var(--c-bronze-top)) 45%, transparent); }
}

@keyframes hubNewGlow {
  0%   { box-shadow: 0 0 0 rgba(232, 147, 26, 0); }
  50%  { box-shadow: 0 0 18px rgba(232, 147, 26, 0.45); }
  100% { box-shadow: 0 0 14px rgba(232, 147, 26, 0.25); }
}


/* ============ COLLAPSIBLE SLOT (customize / settings / bazaar tabs) =======
   Expandable container with a clickable header row + body content.
   Used wherever a list of categories / equipment slots / settings groups
   needs an accordion pattern. State driven via `[data-state="expanded"]`. */

.mb-slot {
  --accent: var(--c-bronze-mid);
  position: relative;
  background: rgba(255, 255, 255, 0.02);
  border: var(--rule-thin) solid color-mix(in srgb, var(--accent) 18%, transparent);
  border-radius: var(--r-card);
  margin-bottom: var(--s-2);
  overflow: hidden;
  transition: background var(--motion-snap), border-color var(--motion-snap);
}

.mb-slot[data-state="expanded"] {
  background: rgba(255, 255, 255, 0.04);
  border-color: color-mix(in srgb, var(--accent) 35%, transparent);
}

.mb-slot-header {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-3);
  cursor: pointer;
}

.mb-slot-icon {
  --accent: var(--c-bronze-mid);
  width: 32px;
  height: 32px;
  border-radius: var(--r-subtle);
  background: color-mix(in srgb, var(--accent) 15%, transparent);
  border: var(--rule-thin) solid color-mix(in srgb, var(--accent) 35%, transparent);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  flex-shrink: 0;
}

.mb-slot-info {
  flex: 1;
  min-width: 0;
}

.mb-slot-name {
  font-family: var(--font-display);
  font-size: var(--t-base);
  letter-spacing: var(--ls-tight);
  color: var(--c-bone);
  text-transform: uppercase;
}

.mb-slot-current {
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  color: var(--c-bronze-mid);
  letter-spacing: var(--ls-tight);
  margin-top: 2px;
}

.mb-slot-chevron {
  font-size: var(--t-sm);
  color: var(--c-bronze-mid);
  transition: transform var(--motion-snap);
}

.mb-slot[data-state="expanded"] .mb-slot-chevron {
  transform: rotate(90deg);
}

.mb-slot-content {
  padding: 0 var(--s-3) var(--s-3) var(--s-3);
  max-height: 240px;
  overflow-y: auto;
}


/* ============ PICK ROW · selectable item in a slot picker ================
   Used inside `.mb-slot-content` for the equippable / placeable item lists.
   States: default | active (currently equipped/placed) | remove (delete row).
   `--accent` drives rarity color. */

.mb-pick-row {
  --accent: var(--c-bronze-mid);
  display: flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-2);
  margin-bottom: var(--s-1);
  border-radius: var(--r-subtle);
  background: rgba(255, 255, 255, 0.02);
  border: var(--rule-thin) solid rgba(138, 125, 58, 0.18);
  cursor: pointer;
  transition: background var(--motion-snap), border-color var(--motion-snap);
}

.mb-pick-row:hover {
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  border-color: color-mix(in srgb, var(--accent) 30%, transparent);
}

.mb-pick-row[data-state="active"] {
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  border-color: color-mix(in srgb, var(--accent) 30%, transparent);
  cursor: default;
  opacity: 0.7;
}
.mb-pick-row[data-state="active"]::after {
  content: '✓';
  font-size: var(--t-xs);
  color: var(--c-aff-scout);
  flex-shrink: 0;
}

.mb-pick-row[data-state="remove"] {
  --accent: #ef4444;
  background: rgba(239, 68, 68, 0.06);
  border-color: rgba(239, 68, 68, 0.18);
}

.mb-pick-row-icon {
  --accent: var(--c-bronze-mid);
  width: 28px;
  height: 28px;
  border-radius: var(--r-subtle);
  background: color-mix(in srgb, var(--accent) 15%, transparent);
  border: var(--rule-thin) solid color-mix(in srgb, var(--accent) 30%, transparent);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  flex-shrink: 0;
}

.mb-pick-row-body {
  flex: 1;
  min-width: 0;
}

.mb-pick-row-name {
  font-family: var(--font-ui);
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--c-bone);
}

.mb-pick-row-desc {
  font-family: var(--font-ui);
  font-size: var(--t-xs);
  color: var(--c-bronze-mid);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mb-pick-row-check {
  font-size: var(--t-xs);
  color: var(--c-aff-scout);
  flex-shrink: 0;
}


/* ============ SQUIRCLE AVATAR (customize / preview contexts) =============
   Squircle-shaped variant of the portrait — distinct from `.mb-portrait-ring`
   (which is a circle). Used in customize-hub to indicate "you're dressing
   the Squire" with the equipment overlay positions. */

.mb-avatar-squircle {
  --accent: var(--c-bronze-top);
  width: 80px;
  height: 80px;
  border-radius: 16px;
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--accent) 12%, transparent),
    color-mix(in srgb, var(--accent) 4%, transparent));
  border: 2px solid color-mix(in srgb, var(--accent) 40%, transparent);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: 36px;
  position: relative;
}

.mb-avatar-squircle[data-glow="true"] {
  box-shadow: 0 0 14px color-mix(in srgb, var(--accent) 25%, transparent);
}


/* ============ DECO MINI GRID · 3-col compact preview ===================== */

.mb-deco-mini-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-2);
}

.mb-deco-mini-cell {
  --accent: var(--c-bronze-mid);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: var(--s-2) 4px;
  border-radius: var(--r-subtle);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  border: var(--rule-thin) dashed color-mix(in srgb, var(--accent) 30%, transparent);
}

.mb-deco-mini-cell[data-placed="true"] {
  border-style: solid;
}

.mb-deco-mini-icon {
  font-size: 20px;
}

.mb-deco-mini-label {
  font-family: var(--font-mono);
  font-size: 9px;
  color: var(--c-bronze-mid);
  text-align: center;
  letter-spacing: var(--ls-tight);
}


/* ============ STATUS PILL · centered colored callout =====================
   Used for "N changes pending" or similar single-line status indicators. */

.mb-status-pill {
  --accent: #4ade80;
  text-align: center;
  padding: var(--s-2);
  border-radius: var(--r-card);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  border: var(--rule-thin) solid color-mix(in srgb, var(--accent) 25%, transparent);
  font-family: var(--font-display);
  font-size: var(--t-xs);
  letter-spacing: var(--ls-normal);
  color: var(--accent);
  text-transform: uppercase;
  font-weight: 700;
  margin-bottom: var(--s-2);
}


/* ============ CARD ACCENT EMPHASIS · biome / ritual / mystery emphasis ====
   Optional `[data-accent="strong"]` on `.mb-card` opts into accent-tinted
   border + corner pixels + soft accent wash. Driven by inline `--accent`.
   Used by Bazaar (Wave 7) for biome special, mystery item, ritual cards. */

.mb-card[data-accent="strong"] {
  border-color: color-mix(in srgb, var(--accent) 50%, transparent);
  background-color: color-mix(in srgb, var(--accent) 8%, rgba(26, 20, 32, 0.7));
}

.mb-card[data-accent="strong"]::before,
.mb-card[data-accent="strong"]::after {
  background: var(--accent);
}


/* ============ SHOP ROW · price + buy on the right =========================
   Non-clickable list row for shop items. Differs from `.mb-pick-row` (which
   is fully clickable as a selector). Here the row is read-only; only the
   action button on the right is interactive. `--accent` colors the name
   (rarity color). Used by Bazaar (Wave 7) for cosmetic shelves, soul-gem
   rituals, sell list. */

.mb-shop-row {
  --accent: var(--c-bronze-mid);
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  padding: var(--s-3) 0;
  border-bottom: var(--rule-hair) solid rgba(138, 125, 58, 0.12);
}

.mb-shop-row:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

.mb-shop-row-icon {
  --accent: var(--c-bronze-mid);
  width: 32px;
  height: 32px;
  border-radius: var(--r-subtle);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border: var(--rule-thin) solid color-mix(in srgb, var(--accent) 30%, transparent);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  flex-shrink: 0;
}

.mb-shop-row-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.mb-shop-row-name {
  font-family: var(--font-ui);
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--accent);
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

.mb-shop-row-desc {
  font-family: var(--font-ui);
  font-style: italic;
  font-size: var(--t-xs);
  color: var(--c-bronze-mid);
  line-height: 1.4;
}

.mb-shop-row-effect {
  font-family: var(--font-ui);
  font-size: var(--t-xs);
  color: #cbd5e1;
  line-height: 1.4;
}

.mb-shop-row-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: 2px;
}

.mb-shop-row-action {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  flex-shrink: 0;
  min-width: 72px;
}

.mb-shop-row-price {
  --accent: var(--c-bronze-top);
  font-family: var(--font-mono);
  font-size: var(--t-sm);
  font-weight: 700;
  color: var(--accent);
  white-space: nowrap;
  letter-spacing: var(--ls-tight);
}

.mb-shop-row-price-strike {
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  color: var(--c-bronze-mid);
  text-decoration: line-through;
  opacity: 0.65;
  margin-right: 4px;
}

/* Compact action button variant for shop rows — overrides `.mb-btn` width. */
.mb-btn--compact {
  width: auto;
  padding: 6px var(--s-3);
  font-size: var(--t-xs);
  letter-spacing: var(--ls-tight);
}


/* ============ EMPTY STATE · centered "nothing here" card body ============
   For closed merchant, empty inventory, no-stock-at-quest-level. Sits inside
   a `.mb-card` so the framing is shared. */

.mb-empty-state {
  text-align: center;
  padding: var(--s-5) var(--s-3);
}

.mb-empty-state-icon {
  font-size: 40px;
  margin-bottom: var(--s-2);
  opacity: 0.65;
  line-height: 1;
}

.mb-empty-state-title {
  font-family: var(--font-display);
  font-size: var(--t-md);
  letter-spacing: var(--ls-normal);
  color: var(--c-bronze-top);
  text-transform: uppercase;
  margin-bottom: var(--s-2);
}

.mb-empty-state-body {
  font-family: var(--font-script);
  font-style: italic;
  font-size: var(--t-sm);
  color: var(--c-bronze-mid);
  line-height: 1.55;
  max-width: 32ch;
  margin: 0 auto;
}


/* ============ PHOTO ANALYSIS SPINNER · meal-encounter photo capture ======
   Restored 2026-04-26 (Wave 8) — original was orphaned in main by an
   unresolved `=======` merge marker that ate the keyframe's closing brace.
   meal-encounter.js's photo loading overlay consumes `animation: photoSpin`. */

@keyframes photoSpin {
  0%   { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}


/* ============ HALL CREST · Chronicle Hall header ===========================
   Wave 8 chronicle-hall composes this with .mb-screen-title (the "Chronicle
   Hall" wordmark) + .mb-badge.mb-badge-strong (level pill) + .mb-progress
   (CP bar). The crest itself is the building emoji + italic Cormorant
   subtitle naming the current hall stage ("Tower Emerging", etc). */

.mb-hall-crest {
  text-align: center;
  padding: var(--s-3) 0 var(--s-1);
}

.mb-hall-crest-emoji {
  font-size: 48px;
  line-height: 1;
  margin-bottom: 4px;
}

.mb-hall-crest-name {
  font-family: var(--font-script);
  font-style: italic;
  font-size: var(--t-xs);
  color: var(--c-bronze-mid);
  margin-top: 2px;
}


/* ============ MINI STAT GRID · 3-up overview tile row ======================
   Compact glance component for "Tiers / Trophies / Weeks" headline numbers.
   Visually adjacent to .mb-tile-grid but smaller — icon-only header, big
   number, tiny label. Do NOT reuse .mb-tile (too tall for this rhythm). */

.mb-mini-stat-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
  padding: 0 var(--s-2);
  margin-bottom: var(--s-3);
}

.mb-mini-stat {
  text-align: center;
  padding: var(--s-2) 4px;
  border-radius: var(--r-subtle);
  background: rgba(26, 20, 32, 0.55);
  border: var(--rule-thin) solid rgba(138, 125, 58, 0.30);
}

.mb-mini-stat-icon {
  font-size: 20px;
  margin-bottom: 2px;
}

.mb-mini-stat-value {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: var(--t-md);
  color: var(--c-bronze-top);
  letter-spacing: var(--ls-tight);
}

.mb-mini-stat-label {
  font-family: var(--font-ui);
  font-size: var(--t-xs);
  color: var(--c-bronze-mid);
}


/* ============ TIER DOTS · achievement tier progress ========================
   Tiny 6px circles, filled or empty per `data-filled` attribute. The JS
   sets `data-filled="true"` on dots `i < ach.tierReached`. Dot count comes
   from `achDef.tiers.length`, NOT a hardcoded 3 — some achievements have
   more or fewer than 3 tiers. */

.mb-tier-dots {
  display: flex;
  gap: 2px;
}

.mb-tier-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(138, 125, 58, 0.30);
}

.mb-tier-dot[data-filled="true"] {
  background: var(--c-bronze-top);
}


/* ============ GRADE ROW · weekly-run grade distribution ====================
   5-cell row showing how many weeks fell into each grade (S/A/B/C/D).
   Per-cell `--accent` is JS-injected from `RUN_GRADES[grade].color`. The
   `data-active` attr brightens the fill when count > 0. */

.mb-grade-row {
  display: flex;
  gap: 4px;
  padding: 0 var(--s-2);
  margin-bottom: var(--s-3);
}

.mb-grade-cell {
  flex: 1;
  text-align: center;
  padding: var(--s-1) 4px;
  border-radius: var(--r-subtle);
  background: rgba(255, 255, 255, 0.02);
  border: var(--rule-thin) solid rgba(138, 125, 58, 0.30);
}

.mb-grade-cell[data-active="true"] {
  background: color-mix(in srgb, var(--accent, var(--c-bronze-mid)) 8%, transparent);
  border-color: color-mix(in srgb, var(--accent, var(--c-bronze-mid)) 25%, transparent);
}

.mb-grade-cell-letter {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--t-md);
  color: var(--accent, var(--c-bronze-mid));
}

.mb-grade-cell-count {
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  color: var(--c-bronze-mid);
}


/* ============ GRADE BADGE · square plaque on run rows ======================
   36×36 colored square with grade letter. Same `--accent` injection
   pattern as `.mb-grade-cell` — JS sets per row from RUN_GRADES color. */

.mb-grade-badge {
  width: 36px;
  height: 36px;
  border-radius: var(--r-subtle);
  background: color-mix(in srgb, var(--accent, var(--c-bronze-mid)) 12%, transparent);
  border: 2px solid color-mix(in srgb, var(--accent, var(--c-bronze-mid)) 40%, transparent);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: var(--t-md);
  font-weight: 800;
  color: var(--accent, var(--c-bronze-mid));
  flex-shrink: 0;
}


/* ============ STEPPER ROW · meal distribution stepper (Wave 9) =============
   Settings → Ration Style. One row per meal × 4. Each row has a colored
   swatch (--accent set inline from meal palette), the meal name, and a
   −/value/+ stepper triplet. The stepper bottom-totals into `.mb-stepper-total`
   with `data-state="ok|over|under"` driving the success/danger color flip. */

.mb-stepper-row {
  --accent: var(--c-bronze-mid);
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 6px 0;
  border-bottom: var(--rule-thin) solid rgba(138, 125, 58, 0.12);
}
.mb-stepper-row:last-of-type { border-bottom: none; }

.mb-stepper-label {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1;
}

.mb-stepper-swatch {
  width: 8px;
  height: 8px;
  border-radius: 2px;
  background: var(--accent);
}

.mb-stepper-name {
  font-family: var(--font-ui);
  font-size: var(--t-md);
  color: var(--c-bone);
}

.mb-stepper-controls {
  display: flex;
  align-items: center;
  gap: 4px;
}

.mb-stepper-btn {
  width: 28px;
  height: 28px;
  border-radius: var(--r-subtle);
  border: var(--rule-thin) solid rgba(138, 125, 58, 0.25);
  background: rgba(255, 255, 255, 0.04);
  color: var(--c-bone);
  font-family: var(--font-display);
  font-size: var(--t-lg);
  font-weight: 700;
  cursor: pointer;
  transition: background var(--motion-snap), border-color var(--motion-snap);
}
.mb-stepper-btn:hover:not([disabled]):not([aria-disabled="true"]) {
  background: rgba(242, 184, 56, 0.10);
  border-color: var(--c-bronze-top);
}
.mb-stepper-btn[disabled],
.mb-stepper-btn[aria-disabled="true"] {
  background: rgba(255, 255, 255, 0.02);
  color: rgba(232, 220, 192, 0.25);
  cursor: default;
}

.mb-stepper-value {
  --accent: var(--c-bronze-mid);
  min-width: 36px;
  text-align: center;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: var(--t-md);
  color: var(--accent);
  letter-spacing: var(--ls-tight);
}
.mb-stepper-value[data-zero="true"] { color: rgba(138, 125, 58, 0.45); }

.mb-stepper-total {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: var(--s-2);
  padding-top: 6px;
  border-top: var(--rule-thin) solid rgba(242, 184, 56, 0.20);
}
.mb-stepper-total-label {
  font-family: var(--font-display);
  font-size: var(--t-sm);
  letter-spacing: var(--ls-normal);
  color: var(--c-bone);
  text-transform: uppercase;
  font-weight: 700;
}
.mb-stepper-total-value {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: var(--t-md);
}
.mb-stepper-total-value[data-state="ok"]    { color: var(--c-aff-scout); }
.mb-stepper-total-value[data-state="over"],
.mb-stepper-total-value[data-state="under"] { color: var(--c-aff-warrior); }

.mb-stepper-total-help {
  font-family: var(--font-ui);
  font-size: var(--t-xs);
  margin-top: 4px;
  color: var(--c-aff-warrior);
}


/* ============ TOGGLE ROW · settings on/off switch row (Wave 9) =============
   Reusable for any setting expressed as binary on/off. Left side is name +
   description; right side is `.mb-toggle-switch` with `data-on="true|false"`
   driving the success-tinted vs muted visual state. */

.mb-toggle-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--s-2) 0;
  gap: var(--s-3);
}

.mb-toggle-info {
  flex: 1;
  min-width: 0;
}

.mb-toggle-name {
  font-family: var(--font-ui);
  font-size: var(--t-md);
  color: var(--c-bone);
}

.mb-toggle-desc {
  font-family: var(--font-ui);
  font-size: var(--t-xs);
  color: var(--c-bronze-mid);
  margin-top: 2px;
  line-height: 1.45;
}

.mb-toggle-switch {
  padding: 6px var(--s-4);
  border-radius: var(--r-subtle);
  font-family: var(--font-display);
  font-size: var(--t-xs);
  letter-spacing: var(--ls-normal);
  font-weight: 700;
  min-width: 56px;
  text-align: center;
  cursor: pointer;
  background: rgba(255, 255, 255, 0.04);
  border: var(--rule-thin) solid rgba(138, 125, 58, 0.25);
  color: rgba(232, 220, 192, 0.45);
  text-transform: uppercase;
  transition: background var(--motion-snap), border-color var(--motion-snap), color var(--motion-snap);
}
.mb-toggle-switch[data-on="true"] {
  background: color-mix(in srgb, var(--c-aff-scout) 12%, transparent);
  border-color: color-mix(in srgb, var(--c-aff-scout) 40%, transparent);
  color: var(--c-aff-scout);
}


/* ============ PRESET CHIP ROW · ration style quick-select (Wave 9) =========
   Smaller than `.mb-tab` — these are quick-action chips for selecting a
   pre-baked meal distribution (`Standard`, `Athlete`, `OMAD`, etc.). Active
   chip is gold-bordered; inactive is bronze-mid muted. */

.mb-preset-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: var(--s-3);
}

.mb-preset-chip {
  padding: 4px 10px;
  border-radius: var(--r-subtle);
  font-family: var(--font-ui);
  font-size: var(--t-xs);
  letter-spacing: var(--ls-tight);
  cursor: pointer;
  border: var(--rule-thin) solid rgba(138, 125, 58, 0.25);
  background: rgba(255, 255, 255, 0.04);
  color: var(--c-bronze-mid);
  transition: background var(--motion-snap), border-color var(--motion-snap), color var(--motion-snap);
}
.mb-preset-chip:hover { color: var(--c-bone); border-color: var(--c-bronze-mid); }
.mb-preset-chip[data-active="true"] {
  border: 2px solid var(--c-bronze-top);
  background: color-mix(in srgb, var(--c-bronze-top) 12%, transparent);
  color: var(--c-bronze-top);
  padding: 3px 9px;  /* compensate for thicker border */
}


/* ============ BUTTON · tone variants (Wave 9) ==============================
   Adds color-tone modifiers to `.mb-btn` for dev-tools / wipe / export use
   cases where a single screen needs to differentiate primary actions by
   intent. Dev / warn / info / danger. Default `.mb-btn` (gold) remains the
   primary CTA; these are explicit non-primary tones. */

.mb-btn[data-tone="warn"] {
  background: color-mix(in srgb, var(--c-bronze-top) 10%, transparent);
  border-color: color-mix(in srgb, var(--c-bronze-top) 35%, transparent);
  color: var(--c-bronze-top);
}
.mb-btn[data-tone="warn"]:hover {
  background: color-mix(in oklab, var(--c-bronze-top) 18%, transparent);
  color: color-mix(in oklab, var(--c-bronze-top) 80%, white);
}

.mb-btn[data-tone="info"] {
  background: color-mix(in oklab, var(--c-info) 10%, transparent);
  border-color: color-mix(in oklab, var(--c-info) 35%, transparent);
  color: var(--c-info);
}
.mb-btn[data-tone="info"]:hover {
  background: color-mix(in oklab, var(--c-info) 18%, transparent);
  color: color-mix(in oklab, var(--c-info) 70%, white);
}

.mb-btn[data-tone="danger"] {
  background: color-mix(in srgb, var(--c-aff-warrior) 10%, transparent);
  border-color: color-mix(in srgb, var(--c-aff-warrior) 35%, transparent);
  color: var(--c-aff-warrior);
}
.mb-btn[data-tone="danger"]:hover {
  background: color-mix(in oklab, var(--c-aff-warrior) 20%, transparent);
  color: color-mix(in oklab, var(--c-aff-warrior) 60%, white);
}


/* ============ CARD · dev tone (Wave 9) =====================================
   `.mb-card[data-tone="dev"]` opts the card into orange-warning corner
   pixels and a softer header-warning treatment. Used by Dev Tools panels
   that explicitly aren't shipping with the production app. */

.mb-card[data-tone="dev"] {
  border-color: color-mix(in srgb, var(--c-amber) 35%, var(--c-bronze-mid));
}
.mb-card[data-tone="dev"]::before,
.mb-card[data-tone="dev"]::after {
  background: var(--c-amber);
}
.mb-card-title[data-tone="dev"] { color: var(--c-amber); }


/* --------------------------------------------------------------------------
   End of components.css (Wave 9 — settings additions)
   --------------------------------------------------------------------------
   Wave 10+ will add: world-map biome tiles, weekly-summary stat plaques.
   -------------------------------------------------------------------------- */


/* ============ WAVE 11 ADDITIONS — world-map net-new ============ */

/* ── .mb-biome-card · tri-state biome card (current / unlocked / locked) ─────
   Drives styling via [data-state="current|unlocked|locked"].
   [data-complete="true"] on the card turns the meta text success-green. */

.mb-biome-card {
  padding: var(--s-3) var(--s-4);
  margin-bottom: var(--s-1);
  border-radius: var(--r-modal);
  background: rgba(255, 255, 255, 0.02);
  border: var(--rule-thin) solid rgba(255, 255, 255, 0.06);
}
.mb-biome-card:last-child { margin-bottom: 0; }

.mb-biome-card[data-state="current"] {
  background: rgba(251, 191, 36, 0.06);
  border-color: rgba(251, 191, 36, 0.2);
}
.mb-biome-card[data-state="locked"] {
  background: rgba(255, 255, 255, 0.01);
  border-style: dashed;
  border-color: rgba(255, 255, 255, 0.05);
  opacity: 0.4;
}

.mb-biome-card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.mb-biome-card-name {
  display: flex;
  align-items: center;
  gap: var(--s-2);
}
.mb-biome-card-emoji { font-size: var(--t-xl); }
.mb-biome-card-title {
  font-size: var(--t-lg);
  font-weight: 700;
  color: var(--c-bone);
}
.mb-biome-card[data-state="current"] .mb-biome-card-title { color: var(--c-bronze-top); }
.mb-biome-card[data-state="locked"]  .mb-biome-card-title { color: var(--c-stone); }

.mb-biome-card-meta {
  font-size: var(--t-xs);
  color: #94a3b8;
}
.mb-biome-card[data-complete="true"] .mb-biome-card-meta { color: var(--c-aff-scout); }

.mb-biome-card-subtitle {
  font-size: var(--t-tiny);
  color: #64748b;
  margin-top: 2px;
  margin-left: 28px; /* aligns with title text past the emoji */
}


/* ── .mb-node-strip · flex-wrap dot strip for biome node progress ─────────── */

.mb-node-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 3px;
  margin-top: 6px;
  margin-left: 28px;
}

.mb-node-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.06);
  border: var(--rule-thin) solid rgba(255, 255, 255, 0.08);
  transition: background var(--motion-fade);
}
.mb-node-dot[data-state="revealed"] {
  background: var(--c-aff-scout);
  border: none;
}
.mb-node-dot[data-state="current"] {
  background: var(--c-bronze-top);
  border: 2px solid var(--c-bronze-top);
}


/* ── .mb-path-connector · vertical pipe │ between stacked biome cards ─────── */

.mb-path-connector {
  text-align: center;
  padding: 2px 0;
  font-size: var(--t-sm);
  color: rgba(255, 255, 255, 0.06);
}
.mb-path-connector[data-active="true"] {
  color: rgba(255, 255, 255, 0.15);
}

/* ============ END WAVE 11 ADDITIONS ============ */


/* ============ WAVE 10 ADDITIONS ============ */

/* .mb-progress size variants — mini (rank bars, accuracy strips) */
.mb-progress[data-size="mini"]  { height: 4px; margin: 0; }
.mb-progress[data-size="micro"] { height: 6px; margin: 0; }

/* .mb-section-divider — uppercase letterspaced section header (chronicle-hall + weekly-summary) */
.mb-section-divider {
  font-family: var(--font-ui);
  font-size: var(--t-sm);
  font-weight: 700;
  color: var(--c-bone);
  letter-spacing: 0.5px;
  text-transform: uppercase;
  margin: var(--s-8) 0 var(--s-2);
  padding-bottom: var(--s-1);
  border-bottom: 1px solid rgba(138, 125, 58, 0.30);
}
.mb-section-divider:first-child { margin-top: 0; }

/* .mb-stat-quad — 4-up daily totals row (calories / protein / carbs / fat) */
.mb-stat-quad {
  display: flex;
  justify-content: space-around;
  margin-bottom: var(--s-2);
}
.mb-stat-quad-cell { text-align: center; }
.mb-stat-quad-value {
  font-family: var(--font-mono);
  font-size: var(--t-md);
  font-weight: 700;
  color: var(--accent, var(--c-bone));
  letter-spacing: var(--ls-tight);
}
.mb-stat-quad-label {
  font-family: var(--font-ui);
  font-size: 9px;
  color: var(--c-bronze-mid);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

/* .mb-rank-row — ranked-list row: emoji label (96px) + flex bar + value.
   Set `--accent` on the row for current-affinity color emphasis. */
.mb-rank-row {
  display: flex;
  align-items: center;
  gap: var(--s-1);
  padding: 5px 0;
}
.mb-rank-row[data-zero="true"] { opacity: 0.55; }
.mb-rank-label {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 96px;
  flex-shrink: 0;
}
.mb-rank-emoji { font-size: var(--t-md); line-height: 1; }
.mb-rank-name {
  font-size: var(--t-xs);
  color: var(--c-bronze-mid);
  font-weight: 500;
}
.mb-rank-row[data-current="true"] .mb-rank-name {
  color: var(--accent);
  font-weight: 700;
}
.mb-rank-bar { flex: 1; }
.mb-rank-value {
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  color: var(--c-bronze-mid);
  font-weight: 500;
  min-width: 32px;
  text-align: right;
  letter-spacing: var(--ls-tight);
}
.mb-rank-row[data-current="true"] .mb-rank-value {
  color: var(--accent);
  font-weight: 700;
}

/* .mb-week-dots — 7-day weekday dot strip for current-week snapshot */
.mb-week-dots {
  display: flex;
  justify-content: space-around;
  margin-bottom: var(--s-2);
}
.mb-week-day { text-align: center; }
.mb-week-dot {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  margin: 0 auto 2px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  font-weight: 600;
  background: rgba(26, 20, 32, 0.55);
  color: rgba(138, 125, 58, 0.55);
  border: none;
}
.mb-week-dot[data-state="done"] {
  background: var(--c-aff-scout);
  color: var(--c-bg-deep);
}
.mb-week-dot[data-state="today"] {
  background: var(--c-amber);
  color: var(--c-bg-deep);
  border: 2px solid var(--c-amber);
}
.mb-week-day-label {
  font-family: var(--font-ui);
  font-size: 8px;
  color: rgba(138, 125, 58, 0.55);
}
.mb-week-day[data-state="today"] .mb-week-day-label { color: var(--c-amber); }

/* ============ END WAVE 10 ADDITIONS ============ */

/* ============ WAVE 12 ADDITIONS — weekly-summary net-new ============ */

/* .mb-grade-reveal — animated 120×120 grade circle with spring-back cubic-bezier */
.mb-grade-reveal {
  width: 120px; height: 120px;
  border-radius: 50%;
  border: 4px solid var(--accent, var(--c-bone));
  display: flex; align-items: center; justify-content: center;
  flex-direction: column;
  margin: 0 auto var(--s-4);
  background: radial-gradient(circle, color-mix(in oklab, var(--accent, var(--c-bone)) 12%, transparent), transparent);
  opacity: 0;
  transform: scale(0.5);
  transition: opacity 0.8s cubic-bezier(0.34, 1.56, 0.64, 1),
              transform 0.8s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.mb-grade-reveal[data-animate-in="true"] {
  opacity: 1;
  transform: scale(1);
}
.mb-grade-reveal-letter {
  font-size: 48px; font-weight: 900;
  color: var(--accent, var(--c-bone));
  line-height: 1; font-family: var(--font-script);
}
.mb-grade-reveal-label {
  font-size: var(--t-xs); font-weight: 700;
  color: var(--accent, var(--c-bone)); margin-top: 2px;
}

/* .mb-result-card — left-edge accent card (apply alongside .mb-card) */
.mb-result-card {
  border-left: 3px solid var(--accent, var(--c-bronze-mid));
  background: color-mix(in oklab, var(--accent, var(--c-onyx)) 4%, transparent);
}
.mb-result-card-title {
  font-size: var(--t-sm); font-weight: 700;
  color: var(--accent, var(--c-bone));
  display: flex; align-items: center; gap: var(--s-2);
}
.mb-result-card-status {
  margin-left: auto; font-size: var(--t-xs); font-weight: 700;
  padding: 2px var(--s-2); border-radius: var(--r-subtle);
  background: color-mix(in oklab, var(--accent, var(--c-bronze-mid)) 12%, transparent);
  color: var(--accent, var(--c-bronze-mid));
}
.mb-result-card-status[data-tone="success"] { --accent: var(--c-aff-scout); }
.mb-result-card-status[data-tone="warn"]    { --accent: var(--c-amber); }
.mb-result-card-status[data-tone="fail"]    { --accent: var(--c-aff-warrior); }
.mb-result-card-status[data-tone="muted"]   { --accent: var(--c-bronze-mid); }

/* .mb-trend-row — Plateau Watch 3-cell weight trend comparison */
.mb-trend-row { display: flex; justify-content: space-between; gap: var(--s-2); }
.mb-trend-cell {
  flex: 1; text-align: center; padding: var(--s-2) 4px;
  border-radius: var(--r-subtle);
  background: rgba(26, 20, 32, 0.55);
  border: 1px solid rgba(138, 125, 58, 0.30);
}
.mb-trend-cell[data-current="true"] {
  background: color-mix(in oklab, var(--c-amber) 10%, transparent);
  border-color: color-mix(in oklab, var(--c-amber) 20%, transparent);
}
.mb-trend-cell-label { font-size: 10px; color: var(--c-bronze-mid); margin-bottom: 4px; }
.mb-trend-cell-value { font-family: var(--font-mono); font-size: var(--t-md); font-weight: 700; color: var(--c-bone); }
.mb-trend-cell[data-current="true"] .mb-trend-cell-value { color: var(--c-amber); }
.mb-trend-cell-delta { font-size: 10px; margin-top: 2px; }
.mb-trend-cell-delta[data-tone="warn"]    { color: var(--c-amber); }
.mb-trend-cell-delta[data-tone="success"] { color: var(--c-aff-scout); }

/* .mb-quote — italic motivational quote (Cormorant, dim, centered) */
.mb-quote {
  font-family: var(--font-script);
  font-style: italic;
  font-size: var(--t-sm);
  color: rgba(138, 125, 58, 0.55);
  text-align: center;
  margin: var(--s-4) 0;
  padding: 0 var(--s-4);
  line-height: 1.6;
}

/* ============ END WAVE 12 ADDITIONS ============ */


/* ============ WAVE 13 ADDITIONS — onboarding sweep ======================== */

/* .mb-species-card — companion selection card for species-picker.js.
   `--accent` injected per card from species.color (JS inline style).
   `data-state="selected"` applied when this species is active. */
.mb-species-card {
  background: rgba(26, 20, 32, 0.55);
  border: 2px solid rgba(138, 125, 58, 0.30);
  border-radius: var(--r-tile);
  padding: var(--s-4);
  margin-bottom: var(--s-3);
  cursor: pointer;
  transition: background var(--motion-snap), border-color var(--motion-snap);
  text-align: left;
}
.mb-species-card[data-state="selected"] {
  background: color-mix(in oklab, var(--accent, var(--c-bronze-top)) 10%, transparent);
  border-color: var(--accent, var(--c-bronze-top));
}
.mb-species-card-header {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin-bottom: var(--s-2);
}
.mb-species-card-sprite-wrap {
  width: 64px;
  height: 64px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  background: color-mix(in oklab, var(--accent, var(--c-bronze-mid)) 12%, transparent);
  border-radius: var(--r-card);
}
.mb-species-card-name {
  font-weight: 500;
  font-size: var(--t-xl);
  color: var(--c-bone);
}
.mb-species-card[data-state="selected"] .mb-species-card-name {
  color: var(--accent, var(--c-bronze-top));
}
.mb-species-card-archetype {
  font-family: var(--font-script);
  font-style: italic;
  font-size: var(--t-sm);
  color: var(--c-bronze-mid);
}
.mb-species-card-desc {
  font-size: var(--t-sm);
  color: var(--c-bone);
  line-height: 1.5;
  margin-bottom: var(--s-2);
}
.mb-species-card-quote {
  font-family: var(--font-script);
  font-style: italic;
  font-size: var(--t-sm);
  color: var(--accent, var(--c-bronze-mid));
  background: rgba(0, 0, 0, 0.25);
  border-left: 3px solid color-mix(in oklab, var(--accent, var(--c-bronze-mid)) 55%, transparent);
  border-radius: var(--r-card);
  padding: var(--s-2) var(--s-3);
  line-height: 1.4;
}

/* Inline name + begin block on selected card */
.mb-species-card-name-block { margin-top: var(--s-3); }
.mb-species-card-name-label {
  font-family: var(--font-display);
  font-size: var(--t-xs);
  letter-spacing: 2px;
  color: var(--c-bronze-mid);
  text-transform: uppercase;
  margin-bottom: var(--s-2);
}
.mb-species-card-name-input {
  background: var(--c-onyx);
  border: 2px solid color-mix(in oklab, var(--accent, var(--c-bronze-top)) 50%, transparent);
  border-radius: var(--r-card);
  padding: var(--s-3) var(--s-4);
  text-align: center;
  font-size: var(--t-xl);
  font-weight: 500;
  color: var(--c-bone);
  width: 100%;
  outline: none;
  font-family: inherit;
}
.mb-species-card-name-input:focus {
  border-color: var(--accent, var(--c-bronze-top));
  background: rgba(26, 20, 32, 0.85);
}

/* ============ END WAVE 13 ADDITIONS ============ */


/* ============ WAVE 14a ADDITIONS — generic ceremony chrome ============ */

/* .mb-ceremony-page — full-bleed dramatic page chrome for peak-end ceremonial
   moments. Deeper radial vignette than .mb-screen-page; position:relative
   anchors confetti/particle overlay layers. */
.mb-ceremony-page {
  min-height: 100vh;
  padding: var(--s-6) var(--s-5);
  background:
    radial-gradient(ellipse at 50% 35%, var(--c-plum) 0%, var(--c-onyx) 70%),
    var(--c-onyx);
  display: flex;
  flex-direction: column;
  font-family: var(--font-ui);
  color: var(--c-bone);
  position: relative;
  overflow: hidden;
}

/* .mb-ceremony-crest — large central icon container with per-ceremony radial
   glow. JS injects --accent: gold (level-up), biome color (monday-start),
   affinity color (shift), squire color (evolution). */
.mb-ceremony-crest {
  text-align: center;
  padding: var(--s-4) var(--s-3) var(--s-5);
  background: radial-gradient(ellipse at center,
    color-mix(in oklab, var(--accent, var(--c-bronze-top)) 15%, transparent) 0%,
    transparent 70%);
  border-radius: var(--r-modal);
  margin-bottom: var(--s-4);
}
.mb-ceremony-crest-icon {
  font-size: 56px;
  line-height: 1;
  margin-bottom: var(--s-3);
  filter: drop-shadow(0 0 14px color-mix(in oklab, var(--accent, var(--c-bronze-top)) 60%, transparent));
}

/* .mb-ceremony-eyebrow — Forum tracked uppercase announcement text above the
   main ceremony title. "The Guild Assessor Proclaims", "New Expedition", etc. */
.mb-ceremony-eyebrow {
  font-family: var(--font-display);
  font-size: var(--t-xs);
  letter-spacing: 4px;
  color: var(--c-bronze-mid);
  text-transform: uppercase;
  text-align: center;
  margin-bottom: var(--s-2);
}

/* ============ END WAVE 14a ADDITIONS ============ */


/* ============ WAVE 14b ADDITIONS — day-boss-specific chrome ============ */

/* Boss HP bar — the phase-reveal drain bar at the top of the arena */
.mb-boss-hp-bar-bg {
  width: 100%;
  height: 20px;
  background: rgba(255,255,255,0.08);
  border-radius: 10px;
  overflow: hidden;
  position: relative;
}
.mb-boss-hp-bar-fill {
  height: 100%;
  width: 100%;
  background: linear-gradient(90deg, var(--c-aff-warrior), #dc2626);
  border-radius: 10px;
  transition: width 0.8s ease-out;
}

/* Phase dot — one per macro phase, animated by JS on reveal */
.mb-boss-phase-dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: rgba(255,255,255,0.06);
  border: 2px solid rgba(255,255,255,0.15);
  font-size: 14px;
  cursor: default;
}
.mb-boss-phase-label {
  font-size: 9px;
  color: var(--c-bronze-mid);
}

/* Combatant card — Squire and boss side-by-side in the battle arena */
.mb-boss-combatant {
  padding: var(--s-4) var(--s-5);
  border-radius: var(--r-card);
  transition: all 0.6s;
  text-align: center;
}

/* ============ END WAVE 14b ADDITIONS ============ */

/* ============ QTY BUTTON PRIMITIVE (2026-04-29) ============ */
/* 24×24 micro-control for inline qty contexts (+/-, remove, etc.).
   NOT .mb-btn — primary-CTA pattern would balloon the form factor.
   NOT .mb-icon-btn — that selector is owned by hub-town settings gear (Wave 5).
   Used in: snack-log tray rows; meal-encounter tray rows (Wave 15b).
   Variants:
     [data-tone="danger"] — destructive remove; warrior-red tint via color-mix.
*/
.mb-qty-btn {
  width: 24px;
  height: 24px;
  border-radius: var(--r-card);
  border: none;
  background: rgba(255,255,255,0.08);
  color: var(--c-bone);
  font-size: var(--t-lg);
  font-family: inherit;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
  transition: background 120ms ease;
}
.mb-qty-btn:hover {
  background: rgba(255,255,255,0.14);
}
.mb-qty-btn:active {
  transform: scale(0.95);
}
.mb-qty-btn[data-tone="danger"] {
  color: color-mix(in oklab, var(--c-aff-warrior) 90%, var(--c-bone));
}
.mb-qty-btn[data-tone="danger"]:hover {
  background: color-mix(in oklab, var(--c-aff-warrior) 18%, transparent);
}


/* ─── Squire Header Avatar (Wave 20a) ─────────────────────────────────────
   Persistent 32px Squire avatar in the .mb-hud-strip. Tappable → Squire Den.
   Notification dot (::after) communicates highest-priority pending state per §4.3. */

.mb-squire-header-avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px solid var(--accent, var(--c-bronze-mid));
  background: transparent;
  padding: 2px;
  cursor: pointer;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.mb-squire-header-avatar img {
  width: 32px;
  height: 32px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  image-rendering: crisp-edges;
}

/* Notification dot — single highest-priority trigger, per §4.3 */
.mb-squire-header-avatar[data-notification-priority="1"]::after,
.mb-squire-header-avatar[data-notification-priority="2"]::after,
.mb-squire-header-avatar[data-notification-priority="3"]::after,
.mb-squire-header-avatar[data-notification-priority="4"]::after {
  content: '';
  position: absolute;
  top: -2px;
  right: -2px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  border: 1px solid var(--c-onyx);
}

.mb-squire-header-avatar[data-notification-priority="1"]::after { background: var(--c-bronze-mid); }
.mb-squire-header-avatar[data-notification-priority="2"]::after { background: var(--c-amber); }
.mb-squire-header-avatar[data-notification-priority="3"]::after { background: var(--accent, var(--c-bronze-top)); }
.mb-squire-header-avatar[data-notification-priority="4"]::after { background: var(--c-aff-warrior); }

/* Quiet state — avatar recedes during active logging (per §4.1) */
.mb-squire-header-avatar[data-quiet="true"] {
  opacity: 0.5;
}
.mb-squire-header-avatar[data-quiet="true"]::after {
  display: none;
}

/* Stage scaling — Wave 20b carries the full CSS effects; placeholders here keep Stage 5 readable */
.mb-squire-header-avatar[data-stage="5"] {
  width: 40px;
  height: 40px;
}
.mb-squire-header-avatar[data-stage="5"] img {
  width: 36px;
  height: 36px;
}

/* Reduced-motion guard — mandatory per §5.4 accessibility constraint */
@media (prefers-reduced-motion: reduce) {
  .mb-squire-header-avatar {
    transition: none !important;
    animation: none !important;
  }
}

/* ─── Screen Header (Wave 20a-2) ──────────────────────────────────────────
   Wraps .mb-back-link (left) + .mb-squire-header-avatar (right) on screens
   that don't have .mb-hud-strip. */
.mb-screen-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  margin-bottom: var(--s-3);
}
.mb-screen-header .mb-back-link { flex-shrink: 0; }
.mb-screen-header .mb-squire-header-avatar { flex-shrink: 0; }
