/* Save-heart button.

   Reusable save toggle — circular surface, bookmark glyph, primary-tomato
   when active. Shared by the recipe-card overlay (top-right of media) and
   the peek-panel topbar. The button itself does NOT own positioning;
   surrounding components position it.

   Used in: recipe-card (.recipe-card__save-wrap), peek-panel
   (.peek-panel__topbar-save). The recipe-detail labelled CTA is a
   different partial (recipe_save_button → .recipe-save-button).

   Variants: default (outline bookmark on overlay-light translucent disc),
   `--saved` (fill bookmark on primary-tomato disc with shadow).

   Visibility:
     - Inside .recipe-card: unsaved chip is hidden by default and fades in
       on card hover; saved chip is always visible regardless of hover.
     - Outside .recipe-card (e.g. peek_panel topbar): chip is always
       visible — context implies the affordance is intentional.
     - Below 768px and inside .recipe-card: unsaved chip is fully absent
       (the mobile flow goes through the drawer; saved chip remains).
     - prefers-reduced-motion: transitions collapse to instant snap.

   Spec source: docs/ui-bugs/12-target.md "Locked legacy specs" (issue
   #317 PR1). Ports legacy `SaveButton.tsx` verbatim, minus the
   framer-motion spring on tap (CSS-only transform: scale(0.85) for PR1;
   JS spring is a TODO for PR2/PR3 polish).

   Cascade-layer note: lives in `components` so reset/layout never
   overrides it, and utility classes always do. */

@layer components {
  .save-heart {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border: none;
    border-radius: var(--radius-pill);
    /* Unsaved: rgba(250,250,250,0.95) — color-mix yields the exact value
       since --md-surface = #fafafa. Backdrop-blur keeps the disc legible
       over arbitrary photo content. */
    background: color-mix(in srgb, var(--md-surface) 95%, transparent);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    color: var(--md-on-surface);
    cursor: pointer;
    transition:
      opacity var(--motion-spring-default-effects-duration) var(--motion-spring-default-effects),
      background-color var(--motion-spring-default-effects-duration) var(--motion-spring-default-effects),
      color var(--motion-spring-default-effects-duration) var(--motion-spring-default-effects),
      transform var(--motion-spring-default-effects-duration) var(--motion-spring-default-effects);
  }

  .save-heart:is(:hover, [data-force~="hover"]) {
    background: var(--md-surface-container-low);
  }

  .save-heart:is(:active, [data-force~="active"]) {
    /* Aggressive 0.85 scale matches legacy framer-motion whileTap. The
       legacy spring (stiffness 400, damping 17) is a TODO follow-up;
       CSS scale is the PR1 stand-in. */
    transform: scale(0.85);
  }

  .save-heart--saved {
    background: var(--md-primary);
    color: var(--md-on-primary);
    box-shadow: var(--shadow-md);
  }

  .save-heart--saved:is(:hover, [data-force~="hover"]) {
    /* Hover-token usage is canonically reserved to save-heart per slice B
       Drift (c); all other primary surfaces use .state-layer instead. */
    background: var(--md-primary-hover);
  }

  .save-heart svg {
    display: block;
  }

  /* Visibility — scoped to .recipe-card context so the chip is hidden by
     default ONLY when it lives over a hover-revealable card. Outside that
     context (peek_panel topbar, dev playgrounds rendering bare chips) the
     chip is always visible at its default opacity: 1. */
  .recipe-card .save-heart:not(.save-heart--saved) {
    opacity: 0;
  }

  .recipe-card:is(:hover, :focus-within, [data-force~="hover"], [data-force~="focus"]) .save-heart:not(.save-heart--saved),
  [data-force~="hover"] .recipe-card .save-heart:not(.save-heart--saved),
  [data-force~="focus"] .recipe-card .save-heart:not(.save-heart--saved) {
    opacity: 1;
  }

  /* Mobile (<768px): unsaved chip is absent from cards. The save flow
     goes through the bottom-sheet drawer (PR3). The saved-state chip
     remains visible — that's the legacy invariant. */
  @media (max-width: 767.98px) {
    .recipe-card .save-heart:not(.save-heart--saved) {
      display: none;
    }
  }

  @media (prefers-reduced-motion: reduce) {
    .save-heart {
      transition: none;
    }
    .save-heart:is(:active, [data-force~="active"]) {
      transform: none;
    }
  }
}
