/* Private Property page and interface. The map itself is drawn on the canvas.

   Platforms (docs/PLATFORMS.md; DESIGN.md, "Platforms (#862)"): the game fills
   the space it has on the page and in full screen, held either way; text is at
   least --t-min; every button is at least 44 px with 8 px between buttons;
   the dense lawn grid uses whole-tile targets at least 24 px (DESIGN.md);
   everything the player reads or touches keeps inside the safe areas, and
   touch controls a further 16 px in from an edge that has an inset. */
:root {
  --bg: #141a12;
  --night: #10180f;
  --panel: rgba(22, 32, 24, 0.95);
  --panel-2: #223224;
  --panel-3: #2d4230;
  --line: #466148;
  --text: #f3f6ee;
  --muted: #b5c4ae;
  --gold: #ffcf5c;
  --gold-2: #f0a93b;
  --ink: #2a1a05;
  --good: #8fe39a;
  --bad: #ff8f8f;
  --heroic: #c6a4ff;
  --radius: 12px;
  /* The smallest text: 14 px on a desktop, 15 on a tablet, 13 on a phone. */
  --t-min: 14px;
  /* Thumb-sized controls, and the space between them. */
  --btn: 44px;
  --gap: 8px;
  /* Safe areas. Tests set these to a device's insets; browsers that have none report 0. */
  --safe-t: env(safe-area-inset-top, 0px);
  --safe-r: env(safe-area-inset-right, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-l: env(safe-area-inset-left, 0px);
  /* Touch controls keep 16 px further in from an edge that has an inset (the
     home indicator, and Safari's edge swipes beside a notch). min() is 0 where
     the inset is 0, and 16 px where there is one. */
  --safe-r-touch: calc(var(--safe-r) + min(16px, var(--safe-r) * 1000));
  --safe-b-touch: calc(var(--safe-b) + min(16px, var(--safe-b) * 1000));
  --safe-l-touch: calc(var(--safe-l) + min(16px, var(--safe-l) * 1000));
  /* Above the game on the page: the site header (48 px and the top inset,
     site/site.css) and the page's padding. */
  --top: calc(48px + var(--safe-t) + 8px);
  --foot: max(8px, var(--safe-b-touch));
  --pad-l: max(8px, var(--safe-l-touch));
  --pad-r: max(8px, var(--safe-r-touch));
  /* One row of the HUD. */
  --hud-h: 57px;
  /* The HUD's column on a phone held sideways. */
  --side-w: 164px;
  /* A ring option: wide enough for its longest word at the smallest text. */
  --opt-w: 84px;
  --opt-h: 76px;
  color-scheme: dark;
}

/* A tablet: a touch screen 600 px or more each way. */
@media (pointer: coarse) {
  :root {
    --t-min: 15px;
    --opt-w: 88px;
    --opt-h: 80px;
  }
}

/* A phone: a touch screen under 600 px one way or the other. */
@media (pointer: coarse) and (max-width: 599px), (pointer: coarse) and (max-height: 599px) {
  :root {
    --t-min: 13px;
    --opt-w: 80px;
    --opt-h: 72px;
  }
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Ubuntu, sans-serif;
  -webkit-text-size-adjust: 100%;
}

a {
  color: var(--gold);
}

button {
  font: inherit;
  color: inherit;
  touch-action: manipulation;
}

[hidden] {
  display: none !important;
}

.site-header {
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 16px;
  border-bottom: 1px solid #43372b;
}

.site-header nav a {
  color: #b5a797;
  text-decoration: none;
  font-size: 14px;
}

.page {
  padding: 8px var(--pad-r) 40px var(--pad-l);
}

.df-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

kbd {
  display: inline-block;
  min-width: 1.5em;
  padding: 0 5px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--panel-2);
  color: var(--text);
  font: 700 max(var(--t-min), 12px) / 1.4 system-ui, -apple-system, 'Segoe UI', Roboto, Ubuntu, sans-serif;
  text-align: center;
}

/* Key hints follow the last input used (main.js): none after a touch. */
.game-root.df-touch kbd {
  display: none;
}

/* ---------- Game frame ---------- */

/* The game is one screen tall on the page: the window's height under the site
   header, and no taller than the map needs at the page's width (16:9, or 9:16
   held upright, where the map is shown turned). The stage takes whatever the
   HUD leaves, and the map is drawn to fit it (src/render.js). */
.game-root {
  --game-w: min(1440px, calc(100vw - var(--pad-l) - var(--pad-r)));
  --avail-h: calc(100vh - var(--top) - var(--foot));
  --avail-h: calc(100dvh - var(--top) - var(--foot));
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 1440px;
  height: max(260px, min(var(--avail-h), calc(var(--game-w) * 9 / 16 + var(--hud-h))));
  margin: 0 auto;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--night);
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}

@media (orientation: portrait) {
  .game-root {
    height: max(260px, min(var(--avail-h), calc(var(--game-w) * 16 / 9 + 2 * var(--hud-h))));
  }
}

