@layer components {
  /* Flash highlight on scroll-to from a goal/red-card toast click */
  @keyframes match-card-flash {
    0%,
    100% {
      box-shadow: none;
    }

    50% {
      box-shadow: 0 0 0 2px var(--color-accent);
    }
  }

  .match-card--flash {
    animation: match-card-flash 1.5s ease-out;
  }

  @media (prefers-reduced-motion: reduce) {
    .match-card--flash {
      animation: none;
    }
  }

  .match-card {
    display: flex;
    align-items: center;
    gap: 12px;
    background: var(--color-surface);
    border-radius: var(--radius-lg);
    padding: 14px 16px;
    margin: 0 0 8px;
    cursor: pointer;
    text-decoration: none;
  }

  .match-card:last-child {
    margin-bottom: 0;
  }

  .match-card:hover {
    background: var(--color-surface-hover);
  }

  .match-card:active {
    transform: scale(0.98);
  }

  /* League overview nests the match-card inside an already-surface card,
     so the default surface fill camouflages them. Inside
     `.league-matchday-list` we bump the fill to surface-hover and move
     the hover/focus cue to an accent border + soft ring so the card
     stays visible in the parent chrome. Home portada keeps the simple
     behaviour above. */
  .card .league-matchday-list .match-card {
    background: var(--color-surface-hover);
    border: 1px solid transparent;
    transition:
      border-color 120ms ease,
      box-shadow 120ms ease,
      transform 120ms ease;
  }

  .card .league-matchday-list .match-card:hover {
    background: var(--color-surface-hover);
    border-color: color-mix(in srgb, var(--color-accent) 55%, transparent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent) 12%, transparent);
  }

  .card .league-matchday-list .match-card:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
  }

  .card .league-matchday-list .match-card:active {
    background: color-mix(in srgb, var(--color-surface-hover) 88%, var(--color-text) 8%);
    border-color: var(--color-accent);
    transform: scale(0.98);
  }

  /* Light themes: subtle dual-layer shadow to define cards on white */
  /* stylelint-disable-next-line no-descending-specificity */
  :root[data-theme^="light"] .match-card {
    box-shadow:
      0 1px 2px rgb(0 0 0 / 4%),
      0 1px 1px rgb(0 0 0 / 3%);
  }

  /* Status column */
  .match-card__status {
    min-width: 44px;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
  }

  .match-card__status-text {
    font-size: 12px;
    font-weight: var(--weight-bold);
    color: var(--color-text-secondary);
  }

  .match-card--ft .match-card__status-text {
    color: var(--color-text-muted);
  }

  .match-card--live .match-card__status-text {
    color: var(--color-live);
  }

  .match-card--live .match-card__status::before {
    content: "";
    width: 8px;
    height: 8px;
    background: var(--color-live);
    border-radius: 50%;
    animation: pulse-dot 1.5s ease-in-out infinite;
  }

  /* Teams column */
  .match-card__teams {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
  }

  /* Grid layout. Logo pinned to row 1 so it sits at the team-name
     baseline whether scorers exist or not (avoids the "logo floating
     mid-rows" effect when row 2 is populated). The scorers row only
     materializes on desktop — mobile collapses to zero height because
     the helper returns '' visually via `display: none` below. */
  .match-card__team {
    display: grid;
    grid-template-columns: 22px minmax(0, 1fr);
    align-items: center;
    column-gap: 10px;
    row-gap: 2px;
    min-width: 0;
  }

  .match-card__team .match-card__logo {
    grid-row: 1;
    grid-column: 1;
    align-self: center;
  }

  .match-card__team-content {
    grid-column: 2;
    display: contents;
  }

  .match-card__team-line {
    grid-column: 2;
    grid-row: 1;
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
  }

  /* Scorers sub-line — desktop-only, sits below the team name and
     indents past the logo (column 2) so the goal events line up with
     the team-name baseline. Mobile keeps the compact one-line card
     1:1 — the row is `display: none` below the breakpoint. */
  .match-card__scorers {
    display: none;
  }

  /* Scorers on desktop disabled for now — feeling too cluttered next
     to the rest of the card chrome (red cards + star + score + status).
     Keeping the helper + CSS in place so we can flip the display back
     to `flex` when we revisit the density question. */
  @media (width >= 1200px) {
    .match-card__scorers {
      grid-column: 2;
      grid-row: 2;
      display: none;
      flex-wrap: wrap;
      align-items: center;
      gap: 3px 10px;
      font-size: 10px;
      line-height: 1.3;
      min-width: 0;
    }
  }

  .match-card__scorer {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    white-space: nowrap;
  }

  .match-card__scorer-icon {
    font-size: 9px;
    line-height: 1;
    filter: grayscale(0.4);
  }

  .match-card__scorer-min {
    color: var(--color-text-muted);
    font-weight: var(--weight-normal);
    font-variant-numeric: tabular-nums;
  }

  .match-card__scorer-name {
    color: var(--color-text);
    font-weight: var(--weight-normal);
  }

  .match-card__scorer em {
    font-style: italic;
    color: var(--color-text-muted);
  }

  .match-card__scorer-pen {
    color: var(--color-text-muted);
  }

  .match-card__logo {
    width: 22px;
    height: 22px;
    flex-shrink: 0;
    object-fit: contain;
    border-radius: 4px;
  }

  /* Escudo placeholder estilo placeholder — circulo con borde sutil
     cuando el equipo aún no se conoce (bracket KO con clasificados
     pendientes). Reserva el espacio para que el nombre no salte de
     posición cuando luego cargue el escudo real. */
  .match-card__logo--placeholder {
    display: inline-block;
    border-radius: 50%;
    border: 1.5px dashed var(--color-border);
    background: var(--color-surface-hover);
  }

  .match-card__team-name {
    font-size: 14px;
    font-weight: var(--weight-medium);
    color: var(--color-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
  }

  /* Red-card pip — appears beside `.match-card__team-name` when the team
     received one or more reds. Sits at the end of the row, doesn't
     compete with the name for ellipsis space (both are `min-width: 0`
     in the row so the name truncates first). The inner `.card-icon.red`
     is the same 12 × 16 rounded rectangle used in the match-detail
     events timeline — keeps a single visual vocabulary for "red" across
     the app. */
  .match-card__red-card {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    flex-shrink: 0;
  }

  .match-card__red-card .card-icon.red {
    width: 9px;
    height: 12px;
    background: var(--color-card-red);
    border-radius: 1.5px;
  }

  .match-card__red-card-count {
    font-size: 11px;
    font-weight: var(--weight-semibold);
    color: var(--color-text-muted);
    line-height: 1;
  }

  /* Score column */
  .match-card__score {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    min-width: 32px;
    flex-shrink: 0;
  }

  .match-card__score-home,
  .match-card__score-away {
    font-family: var(--font-title);
    font-size: 16px;
    font-weight: var(--weight-bold);
    color: var(--color-text);
    line-height: 22px;
    font-variant-numeric: tabular-nums;
  }

  /* Loser score dimmed */
  .match-card__score--loser {
    color: var(--color-text-muted);
  }

  /* Loser team — applied only in KO context (when the match-card
     receives an explicit `winnerId`). Strikes through the name and
     dims the crest to mirror `_match_card_tie` so single-leg KO
     fixtures (Copa Final, World Cup last-16+) read consistently with
     the two-leg tie cards. */
  .match-card__team--loser .match-card__team-name {
    text-decoration: line-through;
    text-decoration-color: color-mix(in oklab, var(--color-text) 80%, transparent);
    text-decoration-thickness: 2px;
    opacity: 0.5;
  }
  .match-card__team--loser .match-card__logo {
    opacity: 0.45;
  }

  /* Half-time — yellow with pause symbol */
  .match-card--ht .match-card__status-text {
    color: var(--color-yellow-card);
    font-size: 9px;
    font-weight: var(--weight-bold);
    letter-spacing: 0.5px;
  }

  .match-card__pause {
    font-size: 16px;
    font-weight: var(--weight-bold);
    color: var(--color-yellow-card);
    letter-spacing: -1px;
    line-height: 1;
  }

  /* Penalties */
  .match-card--pen .match-card__status-text {
    color: var(--color-purple);
    font-size: 11px;
    font-weight: var(--weight-bold);
  }

  /* Extra time break */
  .match-card--et-break .match-card__status-text,
  .match-card--break .match-card__status-text {
    color: var(--color-yellow-card);
    font-size: 11px;
    font-weight: var(--weight-bold);
  }

  /* Pen break */
  .match-card--pen-break .match-card__status-text {
    color: var(--color-indigo);
    font-size: 11px;
    font-weight: var(--weight-bold);
  }

  /* Postponed / Cancelled / Suspended / Abandoned / Awarded */
  .match-card--postponed .match-card__status-text,
  .match-card--cancelled .match-card__status-text,
  .match-card--suspended .match-card__status-text,
  .match-card--abandoned .match-card__status-text,
  .match-card--awarded .match-card__status-text {
    color: var(--color-zone-cl-playoff);
    font-size: 11px;
    font-weight: var(--weight-bold);
  }

  /* Follow star — replaces the legacy bell for ALL match states so the
     action slot is always present (Sofascore-style coherence). Future
     work: toggle a `.is-followed` class on click + persist via
     match-list controller; for the visual baseline the star is the
     same outline icon for now. */
  .match-card__follow {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    flex-shrink: 0;
    background: none;
    border: none;
    border-radius: 6px;
    cursor: pointer;
    padding: 0;
  }

  .match-card__follow:hover {
    background: var(--color-surface-hover);
  }

  .match-card__follow svg {
    width: 18px;
    height: 18px;
    stroke: var(--color-text-muted);
  }

  .match-card__follow.is-followed svg,
  .match-card__follow[data-active="true"] svg {
    fill: var(--color-accent);
    stroke: var(--color-accent);
  }

  /* Video-highlights indicator — ghost play-triangle in a ring, marking a
     finished match that has a post-match summary. Sits in the trailing slot
     just left of the follow star (the conventional per-row action column).
     Non-interactive: it inherits the card's anchor (tap → match → Highlights),
     so it's a decorative <span>, not a button. The 32px box matches the follow
     star's footprint to keep the action zone vertically aligned and gives a
     comfortable tap surface even though the glyph itself is ~20px. */
  .match-highlight-indicator {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 20px;
    flex-shrink: 0;
    color: var(--color-text-muted);
    pointer-events: none;
  }

  .match-highlight-indicator svg {
    width: 18px;
    height: 18px;
  }

  /* The attribute must neutralize the flex display, per the project's
     hidden-attribute rule. */
  .match-highlight-indicator[hidden] {
    display: none;
  }

  /* Muted score for pre-match / postponed / cancelled — the slot is
     always rendered now (no more bell swap), so we soften the dashes
     so the eye anchors on the time column instead. */
  .match-card__score--muted .match-card__score-home,
  .match-card__score--muted .match-card__score-away {
    color: var(--color-text-subtle, var(--color-text-muted));
    font-weight: var(--weight-normal);
    font-size: 14px;
  }

  /* Bell icon for NS matches */
  .match-card__bell {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    flex-shrink: 0;
    background: none;
    border: none;
    border-radius: 6px;
    cursor: pointer;
    padding: 0;
  }

  .match-card__bell:hover {
    background: var(--color-surface-hover);
  }

  .match-card__bell svg {
    width: 20px;
    height: 20px;
    stroke: var(--color-text-muted);
  }

  .match-card__bell[data-active="true"] svg,
  .match-card__bell.is-active svg {
    stroke: var(--color-accent);
    fill: color-mix(in srgb, var(--color-accent) 20%, transparent);
  }

  /* Dot pulse animation */
  @keyframes pulse-dot {
    0%,
    100% {
      opacity: 1;
      transform: scale(1);
    }

    50% {
      opacity: 0.4;
      transform: scale(1.2);
    }
  }

  @media (prefers-reduced-motion: reduce) {
    .match-card--live .match-card__status::before {
      animation: none;
    }
  }
}
