/* ============================================================================
   INGSOC design system — shared foundation for every surface
   (auth · public · cabinet · admin). Loaded first in all four layouts.

   Concept: total surveillance as backdrop (concrete grey-blue, black
   telescreen, party red) pierced by the warm amber lamp of freedom — the
   VPN as quiet resistance. Two themes: light = Ministry daylight,
   dark = telescreen night. All assets self-hosted (no external origins).
   ============================================================================ */

/* --- Self-hosted fonts (variable, subset latin + cyrillic) ---------------- */
@font-face {
  font-family: "Oswald";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/static/fonts/oswald-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Oswald";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/static/fonts/oswald-cyrillic.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("/static/fonts/jetbrains-mono-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("/static/fonts/jetbrains-mono-cyrillic.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

/* --- Tokens: light (Ministry daylight) ----------------------------------- */
:root {
  /* concrete / paper surfaces */
  --bg: #d5d8d6;
  --bg-2: #c7cbca;
  --surface: #eef0ec;
  --surface-2: #e2e5e0;
  --surface-inset: #dadedd;
  --border: #b2b7b8;
  --border-strong: #9aa0a2;
  --text: #171b21;
  --text-strong: #0b0e13;
  --muted: #59626f;

  /* the lamp of freedom (amber) — our product's actions */
  --primary: #955400;        /* readable amber-bronze for links/text on light */
  --primary-dark: #6f3f00;
  --lamp: #d98a1a;           /* amber fill for CTAs */
  --lamp-strong: #c47a10;
  --lamp-ink: #1f1400;       /* dark ink on amber */
  --glow-amber: rgba(217, 138, 26, 0.35);

  /* the Party (red) — surveillance, authority, danger */
  --party: #ad2027;
  --party-soft: rgba(173, 32, 39, 0.12);
  --glow-red: rgba(173, 32, 39, 0.28);

  --accent: var(--primary); /* alias used by inline template styles */
  --success: #2f7d46;
  --warning: #a5650a;
  --danger: #ad2027;

  /* telescreen atmosphere */
  --scan: rgba(10, 14, 20, 0.045);
  --grid-line: rgba(10, 14, 20, 0.05);
  --vignette: rgba(10, 14, 20, 0.14);
  --tele-ink: #10141b;

  --radius: 4px;
  --radius-sm: 2px;
  --radius-lg: 8px;
  --shadow: 0 1px 0 rgba(0, 0, 0, 0.1), 0 2px 10px rgba(20, 24, 30, 0.1);
  --shadow-lg: 0 12px 40px rgba(16, 20, 27, 0.22);

  --font-display: "Oswald", "Arial Narrow", system-ui, sans-serif;
  --font-body: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial,
    sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, "Cascadia Code", monospace;

  /* cursor spotlight position (updated by app.js) */
  --spot-x: 50%;
  --spot-y: 0%;

  /* motion tokens — shared by hover, page enter, flash, busy states */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
  --motion-fast: 0.14s;
  --motion-base: 0.22s;
  --motion-slow: 0.38s;
}

/* --- Tokens: dark (telescreen night) ------------------------------------- */
[data-theme="dark"] {
  --bg: #080a0e;
  --bg-2: #05070a;
  --surface: #10141b;
  --surface-2: #161b23;
  --surface-inset: #0b0e13;
  --border: #262d38;
  --border-strong: #38414f;
  --text: #cdd4de;
  --text-strong: #eef2f7;
  --muted: #78828f;

  --primary: #e6a52c;
  --primary-dark: #f0b84a;
  --lamp: #e6a52c;
  --lamp-strong: #f0b84a;
  --lamp-ink: #170f00;
  --glow-amber: rgba(230, 165, 44, 0.4);

  --party: #d94141;
  --party-soft: rgba(217, 65, 65, 0.14);
  --glow-red: rgba(217, 65, 65, 0.4);

  --accent: var(--primary);
  --success: #48b06a;
  --warning: #e0902a;
  --danger: #d94141;

  --scan: rgba(255, 255, 255, 0.028);
  --grid-line: rgba(255, 255, 255, 0.03);
  --vignette: rgba(0, 0, 0, 0.55);
  --tele-ink: #000000;

  --shadow: 0 2px 12px rgba(0, 0, 0, 0.5);
  --shadow-lg: 0 20px 50px rgba(0, 0, 0, 0.6);
}

/* --- Base reset ---------------------------------------------------------- */
* {
  box-sizing: border-box;
}
::selection {
  background: var(--glow-amber);
  color: var(--text-strong);
}
html {
  -webkit-text-size-adjust: 100%;
  /* backstop behind the fixed .tele-bg layer: overscroll and page edges must
     never flash white — surfaces override body backgrounds to transparent. */
  background: var(--bg);
}
body {
  margin: 0;
  font-family: var(--font-body);
  background: var(--bg);
  color: var(--text);
  font-size: 14px;
  line-height: 1.55;
}
h1,
h2,
h3,
h4 {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--text-strong);
}
a {
  color: var(--primary);
  text-decoration: none;
  transition: color 0.15s ease, opacity 0.15s ease;
}
a:hover {
  text-decoration: underline;
}
code,
kbd,
samp {
  font-family: var(--font-mono);
}

/* Section eyebrow / label — small INGSOC caps */
.eyebrow {
  font-family: var(--font-display);
  text-transform: uppercase;
  letter-spacing: 0.18em;
  font-size: 11px;
  color: var(--muted);
}

/* ============================================================================
   Atmosphere primitives (decorative, always aria-hidden in markup)
   ============================================================================ */

/* Full-viewport telescreen backdrop: concrete wash, surveillance grid,
   vignette, cursor spotlight, and slow scan sweep. */
.tele-bg {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(
      120% 80% at var(--spot-x) var(--spot-y),
      var(--glow-amber),
      transparent 42%
    ),
    linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px),
    radial-gradient(140% 120% at 50% -10%, transparent 55%, var(--vignette)),
    var(--bg);
  background-size: 100% 100%, 34px 34px, 34px 34px, 100% 100%, 100% 100%;
}
/* moving scan bar + fine scanlines layered above the wash */
.tele-bg::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(
    0deg,
    var(--scan) 0,
    var(--scan) 1px,
    transparent 1px,
    transparent 3px
  );
  opacity: 0.6;
  mix-blend-mode: multiply;
}
[data-theme="dark"] .tele-bg::before {
  mix-blend-mode: screen;
}
.tele-bg::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: 30vh;
  top: -30vh;
  background: linear-gradient(
    180deg,
    transparent,
    var(--scan) 60%,
    transparent
  );
  opacity: 0.9;
  animation: tele-sweep 7.5s linear infinite;
}
@keyframes tele-sweep {
  0% {
    transform: translateY(0);
  }
  100% {
    transform: translateY(160vh);
  }
}
/* calm variant (admin control room): no moving sweep, fainter grid */
.tele-bg.calm {
  background-size: 100% 100%, 40px 40px, 40px 40px, 100% 100%, 100% 100%;
}
.tele-bg.calm::after {
  display: none;
}
.tele-bg.calm::before {
  opacity: 0.35;
}

