/* ==========================================================================
   VARDIYA — Operator Dashboard Shell
   Framework-only styles: sidebar, topbar, widget grid, skeleton placeholders.
   No real content, no marketing patterns. Enterprise SOC console aesthetic.
   ========================================================================== */

/* ---------- Design tokens ---------- */
:root {
	/* Surfaces */
	--vd-bg-void:      #0a0c0f;
	--vd-bg-surface:    #101317;
	--vd-bg-panel:      #14181d;
	--vd-bg-panel-hover: #171c22;
	--vd-bg-inset:      #0d0f13;

	/* Borders */
	--vd-border:        #21262d;
	--vd-border-soft:   #1a1e24;
	--vd-border-accent: #3a5347;

	/* Text */
	--vd-text-primary:   #e7eaed;
	--vd-text-secondary: #8b9299;
	--vd-text-tertiary:  #565c63;

	/* Accent — muted sage/forest green, used sparingly */
	--vd-accent:        #5da483;
	--vd-accent-dim:     #3d6b56;
	--vd-accent-glow:    rgba(93, 164, 131, 0.14);
	--vd-accent-glow-strong: rgba(93, 164, 131, 0.28);

	/* Status */
	--vd-status-ok:     #5da483;

	/* Sprint 5 — data-visualization tokens. Additive only: these sit
	   alongside the existing palette at the same muted saturation/
	   lightness as --vd-accent, so severity badges, status pills and
	   chart segments read as part of the same visual language rather
	   than a bolted-on color system. No existing token above is
	   changed. */
	--vd-sev-critical:      #c9584f;
	--vd-sev-critical-glow: rgba(201, 88, 79, 0.16);
	--vd-sev-high:          #c98a4f;
	--vd-sev-high-glow:     rgba(201, 138, 79, 0.16);
	--vd-sev-medium:        #c9b84f;
	--vd-sev-medium-glow:   rgba(201, 184, 79, 0.14);
	--vd-sev-low:           #6c93a6;
	--vd-sev-low-glow:      rgba(108, 147, 166, 0.14);
	--vd-viz-alt-1:         #6c93a6;
	--vd-viz-alt-2:         #8b7fc9;
	--vd-viz-alt-3:         #565c63;

	/* Type */
	--vd-font-ui:   "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
	--vd-font-mono: "IBM Plex Mono", "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

	/* Layout */
	--vd-sidebar-w: 76px;
	--vd-topbar-h: 60px;
	--vd-radius-sm: 6px;
	--vd-radius-md: 10px;
	--vd-gap: 16px;

	color-scheme: dark;
}

/* ---------- Reset (scoped to dashboard) ---------- */
.vardiya-dashboard,
.vardiya-dashboard * ,
.vardiya-dashboard *::before,
.vardiya-dashboard *::after {
	box-sizing: border-box;
	margin: 0;
	padding: 0;
}

.vardiya-dashboard {
	background: var(--vd-bg-void);
	color: var(--vd-text-primary);
	font-family: var(--vd-font-ui);
	font-size: 14px;
	line-height: 1.4;
	-webkit-font-smoothing: antialiased;
}

.vardiya-dashboard a {
	color: inherit;
	text-decoration: none;
}

.vardiya-dashboard ul {
	list-style: none;
}

.vardiya-dashboard button {
	font-family: inherit;
	background: none;
	border: none;
	color: inherit;
	cursor: pointer;
}

.vardiya-dashboard :focus-visible {
	outline: 2px solid var(--vd-accent);
	outline-offset: 2px;
}

/* ---------- Shell grid ---------- */
.vd-shell {
	display: grid;
	grid-template-columns: var(--vd-sidebar-w) 1fr;
	grid-template-rows: var(--vd-topbar-h) 1fr;
	grid-template-areas:
		"sidebar topbar"
		"sidebar main";
	/* Sprint 8.5: no longer height:100vh / overflow:hidden on desktop —
	   that turned .vd-main into a second, internally-scrolling viewport
	   on top of the page's own scrollbar. The shell now grows with its
	   content and the whole page scrolls once. Mobile keeps the old
	   100vh + hidden-overflow shell (restored in the 768px block below)
	   since that's what pins the bottom nav and is explicitly out of
	   scope for this fix. */
}

/* ---------- Sidebar ---------- */
.vd-sidebar {
	grid-area: sidebar;
	background: var(--vd-bg-surface);
	border-right: 1px solid var(--vd-border-soft);
	display: flex;
	flex-direction: column;
	align-items: center;
	padding: 16px 0;
	z-index: 20;
}

.vd-sidebar__mark {
	width: 32px;
	height: 32px;
	border-radius: var(--vd-radius-sm);
	border: 1px solid var(--vd-border);
	display: flex;
	align-items: center;
	justify-content: center;
	margin-bottom: 28px;
}

.vd-sidebar__mark-dot {
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: var(--vd-accent);
}

.vd-sidebar__nav {
	width: 100%;
	flex: 1;
}

.vd-sidebar__list {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 4px;
}

.vd-sidebar__link {
	position: relative;
	width: 52px;
	height: 52px;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 4px;
	border-radius: var(--vd-radius-sm);
	color: var(--vd-text-tertiary);
	transition: color 0.15s ease, background-color 0.15s ease;
}

.vd-sidebar__link:hover {
	color: var(--vd-text-primary);
	background: var(--vd-bg-panel-hover);
}

.vd-sidebar__link.is-active {
	color: var(--vd-accent);
	background: var(--vd-accent-glow);
}

.vd-sidebar__link.is-active::before {
	content: "";
	position: absolute;
	left: -16px;
	top: 50%;
	transform: translateY(-50%);
	width: 2px;
	height: 18px;
	background: var(--vd-accent);
	border-radius: 2px;
}

.vd-sidebar__icon svg {
	width: 19px;
	height: 19px;
	display: block;
}

.vd-sidebar__label {
	font-size: 9.5px;
	letter-spacing: 0.02em;
	font-weight: 500;
}

.vd-sidebar__footer {
	padding-top: 12px;
}

.vd-sidebar__pulse {
	display: block;
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background: var(--vd-accent-dim);
}

/* ---------- Topbar ---------- */
.vd-topbar {
	grid-area: topbar;
	background: var(--vd-bg-surface);
	border-bottom: 1px solid var(--vd-border-soft);
	display: flex;
	align-items: center;
	padding: 0 20px;
	gap: 24px;
	z-index: 10;
}

.vd-topbar__logo {
	display: flex;
	align-items: center;
	gap: 10px;
	flex: 0 0 auto;
}

.vd-topbar__menu-btn {
	display: none;
	width: 32px;
	height: 32px;
	align-items: center;
	justify-content: center;
	border-radius: var(--vd-radius-sm);
	color: var(--vd-text-secondary);
}

.vd-topbar__menu-btn svg {
	width: 18px;
	height: 18px;
}

.vd-topbar__wordmark {
	font-family: var(--vd-font-mono);
	font-size: 14px;
	font-weight: 600;
	letter-spacing: 0.08em;
	margin: 0; /* h1 default browser margin would otherwise shift the topbar */
}

.vd-topbar__tag {
	font-family: var(--vd-font-mono);
	font-size: 10px;
	letter-spacing: 0.1em;
	color: var(--vd-text-tertiary);
	border-left: 1px solid var(--vd-border);
	padding-left: 10px;
}

.vd-topbar__search {
	flex: 1 1 auto;
	max-width: 480px;
	margin: 0 auto;
	display: flex;
	align-items: center;
	gap: 8px;
	background: var(--vd-bg-inset);
	border: 1px solid var(--vd-border);
	border-radius: var(--vd-radius-sm);
	padding: 0 12px;
	height: 34px;
	color: var(--vd-text-tertiary);
	transition: border-color 0.15s ease;
}

.vd-topbar__search:focus-within {
	border-color: var(--vd-border-accent);
}

.vd-topbar__search svg {
	width: 15px;
	height: 15px;
	flex: none;
}

.vd-topbar__search-input {
	flex: 1;
	background: none;
	border: none;
	color: var(--vd-text-primary);
	font-size: 13px;
	outline: none;
}

.vd-topbar__search-input::placeholder {
	color: var(--vd-text-tertiary);
}

.vd-topbar__kbd {
	font-family: var(--vd-font-mono);
	font-size: 10px;
	color: var(--vd-text-tertiary);
	border: 1px solid var(--vd-border);
	border-radius: 4px;
	padding: 1px 5px;
}

.vd-topbar__actions {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	gap: 12px;
}

.vd-status {
	display: flex;
	align-items: center;
	gap: 7px;
	font-family: var(--vd-font-mono);
	font-size: 11px;
	color: var(--vd-text-secondary);
	letter-spacing: 0.04em;
	padding: 5px 10px;
	border: 1px solid var(--vd-border);
	border-radius: 20px;
}

