/* The front end.
 *
 * Four pages living inside one #title-screen, shown one at a time by
 * data-page on the container. Everything is centred: the title page is a title
 * and nothing else, and the choices that used to crowd it now have a page of
 * their own where they have room to explain themselves.
 */

#title-screen { justify-content: center; }

.mpage {
  position: relative; z-index: 2;
  display: none;
  flex-direction: column;
  align-items: center;
  text-align: center;
  width: min(1080px, 94vw);
  max-height: 100vh;
  padding: 28px 20px;
  overflow-y: auto;
  overscroll-behavior: contain;
}
/* Any page whose name matches the container's data-page. Written as an
   attribute match on the pair rather than one selector per page, so removing a
   page cannot decapitate the rule — which is exactly what happened when the
   archive line was deleted and it took the opening brace with it, leaving every
   page display:none and the game unreachable past the title screen. */
#title-screen[data-page="home"]     .mpage[data-for="home"],
#title-screen[data-page="loadout"]  .mpage[data-for="loadout"],
#title-screen[data-page="controls"] .mpage[data-for="controls"],
#title-screen[data-page="coop"]     .mpage[data-for="coop"],
#title-screen[data-page="credits"]  .mpage[data-for="credits"] {
  display: flex;
  animation: mpIn .28s ease both;
}
@keyframes mpIn { from { opacity: 0; transform: translateY(9px); } }

.mpage-title {
  font: 700 12px/1 "Courier New", monospace;
  letter-spacing: .42em; text-transform: uppercase;
  color: #8a8478;
  margin: 26px 0 14px;
}
.mpage-title:first-child { margin-top: 4px; }
/* A hairline either side, so the heading reads as a divider rather than a label. */
.mpage-title::before, .mpage-title::after {
  content: ""; display: inline-block; vertical-align: middle;
  width: clamp(20px, 7vw, 90px); height: 1px; margin: 0 16px;
  background: linear-gradient(90deg, transparent, rgba(190,160,110,.4), transparent);
}

/* ---------------------------------------------------------------- personas */

/* The roster is a row of five on a wide screen, wrapping as it narrows. Flex
   rather than grid specifically so a wrapped row of two or three still centres
   under the row above it — in a fixed grid an orphan row strands itself on the
   left and reads as a mistake. */
#persona-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
  width: 100%;
  max-width: 940px;
}
#persona-grid .p-card { flex: 0 1 175px; }
@media (max-width: 560px) { #persona-grid .p-card { flex: 0 1 140px; } }
.p-card {
  position: relative;
  cursor: pointer; pointer-events: auto;
  display: flex; flex-direction: column; align-items: stretch;
  padding: 0; overflow: hidden;
  background: linear-gradient(170deg, rgba(24,28,33,.9), rgba(9,11,14,.95));
  border: 1px solid rgba(150,150,150,.2);
  border-radius: 4px;
  color: inherit; font-family: inherit;
  transition: border-color .16s, transform .16s, box-shadow .16s;
}
.p-card:hover { border-color: rgba(190,160,110,.55); transform: translateY(-3px); }
.p-card.sel {
  border-color: #b0453a;
  box-shadow: 0 0 0 1px rgba(176,69,58,.5), 0 10px 30px rgba(0,0,0,.7);
}
.p-card.sel::after {
  content: "SELECTED";
  position: absolute; top: 8px; right: 8px;
  padding: 3px 7px; border-radius: 2px;
  background: rgba(150,32,24,.9);
  font: 700 8px/1 "Courier New", monospace; letter-spacing: .16em; color: #ffe7df;
}
/* The portrait is painted at runtime into a canvas, so there is no image to ship. */
.p-card .p-portrait {
  display: block; width: 100%; height: auto; aspect-ratio: 3 / 4;
  background: #0a0c0f;
  filter: contrast(1.05) saturate(.9);
}
.p-card .p-body { padding: 10px 12px 13px; text-align: left; }
.p-card .p-name {
  display: block;
  font: 700 13px/1.1 "Trebuchet MS", sans-serif;
  letter-spacing: .14em; text-transform: uppercase; color: #ded6c2;
}
.p-card .p-blurb {
  display: block; margin-top: 6px;
  font: 400 11px/1.45 Georgia, serif; font-style: italic; color: #8a8479;
}
.p-card .p-perk {
  display: block; margin-top: 9px;
  font: 700 9px/1 "Courier New", monospace; letter-spacing: .13em;
  text-transform: uppercase; color: #9c8b62;
}
.p-card .p-perk.none { color: #5f6167; }

#callsign-row {
  display: flex; align-items: center; justify-content: center; gap: 11px;
  margin-top: 15px;
}
.cs-label {
  font: 700 9px/1 "Courier New", monospace; letter-spacing: .3em;
  text-transform: uppercase; color: #6d6a63;
}
#callsign {
  color: #d8d0bb;
  font: 700 14px/1 "Courier New", monospace; letter-spacing: .16em;
}
#callsign-reroll {
  cursor: pointer; pointer-events: auto;
  width: 26px; height: 26px; border-radius: 3px;
  background: rgba(10,13,16,.75); border: 1px solid rgba(150,150,150,.24);
  color: #9a9384; font-size: 14px; line-height: 1;
  transition: color .15s, border-color .15s;
}
#callsign-reroll:hover { color: #e6dcc4; border-color: #9c8b62; }

