/* ═══════════════════════════════════════════════════════════════════
   SkyTrace shared design tokens + common components
   Served at /shared/tokens.css on all three subdomains (input / map / ops).
   Load order per page: /shared/fonts.css → /shared/tokens.css → /assets/main.css
   Per-app stylesheets contain ONLY app-specific layout; everything visual
   that is common (tokens, login, skeletons, legends, markers, badges,
   icons, type) lives here so the three UIs cannot drift apart.
   ═══════════════════════════════════════════════════════════════════ */

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

/* Visually hidden but screen-reader accessible */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

:root {
  /* ── Color tokens ── */
  --color-canvas: #0d1117;
  --color-surface: #161b22;
  --color-raised: #21262d;
  --color-raised-hover: #1c2128;
  --color-selection-surface: #0d2847;
  --color-border: #30363d;
  --color-border-muted: #484f58;
  --color-selected-border: #388bfd;
  --color-ink: #e6edf3;
  --color-ink-muted: #8b949e;
  --color-ink-secondary: #c9d1d9;
  --color-accent-blue: #58a6ff;
  --color-action-blue: #1f6feb;
  --color-action-green: #238636;
  --color-action-green-hover: #2ea043;
  --color-success: #3fb950;
  --color-success-surface: #0d2416;
  --color-danger: #f85149;
  --color-danger-deep: #b91c1c;
  --color-danger-surface: #3d0f0f;
  --color-warning: #d29922;
  --color-warning-surface: #27210a;
  --color-event-orange: #f97316;
  --color-drone-purple: #9333ea;
  --color-risk4-surface: #3d200f;
  --color-white: #fff;

  /* ── Typography ── */
  --font-sans: 'IBM Plex Sans Arabic', 'Segoe UI', Tahoma, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, 'Cascadia Mono', 'Courier New', monospace;

  /* ── Z-index scale (Leaflet uses up to ~1000 for its panes/controls) ── */
  --z-map-control: 1010;
  --z-modal: 1100;

  /* ── Motion ── */
  --ease-out-quint: cubic-bezier(0.22, 1, 0.36, 1);
}

html, body {
  height: 100%;
  overflow: hidden;
  background: var(--color-canvas);
  color: var(--color-ink);
  font-family: var(--font-sans);
}

input, button, select, textarea { font-family: inherit; }

/* ── Icon system (Tabler sprite at /shared/icons.svg) ──
   Uniform stroke, currentColor, sized to the surrounding text. */
.icon {
  width: 1.05em; height: 1.05em;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
  vertical-align: -0.15em;
  flex-shrink: 0;
}

/* ── Operational data: mono + tabular so changing values never jitter ── */
.mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  direction: ltr;
  unicode-bidi: embed;
}

/* ── Login — cinematic title screen (identical on all three UIs) ──
   A film-poster opening: near-black stage, soft overhead vignette,
   the metallic Kaayaan Ai / SkyTrace mark, then a minimal steel form.
   The dark-room drama lives HERE; the working surfaces stay calm. */