.vd-status__dot {
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background: var(--vd-status-ok);
	box-shadow: 0 0 0 3px var(--vd-accent-glow);
}

.vd-icon-btn {
	width: 32px;
	height: 32px;
	display: flex;
	align-items: center;
	justify-content: center;
	border-radius: var(--vd-radius-sm);
	border: 1px solid var(--vd-border);
	color: var(--vd-text-secondary);
	transition: color 0.15s ease, border-color 0.15s ease;
}

.vd-icon-btn:hover {
	color: var(--vd-text-primary);
	border-color: var(--vd-border-accent);
}

.vd-icon-btn svg {
	width: 16px;
	height: 16px;
}

.vd-btn {
	font-size: 12.5px;
	font-weight: 500;
	padding: 8px 16px;
	border-radius: var(--vd-radius-sm);
	border: 1px solid var(--vd-border);
	color: var(--vd-text-primary);
	white-space: nowrap;
	transition: border-color 0.15s ease, background-color 0.15s ease;
}

.vd-btn--primary {
	background: var(--vd-accent-glow);
	border-color: var(--vd-border-accent);
}

.vd-btn--primary:hover {
	background: var(--vd-accent-glow-strong);
}

/* ---------- Main dashboard grid ---------- */
/* grid-auto-flow stays in default row order (no "dense" packing): each
   widget keeps the column width it was given and never gets reflowed
   sideways to backfill a gap. Expansion only ever grows a widget's own
   row-span, which pushes later rows down in normal document order —
   siblings shift vertically as an unavoidable consequence of the card
   growing taller, but they never swap positions or change width. */
.vd-main {
	grid-area: main;
	/* Sprint 8.5: no longer overflow-y:auto on desktop — the widget grid
	   now expands to its natural height and scrolls with the page,
	   removing the second vertical scrollbar. Restored for mobile only
	   (768px block) where it's paired with the pinned bottom nav. */
	padding: var(--vd-gap);
	display: grid;
	gap: var(--vd-gap);
	grid-template-columns: repeat(12, 1fr);
	grid-auto-rows: 92px;
	grid-auto-flow: row;
	align-content: start;
}

/* Reading order (row 1 → row 5): status strip, primary widget, medium
   pair, equal trio, wide pair. Row height is kept at the same span-2
   unit used throughout the dashboard — only column width and DOM order
   change to build the hierarchy, per the "grid spans / columns / row
   order only" scope for this pass. */
.vd-widget--score     { grid-column: span 4;  grid-row: span 2; } /* row 1 — status strip */
.vd-widget--alerts    { grid-column: span 4;  grid-row: span 2; } /* row 1 — status strip */
.vd-widget--mitre     { grid-column: span 4;  grid-row: span 2; } /* row 1 — status strip */
.vd-widget--feed      { grid-column: span 12; grid-row: span 2; } /* row 2 — primary widget */
.vd-widget--activity  { grid-column: span 6;  grid-row: span 2; } /* row 3 — medium pair */
.vd-widget--ioc       { grid-column: span 6;  grid-row: span 2; } /* row 3 — medium pair */
.vd-widget--map       { grid-column: span 4;  grid-row: span 2; } /* row 4 — equal trio */
.vd-widget--assets    { grid-column: span 4;  grid-row: span 2; } /* row 4 — equal trio */
.vd-widget--research  { grid-column: span 4;  grid-row: span 2; } /* row 4 — equal trio */
.vd-widget--projects  { grid-column: span 6;  grid-row: span 2; } /* row 5 — wide pair */
.vd-widget--services  { grid-column: span 6;  grid-row: span 2; } /* row 5 — wide pair */

/* Expanded spans. Row-span is a discrete grid property — it can't be
   smoothly interpolated, so the cell's height allowance resizes in one
   step the moment .is-expanded is toggled. What reads as "the card
   growing" is the panel content revealing over ~280ms inside that cell
   (see .vd-widget__panel below). Column span is intentionally left
   untouched on every widget: width, position, and the grid template
   are locked, so no widget ever changes size or moves sideways when a
   sibling expands — only rows further down get pushed lower. */
.vd-widget.is-expanded {
	grid-row: span 6;
}

.vd-widget--feed.is-expanded {
	grid-row: span 5;
}

/* ---------- Widget shell ---------- */
.vd-widget {
	background: var(--vd-bg-panel);
	border: 1px solid var(--vd-border-soft);
	border-radius: var(--vd-radius-md);
	display: flex;
	flex-direction: column;
	min-height: 0;
	position: relative;
	transition: transform 0.22s ease, border-color 0.22s ease, box-shadow 0.22s ease, background-color 0.22s ease;
}

.vd-widget:hover {
	transform: translateY(-3px);
	border-color: var(--vd-border-accent);
	background: var(--vd-bg-panel-hover);
	box-shadow: 0 10px 28px -12px rgba(0, 0, 0, 0.65), 0 0 0 1px var(--vd-accent-glow-strong);
}

.vd-widget.is-expanded {
	border-color: var(--vd-border-accent);
	background: var(--vd-bg-panel-hover);
}

.vd-widget.is-expanded:hover {
	transform: none;
}

/* ---------- Widget header / toggle ---------- */
/* Follows the WAI-ARIA APG accordion pattern: the heading element wraps
   the interactive button, rather than a heading living inside a button.
   The button carries aria-expanded/aria-controls and gets Enter/Space
   for free because it's a native <button>. */
.vd-widget__title-wrap {
	flex: none;
}

.vd-widget__toggle {
	width: 100%;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	padding: 14px 16px;
	border-bottom: 1px solid var(--vd-border-soft);
	background: none;
	border-left: none;
	border-right: none;
	border-top: none;
	color: inherit;
	font: inherit;
	text-align: left;
	cursor: pointer;
}

.vd-widget__toggle-left {
	display: flex;
	align-items: center;
	gap: 9px;
	color: var(--vd-text-secondary);
	min-width: 0;
}

.vd-widget__toggle-right {
	display: flex;
	align-items: center;
	gap: 10px;
	flex: none;
}

.vd-widget__icon {
	width: 15px;
	height: 15px;
	flex: none;
}

.vd-widget__title {
	font-size: 12.5px;
	font-weight: 600;
	letter-spacing: 0.01em;
	color: var(--vd-text-primary);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.vd-widget__toggle:hover .vd-widget__title {
	color: var(--vd-text-primary);
}

.vd-widget__toggle:hover .vd-widget__toggle-left {
	color: var(--vd-accent);
}

.vd-widget__chevron {
	width: 14px;
	height: 14px;
	color: var(--vd-text-tertiary);
	transition: transform 0.2s ease, color 0.2s ease;
}

.vd-widget.is-expanded .vd-widget__chevron {
	transform: rotate(180deg);
	color: var(--vd-accent);
}

.vd-badge {
	font-family: var(--vd-font-mono);
	font-size: 10px;
	letter-spacing: 0.04em;
	padding: 3px 8px;
	border-radius: 20px;
	border: 1px solid var(--vd-border);
	color: var(--vd-text-tertiary);
	white-space: nowrap;
}

.vd-badge--live {
	color: var(--vd-accent);
	border-color: var(--vd-border-accent);
}

/* ---------- Collapsed overview ---------- */
.vd-widget__overview {
	padding: 18px 16px 20px;
	display: flex;
	flex-direction: column;
	gap: 4px;
}

.vd-widget__metric {
	font-family: var(--vd-font-mono);
	font-size: 28px;
	font-weight: 600;
	line-height: 1;
	color: var(--vd-text-primary);
}

.vd-widget__metric-unit {
	font-size: 15px;
	font-weight: 500;
	color: var(--vd-text-secondary);
	margin-left: 2px;
}

.vd-widget__metric-label {
	font-size: 11px;
	color: var(--vd-text-tertiary);
	letter-spacing: 0.02em;
}

/* Sprint 3 swaps a few of the short numeric placeholders for honest
   status phrases ("Synchronizing…", "Waiting for data…"). Those don't
   fit the 28px numeric scale used for "--" and "97", so this modifier
   steps the same metric element down to a size built for words rather
   than digits — same token, same weight, same family, just legible at
   sentence length instead of glyph length. */
.vd-widget__metric--text {
	font-size: 16px;
	font-weight: 500;
}

.vd-widget__empty-state {
	font-size: 11px;
	color: var(--vd-text-tertiary);
	line-height: 1.4;
	margin-top: 8px;
}

/* ---------- Expanded panel ---------- */
/* max-height is measured and set inline by JS (element.scrollHeight) so
   the 300ms ease transition tracks the panel's real content height
   rather than an arbitrary large ceiling — that's what keeps the
   animation timing consistent regardless of how much list content a
   given widget has. */
.vd-widget__panel {
	max-height: 0;
	opacity: 0;
	overflow: hidden;
	transform: translateY(-6px);
	transition: max-height 0.28s ease, opacity 0.28s ease, transform 0.28s ease;
}

.vd-widget.is-expanded .vd-widget__panel {
	opacity: 1;
	transform: translateY(0);
}

.vd-widget__panel-inner {
	padding: 0 16px 18px;
}

.vd-widget__divider {
	border: none;
	border-top: 1px solid var(--vd-border-soft);
	margin: 0 0 14px;
}

.vd-widget__section-title {
	font-size: 10.5px;
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--vd-text-tertiary);
	margin-bottom: 10px;
}

