/* Native-feel layer — applies ONLY inside the Capacitor app (html.native-app,
   set by native-enhance.js). The browser / PWA / desktop are never affected. */

/* EXCEPTION — this one applies everywhere (browser, PWA, native): pin the text size so
   iOS never auto-inflates it (Larger Text / its own heuristic), which otherwise blows
   out fixed-width cards and overflows the screen horizontally. */
html,
body {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
/* 2026-09-17: INSIDE THE APP, THE PHONE'S TEXT SIZE. The pin above kept Larger Text
   out entirely: someone who raised the text size in iOS Settings still read 9-10.5px
   labels. native-enhance.js reads the size the phone asks for (-apple-system-body)
   and writes its ratio to --native-text-size, 100% at the default size and at most
   135%; here it becomes the adjust on html and body (a class and an element beat the
   bare `html` and `body` pins here and in employee-field-app.css), and everything
   below inherits it. With no value written — a browser, the PWA, an engine that does
   not know the font keyword — it is the 100% it always was. */
html.native-app,
html.native-app body {
  -webkit-text-size-adjust: var(--native-text-size, 100%);
  text-size-adjust: var(--native-text-size, 100%);
}
/* The hub's rows have a fixed height and already clip their text at 1.0x by design;
   growing it there would redesign the hub, so the tiles keep today's size. */
html.native-app[data-ui="bento"] .bento-grid {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

/* ---------- Kill the web-isms ---------- */
html.native-app,
html.native-app * {
  -webkit-tap-highlight-color: transparent;   /* no grey flash on tap */
  -webkit-touch-callout: none;                /* no long-press image/link menu */
}
html.native-app,
html.native-app body {
  -webkit-user-select: none;
  user-select: none;                          /* no accidental text selection… */
  overscroll-behavior: none;                  /* …and no full-page rubber-band bounce */
  touch-action: manipulation;                 /* no 300ms tap delay, no double-tap zoom */
}
/* Text is still selectable where it matters. */
html.native-app input,
html.native-app textarea,
html.native-app [contenteditable="true"],
html.native-app .selectable {
  -webkit-user-select: text;
  user-select: text;
}
/* 2026-09-17: WHAT PEOPLE WRITE CAN BE COPIED. The switch-off above left no content
   text selectable in the app, and .selectable was never put on anything: a
   long-press on a gate code in a board post, a comment, a house note or a client's
   text message did nothing, in either app. These are the text of those, by the
   class names the markup really uses (team-home.js, manager-house-collab.js and the
   crew's own notes, manager-messages.js). None of them is a tap target, and the
   controls around them (the post's ⋯, Edit, Delete, Retry) stay unselectable. */
html.native-app .th-post > p,
html.native-app .th-pinned p,
html.native-app .th-ct,
html.native-app .collab-note-text,
html.native-app .msg-bub {
  -webkit-user-select: text;
  user-select: text;
  -webkit-touch-callout: default;
}
/* Images can't be dragged out or long-pressed into a menu. */
html.native-app img { -webkit-user-drag: none; user-drag: none; pointer-events: none; }
html.native-app a img,
html.native-app button img,
html.native-app [role="button"] img { pointer-events: auto; }

/* ---------- Instant, tactile press feedback (<100ms), no 300ms delay ---------- */
html.native-app button,
html.native-app a,
html.native-app [role="button"],
html.native-app .bento-tile,
html.native-app .chip,
html.native-app .job,
html.native-app .pcard,
html.native-app .bento-nav button,
html.native-app label.profile-settings-toggle {
  touch-action: manipulation;
}
/* .job is NOT in this list on purpose: the house card is a container of many
   controls (label toggle, quick-date, lockbox copy) — squeezing the whole card
   on any inner tap read as the card being the button. Its buttons press on
   their own via bento.css. */
html.native-app button:active,
html.native-app a.button:active,
html.native-app [role="button"]:active,
html.native-app .bento-tile:active,
html.native-app .chip:active,
html.native-app .pcard:active,
html.native-app .bento-nav button:active {
  transform: scale(.97);
  transition: transform .06s ease;
}

/* ---------- Smooth, momentum scrolling on lists (60fps) ---------- */
html.native-app #cards,
html.native-app .bento-list,
html.native-app .drawer .drawer-inner,
html.native-app .modal .modal-inner,
html.native-app .money-v2-sheet-wrap,
html.native-app .expenses-table-wrap {
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;               /* scroll stops at the list edge, no page bounce */
}
/* Cards paint on their own layer so long lists don't thrash. */
html.native-app .job,
html.native-app .bento-tile,
html.native-app .pcard {
  content-visibility: auto;
  contain: layout paint style;
}

/* ---------- Respect the notch / home indicator safe areas ---------- */
/* Scoped away from the bento manager on purpose. This rule and bento.css's
   `html[data-ui="bento"] body { padding-bottom: ... }` have IDENTICAL specificity
   (0,1,2), and native-feel.css is linked (index.html) AFTER bento.css is
   document.write'n — so inside the iOS app this used to REPLACE bento's 96px of
   scroll clearance with ~34px, and the last row of every bento page (Houses,
   Money, Team, More, Messages, Alerts) sat under the floating .bento-nav pill.
   In a desktop browser it did not, because the rule is gated on html.native-app.
   bento.css now owns its own clearance INCLUDING the inset; everyone else — the
   classic manager skin and the crew shell — keeps this. */
html.native-app:not([data-ui="bento"]) body { padding-bottom: env(safe-area-inset-bottom); }

/* ...and NOT the crew field app either, for the mirror-image reason.
   The rule above pays the home indicator on <body>. The crew's own .app-shell pays
   it too, through --sys-scroll-clear, which is where that inset now lives for the
   whole crew app. Two payments give 155px of clearance under a 105px bar: ~34px of
   dead scroll at the foot of every crew screen, invisible in any desktop browser
   because env() is 0 there, which is how it survived four waves.
   body[data-employee-field-app] is set in the markup of team-clean.html and
   employees.html and nowhere else, so this cannot reach any other shell, and
   ?classic=1, inventory and photography keep their inset from the rule above.

   THIS RULE AND THE CREW STYLESHEET HAVE TO BE READ TOGETHER, and there is a scar
   here worth keeping. For a while the crew stylesheet ALSO carried an
   `html.native-app .app-shell` override that dropped the inset from the shell's
   side, written to fix this same double payment from the other end. Each fix was
   right alone and each assumed the other side was still paying; together they paid
   it ZERO times, and the last row of the Jobs hub landed exactly on the nav pill —
   0px of air inside the iOS app where there had been 179. Worse, that override also
   reached employees.html, which does not load THIS file at all, so the crew's second
   route lost the inset outright.
   The override is gone. --sys-scroll-clear is the one owner: it contains the inset
   once, it is the same expression in both crew routes, and it needs no help from a
   stylesheet that only one of them loads.
   "Not twice" and "at least once" are different sentences, and qa:layout-contract
   now asserts both — because asserting only the first is how you land on zero. */
html.native-app:not([data-ui="bento"]) body[data-employee-field-app] { padding-bottom: 0; }

/* ---------- Subtle iOS-style transition when switching sections ---------- */
html.native-app #cards {
  animation: nativePageIn .22s cubic-bezier(.2,.7,.2,1);
}
@keyframes nativePageIn {
  from { opacity: .35; transform: translateX(10px); }
  to   { opacity: 1;   transform: none; }
}
/* Sheet contents fade in as the sheet slides up (the slide itself is handled by
   the bento bottom-sheet animation). No horizontal nudge — that fought the slide. */
html.native-app #editor.open #houseForm {
  animation: nativeSheetIn .26s cubic-bezier(.2,.7,.2,1);
}
@keyframes nativeSheetIn {
  from { opacity: .55; }
  to   { opacity: 1; }
}
/* 2026-09-17: Reduce Motion in iOS Settings turns both of these off: the section and
   the form simply appear. */
@media (prefers-reduced-motion: reduce) {
  html.native-app #cards,
  html.native-app #editor.open #houseForm { animation: none; }
}

/* ---------- In-app error recovery + offline (styled, never a white page) ---------- */
/* On the tokens (2026-09-05 restyle): the one screen that must never be white
   still paints itself, but with the system's ink, muted grey and font — and its
   button is the accent, like every primary button in the two apps, not an ink pill. */
#nativeRecovery {
  position: fixed; inset: 0; z-index: 2000000; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 16px; padding: 28px; text-align: center;
  background: var(--sys-panel); color: var(--sys-ink); font-family: var(--sys-font);
}
#nativeRecovery .nr-title { font-size: 19px; font-weight: var(--sys-w-bold); letter-spacing: -.01em; }
#nativeRecovery button {
  margin-top: 8px; min-height: 48px; padding: 0 30px; border: 0; border-radius: var(--sys-r-pill);
  background: var(--sys-accent); color: #fff; font-family: inherit; font-size: var(--sys-t-lead); font-weight: var(--sys-w-semibold);
}
