/* =============================================================================
   澄 Lucid — TTPush 金幣管理台 · foundation（設計系統基礎層）
   Spec: docs/DESIGN.md · Live catalogue: docs/ui-gallery.html

   Everything here lives in the cascade layers below, so ANY unlayered rule in
   ui/shell.css or a domain sheet (ui/home.css … ui/settings.css) wins over it
   without specificity games. Domain sheets must therefore scope every rule under
   their own page container or class prefix (see DESIGN.md「命名規則」).

   Rules for this file
   - Colour codes appear only inside the token blocks (§2). Components use tokens.
   - Shared vocabulary that already exists in app markup keeps its name
     (.panel, .panel-header, .status, .muted, .eyebrow, .primary …).
   - New shared components use the `ui-` prefix. Domain components never do.
   ============================================================================= */
@layer ui.reset, ui.tokens, ui.base, ui.components, ui.layouts, ui.tones, ui.utilities;

/* -----------------------------------------------------------------------------
   1. Tokens that do not change with the theme
   ----------------------------------------------------------------------------- */
@layer ui.tokens {
  :root {
    --font-ui: "Inter", "Noto Sans TC", "PingFang TC", "Microsoft JhengHei", system-ui, sans-serif;
    --font-num: "Inter Tight", "Inter", "Noto Sans TC", system-ui, sans-serif;
    --font-mono: ui-monospace, "SFMono-Regular", "Cascadia Mono", Consolas, monospace;

    /* Type scale (px). Minimum on screen is 12px. */
    --fs-12: 12px; --fs-13: 13px; --fs-14: 14px; --fs-15: 15px; --fs-16: 16px; --fs-18: 18px;
    --fs-20: 20px; --fs-24: 24px; --fs-28: 28px; --fs-32: 32px; --fs-40: 40px; --fs-48: 48px;
    --lh-tight: 1.2; --lh-snug: 1.4; --lh-body: 1.6; --lh-long: 1.7;

    /* Spacing on a 4px rhythm. */
    --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 20px; --sp-6: 24px; --sp-7: 32px; --sp-8: 40px; --sp-9: 56px;

    /* Precise, small radii — never pills for buttons. */
    --r-xs: 4px; --r-sm: 6px; --r-md: 8px; --r-lg: 12px; --r-xl: 16px; --r-2xl: 20px; --r-sheet: 22px; --r-round: 999px;

    /* Control heights. Touch screens and phones raise everything to --h-touch. */
    --h-sm: 34px; --h-md: 40px; --h-lg: 48px; --h-touch: 44px;

    /* Shell geometry (desktop > 900px, phone ≤ 900px). */
    --page-max: 1360px; --gutter: 32px;
    --appbar-h: 64px; --vitals-h: 64px; --mobile-header-h: 56px; --mobile-vitals-h: 52px; --tabbar-h: 66px;

    /* Motion */
    --ease: cubic-bezier(.2, .8, .2, 1);
    --ease-out: cubic-bezier(.16, 1, .3, 1);
    --ease-spring: cubic-bezier(.3, 1.35, .6, 1);
    --t-fast: 120ms; --t-mid: 220ms; --t-slow: 380ms;

    /* Stacking (dialogs, the toast and menus opened as popovers use the top layer). */
    --z-sticky: 30; --z-deck: 40; --z-tabbar: 45; --z-mobilebar: 50; --z-backdrop: 59; --z-drawer: 60; --z-menu: 70; --z-float: 80;
    /* Opaque stop for mask-image fades (masks read alpha only). */
    --mask-solid: #000000;
    /* Letterbox behind video in both themes. */
    --media-bg: #05080F;
  }

  /* ---------------------------------------------------------------------------
     2a. Light theme「晴」(also the default before theme-init.js runs)
     --------------------------------------------------------------------------- */
  :root, :root[data-theme="light"] {
    color-scheme: light;
    --bg: #F3F5F9;
    --bg-wash: radial-gradient(1100px 380px at 12% -120px, rgba(36, 83, 224, .07), transparent 70%), radial-gradient(900px 300px at 95% -160px, rgba(18, 160, 110, .05), transparent 70%);
    --deck: #FFFFFF;
    --surface: #FFFFFF;
    --surface-2: #F6F8FB;
    --surface-3: #EDF1F6;
    --raise: #FFFFFF;
    --field: #FFFFFF;
    --row-hover: #F8FAFD;
    --hover-veil: rgba(13, 27, 46, .045);
    --line: #DCE2EB;
    --line-2: #E9EDF3;
    --line-strong: #C3CCD9;

    --ink: #0D1B2E;
    --ink-2: #3A4960;
    --ink-3: #5B6A80;
    --ink-4: #8592A6;

    --brand: #2453E0;
    --brand-hover: #1D47CB;
    --brand-press: #183BAA;
    --brand-ink: #1E49CF;
    --brand-soft: #EBF0FE;
    --brand-line: #C9D6FB;
    --on-brand: #FFFFFF;

    --inv: #0D1B2E;
    --inv-hover: #1C2B44;
    --on-inv: #FFFFFF;

    --coin: #F5B70A;
    --coin-deep: #9A6500;
    --coin-soft: #FFF5D6;
    --coin-line: #F2D58A;

    --ok: #0B7A53;      --ok-solid: #0B7A53;   --on-ok: #FFFFFF;   --ok-soft: #E7F6EF;   --ok-line: #B5E3CE;
    --warn: #AE4E07;    --warn-solid: #EF7D17; --on-warn: #2B1700; --warn-soft: #FFF2E5; --warn-line: #F7CDA3;
    --bad: #BF2828;     --bad-solid: #D93636;  --on-bad: #FFFFFF;  --bad-soft: #FDECEC;  --bad-line: #F3BDBD;
    --ai: #6544D6;      --ai-solid: #6544D6;   --on-ai: #FFFFFF;   --ai-soft: #F2EDFE;   --ai-line: #D8CBFA;
    --muted-solid: #5B6A80; --on-muted: #FFFFFF;

    --mark: #FFE59A;
    --focus: #2453E0;
    --focus-ring: 0 0 0 3px rgba(36, 83, 224, .26);
    --scrim: rgba(13, 27, 46, .44);

    --sh-1: 0 1px 2px rgba(13, 27, 46, .06), 0 1px 1px rgba(13, 27, 46, .03);
    --sh-2: 0 10px 24px -10px rgba(13, 27, 46, .16), 0 2px 6px -2px rgba(13, 27, 46, .06);
    --sh-3: 0 32px 72px -18px rgba(13, 27, 46, .34), 0 10px 24px -10px rgba(13, 27, 46, .14);
    --sh-deck: 0 1px 0 rgba(13, 27, 46, .02), 0 8px 24px -18px rgba(13, 27, 46, .25);
    --sh-btn: 0 1px 2px rgba(13, 27, 46, .16), inset 0 1px 0 rgba(255, 255, 255, .18);
    --sh-btn-commit: 0 6px 16px -8px rgba(13, 27, 46, .5), inset 0 1px 0 rgba(255, 255, 255, .12);
    --sh-tabbar: 0 -10px 28px -16px rgba(13, 27, 46, .25);
    --card-sheen: linear-gradient(transparent, transparent);

    --hero-a: #2B5CF0; --hero-b: #1636A8; --on-hero: #FFFFFF; --hero-sub: rgba(255, 255, 255, .92);
    --toast-bg: #0D1B2E; --toast-ink: #F4F7FB; --toast-line: #0D1B2E;
    --kbd-bg: #FFFFFF;
    --skeleton-a: #EDF1F6; --skeleton-b: #F7F9FC;
    --hatch: repeating-linear-gradient(135deg, #C3CCD9 0 2px, transparent 2px 6px);

    /* Name-initial avatars: eight tints, picked from the account id. */
    --av-1-bg: #E3EAFD; --av-1-ink: #1E49CF;
    --av-2-bg: #DDF3F0; --av-2-ink: #0B6E66;
    --av-3-bg: #FCEFD3; --av-3-ink: #8A5A00;
    --av-4-bg: #FCE4EA; --av-4-ink: #B4234F;
    --av-5-bg: #EEE8FD; --av-5-ink: #5B3CC4;
    --av-6-bg: #E2F4E6; --av-6-ink: #1D7A3A;
    --av-7-bg: #DFF1FB; --av-7-ink: #0A6A9A;
    --av-8-bg: #FDE9DC; --av-8-ink: #A84A0F;

    --select-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235B6A80' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    --check-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23FFFFFF' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7.5'/%3E%3C/svg%3E");
  }

  /* ---------------------------------------------------------------------------
     2b. Dark theme「夜」— its own recipe, not an inversion.
     Keep this block and the fallback copy in §2c identical (test enforced).
     --------------------------------------------------------------------------- */
  :root[data-theme="dark"] {
    color-scheme: dark;
    --bg: #080D17;
    --bg-wash: radial-gradient(1200px 520px at 8% -200px, rgba(58, 102, 242, .18), transparent 65%), radial-gradient(900px 420px at 100% -240px, rgba(31, 175, 120, .07), transparent 65%);
    --deck: #0C1321;
    --surface: #101929;
    --surface-2: #142034;
    --surface-3: #1A263D;
    --raise: #2A3955;
    --field: #0C1424;
    --row-hover: #13203A;
    --hover-veil: rgba(238, 242, 249, .05);
    --line: #233049;
    --line-2: #1B273C;
    --line-strong: #33435F;

    --ink: #EEF2F9;
    --ink-2: #BAC4D6;
    --ink-3: #8E9AB1;
    --ink-4: #66738C;

    --brand: #3A66F2;
    --brand-hover: #4B75F6;
    --brand-press: #2F57D9;
    --brand-ink: #93AEFF;
    --brand-soft: #172645;
    --brand-line: #2F4576;
    --on-brand: #FFFFFF;

    --inv: #F1F4FA;
    --inv-hover: #FFFFFF;
    --on-inv: #0A0F1A;

    --coin: #FFC738;
    --coin-deep: #FFD666;
    --coin-soft: #2A2614;
    --coin-line: #4A3F1B;

    --ok: #45D49A;      --ok-solid: #1FAF78;   --on-ok: #062016;   --ok-soft: #12302B;   --ok-line: #1E5446;
    --warn: #FFAE63;    --warn-solid: #F08A2A; --on-warn: #2B1700; --warn-soft: #2E2418; --warn-line: #5C3F1F;
    --bad: #FF8B8B;     --bad-solid: #D6383E;  --on-bad: #FFFFFF;  --bad-soft: #32202A;  --bad-line: #66303A;
    --ai: #B6A1FF;      --ai-solid: #B6A1FF;   --on-ai: #120B2E;   --ai-soft: #221F45;   --ai-line: #41397A;
    --muted-solid: #66738C; --on-muted: #FFFFFF;

    --mark: rgba(255, 199, 56, .26);
    --focus: #6E91FF;
    --focus-ring: 0 0 0 3px rgba(110, 145, 255, .42);
    --scrim: rgba(2, 5, 11, .70);

    --sh-1: inset 0 1px 0 rgba(255, 255, 255, .03), 0 1px 2px rgba(0, 0, 0, .45);
    --sh-2: inset 0 1px 0 rgba(255, 255, 255, .04), 0 14px 32px -12px rgba(0, 0, 0, .65);
    --sh-3: inset 0 1px 0 rgba(255, 255, 255, .05), 0 40px 96px -20px rgba(0, 0, 0, .8);
    --sh-deck: 0 1px 0 rgba(0, 0, 0, .4), 0 10px 30px -18px rgba(0, 0, 0, .8);
    --sh-btn: 0 1px 2px rgba(0, 0, 0, .4), inset 0 1px 0 rgba(255, 255, 255, .14);
    --sh-btn-commit: 0 6px 18px -8px rgba(0, 0, 0, .7), inset 0 1px 0 rgba(255, 255, 255, .5);
    --sh-tabbar: 0 -12px 30px -16px rgba(0, 0, 0, .8);
    --card-sheen: linear-gradient(180deg, rgba(255, 255, 255, .018), rgba(255, 255, 255, 0) 120px);

    --hero-a: #2A55E0; --hero-b: #11286E; --on-hero: #FFFFFF; --hero-sub: rgba(232, 238, 255, .9);
    --toast-bg: #1D2A43; --toast-ink: #EEF2F9; --toast-line: #2F4576;
    --kbd-bg: #1A263D;
    --skeleton-a: #172234; --skeleton-b: #1F2C44;
    --hatch: repeating-linear-gradient(135deg, #33435F 0 2px, transparent 2px 6px);

    --av-1-bg: #1B2B55; --av-1-ink: #A9BEFF;
    --av-2-bg: #123634; --av-2-ink: #7FDCD0;
    --av-3-bg: #3A2E12; --av-3-ink: #FFD27A;
    --av-4-bg: #3D1A27; --av-4-ink: #FF9CB8;
    --av-5-bg: #2A2150; --av-5-ink: #C4B2FF;
    --av-6-bg: #16341F; --av-6-ink: #8EE0A5;
    --av-7-bg: #12304A; --av-7-ink: #8ED3F7;
    --av-8-bg: #3B2414; --av-8-ink: #FFB585;

    --select-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238E9AB1' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    --check-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23062016' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7.5'/%3E%3C/svg%3E");
  }

  /* ---------------------------------------------------------------------------
     2c. No data-theme (theme-init.js blocked): follow the system. Copy of §2b.
     --------------------------------------------------------------------------- */
  @media (prefers-color-scheme: dark) {
    :root:not([data-theme]) {
      color-scheme: dark;
      --bg: #080D17;
      --bg-wash: radial-gradient(1200px 520px at 8% -200px, rgba(58, 102, 242, .18), transparent 65%), radial-gradient(900px 420px at 100% -240px, rgba(31, 175, 120, .07), transparent 65%);
      --deck: #0C1321;
      --surface: #101929;
      --surface-2: #142034;
      --surface-3: #1A263D;
      --raise: #2A3955;
      --field: #0C1424;
      --row-hover: #13203A;
      --hover-veil: rgba(238, 242, 249, .05);
      --line: #233049;
      --line-2: #1B273C;
      --line-strong: #33435F;

      --ink: #EEF2F9;
      --ink-2: #BAC4D6;
      --ink-3: #8E9AB1;
      --ink-4: #66738C;

      --brand: #3A66F2;
      --brand-hover: #4B75F6;
      --brand-press: #2F57D9;
      --brand-ink: #93AEFF;
      --brand-soft: #172645;
      --brand-line: #2F4576;
      --on-brand: #FFFFFF;

      --inv: #F1F4FA;
      --inv-hover: #FFFFFF;
      --on-inv: #0A0F1A;

      --coin: #FFC738;
      --coin-deep: #FFD666;
      --coin-soft: #2A2614;
      --coin-line: #4A3F1B;

      --ok: #45D49A;      --ok-solid: #1FAF78;   --on-ok: #062016;   --ok-soft: #12302B;   --ok-line: #1E5446;
      --warn: #FFAE63;    --warn-solid: #F08A2A; --on-warn: #2B1700; --warn-soft: #2E2418; --warn-line: #5C3F1F;
      --bad: #FF8B8B;     --bad-solid: #D6383E;  --on-bad: #FFFFFF;  --bad-soft: #32202A;  --bad-line: #66303A;
      --ai: #B6A1FF;      --ai-solid: #B6A1FF;   --on-ai: #120B2E;   --ai-soft: #221F45;   --ai-line: #41397A;
      --muted-solid: #66738C; --on-muted: #FFFFFF;

      --mark: rgba(255, 199, 56, .26);
      --focus: #6E91FF;
      --focus-ring: 0 0 0 3px rgba(110, 145, 255, .42);
      --scrim: rgba(2, 5, 11, .70);

      --sh-1: inset 0 1px 0 rgba(255, 255, 255, .03), 0 1px 2px rgba(0, 0, 0, .45);
      --sh-2: inset 0 1px 0 rgba(255, 255, 255, .04), 0 14px 32px -12px rgba(0, 0, 0, .65);
      --sh-3: inset 0 1px 0 rgba(255, 255, 255, .05), 0 40px 96px -20px rgba(0, 0, 0, .8);
      --sh-deck: 0 1px 0 rgba(0, 0, 0, .4), 0 10px 30px -18px rgba(0, 0, 0, .8);
      --sh-btn: 0 1px 2px rgba(0, 0, 0, .4), inset 0 1px 0 rgba(255, 255, 255, .14);
      --sh-btn-commit: 0 6px 18px -8px rgba(0, 0, 0, .7), inset 0 1px 0 rgba(255, 255, 255, .5);
      --sh-tabbar: 0 -12px 30px -16px rgba(0, 0, 0, .8);
      --card-sheen: linear-gradient(180deg, rgba(255, 255, 255, .018), rgba(255, 255, 255, 0) 120px);

      --hero-a: #2A55E0; --hero-b: #11286E; --on-hero: #FFFFFF; --hero-sub: rgba(232, 238, 255, .9);
      --toast-bg: #1D2A43; --toast-ink: #EEF2F9; --toast-line: #2F4576;
      --kbd-bg: #1A263D;
      --skeleton-a: #172234; --skeleton-b: #1F2C44;
      --hatch: repeating-linear-gradient(135deg, #33435F 0 2px, transparent 2px 6px);

      --av-1-bg: #1B2B55; --av-1-ink: #A9BEFF;
      --av-2-bg: #123634; --av-2-ink: #7FDCD0;
      --av-3-bg: #3A2E12; --av-3-ink: #FFD27A;
      --av-4-bg: #3D1A27; --av-4-ink: #FF9CB8;
      --av-5-bg: #2A2150; --av-5-ink: #C4B2FF;
      --av-6-bg: #16341F; --av-6-ink: #8EE0A5;
      --av-7-bg: #12304A; --av-7-ink: #8ED3F7;
      --av-8-bg: #3B2414; --av-8-ink: #FFB585;

      --select-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238E9AB1' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
      --check-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23062016' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7.5'/%3E%3C/svg%3E");
    }
  }

  /* Tone aliases shared by every theme. */
  :root {
    --info: var(--brand-ink); --info-solid: var(--brand); --on-info: var(--on-brand); --info-soft: var(--brand-soft); --info-line: var(--brand-line);
  }
  @media (max-width: 1180px) { :root { --gutter: 24px; } }
  @media (max-width: 900px) { :root { --gutter: 16px; } }
}

/* -----------------------------------------------------------------------------
   3. Reset
   ----------------------------------------------------------------------------- */
@layer ui.reset {
  *, *::before, *::after { box-sizing: border-box; }
  html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
  body { margin: 0; }
  h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd, pre { margin: 0; }
  ul, ol { margin: 0; padding-inline-start: 1.4em; }
  img, video, canvas { max-width: 100%; height: auto; }
  img, video { display: block; }
  button, input, select, textarea { font: inherit; color: inherit; letter-spacing: inherit; }
  table { border-collapse: separate; border-spacing: 0; }
  fieldset { margin: 0; }
}

/* -----------------------------------------------------------------------------
   4. Base: document, typography, native elements
   ----------------------------------------------------------------------------- */
@layer ui.base {
  html { background: var(--bg); scrollbar-color: var(--line-strong) transparent; }
  body {
    min-height: 100dvh;
    font-family: var(--font-ui);
    font-size: var(--fs-15);
    line-height: var(--lh-body);
    color: var(--ink);
    background: var(--bg-wash), var(--bg);
    overflow-wrap: break-word;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    -webkit-tap-highlight-color: transparent;
  }
  @media (hover: hover) and (pointer: fine) { body { background-attachment: fixed, fixed; } }

  h1 { font-size: var(--fs-28); font-weight: 800; line-height: 1.3; letter-spacing: -.01em; }
  h2 { font-size: var(--fs-20); font-weight: 700; line-height: 1.35; }
  h3 { font-size: var(--fs-16); font-weight: 700; line-height: 1.4; }
  h4 { font-size: var(--fs-15); font-weight: 700; line-height: 1.45; }
  small { font-size: var(--fs-13); }
  strong, b { font-weight: 700; }
  a { color: var(--brand-ink); text-underline-offset: 3px; text-decoration-thickness: 1px; }
  a:hover { text-decoration-thickness: 2px; }
  code, kbd, samp { font-family: var(--font-mono); font-size: .92em; }
  code { padding: 1px 6px; border-radius: var(--r-sm); background: var(--surface-3); color: var(--ink); }
  pre {
    padding: var(--sp-3) var(--sp-4); overflow: auto; border: 1px solid var(--line-2); border-radius: var(--r-md);
    background: var(--surface-2); color: var(--ink-2); font-family: var(--font-mono); font-size: var(--fs-13); line-height: 1.65;
    white-space: pre-wrap; overflow-wrap: anywhere;
  }
  kbd {
    display: inline-grid; place-items: center; min-width: 24px; height: 22px; padding: 0 6px;
    border: 1px solid var(--line-strong); border-bottom-width: 2px; border-radius: var(--r-sm);
    background: var(--kbd-bg); color: var(--ink-2); font-family: var(--font-ui); font-size: var(--fs-12); font-weight: 700; line-height: 1;
  }
  hr { height: 1px; margin: var(--sp-5) 0; border: 0; background: var(--line); }
  mark {
    padding: 0 2px; color: inherit; font-weight: 700;
    background: linear-gradient(transparent 58%, var(--mark) 58%, var(--mark) 92%, transparent 92%);
  }
  ::selection { background: var(--brand-soft); color: var(--ink); }
  :focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
  ::-webkit-scrollbar { width: 10px; height: 10px; }
  ::-webkit-scrollbar-thumb { border: 2px solid transparent; border-radius: var(--r-round); background: var(--line-strong) padding-box; }
  ::-webkit-scrollbar-track { background: transparent; }

  /* Sprite icons without an explicit size render at 20px (svg defaults to 300×150). */
  :where(svg):has(> use[href^="#i-"]) { width: 20px; height: 20px; flex: none; }
  svg.icon { width: 20px; height: 20px; flex: none; }

  /* ----- Buttons: neutral by default; .primary / .commit / .danger / .warning / .ghost ----- */
  button {
    --btn-bg: var(--surface); --btn-ink: var(--ink); --btn-line: var(--line-strong);
    --btn-bg-hover: var(--surface-2); --btn-line-hover: var(--ink-4); --btn-shadow: none;
    display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
    min-width: 0; min-height: var(--h-md); padding: 0 var(--sp-4);
    border: 1px solid var(--btn-line); border-radius: var(--r-md);
    background: var(--btn-bg); color: var(--btn-ink); box-shadow: var(--btn-shadow);
    font-size: var(--fs-15); font-weight: 650; line-height: 1.3; text-align: center;
    overflow-wrap: anywhere; white-space: normal; cursor: pointer;
    transition: background-color var(--t-fast), border-color var(--t-fast), color var(--t-fast), box-shadow var(--t-fast), transform var(--t-fast);
  }
  button > svg { width: 18px; height: 18px; flex: none; }
  button:hover:not(:disabled) { background: var(--btn-bg-hover); border-color: var(--btn-line-hover); }
  button:active:not(:disabled) { transform: translateY(1px); }
  button:disabled { cursor: not-allowed; opacity: .5; box-shadow: none; }
  button[aria-busy="true"] { cursor: progress; }
  button.secondary { --btn-bg: var(--surface); --btn-ink: var(--ink); --btn-line: var(--line-strong); }
  button.primary {
    --btn-bg: var(--brand); --btn-ink: var(--on-brand); --btn-line: var(--brand);
    --btn-bg-hover: var(--brand-hover); --btn-line-hover: var(--brand-hover); --btn-shadow: var(--sh-btn);
  }
  button.primary:active:not(:disabled) { --btn-bg: var(--brand-press); }
  /* Money commit: ink (white in the dark theme), always with a lock icon and the amount in its label. */
  button.commit {
    --btn-bg: var(--inv); --btn-ink: var(--on-inv); --btn-line: var(--inv);
    --btn-bg-hover: var(--inv-hover); --btn-line-hover: var(--inv-hover); --btn-shadow: var(--sh-btn-commit);
  }
  button.danger {
    --btn-bg: var(--bad-solid); --btn-ink: var(--on-bad); --btn-line: var(--bad-solid);
    --btn-bg-hover: var(--bad); --btn-line-hover: var(--bad); --btn-shadow: var(--sh-btn);
  }
  :root[data-theme="dark"] button.danger { --btn-bg-hover: var(--bad-solid); }
  button.warning {
    --btn-bg: var(--warn-solid); --btn-ink: var(--on-warn); --btn-line: var(--warn-solid);
    --btn-bg-hover: var(--warn-solid); --btn-line-hover: var(--warn); --btn-shadow: var(--sh-btn);
  }
  button.ghost {
    --btn-bg: transparent; --btn-ink: var(--brand-ink); --btn-line: transparent;
    --btn-bg-hover: var(--brand-soft); --btn-line-hover: transparent;
  }
  button.small { min-height: var(--h-sm); padding: 0 var(--sp-3); font-size: var(--fs-14); }
  button.large { min-height: var(--h-lg); padding: 0 22px; font-size: var(--fs-16); border-radius: 10px; }
  button.active:not(.primary):not(.commit):not(.danger):not(.warning) {
    --btn-bg: var(--brand-soft); --btn-ink: var(--brand-ink); --btn-line: var(--brand-line);
    --btn-bg-hover: var(--brand-soft); --btn-line-hover: var(--brand);
  }

  /* ----- Text fields ----- */
  /* :where() keeps these at zero specificity so the state rules below (hover → focus → disabled → read-only →
     invalid) win in source order, and any class in a later layer or sheet can restyle a field. */
  :where(input:not([type="checkbox"], [type="radio"], [type="range"], [type="file"], [type="color"], [type="hidden"]), select, textarea) {
    width: 100%; min-width: 0; min-height: 44px; padding: 10px 12px;
    border: 1px solid var(--line-strong); border-radius: var(--r-md);
    background: var(--field); color: var(--ink);
    font-size: var(--fs-16); font-weight: 400; line-height: 1.4;
    transition: border-color var(--t-fast), box-shadow var(--t-fast), background-color var(--t-fast);
  }
  input::placeholder, textarea::placeholder { color: var(--ink-3); opacity: 1; }
  :where(input:not([type="checkbox"], [type="radio"]), select, textarea):hover { border-color: var(--ink-4); }
  :where(input:not([type="checkbox"], [type="radio"]), select, textarea):focus { border-color: var(--brand); box-shadow: var(--focus-ring); outline: none; }
  :where(input, select, textarea):disabled { cursor: not-allowed; background-color: var(--surface-3); color: var(--ink-3); }
  :where(input, textarea)[readonly] { background-color: var(--surface-2); }
  :where(input, select, textarea)[aria-invalid="true"] { border-color: var(--bad-solid); }
  :where(input, select, textarea)[aria-invalid="true"]:focus { box-shadow: 0 0 0 3px var(--bad-soft); }
  select {
    appearance: none; padding-right: 38px; cursor: pointer;
    background-image: var(--select-arrow); background-repeat: no-repeat; background-position: right 10px center; background-size: 18px;
  }
  textarea { min-height: 96px; resize: vertical; line-height: var(--lh-long); }
  input[type="checkbox"], input[type="radio"] { width: 18px; height: 18px; margin: 0; flex: none; accent-color: var(--brand); cursor: pointer; }
  input[type="range"] { width: 100%; accent-color: var(--brand); }
  input[type="file"] { max-width: 100%; color: var(--ink-2); font-size: var(--fs-14); }
  input[type="file"]::file-selector-button {
    min-height: var(--h-md); margin-right: var(--sp-3); padding: 0 var(--sp-4);
    border: 1px solid var(--line-strong); border-radius: var(--r-md); background: var(--surface); color: var(--ink);
    font: inherit; font-weight: 650; cursor: pointer;
  }

  /* A label wraps its control: label text above, field below. Checkbox/radio labels sit in one row. */
  label { display: grid; gap: 6px; min-width: 0; color: var(--ink-2); font-size: var(--fs-14); font-weight: 600; line-height: 1.45; }
  label:has(> input:is([type="checkbox"], [type="radio"])) { display: flex; align-items: center; gap: 10px; cursor: pointer; }
  label.disabled, label:has(> input:disabled) { cursor: not-allowed; opacity: .6; }
  fieldset { min-width: 0; padding: var(--sp-4); border: 1px solid var(--line); border-radius: var(--r-lg); }
  legend { padding: 0 6px; color: var(--ink); font-size: var(--fs-14); font-weight: 700; }

  /* ----- Tables: header row always has a background ----- */
  table { width: 100%; font-variant-numeric: tabular-nums; }
  th {
    padding: 11px 14px; text-align: left; white-space: nowrap; vertical-align: middle;
    border-bottom: 1px solid var(--line); background: var(--surface-2); color: var(--ink-2);
    font-size: var(--fs-13); font-weight: 700; line-height: 1.4;
  }
  td { padding: 12px 14px; border-bottom: 1px solid var(--line-2); vertical-align: middle; font-size: var(--fs-15); line-height: 1.5; }
  tbody tr:last-child td { border-bottom: 0; }
  @media (hover: hover) { tbody tr:hover td { background: var(--row-hover); } }
  caption { padding: 0 0 var(--sp-2); color: var(--ink-3); font-size: var(--fs-13); text-align: left; }

  /* ----- Disclosure ----- */
  summary { display: flex; align-items: center; gap: var(--sp-2); min-height: 40px; border-radius: var(--r-md); color: var(--brand-ink); font-weight: 650; cursor: pointer; list-style: none; }
  summary::-webkit-details-marker { display: none; }
  summary::before {
    content: ""; width: 8px; height: 8px; flex: none; margin: 0 4px 0 2px;
    border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
    transform: rotate(-45deg); transition: transform var(--t-mid) var(--ease);
  }
  details[open] > summary::before { transform: rotate(45deg); }

  /* ----- Progress ----- */
  progress { width: 100%; height: 8px; border: 0; border-radius: var(--r-round); overflow: hidden; background: var(--surface-3); appearance: none; }
  progress::-webkit-progress-bar { background: var(--surface-3); }
  progress::-webkit-progress-value { border-radius: var(--r-round); background: var(--brand); }
  progress::-moz-progress-bar { border-radius: var(--r-round); background: var(--brand); }

  /* ----- Dialog element (frame details for #modal live in shell.css) ----- */
  dialog { max-width: calc(100vw - 32px); padding: 0; border: 1px solid var(--line); border-radius: var(--r-xl); color: var(--ink); background: var(--surface); box-shadow: var(--sh-3); }
  dialog::backdrop { background: var(--scrim); }
}

/* -----------------------------------------------------------------------------
   5. Components. Legacy shared names first, then ui-* components.
   ----------------------------------------------------------------------------- */
@layer ui.components {
  /* ----- Text roles ----- */
  .muted { color: var(--ink-3); }
  .eyebrow { margin: 0 0 4px; color: var(--brand-ink); font-size: var(--fs-13); font-weight: 700; letter-spacing: .02em; line-height: 1.4; }
  .error-text { min-height: 1.4em; margin: 0; color: var(--bad); font-size: var(--fs-14); font-weight: 600; line-height: 1.6; white-space: pre-line; overflow-wrap: anywhere; }
  .error-text:empty { min-height: 0; }
  .account-backup-status { color: var(--ink-3); font-size: var(--fs-13); line-height: 1.6; }

  /* ----- Card ----- */
  .panel {
    --panel-pad: var(--sp-5);
    min-width: 0; padding: var(--panel-pad);
    border: 1px solid var(--line); border-radius: var(--r-lg);
    background: var(--card-sheen), var(--surface); box-shadow: var(--sh-1);
  }
  .panel > * + * { margin-top: var(--sp-4); }
  .panel h2 { font-size: 17px; }
  .panel h3 { font-size: var(--fs-15); }
  .panel-header { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-2) var(--sp-4); min-width: 0; }
  .panel-header > * { min-width: 0; }
  .panel-header > div:first-child { display: grid; gap: 2px; }
  .panel-header h2, .panel-header h3 { margin: 0; line-height: 1.35; }
  .panel-header .muted, .panel-header p { font-size: var(--fs-13); line-height: 1.5; }
  .panel-header > :is(button, .actions, .status):last-child { flex: none; }

  /* ----- Page head「狀態與下一步」 (.view-intro is the legacy alias) ----- */
  .ui-page-head, .view-intro {
    display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between;
    gap: var(--sp-4) var(--sp-6); min-width: 0; margin-bottom: var(--sp-5);
  }
  .ui-page-head-main, .view-intro > div:first-child { display: grid; gap: 6px; flex: 1 1 520px; min-width: min(100%, 320px); }
  .ui-page-head h2, .view-intro h2 { color: var(--ink); font-size: var(--fs-28); font-weight: 800; line-height: 1.3; letter-spacing: -.01em; }
  .ui-page-head p:not(.eyebrow), .view-intro p:not(.eyebrow) { max-width: 820px; color: var(--ink-2); font-size: var(--fs-16); line-height: var(--lh-long); }
  .ui-page-head p strong, .view-intro p strong { color: var(--ink); }
  .ui-page-head-actions { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
  .ui-page-head-stats, .view-intro-stats {
    display: grid; grid-auto-flow: column; grid-auto-columns: minmax(96px, 1fr); flex: none;
    overflow: hidden; border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface); box-shadow: var(--sh-1);
  }
  .view-intro-stats.three { grid-template-columns: repeat(3, minmax(96px, 1fr)); grid-auto-flow: row; }
  .ui-page-head-stats > div, .view-intro-stats > div { min-width: 0; padding: 10px 16px; }
  .ui-page-head-stats > div + div, .view-intro-stats > div + div { border-left: 1px solid var(--line-2); }
  .ui-page-head-stats strong, .view-intro-stats strong {
    display: block; color: var(--ink); font-family: var(--font-num); font-size: var(--fs-24); font-weight: 700;
    font-variant-numeric: tabular-nums; line-height: 1.2; letter-spacing: -.01em;
  }
  .ui-page-head-stats span, .view-intro-stats span { display: block; margin-top: 2px; color: var(--ink-3); font-size: var(--fs-13); font-weight: 600; }
  .view-intro-stats .attention strong { color: var(--warn); }

  /* ----- Sections inside a page or dialog ----- */
  .ui-section { display: grid; gap: var(--sp-3); min-width: 0; }
  .ui-section-head, .qr-section-heading { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--sp-2) var(--sp-3); min-width: 0; }
  .ui-section-head h3, .qr-section-heading h3 { color: var(--ink); font-size: var(--fs-16); }
  .ui-section-head p, .qr-section-heading p { margin-top: 2px; color: var(--ink-3); font-size: var(--fs-14); line-height: 1.6; }
  .qr-section-heading > span { flex: none; }
  .notification-detail-section { min-width: 0; padding: var(--sp-4); border: 1px solid var(--line-2); border-radius: var(--r-lg); background: var(--surface-2); }
  .notification-detail-section > * + * { margin-top: var(--sp-2); }
  .notification-detail-section h3 { font-size: var(--fs-15); }
  .notification-raw { margin-top: var(--sp-3); padding-top: var(--sp-2); border-top: 1px solid var(--line-2); }
  .notification-raw > summary { font-size: var(--fs-14); }
  .notification-raw[open] > summary { margin-bottom: var(--sp-2); }

  /* ----- KPI number tiles ----- */
  .ui-kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: var(--sp-4); min-width: 0; }
  .ui-kpi {
    --tone-ink: var(--ink-2); --tone-soft: var(--surface-3); --tone-value: var(--ink);
    display: flex; align-items: flex-start; gap: var(--sp-3); min-width: 0; padding: var(--sp-4) var(--sp-5);
    border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--card-sheen), var(--surface); box-shadow: var(--sh-1);
  }
  .ui-kpi-icon { display: grid; place-items: center; flex: none; width: 40px; height: 40px; border-radius: 11px; color: var(--tone-ink); background: var(--tone-soft); }
  .ui-kpi-icon > svg { width: 22px; height: 22px; }
  .ui-kpi-body { display: grid; gap: 2px; min-width: 0; }
  .ui-kpi-label { color: var(--ink-3); font-size: var(--fs-13); font-weight: 650; }
  .ui-kpi-value {
    display: flex; align-items: baseline; gap: 4px; color: var(--tone-value);
    font-family: var(--font-num); font-size: var(--fs-32); font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1.12; letter-spacing: -.02em;
  }
  .ui-kpi-value small { color: var(--ink-2); font-family: var(--font-ui); font-size: var(--fs-14); font-weight: 650; letter-spacing: 0; }
  .ui-kpi-sub { color: var(--ink-2); font-size: var(--fs-13); line-height: 1.5; }
  button.ui-kpi { justify-content: flex-start; text-align: left; font-weight: inherit; min-height: 0; }

  /* ----- Facts grid (.merchant-detail-facts is the legacy alias) ----- */
  /* Hairlines come from each cell (right + bottom); the frame clips the outer ones, so an empty last cell blends in. */
  .ui-facts, .merchant-detail-facts {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 0; min-width: 0;
    overflow: hidden; border: 1px solid var(--line-2); border-radius: var(--r-lg); background: var(--surface-2);
  }
  .ui-facts > div, .merchant-detail-facts > div { min-width: 0; padding: 12px 14px; box-shadow: 1px 0 0 var(--line-2), 0 1px 0 var(--line-2); }
  .ui-facts dt, .ui-facts span, .merchant-detail-facts span { display: block; color: var(--ink-3); font-size: var(--fs-13); font-weight: 600; }
  .ui-facts dd, .ui-facts strong, .merchant-detail-facts strong {
    display: block; margin: 3px 0 0; color: var(--ink); font-size: var(--fs-15); font-weight: 700; line-height: 1.5; white-space: pre-line; overflow-wrap: anywhere;
  }

  /* ----- Meta chips, links ----- */
  .event-meta { display: flex; flex-wrap: wrap; gap: 6px; color: var(--ink-2); font-size: var(--fs-13); }
  .event-meta > span { padding: 2px 8px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--surface-3); line-height: 1.5; }
  .external-links { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
  .external-links a, .official-link {
    display: inline-flex; align-items: center; gap: 6px; min-height: var(--h-md); padding: 0 var(--sp-3);
    border: 1px solid var(--brand-line); border-radius: var(--r-md); background: var(--brand-soft); color: var(--brand-ink);
    font-size: var(--fs-14); font-weight: 650; text-decoration: none; overflow-wrap: anywhere;
  }
  .external-links a::after, .official-link::after { content: "↗"; font-weight: 700; }
  .external-links a:hover, .official-link:hover { border-color: var(--brand); text-decoration: none; }

  /* ----- Pre-formatted text (.pre-wrap on prose keeps the UI font) ----- */
  .pre-wrap { white-space: pre-wrap; overflow-wrap: anywhere; line-height: var(--lh-long); }
  pre.pre-wrap { max-height: 360px; }
  .modal-loading {
    display: flex; align-items: center; justify-content: center; gap: var(--sp-3); min-height: 160px; padding: var(--sp-7) var(--sp-4);
    color: var(--ink-3); font-size: var(--fs-15); text-align: center;
  }
  .modal-loading::before { content: ""; width: 22px; height: 22px; flex: none; border: 3px solid var(--line); border-top-color: var(--brand); border-radius: 50%; animation: ui-spin .8s linear infinite; }
  .loading { cursor: progress; }

  /* ----- Spinner (.auto-transfer-spinner is the legacy alias) ----- */
  .ui-spinner, .auto-transfer-spinner {
    display: inline-block; width: 26px; height: 26px; flex: none;
    border: 3px solid var(--line); border-top-color: var(--brand); border-radius: 50%; animation: ui-spin .8s linear infinite;
  }

  /* ----- Empty / error / loading states (.merchant-empty and .view-state are legacy aliases) ----- */
  .ui-state, .merchant-empty, .view-state {
    --tone-ink: var(--brand-ink); --tone-soft: var(--brand-soft);
    display: grid; justify-items: center; align-content: center; gap: var(--sp-2); min-width: 0; min-height: 220px;
    padding: var(--sp-7) var(--sp-5); color: var(--ink-3); text-align: center;
  }
  .view-state { grid-column: 1 / -1; border: 1px dashed var(--line-strong); border-radius: var(--r-lg); background: var(--surface-2); }
  .view-state.loading-state, .loading-state { border-style: solid; background: var(--card-sheen), var(--surface); min-height: 260px; }
  .ui-state.compact, .view-state.compact { min-height: 150px; padding-block: var(--sp-5); }
  .ui-state-icon, .merchant-empty-icon, .view-state > span:first-child:not(.auto-transfer-spinner):not(.ui-spinner) {
    display: grid; place-items: center; width: 56px; height: 56px; margin-bottom: var(--sp-1);
    border-radius: 16px; color: var(--tone-ink); background: var(--tone-soft); font-size: 22px; font-weight: 800; line-height: 1;
  }
  .ui-state-icon > svg { width: 26px; height: 26px; }
  .error-state { --tone-ink: var(--bad); --tone-soft: var(--bad-soft); }
  :is(.ui-state, .merchant-empty, .view-state) > * { margin: 0; }
  :is(.ui-state, .merchant-empty, .view-state) :is(h2, h3) { color: var(--ink); font-size: var(--fs-16); }
  :is(.ui-state, .merchant-empty, .view-state) p { max-width: 480px; color: var(--ink-3); font-size: var(--fs-14); line-height: var(--lh-long); }
  :is(.ui-state, .merchant-empty, .view-state) > :is(button, .actions) { margin-top: var(--sp-2); }

  /* Skeleton placeholders for loading content. */
  .ui-skeleton {
    display: block; height: 14px; border-radius: var(--r-sm);
    background: linear-gradient(90deg, var(--skeleton-a) 0%, var(--skeleton-b) 50%, var(--skeleton-a) 100%); background-size: 220% 100%;
    animation: ui-shimmer 1.4s linear infinite;
  }
  .ui-skeleton.is-title { height: 22px; width: 46%; }
  .ui-skeleton.is-block { height: 88px; border-radius: var(--r-lg); }

  /* ----- Notice / callout (.alert-refresh-warning is a warn-toned legacy alias) ----- */
  .ui-notice, .alert-refresh-warning {
    --tone-ink: var(--brand-ink); --tone-soft: var(--brand-soft); --tone-line: var(--brand-line);
    display: flex; align-items: flex-start; gap: var(--sp-3); min-width: 0; padding: 12px 16px;
    border: 1px solid var(--tone-line); border-radius: var(--r-lg); background: var(--tone-soft);
    color: var(--ink-2); font-size: var(--fs-15); line-height: var(--lh-long); overflow-wrap: anywhere;
  }
  .alert-refresh-warning { --tone-ink: var(--warn); --tone-soft: var(--warn-soft); --tone-line: var(--warn-line); font-weight: 600; }
  .ui-notice > svg:first-child { width: 20px; height: 20px; margin-top: 3px; color: var(--tone-ink); }
  .ui-notice > div { flex: 1; min-width: 0; }
  .ui-notice strong { color: var(--ink); }
  .ui-notice > button { flex: none; margin-left: auto; }

  /* ----- Status pill (status() output) and tag / badge ----- */
  .status {
    --tone-ink: var(--ink-2); --tone-soft: var(--surface-3); --tone-line: var(--line);
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
    max-width: 100%; min-height: 24px; padding: 2px 9px; vertical-align: middle;
    border: 1px solid var(--tone-line); border-radius: var(--r-sm); background: var(--tone-soft); color: var(--tone-ink);
    font-size: var(--fs-13); font-weight: 700; line-height: 1.35; text-align: center; white-space: normal; overflow-wrap: anywhere;
  }
  .status::before { content: ""; width: 7px; height: 7px; flex: none; border-radius: 50%; background: currentColor; }
  .status:is(.running, .dispatching, .preparing)::before { animation: ui-live 1.8s ease-out infinite; }
  .ui-tag {
    --tone-ink: var(--ink-2); --tone-soft: var(--surface-3); --tone-line: var(--line); --tone-solid: var(--muted-solid); --tone-on: var(--on-muted);
    display: inline-flex; align-items: center; gap: 6px; max-width: 100%; min-height: 24px; padding: 2px 8px; vertical-align: middle;
    border: 1px solid var(--tone-line); border-radius: var(--r-sm); background: var(--tone-soft); color: var(--tone-ink);
    font-size: var(--fs-13); font-weight: 700; line-height: 1.35; white-space: nowrap;
  }
  .ui-tag > svg { width: 15px; height: 15px; }
  .ui-tag.is-solid { border-color: var(--tone-solid); background: var(--tone-solid); color: var(--tone-on); }
  .ui-badge {
    --tone-solid: var(--bad-solid); --tone-on: var(--on-bad);
    display: inline-grid; place-items: center; min-width: 20px; height: 20px; padding: 0 6px;
    border-radius: var(--r-round); background: var(--tone-solid); color: var(--tone-on);
    font-family: var(--font-num); font-size: var(--fs-12); font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums;
  }

  /* ----- Name-initial avatar (accountAvatarMarkup) ----- */
  .ui-avatar {
    --av-bg: var(--av-1-bg); --av-ink: var(--av-1-ink);
    position: relative; display: inline-grid; place-items: center; flex: none; width: 36px; height: 36px;
    border-radius: 10px; background: var(--av-bg); color: var(--av-ink);
    font-family: var(--font-num); font-size: var(--fs-15); font-weight: 800; line-height: 1; letter-spacing: -.01em;
    font-variant-numeric: tabular-nums; user-select: none;
  }
  .ui-avatar[data-tint="2"] { --av-bg: var(--av-2-bg); --av-ink: var(--av-2-ink); }
  .ui-avatar[data-tint="3"] { --av-bg: var(--av-3-bg); --av-ink: var(--av-3-ink); }
  .ui-avatar[data-tint="4"] { --av-bg: var(--av-4-bg); --av-ink: var(--av-4-ink); }
  .ui-avatar[data-tint="5"] { --av-bg: var(--av-5-bg); --av-ink: var(--av-5-ink); }
  .ui-avatar[data-tint="6"] { --av-bg: var(--av-6-bg); --av-ink: var(--av-6-ink); }
  .ui-avatar[data-tint="7"] { --av-bg: var(--av-7-bg); --av-ink: var(--av-7-ink); }
  .ui-avatar[data-tint="8"] { --av-bg: var(--av-8-bg); --av-ink: var(--av-8-ink); }
  .ui-avatar.is-sm { width: 28px; height: 28px; border-radius: 8px; font-size: var(--fs-13); }
  .ui-avatar.is-lg { width: 48px; height: 48px; border-radius: 13px; font-size: var(--fs-18); }
  .ui-avatar[data-state]::after {
    content: ""; position: absolute; right: -3px; bottom: -3px; width: 12px; height: 12px;
    border: 2px solid var(--surface); border-radius: 50%; background: var(--tone-solid, var(--ok-solid));
  }

  /* ----- Filters: toolbar row, chips, segmented control ----- */
  .ui-filters, .toolbar {
    display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--sp-3); min-width: 0; margin-bottom: var(--sp-4); padding: var(--sp-3);
    border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface); box-shadow: var(--sh-1);
  }
  .ui-filters > label, .toolbar > label { flex: 1 1 200px; }
  .ui-filters > label:has(> input[type="checkbox"]), .toolbar > label:has(> input[type="checkbox"]) { flex: 0 1 auto; min-height: 44px; }
  .ui-chips, .account-picker-tag-filter { display: flex; flex-wrap: wrap; gap: var(--sp-2); min-width: 0; }
  .ui-chip, .account-picker-tag-filter > button {
    --btn-bg: var(--surface); --btn-ink: var(--ink-2); --btn-line: var(--line-strong); --btn-bg-hover: var(--surface-2);
    gap: 7px; min-height: var(--h-sm); padding: 0 var(--sp-3); font-size: var(--fs-14); font-weight: 600; white-space: nowrap;
  }
  .ui-chip b, .account-picker-tag-filter > button b { color: var(--ink-3); font-family: var(--font-num); font-size: var(--fs-12); font-weight: 800; }
  .ui-chip:is([aria-pressed="true"], .active), .account-picker-tag-filter > button:is([aria-pressed="true"], .active) {
    --btn-bg: var(--brand-soft); --btn-ink: var(--brand-ink); --btn-line: var(--brand); --btn-bg-hover: var(--brand-soft);
  }
  .ui-chip:is([aria-pressed="true"], .active) b, .account-picker-tag-filter > button:is([aria-pressed="true"], .active) b { color: var(--brand-ink); }
  .ui-segmented {
    display: inline-flex; flex-wrap: wrap; gap: 2px; max-width: 100%; padding: 3px;
    border: 1px solid var(--line); border-radius: 10px; background: var(--surface-3);
  }
  .ui-segmented > :is(button, a) {
    --btn-bg: transparent; --btn-ink: var(--ink-2); --btn-line: transparent; --btn-bg-hover: var(--hover-veil); --btn-line-hover: transparent;
    min-height: var(--h-sm); padding: 0 14px; border-radius: var(--r-md); font-size: var(--fs-14); font-weight: 650; text-decoration: none; white-space: nowrap;
  }
  .ui-segmented > :is(button, a):is([aria-pressed="true"], [aria-selected="true"], [aria-current="page"], .active) {
    --btn-bg: var(--raise); --btn-ink: var(--ink); --btn-bg-hover: var(--raise);
    box-shadow: var(--sh-1), 0 0 0 1px var(--line);
  }

  /* ----- Pagination (.merchant-pagination is the legacy alias) ----- */
  .ui-pagination, .merchant-pagination {
    display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-2) var(--sp-3);
    margin-top: var(--sp-4); padding-top: var(--sp-3); border-top: 1px solid var(--line-2);
  }
  .ui-pagination > span, .merchant-pagination > span { color: var(--ink-3); font-size: var(--fs-13); font-weight: 600; text-align: center; }

  /* ----- Lists: rows with avatar/icon, main text, meta and one action ----- */
  .ui-list { display: grid; margin: 0; padding: 0; list-style: none; }
  .ui-row {
    --tone-ink: var(--ink-3); --tone-soft: var(--surface-3); --tone-solid: transparent;
    position: relative; display: flex; align-items: center; gap: var(--sp-3); min-width: 0; padding: 12px 0;
    border-bottom: 1px solid var(--line-2); color: inherit; text-align: left;
  }
  .ui-row:last-child { border-bottom: 0; }
  button.ui-row, a.ui-row {
    width: 100%; min-height: 0; padding: 12px var(--sp-3); border: 0; border-bottom: 1px solid var(--line-2); border-radius: 0;
    background: transparent; font-weight: inherit; text-decoration: none; justify-content: flex-start;
  }
  button.ui-row:hover, a.ui-row:hover { background: var(--row-hover); }
  .ui-row-icon { display: grid; place-items: center; flex: none; width: 36px; height: 36px; border-radius: 10px; color: var(--tone-ink); background: var(--tone-soft); }
  .ui-row-main { display: grid; gap: 2px; flex: 1; min-width: 0; }
  .ui-row-main strong { color: var(--ink); font-size: var(--fs-15); font-weight: 700; line-height: 1.45; }
  .ui-row-main small, .ui-row-main p { color: var(--ink-3); font-size: var(--fs-13); line-height: 1.6; }
  .ui-row-meta { display: grid; justify-items: end; gap: 2px; flex: none; text-align: right; }
  .ui-row-meta b { color: var(--ink); font-family: var(--font-num); font-size: var(--fs-16); font-variant-numeric: tabular-nums; }
  .ui-row-meta small { color: var(--ink-3); font-size: var(--fs-12); }
  .ui-row-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--sp-2); flex: none; }
  /* 「先處理這 N 件事」: a ui-list of full sentences, each with its consequence and one clear action. */
  .ui-todo > .ui-row { align-items: flex-start; padding-left: var(--sp-4); }
  .ui-todo > .ui-row::before { content: ""; position: absolute; left: 0; top: 14px; bottom: 14px; width: 3px; border-radius: 2px; background: var(--tone-solid); }
  .ui-todo .ui-row-main p { color: var(--ink-2); font-size: var(--fs-14); }

  /* ----- Steps: 選擇 → 預覽 → 輸入交易 PIN → 完成 ----- */
  .ui-steps { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); margin: 0; padding: 0; list-style: none; counter-reset: ui-step; }
  .ui-steps > li {
    display: flex; align-items: center; gap: var(--sp-2); min-width: 0; color: var(--ink-3);
    font-size: var(--fs-14); font-weight: 700; white-space: nowrap; counter-increment: ui-step;
  }
  .ui-steps > li + li::before { content: ""; width: 28px; height: 2px; flex: none; border-radius: 1px; background: var(--line); }
  .ui-steps > li > b {
    display: grid; place-items: center; width: 26px; height: 26px; flex: none; border: 2px solid var(--line-strong); border-radius: 50%;
    color: var(--ink-3); background: var(--surface); font-family: var(--font-num); font-size: var(--fs-13); font-weight: 800;
  }
  .ui-steps > li > b:empty::before { content: counter(ui-step); }
  .ui-steps > li:is([data-state="current"], [aria-current="step"]) { color: var(--ink); }
  .ui-steps > li:is([data-state="current"], [aria-current="step"]) > b { border-color: var(--brand); color: var(--on-brand); background: var(--brand); box-shadow: 0 0 0 4px var(--brand-soft); }
  .ui-steps > li[data-state="done"] { color: var(--ink-2); }
  .ui-steps > li[data-state="done"]::before { background: var(--ok-solid); }
  .ui-steps > li[data-state="done"] > b { border-color: var(--ok-solid); color: transparent; background: var(--ok-solid) var(--check-glyph) center / 14px no-repeat; }
  .ui-steps > li[data-state="done"] > b::before { content: ""; }

  /* ----- Money flow summary: 從 → 金額 → 給 ----- */
  .ui-flow {
    display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; gap: var(--sp-3);
    padding: var(--sp-4) var(--sp-5); border: 1px solid var(--line-2); border-radius: 14px; background: var(--surface-2);
  }
  .ui-flow-side { display: grid; gap: 2px; min-width: 0; }
  .ui-flow-side.is-to { text-align: right; justify-items: end; }
  .ui-flow-side small { color: var(--ink-3); font-size: var(--fs-13); font-weight: 650; }
  .ui-flow-side strong { color: var(--ink); font-size: var(--fs-16); }
  .ui-flow-side span { color: var(--ink-3); font-size: var(--fs-13); }
  .ui-flow-mid { display: grid; justify-items: center; gap: 6px; min-width: 120px; }
  .ui-flow-mid strong { color: var(--ink); font-family: var(--font-num); font-size: var(--fs-24); font-weight: 800; font-variant-numeric: tabular-nums; white-space: nowrap; }
  .ui-flow-mid i { position: relative; display: block; width: 100%; height: 2px; border-radius: 1px; background: var(--line-strong); }
  .ui-flow-mid i::after { content: ""; position: absolute; right: -1px; top: -4px; width: 10px; height: 10px; border-top: 2px solid var(--line-strong); border-right: 2px solid var(--line-strong); transform: rotate(45deg); }

  /* ----- Code inputs: confirmation code, transaction PIN, OTP ----- */
  input.ui-code {
    max-width: 360px; font-family: var(--font-num); font-size: var(--fs-24); font-weight: 700; letter-spacing: .32em;
    text-align: center; font-variant-numeric: tabular-nums;
  }

  /* ----- Fields with an icon and a trailing button (password reveal) ----- */
  .field-shell { position: relative; display: flex; align-items: center; min-width: 0; }
  .field-shell > input { flex: 1; }
  .field-shell > .field-icon { position: absolute; left: 12px; width: 18px; height: 18px; color: var(--ink-3); pointer-events: none; }
  .field-shell > .field-icon ~ input { padding-left: 40px; }
  .field-shell > .field-reveal {
    --btn-bg: transparent; --btn-line: transparent; --btn-ink: var(--ink-3); --btn-bg-hover: var(--hover-veil); --btn-line-hover: transparent;
    position: absolute; right: 4px; min-width: 38px; min-height: 38px; padding: 0 8px;
  }
  .field-shell > .field-reveal ~ input, .field-shell > input:has(~ .field-reveal) { padding-right: 48px; }
  .ui-field-hint { color: var(--ink-3); font-size: var(--fs-13); font-weight: 400; line-height: 1.6; }

  /* ----- Toggle switch ----- */
  .ui-switch { position: relative; display: inline-flex; align-items: center; gap: var(--sp-3); min-height: 44px; cursor: pointer; }
  .ui-switch > input { position: absolute; width: 1px; height: 1px; opacity: 0; }
  .ui-switch-track { position: relative; width: 44px; height: 26px; flex: none; border-radius: 13px; background: var(--line-strong); transition: background-color var(--t-mid) var(--ease); }
  .ui-switch-track::after { content: ""; position: absolute; top: 3px; left: 3px; width: 20px; height: 20px; border-radius: 50%; background: var(--surface); box-shadow: var(--sh-1); transition: transform var(--t-mid) var(--ease-spring); }
  .ui-switch > input:checked + .ui-switch-track { background: var(--brand); }
  .ui-switch > input:checked + .ui-switch-track::after { transform: translateX(18px); }
  .ui-switch > input:focus-visible + .ui-switch-track { outline: 2px solid var(--focus); outline-offset: 2px; }
  .ui-switch > input:disabled + .ui-switch-track { opacity: .5; }

  /* ----- Meter / countdown ----- */
  .ui-meter { --tone-solid: var(--brand); display: block; height: 6px; overflow: hidden; border-radius: var(--r-round); background: var(--surface-3); }
  .ui-meter > i { display: block; height: 100%; border-radius: inherit; background: var(--tone-solid); }
  .ui-countdown { color: var(--brand-ink); font-family: var(--font-num); font-size: var(--fs-40); font-weight: 700; line-height: 1.05; letter-spacing: -.02em; font-variant-numeric: tabular-nums; white-space: nowrap; }

  /* ----- Pre-start checklist (開場前檢查) and the account squares (帳號方格) ----- */
  .ui-checklist { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: var(--sp-2); margin: 0; padding: 0; list-style: none; }
  .ui-checklist > li {
    --tone-ink: var(--ok); --tone-soft: var(--ok-soft); --tone-line: var(--ok-line);
    display: flex; align-items: center; gap: 10px; min-width: 0; padding: 10px 12px;
    border: 1px solid var(--line); border-radius: var(--r-md); background: var(--surface);
  }
  .ui-checklist > li[data-state="warn"] { --tone-ink: var(--warn); --tone-soft: var(--warn-soft); --tone-line: var(--warn-line); }
  .ui-checklist > li[data-state="bad"] { --tone-ink: var(--bad); --tone-soft: var(--bad-soft); --tone-line: var(--bad-line); border-color: var(--bad-line); background: var(--bad-soft); }
  .ui-checklist > li[data-state="wait"] { --tone-ink: var(--ink-3); --tone-soft: var(--surface-3); --tone-line: var(--line); }
  .ui-checklist-icon { display: grid; place-items: center; width: 28px; height: 28px; flex: none; border-radius: var(--r-sm); color: var(--tone-ink); background: var(--tone-soft); }
  .ui-checklist-icon > svg { width: 17px; height: 17px; }
  .ui-checklist small { display: block; color: var(--ink-3); font-size: var(--fs-12); font-weight: 650; }
  .ui-checklist strong { display: block; color: var(--ink); font-size: var(--fs-14); line-height: 1.4; }
  .ui-account-grid { display: flex; flex-wrap: wrap; gap: 5px; margin: 0; padding: 0; list-style: none; }
  .ui-account-cell {
    --cell: var(--brand); --cell-ink: var(--on-brand);
    display: grid; place-items: center; width: 22px; height: 22px; border-radius: 5px;
    background: var(--cell); color: var(--cell-ink); font-family: var(--font-num); font-size: var(--fs-12); font-weight: 800; line-height: 1;
  }
  .ui-account-grid.is-labelled .ui-account-cell { width: auto; min-width: 44px; height: 36px; padding: 0 6px; border-radius: var(--r-sm); }
  .ui-account-cell[data-state="ready"] { --cell: var(--brand); --cell-ink: var(--on-brand); }
  .ui-account-cell[data-state="sent"] { --cell: var(--brand-soft); --cell-ink: var(--brand-ink); box-shadow: inset 0 0 0 2px var(--brand); }
  .ui-account-cell[data-state="ok"] { --cell: var(--ok-solid); --cell-ink: var(--on-ok); }
  .ui-account-cell[data-state="warn"] { --cell: var(--warn-solid); --cell-ink: var(--on-warn); }
  .ui-account-cell[data-state="bad"] { --cell: var(--bad-solid); --cell-ink: var(--on-bad); }
  .ui-account-cell[data-state="wait"] { --cell: var(--surface-3); --cell-ink: var(--ink-3); box-shadow: inset 0 0 0 1px var(--line); }
  .ui-account-cell[data-state="off"] { --cell: var(--surface); --cell-ink: var(--ink-3); background: var(--hatch), var(--surface); box-shadow: inset 0 0 0 1px var(--line-strong); }
  .ui-legend { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4); margin: 0; padding: 0; list-style: none; color: var(--ink-2); font-size: var(--fs-13); font-weight: 600; }
  .ui-legend > li { display: inline-flex; align-items: center; gap: 6px; }
  .ui-legend > li::before { content: ""; width: 10px; height: 10px; border-radius: 3px; background: var(--brand); }
  .ui-legend > li[data-state="sent"]::before { background: var(--brand-soft); box-shadow: inset 0 0 0 2px var(--brand); }
  .ui-legend > li[data-state="ok"]::before { background: var(--ok-solid); }
  .ui-legend > li[data-state="warn"]::before { background: var(--warn-solid); }
  .ui-legend > li[data-state="bad"]::before { background: var(--bad-solid); }
  .ui-legend > li[data-state="wait"]::before { background: var(--surface-3); box-shadow: inset 0 0 0 1px var(--line-strong); }
  .ui-legend > li[data-state="off"]::before { background: var(--hatch), var(--surface); box-shadow: inset 0 0 0 1px var(--line-strong); }
  .ui-legend b { color: var(--ink); font-family: var(--font-num); }

  /* ----- 今日整點: vertical hour line for activity side columns ----- */
  .ui-hourline { position: relative; display: grid; gap: 2px; margin: 0; padding: 0; list-style: none; }
  .ui-hourline::before { content: ""; position: absolute; top: 14px; bottom: 14px; left: 59px; width: 2px; background: var(--line); }
  .ui-hourline > li {
    --dot: var(--surface); --dot-line: var(--line-strong);
    position: relative; display: grid; grid-template-columns: 46px 14px minmax(0, 1fr); align-items: center; gap: 0 var(--sp-3);
    min-height: 32px; padding: 3px 8px 3px 0; border-radius: var(--r-md); color: var(--ink-2); font-size: var(--fs-14);
  }
  .ui-hourline > li::before {
    content: ""; grid-column: 2; grid-row: 1; justify-self: center; width: 12px; height: 12px; border: 2px solid var(--dot-line); border-radius: 50%; background: var(--dot);
  }
  .ui-hourline time { grid-column: 1; grid-row: 1; color: var(--ink-3); font-family: var(--font-num); font-size: var(--fs-13); font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; }
  .ui-hourline > li > span { grid-column: 3; grid-row: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .ui-hourline > li[data-state="done"] { --dot: var(--ok-solid); --dot-line: var(--ok-solid); color: var(--ink-3); }
  .ui-hourline > li[data-state="live"] { --dot: var(--warn-solid); --dot-line: var(--warn-solid); color: var(--ink); }
  .ui-hourline > li[data-state="live"]::before { animation: ui-live 1.8s ease-out infinite; color: var(--warn-solid); }
  .ui-hourline > li[data-state="next"] { --dot: var(--brand); --dot-line: var(--brand); color: var(--ink); font-weight: 700; background: var(--brand-soft); }
  .ui-hourline > li[data-state="next"] time { color: var(--brand-ink); }
  .ui-hourline > li[data-state="now"] { min-height: 22px; color: var(--bad); }
  .ui-hourline > li[data-state="now"]::before { width: 9px; height: 9px; border: 0; background: var(--bad-solid); }
  .ui-hourline > li[data-state="now"]::after { content: ""; grid-column: 3; grid-row: 1; height: 2px; border-radius: 1px; background: var(--bad-solid); }
  .ui-hourline > li[data-state="now"] time { color: var(--bad); }

  /* ----- Dialog content: footer with the consequence on the left, buttons on the right ----- */
  .ui-dialog-foot {
    position: sticky; bottom: calc(-1 * var(--modal-pad-b, 24px)); z-index: 1;
    display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 10px;
    margin: var(--sp-5) calc(-1 * var(--modal-pad-x, 24px)) calc(-1 * var(--modal-pad-b, 24px));
    padding: 14px var(--modal-pad-x, 24px) calc(14px + env(safe-area-inset-bottom));
    border-top: 1px solid var(--line-2); background: var(--surface-2);
  }
  /* The note takes its own row when the button does not fit beside it (S dialogs), instead of breaking mid-sentence. */
  .ui-dialog-foot > p, .ui-dialog-foot-note { flex: 1 1 260px; min-width: 0; color: var(--ink-2); font-size: var(--fs-14); line-height: 1.6; }
  .ui-dialog-foot > p strong { color: var(--ink); }

  /* ----- Account pickers (shared by activities, transfers, points, coupons, QR) ----- */
  .account-check-picker { display: grid; gap: var(--sp-3); min-width: 0; }
  .account-check-picker-actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-2) var(--sp-3); }
  .account-check-picker-actions > strong { color: var(--ink); font-size: var(--fs-14); }
  .account-check-picker-actions > div { display: flex; flex-wrap: wrap; gap: 6px; }
  .check-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: var(--sp-2); min-width: 0; }
  .check-card {
    display: flex; align-items: center; gap: 10px; min-width: 0; min-height: 56px; padding: 10px 12px;
    border: 1px solid var(--line); border-radius: 10px; background: var(--surface); color: var(--ink);
    font-size: var(--fs-14); font-weight: 600; cursor: pointer;
    transition: border-color var(--t-fast), background-color var(--t-fast);
  }
  .check-card:hover { border-color: var(--ink-4); }
  .check-card:has(> input:checked) { border-color: var(--brand); background: var(--brand-soft); }
  .check-card:has(> input:focus-visible) { outline: 2px solid var(--focus); outline-offset: 2px; }
  .check-card-body { display: grid; gap: 1px; min-width: 0; }
  .check-card-body > strong { overflow: hidden; color: var(--ink); font-size: var(--fs-14); text-overflow: ellipsis; white-space: nowrap; }
  .check-card-body > small { color: var(--ink-3); font-family: var(--font-num); font-size: var(--fs-13); font-weight: 600; }
  .account-check-filter-empty { padding: 10px 12px; border: 1px dashed var(--line-strong); border-radius: var(--r-md); color: var(--ink-3); font-size: var(--fs-14); }
  .account-native-picker { display: grid; gap: var(--sp-2); flex: 1 1 320px; min-width: 0; }
  .account-native-picker > small { color: var(--warn); font-size: var(--fs-13); font-weight: 600; }
  /* Account tags (accountTagBadgesMarkup): used in pickers, account lists and transfer sources. */
  .account-tag-badges { display: inline-flex; flex-wrap: wrap; gap: 4px; min-width: 0; max-width: 100%; }
  .account-tag-badges > span {
    max-width: 100%; padding: 0 6px; overflow: hidden; border: 1px solid var(--line); border-radius: var(--r-xs);
    background: var(--surface-2); color: var(--ink-2); font-size: var(--fs-12); font-weight: 650; line-height: 18px; text-overflow: ellipsis; white-space: nowrap;
  }
  .account-tags-none { color: var(--ink-3); font-size: var(--fs-12); }

  /* ----- Tables: horizontal scroll on desktop, labelled cards on phones ----- */
  .table-wrap {
    max-width: 100%; overflow: auto; overscroll-behavior-inline: contain;
    border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface); box-shadow: var(--sh-1);
    scrollbar-width: thin; -webkit-overflow-scrolling: touch;
  }
  .table-wrap > table { min-width: 720px; }
  .panel .table-wrap { box-shadow: none; }
  .table-empty td { padding: var(--sp-6) var(--sp-4); color: var(--ink-3); text-align: center; }

  /* ----- Buttons that belong to shared patterns ----- */
  .icon-button {
    --btn-bg: transparent; --btn-line: var(--line); --btn-ink: var(--ink-2);
    width: var(--h-md); min-width: var(--h-md); padding: 0; font-size: 20px; line-height: 1;
  }
  .reveal-more { width: 100%; margin-top: var(--sp-3); }
  .actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); min-width: 0; }
  .stack { display: grid; gap: var(--sp-4); min-width: 0; }
  .stack > * { min-width: 0; }
}

