﻿/*
	Fixes for FluentUI v5 that have to be global, so they cannot live in a component's scoped CSS. Link it from every app
	referencing this library, after the FluentUI bundle:
		<link rel="stylesheet" href="_content/RazorClassLibrary/fluentui-v5.css" />
*/

/*
	Chrome paints an autofilled input light blue with dark text, which on the dark theme reads as a white box inside the
	field. v4's text field hid it; in v5 the input is inside the web component's shadow root, where page CSS cannot reach
	except through the part it exposes. The background is set with an inset shadow because Chrome does not let a page
	override an autofilled input's background-color. Two rules, not one list: a selector the browser does not know
	would drop the whole list.
*/
fluent-text-input::part(control):-webkit-autofill {
	-webkit-text-fill-color: var(--colorNeutralForeground1);
	caret-color: var(--colorNeutralForeground1);
	-webkit-box-shadow: 0 0 0 1000px var(--colorNeutralBackground1) inset;
}

fluent-text-input::part(control):autofill {
	-webkit-text-fill-color: var(--colorNeutralForeground1);
	caret-color: var(--colorNeutralForeground1);
	box-shadow: 0 0 0 1000px var(--colorNeutralBackground1) inset;
}

/*
	THE v4 LOOK. FluentUI v4 computed its colours from a luminance algorithm; the values below are exactly what it produced
	for this app (default accent #0078d4, dark = luminance 0.15, light = 0.98), read from the v4 web components themselves.
	They do three jobs:
	  - define the v4 tokens this app's own CSS and inline styles still name (--neutral-foreground-rest, --accent-fill-rest,
	    ...), which v5 no longer sets, so every rule using them had silently stopped applying;
	  - put back v4's page background (its reboot.css painted the body with --neutral-fill-layer-rest: #333 dark, #fff light);
	  - restore the controls v5 redrew: stealth / lightweight buttons, accent icons, the accent avatar.
	v5 resolves data-theme="system" to "dark" or "light" on <body> once it starts; the media query covers the moment before.
*/
body {
	--neutral-fill-layer-rest: #ffffff;
	--neutral-layer-1: #fbfbfb;
	--neutral-layer-2: #f3f3f3;
	--neutral-layer-3: #ebebeb;
	--neutral-layer-4: #e0e0e0;
	--neutral-fill-rest: #ffffff;
	--neutral-fill-stealth-rest: #fbfbfb;
	--neutral-fill-stealth-hover: #efefef;
	--neutral-fill-stealth-active: #f3f3f3;
	--neutral-foreground-rest: #1a1a1a;
	--neutral-foreground-hint: #717171;
	--neutral-stroke-rest: #d6d6d6;
	--neutral-stroke-divider-rest: #ebebeb;
	--accent-fill-rest: #036ac4;
	--accent-fill-hover: #0473ce;
	--accent-fill-active: #0481e0;
	--accent-foreground-rest: #023b8f;
	--accent-foreground-hover: #012e7f;
	--foreground-on-accent-rest: #ffffff;
	--type-ramp-base-font-size: 14px;
	--type-ramp-base-line-height: 20px;
	--warning: #E9835E;
	--error: #BC2F32;
	--success: #0E700E;
	--info: #616161;
}

body[data-theme="dark"] {
	--neutral-fill-layer-rest: #333333;
	--neutral-layer-1: #272727;
	--neutral-layer-2: #1a1a1a;
	--neutral-layer-3: #0b0b0b;
	--neutral-layer-4: #000000;
	--neutral-fill-rest: #333333;
	--neutral-fill-stealth-rest: #272727;
	--neutral-fill-stealth-hover: #383838;
	--neutral-fill-stealth-active: #333333;
	--neutral-foreground-rest: #ffffff;
	--neutral-foreground-hint: #8e8e8e;
	--neutral-stroke-rest: #505050;
	--neutral-stroke-divider-rest: #3d3d3d;
	--accent-fill-rest: #60c9fc;
	--accent-fill-hover: #4fc0fc;
	--accent-fill-active: #34b0fb;
	--accent-foreground-rest: #82ddfd;
	--accent-foreground-hover: #9eecfd;
	--foreground-on-accent-rest: #000000;
}

@media (prefers-color-scheme: dark) {
	body[data-theme="system"] {
		--neutral-fill-layer-rest: #333333;
		--neutral-fill-stealth-rest: #272727;
		--neutral-foreground-rest: #ffffff;
		--accent-fill-rest: #60c9fc;
	}
}

body[data-theme] {
	background-color: var(--neutral-fill-layer-rest);
	color: var(--neutral-foreground-rest);
}

