/* Touch control surface, gesture suppression, and safe-area handling —
   everything here is gated on `html.touch`, which touch.js sets from the
   primary pointer and keeps in step with actual use, so a tablet with a
   keyboard case can change its mind mid-session (house pattern, Tank
   Arena's touch.css). */

:root {
  --sat: env(safe-area-inset-top, 0px);
  --sar: env(safe-area-inset-right, 0px);
  --sab: env(safe-area-inset-bottom, 0px);
  --sal: env(safe-area-inset-left, 0px);
  --ubtn: 44px;   /* accessibility floor for a touch target */
  --tbtn: 68px;   /* the primary action buttons */
}

/* The canvas already declines its own gestures, but the document still owns
   pull-to-refresh, rubber-band scroll and double-tap zoom, and every one of
   those fires mid-build. `manipulation`, not `none`, so the menu (which
   must scroll on a short phone) is never accidentally made unscrollable. */
html, body {
  overscroll-behavior: none;
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
}
#hud, #touchui { touch-action: none; }
/* Every text field in the game, not just the menu's name box: the journal's
   pairing code, its first-finder naming prompt and the chat line all became
   reachable on touch in this pass, and a field you cannot put a caret in or
   select text inside is not a usable field. (#claimScreen is listed for the
   day that panel grows one — it has no field today.) The three screens
   themselves are OUTSIDE #hud, so they keep the document's own
   `touch-action: manipulation` and scroll normally under a thumb. */
#menu input, #journalScreen input, #journalPrompt input,
#chatBar input, #claimScreen input {
  -webkit-user-select: text; user-select: text; -webkit-touch-callout: default;
}

/* ===================== safe areas ===================== */
#readouts { top: calc(10px + var(--sat)); }
#debug { top: calc(48px + var(--sat)); left: calc(10px + var(--sal)); }
#hotbarWrap { bottom: calc(14px + var(--sab)); }
#menu { padding: calc(20px + var(--sat)) calc(20px + var(--sar)) calc(20px + var(--sab)) calc(20px + var(--sal)); }

/* ===================== touch control surface ===================== */
#touchui { position: absolute; inset: 0; pointer-events: none; }
#touchui[hidden] { display: none; }
html:not(.touch) #touchui { display: none; }

#tstickzone {
  position: absolute; left: 0; bottom: 0;
  width: 46%; height: 66%;
  pointer-events: auto;
}

#tstick {
  position: absolute; left: 0; top: 0;
  width: 124px; height: 124px; margin: -62px 0 0 -62px;
  transform: translate(var(--sx, -999px), var(--sy, -999px));
  border-radius: 50%;
  border: 2px solid rgba(95, 191, 106, .32);
  background: radial-gradient(circle, rgba(9, 16, 12, .4), rgba(9, 16, 12, .12));
  opacity: 0; transition: opacity .12s;
  pointer-events: none;
}
#tstick.on { opacity: 1; }
#tknob {
  position: absolute; left: 50%; top: 50%;
  width: 54px; height: 54px; margin: -27px 0 0 -27px;
  transform: translate(var(--kx, 0px), var(--ky, 0px));
  border-radius: 50%;
  background: radial-gradient(circle at 38% 34%, #a7ecac, var(--leaf));
  box-shadow: 0 3px 14px rgba(0, 0, 0, .6);
  opacity: 0;
}

/* Three rows now (was two). Row 1 is the SCREENS — journal, chat, claims —
   which were keyboard-only until this pass and are therefore a third of M7
   unreachable on the device this game is explicitly meant to be played on.
   They are 44px pills, not 68px action discs, because they are not things a
   thumb holds during play: same distinction #btnInventory/#btnView already
   drew, so this is the existing idiom with three more members and not a
   second control style.

   Height, which the whole ladder below depends on:
     --ubtn(44) + 10 + --tbtn(68) + 10 + --tbtn(68) = 200px
   sitting 14px off the bottom, so the cluster's top edge is at 214px. */
#tactions {
  position: absolute;
  right: calc(14px + var(--sar)); bottom: calc(14px + var(--sab));
  display: grid; gap: 10px; grid-template-columns: auto auto auto;
  grid-template-areas: "jrnl chat claim" "inv view jump" "harvest break place";
  align-items: end; justify-items: end;
  pointer-events: none;
}
#btnJournal { grid-area: jrnl; }
#btnChat { grid-area: chat; }
#btnClaim { grid-area: claim; }
#btnInventory { grid-area: inv; }
#btnView { grid-area: view; }
#btnJump { grid-area: jump; }
#btnHarvest { grid-area: harvest; }
#btnBreak { grid-area: break; }
#btnPlace { grid-area: place; }