/* ------------------------------------------------------------ difficulty */

#diff-grid {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 11px; width: 100%; max-width: 900px;
}
#diff-grid .diff-card { flex: 1 1 200px; max-width: 260px; }
.diff-card {
  cursor: pointer; pointer-events: auto;
  display: flex; flex-direction: column; gap: 7px;
  padding: 14px 16px; text-align: left;
  background: rgba(10,13,16,.78);
  border: 1px solid rgba(150,150,150,.2);
  border-radius: 4px; font-family: inherit;
  transition: border-color .15s, background .15s, transform .15s;
}
.diff-card:hover { border-color: rgba(190,160,110,.5); transform: translateY(-2px); }
.diff-card.sel { background: rgba(96,22,16,.4); border-color: #b0453a; }
.dc-name {
  font: 700 14px/1 "Trebuchet MS", sans-serif;
  letter-spacing: .18em; text-transform: uppercase; color: #ded6c2;
}
.diff-card.sel .dc-name { color: #ffd9d0; }
.dc-line { font: 400 11.5px/1.5 Georgia, serif; font-style: italic; color: #8b857a; }
.dc-stats { display: flex; flex-wrap: wrap; gap: 4px 12px; margin-top: 2px; }
.dc-stats i {
  font: 700 9px/1 "Courier New", monospace; font-style: normal;
  letter-spacing: .1em; text-transform: uppercase; color: #6f7780;
}
.diff-card.sel .dc-stats i { color: #a8867c; }

/* -------------------------------------------------------------- controls */

.ctl-tabs { display: flex; gap: 7px; margin-bottom: 15px; flex-wrap: wrap; justify-content: center; }
.ctl-tab {
  cursor: pointer; pointer-events: auto;
  padding: 8px 15px; border-radius: 3px; font-family: inherit;
  background: rgba(10,13,16,.78); border: 1px solid rgba(150,150,150,.2);
  color: #8b8579; font: 700 10px/1 "Courier New", monospace;
  letter-spacing: .16em; text-transform: uppercase;
  transition: color .15s, border-color .15s, background .15s;
}
.ctl-tab:hover { color: #ded6c2; border-color: #7d746a; }
.ctl-tab.sel { color: #ffd9d0; background: rgba(96,22,16,.42); border-color: #b0453a; }
#ctl-list { margin-top: 0; min-width: min(520px, 90vw); }

/* -------------------------------------------------------------- touch fit */

html.is-touch .mpage { padding: 16px 12px; }
html.is-touch .mpage-title { margin: 16px 0 10px; }
html.is-touch #persona-grid { gap: 9px; }
html.is-touch #persona-grid .p-card { flex: 0 1 124px; }
html.is-touch .p-card .p-blurb { display: none; }   /* the portrait and name carry it */
html.is-touch #diff-grid .diff-card { flex: 1 1 100%; max-width: none; }
html.is-touch .dc-stats { display: none; }
/* Landscape phones have almost no vertical room, so the title page compresses. */
@media (orientation: landscape) and (max-height: 500px) {
  h1.game-title { font-size: clamp(34px, 7vw, 56px); }
  .menu-col { margin-top: 16px; gap: 8px; }
  .best-line { margin-top: 10px; }
  .mpage-title { margin: 12px 0 8px; }
}

/* Creative is a sandbox rather than a difficulty step, so it reads differently
   from the three that sit on the same scale. */
.diff-card.creative { border-color: rgba(120,150,190,.26); }
.diff-card.creative:hover { border-color: rgba(130,175,225,.55); }
.diff-card.creative.sel { background: rgba(20,48,80,.44); border-color: #4d82b8; }
.diff-card.creative.sel .dc-name { color: #cfe4fb; }
.diff-card.creative.sel .dc-stats i { color: #7c9dbd; }
.dc-note {
  font: 700 8.5px/1.4 "Courier New", monospace;
  letter-spacing: .1em; text-transform: uppercase; color: #5f6167;
}

/* ------------------------------------------------------------------- co-op */

.coop-intro {
  max-width: 560px; margin-bottom: 20px;
  font: 400 12.5px/1.65 Georgia, serif; font-style: italic; color: #8b857a;
}
#coop-panels {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 12px;
  width: 100%; max-width: 720px;
}
.coop-card {
  flex: 1 1 300px; max-width: 350px;
  display: flex; flex-direction: column; gap: 9px;
  padding: 18px 20px; text-align: left;
  background: rgba(10,13,16,.78);
  border: 1px solid rgba(150,150,150,.2); border-radius: 4px;
}
.cc-head {
  font: 700 12px/1 "Trebuchet MS", sans-serif;
  letter-spacing: .22em; text-transform: uppercase; color: #ded6c2;
}
.cc-line { font: 400 11.5px/1.5 Georgia, serif; font-style: italic; color: #8b857a; }
.cc-key {
  padding: 12px 0; text-align: center;
  font: 700 26px/1 "Courier New", monospace; letter-spacing: .28em;
  color: #e6dcc4; text-shadow: 0 0 22px rgba(190,150,90,.3);
  background: rgba(4,6,8,.6); border: 1px dashed rgba(190,160,110,.28); border-radius: 3px;
}
.cc-input {
  padding: 11px 13px; width: 100%;
  background: rgba(4,6,8,.6); border: 1px solid rgba(150,150,150,.24); border-radius: 3px;
  color: #e6dcc4; font: 700 20px/1 "Courier New", monospace;
  letter-spacing: .22em; text-align: center; text-transform: uppercase;
}
.cc-input:focus { outline: none; border-color: #9c8b62; }
.cc-input::placeholder { color: #4b4d52; }
.cc-actions { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; }
.cc-actions .mbtn { min-width: 0; flex: 1 1 auto; font-size: 14px; }
.cc-actions .mbtn[disabled] { opacity: .4; pointer-events: none; }

.cc-status {
  max-width: 620px; margin-top: 18px;
  font: 700 10.5px/1.6 "Courier New", monospace;
  letter-spacing: .1em; color: #7c7568;
}
.cc-status.ok  { color: #8fbb84; }
.cc-status.bad { color: #c4776c; }

html.is-touch .coop-card { flex: 1 1 100%; }

/* ------------------------------------------------------------------ credits */
.credits-body { max-width: 620px; text-align: left; }
.credits-body p { margin-bottom: 12px; font: 400 12.5px/1.7 Georgia, serif; color: #9a9384; }
.credits-body b { color: #ded6c2; }
.credits-body a { color: #b99a64; text-decoration: underline; pointer-events: auto; }
.credits-body a:hover { color: #e6dcc4; }
.cr-head {
  font: 700 9px/1 "Courier New", monospace !important;
  letter-spacing: .3em; text-transform: uppercase; color: #6d6a63 !important;
  margin: 20px 0 8px !important;
}
.cr-note { font-style: italic; color: #6d6a63 !important; font-size: 11.5px !important; }

/* ---------------------------------------------------------------------------
   The primary action must never be below the fold.

   On a landscape phone the loadout page is ~1233px tall (five soldier cards, a
   callsign row, four difficulty cards) inside a 390px viewport, which put Deploy
   at y=1156. The page scrolls, but a button 1150px down is not discoverable —
   this is why the game read as "won't let me start".

   So the action bar sticks to the bottom of the scroller. It is always on screen,
   at any height, without shortening the content above it.
   --------------------------------------------------------------------------- */
.mpage[data-for="loadout"] .menu-col,
.mpage[data-for="coop"] .menu-col {
  /* fixed, not sticky. Sticky depends on the scroll container resolving the
     element's containing block the way you expect, and here it did not hold —
     Deploy stayed at y=1156 in a 390px viewport. Fixed to the viewport is
     unambiguous and cannot be defeated by a scroll ancestor. */
  position: fixed;
  left: 0; right: 0;
  bottom: 0;
  width: 100%;
  margin-top: 0;
  padding: 14px 0 max(14px, env(safe-area-inset-bottom));
  /* fades the content out behind it rather than cutting it off with a hard edge */
  background: linear-gradient(180deg, rgba(3,4,6,0) 0%, rgba(3,4,6,.86) 26%, rgba(3,4,6,.985) 62%, #030406 100%);
  border-top: 1px solid rgba(190,160,110,.16);
  z-index: 4;
}
/* Give the scroller room so the last card is not permanently hidden behind the bar. */
/* room so the last card is not stuck behind the fixed bar */
.mpage[data-for="loadout"], .mpage[data-for="coop"] { padding-bottom: 132px; }

/* A short viewport also needs the cards themselves to be smaller, or scrolling
   past five of them to reach the difficulty choice is a chore. */
@media (max-height: 460px) {
  #persona-grid .p-card { flex: 0 1 122px; }
  #persona-grid .p-card .p-blurb,
  #persona-grid .p-card .p-perk { display: none; }
  #persona-grid .p-card .p-body { padding: 6px 8px 8px; }
  .mpage-title { margin: 10px 0 7px; }
  #diff-grid .diff-card { padding: 9px 11px; }
  .dc-line { display: none; }
}

/* ---------------------------------------------------------------------------
   Minimum tap targets, applied at the base rather than only under .is-touch.

   A sweep at 844x390 found ten controls under the 44px minimum — every menu
   button (37px and 30px), the callsign reroll (24px), the join/host buttons and
   the controls tabs. The is-touch overrides did cover some of these, but they
   only apply when platform detection says touch-first, so a small desktop
   window, a touchscreen laptop, or the game in an iOS webview that reports
   oddly all got the cramped version. Sizing them properly everywhere costs
   nothing on a mouse and removes a whole class of "I tapped it and nothing
   happened".
   --------------------------------------------------------------------------- */
.mbtn { min-height: 48px; }
.mbtn.small { min-height: 44px; }
#callsign-reroll { width: 44px; height: 44px; font-size: 18px; }
.ctl-tab { min-height: 44px; padding: 12px 16px; }
.diff-card { min-height: 44px; }
.p-card { min-height: 44px; }
#coop-input { min-height: 48px; }
#btn-copy-key, #btn-host, #btn-join { min-height: 44px; }
#tc-pause, #tc-more { min-width: 44px; min-height: 44px; }

/* Short viewports: shrink the cards so the difficulty row is a short scroll,
   not a long one, now that the action bar is pinned. */
@media (max-height: 430px) {
  #persona-grid .p-card { flex: 0 1 108px; }
  #persona-grid .p-card .p-name { font-size: 11px; }
  .mpage-title { margin: 8px 0 6px; font-size: 10px; letter-spacing: .3em; }
  .mpage-title::before, .mpage-title::after { width: clamp(12px, 4vw, 40px); margin: 0 10px; }
  #diff-grid .diff-card { padding: 8px 10px; }
  .dc-stats { display: none; }
  #callsign-row { margin-top: 8px; }
}