#login-screen {
  position: fixed; inset: 0; z-index: var(--z-modal);
  background:
    radial-gradient(115% 75% at 50% 18%, #16191f 0%, #0b0d11 48%, #050608 100%);
  display: flex; align-items: center; justify-content: center;
}
/* faint film grain over the stage (decorative, behind the form) */
#login-screen::before {
  content: '';
  position: absolute; inset: 0; pointer-events: none; opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
}
.login-box {
  position: relative;
  background: none;
  border: 0;
  padding: 24px;
  width: 380px;
  max-width: calc(100vw - 32px);
  text-align: center;
}
.brand-wrap {
  position: relative;
  display: block;
  width: min(320px, 78vw);
  margin: 0 auto 4px;
  overflow: hidden;
  /* mask the mockup's rectangular edges into the stage */
  -webkit-mask-image: radial-gradient(105% 105% at 50% 50%, #000 62%, transparent 98%);
  mask-image: radial-gradient(105% 105% at 50% 50%, #000 62%, transparent 98%);
}
.brand-logo { display: block; width: 100%; height: auto; }
/* one-shot key-light sheen that sweeps the metal after the title settles;
   parked off-canvas so reduced-motion users never see it */
.brand-wrap::after {
  content: '';
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(115deg, transparent 32%, rgba(255,255,255,0.16) 50%, transparent 68%);
  transform: translateX(-130%);
}
/* small metallic arrow mark for app chrome (headers, error cards) */
.brand-mark {
  display: block; height: 22px; width: auto; flex-shrink: 0;
  -webkit-mask-image: radial-gradient(115% 115% at 50% 50%, #000 55%, transparent 96%);
  mask-image: radial-gradient(115% 115% at 50% 50%, #000 55%, transparent 96%);
}
.login-box h1 {
  font-size: 1.4rem; margin-bottom: 6px; color: var(--color-accent-blue);
  display: flex; align-items: center; justify-content: center; gap: 8px;
}
.login-box p {
  font-size: 0.85rem; color: #9aa3ad; margin-bottom: 30px;
  padding-top: 16px;
  position: relative;
}
/* hairline "title card" rule above the subtitle */
.login-box p::before {
  content: '';
  position: absolute; top: 0; left: 50%; transform: translateX(-50%);
  width: 180px; height: 1px;
  background: linear-gradient(90deg, transparent, #4a515b 50%, transparent);
}
.login-box input {
  width: 100%; padding: 11px 14px; margin-bottom: 14px;
  background: rgba(13, 17, 23, 0.75);
  border: 1px solid #2c323b; border-radius: 6px;
  color: var(--color-ink); font-size: 0.95rem; text-align: start;
}
.login-box input::placeholder { color: #9aa3ad; }
.login-box input:focus { outline: none; border-color: var(--color-accent-blue); }
/* steel key-light button: near-white on black, the film-title CTA */
.login-box button {
  width: 100%; padding: 11px; background: var(--color-ink); border: none;
  border-radius: 6px; color: #0b0d11; font-size: 1rem; font-weight: 600;
  letter-spacing: 0.02em; cursor: pointer;
  transition: background 0.12s;
}
.login-box button:hover { background: var(--color-white); }
.login-box button:focus-visible { outline: 2px solid var(--color-accent-blue); outline-offset: 2px; }
#login-error { color: var(--color-danger); font-size: 0.85rem; margin-top: 10px; min-height: 18px; }

/* title-screen entrance: an opening sequence — the mark lands, the title
   card follows, then the form; finally one key-light sheen crosses the metal */
@media (prefers-reduced-motion: no-preference) {
  @keyframes title-rise {
    from { opacity: 0; transform: translateY(12px); }
    to   { opacity: 1; transform: translateY(0); }
  }
  .brand-wrap    { animation: title-rise 0.7s var(--ease-out-quint) both; }
  .login-box p   { animation: title-rise 0.7s 0.15s var(--ease-out-quint) both; }
  .login-box form { animation: title-rise 0.7s 0.3s var(--ease-out-quint) both; }
  @keyframes brand-sheen { to { transform: translateX(130%); } }
  .brand-wrap::after { animation: brand-sheen 1.3s 0.9s cubic-bezier(0.4, 0, 0.2, 1) forwards; }
}

/* ── Loading skeleton (shimmer) ── */
.sk-bar {
  display: block; height: 12px; border-radius: 4px;
  background: linear-gradient(90deg, var(--color-surface) 25%, var(--color-raised) 37%, var(--color-surface) 63%);
  background-size: 400% 100%;
  animation: sk-shimmer 1.4s ease infinite;
}
@keyframes sk-shimmer { from { background-position: 100% 0; } to { background-position: 0 0; } }

/* ── Map legend (visuals shared; position/offsets are set per app) ── */
.map-legend {
  background: rgba(13, 17, 23, 0.92);
  border: 1px solid var(--color-border); border-radius: 6px;
  color: var(--color-ink); font-size: 0.74rem; direction: rtl; max-width: 230px;
}
.map-legend summary {
  cursor: pointer; padding: 7px 12px; color: var(--color-ink-muted); font-weight: 600;
  list-style: none; user-select: none;
}
.map-legend summary::-webkit-details-marker { display: none; }
.map-legend summary:focus-visible { outline: 2px solid var(--color-accent-blue); outline-offset: 2px; }
.map-legend[open] summary { border-bottom: 1px solid var(--color-border); color: var(--color-ink); }
.legend-body { padding: 10px 12px; display: flex; flex-direction: column; gap: 12px; }
.legend-group { display: flex; flex-direction: column; gap: 5px; }
.legend-group-title { color: var(--color-ink-muted); font-size: 0.68rem; margin-bottom: 2px; }
.legend-row { display: flex; align-items: center; gap: 8px; line-height: 1.2; }
.lg-dot { width: 11px; height: 11px; border-radius: 50%; border: 1.5px solid var(--color-white); flex-shrink: 0; }
.lg-ring { width: 11px; height: 11px; border-radius: 50%; outline: 2px solid var(--color-danger); outline-offset: 1px; flex-shrink: 0; }
.lg-line { width: 14px; height: 0; border-top: 3px solid var(--color-danger); flex-shrink: 0; }
.lg-glyph { width: 12px; text-align: center; flex-shrink: 0; }
.lg-stars { color: var(--color-warning); letter-spacing: 1px; }
.lg-dot-uav   { background: var(--color-success); }
.lg-dot-drone { background: var(--color-drone-purple); }
.lg-dot-event { background: var(--color-event-orange); }
.lg-glyph-mil   { color: var(--color-danger); }
.lg-glyph-oil   { color: var(--color-ink-secondary); }
.lg-glyph-infra { color: var(--color-accent-blue); }

/* ── Incident start markers (Leaflet divIcons, ops + map) ── */
.start-marker, .start-marker-drone, .start-marker-event {
  border-radius: 50%;
  color: white;
  font-weight: bold;
  font-size: 10px;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid white;
  box-shadow: 0 1px 4px rgba(0,0,0,0.5);
  text-align: center;
  line-height: 1.1;
}
.start-marker       { background: var(--color-success); }
.start-marker-drone { background: var(--color-drone-purple); }
.start-marker-event { background: var(--color-event-orange); font-size: 8px; }

/* ── Risk badges (1 = lowest, 5 = highest) ── */
.risk-badge {
  display: inline-block;
  padding: 1px 7px;
  border-radius: 10px;
  font-size: 0.70rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.risk-5 { background: var(--color-danger-surface); color: var(--color-danger); }
.risk-4 { background: var(--color-risk4-surface); color: var(--color-event-orange); }
.risk-3 { background: var(--color-warning-surface); color: var(--color-warning); }
.risk-2 { background: var(--color-success-surface); color: var(--color-success); }
.risk-1 { background: var(--color-raised-hover); color: var(--color-ink-muted); }

/* ── Spinner (inline pending indicator, e.g. login button) ── */
.spinner {
  display: inline-block; width: 16px; height: 16px;
  border: 2px solid var(--color-border); border-top-color: var(--color-accent-blue);
  border-radius: 50%; animation: spin 0.7s linear infinite;
  vertical-align: middle;
}
@keyframes spin { to { transform: rotate(360deg); } }
.login-box .spinner { border-color: rgba(11,13,17,0.3); border-top-color: #0b0d11; }

/* ═══════════════════════════════════════════════════════════════
   Motion system — functional feedback only, never decoration.
   Fast (150-300ms), eased with --ease-out-quint, and every rule in
   this block is gated behind prefers-reduced-motion: no-preference
   so reduced-motion users get instant state changes instead.
   ═══════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: no-preference) {

  /* Tactile press: buttons acknowledge the click physically */
  .btn, .cmd-btn, .del-btn, .type-card, .feed-toggle, .all-type, .all-toggle,
  .result-link, .login-box button,
  #logout-btn, #ops-logout-btn, #lang-toggle, #toggle-locations, #panel-collapse, #panel-reopen {
    transition-property: transform, background, color, border-color, opacity;
    transition-duration: 0.12s;
  }
  .btn:active:not(:disabled), .cmd-btn:active, .del-btn:active, .type-card:active,
  .feed-toggle:active:not(:disabled), .all-type:active, .all-toggle:active,
  .result-link:active, .login-box button:active:not(:disabled),
  #logout-btn:active, #ops-logout-btn:active, #lang-toggle:active,
  #toggle-locations:active, #panel-collapse:active, #panel-reopen:active {
    transform: scale(0.98);
  }

  /* Content enter: new content rises softly into place (state transition) */
  @keyframes rise-in {
    from { opacity: 0; transform: translateY(4px); }
    to   { opacity: 1; transform: translateY(0); }
  }
  .content-enter { animation: rise-in 0.2s var(--ease-out-quint) both; }

  /* Overlay/dialog enter: fade the scrim, pop the box (state transition) */
  @keyframes overlay-fade { from { opacity: 0; } to { opacity: 1; } }
  @keyframes pop-in {
    from { opacity: 0; transform: scale(0.96); }
    to   { opacity: 1; transform: scale(1); }
  }

  /* Login error: horizontal wiggle, 3 oscillations, 300ms (feedback) */
  @keyframes login-shake {
    0%, 100% { transform: translateX(0); }
    20%      { transform: translateX(-4px); }
    40%      { transform: translateX(4px); }
    60%      { transform: translateX(-4px); }
    80%      { transform: translateX(4px); }
  }
  .login-box.shake { animation: login-shake 0.3s ease-in-out; }

  /* One-shot state-change ping (session badge flips, marker focus) */
  @keyframes badge-ping {
    50% { transform: scale(1.06); }
  }
  .badge-ping { display: inline-block; animation: badge-ping 0.3s var(--ease-out-quint); }

  /* One-shot attention ring on a focused map marker (never loops) */
  @keyframes ping-once {
    from { transform: scale(0.8); opacity: 0.9; }
    to   { transform: scale(1.7); opacity: 0; }
  }
  .marker-ping { position: relative; }
  .marker-ping::after {
    content: '';
    position: absolute;
    inset: -5px;
    border-radius: 50%;
    border: 2px solid var(--color-accent-blue);
    animation: ping-once 0.7s var(--ease-out-quint) forwards;
    pointer-events: none;
  }
}

/* ── Reduced motion (shared pieces; apps extend this for their own animations) ── */
@media (prefers-reduced-motion: reduce) {
  .sk-bar { animation: none; }
  .spinner { animation: none; }
}