.vd-widget__list {
	display: flex;
	flex-direction: column;
	gap: 2px;
	margin-bottom: 14px;
}

.vd-widget__list-item {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 8px 10px;
	border-radius: 6px;
	font-size: 12.5px;
	color: var(--vd-text-secondary);
	transition: background-color 0.15s ease, color 0.15s ease;
}

.vd-widget__list-item:hover {
	background: var(--vd-bg-inset);
	color: var(--vd-text-primary);
}

.vd-widget__mini-arrow {
	color: var(--vd-text-tertiary);
	font-size: 13px;
	line-height: 1;
}

.vd-widget__cta {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	font-size: 12px;
	font-weight: 500;
	color: var(--vd-accent);
}

.vd-widget__cta:hover {
	color: var(--vd-text-primary);
}

/* ==========================================================================
   Sprint 5 — Visualization layer
   Small, reusable components that live INSIDE existing widget markup only.
   Nothing here touches grid, spacing, widget sizing, sidebar, topbar,
   typography scale, or the accordion mechanics above. SVG + CSS only.
   ========================================================================== */

/* ---------- Overview row: pairs a ring/metric with supporting content ---------- */
.vd-widget__overview-row {
	display: flex;
	align-items: center;
	gap: 14px;
}

.vd-widget__overview-col {
	display: flex;
	flex-direction: column;
	gap: 4px;
	min-width: 0;
}

/* ---------- Radial ring (Security Score, MITRE Coverage %) ---------- */
.vd-ring {
	position: relative;
	width: 56px;
	height: 56px;
	flex: none;
}

.vd-ring svg {
	width: 100%;
	height: 100%;
	transform: rotate(-90deg);
}

.vd-ring__track {
	fill: none;
	stroke: var(--vd-border-soft);
	stroke-width: 5;
}

.vd-ring__value {
	fill: none;
	stroke: var(--vd-accent);
	stroke-width: 5;
	stroke-linecap: round;
	stroke-dasharray: 150.8 150.8;
	stroke-dashoffset: calc(150.8 - (150.8 * var(--vd-ring-pct, 0) / 100));
	transition: stroke-dashoffset 0.6s ease;
}

.vd-ring__label {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	font-family: var(--vd-font-mono);
	font-size: 13px;
	font-weight: 600;
	color: var(--vd-text-primary);
}

/* ---------- Linear progress bar (Projects, score sub-metrics) ---------- */
.vd-bar {
	position: relative;
	display: block;
	width: 100%;
	height: 5px;
	border-radius: 4px;
	background: var(--vd-bg-inset);
	overflow: hidden;
	margin-top: 6px;
}

.vd-bar__fill {
	position: absolute;
	inset: 0;
	width: var(--vd-bar-pct, 0%);
	background: var(--vd-accent);
	border-radius: 4px;
	transition: width 0.6s ease;
}

.vd-bar__fill--high { background: var(--vd-sev-high); }
.vd-bar__fill--low { background: var(--vd-sev-low); }

/* ---------- Stacked bar (Asset Inventory OS distribution) ---------- */
.vd-stack-bar {
	display: flex;
	height: 8px;
	border-radius: 4px;
	overflow: hidden;
	background: var(--vd-bg-inset);
	margin-top: 10px;
}

.vd-stack-bar__seg {
	height: 100%;
}

.vd-stack-bar__seg--a { background: var(--vd-accent); }
.vd-stack-bar__seg--b { background: var(--vd-viz-alt-1); }
.vd-stack-bar__seg--c { background: var(--vd-viz-alt-2); }
.vd-stack-bar__seg--d { background: var(--vd-viz-alt-3); }

.vd-stack-legend {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin-top: 8px;
}

.vd-stack-legend__item {
	display: flex;
	align-items: center;
	gap: 6px;
	font-size: 11px;
	color: var(--vd-text-tertiary);
}

.vd-stack-legend__dot {
	width: 7px;
	height: 7px;
	border-radius: 50%;
	flex: none;
}

.vd-stack-legend__dot--a { background: var(--vd-accent); }
.vd-stack-legend__dot--b { background: var(--vd-viz-alt-1); }
.vd-stack-legend__dot--c { background: var(--vd-viz-alt-2); }
.vd-stack-legend__dot--d { background: var(--vd-viz-alt-3); }

/* ---------- Severity / status badge modifiers ---------- */
.vd-badge--critical { color: var(--vd-sev-critical); border-color: rgba(201, 88, 79, 0.4); }
.vd-badge--high      { color: var(--vd-sev-high);     border-color: rgba(201, 138, 79, 0.4); }
.vd-badge--medium    { color: var(--vd-sev-medium);   border-color: rgba(201, 184, 79, 0.4); }
.vd-badge--low       { color: var(--vd-sev-low);      border-color: rgba(108, 147, 166, 0.4); }
.vd-badge--good      { color: var(--vd-accent);       border-color: var(--vd-border-accent); }
.vd-badge--offline   { color: var(--vd-sev-critical); border-color: rgba(201, 88, 79, 0.4); }

/* ---------- Inline severity badge cluster (Critical Alerts, Threat Feed) ---------- */
.vd-badge-row {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	margin-top: 10px;
}

.vd-badge-count {
	font-family: var(--vd-font-mono);
	margin-left: 5px;
	font-weight: 700;
}

/* ---------- Status dot (used inline with list items and events) ---------- */
.vd-dot {
	width: 6px;
	height: 6px;
	border-radius: 50%;
	flex: none;
	background: var(--vd-text-tertiary);
}

.vd-dot--critical { background: var(--vd-sev-critical); box-shadow: 0 0 0 3px var(--vd-sev-critical-glow); }
.vd-dot--high      { background: var(--vd-sev-high);     box-shadow: 0 0 0 3px var(--vd-sev-high-glow); }
.vd-dot--medium    { background: var(--vd-sev-medium);   box-shadow: 0 0 0 3px var(--vd-sev-medium-glow); }
.vd-dot--low       { background: var(--vd-sev-low);      box-shadow: 0 0 0 3px var(--vd-sev-low-glow); }
.vd-dot--good      { background: var(--vd-accent);       box-shadow: 0 0 0 3px var(--vd-accent-glow); }

/* ---------- List item value + meta (appended into existing .vd-widget__list-item) ---------- */
.vd-widget__list-value {
	font-family: var(--vd-font-mono);
	font-size: 11.5px;
	color: var(--vd-text-tertiary);
	white-space: nowrap;
	margin-right: 6px;
}

.vd-widget__list-main {
	display: flex;
	align-items: center;
	gap: 8px;
	min-width: 0;
}

.vd-widget__list-text {
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-width: 0;
}

