/* shared/base.css — the single entry imported by every admin HTML.
 *
 * Every admin page has `<link rel="stylesheet" href="../shared/base.css">`.
 * To keep that contract intact, this file is now a THIN COMPOSITION ROOT:
 * it @imports the topical files (which MUST come before any rules per CSS
 * spec) and then declares only the cross-file primitives — design tokens,
 * the universal box-sizing reset, body/html resets, and the fixed canvas
 * layers used by background.js.
 *
 * Load order matters. The split files below are ordered so the cascade
 * produces the SAME result as the old single-file base.css:
 *
 *   glass.css          liquid-glass surfaces, .card-glass, .icon-badge,
 *                      prefers-reduced-transparency fallback.
 *   buttons.css        global button transitions, .liquid-glass-btn,
 *                      .pill-btn variants, .input-glass, range slider.
 *                      Loaded AFTER glass so `button {…}` wins over any
 *                      button-shaped liquid-glass-dark child.
 *   shell.css          .dashboard-shell, .topbar, .main, .page-content,
 *                      stagger-in keyframes.
 *   nav.css            .sidebar, .nav-item, .btn-logout, .sidebar-backdrop.
 *   ph-placeholder.css .ph-wrap / .ph-card / .placeholder empty-state.
 *   toast.css          .toast-container, .toast, toast-in/out keyframes.
 *   mobile.css         ALL @media (max-width:767px) + tablet breakpoint.
 *                      Must be LAST so media overrides beat every rule above.
 *
 * Anything global that doesn't fit in one of those buckets stays at the
 * bottom of this file. Keep this file under ~150 lines (it's currently
 * well under budget).
 */

/* v= param on each @import is REQUIRED — browsers don't inherit the
   parent stylesheet's query string, so `base.css?v=N` alone busts cache
   for base.css only. Without ?v on each import, mobile.css / nav.css
   etc. get served from stale cache forever after first load. Bump these
   numbers whenever you touch the respective file. */
@import url('glass.css?v=2026042504');
@import url('buttons.css?v=2026042412');
@import url('shell.css?v=2026042239');
@import url('nav.css?v=2026042418');
@import url('ph-placeholder.css?v=2026042239');
@import url('toast.css?v=2026042239');
@import url('mobile.css?v=2026042239');

