<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.
  //
  // v0.3 Phase 3 update — left-bar accent pattern. The visible status
  // signal now lives on a 4-px solid left border in the tone colour
  // (100% opacity, fill-grade chroma); the surrounding container uses
  // a soft tone-tinted background and a subtle outer border. Icon,
  // title and body text all use --color-text so they remain legible
  // across every theme combination, including quietware light mode
  // where --color-caution is the bright #FFCD00 fill (would fail as
  // text on cream). Same accessibility role semantics retained.
  //
  // Pattern matches Material Design "banner with leading accent" and
  // IBM Carbon "inline notification" guidance: status colour on a
  // large fill surface (the bar), neutral foreground text. Works for
  // any tone in any theme regardless of WCAG-text contrast on the
  // role colour itself.
  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, { bar: string; bg: string; icon: typeof Info }> = {
    info: {
      bar: "border-l-info",
      bg: "bg-info/10",
      icon: Info,
    },
    caution: {
      bar: "border-l-caution",
      bg: "bg-caution/10",
      icon: AlertTriangle,
    },
    danger: {
      bar: "border-l-danger",
      bg: "bg-danger/10",
      icon: AlertOctagon,
    },
    success: {
      bar: "border-l-success",
      bg: "bg-success/10",
      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-r-lg rounded-l-sm border border-l-4
    border-border-subtle text-[13px] flex items-start gap-2.5
    {tonePal.bar} {tonePal.bg} {classes}"
>
  <ToneIcon size={16} class="mt-0.5 shrink-0 text-text" 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>
