// Shared SCSS mixins.
//
// Available via:
//   @use 'ngwr/theme/mixins' as wr;
//   .thing { @include wr.smooth-br(0.625rem); }

/// Smooth border-radius — opts into the native `corner-shape: squircle`
/// CSS spec (Chrome 145+) when the browser supports it, otherwise
/// falls back to a plain `border-radius`.
///
/// **Experimental.** `corner-shape` is a draft CSS specification; the
/// property name, value space, and metrics may change before it
/// stabilises. Components are free to swap this mixin out for plain
/// `border-radius` at any time. For a deterministic squircle that
/// works across browsers, prefer the `[wrSquircle]` directive — it
/// uses a `clip-path` superellipse instead of relying on `corner-shape`.
///
/// `corner-shape: squircle` renders a continuous-curvature corner (iOS /
/// macOS style) instead of a circular arc. The squircle reads as
/// "less rounded" at the same numeric radius, so we bump the radius by
/// 1.85× under `@supports` to keep the perceived roundness consistent
/// across browsers — that ratio is the rough empirical match.
///
/// Use this anywhere a soft rounded look matters (buttons, cards,
/// inputs, dialogs, dropdowns, tiles). Skip it for full circles
/// (`50%`) and pills (`999px` / `--wr-border-radius-pill`) — those are
/// already maximally curved, no smoothing to do.
///
/// **Gotcha — shape="pill" variants.** If a component applies
/// `smooth-br($radius-var)` and a child rule overrides that var to a
/// pill value, the squircle math doesn't degenerate to a pill shape —
/// it draws a different (slightly inset) curve at huge radii. Reset
/// the corner type explicitly on the pill rule:
///
/// ```scss
/// .wr-btn {
///   --wr-btn-radius: var(--wr-border-radius-base);
///   @include smooth-br(var(--wr-btn-radius));
/// }
/// .wr-btn--pill {
///   --wr-btn-radius: var(--wr-border-radius-pill);
///   corner-shape: round; // browsers without the prop ignore it
/// }
/// ```
///
/// @example scss
///   .thing {
///     @include smooth-br(0.625rem);
///   }
@mixin smooth-br($br) {
  border-radius: $br;

  @supports (corner-shape: squircle) {
    corner-shape: squircle;
    border-radius: calc(#{$br} * 1.85);
  }
}

/// Expand a small control's touch hit area to a comfortable minimum on
/// coarse (touch) pointers, without changing how it looks. Lays an
/// invisible, centred `::after` over the control that's at least `$size`
/// square; taps on the slack still land on the host. Fine-pointer
/// (mouse / trackpad) layouts are left exactly as-is, so dense desktop
/// UIs keep their tight targets.
///
/// Use on small icon-only controls — close (×) buttons, chip removes,
/// tree / cascader toggles — where the visible glyph is well under the
/// ~44px comfortable tap size. Skip controls that are already tall
/// enough, and avoid it on tightly-packed rows where a 44px slack would
/// overlap a neighbouring target.
///
/// The pseudo is absolutely positioned, so the host must be a containing
/// block. For the common static control the mixin sets `position:
/// relative` for you; pass `$positioned: true` when the host is already
/// `absolute` / `fixed` / `relative` so the mixin doesn't downgrade its
/// positioning under the media query.
///
/// @param {Length} $size [44px] - Minimum hit-area edge (Apple HIG).
/// @param {Bool} $positioned [false] - Set true if the host already
///   establishes a positioning context (skips `position: relative`).
///
/// @example scss
///   .wr-alert__close {
///     @include touch-target;
///   }
@mixin touch-target($size: 44px, $positioned: false) {
  @media (pointer: coarse) {
    @if not $positioned {
      position: relative;
    }

    &::after {
      content: '';
      position: absolute;
      top: 50%;
      left: 50%;
      width: 100%;
      height: 100%;
      min-width: $size;
      min-height: $size;
      transform: translate(-50%, -50%);
    }
  }
}
