local _, GF = ...

GF.FRAME_W_LEGACY_DEFAULT = 1024
GF.FRAME_PREVIOUS_DEFAULT_W = 1120
GF.FRAME_PREVIOUS_NAV_DEFAULT_H = 550
-- 840px browse columns + 4px ColumnDisplay compensation + current panel/nav/scroll insets.
GF.FRAME_W = 1220
GF.FRAME_H = 597
GF.FRAME_MIN_W = GF.FRAME_W
GF.FRAME_MIN_H = GF.FRAME_H
GF.FRAME_FOOTER_LAYOUT_VERSION = 3
GF.FRAME_NAV_LAYOUT_VERSION = 2
GF.FRAME_PREVIOUS_DEFAULT_H = 552
GF.FRAME_LEGACY_PANEL_BOTTOM = 24
GF.FRAME_INTERIM_PANEL_BOTTOM = 44
GF.FRAME_INTERIM_DEFAULT_H = 560
GF.PANEL_SCALE_MIN_PCT = 100
GF.PANEL_SCALE_MAX_PCT = 150
GF.PANEL_SCALE_DEFAULT_PCT = 100
GF.FONT_SCALE_MIN_PCT = 100
GF.FONT_SCALE_MAX_PCT = 150
GF.FONT_SCALE_DEFAULT_PCT = 100
GF.LIST_BACKGROUND_ALPHA_MIN_PCT = 30
GF.LIST_BACKGROUND_ALPHA_MAX_PCT = 100
GF.LIST_BACKGROUND_ALPHA_DEFAULT_PCT = 100
GF.LIST_BACKGROUND_NORMAL_ALPHA_DEFAULT_PCT = 30
GF.DEFAULT_REQUIRED_ITEM_LEVEL_MIN = 0
GF.DEFAULT_REQUIRED_ITEM_LEVEL_DEFAULT = 0
GF.FRAME_PAD = 4
GF.FRAME_TITLE_TOP = 24
GF.FRAME_BODY_BOTTOM = 41
GF.FRAME_CONTENT_BOTTOM = GF.FRAME_BODY_BOTTOM + GF.FRAME_PAD
GF.MAIN_PANEL_INSET_LEFT = 26
GF.MAIN_PANEL_INSET_RIGHT = 26
GF.MAIN_PANEL_INSET_TOP = 64
GF.MAIN_PANEL_INSET_BOTTOM = 36
GF.MAIN_PANEL_BACKPLATE_BG_INSET_LEFT = 5
GF.MAIN_PANEL_BACKPLATE_BG_INSET_RIGHT = 5
GF.MAIN_PANEL_BACKPLATE_BG_INSET_TOP = 2
GF.MAIN_PANEL_BACKPLATE_BG_INSET_BOTTOM = 10
GF.MAIN_PANEL_BACKPLATE_BG_COLOR = { 0, 0, 0, 1 }
GF.PLAYER_CONTEXT_DIALOG_BACKGROUND_COLOR = { 0, 0, 0, 0.82 }
GF.MAIN_PANEL_DECORATIVE_BORDER_ATLAS = "transmog-tabs-frame"
GF.MAIN_PANEL_DECORATIVE_BACKGROUND_ATLAS = "transmog-tabs-frame-bg"
GF.MAIN_PANEL_DECORATIVE_BACKGROUND_INSET_LEFT = 15
GF.MAIN_PANEL_DECORATIVE_BACKGROUND_INSET_RIGHT = 15
GF.MAIN_PANEL_DECORATIVE_BACKGROUND_INSET_TOP = 16
GF.MAIN_PANEL_DECORATIVE_BACKGROUND_INSET_BOTTOM = 14
GF.MAIN_PANEL_DECORATIVE_BACKGROUND_ALPHA = 0.42
GF.MAIN_PANEL_CONTENT_PADDING_X = GF.MAIN_PANEL_BACKPLATE_BG_INSET_LEFT
GF.MAIN_PANEL_CONTENT_PADDING_TOP = GF.MAIN_PANEL_BACKPLATE_BG_INSET_TOP
GF.MAIN_PANEL_CONTENT_PADDING_BOTTOM = GF.MAIN_PANEL_BACKPLATE_BG_INSET_BOTTOM
GF.MAIN_PANEL_TAB_MIN_WIDTH = 95
GF.MAIN_PANEL_TAB_MAX_WIDTH = 170
GF.MAIN_PANEL_TAB_HEIGHT = 32
GF.MAIN_PANEL_TAB_GAP = 1
GF.MAIN_PANEL_TAB_SELECTED_FONT_OBJECT = "GameFontHighlight"
GF.MAIN_PANEL_TAB_UNSELECTED_FONT_OBJECT = "GameFontNormal"
GF.MAIN_PANEL_TAB_DISABLED_FONT_OBJECT = "GameFontDisable"
GF.MAIN_WINDOW_TITLE_OFFSET_Y = -6
GF.MAIN_WINDOW_DRAG_HANDLE_LEFT_INSET = 18
GF.MAIN_WINDOW_DRAG_HANDLE_RIGHT_INSET = 46
GF.MAIN_WINDOW_DRAG_HANDLE_TOP_OFFSET = 0
GF.MAIN_WINDOW_DRAG_HANDLE_BOTTOM_OFFSET = -40
GF.MAIN_WINDOW_ROLE_BUTTON_SIZE = 32
GF.MAIN_WINDOW_ROLE_BUTTON_GAP = 9
GF.MAIN_WINDOW_ROLE_BUTTON_RIGHT_INSET = 48
GF.MAIN_WINDOW_ROLE_BUTTON_CENTER_OFFSET = 46
GF.MAIN_WINDOW_ROLE_BUTTON_TOP_OFFSET = GF.MAIN_WINDOW_ROLE_BUTTON_CENTER_OFFSET - (GF.MAIN_WINDOW_ROLE_BUTTON_SIZE / 2)
GF.MAIN_WINDOW_EYE_SIZE = 44
GF.MAIN_WINDOW_EYE_HOST_SIZE = 68
GF.MAIN_WINDOW_EYE_BACKGROUND_SIZE = 54
GF.MAIN_WINDOW_EYE_BACKGROUND_MASK = "Interface\\CharacterFrame\\TempPortraitAlphaMask"
GF.ADDON_LOGO_TEXTURE = "Interface\\AddOns\\GroupFinder\\Art\\Logo\\GroupFinderIcon.png"
GF.ADDON_MENU_LOGO_TEXTURE = "Interface\\AddOns\\GroupFinder\\Art\\Logo\\GroupFinder.png"
GF.ADDON_ART_UI_PATH = "Interface\\AddOns\\GroupFinder\\Art\\UI\\"
GF.ADDON_ART_ICON_PATH = GF.ADDON_ART_UI_PATH .. "Icon\\"
GF.ADDON_SOUNDS_PATH = "Interface\\AddOns\\GroupFinder\\Sounds\\"
GF.COMMON_ATLAS_TEXTURE = GF.ADDON_ART_UI_PATH .. "Common.png"
GF.COMMON_ATLAS_WIDTH = 512
GF.COMMON_ATLAS_HEIGHT = 167
GF.COMMON_ATLAS_REGIONS = {
	addonButtons = { 0, 0, 128, 64 },
	filterCheck = { 129, 0, 124, 62 },
	closeButtonNormal = { 254, 0, 41, 41 },
	closeButtonHighlighted = { 296, 0, 41, 41 },
	closeButtonPressed = { 338, 0, 41, 41 },
	closeButtonDisabled = { 380, 0, 41, 41 },
	-- 新关于图标的 14×32px 有效像素逆时针旋转后位于该区中央；
	-- 周围透明留白把按钮内可见高度校准为与黄色 X 相同的约 14px。
	titleAboutGlyph = { 422, 0, 46, 20 },
	closeButtonGlyph = { 469, 0, 26, 26 },
	sliderTrack = { 422, 27, 54, 25 },
	sliderBackNormal = { 477, 27, 25, 25 },
	sliderBackHighlighted = { 254, 42, 25, 25 },
	sliderBackPressed = { 280, 42, 25, 25 },
	sliderBackDisabled = { 306, 42, 25, 25 },
	sliderForwardNormal = { 332, 42, 25, 25 },
	sliderForwardHighlighted = { 358, 42, 25, 25 },
	sliderForwardPressed = { 384, 42, 25, 25 },
	redButtonNormal = { 0, 68, 176, 48 },
	redButtonHighlighted = { 177, 68, 176, 48 },
	redButtonSquareNormal = { 354, 68, 48, 48 },
	redButtonSquareHighlighted = { 403, 68, 48, 48 },
	redButtonSquarePressed = { 452, 68, 48, 48 },
	redButtonPressed = { 0, 117, 176, 48 },
	refresh = { 177, 117, 49, 49 },
	sliderThumbNormal = { 227, 117, 36, 36 },
	sliderThumbHighlighted = { 264, 117, 36, 36 },
	sliderThumbPressed = { 301, 117, 36, 36 },
	sliderThumbDisabled = { 338, 117, 36, 36 },
	sliderForwardDisabled = { 375, 117, 25, 25 },
}
local function commonAtlasTexCoord(region, inset)
	region = region or { 0, 0, 1, 1 }
	inset = tonumber(inset) or 0
	return {
		(region[1] + inset) / GF.COMMON_ATLAS_WIDTH,
		(region[1] + region[3] - inset) / GF.COMMON_ATLAS_WIDTH,
		(region[2] + inset) / GF.COMMON_ATLAS_HEIGHT,
		(region[2] + region[4] - inset) / GF.COMMON_ATLAS_HEIGHT,
	}
end
GF.FOOTER_ACTION_BUTTON_SIZE = 35
GF.FOOTER_ACTION_BUTTON_GAP = 0
GF.FOOTER_ACTION_BUTTON_NORMAL_ATLAS = "ui-journeys-greatvault-button"
GF.FOOTER_ACTION_BUTTON_PRESSED_ATLAS =
	"ui-journeys-greatvault-button-pressed"
GF.FOOTER_ACTION_BORDER_TEXTURE =
	GF.ADDON_ART_UI_PATH .. "ApertureBorder.png"
