/* Needle in a Haystack -- late afternoon in a hayfield, seen from the working end.
   Deep teal shade, straw gold, and a bright teal pen you can spot from the
   far side of the yard. */

:root {
  --ink: #0d2a2c;
  --ink-2: #14393b;
  --ink-3: #1d4c4d;
  --straw: #e3b455;
  --straw-bright: #f6d98a;
  --pen: #59e0c8;
  /* Money is its own colour, and it is green. Everything the goat pays you
   * says so: the sign that floats off a deposit and the line that says what
   * was banked. The teal above is the pen, the marker and the buttons, and a
   * payout wearing it read as one more piece of the interface rather than as
   * being paid. */
  --cash: #6ee06a;
  --cash-bright: #a6f79c;
  --paper: #f6f0e0;
  --paper-dim: #c9c2ad;
  --danger: #e2705a;
  --shadow: 0 10px 30px rgba(6, 22, 24, 0.45);
  --radius: 14px;
  --pad: 14px;
  --safe-t: env(safe-area-inset-top, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-l: env(safe-area-inset-left, 0px);
  --safe-r: env(safe-area-inset-right, 0px);
}

* { box-sizing: border-box; }

/* Every panel in this page is a flex or grid box, and an author display rule
   beats the browser's own [hidden]. Without this, "hidden" is a suggestion. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;
  /* The yard's sunset, the same as the loading card's, so no moment before
     the first frame of the game is ever a dark screen. */
  background:
    radial-gradient(ellipse 120% 70% at 50% 100%, rgba(255, 168, 82, 0.55) 0%, rgba(255, 168, 82, 0) 60%),
    linear-gradient(180deg, #2f5f9c 0%, #6d86ad 42%, #e7a35c 78%, #6b3f1c 100%) fixed;
  color: var(--paper);
  font-family: "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior: none;
  touch-action: none;
}

body { position: fixed; inset: 0; }

#scene {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  touch-action: none;
  cursor: crosshair;
}

/* ---------------- buttons ---------------- */

.btn {
  appearance: none;
  border: 1px solid rgba(246, 240, 224, 0.28);
  background: rgba(20, 57, 59, 0.86);
  color: var(--paper);
  font: inherit;
  font-weight: 600;
  font-size: 0.95rem;
  padding: 10px 16px;
  border-radius: 10px;
  cursor: pointer;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  justify-content: center;
  transition: background 0.12s ease, transform 0.08s ease, border-color 0.12s ease;
  -webkit-tap-highlight-color: transparent;
}
.btn:hover { background: rgba(29, 76, 77, 0.95); border-color: rgba(246, 240, 224, 0.45); }
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: 3px solid var(--pen); outline-offset: 2px; }

.btn-primary {
  background: var(--straw);
  color: #22190a;
  border-color: rgba(255, 255, 255, 0.35);
}
.btn-primary:hover { background: var(--straw-bright); }

.btn-quiet { background: rgba(20, 57, 59, 0.5); color: var(--paper-dim); }
.btn-small { font-size: 0.85rem; padding: 7px 12px; min-height: 40px; }
.btn-round { border-radius: 999px; min-width: 74px; height: 74px; padding: 0 12px; font-size: 0.86rem; }
.btn-icon { min-width: 40px; padding: 7px 10px; font-size: 1rem; }
.btn:disabled { opacity: 0.45; cursor: not-allowed; transform: none; }

kbd {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.72rem;
  background: rgba(246, 240, 224, 0.14);
  border: 1px solid rgba(246, 240, 224, 0.22);
  border-radius: 5px;
  padding: 1px 5px;
  margin-left: 5px;
}
.btn-primary kbd { background: rgba(34, 25, 10, 0.16); border-color: rgba(34, 25, 10, 0.25); color: #22190a; }

/* ---------------- HUD ---------------- */

.hud {
  position: absolute;
  inset: 0;
  pointer-events: none;
  display: flex;
  flex-direction: column;
  /* Down from the top, not spread between both ends. The bar of numbers and
     the notices are the only two things left in the flow up there, and the
     notices belong directly under the numbers on every screen rather than at
     a height that happens to be free on one of them. The bottom block pushes
     itself down instead. */
  justify-content: flex-start;
  padding: calc(var(--pad) + var(--safe-t)) calc(var(--pad) + var(--safe-r)) calc(var(--pad) + var(--safe-b)) calc(var(--pad) + var(--safe-l));
  transition: opacity 0.25s ease;
}
.hud[aria-hidden="true"] { opacity: 0; }
.hud > * { pointer-events: none; }
.hud button { pointer-events: auto; }

.hud-top {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  flex-wrap: wrap;
}

.stat {
  background: rgba(13, 42, 44, 0.62);
  border: 1px solid rgba(246, 240, 224, 0.14);
  border-radius: 12px;
  padding: 5px 12px 7px;
  display: flex;
  flex-direction: column;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  min-width: 0;
}
.stat-label {
  font-size: 0.63rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--paper-dim);
  white-space: nowrap;
}
.stat-value {
  font-size: 1.18rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
  white-space: nowrap;
}
.stat.money .stat-value { color: var(--straw-bright); font-size: 1.38rem; }
/* The kick this value gives when it goes up is asked for from the HUD, not
   from a class: see `_bumpMoney` in ui.js for why it is not a keyframe rule. */

.hud-buttons { margin-left: auto; display: flex; gap: 8px; }
/* Phones only: a computer pauses with Escape. */
.btn-pause { display: none; }
body.touch .btn-pause { display: inline-flex; align-items: center; justify-content: center; }
.btn-pause {
  position: absolute;
  top: calc(var(--pad) + var(--safe-t));
  right: calc(var(--pad) + var(--safe-r));
}
/* Room for it at the end of the top row, beside the ?. */
body.touch .hud-buttons { margin-right: 48px; }
.btn-pause svg { width: 18px; height: 18px; display: block; }

/* The shop, next to the money it is spent from. The money sits in the corner
   from the first minute and the shop was a word on the far side of the screen,
   so a player could earn for a long time without noticing there was anywhere
   to spend it. The dot is the other half of that: it pulses while there is
   something in the shop they can afford right now, and goes away when there is
   not, which is the only moment the shop has anything to say. */
/* The key that opens it is printed on the button, hanging off its bottom edge
   the way a keyboard cap would. A shop is opened with Tab and there was no way
   to know that from the screen: the button said the word and nothing said the
   key. A phone has no Tab, so the chip is the decorative half of the button
   there and the cart alone is what is pressed. */
.shop-slot {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0;
}
.shop-tab {
  font-size: 0.55rem;
  line-height: 1.3;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--paper-dim);
  background: rgba(13, 42, 44, 0.86);
  border: 1px solid rgba(246, 240, 224, 0.18);
  border-radius: 6px;
  padding: 0 6px 1px;
  margin-top: -4px;
  position: relative;
  z-index: 1;
}
.shop-badge { position: relative; padding: 6px 8px; }
.shop-badge .cart { display: block; width: 20px; height: 20px; }
.shop-dot {
  position: absolute;
  top: 0;
  right: 0;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: #e8483c;
  box-shadow: 0 0 0 2px rgba(13, 42, 44, 0.92);
  animation: shop-dot 1.15s ease-in-out infinite;
}
@keyframes shop-dot {
  0%, 100% { transform: scale(0.82); opacity: 0.72; }
  50% { transform: scale(1.26); opacity: 1; }
}

/* The gather dial.
 *
 * Under the crosshair, because gathering is done by looking at the hay and
 * holding a button, and the thing that says how the hold is going belongs
 * where the eyes already are. It is only in the DOM's way while a button is
 * down: between holds it is hidden outright, so the middle of the view is the
 * view. The prompt plate slides down out of its way rather than the dial being
 * moved off the middle, because the middle is where it has to be.
 *
 * A ring rather than a bar. A bar across the middle answers "how full am I",
 * which the arms gauge in the corner already answers with a number, and it
 * answers it for the whole hold, so a player watching it has no idea whether
 * the next bundle is a moment away or five seconds. A ring that sweeps and
 * snaps back answers "how long is this one taking", once per bundle, which is
 * the question you actually have while holding the button down. */
.collect {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: var(--dial);
  height: var(--dial);
  /* Forty per cent down from where it was. It is the cursor now as well as the
     readout, so it is on screen whenever there is hay in reach rather than only
     while a button is down, and at the old size that was a ring the width of
     your thumb parked over the middle of the view for most of a dig. Small
     enough to be a cursor, big enough to read a three figure count inside. */
  --dial: min(11.4vmin, 77px);
  pointer-events: none;
}
.collect-ring {
  width: 100%;
  height: 100%;
  display: block;
  /* Twelve o'clock is where a sweep starts. */
  transform: rotate(-90deg);
}
.collect-ring circle {
  fill: none;
  stroke-width: 9;
  stroke-linecap: round;
}
.ring-track {
  stroke: rgba(9, 30, 32, 0.66);
}
.ring-fill {
  stroke: #f2d489;
  /* 2 * pi * 52, matching the r in the markup: the sweep is one attribute to
     set per frame and no layout at all. */
  stroke-dasharray: 326.73;
  stroke-dashoffset: 326.73;
  filter: drop-shadow(0 0 5px rgba(242, 212, 137, 0.5));
}
/* Up with nothing in it: the cursor as a ring, with no count and no word,
   because nothing has been pulled yet. */
.collect.idle .collect-mid { display: none; }
.collect.idle .ring-track { stroke: rgba(9, 30, 32, 0.5); }
/* Feeding the goat pays rather than fills, and the ring says so by turning the
   colour of the trough it is going into. */
.collect.pay .ring-fill {
  stroke: #7ff0dd;
  filter: drop-shadow(0 0 5px rgba(127, 240, 221, 0.5));
}
.collect-mid {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  text-align: center;
}
.collect-mid b {
  font-size: 0.95rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--paper);
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.75);
  line-height: 1;
}
.collect-mid span {
  font-size: 0.42rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--paper-dim);
  text-shadow: 0 1px 5px rgba(0, 0, 0, 0.8);
}
/* The gather dial is up, and the dial lives in the middle of the view. The
   block steps UP out of the ring's way, into the free space above it: down is
   where the controls are now, and there is nothing below the words to step
   into. */
.prompt-wrap.shift { transform: translateY(-16px); }

.crosshair {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 7px;
  height: 7px;
  transition: transform 0.12s ease, opacity 0.15s ease;
}
/* A point, and only a point: a round dot with a dark halo so it stays legible
   over straw, over a barn wall and over the sky. */
.crosshair span {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: rgba(255, 253, 246, 0.95);
  box-shadow: 0 0 0 1.5px rgba(9, 30, 32, 0.55), 0 0 6px rgba(0, 0, 0, 0.85);
}
/* Something to pull. The point does not grow into anything itself: the ring
   from the dial opens around it, and the dot inside turns the colour of the
   sweep so the two read as one thing. */
