/* Admin dashboard stylesheet. Styled with the iotready.com design tokens
   (teal/amber, IBM Plex, near-square corners, light + dark). */
/* IoTReady design tokens, copied from the iotready.com site
   (src/styles/tokens.css + fonts.css). Two layers: PALETTE (raw values) and
   SEMANTIC (jobs). Rules below reference the semantic layer only, so a
   theme change is a change to this block. Dark mode repoints the same
   semantic tokens: automatically from the OS setting, or forced with
   <html data-theme="light|dark">. */

@font-face {
	font-family: "IBM Plex Sans";
	font-style: normal;
	font-display: swap;
	font-weight: 100 700;
	src: url(fonts/ibm-plex-sans-latin-wght-normal.woff2) format("woff2");
	unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
	font-family: "IBM Plex Mono";
	font-style: normal;
	font-display: swap;
	font-weight: 400;
	src: url(fonts/ibm-plex-mono-latin-400-normal.woff2) format("woff2");
	unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
	font-family: "IBM Plex Mono";
	font-style: normal;
	font-display: swap;
	font-weight: 500;
	src: url(fonts/ibm-plex-mono-latin-500-normal.woff2) format("woff2");
	unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

:root {
	/* PALETTE */
	--teal-50: #f2f7f7;  --teal-100: #e6f0f0; --teal-200: #c3dbdc; --teal-300: #8fbbbd;
	--teal-400: #4e9296; --teal-500: #0b5d63; --teal-600: #094a4f; --teal-700: #07383c;
	--teal-800: #052729;
	--amber-100: #fdf3dc; --amber-200: #f9d89a; --amber-500: #f5a623;
	--amber-600: #c9820d; --amber-700: #8a5a0f;
	--neutral-0: #ffffff; --neutral-50: #f7f9f9; --neutral-100: #edf1f1; --neutral-200: #d8dedd;
	--neutral-400: #9aa6a4; --neutral-600: #5c6b69; --neutral-800: #2c3937; --neutral-900: #15211f;
	--red-500: #b4372e; --red-100: #fbeceb;
	--green-600: #2f7d4f; --green-100: #e4f2e8;

	/* SEMANTIC */
	--brand: var(--teal-500);
	--brand-fill: var(--teal-500);
	--brand-hover: var(--teal-600);
	--brand-subtle: var(--teal-100);
	--brand-contrast: var(--neutral-0);
	--accent: var(--amber-500);
	--accent-text: var(--amber-600);
	--accent-subtle: var(--amber-100);
	--attention-ink: var(--amber-700);
	--accent-contrast: #2a1c05;
	--ink: var(--neutral-900);
	--muted: var(--neutral-600);
	--faint: var(--neutral-400);
	--page: var(--neutral-0);
	--surface: var(--neutral-50);
	--surface-2: var(--neutral-100);
	--hairline: var(--neutral-200);
	--danger: var(--red-500);
	--danger-subtle: var(--red-100);
	--ok: var(--green-600);
	--ok-subtle: var(--green-100);

	/* TYPE */
	--font-sans: "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
	--font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;
	--text-xs: 0.75rem;
	--text-sm: 0.875rem;
	--text-base: 1rem;
	--text-lg: 1.125rem;
	--text-xl: 1.375rem;
	--leading-tight: 1.12;
	--leading-snug: 1.35;
	--leading-body: 1.5;
	--tracking-tight: -0.02em;
	--tracking-label: 0.14em;
	--weight-medium: 500;
	--weight-semi: 600;

	/* SPACE / SHAPE / MOTION */
	--space-1: 0.25rem; --space-2: 0.5rem; --space-3: 0.75rem; --space-4: 1rem;
	--space-5: 1.5rem; --space-6: 2rem;
	--radius-sm: 2px; --radius-md: 4px; --radius-lg: 8px;
	--shadow-sm: 0 1px 2px rgb(21 33 31 / 0.06);
	--shadow-md: 0 4px 16px rgb(21 33 31 / 0.08);
	--ease: cubic-bezier(0.4, 0, 0.2, 1);
	--duration: 160ms;

	color-scheme: light;
}

:root[data-theme="dark"] {
	--brand: var(--teal-300);
	--brand-fill: var(--teal-300);
	--brand-hover: var(--teal-200);
	--brand-subtle: var(--teal-700);
	--brand-contrast: var(--teal-800);
	--accent-text: var(--amber-500);
	--accent-subtle: var(--teal-700);
	--attention-ink: var(--amber-500);
	--ink: var(--neutral-0);
	--muted: var(--teal-300);
	--faint: var(--teal-400);
	--page: var(--teal-800);
	--surface: #063134;
	--surface-2: var(--teal-700);
	--hairline: var(--teal-700);
	--danger: #e8837a;
	--danger-subtle: #3a1f1c;
	--ok: #6fcf97;
	--ok-subtle: #103a2a;
	--shadow-sm: 0 1px 2px rgb(0 0 0 / 0.3);
	--shadow-md: 0 4px 16px rgb(0 0 0 / 0.4);
	color-scheme: dark;
}

@media (prefers-color-scheme: dark) {
	:root:not([data-theme="light"]) {
		--brand: var(--teal-300);
		--brand-fill: var(--teal-300);
		--brand-hover: var(--teal-200);
		--brand-subtle: var(--teal-700);
		--brand-contrast: var(--teal-800);
		--accent-text: var(--amber-500);
		--accent-subtle: var(--teal-700);
		--attention-ink: var(--amber-500);
		--ink: var(--neutral-0);
		--muted: var(--teal-300);
		--faint: var(--teal-400);
		--page: var(--teal-800);
		--surface: #063134;
		--surface-2: var(--teal-700);
		--hairline: var(--teal-700);
		--danger: #e8837a;
		--danger-subtle: #3a1f1c;
		--ok: #6fcf97;
		--ok-subtle: #103a2a;
		--shadow-sm: 0 1px 2px rgb(0 0 0 / 0.3);
		--shadow-md: 0 4px 16px rgb(0 0 0 / 0.4);
		color-scheme: dark;
	}
}

*, *::before, *::after { box-sizing: border-box; }
:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: var(--radius-sm); }
::selection { background: var(--accent-subtle); color: var(--ink); }
@media (prefers-reduced-motion: reduce) {
	*, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}



