/* Safari 17.x bug: `:scope:not(...):hover` (Flavor A) and `:scope[checked]`
   (Flavor B — attribute-removal restyle) both fail inside `@scope`.
   Selectors moved out. See docs/BROWSER-COMPAT.md §3a. */
option-card-ui:not([checked]):not([disabled]):hover {
  background: var(--option-card-bg-hover);
  border-color: var(--option-card-border-hover);
}
option-card-ui[checked] > :not([slot]) {
  display: block;
}
option-card-ui[checked] {
  background: var(--option-card-bg-checked);
  border-color: var(--option-card-border-checked);
}
option-card-ui[checked]::before {
  border-color: var(--option-card-radio-fill);
  background:
    radial-gradient(
      circle,
      var(--option-card-radio-dot) 0 30%,
      var(--option-card-radio-fill) 30% 100%
    );
}
option-card-ui[checked] [slot="heading"] {
  color: var(--option-card-heading-color-checked);
}
option-card-ui[checked] [slot="icon"] {
  color: var(--option-card-icon-color-checked);
}

@scope (option-card-ui) {
  :where(:scope) {
    /* ── Container ── */
    --option-card-padding-block:    var(--a-space-3);
    --option-card-padding-inline:   var(--a-space-4);
    --option-card-radius:           var(--a-radius-md);
    --option-card-bg:               var(--a-bg);
    --option-card-border:           var(--a-border);
    --option-card-gap-x:            var(--a-space-3);
    --option-card-gap-y:            var(--a-space-1);

    /* ── State: hover ── */
    --option-card-bg-hover:         var(--a-bg-muted);
    --option-card-border-hover:     var(--a-fg-subtle);

    /* ── State: checked ── */
    --option-card-bg-checked:       var(--a-accent-muted);
    --option-card-border-checked:   var(--a-accent);

    /* ── Indicator (CSS radio circle, same size + recipe as <radio-ui>). */
    --option-card-radio-size:       var(--a-toggle-size);
    --option-card-radio-bg:         var(--a-bg);
    --option-card-radio-border:     var(--a-border);
    --option-card-radio-fill:       var(--a-accent);
    /* Mirror radio.css's --radio-fg-checked recipe: an always-light
       token rather than --a-accent-fg, which can flip dark depending
       on theme/scheme combos and produce a near-black inner dot
       against the accent disc. */
    --option-card-radio-dot:        var(--a-chrome-light);

    /* ── Typography ── */
    --option-card-heading-color:          var(--a-fg);
    --option-card-heading-color-checked:  var(--a-fg-strong);
    --option-card-heading-weight:         var(--a-weight-medium);
    --option-card-heading-size:           var(--a-ui-size);
    --option-card-desc-color:             var(--a-fg-muted);
    --option-card-desc-size:              var(--a-ui-sm);
    --option-card-desc-line-height:       1.4;
    --option-card-icon-color:             var(--a-fg-subtle);
    --option-card-icon-color-checked:     var(--a-fg-strong);
    --option-card-icon-size:              1.5rem;

    /* ── State: disabled ── */
    --option-card-disabled-opacity: 0.6;

    /* ── Focus ── */
    --option-card-focus-ring:       var(--a-focus-ring);

    /* ── Transitions ── */
    --option-card-duration:         var(--a-duration-fast);
    --option-card-easing:           var(--a-easing);
  }

  /* ── Base — grid: indicator | (heading + description). Optional icon
       sits between indicator and heading via :has() rules below. ── */
  :scope {
    box-sizing: border-box;
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas:
      "indicator heading"
      "indicator description";
    column-gap: var(--option-card-gap-x);
    row-gap: var(--option-card-gap-y);
    padding: var(--option-card-padding-block) var(--option-card-padding-inline);
    border: 1px solid var(--option-card-border);
    border-radius: var(--option-card-radius);
    background: var(--option-card-bg);
    cursor: pointer;
    user-select: none;
    outline: none;
    transition:
      background var(--option-card-duration) var(--option-card-easing),
      border-color var(--option-card-duration) var(--option-card-easing),
      box-shadow var(--option-card-duration) var(--option-card-easing);
  }

  /* When an icon slot is present, insert a third column for it
     between indicator and heading. */
  :scope:has([slot="icon"]) {
    grid-template-columns: auto auto minmax(0, 1fr);
    grid-template-areas:
      "indicator icon heading"
      "indicator icon description";
  }
  :scope [slot="icon"] {
    grid-area: icon;
    align-self: start;
    color: var(--option-card-icon-color);
    --a-icon-size: var(--option-card-icon-size);
    transition: color var(--option-card-duration) var(--option-card-easing);
  }

  /* ── Indicator — pure CSS radio circle, no separate <radio-ui>. */
  :scope::before {
    content: '';
    grid-area: indicator;
    width: var(--option-card-radio-size);
    height: var(--option-card-radio-size);
    border: 1.5px solid var(--option-card-radio-border);
    border-radius: var(--a-radius-full);
    background: var(--option-card-radio-bg);
    align-self: start;
    margin-block-start: 0.125rem;
    flex-shrink: 0;
    transition:
      background var(--option-card-duration) var(--option-card-easing),
      border-color var(--option-card-duration) var(--option-card-easing);
  }

  /* ── Slots — heading + description ── */
  :scope [slot="heading"] {
    grid-area: heading;
    color: var(--option-card-heading-color);
    font-weight: var(--option-card-heading-weight);
    font-size: var(--option-card-heading-size);
    transition: color var(--option-card-duration) var(--option-card-easing);
  }
  :scope [slot="description"] {
    grid-area: description;
    color: var(--option-card-desc-color);
    font-size: var(--option-card-desc-size);
    line-height: var(--option-card-desc-line-height);
  }

  /* ── Default slot — "spillover" content revealed when checked.
       Aligns with the heading/description column (skips the indicator
       gutter). Common pattern: an "Other" option with a free-text
       textarea, conditional follow-up fields, etc. ── */
  :scope > :not([slot]) {
    grid-column: 2 / -1;
    margin-block-start: var(--a-space-3);
    display: none;
  }
  :scope:has([slot="icon"]) > :not([slot]) {
    grid-column: 3 / -1;
  }
  /* hover + [checked] state rules moved outside @scope — see Safari 17.x bug note at top.
     The :scope[checked]::before recipe lives at top-of-file: an accent disc
     with a centered dot via radial-gradient, mirroring radio-ui's recipe. */

  /* ── Layout: tile — icon top-left, indicator top-right, heading +
       description below, all left-aligned. Used for hero pickers
       (data source, role, plan tiles) where the icon is a primary
       brand cue rather than secondary chrome. ── */
  /* Tile layout — a vertical content stack (icon → heading → description →
     body → action) with the radio indicator pinned top-right OUT of flow.
     Flex (not grid) so content flows in DOM order with no reserved/empty
     tracks: a no-icon plan card has no dead left column, and a slotted CTA
     (slot="action") anchors to the card bottom regardless of how much body
     content (price / feature list) precedes it. (Plan Picker option-card grid) */
  :scope[layout="tile"] {
    display: flex;
    flex-direction: column;
    gap: var(--option-card-gap-y);
    position: relative;
    /* padding inherited from base :scope (token-driven, --option-card-padding-*) */
  }
  /* Radio pinned to the card's top-right corner, OUT of flow. Clear the
     base grid-area:indicator so the absolute containing block is the card
     itself (position:relative) rather than a collapsed grid cell — otherwise
     a grid-forcing host (plan-picker-ui) strands the indicator in an 8px
     gutter and inset-inline-end resolves negative. Inset by the active
     padding token so the dot aligns with the content edge. */
  :scope[layout="tile"]::before {
    position: absolute;
    grid-area: auto;
    inset-block-start: var(--option-card-padding-block);
    inset-inline-end: var(--option-card-padding-inline);
    margin-block-start: 0;
  }
  /* Visual order is fixed via `order`, NOT DOM order: composites
     (plan-picker-ui) append default-slot body content BEFORE option-card
     stamps the heading/description spans on connect, so a flex stack that
     trusted DOM order would render the body above the title. */
  :scope[layout="tile"] [slot="icon"] {
    order: 1;
    align-self: start;
    --option-card-icon-size: 1.75rem;
  }
  :scope[layout="tile"] [slot="heading"] {
    order: 2;
    /* Reserve the top-right radio's footprint so a long heading doesn't run
       under it. */
    padding-inline-end: var(--a-space-6);
  }
  :scope[layout="tile"] [slot="description"] {
    order: 3;
  }
  :scope[layout="tile"] > :not([slot]) {
    order: 4;
  }
  /* CTA anchors to the card bottom (auto top-margin) + full-width, so a row of
     plan cards with different body lengths keeps their buttons aligned. */
  :scope[layout="tile"] [slot="action"] {
    order: 5;
    width: 100%;
    margin-block-start: auto;
  }

  /* ── State: disabled ── */
  :scope[disabled] {
    cursor: not-allowed;
    opacity: var(--option-card-disabled-opacity);
  }

  /* ── Focus ── */
  :scope:focus-visible {
    box-shadow: var(--option-card-focus-ring);
  }
}