.crosshair.aim span { background: var(--straw-bright); }
.crosshair.hidden { opacity: 0; }

.prompt-wrap {
  /* Directly above the controls, in the flow, and never at a height of its
     own. It used to be pinned to a fraction of the window, which is right on
     exactly the screen that fraction was chosen on: the block is three lines
     tall now, and on a phone held upright or a laptop held landscape the
     pinned height put the sweeping line straight through the tool chips. The
     bottom block is a different height on every screen, so the only place
     reliably clear of it is the space immediately above it, and the flex
     column is what knows where that is. */
  align-self: center;
  margin: auto 0 22px;
  text-align: center;
  width: min(92%, 460px);
  /* The prompt is the one thing that has to be readable over whatever the
     player happens to be looking at, and over the pale cap of the collection
     bay a drop shadow alone left the second line invisible at the exact
     moment it mattered. A soft plate with no edge fixes it on every
     background without turning into a box. */
  padding: 10px 22px;
  background: radial-gradient(
    105% 72% at 50% 50%,
    rgba(9, 30, 32, 0.74) 0%,
    rgba(9, 30, 32, 0.40) 62%,
    rgba(9, 30, 32, 0) 100%
  );
  transition: opacity 0.18s ease, transform 0.16s ease;
}
/* Nothing to say, so nothing to show. The plate is there to make the words
   readable; with no words it is only a grey band across the middle of the
   view, which on a phone held upright lies over the stack itself. */
.prompt-wrap.quiet {
  opacity: 0;
}
.prompt {
  font-size: 0.86rem;
  font-weight: 700;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.9);
  color: var(--paper);
  min-height: 1.3em;
}
.prompt.pay { color: var(--pen); }
.prompt.win-prompt { color: var(--straw-bright); font-size: 1.04rem; animation: pulse 1.1s ease-in-out infinite; }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.62; } }
.prompt-sub {
  font-size: 0.72rem;
  color: #ded7c2;
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.95), 0 0 12px rgba(0, 0, 0, 0.7);
  min-height: 1.1em;
  margin-top: 3px;
}

.hud-bottom {
  /* The space above the controls belongs to the prompt block, which asks for
     all of it: the controls and the words travel down together and the words
     are always the thing directly above the buttons. */
  margin-top: 0;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
}