/* In play nothing scrolls, zooms or selects: not the page, not the map. The
   menus scroll themselves (.df-screen). */
.game-root[data-screen='play'] {
  touch-action: none;
  overscroll-behavior: none;
}

.df-stage {
  position: relative;
  flex: 1 1 0;
  min-height: 0;
  width: 100%;
  overflow: hidden;
  background: var(--night);
  touch-action: none;
}

.df-stage canvas {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}

/* Where the map keeps from the stage's edges (main.js reads it through this
   probe): the safe areas, and for touch a further 16 px from an inset. */
.df-probe {
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  padding: var(--safe-t) var(--safe-r-touch) var(--safe-b-touch) var(--safe-l-touch);
  visibility: hidden;
  pointer-events: none;
}

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

.df-hud {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap) 12px;
  min-height: var(--hud-h);
  padding: 6px 8px;
  border-bottom: 1px solid var(--line);
  background: linear-gradient(#181c38, #10132a);
  touch-action: none;
}

.df-hud-stats,
.df-hud-buttons {
  display: flex;
  align-items: center;
  gap: var(--gap) 12px;
  min-width: 0;
}

.df-hud-buttons {
  gap: var(--gap);
  margin-left: auto;
}

.df-readouts {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 12px;
  min-width: 0;
}

.df-stat {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: max(var(--t-min), 18px);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.df-stat-gold {
  min-width: 64px;
}

.df-lbl {
  color: var(--muted);
  font-size: var(--t-min);
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.df-ico {
  flex: none;
  display: inline-block;
}

.df-ico-ember {
  width: 15px;
  height: 14px;
  margin: 1px 0 0;
  clip-path: polygon(50% 0, 100% 45%, 86% 45%, 86% 100%, 14% 100%, 14% 45%, 0 45%);
  background: linear-gradient(#c8553d 0 45%, #f4ecd8 45% 100%);
}

.df-ico-gold {
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #fff4bf, #ffc93c 55%, #b9831b);
  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.35);
}

.df-preview {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--gap);
  min-width: 0;
}

.df-preview-label {
  color: var(--muted);
  font-size: var(--t-min);
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* The next wave: one button, its animals side by side (at most four). */
.df-chips {
  position: relative;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 2px;
  min-width: var(--btn);
  height: var(--btn);
  padding: 0 7px;
  border: 1px solid var(--line);
  border-radius: 22px;
  background: #1c2248;
  cursor: pointer;
}

.df-chips img {
  display: block;
  width: 26px;
  height: 26px;
}

.df-chips.df-new {
  border-color: var(--gold);
}

.df-chips.df-new::after {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--gold);
}

.df-hbtn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: var(--btn);
  min-width: var(--btn);
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel-3);
  color: var(--text);
  font-size: max(var(--t-min), 14px);
  font-weight: 800;
  white-space: nowrap;
  overflow: hidden;
  cursor: pointer;
}

@media (hover: hover) {
  .df-hbtn:hover {
    background: #2c3566;
  }
}

.df-hbtn:focus-visible,
.df-btn:focus-visible,
.df-map:focus-visible,
.df-up:focus-visible,
.df-tab:focus-visible,
.df-chips:focus-visible,
.df-opt:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

.df-hbtn kbd {
  min-width: 0;
  padding: 0 4px;
  line-height: 1.3;
  background: rgba(0, 0, 0, 0.25);
  border-color: rgba(255, 255, 255, 0.22);
}

.df-small-btn {
  width: var(--btn);
  padding: 0;
}

#df-mute .df-cross,
#df-mute[aria-pressed='true'] .df-waves {
  display: none;
}

#df-mute[aria-pressed='true'] .df-cross {
  display: inline;
}

#df-mute[aria-pressed='true'] {
  color: var(--muted);
}

.df-next {
  min-width: 112px;
  border-color: #ffe29a;
  background: linear-gradient(#ffd976, var(--gold-2));
  color: var(--ink);
}

@media (hover: hover) {
  .df-next:hover {
    background: linear-gradient(#ffe08c, #f5b24a);
  }
}

.df-next::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 4px;
  background: rgba(42, 26, 5, 0.55);
  transform: scaleX(var(--fill, 0));
  transform-origin: left center;
}

.df-next:disabled {
  border-color: var(--line);
  background: var(--panel-2);
  color: var(--muted);
  cursor: default;
}

.df-bonus {
  font-size: var(--t-min);
  color: #6b3d00;
}

.df-bonus:empty {
  display: none;
}

.df-next.df-pulse {
  animation: df-pulse 1.4s ease-in-out infinite;
}

@keyframes df-pulse {
  50% {
    box-shadow: 0 0 0 4px rgba(255, 207, 92, 0.35), 0 0 18px rgba(255, 207, 92, 0.6);
  }
}

.df-power {
  min-width: 68px;
  background: #1d2750;
}

.df-power::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: calc(var(--cd, 0) * 100%);
  background: rgba(0, 0, 0, 0.55);
  pointer-events: none;
}

