/* JPKCom Desktop — shared components: tiles, buttons, segments, switches, fields, sheets, rows — © Jean Pierre Kolb — MIT License

   Used across core parts, modules and apps. Module CSS styles its own
   layout and reuses these classes instead of redefining controls:

     .tile .tile-logo .tile-mark   app tile (core/icons.js tile()) — --tint from the tint;
                           the logo variant and the short text mark inside it
     .btn .btn-primary .btn-danger
     .seg                  native radios as segments  (label > input + span)
     .swatches             native radios as colour dots (--c on the span)
     .switch               native checkbox as a switch (role="switch")
     .check                native checkbox for a choice
     .field .field-input   search/text field with an icon
     .sheet .sheet-box .sheet-btns   a question inside a window (.sheet-global: over the page) — core/dialog.js
     .panel                padded, scrolling content of a native window
     .notice               centred message in a window (tile, title, text, button)
     .set-row …            label/control rows (settings, reset, backup) */

@layer components {

	/* ---------- App tile ---------- */

	.tile {
		--tint: var(--t-slate);
		display: grid;
		place-items: center;
		width: var(--tile);
		height: var(--tile);
		border-radius: var(--radius-tile);
		background: linear-gradient(180deg, var(--tint));
		box-shadow: var(--tile-box-shadow);
		color: var(--tile-fg);
		font-size: calc(var(--tile) * 0.5);

		/* The logo fills the tile; the tile's rounding clips it */
		&.tile-logo {
			overflow: hidden;
			background: none;

			svg {
				display: block;
				width: 100%;
				height: 100%;
			}
		}

		/* White glyphs on the light top of a tint: a shadow edge keeps them apart from it
		   (WCAG 1.4.11 — the tile is the only visual identifier in the Dock) */
		&:not(.tile-logo) > svg {
			filter: var(--tile-glyph-filter);
		}

		.tile-mark {
			font: 800 calc(var(--tile) * 0.38) / 1 var(--font-mono);
			letter-spacing: -0.04em;
			text-shadow: var(--tile-mark-shadow);
		}
	}

	/* ---------- Buttons ---------- */

	.btn {
		padding: 4px 14px;
		border-radius: var(--radius-btn);
		background: rgb(var(--ink) / 0.14);
		box-shadow: var(--shadow-btn);
		color: var(--text);
		font-size: 13px;

		&:hover {
			background: rgb(var(--ink) / 0.2);
		}

		&:disabled {
			opacity: 0.4;
			background: rgb(var(--ink) / 0.08);
		}

		&.btn-primary {
			background: var(--accent);
			color: var(--on-accent);
		}

		&.btn-danger {
			background: var(--danger);
			color: var(--on-accent);
		}

		&.btn-primary:hover,
		&.btn-danger:hover {
			filter: brightness(1.12);
		}
	}

	/* ---------- Segments and swatches (native radios) ---------- */

	.seg,
	.swatches {
		display: flex;
		flex: none;
		flex-wrap: wrap;
		gap: 2px;

		input {
			position: absolute;
			opacity: 0;
			pointer-events: none;
		}
	}

	.seg {
		padding: 2px;
		border-radius: var(--radius-seg);
		background: var(--line);

		span {
			display: block;
			padding: 3px 12px;
			border-radius: var(--radius-seg-item);
			color: var(--text-2);
		}

		input:checked + span {
			background: var(--accent);
			color: var(--on-accent);
		}

		input:focus-visible + span {
			outline: 2px solid var(--focus);
			outline-offset: 1px;
		}
	}

	/* The colour comes from --c on the span (style: { '--c': … } in h()) */
	.swatches {
		gap: 8px;

		span {
			display: block;
			width: 22px;
			height: 22px;
			border-radius: var(--radius-swatch);
			background: var(--c);
			box-shadow: var(--shadow-swatch);
		}

		input:checked + span {
			box-shadow: 0 0 0 2px var(--win-bg), 0 0 0 4px var(--c);
		}

		input:focus-visible + span {
			outline: 2px solid var(--focus);
			outline-offset: 5px;
		}
	}

	/* ---------- Switch and checkbox ---------- */

	.switch {
		position: relative;
		flex: none;
		width: 34px;
		height: 20px;
		margin: 0;
		border-radius: var(--radius-switch);
		background: var(--line-strong);
		-webkit-appearance: none;
		appearance: none;
		transition: background var(--dur) var(--ease);

		&::before {
			content: "";
			position: absolute;
			inset-block-start: 2px;
			inset-inline-start: 2px;
			width: 16px;
			height: 16px;
			border-radius: var(--radius-switch-knob);
			background: var(--switch-knob);
			box-shadow: var(--shadow-switch-knob);
			transition: translate var(--dur) var(--ease);
		}

		/* Off: the track and the knob get a 3:1 edge (WCAG 1.4.11) — the light track alone is not enough */
		&:not(:checked) {
			box-shadow: var(--shadow-control-edge);

			&::before {
				box-shadow: var(--shadow-switch-knob-off);
			}
		}

		&:checked {
			background: var(--accent);

			&::before {
				translate: 14px 0;
			}
		}

		&:focus-visible {
			outline: 2px solid var(--focus);
			outline-offset: 2px;
		}
	}

	:root[dir="rtl"] .switch:checked::before {
		translate: -14px 0;
	}

	.check {
		flex: none;
		width: 18px;
		height: 18px;
		margin: 0;
		accent-color: var(--accent);
	}

	/* ---------- Text field with icon ---------- */

	.field {
		display: flex;
		flex: 1;
		align-items: center;
		gap: 6px;
		max-width: 300px;
		height: 28px;
		padding: 0 8px;
		border-radius: var(--radius-input);
		background: rgb(var(--ink) / 0.08);
		box-shadow: var(--shadow-control-edge);
		color: var(--text-3);
		font-size: 14px;

		/* The ring keeps the edge; the transparent outline shows in forced colours, where shadows go */
		&:focus-within {
			outline: 2px solid transparent;
			box-shadow: var(--shadow-control-edge), var(--ring-focus);
		}
	}

	.field-input {
		flex: 1;
		min-width: 0;
		border: 0;
		outline: 0;
		background: none;
		color: var(--text);
		font: 13px var(--font);
		-webkit-user-select: text;
		user-select: text;

		&::placeholder {
			color: var(--text-3);
		}
	}

	/* ---------- Sheet: a question inside a window ---------- */

	.sheet {
		position: absolute;
		inset: 0;
		z-index: 5;
		display: flex;
		align-items: flex-start;
		justify-content: center;
		padding: 0 12px;
		background: rgb(0 0 0 / calc(0.35 * var(--shade)));

		/* Without a window (core/dialog.js, within: null): over the whole page, under the menu bar */
		&.sheet-global {
			position: fixed;
			inset: var(--mb-total) 0 0;
			z-index: var(--z-popover);
		}
	}

	.sheet-box {
		width: min(100%, 380px);
		padding: 18px 18px 14px;
		border-radius: 0 0 var(--radius-sheet) var(--radius-sheet);
		background: var(--glass-strong);
		-webkit-backdrop-filter: var(--sheet-backdrop);
		backdrop-filter: var(--sheet-backdrop);
		box-shadow: var(--shadow-sheet);

		h3 {
			margin: 0 0 6px;
			font-size: 14px;
			overflow-wrap: anywhere;
		}

		p {
			margin: 0;
			color: var(--text-2);
		}
	}

	.sheet-btns {
		display: flex;
		flex-wrap: wrap;
		justify-content: flex-end;
		gap: 8px;
		margin-top: 16px;
	}

	/* ---------- Panel and notice ---------- */

	.panel {
		height: 100%;
		overflow-y: auto;
		padding: 22px 26px;
		color: var(--text-2);
		font-size: 13px;
		line-height: 1.55;
		-webkit-user-select: text;
		user-select: text;

		h2,
		h3 {
			margin: 0 0 6px;
			color: var(--text);
			line-height: 1.25;
		}

		p {
			margin: 0 0 12px;
		}

		a {
			color: var(--reader-link);
		}
	}

	kbd {
		padding: 1px 5px;
		border-radius: var(--radius-kbd);
		background: rgb(var(--ink) / 0.1);
		font: 12px var(--font);
	}

	.notice {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		gap: 4px;
		text-align: center;

		.tile {
			--tile: 64px;
			margin-bottom: 14px;
		}

		p {
			max-width: 34em;
			margin-bottom: 16px;
		}
	}

	/* ---------- Label/control rows ---------- */

	.set-row {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 16px;
		padding: 11px 0;
		border-top: 1px solid var(--line);

		/* No rule above the first row — rows mix <div> and <label>, so not :first-of-type */
		h2 + &,
		.set-intro + & {
			border-top: 0;
		}
	}

	.set-label {
		display: flex;
		flex: 1 1 auto;
		flex-direction: column;
		min-width: 0;
		color: var(--text);

		small {
			color: var(--text-3);
			font-size: 12px;
		}
	}

	.set-value {
		color: var(--text-2);
		font-variant-numeric: tabular-nums;
		text-align: end;
	}

	.set-intro {
		margin: 0 0 6px;
	}

	.set-actions {
		display: flex;
		flex-wrap: wrap;
		gap: 8px;
		margin-top: 14px;
	}

	.set-confirm {
		margin-top: 16px;
		padding: 12px 14px;
		border-radius: var(--radius-inset);
		background: var(--line);
		box-shadow: var(--shadow-hairline);

		p {
			margin: 0;
			color: var(--text);
		}

		.set-actions {
			margin-top: 10px;
		}
	}

	/* ---------- Forced colours (Windows High Contrast) ----------
	   Backgrounds and shadows are replaced by system colours there: the switch would vanish
	   and the chosen segment look like the others. Both draw themselves with system colours. */

	@media (forced-colors: active) {

		.switch {
			box-sizing: border-box;
			border: 1px solid ButtonText;
			background: Canvas;
			forced-color-adjust: none;

			&::before {
				inset-block-start: 1px;
				inset-inline-start: 1px;
				background: ButtonText;
				box-shadow: none;
			}

			&:not(:checked),
			&:not(:checked)::before {
				box-shadow: none;
			}

			&:checked {
				border-color: Highlight;
				background: Highlight;
			}

			&:checked::before {
				background: HighlightText;
			}
		}

		.seg input:checked + span {
			background: Highlight;
			color: HighlightText;
			forced-color-adjust: none;
		}
	}
}

@layer compact {

	body.compact {

		.panel {
			padding: 20px;
			font-size: 15px;
		}

		.field {
			max-width: none;
			height: 36px;
		}

		/* 16px keeps iOS from zooming into the field */
		.field-input {
			font-size: 16px;
		}

		/* Only segments and swatches may drop below their label; switches stay at the end */
		.set-row:has(.seg, .swatches) {
			flex-wrap: wrap;
		}
	}
}