body {
	margin: 0;
	background: var(--surface);
	color: var(--ink);
	font: 16px/var(--leading-body) var(--font-sans);
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
	min-height: 100vh;
}
/* Signed-in pages: top bar, sidebar and main are direct children of body
   (each template writes its own shell), laid out as in the end-user portal. */
body:has(> .bar) {
	display: grid;
	grid-template-columns: 15rem minmax(0, 1fr);
	grid-template-rows: auto 1fr;
	align-items: start;
}
body > .bar { grid-column: 1 / -1; }
body > .sidebar { grid-column: 1; grid-row: 2; }
body > main { grid-column: 2; grid-row: 2; }

button {
	font: inherit;
	cursor: pointer;
}

a { color: var(--brand); }
a:hover { color: var(--brand-hover); }
code, kbd, samp, pre { font-family: var(--font-mono); font-size: .9em; }
h1, h2, h3 { letter-spacing: var(--tracking-tight); }
[hidden] { display: none !important; }

.bar {
	display: flex; align-items: center; justify-content: space-between; gap: 1rem;
	position: sticky; top: 0; z-index: 50; min-height: 2.75rem;
	padding: .3rem 1rem; background: var(--page); color: var(--ink); border-bottom: 1px solid var(--hairline);
}
.bar-left { display: flex; align-items: center; gap: .35rem; }
.brand { display: inline-flex; align-items: center; gap: .6rem; color: var(--brand); font-weight: var(--weight-semi); font-size: 1rem; text-decoration: none; }
.brand:hover { color: var(--brand-hover); }
.brand::before {
	content: "IR"; display: inline-grid; place-items: center; width: 1.6rem; height: 1.6rem;
	border-radius: 20%; background: var(--brand-fill); color: var(--brand-contrast);
	font-size: .7rem; font-weight: 700; letter-spacing: 0;
}
.brand-sub { color: var(--muted); font-weight: 400; margin-left: -.25rem; }
.who { display: flex; align-items: center; gap: .25rem; margin: 0; font-size: .95rem; }
.icon-btn {
	position: relative; display: inline-grid; place-items: center; width: 2rem; height: 2rem;
	border-radius: var(--radius-md); color: var(--muted); cursor: pointer; list-style: none;
}
button.icon-btn { background: none; border: 0; padding: 0; }
.icon-btn::-webkit-details-marker { display: none; }
.icon-btn:hover, .usermenu[open] > .icon-btn { background: var(--surface-2); color: var(--brand); }
.icon-btn svg { width: 1.15rem; height: 1.15rem; }
.usermenu { position: relative; }
.usermenu-panel {
	position: absolute; right: 0; top: calc(100% + .35rem); z-index: 60; min-width: 11rem;
	padding: .35rem; background: var(--page); border: 1px solid var(--hairline);
	border-radius: var(--radius-md); box-shadow: var(--shadow-md);
}
.usermenu-name { margin: 0; padding: .35rem .5rem .45rem; font-weight: var(--weight-semi); border-bottom: 1px solid var(--hairline); overflow-wrap: anywhere; }
.usermenu-panel form { margin: 0; }
.usermenu-item {
	display: block; width: 100%; margin-top: .25rem; padding: .4rem .5rem; text-align: left;
	background: none; border: 0; border-radius: var(--radius-sm); color: var(--ink); font: inherit; cursor: pointer;
	text-decoration: none;
}
.usermenu-item:hover { background: var(--brand-subtle); color: var(--brand); }

.sidebar {
	width: 15rem; box-sizing: border-box;
	position: sticky; top: 2.75rem; max-height: calc(100vh - 2.75rem); overflow-y: auto;
	background: var(--page); border-right: 1px solid var(--hairline); padding: .75rem;
}
.sidebar nav { display: flex; flex-direction: column; gap: .25rem; }
.nav-top, .nav-section ul, .nav-events ul { list-style: none; margin: 0; padding: 0; }
.nav-top { margin-bottom: .25rem; }
.nav-section > summary, .nav-events > summary {
	cursor: pointer; padding: .4rem .3rem; border-radius: var(--radius-md); list-style: none;
	font-size: var(--text-xs); font-weight: var(--weight-semi); letter-spacing: var(--tracking-label);
	text-transform: uppercase; color: var(--muted);
}
.nav-section > summary::-webkit-details-marker, .nav-events > summary::-webkit-details-marker { display: none; }
.nav-section > summary::before, .nav-events > summary::before { content: "\25B8"; display: inline-block; width: 1em; color: var(--muted); }
.nav-section[open] > summary::before, .nav-events[open] > summary::before { content: "\25BE"; }
.nav-section > summary:hover, .nav-events > summary:hover { color: var(--ink); }
.nav-section > ul { margin: 0 0 .5rem; padding-left: 1.1rem; }
.nav-events > ul { padding-left: 1.1rem; }
.nav-events > summary { text-transform: none; letter-spacing: 0; font-weight: 400; font-size: .9rem; }
.nav-app > summary { text-transform: none; letter-spacing: 0; font-size: .9rem; color: var(--ink); }
.sidebar li a {
	display: flex; align-items: center; justify-content: space-between; gap: .4rem;
	padding: .3rem .3rem; border-radius: var(--radius-md); color: var(--ink); text-decoration: none;
	font-size: .9rem; overflow-wrap: anywhere;
}
.sidebar li a:hover, .sidebar li a:focus { background: var(--brand-subtle); color: var(--brand); }
.sidebar li a.active { background: var(--brand-subtle); color: var(--brand); font-weight: var(--weight-semi); box-shadow: inset 3px 0 0 var(--brand); }
.sidebar a.muted-link { color: var(--muted); margin: 0; font-size: .9rem; }
.nav-toggle { display: none; }

