@font-face {
  font-family: "Fraunces";
  src: local("Fraunces");
}

*, *::before, *::after { box-sizing: border-box; }
/* No explicit height here on purpose: `height: 100%` on both html and body
   turns body into its own independent scroll container in most browsers
   (the classic "double 100%" trap), which silently breaks window.scrollTo
   (it targets documentElement, which then has nothing to scroll). Letting
   body size to its content keeps the document itself as the one scroll
   container; min-height: 100vh where needed (.app-shell, .login-screen)
   doesn't depend on this rule. */
html, body { overflow-x: hidden; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  font-family: var(--font-body);
  background: var(--porcelain);
  color: var(--text-primary);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  margin: 0;
  color: var(--text-primary);
  letter-spacing: -0.01em;
}

p { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }
button { font: inherit; }
input, select, textarea { font: inherit; }

button, [role="button"], input, select {
  outline: none;
}

:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
  border-radius: var(--r-sm);
}

::selection {
  background: var(--teal);
  color: var(--text-on-dark);
}

.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* Simple view-transition-style fade for route swaps */
.view-enter {
  animation: viewFadeIn var(--dur-slow) var(--ease-out);
}
@keyframes viewFadeIn {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}

.skeleton {
  background: linear-gradient(90deg, var(--porcelain-dim) 25%, var(--porcelain-line) 37%, var(--porcelain-dim) 63%);
  background-size: 400% 100%;
  animation: shimmer 1.4s ease infinite;
  border-radius: var(--r-sm);
}
@keyframes shimmer {
  0% { background-position: 100% 50%; }
  100% { background-position: 0 50%; }
}

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
