/**
 * Character Portrait Styling
 * Clean layout for character portrait and stats
 */

/* Wayfarer's Toy Box is declared in the critical CSS (sass/terraboops.scss), which headings use too */

/* Header Character Portrait: its layout, image and name are in the critical CSS (sass/terraboops.scss) and only
   there; restated here, this file (loaded after the first paint) overrode the phone layout and the page jumped */
.character-portrait:hover {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  border-color: var(--colour-accent-light);
  transform: translateY(-2px);
}

.character-level {
  font-family: 'Wayfarer\'s Toy Box', sans-serif;
  font-size: 0.85rem;
  color: var(--text-secondary, #666);
  font-style: normal;
}

/* Stat Bars */
.stat-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.8rem;
}

.stat-label {
  font-family: 'Wayfarer\'s Toy Box', sans-serif;
  font-size: 1.5rem;
  flex-shrink: 0;
  width: 30px;
  text-align: center;
}

.stat-bar {
  flex: 1;
  height: 28px;
  min-height: 28px;
  background: rgba(0, 0, 0, 0.2);
  border: 2px solid white;
  border-radius: 20px;
  overflow: hidden;
  position: relative;
  min-width: 100px;
  display: block;
}

.health-fill,
.energy-fill,
.xp-fill {
  height: 100%;
  transition: width 0.3s ease;
  border-radius: 18px;
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
}