@media (max-width: 720px) {
	body:has(> .bar) { grid-template-columns: minmax(0, 1fr); }
	body > .sidebar, body > main { grid-column: 1; }
	body > .sidebar { grid-row: 2; position: static; width: auto; max-height: none; overflow-y: visible; border-right: 0; border-bottom: 1px solid var(--hairline); }
	body > main { grid-row: 3; }
	.js .nav-toggle { display: inline-grid; }
	.js body > .sidebar {
		display: none; position: fixed; z-index: 45; top: 2.75rem; left: 0; bottom: 0;
		width: min(85vw, 20rem); max-height: none; overflow-y: auto; box-shadow: var(--shadow-md);
	}
	.js.nav-open body > .sidebar { display: block; }
	.js.nav-open body::after { content: ""; position: fixed; z-index: 40; inset: 2.75rem 0 0 0; background: rgb(0 0 0 / .35); }
	.js.nav-open { overflow: hidden; }
}

main {
	min-width: 0;
	overflow-x: auto;
	padding: 1rem 1.25rem 2.5rem;
}

.page-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-bottom: 16px;
}

.page-header h1 {
	margin: 0;
	font-size: 1.5rem;
	font-weight: var(--weight-semi);
	line-height: var(--leading-tight);
}

.page-header button {
	background: var(--brand-fill);
	color: var(--brand-contrast);
	border: none;
	border-radius: var(--radius-md);
	padding: .5rem 1rem;
	min-height: 2.5rem;
	font-size: 1rem;
	font-weight: var(--weight-semi);
}

main > section {
	margin-bottom: 26px;
}

table + h2, .table-scroll + h2 { margin-top: 1.5rem; }
main h2 {
	font-size: 1.15rem;
	font-weight: var(--weight-semi);
	line-height: var(--leading-tight);
	margin: 0 0 .5rem;
}

.add-row {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	gap: 10px;
	margin-bottom: 14px;
	padding: 12px 14px;
	background: var(--page);
	border: 1px solid var(--hairline);
	border-radius: var(--radius-md);
}

.add-row label {
	display: flex;
	flex-direction: column;
	gap: 3px;
	font-size: 11.5px;
	color: var(--muted);
}

.add-row input {
	font: inherit;
	font-size: 13px;
	padding: 5px 7px;
	border: 1px solid var(--hairline);
	border-radius: var(--radius-md);
	color: var(--ink);
}

.add-row button {
	background: var(--brand-fill);
	color: var(--brand-contrast);
	border: none;
	border-radius: var(--radius-md);
	padding: .5rem 1rem;
	min-height: 2.5rem;
	font-size: 1rem;
	font-weight: var(--weight-semi);
}

/* Grid tables can have more columns than a phone-width viewport fits -
   the table scrolls horizontally in its own box, the page itself never
   does (see the responsive-width constraint this stack is meant to
   respect). */
.table-scroll {
	overflow-x: auto;
}
.table-scroll td { white-space: nowrap; }

table {
	width: 100%;
	font-size: .95rem;
	border-collapse: collapse;
	background: var(--page);
	border: 1px solid var(--hairline);
}

thead th {
	text-align: left;
	border-bottom: 2px solid var(--brand);
	font-size: var(--text-xs);
	font-weight: var(--weight-semi);
	text-transform: uppercase;
	letter-spacing: .1em;
	color: var(--muted);
	background: var(--surface);
	padding: .55rem .75rem;
	white-space: nowrap;
}

thead th button {
	all: unset;
	color: inherit;
	font: inherit;
	text-transform: inherit;
	letter-spacing: inherit;
	cursor: pointer;
}

thead th button:hover {
	color: var(--brand);
}

thead .filter-row th {
	background: var(--surface);
	padding: 5px 8px;
	font-weight: 400;
	text-transform: none;
	letter-spacing: normal;
	border-bottom: 1px solid var(--hairline);
}

.filter-row input {
	all: unset;
	box-sizing: border-box;
	width: 100%;
	min-width: 90px;
	font-family: var(--font-sans);
	font-size: 12px;
	color: var(--ink);
	background: var(--page);
	border: 1px solid var(--hairline);
	border-radius: var(--radius-md);
	padding: 3px 6px;
}

.filter-row input::placeholder {
	color: var(--muted);
}

.filter-row input:focus {
	border-color: var(--brand);
}

.range-filter {
	display: flex;
	gap: 4px;
}

.range-filter input {
	min-width: 0;
}

thead th.num, td.num {
	text-align: right;
}

tbody td {
	padding: .55rem .75rem;
	border-bottom: 1px solid var(--hairline);
	font-variant-numeric: tabular-nums;
}

tbody td.num {
	font-family: var(--font-mono);
}

tbody td.ro {
	color: var(--muted);
	font-style: italic;
}

tbody tr:hover {
	background: var(--surface);
}

td.editable {
	cursor: text;
	background: var(--surface);
	box-shadow: inset 0 -1px 0 var(--hairline);
}

