/* Page base styles, a file rather than an inline <style> so the
   Content-Security-Policy needs no 'unsafe-inline' (vite.config.js). */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body, #root { height: 100%; width: 100%; overflow: hidden; }
/* Inset the whole app below the iOS status bar / Dynamic Island. env() is
   0 on web/desktop, so this only bites in the native app. box-sizing:
   border-box (above) keeps the height at 100% while shrinking content. */
#root { padding-top: env(safe-area-inset-top); }
/* Page ground behind the app (iOS overscroll, before first paint).
   T.white keeps light exactly as it was; follows the theme in dark. */
html { background: var(--t-white, #FFFFFF); }
/* Before the theme script runs there are no variables yet: a dark
   device gets the dark card colour from the first paint, no flash. */
@media (prefers-color-scheme: dark) { html { background: var(--t-white, #252321); } }
body { font-family: 'DM Sans', system-ui, -apple-system, sans-serif; -webkit-font-smoothing: antialiased; }
input, textarea, button { font-family: inherit; }
textarea { -webkit-appearance: none; }
/* Kill iOS/WebKit's yellow autofill highlight app-wide. The inset
   shadow paints over the yellow in our field white (every text field
   is T.white); !important because inputStyle's inline transition
   overrides the old 99999s background-transition trick, which is why
   the yellow still showed on sign-up. */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active,
textarea:-webkit-autofill,
select:-webkit-autofill {
  -webkit-box-shadow: 0 0 0 1000px var(--t-white) inset !important;
  box-shadow: 0 0 0 1000px var(--t-white) inset !important;
  transition: background-color 99999s ease-in-out 0s;
  -webkit-text-fill-color: var(--t-ink);
  caret-color: var(--t-ink);
}
/* Loader (Icon.Loader): the app icon's three strings sway from their
   feet in turn. fill-box makes each stroke's transform-origin its own
   bounding box, so "100% 100%" is the foot of the string. With reduced
   motion they only pulse. */
@keyframes vxString { 0%, 100% { transform: rotate(0deg); opacity: 0.4; } 50% { transform: rotate(-6deg); opacity: 1; } }
@keyframes vxPulse { 0%, 100% { opacity: 0.4; } 50% { opacity: 1; } }
.vx-string { transform-box: fill-box; animation: vxString 1.2s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .vx-string { animation-name: vxPulse; } }
