/* --------------------------------------------------------------------------
 * base-reset.css — global CSS foundations for Tynker on Django.
 *
 * Adapted from good-css.com's technique list ("The reset" plus the scroll /
 * viewport / interaction entries). Linked from every standalone base
 * template.
 *
 * Everything lives in `@layer reset`. Layered rules lose to ALL unlayered
 * rules regardless of specificity or load order, so first-party sheets AND
 * the mirrored legacy bundles (tynker.css, site_webpack_modern.css, which
 * some bases load before this file) always win. That matters: Foundation's
 * `*, ::before, ::after { box-sizing: inherit }` must keep working for
 * widgets that opt a subtree into content-box. (Note: inside a layer,
 * !important is STRONGER than unlayered !important — fine for the two
 * deliberate kill-switches below.) The one unlayered rule is the anchor
 * focus ring at the bottom, which must beat the legacy bundle.
 *
 * Two deliberate omissions from the reference reset:
 *   - No global `min-width: 0` — in an existing 20k-line stylesheet it
 *     changes how already-tuned flex/grid rows render. Overflow-prone rows
 *     get targeted `min-width: 0` fixes instead (46 exist already).
 *   - No `input { font-size: max(16px, 1rem) }` on desktop — it would
 *     re-size every compact dashboard field. The iOS-scoped block below
 *     fixes the actual bug (focus zoom) only where it happens.
 *   - No `@view-transition { navigation: auto }` — a same-origin
 *     cross-fade on EVERY page nav is a visible product change, not a
 *     reset. Do not re-add: the port adds no page-level motion.
 * ----------------------------------------------------------------------- */

@layer reset {

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

  :root {
    /* Let width/height interpolate to and from keyword sizes like `auto`
       (Chrome 129+; dormant elsewhere). Enables height:auto accordions. */
    interpolate-size: allow-keywords;

    /* Reserve the scrollbar's space so a locked-scroll modal or a page that
       grows past one screen can't shift the layout sideways. */
    scrollbar-gutter: stable;

    /* Inherited type niceties: pretty keeps a lone short word off the last
       line; break-word keeps URLs and IDs inside their boxes. */
    text-wrap: pretty;
    overflow-wrap: break-word;

    /* Type fidelity: no synthesized bold/italic, macOS grayscale antialiasing,
       no iOS landscape text inflation, no gray flash over tapped elements. */
    font-synthesis: none;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    -webkit-text-size-adjust: 100%;
    -webkit-tap-highlight-color: transparent;

    /* In-page anchors land clear of a sticky header. Sheets that render a
       sticky header set --anchor-offset (site.css and learn.css do). */
    scroll-padding-top: var(--anchor-offset, 0px);
  }

  body {
    margin: 0;
    /* svh measures the viewport WITH mobile browser toolbars shown, so a
       full-height page never sits underneath them. */
    min-height: 100svh;
  }

  /* Headings wrap in lines of similar length. */
  h1, h2, h3, h4, h5, h6 {
    text-wrap: balance;
  }

  /* Media never forces a container wider than its box. */
  img, svg, video {
    max-width: 100%;
  }
  img, video {
    height: auto;
  }

  /* Pressable elements fire `click` without the double-tap-zoom wait and a
     long press doesn't select the control's label. */
  button, a, [role="button"], summary {
    touch-action: manipulation;
  }
  button, [role="button"], summary {
    user-select: none;
    -webkit-user-select: none;
  }

  /* iOS Safari zooms the page in when an input under 16px receives focus —
     and never zooms back out. -webkit-touch-callout support scopes the 16px
     floor to Apple browsers only, leaving desktop density alone. */
  @supports (-webkit-touch-callout: none) {
    input, textarea, select {
      font-size: 16px !important;
    }
  }

  /* One keyboard focus ring as a backstop. Being layered, any unlayered
     component focus style wins — this only reaches controls that would
     otherwise show nothing. */
  :where(a, button, [role="button"], summary, [tabindex]):focus-visible {
    outline: 2px solid #6c4aee;
    outline-offset: 2px;
  }

  /* Honor OS-level reduced motion globally. Layered !important outranks any
     unlayered rule, so nothing re-enables motion here by accident. */
  @media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important;
    }
    html {
      scroll-behavior: auto !important;
    }
  }

  /* No rubber-band overscroll at the document edge on desktop. Touch devices
     keep native pull-to-refresh and bounce. */
  @media (hover: hover) and (pointer: fine) {
    html {
      overscroll-behavior-y: none;
    }
  }

} /* @layer reset */

/* Anchors need a real selector: the mirrored site_webpack_modern.css bundle
   (loaded before this file on base_live pages) kills rings globally with
   `a:focus, a:focus-visible { outline: 0 }` at the same specificity, so
   source order decides — and this file loads later there. Later-loading
   first-party sheets can still suppress it the same way. */
a:focus-visible {
  outline: 2px solid #6c4aee;
  outline-offset: 2px;
}