GF.FOOTER_ACTION_BORDER_SIZE = 37
GF.FOOTER_ACTION_BORDER_COLUMNS = 5
GF.FOOTER_ACTION_BORDER_ROWS = 6
GF.GREAT_VAULT_BUTTON_SIZE = GF.FOOTER_ACTION_BUTTON_SIZE
GF.GREAT_VAULT_BUTTON_NORMAL_ATLAS =
	GF.FOOTER_ACTION_BUTTON_NORMAL_ATLAS
GF.GREAT_VAULT_BUTTON_PRESSED_ATLAS =
	GF.FOOTER_ACTION_BUTTON_PRESSED_ATLAS
GF.GREAT_VAULT_READY_BORDER_TEXTURE =
	GF.FOOTER_ACTION_BORDER_TEXTURE
GF.GREAT_VAULT_READY_BORDER_SIZE = GF.FOOTER_ACTION_BORDER_SIZE
GF.GREAT_VAULT_READY_BORDER_COLUMNS = GF.FOOTER_ACTION_BORDER_COLUMNS
GF.GREAT_VAULT_READY_BORDER_ROWS = GF.FOOTER_ACTION_BORDER_ROWS
GF.GREAT_VAULT_READY_BORDER_FPS = 24
GF.KEYSTONE_LOOT_ADDON_NAME = "KeystoneLoot"
GF.KEYSTONE_LOOT_BUTTON_SIZE = GF.GREAT_VAULT_BUTTON_SIZE
GF.KEYSTONE_LOOT_BUTTON_GAP = GF.FOOTER_ACTION_BUTTON_GAP
GF.KEYSTONE_LOOT_BUTTON_ATLAS_TEXTURE =
	GF.COMMON_ATLAS_TEXTURE
GF.KEYSTONE_LOOT_BUTTON_ICON_TEXTURE =
	GF.ADDON_ART_ICON_PATH .. "Gear.png"
local KEYSTONE_LOOT_BUTTON_REGION = GF.COMMON_ATLAS_REGIONS.addonButtons
GF.KEYSTONE_LOOT_BUTTON_NORMAL_TEXCOORD = {
	(KEYSTONE_LOOT_BUTTON_REGION[1] + 0.5) / GF.COMMON_ATLAS_WIDTH,
	(KEYSTONE_LOOT_BUTTON_REGION[1] + 64 - 0.5) / GF.COMMON_ATLAS_WIDTH,
	(KEYSTONE_LOOT_BUTTON_REGION[2] + 0.5) / GF.COMMON_ATLAS_HEIGHT,
	(KEYSTONE_LOOT_BUTTON_REGION[2] + 64 - 0.5) / GF.COMMON_ATLAS_HEIGHT,
}
GF.KEYSTONE_LOOT_BUTTON_PRESSED_TEXCOORD = {
	(KEYSTONE_LOOT_BUTTON_REGION[1] + 64 + 0.5) / GF.COMMON_ATLAS_WIDTH,
	(KEYSTONE_LOOT_BUTTON_REGION[1] + 128 - 0.5) / GF.COMMON_ATLAS_WIDTH,
	(KEYSTONE_LOOT_BUTTON_REGION[2] + 0.5) / GF.COMMON_ATLAS_HEIGHT,
	(KEYSTONE_LOOT_BUTTON_REGION[2] + 64 - 0.5) / GF.COMMON_ATLAS_HEIGHT,
}
GF.KEYSTONE_LOOT_BUTTON_VISUAL_SIZE = 30
GF.KEYSTONE_LOOT_BUTTON_VISUAL_OFFSET_X = 0
GF.KEYSTONE_LOOT_BUTTON_VISUAL_OFFSET_Y = 0
GF.KEYSTONE_LOOT_BUTTON_ICON_SIZE = 17
GF.KEYSTONE_LOOT_BUTTON_ICON_OFFSET_X = -0.5
GF.KEYSTONE_LOOT_BUTTON_ICON_OFFSET_Y = 0.5
GF.KEYSTONE_LOOT_BUTTON_PRESSED_ICON_OFFSET_X = 0.5
GF.KEYSTONE_LOOT_BUTTON_PRESSED_ICON_OFFSET_Y = -0.5
GF.KEYSTONE_LOOT_BUTTON_DISABLED_ALPHA = 0.45
GF.TITLE_ACTION_BUTTON_GAP = 2
GF.VERSION_DISCOVERY_BADGE_ATLAS = "communities-icon-notification"
GF.VERSION_DISCOVERY_BADGE_SIZE = 11
GF.TITLE_ABOUT_BUTTON_ICON_TEXTURE = GF.COMMON_ATLAS_TEXTURE
local TITLE_ABOUT_BUTTON_ICON_REGION = GF.COMMON_ATLAS_REGIONS.titleAboutGlyph
local TITLE_ABOUT_BUTTON_ICON_LEFT =
	TITLE_ABOUT_BUTTON_ICON_REGION[1] / GF.COMMON_ATLAS_WIDTH
local TITLE_ABOUT_BUTTON_ICON_RIGHT =
	(TITLE_ABOUT_BUTTON_ICON_REGION[1] + TITLE_ABOUT_BUTTON_ICON_REGION[3])
	/ GF.COMMON_ATLAS_WIDTH
local TITLE_ABOUT_BUTTON_ICON_TOP =
	TITLE_ABOUT_BUTTON_ICON_REGION[2] / GF.COMMON_ATLAS_HEIGHT
local TITLE_ABOUT_BUTTON_ICON_BOTTOM =
	(TITLE_ABOUT_BUTTON_ICON_REGION[2] + TITLE_ABOUT_BUTTON_ICON_REGION[4])
	/ GF.COMMON_ATLAS_HEIGHT
-- 图集中保存的是原图有效像素逆时针旋转后的横向切片，实际像素位于
-- [429,3,32,14]，外层透明区负责尺寸校准。八点 UV 以左上、左下、
-- 右上、右下顺序把它还原为玩家提供的竖向图标。
GF.TITLE_ABOUT_BUTTON_ICON_TEXCOORD = {
	TITLE_ABOUT_BUTTON_ICON_LEFT, TITLE_ABOUT_BUTTON_ICON_BOTTOM,
	TITLE_ABOUT_BUTTON_ICON_RIGHT, TITLE_ABOUT_BUTTON_ICON_BOTTOM,
	TITLE_ABOUT_BUTTON_ICON_LEFT, TITLE_ABOUT_BUTTON_ICON_TOP,
	TITLE_ABOUT_BUTTON_ICON_RIGHT, TITLE_ABOUT_BUTTON_ICON_TOP,
}
-- 原 32×32px 画布按 20px 高显示；有效像素宽 14px，保持源纵横比。
GF.TITLE_ABOUT_BUTTON_ICON_WIDTH = 20 * 14 / 32
GF.TITLE_ABOUT_BUTTON_ICON_HEIGHT = 20
GF.WHITE_TEXTURE = "Interface\\Buttons\\WHITE8X8"
GF.BUTTON_VISUAL_STATE = {
	NORMAL = "normal",
	HOVER = "hover",
	PRESSED = "pressed",
	DISABLED = "disabled",
}
GF.COMMON_BUTTON_TEXTURE = GF.COMMON_ATLAS_TEXTURE
GF.COMMON_BUTTON_ATLAS_WIDTH = GF.COMMON_ATLAS_WIDTH
GF.COMMON_BUTTON_ATLAS_HEIGHT = GF.COMMON_ATLAS_HEIGHT
GF.COMMON_TITLE_BUTTON_TEXTURE = GF.COMMON_ATLAS_TEXTURE
GF.COMMON_TITLE_BUTTON_BACKGROUND_REGIONS = {
	normal = GF.COMMON_ATLAS_REGIONS.closeButtonNormal,
	hover = GF.COMMON_ATLAS_REGIONS.closeButtonHighlighted,
	pressed = GF.COMMON_ATLAS_REGIONS.closeButtonPressed,
	disabled = GF.COMMON_ATLAS_REGIONS.closeButtonDisabled,
}
GF.COMMON_TITLE_BUTTON_CLOSE_GLYPH_REGION =
	GF.COMMON_ATLAS_REGIONS.closeButtonGlyph
GF.COMMON_TITLE_BUTTON_VISUAL_SIZE = 22
-- X 的 26px 源区约有 24px alpha 可见区；0.632 对应约 14px 可见尺寸。
GF.COMMON_TITLE_BUTTON_CLOSE_GLYPH_SCALE = 0.632
-- 源素材的 alpha 重心约低于画布中心 1.5px，绘制后向右/上微调。
GF.COMMON_TITLE_BUTTON_CLOSE_GLYPH_OFFSET_X = 0.1
GF.COMMON_TITLE_BUTTON_CLOSE_GLYPH_OFFSET_Y = 0.9
GF.COMMON_TITLE_BUTTON_PRESSED_OFFSET_X = 1
GF.COMMON_TITLE_BUTTON_PRESSED_OFFSET_Y = -1
GF.COMMON_TITLE_BUTTON_DISABLED_GLYPH_ALPHA = 0.5
GF.COMMON_TITLE_BUTTON_HOVER_GLOW_ALPHA = 0.4
GF.COMMON_TITLE_BUTTON_CLOSE_HOVER_GLOW_ALPHA =
	GF.COMMON_TITLE_BUTTON_HOVER_GLOW_ALPHA