/* -----------------------------------------------------------------------------
   6. Layout patterns
   ----------------------------------------------------------------------------- */
@layer ui.layouts {
  /* Main + side column. Collapses to one column at ≤ 900px. */
  .ui-split { display: grid; grid-template-columns: minmax(0, 1fr) minmax(300px, 380px); gap: var(--sp-5); align-items: start; min-width: 0; }
  .ui-split[data-ratio="half"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ui-split[data-ratio="wide-side"] { grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); }
  .ui-split > * { min-width: 0; }
  .ui-split-side { display: grid; gap: var(--sp-4); }
  .ui-split-side.is-sticky { position: sticky; top: calc(var(--appbar-h) + var(--vitals-h) + var(--sp-4)); }
  /* Auto-fitting card grid: set --min on the element (style attribute is allowed). */
  .ui-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--min, 260px)), 1fr)); gap: var(--sp-4); min-width: 0; }
  .ui-grid > * { min-width: 0; }

  @media (max-width: 900px) {
    .ui-split, .ui-split[data-ratio] { grid-template-columns: minmax(0, 1fr); }
    .ui-split-side.is-sticky { position: static; }
  }
  @media (max-width: 600px) {
    .panel { --panel-pad: var(--sp-4); }
    .ui-page-head, .view-intro { flex-direction: column; align-items: stretch; gap: var(--sp-3); margin-bottom: var(--sp-4); }
    .ui-page-head > *, .view-intro > * { flex: 0 0 auto; }
    .ui-page-head h2, .view-intro h2 { font-size: 23px; }
    .ui-page-head p:not(.eyebrow), .view-intro p:not(.eyebrow) { font-size: var(--fs-15); }
    /* Explicit width: in the column head, a wrapping row would otherwise be sized at its fit-content width. */
    .ui-page-head-actions { width: 100%; }
    .ui-page-head-actions > button { flex: 1 1 140px; }
    .ui-page-head-stats, .view-intro-stats { grid-auto-flow: row; grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .view-intro-stats.three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .ui-page-head-stats > div:nth-child(odd), .view-intro-stats > div:nth-child(odd) { border-left: 0; }
    .ui-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-3); }
    .ui-kpi { padding: var(--sp-3) var(--sp-4); flex-direction: column; gap: var(--sp-2); }
    .ui-kpi-value { font-size: var(--fs-24); }
    .ui-flow { grid-template-columns: minmax(0, 1fr); text-align: left; }
    .ui-flow-side.is-to { text-align: left; justify-items: start; }
    .ui-flow-mid { justify-items: start; min-width: 0; }
    .ui-flow-mid i { display: none; }
    .ui-row { flex-wrap: wrap; }
    .ui-row-actions { width: 100%; justify-content: stretch; }
    .ui-row-actions > button { flex: 1 1 140px; }
    .check-grid { grid-template-columns: minmax(0, 1fr); }
    .ui-filters, .toolbar { padding: var(--sp-3); }
    .ui-filters > label, .toolbar > label { flex-basis: 100%; }
    .ui-chips, .account-picker-tag-filter { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; margin-inline: calc(-1 * var(--sp-1)); padding: 2px var(--sp-1); }
    .ui-chips::-webkit-scrollbar, .account-picker-tag-filter::-webkit-scrollbar { display: none; }
    .ui-dialog-foot > :is(button, .actions) { flex: 1 1 100%; }

    /* Page-level data tables become labelled cards. */
    .responsive-table-wrap { overflow: visible; border: 0; border-radius: 0; background: transparent; box-shadow: none; }
    .responsive-data-table { display: block; min-width: 0; background: transparent; }
    .responsive-data-table thead { display: none; }
    .responsive-data-table tbody { display: grid; gap: 10px; min-width: 0; }
    .responsive-data-table tr { display: grid; min-width: 0; overflow: hidden; border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface); box-shadow: var(--sh-1); }
    .responsive-data-table td {
      display: grid; grid-template-columns: minmax(82px, .38fr) minmax(0, 1fr); align-items: start; gap: 10px; min-width: 0;
      padding: 10px 12px; border-bottom: 1px solid var(--line-2); overflow-wrap: anywhere;
    }
    .responsive-data-table td:last-child { border-bottom: 0; }
    .responsive-data-table td::before { content: attr(data-label); min-width: 0; color: var(--ink-3); font-size: var(--fs-13); font-weight: 700; line-height: 1.5; }
    .responsive-data-table td > * { grid-column: 2; min-width: 0; }
    .responsive-data-table td > br { display: none; }
    .responsive-data-table td .pre-wrap { width: 100%; max-height: 180px; }
    .responsive-data-table td .actions { display: grid; gap: 6px; width: 100%; }
    .responsive-data-table td button { width: 100%; min-height: 44px; }
    .responsive-data-table .table-empty { display: block; border: 0; background: transparent; box-shadow: none; }
    .responsive-data-table .table-empty td { display: block; padding: var(--sp-5) var(--sp-4); border: 1px dashed var(--line-strong); border-radius: var(--r-lg); background: var(--surface-2); text-align: center; }
    .responsive-data-table .table-empty td::before { display: none; }
  }

  /* Touch screens and phones: every control is at least 44px tall. */
  @media (max-width: 900px), (pointer: coarse) {
    button, button.small, .ui-chip, .account-picker-tag-filter > button, .ui-segmented > :is(button, a), .external-links a, .official-link { min-height: var(--h-touch); }
    .icon-button { width: var(--h-touch); min-width: var(--h-touch); }
    summary { min-height: var(--h-touch); }
  }
}

