@layer base {
  body {
    font-family: var(--font-ui);
    background: var(--color-bg);
    color: var(--color-text);
    line-height: 1.6;
  }

  :is(a, button, input, select, textarea):where(:focus-visible) {
    outline: 2px solid var(--color-focus);
    outline-offset: 2px;
  }

  /* scrollbar */
  ::-webkit-scrollbar { width: 6px; }
  ::-webkit-scrollbar-track { background: transparent; }
  ::-webkit-scrollbar-thumb { background: var(--ink-200); border-radius: 3px; }

  /* A variant that fails to load (e.g. a transient S3 blip serving the
     representation) degrades to the same muted "no preview" placeholder as a
     not-yet-processed upload, rather than an empty grey box. The `thumbnail`
     Stimulus controller clears the src and adds this class after it gives up
     retrying. */
  img.is-broken {
    background-color: var(--ink-100);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%238A9485' stroke-width='1.2' stroke-linecap='round'%3E%3Cpath d='M2 12l4-5 3 3.5 2.5-3L15 12'/%3E%3Ccircle cx='13' cy='5' r='2'/%3E%3Crect x='1' y='2' width='14' height='12' rx='1.5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: center;
    background-size: clamp(14px, 35%, 40px);
    border-radius: var(--r-sm);
  }

  /* A thumbnail whose variant hasn't loaded yet (still warming, or the
     `thumbnail` controller is retrying a throttled proxy). A moving shimmer
     reads as "preparing", not "broken", and clears the moment the image loads. */
  img.is-loading {
    background-color: var(--ink-100);
    background-image: linear-gradient(
      100deg,
      transparent 30%,
      rgba(255, 255, 255, 0.55) 50%,
      transparent 70%
    );
    background-size: 220% 100%;
    background-repeat: no-repeat;
    border-radius: var(--r-sm);
    animation: thumb-shimmer 1.4s ease-in-out infinite;
  }

  @keyframes thumb-shimmer {
    from { background-position: 180% 0; }
    to   { background-position: -80% 0; }
  }

  @media (prefers-reduced-motion: reduce) {
    img.is-loading { animation: none; }
  }
}