GF.COMMON_TITLE_BUTTON_CLOSE_HOVER_GLOW_SCALE = 1
GF.COMMON_TITLE_BUTTON_CLOSE_HOVER_GLOW_DESATURATED = true
GF.COMMON_BUTTON_WIDE_REGIONS = {
	normal = GF.COMMON_ATLAS_REGIONS.redButtonNormal,
	highlight = GF.COMMON_ATLAS_REGIONS.redButtonHighlighted,
	pressed = GF.COMMON_ATLAS_REGIONS.redButtonPressed,
}
GF.COMMON_BUTTON_SQUARE_REGIONS = {
	normal = GF.COMMON_ATLAS_REGIONS.redButtonSquareNormal,
	highlight = GF.COMMON_ATLAS_REGIONS.redButtonSquareHighlighted,
	pressed = GF.COMMON_ATLAS_REGIONS.redButtonSquarePressed,
}
GF.COMMON_BUTTON_VISUALS = {
	normal = {
		atlasState = "normal",
		textColor = { 1, 0.82, 0, 1 },
		textureColor = { 1, 1, 1, 1 },
		iconColor = { 1, 1, 1, 1 },
		textOffset = { 0, 0 },
		desaturated = false,
	},
	hover = {
		atlasState = "highlight",
		textColor = { 1, 0.95, 0.45, 1 },
		textureColor = { 1, 1, 1, 1 },
		iconColor = { 1, 0.96, 0.58, 1 },
		textOffset = { 0, 0 },
		desaturated = false,
	},
	pressed = {
		atlasState = "pressed",
		textColor = { 1, 0.68, 0.12, 1 },
		textureColor = { 1, 1, 1, 1 },
		iconColor = { 1, 1, 1, 1 },
		textOffset = { 1, -1 },
		desaturated = false,
	},
	disabled = {
		atlasState = "normal",
		textColor = { 0.55, 0.55, 0.55, 1 },
		textureColor = { 0.55, 0.55, 0.55, 0.82 },
		iconColor = { 1, 1, 1, 0.45 },
		textOffset = { 0, 0 },
		desaturated = true,
	},
}
GF.CONTROL_FRAME_ATLAS_STATES = {
	normal = "house-chest-list-Item-pressed",
	hover = "house-chest-list-Item-active",
	focus = "house-chest-list-Item-active",
	checked = "house-chest-list-Item-active",
	highlighted = "house-chest-list-Item-active",
}
-- Small square controls and input fields use the local two-state texture.
-- Each raw 64px state cell contains a weak antialiased fringe around the
-- visible outline. Sampling that fringe while minifying to 16-30px can skip
-- the one-pixel normal-state side border entirely, so every local renderer
-- starts from the same measured visible-content rectangle.
GF.FILTER_CHECK_ATLAS_TEXTURE =
	GF.COMMON_ATLAS_TEXTURE
GF.FILTER_CHECK_ATLAS_WIDTH = GF.COMMON_ATLAS_WIDTH
GF.FILTER_CHECK_ATLAS_HEIGHT = GF.COMMON_ATLAS_HEIGHT
GF.FILTER_CHECK_ATLAS_ORIGIN_X = GF.COMMON_ATLAS_REGIONS.filterCheck[1]
GF.FILTER_CHECK_ATLAS_ORIGIN_Y = GF.COMMON_ATLAS_REGIONS.filterCheck[2]
GF.FILTER_CHECK_ATLAS_CELL_WIDTH = 62
GF.FILTER_CHECK_ATLAS_CELL_HEIGHT = 62
GF.FILTER_CHECK_ATLAS_CONTENT_INSETS = {
	left = 0,
	top = 0,
	right = 1,
	bottom = 0,
}
GF.FILTER_CHECK_ATLAS_CONTENT_WIDTH =
	GF.FILTER_CHECK_ATLAS_CELL_WIDTH
	- GF.FILTER_CHECK_ATLAS_CONTENT_INSETS.left
	- GF.FILTER_CHECK_ATLAS_CONTENT_INSETS.right
GF.FILTER_CHECK_ATLAS_CONTENT_HEIGHT =
	GF.FILTER_CHECK_ATLAS_CELL_HEIGHT
	- GF.FILTER_CHECK_ATLAS_CONTENT_INSETS.top
	- GF.FILTER_CHECK_ATLAS_CONTENT_INSETS.bottom
GF.FILTER_CHECK_ATLAS_REGIONS = {
	highlighted = {
		GF.FILTER_CHECK_ATLAS_ORIGIN_X
			+ GF.FILTER_CHECK_ATLAS_CONTENT_INSETS.left,
		GF.FILTER_CHECK_ATLAS_ORIGIN_Y
			+ GF.FILTER_CHECK_ATLAS_CONTENT_INSETS.top,
		GF.FILTER_CHECK_ATLAS_CONTENT_WIDTH,
		GF.FILTER_CHECK_ATLAS_CONTENT_HEIGHT,
	},
	normal = {
		GF.FILTER_CHECK_ATLAS_ORIGIN_X
			+ GF.FILTER_CHECK_ATLAS_CELL_WIDTH
			+ GF.FILTER_CHECK_ATLAS_CONTENT_INSETS.left,
		GF.FILTER_CHECK_ATLAS_ORIGIN_Y
			+ GF.FILTER_CHECK_ATLAS_CONTENT_INSETS.top,
		GF.FILTER_CHECK_ATLAS_CONTENT_WIDTH,
		GF.FILTER_CHECK_ATLAS_CONTENT_HEIGHT,
	},
}
GF.FILTER_CHECK_ATLAS_STATES = {
	normal = "normal",
	hover = "highlighted",
	focus = "highlighted",
	checked = "highlighted",
	highlighted = "highlighted",
}
GF.FILTER_INPUT_ATLAS_STATES = GF.FILTER_CHECK_ATLAS_STATES
GF.COMPACT_CONTROL_ATLAS_STATES = GF.FILTER_CHECK_ATLAS_STATES
GF.FILTER_CHECK_ATLAS_COORDS = {
	highlighted = {
		(GF.FILTER_CHECK_ATLAS_ORIGIN_X
			+ GF.FILTER_CHECK_ATLAS_CONTENT_INSETS.left)
			/ GF.FILTER_CHECK_ATLAS_WIDTH,
		(GF.FILTER_CHECK_ATLAS_ORIGIN_X
			+ GF.FILTER_CHECK_ATLAS_CELL_WIDTH
			- GF.FILTER_CHECK_ATLAS_CONTENT_INSETS.right)
			/ GF.FILTER_CHECK_ATLAS_WIDTH,
		(GF.FILTER_CHECK_ATLAS_ORIGIN_Y
			+ GF.FILTER_CHECK_ATLAS_CONTENT_INSETS.top)
			/ GF.FILTER_CHECK_ATLAS_HEIGHT,
		(GF.FILTER_CHECK_ATLAS_ORIGIN_Y
			+ GF.FILTER_CHECK_ATLAS_CELL_HEIGHT
			- GF.FILTER_CHECK_ATLAS_CONTENT_INSETS.bottom)
			/ GF.FILTER_CHECK_ATLAS_HEIGHT,
	},
	normal = {
		(GF.FILTER_CHECK_ATLAS_ORIGIN_X
			+ GF.FILTER_CHECK_ATLAS_CELL_WIDTH
			+ GF.FILTER_CHECK_ATLAS_CONTENT_INSETS.left)
			/ GF.FILTER_CHECK_ATLAS_WIDTH,
		(GF.FILTER_CHECK_ATLAS_ORIGIN_X
			+ (GF.FILTER_CHECK_ATLAS_CELL_WIDTH * 2)
			- GF.FILTER_CHECK_ATLAS_CONTENT_INSETS.right)
			/ GF.FILTER_CHECK_ATLAS_WIDTH,
		(GF.FILTER_CHECK_ATLAS_ORIGIN_Y
			+ GF.FILTER_CHECK_ATLAS_CONTENT_INSETS.top)
			/ GF.FILTER_CHECK_ATLAS_HEIGHT,
		(GF.FILTER_CHECK_ATLAS_ORIGIN_Y
			+ GF.FILTER_CHECK_ATLAS_CELL_HEIGHT
			- GF.FILTER_CHECK_ATLAS_CONTENT_INSETS.bottom)
			/ GF.FILTER_CHECK_ATLAS_HEIGHT,
	},
}
GF.FILTER_INPUT_SLICE_RATIOS = { 0.45, 0.55 }
GF.FILTER_INPUT_CAP_W = 9
GF.FILTER_NUMBER_INPUT_CAP_W = GF.FILTER_INPUT_CAP_W
-- Source ratios preserve the current effective 16px cap proportions without
-- depending on a particular atlas file size or resolution scale.
GF.CONTROL_FRAME_SLICE_RATIOS = {
	normal = {
		left = 16 / 104,
		right = 1 - (16 / 104),
		top = 16 / 108,
		bottom = 1 - (16 / 108),
	},
	highlighted = {
		left = 16 / 108,
		right = 1 - (16 / 108),
		top = 16 / 108,
		bottom = 1 - (16 / 108),
	},
}
GF.CONTROL_FRAME_DISPLAY_MARGIN = 8
GF.FILTER_MULTILINE_INPUT_SOURCE_MARGIN = 16
GF.FILTER_MULTILINE_INPUT_DISPLAY_MARGIN = 8
GF.FILTER_MULTILINE_INPUT_SLICE_RATIOS = {
	-- 合图前的 64px 单元从 16px 分割；打包时已物理删除左/上 1px 外圈。
	left = 15 / 61,
	right = 47 / 61,
	top = 15 / 62,
	bottom = 47 / 62,
}
GF.FILTER_CHECK_ATLAS_DISPLAY_MARGIN =
	GF.FILTER_MULTILINE_INPUT_DISPLAY_MARGIN
GF.FILTER_CHECK_ATLAS_SLICE_RATIOS =
	GF.FILTER_MULTILINE_INPUT_SLICE_RATIOS
GF.COMPACT_CONTROL_SLICE_RATIOS =
	GF.FILTER_MULTILINE_INPUT_SLICE_RATIOS
GF.INFO_ATLAS_TEXTURE = GF.ADDON_ART_UI_PATH .. "InfoAtlas.png"
GF.INFO_ATLAS_WIDTH = 1697
GF.INFO_ATLAS_HEIGHT = 696
GF.INFO_ATLAS_REGIONS = {
	title = { 4, 4, 1689, 348 },
	notice = { 4, 368, 1507, 324 },
}
GF.MYTHIC_PLUS_FRAME_ATLAS_TEXTURE = GF.ADDON_ART_UI_PATH .. "FrameAtlas.png"
GF.MYTHIC_PLUS_FRAME_ATLAS_WIDTH = 704
GF.MYTHIC_PLUS_FRAME_ATLAS_HEIGHT = 712
GF.MYTHIC_PLUS_FRAME_ATLAS_REGIONS = {
	dark = { 4, 4, 344, 200 },
	brown = { 356, 4, 344, 200 },
	class = { 4, 212, 344, 200 },
	border = { 356, 212, 344, 200 },
	hover = { 4, 420, 344, 200 },
	roleMask = { 4, 628, 695, 80 },
}
GF.REFRESH_TEXTURE = GF.COMMON_ATLAS_TEXTURE
GF.REFRESH_TEXTURE_TEXCOORD = commonAtlasTexCoord(
	GF.COMMON_ATLAS_REGIONS.refresh)
