/* =============================================================
 * OSINT Workspace — hero + full-width layout.
 *
 * Dark hero header with stats + horizontal tabs,
 * followed by full-width content area.
 * Sharp corners, dark palette, RTL-first.
 * =========================================================== */

/* ---- Page-level ---- */
body.page-template-page-osint {
	background: var(--c-bg-alt);
}
body.page-template-page-osint .eekad-main {
	background: var(--c-bg-alt);
	padding: 0;
}

/* ---- Layout shell ---- */
.osint {
	display: flex;
	flex-direction: column;
	min-height: 100vh;
}

/* =============================================================
 * HERO — dark header matching the nav bar
 * =========================================================== */
.osint__hero {
	position: relative;
	overflow: hidden;
	background: var(--c-bg-alt);
	padding: 120px 0 0;
}

/* Background artwork (file / dataset / scoped-subject cover).
   The stack fades in once on load; individual layers inside it cross-fade
   when the subject changes, so the reveal and the swap never fight. */
.osint__hero-bgs {
	position: absolute;
	inset: 0;
	z-index: 0;
	opacity: 0;
	transition: opacity .6s ease;
}
.osint__hero.is-revealed .osint__hero-bgs {
	opacity: .72;
}
.osint__hero-bg {
	position: absolute;
	inset: 0;
	background-size: cover;
	background-position: center;
	/* Subject covers are the same photograph with the marker moved onto a
	   different person, so the swap has to read as the focus travelling —
	   slow enough to follow, and never a cut. */
	transition: opacity .5s ease;
}
/* The incoming layer starts transparent and is faded up by the script; the
   outgoing one is faded down and removed. */
.osint__hero-bg.is-entering {
	opacity: 0;
}
/* The scrim only has to protect the text, and the text sits on the floor of
   the hero — so it stays solid at the bottom edge, where it also dissolves
   into the page, and lifts quickly above that. Weighting the top as heavily
   as the bottom just buried the artwork. */
.osint__hero-scrim {
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	background: linear-gradient(
		to top,
		var(--c-bg-alt) 0%,
		rgba(var(--c-bg-alt-rgb), .40) 42%,
		rgba(var(--c-bg-alt-rgb), .12) 100%
	);
}
@media (prefers-reduced-motion: reduce) {
	.osint__hero-bgs,
	.osint__hero-bg {
		transition: none;
	}
}

.osint__hero-inner {
	position: relative;
	z-index: 1;
	max-width: 1232px;
	margin: 0 auto;
	padding: 0 24px 48px;
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 40px;
}
/* The scope rail supplies its own breathing room below the hero text, so the
   hero's 48px floor would stack into a canyon above the chips. */
.osint__hero-inner:has(+ .osint__scope) {
	padding-bottom: 28px;
}
.osint__hero-kicker {
	display: inline-flex;
	align-items: center;
	gap: 10px;
	color: var(--c-text-muted);
	font-size: 13px;
	font-weight: 600;
	letter-spacing: 0; /* Arabic — never tracked */
	margin-bottom: 16px;
}
.osint__hero-kicker svg {
	width: 18px;
	height: 18px;
}
.osint__hero-title {
	margin: 0 0 12px;
	font-size: clamp(44px, 5vw, 64px);
	font-weight: 700;
	color: var(--c-text);
	line-height: 1.15;
}
.osint__hero-desc {
	margin: 0;
	font-size: 16px;
	color: var(--c-text-3);
	line-height: 1.7;
	max-width: 640px;
}

/* ---- Hero stats ---- */
.osint__hero-stats {
	display: flex;
	gap: 32px;
	flex-shrink: 0;
}
.osint__hero-stat {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 6px;
}
.osint__hero-stat-value {
	font-family: "itf Somaya Arabic";
	font-size: 36px;
	font-weight: 700;
	color: var(--c-text);
	line-height: 1;
}
.osint__hero-stat-label {
	font-size: 12px;
	color: var(--c-text-faint);
	font-weight: 500;
}

/* ---- Horizontal tabs ---- */
.osint__tabs {
	position: relative;
	z-index: 1;
	display: flex;
	align-items: center;
	gap: 2px;
	max-width: 1232px;
	margin: 0 auto;
	padding: 0 24px;
	/* Phones: the rail scrolls, the page never does.
	   `width` is what pins it. As a flex item of .osint the nav would stretch to
	   the viewport, except stretch cannot pull an item below its min-content
	   size — and the nowrap tabs make that 758px. On the picker page that pushed
	   the whole document into horizontal scroll and carried the dataset cards
	   off-screen. An explicit width forces the used cross size, and overflow-x
	   then scrolls the rail rather than the page. */
	width: 100%;
	min-width: 0;
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
	scrollbar-width: none;
}
.osint__tabs::-webkit-scrollbar { display: none; }
.osint__tab {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 14px 20px;
	font-size: 15px;
	font-weight: 500;
	color: var(--c-text-muted);
	text-decoration: none;
	border-bottom: 2px solid transparent;
	transition: color .15s, border-color .15s;
	white-space: nowrap;
}
.osint__tab svg {
	width: 18px;
	height: 18px;
	flex-shrink: 0;
}
.osint__tab:hover {
	color: var(--c-text-2);
}
.osint__tab.is-active {
	color: var(--c-text);
	border-bottom-color: var(--c-text); /* selection = contrast, not accent */
}
.osint__tab-sep {
	width: 1px;
	height: 22px;
	background: rgba(var(--c-border-rgb), .08);
	margin-inline: 8px;
	flex-shrink: 0;
}
.osint__tab--inv {
	font-size: 13px;
	color: var(--c-text-faint);
}
.osint__tab--inv.is-active {
	color: var(--c-text);
	border-bottom-color: var(--c-text);
}
.osint__tab-count {
	font-family: "itf Somaya Arabic";
	font-size: 10px;
	opacity: .5;
}
.osint__tab--clear {
	padding: 12px 8px;
}
.osint__tab--clear svg {
	width: 13px;
	height: 13px;
}

/* =============================================================
 * SUBJECT SCOPE RAIL — focus the whole workspace on one subject.
 *
 * Sits ABOVE the tabs because the subject outranks the view: choosing one
 * rescopes every tab, so it must not read as a control belonging to whichever
 * tab is open. Chips carry the subject's logo — in a militia file the emblem is
 * recognised before the name is read. Material and selection come from the
 * PILL KIT in the theme: active is white-on-dark contrast, never lime.
 * =========================================================== */