td.editable:hover {
	background: var(--brand-subtle);
	box-shadow: inset 0 -2px 0 var(--brand);
}

/* `all: unset` strips the browser's own form-control UA styling (which
   includes font metrics that don't reliably match table-cell text, since
   inputs are replaced elements with their own internal box) before
   reapplying only what's needed, so the input renders at exactly the
   td's own line-box height and the row doesn't grow in edit mode. */
td.editable input {
	all: unset;
	display: inline-block;
	box-sizing: border-box;
	width: 100%;
	font: inherit;
}

td.editable.num input {
	font-family: var(--font-mono);
	text-align: right;
}

td.cell-error {
	box-shadow: inset 0 -2px 0 var(--danger);
}

.sort-arrow {
	color: var(--brand);
	margin-left: 3px;
}

footer {
	margin-top: 10px;
	color: var(--muted);
	font-size: 11.5px;
}

.error {
	color: var(--danger);
	font-size: 13px;
}

.login-body {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 100vh;
	width: 100%;
}

.login-card {
	flex: none;
	background: var(--page);
	border: 1px solid var(--hairline);
	border-radius: var(--radius-md);
	padding: 28px 32px;
	width: min(320px, calc(100vw - 32px));
}

.login-card h1 {
	font-size: 16px;
	margin: 0 0 16px;
}

