/* ------------------------------------------------------------------ *
 * kvkli-theme.css — the ONE stylesheet kvkli-web adds to the portal's
 * static/ (reviewed in the mockup). Loaded after app.css by
 * layout/base.html and layout/bare.html, it overrides nothing but the DaisyUI
 * theme variables of the `proximos` theme with the HARDWARIO brandbook
 * palette of plan-implementation.md §10.10 / thingsboard-plan.md §7.1.
 * No new utility class, no layout change, no markup change.
 *
 * It carries five component rules, and only because the committed app.css
 * writes those colours as fixed Tailwind values that no theme variable can
 * reach: the four filled state chips (`badge-status-*`, where the red that
 * says "mimo mez" lives) and the active range pill. §10.10 asks for the
 * theme file to be the only place a colour is written — this is that file
 * doing it.
 *
 * Every value is written as space-separated `hsl(H S% L%)` on purpose:
 * static/js/portal-charts.js reads the theme through
 * getComputedStyle(...).getPropertyValue() and its `cssVar()` accepts
 * ONLY that syntax — the compiled app.css emits hex, so the shipped
 * portal silently charts with the FIBER-orange fallback constants.
 * Written like this, the charts take KVKLI's colours too.
 *
 * `--color-critical` and `--color-alarm` are the portal's own extra
 * tokens (@theme in assets/css/app.css), not DaisyUI's: `bg-critical`
 * is the card/gauge red and `bg-alarm` the top bar's disconnected pill.
 * Both are #e30427 — every one of them is an alarm, which is the only
 * thing the brandbook lets that red mean (§10.10, "nowhere else, not in
 * headings, borders or buttons").
 *
 * Which palette applies is the `data-theme` attribute of <html>, which
 * partials/theme_head.html sets before the first paint (§11.9): `kvkli-dark`
 * is the dark palette, anything else — `kvkli`, or no attribute at all on a
 * page whose script did not run — the light one. The viewer picks it with
 * the top bar's moon/sun; until they do, it is the browser's colour scheme.
 * ------------------------------------------------------------------ */

:root:not([data-theme="kvkli-dark"]) {
	color-scheme: light;

	/* Grounds: white page/cards, near-white chrome (§10.10). */
	--color-base-100: hsl(0 0% 100%);
	--color-base-200: hsl(216 33.3% 97.1%);   /* #f5f7fa */
	--color-base-300: hsl(214 25% 89%);       /* hairline, desaturated from Grey */
	--color-base-content: hsl(240 14.9% 17.1%); /* #252532 — never pure black */

	--color-primary: hsl(202.6 100% 49%);     /* #009cfa Bright Blue */
	--color-primary-content: hsl(0 0% 100%);
	--color-secondary: hsl(210.1 99.1% 41.8%); /* #016ad4 Dark Blue */
	--color-secondary-content: hsl(0 0% 100%);
	--color-accent: hsl(215.2 90.6% 25.1%);   /* #06367a Navy */
	--color-accent-content: hsl(0 0% 100%);
	--color-neutral: hsl(0 0.5% 41.8%);       /* #6b6a6a Grey */
	--color-neutral-content: hsl(0 0% 100%);

	--color-info: hsl(210.1 99.1% 41.8%);     /* #016ad4 Dark Blue, the second brand hue */
	--color-info-content: hsl(0 0% 100%);
	--color-success: hsl(142.4 71.8% 29.2%);  /* #15803d documented extension */
	--color-success-content: hsl(0 0% 100%);
	--color-warning: hsl(36.5 71.2% 57.8%);   /* #e0a447 */
	--color-warning-content: hsl(36.3 88.4% 33.7%); /* #a2660a, the warning text */
	--color-error: hsl(350.6 96.5% 45.3%);    /* #e30427 — alarms only */
	--color-error-content: hsl(0 0% 100%);

	/* portal @theme tokens daisyUI does not re-derive per theme. */
	--color-critical: hsl(350.6 96.5% 45.3%);
	/* The portal's fourth severity. It paints the top bar's "Odpojeno" pill,
	   which IS an alarm — the box has lost the ThingsBoard link — so it takes
	   the brandbook red rather than an invented orange. */
	--color-alarm: hsl(350.6 96.5% 45.3%);
	--color-muted: hsl(216 33.3% 97.1%);
	--color-muted-fg: hsl(0 0.5% 41.8%);
	/* §10.10: Navy is "the top bar in the light theme". The shell paints the
	   sidebar, the top bar and the corner behind the content panel from this
	   one token, so the whole chrome goes navy together. */
	--color-sidebar: hsl(215.2 90.6% 25.1%);   /* #06367a */
	--color-sidebar-border: hsl(215 62% 34%);
}

