/*
 * theme.css - design tokens and primitives.
 *
 * The visual language is a neutral, flat, low-radius system: achromatic greys carry
 * the whole interface and colour is reserved for state (success, warning, danger)
 * and prize rarity. Nothing here targets a feature; features compose these.
 *
 * Tokens are plain CSS custom properties in oklch, so a lightness tweak never
 * shifts hue and both themes stay on one scale. theme-boot.js sets
 * document.documentElement.dataset.theme before first paint, so [data-theme]
 * is the single switch - no flash, no class juggling.
 *
 * Scale: every surface is one of background < card < popover, every separation is
 * --border, every radius derives from --radius. If a component needs a value that
 * is not here, the token is missing, not the component.
 */

:root,
:root[data-theme="light"] {
  color-scheme: light;

  --background: oklch(100% 0 0);
  --foreground: oklch(14.5% 0 0);
  --card: oklch(100% 0 0);
  --card-foreground: oklch(14.5% 0 0);
  --popover: oklch(100% 0 0);
  --popover-foreground: oklch(14.5% 0 0);

  /* "primary" is the inverted surface: a near-black button on a white page. */
  --primary: oklch(20.5% 0 0);
  --primary-foreground: oklch(98.5% 0 0);
  --secondary: oklch(97% 0 0);
  --secondary-foreground: oklch(20.5% 0 0);
  --muted: oklch(97% 0 0);
  --muted-foreground: oklch(55.6% 0 0);
  --accent: oklch(97% 0 0);
  --accent-foreground: oklch(20.5% 0 0);

  --destructive: oklch(57.7% 0.245 27.325);
  --success: oklch(56% 0.15 155);
  --warning: oklch(66% 0.15 70);
  --info: oklch(50% 0 0);

  --border: oklch(92.2% 0 0);
  --input: oklch(92.2% 0 0);
  --ring: oklch(70.8% 0 0);

  --shadow-sm: 0 1px 2px oklch(0% 0 0 / 0.05);
  --shadow-md: 0 4px 12px oklch(0% 0 0 / 0.08);
  --shadow-lg: 0 16px 48px oklch(0% 0 0 / 0.12);
}

:root[data-theme="dark"] {
  color-scheme: dark;

  --background: oklch(16% 0 0);
  --foreground: oklch(97% 0 0);
  --card: oklch(18.5% 0 0);
  --card-foreground: oklch(97% 0 0);
  --popover: oklch(19.5% 0 0);
  --popover-foreground: oklch(97% 0 0);

  --primary: oklch(96% 0 0);
  --primary-foreground: oklch(20% 0 0);
  --secondary: oklch(21.5% 0 0);
  --secondary-foreground: oklch(97% 0 0);
  --muted: oklch(21.5% 0 0);
  --muted-foreground: oklch(66% 0 0);
  --accent: oklch(22.5% 0 0);
  --accent-foreground: oklch(97% 0 0);

  --destructive: oklch(68% 0.17 24);
  --success: oklch(74% 0.11 155);
  --warning: oklch(80% 0.11 80);
  --info: oklch(72% 0 0);

  /* Borders are alpha, not a fixed grey, so a card on a card still separates. */
  --border: oklch(100% 0 0 / 0.08);
  --input: oklch(100% 0 0 / 0.11);
  --ring: oklch(60% 0 0);

  --shadow-sm: 0 1px 2px oklch(0% 0 0 / 0.3);
  --shadow-md: 0 4px 12px oklch(0% 0 0 / 0.4);
  --shadow-lg: 0 16px 48px oklch(0% 0 0 / 0.55);
}