.login-card form {
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.login-card label {
	display: flex;
	flex-direction: column;
	gap: 4px;
	font-size: 12.5px;
	color: var(--muted);
}

.login-card input {
	font: inherit;
	font-size: 14px;
	padding: 7px 9px;
	border: 1px solid var(--hairline);
	border-radius: var(--radius-md);
	color: var(--ink);
}

.login-card button {
	margin-top: 6px;
	background: var(--brand-fill);
	color: var(--brand-contrast);
	border: none;
	border-radius: var(--radius-md);
	padding: 9px 14px;
	font-size: 14px;
}

.login-sso {
	display: flex;
	flex-direction: column;
	gap: 8px;
	margin-top: 18px;
	padding-top: 16px;
	border-top: 1px solid var(--hairline);
}

.login-sso-button {
	display: block;
	text-align: center;
	padding: 8px 14px;
	border: 1px solid var(--hairline);
	border-radius: var(--radius-md);
	color: var(--ink);
	font-size: 14px;
	text-decoration: none;
}

.login-sso-button:hover {
	border-color: var(--brand);
}

/* Shared by the apps/users/roles management pages - plainer than the
   grid/hooks pages (no fixi involved: see users.go's doc comment on why
   these use plain forms + full-page redirects instead). */

.admin-section {
	margin-bottom: 28px;
}

.admin-section h2 {
	font-size: 1.15rem;
	font-weight: var(--weight-semi);
	margin: 0 0 .5rem;
}

.muted {
	color: var(--muted);
	font-size: 12.5px;
}

.muted-link {
	margin-left: 8px;
	font-size: 12px;
	color: var(--muted);
}

.plain-list {
	list-style: none;
	margin: 0 0 10px;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 6px;
}

.plain-list li {
	display: flex;
	align-items: center;
	gap: 8px;
}

.form-card {
	display: flex;
	flex-direction: column;
	gap: 12px;
	background: var(--page);
	border: 1px solid var(--hairline);
	border-radius: var(--radius-md);
	padding: 14px 16px;
	max-width: 480px;
}

.form-card label {
	display: flex;
	flex-direction: column;
	gap: 4px;
	font-size: .875rem;
	color: var(--muted);
}

/* .field: a formgroup wrapper (heading label + control, stacked) used
   instead of a label wrapping its control directly - needed once a
   field's control isn't itself a simple one-line input (see
   .field-control below, for the "Not null" checkbox), but used for
   every field in a .form-card-row so all of a row's fields share the
   exact same two-row shape and the same 34px control height, rather
   than relying on same-looking-by-coincidence markup per field type
   (that's what produced the mismatched input/select/checkbox/button
   heights this replaces - a bare <select> never picked up
   .form-card's own input styling, and the "Not null" checkbox had no
   heading row above it at all, so flex-end alignment landed it at a
   different baseline than every other field). */
.form-card .field {
	display: flex;
	flex-direction: column;
	gap: 4px;
}

.form-card-row .field-control {
	display: flex;
	align-items: center;
	height: 34px;
}

.form-card input:not([type="checkbox"]),
.form-card select {
	font: inherit;
	font-size: 1rem;
	height: 2.5rem;
	padding: 0 .65rem;
	border: 1px solid var(--hairline);
	border-radius: var(--radius-md);
	color: var(--ink);
	background: var(--page);
}

.form-card fieldset {
	border: 1px solid var(--hairline);
	border-radius: var(--radius-md);
	padding: 8px 10px;
}

.form-card legend {
	font-size: 11.5px;
	color: var(--muted);
	padding: 0 4px;
}

.checkbox-label {
	display: flex !important;
	flex-direction: row !important;
	align-items: center;
	gap: 6px;
	font-size: 13px !important;
	color: var(--ink) !important;
}

.form-card button,
.admin-section > form:not(.form-card) button {
	align-self: flex-start;
	display: flex;
	align-items: center;
	background: var(--brand-fill);
	color: var(--brand-contrast);
	border: none;
	border-radius: var(--radius-md);
	padding: .5rem 1rem;
	min-height: 2.5rem;
	font-size: 1rem;
	font-weight: var(--weight-semi);
	cursor: pointer;
}

/* .form-card-row: a form-card whose fields sit in one horizontal row
   (each <label> wraps its own field, unlike .inline-form's bare
   inputs) - used for "add a row of structured fields" forms like
   add-column/add-role-binding, which used to carry BOTH .form-card
   and .inline-form. That combination fought itself: both classes set
   `display` and only .form-card set `flex-direction: column`, so the
   cascade (.inline-form sorts after .form-card below) applied
   `display: inline-flex` while leaving `flex-direction: column` in
   place - an inline-flex column shrinks to its content's width, which
   is what rendered as a narrow card floating over the table instead
   of a normal block-width row of fields. */
.form-card-row {
	flex-direction: row;
	flex-wrap: wrap;
	align-items: flex-end;
	max-width: none;
}

/* .form-card-wide: lifts the base .form-card's 480px cap for a form
   whose content (the new-table columns/roles indexed-rows tables) is
   naturally wider than a simple single-column form - without this, the
   whole card (not just the table) gets squeezed to 480px, so the
   table's own overflow-x scroll area is confined to that same 480px
   regardless of how much room main actually has. */
.form-card-wide {
	max-width: none;
}

.form-card-row .field {
	flex: 0 1 160px;
}

.form-card-row button {
	align-self: flex-end;
	height: 34px;
	padding: 0 14px;
}

.inline-form {
	display: inline-flex;
	align-items: center;
	gap: 6px;
}

.inline-form input,
.inline-form select {
	font: inherit;
	font-size: 13px;
	padding: 4px 6px;
	border: 1px solid var(--hairline);
	border-radius: var(--radius-md);
}

.inline-form button {
	background: var(--brand-subtle);
	color: var(--brand);
	border: 1px solid var(--hairline);
	border-radius: var(--radius-md);
	padding: 4px 10px;
	font-size: 12.5px;
	cursor: pointer;
}

/* indexed-rows tables (new-table columns/roles, "add another row" forms)
   size themselves to their inputs' content rather than being squeezed
   to 100% of the surrounding form-card - a row with 7 columns (name,
   label, type, not null, default, unique, indexed) at a shared card
   width otherwise divides into unreadably narrow cells. Letting the
   table grow past the card and scrolling it horizontally via
   .table-scroll (see above) keeps every input at a legible minimum
   width instead. */
table.indexed-rows {
	width: auto;
	min-width: 100%;
}

table.indexed-rows input,
table.indexed-rows select {
	font: inherit;
	font-size: 13px;
	padding: 4px 6px;
	border: 1px solid var(--hairline);
	border-radius: var(--radius-md);
	width: auto;
}

table.indexed-rows input:not([type="checkbox"]),
table.indexed-rows select {
	min-width: 90px;
}

.danger-button {
	background: var(--danger);
	color: var(--brand-contrast);
	border: none;
	border-radius: var(--radius-md);
	padding: .5rem 1rem;
	min-height: 2.5rem;
	font-size: 1rem;
	font-weight: var(--weight-semi);
	cursor: pointer;
}

.banner {
	background: var(--brand-subtle);
	border: 1px solid var(--brand);
	border-radius: var(--radius-md);
	padding: 12px 14px;
	margin-bottom: 20px;
	font-size: 13px;
}

.reveal-key {
	display: block;
	margin-top: 8px;
	padding: 8px 10px;
	background: var(--page);
	border: 1px solid var(--hairline);
	border-radius: var(--radius-md);
	font-family: var(--font-mono);
	font-size: 13px;
	word-break: break-all;
	user-select: all;
}

/* ==================================================================
   Home overview (templates/home.html, home.go) - KPI tiles, the
   needs-attention list, rows-per-day chart, rows-per-table bars and
   the numeric-column stats table. Kept in one block at the end so it
   stays independent of the other pages' rules.

   Colors: the single data hue is slot 1 of the dataviz skill's
   validated palette (blue #2a78d6, also used by home.html's uPlot
   series). Status uses the skill's reserved status steps - critical
   #d03b3b, warning #fab219, good #0ca30c - on marks only (left rule +
   icon disc); the words stay in ink, and every flagged tile/row also
   carries an icon + a text label, so state is never color alone.
   ================================================================== */

.home {
	--series-1: var(--brand);
	--status-bad: var(--danger);
	--status-warn: var(--accent);
	--status-good: var(--ok);
}

.home .page-header {
	flex-wrap: wrap;
	gap: 4px 12px;
}

.state-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
	width: 16px;
	height: 16px;
	border-radius: 50%;
	font-size: 10px;
	font-weight: 700;
	line-height: 1;
	color: var(--brand-contrast);
	background: var(--muted);
}

.state-bad .state-icon, .tile-bad .state-icon { background: var(--status-bad); }
.state-warn .state-icon, .tile-warn .state-icon { background: var(--status-warn); color: var(--accent-contrast); }

.home-attention {
	margin-bottom: 18px;
}

.home-attention ul {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 6px;
}

.home-attention li {
	display: flex;
	align-items: center;
	gap: 8px;
	background: var(--page);
	border: 1px solid var(--hairline);
	border-left-width: 4px;
	border-radius: var(--radius-md);
	padding: 7px 10px;
	font-size: 13px;
}

.home-attention li.state-bad { border-left-color: var(--status-bad); }
.home-attention li.state-warn { border-left-color: var(--status-warn); }

.home-attention a {
	color: var(--ink);
}

.home-allclear {
	display: flex;
	align-items: center;
	gap: 8px;
	margin: 0;
	color: var(--muted);
	font-size: 13px;
}

.home-allclear .state-icon { background: var(--status-good); }

.tile-group {
	margin-bottom: 16px;
}

.tile-group h2,
.home-card h2 {
	font-size: 11.5px;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: var(--tracking-label);
	color: var(--muted);
	margin: 0 0 6px;
}