:root {
  --accent: 244,63,94;
  --accent-text: #fff;
  /* Semantic "destructive" red — INTENTIONALLY independent of --accent.
     Red is the universal "dangerous action" color (delete, logout, empty trash),
     so it MUST stay red across every theme — including white-accent palettes
     (black / carbon / custom). Use `rgb(var(--danger))` / `rgba(var(--danger), a)`
     for delete buttons, destructive card borders, trash hover states, etc. */
  --danger: 244,63,94;
  /* Semantic "positive" green — used for revenue deltas, status pills
     ("Paid", "Active"), match-up arrows. Also independent of --accent
     so green stays green across every theme. rgb(52,211,153) = #34d399. */
  --success: 52,211,153;

  /* ── Design tokens (shared across all pages — extracted from the editor) ── */
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-bounce: cubic-bezier(0.34, 1.36, 0.64, 1);
  --radius-sm: 10px;
  --radius-md: 14px;
  --radius-lg: 18px;

  /* Glass card surface — neutral white-on-dark gradient.
     Alpha bumped 0.045/0.018 → 0.07/0.028 so cards stay visible even
     when backdrop-filter is muted (mobile WebView nested-filter context
     defeats child blur per CSS spec; юзер: «на телефонной версии
     не работает размытие фона хотя на пк работает»).
     На desktop blur всё ещё работает as enhancement, на mobile cards
     читаются как frosted plates за счёт самого base'а. */
  --glass-bg:
    linear-gradient(180deg, rgba(255,255,255,0.07) 0%, rgba(255,255,255,0.028) 100%);
  --glass-border: 1px solid rgba(255,255,255,0.07);
  --glass-border-hover: 1px solid rgba(255,255,255,0.11);
  --glass-shadow:
    inset 0 1px 0 rgba(255,255,255,0.05),
    inset 0 -1px 0 rgba(0,0,0,0.18),
    0 2px 10px -6px rgba(0,0,0,0.3);
  /* Hover shadow used to have an outer cast `0 8px 24px -10px rgba(0,0,0,0.45)`
     which read as a heavy drop-shadow under every card on mouse-over — user
     feedback: "уебищная тень появляется хотя это жидкое стекло, какие нахуй
     тени". Now it's inset-only: a slightly brighter top highlight so glass
     "catches light" without casting anywhere. The lift effect comes from
     transform: translateY on :hover (see each card's rule), not a shadow. */
  --glass-shadow-hover:
    inset 0 1px 0 rgba(255,255,255,0.09),
    inset 0 -1px 0 rgba(0,0,0,0.18);
  /* Liquid-glass hover ease — iterative v5.
     User said 0.55s + scale(1.012) still felt "моментально". The fix:
     (a) longer duration 0.7s, (b) ease-out-cubic-like curve that spreads
     motion more evenly across the timeline (0.2,0.8,... is strong
     front-loaded decel = looks instant then holds), (c) slightly bigger
     scale 1.02 so the distance is visible enough to register as motion.
     Together: a card that visibly grows over ~0.7s, like it has mass. */
  /* v12 final — even snappier per "0.1 сделай". 100ms + 1% scale =
     near-instant micro-pop. Verging on "no animation" territory but
     still visibly animated on 60fps displays (~6 frames of motion). */
  --ease-spring: cubic-bezier(0.4, 0, 0.2, 1);
  --spring-dur: 0.1s;

  /* ── Unified popover / dropdown / floating-menu surface ──
     v2: user said v1 was "ни разу не замутнён" — профиль-карточка behind
     was readable through the popover. Switched to the exact recipe of
     `.ch-ticket-modal` which user called out as "реализовано ровно то
     что я хотел бы видеть": rgba(0,0,0,0.35) + blur(40px). Dropped
     saturate(0) that made the ticket modal greyscale — kept full colour
     saturation so the popover stays warm on custom wallpapers. */
  --popover-bg: rgba(0, 0, 0, 0.35);
  --popover-border: 1px solid rgba(255, 255, 255, 0.1);
  --popover-blur: blur(40px) saturate(1.1);
  --popover-shadow:
    0 16px 44px rgba(0, 0, 0, 0.5),
    0 4px 12px rgba(0, 0, 0, 0.3),
    inset 0 1px 0 rgba(255, 255, 255, 0.08);
  --popover-radius: 16px;

  /* ── Frosted-glass noise grain ──
     Inline SVG data URL that was previously duplicated verbatim across
     .ch-presets, .ch-ticket-modal, .ch-lang-pop, .prs-filter-menu,
     .regs-pagination, chats/sidebar, paid-photo pickers, mobile sidebar,
     and the .liquid-glass-dark primitive in glass.css. Same 200×200
     fractalNoise pattern + 0.65 baseFrequency + 3 octaves. Reference it
     as `background-image: var(--glass-grain);` in any ::before rule.
     Keep opacity 0.03–0.05 — that's the sweet spot where the grain reads
     as texture without looking like TV static. */
  --glass-grain: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E");
  /* Blur + saturate(0.55) — this is the root cause of the "red tint on all
     glass elements" bug. Previously used saturate(1.1) which BOOSTED the
     warm body-bg (red radial blobs + pink avatar gradients) by 10% through
     every glass surface, painting every card/toolbar/popup slightly warmer.
     Dropping below 1.0 desaturates whatever bleeds through, so warm tones
     read as neutral grey rather than pink.  Kept at 0.55 (not 0) so a hint
     of depth/colour variation stays perceptible on real wallpapers — full
     zero looks artificially flat. */
  --glass-blur: blur(18px) saturate(0.55);

  /* Mobile WebView consistently breaks backdrop-filter on elements that
     live inside an ancestor with its own backdrop-filter (.dashboard-shell
     does blur(22) on the wallpaper canvas). Result: child blur is muted,
     frosted-glass cards read as plain dark plates. Юзер: «на телефонной
     версии не работает размытие фона хотя на пк работает».
     Fix: kill backdrop-filter on small screens entirely — the bumped
     base alpha (--glass-bg above) already gives cards a frosted look,
     and dropping the filter saves the GPU thrashing it'd do trying. */

  /* ═══════════════════════════════════════════════════════════════════════
     LIQUID GLASS — user-supplied reference recipe, 1:1 for the block
     surface (background / border / shadow) and the backdrop-filter chain.
     ═══════════════════════════════════════════════════════════════════════ */
  --glass-liquid-bg: rgba(255, 255, 255, 0.03);
  --glass-liquid-border: 0.5px solid rgba(255, 255, 255, 0.2);
  --glass-liquid-filter: blur(30px) saturate(180%) brightness(1.2) url(#liquid-refraction);
  --glass-liquid-shadow:
    0 20px 40px rgba(0, 0, 0, 0.4),
    inset 0 1px 1px rgba(255, 255, 255, 0.3),
    inset 0 -1px 20px rgba(255, 255, 255, 0.05);

  /* Reduced-transparency fallback — respect system setting. */
  --glass-liquid-bg-solid: rgba(22, 22, 26, 0.96);

  /* Typography */
  --label-color: rgba(255,255,255,0.35);
  --label-size: 11px;
  --label-letterspace: 0.04em;
  --section-color: rgba(255,255,255,0.72);
  --section-size: 10.5px;
  --section-letterspace: 0.14em;
  --body-color: rgba(255,255,255,0.88);
  /* WCAG AA: 0.40 на тёмном фоне = ~3.9:1 contrast (fail для normal text).
     0.55 = ~5.6:1 — passes AA для normal + AAA для large.
     Юзер: «серый мелкий текст иногда сливается с фоном на плохих мониторах». */
  --muted-color: rgba(255,255,255,0.55);
}

/* Mobile glass: keep backdrop-filter ON (юзер: «на телефонах везде фон
   должен быть заблюренный»). Modern Chrome/Safari mobile DO render some
   blur even in nested filter context — not as crisp as desktop, but
   visible. Bumped --glass-bg alpha (above) compensates if filter is
   muted. Don't strip blur globally — wastes the effect where it works. */

/* Universal reset — every element box-models the same way, no default
   browser margin / padding. */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* ── Global font-smoothing — fix for "hover-blur" bug ──
   When an element transitions via `transform` (translate, scale, etc.),
   the browser promotes it to its own GPU compositing layer. Default
   subpixel antialiasing (LCD-optimized) doesn't survive this promotion —
   mid-animation the text re-rasterises as a bitmap and reads as
   "blurred" until the transform settles. Forcing grayscale AA at the
   <html> level keeps text crisp through every transform, because
   grayscale AA is rasterisation-independent.
   Affects 100% of pages — do NOT add `transform: translateZ(0)` globally,
   that would force every element onto its own layer and tank memory. */
html {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

/* ── a11y: visually-hidden utility (for screen-reader only labels) ──
   !important on the position/width/height is standard Bootstrap-style
   to win over any page-level rule that accidentally makes such elements
   visible. */
.sr-only {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
  white-space: nowrap;
  border: 0;
}

/* ── Respect OS accessibility setting: reduce motion for animation-sensitive users ──
   v2: KILLED the `transition-duration: 0.001ms !important` line because
   it was silently nuking every hover transition on the page for users who
   have "Animation effects: Off" set in Windows 11 (common default on laptop
   battery-savers). Symptom: user sees `transform: scale(1.04)` applying
   but NO animation, element just snaps. Root cause: reduced-motion is
   about AUTO-PLAYING animations (carousels, parallax, marquees) — not
   user-triggered hover transitions. Hover is consensual motion: user
   chose to hover, they get the feedback. Leaving `animation-duration`
   killswitch in place so infinite-loop animations still get muted. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
}

body {
  min-height: 100vh;
  background: #000;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  position: relative;
}

/* ── Canvas layers (background.js writes into these) ── */
#bgCanvas, #grainCanvas {
  position: fixed;
  inset: 0;
  pointer-events: none;
}
#bgCanvas { z-index: 0; }
#grainCanvas {
  z-index: 1;
  opacity: 0.3;
  mix-blend-mode: overlay;
}

/* ── Small cross-page animations used by a handful of components ── */
@keyframes fade-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes blink-live {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0.2; }
}