/* The watching eye (Big Brother). Decorative SVG lives in the layout; this
   styles + animates the pupil scan and lid glow. Suppressed on admin. */
.watch-eye {
  position: fixed;
  top: clamp(-48px, -3vw, -12px);
  left: 50%;
  transform: translateX(-50%);
  width: min(72vw, 560px);
  height: auto;
  pointer-events: none;
  z-index: -1;
  opacity: 0.4;
  color: var(--party);
}
.watch-eye .eye-glow {
  fill: currentColor;
}
.watch-eye .eye-lid {
  fill: var(--tele-ink);
  stroke: currentColor;
  stroke-width: 1.5;
}
.watch-eye .eye-ring {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
}
.watch-eye .eye-pupil {
  fill: currentColor;
}
.watch-eye .eye-iris {
  transform-box: fill-box;
  transform-origin: center;
  animation: eye-scan 9s ease-in-out infinite;
}
.watch-eye .eye-glow {
  animation: eye-pulse 5s ease-in-out infinite;
}
@keyframes eye-scan {
  0%,
  100% {
    transform: translateX(-3.5px);
  }
  25% {
    transform: translateX(3.5px);
  }
  50% {
    transform: translateX(-1px) translateY(1.5px);
  }
  75% {
    transform: translateX(2px);
  }
}
@keyframes eye-pulse {
  0%,
  100% {
    opacity: 0.35;
  }
  50% {
    opacity: 0.85;
  }
}

