/* ============================================================
   Alert — inline notice with status indicator, icon, title, desc,
   optional CTA link and close button.

   Density modifiers:
   • .alert--card   = 大卡片版 · row-divider 列表（dashboard alerts panel）
   • .alert--row    = 細條版 · single-line with left border accent
                       （inline page warnings）
   • .alert--banner = 頁面公告卡 · dark campaign style
   • .alert--bar    = 通知條 · single-line notification bar（rounded corners +
                       soft shadow, no divider）; neutral surface, icon chip +
                       text-link CTA + round dismiss. Flush（貼頂滿版）or floating
                       per consumer positioning（E-Shop low-stock F2）

   Four status variants（modify icon chip + cta color）:
   .alert--warning · .alert--error · .alert--success · .alert--info

   Anatomy:
     .alert
       .alert__icon  (status-tinted square w/ filled icon glyph)
       .alert__body
         .alert__title
         .alert__desc      (or .alert__meta for --row density)
         .alert__cta       (inline colored link, optional)
       .alert__close       (chevron, .alert--card only)
   ============================================================ */

/* [hidden] 必須蓋過各 density 的 display（flex/grid 會壓過 UA 的 [hidden]）。
   .alert[hidden] specificity 高於 .alert--bar/.alert--card，故 JS 的 el.hidden=true
   能真正隱藏（scenario.js no-event / × 關閉、fans-crm 風險條等都靠這個）。 */
.alert[hidden] { display: none; }

/* ── --card density (rounded-square icon + multi-line body + close) ── */
.alert--card {
  display: grid;
  grid-template-columns: 40px 1fr 28px;
  gap: var(--sp-14);
  align-items: start;
  padding: var(--sp-14) var(--sp-4);
  border-bottom: 1px solid var(--border);
  background: transparent;
  border-radius: 0;
}
.alert--card:last-child { border-bottom: 0; }

.alert--card .alert__icon {
  width: 40px; height: 40px;
  border-radius: 10px;
  display: inline-grid; place-items: center;
  flex-shrink: 0;
  align-self: start;
}
.alert--card .alert__icon .ztor-icon { width: 20px; height: 20px; stroke-width: 1.2; }

.alert--card .alert__body { min-width: 0; padding-top: var(--sp-2); }
.alert--card .alert__title {
  font-family: var(--font-display);
  font-size: var(--fs-14);
  font-weight: var(--fw-regular);
  letter-spacing: -0.005em;
  color: var(--foreground);
  margin-bottom: var(--sp-2);
}
.alert--card .alert__desc {
  font-size: var(--fs-13);
  line-height: var(--lh-relaxed);
  color: var(--foreground-muted);
}
.alert--card .alert__desc em { font-style: normal; font-weight: var(--fw-medium); color: var(--foreground); }
/* Meta row — severity · associated object · processing status (Dashboard F4). */
.alert--card .alert__meta {
  margin-top: 5px;
  font-family: var(--font-ui);
  font-size: var(--fs-11);
  letter-spacing: 0.1px;
  color: var(--muted-foreground);
}
.alert--card .alert__cta {
  display: inline-block;
  margin-top: var(--sp-6);
  font-family: var(--font-ui);
  font-size: var(--fs-13);
  font-weight: var(--fw-regular);
  background: transparent;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-decoration: none;
}
.alert--card .alert__cta:hover { text-decoration: underline; text-underline-offset: 3px; }

/* Close composes the Button atom — markup `.alert__close .btn .btn--icon btn--xs`.
   Hook keeps only grid placement; close icon uses base 16px (Q10 2026-07-13,
   was 20px). */
.alert--card .alert__close { align-self: start; }
/* Blocking item — close control is disabled (resolve only in source module). */
.alert--card .alert__close:disabled { opacity: 0.4; cursor: not-allowed; }

/* Snoozed item — soft-closed info, visually receded but still listed (reappears ~7d). */
.alert--snoozed.alert--card { opacity: 0.62; }
.alert--snoozed.alert--card .alert__cta { opacity: 0.9; }

/* ── --row density (slim, single-line, left-border accent) ── */
.alert--row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: var(--sp-12);
  align-items: center;
  padding: var(--sp-12) var(--sp-14);
  border-radius: var(--radius-md);
  background: var(--muted);
  border-left: 3px solid var(--primary);
}
.alert--row + .alert--row { margin-top: var(--sp-8); }