.vd-widget__list-mono {
	font-family: var(--vd-font-mono);
	font-size: 11.5px;
	color: var(--vd-text-primary);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.vd-widget__list-sub {
	font-size: 10.5px;
	color: var(--vd-text-tertiary);
}

.vd-widget__list-tag {
	font-family: var(--vd-font-mono);
	font-size: 9.5px;
	letter-spacing: 0.04em;
	color: var(--vd-text-tertiary);
	border: 1px solid var(--vd-border);
	border-radius: 4px;
	padding: 1px 5px;
	flex: none;
}

.vd-widget__list-meta {
	display: flex;
	align-items: center;
	gap: 8px;
	flex: none;
}

.vd-widget__list-bar {
	display: flex;
	flex-direction: column;
	gap: 4px;
	flex: 1 1 auto;
	min-width: 0;
}

/* ---------- Scrollable event list (Threat Feed) ---------- */
.vd-scroll-list {
	max-height: 220px;
	overflow-y: auto;
	margin: 2px -4px 14px;
	padding: 0 4px;
}

.vd-scroll-list::-webkit-scrollbar {
	width: 6px;
}

.vd-scroll-list::-webkit-scrollbar-thumb {
	background: var(--vd-border);
	border-radius: 4px;
}

.vd-scroll-list::-webkit-scrollbar-track {
	background: transparent;
}

/* ---------- Timeline (Recent Activity) ---------- */
.vd-timeline {
	display: flex;
	flex-direction: column;
	margin-bottom: 14px;
}

.vd-timeline__item {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: 2px;
	padding: 6px 10px 16px 22px;
	border-radius: 6px;
}

.vd-timeline__item::before {
	content: "";
	position: absolute;
	left: 4px;
	top: 12px;
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: var(--vd-accent);
	box-shadow: 0 0 0 3px var(--vd-accent-glow);
}

.vd-timeline__item::after {
	content: "";
	position: absolute;
	left: 7px;
	top: 20px;
	bottom: -2px;
	width: 1px;
	background: var(--vd-border-soft);
}

.vd-timeline__item:last-child::after {
	display: none;
}

.vd-timeline__item:last-child {
	padding-bottom: 6px;
}

.vd-timeline__time {
	font-family: var(--vd-font-mono);
	font-size: 10px;
	color: var(--vd-text-tertiary);
	letter-spacing: 0.02em;
}

.vd-timeline__label {
	font-size: 12.5px;
	color: var(--vd-text-secondary);
}

/* ---------- Regional activity meter (Threat Map — placeholder viz only) ---------- */
.vd-region-row {
	display: flex;
	align-items: center;
	gap: 10px;
}

.vd-region-row .vd-bar {
	margin-top: 0;
}

.vd-region-pct {
	font-family: var(--vd-font-mono);
	font-size: 11px;
	color: var(--vd-text-tertiary);
	flex: none;
	width: 30px;
	text-align: right;
}

/* ==========================================================================
   Sprint 5 — Premium interaction polish
   Purely additive: no grid, size, position, typography, color, or
   spacing rules above this point are touched. Everything here is
   hover/motion detail layered on top of the approved layout.
   ========================================================================== */

/* ---------- Animated status-badge dot ---------- */
/* Only the dot pulses; badge text stays completely still. Injected by
   JS next to genuine status words (Healthy, Live, Synced) — count
   badges like "342 assets" never get one. */
.vd-badge__dot {
	display: inline-block;
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background: currentColor;
	margin-right: 5px;
	animation: vd-badge-pulse 2s ease-in-out infinite;
}

@keyframes vd-badge-pulse {
	0%, 100% { opacity: 0.4; }
	50%      { opacity: 1; }
}

/* ---------- Progress bar fill: hover brightness only ---------- */
.vd-bar__fill {
	transition: width 0.7s ease, filter 0.2s ease;
}

.vd-widget__list-item:hover .vd-bar__fill {
	filter: brightness(1.15);
}

/* Stacked bar segments animate in on load the same way linear bars do
   (see dashboard.js) — needs its own width transition since the base
   rule only ever set a static width before. */
.vd-stack-bar__seg {
	transition: width 0.7s ease;
}

/* ---------- Severity / service badge hover (badge-row instances only) ---------- */
/* Scoped to .vd-badge-row so the single status badge in a widget's
   header — Healthy, Live, Synced — never gets a hover treatment it
   isn't meant to have; only the inline severity/service clusters do. */
.vd-badge-row .vd-badge {
	transition: background-color 0.18s ease, border-color 0.18s ease;
}

.vd-badge-row .vd-badge--critical:hover { background: var(--vd-sev-critical-glow); border-color: var(--vd-sev-critical); }
.vd-badge-row .vd-badge--high:hover      { background: var(--vd-sev-high-glow);     border-color: var(--vd-sev-high); }
.vd-badge-row .vd-badge--medium:hover    { background: var(--vd-sev-medium-glow);   border-color: var(--vd-sev-medium); }
.vd-badge-row .vd-badge--low:hover       { background: var(--vd-sev-low-glow);      border-color: var(--vd-sev-low); }
.vd-badge-row .vd-badge--good:hover      { background: var(--vd-accent-glow);       border-color: var(--vd-accent); }

/* ---------- Timeline hover (Recent Activity) ---------- */
.vd-timeline__item::before {
	transition: box-shadow 0.2s ease;
}

.vd-timeline__item:hover::before {
	box-shadow: 0 0 0 5px var(--vd-accent-glow-strong);
}

.vd-timeline__time {
	transition: color 0.2s ease;
}

.vd-timeline__item:hover .vd-timeline__time {
	color: var(--vd-text-secondary);
}

/* ---------- Scrollbar refinement (Threat Feed event list) ---------- */
.vd-scroll-list::-webkit-scrollbar-thumb {
	transition: background-color 0.2s ease;
}

.vd-scroll-list:hover::-webkit-scrollbar-thumb {
	background: var(--vd-border-accent);
}

/* ---------- Staggered widget reveal on first load ---------- */
/* Same "hidden until vd-ready" convention as .vd-shell above, just
   scoped to each widget with an incremental delay. Fill-mode: forwards
   plus a non-infinite iteration count means this plays exactly once. */
.vd-main .vd-widget {
	opacity: 0;
}

.vardiya-dashboard.vd-ready .vd-main .vd-widget {
	animation: vd-widget-reveal 0.42s ease forwards;
}

@keyframes vd-widget-reveal {
	from { opacity: 0; transform: translateY(10px); }
	to   { opacity: 1; transform: translateY(0); }
}

.vd-main .vd-widget:nth-child(1)  { animation-delay: 0ms; }
.vd-main .vd-widget:nth-child(2)  { animation-delay: 80ms; }
.vd-main .vd-widget:nth-child(3)  { animation-delay: 160ms; }
.vd-main .vd-widget:nth-child(4)  { animation-delay: 240ms; }
.vd-main .vd-widget:nth-child(5)  { animation-delay: 320ms; }
.vd-main .vd-widget:nth-child(6)  { animation-delay: 400ms; }
.vd-main .vd-widget:nth-child(7)  { animation-delay: 480ms; }
.vd-main .vd-widget:nth-child(8)  { animation-delay: 560ms; }
.vd-main .vd-widget:nth-child(9)  { animation-delay: 640ms; }
.vd-main .vd-widget:nth-child(10) { animation-delay: 720ms; }
.vd-main .vd-widget:nth-child(11) { animation-delay: 800ms; }

/* ---------- Page-load fade-in ---------- */
.vardiya-dashboard .vd-shell {
	opacity: 0;
}

.vardiya-dashboard.vd-ready .vd-shell {
	animation: vd-fade-in 0.5s ease forwards;
}

@keyframes vd-fade-in {
	from { opacity: 0; transform: translateY(4px); }
	to   { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
	.vardiya-dashboard .vd-shell,
	.vardiya-dashboard.vd-ready .vd-shell {
		opacity: 1;
		animation: none;
		transform: none;
	}
	.vd-widget,
	.vd-widget__panel,
	.vd-widget__chevron {
		transition: none;
	}

	/* Sprint 5 additions: kill the initial-load choreography and the
	   infinite badge pulse outright; leave widgets fully visible and
	   final values in place rather than mid-animation. */
	.vd-main .vd-widget,
	.vardiya-dashboard.vd-ready .vd-main .vd-widget {
		opacity: 1;
		animation: none;
		transform: none;
	}

	.vd-badge__dot {
		animation: none;
		opacity: 1;
	}

	.vd-bar__fill,
	.vd-stack-bar__seg,
	.vd-ring__value {
		transition: none;
	}

	.vd-widget:hover,
	.vd-badge-row .vd-badge,
	.vd-timeline__item::before,
	.vd-timeline__time {
		transition: none;
	}
}

/* ==========================================================================
   Responsive — Tablet
   ========================================================================== */
@media (max-width: 1024px) {
	.vd-main {
		grid-auto-rows: 84px;
		grid-template-columns: repeat(6, 1fr);
	}

	.vd-widget--score,
	.vd-widget--alerts,
	.vd-widget--mitre {
		grid-column: span 2; /* row 1 — status strip, thirds */
	}

	.vd-widget--feed {
		grid-column: span 6; /* row 2 — primary widget stays full width */
	}

	.vd-widget--activity,
	.vd-widget--ioc,
	.vd-widget--projects,
	.vd-widget--services {
		grid-column: span 3; /* row 3 / row 5 — halves */
	}

	.vd-widget--map,
	.vd-widget--assets,
	.vd-widget--research {
		grid-column: span 2; /* row 4 — thirds */
	}

	/* Tablet: same rule as desktop — only the row height grows, column
	   width is untouched, so no sibling widget changes size or moves. */
	.vd-widget.is-expanded {
		grid-row: span 6 !important;
	}

	.vd-topbar__tag {
		display: none;
	}
}

/* ==========================================================================
   Responsive — Mobile (Sprint 8.1: mobile foundation, layout only)
   Breakpoint widened to 768px. Behavior below is unchanged from the prior
   640px block — desktop sidebar presentation hides, the same nav element
   re-lays-out as the bottom navigation bar, and the widget grid drops to a
   single column — just spaced per the 8.1 spec and guarded against
   horizontal overflow.
   ========================================================================== */
@media (max-width: 768px) {
	.vd-shell {
		grid-template-columns: 1fr;
		grid-template-rows: var(--vd-topbar-h) 1fr auto;
		grid-template-areas:
			"topbar"
			"main"
			"sidebar";
		height: 100vh; /* mobile-only: pins the bottom nav, unaffected by the Sprint 8.5 desktop fix */
		overflow: hidden;
	}

	/* ---- Sidebar visibility: desktop rail hidden, bottom nav shown ---- */
	.vd-sidebar {
		flex-direction: row;
		justify-content: space-around;
		width: 100%;
		max-width: 100%;
		padding: 8px 4px;
		border-right: none;
		border-top: 1px solid var(--vd-border-soft);
	}

	.vd-sidebar__mark,
	.vd-sidebar__footer {
		display: none;
	}

	.vd-sidebar__nav {
		width: auto;
	}

	.vd-sidebar__list {
		flex-direction: row;
		gap: 2px;
	}

	.vd-sidebar__link {
		width: 44px;
		height: 44px;
	}

	.vd-sidebar__label {
		display: none;
	}

	.vd-sidebar__link.is-active::before {
		left: 50%;
		top: -6px;
		transform: translateX(-50%);
		width: 16px;
		height: 2px;
	}

	/* ==================================================================
	   Sprint 8.2 — Mobile header optimization.
	   Header-only rules. --vd-topbar-h stays 60px (already within the
	   56–64px target) so nothing about the shell's row sizing changes;
	   only the topbar's own contents are re-flowed to fit narrow
	   viewports without wrapping or overflowing.
	   ================================================================== */
	.vd-topbar {
		padding: 0 16px;
		gap: 8px;
		max-width: 100%;
		flex-wrap: nowrap;
		overflow: hidden;
	}

	.vd-topbar__menu-btn {
		display: none;
	}

	.vd-topbar__tag {
		display: none;
	}

	/* Logo: allowed to shrink and ellipsize rather than push other
	   header items into wrapping or off-screen. Text itself is
	   untouched — this only changes how it's clipped if space is
	   genuinely too tight. */
	.vd-topbar__logo {
		flex: 1 1 auto;
		min-width: 0;
	}

	.vd-topbar__wordmark {
		display: block;
		overflow: hidden;
		white-space: nowrap;
		text-overflow: ellipsis;
		min-width: 0;
	}

	/* Search: compact field instead of the desktop full-width bar.
	   Stays a real, focusable, typable input — just narrow — so the
	   existing "/" shortcut and typing behavior keep working. */
	.vd-topbar__search {
		flex: 1 1 88px;
		min-width: 56px;
		max-width: 128px;
		margin: 0;
		padding: 0 8px;
	}

	.vd-topbar__search-input {
		min-width: 0;
	}

	.vd-topbar__kbd {
		display: none;
	}

	.vd-topbar__actions {
		flex: 0 0 auto;
		gap: 8px;
	}

	.vd-status {
		padding: 4px 8px;
	}

	.vd-status__label {
		display: none;
	}

	/* Contact stays visible on mobile (Sprint 8.1 hid it) — sized to
	   fit next to the icon button without wrapping. */
	.vd-btn--primary {
		flex: 0 0 auto;
		padding: 8px 12px;
	}

	/* ---- Main container ---- */
	.vardiya-dashboard {
		overflow-x: hidden;
	}

	/* Mobile: true accordion. Single column, natural content height —
	   the expanding widget simply pushes everything below it down the
	   page, which is the standard mobile accordion behavior. Container
	   padding 16px, gap between cards 16px per Sprint 8.1. */
	.vd-main {
		grid-template-columns: 1fr;
		grid-auto-rows: auto;
		padding: 16px;
		gap: 16px;
		width: 100%;
		max-width: 100%; /* was 100vw — didn't account for this element's own scrollbar width, which pushed the right edge past the viewport and clipped content */
		min-width: 0;
		overflow-x: hidden;
		overflow-y: auto; /* mobile-only: restores the pre-8.5 scroll container */
		box-sizing: border-box;
	}

	/* ---- Dashboard card grid → single column, full width ---- */
	.vd-widget,
	.vd-widget.is-expanded {
		grid-column: span 1 !important;
		grid-row: auto !important;
		width: 100%;
		max-width: 100%;
		min-width: 0;
		box-sizing: border-box;
		overflow: hidden;
		height: auto; /* content-driven height — no leftover desktop cell height */
	}

	.vd-widget:hover {
		transform: none;
	}

	/* ---- Never let card contents (charts, rings, tables) push width ---- */
	.vd-widget img,
	.vd-widget svg,
	.vd-widget canvas,
	.vd-widget table {
		max-width: 100%;
	}

	/* ==================================================================
	   Sprint 8.4 — Mobile widget content polish.
	   Same widgets, same values — just letting badges, titles and list
	   rows wrap instead of forcing a single nowrap line, so nothing
	   clips or overlaps on narrow phones (320–390px). Ring/bar/legend
	   components already used min-width:0 + wrapping columns and don't
	   need changes here.
	   ================================================================== */

	/* KPI header row: title truncates (already ellipsis) before the
	   badge is forced to shrink; the badge itself may now wrap onto a
	   second line ("342 assets", "12 this month") instead of clipping. */
	.vd-widget__toggle {
		flex-wrap: wrap;
		row-gap: 6px;
	}

	.vd-widget__toggle-right {
		flex-wrap: wrap;
		justify-content: flex-end;
	}

	.vd-badge {
		white-space: normal;
		word-break: break-word;
		text-align: center;
	}

	/* List rows (Score/Alerts/MITRE breakdowns, Assets, Projects,
	   Services, Research, Map): allow the value/meta column to drop
	   to its own line instead of overflowing when the label is long. */
	.vd-widget__list-item {
		flex-wrap: wrap;
		row-gap: 4px;
	}

	.vd-widget__list-value {
		white-space: normal;
		word-break: break-word;
	}
}

/* ==========================================================================
   Sprint 6 — Corporate site sections
   Appended below the dashboard shell. Reuses every existing token
   (colors, fonts, radius, gap unit) — no new palette, no new font
   family, no new border-radius scale. The only genuinely new values
   here are heading sizes, since nothing at "marketing headline" scale
   existed before this content did.
   ========================================================================== */

.vd-site {
	background: var(--vd-bg-void);
}

.vd-container {
	max-width: 1180px;
	margin: 0 auto;
	padding: 0 32px;
}

.vd-section {
	padding: 96px 0;
	border-top: 1px solid var(--vd-border-soft);
}

.vd-eyebrow {
	display: inline-block;
	font-family: var(--vd-font-mono);
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--vd-accent);
	margin-bottom: 14px;
}

.vd-section__header {
	max-width: 620px;
	margin-bottom: 56px;
}

.vd-section__title {
	font-family: var(--vd-font-ui);
	font-size: 34px;
	font-weight: 600;
	line-height: 1.18;
	letter-spacing: -0.01em;
	color: var(--vd-text-primary);
	margin-bottom: 14px;
}

.vd-section__subhead {
	font-size: 15px;
	line-height: 1.65;
	color: var(--vd-text-secondary);
}

/* ---------- Workspace navigation (Sprint 6) ---------- */
.vd-workspace-grid {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: var(--vd-gap);
}

.vd-workspace-card {
	background: var(--vd-bg-panel);
	border: 1px solid var(--vd-border-soft);
	border-radius: var(--vd-radius-md);
	padding: 20px 18px;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 10px;
	width: 100%;
	text-align: left;
	cursor: pointer;
	font: inherit;
	color: inherit;
	transition: transform 0.22s ease, border-color 0.22s ease, box-shadow 0.22s ease, background-color 0.22s ease;
}

.vd-workspace-card:hover {
	transform: translateY(-3px);
	border-color: var(--vd-border-accent);
	background: var(--vd-bg-panel-hover);
	box-shadow: 0 10px 28px -12px rgba(0, 0, 0, 0.65), 0 0 0 1px var(--vd-accent-glow-strong);
}

.vd-workspace-card:focus-visible {
	outline: 2px solid var(--vd-accent);
	outline-offset: 2px;
}

.vd-workspace-card.is-active {
	border-color: var(--vd-border-accent);
	background: var(--vd-bg-panel-hover);
}

.vd-workspace-card__icon {
	width: 20px;
	height: 20px;
	color: var(--vd-accent);
}

.vd-workspace-card__title {
	font-size: 13px;
	font-weight: 600;
	letter-spacing: 0.01em;
	color: var(--vd-text-primary);
}

.vd-workspace-card__desc {
	font-size: 12px;
	line-height: 1.5;
	color: var(--vd-text-secondary);
	flex: 1;
}

.vd-workspace-card__arrow {
	width: 16px;
	height: 16px;
	color: var(--vd-text-tertiary);
	align-self: flex-end;
	transition: transform 0.22s ease, color 0.22s ease;
}

.vd-workspace-card:hover .vd-workspace-card__arrow {
	transform: translateX(3px);
	color: var(--vd-accent);
}

.vd-workspace-card.is-active .vd-workspace-card__arrow {
	transform: rotate(180deg);
	color: var(--vd-accent);
}

/* Shared accordion panel — one instance below the grid, content swapped
   per active card. Same timing/easing as the dashboard widget panels. */
.vd-workspace-panel {
	max-height: 0;
	opacity: 0;
	overflow: hidden;
	transform: translateY(-6px);
	transition: max-height 0.28s ease, opacity 0.28s ease, transform 0.28s ease;
}

.vd-workspace-panel.is-open {
	opacity: 1;
	transform: translateY(0);
	margin-top: var(--vd-gap);
}

.vd-workspace-panel__inner {
	background: var(--vd-bg-panel);
	border: 1px solid var(--vd-border-soft);
	border-radius: var(--vd-radius-md);
	padding: 20px 22px;
}

.vd-workspace-panel__title {
	font-size: 10.5px;
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--vd-accent);
	margin-bottom: 10px;
}

