@import "tailwindcss/base";
@import "../../../../deps/petal_components/assets/default.css";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
@import "./theme.css";

/* This file is for your main application CSS */
.inner-container {
	width:100%;
}

/* Tab button styling for Update Statistics filters */
.tab-btn {
	@apply px-3 py-1 rounded text-sm font-medium border border-gray-300 bg-surface text-gray-700 hover:bg-gray-50 transition-colors;
}

.tab-btn.active {
	@apply bg-blue-600 text-white border-blue-600 hover:bg-blue-700;
}

/* AG Grid filter popup styling fixes */
.ag-theme-alpine .ag-filter-popup {
	z-index: 9999 !important;
	min-width: 250px !important;
	max-width: 350px !important;
	box-shadow: 0 4px 6px -1px rgb(var(--c-shadow) / var(--c-shadow-strength)), 0 2px 4px -1px rgb(var(--c-shadow) / var(--c-shadow-strength)) !important;
	border: 1px solid rgb(var(--c-gray-200)) !important;
	border-radius: 6px !important;
	background: rgb(var(--c-surface-raised)) !important;
}

.ag-theme-alpine .ag-filter-popup .ag-filter-body {
	padding: 12px !important;
	min-height: auto !important;
}

.ag-theme-alpine .ag-filter-popup .ag-filter-condition {
	margin-bottom: 8px !important;
}

.ag-theme-alpine .ag-filter-popup .ag-input-wrapper {
	width: 100% !important;
	margin-bottom: 8px !important;
}

.ag-theme-alpine .ag-filter-popup input {
	width: 100% !important;
	padding: 6px 8px !important;
	padding-left: 32px !important;
	border: 1px solid rgb(var(--c-gray-300)) !important;
	border-radius: 4px !important;
	font-size: 14px !important;
	text-indent: 4px !important;
}

/* Fix spacing for AG Grid's built-in filter icon */
.ag-theme-alpine .ag-text-field-input-wrapper {
	position: relative !important;
}

.ag-theme-alpine .ag-text-field-input-wrapper .ag-input-field-input {
	padding-left: 28px !important;
	text-indent: 4px !important;
}

.ag-theme-alpine .ag-filter-popup .ag-icon {
	margin-right: 6px !important;
	margin-left: 2px !important;
}

.ag-theme-alpine .ag-filter-popup select {
	width: 100% !important;
	padding: 6px 8px !important;
	border: 1px solid rgb(var(--c-gray-300)) !important;
	border-radius: 4px !important;
	font-size: 14px !important;
	background: rgb(var(--c-surface-raised)) !important;
}

.ag-theme-alpine .ag-filter-popup .ag-filter-apply-panel {
	padding-top: 8px !important;
	border-top: 1px solid rgb(var(--c-gray-200)) !important;
	margin-top: 8px !important;
}

/* Ensure popup doesn't get clipped by container */
.ag-table-container {
	overflow: visible !important;
}

.ag-theme-alpine {
	overflow: visible !important;
}

/* QR/POS Settlements grids use a fixed-height card layout so the header
   row stays pinned while rows scroll internally. Filter popups escape via
   popupParent (document.body) instead of relying on ancestor overflow, so
   it's safe to override the global overflow:visible rule for these two
   grids specifically — without it the rounded-corner clipping and pinned
   header both break. */
#qrSettlementGrid.ag-theme-alpine,
#posSettlementGrid.ag-theme-alpine,
#misGrid.ag-theme-alpine,
#coreTransactionGrid.ag-theme-alpine,
#posChannelGrid.ag-theme-alpine {
	overflow: hidden !important;
}

/* Custom Device Marker Styling */
.device-marker {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	border-radius: 50%;
	background: rgb(var(--c-surface));
	box-shadow: 0 2px 6px rgb(var(--c-shadow) / 0.25);
	transition: opacity 0.2s ease;
}

.device-marker-image {
	width: 100%;
	height: 100%;
	object-fit: contain;
	padding: 4px;
}

.device-marker-container {
	display: flex;
	align-items: center;
	justify-content: center;
}

/* Hide border when details popup is shown */
.device-marker.no-border {
	border: none !important;
}

