/*
 * Reset, document defaults and typography primitives.
 * Component styling lives in components.css; app chrome in layout.css.
 */

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

* {
  margin: 0;
}

html {
  min-inline-size: 20rem;
  background: var(--surface-canvas);
  color-scheme: light;
  font-family: var(--font-ui);
  /* macOS renders text heavier than intended; set this once on the root. */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -webkit-text-size-adjust: 100%;
}

html[data-theme='dark'] {
  color-scheme: dark;
}

body {
  min-inline-size: 20rem;
  min-height: 100dvh;
  background: var(--surface-canvas);
  color: var(--text-primary);
  font-size: var(--type-body);
  line-height: var(--leading-normal);
  overflow-wrap: break-word;
}

/* ---------- Headings ------------------------------------------------------ */
/* Semantics are chosen first; these are only the visual defaults per level. */

h1,
h2,
h3,
h4 {
  font-weight: 600;
  letter-spacing: var(--tracking-heading);
  line-height: var(--leading-tight);
  text-wrap: balance;
}

h1 {
  font-size: var(--type-h1);
}
h2 {
  font-size: var(--type-h2);
}
h3 {
  font-size: var(--type-h3);
}
h4 {
  font-size: var(--type-lead);
}

p {
  text-wrap: pretty;
}

/* ---------- Text roles --------------------------------------------------- */

.text-display {
  font-size: var(--type-display);
  font-weight: 600;
  letter-spacing: var(--tracking-display);
  line-height: var(--leading-tight);
}

.eyebrow,
.section-label,
.label-text,
.metric-label {
  display: block;
  color: var(--text-tertiary);
  font-size: var(--type-caption);
  font-weight: 600;
  /* Small caps feel crowded without a little positive tracking. */
  letter-spacing: var(--tracking-caps);
  line-height: var(--leading-snug);
  text-transform: uppercase;
}

.section-title {
  font-size: var(--type-h2);
  font-weight: 600;
  letter-spacing: var(--tracking-heading);
  line-height: var(--leading-tight);
}

.section-subtitle,
.muted-copy {
  max-inline-size: var(--measure);
  color: var(--text-secondary);
  font-size: var(--type-ui);
  line-height: var(--leading-relaxed);
}

.field-hint {
  color: var(--text-tertiary);
  font-size: var(--type-caption);
  line-height: var(--leading-relaxed);
}

small {
  display: block;
  color: var(--text-secondary);
  font-size: var(--type-caption);
  line-height: var(--leading-snug);
}

/* Any value that changes has to hold its width, or the layout jitters. */
.tabular-nums,
.metric-value,
.stat-value,
.hero-price,
td:has(> .tabular-nums),
.data-table .tabular-nums {
  font-variant-numeric: tabular-nums;
}

/* Emails, URLs, hashes and identifiers set the min-content width otherwise. */
.break-token {
  overflow-wrap: anywhere;
}

/* ---------- Links -------------------------------------------------------- */

a {
  color: var(--text-link);
  text-decoration-thickness: from-font;
  text-underline-offset: 0.18em;
  text-underline-position: from-font;
}

@media (hover: hover) {
  a:hover {
    color: var(--action-solid);
  }
}

/* ---------- Media -------------------------------------------------------- */

img,
svg,
video {
  display: block;
  max-inline-size: 100%;
}

img,
video {
  /* Pure black / pure white at low opacity. A tinted ring reads as dirt. */
  box-shadow: var(--shadow-image-ring);
}

/* ---------- Forms and controls ------------------------------------------- */

button,
input,
textarea,
select {
  font: inherit;
  color: inherit;
}

button {
  background: none;
  border: 0;
}

button,
[role='button'],
a,
input,
textarea,
select,
summary,
label {
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

/* An input keeps an intrinsic ~20ch width that would size its grid track. */
input,
select,
textarea {
  inline-size: 100%;
  min-inline-size: 0;
}

/* iOS Safari zooms the page when an input's text is under 16px. */
@media (max-width: 47.99rem) {
  input,
  select,
  textarea {
    font-size: var(--type-body);
  }
}

::placeholder {
  color: var(--text-tertiary);
  opacity: 1;
}

/* ---------- Focus -------------------------------------------------------- */

:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* Only remove the ring where a custom, equally visible one is drawn. */
.has-custom-focus:focus-visible {
  outline: none;
}

::selection {
  background: color-mix(in oklch, var(--action-solid) 24%, transparent);
  color: var(--text-primary);
}

/* ---------- Utilities ---------------------------------------------------- */

.skip-link {
  position: fixed;
  z-index: var(--z-skip);
  inset-block-start: var(--space-3);
  inset-inline-start: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-pill);
  background: var(--surface-raised);
  color: var(--text-primary);
  font-size: var(--type-ui);
  font-weight: 500;
  box-shadow: var(--shadow-float);
  transform: translateY(-200%);
}

.skip-link:focus {
  transform: translateY(0);
}

/*
 * Needs a positioned ancestor. Left absolute against the initial containing
 * block it lands outside the viewport and inflates scrollWidth, which reads as
 * a huge horizontal overflow while everything visible fits.
 */
.sr-only {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-inline-size: 0;
}

/* A group gap is at least twice the gap inside a group. */
.stack-lg {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  min-inline-size: 0;
}

.section-spacer {
  margin-block-start: var(--space-6);
}

[hidden] {
  display: none !important;
}

/* ---------- Scrollbars --------------------------------------------------- */

@supports selector(::-webkit-scrollbar) {
  ::-webkit-scrollbar {
    inline-size: 0.75rem;
    block-size: 0.75rem;
  }

  ::-webkit-scrollbar-track {
    background: transparent;
  }

  ::-webkit-scrollbar-thumb {
    border: 4px solid transparent;
    border-radius: var(--radius-pill);
    background: color-mix(in oklch, var(--text-tertiary) 40%, transparent);
    background-clip: padding-box;
  }
}

/* ---------- Loading ------------------------------------------------------ */
/* A skeleton keeps the layout it will be replaced by, so nothing jumps. */

.skeleton {
  border-radius: var(--radius-5);
  background: var(--surface-sunken);
}

.loading-view {
  display: grid;
  gap: var(--space-4);
}

.loading-hero {
  block-size: 9rem;
}

.loading-row {
  block-size: 5rem;
}

@media (prefers-reduced-motion: no-preference) {
  .skip-link {
    transition: transform var(--duration-ui) var(--ease-out);
  }

  .skeleton {
    animation: skeleton-fade 1.4s ease-in-out infinite alternate;
  }

  @keyframes skeleton-fade {
    to {
      opacity: 0.5;
    }
  }
}

/* ---------- Phone adjustments ------------------------------------------- */

@media (pointer: coarse) {
  :root {
    /* Project rule: 48px is preferred on phones. */
    --hit-min: 3rem;
    --control-h: 3rem;
    --control-h-lg: 3.25rem;
  }
}

@media (forced-colors: active) {
  :focus-visible {
    outline-color: Highlight;
  }

  .badge,
  .workspace-card,
  .btn {
    border: 1px solid CanvasText;
  }
}