:root {
  /* One radius seeds the scale; components never hardcode a corner. */
  --radius: 0.625rem;
  --radius-sm: calc(var(--radius) - 4px);
  --radius-md: calc(var(--radius) - 2px);
  --radius-lg: var(--radius);
  --radius-xl: calc(var(--radius) + 4px);
  --radius-pill: 9999px;

  --font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;

  /* 4px grid. Mobile-first: these are the phone values, widened at >=720px. */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;

  --text-xs: 0.6875rem;
  --text-sm: 0.8125rem;
  --text-base: 0.875rem;
  --text-md: 1rem;
  --text-lg: 1.125rem;
  --text-xl: 1.5rem;
  --text-2xl: 2rem;

  /* Rarity is a monochrome ramp from quiet grey to full foreground: the rarer
     the prize, the stronger the ink. The word always comes with it, so the
     scale never depends on telling shades apart. */
  --rarity-common: color-mix(in oklch, var(--foreground) 52%, var(--background));
  --rarity-uncommon: color-mix(in oklch, var(--foreground) 64%, var(--background));
  --rarity-rare: color-mix(in oklch, var(--foreground) 76%, var(--background));
  --rarity-epic: color-mix(in oklch, var(--foreground) 88%, var(--background));
  --rarity-legendary: var(--foreground);

  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --duration-fast: 120ms;
  --duration-base: 200ms;
  --duration-slow: 420ms;

  /* Telegram puts its own chrome over the viewport; panels respect the inset. */
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
}

@media (min-width: 720px) {
  :root {
    --text-base: 0.9375rem;
    --text-xl: 1.75rem;
    --text-2xl: 2.5rem;
  }
}

/* ---------------------------------------------------------------- base --- */

/* The hidden attribute must win over any component's display rule: the
   browser's own [hidden] { display: none } loses to a single class selector,
   which silently leaves "hidden" footers, lists and language blocks on screen. */
[hidden] { display: none !important; }

.t-root {
  background: var(--background);
  color: var(--foreground);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

.t-root :focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

.t-mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.t-muted { color: var(--muted-foreground); }

/* Section heading: a display line plus one muted line, nothing else. */
.t-title {
  margin: 0;
  font-size: var(--text-xl);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.15;
}

.t-subtitle {
  margin: var(--space-1) 0 0;
  color: var(--muted-foreground);
  font-size: var(--text-sm);
}

.t-label {
  color: var(--muted-foreground);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* ---------------------------------------------------------------- card --- */

.t-card {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--card);
  color: var(--card-foreground);
}

.t-card-pad { padding: var(--space-4); }

/* Header strip inside a card: the "General" / "Premium lounge" bar on a forum
   group. Flush to the card's top corners, separated by one hairline. */
.t-card-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0.625rem var(--space-4);
  border-bottom: 1px solid var(--border);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  background: var(--muted);
  font-size: var(--text-sm);
  font-weight: 600;
}

/* Rows stack inside a card and divide themselves; the last one never doubles
   the card's own bottom border. */
.t-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 0.625rem var(--space-4);
  border-bottom: 1px solid var(--border);
}

.t-row:last-child { border-bottom: 0; }

.t-row-link {
  color: inherit;
  text-decoration: none;
  transition: background var(--duration-fast) var(--ease-out);
}

.t-row-link:hover { background: var(--accent); }

/* -------------------------------------------------------------- button --- */

.t-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  /* 40px on touch screens, 36px under a mouse (Telegram Desktop, web). */
  min-height: 2.5rem;
  padding: 0 0.875rem;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  background: var(--primary);
  color: var(--primary-foreground);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background var(--duration-fast) var(--ease-out),
    opacity var(--duration-fast) var(--ease-out),
    transform var(--duration-fast) var(--ease-out);
}

.t-btn:active { transform: scale(0.98); }
.t-btn[disabled] { opacity: 0.5; cursor: not-allowed; transform: none; }

.t-btn-secondary {
  border-color: var(--border);
  background: var(--secondary);
  color: var(--secondary-foreground);
}

.t-btn-secondary:hover:not([disabled]) { background: var(--accent); }

.t-btn-ghost {
  background: transparent;
  color: var(--foreground);
}

.t-btn-ghost:hover:not([disabled]) { background: var(--accent); }

.t-btn-danger { background: var(--destructive); color: oklch(100% 0 0); }

.t-btn-sm { min-height: 2.125rem; padding: 0 var(--space-3); font-size: var(--text-xs); }

@media (pointer: fine) {
  .t-btn { min-height: 2.25rem; }
  .t-btn-sm { min-height: 1.875rem; }
}

/* --------------------------------------------------------------- badge --- */

.t-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 0.125rem var(--space-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--secondary);
  color: var(--secondary-foreground);
  font-size: var(--text-xs);
  font-weight: 600;
  line-height: 1.6;
}