/* telescreen flicker — applied to framed panels that read as monitors */
.flicker {
  animation: flicker 6s steps(1) infinite;
}
@keyframes flicker {
  0%,
  96%,
  100% {
    opacity: 1;
  }
  97% {
    opacity: 0.82;
  }
  98% {
    opacity: 1;
  }
  99% {
    opacity: 0.9;
  }
}

/* ============================================================================
   Shared components — badges (reused across ~15 admin + cabinet screens)
   ============================================================================ */
.badge {
  display: inline-block;
  padding: 2px 9px;
  border-radius: var(--radius-sm);
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border: 1px solid transparent;
}
.badge.green {
  background: rgba(47, 125, 70, 0.14);
  color: var(--success);
  border-color: rgba(47, 125, 70, 0.35);
}
.badge.red {
  background: var(--party-soft);
  color: var(--danger);
  border-color: var(--glow-red);
}
.badge.orange {
  background: rgba(165, 101, 10, 0.14);
  color: var(--warning);
  border-color: rgba(165, 101, 10, 0.35);
}
.badge.blue {
  background: rgba(217, 138, 26, 0.14);
  color: var(--primary);
  border-color: var(--glow-amber);
}
.badge.purple {
  background: rgba(126, 92, 168, 0.16);
  color: #8a6db8;
  border-color: rgba(126, 92, 168, 0.4);
}
[data-theme="dark"] .badge.purple {
  color: #b39ddb;
}
.badge.gray {
  background: rgba(89, 98, 111, 0.16);
  color: var(--muted);
  border-color: var(--border-strong);
}

/* ============================================================================
   Brand — the mark (stacked entropy bars, pinched to an amber core) + wordmark.
   Recolours per theme: bars are ink on light / bone on dark; the pinched core
   bars glow amber (the lamp) in both.
   ============================================================================ */
.logo {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  line-height: 1;
}
.logo-mark {
  height: 1.4em;
  width: 1.4em;
  flex-shrink: 0;
  overflow: visible;
}
.logo-bar {
  fill: var(--text-strong);
  transition: fill 0.3s;
}
.logo-bar.core {
  fill: var(--lamp);
}
[data-theme="dark"] .logo-bar.core {
  filter: drop-shadow(0 0 2.5px var(--glow-amber));
  animation: logo-core 4.5s ease-in-out infinite;
}
@keyframes logo-core {
  0%, 100% { opacity: 0.75; }
  50% { opacity: 1; }
}
.logo:hover .logo-bar { fill: var(--lamp); }
.logo:hover .logo-bar.core { fill: var(--lamp-strong); }
.wm {
  display: inline-flex;
  align-items: baseline;
  gap: 0.28em;
  font-family: var(--font-display);
  font-weight: 700;
  text-transform: uppercase;
}
.wm-main { color: var(--text-strong); }
.wm-vpn { color: var(--lamp); }

/* ============================================================================
   Motion — cross-document page transitions + object smoothness.
   The whole site cross-fades between navigations (Chromium View Transitions);
   panels rise on first paint; controls press. All halted by reduced-motion.
   ============================================================================ */
