/* ==========================================================================
   ghostline — base.css
   Reset, typography, layout skeleton, utility classes, ghostline animations.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Self-hosted fonts (S2.D audit fix 2026-04-23)

   Inter (OFL) + JetBrains Mono (OFL) served from /admin/static/fonts/.
   Replaces the previous `@import url(fonts.googleapis.com)` in tokens.css
   which was failing with CORS errors on every page load (26/26 captures
   in tests/ui/audit-2026-04-23/).

   font-display: swap — show fallback immediately, swap in the downloaded
   face when ready. Zero layout jank on slow/offline networks.
   -------------------------------------------------------------------------- */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: local('Inter Regular'), local('Inter-Regular'),
       url('../fonts/Inter-Regular.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: local('Inter Medium'), local('Inter-Medium'),
       url('../fonts/Inter-Medium.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: local('Inter SemiBold'), local('Inter-SemiBold'),
       url('../fonts/Inter-SemiBold.woff2') format('woff2');
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: local('JetBrains Mono'), local('JetBrainsMono-Regular'),
       url('../fonts/JetBrainsMono-Regular.woff2') format('woff2');
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: local('JetBrains Mono Medium'), local('JetBrainsMono-Medium'),
       url('../fonts/JetBrainsMono-Medium.woff2') format('woff2');
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body,
h1, h2, h3, h4, h5, h6,
p, figure, blockquote,
ul, ol, dl, dd {
  margin: 0;
  padding: 0;
}

ul[role="list"],
ol[role="list"] {
  list-style: none;
}

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  min-height: 100vh;
  background-color: var(--gl-bg-app);
  background-image:
    radial-gradient(80% 60% at 20% 0%, rgba(74, 191, 140, 0.05), transparent 60%),
    radial-gradient(60% 60% at 100% 100%, rgba(62, 42, 85, 0.14), transparent 55%);
  background-attachment: fixed;
  color: var(--gl-ink);
  font-family: var(--font-ui);
  font-size: var(--fs-md);
  font-weight: var(--fw-regular);
  line-height: var(--lh-normal);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-feature-settings: "zero", "ss01", "cv11";
  position: relative;
}

img,
picture,
svg,
video,
canvas {
  display: block;
  max-width: 100%;
}

input,
button,
textarea,
select {
  font: inherit;
  color: inherit;
}

button {
  background: none;
  border: none;
  cursor: pointer;
}

/* --------------------------------------------------------------------------
   Typography
   -------------------------------------------------------------------------- */

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-display);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-tight);
  color: var(--gl-ink);
  letter-spacing: -0.01em;
}

h1 {
  font-size: var(--fs-2xl);
  color: var(--gl-ink);
}

h2 { font-size: var(--fs-xl); }
h3 { font-size: var(--fs-lg); }

h4 {
  font-size: var(--fs-md);
  text-transform: uppercase;
  letter-spacing: var(--letter-spacing-caps);
  color: var(--gl-low);
  font-weight: var(--fw-medium);
}

p {
  color: var(--gl-dim);
  font-size: var(--fs-md);
  line-height: var(--lh-normal);
}

small,
.text-sm {
  font-size: var(--fs-sm);
  color: var(--gl-low);
}

code, kbd, pre, samp {
  font-family: var(--font-mono);
  font-size: 0.92em;
  font-variant-numeric: tabular-nums;
}

pre {
  background: var(--gl-bg-inset);
  border: 1px solid var(--gl-rule);
  border-radius: var(--radius-sm);
  padding: var(--space-3);
  overflow-x: auto;
  color: var(--gl-ink);
}

code {
  padding: 1px 4px;
  background: var(--gl-bg-inset);
  border-radius: var(--radius-xs);
  color: var(--gl-phos);
}

pre code {
  padding: 0;
  background: transparent;
  border-radius: 0;
}

/* --------------------------------------------------------------------------
   Links, selection, focus
   -------------------------------------------------------------------------- */

a {
  color: var(--accent);
  text-decoration: none;
  transition: color var(--motion-fast), text-shadow var(--motion-fast);
}

a:hover {
  color: var(--accent-deep);
  text-shadow: 0 0 6px var(--accent-glow);
}

a:visited {
  color: var(--accent);
}

::selection {
  background-color: var(--accent-glow);
  color: var(--gl-ink);
}

:focus { outline: none; }

:focus-visible {
  outline: 1px solid var(--accent);
  outline-offset: 1px;
  box-shadow: 0 0 0 3px var(--accent-glow);
  border-radius: var(--radius-xs);
}

/* --------------------------------------------------------------------------
   Scrollbars
   -------------------------------------------------------------------------- */

* {
  scrollbar-width: thin;
  scrollbar-color: rgba(74, 191, 140, 0.25) var(--gl-bg-inset);
}

::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

::-webkit-scrollbar-track {
  background: var(--gl-bg-inset);
}