.df-power.df-ready {
  border-color: rgba(255, 207, 92, 0.75);
  box-shadow: inset 0 0 12px rgba(255, 207, 92, 0.18);
}

.df-power.df-aiming {
  border-color: #fff1b8;
  background: linear-gradient(#ffd976, var(--gold-2));
  color: var(--ink);
}

.df-power-name,
.df-power kbd,
.df-power-icon {
  position: relative;
}

/* The power's picture: shown instead of its name where the HUD is narrow (a
   phone), so six controls fit a row at 44 px. */
.df-power-icon {
  display: none;
  width: 28px;
  height: 28px;
  flex: none;
}

/* While a power recharges, its seconds left replace the key hint beside the
   name, so the two never overlap. */
.df-cd {
  position: relative;
  min-width: 2ch;
  font-size: max(var(--t-min), 15px);
  font-weight: 900;
  font-variant-numeric: tabular-nums;
  color: #fff;
  text-shadow: 0 1px 3px #000;
  pointer-events: none;
}

.df-cd:empty {
  display: none;
}

.df-power:not(.df-ready) .df-power-name,
.df-power:not(.df-ready) .df-power-icon {
  opacity: 0.55;
}

.df-power:not(.df-ready) kbd {
  display: none;
}

/* ---------- Build ring and info ---------- */

/* The ring sits above notes and the info panel: it is what the player is
   using, and a note that shows up while it is open must not hide a choice.
   main.js places each option around the tile, far enough apart that every
   option keeps 8 px from the next, inside the stage and its safe areas. */
.df-ring {
  position: absolute;
  inset: 0;
  z-index: 9;
  pointer-events: none;
}

.df-opt {
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  width: var(--opt-w);
  min-height: var(--opt-h);
  padding: 4px 3px;
  border: 1px solid rgba(255, 220, 150, 0.45);
  border-radius: 14px;
  background: rgba(16, 20, 42, 0.95);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.55);
  color: var(--text);
  font: 700 var(--t-min) / 1.1 system-ui, -apple-system, 'Segoe UI', Roboto, Ubuntu, sans-serif;
  pointer-events: auto;
  touch-action: none;
  cursor: pointer;
  animation: df-pop 0.14s ease-out;
}

@keyframes df-pop {
  from {
    transform: scale(0.6);
    opacity: 0;
  }
}

@media (hover: hover) {
  .df-opt:hover {
    border-color: var(--gold);
    background: rgba(30, 36, 72, 0.97);
  }
}

.df-opt img {
  display: block;
  flex: none;
  width: 30px;
  height: 30px;
}

.df-opt-glyph {
  display: block;
  flex: none;
  height: 28px;
  font-size: 20px;
  line-height: 28px;
  color: var(--gold);
}

/* A name keeps to two lines at the smallest text: "Pitching / Machine". */
.df-opt-label {
  display: -webkit-box;
  max-width: 100%;
  overflow: hidden;
  text-align: center;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
}

.df-opt-cost {
  color: var(--gold);
  font-size: var(--t-min);
  font-weight: 900;
}

.df-opt-sell .df-opt-cost {
  color: var(--good);
}

.df-opt-key {
  position: absolute;
  top: 2px;
  right: 3px;
  min-width: 0;
  padding: 0 3px;
  line-height: 1.2;
  opacity: 0.85;
}

.df-opt.df-off {
  opacity: 0.6;
}

.df-opt.df-off .df-opt-cost {
  color: var(--bad);
}

.df-opt.df-armed {
  border-color: var(--gold);
  background: #3a3212;
  box-shadow: 0 0 0 2px var(--gold), 0 4px 14px rgba(0, 0, 0, 0.55);
}

.df-opt.df-armed .df-opt-label {
  color: #fff1b8;
}

/* main.js puts the panel on the side of the stage away from the ring, as wide
   as that side allows. */
.df-info {
  position: absolute;
  z-index: 5;
  max-width: 460px;
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: rgba(11, 13, 28, 0.93);
  font-size: max(var(--t-min), 13px);
  line-height: 1.35;
  pointer-events: none;
}

.df-info strong {
  color: var(--gold);
  font-size: max(var(--t-min), 14px);
}

.df-info p {
  margin: 2px 0 0;
}

.df-info .df-stats {
  color: var(--muted);
  font-size: var(--t-min);
}

/* A defence's numbers; while an upgrade is picked, now and after side by side. */
.df-cmp {
  margin-top: 4px;
  border-collapse: collapse;
  font-size: var(--t-min);
  font-variant-numeric: tabular-nums;
}

.df-cmp th {
  padding: 0 10px 0 0;
  color: var(--muted);
  font-weight: 400;
  text-align: left;
  white-space: nowrap;
}

.df-cmp td {
  padding: 0 4px;
  white-space: nowrap;
}

.df-cmp thead td {
  color: var(--muted);
}