GF.TEAMUP_ATLASES = {
	"plunderstorm-glues-queueselector-solo-selected",
	"plunderstorm-glues-queueselector-duo-selected",
	"plunderstorm-glues-queueselector-trio-selected",
}
GF.TEAMUP_INLINE_ATLASES = {
	applicant = GF.TEAMUP_ATLASES[1],
	group = GF.TEAMUP_ATLASES[3],
}
GF.SETTINGS_SLIDER_TEXTURE = GF.COMMON_ATLAS_TEXTURE
GF.SETTINGS_SLIDER_TRACK_REGION =
	GF.COMMON_ATLAS_REGIONS.sliderTrack
GF.SETTINGS_SLIDER_THUMB_REGIONS = {
	normal = GF.COMMON_ATLAS_REGIONS.sliderThumbNormal,
	highlighted = GF.COMMON_ATLAS_REGIONS.sliderThumbHighlighted,
	pressed = GF.COMMON_ATLAS_REGIONS.sliderThumbPressed,
	disabled = GF.COMMON_ATLAS_REGIONS.sliderThumbDisabled,
}
GF.SETTINGS_SLIDER_BACK_REGIONS = {
	normal = GF.COMMON_ATLAS_REGIONS.sliderBackNormal,
	highlighted = GF.COMMON_ATLAS_REGIONS.sliderBackHighlighted,
	pressed = GF.COMMON_ATLAS_REGIONS.sliderBackPressed,
	disabled = GF.COMMON_ATLAS_REGIONS.sliderBackDisabled,
}
GF.SETTINGS_SLIDER_FORWARD_REGIONS = {
	normal = GF.COMMON_ATLAS_REGIONS.sliderForwardNormal,
	highlighted = GF.COMMON_ATLAS_REGIONS.sliderForwardHighlighted,
	pressed = GF.COMMON_ATLAS_REGIONS.sliderForwardPressed,
	disabled = GF.COMMON_ATLAS_REGIONS.sliderForwardDisabled,
}
GF.SETTINGS_SLIDER_TRACK_SOURCE_CAP_W = 15
GF.SETTINGS_SLIDER_TRACK_DISPLAY_CAP_W = 10
GF.SETTINGS_SLIDER_TRACK_DISPLAY_H = 16
GF.SETTINGS_SLIDER_THUMB_SIZE = 16
GF.SETTINGS_SLIDER_STEPPER_SIZE = 16
GF.SETTINGS_SLIDER_STEPPER_GAP = 4
GF.COMMON_SCROLLBAR_STEPPER_TEXTURE = GF.COMMON_ATLAS_TEXTURE
GF.COMMON_SCROLLBAR_BACK_REGIONS = GF.SETTINGS_SLIDER_BACK_REGIONS
GF.COMMON_SCROLLBAR_FORWARD_REGIONS = GF.SETTINGS_SLIDER_FORWARD_REGIONS
GF.COMMON_SCROLLBAR_STEPPER_SIZE = 16
GF.COMMON_SCROLLBAR_STEPPER_ROTATION = math.pi * 1.5
GF.COMMON_SCROLLBAR_STEPPER_FADE_DURATION = 0.18
GF.FLOATING_TEXTURE = GF.ADDON_ART_UI_PATH .. "Floating.png"
GF.FLOATING_ATLAS_WIDTH = 1920
GF.FLOATING_ATLAS_HEIGHT = 1200
GF.FLOATING_ATLAS_COLUMNS = 6
GF.FLOATING_ATLAS_ROWS = 15
GF.FLOATING_ATLAS_CELL_WIDTH = 320
GF.FLOATING_ATLAS_CELL_HEIGHT = 80
GF.BLACKLIST_ICON_TEXTURE = GF.ADDON_ART_ICON_PATH .. "Blacklist.png"
GF.LEAVER_ICON_TEXTURE = GF.ADDON_ART_ICON_PATH .. "isLeaver.png"
GF.CENSORED_RESULT_ICON_TEXTURE = GF.ADDON_ART_ICON_PATH .. "Censored.png"
GF.CENSORED_RESULT_REVEAL_COLOR = {
	r = 233 / 255,
	g = 213 / 255,
	b = 255 / 255,
}
GF.CENSORED_RESULT_TEXT_COLOR = {
	r = 216 / 255,
	g = 180 / 255,
	b = 254 / 255,
}
GF.CENSORED_RESULT_COMMENT_COLOR = {
	r = 167 / 255,
	g = 139 / 255,
	b = 189 / 255,
}
GF.MYTHIC_PLUS_TELEPORT_ICON_ATLAS = "MagePortalAlliance"
GF.MYTHIC_PLUS_ACTION_BUTTON_HEIGHT = 26
GF.MYTHIC_PLUS_SCORE_COLOR_RULE = {
	OVERALL = "overall",
	SINGLE_DUNGEON = "single_dungeon",
}
GF.MYTHIC_PLUS_SEASON_DUNGEON_SORT_RULE = {
	scoreDirection = "DESC",
	missingScore = 0,
	orderDirection = "ASC",
	orderFields = {
		"seasonMapOrder",
		"orderIndex",
		"sourceOrder",
	},
	preserveInputOrder = true,
}
GF.MYTHIC_PLUS_WORKSPACE_SCROLLBAR_WIDTH = 17
GF.MYTHIC_PLUS_WORKSPACE_SCROLLBAR_OFFSET_X = 17
GF.MYTHIC_PLUS_WORKSPACE_SCROLLBAR_TOP_OFFSET = -4
GF.MYTHIC_PLUS_WORKSPACE_SCROLLBAR_BOTTOM_OFFSET = 4
GF.TOP_NOTICE_TOAST_ATLAS = "evergreen-scenario-TitleBG"
GF.TOP_NOTICE_TOAST_SOUND = GF.ADDON_SOUNDS_PATH .. "Glass.aiff"
-- 兼容现有进组通报入口；共享视觉与声音由 TopNoticeToast 所有。
GF.JOIN_ANNOUNCE_TOAST_ATLAS = GF.TOP_NOTICE_TOAST_ATLAS
GF.JOIN_ANNOUNCE_TOAST_SOUND = GF.TOP_NOTICE_TOAST_SOUND
GF.APPLICANT_ALERT_SOUND_COOLDOWN_SECONDS = 10
GF.APPLICANT_ALERT_SOUND_LEGACY_DEFAULT = "Glass.aiff"
GF.APPLICANT_ALERT_SOUND_DEFAULT = "xalatath.mp3"
GF.APPLICANT_ALERT_SOUND_OPTIONS = {
	{ file = "xalatath.mp3", labelKey = "SET_APPLICANT_ALERT_SOUND_XALATATH", label = "萨拉塔斯" },
	{ file = "millhouse.mp3", labelKey = "SET_APPLICANT_ALERT_SOUND_MILLHOUSE", label = "米尔豪斯" },
	{ file = "murloc.ogg", labelKey = "SET_APPLICANT_ALERT_SOUND_AIYURAS", label = "艾鱼拉斯" },
	{ file = "sylvanas.mp3", labelKey = "SET_APPLICANT_ALERT_SOUND_SYLVANAS", label = "希尔瓦娜斯" },
	{ file = "Glass.aiff", labelKey = "SET_APPLICANT_ALERT_SOUND_GLASS", label = "清脆玻璃提示音" },
	{ file = "", labelKey = "SET_APPLICANT_ALERT_SOUND_OFF", label = "关闭" },
}
GF.ROLE_VACANCY_THRESHOLD_MIN = 1
GF.ROLE_VACANCY_THRESHOLD_MAX = 4
-- 聊天消息格式与输出逻辑见 ChatMessages.lua。
GF.MAIN_WINDOW_LOGO_TEXTURE = GF.ADDON_LOGO_TEXTURE
GF.MAIN_WINDOW_LOGO_SIZE = 54
GF.MINIMAP_ICON_TEXTURE = GF.ADDON_LOGO_TEXTURE
GF.ROLE_ICON_ATLAS = {
	LEADER = "UI-LFG-RoleIcon-Leader",
	GUIDE = "UI-LFG-RoleIcon-Leader",
	TANK = "UI-LFG-RoleIcon-Tank",
	HEALER = "UI-LFG-RoleIcon-Healer",
	DAMAGER = "UI-LFG-RoleIcon-DPS",
	DPS = "UI-LFG-RoleIcon-DPS",
	NONE = "groupfinder-icon-emptyslot",
	DEFAULT = "groupfinder-icon-emptyslot",
}
GF.SEASON_DUNGEON_ROLE_ATLAS = GF.ROLE_ICON_ATLAS
GF.LEADER_ICON_ATLAS = GF.ROLE_ICON_ATLAS.LEADER
GF.TOOLTIP_LEADER_ICON_ATLAS = GF.LEADER_ICON_ATLAS
GF.ROLE_ICON_SIZE = 18
GF.TOOLTIP_ROLE_ICON_SIZE = GF.ROLE_ICON_SIZE
GF.NON_ROLE_ICON_SIZE = 18
GF.MPLUS_BROWSE_PROJECTION_SLOT_SIZE = 20
-- Blizzard role atlases include about 1px of transparent edge padding. A
-- 20px draw box yields a visible 18px disc, matching the specialization icon
-- together with its full class-colored outer ring.
GF.MPLUS_BROWSE_ROLE_PROJECTION_ICON_SIZE = 20
GF.MPLUS_BROWSE_SPEC_PROJECTION_ICON_SIZE = 18
GF.MPLUS_BROWSE_SPEC_PROJECTION_ICON_INSET = 2.25
GF.MPLUS_BROWSE_PROJECTION_START_GAP = 5
GF.MPLUS_BROWSE_PROJECTION_ICON_GAP = 1
GF.MPLUS_BROWSE_MATCH_LABEL_W = 24
GF.MPLUS_BROWSE_MATCH_LABEL_FIT_W = 23
GF.MPLUS_BROWSE_FILTER_LABEL_TEXT_SIZE = 12
GF.MPLUS_BROWSE_MATCH_LABEL_MIN_FONT_SIZE = 8
GF.MPLUS_BROWSE_MATCH_CHECK_W = 16
GF.MPLUS_BROWSE_MATCH_CHECK_H = 16
GF.MPLUS_BROWSE_MATCH_CHECK_LABEL_GAP = 4
-- The keybind atlas is optically shifted 1.5px right inside its logical slot.
-- Half of that shift recenters the full visible checkbox-to-icons group.
GF.MPLUS_BROWSE_MATCH_ROW_VISUAL_OFFSET_X = -0.75
GF.MPLUS_BROWSE_MATCH_CHECK_ATLAS_OFFSET_X = 1.5
GF.MPLUS_BROWSE_MATCH_CHECK_ATLAS_OFFSET_Y = 0
GF.MPLUS_BROWSE_MATCH_CHECK_MARK_OFFSET_X = 1.5
GF.MPLUS_BROWSE_MATCH_CHECK_MARK_OFFSET_Y = 0
GF.MPLUS_BROWSE_MATCH_CHECK_ATLAS = {
	normal = "keybind-bg",
	hover = "keybind-bg_active",
	checked = "keybind-bg_active",
}
GF.MPLUS_BROWSE_PROJECTION_MAX_MEMBERS = 5
GF.MPLUS_BROWSE_PROJECTION_EMPTY_ALPHA = 0.72
GF.MPLUS_BROWSE_PROJECTION_EMPTY_DISABLED_TINT = 0.72
GF.FILTER_DISABLED_ICON_TINT = 0.58
GF.MPLUS_BROWSE_FILTER_DISABLED_ICON_TINT = GF.FILTER_DISABLED_ICON_TINT
GF.MPLUS_BROWSE_FILTER_DISABLED_TEXT_COLOR = { 0.48, 0.47, 0.44, 1 }
GF.MPLUS_BROWSE_CHECK_DISABLED_TINT = 0.72
GF.MPLUS_BROWSE_CHECK_DISABLED_ALPHA = 1
GF.MPLUS_BROWSE_ROLE_CARD_GAP = 2
GF.MPLUS_BROWSE_ROLE_CARD_WIDTHS = { 53, 54, 53 }
GF.MPLUS_BROWSE_ROLE_CARD_VISIBLE_GAP = 8
GF.MPLUS_BROWSE_PRESENCE_CHOICE_VISUAL_OFFSET_X = -0.75
GF.MPLUS_BROWSE_THRESHOLD_OPEN_INPUT_W = 24
GF.MPLUS_BROWSE_THRESHOLD_SCORE_INPUT_W = 70
GF.MPLUS_BROWSE_THRESHOLD_LABEL_TOP_INSET = 14
GF.MPLUS_BROWSE_THRESHOLD_CONTROL_BOTTOM = 14
GF.MPLUS_BROWSE_THRESHOLD_ARROW_W = 8
GF.MPLUS_BROWSE_THRESHOLD_ARROW_H = 13
GF.MPLUS_BROWSE_THRESHOLD_STEP_BUTTON_OFFSET_Y = -0.5
GF.MPLUS_BROWSE_THRESHOLD_DIVIDER_COLOR = { 0.42, 0.34, 0.20, 1 }
GF.MPLUS_BROWSE_THRESHOLD_DIVIDER_ALPHA = 0.72
GF.MPLUS_BROWSE_THRESHOLD_DIVIDER_INSET = 8
GF.CREATE_SIDEBAR_DESC_H = 72
GF.FACTION_ICON_TEXTURES = {
	Alliance = "Interface\\FriendsFrame\\PlusManz-Alliance",
	Horde = "Interface\\FriendsFrame\\PlusManz-Horde",
}
GF.RECOMMENDED_SEARCH_MASK = bit.bor(
	Enum.LFGListFilter.Recommended,
	Enum.LFGListFilter.NotRecommended)