@view-transition {
  navigation: auto;
}
::view-transition-old(root) {
  animation: vt-out 0.22s cubic-bezier(0.4, 0, 1, 1) both;
}
::view-transition-new(root) {
  animation: vt-in 0.28s cubic-bezier(0.16, 1, 0.3, 1) both;
}
@keyframes vt-out {
  to { opacity: 0; transform: translateY(-6px); }
}
@keyframes vt-in {
  from { opacity: 0; transform: translateY(10px); }
}
html {
  scroll-behavior: smooth;
}
@keyframes content-enter {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}
.auth-panel,
.sub-header,
.page > h1 {
  animation: content-enter 0.5s cubic-bezier(0.16, 1, 0.3, 1) both;
}
.page > .subtitle {
  animation: content-enter 0.5s cubic-bezier(0.16, 1, 0.3, 1) 0.05s both;
}
/* staggered surface of main blocks (CSS fallback when JS is off) */
.page > *:not(script):not(h1):not(.subtitle),
.auth-panel > *:not(script):not(.auth-title):not(.auth-lead),
.sub-main > *:not(script) {
  animation: content-enter 0.42s var(--ease-out) both;
}
.page > *:not(script):not(h1):not(.subtitle):nth-child(2),
.auth-panel > *:not(script):not(.auth-title):not(.auth-lead):nth-child(2),
.sub-main > *:nth-child(2) { animation-delay: 0.05s; }
.page > *:not(script):not(h1):not(.subtitle):nth-child(3),
.auth-panel > *:not(script):not(.auth-title):not(.auth-lead):nth-child(3),
.sub-main > *:nth-child(3) { animation-delay: 0.1s; }
.page > *:not(script):not(h1):not(.subtitle):nth-child(4),
.auth-panel > *:not(script):not(.auth-title):not(.auth-lead):nth-child(4),
.sub-main > *:nth-child(4) { animation-delay: 0.14s; }
.page > *:not(script):not(h1):not(.subtitle):nth-child(5),
.auth-panel > *:not(script):not(.auth-title):not(.auth-lead):nth-child(5),
.sub-main > *:nth-child(5) { animation-delay: 0.18s; }
.page > *:not(script):not(h1):not(.subtitle):nth-child(n+6),
.auth-panel > *:not(script):not(.auth-title):not(.auth-lead):nth-child(n+6),
.sub-main > *:nth-child(n+6) { animation-delay: 0.22s; }
body[data-surface="admin"] .page > *:not(script) {
  animation-duration: 0.28s;
  animation-delay: 0s !important;
}
/* press feedback on every actionable control */
.btn:active,
.auth-submit:active,
.auth-action:active,
.sub-btn:active,
.sub-copy-btn:active,
.kit-btn:active,
.tab-bar a:active {
  transform: translateY(1px) scale(0.99);
}
/* cabinet panels lift toward the light on hover */
body[data-surface="cabinet"] .card {
  transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}
body[data-surface="cabinet"] .card:hover {
  transform: translateY(-2px);
  border-color: var(--border-strong);
  box-shadow: var(--shadow-lg);
}

/* ============================================================================
   Micro-interactions — hover/click smoothness, flash, busy, skeleton
   ============================================================================ */