.osint__scope {
	position: relative;
	z-index: 1;
	display: flex;
	align-items: center;
	gap: 8px;
	max-width: 1232px;
	margin: 0 auto;
	padding: 0 24px 18px;
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
	scrollbar-width: none;
}
.osint__scope-label {
	flex-shrink: 0;
	margin-inline-end: 4px;
	font-size: 12px;
	font-weight: 600;
	color: var(--c-text-faint);
}
.osint__scope::-webkit-scrollbar { display: none; }
/* Put the rail back in the page container. The PILL ROW KIT sets
   `max-width: 100%; margin: 0` to own its own horizontal containment, which
   overrides the rail's own centring and runs the chips to the viewport edge
   while the hero text and the tabs stay in the 1232px column. Both the runtime
   wrapper and the rail are constrained: the wrapper is what the scroll paddles
   are positioned against, so leaving it full-bleed would park them at the edge
   of the screen instead of beside the chips. Constraining the rail too means
   the chips still line up where `:has()` is unavailable, which is the part a
   reader would notice. */
.eekad-pill-row-wrap:has( > .osint__scope ) {
	max-width: 1232px;
	margin-inline: auto;
}
.osint__scope.eekad-pill-row {
	max-width: 1232px;
	margin-inline: auto;
}
/* Sizing and typography only — the chips sit on the hero artwork, so their
   material comes from the PILL KIT's `--on-media` modifier in the theme. */
/* Scoped through the rail on purpose. The PILL KIT lives in the theme
   stylesheet, which loads after this one and matches a bare `.osint__scope-chip`
   at the same specificity — so sizing written here without the parent is
   silently discarded and the chips stay at kit defaults. These chips are the
   primary control on the page and sit over photography, so they run one step
   larger than a pill on a flat panel. */
.osint__scope .osint__scope-chip {
	display: inline-flex;
	align-items: center;
	flex-shrink: 0;
	padding: 13px 26px;
	font-size: 17px;
	font-weight: 600;
	text-decoration: none;
}
/* Every chip carries its subject's full name — these are militia names an
   editor chose, and a truncated one ("مليشيات غسان الدهيني(…") is a worse
   label than a wider chip. The rail already scrolls horizontally, so length
   costs nothing; wrapping is what would break the row, so only that is
   prevented. */
.osint__scope-chip-name {
	white-space: nowrap;
}

/* ---- "قريباً" subjects ----
   The chip-level twin of the teaser dataset card, minus the artwork. A card
   says "not yet" by draining the colour out of its image; a chip has no image,
   so the dashed edge carries the whole message and the name steps back to a
   dimmer ink. Deliberately neither lime nor red: this is a statement about the
   work, not an accent and not a warning. The rail already sorts these last, so
   the styling only has to say "named, not open" — it is not also doing the job
   of getting them out of the way.

   Scoped through `.osint__scope` for the same reason the sizing above is: the
   PILL KIT loads after this file and matches a bare `.osint__scope-chip` at the
   same specificity, so an unscoped border or background here is discarded. */
.osint__scope .osint__scope-chip.is-soon {
	gap: 10px;
	border-style: dashed;
	border-color: rgba(255, 255, 255, .22);
}
.osint__scope .osint__scope-chip.is-soon .osint__scope-chip-name {
	opacity: .62;
}
/* Only the visitor's chip is dressed as unavailable — an editor's is a working
   link, and greying it out would misdescribe what clicking it does. */
.osint__scope .osint__scope-chip.is-teaser {
	cursor: default;
	background: rgba(var(--c-bg-alt-rgb), .34);
}
/* Hover is a promise that a click does something. A teaser has none to make,
   so it holds its resting state rather than lighting up under the cursor. */
.osint__scope .osint__scope-chip.is-teaser:hover {
	background: rgba(var(--c-bg-alt-rgb), .34);
	border-color: rgba(255, 255, 255, .22);
}
/* Same plate as the dataset card's eyebrow marker, one step smaller to sit
   inside a chip rather than beside a 24px name. */
.osint__scope-chip-soon {
	flex-shrink: 0;
	padding: 2px 8px;
	background: rgba(255, 255, 255, .14);
	border: 1px solid rgba(255, 255, 255, .28);
	font-size: 11px;
	font-weight: 700;
	line-height: 1.5;
	letter-spacing: 0; /* Arabic — never tracked */
	white-space: nowrap;
}
@media (max-width: 600px) {
	.osint__scope-chip-soon {
		font-size: 10px;
		padding: 1px 6px;
	}
}

/* ---- Team-only markers ----
   Only ever rendered for a viewer who can edit posts; a visitor never receives
   a private dataset at all. Their whole job is to stop a team member mistaking
   "I can see it" for "it is published", so they use the warning red already in
   the palette rather than the lime accent. */
.osint__private-badge {
	display: inline-flex;
	align-items: center;
	flex-shrink: 0;
	padding: 2px 6px;
	background: rgba(209, 54, 54, .16);
	border: 1px solid rgba(209, 54, 54, .4);
	color: #f0a3a3;
	font-size: 10px;
	font-weight: 700;
	letter-spacing: 0; /* Arabic — never tracked */
	white-space: nowrap;
}
.osint__dataset-chip .osint__private-badge {
	margin-inline-start: 6px;
}
/* ---- "قريباً" marker ----
   Unlike the team-only badge this one IS shown to visitors, so it is a
   statement about the work rather than a warning to the team: it borrows the
   neutral surface the eyebrow already sits on and adds weight, instead of the
   red that means "you are seeing something unpublished". */
.osint__soon-badge {
	display: inline-flex;
	align-items: center;
	flex-shrink: 0;
	padding: 2px 8px;
	background: rgba(255, 255, 255, .14);
	border: 1px solid rgba(255, 255, 255, .28);
	color: var(--c-text);
	font-size: 10px;
	font-weight: 700;
	letter-spacing: 0; /* Arabic — never tracked */
	white-space: nowrap;
}
.osint__private-notice {
	display: flex;
	align-items: center;
	gap: 8px;
	margin: 0 0 12px;
	padding: 8px 12px;
	background: rgba(209, 54, 54, .12);
	border-inline-start: 3px solid #d13636;
	font-size: 13px;
	font-weight: 600;
	color: #f0a3a3;
	max-width: max-content;
}

/* Legacy — hide sidebar (replaced by hero tabs) */
.osint__sidebar { display: none; }