-- PvP 评分分级逻辑见 PvpRating.lua。
-- 社交关系与玩家名规范化逻辑见 PlayerIdentity.lua。
-- SettingsFrameTemplate 内缘（与 Bar OptionsFrame / 暴雪 FlatPanel Bg 一致）
GF.FRAME_BG_INSET_LEFT = 7
GF.FRAME_BG_INSET_TOP = -18
GF.FRAME_BG_INSET_RIGHT = -2
GF.FRAME_BG_INSET_BOTTOM = 3
GF.NAV_WIDTH = 180
GF.NAV_WIDTH_MIN = 180
GF.NAV_WIDTH_MAX = 180
-- 大秘境寻找/创建左栏的下拉与搜索框共用内部控件宽度。
GF.MPLUS_LFG_SIDEBAR_CONTROL_W = GF.NAV_WIDTH - 16
-- 大秘境寻找队伍与组队管理共用的纵向节奏。
GF.MPLUS_LFG_SIDEBAR_SECTION_TITLE_H = 16
GF.MPLUS_LFG_SIDEBAR_SECTION_TITLE_INSET_X = 2
GF.MPLUS_LFG_SIDEBAR_TITLE_CONTROL_GAP = 4
GF.MPLUS_LFG_SIDEBAR_BLOCK_GAP = 10
GF.MPLUS_LFG_SIDEBAR_FORM_TOP_INSET = 8
-- 寻找队伍三组筛选卡与创建招募使用同一 164px 名义宽度基准。
GF.MPLUS_BROWSE_FILTER_OUTER_W = GF.MPLUS_LFG_SIDEBAR_CONTROL_W
GF.NAV_DIVIDER_GRIP_W = 6
-- 导航竖线（§3.4，改一处即联动）
GF.NAV_DIVIDER_W = 3
GF.NAV_DIVIDER_OFFSET_X = -3
GF.NAV_DIVIDER_TOP_OFFSET = 4
GF.NAV_DIVIDER_BOTTOM_OFFSET = 2
GF.NAV_DIVIDER_COLOR = { 0.38, 0.34, 0.24, 0.9 }
GF.NAV_DIVIDER_HIGHLIGHT_COLOR = { 0.62, 0.55, 0.38, 0.3 }
GF.NAV_DIVIDER_SHADOW_COLOR = { 0.08, 0.07, 0.05, 0.9 }
GF.NAV_DIVIDER_CENTER_ACCENT_W = 1
GF.NAV_DIVIDER_CENTER_ACCENT_COLOR = { 1, 0.82, 0 }
GF.NAV_LIST_PADDING_TOP = 8
GF.BROWSE_HEADER_TOP_OFFSET = -20
GF.BROWSE_HEADER_BOTTOM_OFFSET = -46
-- 黑名单、大秘境队伍与车队共用的列表表头几何基准。
GF.SHARED_TABLE_HEADER_HEIGHT = math.abs(
	GF.BROWSE_HEADER_BOTTOM_OFFSET - GF.BROWSE_HEADER_TOP_OFFSET)
GF.SHARED_TABLE_HEADER_LIST_GAP = 4
-- 黑名单直接以背板黑底为父级；大秘境工作区则恢复到了完整背板坐标。
-- 补回背板黑底内缩后，背景 atlas 才会落在相同的屏幕范围。
GF.SHARED_TABLE_HEADER_PANEL_INSET_LEFT =
	GF.MAIN_PANEL_BACKPLATE_BG_INSET_LEFT
GF.SHARED_TABLE_HEADER_PANEL_INSET_RIGHT =
	GF.MAIN_PANEL_BACKPLATE_BG_INSET_RIGHT
GF.SHARED_TABLE_HEADER_PANEL_INSET_TOP =
	GF.MAIN_PANEL_BACKPLATE_BG_INSET_TOP
		+ math.abs(GF.BROWSE_HEADER_TOP_OFFSET)
GF.BROWSE_HEADER_CONTENT_INSET_X = 4
GF.BROWSE_HEADER_CONTENT_OFFSET_Y = 4
GF.BROWSE_HEADER_LIST_GAP = 0
GF.SECTION_HEADER_TEXT_SIZE = 14
GF.BROWSE_HEADER_TEXT_SIZE = GF.SECTION_HEADER_TEXT_SIZE
GF.BROWSE_HEADER_TEXT_CENTER_OFFSET_Y = GF.BROWSE_HEADER_CONTENT_OFFSET_Y
GF.BROWSE_HEADER_TEXT_INSET_X = 3
GF.BROWSE_HEADER_TEXT_PRESSED_OFFSET_X = 1
GF.BROWSE_HEADER_TEXT_PRESSED_OFFSET_Y = -1
GF.BROWSE_HEADER_TEXT_PRESSED_ALPHA = 1
GF.BROWSE_HEADER_TEXT_COLOR = { 1, 0.82, 0, 1 }
GF.BROWSE_HEADER_HOVER_TEXT_COLOR = { 1, 0.96, 0.58, 1 }
GF.BROWSE_HEADER_PRESSED_TEXT_COLOR = { 0.95, 0.68, 0.18, 1 }
GF.CREATE_MANAGER_TITLE_TEXT_SIZE = GF.SECTION_HEADER_TEXT_SIZE
GF.CREATE_MANAGER_TITLE_TEXT_COLOR = GF.BROWSE_HEADER_TEXT_COLOR
-- 集合石只读与大秘境组队管理只共享正文禁用视觉；顶部标题条不读取此表。
GF.CREATE_MANAGER_DISABLED_VISUAL = {
	labelTextColor = { 0.72, 0.70, 0.64, 1 },
	inputTextColor = { 0.78, 0.77, 0.72, 1 },
	atlasTint = GF.FILTER_DISABLED_ICON_TINT,
	desaturated = true,
	alpha = 1,
	preserveButtonAlpha = true,
}
GF.CREATE_MANAGER_DROPDOWN_ARROW_ATLAS = "common-dropdown-a-button"
GF.BROWSE_HEADER_BACKGROUND_ATLAS = "housefinder_header-bg-gradient"
GF.BROWSE_HEADER_BACKGROUND_INSET_L = -8
GF.BROWSE_HEADER_BACKGROUND_FRAME_LEVEL_OFFSET = 1
GF.BROWSE_CONTROL_BACKGROUND_ATLAS = GF.BROWSE_HEADER_BACKGROUND_ATLAS
GF.BROWSE_CONTROL_BACKGROUND_ALPHA = 1
GF.BROWSE_HEADER_DIVIDER_ATLAS = "GM-bgOpen-divider-vertical"
GF.BROWSE_HEADER_ACCENT_WIDTH = 1.5
GF.BROWSE_HEADER_ACCENT_HEIGHT = 22
GF.BROWSE_HEADER_ACCENT_COLOR = { 198 / 255, 168 / 255, 96 / 255 }
GF.BROWSE_HEADER_ACCENT_ALPHA = 1
GF.BROWSE_HEADER_ACCENT_TEXTURE = GF.WHITE_TEXTURE
GF.EMPTY_PROMPT_TEXT_SIZE = 14
GF.BROWSE_EMPTY_TEXT_SIZE = GF.EMPTY_PROMPT_TEXT_SIZE
GF.BROWSE_EMPTY_ACTION_MIN_WIDTH = 120
GF.BROWSE_EMPTY_ACTION_MAX_WIDTH = 160
GF.BROWSE_EMPTY_ACTION_HORIZONTAL_PADDING = 28
GF.BROWSE_EMPTY_ACTION_GAP = 10
GF.BROWSE_RESULT_ACTION_ROW_MIN_HEIGHT = 36
GF.BROWSE_RESULT_ACTION_SHORT_OFFSET_Y = 10
GF.BROWSE_HEADER_REFRESH_TEXTURE = GF.REFRESH_TEXTURE
GF.BROWSE_HEADER_REFRESH_BUTTON_SIZE = 35
GF.BROWSE_HEADER_REFRESH_ICON_SIZE = 21
-- 悬停只用 ADD 提亮，保持与常态相同的可见尺寸和中心位置。
GF.BROWSE_HEADER_REFRESH_ICON_HOVER_SIZE =
	GF.BROWSE_HEADER_REFRESH_ICON_SIZE
