:root {
  color-scheme: dark;
  --cream: #fff3c8;
  --gold: #f4c663;
  --green: #233f29;
  --ink: #122b29;
  --muted: #b9cfb8;
  --line: #d4b86f;
  --shadow: #071717;
}
* {
  box-sizing: border-box;
}
html,
body {
  width: 100%;
  height: 100%;
  margin: 0;
  overflow: hidden;
}
body {
  font:
    700 15px/1.35 "Trebuchet MS",
    system-ui,
    sans-serif;
  background: #081f20;
  color: var(--cream);
  -webkit-tap-highlight-color: transparent;
}
button,
select {
  font: inherit;
  color: inherit;
  cursor: pointer;
  touch-action: manipulation;
}
button {
  border: 0;
  transition:
    filter 0.14s,
    transform 0.14s;
}
button:hover:not(:disabled) {
  filter: brightness(1.13);
  transform: translateY(-2px);
}
button:active:not(:disabled) {
  transform: translateY(2px);
}
button:focus-visible,
select:focus-visible {
  outline: 3px solid #e9fcff;
  outline-offset: 5px;
}
button:disabled {
  cursor: not-allowed;
  filter: saturate(0.25);
  opacity: 0.55;
}
[hidden] {
  display: none !important;
}
#app {
  height: 100dvh;
  width: 100%;
  position: relative;
  isolation: isolate;
  container-type: inline-size;
}
#app[data-preview="true"] {
  width: min(100%, 520px);
  margin-inline: auto;
  box-shadow: 0 0 100px #0009;
}
.screen {
  position: absolute;
  inset: 0;
  overflow: hidden;
}
.title-screen {
  background: #143b35 url("assets/title-forest.webp") center center/cover
    no-repeat;
}
.title-shade {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    0deg,
    #061919aa,
    transparent 30%,
    #061d1d10 65%,
    #031f2533
  );
}
.title-menu {
  position: absolute;
  top: 8%;
  left: 50%;
  transform: translateX(-50%);
  width: min(560px, 85vw);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.crest {
  font-size: 58px;
  line-height: 1;
  color: #e7d394;
  text-shadow: 0 0 25px #f7df91aa;
  margin-bottom: 0;
}
h1 {
  font:
    900 clamp(68px, 8vw, 112px) / 1.05 Georgia,
    serif;
  letter-spacing: -5px;
  color: #ffe7a0;
  margin: 0;
  text-shadow:
    0 3px #b2944a,
    0 6px #614d29,
    0 9px #1d322b,
    0 12px 30px #021d25;
  -webkit-text-stroke: 1px #ffedb4;
}
.title-sub {
  display: flex;
  align-items: center;
  gap: 17px;
  width: 90%;
  margin-top: 20px;
}
.title-sub span {
  height: 1px;
  background: linear-gradient(90deg, transparent, #c5b775);
  flex: 1;
}
.title-sub span:last-child {
  transform: rotate(180deg);
}
.title-sub p {
  margin: 0;
  font-size: 12px;
  letter-spacing: 4px;
  text-shadow: 0 2px 4px #000;
}
.title-tagline {
  font:
    italic 18px Georgia,
    serif;
  color: #e6efd4;
  text-shadow: 0 2px 4px #001e1e;
  margin: 28px 0 32px;
}
.gold-button {
  background: linear-gradient(#ffe8a0 0, #f4c868 45%, #e3aa46 100%);
  border: 2px solid #ffe9aa;
  border-radius: 13px;
  color: #513918;
  text-shadow: 0 1px #ffedb3;
  box-shadow:
    0 5px 0 #8c5b2c,
    0 7px 0 #362d1e,
    0 12px 22px #0006,
    inset 0 0 0 2px #c18b3c;
  font-weight: 900;
  padding: 15px 28px;
  font-size: 18px;
}
.play-button {
  min-width: 280px;
  font-size: 28px;
  letter-spacing: 1px;
  padding: 15px 30px;
  display: flex;
  justify-content: center;
  gap: 42px;
}
.play-button span:last-child {
  font-size: 22px;
  align-self: center;
}
.play-button:not(:disabled) {
  animation: bob 4s ease-in-out infinite;
}
.difficulty-picker {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  margin-top: 16px;
  min-height: 44px;
  flex-shrink: 0;
  font-size: 13px;
  color: var(--cream);
  text-shadow: 0 1px 4px #031c18;
}
.difficulty-control { position: relative; width: 216px; }
.difficulty-toggle,
.difficulty-option {
  width: 100%;
  height: 44px;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 0 10px;
  font-size: 13px;
  text-align: left;
  white-space: nowrap;
}
.difficulty-toggle {
  border-radius: 8px;
  background: #0d3029cc;
  box-shadow: inset 0 0 0 1px #c9bd7044;
}
.difficulty-picker small { font-size: 10px; color: #c8cdb5; font-weight: 400; }
.difficulty-arrows { margin-left: auto; line-height: 7px; color: var(--gold); }
.difficulty-options {
  position: absolute;
  top: calc(var(--selected-index, 1) * -44px);
  left: 0;
  width: 100%;
  border-radius: 10px;
  overflow: hidden;
  background: #153e33;
  box-shadow: 0 8px 25px #0009, 0 0 0 1px #c4bb79;
}
.difficulty-option { background: transparent; }
.difficulty-option[aria-selected="true"] { color: var(--gold); background: #3d5137; }
.difficulty-option:focus-visible { outline: 2px solid #e9fcff; outline-offset: -3px; }
.difficulty-toggle:hover:not(:disabled),
.difficulty-option:hover:not(:disabled),
.difficulty-toggle:active:not(:disabled),
.difficulty-option:active:not(:disabled) { transform: none; }
.title-secondary {
  display: flex;
  gap: 14px;
  margin-top: 12px;
}
.wood-button {
  background: linear-gradient(#34564d, #1c3936);
  border: 1px solid #c4bb79;
  border-radius: 9px;
  padding: 12px 22px;
  color: #eee6be;
  box-shadow:
    0 3px 0 #0c2525,
    inset 0 0 0 3px #102b2a;
  font-size: 14px;
}
.title-corner {
  position: absolute;
  bottom: 25px;
  left: 30px;
  display: flex;
  align-items: center;
  gap: 13px;
  color: #cdd9b7;
  font-size: 10px;
  letter-spacing: 2px;
  text-shadow: 0 1px 3px #000;
}
.leaf-mark {
  font-size: 32px;
}
.round-button {
  width: 48px;
  height: 48px;
  border-radius: 14px;
  background: linear-gradient(#375950, #182f2d);
  border: 2px solid #b7b780;
  box-shadow:
    0 4px 0 #0e2623,
    inset 0 0 0 3px #213d34,
    0 6px 18px #0004;
  font-size: 23px;
  color: #ffedbd;
  display: grid;
  place-items: center;
  flex-shrink: 0;
}
.fullscreen {
  position: absolute;
  bottom: 25px;
  right: 30px;
}
#loadStatus {
  font-size: 12px;
  color: #cde1c8;
  margin-top: 15px;
  min-height: 17px;
}
#loadStatus:empty {
  visibility: hidden;
}
.motes {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
}
.motes i {
  position: absolute;
  width: 5px;
  height: 5px;
  background: #eafaac;
  border-radius: 50%;
  box-shadow: 0 0 12px #ffff8a;
  animation: float 9s ease-in-out infinite;
  left: 25%;
  top: 70%;
}
.motes i:nth-child(2) {
  left: 67%;
  top: 56%;
  animation-delay: -3s;
}
.motes i:nth-child(3) {
  left: 46%;
  top: 80%;
  animation-delay: -6s;
}
.motes i:nth-child(4) {
  left: 82%;
  top: 32%;
  animation-delay: -2s;
}
.motes i:nth-child(5) {
  left: 13%;
  top: 22%;
  animation-delay: -5s;
}
.motes i:nth-child(6) {
  left: 73%;
  top: 87%;
  animation-delay: -8s;
}
.motes i:nth-child(7) {
  left: 31%;
  top: 47%;
  animation-delay: -1s;
}
.motes i:nth-child(8) {
  left: 56%;
  top: 30%;
  animation-delay: -4s;
}
@keyframes float {
  0%,
  100% {
    transform: translate(0, 0);
    opacity: 0.25;
  }
  50% {
    transform: translate(22px, -50px);
    opacity: 1;
  }
}
/* Campaign is a game screen, with spatial progress instead of a list. */
.campaign-screen {
  background: radial-gradient(ellipse, #507460, #102f2c);
  display: flex;
  align-items: center;
  justify-content: center;
}
.screen-heading {
  position: absolute;
  top: 22px;
  left: 28px;
  right: 28px;
  display: flex;
  align-items: center;
  gap: 20px;
  z-index: 2;
}
.screen-heading small {
  letter-spacing: 2px;
  color: #cad6ad;
  font-size: 10px;
}
.screen-heading h2 {
  font:
    700 28px Georgia,
    serif;
  margin: 3px 0;
  color: #fff0bb;
  text-shadow: 0 3px 4px #122d21;
}
.star-total {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 10px;
  background: #152e2cd9;
  border: 1px solid #718461;
  border-radius: 30px;
  padding: 11px 20px;
}
.star-total span {
  color: #f6cf70;
  font-size: 25px;
}
.star-total b {
  font-size: 20px;
}
.campaign-board {
  position: relative;
  width: min(100vw, calc(100dvh * 1.5));
  aspect-ratio: 1.5;
  max-height: 100%;
}
#campaignCanvas {
  width: 100%;
  height: 100%;
  display: block;
}
.campaign-board:after {
  content: "";
  position: absolute;
  inset: 0;
  box-shadow: inset 0 0 100px 30px #102e2c;
  pointer-events: none;
}
#levelNodes {
  position: absolute;
  inset: 0;
  z-index: 1;
}
.level-node {
  position: absolute;
  transform: translate(-50%, -50%);
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: linear-gradient(#f5d784, #bb8438);
  border: 3px solid #fff0b0;
  box-shadow:
    0 4px 0 #684b28,
    0 8px 16px #102818b0;
  color: #52391b;
  font-size: 23px;
  font-weight: 900;
}
.level-node:hover:not(:disabled) {
  transform: translate(-50%, -53%);
}
.level-node:disabled {
  opacity: 1;
  background: linear-gradient(#657c70, #354e47);
  border-color: #8fa085;
  color: #b4c3a9;
  filter: none;
}
.level-node.selected {
  outline: 4px solid #edf7a4;
  outline-offset: 7px;
}
.level-node small {
  position: absolute;
  bottom: -26px;
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  font-size: 17px;
  letter-spacing: 2px;
  color: #ffe58d;
  text-shadow: 0 2px 3px #0c241e;
}
.level-node .node-flag {
  position: absolute;
  top: -32px;
  left: 16px;
  color: #fff3bc;
  font-size: 25px;
  animation: bob 2s ease-in-out infinite;
}
.region-label {
  position: absolute;
  letter-spacing: 3px;
  font-size: 10px;
  color: #e3e1ba;
  text-shadow: 0 2px 5px #18342b;
  transform: rotate(-7deg);
}
.region-one {
  left: 13%;
  top: 20%;
}
.region-two {
  right: 16%;
  top: 57%;
}
.mission-panel {
  position: absolute;
  bottom: 22px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  width: min(600px, 90%);
  padding: 16px 22px;
  border: 2px solid #b5a66c;
  border-radius: 16px;
  background: linear-gradient(#223d35f5, #102e29fa);
  box-shadow:
    0 6px 0 #0c211f,
    0 8px 40px #09201c;
  display: flex;
  align-items: center;
  gap: 25px;
}
.mission-panel h3 {
  font:
    700 26px Georgia,
    serif;
  margin: 2px 0 6px;
}
.mission-panel small {
  color: var(--gold);
  font-size: 10px;
  letter-spacing: 2px;
}
.mission-panel p {
  font-size: 12px;
  color: #baceb4;
  margin: 0;
}
.mission-panel > div {
  flex: 1;
}
.mission-panel button {
  white-space: nowrap;
  padding: 13px 22px;
}
/* Battle: terrain first, controls in corners and construction at the selected pad. */
.battle-screen {
  display: flex;
  align-items: center;
  justify-content: center;
  background: #102c25 url("assets/battlefield.webp") center/cover;
}
.battle-screen:before {
  content: "";
  position: absolute;
  inset: 0;
  background: #09231bd9;
  backdrop-filter: blur(15px);
}
.battle-stage {
  position: relative;
  width: min(100vw, calc(100dvh * 1.5));
  aspect-ratio: 1.5;
  isolation: isolate;
}
.battle-field {
  position: relative;
  width: 100%;
  height: 100%;
}
#board {
  display: block;
  width: 100%;
  height: 100%;
}
.pads {
  position: absolute;
  inset: 0;
  z-index: 2;
}
.pad {
  position: absolute;
  width: 8%;
  height: 12%;
  transform: translate(-50%, -50%);
  background: transparent;
  border-radius: 50%;
  padding: 0;
  color: transparent;
}
.pad:hover:not(:disabled) {
  transform: translate(-50%, -50%);
  background: #ffefaf22;
  outline: 2px solid #fff0acaa;
}
.pad:active:not(:disabled) {
  transform: translate(-50%, -50%);
}
.battle-hud {
  position: absolute;
  z-index: 4;
  top: 15px;
  left: 18px;
  right: 18px;
  display: flex;
  align-items: flex-start;
  gap: 14px;
  pointer-events: none;
}
.battle-hud button {
  pointer-events: auto;
}
.hud-resources {
  display: flex;
  gap: 8px;
}
.resource {
  border-radius: 12px;
  background: linear-gradient(#263b30ed, #0b2a23ee);
  border: 2px solid #a6a474;
  padding: 7px 17px 7px 10px;
  display: flex;
  align-items: center;
  gap: 9px;
  box-shadow:
    0 4px 0 #163023,
    0 5px 12px #0004;
}
.resource b {
  font-size: 23px;
  font-weight: 900;
  font-variant-numeric: tabular-nums;
}
.life-icon {
  font-size: 28px;
  color: #ff8971;
  text-shadow: 0 3px #9d453a;
}
.coin-icon {
  font-size: 26px;
  color: #ffcf69;
  text-shadow: 0 3px #96702c;
}
.wave-counter {
  display: flex;
  align-items: center;
  gap: 8px;
  background: #183329df;
  border: 1px solid #a1a174;
  border-radius: 10px;
  padding: 11px 15px;
  margin-left: auto;
}
.wave-counter small {
  font-size: 10px;
  letter-spacing: 1px;
  color: #c4d4a8;
}
.wave-counter b {
  font-size: 18px;
}
.battle-caption {
  position: absolute;
  z-index: 3;
  top: 80px;
  left: 22px;
  display: flex;
  gap: 9px;
  align-items: center;
  color: #fff3ce;
  text-shadow: 0 2px 5px #15351b;
  pointer-events: none;
}
.battle-caption #chapter {
  font-size: 11px;
}
.battle-caption strong {
  font-size: 13px;
}
.battle-caption #best {
  color: #ffe188;
  font-size: 14px;
  letter-spacing: 2px;
}
.battle-bottom {
  position: absolute;
  bottom: 15px;
  left: 18px;
  right: 18px;
  z-index: 4;
  display: flex;
  align-items: flex-end;
  gap: 12px;
  pointer-events: none;
}
.battle-bottom button {
  pointer-events: auto;
}
.battle-message {
  margin: auto auto 4px 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
  text-shadow: 0 2px 4px #0b271c;
  pointer-events: none;
  max-width: 45%;
}
#boardTip {
  font-size: 14px;
  color: #fff3cc;
}
#status {
  font-size: 11px;
  color: #e3ebcd;
}
#wavePreview {
  font-size: 10px;
  color: #d4e1bd;
}
.wave-actions {
  display: flex;
  align-items: flex-end;
  gap: 9px;
}
.send-wave {
  font-size: 14px;
  padding: 13px 17px;
  min-width: 150px;
}
.send-wave:disabled {
  opacity: 1;
  filter: none;
  background: linear-gradient(#3a5742, #233d32);
  color: #d5dfba;
  text-shadow: none;
  border-color: #92a36d;
  box-shadow:
    0 4px 0 #193225,
    inset 0 0 0 2px #304e38;
}
.speed-button {
  background: #203a2bdd;
  border: 2px solid #b6bb80;
  border-radius: 10px;
  color: #fff0bc;
  padding: 9px 11px;
  box-shadow: 0 3px 0 #143024;
  font-size: 15px;
}
.spell-button {
  width: 64px;
  height: 66px;
  border-radius: 16px;
  border: 2px solid #e9d995;
  background: radial-gradient(
    ellipse at 40% 20%,
    #b6d96a,
    #4b7a4a 60%,
    #234835
  );
  box-shadow:
    0 5px 0 #234735,
    0 7px 15px #18341caa;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  position: relative;
}
.spell-button span {
  font-size: 36px;
  color: #fff6bf;
  line-height: 1;
  text-shadow: 0 0 10px #f2ff9b;
}
.spell-button small {
  font-size: 9px;
  letter-spacing: 1px;
}
.spell-button:disabled {
  filter: grayscale(0.6);
  opacity: 0.7;
}
.map-label {
  position: absolute;
  bottom: 3px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 7px;
  letter-spacing: 2px;
  color: #e9edc477;
  pointer-events: none;
}
.entry-flag {
  position: absolute;
  left: 1%;
  top: 32%;
  font-size: 26px;
  color: #ffe9a2;
  text-shadow: 0 2px 4px #392b12;
  z-index: 1;
  animation: bob 1.5s ease-in-out infinite;
}
.build-menu {
  position: absolute;
  z-index: 6;
  width: 290px;
  border: 2px solid #e1ca83;
  border-radius: 16px;
  background: linear-gradient(#274638f7, #15362dfc);
  padding: 12px;
  box-shadow:
    0 5px 0 #152c21,
    0 12px 30px #09231888;
  transform: translate(-50%, -100%);
}
.build-menu:after {
  content: "";
  position: absolute;
  bottom: -9px;
  left: calc(50% - 7px);
  width: 14px;
  height: 14px;
  background: #16372c;
  border-right: 2px solid #e1ca83;
  border-bottom: 2px solid #e1ca83;
  transform: rotate(45deg);
}
.close-build {
  position: absolute;
  right: -11px;
  top: -13px;
  width: 28px;
  height: 28px;
  background: #594335;
  border: 2px solid #dfc68b;
  border-radius: 50%;
  font-size: 19px;
  line-height: 1;
}
.build-heading {
  text-align: center;
  font-size: 12px;
  color: #e8eac4;
  margin: 0 0 8px;
}
#towerShop {
  display: flex;
  gap: 7px;
}
.tower-card {
  background: linear-gradient(#365a43, #213e30);
  border: 1px solid #afbb7d;
  border-radius: 10px;
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  flex-direction: column;
  padding: 4px 3px 8px;
  box-shadow: 0 3px 0 #153124;
}
.tower-card .portrait {
  width: 68px;
  height: 64px;
  border-radius: 8px;
}
.tower-card strong {
  font-size: 11px;
}
.tower-card small {
  font-size: 9px;
  color: #bdcfad;
}
.tower-card .price {
  font-size: 12px;
  color: #ffdd7c;
  margin-top: 4px;
}
.portrait {
  display: block;
  background-image: url("assets/characters.webp");
  background-size: 300% 200%;
  background-repeat: no-repeat;
  mask-image: radial-gradient(
    ellipse at center,
    #000 40%,
    #000b 65%,
    transparent 78%
  );
}
.portrait.reed {
  background-position: 0 0;
}
.portrait.mortar {
  background-position: 50% 0;
}
.portrait.frost {
  background-position: 100% 0;
}
.portrait.basic {
  background-position: 0 100%;
}
.portrait.runner {
  background-position: 50% 100%;
}
.portrait.tank {
  background-position: 100% 100%;
}
#selection {
  text-align: center;
  font-size: 12px;
}
#selection .tower-detail {
  display: flex;
  align-items: center;
  gap: 10px;
  text-align: left;
  margin-bottom: 8px;
}
#selection .portrait {
  width: 60px;
  height: 60px;
  flex-shrink: 0;
}
#selection strong {
  font-size: 15px;
}
#selection small {
  display: block;
  color: #c2d5b9;
  font-size: 10px;
  margin-top: 4px;
}
.upgrade-actions {
  display: flex;
  gap: 7px;
}
.upgrade-actions button {
  flex: 1;
  padding: 9px 6px;
  border-radius: 7px;
  font-size: 11px;
  background: #466744;
  color: #fff2bb;
  border: 1px solid #b4c481;
}
.upgrade-actions button:last-child {
  background: #5c4836;
  border-color: #9c8760;
}
.wave-banner {
  position: absolute;
  z-index: 7;
  left: 50%;
  top: 38%;
  transform: translate(-50%, -50%) scale(0.8);
  opacity: 0;
  pointer-events: none;
  text-align: center;
  color: #ffedbd;
  font:
    900 40px Georgia,
    serif;
  text-shadow:
    0 3px #5a482d,
    0 6px 15px #153823;
  white-space: nowrap;
}
.wave-banner.show {
  animation: banner 2.4s both;
}
@keyframes banner {
  0% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.7);
  }
  15%,
  75% {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
  }
  100% {
    opacity: 0;
    transform: translate(-50%, -55%) scale(1.05);
  }
}
/* In-game dialogs: parchment framed in carved wood. */
dialog {
  background: linear-gradient(130deg, #294a3c, #102e29);
  color: var(--cream);
  border: 3px solid #c3b071;
  border-radius: 22px;
  padding: 32px;
  max-width: 620px;
  width: calc(100% - 32px);
  max-height: calc(100dvh - 35px);
  box-shadow:
    0 7px 0 #0a231f,
    0 25px 100px #000a,
    inset 0 0 0 4px #173b31;
  text-align: center;
}
dialog::backdrop {
  background: #021b19b0;
  backdrop-filter: blur(5px);
}
dialog h2 {
  font:
    700 34px Georgia,
    serif;
  color: #ffe8ad;
  margin: 6px 0 18px;
  text-shadow: 0 3px #113026;
}
dialog p {
  color: #d0dfbf;
  font-size: 14px;
  line-height: 1.7;
}
.eyebrow {
  font-size: 10px !important;
  letter-spacing: 3px;
  color: #b9cc9d !important;
}
.close {
  position: absolute;
  top: 10px;
  right: 12px;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: #132d27;
  color: #f2d99a;
  border: 1px solid #aa9e6d;
  font-size: 23px;
}
.modal-actions {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 25px;
}
.modal-actions button {
  padding: 12px 20px;
  background: linear-gradient(#486345, #294331);
  border: 1px solid #abb477;
  border-radius: 10px;
  box-shadow: 0 4px 0 #102c22;
}
.modal-actions .primary {
  background: linear-gradient(#ffe398, #e4af4c);
  border-color: #ffe4a4;
  color: #4b351d;
  box-shadow: 0 4px 0 #8e6531;
}
.medallion {
  font-size: 60px;
  letter-spacing: 8px;
  color: #ffda73;
  text-shadow:
    0 4px #987137,
    0 0 30px #f6d36b55;
  animation: medal 0.5s cubic-bezier(0.2, 1.5, 0.5, 1);
}
@keyframes medal {
  from {
    transform: scale(0.2);
    opacity: 0;
  }
  to {
    transform: scale(1);
    opacity: 1;
  }
}
.codex-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}
.codex-card {
  background: #ffffff07;
  border: 1px solid #647c54;
  border-radius: 14px;
  padding: 10px 8px;
}
.codex-card .portrait {
  width: 100%;
  aspect-ratio: 1;
  height: auto;
}
.codex-card h3 {
  margin: 4px 0;
  color: #f6d88c;
}
.codex-card p {
  font-size: 11px;
  line-height: 1.5;
}
.setting-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 15px 4px;
  border-bottom: 1px solid #557259;
}
.setting-row select,
.setting-row button {
  background: #244b3c;
  border: 1px solid #a9b57b;
  padding: 9px 18px;
  border-radius: 8px;
}
.setting-note {
  font-size: 11px !important;
}
.result-stats {
  display: flex;
  justify-content: center;
  gap: 25px;
  color: #e6e9bc;
  font-size: 13px;
  margin: 12px 0;
}
.help-steps {
  text-align: left;
}
.help-step {
  display: flex;
  gap: 16px;
  margin: 15px 0;
  align-items: center;
}
.help-step b {
  width: 38px;
  height: 38px;
  border: 1px solid #c5b476;
  background: #3b5b3f;
  border-radius: 50%;
  display: grid;
  place-items: center;
  flex-shrink: 0;
  color: #ffe194;
}
.help-step p {
  font-size: 13px;
  margin: 0;
}
#toast {
  position: fixed;
  z-index: 30;
  bottom: 25px;
  left: 50%;
  transform: translate(-50%, 20px);
  opacity: 0;
  pointer-events: none;
  background: #173d30f5;
  color: #ffebae;
  border: 2px solid #c9bc79;
  border-radius: 12px;
  box-shadow: 0 4px 0 #0b281e;
  padding: 12px 22px;
  text-align: center;
  font-size: 13px;
  transition:
    opacity 0.2s,
    transform 0.2s;
}
#toast.show {
  transform: translate(-50%, 0);
  opacity: 1;
}
@keyframes bob {
  0%,
  100% {
    translate: 0 0;
  }
  50% {
    translate: 0 -5px;
  }
}
@media (min-aspect-ratio: 19/10) {
  .title-menu {
    top: 4%;
  }
  .crest {
    font-size: 42px;
  }
  h1 {
    font-size: 86px;
  }
  .title-tagline {
    margin: 18px 0 22px;
  }
  .title-sub {
    margin-top: 12px;
  }
  .screen-heading {
    top: 12px;
  }
  .mission-panel {
    bottom: 12px;
    padding: 10px 20px;
  }
}
@media (max-width: 700px) {
  .title-menu {
    top: 13%;
    width: 90%;
  }
  h1 {
    font-size: 70px;
    letter-spacing: -4px;
  }
  .crest {
    font-size: 42px;
  }
  .title-sub p {
    font-size: 9px;
    letter-spacing: 2px;
  }
  .title-tagline {
    font-size: 16px;
    margin: 20px 0 30px;
  }
  .title-screen {
    background-position: 48% center;
  }
  .title-corner {
    left: 15px;
    bottom: 20px;
    font-size: 8px;
    letter-spacing: 1px;
    max-width: 72%;
  }
  .fullscreen {
    right: 15px;
    bottom: 20px;
  }
  .play-button {
    min-width: 240px;
    font-size: 25px;
  }
  .screen-heading {
    top: 15px;
    left: 15px;
    right: 15px;
    gap: 12px;
  }
  .screen-heading h2 {
    font-size: 20px;
  }
  .screen-heading small {
    font-size: 8px;
    letter-spacing: 1px;
  }
  .star-total {
    padding: 8px 12px;
    gap: 5px;
  }
  .star-total b {
    font-size: 16px;
  }
  .star-total small {
    display: none;
  }
  .level-node {
    width: 41px;
    height: 41px;
    font-size: 17px;
    border-width: 2px;
  }
  .level-node small {
    font-size: 12px;
    bottom: -20px;
  }
  .level-node.selected {
    outline-width: 3px;
    outline-offset: 4px;
  }
  .level-node .node-flag {
    font-size: 20px;
    top: -27px;
    left: 10px;
  }
  .region-label {
    font-size: 7px;
    letter-spacing: 1px;
  }
  .mission-panel {
    bottom: 25px;
    padding: 15px;
    gap: 12px;
    flex-wrap: wrap;
  }
  .mission-panel h3 {
    font-size: 24px;
  }
  .mission-panel button {
    font-size: 14px;
    width: 100%;
    padding: 11px;
  }
  .mission-panel p {
    font-size: 11px;
  }
  .battle-stage {
    width: 100vw;
  }
  .battle-hud {
    top: 7px;
    left: 8px;
    right: 8px;
    gap: 5px;
  }
  .resource {
    padding: 3px 8px 3px 5px;
    gap: 5px;
    border-width: 1px;
    border-radius: 9px;
  }
  .resource b {
    font-size: 16px;
  }
  .life-icon {
    font-size: 20px;
  }
  .coin-icon {
    font-size: 18px;
  }
  .hud-resources {
    gap: 5px;
  }
  .round-button {
    width: 39px;
    height: 39px;
    border-radius: 11px;
    font-size: 20px;
  }
  .wave-counter {
    padding: 8px;
    gap: 4px;
  }
  .wave-counter small {
    font-size: 8px;
  }
  .wave-counter b {
    font-size: 13px;
  }
  .battle-caption {
    top: 51px;
    left: 10px;
    gap: 6px;
  }
  .battle-caption strong {
    font-size: 10px;
  }
  .battle-caption #chapter {
    font-size: 9px;
  }
  .battle-caption #best {
    font-size: 10px;
  }
  .battle-bottom {
    bottom: 9px;
    left: 9px;
    right: 9px;
    gap: 7px;
  }
  .spell-button {
    width: 45px;
    height: 45px;
    border-radius: 12px;
  }
  .spell-button span {
    font-size: 25px;
  }
  .spell-button small {
    font-size: 7px;
  }
  .wave-actions {
    gap: 5px;
  }
  .send-wave {
    font-size: 11px;
    min-width: 110px;
    padding: 9px 10px;
    border-radius: 9px;
  }
  .speed-button {
    padding: 7px;
    font-size: 11px;
  }
  .battle-message {
    max-width: 37%;
  }
  #boardTip {
    font-size: 10px;
  }
  #status,
  #wavePreview {
    display: none;
  }
  .build-menu {
    width: 250px;
    padding: 8px;
  }
  .tower-card .portrait {
    width: 58px;
    height: 54px;
  }
  .wave-banner {
    font-size: 27px;
  }
  .map-label {
    font-size: 5px;
  }
  .entry-flag {
    font-size: 20px;
  }
  .codex-grid {
    gap: 6px;
  }
  .codex-card {
    padding: 5px;
  }
  .codex-card h3 {
    font-size: 14px;
  }
  .codex-card p {
    font-size: 10px;
  }
  dialog {
    padding: 29px 20px;
  }
  dialog h2 {
    font-size: 28px;
  }
  .medallion {
    font-size: 47px;
  }
  #toast {
    width: 85%;
    font-size: 12px;
  }
}