.df-cmp .df-arrow {
  color: var(--gold);
}

.df-cmp .df-change .df-after {
  color: #9be27a;
  font-weight: 700;
}

.df-cmp .df-same td {
  opacity: 0.7;
}

/* Where the stage leaves the panel too little room beside the ring, it shows
   only what an upgrade changes, and a defence's name and use without its
   numbers. */
.df-info.df-short .df-cmp .df-same,
.df-info.df-short .df-cmp:not(.df-cmp2) {
  display: none;
}

/* ---------- Toast ---------- */

/* max-content: an absolutely placed box at left 50% would otherwise shrink
   to half the stage and wrap a short note into a tall column. */
/* Notes keep inside the stage's safe areas and, on a phone, clear of its
   corners (main.js sets --ui-*, as for the ring). */
.df-toast {
  position: absolute;
  top: calc(10px + var(--ui-t, 0px));
  left: calc(50% + (var(--ui-l, 0px) - var(--ui-r, 0px)) / 2);
  z-index: 8;
  width: max-content;
  max-width: min(540px, calc(100% - 20px - var(--ui-l, 0px) - var(--ui-r, 0px)));
  padding: 8px 14px;
  border: 1px solid rgba(255, 207, 92, 0.6);
  border-radius: 10px;
  background: rgba(10, 12, 26, 0.95);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
  color: var(--text);
  font-size: max(var(--t-min), 14px);
  line-height: 1.35;
  text-align: center;
  white-space: pre-line;
  transform: translateX(-50%);
  pointer-events: none;
}

.df-stage[data-info-side='top'] .df-toast {
  top: auto;
  bottom: calc(10px + var(--ui-b, 0px));
}

/* While a ring is open the ring and its panel come first: a notice goes
   under them and fades back. */
.df-stage[data-info-side] .df-toast {
  z-index: 4;
  opacity: 0.35;
}

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

.df-screen {
  position: absolute;
  inset: 0;
  z-index: 6;
  display: flex;
  padding: 14px max(14px, var(--screen-r, 0px)) max(14px, var(--screen-b, 0px)) max(14px, var(--screen-l, 0px));
  padding-top: max(14px, var(--screen-t, 0px));
  overflow-y: auto;
  overscroll-behavior: contain;
  touch-action: pan-y;
  background: radial-gradient(ellipse at center, rgba(8, 10, 22, 0.5), rgba(8, 10, 22, 0.86));
  -webkit-overflow-scrolling: touch;
}

.game-root[data-screen='title'] .df-screen {
  background: radial-gradient(ellipse at center, rgba(8, 10, 22, 0.25), rgba(8, 10, 22, 0.75));
}

.df-panel {
  width: min(760px, 100%);
  margin: auto;
  padding: 16px 18px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--panel);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
  user-select: text;
  -webkit-user-select: text;
}

.df-small-panel {
  width: min(430px, 100%);
}

.df-panel h2 {
  margin: 0;
  font-size: max(var(--t-min), 21px);
  line-height: 1.2;
}

.df-title {
  width: min(460px, 100%);
  border: 0;
  background: transparent;
  box-shadow: none;
  text-align: center;
}

.df-logo {
  margin: 0 0 4px !important;
  color: #ffe7a3;
  font: 800 clamp(34px, 6.5vw, 64px) / 1.05 Georgia, 'Times New Roman', serif !important;
  letter-spacing: 0.02em;
  text-shadow: 0 0 22px rgba(255, 190, 80, 0.6), 0 2px 0 #7a4b10;
}

.df-sub {
  margin: 4px 0 12px;
  color: var(--muted);
}

.df-title .df-sub {
  color: #d8dcf5;
  text-shadow: 0 1px 4px #000;
}

.df-menu {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--gap);
  max-width: 360px;
  margin: 0 auto;
}

.df-menu.df-row {
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: center;
  max-width: none;
  margin-top: 12px;
}

.df-row {
  display: flex;
  gap: var(--gap);
}

.df-row > .df-btn {
  flex: 1 1 auto;
}

.df-btn {
  min-height: var(--btn);
  min-width: var(--btn);
  padding: 8px 16px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel-3);
  color: var(--text);
  font-size: max(var(--t-min), 15px);
  font-weight: 800;
  line-height: 1.2;
  cursor: pointer;
}

@media (hover: hover) {
  .df-btn:hover {
    background: #2d3668;
  }
}

.df-btn small {
  display: block;
  margin-top: 1px;
  color: var(--muted);
  font-size: var(--t-min);
  font-weight: 600;
}