/* Investigation active banner */
.osint__inv-banner {
	display: flex;
	align-items: center;
	gap: 8px;
	padding: 10px 16px;
	background: rgba(88, 81, 207, .08);
	border-bottom: 1px solid rgba(88, 81, 207, .15);
}
.osint__inv-banner > svg {
	width: 14px;
	height: 14px;
	color: #7c6ceb;
	flex-shrink: 0;
}
.osint__inv-banner-label {
	font-size: 12px;
	color: var(--c-text-faint);
}
.osint__inv-banner-name {
	font-size: 13px;
	font-weight: 600;
	color: var(--c-text);
}
.osint__inv-banner-count {
	font-family: "itf Somaya Arabic";
	font-size: 11px;
	color: var(--c-text-faint);
	margin-inline-start: auto;
}
.osint__inv-banner-clear {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 20px;
	height: 20px;
	color: var(--c-text-faint);
	transition: color .15s;
	flex-shrink: 0;
}
.osint__inv-banner-clear svg {
	width: 14px;
	height: 14px;
}
.osint__inv-banner-clear:hover {
	color: var(--c-text-3);
}

/* =============================================================
 * MAIN PANEL — floating card
 * =========================================================== */
.osint__main {
	flex: 1;
	min-width: 0;
	max-width: 1232px;
	margin: 0 auto;
	padding: 32px 24px 80px;
	width: 100%;
}
.osint__hero--file ~ .osint__main {
	opacity: 0;
	transform: translateY(18px);
	animation: osint-content-reveal .5s ease .35s forwards;
}
@keyframes osint-content-reveal {
	to { opacity: 1; transform: translateY(0); }
}

.osint__panel {
	/* no extra padding — main handles it */
}
.osint__panel--graph {
	padding-bottom: 0;
	display: flex;
	flex-direction: column;
	height: calc(100vh - 200px);
}

.osint__panel-header {
	margin-bottom: 20px;
}
.osint__panel--graph .osint__panel-header {
	flex-shrink: 0;
}

/* Map view — full-height like graph */
.osint__panel--map {
	padding-bottom: 0;
	display: flex;
	flex-direction: column;
	height: calc(100vh - 200px);
}
.osint__panel--map .osint__panel-header {
	flex-shrink: 0;
}
/* Shared map root — used by the workspace map view and by the homepage
   database device, so it owns the column layout rather than the panel. */
.osint__map {
	display: flex;
	flex-direction: column;
	flex: 1;
	min-height: 0;
}
.osint__map-filter {
	display: flex;
	align-items: center;
	gap: 10px;
	justify-content: flex-start;
	padding-bottom: 8px;
	flex-shrink: 0;
}
/* Basemap switch sits beside the view-mode switch with a wider gutter, so
   the two read as two controls rather than one four-way segmented row. */