::-webkit-scrollbar-thumb {
  background: rgba(74, 191, 140, 0.22);
  border-radius: var(--radius-xs);
  border: 2px solid var(--gl-bg-inset);
}

::-webkit-scrollbar-thumb:hover {
  background: var(--gl-phos);
}

::-webkit-scrollbar-corner {
  background: var(--gl-bg-inset);
}

/* --------------------------------------------------------------------------
   Layout skeleton
   -------------------------------------------------------------------------- */

.container {
  max-width: var(--layout-max);
  margin: 0 auto;
  padding: var(--space-4);
}

.layout {
  display: grid;
  grid-template-columns: var(--rail-w) 1fr;
  /* Session 14 NAV2 убрал top-header и bundle-tabs над контентом — у нас
     только левый sidebar. Layout должен растягиваться на весь viewport,
     иначе chat-messenger (100vh - 92px) оставляет пустую полосу снизу. */
  min-height: 100vh;
  position: relative;
  z-index: 1;
}

.layout__main {
  background: transparent;
  padding: var(--space-4);
  overflow-x: auto;
  position: relative;
}

/* --------------------------------------------------------------------------
   Page titles
   -------------------------------------------------------------------------- */

.page-title {
  font-size: var(--fs-2xl);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-tight);
  color: var(--gl-ink);
  letter-spacing: -0.01em;
  margin-bottom: var(--space-4);
  font-family: var(--font-display);
}

.section-title {
  font-size: var(--fs-xl);
  font-weight: var(--fw-semibold);
  color: var(--gl-ink);
  margin-bottom: var(--space-3);
  font-family: var(--font-display);
}

/* --------------------------------------------------------------------------
   Utility classes
   -------------------------------------------------------------------------- */

.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.text-xs { font-size: var(--fs-xs); }
.text-sm { font-size: var(--fs-sm); }
.text-md { font-size: var(--fs-md); }
.text-muted { color: var(--gl-dim); }
.text-dim   { color: var(--gl-low); }
.text-fg-0  { color: var(--gl-ink); }
.text-fg-1  { color: var(--gl-dim); }
.text-fg-brand { color: var(--gl-phos); text-shadow: 0 0 6px var(--gl-phos-glow); }

.uppercase-eyebrow {
  text-transform: uppercase;
  letter-spacing: var(--letter-spacing-caps);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  color: var(--gl-low);
}

.hidden { display: none !important; }
.flex { display: flex; }
.flex-col { display: flex; flex-direction: column; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-1 { gap: var(--space-1); }
.gap-2 { gap: var(--space-2); }
.gap-3 { gap: var(--space-3); }
.gap-4 { gap: var(--space-4); }

/* --------------------------------------------------------------------------
   HTMX loading states
   -------------------------------------------------------------------------- */

.htmx-request { cursor: wait; }

.htmx-indicator {
  opacity: 0;
  transition: opacity var(--motion-fast);
}

.htmx-request .htmx-indicator,
.htmx-request.htmx-indicator {
  opacity: 1;
}

body.htmx-request::before {
  content: "";
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 1px;
  background: var(--accent);
  box-shadow: 0 0 8px var(--accent-glow);
  animation: htmx-progress 120ms linear infinite;
  z-index: 9999;
}

@keyframes htmx-progress {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(100%); }
}

/* ==========================================================================
   GHOSTLINE — motion / glass / magnetic / cursor-glow
   ========================================================================== */