/* ------------------------------------------------------------------ *
 * The light palette's text, made heavier (asked for 2026-10-08: "white
 * mode is not good designed … make the text more bold"). Inter is a
 * variable font (100–900), so every step takes effect: plain text goes
 * from 400 to 500 and each weight class one step up, the grey secondary
 * text and the hairlines get darker, and the amber banner's text turns
 * dark brown, which reads both on the amber and on white. The dark
 * palette keeps its weights: light text on a dark ground already looks
 * heavier than it is.
 * ------------------------------------------------------------------ */
:root:not([data-theme="kvkli-dark"]) {
	--font-weight-normal: 500;
	--font-weight-medium: 600;
	--font-weight-semibold: 700;
	--font-weight-bold: 800;
	--color-base-content: hsl(240 18% 12%);     /* #191924 */
	--color-base-300: hsl(214 20% 80%);         /* hairlines a step darker */
	--color-muted-fg: hsl(240 6% 32%);          /* #4c4c56, was Grey #6b6a6a */
	--color-warning-content: hsl(36 90% 20%);   /* #613a05 */
}
:root:not([data-theme="kvkli-dark"]) body {
	font-weight: var(--font-weight-normal);
}

/* ------------------------------------------------------------------ *
 * The chrome is navy, so the tokens the chrome's own text reads have to
 * be the ones that work on navy. Custom properties cascade, so this
 * re-points them for the sidebar and the top bar ALONE — `main` is
 * outside both and keeps the light paper values above. No new class, no
 * template change: every element in there already reads these tokens.
 * ------------------------------------------------------------------ */
#app-sidebar,
header.bg-sidebar {
	/* The ink, not only the token. `text-base-content` is applied once, on
	   <body>, so the colour is COMPUTED there and inherited into the chrome;
	   redefining the variable here would only reach elements that set their
	   own `color` (the ones with a `text-…` class). Everything else — the
	   account name, the page title in the top bar — would keep the body's
	   dark ink and sit unreadable on the navy, which is what a light-mode
	   browser showed. Setting `color` here re-bases the inheritance. */
	color: var(--color-base-content);
	--color-base-content: hsl(216 45.5% 93.5%);  /* #e7edf6 */
	--color-muted-fg: hsl(212 46% 78%);
	--color-base-300: hsl(215 62% 38%);
	--color-muted: hsl(215 66% 30%);
	/* `btn-v1-outline` and the like paint `base-100`; on navy that has to be
	   the navy itself, not white paper. */
	--color-base-100: hsl(215.2 90.6% 25.1%);
	/* Navy is a dark ground, so inside the chrome every hue takes the
	   right-hand column of thingsboard-plan.md §7.1 — the same substitution
	   the dark theme makes, for the same reason: #009cfa reads heavy and
	   #15803d/#e30427 go muddy on dark. */
	--color-primary: hsl(203.1 100% 61.8%);      /* #3cb4ff */
	--color-primary-content: hsl(215.2 90.6% 25.1%);
	--color-success: hsl(141.9 69.2% 58%);       /* #4ade80 */
	--color-error: hsl(352.1 100% 68.6%);        /* #ff5f74 */
	--color-error-content: hsl(215.2 90.6% 25.1%);
	--color-critical: hsl(352.1 100% 68.6%);
	--color-alarm: hsl(352.1 100% 68.6%);
}

/* …except the account menu, which IS white paper hanging over the navy —
   including its inherited ink, for the same reason as above. */
#app-sidebar .user-menu > div {
	color: var(--color-base-content);
	--color-base-100: hsl(0 0% 100%);
	--color-base-content: hsl(240 14.9% 17.1%);
	--color-muted-fg: hsl(0 0.5% 41.8%);
	--color-base-300: hsl(214 25% 89%);
}

/* §10.10: the white horizontal logo whenever the bar it sits on is navy. */
#app-sidebar img[src$="logo.svg"] {
	content: url("../logo-white.svg");
}