@media (max-height: 560px) and (orientation: landscape) {
  .battle-stage {
    width: min(100vw, calc(100dvh * 1.5));
    margin-top: 0;
  }
  .title-menu {
    top: 3%;
  }
  .crest {
    display: none;
  }
  h1 {
    font-size: 62px;
  }
  .title-sub {
    margin-top: 10px;
  }
  .title-tagline {
    margin: 14px 0 20px;
    font-size: 15px;
  }
  .play-button {
    font-size: 22px;
    padding: 10px;
    min-width: 230px;
  }
  .title-secondary {
    margin-top: 18px;
  }
  .wood-button {
    padding: 8px 18px;
  }
  .title-corner {
    bottom: 10px;
  }
  .fullscreen {
    bottom: 10px;
  }
  .screen-heading {
    top: 10px;
  }
  .screen-heading h2 {
    font-size: 19px;
  }
  .mission-panel {
    bottom: 10px;
    width: 440px;
    padding: 8px 15px;
  }
  .mission-panel h3 {
    font-size: 20px;
  }
  .mission-panel p {
    display: none;
  }
  .mission-panel button {
    font-size: 13px;
    padding: 10px;
  }
  .battle-caption {
    top: 47px;
    left: 12px;
  }
  .battle-caption strong {
    font-size: 10px;
  }
  .battle-bottom {
    bottom: 9px;
    left: 10px;
    right: 10px;
    gap: 8px;
  }
  .battle-message {
    max-width: 38%;
  }
  #boardTip {
    font-size: 11px;
  }
  #status,
  #wavePreview {
    display: none;
  }
  .wave-actions {
    margin-left: auto;
    gap: 6px;
  }
  .send-wave {
    padding: 10px;
    min-width: 120px;
    min-height: 44px;
    font-size: 11px;
  }
  .speed-button {
    min-height: 44px;
    padding: 8px;
    font-size: 12px;
  }
  .spell-button {
    width: 46px;
    height: 46px;
    flex-shrink: 0;
    border-radius: 12px;
  }
  .spell-button span {
    font-size: 27px;
  }
  .spell-button small {
    font-size: 7px;
  }
  .battle-hud {
    top: 8px;
    left: 10px;
    right: 10px;
    gap: 8px;
  }
  .resource b {
    font-size: 17px;
  }
  .resource {
    padding: 3px 8px;
    gap: 6px;
  }
  .life-icon,
  .coin-icon {
    font-size: 20px;
  }
  .round-button {
    width: 37px;
    height: 37px;
  }
  .wave-counter {
    padding: 8px;
    gap: 5px;
  }
  .wave-counter b {
    font-size: 14px;
  }
  .wave-counter small {
    font-size: 8px;
  }
  .build-menu {
    width: 250px;
  }
  .tower-card .portrait {
    width: 54px;
    height: 48px;
  }
  .wave-banner {
    font-size: 30px;
  }
}
@media (prefers-reduced-motion: reduce) {
  *,
  *:before,
  *:after {
    animation: none !important;
    transition: none !important;
  }
  .wave-banner.show {
    opacity: 1;
    transform: translate(-50%, -50%);
  }
}
.pads {
  pointer-events: none;
}
.pad {
  pointer-events: auto;
  min-width: 38px;
  min-height: 38px;
}
/* A vertical playfield for narrow windows and embedded panels. The world is
   projected by graphics.js; UI and hit targets remain upright and full size. */