.df-primary {
  border-color: #ffe29a;
  background: linear-gradient(#ffd976, var(--gold-2));
  color: var(--ink);
}

@media (hover: hover) {
  .df-primary:hover {
    background: linear-gradient(#ffe08c, #f5b24a);
  }
}

.df-primary small {
  color: #5c3a08;
}

.df-ghost {
  background: transparent;
}

.df-locked {
  opacity: 0.6;
}

.df-danger {
  margin-top: 14px;
  border-color: #7a2c2c;
  background: #341515;
  color: #ffb3b3;
}

.df-heroic {
  border-color: #d9c2ff;
  background: linear-gradient(#a57dff, #6f43e8);
  color: #fff;
}

.df-heroic small {
  color: #efe6ff;
}

.df-foot {
  margin: 12px 0 0;
  color: var(--muted);
  font-size: max(var(--t-min), 13px);
}

.df-title .df-foot {
  color: #d8dcf5;
  text-shadow: 0 1px 4px #000;
}

.df-warn {
  color: #ffb38a;
  font-size: max(var(--t-min), 13px);
}

.df-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
}

.df-bar h2 {
  flex: 1;
  min-width: 0;
}

.df-bar .df-btn {
  padding: 6px 14px;
}

.df-count {
  color: var(--gold);
  font-weight: 900;
  white-space: nowrap;
}

/* The chapters wrap to a second row rather than scroll out of sight. */
.df-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap);
  margin: 4px 0 8px;
}

.df-tab {
  flex: none;
  min-height: var(--btn);
  padding: 6px 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--panel-2);
  color: var(--muted);
  font-size: max(var(--t-min), 14px);
  font-weight: 800;
  cursor: pointer;
}

.df-tab.df-on {
  border-color: #ffe29a;
  background: var(--gold);
  color: var(--ink);
}

.df-tab.df-locked {
  opacity: 0.55;
}

.df-maps {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: var(--gap);
}

.df-map {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  min-height: 78px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--panel-2);
  color: var(--text);
  text-align: left;
  cursor: pointer;
}

@media (hover: hover) {
  .df-map:hover {
    border-color: var(--gold);
  }
}

.df-map.df-locked {
  opacity: 0.5;
}

.df-bossmap {
  border-color: #6a4fc9;
  background: linear-gradient(#251d4c, var(--panel-2));
}

.df-map-num {
  color: var(--muted);
  font-size: var(--t-min);
  font-weight: 900;
}

.df-map-name {
  font-size: max(var(--t-min), 15px);
  font-weight: 800;
}

.df-lock,
.df-best {
  color: var(--muted);
  font-size: var(--t-min);
  font-weight: 700;
}

.df-stars {
  display: inline-flex;
  gap: 1px;
  white-space: nowrap;
}

.df-star {
  color: #3a4170;
  font-size: 17px;
  line-height: 1;
}

.df-star.df-on {
  color: var(--gold);
  text-shadow: 0 0 6px rgba(255, 207, 92, 0.6);
}

.df-star.df-heroic.df-on {
  margin-left: 3px;
  color: var(--heroic);
  text-shadow: 0 0 6px rgba(198, 164, 255, 0.7);
}

.df-bigstars {
  margin: 6px 0;
}

.df-bigstars .df-star {
  font-size: 46px;
}

.df-bigstars .df-star.df-on {
  animation: df-star-in 0.45s cubic-bezier(0.2, 1.6, 0.4, 1) both;
}

.df-bigstars .df-star:nth-child(2) {
  animation-delay: 0.26s;
}

.df-bigstars .df-star:nth-child(3) {
  animation-delay: 0.52s;
}

@keyframes df-star-in {
  from {
    transform: scale(0.2) rotate(-40deg);
    opacity: 0;
  }
}

/* Briefing */
.df-tip {
  margin: 8px 0;
  padding: 7px 10px;
  border-left: 3px solid var(--gold);
  border-radius: 6px;
  background: rgba(255, 207, 92, 0.1);
}

.df-intro {
  display: grid;
  gap: 8px;
  margin: 10px 0;
}

.df-card {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 8px 0;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #151a38;
}

.df-intro .df-card {
  margin: 0;
}

.df-card img {
  flex: none;
}

.df-card p {
  margin: 2px 0 0;
  color: var(--muted);
  font-size: max(var(--t-min), 14px);
}

.df-card-glyph {
  display: grid;
  flex: none;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--gold);
  color: var(--ink);
  font-weight: 900;
}

.df-rules,
.df-small {
  margin: 8px 0 0;
  color: var(--muted);
  font-size: max(var(--t-min), 13px);
}

/* Results */
.df-results {
  text-align: center;
}

.df-results h2 {
  font-size: 28px;
}

.df-win {
  color: var(--gold);
}

.df-lose {
  color: #ffa08f;
}

.df-good {
  margin: 4px 0;
  color: var(--good);
  font-weight: 800;
}

.df-stats-grid {
  display: grid;
  grid-template-columns: auto auto;
  justify-content: center;
  gap: 3px 16px;
  margin: 12px 0 6px;
}

.df-stats-grid dt {
  color: var(--muted);
  text-align: right;
}

.df-stats-grid dd {
  margin: 0;
  font-weight: 800;
  text-align: left;
  font-variant-numeric: tabular-nums;
}

.df-ach-new {
  margin: 4px 0;
  color: var(--heroic);
  font-weight: 800;
}