.tiles {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
	gap: 8px;
}

.tile {
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-width: 0;
	background: var(--page);
	border: 1px solid var(--hairline);
	border-radius: var(--radius-md);
	padding: 9px 12px 10px;
	color: var(--ink);
	text-decoration: none;
}

a.tile:hover {
	border-color: var(--brand);
	box-shadow: inset 0 -2px 0 var(--brand);
}

.tile-bad { border-left: 4px solid var(--status-bad); }
.tile-warn { border-left: 4px solid var(--status-warn); }

.tile-label {
	font-size: 12px;
	color: var(--muted);
}

.tile-value {
	font-size: 22px;
	font-weight: 600;
	line-height: 1.2;
}

.tile-note {
	font-size: 11.5px;
	color: var(--muted);
}

.tile-state {
	display: flex;
	align-items: center;
	gap: 5px;
	font-size: 11.5px;
	font-weight: 600;
}

.home-charts {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr));
	gap: 12px;
	margin-top: 20px;
}

.home-card {
	min-width: 0;
	background: var(--page);
	border: 1px solid var(--hairline);
	border-radius: var(--radius-md);
	padding: 12px 14px 14px;
}

.home-card-wide {
	grid-column: 1 / -1;
}

.home-sub {
	margin: 0 0 10px;
	font-size: 12px;
	color: var(--muted);
}

.home-figure {
	margin: 0 0 6px;
	font-size: 13px;
	color: var(--muted);
}

.home-figure strong {
	font-size: 18px;
	color: var(--ink);
}

.home-empty {
	margin: 4px 0 0;
	font-size: 13px;
	color: var(--muted);
	max-width: 60ch;
}

.home-sources {
	margin: 6px 0 0;
	font-size: 11.5px;
	overflow-wrap: anywhere;
}

.line-chart {
	width: 100%;
	overflow: hidden;
}

/* Hover readout under the rows-per-day chart (uPlot's own legend is off). */
.chart-readout {
	margin: 4px 0 0;
	font-size: 12.5px;
	font-variant-numeric: tabular-nums;
	min-height: 1.5em;
}

/* Rows per table: plain HTML horizontal bars (14px thick, 4px rounded
   data end, square at the baseline). On narrow screens the name moves
   above its bar so long app/table names don't squeeze the bar. */
.hbars {
	list-style: none;
	margin: 0 0 8px;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 6px;
}

.hbars li {
	display: grid;
	grid-template-columns: minmax(0, 26ch) 1fr auto;
	align-items: center;
	gap: 10px;
	font-size: 13px;
}