/* ------------------------------------------------------------------ *
 * The filled state chips. The committed app.css writes them as fixed
 * Tailwind colours (`oklch(57.7% .245 27.325)` and friends), so the theme
 * never reached the one place the palette matters most — the chip that
 * says "mimo mez". These four lines put the brandbook's own red, green,
 * amber and grey back in charge. Nothing else about the component
 * changes: same shape, same size, same markup.
 * ------------------------------------------------------------------ */
.badge-status-normal {
	background-color: var(--color-success);
	color: var(--color-success-content);
}
.badge-status-warning {
	background-color: var(--color-warning);
	color: hsl(240 14.9% 17.1%);   /* #252532 on amber, in both themes */
}
.badge-status-critical {
	background-color: var(--color-critical);
	color: hsl(0 0% 100%);
}
.badge-status-offline,
.badge-status-neutral {
	background-color: var(--color-neutral);
	color: var(--color-neutral-content);
}

/* §11.5 offline at a glance: the wifi-off mark in every offline badge and in the card's
   reason line; on the monitoring rows a dashed frame on a hatched ground, and the gauge,
   graph and readings faded, because what they show is old. */
.offline-icon {
	width: 0.8rem;
	height: 0.8rem;
	flex-shrink: 0;
}
.badge-status .offline-icon {
	display: inline-block;
	vertical-align: -0.125em;
	margin-right: 0.25rem;
}
.monitoring-row[data-status="Disconnected"] {
	border-style: dashed;
	background-image: repeating-linear-gradient(
		135deg,
		transparent 0 10px,
		hsl(0 0% 50% / 0.07) 10px 20px
	);
}
.monitoring-row[data-status="Disconnected"] .offline-fade {
	opacity: 0.4;
	filter: grayscale(1);
}

/* The active range pill reads as the brand's blue rather than as plain
   text on a white chip — the only decorative use of a brand colour here,
   and it is the primary hue, never the red. */
.pill.is-active {
	color: var(--color-primary);
}

/* The dark variant of §11.9: `data-theme="kvkli-dark"` on <html>, set by
 * partials/theme_head.html from the viewer's choice or, without one, from
 * the browser's colour scheme. Every rule of it starts from that root, so
 * it outranks the light rule it replaces wherever the two meet. */
:root[data-theme="kvkli-dark"] {
	color-scheme: dark;

	--color-base-100: hsl(240 14.9% 17.1%);  /* #252532 */
	--color-base-200: hsl(240 16.9% 12.7%);  /* #1b1b26 */
	--color-base-300: hsl(240 12% 27%);
	--color-base-content: hsl(216 45.5% 93.5%); /* #e7edf6 */

	--color-primary: hsl(203.1 100% 61.8%);  /* #3cb4ff */
	--color-primary-content: hsl(240 16.9% 12.7%);
	--color-secondary: hsl(202.4 100% 71.2%); /* #6cc8ff */
	--color-secondary-content: hsl(240 16.9% 12.7%);
	--color-accent: hsl(203.1 100% 61.8%);
	--color-accent-content: hsl(240 16.9% 12.7%);
	--color-neutral: hsl(216.7 22.2% 68.2%); /* #9caac0 */
	--color-neutral-content: hsl(240 16.9% 12.7%);

	--color-info: hsl(203.1 100% 61.8%);
	--color-info-content: hsl(240 16.9% 12.7%);
	--color-success: hsl(141.9 69.2% 58%);   /* #4ade80 */
	--color-success-content: hsl(240 16.9% 12.7%);
	--color-warning: hsl(36.5 71.2% 57.8%);
	--color-warning-content: hsl(240 16.9% 12.7%);
	--color-error: hsl(352.1 100% 68.6%);   /* #ff5f74 */
	--color-error-content: hsl(240 16.9% 12.7%);

	--color-critical: hsl(352.1 100% 68.6%);
	--color-alarm: hsl(352.1 100% 68.6%);
	--color-muted: hsl(240 16.9% 12.7%);
	--color-muted-fg: hsl(216.7 22.2% 68.2%);
	/* Navy in the dark theme too, darkened to sit under the page rather
	   than shout over it — same hue as #06367a, which is what keeps the
	   chrome recognisably HARDWARIO whichever palette is on. */
	--color-sidebar: hsl(215 70% 13%);
	--color-sidebar-border: hsl(215 55% 24%);
}