/*
	v4's stealth button (converted to v5's subtle): the layer colour at rest, a lighter fill on hover. And its lightweight
	button (converted to transparent): the same fill with the label in the accent colour. Page styles on the host outrank
	the component's own :host rules - including :host(:hover) - so every state is restated.
*/
fluent-button[appearance="subtle"],
fluent-anchor-button[appearance="subtle"],
fluent-button[appearance="transparent"],
fluent-anchor-button[appearance="transparent"] {
	background-color: var(--neutral-fill-stealth-rest);
}

fluent-button[appearance="subtle"]:hover,
fluent-anchor-button[appearance="subtle"]:hover,
fluent-button[appearance="transparent"]:hover,
fluent-anchor-button[appearance="transparent"]:hover {
	background-color: var(--neutral-fill-stealth-hover);
}

fluent-button[appearance="subtle"]:active,
fluent-anchor-button[appearance="subtle"]:active,
fluent-button[appearance="transparent"]:active,
fluent-anchor-button[appearance="transparent"]:active {
	background-color: var(--neutral-fill-stealth-active);
}

fluent-button[appearance="transparent"]:not([disabled]),
fluent-anchor-button[appearance="transparent"] {
	color: var(--accent-foreground-rest);
}

/*
	Icons: v4 drew every FluentIcon in the accent colour unless told otherwise; UseV4IconColours sets that default again (as
	v5's brand colour, so icons agree with the rest of v5's accents). A filled button is the exception - its icon takes the label's colour, as in v4 - and so
	is a disabled one, which must look disabled. The fill is an inline style, hence !important.
*/
fluent-button[appearance="primary"] svg,
fluent-anchor-button[appearance="primary"] svg,
fluent-button[disabled] svg {
	fill: currentColor !important;
}

/* BackButton: the arrow in the accent colour, on the stealth fill above */
fluent-anchor-button.app-back-button {
	color: var(--colorBrandForeground1);
}

/*
	v4's tab spacing. A v5 tab is padded 10px either side and 12px above and below, which spread every strip out and made
	it taller; v4's were 6px across and 32px tall. The padding is a custom property the tablist sets on itself, so a page
	rule on the host overrides it for every tab size (and the active indicator, which is inset by the same amount, follows).
*/
fluent-tablist {
	--tabPaddingInline: 6px;
	--tabPaddingBlock: 6px;
}

/*
	A dialog's actions stay one row of normal-sized buttons on the right, as in v4, at every width. Under 480px of body v5
	stacks them full width instead - twice over: the dialog body's own actions area turns into a stretching column, and the
	slotted row is forced to a column by an !important container query. That caught every dialog of about 530px or narrower,
	most of them here. The actions area is given the layout v5 itself uses for a wide dialog, and the body prefix and [fuib]
	outrank the container query.
*/
body fluent-dialog-body[fuib]::part(actions) {
	flex-direction: row;
	align-items: center;
	justify-content: flex-end;
}

body fluent-dialog-body[fuib] > div[slot="action"] {
	flex-direction: row !important;
	align-items: center;
	justify-content: flex-end;
}

/*
	Room for a focus outline round a field flush with the edge of a dialog's content. That area scrolls (overflow: auto),
	so it clips everything outside its box, and a focused v5 field draws a 2px outline just outside its own - an autofocused
	dropdown at the left edge, as in the transfer dialog, showed with that side cut off. The padding makes the room and the
	matching negative margin cancels it, so nothing inside moves.
*/
body fluent-dialog-body[fuib]::part(content) {
	padding: 4px;
	margin: -4px;
}

/* v4's profile persona: initials on the accent fill */
fluent-avatar.app-accent-avatar {
	background-color: var(--colorBrandForeground1);
	color: var(--foreground-on-accent-rest);
}

/*
	The grid's sticky header: v5 paints it near-black (--colorNeutralBackground4), v4 with the layer colour - the same as the
	stealth fill above, so its column buttons sit flush in it rather than reading as boxes. Prefixed with body because each
	app's scoped bundle @imports FluentUI's stylesheet again, after this file, so an equally specific rule would lose.
*/
body .fluent-data-grid tr[row-type=sticky-header] > th,
body .fluent-data-grid tr[row-type=sticky-header] > th[col-pinned=start],
body .fluent-data-grid tr[row-type=sticky-header] > th[col-pinned=end] {
	background-color: var(--neutral-layer-1);
}

/*
	A FluentSelect given a Width: v5 applies it to the field around the dropdown, but the dropdown's own control has a
	min-width of 160px set inside its shadow root, with no part or variable to change it. So a narrower Width left the field
	narrower than what it holds, and the dropdown spilled over whatever followed it (the grid toolbars' item count). The field
	now grows to what the dropdown needs, and the dropdown fills a field wider than that.
*/
fluent-field[style*="width"]:has(> fluent-dropdown) {
	min-width: min-content;
}

fluent-field[style*="width"] > fluent-dropdown {
	width: 100%;
}