:is(.btn, .auth-submit, .auth-action, .sub-btn, .sub-copy-btn, .kit-btn, .nav-link, .tab-bar a, .device-remove) {
  transition:
    color var(--motion-fast) var(--ease-out),
    background-color var(--motion-fast) var(--ease-out),
    border-color var(--motion-fast) var(--ease-out),
    box-shadow var(--motion-base) var(--ease-out),
    transform var(--motion-fast) var(--ease-out),
    opacity var(--motion-fast) var(--ease-out);
}
:is(.btn, .auth-submit, .sub-btn, .kit-btn):hover:not(:disabled):not(.is-busy) {
  transform: translateY(-1px);
}
:is(.btn, .auth-submit, .sub-btn, .kit-btn).primary:hover:not(:disabled):not(.is-busy),
.auth-action.primary:hover {
  transform: translateY(-2px);
}
.nav-link:hover {
  transform: translateX(2px);
}
.nav-link.active:hover {
  transform: none;
}
input:not([type="checkbox"]):not([type="radio"]),
select,
textarea,
.auth-input {
  transition:
    border-color var(--motion-fast) var(--ease-out),
    box-shadow var(--motion-base) var(--ease-out),
    background-color var(--motion-fast) var(--ease-out);
}
.checkbox input,
input[type="checkbox"],
input[type="radio"] {
  transition: transform var(--motion-fast) var(--ease-out);
}
.checkbox input:active,
input[type="checkbox"]:active,
input[type="radio"]:active {
  transform: scale(0.92);
}
/* flash / toast surfacing */
@keyframes flash-surface {
  from { opacity: 0; transform: translateY(-10px); }
  to { opacity: 1; transform: none; }
}
@keyframes flash-shake {
  0%, 100% { transform: translateX(0); }
  18% { transform: translateX(-7px); }
  36% { transform: translateX(7px); }
  54% { transform: translateX(-4px); }
  72% { transform: translateX(4px); }
}
@keyframes flash-success-pulse {
  0%, 100% { box-shadow: none; }
  50% { box-shadow: 0 0 0 3px var(--glow-amber); }
}
.flash,
.auth-flash {
  animation: flash-surface var(--motion-slow) var(--ease-out) both;
}
.flash.error,
.auth-flash.error {
  animation:
    flash-surface var(--motion-slow) var(--ease-out) both,
    flash-shake 0.48s var(--ease-out) 0.32s;
}
.flash.success,
.auth-flash.success {
  animation:
    flash-surface var(--motion-slow) var(--ease-out) both,
    flash-success-pulse 0.55s var(--ease-out) 0.28s;
}
/* submit busy — spinner injected by interactions.js; CSS-only fallback ring */
@keyframes ui-spin {
  to { transform: rotate(360deg); }
}
.is-busy {
  cursor: wait;
  pointer-events: none;
  opacity: 0.9;
}
.is-busy::before {
  content: "";
  display: inline-block;
  width: 0.85em;
  height: 0.85em;
  margin-right: 0.4em;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: ui-spin 0.65s linear infinite;
  vertical-align: -0.12em;
}
/* skeleton shimmer for deferred blocks (opt-in via class) */
@keyframes skeleton-shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
.skeleton {
  display: block;
  border-radius: var(--radius);
  min-height: 1rem;
  background: linear-gradient(
    90deg,
    var(--surface-2) 0%,
    var(--surface) 45%,
    var(--surface-2) 90%
  );
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.3s var(--ease-in-out) infinite;
}
.skeleton-text { height: 0.85rem; margin-bottom: 0.5rem; }
.skeleton-text.wide { width: 92%; }
.skeleton-text.mid { width: 68%; }
.skeleton-text.short { width: 42%; }
.skeleton-btn { height: 2.25rem; width: 8rem; }
.is-loading .skeleton-hide {
  opacity: 0;
  pointer-events: none;
}

/* ============================================================================
   Detail — grain, terminal corner brackets, header ticks.
   ============================================================================ */
/* fine film grain layered into the telescreen wash */
.tele-bg::before {
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E"),
    repeating-linear-gradient(
      0deg,
      var(--scan) 0,
      var(--scan) 1px,
      transparent 1px,
      transparent 3px
    );
  background-size: 200px 200px, auto;
}
/* terminal corner brackets on framed panels */
.card,
.sub-card {
  position: relative;
}
.card::before,
.card::after,
.sub-card::before,
.sub-card::after {
  content: "";
  position: absolute;
  width: 9px;
  height: 9px;
  border: 1px solid var(--border-strong);
  pointer-events: none;
  opacity: 0.7;
}
.card::before,
.sub-card::before {
  top: 4px;
  left: 4px;
  border-right: 0;
  border-bottom: 0;
}
.card::after,
.sub-card::after {
  bottom: 4px;
  right: 4px;
  border-left: 0;
  border-top: 0;
}
/* lit amber accent bar on the left edge of every panel header */
.card-header {
  position: relative;
}
.card-header::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: var(--lamp);
  box-shadow: 0 0 8px var(--glow-amber);
}

/* ============================================================================
   Secret-reveal shutter + lens-cover flash (injected by app.js)
   ============================================================================ */
.shutter-cover {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: inherit;
  pointer-events: none;
  z-index: 3;
}
.shutter-leaf {
  position: absolute;
  left: 0;
  right: 0;
  height: 50%;
  background: linear-gradient(var(--tele-ink), #1c222c);
  border-color: var(--border-strong);
}
.shutter-leaf.top {
  top: 0;
  border-bottom: 1px solid var(--lamp);
  box-shadow: 0 1px 12px var(--glow-amber);
}
.shutter-leaf.bottom {
  bottom: 0;
  border-top: 1px solid var(--lamp);
  box-shadow: 0 -1px 12px var(--glow-amber);
}
.shutter-scan {
  position: absolute;
  left: 0;
  right: 0;
  height: 40%;
  background: linear-gradient(180deg, transparent, var(--glow-amber), transparent);
}
.lens-flash {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: 4;
  background: repeating-linear-gradient(
      0deg,
      rgba(255, 255, 255, 0.12) 0,
      rgba(255, 255, 255, 0.12) 1px,
      transparent 1px,
      transparent 3px
    ),
    var(--glow-amber);
  mix-blend-mode: screen;
}

/* ============================================================================
   Accessibility — reduced motion halts every atmospheric loop, keeping the
   static surveillance backdrop intact.
   ============================================================================ */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  html {
    scroll-behavior: auto;
  }
  .tele-bg::after {
    display: none;
  }
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation: none !important;
  }
}