.vd-workspace-panel__body {
	font-size: 13px;
	line-height: 1.6;
	color: var(--vd-text-secondary);
}

@media (prefers-reduced-motion: reduce) {
	.vd-workspace-card,
	.vd-workspace-card__arrow,
	.vd-workspace-panel {
		transition: none;
	}
}

/* ---------- About module (Sprint 6.1) ---------- */
/* Lives inside .vd-workspace-panel__inner, swapped in for the "about"
   card only — every other card keeps the generic placeholder. Internal
   scroll keeps the shared panel from ever growing past a fixed cap. */
.vd-about__scroll {
	max-height: 600px;
	overflow-y: auto;
	padding-right: 4px;
}

.vd-about__grid {
	display: grid;
	grid-template-columns: 3fr 2fr;
	gap: 28px;
	align-items: start;
}

.vd-about__col {
	display: flex;
	flex-direction: column;
	gap: 24px;
	min-width: 0;
}

.vd-about__section-title {
	font-size: 10.5px;
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--vd-text-tertiary);
	margin-bottom: 10px;
}

.vd-about__text {
	font-size: 13px;
	line-height: 1.6;
	color: var(--vd-text-secondary);
	margin-bottom: 8px;
}

.vd-about__text:last-child {
	margin-bottom: 0;
}