.hbar-name {
	color: var(--ink);
	text-decoration: none;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.hbar-name:hover { color: var(--brand); }

.hbar-track {
	display: block;
	height: 14px;
	border-left: 1px solid var(--hairline);
}

.hbar-fill {
	display: block;
	height: 100%;
	min-width: 2px;
	background: var(--series-1);
	border-radius: 0 4px 4px 0;
}

.hbar-value {
	font-variant-numeric: tabular-nums;
	text-align: right;
	min-width: 3ch;
}

@media (max-width: 520px) {
	.hbars li {
		grid-template-columns: 1fr auto;
		row-gap: 2px;
	}
	.hbar-name { grid-column: 1 / -1; }
}

.stats-table {
	font-size: 12.5px;
}

.stats-table thead th,
.stats-table tbody td {
	padding: 6px 10px;
}

.stats-table td a {
	color: var(--ink);
	text-decoration: none;
	white-space: nowrap;
}

.stats-table td a:hover { color: var(--brand); }

.stats-table td.num {
	white-space: nowrap;
}

@media (max-width: 520px) {
	main { padding: .75rem; }
}

/* ==========================================================================
   Admin tools (hook editor, service accounts, devices) - dashboard-admin-gaps.
   Kept together at the end of the file to stay merge-friendly.
   ========================================================================== */

.section-head {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 8px;
	margin-bottom: 4px;
}

.section-head h2 {
	margin: 0;
}

.button-link {
	display: inline-block;
	background: var(--brand-fill);
	color: var(--brand-contrast);
	border-radius: var(--radius-md);
	padding: .5rem 1rem;
	min-height: 2.5rem;
	font-size: 1rem;
	font-weight: var(--weight-semi);
	text-decoration: none;
}

.button-link:hover {
	background: var(--brand-hover);
	color: var(--brand-contrast);
}

.hook-state {
	display: inline-block;
	padding: 1px 7px;
	border-radius: 10px;
	border: 1px solid var(--hairline);
	font-size: 11.5px;
	font-weight: 400;
	color: var(--muted);
	white-space: nowrap;
	vertical-align: middle;
}

.hook-state-ok {
	color: var(--brand);
	border-color: var(--brand);
	background: var(--brand-subtle);
}

.hook-state-bad {
	color: var(--danger);
	border-color: var(--danger);
	background: var(--danger-subtle);
}

.hook-state-warn {
	color: var(--accent-text);
	border-color: var(--accent);
	background: var(--accent-subtle);
}

.hook-error {
	border: 1px solid var(--danger);
	border-left-width: 4px;
	background: var(--danger-subtle);
	color: var(--danger);
	border-radius: var(--radius-md);
	padding: 10px 14px;
	margin-bottom: 14px;
	font-size: 13px;
}

.hook-error-line {
	margin: 6px 0 0;
	padding: 6px 8px;
	background: var(--page);
	border: 1px solid var(--hairline);
	border-radius: var(--radius-md);
	color: var(--ink);
	font-family: var(--font-mono);
	font-size: 12.5px;
	overflow-x: auto;
}

.hook-form .form-card-row {
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	align-items: flex-end;
	gap: 10px;
}

.hook-form .form-card-row .field {
	flex: 0 1 150px;
}

.hook-form .form-card-row .hook-field-wide {
	flex: 1 1 200px;
}

.hook-form .form-card-row .hook-field-narrow {
	flex: 0 1 100px;
}

.hook-form .form-card-row input:not([type="checkbox"]),
.hook-form .form-card-row select {
	width: 100%;
}

.field-label {
	font-size: 12.5px;
}

textarea.source-editor {
	width: 100%;
	font-family: var(--font-mono);
	font-size: 13px;
	line-height: 1.5;
	tab-size: 4;
	padding: 8px 10px;
	border: 1px solid var(--hairline);
	border-radius: var(--radius-md);
	color: var(--ink);
	background: var(--page);
	resize: vertical;
	white-space: pre;
	overflow: auto;
}

textarea.source-editor:focus {
	outline: none;
	border-color: var(--brand);
}

.hook-help summary {
	cursor: pointer;
	font-size: 12.5px;
	color: var(--muted);
}

.hook-help pre {
	margin: 6px 0 0;
	padding: 8px 10px;
	background: var(--surface);
	border: 1px solid var(--hairline);
	border-radius: var(--radius-md);
	font-family: var(--font-mono);
	font-size: 12px;
	overflow-x: auto;
}

.button-row {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

.form-card .button-row .secondary-button {
	background: var(--brand-subtle);
	color: var(--brand);
	border: 1px solid var(--hairline);
}

.hook-test {
	display: flex;
	flex-direction: column;
	gap: 8px;
}

.hook-test-result {
	border-top: 1px solid var(--hairline);
	padding-top: 8px;
}

.hook-test-result h3 {
	margin: 0 0 6px;
	font-size: 13px;
}

.hook-test-result dl {
	display: grid;
	grid-template-columns: max-content 1fr;
	gap: 4px 14px;
	margin: 0;
	font-size: 13px;
}

.hook-test-result dt {
	color: var(--muted);
}

.hook-test-result dd {
	margin: 0;
	word-break: break-word;
}

.hook-runtime-errors code {
	font-size: 12px;
	word-break: break-word;
}

/* .admin-section's generic form-button rule outranks .danger-button. */
.admin-section > form:not(.form-card) button.danger-button {
	background: var(--danger);
}

/* Service accounts / devices lists: keep names, IDs and dates on one line
   (on a phone the table scrolls in its .table-scroll box instead of
   breaking "pw-csrf-check" one syllable per line), and give the form
   section below the table some room. */
.credential-table td {
	white-space: nowrap;
}

.table-scroll + .admin-section {
	margin-top: 22px;
}

/* Settings tab editor (settings_tab.html): plain textareas share the
   form-card input look; .source-editor (JSON list fields) has its own. */
.form-card textarea:not(.source-editor) {
	font: inherit;
	font-size: 14px;
	padding: 6px 8px;
	border: 1px solid var(--hairline);
	border-radius: var(--radius-md);
	color: var(--ink);
	background: var(--page);
	resize: vertical;
}

/* Controls: a stronger border than the structural hairline, so fields read as fields. */
.add-row input, .form-card input:not([type="checkbox"]), .form-card select, .form-card textarea,
.inline-form input, .inline-form select, table.indexed-rows input, table.indexed-rows select,
.login-card input, .filter-row input, textarea.source-editor {
	border-color: var(--faint);
	background: var(--page);
	color: var(--ink);
}
.add-row input:focus, .form-card input:focus, .form-card select:focus, .form-card textarea:focus,
.login-card input:focus, .inline-form input:focus, .inline-form select:focus {
	outline: 2px solid var(--brand);
	outline-offset: 1px;
}

.login-card::before {
	content: "IR";
	display: grid;
	place-items: center;
	width: 2.25rem;
	height: 2.25rem;
	margin-bottom: 14px;
	border-radius: 20%;
	background: var(--brand-fill);
	color: var(--brand-contrast);
	font-size: 14px;
	font-weight: 700;
}

#hooks-status > section { margin-bottom: 1.5rem; }

/* App store (issue #591): the card grid and the capability list. */
.store-search { display: flex; gap: 8px; margin: 0 0 14px; }
.store-search input[type="search"] { flex: 1; max-width: 24rem; }
.store-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr));
	gap: 12px;
	margin: 0 0 20px;
}
.store-card {
	display: flex;
	flex-direction: column;
	gap: 6px;
	min-width: 0;
	padding: 12px 14px;
	background: var(--page);
	border: 1px solid var(--hairline);
	border-radius: var(--radius-md);
}
.store-card h3 { margin: 0; font-size: 1rem; }
.store-card p { margin: 0; overflow-wrap: anywhere; }
.store-card .store-card-foot { margin-top: auto; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.store-caps th { text-align: left; white-space: nowrap; vertical-align: top; padding-right: 14px; }
.store-caps ul { margin: 0; padding-left: 1.1rem; }
.store-caps li { overflow-wrap: anywhere; }
.store-post { white-space: pre-wrap; overflow-wrap: anywhere; }

/* Record detail pages (user detail, issue #771): one card per concern in
   a two-column grid, small secondary buttons beside what they act on,
   rarely used forms behind a <details> toggle, and the destructive
   actions together in a red-bordered card at the bottom. */
.detail-sub { margin: 4px 0 0; color: var(--muted); font-size: 13px; }
.detail-grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 16px;
	align-items: start;
}
@media (max-width: 900px) {
	.detail-grid { grid-template-columns: minmax(0, 1fr); }
}
.detail-card {
	min-width: 0;
	background: var(--page);
	border: 1px solid var(--hairline);
	border-radius: var(--radius-md);
	padding: 12px 16px 16px;
}
.detail-card-wide { grid-column: 1 / -1; }
.detail-card h2 { font-size: 1.05rem; font-weight: var(--weight-semi); margin: 0 0 10px; }
.detail-card .section-head { margin-bottom: 10px; }
.detail-card p.muted { margin: 6px 0 0; }
.detail-list {
	display: grid;
	grid-template-columns: max-content minmax(0, 1fr);
	gap: 12px 20px;
	margin: 0;
	align-items: baseline;
}
.detail-list dt { color: var(--muted); font-size: 13px; }
.detail-list dd { margin: 0; overflow-wrap: anywhere; }
.chip-list { list-style: none; margin: 0 0 12px; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
	display: inline-flex;
	align-items: center;
	gap: 2px;
	padding: 2px 3px 2px 10px;
	border: 1px solid var(--hairline);
	border-radius: 999px;
	background: var(--surface-2);
	font-size: 13px;
}
.chip form { margin: 0; display: inline-flex; }
.chip-remove {
	background: none;
	border: 0;
	border-radius: 999px;
	color: var(--muted);
	cursor: pointer;
	width: 1.4rem;
	height: 1.4rem;
	padding: 0;
	font-size: 15px;
	line-height: 1;
}
.chip-remove:hover { color: var(--danger); background: var(--danger-subtle); }
.detail-table th[scope="row"] { text-align: left; font-weight: 400; white-space: nowrap; width: 1%; padding-right: 24px; }
.detail-table td, .detail-table th[scope="row"] { vertical-align: middle; }
.detail-table td.actions { text-align: right; white-space: nowrap; width: 1%; }
.detail-table form { margin: 0; }
details.reveal > summary {
	display: inline-block;
	list-style: none;
	cursor: pointer;
	background: var(--brand-subtle);
	color: var(--brand);
	border: 1px solid var(--hairline);
	border-radius: var(--radius-md);
	padding: 4px 10px;
	font-size: 12.5px;
}
details.reveal > summary::-webkit-details-marker { display: none; }
details.reveal[open] > summary { margin-bottom: 8px; }
details.reveal p.muted { white-space: normal; max-width: 28rem; margin-left: auto; text-align: right; }
.totp-pending > * + * { margin-top: 8px; }
.danger-zone { border-color: var(--danger); }
.danger-row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	padding: 10px 0;
	border-top: 1px solid var(--hairline);
}
.danger-row:first-of-type { border-top: 0; padding-top: 0; }
.danger-row p.muted { margin: 2px 0 0; }
.inline-form button.danger-outline { color: var(--danger); background: var(--danger-subtle); border-color: var(--danger); }
.inline-form button.danger-outline:hover { background: var(--danger); color: var(--brand-contrast); }