.gauges { display: flex; flex-direction: column; gap: 7px; width: min(46vw, 300px); }
.gauge {
  background: rgba(13, 42, 44, 0.62);
  border: 1px solid rgba(246, 240, 224, 0.14);
  border-radius: 10px;
  padding: 5px 9px 7px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.gauge[hidden] { display: none; }
.gauge-head {
  display: flex;
  justify-content: space-between;
  font-size: 0.66rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--paper-dim);
  margin-bottom: 4px;
}
.gauge-bar {
  height: 9px;
  background: rgba(246, 240, 224, 0.14);
  border-radius: 5px;
  overflow: hidden;
}
.gauge-bar i {
  display: block;
  height: 100%;
  width: 0%;
  background: linear-gradient(90deg, var(--straw) 0%, var(--straw-bright) 100%);
  border-radius: 5px;
  transition: width 0.09s linear;
}
.gauge-hopper .gauge-bar i { background: linear-gradient(90deg, #3aa79a 0%, var(--pen) 100%); }
.gauge.full .gauge-bar i { background: linear-gradient(90deg, #d96b4f 0%, #f0a05a 100%); }

.hud-right { display: flex; flex-direction: column; align-items: flex-end; gap: 10px; }

.tools { display: flex; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
.tool-chip {
  /* The arrow above a freshly bought chip is drawn outside the button's own
     box, so the button is what it is positioned against. */
  position: relative;
  background: rgba(13, 42, 44, 0.72);
  border: 1px solid rgba(246, 240, 224, 0.2);
  color: var(--paper);
  border-radius: 10px;
  padding: 7px 11px;
  font: inherit;
  font-size: 0.78rem;
  font-weight: 600;
  cursor: pointer;
  min-height: 40px;
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: 6px;
  -webkit-tap-highlight-color: transparent;
}
.tool-chip .key {
  font-size: 0.66rem;
  opacity: 0.7;
  font-family: ui-monospace, Menlo, monospace;
}
/* The tool in hand.
 *
 * This is the answer to "what am I holding", and it is asked while looking at
 * the middle of the screen with a tool's worth of money already spent. A gold
 * fill alone was not an answer: on a bright yard of straw it is a warm chip
 * among warm chips, and the one that is lit has to be readable from the corner
 * of an eye. So it is gold AND ringed AND lit: the outline and the glow are
 * drawn outside the box, which is what keeps the row from reflowing every time
 * the player switches tools. */
.tool-chip.selected {
  background: linear-gradient(180deg, var(--straw-bright) 0%, var(--straw) 100%);
  color: #22190a;
  border-color: #fff3cf;
  font-weight: 800;
  outline: 3px solid rgba(233, 197, 106, 0.55);
  outline-offset: 1px;
  box-shadow: 0 0 14px rgba(233, 197, 106, 0.45);
}
.tool-chip.selected .key { opacity: 1; color: #5a4715; }
/* Dimming a translucent chip to a third does not read as "not yours yet" over
   a bright field of straw, it reads as a smudge. An unowned tool keeps its
   contrast and loses its warmth instead. */
.tool-chip.locked {
  background: rgba(13, 42, 44, 0.55);
  color: rgba(246, 240, 224, 0.62);
  border-color: rgba(246, 240, 224, 0.14);
  border-style: dashed;
}

/* A tool that has just been bought and is not in hand yet.
 *
 * It is the only chip that moves, and it has to be, because it is asking for
 * something: the player is looking at the middle of the screen with a new tool
 * they have never held, and the answer is a button at the bottom edge of it.
 * It moves in the two ways that cost nothing: the glow grows outward and the
 * whole chip lifts, both of which are painted outside the box, so nothing in
 * the row reflows while it is lit and the other buttons stay where the thumb
 * left them. The colours are set flat as well as animated, so a visitor who has
 * asked for no motion still gets a chip that is unmistakably the live one.
 *
 * It was a thin gold ring on a dark chip before, and the report was that the
 * equipment highlighting is not noticeable enough to find. It is now the
 * brightest object in the HUD: a solid ring, a breathing halo, a lift, and on a
 * phone a word, because a phone has no number key to read and the thing that
 * has to be communicated is not which key it is but that it wants pressing. */
.tool-chip.highlight {
  border-style: solid;
  border-color: #fff3cf;
  background: rgba(122, 96, 30, 0.95);
  color: #fff3cf;
  font-weight: 800;
  outline: 4px solid rgba(246, 217, 138, 0.8);
  outline-offset: 1px;
  z-index: 2;
  animation: chipWants 0.9s ease-in-out infinite;
}
/* AN ARROW OVER THE BUTTON YOU HAVE JUST BOUGHT.
 *
 * A bought rake lands in the row along the bottom and the row is four chips of
 * the same shape in the corner of the eye, so "you now own a rake, and it is
 * that one" was carried by colour alone, and colour alone is a message you can
 * miss while looking at the middle of the screen. The arrow is the words.
 *
 * It is the chip's own ::before and ::after, so it is attached to the button
 * rather than to the corner of the screen: the row wraps on a phone, the chips
 * move, and an arrow drawn at a fixed place would point at whatever ended up
 * there. It is gated on the same `highlight` class the colour is, so it
 * appears the moment the tool is bought and is gone the moment it is picked
 * up, with nothing in the game having to remember to hide it. */
.tool-chip.highlight::before,
.tool-chip.highlight::after {
  content: "";
  position: absolute;
  left: 50%;
  pointer-events: none;
}
/* The shaft. */
.tool-chip.highlight::before {
  bottom: calc(100% + 12px);
  width: 4px;
  height: 16px;
  margin-left: -2px;
  border-radius: 2px;
  background: #fff3cf;
  box-shadow: 0 0 8px 2px rgba(233, 197, 106, 0.75);
  animation: chipArrow 0.9s ease-in-out infinite;
}
/* The head, a triangle pointing down at the chip. */
.tool-chip.highlight::after {
  bottom: calc(100% + 2px);
  width: 0;
  height: 0;
  margin-left: -9px;
  border-left: 9px solid transparent;
  border-right: 9px solid transparent;
  border-top: 11px solid #fff3cf;
  filter: drop-shadow(0 0 6px rgba(233, 197, 106, 0.85));
  animation: chipArrow 0.9s ease-in-out infinite;
}
@keyframes chipArrow {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(5px); }
}

.tool-chip .tip {
  font-size: 0.6rem;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: #fff3cf;
}
/* A keyboard has the number printed on the chip; a thumb does not, so the word
   is the whole message there and the number is the whole message here. */
body:not(.touch) .tool-chip .tip { display: none; }
@keyframes chipWants {
  0%, 100% { box-shadow: 0 0 0 0 rgba(233, 197, 106, 0.12); transform: translateY(0); }
  50% { box-shadow: 0 0 22px 7px rgba(233, 197, 106, 0.6); transform: translateY(-3px); }
}
@media (prefers-reduced-motion: reduce) {
  /* Motion is the loudest half of this, and a visitor who has asked for none
     still gets the colours, the solid ring and the lift. */
  .tool-chip.highlight { animation: none; transform: translateY(-3px); box-shadow: 0 0 18px 4px rgba(233, 197, 106, 0.45); }
  /* The arrow stays, and stops moving. A visitor who has asked for no motion
     is asking not to be bounced at, not to be left guessing which of four
     identical chips they have just paid for. */
  .tool-chip.highlight::before,
  .tool-chip.highlight::after { animation: none; }
}

/* There is no keyboard on a phone, so a shortcut hint is a wide label for a
   fact nobody can use. "locked" and "L2" are not shortcuts and they stay. */
body.touch .tool-chip .key { display: none; }
body.touch .tool-chip.locked .key,
body.touch .tool-chip .key.lvl-tag { display: inline; }
body.touch .tools { gap: 5px; }
body.touch .tool-chip {
  padding: 4px 7px;
  min-height: 36px;
  gap: 4px;
  font-size: 0.68rem;
}
body.touch .tool-chip .key { font-size: 0.6rem; }

.touch-actions { display: none; gap: 12px; align-items: center; }
.btn-action {
  min-width: 104px;
  height: 84px;
  border-radius: 18px;
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: 0.03em;
  background: rgba(20, 57, 59, 0.9);
  border: 1px solid rgba(246, 240, 224, 0.35);
}
.btn-action.pay { background: var(--pen); color: #10322c; border-color: #b7f6e8; }
.btn-action.shiny { background: var(--straw-bright); color: #2b1f06; border-color: #fff3cf; }
.btn-action:disabled { opacity: 0.4; }

body.touch .touch-actions { display: flex; }
body.touch .crosshair { opacity: 0.55; }

/* Notices about the tool in your hand: what you just picked up, what you
   cannot pick up yet.

   Down the left edge, in a column, left aligned. They used to be a stack
   centred in the middle of the view, which put a list of small print over the
   exact thing the player was looking at, and made every one of them a caption
   under the game rather than a note beside it. On the left they read as what
   they are, an edge of the screen that tells you what happened, and the middle
   of the view stays the game. */
.toasts {
  /* In the flow, directly under the top bar, on the left. It used to be pinned
     to a height, which put it in the middle of the screen on a tall window and
     on top of the prompt column on a short one: the top bar is a different
     height on every screen, so the only place that is reliably clear of both
     is the one measured from the bar itself. */
  align-self: flex-start;
  margin-top: 10px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  width: min(64%, 360px);
}
.toast {
  background: rgba(13, 42, 44, 0.9);
  border: 1px solid rgba(246, 240, 224, 0.2);
  border-left: 3px solid var(--straw);
  border-radius: 9px;
  padding: 8px 13px;
  font-size: 0.86rem;
  font-weight: 600;
  text-align: left;
  animation: toastIn 0.22s ease;
  box-shadow: var(--shadow);
}
.toast.good { border-left-color: var(--pen); }
.toast.bad { border-left-color: var(--danger); }
/* A payout, as opposed to a plain bit of good news. */
.toast.money { border-left-color: var(--cash); }
.toast.money, .toast.money b { color: var(--cash-bright); }
.toast.out { animation: toastOut 0.3s ease forwards; }
@keyframes toastIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes toastOut { to { opacity: 0; transform: translateY(-8px); } }

/* money that floats up off a deposit */
.coin-pop {
  position: absolute;
  font-weight: 800;
  font-size: 1.05rem;
  color: var(--cash-bright);
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.9), 0 0 14px rgba(110, 224, 106, 0.45);
  pointer-events: none;
  animation: coinUp 1.05s ease-out forwards;
  font-variant-numeric: tabular-nums;
}
/* A critical hit: the middle circle goes gold for a moment. */
.collect.crit { animation: critPulse 0.6s ease-out; }
.collect.crit .ring-track { stroke: rgba(255, 196, 40, 0.85); }
.collect.crit .ring-fill { stroke: #ffd23f; filter: drop-shadow(0 0 10px rgba(255, 200, 40, 0.95)); }
.collect.crit .collect-mid b { color: #ffd23f; }
.collect.crit .collect-ring { border-radius: 50%; background: radial-gradient(circle, rgba(255, 210, 63, 0.55) 0%, rgba(255, 190, 40, 0.18) 55%, rgba(255, 190, 40, 0) 72%); }
@keyframes critPulse {
  0% { scale: 1; }
  30% { scale: 1.28; }
  100% { scale: 1; }
}
.crit-pop {
  position: absolute;
  left: 50%;
  top: calc(50% - 58px);
  z-index: 6;
  font-weight: 900;
  font-size: 1.2rem;
  letter-spacing: 0.03em;
  color: #ffd23f;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.9), 0 0 16px rgba(255, 190, 40, 0.7);
  pointer-events: none;
  white-space: nowrap;
  animation: critUp 1.25s ease-out forwards;
}
@keyframes critUp {
  from { opacity: 0; transform: translate(-50%, 0) scale(0.7); }
  18% { opacity: 1; transform: translate(-50%, -14px) scale(1.15); }
  to { opacity: 0; transform: translate(-50%, -70px) scale(1); }
}
/* What an opened chest gave. */
.chest-banner {
  position: absolute;
  left: 50%;
  top: 34%;
  z-index: 7;
  transform: translate(-50%, -50%);
  pointer-events: none;
  animation: bannerLife 3.1s ease-out forwards;
}
.chest-banner-text {
  display: block;
  position: relative;
  z-index: 1;
  padding: 10px 18px 12px;
  border-radius: 14px;
  background: rgba(60, 10, 8, 0.78);
  border: 1px solid rgba(255, 120, 100, 0.55);
  color: #fff1d6;
  font-weight: 900;
  font-size: clamp(1rem, 3.6vmin, 1.5rem);
  white-space: nowrap;
  text-shadow: 0 0 14px rgba(255, 70, 50, 0.8);
  box-shadow: 0 0 28px rgba(255, 50, 30, 0.45);
}
.chest-spark {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 8px;
  height: 8px;
  margin: -4px 0 0 -4px;
  border-radius: 50%;
  background: radial-gradient(circle, #fff 0%, #ff5a3c 45%, rgba(255, 40, 20, 0) 75%);
  opacity: 0;
  animation: sparkOut 1.3s ease-out forwards;
}
@keyframes sparkOut {
  0% { opacity: 1; transform: translate(0, 0) scale(1.4); }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(0.4); }
}
@keyframes bannerLife {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(0.6); }
  12% { opacity: 1; transform: translate(-50%, -50%) scale(1.08); }
  20% { transform: translate(-50%, -50%) scale(1); }
  80% { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -60%) scale(1); }
}
@keyframes coinUp {
  from { opacity: 0; transform: translate(-50%, 0) scale(0.85); }
  20% { opacity: 1; transform: translate(-50%, -12px) scale(1.08); }
  to { opacity: 0; transform: translate(-50%, -64px) scale(1); }
}

/* The sweeping pill: what the tool is telling you about where the needle is.
   It sits in the prompt column, last of the three, so it is under the words
   and moves with them rather than landing on top of them. */
.detector {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
  background: rgba(13, 42, 44, 0.7);
  border: 1px solid rgba(89, 224, 200, 0.4);
  border-radius: 999px;
  padding: 4px 13px 4px 6px;
  font-size: 0.78rem;
  color: var(--pen);
  font-variant-numeric: tabular-nums;
}
.detector-arrow {
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  color: var(--pen);
  transition: transform 0.08s linear;
}
.detector-arrow::before { content: "\25B2"; font-size: 1.15rem; }
.detector.hot { border-color: var(--straw-bright); color: var(--straw-bright); }
.detector.hot .detector-arrow { color: var(--straw-bright); }

/* The goat's line is no longer a panel of the HUD. It is a dialogue box over
   the animal's own head, in the yard, drawn by the renderer with the same
   canvas-and-texture the board over the trough is painted with, so it is
   subject to the camera and not to a breakpoint. The rules that laid out a
   strip of screen for it are gone with it; the hill of comments that stood
   here argued over which fraction of a phone it should be pinned to, and the
   answer turned out to be none of them. */


/* ---------------- screens ---------------- */

.screen {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: calc(16px + var(--safe-t)) calc(16px + var(--safe-r)) calc(16px + var(--safe-b)) calc(16px + var(--safe-l));
  overflow: auto;
  overscroll-behavior: contain;
  z-index: 10;
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(227, 180, 85, 0.20) 0%, rgba(13, 42, 44, 0) 58%),
    linear-gradient(180deg, rgba(13, 42, 44, 0.90) 0%, rgba(9, 30, 32, 0.97) 100%);
  animation: fadeIn 0.2s ease;
}
.screen[hidden] { display: none; }
.screen-dark { background: rgba(9, 30, 32, 0.90); backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); }
/* The title is the one screen with a whole world built to stand behind it, and
   at 90 percent it was a picture of a dark rectangle. The card carries its own
   near-opaque panel, so the scrim only has to hold the edges down. */
#screen-title {
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(227, 180, 85, 0.20) 0%, rgba(13, 42, 44, 0) 58%),
    linear-gradient(180deg, rgba(13, 42, 44, 0.40) 0%, rgba(9, 30, 32, 0.72) 100%);
}
/* Help is a note pinned into the corner of the running game, not a screen over
   it. It used to be a full scrim with a card in the middle, and the frame that
   came out of it was an instructions panel with no game in it: the yard, the
   HUD, the shop icon and whatever the player was looking at were all gone. The
   card keeps its own panel, the screen behind it is nothing at all, and the
   HUD stays up because showScreen treats help as the one screen that is not
   modal. Nothing here is allowed to cover the middle of the view. */
#screen-help {
  background: none;
  animation: none;
  pointer-events: none;
  align-items: flex-start;
  justify-content: flex-start;
  padding: calc(70px + var(--safe-t)) 12px 12px calc(12px + var(--safe-l));
  overflow: hidden;
}
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

.panel {
  width: min(680px, 100%);
  background: linear-gradient(180deg, rgba(20, 57, 59, 0.96) 0%, rgba(13, 42, 44, 0.97) 100%);
  border: 1px solid rgba(246, 240, 224, 0.17);
  border-radius: 20px;
  padding: clamp(18px, 3.4vw, 34px);
  box-shadow: var(--shadow);
  max-height: 100%;
  overflow: auto;
}
.panel-narrow { width: min(460px, 100%); }
/* The pause menu's two volume sliders: a name, the track, and the number. */
.volume-rows { display: grid; gap: 10px; margin: 2px 0 16px; }
.volume-row {
  display: grid;
  grid-template-columns: 4.2em 1fr 2.2em;
  align-items: center;
  gap: 12px;
  font-weight: 700;
  color: var(--paper);
}
.volume-num { text-align: right; font-variant-numeric: tabular-nums; color: var(--paper-dim); font-size: 0.9rem; }
.volume-slider {
  width: 100%;
  height: 32px;
  margin: 0;
  accent-color: var(--straw-bright);
  cursor: pointer;
  touch-action: pan-y;
}
/* The card sits under the money, top left, and stops well short of the middle
   of the screen: the stack has to be the thing in the picture. */
.panel-help {
  width: min(430px, 44vw);
  max-height: 84%;
  pointer-events: auto;
  padding: 10px 13px;
  font-size: 0.86rem;
  box-shadow: 0 10px 30px rgba(6, 20, 22, 0.5);
}
.panel-help .help-list { font-size: 0.84rem; }

/* The note is read at a glance, so its two lists stay side by side whatever
   the screen does: stacked, they are taller than the card. */
.panel-help .controls-card { grid-template-columns: 1fr 1fr; gap: 6px 15px; padding-top: 9px; margin-top: 0; }
.panel-help .controls-card ul { font-size: 0.8rem; line-height: 1.5; }
.help-line { margin: 0; font-size: 0.82rem; line-height: 1.5; color: #ded7c2; }
.help-line b { color: var(--straw-bright); }
/* The card can be taller than a landscape phone, and it scrolls. The way out
   sits at the top of it, where it is on screen the moment the card opens,
   rather than at the foot of a list nobody has scrolled to yet. */
.help-head {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 0 0 8px;
  padding: 0 0 8px;
  background: rgba(18, 52, 54, 0.99);
  border-bottom: 1px solid rgba(246, 240, 224, 0.10);
}
.help-head h2 { margin: 0; }
.help-head .btn { flex: none; }
.panel-shop { width: min(1080px, 100%); display: flex; flex-direction: column; padding: 0; overflow: hidden; }
.panel-win { width: min(600px, 100%); text-align: center; position: relative; }

h1.title {
  font-size: clamp(2rem, 7vw, 3.1rem);
  margin: 0 0 6px;
  letter-spacing: -0.02em;
  color: var(--straw-bright);
  line-height: 1.02;
}
.subtitle { margin: 0 0 14px; font-size: clamp(0.95rem, 2.6vw, 1.1rem); color: var(--paper-dim); font-weight: 600; }
.lede { margin: 0 0 20px; font-size: 0.94rem; line-height: 1.55; color: #e6dfcb; }
.lede b { color: var(--straw-bright); }

.title-actions { display: flex; gap: 10px; flex-wrap: wrap; margin: 4px 0 12px; }
.panel-win .title-actions { justify-content: center; }

.save-note { font-size: 0.82rem; color: var(--paper-dim); min-height: 1.2em; margin-bottom: 12px; }
.save-note.saved { color: var(--pen); }
.save-note.error { color: var(--danger); }

.controls-card {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px 22px;
  border-top: 1px solid rgba(246, 240, 224, 0.14);
  padding-top: 15px;
  margin-top: 6px;
}
.controls-card h3 { margin: 0 0 7px; font-size: 0.74rem; text-transform: uppercase; letter-spacing: 0.1em; color: var(--straw); }
.controls-card ul { margin: 0; padding-left: 17px; font-size: 0.85rem; line-height: 1.62; color: #ded7c2; }
.controls-card li + li { margin-top: 3px; }

/* ---------------- shop ---------------- */

.shop-head {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 18px clamp(16px, 2.6vw, 26px);
  border-bottom: 1px solid rgba(246, 240, 224, 0.14);
  flex-wrap: wrap;
  background: rgba(9, 30, 32, 0.5);
  position: sticky;
  top: 0;
  z-index: 2;
}
.shop-head h2 { margin: 0 0 3px; font-size: 1.5rem; color: var(--straw-bright); }
.shop-sub { margin: 0; font-size: 0.84rem; color: var(--paper-dim); max-width: 46ch; }
.shop-money {
  margin-left: auto;
  background: rgba(13, 42, 44, 0.8);
  border: 1px solid rgba(227, 180, 85, 0.4);
  border-radius: 12px;
  padding: 5px 14px 7px;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
}
.shop-money .stat-value { color: var(--straw-bright); font-size: 1.35rem; }

.shop-scroll { overflow: auto; padding: 6px clamp(14px, 2.6vw, 26px) 26px; }
.shop-section {
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--straw);
  margin: 20px 0 10px;
}
/* TWO HUNDRED AND TWENTY, and the number is a window that has to fit four
   across rather than a card width anybody chose.

   Four across is what keeps the shop on one screen: the four upgrades in one
   row and the three instruments in the next, instead of three rows of cards
   whose last row runs off the bottom. The instrument card is the tall one now
   that each carries its whole ladder, so the row it is in is the row that
   decides whether the screen scrolls.

   At two hundred and forty that held at 1280 by 800 and above and failed at
   1024 by 768, which is the commonest small laptop and a tablet on its side:
   the grid there is 938 pixels wide, and (938 + 13) / (240 + 13) is 3.76, so
   it fell to three columns and the shop scrolled 224 pixels with every Buy
   button on the instruments below the fold. At two hundred and twenty the same
   grid is (938 + 13) / (220 + 13) = 4.08, so 1024 gets its four columns and its
   two rows, and 1280 and 1440 are unchanged at four. Measured at 844x390,
   390x844, 360x640, 1024x768, 1280x800 and 1440x900: nine rungs on the cards,
   a forty-four pixel Buy button, and no scrollbar on any of them. */
.shop-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 13px;
}

.card {
  border: 1px solid rgba(246, 240, 224, 0.16);
  border-radius: 14px;
  padding: 14px;
  background: rgba(9, 30, 32, 0.5);
  display: flex;
  flex-direction: column;
  gap: 9px;
  transition: border-color 0.15s ease, background 0.15s ease;
  /* A card is its own container, because what decides whether a rung can be
     said in full is the width of the card rather than the width of the window:
     the same 1280 pixel window gives a card of 330 or of 247 depending on how
     many columns the grid chose, and the ladder's long form wraps on the narrow
     one and not on the wide one. */
  container-type: inline-size;
}
.card.maxed { border-color: rgba(89, 224, 200, 0.35); background: rgba(20, 57, 59, 0.42); }
.card.affordable { border-color: rgba(227, 180, 85, 0.5); }
.card-top { display: flex; align-items: baseline; gap: 8px; }
.card h4 { margin: 0; font-size: 1.02rem; color: var(--paper); }
.card .tag {
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink);
  background: var(--pen);
  border-radius: 999px;
  padding: 2px 8px;
  font-weight: 800;
}
.card .lvl {
  margin-left: auto;
  font-size: 0.7rem;
  color: var(--paper-dim);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.card p { margin: 0; font-size: 0.83rem; line-height: 1.5; color: #cfc8b4; }
.card .track { display: flex; gap: 4px; }
.card .track i {
  flex: 1;
  height: 5px;
  border-radius: 3px;
  background: rgba(246, 240, 224, 0.16);
}
.card .track i.on { background: var(--straw); }
.card .now {
  font-size: 0.78rem;
  color: var(--paper-dim);
  display: flex;
  justify-content: space-between;
  gap: 10px;
  font-variant-numeric: tabular-nums;
}
.card .now b { color: var(--paper); }
.card .next-up {
  font-size: 0.78rem;
  color: var(--pen);
  display: flex;
  justify-content: space-between;
  gap: 10px;
  font-variant-numeric: tabular-nums;
  margin-top: 2px;
}
.card .next-up b { color: var(--pen); font-weight: 700; }
.card .row { display: flex; align-items: center; gap: 9px; margin-top: auto; padding-top: 8px; }
.card .price {
  font-weight: 800;
  font-size: 1rem;
  color: var(--straw-bright);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.card .row .btn { margin-left: auto; }
.card .owned-note { color: var(--pen); font-weight: 700; font-size: 0.86rem; margin-left: auto; }

/* THE WHOLE INSTRUMENT LADDER, one line per rung: the level, what that rung
   buys and what it costs. The rake's three rungs and the vac's five are a list
   of prices somebody asked for, and a card that shows only the rung you are on
   and the one above it leaves the rest of the list off the screen -- there was
   nothing on the page that said the vac had five rungs. A rung already owned
   is straw, the one the button buys is lit and boxed, the ones above it are
   dim until the money is there.

   The note under each rung is the line the level was written with, so the two
   numbers a rung is known by -- its price and its speed -- are read off the
   card rather than off the shop's prose. */
.card .ladder {
  display: flex;
  flex-direction: column;
  gap: 1px;
  font-variant-numeric: tabular-nums;
}
.card .rung {
  display: flex;
  align-items: baseline;
  gap: 5px;
  font-size: 0.73rem;
  line-height: 1.3;
  color: rgba(207, 200, 180, 0.62);
}
/* The short form of the same rung is what a card shows by default, and a card
   wide enough for the long one swaps it in at the bottom of this file. Both are
   in the card, and no reading of it is ever cut short: the brief carries the
   rung's number and its price, which is the whole of what a rung is. */
.card .rung-note { flex: 1 1 auto; min-width: 0; display: none; }
.card .rung-brief { flex: 1 1 auto; min-width: 0; }
.card .rung-lvl {
  flex: 0 0 auto;
  font-size: 0.68rem;
  font-weight: 800;
  color: rgba(207, 200, 180, 0.5);
}
.card .rung-cost {
  flex: 0 0 auto;
  font-weight: 800;
  color: var(--paper-dim);
}
.card .rung.on { color: #cfc8b4; }
.card .rung.on .rung-lvl { color: var(--straw); }
.card .rung.on .rung-cost { color: var(--straw); }
/* The rung that is one press away: the same highlight the card gets when the
   money is in hand, so the price on the button and the line it buys match. */
.card .rung.next {
  color: var(--pen);
  font-weight: 700;
  background: rgba(89, 224, 200, 0.14);
  border-radius: 4px;
  padding: 0 3px;
  margin: 0 -3px;
}
.card .rung.next .rung-lvl, .card .rung.next .rung-cost { color: var(--pen); }

/* ---------------- win ---------------- */

.screen-win {
  background:
    radial-gradient(90% 60% at 50% 34%, rgba(246, 217, 138, 0.45) 0%, rgba(13, 42, 44, 0) 62%),
    linear-gradient(180deg, rgba(20, 57, 59, 0.94) 0%, rgba(9, 30, 32, 0.98) 100%);
}
.win-title {
  font-size: clamp(1.7rem, 5.6vw, 2.5rem);
  margin: 12px 0 8px;
  color: var(--straw-bright);
  letter-spacing: -0.02em;
}
.win-cleared { margin: 0 0 18px; color: var(--straw-bright); font-size: 1.3rem; font-weight: 800; letter-spacing: 0.02em; }
.win-cleared[hidden], .win-grandma[hidden], .win-sub[hidden], .win-note[hidden] { display: none; }
.win-grandma { margin: 0 0 8px; color: var(--straw-bright); font-size: 1.12rem; font-weight: 700; }
.win-sub { margin: 0 0 18px; color: var(--paper-dim); font-size: 0.98rem; }
.win-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
  gap: 10px;
  margin-bottom: 20px;
  text-align: left;
}
/* Label over value, never beside it. Inline, the label and the number both
   refuse to wrap and "1,000,000" runs straight through the next box. */
.win-stat {
  background: rgba(9, 30, 32, 0.55);
  border: 1px solid rgba(246, 240, 224, 0.14);
  border-radius: 11px;
  padding: 9px 12px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.win-stat .stat-value { font-size: 1.12rem; }
.win-note { font-size: 0.8rem; color: var(--paper-dim); margin: 10px 0 0; }

/* THE WIN CARD ON A SHORT FRAME. It is a title, a line, eight stat tiles and
   two buttons, and under about 660 pixels of height it is taller than the
   screen. It scrolls, which is not the same as working: what scrolled away was
   the pair of buttons, so the player won and was left looking at a column of
   numbers with nothing to press and no sign that anything was below.
   Two things fix it, and neither touches a tall frame.
   1. The tiles take four across instead of three or two, and the air around
   them comes in. At 844x390 that is two rows in place of three; at 360x640 it
   is four rows in place of eight, which is the whole of the overflow.
   2. The action row sticks to the foot of the visible card, the way the help
   card's Close sticks to its head, so the way on is on screen whatever the
   card is doing. In a card that already fits, a sticky row does not move:
   this is inert everywhere the card is not taller than the frame. */
@media (max-height: 660px) {
  .needle-mark { height: 24px; }
  .win-title { font-size: clamp(1.4rem, 4.6vw, 1.9rem); margin: 6px 0 4px; }
  .win-grandma { margin: 0 0 4px; font-size: 1rem; }
  .win-cleared { margin: 0 0 10px; font-size: 1.12rem; }
  .win-sub { margin: 0 0 10px; font-size: 0.9rem; }
  .win-stats { gap: 7px; margin-bottom: 10px; grid-template-columns: repeat(auto-fit, minmax(124px, 1fr)); }
  /* The label is nowrap by design, so at four across it has to be small enough
     to sit inside a 124 pixel tile: "DEPTH OF THE NEEDLE" still runs to the
     edge at the size the tall card gives it, and touches the next tile. */
  .win-stat .stat-label { font-size: 0.56rem; letter-spacing: 0.06em; }
  .win-stat { padding: 6px 10px; }
  .panel-win .title-actions {
    position: sticky;
    bottom: 0;
    z-index: 1;
    margin: 0 -4px;
    padding: 8px 4px;
    background: linear-gradient(180deg, rgba(13, 42, 44, 0) 0%, rgba(13, 42, 44, 0.97) 46%);
  }
  .win-note { margin-top: 4px; }
}
/* And the narrowest phone there is. A 320 pixel frame gives the card 288, so
   four tiles across is impossible and the auto-fit falls to ONE column: eight
   tiles stacked, 235 pixels of them below the fold even after the block above.
   Below 380 pixels wide the tiles are told to pair up, and the label is let
   onto a second line rather than staying on one and running into its
   neighbour. Four rows in place of eight. */
@media (max-height: 660px) and (max-width: 380px) {
  .win-stats { grid-template-columns: 1fr 1fr; }
  .win-stat .stat-label { white-space: normal; }
}

.needle-mark { height: 42px; display: grid; place-items: center; }
.needle-mark i {
  display: block;
  width: 74px;
  height: 4px;
  background: linear-gradient(90deg, #fff8e2 0%, #e3b455 72%, #fff8e2 100%);
  border-radius: 2px;
  transform: rotate(-22deg);
  box-shadow: 0 0 22px rgba(246, 217, 138, 0.95);
  animation: shimmer 2.1s ease-in-out infinite;
}
@keyframes shimmer { 0%, 100% { opacity: 1; } 50% { opacity: 0.62; } }

.help-list { margin: 0 0 18px; padding-left: 20px; font-size: 0.9rem; line-height: 1.68; color: #ded7c2; }
.help-list li + li { margin-top: 7px; }
.help-list b { color: var(--straw-bright); }

/* The black a new stack is started through. See the note in index.html.

   Above every screen (10) and above the boot error (40), because it is the
   one thing that has to be able to cover all of them. It never takes a
   pointer event: it is a colour, not a control, and a player who clicks
   during the half second it is up must reach whatever is underneath.

   The transition is on opacity and nothing else, which is the one property a
   browser can carry on its own even while the page is busy. Starting a stack
   blocks the main thread for seconds, and a fade the game has to animate
   itself is a fade that stops halfway and jumps. */
.fade {
  position: absolute;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Not black: the yard's own sunset, so the first frame is already this
     game and not a screen that has not started. */
  background:
    radial-gradient(ellipse 120% 70% at 50% 100%, rgba(255, 168, 82, 0.55) 0%, rgba(255, 168, 82, 0) 60%),
    linear-gradient(180deg, #2f5f9c 0%, #6d86ad 42%, #e7a35c 78%, #6b3f1c 100%);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.42s ease;
}
.fade.covered { opacity: 1; }
/* For the one frame where the black has to be exact: on instantly, no ramp. */
.fade.now { transition: none; }
.fade-card {
  position: relative;
  padding: 18px 30px 20px;
  border: 6px solid transparent;
  border-radius: 14px;
  text-align: center;
  color: var(--cream, #f4ead2);
  background:
    linear-gradient(180deg, rgba(44, 26, 13, 0.88) 0%, rgba(30, 17, 8, 0.92) 100%) padding-box,
    url("../assets/ui/wood.jpg") center / 220px auto padding-box,
    url("../assets/ui/wood.jpg") center / 220px auto border-box;
  box-shadow: 0 0 0 1px rgba(26, 13, 4, 0.85), 0 10px 30px rgba(10, 5, 0, 0.45);
  max-width: calc(100vw - 40px);
}
.fade-title {
  font-size: clamp(1.4rem, 5vw, 2.2rem);
  font-weight: 800;
  text-shadow: 0 2px 0 #2a1607;
}
.fade-sub {
  margin-top: 4px;
  font-size: clamp(0.85rem, 2.6vw, 1rem);
  color: rgba(244, 234, 210, 0.82);
}
.fade-dots { margin-top: 10px; display: flex; gap: 8px; justify-content: center; }
.fade-dots i {
  width: 9px; height: 9px; border-radius: 50%;
  background: #f0c25a;
  animation: fade-dot 1.1s ease-in-out infinite;
}
.fade-dots i:nth-child(2) { animation-delay: 0.18s; }
.fade-dots i:nth-child(3) { animation-delay: 0.36s; }
@keyframes fade-dot { 0%, 100% { opacity: 0.25; transform: translateY(0); } 50% { opacity: 1; transform: translateY(-4px); } }

.boot-error {
  position: absolute;
  inset: auto 12px 12px 12px;
  z-index: 40;
  background: rgba(150, 50, 40, 0.94);
  border-radius: 10px;
  padding: 12px 14px;
  font-size: 0.85rem;
}

/* ---------------- narrow and short screens ---------------- */

@media (max-width: 720px) {
  :root { --pad: 10px; }
  .stat-label { font-size: 0.58rem; }
  .stat-value { font-size: 1rem; }
  .stat.money .stat-value { font-size: 1.16rem; }
  /* The count of what is still in the stack sits beside Cleared, the same
     size, in the one row. It used to take a line of its own across the whole
     screen on a phone, which put it under Cleared and made it the widest
     thing in the HUD. */
  .hud-top { gap: 6px; flex-wrap: nowrap; }
  /* The keyboard cap is only a keyboard cap on a machine with a keyboard, and
     at this width it is a fifth block in a row that already wraps. */
  .shop-tab { display: none; }
  /* Money, the cart beside it, then the count, then the two buttons: the row
     that wraps keeps the shop next to the thing it is spent from. */
  .hud-buttons { gap: 6px; flex: none; }
  .stat { padding: 4px 9px 6px; flex: none; }
  /* The dial is sized off the short side of the window, so on a phone held
     upright it stays small enough to leave the stack visible behind it and
     sits clear of the thumb buttons at the bottom. */
  /* The same forty per cent off, on the breakpoint that also has to shrink it
     so it stays clear of the thumb buttons. */
  .collect { --dial: min(15.6vmin, 71px); }
  .collect-mid b { font-size: 0.9rem; }
  .controls-card { grid-template-columns: 1fr; gap: 12px; }
  .gauges { width: min(52vw, 230px); }
  .btn-round { min-width: 62px; height: 62px; font-size: 0.8rem; }
  .btn-action { min-width: 92px; height: 76px; font-size: 0.94rem; }
  .shop-grid { grid-template-columns: 1fr; }
  .panel { border-radius: 16px; }
  .panel-shop { max-height: 100%; }
  .shop-head { padding: 14px; }
  .shop-money { margin-left: 0; }
  #btn-shop-close { margin-left: auto; }
}

/* A SHORT FRAME GETS THE WHOLE SHOP, not two cards and a scrollbar.
 *
 * Measured at 844 by 390, the phone's landscape frame, the shop drew two
 * cards: Arm Reach and Work Boots. Handling and Carrying were half cut off at
 * the bottom edge and every instrument, the rake and the vac among them, was
 * below the fold, so the three things a player opens this screen to look at
 * were the three it did not show. The cards are laid out for a window, where
 * height is cheap: 203px each, seven of them, three rows.
 *
 * A short frame has 390px of height and wants all seven on it, so at this size
 * the grid goes to four columns, the descriptive sentence comes off, and the
 * line that says what the next rung buys keeps its place, because that line is
 * the decision. Two rows of four hold the lot and nothing scrolls.
 *
 * A NARROW frame is the same problem turned on its side. A phone held upright
 * is 390 wide and 844 tall, which is room for seven cards and no room for the
 * sentences on them, so it takes the same treatment and gets two columns of
 * four rows, the whole shop on one screen. What is given up on a phone is the
 * one line of prose on each card; what is kept is every name, every rung and
 * every price, which is what the screen is for. A window wide enough for a
 * sentence still shows it. */
/* A phone held upright: the whole bar still fits one row, money to pause.
   The two square buttons stack in the corner rather than sit side by side,
   and everything else gives up a little air. */
@media (max-width: 440px) {
  .hud-top { gap: 5px; }
  .stat { padding: 3px 7px 5px; }
  .stat-label { letter-spacing: 0.04em; }
  .stat-value { font-size: 0.94rem; }
  .stat.money .stat-value { font-size: 1.06rem; }
  .hud-buttons { flex-direction: column; gap: 5px; }
  .hud-top .btn-icon, .btn-pause { min-width: 34px; padding: 5px 7px; }
  /* Upright, it stands under the ? instead of beside it. */
  body.touch .hud-buttons { margin-right: 0; }
  .btn-pause { top: calc(var(--pad) + var(--safe-t) + 45px); }
}
@media (max-width: 340px) {
  .hud-top { gap: 3px; }
  .stat { padding: 3px 5px 5px; }
  .stat-label { font-size: 0.54rem; }
}

@media (max-height: 600px), (max-width: 720px) {
  .shop-head { padding: 5px 14px; gap: 10px; }
  .shop-head h2 { font-size: 1.02rem; margin: 0; }
  /* The flavour line goes first: it says nothing a price does not, and at this
     height it costs a card and a half of the room the prices need. */
  .shop-sub { display: none; }
  .shop-money { padding: 2px 10px 3px; }
  .shop-money .stat-value { font-size: 1rem; }
  .shop-money .stat-label { font-size: 0.55rem; }
  .shop-head .btn { padding: 7px 12px; font-size: 0.82rem; }
  /* The instrument row is the tall one now that it carries five rungs, and the
     twelve pixels between the bottom of it and the edge of the panel are what
     decide whether a landscape phone scrolls: the padding under the grid comes
     down with it, and the two section headings above it tighten by a hair. The
     Buy button keeps its forty-four pixels, which is a thumb. */
  /* Nine pixels under the grid, not three: at three the panel's own dark
     inner edge sat over the instrument cards' bottom rims and read as a cut.
     The headings and the gap give back the room it takes. */
  .shop-scroll { padding: 2px clamp(10px, 2vw, 18px) 9px; }
  .shop-section { margin: 2px 0 1px; font-size: 0.64rem; }
  .shop-grid { grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); gap: 6px; }
  .card { padding: 4px 8px; gap: 2px; border-radius: 10px; }
  .card h4 { font-size: 0.86rem; }
  .card .tag { display: none; }
  /* The pips already say which rung you are on, and the words beside them were
     what pushed the name off the card once it was 179px wide. */
  .card .lvl { display: none; }
  .card p { display: none; }
  .card .now, .card .next-up { font-size: 0.68rem; gap: 6px; margin-top: 0; }
  /* The ladder is five lines on the vac, which is the tallest thing on this
     screen by a long way. At this size it is the one card that sets the height
     of both its row and the shop, so it is set as small as it can be read, and
     each rung is said in its short form: the long one wraps on every rung at
     this width, and five wrapped rungs put the vac's card past the bottom of a
     landscape phone. */
  /* Seven rungs on the vac now, not five. Set solid, a line of this type is
     ten pixels rather than eleven and a half, which is the eleven pixels the
     two new rungs cost a landscape phone; the type itself does not get any
     smaller, because it is already as small as it can be read. */
  .card .rung { font-size: 0.6rem; line-height: 1; gap: 4px; }
  .card .rung-lvl { font-size: 0.56rem; }
  .card .rung-cost { font-size: 0.62rem; }
  .card .ladder { gap: 0; }
  /* "Next Level" broke in half at this width, which reads as two words and a
     label that is not one. The label stays whole and the figure beside it is
     what wraps. */
  .card .now span, .card .next-up span { white-space: nowrap; }
  .card .row { padding-top: 0; gap: 6px; }
  .card .price { font-size: 0.88rem; }
  .card .row .btn { padding: 5px 9px; font-size: 0.74rem; }
  .card .owned-note { font-size: 0.76rem; }
}

/* A WIDE FRAME THAT IS NOT TALL: the small laptop and the tablet on its side.
 *
 * 1024 by 768 fits four cards across and two rows, which is the whole shop; it
 * still had 224 pixels of scroll because the roomy spacing that a 900-tall
 * window can afford is what the two section headings, the header and the air
 * under the grid were spending. Nothing is dropped and nothing is made
 * smaller: the header's eighteen pixels of padding come down to twelve, each
 * section heading keeps twelve above it and eight below instead of twenty and
 * ten, and the padding under the grid comes down to fourteen. Forty-four
 * pixels in all, against the twenty-eight that were wanted, and every one of
 * them is air.
 *
 * Eight hundred tall is the cut, and it is where the room fits again: at 1280
 * by 800 the shop already stands with fifty-five pixels to spare, and 1440 by
 * 900 has more. Below 721 wide, and below 601 tall, this is the phone and
 * short-frame layout, and the block above has tightened all of it already:
 * the two conditions are what keep this from loosening a landscape phone back
 * into a scrollbar, which it did when the block first landed. */
@media (min-width: 721px) and (min-height: 601px) and (max-height: 800px) {
  .shop-head { padding: 12px clamp(16px, 2.6vw, 26px); }
  .shop-section { margin: 12px 0 8px; }
  .shop-scroll { padding-bottom: 14px; }
  /* At 1280 by 720 the two headings' margins were the ten pixels that cut
     the bottom edge off the instrument cards: tighter here, it all fits. */
  @media (max-height: 740px) { .shop-section { margin: 6px 0 5px; } }
  /* SEVEN RUNGS ON THE VAC, two more than this block was measured against, and
     at sixteen pixels a rung they were the thirty-three pixels that put a
     scrollbar back on 1024 by 768 and tripled the one on 1280 by 720. They are
     paid for in leading and air and nothing else: the type is the size it was,
     the lines sit closer, and the card's own gap comes in by three pixels. */
  .card { gap: 6px; }
  .card .ladder { gap: 0; }
  .card .rung { line-height: 1.12; }
}

/* A phone held upright has room for two columns of this and no more, and two
 * columns is what brings the whole shop onto the screen: four rows of two at
 * this card size, against seven rows of one, which ran off the bottom. */
@media (max-width: 720px) {
  .shop-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-height: 460px) {
  .collect { transform: translate(-50%, 22px); padding: 5px 10px 7px; }
  /* The words move out of the middle column on a short screen.
   *
   * There is no longer a ring in the middle only while a button is down: the
   * dial IS the cursor now, so it is up for as long as there is hay in reach,
   * and the prompt block sat on it. Measured at 844 by 390, the ring's top edge
   * fell on the second line of the prompt and its stroke crossed the words. The
   * block keeps to the left of the centre strip instead, on the same side as
   * the toasts, and the middle of the view is left to the thing being aimed at.
   * 46 per cent of 844 is 388, which is clear of the ring's left edge at 400,
   * and the block is never so wide that it reaches back under it. */
  .prompt-wrap {
    align-self: flex-start;
    margin: auto 0 16px;
    width: min(46%, 360px);
    text-align: left;
    padding: 8px 16px;
  }
  .prompt-wrap.shift { transform: translateY(-10px); }
  .toast { padding: 6px 11px; font-size: 0.8rem; }
  .gauge-head { font-size: 0.6rem; margin-bottom: 2px; }
  .gauge-bar { height: 7px; }
  .lede { margin-bottom: 12px; }
  /* Short and wide. The controls used to be dropped here, which left a
     landscape phone with no way to read them at all; the screen has the width
     for two columns and only lacks the height, so they come back as columns. */
  .controls-card { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 16px; padding-top: 10px; }
  .controls-card ul { font-size: 0.76rem; line-height: 1.5; }
  .help-list { font-size: 0.84rem; }
  .btn-round { min-width: 56px; height: 56px; font-size: 0.76rem; }
  .btn-action { min-width: 84px; height: 68px; }
  .tool-chip { padding: 5px 9px; min-height: 34px; font-size: 0.72rem; }
}

/* A very narrow phone held upright: field of view is tall, so lift the
   gauges and keep the action buttons clear of the thumbs. */
@media (max-aspect-ratio: 3/4) {
  /* A phone held upright is narrow enough that the note has to be short as
     well, or it stops being a note and becomes the picture. */
  .panel-help { width: min(430px, 100%); max-height: 34%; font-size: 0.8rem; }
  .panel-help .help-list { font-size: 0.8rem; }
  .gauges { width: min(60vw, 260px); }
  .hud-bottom { flex-direction: column-reverse; align-items: stretch; gap: 10px; }
  /* The tool row gets the whole width. Side by side with the thumb buttons it
     had about half of it, and four chips in one column bury the hands. */
  .hud-right { flex-direction: column; align-items: stretch; gap: 8px; }
  .tools { justify-content: flex-end; }
  .touch-actions { justify-content: flex-end; }
  /* Narrow enough that the notices are most of the width, so they get a
     smaller type size rather than a taller column. */
  .toast { font-size: 0.8rem; padding: 6px 11px; }
}

/* A card with three hundred pixels of width says a rung the long way, "1
 * column wide, x3.1 speed", because there is room for the whole sentence and
 * the width of the scoop is worth reading. Below that the same rung is said
 * short, "x3.1 speed", which is what the price list called it. The card is the
 * container this asks about, not the window: at 1280 pixels wide the grid is
 * four columns and the card is 247, at 1024 it is three columns and the card is
 * 305, and the window's own width would get both of those wrong. */
@container (min-width: 300px) {
  .card .rung-note { display: block; }
  .card .rung-brief { display: none; }
}

/* A narrow card keeps its name on one line by giving up the pill that says
   what kind of instrument it is. At 1280 pixels the grid is four columns and
   the name wrapped under its own tag -- "Hay" over "Rake" -- which is a card
   that cannot be read at a glance for the sake of a word the blurb below it
   already carries. */
@container (max-width: 270px) {
  .card .tag { display: none; }
}

/* The smallest phone there is, held upright: 360 by 640. Two columns of seven
 * cards is four rows and there is thirteen pixels too little for four rows, so
 * at this size and no other the card loses a little of its padding and its name
 * keeps its place on it. Nothing is dropped: every rung and every price is on
 * the card, and the four rows fit. */
@media (max-width: 420px) and (max-height: 700px) {
  .card { padding: 3px 7px; }
  .card h4 { font-size: 0.8rem; }
  .card .rung { font-size: 0.58rem; line-height: 1; }
  .card .row .btn { padding: 4px 8px; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}


/* =====================================================================
   WOOD AND STRAW: the look the person drew.
   Every box the HUD puts over the yard, and the pause card, wears a frame of
   weathered oak with a brass rivet in each corner and dark boards inside.
   Nothing about what the boxes hold or do changes here; this is paint.
   ===================================================================== */

:root {
  --wood: url("../assets/ui/wood.jpg");
  --board-in: linear-gradient(180deg, rgba(44, 26, 13, 0.90) 0%, rgba(30, 17, 8, 0.93) 100%);
  --rivet: radial-gradient(circle at 40% 36%, #fbe7b4 0, #c99b52 32%, #6b4519 70%, rgba(40, 22, 6, 0) 76%);
  --cream: #f4ead2;
  --gold: #f0c25a;
}

/* ---- the small frames: stats, gauges, tool chips, HUD buttons ---- */
.hud .stat,
.hud .gauge,
.hud .tool-chip,
.hud .hud-buttons .btn,
.hud .shop-badge,
body .btn-pause {
  border: 4px solid transparent;
  border-radius: 9px;
  background:
    var(--rivet) left 1px top 1px / 6px 6px no-repeat border-box,
    var(--rivet) right 1px top 1px / 6px 6px no-repeat border-box,
    var(--rivet) left 1px bottom 1px / 6px 6px no-repeat border-box,
    var(--rivet) right 1px bottom 1px / 6px 6px no-repeat border-box,
    var(--board-in) padding-box,
    var(--wood) center / 160px auto padding-box,
    var(--wood) center / 160px auto border-box;
  box-shadow:
    0 0 0 1px rgba(26, 13, 4, 0.85),
    inset 0 0 0 1px rgba(14, 7, 2, 0.75),
    inset 0 2px 6px rgba(0, 0, 0, 0.45),
    0 4px 12px rgba(10, 5, 0, 0.35);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  color: var(--cream);
}
.hud .stat { padding: 3px 11px 5px; }
.hud .stat-label,
.hud .gauge-head { color: rgba(244, 234, 210, 0.82); }
.hud .stat-value { color: #fffaf0; text-shadow: 0 1px 0 rgba(0, 0, 0, 0.5); }
.hud .stat.money .stat-value { color: var(--gold); }
.hud .gauge { padding: 4px 9px 6px; }
.hud .gauge-bar {
  background: rgba(14, 7, 2, 0.75);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.6);
}
.hud .gauge-bar i { background: linear-gradient(180deg, #f8d77e 0%, #e6a93c 100%); }
.hud .hud-buttons .btn:hover,
.hud .shop-badge:hover { filter: brightness(1.12); }
.hud .shop-tab {
  background: #2a170a;
  border: 1px solid #5a3a1c;
  color: var(--cream);
}

/* The tool in hand: gold boards inside the same oak frame. */
.hud .tool-chip.selected {
  background:
    var(--rivet) left 1px top 1px / 6px 6px no-repeat border-box,
    var(--rivet) right 1px top 1px / 6px 6px no-repeat border-box,
    var(--rivet) left 1px bottom 1px / 6px 6px no-repeat border-box,
    var(--rivet) right 1px bottom 1px / 6px 6px no-repeat border-box,
    linear-gradient(180deg, #f9dc8a 0%, #e8b448 100%) padding-box,
    var(--wood) center / 160px auto border-box;
  color: #2a1a06;
  border-color: transparent;
  outline: 2px solid rgba(240, 194, 90, 0.55);
  outline-offset: 1px;
}
.hud .tool-chip.locked {
  border-style: solid;
  border-color: transparent;
  color: rgba(244, 234, 210, 0.6);
}
.hud .tool-chip.locked::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 5px;
  background: rgba(10, 5, 1, 0.32);
  pointer-events: none;
}

/* ---- the pause card ---- */
.screen-pause {
  background: radial-gradient(90% 80% at 50% 50%, rgba(10, 5, 1, 0.25) 0%, rgba(10, 5, 1, 0.55) 100%);
}
.panel.pause-card {
  position: relative;
  overflow: visible;
  width: min(440px, 100%);
  max-height: none;
  padding: clamp(14px, 3vw, 24px) clamp(18px, 4.4vw, 34px) clamp(18px, 3.4vw, 28px);
  border: 16px solid transparent;
  border-radius: 18px;
  background:
    var(--rivet) left 2px top 2px / 12px 12px no-repeat border-box,
    var(--rivet) right 2px top 2px / 12px 12px no-repeat border-box,
    var(--rivet) left 2px bottom 2px / 12px 12px no-repeat border-box,
    var(--rivet) right 2px bottom 2px / 12px 12px no-repeat border-box,
    linear-gradient(180deg, rgba(40, 23, 11, 0.88) 0%, rgba(26, 14, 6, 0.92) 100%) padding-box,
    var(--wood) center / 300px auto padding-box,
    var(--wood) center / 300px auto border-box;
  box-shadow:
    0 0 0 2px #241306,
    inset 0 0 0 2px #1a0d04,
    inset 0 0 0 4px rgba(255, 220, 160, 0.06),
    inset 0 6px 18px rgba(0, 0, 0, 0.55),
    0 18px 40px rgba(8, 4, 0, 0.6);
  color: var(--cream);
  text-align: center;
}
.pause-title {
  margin: 0;
  font-size: clamp(1.9rem, 6vw, 2.5rem);
  font-weight: 800;
  letter-spacing: 0.01em;
  color: var(--cream);
  text-shadow: 0 2px 0 #2a1607, 0 0 14px rgba(0, 0, 0, 0.45);
}
.wheat-rule {
  display: flex;
  align-items: center;
  gap: 4px;
  margin: 2px 0 14px;
}
.wheat-rule svg { width: 64px; height: 26px; flex: none; }
.wheat-rule .rule-line {
  flex: 1;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, rgba(233, 191, 98, 0) 0%, #d6a44c 100%);
}
.wheat-rule .rule-line:last-child { background: linear-gradient(90deg, #d6a44c 0%, rgba(233, 191, 98, 0) 100%); }

.pause-card .volume-rows { gap: 14px; margin: 0 0 22px; }
.pause-card .volume-row {
  grid-template-columns: 6.2em 1fr;
  gap: 14px;
  font-size: 1.12rem;
  font-weight: 800;
  color: var(--cream);
  text-align: left;
  text-shadow: 0 1px 0 #1a0d04;
}
.pause-card .volume-slider {
  -webkit-appearance: none;
  appearance: none;
  height: 28px;
  background: transparent;
  --p: 50%;
}
.pause-card .volume-slider::-webkit-slider-runnable-track {
  height: 10px;
  border-radius: 6px;
  border: 1px solid #140a03;
  background: linear-gradient(90deg, #f4cf6c 0%, #e0a238 var(--p), #3b2312 var(--p), #2c190b 100%);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.5);
}
.pause-card .volume-slider::-moz-range-track {
  height: 10px;
  border-radius: 6px;
  border: 1px solid #140a03;
  background: #2c190b;
}
.pause-card .volume-slider::-moz-range-progress {
  height: 10px;
  border-radius: 6px;
  background: linear-gradient(90deg, #f4cf6c 0%, #e0a238 100%);
}
.pause-card .volume-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 24px;
  height: 24px;
  margin-top: -8px;
  border-radius: 50%;
  background: radial-gradient(circle at 40% 35%, #fffaf0 0%, #f1e6cc 60%, #d6c49c 100%);
  border: 3px solid #8a5a26;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.55);
}
.pause-card .volume-slider::-moz-range-thumb {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #f4ead2;
  border: 3px solid #8a5a26;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.55);
}

/* A short phone on its side (390 tall and under): the shop header and the
   cards give up a few pixels so the last row's rims are not cut. */
@media (max-height: 400px) {
  .shop-head { padding-top: 3px; padding-bottom: 3px; }
  .card { padding-top: 3px; padding-bottom: 3px; }
}

/* The Arrows option: two wooden halves, the chosen one lit in straw. */
.arrow-choice { display: flex; gap: 0; border: 2px solid #140a03; border-radius: 9px; overflow: hidden; }
.arrow-opt {
  flex: 1 1 0;
  min-height: 34px;
  border: 0;
  margin: 0;
  font: inherit;
  font-size: 0.95rem;
  font-weight: 800;
  color: var(--cream);
  background: #2c190b;
  cursor: pointer;
}
.arrow-opt + .arrow-opt { border-left: 2px solid #140a03; }
.arrow-opt.on { background: linear-gradient(180deg, #f4cf6c 0%, #e0a238 100%); color: #2a1606; text-shadow: none; }
body.touch .arrows-row { display: none; }

.pause-actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}
.btn.wood-btn {
  width: min(250px, 100%);
  min-height: 50px;
  font-size: 1.12rem;
  font-weight: 800;
  color: var(--cream);
  text-shadow: 0 1px 0 #1a0d04, 0 0 6px rgba(0, 0, 0, 0.4);
  border: 2px solid #221105;
  border-radius: 9px;
  background:
    radial-gradient(circle, #f0d9a4 0, #9b6b32 45%, #4a2d10 75%, rgba(0, 0, 0, 0) 80%) left 9px center / 8px 8px no-repeat,
    radial-gradient(circle, #f0d9a4 0, #9b6b32 45%, #4a2d10 75%, rgba(0, 0, 0, 0) 80%) right 9px center / 8px 8px no-repeat,
    linear-gradient(180deg, rgba(255, 220, 160, 0.16) 0%, rgba(0, 0, 0, 0) 45%, rgba(0, 0, 0, 0.28) 100%),
    var(--wood) center / 260px auto;
  box-shadow:
    inset 0 1px 0 rgba(255, 230, 180, 0.25),
    inset 0 -2px 0 rgba(0, 0, 0, 0.35),
    0 3px 0 #1a0d04,
    0 6px 12px rgba(0, 0, 0, 0.45);
}
.btn.wood-btn:hover { filter: brightness(1.12); border-color: #221105; }
.btn.wood-btn:active { transform: translateY(2px); box-shadow: inset 0 1px 0 rgba(255, 230, 180, 0.2), 0 1px 0 #1a0d04; }
.btn.wood-btn:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }

.pause-card .straw {
  position: absolute;
  bottom: -30px;
  width: clamp(70px, 18vw, 104px);
  height: auto;
  pointer-events: none;
  filter: drop-shadow(0 3px 3px rgba(0, 0, 0, 0.45));
}
.pause-card .straw-l { left: -34px; transform: rotate(-38deg); }
.pause-card .straw-r { right: -34px; transform: scaleX(-1) rotate(-38deg); }

/* A short landscape phone: the card is tighter so all of it fits. */
@media (max-height: 460px) {
  .panel.pause-card { padding-top: 8px; padding-bottom: 12px; border-width: 12px; }
  .pause-title { font-size: 1.7rem; }
  .wheat-rule { margin-bottom: 8px; }
  .pause-card .volume-rows { gap: 6px; margin-bottom: 12px; }
  .pause-actions { flex-direction: row; justify-content: center; gap: 10px; }
  .btn.wood-btn { min-height: 44px; width: auto; flex: 1 1 0; max-width: 200px; padding: 8px 26px; }
  .pause-card .straw { width: 64px; bottom: -22px; }
}

/* Touch buttons in the same oak, the states keep their own colour inside. */
.hud .touch-actions .btn {
  border: 4px solid transparent;
  background:
    var(--board-in) padding-box,
    var(--wood) center / 160px auto padding-box,
    var(--wood) center / 160px auto border-box;
  box-shadow: 0 0 0 1px rgba(26, 13, 4, 0.85), inset 0 2px 6px rgba(0, 0, 0, 0.45), 0 4px 12px rgba(10, 5, 0, 0.35);
  color: var(--cream);
}
.hud .touch-actions .btn-action.pay {
  background: linear-gradient(180deg, #7cead6, #3fb9a4) padding-box, var(--wood) center / 160px auto border-box;
  color: #10322c;
}
.hud .touch-actions .btn-action.shiny {
  background: linear-gradient(180deg, #f9dc8a, #e8b448) padding-box, var(--wood) center / 160px auto border-box;
  color: #2b1f06;
}
.hud .tool-chip.locked { color: rgba(244, 234, 210, 0.78); }
.hud .tool-chip.locked::after { background: rgba(10, 5, 1, 0.2); }
.wheat-rule svg { width: 30px; height: 38px; margin: 0 8px; }
.btn.wood-btn { white-space: nowrap; }
.prompt-wrap {
  background: radial-gradient(105% 72% at 50% 50%, rgba(30, 17, 8, 0.76) 0%, rgba(30, 17, 8, 0.42) 62%, rgba(30, 17, 8, 0) 100%);
}
.toast { background: rgba(34, 19, 8, 0.92); border-color: rgba(120, 82, 40, 0.7); color: var(--cream); }

/* =====================================================================
   THE REST OF THE INTERFACE IN THE SAME WOOD.
   The shop, the help note, the win card, the title and every button and
   card in them wear the riveted oak frame and the dark boards the pause card
   and the HUD already do, drawn to the person's shop mockup. Paint only:
   nothing here changes a word, a size that decides a layout, or a behaviour.
   ===================================================================== */

/* ---- the big frames ---- */
.panel,
.panel.panel-help,
.panel.panel-shop,
.panel.panel-win,
.panel.panel-title {
  border: 14px solid transparent;
  border-radius: 18px;
  background:
    var(--rivet) left 2px top 2px / 10px 10px no-repeat border-box,
    var(--rivet) right 2px top 2px / 10px 10px no-repeat border-box,
    var(--rivet) left 2px bottom 2px / 10px 10px no-repeat border-box,
    var(--rivet) right 2px bottom 2px / 10px 10px no-repeat border-box,
    linear-gradient(180deg, rgba(42, 25, 12, 0.95) 0%, rgba(27, 15, 7, 0.97) 100%) padding-box,
    var(--wood) center / 300px auto padding-box,
    var(--wood) center / 300px auto border-box;
  box-shadow:
    0 0 0 2px #241306,
    inset 0 0 0 2px #1a0d04,
    inset 0 0 0 4px rgba(255, 220, 160, 0.06),
    inset 0 6px 18px rgba(0, 0, 0, 0.55),
    0 18px 40px rgba(8, 4, 0, 0.6);
  color: var(--cream);
}
.panel.panel-help { border-width: 9px; border-radius: 14px; }
.panel.panel-help {
  background:
    var(--rivet) left 1px top 1px / 7px 7px no-repeat border-box,
    var(--rivet) right 1px top 1px / 7px 7px no-repeat border-box,
    var(--rivet) left 1px bottom 1px / 7px 7px no-repeat border-box,
    var(--rivet) right 1px bottom 1px / 7px 7px no-repeat border-box,
    linear-gradient(180deg, rgba(42, 25, 12, 0.95) 0%, rgba(27, 15, 7, 0.97) 100%) padding-box,
    var(--wood) center / 220px auto padding-box,
    var(--wood) center / 220px auto border-box;
}
/* The pause card keeps its own, wider frame. */
.panel.pause-card { border-width: 16px; }

/* Scrims: brown dusk instead of teal. */
.screen-dark { background: rgba(18, 10, 4, 0.72); }
.screen-win {
  background:
    radial-gradient(90% 60% at 50% 34%, rgba(246, 217, 138, 0.32) 0%, rgba(18, 10, 4, 0) 62%),
    linear-gradient(180deg, rgba(30, 17, 8, 0.86) 0%, rgba(14, 8, 3, 0.94) 100%);
}
#screen-title {
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(227, 180, 85, 0.20) 0%, rgba(18, 10, 4, 0) 58%),
    linear-gradient(180deg, rgba(20, 11, 5, 0.40) 0%, rgba(14, 8, 3, 0.72) 100%);
}

/* ---- headings and rules ---- */
h1.title, .shop-head h2, .win-title, .win-grandma, .win-cleared { color: var(--gold); text-shadow: 0 2px 0 #1a0d04; }
.help-head h2 { color: var(--cream); text-shadow: 0 2px 0 #1a0d04; }
.subtitle, .shop-sub, .win-sub, .win-note, .save-note { color: rgba(244, 234, 210, 0.78); }
.lede, .help-line, .controls-card ul { color: #ecdfc0; }
.lede b, .help-line b { color: var(--gold); }
.controls-card { border-top-color: rgba(214, 164, 76, 0.35); }
.controls-card h3 { color: var(--gold); }

.shop-head {
  background: linear-gradient(180deg, rgba(20, 11, 5, 0.55), rgba(20, 11, 5, 0.25));
  border-bottom: 2px solid rgba(214, 164, 76, 0.38);
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.5);
}
.help-head {
  background: rgba(36, 21, 10, 0.99);
  border-bottom: 2px solid rgba(214, 164, 76, 0.38);
}
/* Section names: gold capitals with a wheat-coloured rule running off them. */
.shop-section {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--gold);
  font-weight: 800;
  text-shadow: 0 1px 0 #1a0d04;
}
.shop-section::after {
  content: "";
  flex: 1;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, #d6a44c 0%, rgba(214, 164, 76, 0) 100%);
}

/* ---- the money box in the shop: a small oak frame like the HUD's ---- */
.shop-money,
.win-stat {
  border: 5px solid transparent;
  border-radius: 10px;
  background:
    var(--rivet) left 1px top 1px / 6px 6px no-repeat border-box,
    var(--rivet) right 1px top 1px / 6px 6px no-repeat border-box,
    var(--rivet) left 1px bottom 1px / 6px 6px no-repeat border-box,
    var(--rivet) right 1px bottom 1px / 6px 6px no-repeat border-box,
    var(--board-in) padding-box,
    var(--wood) center / 160px auto padding-box,
    var(--wood) center / 160px auto border-box;
  box-shadow: 0 0 0 1px rgba(26, 13, 4, 0.85), inset 0 2px 6px rgba(0, 0, 0, 0.45), 0 3px 8px rgba(10, 5, 0, 0.35);
}
.shop-money .stat-label, .win-stat .stat-label { color: rgba(244, 234, 210, 0.82); }
.shop-money .stat-value { color: var(--gold); text-shadow: 0 1px 0 rgba(0, 0, 0, 0.5); }
.win-stat .stat-value { color: #fffaf0; }

/* ---- the shop cards ---- */
.card,
.card.maxed,
.card.affordable {
  border: 6px solid transparent;
  border-radius: 12px;
  background:
    var(--rivet) left 1px top 1px / 7px 7px no-repeat border-box,
    var(--rivet) right 1px top 1px / 7px 7px no-repeat border-box,
    var(--rivet) left 1px bottom 1px / 7px 7px no-repeat border-box,
    var(--rivet) right 1px bottom 1px / 7px 7px no-repeat border-box,
    linear-gradient(180deg, rgba(48, 29, 14, 0.94) 0%, rgba(32, 18, 8, 0.96) 100%) padding-box,
    var(--wood) center / 200px auto padding-box,
    var(--wood) center / 200px auto border-box;
  box-shadow:
    0 0 0 1px rgba(26, 13, 4, 0.9),
    inset 0 0 0 1px rgba(14, 7, 2, 0.8),
    inset 0 3px 8px rgba(0, 0, 0, 0.45),
    0 5px 12px rgba(8, 4, 0, 0.4);
}
.card.affordable { box-shadow: 0 0 0 1px rgba(26, 13, 4, 0.9), 0 0 0 3px rgba(240, 194, 90, 0.45), inset 0 3px 8px rgba(0, 0, 0, 0.45), 0 5px 12px rgba(8, 4, 0, 0.4); }
.card h4 { color: #fffaf0; text-shadow: 0 1px 0 #1a0d04; }
.card .lvl { color: rgba(244, 234, 210, 0.8); }
.card p { color: #e6d8b8; }
.card .track i { background: rgba(14, 7, 2, 0.7); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.6); }
.card .track i.on { background: linear-gradient(180deg, #f8d77e 0%, #e6a93c 100%); }
.card .now { color: rgba(244, 234, 210, 0.8); }
.card .now b { color: #fffaf0; }
.card .next-up, .card .next-up b { color: var(--gold); }
.card .price { color: var(--gold); text-shadow: 0 1px 0 #1a0d04; }
.card .owned-note { color: var(--gold); }
.card .tag { background: var(--gold); color: #2a1a06; }
.card .rung { color: rgba(230, 216, 184, 0.6); }
.card .rung-lvl { color: rgba(230, 216, 184, 0.5); }
.card .rung-cost { color: rgba(244, 234, 210, 0.75); }
.card .rung.on, .card .rung.on .rung-lvl, .card .rung.on .rung-cost { color: #e6d8b8; }
.card .rung.on .rung-lvl, .card .rung.on .rung-cost { color: #e6a93c; }
.card .rung.next { color: var(--gold); background: rgba(240, 194, 90, 0.14); }
.card .rung.next .rung-lvl, .card .rung.next .rung-cost { color: var(--gold); }

/* ---- buttons: oak, gold for the main one, dark iron when they cannot be pressed ---- */
.panel .btn:not(.wood-btn) {
  border: 3px solid transparent;
  border-radius: 9px;
  color: var(--cream);
  text-shadow: 0 1px 0 #1a0d04;
  background:
    linear-gradient(180deg, rgba(255, 220, 160, 0.14) 0%, rgba(0, 0, 0, 0) 45%, rgba(0, 0, 0, 0.3) 100%) padding-box,
    var(--wood) center / 220px auto padding-box,
    var(--wood) center / 220px auto border-box;
  box-shadow:
    0 0 0 1px #1a0d04,
    inset 0 1px 0 rgba(255, 230, 180, 0.22),
    0 3px 0 #1a0d04,
    0 5px 10px rgba(0, 0, 0, 0.4);
}
.panel .btn.btn-primary:not(.wood-btn) {
  color: #2a1a06;
  text-shadow: 0 1px 0 rgba(255, 240, 200, 0.5);
  background:
    linear-gradient(180deg, #fbe39a 0%, #f0c25a 55%, #d9a03c 100%) padding-box,
    var(--wood) center / 220px auto border-box;
}
.panel .btn:not(.wood-btn):hover { filter: brightness(1.1); }
.panel .btn:not(.wood-btn):active { transform: translateY(2px); box-shadow: 0 0 0 1px #1a0d04, 0 1px 0 #1a0d04; }
.panel .btn:not(.wood-btn):focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }
.panel .btn:not(.wood-btn):disabled {
  opacity: 1;
  color: rgba(220, 215, 205, 0.55);
  text-shadow: none;
  background: linear-gradient(180deg, #4b4844 0%, #3a3734 100%) padding-box,
              linear-gradient(180deg, #2b2826, #1f1c1a) border-box;
  box-shadow: 0 0 0 1px #141210, inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 2px 4px rgba(0, 0, 0, 0.35);
  filter: none;
}

/* Keys drawn on the help card: small oak tiles. */
kbd {
  background: #3a2210;
  border-color: #6b4519;
  color: var(--cream);
  box-shadow: 0 1px 0 #1a0d04;
}
.btn-primary kbd { background: rgba(42, 26, 6, 0.16); border-color: rgba(42, 26, 6, 0.3); color: #2a1a06; }

/* The prompt under the dial and the HUD tooltips in the same brown. */
.tool-chip .tip { background: rgba(34, 19, 8, 0.95); border-color: rgba(120, 82, 40, 0.8); color: var(--cream); }
.boot-error { background: rgba(34, 19, 8, 0.96); color: var(--cream); }
.toast.good { border-left-color: var(--gold); }