/* --- Site footer (cabinet + public + auth pages) ---
   A quiet closing block, translucent so the telescreen backdrop shows through. On the public
   pages the content column fills the first screen, so the footer only shows up on scroll. In
   the cabinet it stays pinned to the bottom of the viewport (`margin-top: auto`) — stretching
   the short cabinet pages to a full screen just to hide it would leave a dead empty area.
   Auth uses the same partial outside .auth-shell so the footer is full-bleed. */
.site-footer {
  margin-top: auto;
  padding: 18px 28px 14px;
  border-top: 1px solid color-mix(in srgb, var(--border) 65%, transparent);
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--lamp) 22%, transparent);
  background: transparent;
  background: color-mix(in srgb, var(--surface-inset) 40%, transparent);
}

/* Public pages: the content column fills the first viewport, pushing the footer below the fold. */
body[data-surface="public"] {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}
body[data-surface="public"] .sub-page {
  flex: 1 0 auto;
  min-height: 100vh;
  min-height: 100svh;
}

/* Auth: shell grows; footer sits below (full width, not in the 500px column). */
body[data-surface="auth"] .site-footer {
  width: 100%;
  flex-shrink: 0;
}

/* Cabinet: the footer lives inside .content, after the page body.
   Do not stretch .page itself — that painted a dead black slab over the
   telescreen. margin-top:auto on the footer still pins it to the bottom. */
.content { display: flex; flex-direction: column; min-height: 100vh; }
.content .page { flex: 0 0 auto; }

/* The brand block sits to the left of the link columns and drops above them when
   the row no longer fits — hence flex here and a nested grid for the columns,
   rather than one five-column grid that would squeeze the links on a laptop. */
.site-footer-inner {
  display: flex;
  flex-wrap: wrap;
  gap: 22px 40px;
  align-items: flex-start;
  justify-content: space-between;
  max-width: 1100px;
  width: 100%;
  margin: 0 auto;
}

.footer-brand {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
}
/* The wordmark carries no type of its own (it inherits, so the header can size
   it); the footer instance needs the same display face at a quieter size. */
.footer-brand .logo {
  font-family: var(--font-display);
  font-size: 1.1rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

/* Quiet amber outline: the manifest is the one piece of writing we point at from
   every page, so it gets a button rather than another line in a link column. */
.footer-manifest {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 8px 14px;
  border: 1px solid color-mix(in srgb, var(--lamp) 45%, transparent);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--lamp) 8%, transparent);
  color: var(--primary);
  font-family: var(--font-display);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
  transition: border-color var(--motion-fast) var(--ease-out),
    background-color var(--motion-fast) var(--ease-out);
}
.footer-manifest:hover,
.footer-manifest:focus-visible {
  border-color: var(--lamp);
  background: color-mix(in srgb, var(--lamp) 16%, transparent);
  text-decoration: none;
}
.footer-manifest .footer-ico {
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
  color: currentColor;
}

.footer-cols {
  flex: 1 1 620px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(155px, 1fr));
  gap: 18px 26px;
  align-items: start;
}

.footer-col {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-self: start;
  gap: 5px;
  min-width: 0;
}

.footer-head {
  margin: 0 0 2px;
  font-family: var(--font-display);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-strong);
}

/* Sized for four link columns sharing a row with the brand block: at the old
   1.02rem the longest labels ("Политика конфиденциальности") wrapped to three
   lines on a laptop. */
