/* ==========================================================================
   Phantom — reset, typography, primitives
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

* { margin: 0; padding: 0; }

html {
  -webkit-text-size-adjust: 100%;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body {
  min-height: 100dvh;
  background: var(--canvas);
  color: var(--text-1);
  font-family: var(--font-sans);
  font-size: var(--t-base);
  line-height: 1.5;

  /* Ligatures and contextual alternates on; tabular figures are opt-in per
     element so prose keeps proportional numerals. */
  font-feature-settings: "liga" 1, "calt" 1;
  font-optical-sizing: auto;
}

img, svg, video { display: block; max-width: 100%; }
button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; }

/* ── Typography scale ──────────────────────────────────────────────────
   Letter-spacing is size-dependent: tighter as type grows. Leaving it at
   `normal` everywhere is the clearest "used the defaults" signal there is. */

/* Display sizes switch to Manrope at weight 800 with tight tracking — the
   exact treatment on the R5 headline. Body sizes stay on Inter; mixing the
   display face into running copy is what makes a brand font look misapplied. */
.t-3xl { font-family: var(--font-display); font-size: var(--t-3xl); line-height: 1.05; letter-spacing: -0.025em; font-weight: 800; }
.t-2xl { font-family: var(--font-display); font-size: var(--t-2xl); line-height: 1.1;  letter-spacing: -0.023em; font-weight: 800; }
.t-xl  { font-family: var(--font-display); font-size: var(--t-xl);  line-height: 1.2;  letter-spacing: -0.02em;  font-weight: 750; }
.t-lg  { font-family: var(--font-display); font-size: var(--t-lg);  line-height: 1.3;  letter-spacing: -0.015em; font-weight: 700; }
.t-md  { font-size: var(--t-md);  line-height: 1.5;  letter-spacing: -0.006em; }
.t-base{ font-size: var(--t-base);line-height: 1.45; letter-spacing: -0.004em; }
.t-sm  { font-size: var(--t-sm);  line-height: 1.42; }
.t-xs  { font-size: var(--t-xs);  line-height: 1.35; }
.t-2xs { font-size: var(--t-2xs); line-height: 1.3; }

/* The old dark theme gave small text positive tracking, because light-on-dark
   type optically bleeds and reads tighter than it is. On a light ground the
   effect reverses, so that correction is gone rather than merely retuned. */

/* The R5 eyebrow, to the letter: 13px, weight 650, 0.14em tracking. The wide
   tracking is the whole effect — at 0.055em it just looks like small caps. */
.label {
  font-size: var(--t-xs);
  font-weight: 650;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-2);
}

.mono {
  font-family: var(--font-mono);
  font-size: 0.925em;
  letter-spacing: -0.01em;
  font-feature-settings: "liga" 0;
}

/* Digits must not jitter as values update — the most visible amateur tell
   in any dashboard. */
.tabular, td, .metric { font-variant-numeric: tabular-nums; }

.dim  { color: var(--text-3); }
.muted{ color: var(--text-2); }
.faint{ color: var(--text-4); }

h1, h2, h3, .balance { text-wrap: balance; }
p, .prose { text-wrap: pretty; }
.measure { max-width: 66ch; }

.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.clamp-2 {
  display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2;
  -webkit-box-orient: vertical; overflow: hidden;
}

/* ── Focus ─────────────────────────────────────────────────────────────
   WCAG 2.2 wants a 2px perimeter at 3:1 against adjacent colours.
   :focus-visible so pointer users never see it. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}
/* Inside clipping containers, pull the ring inward so it isn't sliced. */
.clip :focus-visible { outline-offset: -2px; }

::selection { background: var(--accent-line); color: var(--ink); }

/* ── Scrollbars ─────────────────────────────────────────────────────── */
* { scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--line-strong);
  border-radius: var(--r-full);
  border: 3px solid transparent;
  background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--text-4); background-clip: content-box; }

/* ── Layout helpers ─────────────────────────────────────────────────── */
.row   { display: flex; align-items: center; gap: var(--sp-2); }
.row-b { display: flex; align-items: baseline; gap: var(--sp-2); }
.col   { display: flex; flex-direction: column; }
.between { justify-content: space-between; }
.grow  { flex: 1; min-width: 0; }
.shrink-0 { flex-shrink: 0; }
.wrap  { flex-wrap: wrap; }
.stack > * + * { margin-top: var(--gap, var(--sp-5)); }

.hidden { display: none !important; }

/* The browser's own [hidden] rule loses to any author rule that sets display,
   so `hidden` on a .banner or a flex row did nothing — an empty red error
   banner sat permanently on Settings → Repository. This makes the attribute
   mean what it says everywhere. */
[hidden] { display: none !important; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

/* ── Motion ──────────────────────────────────────────────────────────── */
@keyframes fade-in     { from { opacity: 0 } to { opacity: 1 } }
@keyframes rise        { from { opacity: 0; transform: translateY(6px) } to { opacity: 1; transform: none } }
@keyframes spin        { to { transform: rotate(360deg) } }
@keyframes pulse-soft  { 0%, 100% { opacity: 1 } 50% { opacity: 0.35 } }

.animate-in { animation: rise var(--dur-slow) var(--ease-out) both; }

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