.tbtn {
  position: relative;
  width: var(--tbtn); height: var(--tbtn);
  display: grid; place-items: center;
  font: inherit; color: #eaf3ec;
  border-radius: 50%;
  border: 1.5px solid rgba(255, 255, 255, .3);
  background: rgba(9, 16, 12, .55);
  backdrop-filter: blur(6px);
  pointer-events: auto;
  touch-action: none;
  transition: transform .07s, background .12s;
}
.tbtn em { font-style: normal; font-size: 9.5px; letter-spacing: .06em; }
.tbtn.jump { border-color: rgba(95, 191, 106, .75); background: rgba(95, 191, 106, .16); }
.tbtn.jump em { color: #b6f0ba; font-weight: 700; }
.tbtn.down { transform: scale(.92); background: rgba(95, 191, 106, .38); }

#btnView.ubtn {
  width: var(--ubtn); height: var(--ubtn);
  font: inherit; font-size: 10px; letter-spacing: .06em; color: #cdd6cf;
  border-radius: 10px; border: 1px solid rgba(255, 255, 255, .2);
  background: rgba(9, 16, 12, .55); backdrop-filter: blur(6px);
  pointer-events: auto; touch-action: none;
}
#btnView.down { background: rgba(95, 191, 106, .3); }

/* Phase B: btnInventory shares btnView's compact 44px pill shape;
   btnHarvest is a full 68px primary action button like break/place.
   Closing pass: btnJournal/btnChat/btnClaim join that same pill rule rather
   than getting one of their own — one shape for "opens a screen", one shape
   for "acts on the world", which is the distinction the cluster already
   made. CLAIM is the longest label at five characters, so the shared
   font-size is what keeps all five pills legible at 44px. */
#btnInventory, #btnJournal, #btnChat, #btnClaim {
  width: var(--ubtn); height: var(--ubtn);
  font: inherit; font-size: 9.5px; letter-spacing: .04em; color: #cdd6cf;
  border-radius: 10px; border: 1px solid rgba(255, 255, 255, .2);
  background: rgba(9, 16, 12, .55); backdrop-filter: blur(6px);
  pointer-events: auto; touch-action: none;
}
#btnClaim { font-size: 8.5px; letter-spacing: .02em; }
#btnInventory.down, #btnJournal.down, #btnChat.down, #btnClaim.down,
#btnJournal.on, #btnChat.on, #btnClaim.on { background: rgba(95, 191, 106, .3); }
/* A finger cannot hover, so "this screen is the one that is open" has to be
   painted. .on is set by touch.js from each surface's own open state. */
#btnJournal.on, #btnChat.on, #btnClaim.on { border-color: rgba(95, 191, 106, .75); color: #d9f2dc; }

/* ===================== inventory screen safe areas ===================== */
#invScreen { padding: calc(20px + var(--sat)) calc(20px + var(--sar)) calc(20px + var(--sab)) calc(20px + var(--sal)); }
html.touch .invBody { flex-direction: column; }
html.touch .invRight { border-left: 0; padding-left: 0; border-top: 1px solid rgba(255, 255, 255, .08); padding-top: 12px; }
/* .islot/.hbslot deliberately excluded from this floor (fixer round 2's
   own finding): both are already sized by their own layout (.islot's
   aspect-ratio:1 grid cell, .hbslot's explicit 35x35px narrow-viewport
   rule in style.css) — a blanket min-height:44px here only fights that
   sizing on a real phone-width grid (9 columns leaves each backpack cell
   under 44px wide well before the min-height floor kicks in on height
   alone), stretching every slot into a tall pill instead of a square icon
   tile (confirmed on a 390x844 screenshot). Square-but-under-44px reads
   correctly; 44px-tall-by-~32px-wide does not. */
@media (pointer: coarse) {
  .rcraft, #repairBtn, #craftBtn, .invHead button { min-height: 44px; }
  /* The returning-player summary's own dismiss button — the first control a
     touch player ever meets, since every rejoin shows this panel. */
  #away button { min-height: 44px; padding: 8px 18px; }
  #away { max-height: 70vh; overflow: auto; }
}