.vd-about__pair {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 12px;
}

.vd-about__card {
	background: var(--vd-bg-panel);
	border: 1px solid var(--vd-border-soft);
	border-radius: var(--vd-radius-md);
	padding: 16px;
	transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}

.vd-about__card:hover {
	transform: translateY(-2px);
	border-color: var(--vd-border-accent);
	box-shadow: 0 8px 20px -12px rgba(0, 0, 0, 0.5), 0 0 0 1px var(--vd-accent-glow);
}

.vd-about__card-head {
	display: flex;
	align-items: center;
	gap: 8px;
	margin-bottom: 8px;
}

.vd-about__card-icon {
	width: 16px;
	height: 16px;
	flex: none;
	color: var(--vd-accent);
}

.vd-about__card-title {
	font-size: 12px;
	font-weight: 600;
	color: var(--vd-text-primary);
}

.vd-about__card-text {
	font-size: 12.5px;
	line-height: 1.55;
	color: var(--vd-text-secondary);
}

/* ---------- About: stat cards ---------- */
.vd-about__stats {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 10px;
}

.vd-about__stat {
	background: var(--vd-bg-inset);
	border: 1px solid var(--vd-border);
	border-radius: var(--vd-radius-sm);
	padding: 12px 14px;
	display: flex;
	flex-direction: column;
	gap: 2px;
	opacity: 0;
	transform: translateY(6px);
	transition: transform 0.2s ease, border-color 0.2s ease, opacity 0.4s ease, transform 0.4s ease;
}

.vd-about.is-visible .vd-about__stat {
	opacity: 1;
	transform: translateY(0);
}

.vd-about__stat:hover {
	transform: translateY(-2px);
	border-color: var(--vd-border-accent);
}

.vd-about.is-visible .vd-about__stat:nth-child(1) { transition-delay: 0ms; }
.vd-about.is-visible .vd-about__stat:nth-child(2) { transition-delay: 60ms; }
.vd-about.is-visible .vd-about__stat:nth-child(3) { transition-delay: 120ms; }
.vd-about.is-visible .vd-about__stat:nth-child(4) { transition-delay: 180ms; }

.vd-about__stat-value {
	font-family: var(--vd-font-mono);
	font-size: 20px;
	font-weight: 600;
	color: var(--vd-text-primary);
}

.vd-about__stat-label {
	font-size: 10.5px;
	color: var(--vd-text-tertiary);
}

/* ---------- About: timeline ---------- */
/* Reuses the dashboard's own .vd-timeline component as-is (dot, glow,
   connecting line, hover state) — only the dot's resting glow gets a
   slow, scoped pulse so it never touches the Recent Activity widget. */
.vd-about__timeline {
	margin-top: 4px;
}

.vd-about__timeline .vd-timeline__item::before {
	animation: vd-about-dot-glow 2.6s ease-in-out infinite;
}

@keyframes vd-about-dot-glow {
	0%, 100% { box-shadow: 0 0 0 3px var(--vd-accent-glow); }
	50%      { box-shadow: 0 0 0 5px var(--vd-accent-glow-strong); }
}

/* ---------- About: core values ---------- */
.vd-about__values {
	margin-top: 32px;
	padding-top: 24px;
	border-top: 1px solid var(--vd-border-soft);
}

.vd-about__values-grid {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 10px;
}

.vd-about__value {
	background: var(--vd-bg-inset);
	border: 1px solid var(--vd-border);
	border-radius: var(--vd-radius-sm);
	padding: 13px;
	display: flex;
	flex-direction: column;
	gap: 6px;
	transition: transform 0.2s ease, border-color 0.2s ease;
}

.vd-about__value:hover {
	transform: translateY(-2px);
	border-color: var(--vd-border-accent);
}

.vd-about__value-icon {
	width: 20px;
	height: 20px;
	color: var(--vd-accent);
}

.vd-about__value-title {
	font-size: 12.5px;
	font-weight: 600;
	color: var(--vd-text-primary);
}

.vd-about__value-text {
	font-size: 11.5px;
	line-height: 1.5;
	color: var(--vd-text-secondary);
}