GF.BROWSE_HEADER_REFRESH_ICON_HOVER_GLOW_ALPHA = 0.4
GF.BROWSE_HEADER_REFRESH_ICON_HOVER_GLOW_DESATURATED = true
GF.BROWSE_HEADER_REFRESH_ICON_PRESSED_SIZE = 19
GF.APPLICANT_HEADER_REFRESH_BUTTON_OFFSET_Y = 0
GF.HEADER_REFRESH_ICON_VISUALS = {
	[GF.BUTTON_VISUAL_STATE.NORMAL] = {
		size = GF.BROWSE_HEADER_REFRESH_ICON_SIZE,
		offset = { 0, 0 },
		alpha = 1,
		desaturated = false,
		blendMode = "BLEND",
	},
	[GF.BUTTON_VISUAL_STATE.HOVER] = {
		size = GF.BROWSE_HEADER_REFRESH_ICON_HOVER_SIZE,
		offset = { 0, 0 },
		alpha = 1,
		desaturated = false,
		blendMode = "ADD",
	},
	[GF.BUTTON_VISUAL_STATE.PRESSED] = {
		size = GF.BROWSE_HEADER_REFRESH_ICON_PRESSED_SIZE,
		offset = { 1, -1 },
		alpha = 0.86,
		desaturated = false,
		blendMode = "BLEND",
	},
	[GF.BUTTON_VISUAL_STATE.DISABLED] = {
		size = GF.BROWSE_HEADER_REFRESH_ICON_SIZE,
		offset = { 0, 0 },
		alpha = 0.45,
		desaturated = true,
		blendMode = "BLEND",
	},
}
GF.BROWSE_LOADING_TEAMUP_ATLASES = GF.TEAMUP_ATLASES
GF.BROWSE_LOADING_ICON_COUNT = 3
GF.BROWSE_LOADING_ICON_SIZE = 25
GF.BROWSE_LOADING_ICON_WIDTH = GF.BROWSE_LOADING_ICON_SIZE
GF.BROWSE_LOADING_ICON_HEIGHT = GF.BROWSE_LOADING_ICON_SIZE
GF.BROWSE_LOADING_ICON_GAP = 6
GF.BROWSE_LOADING_TEXT_GAP = 7
GF.BROWSE_LOADING_STEP_SECONDS = 0.28
GF.BROWSE_LOADING_FADE_IN_SECONDS = 0.16
GF.BROWSE_LOADING_HOLD_SECONDS = 0.4
GF.BROWSE_LOADING_FADE_OUT_SECONDS = 0.45
GF.ROW_BACKGROUND_ATLAS = "UI-QuestTracker-Secondary-Objective-Header"
GF.ROW_BACKGROUND_FALLBACK_TEXTURE = GF.WHITE_TEXTURE
GF.ROW_BACKGROUND_SOURCE_WIDTH = 564
GF.ROW_BACKGROUND_SOURCE_HEIGHT = 52
GF.ROW_BACKGROUND_SOURCE_CAP_WIDTH = 18
GF.ROW_BACKGROUND_TOP_SOURCE_HEIGHT = 8
-- The native atlas ends with a faint bottom rule. Standard list surfaces crop
-- that rule and share one pixel-aligned geometry for base/hover/selected art.
GF.ROW_BACKGROUND_PROFILE = {
	sourceWidth = GF.ROW_BACKGROUND_SOURCE_WIDTH,
	sourceHeight = GF.ROW_BACKGROUND_SOURCE_HEIGHT,
	sourceCapWidth = GF.ROW_BACKGROUND_SOURCE_CAP_WIDTH,
	topSourceHeight = GF.ROW_BACKGROUND_TOP_SOURCE_HEIGHT,
	cropTopPixels = 0,
	cropBottomPixels = 2,
	maxDisplayHeight = 32,
	pixelAligned = true,
	verticalAlign = "CENTER",
	oddPixelBias = "UP",
}
GF.ROW_BACKGROUND_STATE_COLORS = {
	red = { 1, 0.16, 0.12, 1 },
	blue = { 0.36, 0.68, 1, 1 },
	green = { 0.14, 0.95, 0.24, 1 },
	censored = { 0.62, 0.42, 0.78, 1 },
	grey = { 0.52, 0.52, 0.52, 1 },
}
GF.BROWSE_ROW_NORMAL_COLOR = { 1, 1, 1, 1 }
GF.LIST_BACKGROUND_STYLE_DEFAULTS = {
	normal = {
		r = GF.BROWSE_ROW_NORMAL_COLOR[1],
		g = GF.BROWSE_ROW_NORMAL_COLOR[2],
		b = GF.BROWSE_ROW_NORMAL_COLOR[3],
		alphaPct = GF.LIST_BACKGROUND_NORMAL_ALPHA_DEFAULT_PCT or 30,
	},
	friend = { r = 0.36, g = 0.68, b = 1, alphaPct = GF.LIST_BACKGROUND_ALPHA_DEFAULT_PCT or 100 },
	application = { r = 0.14, g = 0.95, b = 0.24, alphaPct = GF.LIST_BACKGROUND_ALPHA_DEFAULT_PCT or 100 },
	censored = { r = 0.62, g = 0.42, b = 0.78, alphaPct = GF.LIST_BACKGROUND_ALPHA_DEFAULT_PCT or 100 },
	warning = { r = 1, g = 0.16, b = 0.12, alphaPct = GF.LIST_BACKGROUND_ALPHA_DEFAULT_PCT or 100 },
	disabled = { r = 0.52, g = 0.52, b = 0.52, alphaPct = GF.LIST_BACKGROUND_ALPHA_DEFAULT_PCT or 100 },
}
GF.LIST_BACKGROUND_STYLE_ORDER = { "normal", "friend", "application", "censored", "warning", "disabled" }
GF.LIST_BACKGROUND_STATE_TO_STYLE = {
	normal = "normal",
	green = "application",
	blue = "friend",
	censored = "censored",
	red = "warning",
	grey = "disabled",
}
GF.BROWSE_ROW_BACKGROUND_ALPHA = 0.92
GF.BROWSE_ROW_BACKGROUND_FADE_SECONDS = 0.24
GF.BROWSE_ROW_TEXT_FADE_SECONDS = 0.18
GF.BROWSE_BLOCKLIST_RETIRE_SECONDS = 0.28
GF.BROWSE_DECLINED_FILTER_FEEDBACK_SECONDS = 0.8
GF.APPLICANT_DECLINED_MIN_VISIBLE_SECONDS = 0.8
GF.APPLICANT_ACTION_PENDING_TIMEOUT_SECONDS = 3
GF.APPLICANT_DECLINE_PENDING_TIMEOUT_SECONDS = 1.5
GF.APPLICANT_LISTING_LOSS_INVITE_GRACE_SECONDS = 1
GF.BROWSE_ROW_HOVER_COLOR = { 1, 0.74, 0.18, 0.13 }
GF.BROWSE_ROW_HOVER_RED_COLOR = { 1, 0.12, 0.08, 0.18 }
GF.BROWSE_ROW_HOVER_BLUE_COLOR = { 0.35, 0.75, 1, 0.16 }
GF.BROWSE_ROW_HOVER_GREY_COLOR = { 0.65, 0.65, 0.65, 0.18 }
GF.BROWSE_ROW_SELECTED_COLOR = { 1, 0.9, 0.08, 0.82 }
GF.BROWSE_ROW_SELECTED_ALPHA = 1
GF.BROWSE_ROW_MEMBER_ICON_SIZE = GF.ROLE_ICON_SIZE
GF.BROWSE_ROW_MEMBER_ICON_GAP = 2
GF.BROWSE_ROW_MEMBER_MAX_ICONS = 5
GF.BROWSE_ROW_MEMBER_EMPTY_SLOT_ATLAS = GF.ROLE_ICON_ATLAS.DEFAULT
GF.BROWSE_ROW_MEMBER_ROLE_BADGE_SIZE = 12
GF.BROWSE_ROW_MEMBER_ROLE_BADGE_LARGE_SIZE = 14
GF.BROWSE_ROW_MEMBER_ROLE_BADGE_OFFSET_X = 2
GF.BROWSE_ROW_MEMBER_ROLE_BADGE_OFFSET_Y = 2
GF.BROWSE_ROW_MEMBER_LEADER_BADGE_SIZE = GF.BROWSE_ROW_MEMBER_ROLE_BADGE_SIZE
GF.BROWSE_ROW_MEMBER_LEADER_BADGE_OFFSET_X = GF.BROWSE_ROW_MEMBER_ROLE_BADGE_OFFSET_X
GF.BROWSE_ROW_MEMBER_LEADER_BADGE_OFFSET_Y = GF.BROWSE_ROW_MEMBER_ROLE_BADGE_OFFSET_Y
GF.MEMBER_DISPLAY_MODE_ROLE = "role"
GF.MEMBER_DISPLAY_MODE_SPEC = "spec"
GF.MEMBER_DISPLAY_MODE_SPEC_LARGE = "spec_large"
GF.MEMBER_DISPLAY_MODE_DEFAULT = GF.MEMBER_DISPLAY_MODE_ROLE
GF.MEMBER_TOOLTIP_MODE_DETAILS = "details"
GF.MEMBER_TOOLTIP_MODE_SPEC_COUNT = "spec_count"
GF.MEMBER_TOOLTIP_MODE_DEFAULT = GF.MEMBER_TOOLTIP_MODE_DETAILS
GF.BROWSE_COLUMN_PRESET_VERSION = 5
GF.APPLICANT_COLUMN_PRESET_VERSION = 6
GF.APPLICANT_ROW_H = 33
GF.APPLICANT_ROW_BACKGROUND_INSET_TOP = 2
GF.APPLICANT_ROW_BACKGROUND_INSET_BOTTOM = 0
GF.APPLICANT_ROW_CONTENT_OFFSET_Y = -1
GF.APPLICANT_ACTION_BUTTON_SIZE = 24
GF.APPLICANT_ACTION_ICON_SIZE = 12
GF.SUBTITLE_H = 42
GF.SUBTITLE_HEADER_H = 26
GF.BROWSE_CONTROL_BACKGROUND_H = GF.SUBTITLE_HEADER_H
GF.BROWSE_CONTROL_BACKGROUND_OFFSET_Y = 4
GF.SUBTITLE_CONTROL_CENTER_OFFSET_Y =
	((GF.SUBTITLE_H + GF.BROWSE_CONTROL_BACKGROUND_OFFSET_Y) / 2) - (GF.SUBTITLE_H / 2)