/* ===================== HUD reflow for touch ===================== */
/* THE WHOLE BOTTOM LADDER RISES, not just the hotbar.
   style.css:176-179 documents one ladder measured from the viewport bottom —
   hotbar 14..80, tool label 92..105, chat bar 112..145 (chat.js), pickups
   152, chat rail 156 (chat.js), claim banner 176 (claims.js), graft hint 180
   — and the Phase D fixer tuned every one of those rungs against the others.
   Only the hotbar was ever lifted for touch (to 165px), which was correct as
   far as it went and wrong for everything else: on a 390x844 emulated phone
   the tool label at 92px sat squarely inside #tactions' own [160,306] band
   (measured, not guessed — the harness for this pass reports every rung's
   rect and flagged toolLabel x tactions BEFORE any of this change landed),
   and the moment chat became reachable at all the full-width chat bar at
   112..145 would have been drawn straight through the JUMP/BAG/3RD row.

   So: ONE lift applied to every rung, which preserves the fixer's relative
   spacing exactly (the ladder is translated, never re-tuned) and clears the
   now-200px-tall action cluster. 208px = the cluster's 214px top edge, plus
   8px of air, minus the hotbar's own 14px base offset. */
html.touch { --tlift: 208px; }
html.touch #hotbarWrap { bottom: calc(14px + var(--tlift) + var(--sab)); }
html.touch #toolLabel { bottom: calc(92px + var(--tlift) + var(--sab)); }
html.touch #pickups { bottom: calc(152px + var(--tlift) + var(--sab)); }
html.touch #graftHint { bottom: calc(180px + var(--tlift) + var(--sab)); }
/* chat.js and claims.js build their own DOM (neither owns index.html or
   style.css), so their rungs are lifted here by id — the same three numbers
   their own files use, plus the same lift. #claimBanner's `bottom` is an
   INLINE style, so this one needs the cascade-beating !important; the other
   two come from an injected <style> block and do not. */
html.touch #chatBar { bottom: calc(112px + var(--tlift) + var(--sab)); }
html.touch #chatRail { bottom: calc(156px + var(--tlift) + var(--sab)); }
html.touch #claimBanner { bottom: calc(176px + var(--tlift) + var(--sab)) !important; }
html.touch #readouts { font-size: 10.5px; gap: 8px; padding: 5px 12px; }

/* A finger cannot hover, so hover-only affordances must not be the only way
   to see something is interactive, and touch targets stay at the 44px floor. */
@media (pointer: coarse) {
  .field input { font-size: 16px; padding: 13px; min-height: 48px; }
  #playBtn { min-height: 52px; }
}

/* A landscape phone has ~460px of height and plenty of width, so the cluster
   spends the width instead of the height: five columns, two rows. Stacking
   the pill row on top (as portrait does) would put the cluster's top edge at
   184px of a 460px screen and the lifted ladder's top rung above 380px —
   more than four fifths of the viewport spent on chrome. Here the pills sit
   BESIDE the action discs instead: 38 + 10 + 56 = 104px tall, top edge
   118px, so --tlift is 112px and the ladder tops out around 320px. */
@media (orientation: landscape) and (max-height: 460px) {
  :root { --tbtn: 56px; --ubtn: 38px; }
  #tactions {
    grid-template-columns: auto auto auto auto auto;
    grid-template-areas: "jrnl chat claim inv view" "none jump harvest break place";
  }
  html.touch { --tlift: 112px; }
}

/* ===================== account launcher ===================== */
/* account.js appends a fixed z-index-9000 launcher and account.css parks it
   bottom-left — which is exactly #tstickzone's [left 0, bottom 0, 46% x 66%]
   thumb corner, and at 9000 it wins the hit test against this game's whole
   stack (which tops out at 45). The first thing a phone player does is plant
   a thumb there to walk, and they would press "Sign in" instead. Fixed here
   rather than there because account.css is one of five byte-identical copies
   hashed by accounts/tools/parity.py, so a Perennial-shaped fix cannot live
   in it. Top-left is empty except for #debug, which moves down to match.
   This matters more than it looks: #menu goes opacity:0/pointer-events:none
   on join and is never re-shown, so this launcher is the ONLY in-world route
   to a player's key. */
html.touch .sga-floating {
  left: calc(10px + var(--sal));
  right: auto;
  bottom: auto;
  top: calc(10px + var(--sat));
}
html.touch #debug { top: calc(92px + var(--sat)); }