.alert--row .alert__icon {
  width: 30px; height: 30px;
  border-radius: var(--radius-sm);
  display: inline-grid; place-items: center;
  background: var(--card);
  font-size: var(--fs-13);
}
.alert--row .alert__body { display: flex; flex-direction: column; gap: var(--sp-2); min-width: 0; }
.alert--row .alert__title {
  font-family: var(--font-display);
  font-size: var(--fs-13);
  font-weight: var(--fw-regular);
}
.alert--row .alert__desc,
.alert--row .alert__meta { font-size: var(--fs-12); color: var(--muted-foreground); }
.alert--row .alert__cta {
  font-family: var(--font-ui);
  font-size: var(--fs-12);
  font-weight: var(--fw-regular);
  color: var(--foreground);
  border-bottom: 1px solid var(--border);
  padding-bottom: 1px;
  cursor: pointer;
  text-decoration: none;
}

/* ── --banner density (page-level announcement, dark campaign style) ── */
.alert--banner {
  position: relative;
  display: grid;
  grid-template-columns: 42px minmax(0, 1fr) auto;
  gap: var(--sp-16);
  align-items: center;
  min-height: 104px;
  padding: var(--sp-20) var(--sp-24);
  padding-right: 54px;
  border-radius: var(--radius-xl);
  background: var(--card);
  box-shadow: var(--shadow-card);
  color: var(--foreground);
}
.alert.alert--banner .alert__icon {
  width: 42px;
  height: 42px;
  display: inline-grid;
  place-items: center;
  border-radius: var(--radius-md);
  background: var(--muted);
  color: var(--primary);
  font-family: var(--font-ui);
  font-size: var(--fs-16);
  font-weight: var(--fw-regular);
}
.alert--banner .alert__body {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: var(--sp-4);
}
.alert--banner .alert__title {
  color: var(--foreground);
  font-family: var(--font-display);
  font-size: var(--fs-16);
  font-weight: var(--fw-regular);
  letter-spacing: -0.01em;
}
.alert--banner .alert__desc,
.alert--banner .alert__meta {
  color: var(--foreground-muted);
  font-size: var(--fs-13);
  line-height: var(--lh-comfy);
}
.alert.alert--banner .alert__cta {
  display: inline-flex;
  min-height: 42px;
  align-items: center;
  justify-content: center;
  gap: var(--sp-14);
  padding: 0 var(--sp-18);
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--primary);
  color: var(--primary-foreground);
  font-family: var(--font-ui);
  font-size: var(--fs-13);
  font-weight: var(--fw-regular);
  text-decoration: none;
  white-space: nowrap;
  transition:
    background var(--duration) var(--easing),
    transform var(--duration) var(--easing);
}
.alert.alert--banner .alert__cta::after {
  content: "→";
  font-size: var(--fs-18);
  font-weight: var(--fw-regular);
  line-height: var(--lh-none);
}
.alert.alert--banner .alert__cta:hover {
  background: var(--primary-hover);
  transform: translateY(-1px);
}
.alert--banner .alert__dismiss {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 28px;
  height: 28px;
  display: inline-grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--muted-foreground);
  cursor: pointer;
  font-size: var(--fs-16);
  line-height: var(--lh-none);
  transition:
    background var(--duration) var(--easing),
    color var(--duration) var(--easing);
}
.alert--banner .alert__dismiss:hover {
  background: color-mix(in srgb, var(--foreground) 6%, transparent);
  color: var(--foreground);
}

[data-theme="dark"] .alert--banner {
  background: var(--card);
  color: var(--foreground);
}
[data-theme="dark"] .alert.alert--banner .alert__icon {
  background: color-mix(in srgb, var(--foreground) 8%, var(--card));
}
[data-theme="dark"] .alert--banner .alert__title {
  color: var(--foreground);
}
[data-theme="dark"] .alert--banner .alert__desc,
[data-theme="dark"] .alert--banner .alert__meta,
[data-theme="dark"] .alert--banner .alert__dismiss {
  color: var(--foreground-muted);
}
[data-theme="dark"] .alert--banner .alert__dismiss:hover {
  background: color-mix(in srgb, var(--foreground) 10%, transparent);
  color: var(--foreground);
}

@media (max-width: 720px) {
  .alert--banner {
    grid-template-columns: 38px minmax(0, 1fr);
    min-height: 0;
    padding: var(--sp-18);
    padding-right: var(--sp-48);
  }
  .alert--banner .alert__icon {
    width: 38px;
    height: 38px;
  }
  .alert--banner .alert__cta {
    grid-column: 1 / -1;
    justify-self: start;
    margin-top: var(--sp-4);
  }
}

/* ── --bar density (single-line notification bar; neutral surface, rounded
     corners + soft shadow, no divider). Warning icon chip + dark text-link CTA
     + round dismiss. Sits below the app topbar; pair with position:sticky.
     Consumer may run it flush（貼頂滿版、上緣兩角 border-radius:inherit）or as a
     floating card. (2026-06-15 F2; 2026-06-16 hairline→shadow, flush variant) ── */