/* Coloured pill badges rendered inside ag-grid cells (Source, Txn Type,
   Status, …). The background colour is applied inline per value by the grid
   hook; this class supplies the white text, padding and pill shape so the
   badges read like the Risk Hold button rather than bare coloured text. */
.ag-badge {
	display: inline-block;
	padding: 2px 10px;
	border-radius: 9999px;
	color: #fff;
	font-size: 11px;
	font-weight: 600;
	line-height: 1.5;
	text-align: center;
	white-space: nowrap;
	vertical-align: middle;
}

/* ---------------------------------------------------------------------------
 * AG Grid — dark theme
 *
 * All 14 grids in the app mount with `ag-theme-alpine`. AG Grid 32.x drives
 * that theme entirely from `--ag-*` custom properties, so dark mode is a
 * variable swap here rather than a class change at each of the 14 call sites
 * (and rather than shipping the separate alpine-dark stylesheet).
 *
 * Values come off the shared ramp so the grids track the rest of the UI.
 * ------------------------------------------------------------------------ */

.theme-dark .ag-theme-alpine {
	--ag-browser-color-scheme: dark;

	--ag-background-color: rgb(var(--c-surface));
	--ag-foreground-color: rgb(var(--c-gray-800));
	--ag-data-color: rgb(var(--c-gray-700));
	--ag-secondary-foreground-color: rgb(var(--c-gray-600));
	--ag-disabled-foreground-color: rgb(var(--c-gray-500));

	--ag-header-background-color: rgb(var(--c-gray-100));
	--ag-header-foreground-color: rgb(var(--c-gray-700));
	--ag-subheader-background-color: rgb(var(--c-gray-100));

	--ag-border-color: rgb(var(--c-gray-200));
	--ag-secondary-border-color: rgb(var(--c-gray-200));
	--ag-row-border-color: rgb(var(--c-gray-200));

	--ag-odd-row-background-color: rgb(var(--c-surface));
	--ag-row-hover-color: rgb(var(--c-gray-100));
	--ag-selected-row-background-color: rgb(59 130 246 / 0.18);
	--ag-range-selection-background-color: rgb(59 130 246 / 0.16);

	--ag-control-panel-background-color: rgb(var(--c-gray-100));
	--ag-side-button-selected-background-color: rgb(var(--c-surface));
	--ag-panel-background-color: rgb(var(--c-surface-raised));
	--ag-menu-background-color: rgb(var(--c-surface-raised));
	--ag-tooltip-background-color: rgb(var(--c-surface-raised));
	--ag-modal-overlay-background-color: rgb(var(--c-surface-sunken) / 0.7);

	--ag-input-background-color: rgb(var(--c-gray-100));
	--ag-input-border-color: rgb(var(--c-gray-300));
	--ag-input-disabled-background-color: rgb(var(--c-gray-100));
	--ag-checkbox-unchecked-color: rgb(var(--c-gray-400));

	--ag-alpine-active-color: rgb(59 130 246);
	--ag-active-color: rgb(59 130 246);
	--ag-chip-background-color: rgb(var(--c-gray-200));
}

/* The loading/no-rows overlay paints its own light backdrop. */
.theme-dark .ag-theme-alpine .ag-overlay-loading-center,
.theme-dark .ag-theme-alpine .ag-overlay-no-rows-center {
	background: rgb(var(--c-surface-raised));
	color: rgb(var(--c-gray-700));
	border-color: rgb(var(--c-gray-200));
}

/* ---------------------------------------------------------------------------
 * Leaflet — dark theme
 *
 * Raster tiles come from the provider already lit for daytime, so they get a
 * measured filter rather than a full inversion (inverting turns water pink and
 * makes labels unreadable). Chrome around the map is themed normally.
 * ------------------------------------------------------------------------ */

.theme-dark .leaflet-tile-pane {
	filter: brightness(0.75) contrast(1.05) saturate(0.75);
}

.theme-dark .leaflet-container {
	background: rgb(var(--c-gray-100));
}

.theme-dark .leaflet-bar a,
.theme-dark .leaflet-control-layers,
.theme-dark .leaflet-popup-content-wrapper,
.theme-dark .leaflet-popup-tip {
	background: rgb(var(--c-surface-raised));
	color: rgb(var(--c-gray-800));
	border-color: rgb(var(--c-gray-200));
}