@media (max-width: 1024px) {
	.vd-about__grid {
		grid-template-columns: 1fr;
		gap: 24px;
	}

	.vd-about__values-grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (max-width: 640px) {
	.vd-about__pair,
	.vd-about__stats {
		grid-template-columns: 1fr;
	}

	.vd-about__values-grid {
		grid-template-columns: 1fr;
	}
}

@media (prefers-reduced-motion: reduce) {
	.vd-about__card,
	.vd-about__stat,
	.vd-about__value {
		transition: none;
	}

	.vd-about__stat {
		opacity: 1;
		transform: none;
	}

	.vd-about__timeline .vd-timeline__item::before {
		animation: none;
	}
}

/* ---------- 1. Who We Are ---------- */
.vd-who__grid {
	display: grid;
	grid-template-columns: 1.1fr 0.9fr;
	gap: 64px;
	align-items: start;
}

.vd-who__lede {
	font-size: 15.5px;
	line-height: 1.7;
	color: var(--vd-text-secondary);
	max-width: 60ch;
	margin-bottom: 36px;
}

.vd-who__stats {
	display: flex;
	gap: 32px;
	padding: 24px 0;
	border-top: 1px solid var(--vd-border-soft);
	border-bottom: 1px solid var(--vd-border-soft);
	margin-bottom: 36px;
}

.vd-who__stat {
	display: flex;
	flex-direction: column;
	gap: 4px;
}

.vd-who__stat-value {
	font-family: var(--vd-font-mono);
	font-size: 26px;
	font-weight: 600;
	color: var(--vd-text-primary);
}

.vd-who__stat-label {
	font-size: 11.5px;
	color: var(--vd-text-tertiary);
}

.vd-who__pillars {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 16px;
	margin-bottom: 36px;
}

.vd-who__pillar {
	background: var(--vd-bg-panel);
	border: 1px solid var(--vd-border-soft);
	border-radius: var(--vd-radius-md);
	padding: 18px;
}

.vd-who__pillar-title {
	font-size: 12.5px;
	font-weight: 600;
	color: var(--vd-accent);
	margin-bottom: 8px;
}

.vd-who__pillar p {
	font-size: 13px;
	line-height: 1.55;
	color: var(--vd-text-secondary);
}

.vd-who__values {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 16px 24px;
}

.vd-who__values li {
	display: flex;
	flex-direction: column;
	gap: 3px;
	font-size: 13px;
	line-height: 1.5;
	color: var(--vd-text-secondary);
}

.vd-who__value-title {
	font-size: 13px;
	font-weight: 600;
	color: var(--vd-text-primary);
}

.vd-who__visual {
	position: relative;
	aspect-ratio: 1 / 1.05;
	background: var(--vd-bg-panel);
	border: 1px solid var(--vd-border-soft);
	border-radius: var(--vd-radius-md);
	overflow: hidden;
}

.vd-who__visual-grid {
	position: absolute;
	inset: 0;
	background-image:
		linear-gradient(to right, var(--vd-border-soft) 1px, transparent 1px),
		linear-gradient(to bottom, var(--vd-border-soft) 1px, transparent 1px);
	background-size: 32px 32px;
	mask-image: radial-gradient(ellipse at center, black 45%, transparent 82%);
}

.vd-who__visual-ring {
	position: absolute;
	top: 50%;
	left: 50%;
	width: 220px;
	height: 220px;
	border: 1px solid var(--vd-border-accent);
	border-radius: 50%;
	transform: translate(-50%, -50%);
}

.vd-who__visual-ring::before {
	content: "";
	position: absolute;
	inset: 32px;
	border: 1px solid var(--vd-border-soft);
	border-radius: 50%;
}

.vd-who__visual-node {
	position: absolute;
	width: 8px;
	height: 8px;
	border-radius: 50%;
	background: var(--vd-accent);
	box-shadow: 0 0 0 5px var(--vd-accent-glow);
}

.vd-who__visual-node--1 { top: 28%; left: 34%; }
.vd-who__visual-node--2 { top: 62%; left: 68%; }
.vd-who__visual-node--3 { top: 70%; left: 30%; }

/* ---------- 2. Core Services ---------- */
.vd-service-grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 16px;
}

.vd-service-card {
	position: relative;
	background: var(--vd-bg-panel);
	border: 1px solid var(--vd-border-soft);
	border-radius: var(--vd-radius-md);
	padding: 20px;
	padding-bottom: 36px;
	transition: transform 0.22s ease, border-color 0.22s ease, box-shadow 0.22s ease;
}

.vd-service-card:hover {
	transform: translateY(-3px);
	border-color: var(--vd-border-accent);
	box-shadow: 0 10px 28px -14px rgba(0, 0, 0, 0.6), 0 0 0 1px var(--vd-accent-glow);
}

.vd-service-card__icon {
	width: 22px;
	height: 22px;
	color: var(--vd-accent);
	margin-bottom: 14px;
}

.vd-service-card__title {
	font-size: 14px;
	font-weight: 600;
	color: var(--vd-text-primary);
	margin-bottom: 6px;
}

.vd-service-card__desc {
	font-size: 12.5px;
	line-height: 1.5;
	color: var(--vd-text-secondary);
}

.vd-service-card__arrow {
	position: absolute;
	right: 16px;
	bottom: 14px;
	color: var(--vd-text-tertiary);
	font-size: 14px;
	line-height: 1;
	transition: color 0.22s ease, transform 0.22s ease;
}

.vd-service-card:hover .vd-service-card__arrow {
	color: var(--vd-accent);
	transform: translateX(2px);
}

/* ---------- 3. Technology Stack ---------- */
.vd-logo-wall {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 12px;
}

.vd-logo-card {
	display: flex;
	align-items: center;
	justify-content: center;
	height: 76px;
	background: var(--vd-bg-inset);
	border: 1px solid var(--vd-border-soft);
	border-radius: var(--vd-radius-sm);
	font-family: var(--vd-font-mono);
	font-size: 12.5px;
	font-weight: 500;
	color: var(--vd-text-secondary);
	text-align: center;
	padding: 0 12px;
	transition: border-color 0.22s ease, box-shadow 0.22s ease, color 0.22s ease;
}

.vd-logo-card:hover {
	border-color: var(--vd-border-accent);
	box-shadow: 0 0 0 1px var(--vd-accent-glow), 0 0 24px -8px var(--vd-accent-glow-strong);
	color: var(--vd-text-primary);
}

/* ---------- 4. Featured Projects ---------- */
.vd-case-list {
	display: flex;
	flex-direction: column;
	gap: 24px;
}

.vd-case {
	display: grid;
	grid-template-columns: 1.3fr 1fr;
	gap: 0;
	background: var(--vd-bg-panel);
	border: 1px solid var(--vd-border-soft);
	border-radius: var(--vd-radius-md);
	overflow: hidden;
}

.vd-case--reverse {
	grid-template-columns: 1fr 1.3fr;
}

.vd-case--reverse .vd-case__body {
	order: 2;
}

.vd-case--reverse .vd-case__visual {
	order: 1;
}

.vd-case__body {
	padding: 40px;
}

.vd-case__title {
	font-size: 21px;
	font-weight: 600;
	color: var(--vd-text-primary);
	margin-bottom: 20px;
	line-height: 1.25;
}

.vd-case__facts {
	display: flex;
	flex-direction: column;
	gap: 14px;
	margin-bottom: 20px;
}

.vd-case__facts dt {
	font-family: var(--vd-font-mono);
	font-size: 10.5px;
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--vd-text-tertiary);
	margin-bottom: 4px;
}

.vd-case__facts dd {
	font-size: 13.5px;
	line-height: 1.6;
	color: var(--vd-text-secondary);
}

.vd-case__tags {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	margin-bottom: 22px;
}

.vd-case__tag {
	font-family: var(--vd-font-mono);
	font-size: 10.5px;
	color: var(--vd-text-tertiary);
	border: 1px solid var(--vd-border);
	border-radius: 20px;
	padding: 3px 9px;
}

.vd-case__visual {
	position: relative;
	background: var(--vd-bg-inset);
	border-left: 1px solid var(--vd-border-soft);
	min-height: 260px;
}

.vd-case--reverse .vd-case__visual {
	border-left: none;
	border-right: 1px solid var(--vd-border-soft);
}

.vd-case__visual-grid {
	position: absolute;
	inset: 0;
	background-image:
		linear-gradient(to right, var(--vd-border-soft) 1px, transparent 1px),
		linear-gradient(to bottom, var(--vd-border-soft) 1px, transparent 1px);
	background-size: 26px 26px;
	mask-image: radial-gradient(ellipse at center, black 35%, transparent 75%);
}

/* ---------- 5. Research & Publications ---------- */
.vd-report-grid {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 16px;
}

.vd-report-card {
	background: var(--vd-bg-panel);
	border: 1px solid var(--vd-border-soft);
	border-radius: var(--vd-radius-md);
	padding: 24px;
	transition: transform 0.22s ease, border-color 0.22s ease, box-shadow 0.22s ease;
}

.vd-report-card:hover {
	transform: translateY(-3px);
	border-color: var(--vd-border-accent);
	box-shadow: 0 10px 28px -14px rgba(0, 0, 0, 0.6), 0 0 0 1px var(--vd-accent-glow);
}

.vd-report-card__meta {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-bottom: 14px;
}

.vd-report-card__category {
	font-family: var(--vd-font-mono);
	font-size: 10.5px;
	font-weight: 600;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	color: var(--vd-accent);
}

.vd-report-card__date {
	font-family: var(--vd-font-mono);
	font-size: 11px;
	color: var(--vd-text-tertiary);
}

.vd-report-card__title {
	font-size: 16.5px;
	font-weight: 600;
	line-height: 1.35;
	color: var(--vd-text-primary);
	margin-bottom: 10px;
}

.vd-report-card__summary {
	font-size: 13px;
	line-height: 1.6;
	color: var(--vd-text-secondary);
	margin-bottom: 18px;
}

.vd-report-card__footer {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding-top: 14px;
	border-top: 1px solid var(--vd-border-soft);
}

.vd-report-card__tag {
	font-family: var(--vd-font-mono);
	font-size: 10.5px;
	color: var(--vd-text-tertiary);
	border: 1px solid var(--vd-border);
	border-radius: 20px;
	padding: 3px 9px;
}

.vd-report-card__time {
	font-size: 11.5px;
	color: var(--vd-text-tertiary);
}

