Tarjeta con luz

La tarjeta de siempre (una capa con borde de 1px) con una luz suave que sigue al cursor y enciende el borde bajo él. Para paquetes, planes o maestras: invita a explorar sin gritar. Con href: toda la tarjeta es un enlace, accesible y con un solo punto de tabulación.

Vigencia 60 días

Paquete 10 clases

Yoga, mat o reformer, a la hora que quieras.

$1,450 $145 por clase

app/views/… (la demo de arriba)

<div class="@container w-full max-w-2xl">
  <div class="grid gap-4 @lg:grid-cols-2">
    <%= render Ui::SpotlightCardComponent.new(href: "#", label: "Paquete de 10 clases, $1,450") do %>
      <div class="flex items-start justify-between gap-3">
        <span class="grid size-9 place-items-center rounded-lg border border-border bg-raised text-muted-foreground" aria-hidden="true">
          <%= render Ui::IconComponent.new(:ticket) %>
        </span>
        <span class="eui-label">Vigencia 60 días</span>
      </div>
      <h3 class="mt-5 text-base font-semibold tracking-tight">Paquete 10 clases</h3>
      <p class="mt-1 text-sm text-muted-foreground">Yoga, mat o reformer, a la hora que quieras.</p>
      <p class="mt-5 flex items-baseline gap-2">
        <span class="text-2xl font-semibold tracking-[-0.03em] eui-numeric">$1,450</span>
        <span class="font-mono text-2xs text-faint">$145 por clase</span>
      </p>
    <% end %>

    <%= render Ui::SpotlightCardComponent.new(class: "hidden @lg:flex flex-col") do %>
      <div class="flex items-center gap-3">
        <span class="grid size-9 place-items-center rounded-full bg-muted text-xs font-medium text-muted-foreground" aria-hidden="true">AG</span>
        <div class="min-w-0">
          <h3 class="text-sm font-semibold tracking-tight">Ana García</h3>
          <p class="text-xs text-faint">Vinyasa · Yin · Meditación</p>
        </div>
      </div>
      <p class="mt-5 text-sm text-muted-foreground">Clases privadas de 60 minutos, en el estudio o en línea. Ideal para empezar.</p>
      <div class="mt-auto flex items-center justify-between gap-3 pt-5">
        <span class="font-mono text-2xs text-faint">$650 / sesión</span>
        <%= render Ui::ButtonComponent.new(variant: :secondary, size: :sm) do %>Agendar<% end %>
      </div>
    <% end %>
  </div>
</div>

Qué hace

  • La luz es CSS puro (eui-spotlight); el JS solo escribe la posición del cursor una vez por cuadro.
  • El borde se ilumina bajo el cursor con una máscara, sin elementos extra.
  • Contenido libre por bloque; botones internos quedan encima del enlace con relative z-10.
  • En táctil la superficie se queda quieta.

Props

Nombre Tipo Default Descripción
href String nil Vuelve clicable toda la tarjeta con un enlace estirado.
label String nil Nombre accesible del enlace; obligatorio con href.
padding :sm | :md | :lg :md Aire interno; sigue el dial de densidad.
tag Symbol :div Elemento raíz (:article, :li…).
link Hash {} Atributos extra del enlace (p. ej. data: { turbo_frame: }).

Accesibilidad