#app[data-layout="portrait"] {
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --battle-head: 88px;
  --battle-foot: 182px;
}
#app[data-layout="portrait"] .title-screen {
  background-image: url("assets/title-forest-portrait.webp");
  background-position: center;
}
#app[data-layout="portrait"] .battle-screen {
  background-image: url("assets/battlefield-portrait.webp");
}
#app[data-layout="portrait"] .title-menu {
  top: calc(var(--safe-top) + 7dvh);
  bottom: calc(var(--safe-bottom) + 104px);
  width: calc(100% - 44px);
}
#app[data-layout="portrait"] .crest {
  display: block;
  font-size: 44px;
}
#app[data-layout="portrait"] h1 {
  font-size: clamp(50px, 15cqw, 82px);
  letter-spacing: -4px;
}
#app[data-layout="portrait"] .title-sub {
  margin-top: 16px;
  width: 100%;
  gap: 10px;
}
#app[data-layout="portrait"] .title-sub p {
  font-size: 9px;
  letter-spacing: 2px;
}
#app[data-layout="portrait"] .title-tagline {
  margin: 22px 0;
  font-size: 16px;
}
#app[data-layout="portrait"] .play-button {
  margin-top: auto;
  width: min(100%, 320px);
  min-width: 0;
  min-height: 64px;
  font-size: 26px;
}
#app[data-layout="portrait"] .title-secondary {
  margin-top: 12px;
  gap: 12px;
}
#app[data-layout="portrait"] .wood-button {
  min-height: 48px;
  padding: 12px 14px;
}
#app[data-layout="portrait"] .title-shade {
  background: linear-gradient(#06262288, transparent 35%, #06262211 55%, #031e20ee);
}
#app[data-layout="portrait"] .title-corner {
  left: 18px;
  bottom: calc(var(--safe-bottom) + 22px);
  max-width: calc(100% - 90px);
  font-size: 8px;
  letter-spacing: 1px;
}
#app[data-layout="portrait"] .fullscreen {
  right: 18px;
  bottom: calc(var(--safe-bottom) + 22px);
}
#app[data-layout="portrait"] .round-button {
  width: 44px;
  height: 44px;
  font-size: 21px;
  border-radius: 13px;
}
/* Campaign keeps the whole route between a compact header and mission dock. */
#app[data-layout="portrait"] .campaign-screen {
  background: #153e33 url("assets/world-map-portrait.webp") center/cover;
}
#app[data-layout="portrait"] .campaign-screen:before {
  content: "";
  position: absolute;
  inset: 0;
  background: #0d312ce8;
  backdrop-filter: blur(12px);
}
#app[data-layout="portrait"] .screen-heading {
  top: calc(var(--safe-top) + 18px);
  left: 16px;
  right: 16px;
  gap: 12px;
}
#app[data-layout="portrait"] .screen-heading > div:not(.star-total) {
  min-width: 0;
}
#app[data-layout="portrait"] .screen-heading h2 {
  font-size: clamp(17px, 4.7cqw, 25px);
  line-height: 1.15;
}
#app[data-layout="portrait"] .screen-heading small {
  font-size: 8px;
  letter-spacing: 1px;
}
#app[data-layout="portrait"] .star-total {
  padding: 8px 10px;
  gap: 5px;
  flex-shrink: 0;
}
#app[data-layout="portrait"] .star-total b { font-size: 17px; }
#app[data-layout="portrait"] .star-total small { display: none; }
#app[data-layout="portrait"] .campaign-board {
  position: absolute;
  top: calc(var(--safe-top) + 112px);
  bottom: calc(var(--safe-bottom) + 184px);
  left: 0;
  width: 100%;
  height: auto;
  max-height: none;
  aspect-ratio: auto;
  transform: none;
}
#app[data-layout="portrait"] .campaign-board:after {
  box-shadow: inset 0 0 40px 4px #102e2c;
}
#app[data-layout="portrait"] .region-label { display: none; }
#app[data-layout="portrait"] .level-node {
  width: 44px;
  height: 44px;
  font-size: 18px;
  border-width: 2px;
}
#app[data-layout="portrait"] .level-node small {
  font-size: 12px;
  bottom: -20px;
}
#app[data-layout="portrait"] .level-node.selected {
  outline-width: 3px;
  outline-offset: 4px;
}
#app[data-layout="portrait"] .level-node .node-flag {
  font-size: 20px;
  top: -27px;
  left: 10px;
}
#app[data-layout="portrait"] .mission-panel {
  bottom: calc(var(--safe-bottom) + 18px);
  width: calc(100% - 32px);
  padding: 14px 16px;
  display: grid;
  gap: 12px;
}
#app[data-layout="portrait"] .mission-panel h3 {
  font-size: clamp(20px, 5.5cqw, 27px);
  margin: 3px 0;
}
#app[data-layout="portrait"] .mission-panel p {
  display: block;
  font-size: 11px;
}
#app[data-layout="portrait"] .mission-panel button {
  width: 100%;
  min-height: 48px;
  font-size: 16px;
  padding: 10px;
}
/* Combat: status above, vertical terrain, then thumb-accessible controls. */
#app[data-layout="portrait"] .battle-stage {
  width: 100%;
  height: 100%;
  margin: 0;
  aspect-ratio: auto;
  display: grid;
  grid-template-rows: calc(var(--battle-head) + var(--safe-top)) minmax(0, 1fr) calc(var(--battle-foot) + var(--safe-bottom));
}
#app[data-layout="portrait"] .battle-field {
  grid-row: 2;
  justify-self: center;
  align-self: center;
  width: min(100%, calc((100dvh - var(--battle-head) - var(--battle-foot) - var(--safe-top) - var(--safe-bottom)) * 2 / 3));
  height: auto;
  aspect-ratio: 2 / 3;
  border-radius: 18px;
  overflow: hidden;
  box-shadow: 0 0 0 1px #b9c58244, 0 15px 50px #001c1c88;
}
#app[data-layout="portrait"] .battle-hud {
  top: calc(var(--safe-top) + 12px);
  left: 16px;
  right: 16px;
  align-items: center;
  gap: 8px;
}
#app[data-layout="portrait"] .hud-resources { gap: 6px; }
#app[data-layout="portrait"] .resource {
  padding: 6px 10px;
  gap: 7px;
  border-width: 1px;
  border-radius: 12px;
}
#app[data-layout="portrait"] .resource b { font-size: 20px; }
#app[data-layout="portrait"] .life-icon,
#app[data-layout="portrait"] .coin-icon { font-size: 23px; }
#app[data-layout="portrait"] .wave-counter {
  gap: 4px;
  padding: 4px 10px;
  min-height: 44px;
  flex-direction: column;
  justify-content: center;
  line-height: 1.1;
}
#app[data-layout="portrait"] .wave-counter small { font-size: 8px; }
#app[data-layout="portrait"] .wave-counter b { font-size: 16px; }
#app[data-layout="portrait"] .battle-caption {
  top: calc(var(--safe-top) + 65px);
  left: 18px;
  right: 18px;
  justify-content: center;
  gap: 9px;
}
#app[data-layout="portrait"] .battle-caption strong {
  font-size: 12px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