/* A panel's buttons stay in view at the foot of the screen while the rest
   scrolls under them, on a screen too short for the whole panel. */
.df-results > .df-menu,
.df-brief > .df-menu,
.df-daily > .df-menu {
  position: sticky;
  bottom: -14px;
  z-index: 1;
  margin: 12px -18px -16px;
  padding: 10px 18px 14px;
  border-radius: 0 0 16px 16px;
  background: var(--panel);
}

/* Room for the house ad before it fills, so the buttons above do not jump. */
.df-ad-results {
  min-height: 94px;
  margin-top: 14px;
  text-align: left;
}

/* Upgrades */
.df-uplist {
  display: grid;
  gap: 10px;
}

.df-upline {
  display: grid;
  grid-template-columns: 112px 1fr;
  align-items: center;
  gap: var(--gap);
}

.df-upline-name {
  font-weight: 900;
}

.df-upranks {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--gap);
}

.df-up {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-height: 86px;
  padding: 8px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel-2);
  color: var(--text);
  font-size: var(--t-min);
  text-align: left;
  cursor: pointer;
}

.df-up strong {
  font-size: max(var(--t-min), 14px);
}

.df-up-desc {
  color: var(--muted);
}

.df-up-cost {
  margin-top: auto;
  color: var(--gold);
  font-weight: 900;
}

.df-up-owned {
  border-color: var(--gold);
  background: #2c2917;
}

.df-up-owned .df-up-cost {
  color: var(--good);
}

.df-up-locked {
  opacity: 0.6;
}

.df-up-short .df-up-cost {
  color: var(--bad);
}

/* Achievements */
.df-achs {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 6px;
  margin: 8px 0 0;
  padding: 0;
  list-style: none;
}

.df-achs li {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px 10px;
  border-left: 3px solid var(--line);
  border-radius: 8px;
  background: #151a38;
  font-size: max(var(--t-min), 13px);
  opacity: 0.6;
}

.df-achs li span {
  color: var(--muted);
}

.df-achs li.df-got {
  border-left-color: var(--gold);
  opacity: 1;
}

/* Settings: a slider or a checkbox is pressed by its whole row. */
.df-volumes {
  display: grid;
  gap: var(--gap);
  width: 100%;
  margin: 6px 0;
}

.df-slider {
  display: grid;
  grid-template-columns: 64px 1fr;
  align-items: center;
  gap: 8px;
  min-height: var(--btn);
  font-weight: 700;
}

.df-slider input {
  width: 100%;
  height: var(--btn);
  margin: 0;
  accent-color: var(--gold);
  touch-action: pan-y;
}

.df-check {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: var(--btn);
  margin: 12px 0;
  cursor: pointer;
}

.df-check input {
  flex: none;
  width: 22px;
  height: 22px;
  margin: 0;
  accent-color: var(--gold);
}

.df-keys {
  color: var(--muted);
  font-size: max(var(--t-min), 13px);
  line-height: 1.7;
}

.df-keys h3 {
  margin: 10px 0 2px;
  color: var(--text);
  font-size: max(var(--t-min), 15px);
}

.df-keys p {
  margin: 0 0 4px;
}

/* Daily Patrol */
.df-icons {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 6px;
}

.df-icon {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: max(var(--t-min), 13px);
  font-weight: 700;
}

/* ---------- Page below the game ---------- */

.ad-slot {
  max-width: 970px;
  margin: 12px auto 0;
  min-height: 0;
}

.ad-slot[data-filled='true'] {
  min-height: 90px;
}

.about {
  max-width: 820px;
  margin: 24px auto 0;
  color: var(--muted);
  font-size: 15px;
  line-height: 1.55;
}

.about h1,
.about h2 {
  color: var(--text);
}

.about strong {
  color: var(--text);
}

/* ---------- Narrow screens: a phone held upright ---------- */

/* Two rows of HUD: the readouts and the next wave, then the controls, with
   the powers as pictures so the six fit a row. */