.footer-icon-link {
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: 100%;
  color: var(--muted);
  text-decoration: none;
  font-size: 0.88rem;
  line-height: 1.35;
  transition: color var(--motion-fast) var(--ease-out);
}
.footer-icon-link:hover,
.footer-icon-link:focus-visible {
  color: var(--primary);
  text-decoration: none;
}
.footer-icon-link .footer-ico,
.footer-icon-link .icon-telegram,
.footer-icon-link .icon-tor,
.footer-icon-link .icon-simplex {
  width: 17px;
  height: 17px;
  flex: 0 0 auto;
  color: var(--muted);
  opacity: 0.95;
}
.footer-icon-link:hover .footer-ico,
.footer-icon-link:hover .icon-telegram,
.footer-icon-link:hover .icon-tor,
.footer-icon-link:focus-visible .footer-ico,
.footer-icon-link:focus-visible .icon-telegram,
.footer-icon-link:focus-visible .icon-tor {
  color: var(--lamp);
  opacity: 1;
}
.footer-icon-link .icon-telegram,
.footer-icon-link .icon-tor { display: block; }

/* Tor onion is tall — keep width, let height breathe a hair. */
.footer-icon-link .icon-tor {
  width: 14px;
  height: 19px;
}

/* SimpleX: brand mark (two-tone gray), keep as-is. */
.footer-icon-link .icon-simplex {
  display: block;
  object-fit: contain;
  opacity: 1;
}

/* Long addresses (support email) may break mid-word rather than widen a column. */
.footer-break { word-break: break-all; }

/* --- Footer bottom bar --- */
.site-footer-bottom {
  max-width: 1100px;
  margin: 16px auto 0;
  padding-top: 10px;
  border-top: 1px solid color-mix(in srgb, var(--border) 65%, transparent);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 24px;
}

.footer-copy {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.04em;
  color: var(--muted);
}

.footer-status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-display);
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: none;
  transition: color var(--motion-fast) var(--ease-out);
}
.footer-status:hover,
.footer-status:focus-visible {
  color: var(--primary);
  text-decoration: none;
}
.footer-status-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--lamp);
  box-shadow: 0 0 8px var(--glow-amber);
}

@media (max-width: 900px) {
  .footer-cols {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px 28px;
  }
}

@media (max-width: 640px) {
  .site-footer { padding: 16px 16px 12px; }
  .site-footer-inner { gap: 18px; }
  .footer-cols {
    grid-template-columns: 1fr;
    gap: 16px;
  }
}

/* --- Utilities ------------------------------------------------------------
   A deliberately small layer, added when 'unsafe-inline' left style-src: every
   one of these replaces a style="..." attribute that CSP now forbids. Keep it
   small. A tweak that belongs to a component belongs in that component's rule,
   next to it — not here. Loaded by all four layouts, so anything here must be
   surface-agnostic.
   -------------------------------------------------------------------------- */
.u-m0 { margin: 0; }
.u-mt0 { margin-top: 0; }
.u-mt4 { margin: 4px 0 0; }
.u-mt6 { margin-top: 6px; }
.u-mt8 { margin-top: 8px; }
.u-mt12 { margin-top: 12px; }
.u-mt16 { margin-top: 16px; }
.u-mb6 { margin-bottom: 6px; }
.u-ml-auto { margin-left: auto; }
.u-pt0 { padding-top: 0; }
.u-pad-top { padding: 16px 16px 0; }
.u-fs13 { font-size: 13px; }
.u-inline { display: inline; }
.u-hidden { display: none; }
.u-span-all { grid-column: 1 / -1; }
.u-w100 { width: 100%; }
.u-w70 { width: 70px; }
.u-mw100 { max-width: 100px; }
.u-mw520 { max-width: 520px; }
.u-nowrap { white-space: nowrap; }
.u-pre { white-space: pre-wrap; }
.u-break { word-break: break-all; }
.u-pre-break { white-space: pre-wrap; word-break: break-all; }
.u-pointer { cursor: pointer; }

/* Big numeral in a stat/summary block. */
.u-stat-md { font-size: 22px; font-weight: 700; }
.u-stat-lg { font-size: 28px; font-weight: 700; }

/* A rule between sections, drawn with the theme border rather than the UA default. */
.u-rule { border: none; border-top: 1px solid var(--border); margin: 14px 0; }

/* Label and value pushed to opposite ends of a fixed-width row. */
.u-split { display: flex; justify-content: space-between; gap: 12px; min-width: 140px; }
