/* The app owns its palette rather than inheriting Telegram's.

   Deferring to --tg-theme-* made every client repaint the page in its own
   chrome — the desktop client turned the accent Telegram blue — so twelve
   divination systems rendered as a generic form. A divination app needs its own
   atmosphere, so only the base surfaces follow the client's light/dark choice
   and every expressive colour is ours.

   These values mirror chart.DefaultPalette / DarkPalette in internal/chart.
   Charts arrive as server-rendered SVG and cannot read CSS variables, so the
   two must be edited together or the page and its plates drift apart. */
:root {
  color-scheme: light dark;

  --bg: #0f0d14;
  --bg-deep: #08070b;
  --fg: #ece7f2;
  --muted: #9d94ad;
  --card: #191621;
  --card-edge: #2b2536;
  --accent: #c9a227;
  --accent-fg: #14111a;
  --glow: #6d5a9c;
  --good: #7fb08c;
  --bad: #d98a7e;
  --radius: 14px;

  /* Per-system accents, mirroring systemThemes in internal/chart/theme.go.
     Set on <body> as data-system so the whole page shifts with the reading. */
  --sys-accent: var(--accent);
  --sys-glow: var(--glow);
}

/* A light client keeps the mystic character but lifts the surfaces, so the app
   stays readable in daylight without becoming a plain white form. */
@media (prefers-color-scheme: light) {
  :root {
    --bg: #f4f1ea;
    --bg-deep: #e8e3d8;
    --fg: #241f2e;
    --muted: #625a70;
    --card: #fffdf9;
    --card-edge: #e0d8ca;
    --accent: #8a6a12;
    --accent-fg: #fffdf9;
    --glow: #9b8bc4;
  }
}