GF.SUBTITLE_CATEGORY_ACCENT_GAP = 10
GF.SUBTITLE_CATEGORY_MIN_W = 140
GF.SUBTITLE_CONTROL_LEFT_PAD = 15
GF.SUBTITLE_CONTROL_RIGHT_PAD = 10
GF.SUBTITLE_CONTROL_GAP = 7
GF.SUBTITLE_CONTROL_TOP_OFFSET = -8
GF.SUBTITLE_SEARCH_W = 220
GF.SUBTITLE_SEARCH_H = 26
GF.SUBTITLE_SEARCH_CENTER_OFFSET_Y = 1
GF.SUBTITLE_SEARCH_TEXT_SIZE = 12
GF.SUBTITLE_SEARCH_ICON_INSET = 8
GF.SUBTITLE_SEARCH_ICON_SIZE = 14
GF.SUBTITLE_SEARCH_TEXT_INSET_LEFT = 27
GF.SUBTITLE_SEARCH_TEXT_INSET_RIGHT = 24
GF.SUBTITLE_SEARCH_CLEAR_INSET = 6
GF.MPLUS_BROWSE_SEARCH_FIT_PADDING = 2
GF.MPLUS_BROWSE_SEARCH_MIN_TEXT_SIZE = 9
GF.SUBTITLE_SEARCH_TEXT_COLOR = { 1, 0.96, 0.86, 1 }
GF.SUBTITLE_SEARCH_PLACEHOLDER_COLOR = { 0.55, 0.55, 0.55, 1 }
GF.SUBTITLE_SEARCH_OWNERSHIP_POLL_SEC = 0.5
GF.SUBTITLE_OPTION_CHECK_SIZE = 20
GF.SUBTITLE_OPTION_TEXT_SIZE = 13
GF.SUBTITLE_CATEGORY_TEXT_SIZE = 13
-- Shared by the browse footer options and the applicant auto-invite control.
GF.SUBTITLE_OPTION_TEXT_GAP = 4
GF.SUBTITLE_OPTION_GROUP_GAP = 12
GF.SUBTITLE_OPTION_TEXT_COLOR = { 1, 0.82, 0, 1 }
GF.FILTER_FOOTER_H = GF.SUBTITLE_H
GF.FILTER_FOOTER_INSET_L = GF.FRAME_BG_INSET_LEFT
GF.FILTER_FOOTER_INSET_R = GF.FRAME_BG_INSET_RIGHT
GF.FILTER_FOOTER_INSET_B = GF.FRAME_BG_INSET_BOTTOM
GF.FILTER_FOOTER_BUTTON_OFFSET_Y = 12
GF.FILTER_FOOTER_BUTTON_GAP = 10
GF.FILTER_SCROLLBAR_WIDTH = 8
GF.FILTER_SCROLLBAR_RIGHT_INSET = 8
GF.FILTER_SCROLLBAR_TOP_INSET = 8
GF.FILTER_SCROLLBAR_BOTTOM_INSET = 8
GF.FILTER_TEXT_COLOR = GF.SUBTITLE_OPTION_TEXT_COLOR
GF.SIDE_PANEL_W = 260
GF.FILTER_PANEL_W = GF.SIDE_PANEL_W
GF.FILTER_CHECK_SIZE = 20
GF.FILTER_CHECK_LABEL_GAP = 6
GF.FILTER_NUMBER_INPUT_H = 20
GF.FILTER_STEP_BUTTON_SIZE = GF.FILTER_NUMBER_INPUT_H
GF.FILTER_STEP_BUTTON_GAP = 2
GF.FILTER_STEP_ARROW_CENTER_OFFSET_X = 1
GF.PANEL_BUTTON_H = 24
GF.PANEL_BUTTON_STANDARD_W = 72
GF.PANEL_BUTTON_TWO_CHAR_W = GF.PANEL_BUTTON_STANDARD_W
GF.PANEL_CONFIRM_BUTTON_W = GF.PANEL_BUTTON_STANDARD_W
GF.PANEL_CONFIRM_BUTTON_FONT_SIZE = 14
GF.APPLICANT_MANAGE_BUTTON_W = GF.PANEL_BUTTON_STANDARD_W
GF.PLAYER_CONTEXT_DIALOG_STYLE = {
	WIDTH = 420,
	HEIGHT = 176,
	LEVEL_OFFSET = 18,
	BACKGROUND_COLOR = GF.PLAYER_CONTEXT_DIALOG_BACKGROUND_COLOR,
	CONTENT_INSET_X = 36,
	CONTENT_TOP_INSET = 38,
	CONTENT_BOTTOM_INSET = 18,
	CONTENT_ACTION_GAP = 12,
	PRIMARY_TEXT_FONT_SIZE = 15,
	SECONDARY_TEXT_FONT_SIZE = 12,
	ACCENT_TEXT_FONT_SIZE = 15,
	PRIMARY_TEXT_COLOR = { 1, 1, 1, 1 },
	SECONDARY_TEXT_COLOR = { 0.78, 0.76, 0.70, 1 },
	ACCENT_TEXT_COLOR = { 1, 0.82, 0, 1 },
	TEXT_LINE_GAP = 5,
	TEXT_TO_INPUT_GAP = 8,
	COPY_HINT_TO_INPUT_GAP = 10,
	BLACKLIST_INPUT_CENTER_OFFSET_Y = -21,
	COPY_INPUT_CENTER_OFFSET_Y = -12,
	TELEPORT_MESSAGE_CENTER_OFFSET_Y = 4,
	TELEPORT_TEXT_LINE_GAP = 7,
	INPUT_WIDTH = 330,
	INPUT_HEIGHT = 30,
	INPUT_VALUE_FONT_SIZE = 15,
	INPUT_EDIT_FONT_SIZE = 14,
	INPUT_PLACEHOLDER_FONT_SIZE = 12,
	MIN_FITTED_TEXT_SIZE = 10,
	BUTTON_WIDTH = GF.PANEL_BUTTON_STANDARD_W,
	BUTTON_HEIGHT = GF.PANEL_BUTTON_H,
	BUTTON_GAP = 12,
	BUTTON_FONT_SIZE = 15,
	SCREEN_OFFSET_Y = 20,
}
GF.APPLICANT_ACTIVE_ROLE_SUMMARY_W = 168
GF.APPLICANT_ACTIVE_ROLE_SUMMARY_X = 6
GF.NAV_L0_ROW_H = 45
GF.NAV_L0_BUTTON_H = 43
GF.NAV_ROW_H = { [0] = GF.NAV_L0_ROW_H, [1] = 38, [2] = 34, [3] = 30 }
GF.NAV_TRANSMOG_BUTTON_H = { [0] = GF.NAV_L0_BUTTON_H, [1] = 34, [2] = 30, [3] = 26 }
GF.NAV_TRANSMOG_BUTTON_OFFSET_X = 0
GF.NAV_TRANSMOG_BUTTON_WIDTH_PAD = { [0] = 20, [1] = 32, [2] = 44, [3] = 56 }
GF.NAV_TRANSMOG_BUTTON_TEXT_LEFT = { [0] = 12, [1] = 14, [2] = 16, [3] = 18 }
GF.NAV_TRANSMOG_BUTTON_TEXT_RIGHT = 8
GF.NAV_QUICK_SEARCH_ICON_ATLAS = "common-search-magnifyingglass"
GF.NAV_QUICK_SEARCH_ICON_TEXTURE = "Interface\\Common\\UI-Searchbox-Icon"
GF.NAV_QUICK_SEARCH_ICON_SIZE = 14
GF.NAV_QUICK_SEARCH_ICON_GAP = 3
GF.FAVORITE_INSTANCE_ICON_ATLAS = "campcollection-icon-star"
GF.FAVORITE_INSTANCE_ICON_SIZE = 14
GF.FAVORITE_INSTANCE_ICON_GAP = 3
GF.NAV_L0_ROW_SPACING = 2
GF.NAV_ROW_H_DEFAULT = 28
GF.NAV_FLYOUT_PANEL_MIN_W = 120
GF.NAV_FLYOUT_PANEL_MAX_W = 260
GF.NAV_FLYOUT_ROOT_GAP = 2
GF.NAV_FLYOUT_ROOT_ANCHOR_GAP_X = 4
GF.NAV_FLYOUT_ROOT_ANCHOR_GAP_Y = 2
GF.NAV_FLYOUT_PANEL_GAP = 6
GF.NAV_FLYOUT_STAIR_STEP_Y = 9
GF.NAV_FLYOUT_SCREEN_MARGIN_TOP = 12
GF.NAV_FLYOUT_SCREEN_MARGIN_BOTTOM = 12
GF.NAV_FLYOUT_WINDOW_BOTTOM_GAP = 0
GF.NAV_FLYOUT_ROW_H = { [1] = 32, [2] = 32, [3] = 30 }
GF.NAV_FLYOUT_ROW_H_DEFAULT = 30
GF.NAV_FLYOUT_ROW_TEXT_L = 12
GF.NAV_FLYOUT_ROW_TEXT_R = 10
GF.NAV_FLYOUT_ARROW_ATLAS = "bag-arrow"
GF.NAV_FLYOUT_ARROW_W = 10
GF.NAV_FLYOUT_ARROW_H = 16
GF.NAV_FLYOUT_ARROW_R = 8
GF.NAV_FLYOUT_ARROW_RESERVE_W = 28
GF.NAV_FLYOUT_LABEL_EXTRA_W = 8
GF.NAV_FLYOUT_HIGHLIGHT_INSET_X = 3
GF.NAV_FLYOUT_HIGHLIGHT_INSET_TOP = 3
GF.NAV_FLYOUT_HIGHLIGHT_INSET_BOTTOM = 1
GF.NAV_FLYOUT_ROW_TEXTURE_EXTEND_X = 8
GF.NAV_FLYOUT_HIGHLIGHT_ATLAS = GF.ROW_BACKGROUND_ATLAS
GF.NAV_FLYOUT_HIGHLIGHT_DISPLAY_H = 28
GF.NAV_FLYOUT_BG_ATLAS = "common-dropdown-bg"
GF.NAV_FLYOUT_BG_EXTEND_X = 10
GF.NAV_FLYOUT_BG_EXTEND_TOP = 3
GF.NAV_FLYOUT_BG_EXTEND_BOTTOM = 3
GF.NAV_FLYOUT_BG_ALPHA = 0.925
GF.NAV_FLYOUT_CONTENT_INSET_L = 8
GF.NAV_FLYOUT_CONTENT_INSET_R = 8
GF.NAV_FLYOUT_CONTENT_INSET_T = 8
GF.NAV_FLYOUT_CONTENT_INSET_B = 15
GF.LIST_ROW_H = 32
GF.LIST_ROW_H_DEFAULT = 32
GF.BROWSE_TEXT_CELL_INSET_X = 2
GF.ROLE_COUNT_ICON_DEFAULT = GF.ROLE_ICON_SIZE
GF.ROLE_COUNT_NUM_ICON_GAP = 5
local function publishConstants(values)
	for name, value in pairs(values) do
		GF[name] = value
	end