/* Rarity reads as a word first and a colour second, so it survives a
   colour-blind viewer and a greyscale screenshot alike. */
.t-rarity { font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.04em; }
.t-rarity-common { color: var(--rarity-common); }
.t-rarity-uncommon { color: var(--rarity-uncommon); }
.t-rarity-rare { color: var(--rarity-rare); }
.t-rarity-epic { color: var(--rarity-epic); }
.t-rarity-legendary { color: var(--rarity-legendary); }

/* A dot that states presence without relying on colour alone elsewhere. */
.t-dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: var(--radius-pill);
  background: var(--muted-foreground);
  flex: none;
}

.t-dot-online { background: var(--success); }

/* ---------------------------------------------------------------- tabs --- */

/* Tabs wrap onto a second row instead of scrolling sideways: nothing is ever
   cut off at the edge of a narrow Telegram window. */
.t-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  padding: var(--space-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--muted);
}

.t-tabs::-webkit-scrollbar { display: none; }

.t-tab {
  flex: 1 1 auto;
  justify-content: center;
  min-height: 2rem;
  padding: 0 0.625rem;
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--muted-foreground);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 500;
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-out);
}

.t-tab[aria-selected="true"] {
  background: var(--card);
  color: var(--foreground);
  box-shadow: var(--shadow-sm);
}

/* --------------------------------------------------------------- table --- */

.t-table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }

.t-table th {
  padding: 0.5625rem 0.875rem;
  border-bottom: 1px solid var(--border);
  background: var(--muted);
  color: var(--muted-foreground);
  font-weight: 500;
  text-align: left;
}

.t-table td {
  padding: 0.5625rem 0.875rem;
  border-bottom: 1px solid var(--border);
}

.t-table tr:last-child td { border-bottom: 0; }
.t-table .t-num { text-align: right; font-variant-numeric: tabular-nums; }

/* --------------------------------------------------------------- input --- */

.t-input {
  width: 100%;
  min-height: 2.5rem;
  padding: 0 var(--space-3);
  border: 1px solid var(--input);
  border-radius: var(--radius-md);
  background: var(--background);
  color: var(--foreground);
  font: inherit;
  font-size: var(--text-sm);
}

.t-input::placeholder { color: var(--muted-foreground); }
.t-textarea { min-height: 6rem; padding: var(--space-3); line-height: 1.6; resize: vertical; }

/* --------------------------------------------------------------- modal --- */

.t-overlay {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: center;
  padding: var(--space-4);
  background: oklch(0% 0 0 / 0.6);
  animation: t-fade var(--duration-base) var(--ease-out);
}

.t-modal {
  width: min(100%, 26rem);
  max-height: calc(100dvh - var(--space-7));
  overflow: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  background: var(--popover);
  color: var(--popover-foreground);
  box-shadow: var(--shadow-lg);
  animation: t-rise var(--duration-base) var(--ease-out);
}

/* -------------------------------------------------------------- states --- */

.t-empty {
  display: grid;
  gap: var(--space-2);
  justify-items: center;
  padding: var(--space-5) var(--space-4);
  color: var(--muted-foreground);
  text-align: center;
}

/* Skeletons reserve the real height, so nothing jumps when data lands. */
.t-skeleton {
  border-radius: var(--radius-md);
  background: linear-gradient(90deg, var(--muted) 25%, var(--accent) 50%, var(--muted) 75%);
  background-size: 200% 100%;
  animation: t-shimmer 1.4s linear infinite;
}

@keyframes t-fade { from { opacity: 0; } }
@keyframes t-rise { from { opacity: 0; transform: translateY(8px) scale(0.98); } }
@keyframes t-shimmer { to { background-position: -200% 0; } }

/* Motion: the OS setting by default ([data-motion="system"]), or the user's own
   choice from Settings, which wins in both directions. */
@media (prefers-reduced-motion: reduce) {
  :root:not([data-motion="full"]) .t-root *,
  :root:not([data-motion="full"]) .t-root *::before,
  :root:not([data-motion="full"]) .t-root *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
  }
}

:root[data-motion="reduced"] .t-root *,
:root[data-motion="reduced"] .t-root *::before,
:root[data-motion="reduced"] .t-root *::after {
  animation-duration: 1ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 1ms !important;
}