.health-fill {
  background: linear-gradient(90deg, #22c55e 0%, #4ade80 100%);
  width: 100%;
}

.energy-fill {
  background: linear-gradient(90deg, #3b82f6 0%, #60a5fa 100%);
  width: 100%;
}

.xp-fill {
  background: linear-gradient(90deg, #a855f7 0%, #c084fc 100%);
  width: 0%;
}

.health-stat,
.energy-stat,
.xp-stat {
  font-family: 'Wayfarer\'s Toy Box', sans-serif;
  font-size: 0.9rem;
  font-weight: normal;
  color: white;
  white-space: nowrap;
  position: absolute;
  top: calc(50% + 2px);
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 10;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}

/* Game UI Character Panel (Konami Mode) */
/* Cute Fantasy UI pack: the panel is the pack's large frame, 9-sliced (static/game-assets/ui/parts,
   cut by scripts/ui-pack-parts.py). 12px slices at 3x = 36px borders; `fill` paints the centre. */
.game-character-panel {
  position: fixed;
  top: 20px;
  left: 20px;
  padding: 1rem 1.25rem 1.1rem;
  min-width: 280px;
  max-width: calc(100vw - 40px);
  /* the pack frame at 2x (its 12/18 px slices at 24/36): as crisp as 3x and a third slimmer, so the character
     panel and the bag fit one above the other on a 768 px screen */
  border: 24px solid transparent;
  border-image: url('/game-assets/ui/parts/frame-panel.png') 12 12 18 12 fill / 24px 24px 36px 24px stretch;
  background: #e4a672 padding-box; /* the frame's own parchment under it: a seam where its stretched middle meets an edge shows parchment, not the world */
  image-rendering: pixelated;
  color: #3b2415;
  filter: drop-shadow(0 6px 0 rgba(0, 0, 0, 0.25));
}

/* a button (customization, from the keyboard too), drawn as the portrait alone */
.game-portrait {
  display: block;
  margin: 0 auto 0.75rem;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: center;
  cursor: pointer;
  transition: transform 0.2s ease;
}

.game-portrait:hover {
  transform: scale(1.05);
}

.game-portrait img {
  width: 96px;
  height: 96px;
  border: 3px solid var(--colour-accent-main);
  border-radius: 8px;
  image-rendering: pixelated;
  transition: border-color 0.2s ease;
}

.game-portrait:hover img {
  border-color: var(--colour-accent-light);
}

.game-info {
  text-align: center;
  margin-bottom: 0.7rem;
  padding-bottom: 0.7rem;
  border-bottom: 3px solid #b5713f;
}

.game-info .character-name {
  font-family: 'Wayfarer\'s Toy Box', sans-serif;
  font-size: 1.5rem;
  font-weight: normal;
  margin-bottom: 0.25rem;
  line-height: 1;
}

.game-info .character-level {
  font-family: 'Wayfarer\'s Toy Box', sans-serif;
  font-size: 0.9rem;
}

.game-stat-bars {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}

.game-stat-bars .stat-row {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.game-stat-bars .stat-label {
  font-family: 'Wayfarer\'s Toy Box', sans-serif;
  font-size: 1.35rem;
  font-weight: normal;
  width: 100%;
  text-align: left;
}

/* Scoped under .game-ui so these outrank the dark-theme .stat-bar rule below. */
.game-ui .game-stat-bars .stat-bar {
  /* Pack bar sprites are 30x5; the track and the fills scale to the bar box (pixelated). */
  height: 30px;
  width: 100%;
  border: 0;
  border-radius: 0;
  background: url('/game-assets/ui/parts/bar-track.png') no-repeat;
  background-size: 100% 100%;
  image-rendering: pixelated;
}

.game-ui .game-stat-bars .health-fill,
.game-ui .game-stat-bars .energy-fill,
.game-ui .game-stat-bars .xp-fill {
  border-radius: 0;
  background-repeat: no-repeat;
  background-size: 100% 100%;
  image-rendering: pixelated;
  /* The fill sprite is sized to the whole bar and clipped by the element width, so the right cap
     travels with the fill instead of squashing. */
  background-attachment: scroll;
}

/* bar-*-full: the pack's fills end in a dark stub that, scaled up, made a full bar look short */
.game-ui .game-stat-bars .health-fill { background-image: url('/game-assets/ui/parts/bar-red-full.png'); }
.game-ui .game-stat-bars .energy-fill { background-image: url('/game-assets/ui/parts/bar-blue-full.png'); }
.game-ui .game-stat-bars .xp-fill { background-image: url('/game-assets/ui/parts/bar-green-full.png'); }

.game-stat-bars .health-stat,
.game-stat-bars .energy-stat,
.game-stat-bars .xp-stat {
  color: #fff;
  text-shadow: 1px 1px 0 #000;
}

/* ---- Pack bitmap font (Font-3.png: the pack's Font.png, 6px caps + digits, with ' É Ə ʷ ʔ added for the story signs and a
   third row for [ ] * " (every prompt's [E], the animals' *lines*)), rendered by frontend/src/ui/bitmap-font.ts ---- */
.pxf {
  --pxf-scale: 3;
  display: inline-block;
  vertical-align: middle;
  width: calc(var(--gw) * var(--pxf-scale) * 1px);
  height: calc(8 * var(--pxf-scale) * 1px);
  margin-right: calc(1px * var(--pxf-scale));
  background-image: url('/game-assets/ui/Font-3.png');
  background-repeat: no-repeat;
  background-size: calc(160px * var(--pxf-scale)) calc(24px * var(--pxf-scale));
  background-position: calc(var(--gx) * var(--pxf-scale) * -1px) calc(var(--gy) * var(--pxf-scale) * -1px);
  image-rendering: pixelated;
}

.pxf-word {
  white-space: nowrap;
}

.pxf--space {
  width: calc(3px * var(--pxf-scale));
  background: none;
}

/* Pack icons (UI_Icons.png) beside the stat labels, drawn at 2x. */
.game-stat-bars .stat-label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.ui-icon {
  display: inline-block;
  width: 28px;
  height: 30px;
  background-repeat: no-repeat;
  background-size: 100% 100%;
  image-rendering: pixelated;
  flex-shrink: 0;
}

.ui-icon--heart { background-image: url('/game-assets/ui/parts/icon-heart.png'); }
.ui-icon--bolt { width: 24px; background-image: url('/game-assets/ui/parts/icon-bolt.png'); }
.ui-icon--star { background-image: url('/game-assets/ui/parts/icon-star.png'); }

/* white pack glyphs on the parchment read only with their dark shadow (2:1 without it), as the bar numbers below have */
.game-stat-bars .stat-label .pxf,
.game-info .character-name .pxf { --pxf-scale: 3; filter: drop-shadow(2px 2px 0 #000); }
.game-stat-bars .health-stat .pxf,
.game-stat-bars .energy-stat .pxf,
.game-stat-bars .xp-stat .pxf { --pxf-scale: 2; filter: drop-shadow(1px 1px 0 #000); }

.game-stat-bars .health-stat,
.game-stat-bars .energy-stat,
.game-stat-bars .xp-stat {
  font-family: 'Wayfarer\'s Toy Box', sans-serif;
  font-size: 1rem;
}

/* Exit Hint */
.exit-hint {
  position: fixed;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  max-width: calc(100vw - 40px);
  color: #3b2415;
  padding: 0.5rem 1rem;
  border: 24px solid transparent;
  border-image: url('/game-assets/ui/parts/frame-small.png') 8 fill / 24px stretch;
  image-rendering: pixelated;
  font-size: 1rem;
  font-weight: bold;
  filter: drop-shadow(0 4px 0 rgba(0, 0, 0, 0.25));
}

/* Dark Theme Support */
[data-theme="dark"] .character-portrait {
  background: var(--colour-bg-secondary);
  border-color: var(--colour-accent-main);
}

[data-theme="dark"] .character-name {
  color: var(--colour-text-primary);
}

[data-theme="dark"] .character-level {
  color: var(--colour-text-secondary);
}

[data-theme="dark"] .portrait-image img {
  border-color: var(--colour-accent-main);
}

[data-theme="dark"] .stat-bar {
  background: rgba(255, 255, 255, 0.1);
  border-color: rgba(255, 255, 255, 0.2);
}

[data-theme="dark"] .game-character-panel {
  /* The pack frame paints the panel in both themes. */
  background: none;
  border-color: transparent;
}

[data-theme="dark"] .game-info {
  border-bottom-color: var(--colour-accent-main);
}

/* Responsive Design */
@media (max-width: 768px) {
  /* the header tile's phone sizes are in the critical CSS (sass/terraboops.scss), so the first paint has them */
  .character-level {
    font-size: 0.75rem;
  }

  .stat-row {
    font-size: 0.7rem;
  }

  .stat-label {
    font-size: 0.85rem;
    width: 18px;
  }

  .stat-bar {
    height: 10px;
    min-width: 60px;
  }

  .game-character-panel {
    min-width: 220px;
    padding: 1rem;
    top: 10px;
    left: 10px;
  }

  .game-portrait img {
    width: 72px;
    height: 72px;
  }
}

/* Accessibility */
@media (prefers-reduced-motion: reduce) {
  .character-portrait,
  .health-fill,
  .energy-fill,
  .xp-fill {
    transition: none;
  }
}

/* ---- Selkirk Valley level banner (Konami HUD) ---- */
.level-banner {
  position: fixed;
  top: 20px;
  right: 20px;
  /* one panel on every level: the width is set, and each line below keeps its room when it has nothing to say (a
     one-line name, a room with no season or map credit), so the corner does not change size as levels load */
  width: min(420px, calc(100vw - 40px));
  padding: 0.5rem 1rem 0.75rem;
  border: 36px solid transparent;
  border-image: url('/game-assets/ui/parts/frame-panel.png') 12 12 18 12 fill / 36px 36px 54px 36px stretch;
  background: #e4a672 padding-box; /* the frame's own parchment under it: a seam where its stretched middle meets an edge shows parchment, not the world */
  image-rendering: pixelated;
  color: #3b2415;
  text-align: center;
  filter: drop-shadow(0 6px 0 rgba(0, 0, 0, 0.25));
  transition: opacity 0.4s ease;
}

.level-banner[hidden] { display: none; }

.level-banner__region { font-size: 0.8rem; letter-spacing: 0.08em; opacity: 0.8; }
/* the name's glyphs are 24 px tall (3x): its words (bitmap-font.ts: a word is one unbreakable run, a space its own
   box) wrap as flex items with 10 px of leading between lines, and the block holds two lines, a one-line name
   centred in them */
.level-banner__name { margin: 0.35rem 0; min-height: 64px; display: flex; flex-wrap: wrap; justify-content: center; align-content: center; row-gap: 10px; }
/* the map credit on levels drawn from OpenStreetMap: set apart by a stitched rule, in small caps */
.level-banner__attribution {
  margin-top: 0.55rem;
  padding-top: 0.45rem;
  border-top: 2px dashed rgba(59, 36, 21, 0.3);
  font-family: 'Wayfarer\'s Toy Box', monospace;
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  font-variant: small-caps;
  line-height: 1.4;
  min-height: calc(2 * 1.4em + 0.45rem + 2px); /* the credit's two lines (with its rule: border-box), kept on a level without one */
  opacity: 0.85; /* the game's words are never dimmed below 0.85 (5.1:1 on the parchment) */
}
.level-banner__attribution:empty,
.level-banner__season:empty { visibility: hidden; }
.level-banner__season { margin-top: 0.2rem; font-size: 0.85em; opacity: 0.9; min-height: 16px; line-height: 16px; }

/* ---- Selkirk Valley: prompt, toast, bag, crafting (Konami HUD) ---- */
.game-prompt,
.game-toast {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  width: max-content;
  max-width: calc(100vw - 40px);
  padding: 0.35rem 0.9rem;
  border: 20px solid transparent;
  border-image: url('/game-assets/ui/parts/frame-small.png') 8 fill / 20px stretch;
  background: #e4a672 padding-box; /* the frame's own parchment under it: a seam where its stretched middle meets an edge shows parchment, not the world */
  image-rendering: pixelated;
  color: #3b2415;
  font-family: 'Wayfarer\'s Toy Box', monospace;
  font-size: 1rem;
  filter: drop-shadow(0 4px 0 rgba(0, 0, 0, 0.25));
}

.game-prompt { bottom: 126px; } /* a clear step above the "Press ESC" hint, not touching it */
/* the open bag (bottom left) would be painted over the prompt and cut its first words off: while it is open the prompt
   keeps to the room right of it (to the toolbar), centred there and wrapping; --bag-right is kept by main.ts */
body:has(#inventory[data-open="true"]) .game-prompt {
  left: calc(var(--bag-right, 336px) + 16px);
  right: 96px;
  margin-inline: auto;
  transform: none;
  max-width: calc(100vw - var(--bag-right, 336px) - 112px);
}
.game-toast { top: 20px; left: 50%; transition: opacity 0.3s ease; }
.game-prompt[hidden], .game-toast[hidden], .craft-panel[hidden] { display: none; }

.inventory {
  position: fixed;
  left: 20px;
  bottom: 20px;
  width: max-content;
  /* the pack frame at 2x (its 12/18 px slices at 24/36): as crisp as 3x and a third slimmer, so the character
     panel and the bag fit one above the other on a 768 px screen */
  border: solid transparent;
  border-width: 12px 12px 18px;
  border-image: url('/game-assets/ui/parts/frame-panel.png') 12 12 18 12 fill / 12px 12px 18px 12px stretch;
  background: #e4a672 padding-box; /* the frame's own parchment under it: a seam where its stretched middle meets an edge shows parchment, not the world */
  image-rendering: pixelated;
  color: #3b2415;
  filter: drop-shadow(0 6px 0 rgba(0, 0, 0, 0.25));
}
/* open, it is the full panel: wide enough for "Strawberry seeds x99", and ends clear of the centred
   "Press ESC" box on a 1280 px screen */
.inventory[data-open="true"] {
  width: 316px;
  padding: 0.5rem 0.75rem 0.75rem;
  border-width: 24px 24px 36px;
  border-image-width: 24px 24px 36px 24px;
  /* it grows upward with what it holds: it stops 12 px short of the character panel above it (--panel-bottom, kept
     by main.ts) and its body scrolls, as the craft panel's does, rather than paint over the health and energy bars */
  box-sizing: border-box;
  max-height: calc(100vh - var(--panel-bottom, 490px) - 32px);
  display: flex;
  flex-direction: column;
}
.inventory[data-open="true"] .inventory__body { min-height: 0; overflow-y: auto; }
/* while it scrolls, the body reaches into the panel's right padding by its scrollbar's width (up to the 12 px of
   padding; --bag-scrollbar is measured by main.ts), so the scrollbar sits in the padding and not over the rows: a
   name that fits the bag at rest still fits on one line when the bag scrolls ("Seed catalogue", "Cactus flower") */
.inventory[data-open="true"] .inventory__body { margin-right: calc(-1 * min(var(--bag-scrollbar, 0px), 0.75rem)); }
/* one scroll for the whole bag, not a second one inside its list */
.inventory[data-open="true"] .inventory__list { max-height: none; overflow: visible; }

.inventory__toggle {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  margin: 0;
  padding: 2px 4px;
  border: 0;
  background: none;
  color: inherit;
  font: 0.8rem/1 'Wayfarer\'s Toy Box', monospace;
  cursor: pointer;
}
.inventory__toggle:focus-visible { outline: 2px solid #3b2415; outline-offset: 2px; }
.inventory__icon { width: 32px; height: 32px; image-rendering: pixelated; }
.inventory__count:empty { display: none; }
.inventory__key {
  margin-left: auto;
  padding: 1px 5px;
  border: 2px solid currentColor;
  border-radius: 4px;
  font: inherit;
  opacity: 0.85; /* a quiet key cap, still 5.1:1 (the game's text is never dimmed below 0.85: 4.11:1 at 0.75) */
}
.inventory__body { margin-top: 0.5rem; }
.inventory__body[hidden] { display: none; }
.inventory__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.3rem; max-height: 220px; overflow: auto; }
.inventory__list li { display: flex; justify-content: space-between; gap: 0.25rem; white-space: nowrap; }
.inventory__list li b { flex-shrink: 0; }
.inventory .pxf { --pxf-scale: 2; }
.inventory[data-has-items="true"] .inventory__saved { margin: 0.5rem 0 0.25rem; font-family: 'Wayfarer\'s Toy Box', monospace; font-size: 0.7rem; } /* full ink: at 0.75 it was 4.14:1 */
.inventory__new-game {
  font: inherit;
  font-family: 'Wayfarer\'s Toy Box', monospace;
  font-size: 0.75rem;
  padding: 0.2rem 0.5rem;
  border: 2px solid currentColor;
  border-radius: 4px;
  background: transparent;
  color: inherit;
  cursor: pointer;
}
.inventory__new-game[data-armed="true"] { background: #a33a2a; color: #fff; border-color: #a33a2a; }
.inventory__new-game:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

.craft-panel {
  position: fixed;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: min(420px, calc(100vw - 40px));
  /* never taller than the screen: the shop's list of goods ran off the bottom, so nothing past the first few could
     be reached; the list scrolls inside the panel, and the title and Close stay put */
  max-height: calc(100vh - 40px);
  display: flex;
  flex-direction: column;
  padding: 0.5rem 0.75rem 0.75rem;
  border: 36px solid transparent;
  border-image: url('/game-assets/ui/parts/frame-panel.png') 12 12 18 12 fill / 36px 36px 54px 36px stretch;
  background: #e4a672 padding-box; /* the frame's own parchment under it: a seam where its stretched middle meets an edge shows parchment, not the world */
  image-rendering: pixelated;
  color: #3b2415;
  z-index: 2100;
  filter: drop-shadow(0 6px 0 rgba(0, 0, 0, 0.3));
}

.craft-panel__list { list-style: none; margin: 0 0 0.5rem; padding: 0 4px 0 0; display: grid; gap: 0.35rem; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.craft-panel__title, .craft-panel__close { flex-shrink: 0; }
/* one card shape for every recipe: an icon column held open (a recipe without an icon keeps its text in line), the
   name in the pack font at 2x, wrapping between its words when it is long, the note under it */
.craft-panel__list button {
  display: grid;
  grid-template-columns: 32px minmax(0, 1fr);
  column-gap: 0.6rem;
  align-items: center;
  width: 100%;
  text-align: left;
  padding: 0.35rem 0.6rem;
  border: 12px solid transparent;
  border-image: url('/game-assets/ui/parts/button.png') 5 fill / 12px stretch;
  image-rendering: pixelated;
  background: none;
  color: #3b2415;
  font-family: 'Wayfarer\'s Toy Box', monospace;
  font-size: 0.95rem;
  cursor: pointer;
}
/* a recipe you cannot make yet keeps its words at full ink (dimmed whole, its name was 2.2:1 and its needs 1.9:1, and
   at the start of a save every recipe is one); the picture says it is out of reach */
.craft-panel__list button[disabled] { cursor: default; }
.craft-panel__list button[disabled] > .bag-icon { opacity: 0.4; filter: grayscale(1); }
.craft-panel__list button > .bag-icon { grid-column: 1; grid-row: 1 / span 2; }
.craft-panel__list button > span,
.craft-panel__list button > small { grid-column: 2; }
/* "Buy strawberry seeds x2" is 240 px in a 220 px column: on one line its count ran past the panel and the list
   scrolled sideways; every word of every recipe fits the column alone (tests/unit/selkirk-systems.test.ts) */
.craft-panel__list button > span { white-space: normal; }
.craft-panel__list button > span .pxf { --pxf-scale: 2; }
.craft-panel__list small { display: block; font-family: 'Wayfarer\'s Toy Box', monospace; font-size: 0.7rem; opacity: 0.85; }
/* the way out of the panel is a pack button like the recipes above it (it was an unstyled browser button: small,
   white and in the system face, it read as broken rather than as Close) */
.craft-panel__close, .too-small__leave {
  display: block;
  margin: 0.25rem 0 0 auto;
  padding: 0.25rem 0.75rem;
  border: 12px solid transparent;
  border-image: url('/game-assets/ui/parts/button.png') 5 fill / 12px stretch;
  image-rendering: pixelated;
  background: none;
  color: #3b2415;
  font-family: 'Wayfarer\'s Toy Box', monospace;
  font-size: 0.9rem;
  cursor: pointer;
}
.craft-panel__close:hover, .too-small__leave:hover { border-image-source: url('/game-assets/ui/parts/button-pressed.png'); }
.craft-panel__close:focus-visible, .too-small__leave:focus-visible { outline: 2px solid #3b2415; outline-offset: 2px; }

.game-ui .inventory,
.game-ui .game-prompt,
.game-ui .game-toast,
.game-ui .craft-panel,
.game-ui .game-portrait { pointer-events: auto; } /* the portrait opens the customisation screen */

/* Pack item icons (static/game-assets/cf/icons, 16px cells) in the bag and crafting panel */
.bag-icon {
  display: inline-block;
  width: 32px;
  height: 32px;
  margin-right: 0.4rem;
  vertical-align: middle;
  background-repeat: no-repeat;
  background-position: calc(var(--ix) * -32px) calc(var(--iy) * -32px);
  image-rendering: pixelated;
  flex-shrink: 0;
}
.bag-icon--food { background-image: url('/game-assets/cf/icons/food.png'); background-size: 256px 384px; }
.bag-icon--resources { background-image: url('/game-assets/cf/icons/resources.png'); background-size: 192px 192px; }
.bag-icon--tools { background-image: url('/game-assets/cf/icons/tools.png'); background-size: 320px 32px; }

/* Tools: a column on the right edge; the one in hand is raised. 1-5 choose, F uses, Space jumps. */
.toolbar {
  position: fixed;
  right: 20px;
  /* anchored above the bottom-right corner (clear of the map credit), not centred: centred, its top slots
     ran into the level banner that opens in the top-right corner on every level */
  bottom: 88px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  pointer-events: auto;
}
.toolbar__slot {
  position: relative;
  display: grid;
  place-items: center;
  width: 60px;
  height: 60px;
  padding: 0;
  border: 12px solid transparent;
  border-image: url('/game-assets/ui/parts/frame-small.png') 8 fill / 12px stretch;
  background: #e4a672 padding-box; /* the frame's own parchment under it: a seam where its stretched middle meets an edge shows parchment, not the world */
  image-rendering: pixelated;
  cursor: pointer;
  filter: drop-shadow(0 4px 0 rgba(0, 0, 0, 0.25));
  transition: transform 0.1s ease;
}
.toolbar__slot .bag-icon { margin: 0; }
.toolbar__slot b {
  position: absolute;
  right: -6px;
  bottom: -8px;
  font: 11px/1 'Wayfarer\'s Toy Box', monospace;
  color: #3b2415;
}
/* the tool in hand is marked inside its own box, so the column keeps both edges and its even gaps: the icon grows
   and an accent ring sits just inside the frame (a grown slot stuck out of the column and squeezed its neighbours).
   The ring is its own box, not the outline: the outline is the keyboard focus ring, and must show on this slot too */
.toolbar__slot[aria-pressed="true"]::after {
  content: '';
  position: absolute;
  inset: -4px;
  border: 2px solid #e57052;
  pointer-events: none;
}
.toolbar__slot[aria-pressed="true"] .bag-icon { transform: scale(1.2); }
.bag-icon--fruit { background-image: url('/game-assets/cf/seasonal/fruit-objects.png'); background-size: 160px 32px; }
/* where the icon sheets have no picture, the item's own sprite, every one a 16 px cell drawn at 2x like the icons: the
   bench is its wooden 32 px cell halved and re-outlined (bench-icon-16.png; at 1x its pixels were half the others') */
.bag-icon--flowers { background-image: url('/game-assets/decorations/flowers.png'); background-size: 320px 320px; }
.bag-icon--fences { background-image: url('/game-assets/decorations/outdoor/Fences.png'); background-size: 128px 128px; }
.bag-icon--benches { background-image: url('/game-assets/decorations/outdoor/bench-icon-16.png'); background-size: 32px 32px; }
.bag-icon--boots { background-image: url('/game-assets/cf/player/boots-red-icon-16.png'); background-size: 32px 32px; }
.bag-icon--cactusflower { background-image: url('/game-assets/cf/desert/cactus-flower-icon-16.png'); background-size: 32px 32px; }
.bag-icon--broom { background-image: url('/game-assets/cf/icons/broom-icon-16.png'); background-size: 32px 32px; }
.bag-icon--cheese { background-image: url('/game-assets/cf/icons/cheese-icon-16.png'); background-size: 32px 32px; }
.bag-icon--catalogue { background-image: url('/game-assets/cf/icons/catalogue-icon-16.png'); background-size: 32px 32px; }
.bag-icon--truffle { background-image: url('/game-assets/cf/icons/truffle-icon-16.png'); background-size: 32px 32px; }
.bag-icon--pie { background-image: url('/game-assets/cf/icons/pie-slice-icon-16.png'); background-size: 32px 32px; }
.bag-icon--bouquet { background-image: url('/game-assets/cf/icons/bouquet-icon-16.png'); background-size: 32px 32px; }
.bag-icon--wildflower { background-image: url('/game-assets/cf/icons/wildflower-icon-16.png'); background-size: 32px 32px; }
.bag-icon--fencepost { background-image: url('/game-assets/cf/icons/fence-icon-16.png'); background-size: 32px 32px; }
.bag-icon--dunebook { background-image: url('/game-assets/cf/icons/dunebook-icon-16.png'); background-size: 32px 32px; }
/* what is worn sits under the items, a rule apart */
.inventory__worn { margin-top: 6px; padding-top: 6px; border-top: 2px dotted rgba(59, 36, 21, 0.4); }
.inventory__worn[hidden] { display: none; }
/* the quest log, a rule apart again (each line says open or done; not dimmed, which would cost its contrast) */
.inventory__quests { margin-top: 6px; padding-top: 6px; border-top: 2px dotted rgba(59, 36, 21, 0.4); }
.inventory__quests[hidden] { display: none; }
/* a quest's line wraps rather than giving way at the edge as a long item name does: all of it is the point */
/* a quest's task has the row's whole width, its state on the line under it (beside it, a short name broke before
   its last word); the bag's rows are nowrap, a quest's may break between words */
.inventory__list.inventory__quests li { flex-direction: column; align-items: flex-start; justify-content: flex-start; gap: 2px; white-space: normal; }
.inventory__list.inventory__quests li > span:first-of-type { flex: none; overflow: visible; }
.inventory__list li { align-items: center; min-width: 0; }
/* a long name wraps between its words rather than run under the count ("Strawberry seeds" is 190 px; the cell is 166,
   151 once the bag scrolls, 137 beside a count of x99): the count stays beside it, centred on the row. Every word of
   every item fits the narrowest cell on its own (tests/unit/selkirk-systems.test.ts), so nothing is cut mid-word */
.inventory__list li > span:first-of-type { flex: 1; min-width: 0; white-space: normal; }
/* a food's row is a button (eaten on a click): the row's own look, the whole width, lit under the pointer */
.inventory__use { display: flex; align-items: center; gap: 0.25rem; width: 100%; min-width: 0; padding: 0; border: 0; border-radius: 4px; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.inventory__use > span:first-of-type { flex: 1; min-width: 0; white-space: normal; text-align: left; }
.inventory__use > b { flex-shrink: 0; }
/* at rest too, a food's name says it can be clicked: a dotted line under each word (the name is bitmap glyphs, so
   the line is the words' own border, not text-decoration) */
.inventory__use > span:first-of-type .pxf-word { border-bottom: 2px dotted rgba(59, 36, 21, 0.6); }
@media (hover: hover) { .inventory__use:hover { background: rgba(59, 36, 21, 0.12); } }

/* Pack bitmap text on the light tan panels: the Font.png glyphs are white, which washes out on tan, so here they
   are drawn in the panels' own ink (the glyph sheet as a mask, so every pixel stays crisp). The character panel's
   labels keep white with their dark drop shadow. */
.level-banner .pxf,
.game-prompt .pxf,
.game-toast .pxf,
.exit-hint .pxf,
.inventory__title .pxf,
.inventory__count .pxf,
.inventory__list .pxf,
.craft-panel__title .pxf,
.craft-panel__list .pxf {
  background-image: none;
  background-color: #3b2415;
  -webkit-mask-image: url('/game-assets/ui/Font-3.png');
  mask-image: url('/game-assets/ui/Font-3.png');
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-size: calc(160px * var(--pxf-scale)) calc(24px * var(--pxf-scale));
  mask-size: calc(160px * var(--pxf-scale)) calc(24px * var(--pxf-scale));
  -webkit-mask-position: calc(var(--gx) * var(--pxf-scale) * -1px) calc(var(--gy) * var(--pxf-scale) * -1px);
  mask-position: calc(var(--gx) * var(--pxf-scale) * -1px) calc(var(--gy) * var(--pxf-scale) * -1px);
}
/* a word space is an empty glyph box: no ink in it (the mask would otherwise leave a solid bar) */
.level-banner .pxf--space,
.game-prompt .pxf--space,
.game-toast .pxf--space,
.exit-hint .pxf--space,
.inventory__title .pxf--space,
.inventory__count .pxf--space,
.inventory__list .pxf--space,
.craft-panel__title .pxf--space,
.craft-panel__list .pxf--space { background-color: transparent; }

/* short screens (768-820 px tall): a smaller portrait keeps the character panel clear of the bag below it */
@media (max-height: 820px) {
  .game-ui .game-portrait img { width: 72px; height: 72px; }
}

/* the level banner reads as a title card: the level's name large, the valley above it and the season below it
   smaller */
.level-banner__region .pxf, .level-banner__season .pxf { --pxf-scale: 2; }
.level-banner__region { opacity: 0.85; } /* 5.1:1; at 0.75 the valley's name was 4.11:1 */

/* The exit hint is a quiet reminder, not a headline: 2x type, short words, so it sits between the bag and the
   map credit even at 1024 px. While the level banner is up (top right), a toast drops below it instead of
   running into it. */
.exit-hint .pxf { --pxf-scale: 2; }
.level-banner:not([hidden]) ~ .game-toast { top: 290px; }
/* a toast lives in the gap between the character panel (left) and the toolbar (right): long ones (a combat
   reward) wrap onto a second line instead of running over either */
.game-toast { max-width: min(640px, calc(100vw - 680px)); text-align: center; }

/* ---- How to play --------------------------------------------------------------------------------------------
   One small "?" in the bottom-right corner instead of tips across the screen. It opens a short click-through
   (a screenshot, the keys as pack buttons, one line each), and pulses until it has been opened once. */
.help-button {
  position: fixed;
  right: 20px;
  bottom: 20px;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  padding: 0;
  border: 10px solid transparent;
  border-image: url('/game-assets/ui/parts/frame-small.png') 8 fill / 10px stretch;
  background: none;
  image-rendering: pixelated;
  cursor: pointer;
  pointer-events: auto;
  filter: drop-shadow(0 4px 0 rgba(0, 0, 0, 0.25));
}
.help-button img { width: 32px; height: 32px; image-rendering: pixelated; }
.help-button:focus-visible { outline: 3px solid #3b2415; outline-offset: 3px; }
@media (hover: hover) { .help-button:hover { transform: translateY(-2px); } }
.help-button[data-new] { animation: help-nudge 1.6s ease-in-out infinite; }
@keyframes help-nudge { 0%, 70%, 100% { transform: translateY(0); } 80% { transform: translateY(-5px); } 90% { transform: translateY(0); } }
@media (prefers-reduced-motion: reduce) { .help-button[data-new] { animation: none; } }
/* in play the map credit sits beside the "?" as its pair: the HUD's 20 px grid, the same 52 px box */
body.konami-mode .map-credit { right: 80px; bottom: 20px; border-width: 10px; border-image-width: 10px; }

.help-dialog {
  margin: auto;
  width: min(560px, calc(100vw - 32px));
  padding: 4px 12px 8px;
  border: solid transparent;
  border-width: 24px 24px 36px;
  border-image: url('/game-assets/ui/parts/frame-panel.png') 12 12 18 12 fill / 24px 24px 36px 24px stretch;
  background: #e4a672 padding-box; /* the frame's own parchment under it: a seam where its stretched middle meets an edge shows parchment, not the world */
  image-rendering: pixelated;
  color: #3b2415;
  pointer-events: auto; /* .game-ui, its parent, lets clicks through to the game */
}
.help-dialog::backdrop { background: rgba(20, 12, 8, 0.55); }
/* the panel's own ink: the site's heading accent (h1-h6, terraboops.scss) is salmon, 1.5:1 on the parchment */
.help-dialog__title { margin: 0 0 10px; font: 1.25rem/1.2 'Wayfarer\'s Toy Box', monospace; color: #3b2415; }
.help-pages { list-style: none; margin: 0; padding: 0; }
.help-page[hidden] { display: none; }
.help-page__shot {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  border: 3px solid #3b2415;
  border-radius: 4px;
  image-rendering: auto;
  background: #1a1320;
}
.help-page__keys { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; margin: 12px 0 6px; }
.help-page__text { margin: 0 0 10px; text-align: center; font: 1rem/1.4 'Wayfarer\'s Toy Box', monospace;
  min-height: 2.8em; /* two lines on every page, so a caption that wraps does not grow the dialog as you page */ }
.key {
  display: inline-grid;
  place-items: center;
  min-width: 44px;
  height: 44px;
  padding: 0 4px;
  border: 6px solid transparent;
  border-image: url('/game-assets/ui/parts/button.png') 5 fill / 8px stretch;
  image-rendering: pixelated;
  color: #3b2415;
  font: 0.85rem/1 'Wayfarer\'s Toy Box', monospace;
}
.key--icon img { width: 32px; height: 32px; image-rendering: pixelated; } /* 2x the pack's 16 px, crisp */
.help-dialog__nav { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.help-dialog__count { font: 0.85rem/1 'Wayfarer\'s Toy Box', monospace; opacity: 0.85; }
.help-dialog__button {
  min-width: 96px;
  padding: 0.25rem 0.75rem;
  border: 12px solid transparent;
  border-image: url('/game-assets/ui/parts/button.png') 5 fill / 12px stretch;
  image-rendering: pixelated;
  background: none;
  color: #3b2415;
  font: 0.9rem/1 'Wayfarer\'s Toy Box', monospace;
  cursor: pointer;
}
/* Back on the first page: hidden in place while there is nowhere to go (dimmed to 0.35 it was 1.81:1 text) */
.help-dialog__button:disabled { visibility: hidden; }
.help-dialog__button:focus-visible, .help-dialog__close:focus-visible { outline: 2px solid #3b2415; outline-offset: 2px; }
.help-dialog form { position: absolute; top: 6px; right: 8px; margin: 0; }
.help-dialog__close { border: 0; background: none; color: #3b2415; font: 1.6rem/1 system-ui, sans-serif; cursor: pointer; padding: 2px 6px; }

/* ---- A window smaller than the game in play (the game starts only from 1024 x 768: main.ts) ----
   Below that the world no longer fits (under 768 px wide the page hides it altogether) and the HUD panels pile onto
   each other, so the world is covered and the reason given; it lifts as soon as the window is big enough again. */
.too-small { display: none; }
@media (max-width: 1023px), (max-height: 767px) {
  .too-small {
    display: flex;
    align-items: center;
    justify-content: center;
    position: fixed;
    inset: 0;
    z-index: 2500; /* over every HUD panel (the craft panel is 2100) */
    padding: 16px;
    background: rgba(20, 12, 8, 0.85);
    pointer-events: auto; /* .game-ui lets clicks through to the game; none reach it behind this */
  }
}
.too-small__card {
  width: min(420px, 100%);
  box-sizing: border-box;
  padding: 4px 12px 8px;
  border: solid transparent;
  border-width: 24px 24px 36px;
  border-image: url('/game-assets/ui/parts/frame-panel.png') 12 12 18 12 fill / 24px 24px 36px 24px stretch;
  background: #e4a672 padding-box;
  image-rendering: pixelated;
  color: #3b2415;
  text-align: center;
  font: 1rem/1.45 system-ui, sans-serif;
}
.too-small__card p { margin: 0; }
.too-small__title { margin-bottom: 10px; }
.too-small__title .pxf { --pxf-scale: 3; }
.too-small__leave { margin: 12px auto 0; }
