/*
 * Replaces the Tailwind Preflight that `to-convert/css/style.css` relied on via
 * `@import "tailwindcss"`. Scoped to the elements this app actually renders.
 *
 * The layer statement below is load-bearing: `remix/ui` emits every `css()` rule
 * into the `rmx` layer, and unlayered CSS outranks layered CSS. Declaring
 * `base` before `rmx` makes these defaults lose to component styles, so a
 * component's own `margin`/`padding` always wins over the reset.
 */
@layer base, rmx;

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

  body {
    margin: 0;
  }

  p,
  h1,
  h2,
  h3,
  h4,
  h5,
  h6,
  figure {
    margin: 0;
  }

  ul,
  ol {
    margin: 0;
    padding: 0;
    list-style: none;
  }

  img,
  svg {
    display: block;
  }

  table {
    border-collapse: collapse;
  }

  button {
    font: inherit;
    color: inherit;
    background: none;
    border: 0;
  }

  /* Form controls don't inherit the body font by default; without this every
   * input on `/form-elements` renders in the UA font instead of IBM Plex Sans. */
  input,
  select,
  textarea {
    font: inherit;
    color: inherit;
  }

  /*
   * Native checkboxes take the same 3px the app's own drawn checkboxes do.
   *
   * The UA gives them 4px, which is close enough to look like a mistake rather than a difference:
   * the data tables use real `<input type="checkbox">` while the form-elements page draws its own,
   * and a page showing both had two checkbox shapes 1px apart. `accent-color` is the matching
   * declaration for the fill — it is the one supported way to brand a native control without
   * `appearance: none`, which would mean rebuilding the tick and the indeterminate state by hand.
   *
   * Radios are deliberately not included. A round radio is one of the three shapes zero bevel
   * exempts; see the radius block in `theme.ts`.
   */
  input[type="checkbox"] {
    border-radius: var(--radius-check);
  }

  input[type="checkbox"],
  input[type="radio"] {
    accent-color: var(--color-brand-500);
  }

  /*
   * The app's one focus ring, declared once.
   *
   * `:focus-visible` rather than `:focus` so a pointer click on a button doesn't leave a ring
   * behind, while keyboard and assistive-tech focus always does.
   *
   * This belongs in `base` and not in a `css()` mixin precisely *because* base loses to `rmx`.
   * Text inputs want a different treatment — border colour plus a soft halo rather than an
   * offset outline — and `form-styles.ts` overrides this by simply declaring its own rule in the
   * `rmx` layer. The cascade does the work, so neither side needs `!important`, which is what the
   * reference had to reach for.
   */
  :focus-visible {
    outline: var(--focus-ring-width) solid var(--focus-ring);
    outline-offset: var(--focus-ring-offset);
  }

  /*
   * Zero bevel puts more weight on typography, and a ragged right edge under a squared card reads
   * as sloppy in a way it does not under a rounded one. `balance` evens the line lengths of a
   * heading (capped by the UA at ~6 lines, so it costs nothing on long text); `pretty` only
   * prevents orphans, which is the version that is cheap enough for body copy.
   */
  h1,
  h2,
  h3 {
    text-wrap: balance;
  }

  p {
    text-wrap: pretty;
  }

  /*
   * The single permitted keyframe. `Spinner` is the only component in the app that animates
   * continuously; everything else transitions between two states via `motion.ts`.
   */
  @keyframes rmx-spin {
    to {
      transform: rotate(360deg);
    }
  }

  /*
   * Honour a reduced-motion preference globally rather than component by component. `0.01ms` and
   * not `0` because a zero-duration transition never fires `transitionend`, and any handler
   * waiting on one would hang.
   */
  @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;
    }
  }
}