/* ---------- 6. Client Process ---------- */
.vd-process {
	display: grid;
	grid-template-columns: repeat(6, 1fr);
	gap: 16px;
	list-style: none;
	counter-reset: vd-step;
}

.vd-process__step {
	position: relative;
	padding-top: 28px;
}

.vd-process__step::before {
	content: "";
	position: absolute;
	top: 15px;
	left: 0;
	right: 0;
	height: 1px;
	background: var(--vd-border-soft);
}

.vd-process__step:first-child::before {
	left: 50%;
}

.vd-process__step:last-child::before {
	right: 50%;
}

.vd-process__icon {
	position: relative;
	z-index: 1;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 30px;
	height: 30px;
	margin-bottom: 16px;
	background: var(--vd-bg-void);
	border: 1px solid var(--vd-border-accent);
	border-radius: 50%;
	color: var(--vd-accent);
}

.vd-process__icon svg {
	width: 15px;
	height: 15px;
}

.vd-process__title {
	font-size: 13px;
	font-weight: 600;
	color: var(--vd-text-primary);
	margin-bottom: 6px;
}

.vd-process__desc {
	font-size: 12px;
	line-height: 1.55;
	color: var(--vd-text-secondary);
}

/* ---------- 7. Certifications ---------- */
.vd-cert-grid {
	display: grid;
	grid-template-columns: repeat(7, 1fr);
	gap: 12px;
}

.vd-cert-card {
	display: flex;
	align-items: center;
	justify-content: center;
	height: 64px;
	background: var(--vd-bg-inset);
	border: 1px solid var(--vd-border-soft);
	border-radius: var(--vd-radius-sm);
	font-family: var(--vd-font-mono);
	font-size: 11.5px;
	font-weight: 500;
	color: var(--vd-text-tertiary);
	text-align: center;
	padding: 0 8px;
	transition: border-color 0.22s ease, color 0.22s ease;
}

.vd-cert-card:hover {
	border-color: var(--vd-border-accent);
	color: var(--vd-text-primary);
}

/* ---------- 8. Contact ---------- */
.vd-contact__grid {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 64px;
}

.vd-contact__details {
	display: flex;
	flex-direction: column;
	gap: 14px;
	margin: 32px 0 24px;
}

.vd-contact__details li {
	display: flex;
	align-items: center;
	gap: 12px;
	font-size: 13.5px;
	color: var(--vd-text-secondary);
}

.vd-contact__details svg {
	width: 17px;
	height: 17px;
	flex: none;
	color: var(--vd-accent);
}

.vd-contact__details a {
	color: var(--vd-text-secondary);
}

.vd-contact__details a:hover {
	color: var(--vd-text-primary);
}

.vd-contact__social {
	display: flex;
	gap: 10px;
}

.vd-contact__form {
	background: var(--vd-bg-panel);
	border: 1px solid var(--vd-border-soft);
	border-radius: var(--vd-radius-md);
	padding: 28px;
	display: flex;
	flex-direction: column;
	gap: 16px;
}

.vd-contact__field {
	display: flex;
	flex-direction: column;
	gap: 6px;
}

.vd-contact__field label {
	font-size: 12px;
	font-weight: 500;
	color: var(--vd-text-secondary);
}

.vd-contact__field input,
.vd-contact__field textarea {
	background: var(--vd-bg-inset);
	border: 1px solid var(--vd-border);
	border-radius: var(--vd-radius-sm);
	padding: 10px 12px;
	font-family: var(--vd-font-ui);
	font-size: 13.5px;
	color: var(--vd-text-primary);
	transition: border-color 0.15s ease;
}

.vd-contact__field input:focus,
.vd-contact__field textarea:focus {
	outline: none;
	border-color: var(--vd-border-accent);
}

.vd-contact__field textarea {
	resize: vertical;
	min-height: 90px;
}

.vd-contact__submit {
	align-self: flex-start;
	margin-top: 4px;
}

.vd-contact__note {
	font-size: 11.5px;
	color: var(--vd-text-tertiary);
	text-align: center;
}

/* ---------- Scroll reveal (site sections only) ---------- */
/* Same "hidden until ready" idea as the dashboard's own load-in, just
   triggered per-section via IntersectionObserver as the visitor
   scrolls, since these sections are off-screen at load. */
.vd-section {
	opacity: 0;
	transform: translateY(14px);
	transition: opacity 0.5s ease, transform 0.5s ease;
}

.vd-section.is-visible {
	opacity: 1;
	transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
	.vd-section {
		opacity: 1;
		transform: none;
		transition: none;
	}
	.vd-service-card,
	.vd-report-card,
	.vd-logo-card,
	.vd-cert-card {
		transition: none;
	}
}

/* ==========================================================================
   Sprint 6 — Site sections responsive
   Kept separate from the dashboard's own tablet/mobile blocks above so
   neither set of rules has to be re-read to understand the other.
   ========================================================================== */
@media (max-width: 1024px) {
	.vd-section {
		padding: 72px 0;
	}

	.vd-container {
		padding: 0 24px;
	}

	.vd-section__title {
		font-size: 28px;
	}

	.vd-workspace-grid {
		grid-template-columns: repeat(2, 1fr);
	}

	.vd-who__grid {
		grid-template-columns: 1fr;
		gap: 40px;
	}

	.vd-who__visual {
		aspect-ratio: 16 / 9;
	}

	.vd-service-grid {
		grid-template-columns: repeat(2, 1fr);
	}

	.vd-logo-wall {
		grid-template-columns: repeat(3, 1fr);
	}

	.vd-report-grid {
		grid-template-columns: 1fr;
	}

	.vd-case,
	.vd-case--reverse {
		grid-template-columns: 1fr;
	}

	.vd-case__visual {
		border-left: none;
		border-right: none;
		border-top: 1px solid var(--vd-border-soft);
		min-height: 180px;
	}

	.vd-case--reverse .vd-case__body,
	.vd-case--reverse .vd-case__visual {
		order: initial;
	}

	.vd-process {
		grid-template-columns: repeat(3, 1fr);
		gap: 32px 16px;
	}

	.vd-process__step:nth-child(3)::before {
		right: 50%;
	}

	.vd-process__step:nth-child(4)::before {
		left: 50%;
	}

	.vd-cert-grid {
		grid-template-columns: repeat(4, 1fr);
	}

	.vd-contact__grid {
		grid-template-columns: 1fr;
		gap: 40px;
	}
}

@media (max-width: 640px) {
	.vd-section {
		padding: 56px 0;
	}

	.vd-container {
		padding: 0 20px;
	}

	.vd-section__title {
		font-size: 24px;
	}

	.vd-workspace-grid {
		grid-template-columns: 1fr;
	}

	.vd-who__stats {
		flex-wrap: wrap;
		gap: 20px;
	}

	.vd-who__pillars,
	.vd-who__values {
		grid-template-columns: 1fr;
	}

	.vd-service-grid {
		grid-template-columns: 1fr;
	}

	.vd-logo-wall {
		grid-template-columns: repeat(2, 1fr);
	}

	.vd-case__body {
		padding: 26px;
	}

	.vd-process {
		grid-template-columns: 1fr;
		gap: 24px;
	}

	.vd-process__step::before {
		display: none;
	}

	.vd-cert-grid {
		grid-template-columns: repeat(3, 1fr);
	}

	.vd-footer {
		padding: 22px 0;
	}

	.vd-footer__inner {
		flex-direction: column;
		align-items: flex-start;
	}
}

/* ==========================================================================
   Sprint 9.0 — Minimal footer
   Sits at the very bottom of .vd-site, right after the workspace section.
   Reuses existing tokens only (--vd-border-soft, --vd-text-secondary/
   tertiary, .vd-container) — no new colors, no new breakpoints.
   ========================================================================== */
.vd-footer {
	border-top: 1px solid var(--vd-border-soft);
	padding: 28px 0;
}

.vd-footer__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 12px 24px;
}

.vd-footer__brand {
	display: flex;
	align-items: baseline;
	flex-wrap: wrap;
	gap: 8px;
	font-size: 12px;
	line-height: 1.5;
}

.vd-footer__copy {
	color: var(--vd-text-secondary);
}

.vd-footer__tagline {
	color: var(--vd-text-tertiary);
}

.vd-footer__tagline::before {
	content: "·";
	margin-right: 8px;
	color: var(--vd-text-tertiary);
}

.vd-footer__links {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 20px;
}

.vd-footer__link {
	font-size: 12px;
	color: var(--vd-text-tertiary);
}

a.vd-footer__link {
	transition: color 0.18s ease;
}

a.vd-footer__link:hover {
	color: var(--vd-text-primary);
}