/* §10.10: the white horizontal logo on the dark ground. The shell renders
 * one <img>, so the variant is swapped here rather than by editing three
 * templates. */
:root[data-theme="kvkli-dark"] img[src$="logo.svg"] {
	content: url("../logo-white.svg");
}

/* The chrome's own tokens, re-pointed at the dark navy. */
:root[data-theme="kvkli-dark"] #app-sidebar,
:root[data-theme="kvkli-dark"] header.bg-sidebar {
	color: var(--color-base-content);
	--color-base-content: hsl(216 45.5% 93.5%);
	--color-muted-fg: hsl(212 30% 72%);
	--color-base-300: hsl(215 50% 26%);
	--color-muted: hsl(215 55% 18%);
	--color-base-100: hsl(215 70% 13%);
}
:root[data-theme="kvkli-dark"] #app-sidebar .user-menu > div {
	color: var(--color-base-content);
	--color-base-100: hsl(240 14.9% 17.1%);
	--color-base-content: hsl(216 45.5% 93.5%);
	--color-muted-fg: hsl(216.7 22.2% 68.2%);
	--color-base-300: hsl(240 12% 27%);
}

/* §11.9: the top bar's moon/sun shows the way out — the moon on the light
 * palette, the sun on the dark one. */
.theme-toggle .theme-icon-sun,
:root[data-theme="kvkli-dark"] .theme-toggle .theme-icon-moon {
	display: none;
}
:root[data-theme="kvkli-dark"] .theme-toggle .theme-icon-sun {
	display: inline-flex;
}

/* ------------------------------------------------------------------ *
 * The brandbook red, used as a brand colour and not as a state
 * (asked for 2026-09-16: "use more colors from HARDWARIO like the red").
 *
 * It goes on the two surfaces that carry no data and can never be read as
 * an alarm:
 *
 *   1. the account's avatar — the round initial at the foot of the
 *      sidebar, in the user list and on a user's page. It is identity,
 *      not state, and it is a letter in a circle, never a chip;
 *   2. the login and setup hero — the one screen in the product that is
 *      design rather than measurement: its headline runs from Bright Blue
 *      into the red, and the lower glow behind it turns red.
 *
 * The state chips, the gauge bands, the group strips, the alarm badge and
 * the 30/60 markLines keep the red they already had, and nothing was
 * given red that carries a measurement. `.text-gradient`, `.bg-accent/20`
 * and the round `.bg-primary/10` exist nowhere else in KVKLI's pages
 * (pages/login.html, pages/setup.html, layout/nav.html,
 * partials/user_row.html, partials/user_detail.html), so these four rules
 * reach exactly those places and nothing more.
 * ------------------------------------------------------------------ */
.rounded-full.bg-primary\/10 {
	background-color: hsl(350.6 96.5% 45.3% / 0.12);
	color: hsl(350.6 96.5% 45.3%);
}
/* The sidebar is a dark ground in BOTH themes now, and #e30427 goes muddy
   on it (thingsboard-plan.md §7.1) — the avatar there takes the dark-ground
   red, the ones in the white content area keep the brandbook one. */
#app-sidebar .rounded-full.bg-primary\/10 {
	background-color: hsl(352.1 100% 68.6% / 0.18);
	color: hsl(352.1 100% 68.6%);
}
.bg-accent\/20 {
	background-color: hsl(350.6 96.5% 45.3% / 0.22);
}
.text-gradient {
	background-image: linear-gradient(to right, var(--color-primary), hsl(350.6 96.5% 45.3%));
}

:root[data-theme="kvkli-dark"] .rounded-full.bg-primary\/10 {
	background-color: hsl(352.1 100% 68.6% / 0.16);
	color: hsl(352.1 100% 68.6%);
}
:root[data-theme="kvkli-dark"] .bg-accent\/20 {
	background-color: hsl(352.1 100% 68.6% / 0.18);
}
:root[data-theme="kvkli-dark"] .text-gradient {
	background-image: linear-gradient(to right, var(--color-primary), hsl(352.1 100% 68.6%));
}