/* ——— premium motion ——— */
@keyframes gl-breathe {
  0%, 100% { opacity: .55; transform: scale(1); }
  50%      { opacity: .95; transform: scale(1.06); }
}
@keyframes gl-shimmer {
  0%   { background-position: -200% 0; }
  100% { background-position:  200% 0; }
}
@keyframes gl-pulse-dot {
  0%, 100% { box-shadow: 0 0 0 0 var(--gl-phos-glow), 0 0 6px var(--gl-phos-glow); }
  50%      { box-shadow: 0 0 0 6px rgba(0, 0, 0, 0), 0 0 10px var(--gl-phos-glow); }
}
@keyframes gl-caret {
  0%, 49%  { opacity: 1; }
  50%, 100% { opacity: 0; }
}
@keyframes gl-rise {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes gl-slide-in-l {
  from { opacity: 0; transform: translateX(-6px); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes gl-slide-in-r {
  from { opacity: 0; transform: translateX(6px); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes gl-scan {
  0%   { transform: translateY(-100%); }
  100% { transform: translateY(900px); }
}
@keyframes gl-orbit {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
@keyframes gl-type-dot {
  0%, 60%, 100% { transform: translateY(0); opacity: .35; }
  30%           { transform: translateY(-3px); opacity: 1; }
}

.gl-rise    { animation: gl-rise .55s var(--ease-gl) both; }
.gl-in-l    { animation: gl-slide-in-l .5s var(--ease-gl) both; }
.gl-in-r    { animation: gl-slide-in-r .5s var(--ease-gl) both; }
.gl-breathe { animation: gl-breathe 4.5s ease-in-out infinite; }
.gl-pulse   { animation: gl-pulse-dot 2.2s ease-in-out infinite; }
.gl-caret   { animation: gl-caret 1.06s steps(1) infinite; display: inline-block; }
.gl-orbit   { animation: gl-orbit 24s linear infinite; display: inline-flex; }

.gl-shimmer {
  background-image: linear-gradient(110deg,
    transparent 20%,
    rgba(255, 255, 255, 0.08) 45%,
    rgba(255, 255, 255, 0.18) 50%,
    rgba(255, 255, 255, 0.08) 55%,
    transparent 80%);
  background-size: 200% 100%;
  animation: gl-shimmer 3.2s ease-in-out infinite;
}

/* ——— liquid glass surface ——— */
.gl-glass {
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0.008) 40%, rgba(0, 0, 0, 0.08)),
    radial-gradient(120% 80% at 0% 0%, rgba(180, 255, 220, 0.05), transparent 55%);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  border: 1px solid transparent;
  background-clip: padding-box;
  position: relative;
}
.gl-glass::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(135deg,
    rgba(255, 255, 255, 0.18),
    rgba(255, 255, 255, 0.02) 40%,
    rgba(255, 255, 255, 0.12) 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  pointer-events: none;
}

/* ——— magnetic cursor glow (JS sets --mx/--my on .gl-cursor-host) ——— */
.gl-cursor-host { position: relative; }
.gl-cursor-glow {
  position: fixed;
  pointer-events: none;
  z-index: 0;
  width: 520px;
  height: 520px;
  left: var(--mx, 50%);
  top: var(--my, 50%);
  transform: translate(-50%, -50%);
  background: radial-gradient(circle, var(--gl-phos-glow) 0%, transparent 65%);
  opacity: .28;
  filter: blur(44px);
  transition: left .6s var(--ease-gl), top .6s var(--ease-gl), opacity .4s;
  mix-blend-mode: screen;
}

/* ——— magnetic button ——— */
.gl-magnetic {
  transition: transform .35s var(--ease-gl), box-shadow .35s ease;
  will-change: transform;
}
.gl-magnetic:hover {
  transform: translateY(-1px) scale(1.03);
  box-shadow: 0 8px 24px var(--gl-phos-glow), 0 0 0 4px rgba(167, 240, 208, 0.08);
}

/* ——— row hover refraction ——— */
.gl-row {
  position: relative;
  overflow: hidden;
  transition: background .25s ease, color .25s ease, padding .25s ease;
}
.gl-row::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, rgba(167, 240, 208, 0.06), transparent);
  transform: translateX(-100%);
  transition: transform .6s var(--ease-gl);
  pointer-events: none;
}
.gl-row:hover::after { transform: translateX(100%); }
.gl-row:hover       { background: rgba(167, 240, 208, 0.05); }

/* ——— input focus glow ——— */
.gl-composer {
  transition: border-color .3s ease, box-shadow .4s ease, transform .3s ease;
}
.gl-composer:focus-within {
  box-shadow: 0 0 0 4px var(--accent-glow), 0 12px 40px rgba(0, 0, 0, 0.4);
  border-color: var(--accent);
}

/* ——— scanline band ——— */
.gl-scanband {
  position: absolute;
  left: 0;
  right: 0;
  height: 120px;
  pointer-events: none;
  background: linear-gradient(180deg, transparent, rgba(167, 240, 208, 0.06), transparent);
  animation: gl-scan 8s linear infinite;
  mix-blend-mode: screen;
}

/* ——— typing dots ——— */
.gl-typing {
  display: inline-flex;
  gap: 3px;
  align-items: center;
}
.gl-typing span {
  width: 5px;
  height: 5px;
  border-radius: 99px;
  background: var(--gl-phos);
  display: inline-block;
}
.gl-typing span:nth-child(1) { animation: gl-type-dot 1.2s ease-in-out 0ms infinite; }
.gl-typing span:nth-child(2) { animation: gl-type-dot 1.2s ease-in-out 180ms infinite; }
.gl-typing span:nth-child(3) { animation: gl-type-dot 1.2s ease-in-out 360ms infinite; }

/* ——— ambient background wash ——— */
.gl-ambient {
  position: fixed;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(80% 60% at 20% 0%, rgba(74, 191, 140, 0.06), transparent 60%),
    radial-gradient(60% 60% at 100% 100%, rgba(62, 42, 85, 0.14), transparent 55%);
  z-index: 0;
}

/* ——— phosphor glow text ——— */
.gl-phos-text {
  color: var(--gl-phos);
  text-shadow: 0 0 6px var(--gl-phos-glow);
}

.gl-gradient-text {
  background: linear-gradient(180deg, var(--gl-ink), var(--gl-phos-deep));
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

/* ——— reduced motion ——— */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  .gl-cursor-glow { display: none; }
}