@media (max-width: 599px) {
  .df-hud {
    gap: var(--gap);
    padding: 6px;
  }
  .df-hud-stats {
    gap: 4px 10px;
    width: 100%;
    /* As tall with or without the next wave's animals (none on the pause
       screen and after the last wave), so the map keeps its size. */
    min-height: var(--btn);
  }
  .df-hud-buttons {
    width: 100%;
    margin-left: 0;
  }
  .df-next {
    flex: 1 1 auto;
    min-width: 0;
    padding: 0 6px;
    gap: 0 4px;
    flex-wrap: wrap;
    align-content: center;
    line-height: 1.1;
  }
  .df-power {
    min-width: var(--btn);
    width: var(--btn);
    padding: 0;
  }
  .df-power .df-power-name,
  .df-power kbd {
    display: none;
  }
  .df-power .df-power-icon {
    display: block;
  }
  .df-power .df-cd {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    background: rgba(0, 0, 0, 0.35);
  }
  .df-preview {
    margin-left: auto;
  }
  .df-preview-label {
    display: none;
  }
  .df-readouts {
    gap: 4px 8px;
  }
  .df-stat {
    font-size: max(var(--t-min), 16px);
  }
  .df-panel {
    padding: 12px;
  }
  .df-screen {
    padding: 8px;
  }
  .df-upline {
    grid-template-columns: 1fr;
    gap: 4px;
  }
  .df-maps {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .df-map {
    min-height: 70px;
    padding: 8px 10px;
  }
}

/* The narrowest phones: the wave count without its word, so the first row
   keeps to one line with six-figure cash and four kinds of animal coming. */
@media (max-width: 379px) {
  .df-stat-wave .df-lbl,
  .df-next-word {
    display: none;
  }
}

/* Phones held upright and sideways: the site header steps aside while a map
   is in play, and comes back on the pause screen and the results, with its
   "Full screen" button. */
@media (orientation: portrait) and (max-width: 599px), (orientation: landscape) and (max-height: 540px) {
  body.df-play .site-header {
    display: none;
  }
  body.df-play {
    --top: max(4px, var(--safe-t));
  }
  body.df-play .page {
    padding-top: max(4px, var(--safe-t));
  }
}

/* ---------- Short screens held sideways: the HUD moves to the side ---------- */

@media (orientation: landscape) and (max-height: 540px) {
  :root {
    --hud-h: 0px;
  }
  body.df-playing .game-root {
    display: grid;
    grid-template-columns: minmax(0, 1fr) var(--side-w);
    grid-template-rows: minmax(0, 1fr);
    height: max(240px, var(--avail-h));
  }
  body.df-playing .df-stage {
    grid-column: 1;
    grid-row: 1;
    height: 100%;
  }
  body.df-playing .df-hud {
    grid-column: 2;
    grid-row: 1;
    flex-direction: column;
    flex-wrap: nowrap;
    align-items: stretch;
    justify-content: flex-start;
    gap: var(--gap);
    min-height: 0;
    padding: 6px;
    border-bottom: 0;
    border-left: 1px solid var(--line);
    overflow-y: auto;
  }
  body.df-playing .df-hud-stats {
    flex-wrap: wrap;
    gap: 4px 10px;
  }
  body.df-playing .df-stat-wave {
    width: 100%;
  }
  body.df-playing .df-preview {
    width: 100%;
  }
  body.df-playing .df-preview-label {
    display: none;
  }
  body.df-playing .df-hud-buttons {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: var(--gap);
    margin: 0;
  }
  body.df-playing .df-power {
    grid-column: span 3;
    min-width: 0;
    padding: 0 4px;
  }
  body.df-playing .df-power .df-power-name,
  body.df-playing .df-power kbd {
    display: none;
  }
  body.df-playing .df-power .df-power-icon {
    display: block;
  }
  body.df-playing .df-next {
    grid-column: span 6;
    min-width: 0;
  }
  body.df-playing .df-small-btn {
    grid-column: span 2;
    width: auto;
  }
  .df-panel {
    padding: 10px 12px;
  }
  .df-screen {
    padding: 6px;
  }
  /* The title beside its buttons, so both fit the height. */
  .df-title {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 300px);
    align-items: center;
    gap: 6px 20px;
    width: min(760px, 100%);
    text-align: left;
  }
  .df-title .df-logo,
  .df-title .df-sub,
  .df-title .df-foot,
  .df-title .df-warn {
    grid-column: 1;
  }
  .df-title .df-menu {
    grid-column: 2;
    grid-row: 1 / span 4;
    width: 100%;
  }
  .df-title .df-logo {
    font-size: 34px !important;
  }
}

/* A phone's rounded corners, which Android doesn't report as safe areas:
   nothing the player reads or touches within 24 px of two of the screen's
   edges. Upright, the HUD's first row keeps 24 px from the sides; sideways,
   the HUD's column keeps 24 px from the top and the bottom. (main.js keeps
   the map and the ring clear of them.) */
@media (pointer: coarse) and (max-width: 599px) {
  .df-hud-stats {
    padding: 0 10px;
  }
}

