/* =========================================================
   IT Document Tracker — Shared design tokens & components
   Brand: Kanda (Smile of living)
   ========================================================= */

/* ─── Register tokens as <color> custom properties so they
       can be transitioned (else var() swaps would snap). ─── */
@property --bg            { syntax: '<color>'; inherits: true; initial-value: #F2EEE3; }
@property --surface       { syntax: '<color>'; inherits: true; initial-value: #FFFFFF; }
@property --surface-soft  { syntax: '<color>'; inherits: true; initial-value: #ECE7D8; }
@property --surface-sunk  { syntax: '<color>'; inherits: true; initial-value: #E2DCC9; }
@property --border        { syntax: '<color>'; inherits: true; initial-value: #DDD7C4; }
@property --border-strong { syntax: '<color>'; inherits: true; initial-value: #B8B197; }
@property --ink           { syntax: '<color>'; inherits: true; initial-value: #1B2418; }
@property --ink-muted     { syntax: '<color>'; inherits: true; initial-value: #4A5446; }
@property --ink-soft      { syntax: '<color>'; inherits: true; initial-value: #79806E; }
@property --ink-ghost     { syntax: '<color>'; inherits: true; initial-value: #B0B3A4; }
@property --blue          { syntax: '<color>'; inherits: true; initial-value: #2F5D3C; }
@property --blue-700      { syntax: '<color>'; inherits: true; initial-value: #1F432A; }
@property --blue-50       { syntax: '<color>'; inherits: true; initial-value: #E6EEE7; }
@property --blue-100      { syntax: '<color>'; inherits: true; initial-value: #C9DAC9; }

:root {
  /* Morph tokens themselves when JS rewrites them */
  transition:
    --bg .55s ease, --surface .55s ease, --surface-soft .55s ease, --surface-sunk .55s ease,
    --border .55s ease, --border-strong .55s ease,
    --ink .55s ease, --ink-muted .55s ease, --ink-soft .55s ease, --ink-ghost .55s ease,
    --blue .55s ease, --blue-700 .55s ease, --blue-50 .55s ease, --blue-100 .55s ease;
}

/* Animate shape + spacing changes everywhere the tokens land */
.option, .option-preview, .option-tag, .option-body, .stat, .memo, .item,
.detail-pane, .list-pane, .detail-stats, .detail-stats > div,
.chip, .badge, .btn-primary, .btn-ghost, .btn-outline, .stage-empty,
.tl-marker, .stage-dot, .progress-pill .seg, .topbar, .empty {
  transition:
    background-color .45s ease, border-color .45s ease, color .35s ease,
    border-radius .55s cubic-bezier(.4,0,.2,1),
    box-shadow .45s ease,
    padding .55s cubic-bezier(.4,0,.2,1),
    gap .55s cubic-bezier(.4,0,.2,1),
    transform .18s ease;
}
.page, .landing, .summary, .options, .rail-section, .split, .filters, .memos,
.page-head, .page-footer, .pipeline, .timeline {
  transition:
    padding .55s cubic-bezier(.4,0,.2,1),
    gap .55s cubic-bezier(.4,0,.2,1),
    margin .55s cubic-bezier(.4,0,.2,1);
}

:root {
  --font: 'Prompt', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;

  /* Surfaces — warm parchment so the eye relaxes, with pure-white
     cards floating on top so MEMO content stays bright + readable. */
  --bg: #F2EEE3;
  --surface: #FFFFFF;
  --surface-soft: #ECE7D8;
  --surface-sunk: #E2DCC9;
  --border: #DDD7C4;
  --border-strong: #B8B197;

  /* Ink — olive-charcoal: dark enough to read, soft enough not to bite */
  --ink: #1B2418;
  --ink-muted: #4A5446;
  --ink-soft: #79806E;
  --ink-ghost: #B0B3A4;

  /* Brand — Kanda deep forest green (mature, professional) */
  --blue: #2F5D3C;
  --blue-700: #1F432A;
  --blue-50: #E6EEE7;
  --blue-100: #C9DAC9;
  --orange: #C97A3D;
  --orange-50: #F6EADF;

  /* Stage palette — distinct hues so the 3 paths stay readable */
  --s-blue: #3B6FB3;
  --s-blue-bg: #E8EFF8;
  --s-amber: #B36A1F;
  --s-amber-bg: #F6EBD9;
  --s-purple: #6B4FA0;
  --s-purple-bg: #ECE5F6;
  --s-green: #2F5D3C;
  --s-green-bg: #E8F4ED;

  /* Shape */
  --r-lg: 18px;
  --r-md: 12px;
  --r-sm: 8px;

  --shadow-sm: 0 1px 2px rgba(27, 36, 24, .04), 0 1px 0 rgba(27, 36, 24, .02);
  --shadow-md: 0 4px 14px rgba(27, 36, 24, .06), 0 1px 0 rgba(27, 36, 24, .02);
  --shadow-lg: 0 18px 48px rgba(27, 36, 24, .09), 0 2px 0 rgba(27, 36, 24, .03);

  /* Spacing */
  --pad-page: 56px;
  --pad-card: 28px;
  --gap-section: 48px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* ── Decorative leaves — subtle brand garnish in two corners
      They’re fixed-position so they ride along while the user scrolls,
      and pointer-events:none so they never interfere with interaction. ── */
body::before,
body::after {
  content: '';
  position: fixed;
  z-index: 0;
  pointer-events: none;
  background-repeat: no-repeat;
  background-size: contain;
  opacity: .55;
}
/* Top-right cluster — two overlapping leaves */
body::before {
  top: -60px; right: -120px;
  width: 520px; height: 520px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'><g fill='%232F5D3C' fill-opacity='.10'><path d='M150 20c-50 8-92 50-100 100 38-8 78-26 96-58 12-22 12-32 4-42z'/><path d='M180 70c-30 22-62 50-72 90 32-4 64-22 78-50 10-22 4-32-6-40z' fill-opacity='.08'/></g></svg>");
  transform: rotate(8deg);
}
/* Bottom-left single leaf */
body::after {
  bottom: -90px; left: -90px;
  width: 420px; height: 420px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'><path d='M40 180c14-50 50-92 100-110-2 40-18 84-50 110-20 16-38 14-50 0z' fill='%232F5D3C' fill-opacity='.09'/></svg>");
  transform: rotate(-18deg);
}

/* Make sure all real content sits above the leaves */
.topbar, .page, .landing, .k-modal-back, .toast { position: relative; z-index: 1; }
.topbar { z-index: 50; }

@media (max-width: 720px) {
  body::before { width: 340px; height: 340px; right: -90px; }
  body::after  { width: 280px; height: 280px; left: -70px; }
}

img { display: block; max-width: 100%; }

h1, h2, h3, h4, p, ol, ul { margin: 0; padding: 0; }
ol, ul { list-style: none; }

button { font-family: inherit; cursor: pointer; }

/* ----- Top bar ----- */
.topbar {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px var(--pad-page);
  background: rgba(242, 238, 227, 0.85);
  backdrop-filter: saturate(160%) blur(14px);
  -webkit-backdrop-filter: saturate(160%) blur(14px);
  border-bottom: 1px solid var(--border);
}
.brand { display: flex; align-items: center; gap: 14px; }
.brand img { height: 38px; width: auto; }
.brand-divider {
  width: 1px; height: 22px; background: var(--border-strong);
}
.brand-tag {
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--blue-700);
  background: var(--blue-50);
  border: 1px solid var(--blue-100);
  padding: 4px 12px;
  border-radius: 999px;
  font-weight: 600;
}

.topbar-right { display: flex; align-items: center; gap: 10px; }

/* ─── Toast notifications ─────────────────────────────── */
.toast {
  position: fixed;
  bottom: 28px;
  left: 50%;
  transform: translate(-50%, 20px);
  background: var(--ink);
  color: #fff;
  padding: 12px 22px;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 500;
  box-shadow: var(--shadow-lg);
  opacity: 0;
  transition: opacity .25s ease, transform .35s cubic-bezier(.2,.8,.2,1);
  z-index: 9000;
  pointer-events: none;
  max-width: 80vw;
  text-align: center;
}
.toast--show { opacity: 1; transform: translate(-50%, 0); }
.toast--err  { background: #B91C1C; }

/* ─── Modal (admin) ───────────────────────────────────── */
.k-modal-back {
  position: fixed; inset: 0;
  background: rgba(27, 36, 24, .35);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  display: flex; align-items: center; justify-content: center;
  z-index: 8000;
  opacity: 0;
  transition: opacity .22s ease;
  padding: 24px;
}
.k-modal-back.is-open { opacity: 1; }
.k-modal {
  background: var(--surface);
  border-radius: var(--r-lg);
  width: 520px;
  max-width: 100%;
  max-height: 90vh;
  display: flex; flex-direction: column;
  box-shadow: 0 30px 80px rgba(27,36,24,.30);
  transform: translateY(16px) scale(.98);
  opacity: 0;
  transition: transform .3s cubic-bezier(.2,.8,.2,1), opacity .2s ease;
  overflow: hidden;
}
.k-modal-back.is-open .k-modal { transform: translateY(0) scale(1); opacity: 1; }

.k-modal-head {
  padding: 22px 26px 14px;
  border-bottom: 1px solid var(--border);
  position: relative;
}
.k-modal-eyebrow {
  font-size: 11px; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 4px;
}
.k-modal-title {
  font-size: 20px; font-weight: 600; color: var(--ink);
  letter-spacing: -.01em;
}
.k-modal-close {
  position: absolute;
  top: 16px; right: 16px;
  width: 34px; height: 34px;
  border-radius: 50%;
  border: 0; background: var(--surface-sunk); color: var(--ink-soft);
  font-size: 22px; line-height: 1; cursor: pointer;
  transition: background .15s, color .15s;
}
.k-modal-close:hover { background: var(--ink); color: #fff; }

.k-modal-body { padding: 18px 26px; overflow-y: auto; }
.k-modal-foot {
  display: flex; align-items: center; gap: 10px;
  padding: 16px 22px;
  border-top: 1px solid var(--border);
  background: var(--surface-soft);
}
.k-spacer { flex: 1; }

/* Fields */
.k-field {
  display: block;
  margin-bottom: 14px;
}
.k-field > span {
  display: block;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--ink-muted);
  margin-bottom: 6px;
}
.k-field input[type="text"],
.k-field input[type="number"],
.k-field input[type="password"],
.k-field select {
  width: 100%;
  height: 40px;
  padding: 0 12px;
  border-radius: var(--r-sm);
  border: 1px solid var(--border-strong);
  background: var(--surface);
  font-family: var(--font);
  font-size: 14px;
  color: var(--ink);
  transition: border-color .15s, box-shadow .15s;
}
.k-field select { padding-right: 32px; }
.k-field input:focus,
.k-field select:focus {
  outline: 0;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px var(--blue-50);
}
.k-field input.is-err { border-color: #B91C1C; box-shadow: 0 0 0 3px rgba(185,28,28,.12); }
.k-field--check {
  display: flex; align-items: center; gap: 8px;
  background: var(--surface-soft);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: 10px 12px;
  margin-bottom: 14px;
  height: 40px;
}
.k-field--check input { width: 18px; height: 18px; accent-color: var(--blue); margin: 0; }
.k-field--check span { margin: 0; color: var(--ink); font-size: 13.5px; }
.k-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
.k-help {
  font-size: 12.5px;
  color: var(--ink-soft);
  line-height: 1.55;
  margin: 2px 0 14px;
  text-wrap: pretty;
}

/* Modal buttons */
.k-btn {
  height: 40px;
  padding: 0 18px;
  border-radius: 999px;
  border: 1px solid transparent;
  font-family: var(--font);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: background .15s, border-color .15s, color .15s, transform .1s;
}
.k-btn:active { transform: scale(.97); }
.k-btn-ghost   { background: transparent; color: var(--ink-muted); }
.k-btn-ghost:hover { background: var(--surface-sunk); color: var(--ink); }
.k-btn-primary { background: var(--blue); color: #fff; }
.k-btn-primary:hover { background: var(--blue-700); }
.k-btn-primary:disabled { background: var(--ink-ghost); cursor: not-allowed; }
.k-btn-danger  { background: #fff; color: #B91C1C; border-color: #FECACA; }
.k-btn-danger:hover { background: #FEF2F2; border-color: #FCA5A5; }

/* Menu list (admin landing) */
.k-menu { display: flex; flex-direction: column; gap: 6px; }
.k-menu-item {
  display: flex; align-items: center; gap: 14px;
  padding: 12px 14px;
  border-radius: var(--r-sm);
  background: transparent;
  border: 1px solid transparent;
  cursor: pointer;
  text-align: left;
  font-family: var(--font);
  color: var(--ink);
  transition: background .15s, border-color .15s, transform .12s;
}
.k-menu-item:hover {
  background: var(--surface-soft);
  border-color: var(--border);
}
.k-menu-item > span:first-child {
  width: 36px; height: 36px;
  flex-shrink: 0;
  border-radius: 10px;
  background: var(--blue-50);
  color: var(--blue);
  font-size: 18px;
  display: flex; align-items: center; justify-content: center;
}
.k-menu-item div b { display: block; font-weight: 600; font-size: 14px; }
.k-menu-item div small { display: block; font-size: 12px; color: var(--ink-soft); margin-top: 2px; }
.k-menu-item--danger > span:first-child { background: #FEF2F2; color: #B91C1C; }
.k-menu-item--danger:hover { background: #FEF2F2; }

/* Confirm card (delete) */
.k-confirm-card {
  background: var(--surface-soft);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: 14px 16px;
  margin-top: 6px;
}
.k-confirm-title { font-size: 15px; font-weight: 500; color: var(--ink); }
.k-confirm-meta  { font-size: 12.5px; color: var(--ink-soft); margin-top: 4px; }

/* Edit button on memo cards / list items — only visible in admin mode */
.memo-edit, .item-edit {
  position: absolute;
  top: 10px; right: 10px;
  width: 28px; height: 28px;
  border-radius: 50%;
  border: 0;
  background: var(--surface);
  box-shadow: var(--shadow-md);
  color: var(--ink-muted);
  font-size: 14px;
  cursor: pointer;
  z-index: 5;
  opacity: 0;
  transform: scale(.85);
  transition: opacity .15s, transform .15s, background .15s, color .15s;
}
body.is-admin .memo,
body.is-admin .item { position: relative; }
body.is-admin .memo:hover .memo-edit,
body.is-admin .item:hover .item-edit { opacity: 1; transform: scale(1); }
.memo-edit:hover, .item-edit:hover { background: var(--blue); color: #fff; }

/* Admin badge on topbar */
.admin-pill {
  display: none;
  align-items: center;
  gap: 6px;
  padding: 0 12px;
  height: 28px;
  border-radius: 999px;
  background: var(--blue-50);
  color: var(--blue-700);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
}
body.is-admin .admin-pill { display: inline-flex; }
.admin-pill::before {
  content: '';
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--blue);
  box-shadow: 0 0 0 3px rgba(47,93,60,.18);
}
  position: fixed;
  bottom: 28px;
  left: 50%;
  transform: translate(-50%, 20px);
  background: var(--ink);
  color: #fff;
  padding: 12px 22px;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 500;
  box-shadow: var(--shadow-lg);
  opacity: 0;
  transition: opacity .25s ease, transform .35s cubic-bezier(.2,.8,.2,1);
  z-index: 200;
  pointer-events: none;
  max-width: 80vw;
  text-align: center;
}
.toast--show {
  opacity: 1;
  transform: translate(-50%, 0);
}
.toast--err {
  background: #B91C1C;
}

/* path tag in list items + edit chip in detail pane */
.item-meta .path-tag {
  display: inline-flex; align-items: center;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .04em;
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--ink);
  color: #fff;
}
.btn-edit-detail {
  margin-left: auto;
  background: var(--blue-50);
  color: var(--blue-700);
  border: 1px solid var(--blue-100);
  border-radius: 999px;
  padding: 4px 12px;
  font-family: var(--font);
  font-size: 12.5px;
  font-weight: 500;
  cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
}
.btn-edit-detail:hover { background: var(--blue); color: #fff; border-color: var(--blue); }

/* Loading skeleton — used on the “อัปเดตล่าสุด” chip before
   the first fetch resolves */
.updated.is-loading::before {
  background: var(--s-amber);
  animation: livePulse 1s ease-in-out infinite;
}

/* ─── View toggle (sits in the middle of the topbar) ─── */
.view-toggle {
  display: inline-flex;
  align-items: center;
  background: var(--surface-sunk);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 3px;
  gap: 2px;
}
.vt-tab {
  display: inline-flex; align-items: center; gap: 7px;
  height: 32px;
  padding: 0 14px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-soft);
  text-decoration: none;
  transition: background .2s, color .2s, box-shadow .2s, transform .15s;
  white-space: nowrap;
}
.vt-tab:hover { color: var(--ink); }
.vt-tab:active { transform: scale(.97); }
.vt-tab svg { width: 14px; height: 14px; opacity: .65; }
.vt-tab.is-active {
  background: var(--surface);
  color: var(--ink);
  box-shadow: var(--shadow-sm);
}
.vt-tab.is-active svg { opacity: 1; color: var(--blue); }

.btn-ghost, .btn-primary, .btn-outline {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 40px;
  padding: 0 18px;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 500;
  border: 1px solid transparent;
  transition: background .15s, border-color .15s, color .15s, transform .12s;
  background: transparent;
  color: var(--ink-muted);
}
.btn-ghost {
  background: var(--blue-50);
  color: var(--blue-700);
  border-color: var(--blue-100);
}
.btn-ghost:hover { background: var(--blue-100); color: var(--blue-700); border-color: var(--blue); }
.btn-outline {
  border-color: var(--border-strong);
  color: var(--ink);
  background: var(--surface);
}
.btn-outline:hover { border-color: var(--ink-soft); }
.btn-primary {
  background: var(--blue);
  color: #fff;
  box-shadow: 0 2px 8px rgba(31,67,42,.22);
}
.btn-primary:hover { background: var(--blue-700); box-shadow: 0 3px 12px rgba(31,67,42,.32); }
.btn-primary svg, .btn-ghost svg, .btn-outline svg { width: 16px; height: 16px; }

/* ----- Page shell ----- */
.page {
  max-width: 1280px;
  margin: 0 auto;
  padding: 64px var(--pad-page) 96px;
}

.page-head {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: end;
  gap: 32px;
  margin-bottom: 56px;
}
.eyebrow {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--blue);
  margin-bottom: 12px;
}
.page-head h1 {
  font-size: 44px;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: var(--ink);
}
.lede {
  margin-top: 12px;
  font-size: 17px;
  color: var(--ink-muted);
  max-width: 56ch;
  text-wrap: pretty;
}
.updated {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--ink-soft);
  font-weight: 500;
  white-space: nowrap;
}
.updated::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--s-green);
  box-shadow: 0 0 0 4px rgba(47,93,60,.20);
}
.updated span { color: var(--ink-muted); }

/* ----- Summary stats ----- */
.summary {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  margin-bottom: var(--gap-section);
}
.stat {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 28px 30px;
  position: relative;
  overflow: hidden;
}
.stat::after {
  content: '';
  position: absolute;
  inset: auto -20px -20px auto;
  width: 80px; height: 80px;
  border-radius: 50%;
  background: var(--blue-50);
  opacity: 0.6;
}
.stat:nth-child(2)::after { background: var(--orange-50); }
.stat:nth-child(3)::after { background: var(--s-purple-bg); }
.stat-label {
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-muted);
  letter-spacing: 0.02em;
  position: relative; z-index: 1;
}
.stat-value {
  font-size: 56px;
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.05;
  margin-top: 10px;
  color: var(--ink);
  position: relative; z-index: 1;
  font-variant-numeric: tabular-nums;
}
.stat-foot {
  font-size: 13px;
  color: var(--ink-soft);
  margin-top: 8px;
  position: relative; z-index: 1;
}

/* ----- Badges ----- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 24px;
  padding: 0 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.01em;
  white-space: nowrap;
}
.badge::before {
  content: '';
  width: 6px; height: 6px; border-radius: 50%;
  background: currentColor;
}
.badge--it     { background: var(--blue-50);    color: var(--blue-700); }
.badge--lic    { background: var(--s-purple-bg);color: var(--s-purple); }
.badge--cons   { background: var(--s-amber-bg); color: #B45309; }
.badge--maint  { background: var(--s-green-bg); color: #047857; }
.badge--far    { background: var(--orange-50);  color: #C24E0A; }

/* ----- Footnote ----- */
.page-footer {
  margin-top: 80px;
  padding-top: 32px;
  border-top: 1px solid var(--border);
  display: flex;
  justify-content: space-between;
  font-size: 13px;
  color: var(--ink-soft);
}
.page-footer .brand-mini { display: flex; align-items: center; gap: 10px; }
.page-footer img { height: 22px; opacity: 0.7; }

/* =========================================================
   Demo Mode — “Play timeline” animations
   Shared classes used by both Variation A (pipeline) and
   Variation B (split-view). Pure CSS hooks; JS just toggles
   classes and writes one custom property (`--play-fill`).
   ========================================================= */

/* ── Play / Stop button (replaces refresh’s neighbour) ── */
.btn-play {
  display: inline-flex; align-items: center; gap: 8px;
  height: 40px; padding: 0 18px;
  border-radius: 999px;
  font-size: 14px; font-weight: 500;
  background: var(--ink);
  color: #fff;
  border: 1px solid var(--ink);
  transition: background .2s, transform .12s, border-color .2s;
}
.btn-play:hover { background: #1f2d44; }
.btn-play:active { transform: scale(.97); }
.btn-play svg { width: 14px; height: 14px; }
.btn-play.is-playing { background: var(--blue); border-color: var(--blue); }
.btn-play.is-playing:hover { background: var(--blue-700); }

/* Pulse dot on the play icon while running */
.btn-play .play-dot {
  display: none;
  width: 8px; height: 8px; border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 0 0 rgba(255,255,255,.6);
  animation: btnPulse 1.1s ease-in-out infinite;
}
.btn-play.is-playing .play-dot { display: inline-block; }
.btn-play.is-playing .play-icon { display: none; }
@keyframes btnPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255,255,255,.55); }
  50%      { box-shadow: 0 0 0 6px rgba(255,255,255,0); }
}

/* ─────────── Variation A — Pipeline play ─────────── */

/* Filled connector that descends behind the dots as we play */
.pipeline {
  --play-fill: 0px;
}
.pipeline::after {
  content: '';
  position: absolute;
  left: 23px;
  top: 14px;
  width: 2px;
  height: var(--play-fill);
  background: linear-gradient(180deg, var(--blue) 0%, var(--blue) 75%, rgba(45,143,91,0) 100%);
  border-radius: 2px;
  z-index: 0;
  box-shadow: 0 0 16px rgba(45,143,91,.45);
  transition: height .65s cubic-bezier(.65,0,.35,1);
  pointer-events: none;
}
.pipeline.is-playing .stage:not(.play-now):not(.play-done) .stage-dot {
  opacity: .55;
  transition: opacity .4s ease;
}
.pipeline.is-playing .stage:not(.play-now):not(.play-done) .memos,
.pipeline.is-playing .stage:not(.play-now):not(.play-done) .stage-empty,
.pipeline.is-playing .stage:not(.play-now):not(.play-done) .stage-head {
  opacity: .55;
  transition: opacity .4s ease;
}

/* The stage currently being “visited” by the playhead */
.stage.play-now .stage-dot {
  background: var(--surface) !important;
  border-color: var(--blue) !important;
  color: var(--blue) !important;
  z-index: 2;
  animation: stagePop .8s cubic-bezier(.4,0,.2,1);
}
@keyframes stagePop {
  0%   { transform: scale(1);    box-shadow: 0 0 0 0 rgba(45,143,91,.5); }
  45%  { transform: scale(1.22); box-shadow: 0 0 0 12px rgba(45,143,91,.18); }
  100% { transform: scale(1.05); box-shadow: 0 0 0 5px var(--bg), 0 0 0 7px rgba(45,143,91,.3); }
}
.stage.play-now .stage-name {
  animation: nameSlide .55s cubic-bezier(.4,0,.2,1);
}
@keyframes nameSlide {
  from { transform: translateX(-8px); opacity: .4; }
  to   { transform: translateX(0);    opacity: 1; }
}
.stage.play-now .memos .memo {
  animation: memoFlyIn .6s cubic-bezier(.4,0,.2,1) backwards;
}
.stage.play-now .memos .memo:nth-child(2) { animation-delay: .12s; }
.stage.play-now .stage-empty {
  animation: memoFlyIn .55s cubic-bezier(.4,0,.2,1) backwards;
}
@keyframes memoFlyIn {
  from { opacity: 0; transform: translateY(12px) scale(.97); }
  to   { opacity: 1; transform: translateY(0)    scale(1); }
}

/* Stages the playhead has passed */
.stage.play-done .stage-dot {
  background: var(--blue) !important;
  border-color: var(--blue) !important;
  color: transparent !important;
}
.stage.play-done .stage-dot::after {
  content: '';
  position: absolute;
  left: 50%; top: 50%;
  width: 14px; height: 7px;
  border-left: 2px solid #fff;
  border-bottom: 2px solid #fff;
  transform: translate(-50%, -70%) rotate(-45deg);
  animation: checkDraw .35s cubic-bezier(.4,0,.2,1) backwards;
}
@keyframes checkDraw {
  from { opacity: 0; transform: translate(-50%, -70%) rotate(-45deg) scale(.3); }
  to   { opacity: 1; transform: translate(-50%, -70%) rotate(-45deg) scale(1); }
}

/* ─────────── Variation B — Timeline fill ─────────── */

.tl-step.fill-in .tl-marker {
  animation: markerIn .55s cubic-bezier(.4,0,.2,1) backwards;
}
@keyframes markerIn {
  0%   { transform: scale(.2); opacity: 0; }
  60%  { transform: scale(1.18); opacity: 1; }
  100% { transform: scale(1);    opacity: 1; }
}
.tl-step.fill-in .tl-label,
.tl-step.fill-in .tl-time {
  animation: labelIn .55s cubic-bezier(.4,0,.2,1) backwards;
}
.tl-step.fill-in .tl-time { animation-delay: .08s; }
@keyframes labelIn {
  from { opacity: 0; transform: translateX(-10px); }
  to   { opacity: 1; transform: translateX(0); }
}

/* The detail pane itself slides between MEMOs while cycling */
.detail-pane.swap-in {
  animation: detailSwap .5s cubic-bezier(.4,0,.2,1);
}
@keyframes detailSwap {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* List item pulses while it’s the focused one */
.item.cycle-focus::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  border-radius: inherit;
  box-shadow: inset 0 0 0 2px var(--blue);
  animation: focusRing 1s cubic-bezier(.4,0,.2,1);
}
@keyframes focusRing {
  0%   { box-shadow: inset 0 0 0 0 var(--blue); opacity: 1; }
  100% { box-shadow: inset 0 0 0 4px rgba(45,143,91,0); opacity: 0; }
}

/* Soft pulse on the live "อัปเดตล่าสุด" status dot — always on */
.updated::before {
  animation: livePulse 2.4s ease-in-out infinite;
}
@keyframes livePulse {
  0%, 100% { box-shadow: 0 0 0 4px rgba(47,93,60,.20); }
  50%      { box-shadow: 0 0 0 8px rgba(47,93,60,.04); }
}

/* =========================================================
   Depth & flair — load cascade, 3D tilt, confetti, comet
   Activated by JS in effects.js.
   ========================================================= */

/* ── Cascade reveal on load ─────────────────────────────── */
.reveal-in {
  animation: reveal .75s cubic-bezier(.2,.8,.2,1) backwards;
}
@keyframes reveal {
  from { opacity: 0; transform: translateY(18px); filter: blur(4px); }
  to   { opacity: 1; transform: translateY(0);    filter: blur(0); }
}

/* ── 3D pointer-tilt with shine highlight ──────────────── */
.tilt-host {
  --tx: 0deg; --ty: 0deg; --lift: 0px;
  transform-style: preserve-3d;
  transform:
    perspective(1100px)
    translateY(var(--lift))
    rotateX(var(--tx))
    rotateY(var(--ty));
  transition:
    transform .35s cubic-bezier(.2,.8,.2,1),
    box-shadow .35s ease,
    border-color .25s ease,
    border-radius .55s cubic-bezier(.4,0,.2,1);
  position: relative;
  will-change: transform;
}
/* Override any prior hover translate so the tilt math stays authoritative */
.memo.tilt-host:hover,
.stat.tilt-host:hover,
.option.tilt-host:hover,
.detail-pane.tilt-host:hover {
  transform:
    perspective(1100px)
    translateY(var(--lift))
    rotateX(var(--tx))
    rotateY(var(--ty));
  box-shadow: var(--shadow-lg);
}
/* Glossy highlight that follows the cursor */
.tilt-host::after {
  /* Don't collide with .stat::after */
}
.tilt-host > .tilt-shine,
.tilt-host .tilt-shine {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: radial-gradient(
    260px 260px at var(--shine-x, 50%) var(--shine-y, 50%),
    rgba(255,255,255,.55),
    rgba(255,255,255,0) 55%
  );
  opacity: 0;
  transition: opacity .25s ease;
  mix-blend-mode: overlay;
  z-index: 2;
}
.tilt-host:hover .tilt-shine { opacity: 1; }

/* ── Comet trail particle ───────────────────────────────── */
.fx-comet {
  --c: var(--blue);
  position: absolute;
  width: 12px; height: 12px;
  background: radial-gradient(circle, var(--c) 0%, rgba(45,143,91,0) 70%);
  border-radius: 50%;
  pointer-events: none;
  z-index: 40;
  transform: translate(-50%, -50%);
  animation: cometFade 1s ease-out forwards;
  filter: blur(.5px);
}
@keyframes cometFade {
  0%   { opacity: .85; width: 20px; height: 20px; }
  100% { opacity: 0;   width: 4px;  height: 4px; }
}

/* ── Confetti chip ──────────────────────────────────────── */
.fx-confetti {
  --c: #2563EB;
  position: absolute;
  width: 9px; height: 14px;
  background: var(--c);
  border-radius: 2px;
  pointer-events: none;
  z-index: 100;
  transform: translate(-50%, -50%);
  animation: confettiFly 1.3s cubic-bezier(.2,.5,.4,1) forwards;
  box-shadow: 0 1px 0 rgba(0,0,0,.05);
}
@keyframes confettiFly {
  0% {
    transform: translate(-50%, -50%) rotate(0deg) scale(.6);
    opacity: 0;
  }
  15% { opacity: 1; }
  100% {
    transform:
      translate(calc(-50% + var(--dx)),
                calc(-50% + var(--dy) + 200px))
      rotate(var(--rot)) scale(1);
    opacity: 0;
  }
}

/* ── Sparkle ring (one-shot radial pulse) ───────────────── */
.fx-sparkle {
  position: absolute;
  left: 12px; top: 14px;
  width: 0; height: 0;
  border-radius: 50%;
  pointer-events: none;
  background: radial-gradient(circle, rgba(45,143,91,.4) 0%, rgba(45,143,91,0) 70%);
  animation: sparkleRing .85s ease-out forwards;
  z-index: 0;
}
.tl-step.now.s-amber  + .fx-sparkle,
.tl-step.now.s-amber .fx-sparkle  { background: radial-gradient(circle, rgba(245,158,11,.45) 0%, rgba(245,158,11,0) 70%); }
.tl-step.now.s-purple .fx-sparkle { background: radial-gradient(circle, rgba(139,92,246,.45) 0%, rgba(139,92,246,0) 70%); }
.tl-step.now.s-green  .fx-sparkle { background: radial-gradient(circle, rgba(16,185,129,.45) 0%, rgba(16,185,129,0) 70%); }
@keyframes sparkleRing {
  0%   { width: 0;    height: 0;    opacity: 1; transform: translate(0, 0); }
  100% { width: 100px; height: 100px; opacity: 0; transform: translate(-44px, -44px); }
}

/* Make sure .stat keeps its decorative circle behind the shine */
.stat::after { z-index: 0; }
.stat-label, .stat-value, .stat-foot { position: relative; z-index: 3; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}