.theme-dark .leaflet-bar a:hover {
	background: rgb(var(--c-gray-100));
}

.theme-dark .leaflet-control-attribution {
	background: rgb(var(--c-surface) / 0.8);
	color: rgb(var(--c-gray-600));
}

.theme-dark .leaflet-control-attribution a {
	color: rgb(var(--c-gray-700));
}

/* ---------------------------------------------------------------------------
 * Deployment topology diagram (/observability/topology)
 *
 * The diagram is one inline SVG whose colours used to be hardcoded hex
 * presentation attributes. That was deliberate — the fills are chosen from a
 * runtime status value, so Tailwind `fill-*`/`stroke-*` utilities would never
 * appear as literals for the scanner and would be purged (see the note in
 * PlatformWeb.ObservabilityLive.Topology).
 *
 * Hand-written CSS sidesteps that entirely: these class names are never
 * scanned, and `fill`/`stroke` are real CSS properties, so they override the
 * presentation attributes they replace.
 *
 * The diagram's neutrals were all slate-scale values to begin with (#f8fafc is
 * slate-50, #94a3b8 is slate-400, …), so pointing them at `--c-slate-*` keeps
 * light mode pixel-identical and makes dark mode fall out of the ramp for free.
 * Only the status pastels need an explicit dark value, because there the hue
 * has to survive while the lightness flips.
 * ------------------------------------------------------------------------ */

.topo-zone {
	fill: rgb(var(--c-slate-50));
	stroke: rgb(var(--c-slate-200));
}

.topo-zone-label,
.topo-edge-label,
.topo-arrow,
.topo-endpoints {
	fill: rgb(var(--c-slate-400));
}

.topo-title {
	fill: rgb(var(--c-slate-900));
}

.topo-host {
	fill: rgb(var(--c-slate-500));
}

.topo-pip-label {
	fill: rgb(var(--c-slate-600));
}

.topo-edge {
	stroke: rgb(var(--c-slate-300));
}

/* Planned links stay indigo in both themes — the point of the dashed lavender
   is that it reads as "not real yet" regardless of surface. */
.topo-edge--planned {
	stroke: #c7d2fe;
}

/* Hardware glyphs. Body and screen sit at opposite ends of the ramp, so they
   swap together and the glyph keeps its internal contrast in both themes. */
.topo-chassis {
	fill: rgb(var(--c-slate-200));
	stroke: rgb(var(--c-slate-500));
}

.topo-chassis-top {
	fill: rgb(var(--c-slate-100));
	stroke: rgb(var(--c-slate-500));
}

.topo-chassis-line {
	stroke: rgb(var(--c-slate-400));
}

.topo-screen {
	fill: rgb(var(--c-slate-50));
	stroke: rgb(var(--c-slate-400));
}

.topo-keys {
	fill: rgb(var(--c-slate-400));
}

.topo-led {
	fill: #10b981;
}

/* Node status. Light keeps the original pastels; dark uses a low-alpha wash of
   the same hue, matching how the accent tints are handled in theme.css. */
.topo-node--up { fill: #ecfdf5; stroke: #10b981; }
.topo-node--down { fill: #fff1f2; stroke: #f43f5e; }
.topo-node--maintenance { fill: #fffbeb; stroke: #f59e0b; }
.topo-node--not_deployed { fill: #f5f3ff; stroke: #c7d2fe; }

.topo-node--unknown {
	fill: rgb(var(--c-slate-50));
	stroke: rgb(var(--c-slate-300));
}

.theme-dark .topo-node--up { fill: rgb(16 185 129 / 0.16); }
.theme-dark .topo-node--down { fill: rgb(244 63 94 / 0.16); }
.theme-dark .topo-node--maintenance { fill: rgb(245 158 11 / 0.16); }
.theme-dark .topo-node--not_deployed { fill: rgb(139 92 246 / 0.18); }

/* The "declared by an operator" legend swatch — same neutral as an unmonitored
   node but with a stronger outline, since here the dash is the whole point. */
.topo-legend-declared {
	fill: rgb(var(--c-slate-50));
	stroke: rgb(var(--c-slate-500));
}