.alert--bar {
  display: flex;
  align-items: center;
  gap: var(--sp-10);
  width: 100%;
  padding: var(--sp-12) 22px;
  background: var(--card);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-card);
}
.alert--bar .alert__icon {
  width: 24px; height: 24px;
  flex-shrink: 0;
  border-radius: var(--radius-sm);
  display: inline-grid; place-items: center;
  font-size: var(--fs-13);
}
/* Title + CTA cluster on the left (body doesn't grow); the dismiss is pushed
   to the far right via margin-left:auto. (2026-06-15) */
.alert--bar .alert__body {
  display: flex; align-items: baseline; gap: var(--sp-8);
  min-width: 0; flex: 0 1 auto;
}
.alert--bar .alert__title {
  font-family: var(--font-display);
  font-size: var(--fs-13); font-weight: var(--fw-regular);
  color: var(--foreground);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.alert--bar .alert__meta { font-size: var(--fs-12); color: var(--muted-foreground); white-space: nowrap; }
.alert.alert--bar .alert__cta {
  flex-shrink: 0;
  display: inline-flex; align-items: center; gap: var(--sp-4);
  font-family: var(--font-ui);
  font-size: var(--fs-12); font-weight: var(--fw-regular);
  color: var(--foreground);
  cursor: pointer; text-decoration: none;
}
.alert--bar .alert__cta::after { content: "\2192"; font-size: var(--fs-14); font-weight: var(--fw-regular); line-height: var(--lh-none); }
.alert--bar .alert__cta:hover { text-decoration: underline; text-underline-offset: 3px; }
.alert--bar .alert__dismiss {
  flex-shrink: 0;
  margin-left: auto;
  width: 26px; height: 26px;
  display: inline-grid; place-items: center;
  padding: 0; border: 0; border-radius: 50%;
  background: transparent; color: var(--muted-foreground);
  cursor: pointer; font-size: var(--fs-16); line-height: var(--lh-none);
  transition:
    background var(--duration) var(--easing),
    color var(--duration) var(--easing);
}
.alert--bar .alert__dismiss:hover {
  background: color-mix(in srgb, var(--foreground) 6%, transparent);
  color: var(--foreground);
}
@media (max-width: 760px) {
  .alert--bar .alert__title { white-space: normal; }
}

/* ── .alert--page-top ── 頁面貼頂常駐通知條（搭 .alert--bar）
   變體基底：滿版邊到邊貼齊 app shell 面板——sticky 貼頂、上緣沿用面板圓角、下緣方角＋
   向下陰影取代分隔線；padding-inline 對齊 .page 內容欄（max-width 1280 + 28px gutter）。
   須為 .main 第一個子元素。兩個使用情境：
   1) events 的 Event Day 情境橫幅（js/scenario.js 注入）——用基底原樣＝滿版邊到邊；
   2) e-shop 低庫存提醒（5.1.5 F2，#eshop-stock-bar）——該頁以 instance 覆寫將其收窄、
      置中對齊內容欄，關閉本變體自帶的下緣陰影與 ::after 角遮罩，改走共用 .edge-shadow
      提供下緣陰影（屬記錄在案的頁面特例，詳見 e-shop.html 頁內註解）。
   ::after 補捲動容器右上方角（.main overflow 不去圓捲動側的角；僅 ≥901px；e-shop 覆寫時關閉）。 */
.alert--page-top {
  position: sticky;
  top: 0;
  z-index: 5;
  width: 100%;
  margin: 0;
  padding-inline: max(28px, calc((100% - 1280px) / 2 + 28px));
  border-top-left-radius: inherit;
  border-top-right-radius: inherit;
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
  box-shadow: var(--shadow-header);   /* sticky 下緣邊緣陰影（E 階梯外邊緣工具，同 wizard header）*/
}
@media (min-width: 901px) {
  .alert--page-top::after {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    width: var(--radius-shell);
    height: var(--radius-shell);
    pointer-events: none;
    background: radial-gradient(circle var(--radius-shell) at bottom left,
      transparent calc(var(--radius-shell) - 1px), var(--surface-shell) var(--radius-shell));
  }
}

/* ── Status variants (shared across densities) ── */
.alert--warning.alert--row { border-left-color: var(--status-warning-ink); }
.alert--error.alert--row   { border-left-color: var(--destructive); }
.alert--info.alert--row    { border-left-color: var(--status-info); }
.alert--success.alert--row { border-left-color: var(--status-success); }

.alert--warning .alert__icon { background: color-mix(in srgb, var(--status-warning) 10%, var(--card)); color: var(--status-warning-ink); }
.alert--error   .alert__icon { background: color-mix(in srgb, var(--destructive)    8%, var(--card)); color: var(--destructive); }
.alert--success .alert__icon { background: color-mix(in srgb, var(--status-success)  8%, var(--card)); color: var(--status-success); }
.alert--info    .alert__icon { background: color-mix(in srgb, var(--status-info)     8%, var(--card)); color: var(--status-info); }

.alert--warning .alert__cta { color: var(--status-warning-ink); }
.alert--error   .alert__cta { color: var(--destructive); }
.alert--success .alert__cta { color: var(--status-success); }
.alert--info    .alert__cta { color: var(--status-info); }

/* ── .alert-inset ＋ .alert--inset-card ── 收窄置中的頁面通知條（取代 .alert--page-top 滿版版）
   Promoted 2026-07-26 自 e-shop 頁內 `#eshop-stock-bar`／`.eshop-stock-bar__card`（Figma 856:25546）：
   活動頁的情境提醒（js/scenario.js）要與電子商店低庫存提醒同一款，兩處消費 → 升為元件。

   兩層結構（缺一不可）：
     .alert-inset                       外層＝定位殼，只管貼頂與對齊內容欄，無視覺
       .alert.alert--bar.alert--inset-card   內層＝視覺卡（實色底＋圓角＋內距）

   為什麼分兩層：外層用 `.page` 同一套 max-width+margin:auto+padding-inline 配方對齊內容欄。
   單層寫 `margin-inline: max(...)` 在 `.main` 這個 flex 直欄容器裡量到的寬度不會扣掉 margin，
   寬螢幕會右側溢出（2026-07-21 於 e-shop 實測）。
   `top` 給實際偏移量而非 0：≤900px 斷點 `.main` 的 margin-top 會被歸零，靠自己撐間距才不會貼死。
   須為 `.main` 的第一個子元素。 */
.alert-inset {
  position: sticky;
  top: var(--sp-16);
  z-index: 6;
  width: 100%;              /* 顯式設；靠 flex 預設 stretch 撐不滿 */
  max-width: 1280px;
  margin-inline: auto;
  padding-inline: 28px;
  margin-bottom: 8px;
}
.alert--inset-card {
  padding: 12px 16px;
  background: var(--surface-shell);
  border-radius: var(--radius-xl);
  box-shadow: none;
}
/* 淺色：shell(#F0F0EE)／page(#FAFAFA) 色差太淺，改白底＋E2 卡陰影才分得出層；
   深色的 --surface-shell 本來就明顯亮於 --surface-page，不需再加。 */
html[data-theme="light"] .alert--inset-card {
  background: var(--card);
  box-shadow: var(--shadow-card);
}
.alert--inset-card .alert__dismiss { width: 32px; height: 32px; font-size: var(--fs-24); }

/* ── 整卡可點（data-go，2026-07-27）──────────────────────────
   Dashboard F4 與 F2 popup 的 alert 卡整張都是點擊目標（不只 CTA 小字）。
   hover 用全站互動統一底色 --accent（此卡是卡面上的分隔列，浮起陰影在同色
   dialog 面上讀不出來）；分隔線處理比照 product-list 列 hover（自身與前一列
   的 border 一併隱藏，圓角底色才不會被線切過）。鍵盤焦點＝全站 focus ring。 */
.alert--card[data-go] {
  cursor: pointer;
  transition: background-color 150ms ease, border-color 150ms ease;
}
.alert--card[data-go]:hover {
  background: var(--accent);
  border-radius: var(--radius-md);
  border-bottom-color: transparent;
}
.alert--card[data-go]:has(+ .alert--card[data-go]:hover) {
  border-bottom-color: transparent;
}
.alert--card[data-go]:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
  border-radius: var(--radius-md);
}

/* ── 可點的 banner（data-go，2026-07-28）──────────────────────
   F7 卡底 risk toast（insight-split__toast）等整條可點的 alert--banner：
   hover 微浮起（E1 raise，比列表列輕——它已是實色錯誤 tint，不再換底色），
   焦點＝全站 focus ring。alert--card 的 --accent hover 不適用於實色 banner。 */
.alert--banner[data-go] {
  cursor: pointer;
  transition: transform var(--duration) var(--easing),
              box-shadow var(--duration) var(--easing);
}
.alert--banner[data-go]:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-raise-strong);
}
.alert--banner[data-go]:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
  .alert--banner[data-go], .alert--banner[data-go]:hover { transition: none; transform: none; }
}