/* The home page's ask box (issue #773) sits above the dashboard. */
.home-ask:not([hidden]) + .page-header {
	border-top: 1px solid var(--hairline);
	padding-top: 24px;
}

/* Settings (settings_index.html, settings_tab.html): the index is a tile
   grid per namespace; a tab is a side nav of its namespace's tabs beside
   one card per section, each field a label+description / control row, with
   a sticky save bar. */
.settings-tiles { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }
.settings-tile-label { font-weight: var(--weight-semi); }

.settings-layout {
	display: grid;
	grid-template-columns: 200px minmax(0, 1fr);
	gap: 24px;
	align-items: start;
}

.settings-nav h2 {
	font-size: 11.5px;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: var(--tracking-label);
	color: var(--muted);
	margin: 0 0 6px;
}

.settings-nav ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }

.settings-nav a {
	display: block;
	padding: 6px 10px;
	border-radius: var(--radius-md);
	color: var(--ink);
	text-decoration: none;
	border-left: 3px solid transparent;
}

.settings-nav a:hover { background: var(--hairline); }
.settings-nav a.current { border-left-color: var(--brand); font-weight: var(--weight-semi); background: var(--hairline); }

.settings-form { border: none; padding: 0; background: none; gap: 16px; }

.form-card fieldset.settings-card {
	background: var(--page);
	border: 1px solid var(--hairline);
	border-radius: var(--radius-md);
	padding: 4px 16px;
	margin: 0;
	min-width: 0;
}

.form-card .settings-card legend {
	font-size: 11.5px;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: var(--tracking-label);
	padding: 0 6px;
}

.settings-row {
	display: grid;
	grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
	gap: 8px 24px;
	padding: 14px 0;
	border-top: 1px solid var(--hairline);
}

.settings-row:first-of-type { border-top: none; }
.settings-row-head, .settings-row-control { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.settings-row-head label { font-weight: var(--weight-semi); color: var(--ink); flex-direction: row; align-items: center; gap: 8px; }
.settings-row-control > input:not([type="checkbox"]), .settings-row-control > select, .settings-row-control > textarea { width: 100%; box-sizing: border-box; }
.settings-row.has-error .settings-row-control > input,
.settings-row.has-error .settings-row-control > textarea { border-color: var(--status-bad); }
.settings-checks { display: flex; flex-wrap: wrap; gap: 6px 16px; }

.settings-actions {
	position: sticky;
	bottom: 0;
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 10px 0;
	background: var(--page);
	border-top: 1px solid var(--hairline);
}

@media (max-width: 760px) {
	.settings-layout { grid-template-columns: minmax(0, 1fr); }
	.settings-nav ul { flex-direction: row; flex-wrap: wrap; }
	.settings-row { grid-template-columns: minmax(0, 1fr); }
}