/* -----------------------------------------------------------------------------
   7. Tones. data-tone="ok|warn|bad|info|ai|coin|muted|brand" on any ui-*
   component; legacy tone classes map onto the same variables. Status pills map
   every state name that status() and the domains emit.
   ----------------------------------------------------------------------------- */
@layer ui.tones {
  :is([data-tone="ok"], .good, .success, .verified) {
    --tone-ink: var(--ok); --tone-solid: var(--ok-solid); --tone-on: var(--on-ok); --tone-soft: var(--ok-soft); --tone-line: var(--ok-line); --tone-value: var(--ok);
  }
  :is([data-tone="warn"], .warn, .warning, .attention) {
    --tone-ink: var(--warn); --tone-solid: var(--warn-solid); --tone-on: var(--on-warn); --tone-soft: var(--warn-soft); --tone-line: var(--warn-line); --tone-value: var(--warn);
  }
  :is([data-tone="bad"], .bad, .danger, .error, .failure) {
    --tone-ink: var(--bad); --tone-solid: var(--bad-solid); --tone-on: var(--on-bad); --tone-soft: var(--bad-soft); --tone-line: var(--bad-line); --tone-value: var(--bad);
  }
  :is([data-tone="info"], [data-tone="brand"], .info, .pending) {
    --tone-ink: var(--brand-ink); --tone-solid: var(--brand); --tone-on: var(--on-brand); --tone-soft: var(--brand-soft); --tone-line: var(--brand-line); --tone-value: var(--brand-ink);
  }
  [data-tone="ai"] {
    --tone-ink: var(--ai); --tone-solid: var(--ai-solid); --tone-on: var(--on-ai); --tone-soft: var(--ai-soft); --tone-line: var(--ai-line); --tone-value: var(--ai);
  }
  [data-tone="coin"] {
    --tone-ink: var(--coin-deep); --tone-solid: var(--coin); --tone-on: var(--ink); --tone-soft: var(--coin-soft); --tone-line: var(--coin-line); --tone-value: var(--ink);
  }
  :is([data-tone="muted"], .disabled) {
    --tone-ink: var(--ink-3); --tone-solid: var(--muted-solid); --tone-on: var(--on-muted); --tone-soft: var(--surface-3); --tone-line: var(--line); --tone-value: var(--ink-2);
  }

  .status:is(.active, .success, .complete, .verified, .healthy, .awarded, .accepted, .ledger_confirmed, .alert-allowed, .good) {
    --tone-ink: var(--ok); --tone-soft: var(--ok-soft); --tone-line: var(--ok-line);
  }
  .status:is(.running, .dispatching, .preparing, .queued, .pending, .draft, .preview_only, .upcoming, .info) {
    --tone-ink: var(--brand-ink); --tone-soft: var(--brand-soft); --tone-line: var(--brand-line);
  }
  .status:is(.unknown, .needs_review, .needs_review_running, .partial, .warning, .pending_review, .alert-pending, .paused, .stopping, .warn) {
    --tone-ink: var(--warn); --tone-soft: var(--warn-soft); --tone-line: var(--warn-line);
  }
  .status:is(.expired, .failure, .failed, .error, .rejected, .critical, .danger, .alert-blocked, .bad) {
    --tone-ink: var(--bad); --tone-soft: var(--bad-soft); --tone-line: var(--bad-line);
  }
  .status:is(.disabled, .archived, .cancelled, .skipped, .idle, .no_balance, .exhausted, .muted) {
    --tone-ink: var(--ink-3); --tone-soft: var(--surface-3); --tone-line: var(--line);
  }
}

