<script lang="ts">
  // v0.2 Phase 5 primitive — inline notice block. Replaces the ~10
  // ad-hoc <div class="bg-{danger,warning,success}/10 …"> patterns
  // scattered across pages. Four tones map to the semantic tokens
  // introduced in Phase 3:
  //   info     — soft blue-grey (--color-info)
  //   caution  — tuned amber (--color-caution)
  //   danger   — tuned red (--color-danger)
  //   success  — moss (--color-success)
  // The icon and aria-role are tone-aware. Dismissible variant is
  // opt-in for transient toasts inline; persistent notices stay
  // visible.
  import { Info, AlertTriangle, AlertOctagon, CheckCircle, X } from "lucide-svelte";
  import type { Snippet } from "svelte";

  type Tone = "info" | "caution" | "danger" | "success";

  interface Props {
    tone?: Tone;
    title?: string;
    dismissible?: boolean;
    onDismiss?: () => void;
    children?: Snippet;
    classes?: string;
  }

  let {
    tone = "info" as Tone,
    title,
    dismissible = false,
    onDismiss,
    children,
    classes = "",
  }: Props = $props();

  const palette: Record<Tone, { bg: string; border: string; fg: string; icon: typeof Info }> = {
    info: {
      bg: "bg-info/10",
      border: "border-info/30",
      fg: "text-info",
      icon: Info,
    },
    caution: {
      bg: "bg-caution/10",
      border: "border-caution/30",
      fg: "text-caution",
      icon: AlertTriangle,
    },
    danger: {
      bg: "bg-danger/10",
      border: "border-danger/30",
      fg: "text-danger",
      icon: AlertOctagon,
    },
    success: {
      bg: "bg-success/10",
      border: "border-success/30",
      fg: "text-success",
      icon: CheckCircle,
    },
  };

  // Danger gets role="alert" so screen readers announce immediately;
  // the others use the less-interrupting role="status".
  const ariaRole = $derived(tone === "danger" ? "alert" : "status");
  const tonePal = $derived(palette[tone]);
  const ToneIcon = $derived(tonePal.icon);
</script>

<div
  role={ariaRole}
  class="px-4 py-3 rounded-lg border text-[13px] flex items-start gap-2.5
    {tonePal.bg} {tonePal.border} {classes}"
>
  <ToneIcon size={16} class="mt-0.5 shrink-0 {tonePal.fg}" aria-hidden="true" />
  <div class="flex-1 min-w-0 leading-relaxed text-text">
    {#if title}
      <p class="font-semibold text-text mb-1">{title}</p>
    {/if}
    {#if children}{@render children()}{/if}
  </div>
  {#if dismissible}
    <button
      type="button"
      class="shrink-0 text-text-tertiary hover:text-text size-5 flex items-center justify-center rounded"
      aria-label="Dismiss notice"
      onclick={onDismiss}
    >
      <X size={14} />
    </button>
  {/if}
</div>