@media (pointer: coarse) and (orientation: landscape) and (max-height: 540px) {
  body.df-playing .df-hud {
    padding-top: 20px;
    padding-bottom: 16px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .df-next.df-pulse,
  .df-opt {
    animation: none;
  }
}

/* ---------- Full screen (the site's button, site/fullscreen.js) ---------- */

/* The game fills the screen: no frame, the HUD and the menus inside the safe
   areas, and the map drawn to fit the rest (main.js keeps it inside them). */
.game-root.df-fs {
  width: 100%;
  max-width: none;
  height: 100%;
  border: 0;
  border-radius: 0;
}

.game-root.df-fs .df-hud {
  padding-top: max(8px, var(--safe-t));
  padding-right: max(8px, var(--safe-r-touch));
  padding-left: max(8px, var(--safe-l-touch));
}

/* "Leave full screen" sits at the top of the screen in the middle (44 px, 8
   px down). The HUD's two halves keep 30 px either side of the middle, and the
   menus start below it. */
.game-root.df-fs .df-hud {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 60px minmax(0, 1fr);
  align-items: center;
}

.game-root.df-fs .df-hud-stats {
  grid-column: 1;
  flex-wrap: wrap;
  /* Keep the exit's row when pause/results hide the wave preview. */
  min-height: var(--btn);
}

.game-root.df-fs .df-hud-buttons {
  grid-column: 3;
  flex-wrap: wrap;
  justify-content: flex-end;
}

.game-root.df-fs .df-screen {
  --screen-t: 60px;
  --screen-r: var(--safe-r-touch);
  --screen-b: var(--safe-b-touch);
  --screen-l: var(--safe-l-touch);
}

.game-root.df-fs[data-screen='play'] .df-screen,
.game-root.df-fs[data-screen='pause'] .df-screen,
.game-root.df-fs[data-screen='results'] .df-screen {
  --screen-t: 0px;
}

/* Under 1200 px wide the controls take a row of their own, below the
   readouts, which part around the middle: the readouts on the left and the
   next wave on the right. (Two rows whatever the last input or the wave, so
   the map keeps its size.) */
@media (max-width: 1199px) {
  .game-root.df-fs .df-hud-stats {
    grid-column: 1 / span 3;
    display: grid;
    grid-template-columns: minmax(0, 1fr) 60px minmax(0, 1fr);
  }
  .game-root.df-fs .df-readouts {
    grid-column: 1;
  }
  .game-root.df-fs .df-preview {
    grid-column: 3;
    justify-self: end;
  }
  .game-root.df-fs .df-hud-buttons {
    grid-column: 1 / span 3;
  }
}

/* A phone held upright: the HUD starts below the button. */
@media (max-width: 599px) {
  .game-root.df-fs .df-hud {
    padding-top: max(60px, var(--safe-t));
  }
  .game-root.df-fs .df-hud-stats {
    display: flex;
  }
}

/* A phone held sideways: the top of the screen in the middle is the yard, so
   the button goes to the top of the HUD's column, which keeps that place free
   for it. */
@media (orientation: landscape) and (max-height: 540px) {
  body.df-playing .game-root.df-fs {
    grid-template-columns: minmax(0, 1fr) calc(var(--side-w) + max(0px, var(--safe-r-touch)));
  }
  body.df-playing .game-root.df-fs .df-hud {
    display: flex;
    padding: max(60px, var(--safe-t)) max(6px, var(--safe-r-touch)) max(24px, var(--safe-b-touch)) 6px;
  }
  body.df-playing .game-root.df-fs .df-hud-stats {
    display: flex;
  }
  body.df-playing .game-root.df-fs .am-fs-exit {
    left: auto;
    right: calc(max(6px, var(--safe-r-touch)) + (var(--side-w) - 12px - 44px) / 2);
  }
}

/* #1165: a small sideways phone needs a narrower rail when a notch and
   gesture insets take both sides. Put speed/sound/pause in a row above the
   yard; the rail then holds the readouts, wave preview, powers and Next. */
@media (orientation: landscape) and (max-height: 540px) and (max-width: 700px) {
  :root { --side-w: 128px; --opt-h: 60px; }
  body.df-playing .df-opt img { width: 20px; height: 20px; }
  body.df-playing .df-screen { padding-top: max(60px, var(--ui-t, 0px)); }
  body.df-playing .df-hud { padding-top: 8px; }
  body.df-playing .df-hud-buttons { width: 100%; row-gap: 8px; }
  body.df-playing .df-chips { padding-inline: 3px; gap: 0; }
  body.df-playing .df-chips img { width: 20px; height: 20px; }
  body.df-playing .df-stat { font-size: max(var(--t-min), 16px); }
  body.df-playing .df-small-btn {
    position: absolute;
    top: 8px;
    width: 44px;
    z-index: 10;
  }
  body.df-playing #df-speed { left: 24px; }
  body.df-playing #df-mute { left: 76px; }
  body.df-playing #df-pause { left: 128px; }
  body.df-playing .game-root.df-fs .df-hud { padding-top: max(8px, var(--safe-t)); }
  body.df-playing .game-root.df-fs .df-small-btn { top: max(8px, var(--safe-t)); }
  body.df-playing .game-root.df-fs #df-speed { left: max(24px, var(--safe-l-touch)); }
  body.df-playing .game-root.df-fs #df-mute { left: calc(max(24px, var(--safe-l-touch)) + 52px); }
  body.df-playing .game-root.df-fs #df-pause { left: calc(max(24px, var(--safe-l-touch)) + 104px); }
  body.df-playing .game-root.df-fs .am-fs-exit {
    top: max(8px, var(--safe-t));
    right: auto;
    left: calc(max(24px, var(--safe-l-touch)) + 156px);
  }
}