/* -----------------------------------------------------------------------------
   8. Utilities and functional rules
   ----------------------------------------------------------------------------- */
@layer ui.utilities {
  [hidden], .hidden { display: none !important; }
  [data-reveal-hidden] { display: none !important; }
  .sr-only, .visually-hidden {
    position: absolute !important; width: 1px !important; height: 1px !important; margin: -1px !important; padding: 0 !important;
    overflow: hidden !important; clip: rect(0 0 0 0) !important; white-space: nowrap !important; border: 0 !important;
  }
  .nowrap { white-space: nowrap; }
  .wide { grid-column: 1 / -1; }
  .section-gap { margin-top: var(--sp-4); }
  .compact { --panel-pad: var(--sp-4); }
  .ui-num { font-family: var(--font-num); font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
  .ui-mark { padding: 0 2px; color: var(--ink); font-weight: 700; background: linear-gradient(transparent 58%, var(--mark) 58%, var(--mark) 92%, transparent 92%); }
  .ui-tone-text { color: var(--tone-ink, inherit); }
}

/* -----------------------------------------------------------------------------
   9. Motion. Keyframes are global; every animation stops for reduced motion.
   ----------------------------------------------------------------------------- */
@keyframes ui-spin { to { transform: rotate(360deg); } }
@keyframes ui-live { 0% { box-shadow: 0 0 0 0 currentColor; } 70%, 100% { box-shadow: 0 0 0 6px transparent; } }
@keyframes ui-shimmer { from { background-position: 120% 0; } to { background-position: -120% 0; } }
@keyframes ui-rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes ui-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes ui-pop { from { opacity: 0; transform: scale(.96); } to { opacity: 1; transform: none; } }
@keyframes ui-sheet { from { opacity: 0; transform: translateY(48px); } to { opacity: 1; transform: none; } }
@keyframes ui-drawer { from { opacity: 0; transform: translateX(32px); } to { opacity: 1; transform: none; } }
@keyframes ui-tick { from { opacity: 0; transform: translateY(-40%); } to { opacity: 1; transform: none; } }
@keyframes ui-grow-x { from { transform: scaleX(0); } to { transform: scaleX(1); } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important; animation-delay: 0ms !important;
    transition-duration: .01ms !important; transition-delay: 0ms !important; scroll-behavior: auto !important;
  }
}