/* ------------------------------------------------------------------ *
 * Phone width (asked for 2026-09-16). The portal's own shell is already
 * responsive — the sidebar becomes a drawer below `md`, the stat tiles go
 * 2×2, every table sits in an `overflow-x-auto` card. These are the five
 * places KVKLI's own pages still broke, and they are fixed here rather
 * than by adding classes, because the committed app.css is a Tailwind
 * build of the portal's templates: a utility no portal template used
 * (`sm:table-cell`) simply is not in it.
 * ------------------------------------------------------------------ */

/* 1. The range pills. `.pill-group` is an `inline-flex` with no wrap, so
      the dashboard chart's six (24 h · 7 dní · 30 dní · 90 dní · 1 rok ·
      vlastní) ran off the side of a phone and took the page's horizontal
      scroll with them. */
.pill-group {
	flex-wrap: wrap;
}

@media (max-width: 40rem) {
	/* 2. Chart islands: 24–32 rem of chart is most of a phone screen. */
	.chart-island {
		height: 16rem !important;
	}

	/* 3. The optional columns of the device page's frame table — the ones
	      an engineer reads on a laptop and nobody reads on a phone. The
	      time, the raw bytes and the decoding stay. */
	.kvkli-col-opt {
		display: none;
	}

	/* 4. A long DevEUI or a `Poslední downlink` value must wrap rather than
	      widen the card it sits in. */
	.font-mono {
		overflow-wrap: anywhere;
	}
}

/* 5. Nothing may make the page itself scroll sideways: a table that is
      wider than the phone scrolls inside its own card (the portal already
      wraps every one of them), and the body does not. */
body {
	overflow-x: hidden;
}

/* ------------------------------------------------------------------ *
 * Full names on a laptop (review UI 2026-10-06: "full device names must
 * fit — check it on a laptop screen"). A monitoring group runs the whole
 * width; its detailed cards go two a row on a laptop and four only from
 * Tailwind's `2xl` (96 rem = 1536 px), where four whole names fit beside
 * the gauge and the trend line. The portal never used `2xl:grid-cols-4`,
 * so the committed app.css has no such utility — it is written here, with
 * Tailwind's own name and breakpoint, so the template reads as Tailwind.
 * ------------------------------------------------------------------ */
@media (min-width: 96rem) {
	.\32xl\:grid-cols-4 {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}
}

/* ------------------------------------------------------------------ *
 * Light mode: the chrome — left menu, top bar and the corner behind the
 * content panel — is light grey instead of navy (asked for 2026-10-12):
 * black text, the selected menu item filled blue with white text, the
 * colour logo. One grey surface, no seam between menu and top bar; the
 * white content panel with its rounded corner is what stands out. Dark
 * mode keeps its own chrome. Last in the file, so it wins over the navy
 * rules above.
 * ------------------------------------------------------------------ */
:root:not([data-theme="kvkli-dark"]) .bg-sidebar {
	--color-sidebar: hsl(210 16% 95%);
	background-color: var(--color-sidebar);
}
:root:not([data-theme="kvkli-dark"]) #app-sidebar,
:root:not([data-theme="kvkli-dark"]) header.bg-sidebar {
	--color-sidebar: hsl(210 16% 95%);
	--color-sidebar-border: hsl(214 14% 86%);
	--color-base-100: hsl(210 16% 95%);
	--color-base-content: hsl(0 0% 7%);
	--color-muted-fg: hsl(0 0% 7%);
	--color-base-300: hsl(214 14% 82%);
	--color-muted: hsl(214 14% 90%);
	--color-primary: hsl(205 100% 38%);
	--color-primary-content: hsl(0 0% 100%);
	--color-success: hsl(142 72% 29%);
	--color-error: hsl(350.6 96.5% 45.3%);
	--color-error-content: hsl(0 0% 100%);
	--color-critical: hsl(350.6 96.5% 45.3%);
	--color-alarm: hsl(350.6 96.5% 45.3%);
	color: var(--color-base-content);
}
:root:not([data-theme="kvkli-dark"]) #app-sidebar img[src$="logo.svg"] {
	content: url("../logo.svg");
}
:root:not([data-theme="kvkli-dark"]) #app-sidebar .rounded-full.bg-primary\/10 {
	background-color: hsl(350.6 96.5% 45.3% / 0.12);
	color: hsl(350.6 96.5% 45.3%);
}