.osint__map-base {
	margin-inline-start: 6px;
}
.osint__map-filter .eekad-select-wrap {
	width: min(100%, 340px);
	min-width: min(100%, 340px);
}
.osint__map-filter .eekad-select {
	width: 100%;
	min-width: 0;
}
.osint__map-mode {
	display: inline-flex;
	align-items: center;
	padding: 3px;
	background: var(--glass-bg);
	border: 1px solid var(--glass-edge);
	border-top-color: var(--glass-edge-top);
}
.osint__map-mode-button {
	appearance: none;
	display: inline-flex;
	align-items: center;
	gap: 7px;
	border: 0;
	border-radius: 0;
	background: transparent;
	color: var(--c-text-muted);
	cursor: pointer;
	font-family: inherit;
	font-size: 13px;
	font-weight: 700;
	line-height: 1;
	padding: 11px 14px;
	white-space: nowrap;
	transition: background-color .18s ease, color .18s ease;
}
.osint__map-mode-button svg {
	width: 15px;
	height: 15px;
	flex: 0 0 auto;
	opacity: .85;
}
.osint__map-mode-button.is-active svg {
	opacity: 1;
}
.osint__map-mode-button:hover {
	color: var(--c-text);
}
.osint__map-mode-button.is-active {
	background: var(--c-text);
	color: var(--c-bg-base);
}
.osint__map-canvas {
	flex: 1;
	min-height: 400px;
	background: var(--c-bg-alt);
	border: 1px solid rgba(var(--c-border-rgb), .08);
}
@media (max-width: 768px) {
	.osint__map-filter {
		align-items: stretch;
		flex-direction: column;
	}
	.osint__map-filter .eekad-select-wrap {
		width: 100%;
		min-width: 0;
	}
	.osint__map-mode {
		width: 100%;
	}
	.osint__map-base {
		margin-inline-start: 0;
	}
	.osint__map-mode-button {
		flex: 1;
	}
}
.osint__map-popup-details {
	display: flex;
	flex-wrap: wrap;
	gap: 4px;
	margin-block-start: 10px;
}
.osint__map-popup-details span,
.osint__map-popup-details time {
	display: inline-flex;
	padding: 2px 6px;
	background: rgba(255, 255, 255, .06);
	color: var(--c-text-muted);
	font-size: 11px;
	line-height: 1.4;
}
.osint__map-popup-card {
	position: relative;
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: 14px;
	width: min(360px, calc(100vw - 48px));
	padding: 18px;
	background: var(--c-bg-surface);
	border: 1px solid rgba(var(--c-border-rgb), .12);
	box-shadow: 0 14px 40px -12px rgba(0, 0, 0, .8);
	color: var(--c-text);
	direction: rtl;
}
.osint__map-popup-card:has(.osint__map-popup-media) {
	grid-template-columns: minmax(0, 1fr) 74px;
}
.osint__map-popup-media {
	display: block;
	width: 74px;
	height: 74px;
	background: var(--c-bg-base);
	overflow: hidden;
}
.osint__map-popup-media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}
.osint__map-popup-body {
	min-width: 0;
}
.osint__map-popup-title {
	display: block;
	color: var(--c-text);
	font-size: 20px;
	font-weight: 800;
	line-height: 1.25;
	text-decoration: none;
	overflow-wrap: anywhere;
}
.osint__map-popup-title:hover {
	color: var(--c-lime);
}
.osint__map-popup-meta {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 7px;
	margin-block-start: 8px;
	color: var(--c-text-3);
	font-size: 12px;
	font-weight: 600;
}
.osint__map-popup-dot {
	width: 7px;
	height: 7px;
	flex: 0 0 auto;
}
.osint__map-popup-sep {
	color: rgba(var(--c-border-rgb), .24);
}
.osint__map-popup-summary {
	margin: 12px 0 0;
	color: var(--c-text-muted);
	font-size: 14px;
	line-height: 1.65;
	display: -webkit-box;
	-webkit-line-clamp: 4;
	-webkit-box-orient: vertical;
	overflow: hidden;
}
.osint__map-popup-source {
	display: inline-flex;
	margin-block-start: 12px;
	color: var(--c-lime);
	font-size: 12px;
	font-weight: 700;
	text-decoration: none;
}
.osint__map .mapboxgl-popup-content {
	background: transparent;
	padding: 0;
	box-shadow: none;
	border: 0;
	border-radius: 0;
}
.osint__map .eekad-home-db__map-hover-wrap .mapboxgl-popup-content {
	background: rgba(var(--c-bg-surface-rgb), .94);
	border: 1px solid rgba(var(--c-border-rgb), .12);
	box-shadow: 0 10px 26px rgba(0, 0, 0, .45);
	padding: 7px 9px;
}
.osint__map-hover-label {
	display: block;
	max-width: 220px;
	color: var(--c-text);
	direction: rtl;
	font-size: 12px;
	font-weight: 700;
	line-height: 1.45;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.osint__map .mapboxgl-popup-tip {
	border-top-color: var(--c-bg-surface);
	border-bottom-color: var(--c-bg-surface);
}
.osint__map .mapboxgl-ctrl-group {
	background: rgba(var(--c-bg-surface-rgb), .9);
	border: 1px solid rgba(var(--c-border-rgb), .08);
	border-radius: 0;
	box-shadow: 0 6px 18px rgba(0, 0, 0, .4);
	backdrop-filter: blur(6px);
	-webkit-backdrop-filter: blur(6px);
}
.osint__map .mapboxgl-ctrl-group button {
	background: transparent;
	width: 32px;
	height: 32px;
}
.osint__map .mapboxgl-ctrl-group button + button {
	border-top: 1px solid rgba(var(--c-border-rgb), .06);
}
.osint__map .mapboxgl-ctrl-group button:hover {
	background: var(--glass-bg-hover);
}
.osint__map .mapboxgl-ctrl-group button .mapboxgl-ctrl-icon {
	filter: invert(1) brightness(.9);
	opacity: .75;
}
.osint__map .mapboxgl-ctrl-group button:hover .mapboxgl-ctrl-icon {
	opacity: 1;
}
.osint__map .mapboxgl-ctrl-attrib {
	background: rgba(var(--c-bg-base-rgb), .75);
	color: var(--c-text-muted);
	font-size: 10px;
}
.osint__map .mapboxgl-ctrl-attrib a {
	color: var(--c-text-3);
}
.osint__map .mapboxgl-ctrl-attrib a:hover {
	color: var(--c-lime);
}
.osint__page-title {
	font-size: 20px;
	font-weight: 700;
	color: var(--c-text);
	margin: 0;
}

/* =============================================================
 * BROWSE — search + schema pills
 * =========================================================== */
.osint__browse-filters {
	display: flex;
	align-items: center;
	gap: 12px;
	padding-bottom: 24px;
}
.osint__browse-search {
	display: flex;
	align-items: center;
	gap: 10px;
	background: var(--glass-bg);
	border: 1px solid var(--glass-edge);
	border-top-color: var(--glass-edge-top);
	padding: 10px 16px;
	min-width: 280px;
	transition: border-color .2s;
}
.osint__browse-search:focus-within {
	border-color: var(--c-lime, #CDFE64);
}
.osint__browse-search svg {
	width: 18px;
	height: 18px;
	color: var(--c-text-faint);
	flex-shrink: 0;
}
.osint__browse-search input[type="text"] {
	background: none;
	border: none;
	color: var(--c-text);
	font-size: 14px;
	font-family: inherit;
	outline: none;
	width: 100%;
	min-width: 0;
	padding: 0;
}
.osint__browse-search input[type="text"]::placeholder {
	color: var(--c-text-faint);
}

/* Schema type dropdown */
.osint__schema-select-wrap {
	position: relative;
	display: inline-flex;
	align-items: center;
}
.osint__schema-select {
	appearance: none;
	-webkit-appearance: none;
	background: var(--glass-bg);
	border: 1px solid var(--glass-edge);
	border-top-color: var(--glass-edge-top);
	color: var(--c-text);
	font-family: inherit;
	font-size: 14px;
	font-weight: 500;
	padding: 10px 40px 10px 16px;
	cursor: pointer;
	transition: border-color .2s;
	min-width: 160px;
}
.osint__schema-select:hover {
	border-color: var(--c-text-faint);
}
.osint__schema-select:focus {
	outline: none;
	border-color: var(--c-lime, #CDFE64);
}
.osint__schema-select option {
	background: var(--c-bg-surface);
	color: var(--c-text);
}
.osint__schema-select-arrow {
	position: absolute;
	inset-inline-end: 12px;
	width: 16px;
	height: 16px;
	color: var(--c-text-faint);
	pointer-events: none;
}

.osint__browse-meta {
	padding-bottom: 8px;
}

/* =============================================================
 * DASHBOARD — type strip over a full-width recent feed
 * =========================================================== */
.osint__dashboard {
	display: flex;
	flex-direction: column;
	gap: 32px;
}
/* Blocks must be allowed to shrink below their content's min-width,
   or one long unbreakable entity name widens the layout past the
   viewport on phones. */
.osint__dash-block {
	min-width: 0;
}
.osint__dash-title {
	font-size: 17px;
	font-weight: 700;
	color: var(--c-text);
	margin: 0 0 16px;
}

/* ---- Type strip — one bounded tile per schema, each a browse filter ---- */
.osint__type-strip {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
	gap: 12px;
}
.osint__type-tile {
	display: flex;
	flex-direction: column;
	gap: 12px;
	min-width: 0;
	padding: 20px;
	background: var(--glass-bg);
	border: 1px solid var(--glass-edge);
	border-top-color: var(--glass-edge-top);
	text-decoration: none;
	transition: background .14s, border-color .14s;
}
.osint__type-tile:hover {
	background: rgba(var(--c-border-rgb), .04);
	border-color: color-mix(in srgb, var(--tile-color, var(--c-text-faint)) 40%, transparent);
}
.osint__type-tile-count {
	font-family: "itf Somaya Arabic";
	font-size: 30px;
	font-weight: 700;
	line-height: 1;
	color: var(--c-text);
}
.osint__type-tile-label {
	display: flex;
	align-items: center;
	gap: 8px;
	min-width: 0;
	font-size: 14px;
	color: var(--c-text-3);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* Schema colour dot — the swatch that ties a type to its graph colour.
   Colour comes from --tile-color so the tile is the single source. */
.osint__schema-dot {
	width: 8px;
	height: 8px;
	flex-shrink: 0;
	background: var(--tile-color, var(--c-text-faint));
}

/* ---- Recent feed — two columns of rows so a full-width card reads
       as a list, not as one absurdly wide row per entity. ---- */
.osint__entity-rows {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	column-gap: 32px;
}

/* ---- Card ---- */
.osint__card {
	background: var(--glass-bg);
	border: 1px solid var(--glass-edge);
	border-top-color: var(--glass-edge-top);
	padding: 28px 28px;
}
.osint__card-header {
	font-size: 17px;
	font-weight: 700;
	color: var(--c-text);
	margin: 0 0 20px;
	padding-bottom: 14px;
	border-bottom: 1px solid rgba(var(--c-border-rgb), .08);
}

/* Entity mini rows (recent list) */
/* min-width: 0 is load-bearing: as a grid item the row's automatic minimum
   size would otherwise be the nowrap entity name's full width, pushing the
   row out of its track and the page into horizontal scroll on phones. */
.osint__entity-row {
	display: flex;
	align-items: center;
	gap: 10px;
	min-width: 0;
	padding: 9px 6px;
	text-decoration: none;
	color: inherit;
	transition: background .12s;
}
.osint__entity-row:hover {
	background: rgba(var(--c-border-rgb), .04);
}
.osint__entity-row-icon {
	width: 34px;
	height: 34px;
	flex-shrink: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	background: currentColor;
	background: color-mix(in srgb, currentColor 8%, transparent);
	border: 1px solid color-mix(in srgb, currentColor 12%, transparent);
}
/* Portrait fills the tile; the tinted glyph chrome would frame the face. */
.osint__entity-row-icon.has-photo {
	background: var(--c-bg-elevated);
	border-color: rgba(var(--c-border-rgb), .12);
	overflow: hidden;
}
.osint__entity-row-icon.has-photo img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}
.osint__entity-row-icon svg {
	width: 18px;
	height: 18px;
	opacity: .8;
}
.osint__entity-row-name {
	flex: 1;
	font-size: 15px;
	color: var(--c-text);
	font-weight: 500;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	min-width: 0;
}

/* =============================================================
 * BROWSE — entity card grid
 * =========================================================== */
.osint__browse-total {
	font-size: 12px;
	color: var(--c-text-faint);
}

.osint__entity-grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 10px;
}

.osint__entity-card {
	display: flex;
	align-items: center;
	gap: 12px;
	background: var(--glass-bg);
	border: 1px solid var(--glass-edge);
	border-top-color: var(--glass-edge-top);
	padding: 16px;
	text-decoration: none;
	color: inherit;
	transition: background .15s;
}
.osint__entity-card:hover {
	background: var(--glass-bg-hover);
}

.osint__entity-card-icon {
	width: 38px;
	height: 38px;
	flex-shrink: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	background: color-mix(in srgb, currentColor 8%, transparent);
	border: 1px solid color-mix(in srgb, currentColor 12%, transparent);
}
.osint__entity-card-icon svg {
	width: 18px;
	height: 18px;
	opacity: .8;
}
.osint__entity-card-icon.has-photo {
	background: var(--c-bg-elevated);
	border-color: rgba(var(--c-border-rgb), .12);
	overflow: hidden;
}
.osint__entity-card-icon img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.osint__entity-card-body {
	flex: 1;
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: 4px;
}
.osint__entity-card-name {
	font-size: 15px;
	font-weight: 600;
	color: var(--c-text);
	line-height: 1.3;
}
.osint__entity-card-meta {
	display: flex;
	align-items: center;
	gap: 8px;
	flex-wrap: wrap;
}
.osint__entity-card-schema {
	font-size: 11px;
	font-weight: 600;
}
.osint__entity-card-country {
	font-size: 11px;
	color: var(--c-text-faint);
}
.osint__entity-card-rels {
	font-size: 11px;
	color: var(--c-text-faint);
}

/* Pagination */
.osint__pagination {
	display: flex;
	gap: 4px;
	margin-top: 20px;
	justify-content: center;
}
.osint__page-link {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 30px;
	height: 30px;
	font-size: 12px;
	color: var(--c-text-faint);
	text-decoration: none;
	background: var(--glass-bg);
	border: 1px solid var(--glass-edge);
	transition: background .12s, color .12s;
}
.osint__page-link:hover {
	background: var(--glass-bg-hover);
	color: var(--c-text-2);
}
.osint__page-link.is-active {
	background: var(--c-text);
	color: var(--c-bg-base);
	border-color: var(--c-text);
}

/* =============================================================
 * GRAPH
 * =========================================================== */
.osint__graph-canvas {
	flex: 1;
	background: var(--c-bg-alt);
	border: 1px solid rgba(var(--c-border-rgb), .04);
	min-height: 500px;
	transition: opacity .6s ease;
}

/* =============================================================
 * TIMELINE — mirrors the investigation timeline visual language
 * (vertical line, 24px markers, lime accent) but with cards.
 * =========================================================== */
.osint-timeline {
	position: relative;
	padding: 0 0 48px;
	padding-inline-start: 56px;
	max-width: 760px;
}

/* Vertical track — full height, same position as investigation */
.osint-timeline__line {
	position: absolute;
	inset-inline-start: 11px;
	top: 0;
	bottom: 0;
	width: 2px;
	background: rgba(var(--c-border-rgb), .18);
	z-index: 0;
}

/* --- Year marker --- */
.osint-timeline__year-marker {
	position: relative;
	padding: 28px 0 10px;
}
.osint-timeline__year-marker:first-child {
	padding-top: 0;
}
.osint-timeline__year {
	font-family: "itf Somaya Arabic";
	font-size: 18px;
	font-weight: 700;
	color: var(--c-text);
	letter-spacing: 0; /* Arabic — never tracked */
}

/* --- Timeline item --- */
.osint-timeline__item {
	position: relative;
	padding: 0;
	padding-block: 8px;
	margin-bottom: 0;
	opacity: 0;
	transform: translateY(16px);
	animation: tl-fade-in .5s ease forwards;
}
.osint-timeline__item:nth-child(2) { animation-delay: .05s; }
.osint-timeline__item:nth-child(3) { animation-delay: .1s; }
.osint-timeline__item:nth-child(4) { animation-delay: .15s; }
.osint-timeline__item:nth-child(5) { animation-delay: .2s; }
.osint-timeline__item:nth-child(6) { animation-delay: .25s; }
.osint-timeline__item:nth-child(7) { animation-delay: .3s; }
.osint-timeline__item:nth-child(8) { animation-delay: .35s; }
.osint-timeline__item:nth-child(n+9) { animation-delay: .4s; }

@keyframes tl-fade-in {
	to { opacity: 1; transform: translateY(0); }
}

/* --- Marker — 14px square on the line --- */
.osint-timeline__dot {
	position: absolute;
	box-sizing: border-box;
	inset-inline-start: -50px;
	top: 18px;
	width: 14px;
	height: 14px;
	border-radius: 0;
	background: var(--c-bg-alt);
	border: 2px solid rgba(var(--c-border-rgb), .25);
	z-index: 2;
	transition:
		border-color .3s ease,
		background .3s ease,
		box-shadow .3s ease,
		transform .3s ease;
}
/* Hover: fill + rotate — no neon glow */
.osint-timeline__item:hover .osint-timeline__dot {
	border-color: var(--c-lime, #CDFE64);
	background: var(--c-lime, #CDFE64);
	transform: rotate(45deg);
}

/* --- Card --- */
.osint-timeline__card {
	background: var(--glass-bg);
	border: 1px solid var(--glass-edge);
	border-top-color: var(--glass-edge-top);
	padding: 18px 22px;
	transition: background .2s;
}
.osint-timeline__card:hover {
	background: var(--glass-bg-hover);
}

/* --- Date --- */
.osint-timeline__date {
	display: inline-block;
	font-family: "itf Somaya Arabic";
	font-size: 12px;
	letter-spacing: 0; /* Arabic — never tracked */
	color: var(--c-text-faint);
	margin-bottom: 8px;
}

/* --- Card body --- */
.osint-timeline__card-body {
	display: flex;
	flex-direction: column;
	gap: 8px;
}

/* --- Title --- */
.osint-timeline__title {
	font-size: 18px;
	font-weight: 700;
	color: var(--c-text);
	line-height: 1.4;
	text-decoration: none;
	transition: color .15s;
}
a.osint-timeline__title:hover {
	color: var(--c-lime, #CDFE64);
}

/* --- Description --- */
.osint-timeline__desc {
	font-size: 14px;
	color: var(--c-text-muted);
	margin: 0;
	line-height: 1.6;
}

/* --- Tags --- */
.osint-timeline__tags {
	display: flex;
	align-items: center;
	gap: 6px;
	flex-wrap: wrap;
	margin-top: 4px;
}

.osint-timeline__type-badge {
	font-size: 11px;
	font-weight: 600;
	padding: 3px 10px;
	background: rgba(var(--c-border-rgb), .05);
	color: var(--c-text-muted);
	letter-spacing: 0; /* Arabic — never tracked */
}

.osint-timeline__entity-tag {
	font-size: 11px;
	font-weight: 500;
	color: var(--c-text-faint) !important;
	transition: color .15s;
}
.osint-timeline__entity-tag:hover {
	color: var(--c-text-3) !important;
}

/* =============================================================
 * FILE SWITCHER — mini cards inside hero to switch files
 * =========================================================== */
.osint__file-switcher {
	display: flex;
	align-items: stretch;
	gap: 10px;
	margin-top: 20px;
}
.osint__file-mini {
	position: relative;
	display: flex;
	align-items: flex-end;
	overflow: hidden;
	width: 160px;
	height: 72px;
	text-decoration: none;
	color: inherit;
	border: 1px solid rgba(var(--c-border-rgb), .08);
	flex-shrink: 0;
	transition: border-color .25s, box-shadow .25s, transform .2s;
	opacity: 0;
	transform: scale(1.15);
	animation: osint-mini-shrink .5s cubic-bezier(.16, 1, .3, 1) forwards;
}
.osint__file-mini:nth-child(1) { animation-delay: .05s; }
.osint__file-mini:nth-child(2) { animation-delay: .1s; }
.osint__file-mini:nth-child(3) { animation-delay: .15s; }
.osint__file-mini:nth-child(4) { animation-delay: .2s; }
.osint__file-mini:nth-child(5) { animation-delay: .25s; }
@keyframes osint-mini-shrink {
	to { opacity: 1; transform: scale(1); }
}
.osint__file-mini:hover {
	border-color: var(--c-text-faint);
	box-shadow: 0 4px 16px rgba(0, 0, 0, .3);
	transform: scale(1.03);
}
.osint__file-mini.is-active {
	border-color: var(--c-text);
	opacity: 1;
	transform: scale(1);
	animation: none;
}
.osint__file-mini.is-active:hover {
	transform: scale(1);
}

/* Skip intro animation on file-switch reloads */
.osint__file-switcher.no-intro .osint__file-mini {
	opacity: 1;
	transform: scale(1);
	animation: none;
}

.osint__dataset-switcher {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 8px;
	margin-top: 12px;
	max-width: min(720px, 100%);
}
.osint__dataset-switcher-label {
	font-size: 12px;
	font-weight: 700;
	color: var(--c-text-muted);
}
.osint__dataset-chip {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	min-height: 34px;
	padding: 7px 11px;
	border: 1px solid var(--glass-edge);
	border-top-color: var(--glass-edge-top);
	background: var(--glass-bg);
	color: var(--c-text-2);
	font-size: 12px;
	font-weight: 700;
	text-decoration: none;
	transition: border-color .2s, color .2s, background .2s;
}
.osint__dataset-chip:hover {
	border-color: rgba(205, 254, 100, .34);
	color: var(--c-text);
}
.osint__dataset-chip.is-active {
	border-color: var(--c-text);
	background: var(--c-text);
	color: var(--c-bg-base);
}
.osint__dataset-chip span {
	color: var(--c-text-faint);
	font-size: 11px;
}
.osint__dataset-chip.is-active span {
	color: var(--c-bg-base);
	opacity: .6;
}
/* Smooth active-state swap when switching */
.osint__file-mini.is-leaving {
	border-color: rgba(var(--c-border-rgb), .08) !important;
	box-shadow: none !important;
}
.osint__file-mini.is-leaving .osint__file-mini-name {
	color: var(--c-text-3) !important;
}
.osint__file-mini.is-entering {
	border-color: var(--c-text) !important;
	box-shadow: none !important;
}
.osint__file-mini.is-entering .osint__file-mini-name {
	color: var(--c-text) !important;
}

/* Cover */
.osint__file-mini-cover {
	position: absolute;
	inset: 0;
	background-size: cover;
	background-position: center;
	z-index: 0;
	transition: transform .3s ease;
}
.osint__file-mini:hover .osint__file-mini-cover {
	transform: scale(1.08);
}
.osint__file-mini-cover--empty {
	background: linear-gradient(135deg, var(--c-bg-alt) 0%, var(--c-bg-surface) 100%);
}

/* Overlay */
.osint__file-mini-overlay {
	position: absolute;
	inset: 0;
	background: linear-gradient(
		to top,
		rgba(var(--c-bg-base-rgb), .92) 0%,
		rgba(var(--c-bg-base-rgb), .55) 100%
	);
	z-index: 1;
}

/* Name */
.osint__file-mini-name {
	position: relative;
	z-index: 2;
	padding: 8px 12px;
	font-size: 13px;
	font-weight: 600;
	color: var(--c-text-3);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	width: 100%;
}
.osint__file-mini.is-active .osint__file-mini-name {
	color: var(--c-text);
}
.osint__file-mini:not(.is-active):hover .osint__file-mini-name {
	color: var(--c-text);
}

/* =============================================================
 * HERO — picker variant (no file selected)
 * =========================================================== */
.osint__hero--picker {
	padding-bottom: 0;
}
.osint__hero-inner--picker {
	padding-bottom: 32px;
}

/* Horizontal file cards strip inside hero */
.osint__hero-files {
	position: relative;
	z-index: 1;
	max-width: 1232px;
	margin: 0 auto;
	padding: 0 24px 40px;
}
.osint__hero-files-track {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
	gap: 16px;
}
/* Cap the card instead of special-casing the count. auto-fit collapses empty
   tracks, so a lone dataset stretched to the full 1232px against a fixed
   200–240px height — a 5:1 letterbox with its title stranded in one corner.
   Capped, the card is the same size whether there is one dataset or six, so
   nothing lurches when the next one lands and there is no `if (count === 1)`
   branch to maintain. Desktop only: on phones the track is a single column
   and full width is correct. */
@media (min-width: 900px) {
	.osint__dataset-card {
		max-width: 560px;
	}
}

/* ---- Dataset picker card ----
   The entry point into a dataset, so it answers three things before you click:
   which file it sits in, what it is, and how much is in it. The figures are the
   dataset hero's own triad in the same order, so the card previews the page
   rather than measuring something else.

   Deliberately short and wide: the radar animation sits directly below and has
   to stay in view, so height is capped rather than tied to an aspect ratio —
   which at full container width would build a ~580px tower. Grid rows already
   equalise sibling heights, so evenness costs nothing; the original ragged look
   came from a missing cover, not from height.

   The cover is a backdrop under a scrim rather than a picture the text sits
   beside, so a dataset with a photograph and one without read as one object. */
.osint__dataset-card {
	position: relative;
	display: flex;
	flex-direction: column;
	justify-content: flex-end;
	overflow: hidden;
	min-height: 200px;
	max-height: 240px;
	text-decoration: none;
	color: inherit;
	background: var(--glass-bg);
	border: 1px solid var(--glass-edge);
	border-top-color: var(--glass-edge-top);
	transition: border-color .25s, box-shadow .25s, transform .25s;
}
.osint__dataset-card:hover {
	border-color: rgba(var(--c-border-rgb), .28);
	box-shadow: 0 12px 40px rgba(0, 0, 0, .4);
	transform: translateY(-3px);
}
/* ---- "قريباً" teaser ----
   A visitor decides whether a card is worth clicking from two metres away, off
   the artwork alone. Dimming was not enough: the card still read as one of the
   open ones with a small chip beside the file name, so the first thing anyone
   learned about it was a dead click.

   Three signals instead, none of which needs to be read to work: the artwork
   goes grey while the open cards stay in colour, the border goes dashed —
   unfinished, not a boundary you can cross — and the marker moves to the middle
   of the card at full size. The name dims so the plate is the loudest thing on
   it. Every one of these is off by default and only applied to `.is-teaser`, so
   an editor's working link is untouched. */
.osint__dataset-card.is-teaser {
	cursor: default;
	border-style: dashed;
	border-color: rgba(var(--c-border-rgb), .22);
}
/* Grayscale is doing the work here, so the opacity stays close to an open
   card's. Stacking a heavy fade on top buried the artwork, and showing the
   artwork is the reason a teaser exists at all. */
.osint__dataset-card.is-teaser .osint__dataset-card-cover {
	filter: grayscale(1) contrast(.92);
	opacity: .45;
}
.osint__dataset-card.is-teaser .osint__dataset-card-name {
	color: var(--c-text-2);
}
.osint__dataset-card.is-teaser .osint__dataset-card-file {
	opacity: .6;
}

.osint__dataset-card-lock {
	position: absolute;
	inset: 0;
	z-index: 2;
	display: flex;
	align-items: center;
	justify-content: center;
	/* The plate is a label, not a control — it must never eat a click or
	   suggest one is being offered. */
	pointer-events: none;
}
.osint__dataset-card-lock-plate {
	padding: 10px 26px;
	background: rgba(var(--c-bg-base-rgb), .72);
	border: 1px solid rgba(255, 255, 255, .22);
	-webkit-backdrop-filter: blur(10px);
	backdrop-filter: blur(10px);
	color: var(--c-text);
	/* One step above the 24px dataset name: the plate has to be the first
	   thing read on the card, not the second. */
	font-size: 26px;
	font-weight: 700;
	line-height: 1;
	letter-spacing: 0; /* Arabic — never tracked */
	white-space: nowrap;
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
	.osint__dataset-card-lock-plate {
		background: rgba(var(--c-bg-base-rgb), .9);
	}
}
@media (max-width: 600px) {
	.osint__dataset-card-lock-plate {
		font-size: 20px;
		padding: 8px 20px;
	}
}

.osint__dataset-card-cover {
	position: absolute;
	inset: 0;
	z-index: 0;
	background-size: cover;
	background-position: center;
	transition: transform .5s ease;
}
.osint__dataset-card:hover .osint__dataset-card-cover {
	transform: scale(1.04);
}

/* Scrim: heavy at the foot where the text sits, clearing towards the top so the
   image still reads. Also drawn on a coverless card, at lower strength, so both
   variants share one surface treatment instead of looking like two components. */
.osint__dataset-card-veil {
	position: absolute;
	inset: 0;
	z-index: 1;
	background: linear-gradient(
		to top,
		rgba(var(--c-bg-base-rgb), .96) 0%,
		rgba(var(--c-bg-base-rgb), .82) 42%,
		rgba(var(--c-bg-base-rgb), .30) 100%
	);
}
/* No cover anywhere — not a void. Borrows the faint plotting grid the
   relationship canvas draws, masked out toward the foot so it never fights the
   text: a coverless dataset then reads as an OSINT surface rather than as a card
   whose image failed to load. */
.osint__dataset-card.has-no-cover {
	background:
		linear-gradient(135deg, rgba(var(--c-border-rgb), .10) 0%, transparent 60%),
		var(--c-bg-surface);
}
.osint__dataset-card.has-no-cover::before {
	content: '';
	position: absolute;
	inset: 0;
	z-index: 0;
	background-image:
		linear-gradient(rgba(var(--c-border-rgb), .10) 1px, transparent 1px),
		linear-gradient(90deg, rgba(var(--c-border-rgb), .10) 1px, transparent 1px);
	background-size: 40px 40px;
	mask-image: linear-gradient(to top, transparent 30%, rgba(0,0,0,.9) 100%);
	-webkit-mask-image: linear-gradient(to top, transparent 30%, rgba(0,0,0,.9) 100%);
}
.osint__dataset-card.has-no-cover .osint__dataset-card-veil {
	background: linear-gradient(to top, rgba(var(--c-bg-base-rgb), .55) 0%, transparent 70%);
}

.osint__dataset-card-body {
	position: relative;
	z-index: 2;
	display: flex;
	flex-direction: column;
	gap: 10px;
	padding: 22px;
}

/* Eyebrow: the parent file as plain quiet text. It was a grey pill with a
   folder icon — chrome competing with the name it was meant to introduce. The
   trail grammar elsewhere in the workspace already says "context is quiet
   text", so this follows it. */
.osint__dataset-card-eyebrow {
	display: flex;
	align-items: center;
	gap: 8px;
	min-width: 0;
}
.osint__dataset-card-file {
	min-width: 0;
	font-size: 12px;
	font-weight: 600;
	color: var(--c-text-faint);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.osint__dataset-card-name {
	font-size: 24px;
	font-weight: 700;
	line-height: 1.25;
	color: var(--c-text);
}

.osint__dataset-card-stats {
	display: flex;
	align-items: baseline;
	gap: 20px;
	padding-top: 12px;
	border-top: 1px solid rgba(var(--c-border-rgb), .12);
}
.osint__dataset-card-stat {
	display: flex;
	align-items: baseline;
	gap: 5px;
	min-width: 0;
}
.osint__dataset-card-stat-value {
	font-family: "itf Somaya Arabic";
	font-size: 17px;
	font-weight: 700;
	line-height: 1;
	color: var(--c-text);
}
.osint__dataset-card-stat-label {
	font-size: 11px;
	color: var(--c-text-faint);
	white-space: nowrap;
}

/* =============================================================
 * LOCKED TABS + DATABASE STATE (no file selected)
 * =========================================================== */
.osint__tabs--locked {
	pointer-events: none;
	opacity: .25;
}
.osint__locked-state {
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 24px 0 48px;
}

/* Radar */
.eekad-radar {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 24px;
	padding: 60px 0;
}
.eekad-radar__disc {
	position: relative;
	width: 180px;
	height: 180px;
}

.eekad-radar__ring {
	position: absolute;
	border: 1px solid rgba(var(--c-lime-rgb), .1);
	border-radius: 50%;
}
.eekad-radar__ring--1 { inset: 0; }
.eekad-radar__ring--2 { inset: 20%; }
.eekad-radar__ring--3 { inset: 40%; }

.eekad-radar__cross {
	position: absolute;
	background: rgba(var(--c-lime-rgb), .06);
}
.eekad-radar__cross--h {
	top: 50%; left: 0; right: 0; height: 1px;
}
.eekad-radar__cross--v {
	left: 50%; top: 0; bottom: 0; width: 1px;
}

.eekad-radar__center {
	position: absolute;
	top: 50%; left: 50%;
	width: 6px; height: 6px;
	margin: -3px 0 0 -3px;
	background: var(--c-lime, #CDFE64);
	border-radius: 50%;
}

.eekad-radar__sweep {
	position: absolute;
	inset: 0;
	border-radius: 50%;
	background: conic-gradient(
		from 0deg,
		transparent 0deg,
		transparent 300deg,
		rgba(var(--c-lime-rgb), .03) 330deg,
		rgba(var(--c-lime-rgb), .12) 355deg,
		rgba(var(--c-lime-rgb), .25) 360deg
	);
	animation: radar-spin 2.5s linear infinite;
}

.eekad-radar__beam {
	position: absolute;
	top: 50%; left: 50%;
	width: 50%; height: 1px;
	transform-origin: 0% 50%;
	background: linear-gradient(90deg, rgba(var(--c-lime-rgb), .6), transparent);
	animation: radar-spin 2.5s linear infinite;
}

@keyframes radar-spin {
	from { transform: rotate(0deg); }
	to   { transform: rotate(360deg); }
}

.eekad-radar__blip {
	position: absolute;
	width: 4px; height: 4px;
	border-radius: 50%;
	background: var(--c-lime, #CDFE64);
	opacity: 0;
	animation: radar-blip 2.5s ease-out infinite;
}
.eekad-radar__blip--1 { top: 22%; left: 65%; animation-delay: 0s; }
.eekad-radar__blip--2 { top: 60%; left: 28%; animation-delay: .8s; }
.eekad-radar__blip--3 { top: 35%; left: 38%; animation-delay: 1.6s; }

@keyframes radar-blip {
	0%   { opacity: 0; transform: scale(.5); }
	10%  { opacity: 1; transform: scale(1); }
	60%  { opacity: .3; transform: scale(1); }
	100% { opacity: 0; transform: scale(.5); }
}

.eekad-radar__label {
	font-size: 13px;
	color: var(--c-text-faint);
	letter-spacing: 0; /* Arabic — never tracked */
}

/* =============================================================
 * EMPTY STATE
 * =========================================================== */
.osint__empty {
	text-align: center;
	padding: 60px 0;
	color: var(--c-text-faint);
	font-size: 13px;
}

/* =============================================================
 * RESPONSIVE
 * =========================================================== */
@media (max-width: 900px) {
	.osint__hero-inner {
		flex-direction: column;
		align-items: flex-start;
		padding: 0 20px 24px;
	}
	.osint__hero-title { font-size: 32px; }
	.osint__hero-stats { gap: 20px; }
	.osint__hero-stat-value { font-size: 24px; }
	.osint__tabs {
		padding: 0 20px;
		overflow-x: auto;
	}
	.osint__main {
		padding: 20px 20px 48px;
	}
	.osint__panel-header {
		margin-bottom: 16px;
	}
}

@media (max-width: 960px) {
	.osint__entity-grid {
		grid-template-columns: repeat(2, 1fr);
	}
}
@media (max-width: 640px) {
	.osint__entity-grid {
		grid-template-columns: 1fr;
	}
	.osint__entity-rows {
		grid-template-columns: 1fr;
	}
	.osint__type-strip {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
	.osint__hero-files-track {
		grid-template-columns: 1fr;
	}
}