body[data-system="bazi"]          { --sys-accent: #c89b6a; --sys-glow: #8a5c38; }
body[data-system="ziwei"]         { --sys-accent: #b3a3e0; --sys-glow: #5a4a8a; }
body[data-system="yijing"]        { --sys-accent: #8fc7b0; --sys-glow: #3f6b5c; }
body[data-system="qimen"]         { --sys-accent: #e09999; --sys-glow: #8a4a4a; }
body[data-system="western_astro"] { --sys-accent: #9dbce8; --sys-glow: #3a5a8a; }
body[data-system="tarot"]         { --sys-accent: #cfa3e0; --sys-glow: #6b3f7a; }
body[data-system="numerology"]    { --sys-accent: #dcbc7f; --sys-glow: #7a5a2a; }
body[data-system="runes"]         { --sys-accent: #a3c4dc; --sys-glow: #41607a; }
body[data-system="omikuji"]       { --sys-accent: #eda0a8; --sys-glow: #a04a52; }
body[data-system="nine_star_ki"]  { --sys-accent: #a5c9d8; --sys-glow: #4a6b7a; }
body[data-system="mayan"]         { --sys-accent: #e0bc74; --sys-glow: #8a6320; }
body[data-system="vedic"]         { --sys-accent: #e6ad76; --sys-glow: #8a5520; }

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

/* A slow drift of two offset radial washes, tinted by the active system. The
   page reads as a night sky rather than a flat panel, and the tint is what
   makes switching systems feel like switching traditions. */
body {
  margin: 0;
  padding: 0 0 32px;
  background:
    radial-gradient(1100px 620px at 18% -8%,
      color-mix(in srgb, var(--sys-glow) 34%, transparent), transparent 62%),
    radial-gradient(900px 560px at 88% 12%,
      color-mix(in srgb, var(--sys-accent) 16%, transparent), transparent 58%),
    linear-gradient(180deg, var(--bg) 0%, var(--bg-deep) 100%);
  background-attachment: fixed;
  color: var(--fg);
  font: 15px/1.65 -apple-system, BlinkMacSystemFont, 'PingFang SC',
        'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;
  transition: background 600ms ease;
}

/* Starfield: three sizes of pinprick, fixed behind the content. Pointer events
   stay off so it never intercepts a tap. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background-image:
    radial-gradient(1.4px 1.4px at 12% 22%, var(--fg), transparent),
    radial-gradient(1px 1px at 34% 68%, var(--fg), transparent),
    radial-gradient(1.6px 1.6px at 58% 14%, var(--sys-accent), transparent),
    radial-gradient(1px 1px at 72% 46%, var(--fg), transparent),
    radial-gradient(1.2px 1.2px at 86% 78%, var(--fg), transparent),
    radial-gradient(1px 1px at 24% 88%, var(--sys-accent), transparent),
    radial-gradient(1.3px 1.3px at 46% 36%, var(--fg), transparent),
    radial-gradient(1px 1px at 92% 28%, var(--fg), transparent);
  opacity: .34;
  animation: twinkle 7s ease-in-out infinite alternate;
}

@keyframes twinkle {
  from { opacity: .22 }
  to   { opacity: .42 }
}

/* Content sits above the starfield. */
.topbar, main, .disclaimer { position: relative; z-index: 1; }

@media (prefers-reduced-motion: reduce) {
  body { transition: none }
  body::before { animation: none }
}

.hidden { display: none !important; }

.topbar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px;
  position: sticky; top: 0; z-index: 10;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid color-mix(in srgb, var(--sys-accent) 22%, transparent);
}
.brand {
  font-size: 17px; font-weight: 600; letter-spacing: .06em;
  color: var(--sys-accent);
  text-shadow: 0 0 18px color-mix(in srgb, var(--sys-accent) 45%, transparent);
  transition: color 400ms ease;
}

main { padding: 0 14px; }

/* Cards read as plates: a translucent surface over the sky, a hairline edge
   tinted by the active system, and a soft lift. */
.card {
  position: relative;
  background: color-mix(in srgb, var(--card) 88%, transparent);
  border: 1px solid var(--card-edge);
  border-radius: var(--radius);
  padding: 18px 16px;
  margin-bottom: 14px;
  box-shadow:
    0 8px 28px rgba(0, 0, 0, .28),
    inset 0 1px 0 color-mix(in srgb, var(--sys-accent) 12%, transparent);
}

/* Corner marks, the same bracket motif the SVG plates use. */
.card::before, .card::after {
  content: '';
  position: absolute;
  width: 13px; height: 13px;
  border: 1px solid color-mix(in srgb, var(--sys-accent) 55%, transparent);
  pointer-events: none;
}
.card::before { top: 7px; left: 7px; border-right: 0; border-bottom: 0; border-radius: 4px 0 0 0 }
.card::after { bottom: 7px; right: 7px; border-left: 0; border-top: 0; border-radius: 0 0 4px 0 }

h2 {
  font-size: 16px; margin: 0 0 6px;
  letter-spacing: .03em;
}
/* Section headings carry a small lozenge, matching the SVG title rule. */
h3 {
  font-size: 13px; margin: 0 0 12px;
  color: var(--sys-accent); font-weight: 600;
  letter-spacing: .08em;
  display: flex; align-items: center; gap: 8px;
}
h3::before {
  content: '';
  width: 6px; height: 6px;
  background: var(--sys-accent);
  transform: rotate(45deg);
  flex: none;
}
h3::after {
  content: '';
  height: 1px; flex: 1;
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--sys-accent) 45%, transparent), transparent);
}

.hint { font-size: 12px; color: var(--muted); margin: 0 0 14px; }
.req { color: var(--bad); font-size: 11px; font-weight: 400; }

label {
  display: block;
  font-size: 13px;
  color: var(--muted);
  margin-bottom: 12px;
}

input, select, textarea {
  display: block;
  width: 100%;
  margin-top: 6px;
  padding: 11px 12px;
  font: inherit;
  color: var(--fg);
  background: color-mix(in srgb, var(--bg-deep) 60%, transparent);
  border: 1px solid var(--card-edge);
  border-radius: 10px;
  outline: none;
  transition: border-color 200ms ease, box-shadow 200ms ease;
}
input:focus, select:focus, textarea:focus {
  border-color: var(--sys-accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--sys-accent) 18%, transparent);
}
/* Field-level error state: a message alone leaves the user hunting for which
   input is at fault. */
input.err, select.err, textarea.err { border-color: var(--bad); }
textarea { resize: vertical; margin-bottom: 12px; }

button {
  font: inherit;
  border: none;
  border-radius: 10px;
  padding: 12px 16px;
  cursor: pointer;
  transition: transform 150ms ease, box-shadow 200ms ease, opacity 200ms ease;
}

/* Keyboard focus must stay visible: outline:none above would otherwise leave
   Tab users with no indication of position. */
button:focus-visible, input:focus-visible,
select:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--sys-accent);
  outline-offset: 2px;
}

.primary {
  width: 100%;
  background: linear-gradient(135deg,
    var(--sys-accent),
    color-mix(in srgb, var(--sys-accent) 72%, var(--sys-glow)));
  color: var(--accent-fg);
  font-weight: 600;
  letter-spacing: .08em;
  box-shadow: 0 4px 18px color-mix(in srgb, var(--sys-glow) 45%, transparent);
}
.primary:hover:not(:disabled) {
  box-shadow: 0 6px 24px color-mix(in srgb, var(--sys-glow) 60%, transparent);
}
.primary:active:not(:disabled) { transform: translateY(1px); }
.primary:disabled { opacity: .5; cursor: not-allowed; box-shadow: none; }

.ghost {
  background: color-mix(in srgb, var(--card) 55%, transparent);
  color: var(--sys-accent);
  border: 1px solid color-mix(in srgb, var(--sys-accent) 35%, transparent);
  padding: 8px 14px;
  font-size: 13px;
}
.ghost:hover { border-color: var(--sys-accent); }
.ghost:active { transform: translateY(1px); }
.wide { width: 100%; }

.chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.chip {
  background: color-mix(in srgb, var(--card) 70%, transparent);
  color: var(--muted);
  border: 1px solid var(--card-edge);
  padding: 7px 13px;
  font-size: 13px;
  border-radius: 999px;
  transition: all 220ms ease;
}
.chip:hover { color: var(--fg); border-color: color-mix(in srgb, var(--sys-accent) 45%, transparent); }
.chip.active {
  background: color-mix(in srgb, var(--sys-accent) 18%, transparent);
  color: var(--sys-accent);
  border-color: var(--sys-accent);
  box-shadow: 0 0 16px color-mix(in srgb, var(--sys-glow) 40%, transparent);
}

.msg { font-size: 13px; margin: 10px 0 0; min-height: 1.2em; }
.msg.err { color: var(--bad); }
.msg.ok { color: var(--good); }

/* Charts scroll horizontally so wide plates stay legible on a phone. */
.charts { margin-bottom: 14px; }
.chart-wrap {
  background: color-mix(in srgb, var(--card) 82%, transparent);
  border: 1px solid var(--card-edge);
  border-radius: var(--radius);
  padding: 10px;
  margin-bottom: 12px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  box-shadow: 0 8px 28px rgba(0, 0, 0, .26);
  /* Each plate fades up as it is inserted, so a spread feels dealt rather
     than pasted. */
  animation: plate-in 520ms ease both;
}
.chart-wrap svg {
  display: block; margin: 0 auto; max-width: 100%; height: auto;
  border-radius: 8px;
}

@keyframes plate-in {
  from { opacity: 0; transform: translateY(12px) scale(.985) }
  to   { opacity: 1; transform: none }
}

.tag-list { list-style: none; margin: 0 0 12px; padding: 0; }
.tag-list li {
  font-size: 13px;
  line-height: 1.55;
  padding: 9px 12px;
  border-radius: 9px;
  margin-bottom: 7px;
  background: color-mix(in srgb, var(--bg-deep) 45%, transparent);
  border-left: 3px solid transparent;
}
.tag-list.good li { border-left-color: var(--good); }
.tag-list.bad li { border-left-color: var(--bad); }

.reading { font-size: 15px; line-height: 1.9; white-space: pre-wrap; word-break: break-word; }
.reading h2 {
  font-size: 15px; margin: 22px 0 8px;
  padding-bottom: 6px;
  color: var(--sys-accent);
  letter-spacing: .05em;
  border-bottom: 1px solid color-mix(in srgb, var(--sys-accent) 28%, transparent);
}
.reading strong {
  color: var(--sys-accent);
  font-weight: 600;
}

@media (prefers-reduced-motion: reduce) {
  .chart-wrap { animation: none }
}

.result-actions { display: flex; gap: 10px; }
.result-actions .ghost { flex: 1; padding: 12px 14px; }

.dots span { animation: blink 1.4s infinite; }
.dots span:nth-child(2) { animation-delay: .2s; }
.dots span:nth-child(3) { animation-delay: .4s; }
@keyframes blink { 0%,60%,100% { opacity:.25 } 30% { opacity:1 } }

/* While a reading streams, a slow shimmer crosses the card so the wait reads
   as the oracle working rather than the app hanging. */
.reading:empty::after,
.dots {
  background: linear-gradient(90deg,
    var(--muted) 20%, var(--sys-accent) 50%, var(--muted) 80%);
  background-size: 200% auto;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: shimmer 2.4s linear infinite;
}
@keyframes shimmer {
  to { background-position: -200% center }
}

/* The primary button sweeps a highlight across itself, which reads as latent
   energy on the one control that starts a reading. */
.primary { position: relative; overflow: hidden; }
.primary::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg,
    transparent 35%,
    color-mix(in srgb, #fff 38%, transparent) 50%,
    transparent 65%);
  transform: translateX(-100%);
  animation: sweep 3.6s ease-in-out infinite;
  pointer-events: none;
}
@keyframes sweep {
  0%, 55% { transform: translateX(-100%) }
  100%    { transform: translateX(100%) }
}
.primary:disabled::after { animation: none; opacity: 0 }

/* Sections rise as they appear, so a result assembles rather than snapping in. */
#framing, #suggest, .reading { animation: rise 480ms ease both }
#framing { animation-delay: 60ms }
.reading { animation-delay: 120ms }
@keyframes rise {
  from { opacity: 0; transform: translateY(10px) }
  to   { opacity: 1; transform: none }
}

@media (prefers-reduced-motion: reduce) {
  .dots, .primary::after, #framing, #suggest, .reading { animation: none }
  .dots { color: var(--muted); -webkit-text-fill-color: currentColor }
  .primary::after { display: none }
}

.disclaimer {
  text-align: center;
  font-size: 11px;
  color: var(--muted);
  padding: 18px 24px 0;
  line-height: 1.6;
}
