/* Touch support. Every rule is behind body.touch-device, which touch.js adds
 * only on a coarse pointer, so a desktop deployment renders exactly as it did.
 *
 * The theme is not restyled here. What changes is what a finger can reach and
 * what a finger can hit — the terminal keeps its own look. */

/* ---- The action bar ------------------------------------------------- */

.touch-action-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 60;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 0 6px calc(6px + env(safe-area-inset-bottom, 0px));
  background: var(--surface-raised, rgba(20, 22, 28, 0.96));
  border-top: 1px solid var(--border-subtle, rgba(255, 255, 255, 0.12));
  /* Repositioned by touch.js when the software keyboard opens; the transition
   * keeps that from reading as a jump. */
  transition: transform 120ms ease-out;
}

.touch-bar-keys {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* ---- Collapsing the bar --------------------------------------------- */

/* The bar is the only permanently docked furniture on a touch device, so
 * whatever it covers is simply unreachable — most visibly the AI chat panel,
 * whose input is the bottom of its own column and so ends up behind the keys.
 * Collapsed, the panel folds away and only the handle is left, in the same
 * shape the terminal tools widget uses at the top of the screen. */
.touch-bar-handle-row {
  display: flex;
  justify-content: flex-end;
  padding: 4px 0 0;
}

.touch-bar-handle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  /* Smaller than the 44px the keys use. It is a chrome control rather than
   * something pressed mid-transaction, and the keys it sits above are what the
   * space at the bottom of the screen is for. */
  min-height: 44px;
  padding: 4px 12px;
  border-radius: 8px;
  border: 1px solid var(--border-subtle, rgba(255, 255, 255, 0.18));
  background: var(--surface-raised, rgba(20, 22, 28, 0.96));
  color: inherit;
  font: inherit;
  font-size: 0.78rem;
  font-weight: 600;
  line-height: 1;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

.touch-bar-handle-icon {
  display: inline-block;
  /* Points at what the press does: down to put the keys away, up to bring
   * them back. */
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid currentColor;
}

.touch-action-bar.is-collapsed .touch-bar-handle-icon {
  border-top: 0;
  border-bottom: 5px solid currentColor;
}

/* display:none rather than a clip: a collapsed key row that is merely
 * invisible keeps 30 buttons in the tab order, and every one of them sends an
 * AID to the host if it is reached and pressed. */
.touch-action-bar.is-collapsed .touch-bar-keys {
  display: none;
}

/* Collapsed, the bar itself stops being a surface — otherwise a full-width
 * plate stays across the bottom of the screen with a single pill on it, which
 * is most of the room the collapse was meant to give back. The handle keeps
 * its own background, so it stays legible over the terminal. */
.touch-action-bar.is-collapsed {
  background: transparent;
  border-top-color: transparent;
  pointer-events: none;
}

.touch-action-bar.is-collapsed .touch-bar-handle {
  pointer-events: auto;
  opacity: 0.92;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
}

.touch-key-row {
  display: flex;
  gap: 6px;
  align-items: stretch;
}

/* The primary row must fit without scrolling — these are the keys somebody
 * reaches for without looking. */
.touch-key-row--primary .touch-key {
  flex: 1 1 0;
  min-width: 0;
}

/* A phone cannot show 24 function keys at a tappable size, and shrinking them
 * until it can is how a keypad stops being usable. So the drawer scrolls. */
.touch-key-row--drawer {
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  padding-bottom: 2px;
}

.touch-key-row--drawer .touch-key {
  flex: 0 0 auto;
  min-width: 64px;
}

.touch-key {
  /* 44px is the smallest target most people hit reliably with a thumb. */
  min-height: 44px;
  padding: 8px 10px;
  border-radius: 8px;
  border: 1px solid var(--border-subtle, rgba(255, 255, 255, 0.18));
  background: var(--surface-sunken, rgba(255, 255, 255, 0.06));
  color: inherit;
  font: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  line-height: 1;
  /* Kills the browser's wait-and-see for a double-tap-to-zoom. On a keypad
   * that delay is the difference between a terminal and a slideshow. */
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  white-space: nowrap;
}

/* On a phone in portrait the six primary keys and the drawer toggle share
 * under 50px each, and at the default size every label longer than three
 * characters was cut off mid-word: the Enter key read "Ente" and Reset read
 * "Rese". These are the keys somebody presses without looking, so the row
 * keeps its one-row shape — a key that has moved is worse than a key that is
 * small — and the type comes down until the words fit. */
@media (max-width: 560px) {
  .touch-key-row {
    gap: 4px;
  }

  .touch-key-row--primary .touch-key {
    padding-inline: 3px;
    font-size: 0.8rem;
  }
}

.touch-key:active {
  background: var(--accent-soft, rgba(120, 180, 255, 0.28));
  transform: translateY(1px);
}

.touch-key--primary {
  background: var(--accent, #2f6fed);
  border-color: var(--accent, #2f6fed);
  /* Every built-in theme's --accent is a bright, saturated color; white text
     on it measures as low as 1.3:1, well under the 3:1 floor for bold text.
     --accent-contrast is the per-theme override that keeps this legible. */
  color: var(--accent-contrast, #000);
}

.touch-key--more {
  flex: 0 0 auto;
  min-width: 56px;
}

/* The bar is fixed over the page, so the page needs room to scroll clear of
 * it — otherwise the last rows of an 24-line screen are permanently behind
 * the keys. --touch-bar-height is published by touch.js and tracks the real
 * height: the PF drawer, the collapse handle and the software keyboard all
 * change it, and a fixed 120px was wrong in every one of those states.
 *
 * The fallback carries the home-indicator inset because it has to stand in for
 * a measurement that has not happened yet — between first paint and touch.js
 * publishing, and on a page where the script never runs. The bar's own padding
 * includes that inset, so a flat 120px is short by it on exactly the devices
 * that have one, and being short means the bottom row of the screen is under
 * the keys. */
body.touch-device .page-wrap {
  padding-bottom: calc(
    var(--touch-bar-height, calc(120px + env(safe-area-inset-bottom, 0px))) + 16px
  );
}

/* The AI chat panel is a full-height fixed column, so its input and its hint
 * sit at the very bottom of the viewport — underneath the bar, which is where
 * this started: a chat panel that can be read and scrolled but not typed
 * into. Ending the panel where the bar begins gives the input back, and
 * because --touch-bar-height includes the software keyboard offset, it stays
 * given back while the operator is typing. */
body.touch-device .copilot-panel {
  height: auto;
  bottom: var(--touch-bar-height, 0px);
}

/* Same fix for the other bottom-docked widgets, which are anchored to the
 * viewport rather than to the page and so do not benefit from the padding
 * above. */
body.touch-device #h3270-notification-container {
  bottom: calc(var(--touch-bar-height, 120px) + 12px);
}

/* Below the 16px iOS Safari zooms the page in on focus and does not zoom back
 * out — and the chat input is the one field on this screen somebody types a
 * sentence into. */
body.touch-device .copilot-panel-form textarea {
  font-size: 16px;
}

/* The chat panel is full-screen furniture on a phone and its own controls
 * were still mouse-sized: a 27px close cross in the corner, 26px header
 * buttons and 30px example chips. The chips in particular are the panel's
 * invitation to try it, and they were the hardest thing on it to hit. */
body.touch-device .copilot-icon-button,
body.touch-device .copilot-example-chip,
body.touch-device .copilot-connect-btn,
body.touch-device .copilot-panel-form button {
  min-height: 44px;
  touch-action: manipulation;
}

body.touch-device .copilot-icon-button {
  min-width: 40px;
  justify-content: center;
}

/* ---- Reaching the rest of the interface ------------------------------ */

/* Toolbar and modal controls are sized for a mouse pointer. A finger needs
 * the same 44px the action bar uses. */
body.touch-device .icon-button,
body.touch-device .toolbar button,
body.touch-device .h3270-key {
  min-height: 44px;
  min-width: 44px;
  touch-action: manipulation;
}

/* Form controls in dialogs are sized for a mouse pointer too, and a select is
 * the worst of them: 31px of target, and a mis-hit lands on the label instead
 * of opening the picker — which reads as "the dropdown does not work" rather
 * than "you missed". The AI provider dialog is a whole dialog of these.
 *
 * font-size:16px is not cosmetic. Below it, iOS Safari zooms the page in when
 * a field takes focus and does not zoom back out, which leaves the rest of the
 * dialog off the side of the screen. */
body.touch-device .ai-field select,
body.touch-device .ai-field input,
body.touch-device .modal select,
body.touch-device .modal input:not([type="checkbox"]):not([type="radio"]) {
  min-height: 44px;
  font-size: 16px;
  touch-action: manipulation;
}

body.touch-device .ai-secondary-btn,
body.touch-device .ai-primary-btn,
body.touch-device .copilot-modal-footer button {
  min-height: 44px;
  touch-action: manipulation;
}

/* The connect form and the dialogs it opens.
 *
 * These are plain buttons in a card rather than toolbar or icon furniture, so
 * none of the rules above reached them, and they came out at 33-37px — on the
 * one page every phone user meets before anything else. The host field is
 * included for the 16px: it is the field somebody types into on this page, and
 * below 16px iOS Safari zooms in on focus and does not zoom back out. */
body.touch-device .connect-row button,
body.touch-device .modal button,
body.touch-device .saved-hosts-row button,
body.touch-device .auth-submit,
body.touch-device .auth-form button {
  min-height: 44px;
  touch-action: manipulation;
}

body.touch-device .connect-row input,
body.touch-device .auth-form input {
  min-height: 44px;
  font-size: 16px;
}

/* An 80-column screen does not fit across a phone. Scrolling it sideways is
 * the honest answer — shrinking the font until it fits makes it unreadable,
 * and reflowing a 3270 screen is not a thing that can be done: the column a
 * character sits in is the information. */
body.touch-device .screen-container {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* Panning and pinch-zoom over the screen, but no double-tap zoom — a
 * double-tap on the grid is two cursor placements, not a zoom gesture. */
body.touch-device .screen-container pre,
body.touch-device .renderer-form {
  touch-action: pan-x pan-y pinch-zoom;
}

/* Tapping protected text places the cursor there, so it should look like
 * something a tap does. */
body.touch-device .screen-container pre {
  cursor: pointer;
}

/* Field inputs get the double-tap delay removed and nothing else.
 *
 * The obvious move — a minimum height so a one-character field is easier to
 * hit — is wrong twice over. A row taller than its line box pushes every row
 * below it down, and a 3270 screen where column 40 of row 6 is not directly
 * under column 40 of row 5 is not a 3270 screen. It also breaks the tap that
 * this file exists to add: cell geometry is the <pre>'s box divided by the
 * row count, so one stretched row makes every tap below it land on the wrong
 * line. The zoom control is the answer for a screen that is too small; it
 * scales the grid, which keeps it a grid. */
body.touch-device .screen-container input {
  touch-action: manipulation;
}

/* Tooltips are hover affordances. On touch they fire on tap and then sit
 * over the thing that was tapped, which turns every button into two taps. */
body.touch-device .tippy-box {
  display: none;
}

/* ---- The landscape suggestion --------------------------------------- */

/* A note, not an interruption: it sits in the space below the terminal that
 * portrait leaves empty, so showing it costs the screen nothing. Everything
 * about the treatment is deliberately quieter than a dialog — it is a
 * suggestion, and the terminal behind it works either way. */
.orientation-hint {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin: 12px 0 0;
  padding: 12px 12px 12px 14px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 10px;
  background: var(--panel-2);
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 180ms ease-out, transform 180ms ease-out;
}

.orientation-hint.is-shown {
  opacity: 1;
  transform: none;
}

.orientation-hint-icon {
  flex: none;
  display: inline-flex;
  color: var(--accent);
}

.orientation-hint-icon svg {
  width: 26px;
  height: 26px;
}

.orientation-hint-body {
  flex: 1 1 auto;
  min-width: 0;
}

.orientation-hint-title {
  margin: 0;
  font-weight: 600;
  line-height: 1.3;
}

.orientation-hint-detail {
  margin: 3px 0 0;
  font-size: 0.85em;
  line-height: 1.35;
  opacity: 0.75;
}

/* 44px, like every other target on a touch device, and pulled out to the
 * padding's edge so the box does not grow to accommodate it. */
.orientation-hint-dismiss {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin: -10px -8px -10px 0;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: none;
  color: inherit;
  opacity: 0.65;
  touch-action: manipulation;
}

.orientation-hint-dismiss:hover,
.orientation-hint-dismiss:focus-visible {
  opacity: 1;
}

.orientation-hint-dismiss svg {
  width: 18px;
  height: 18px;
}

@media (prefers-reduced-motion: reduce) {
  .touch-action-bar,
  .touch-key:active {
    transition: none;
    transform: none;
  }

  .orientation-hint {
    transition: none;
    transform: none;
  }
}