end

-- 内容区 scroll 右缘留白 + 滚动条贴窗右（各内容页共用，仅改此处）
publishConstants({
	COL_MIN_WIDTH_MIN = 20,
	COL_MIN_WIDTH_MAX = 300,
	COL_WEIGHT_MIN = 0,
	COL_WEIGHT_MAX = 3,
	CONTENT_SCROLL_INSET_L = 5,
	CONTENT_SCROLL_INSET_R = 18,
	CONTENT_SCROLL_INSET_B = 0,
	CONTENT_SCROLLBAR_OFFSET_X = 9,
	LIST_CONTENT_EDGE_PAD = 18,
	LIST_CONTENT_EDGE_PAD_MAX = 30,
	LIST_COL_REF_W = 930,
	ACTIVITY_COUNT_RIGHT = 28,
	LIST_WHEEL_ROWS_MIN = 1,
	LIST_WHEEL_ROWS_MAX = 10,
	LIST_WHEEL_ROWS_DEFAULT = 3,
	AUTO_INVITE_MEMBER_LIMIT_MIN = 1,
	AUTO_INVITE_MEMBER_LIMIT_MAX = 40,
	AUTO_INVITE_MEMBER_LIMIT_DEFAULT = 40,
	NAV_WHEEL_ROW_H = 28,
	SETTINGS_WHEEL_ROW_H = 24,
	SETTINGS_COL_W = 280,
	SETTINGS_GUTTER_MIN = 50,
	SETTINGS_GUTTER_WEIGHT = 1,
})
-- 内容区相对 nav 右缘水平偏移（负=向左靠分割线）
GF.CONTENT_NAV_OFFSET_X = 0
-- 列表行四列左边界（在 LIST_COL_REF_W 参考行宽下的 px）
-- host 左缘到石纹内缘；右缘 CONTENT_SCROLL_INSET_R 为滚动条走廊
GF.SETTINGS_LAYOUT_INSET_L = (GF.FRAME_BG_INSET_LEFT or 7) - (GF.FRAME_PAD or 4)
-- 设置页最外层分区标题与滚动条走廊。
publishConstants({
	SETTINGS_SCROLLBAR_WIDTH = 17,
	SETTINGS_SCROLLBAR_GAP = 2,
	SETTINGS_SCROLLBAR_RIGHT_INSET = 10,
	SETTINGS_SCROLLBAR_TOP_INSET = 8,
	SETTINGS_SCROLLBAR_BOTTOM_INSET = 8,
})
GF.SETTINGS_VISIBLE_CONTENT_INSET_R =
	GF.SETTINGS_SCROLLBAR_WIDTH
	+ GF.SETTINGS_SCROLLBAR_GAP
	+ GF.SETTINGS_SCROLLBAR_RIGHT_INSET
-- WowStyle1Dropdown 等控件相对列 Frame 左缘的视觉外溢
-- 设置页控件行距：下拉/滑块底留白 8 + 分区表头前 12 + 表头内锚 8 = 表头上方 28px
publishConstants({
	SETTINGS_CONTENT_TOP_OFFSET = 20,
	SETTINGS_SECTION_TITLE_H = 40,
	SETTINGS_COL_EDGE_INSET_L = 10,
	SETTINGS_ROW_BOTTOM_PAD = 8,
	SETTINGS_SECTION_TOP_PAD = 12,
	SETTINGS_DROPDOWN_W = 260,
	SETTINGS_DROPDOWN_H = 26,
	SETTINGS_SLIDER_W = 220,
	SETTINGS_SLIDER_H = 19,
	FILTER_WHEEL_ROW_H = 28,
	BLOCKLIST_WHEEL_ROW_H = 28,
})
GF.CREATE_DRAWER_W = 600
GF.CREATE_DRAWER_H = 390
GF.CREATE_DRAWER_HORIZONTAL_MIN_W = 560
GF.CREATE_FORM_COLUMN_GAP = 16
GF.CREATE_DRAWER_AVOID_ALPHA = 0.64
GF.CREATE_DRAWER_MAIN_ALPHA = GF.CREATE_DRAWER_AVOID_ALPHA
publishConstants({
	CREATE_WHEEL_ROW_H = 24,
	LIST_REFRESH_DEBOUNCE = 0.2,
	BROWSE_LISTEN_HOLD_SEC = 60,
	BROWSE_SORT_KEY_BATCH = 25,
	FILTER_BATCH = 25,
	ROW_UPDATE_DEBOUNCE = 0.2,
	LAYOUT_RESIZE_DEBOUNCE = 0.1,
	SEARCH_COOLDOWN = 3,
	SEARCH_TIMEOUT_SECONDS = 8,
})

GF.TAB_BROWSE = 1
GF.TAB_CREATE = 2
GF.TAB_BLOCKLIST = 3
GF.TAB_SETTINGS = 4
GF.TAB_DEBUG = 5
GF.TAB_MPLUS_CHARACTER = 101
GF.TAB_MPLUS_GROUP = 102
GF.TAB_MPLUS_CARPOOL = 103
GF.TAB_MPLUS_DUNGEON = 104

GF.WORKSPACE_MEETING_STONE = "standard"
GF.WORKSPACE_MYTHIC_PLUS = "mythic_plus"
GF.WORKSPACE_RAID = "raid"
GF.WORKSPACE_DEFAULT = GF.WORKSPACE_MEETING_STONE
GF.WORKSPACE_TAB_HEIGHT = GF.MAIN_PANEL_TAB_HEIGHT
GF.WORKSPACE_TAB_GAP = GF.MAIN_PANEL_TAB_GAP
GF.WORKSPACE_TAB_TEXT_PADDING = 40
GF.WORKSPACE_TAB_LEFT_INSET = 32
GF.GREAT_VAULT_BUTTON_OFFSET_X = GF.WORKSPACE_TAB_LEFT_INSET
GF.GREAT_VAULT_BUTTON_OFFSET_Y = 2


GF.APPLY_MANUAL = "manual"
GF.APPLY_CLICK_CONFIRM = "click_confirm"
GF.APPLY_DBLCLICK_AUTO = "dblclick_auto"

GF.LIST_HOVER_TOOLTIP_HIDE_DELAY = 0.1

publishConstants({
	FRAME_STRATA_DEFAULT = "MEDIUM",
	FRAME_STRATA_CHOICES = { "LOW", "MEDIUM", "HIGH", "DIALOG" },
	CAT_QUEST = 1,
	CAT_DUNGEON = 2,
	CAT_RAID = 3,
	CAT_CUSTOM = 6,
	CAT_DELVE = 121,
	ACTIVITY_CUSTOM_PVE = 16,
	ACTIVITY_CUSTOM_PVP = 17,
	ACTIVITY_HOUSEWARMING = 1972,
	BODY_BACKGROUND_COLOR = { 0.05, 0.05, 0.08, 0.75 },
	SEL_TEX = "Interface\\PVPFrame\\PvPMegaQueue",
	SEL_TEX_HOVER = { 0.00195313, 0.63867188, 0.70703125, 0.76757813 },
	SEL_TEX_SELECTED = { 0.00195313, 0.63867188, 0.76953125, 0.83007813 },
})

local pvpCategoryDefinitions = {
	{ 8, "PVP_BG" },
	{ 4, "PVP_ARENA" },
	{ 9, "PVP_RATED" },
	{ 7, "PVP_SKIRMISH" },
}
GF.PVP_CATEGORIES = {}
for index = 1, #pvpCategoryDefinitions do
	local definition = pvpCategoryDefinitions[index]
	GF.PVP_CATEGORIES[index] = { id = definition[1], key = definition[2] }
end

function GF.GetBrowseListLayoutWidth()
	local owner = GF.FindGroupTab
	local measure = owner and owner.GetLayoutWidth
	return measure and measure(owner) or 1
end

function GF.GetApplicantListLayoutWidth()
	local list = GF.ApplicantsPanel and GF.ApplicantsPanel.scrollList
	local measure = list and list.GetLayoutWidth
	return measure and measure(list) or 1
end
