/* ===================================================================
   ephemera -- base layer: resets, html/body, brand wordmark,
   typographic primitives, and the small utility classes (.muted,
   .error, .success, .form-hint, .stack-tight, .text-center).
   Loaded after tokens.css. Companion files: forms.css, components.css,
   chrome.css, responsive.css (must load last; cascade-ordered in
   _layout.html).
   =================================================================== */

/* ===================================================================
   Base
   =================================================================== */

* {
  box-sizing: border-box;
}

/* The browser's default [hidden] { display: none } loses to any author rule
   that sets `display` on the same element (e.g. our #tracked-list has
   display:flex, #chrome-menu-scrim has display:flex, etc.). Enforce "hidden
   means hidden" across the whole app with !important -- this is the one
   place a blanket !important is the correct tool, and without it [hidden]
   on the chrome-menu scrim fails to hide the overlay on every page. */
[hidden] {
  /* biome-ignore lint/complexity/noImportantStyles: load-bearing per comment above. */
  display: none !important;
}

html,
body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family:
    -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  font-size: 17px;
  line-height: 1.6;
  min-height: 100vh;
  transition:
    background 200ms ease,
    color 200ms ease;
}

body {
  display: flex;
  flex-direction: column;
  align-items: center;
  /* Off-scale: page-frame outer padding tuned to the wordmark + card +
     footer optical balance. 2.5rem sits between --space-6 (2rem) and
     --space-7 (3rem); 1.25rem sits between --space-4 (1rem) and
     --space-5 (1.5rem). Rounding either way breaks the centring. */
  padding: 2.5rem 1.25rem;
}

.wordmark {
  color: var(--muted);
  font-size: 0.95rem;
  letter-spacing: 0.05em;
  /* Tight against the version tag below; the wordmark + version form
     one brand block, so most of the breathing room to the card sits on
     the version's own margin-bottom. */
  margin-bottom: var(--space-1);
  font-weight: 500;
}

/* Version tag. Sits directly under the wordmark as a "fine print
   adjacent to brand" line (<small> element). Monospace so the version
   reads as code rather than prose. Muted to ~half the wordmark's weight
   -- visible on close look, invisible on scan. */
.app-version {
  display: block;
  text-align: center;
  margin: 0 0 var(--space-5) 0;
  color: var(--muted);
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.65rem;
  letter-spacing: 0.05em;
  opacity: 0.55;
  /* user-select:all means triple-click inside the pill grabs the whole
     version string -- makes copy-into-a-bug-report a one-gesture action. */
  user-select: all;
}

/* ===================================================================
   Typography
   =================================================================== */

h1,
h2 {
  font-weight: 600;
  line-height: 1.3;
  margin: 0 0 var(--space-4);
  letter-spacing: -0.01em;
}

h1 {
  font-size: 1.4rem;
}
h2 {
  font-size: 1.1rem;
}

p {
  margin: 0 0 var(--space-4);
}

.muted {
  color: var(--muted);
  font-size: 0.9rem;
}
.error {
  color: var(--danger);
  font-size: 0.9rem;
  margin-top: var(--space-3);
}
.success {
  color: var(--success);
}

/* Informational hint text within a form -- muted, left-aligned,
   subordinate to the surrounding label/input rhythm. */
.form-hint {
  color: var(--muted);
  font-size: 0.85rem;
  line-height: 1.5;
  margin: var(--space-4) 0 0;
}

/* Modifier states for inline validation feedback. The hint container is
   permanently rendered next to its input (with aria-live="polite" and
   aria-describedby wired in the template), so JS just toggles the
   modifier class as the user approaches / hits the limit, or after a
   paste gets truncated. State precedence handled in the per-form JS:
   paste-trimmed > ceiling-reached > approaching > idle (hidden).
   No new tokens; .is-warning rides --accent and .is-error rides
   --danger so dark-mode variants come along for free. */
.form-hint.is-warning {
  color: var(--accent);
}
.form-hint.is-error {
  color: var(--danger);
}

/* Generic "next-block, default rhythm" utility. Drops a `<p>` or any
   block element down by the standard one-step gap so we don't have to
   reach for inline `style="margin-top: 1rem"` when a sibling needs
   normal vertical breathing. */
.stack-tight {
  margin-top: var(--space-4);
}

/* Centered text utility. Used as an explicit opt-in on page-state
   messages (the landing page's loading / destroyed / gone states)
   where centering reads as the design intent. Stays direction-agnostic
   -- `center` is meaningful in both LTR and RTL writing modes. */
.text-center {
  text-align: center;
}