#app[data-layout="portrait"] .battle-caption #chapter { font-size: 10px; opacity: .65; }
#app[data-layout="portrait"] .battle-caption #best { font-size: 12px; }
#app[data-layout="portrait"] .pad {
  width: 12%;
  height: 8%;
  min-width: 44px;
  min-height: 44px;
}
#app[data-layout="portrait"] .entry-flag {
  transform: translateX(-50%);
  font-size: 25px;
}
#app[data-layout="portrait"] .wave-banner {
  font-size: clamp(24px, 7cqw, 36px);
  white-space: normal;
  width: 90%;
  top: 40%;
}
#app[data-layout="portrait"] .map-label {
  font-size: 6px;
  letter-spacing: 1.5px;
  bottom: 8px;
  white-space: nowrap;
}
#app[data-layout="portrait"] .battle-bottom {
  bottom: calc(var(--safe-bottom) + 18px);
  left: 16px;
  right: 16px;
  display: grid;
  grid-template-columns: 66px minmax(0, 1fr);
  gap: 16px 12px;
  align-items: center;
}
#app[data-layout="portrait"] .battle-message {
  grid-column: 1 / -1;
  text-align: center;
  max-width: none;
  width: 100%;
  min-height: 54px;
  justify-content: center;
  margin: 0;
  gap: 5px;
}
#app[data-layout="portrait"] #boardTip { font-size: 14px; }
#app[data-layout="portrait"] #status { display: none; }
#app[data-layout="portrait"] #wavePreview {
  display: block;
  font-size: 11px;
  color: #b2ccb2;
}
#app[data-layout="portrait"] .spell-button {
  grid-column: 1;
  grid-row: 2;
  width: 66px;
  height: 64px;
  border-radius: 18px;
}
#app[data-layout="portrait"] .spell-button span { font-size: 35px; }
#app[data-layout="portrait"] .spell-button small { font-size: 9px; }
#app[data-layout="portrait"] .wave-actions {
  grid-column: 2;
  grid-row: 2;
  display: grid;
  grid-template-columns: 48px minmax(0, 1fr);
  gap: 10px;
  align-items: center;
  margin: 0;
}
#app[data-layout="portrait"] .speed-button {
  min-height: 48px;
  font-size: 15px;
  padding: 8px;
}
#app[data-layout="portrait"] .send-wave {
  min-width: 0;
  min-height: 60px;
  font-size: 14px;
  line-height: 1.2;
  padding: 10px;
  border-radius: 14px;
}
/* The construction dock replaces the action area, never the playable field. */
#app[data-layout="portrait"] .build-menu {
  left: 12px !important;
  right: 12px;
  top: auto !important;
  bottom: calc(var(--safe-bottom) + 12px);
  width: auto;
  height: 158px;
  transform: none;
  border-radius: 20px;
  padding: 10px 12px;
  box-shadow: 0 5px 0 #09271f, 0 12px 35px #001b19aa;
}
#app[data-layout="portrait"] .build-menu:after { display: none; }
#app[data-layout="portrait"] .build-menu:not([hidden]) ~ .battle-bottom {
  visibility: hidden;
}
#app[data-layout="portrait"] .close-build {
  right: 5px;
  top: 0;
  width: 44px;
  height: 44px;
  background: transparent;
  border: 0;
  font-size: 28px;
  z-index: 1;
}
#app[data-layout="portrait"] .build-heading {
  font-size: 12px;
  min-height: 20px;
  padding-inline: 30px;
  margin-bottom: 6px;
}
#app[data-layout="portrait"] #towerShop { gap: 9px; }
#app[data-layout="portrait"] .tower-card {
  position: relative;
  height: 108px;
  display: grid;
  grid-template-columns: 1fr;
  justify-items: center;
  gap: 0;
  padding: 3px 4px 7px;
  border-radius: 12px;
}
#app[data-layout="portrait"] .tower-card .portrait { width: 58px; height: 50px; }
#app[data-layout="portrait"] .tower-card strong { font-size: 12px; }
#app[data-layout="portrait"] .tower-card small { font-size: 9px; }
#app[data-layout="portrait"] .tower-card .price { font-size: 13px; margin: 0; }
#app[data-layout="portrait"] #selection .tower-detail {
  margin: -4px 0 4px;
  padding-right: 20px;
  gap: 10px;
}
#app[data-layout="portrait"] #selection .portrait { width: 48px; height: 48px; }
#app[data-layout="portrait"] .upgrade-actions button { min-height: 44px; font-size: 12px; }
/* Dialogs live outside #app, including when portrait is previewed on desktop. */
body:has(#app[data-layout="portrait"]) dialog {
  width: min(440px, calc(100% - 28px));
  padding: 34px 18px 24px;
  border-radius: 22px;
}
body:has(#app[data-layout="portrait"]) dialog .close { width: 44px; height: 44px; top: 5px; right: 5px; }
body:has(#app[data-layout="portrait"]) .modal-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
body:has(#app[data-layout="portrait"]) .modal-actions button { min-height: 48px; padding: 10px; }
body:has(#app[data-layout="portrait"]) .modal-actions .primary { grid-column: 1 / -1; }
body:has(#app[data-layout="portrait"]) .codex-grid { grid-template-columns: 1fr; gap: 10px; }
body:has(#app[data-layout="portrait"]) .codex-card {
  display: grid;
  grid-template-columns: 74px 1fr auto;
  grid-template-rows: auto auto;
  align-items: center;
  gap: 4px 10px;
  text-align: left;
  padding: 10px;
}
body:has(#app[data-layout="portrait"]) .codex-card .portrait { grid-row: 1 / 3; width: 74px; height: 74px; }
body:has(#app[data-layout="portrait"]) .codex-card h3 { font-size: 17px; }
body:has(#app[data-layout="portrait"]) .codex-card p { grid-column: 2 / 4; margin: 0; font-size: 11px; }
body:has(#app[data-layout="portrait"]) .codex-card > strong { grid-column: 3; grid-row: 1; color: var(--gold); font-size: 12px; }
@media (max-height: 700px) {
  #app[data-layout="portrait"] { --battle-head: 78px; --battle-foot: 160px; }
  #app[data-layout="portrait"] .battle-caption { top: calc(var(--safe-top) + 59px); }
  #app[data-layout="portrait"] .battle-hud { top: calc(var(--safe-top) + 6px); }
  #app[data-layout="portrait"] .battle-bottom { bottom: calc(var(--safe-bottom) + 12px); gap: 8px 12px; }
  #app[data-layout="portrait"] .battle-message { min-height: 44px; }
  #app[data-layout="portrait"] .build-menu { bottom: calc(var(--safe-bottom) + 6px); height: 146px; padding-block: 6px; }
  #app[data-layout="portrait"] .tower-card { height: 100px; }
  #app[data-layout="portrait"] .tower-card .portrait { height: 43px; }
  #app[data-layout="portrait"] .title-menu { top: 25px; bottom: 80px; }
  #app[data-layout="portrait"] .crest { font-size: 32px; }
  #app[data-layout="portrait"] .title-tagline { margin: 15px 0; }
  #app[data-layout="portrait"] .campaign-board { top: 108px; bottom: 165px; }
  #app[data-layout="portrait"] .mission-panel { padding: 10px 14px; gap: 8px; bottom: 12px; }
  #app[data-layout="portrait"] .mission-panel h3 { font-size: 20px; }
}
