* {
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
}

/* A real phone's scrollbar is a thin, translucent overlay with no arrow
   buttons — the desktop browser default (thick track, up/down arrow
   buttons) only ever shows up when testing on a mouse/trackpad, but reads
   as jarringly out-of-place against the rest of the app's native-app
   look. Applied globally since any screen's scrollable area (chat
   history, a long form, a sheet) should feel the same. */
* {
  scrollbar-width: thin;
  scrollbar-color: rgba(0, 0, 0, 0.18) transparent;
}
*::-webkit-scrollbar {
  width: 5px;
  height: 5px;
}
*::-webkit-scrollbar-track {
  background: transparent;
}
*::-webkit-scrollbar-thumb {
  background: rgba(0, 0, 0, 0.18);
  border-radius: 999px;
}
/* Tamaño de texto (Configuración > Apariencia) rescales every element's
   own inline font-size directly (see window.applyTextSizeToTree in
   settings/preferences.js) right after each render — instantly, with no
   transition of its own, since it's a plain style.fontSize assignment.
   This is what actually makes that jump feel like a smooth resize instead
   of a hard cut, for every screen at once, without that JS needing to
   animate anything itself. */
#app * {
  transition: font-size 0.25s cubic-bezier(0.2, 0.8, 0.2, 1);
}

*::-webkit-scrollbar-button {
  display: none;
  width: 0;
  height: 0;
}
*::-webkit-scrollbar-corner {
  background: transparent;
}

html {
  height: 100%;
  background: #f5f7fa;
  color: var(--color-ink);
  font-family: var(--font-main);
  width: 100%;
  overscroll-behavior-y: none;
}

body {
  height: 100%;
  margin: 0;
  width: 100%;
  overscroll-behavior-y: none;
  user-select: none; /* Make text unselectable like a native app */
  touch-action: pan-x pan-y;
}

button,
input,
select,
textarea {
  font: inherit;
  user-select: auto;
}

button {
  border: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
  transition: all 0.25s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.page-transition-back {
  animation: slideOutRight 0.35s cubic-bezier(0.25, 1, 0.5, 1) forwards;
}

@keyframes fadeSlideIn {
  from { opacity: 0; transform: translateY(12px); }
  to { opacity: 1; transform: translateY(0); }
}

.tab-transition {
  animation: fadeSlideIn 0.3s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

button:active {
  transform: scale(0.96);
}

svg {
  display: block;
  width: 22px;
  height: 22px;
}

img {
  pointer-events: none; /* Evita interacciones directas */
  user-select: none;
  -webkit-user-select: none;
  -webkit-user-drag: none; /* Bloquea el arrastre en navegadores WebKit */
}

.screen-root {
  position: relative;
  height: 100%;
  /* svh (small viewport height), not dvh (dynamic) — dvh actively
     recalculates every time a mobile browser's address bar collapses or
     reappears (scrolling, navigating), which resizes this root container
     — the one every single screen sits inside — live, mid-interaction.
     That's what read as screens "settling"/"rearranging" on their own:
     not an animation, the viewport itself changing size under them. svh
     commits to the smallest guaranteed height up front and never moves
     again; the trade is a sliver of unused space at the very bottom when
     the address bar happens to be hidden, which is far less noticeable
     than the whole screen resizing under someone's thumb. */
  height: 100svh;
  width: 100%;
  max-width: 480px;
  margin: 0 auto;
  overflow: hidden;
  background: linear-gradient(180deg, #ffffff 0%, #fbfcfe 100%);
  box-shadow: 0 0 40px rgba(0, 0, 0, 0.05);
  transform: translateZ(0); /* Creates a containing block for fixed positioned elements */
  display: flex;
  flex-direction: column;
}

.screen-root.admin-mode {
  max-width: 100%;
  border-radius: 0;
  box-shadow: none;
}

.screen-content {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 0 20px 26px;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-y: contain;
}

.screen-content.no-pad {
  padding: 0;
}

.screen-content.no-scroll {
  overflow-y: hidden;
}

.screen-content.no-bottom-pad {
  padding-bottom: 0;
}

.screen-content.flex-col {
  display: flex;
  flex-direction: column;
}

.screen-content.full-height {
  /* Flexbox automatically handles full height when no bottom nav is present */
}

.screen-content::-webkit-scrollbar {
  display: none;
}

/* Real "Descargar PDF" on the receipt screen uses the browser's own print
   dialog (window.print()) instead of faking a download — this hides the
   app chrome so only the receipt card itself ends up on the page/PDF. */
@media print {
  body * {
    visibility: hidden;
  }
  #receipt-printable, #receipt-printable * {
    visibility: visible;
  }
  #receipt-printable {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
  }
  #receipt-actions {
    display: none !important;
  }
}
