ha-mcp-dev 7.6.0.dev636__tar.gz → 7.6.0.dev638__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/MANIFEST.in +2 -0
- {ha_mcp_dev-7.6.0.dev636/src/ha_mcp_dev.egg-info → ha_mcp_dev-7.6.0.dev638}/PKG-INFO +1 -1
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/pyproject.toml +2 -2
- ha_mcp_dev-7.6.0.dev638/src/ha_mcp/settings.css +325 -0
- ha_mcp_dev-7.6.0.dev638/src/ha_mcp/settings.js +2732 -0
- ha_mcp_dev-7.6.0.dev638/src/ha_mcp/settings_ui.py +3119 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638/src/ha_mcp_dev.egg-info}/PKG-INFO +1 -1
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp_dev.egg-info/SOURCES.txt +2 -0
- ha_mcp_dev-7.6.0.dev636/src/ha_mcp/settings_ui.py +0 -6051
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/LICENSE +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/README.md +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/setup.cfg +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/__main__.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/_pypi_marker +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/_version.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/auth/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/auth/consent_form.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/auth/provider.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/backup_manager.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/client/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/client/rest_client.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/client/supervisor_client.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/client/websocket_client.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/client/websocket_listener.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/config.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/errors.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/policy/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/policy/approval_queue.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/policy/evaluator.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/policy/handlers.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/policy/middleware.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/policy/model.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/policy/persistence.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/policy/value_sources.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/py.typed +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/resources/skills-vendor/.claude/settings.json +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/resources/skills-vendor/.claude-plugin/marketplace.json +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/resources/skills-vendor/.claude-plugin/plugin.json +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/resources/skills-vendor/.github/ISSUE_TEMPLATE/skill-rca.md +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/resources/skills-vendor/.github/pull_request_template.md +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/resources/skills-vendor/AGENTS.md +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/resources/skills-vendor/CLAUDE.md +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/resources/skills-vendor/CONTRIBUTING.md +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/resources/skills-vendor/LICENSE +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/resources/skills-vendor/README.md +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/SKILL.md +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/evals/evals.json +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/automation-patterns.md +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-cards.md +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-guide.md +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/device-control.md +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/domain-docs.md +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/examples.yaml +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/helper-selection.md +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/safe-refactoring.md +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/template-guidelines.md +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/yaml-only-integrations.md +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/server.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/smoke_test.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/stdio_settings_sidecar.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/auto_backup.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/backup.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/best_practice_checker.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/device_control.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/enhanced.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/helpers.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/reference_validator.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/registry.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/smart_search.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_addons.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_areas.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_blueprints.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_bug_report.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_calendar.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_camera.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_categories.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_code.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_config_automations.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_config_entry_flow.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_config_helpers.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_config_scenes.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_energy.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_entities.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_filesystem.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_groups.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_hacs.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_history.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_integrations.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_labels.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_mcp_component.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_registry.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_resources.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_search.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_service.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_services.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_system.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_todo.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_traces.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_updates.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_utility.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_yaml_config.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/tools_zones.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/util_helpers.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/tools/validation_middleware.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/transforms/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/transforms/categorized_search.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/transforms/lite_docstrings.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/utils/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/utils/config_hash.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/utils/data_paths.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/utils/domain_handlers.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/utils/fuzzy_search.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/utils/kill_signal_diagnostics.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/utils/operation_manager.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/utils/python_sandbox.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/utils/skill_loader.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp/utils/usage_logger.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp_dev.egg-info/dependency_links.txt +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp_dev.egg-info/entry_points.txt +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp_dev.egg-info/requires.txt +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/src/ha_mcp_dev.egg-info/top_level.txt +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/tests/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/tests/test_constants.py +0 -0
- {ha_mcp_dev-7.6.0.dev636 → ha_mcp_dev-7.6.0.dev638}/tests/test_env_manager.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ha-mcp-dev"
|
|
7
|
-
version = "7.6.0.
|
|
7
|
+
version = "7.6.0.dev638"
|
|
8
8
|
description = "Home Assistant MCP Server - Complete control of Home Assistant through MCP"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.13,<3.14"
|
|
@@ -53,7 +53,7 @@ package-dir = {"" = "src", "tests" = "tests"}
|
|
|
53
53
|
packages = { find = { where = ["src", "."], include = ["ha_mcp*", "tests"] } }
|
|
54
54
|
|
|
55
55
|
[tool.setuptools.package-data]
|
|
56
|
-
ha_mcp = ["py.typed", "_pypi_marker", "resources/skills-vendor/**/*"]
|
|
56
|
+
ha_mcp = ["py.typed", "_pypi_marker", "settings.js", "settings.css", "resources/skills-vendor/**/*"]
|
|
57
57
|
|
|
58
58
|
[tool.mypy]
|
|
59
59
|
python_version = "3.13"
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
|
|
2
|
+
:root {
|
|
3
|
+
--bg: #1c1c1e; --surface: #2c2c2e; --surface-hover: #3a3a3c;
|
|
4
|
+
--text: #f5f5f7; --text-secondary: #98989d; --accent: #0a84ff;
|
|
5
|
+
--accent-hover: #409cff; --danger: #ff453a; --success: #30d158;
|
|
6
|
+
--warning: #ffd60a; --border: #38383a; --disabled-bg: #1a1a1c;
|
|
7
|
+
}
|
|
8
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
9
|
+
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
10
|
+
background: var(--bg); color: var(--text); line-height: 1.5; padding: 16px; }
|
|
11
|
+
/* Small unobtrusive version label at the bottom of every settings
|
|
12
|
+
page so an operator can see the running build without leaving
|
|
13
|
+
the UI. Empty until the /api/settings/info GET populates it. */
|
|
14
|
+
.version-footer { margin-top: 32px; padding: 12px 0; font-size: 0.75rem;
|
|
15
|
+
color: var(--text-secondary); text-align: center;
|
|
16
|
+
border-top: 1px solid var(--border); opacity: 0.7; }
|
|
17
|
+
.header { display: flex; align-items: center; justify-content: space-between;
|
|
18
|
+
padding: 16px 0; border-bottom: 1px solid var(--border); margin-bottom: 16px; }
|
|
19
|
+
.header h1 { font-size: 1.5rem; font-weight: 600; }
|
|
20
|
+
.status { font-size: 0.85rem; padding: 4px 12px; border-radius: 12px;
|
|
21
|
+
background: var(--surface); color: var(--text-secondary); }
|
|
22
|
+
.status.saved { background: #0d3b1e; color: var(--success); }
|
|
23
|
+
.search { width: 100%; padding: 10px 16px; border-radius: 10px; border: 1px solid var(--border);
|
|
24
|
+
background: var(--surface); color: var(--text); font-size: 0.95rem; margin-bottom: 16px;
|
|
25
|
+
outline: none; }
|
|
26
|
+
.search:focus { border-color: var(--accent); }
|
|
27
|
+
.readonly-notice { background: #1a2a3a; border: 1px solid #1a4a7a; border-radius: 10px;
|
|
28
|
+
padding: 12px 16px; margin-bottom: 16px; font-size: 0.85rem; color: #6cb4ff; }
|
|
29
|
+
.group { background: var(--surface); border-radius: 12px; margin-bottom: 8px;
|
|
30
|
+
overflow: hidden; border: 1px solid var(--border); }
|
|
31
|
+
.group-header { display: flex; align-items: center; justify-content: space-between;
|
|
32
|
+
padding: 12px 16px; cursor: pointer; user-select: none; gap: 12px; }
|
|
33
|
+
.group-header:hover { background: var(--surface-hover); }
|
|
34
|
+
.group-header-left { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; }
|
|
35
|
+
.group-name { font-weight: 600; font-size: 0.95rem; }
|
|
36
|
+
.group-count { font-size: 0.8rem; color: var(--text-secondary); }
|
|
37
|
+
.group-chevron { transition: transform 0.2s; color: var(--text-secondary);
|
|
38
|
+
display: inline-block; width: 12px; }
|
|
39
|
+
.group-chevron.open { transform: rotate(90deg); }
|
|
40
|
+
.group-master { flex-shrink: 0; }
|
|
41
|
+
.group-tools { display: none; border-top: 1px solid var(--border); }
|
|
42
|
+
.group-tools.open { display: block; }
|
|
43
|
+
.tool { display: flex; align-items: center; justify-content: space-between;
|
|
44
|
+
padding: 10px 16px; border-bottom: 1px solid var(--border); }
|
|
45
|
+
.tool:last-child { border-bottom: none; }
|
|
46
|
+
.tool.hidden { display: none; }
|
|
47
|
+
.tool.env-pinned .tool-name { color: var(--text-secondary); }
|
|
48
|
+
.tool-info { flex: 1; min-width: 0; }
|
|
49
|
+
.tool-name { font-size: 0.9rem; font-weight: 500; }
|
|
50
|
+
.tool-meta { font-size: 0.75rem; color: var(--text-secondary); margin-top: 2px; }
|
|
51
|
+
.tool-desc { font-size: 0.8rem; color: var(--text-secondary); margin-top: 2px;
|
|
52
|
+
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
53
|
+
.badge { display: inline-block; font-size: 0.7rem; padding: 1px 6px;
|
|
54
|
+
border-radius: 4px; margin-left: 6px; font-weight: 500; }
|
|
55
|
+
.badge.readonly { background: #1a2a3a; color: #6cb4ff; }
|
|
56
|
+
.badge.destructive { background: #3a1a1a; color: #ff6b6b; }
|
|
57
|
+
.badge.mandatory { background: #1a3a1a; color: #6bff6b; }
|
|
58
|
+
.tool-toggles { display: flex; gap: 16px; align-items: center; }
|
|
59
|
+
.toggle-group { display: flex; flex-direction: column; align-items: center; gap: 2px;
|
|
60
|
+
font-size: 0.7rem; color: var(--text-secondary); }
|
|
61
|
+
.toggle-group.disabled-toggle { opacity: 0.35; }
|
|
62
|
+
.switch { position: relative; display: inline-block; width: 36px; height: 20px; }
|
|
63
|
+
.switch input { opacity: 0; width: 0; height: 0; }
|
|
64
|
+
.slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0;
|
|
65
|
+
background: #555; border-radius: 10px; transition: background 0.2s; }
|
|
66
|
+
.slider::before { position: absolute; content: ""; height: 14px; width: 14px; left: 3px;
|
|
67
|
+
top: 3px; background: var(--text); border-radius: 50%; transition: transform 0.2s; }
|
|
68
|
+
input:checked + .slider { background: var(--accent); }
|
|
69
|
+
input:checked + .slider::before { transform: translateX(16px); }
|
|
70
|
+
input:disabled + .slider { cursor: not-allowed; opacity: 0.4; }
|
|
71
|
+
.disabled-by-note { font-size: 0.7rem; color: var(--warning); margin-top: 2px;
|
|
72
|
+
font-style: italic; }
|
|
73
|
+
.summary { display: flex; gap: 16px; padding: 8px 0; margin-bottom: 16px;
|
|
74
|
+
font-size: 0.85rem; color: var(--text-secondary); flex-wrap: wrap; }
|
|
75
|
+
.summary span { background: var(--surface); padding: 4px 12px; border-radius: 8px; }
|
|
76
|
+
.pin-notice { background: #3a2e1a; border: 1px solid #7a5a1a; border-radius: 10px;
|
|
77
|
+
padding: 10px 16px; margin-bottom: 12px; font-size: 0.85rem; color: #ffd680; display: none; }
|
|
78
|
+
.pin-notice.show { display: block; }
|
|
79
|
+
.restart-notice { background: #3a1a1a; border: 1px solid #7a1a1a; border-radius: 10px;
|
|
80
|
+
padding: 12px 16px; margin-bottom: 12px; font-size: 0.9rem; color: #ff9090;
|
|
81
|
+
font-weight: 500; display: none; align-items: center; justify-content: space-between; gap: 12px; }
|
|
82
|
+
.restart-notice.show { display: flex; }
|
|
83
|
+
.restart-notice-text { flex: 1; }
|
|
84
|
+
.restart-btn { padding: 8px 16px; border-radius: 8px; border: none;
|
|
85
|
+
background: var(--accent); color: white; font-weight: 600; cursor: pointer;
|
|
86
|
+
font-size: 0.85rem; flex-shrink: 0; }
|
|
87
|
+
.restart-btn:hover { background: var(--accent-hover); }
|
|
88
|
+
.restart-btn:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
89
|
+
/* Destructive variant — visually distinct from the primary accent
|
|
90
|
+
so a glance at the page makes "Disable settings server"
|
|
91
|
+
obviously not a routine click. Matches the restart-notice red
|
|
92
|
+
family so the danger semantic reads even without label text. */
|
|
93
|
+
.danger-btn { padding: 7px 14px; border-radius: 8px;
|
|
94
|
+
border: 1px solid #7a1a1a; background: transparent; color: #ff9090;
|
|
95
|
+
font-weight: 600; cursor: pointer; font-size: 0.8rem; flex-shrink: 0; }
|
|
96
|
+
.danger-btn:hover { background: #2a0e0e; }
|
|
97
|
+
.danger-btn:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
98
|
+
/* Tabs — generic structure other tabs can stack onto without
|
|
99
|
+
touching existing markup. New tabs add a button to .tabs and
|
|
100
|
+
a sibling .panel below; the JS switcher dispatches via the
|
|
101
|
+
data-panel attribute. */
|
|
102
|
+
.tabs { display: flex; gap: 4px; margin-bottom: 16px; border-bottom: 1px solid var(--border); }
|
|
103
|
+
.tab { padding: 10px 16px; border: none; background: transparent; color: var(--text-secondary);
|
|
104
|
+
font-size: 0.95rem; cursor: pointer; border-bottom: 2px solid transparent; font-weight: 500; }
|
|
105
|
+
.tab.active { color: var(--text); border-bottom-color: var(--accent); }
|
|
106
|
+
.panel { display: none; }
|
|
107
|
+
.panel.active { display: block; }
|
|
108
|
+
/* Backups */
|
|
109
|
+
.backup-filters { display: flex; gap: 8px; margin-bottom: 12px; flex-wrap: wrap; }
|
|
110
|
+
.backup-filters input { padding: 8px 12px; border-radius: 8px; border: 1px solid var(--border);
|
|
111
|
+
background: var(--surface); color: var(--text); font-size: 0.85rem; }
|
|
112
|
+
.backup-filters input:focus { border-color: var(--accent); outline: none; }
|
|
113
|
+
.backup-filters button { padding: 8px 12px; border-radius: 8px; border: none;
|
|
114
|
+
background: var(--surface); color: var(--text); font-size: 0.85rem; cursor: pointer; }
|
|
115
|
+
.backup-filters button:hover { background: var(--surface-hover); }
|
|
116
|
+
.backup-filters button.danger { background: #3a1a1a; color: #ff6b6b; }
|
|
117
|
+
.backup-state { background: var(--surface); border-radius: 10px; padding: 10px 16px; margin-bottom: 12px;
|
|
118
|
+
font-size: 0.85rem; color: var(--text-secondary); display: flex; gap: 16px; flex-wrap: wrap; }
|
|
119
|
+
.backup-state span { display: inline-block; }
|
|
120
|
+
.backup-state strong { color: var(--text); }
|
|
121
|
+
.backup-row { background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
|
|
122
|
+
padding: 10px 14px; margin-bottom: 6px; display: flex; align-items: center; gap: 12px; }
|
|
123
|
+
.backup-row-info { flex: 1; min-width: 0; }
|
|
124
|
+
.backup-row-name { font-size: 0.9rem; font-weight: 500; word-break: break-all; }
|
|
125
|
+
.backup-row-meta { font-size: 0.75rem; color: var(--text-secondary); margin-top: 2px; }
|
|
126
|
+
.backup-row-actions { display: flex; gap: 6px; flex-shrink: 0; }
|
|
127
|
+
.backup-row-actions button { padding: 6px 10px; border-radius: 6px; border: none;
|
|
128
|
+
background: var(--accent); color: white; font-size: 0.8rem; cursor: pointer; }
|
|
129
|
+
.backup-row-actions button:hover { background: var(--accent-hover); }
|
|
130
|
+
.backup-row-actions button.danger { background: var(--danger); }
|
|
131
|
+
.backup-row-actions button.secondary { background: var(--surface-hover); color: var(--text); }
|
|
132
|
+
.backup-empty { padding: 24px; text-align: center; color: var(--text-secondary); font-size: 0.9rem;
|
|
133
|
+
background: var(--surface); border: 1px dashed var(--border); border-radius: 10px; }
|
|
134
|
+
.backup-config { background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
|
|
135
|
+
padding: 14px 16px; margin-bottom: 12px; }
|
|
136
|
+
.backup-config-form { display: grid; grid-template-columns: 1fr; gap: 10px; }
|
|
137
|
+
.backup-field { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
|
|
138
|
+
.backup-field-label { min-width: 200px; font-size: 0.9rem; font-weight: 500; }
|
|
139
|
+
.backup-field-control input[type="number"] { width: 120px; padding: 6px 10px;
|
|
140
|
+
border-radius: 6px; border: 1px solid var(--border); background: var(--bg); color: var(--text); }
|
|
141
|
+
.backup-field-control input[type="number"]:disabled { opacity: 0.55; cursor: not-allowed; }
|
|
142
|
+
.backup-field-locked { background: #2a2520; color: #f4b860; font-size: 0.78rem;
|
|
143
|
+
padding: 2px 8px; border-radius: 999px; }
|
|
144
|
+
.backup-field-help { font-size: 0.75rem; color: var(--text-secondary); flex-basis: 100%; margin-left: 200px; }
|
|
145
|
+
.backup-config-actions { display: flex; align-items: center; gap: 12px; margin-top: 10px;
|
|
146
|
+
padding-top: 10px; border-top: 1px solid var(--border); }
|
|
147
|
+
.backup-config-actions button { padding: 8px 16px; border-radius: 6px; border: none;
|
|
148
|
+
background: var(--accent); color: white; font-size: 0.9rem; cursor: pointer; font-weight: 500; }
|
|
149
|
+
.backup-config-actions button:hover { background: var(--accent-hover); }
|
|
150
|
+
.backup-config-actions button:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
151
|
+
/* Modal */
|
|
152
|
+
.modal-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,0.7);
|
|
153
|
+
display: none; align-items: center; justify-content: center; z-index: 10; padding: 16px; }
|
|
154
|
+
.modal-backdrop.show { display: flex; }
|
|
155
|
+
.modal { background: var(--bg); border: 1px solid var(--border); border-radius: 12px;
|
|
156
|
+
max-width: 900px; width: 100%; max-height: 90vh; display: flex; flex-direction: column; }
|
|
157
|
+
.modal-header { padding: 14px 16px; border-bottom: 1px solid var(--border);
|
|
158
|
+
display: flex; align-items: center; justify-content: space-between; gap: 12px; }
|
|
159
|
+
.modal-title { font-size: 1.05rem; font-weight: 600; word-break: break-all; }
|
|
160
|
+
.modal-close { background: transparent; border: none; color: var(--text-secondary);
|
|
161
|
+
font-size: 1.4rem; cursor: pointer; padding: 0 8px; }
|
|
162
|
+
.modal-body { flex: 1; overflow: auto; padding: 16px; }
|
|
163
|
+
.modal-body pre { background: var(--surface); padding: 12px; border-radius: 8px;
|
|
164
|
+
font-size: 0.8rem; overflow: auto; line-height: 1.4; }
|
|
165
|
+
.diff-add { color: #6bff6b; }
|
|
166
|
+
.diff-rem { color: #ff6b6b; }
|
|
167
|
+
.diff-hdr { color: #6cb4ff; }
|
|
168
|
+
/* Server-settings rows (#863). One row per FEATURE_FLAG_FIELDS
|
|
169
|
+
entry. Locked rows (env / addon origin) get the dim treatment +
|
|
170
|
+
a small inline note pointing at the env var to adjust. */
|
|
171
|
+
.features-sub { font-size: 0.75rem; color: var(--text-secondary);
|
|
172
|
+
margin-bottom: 8px; }
|
|
173
|
+
.feature-row { display: flex; align-items: flex-start; justify-content: space-between;
|
|
174
|
+
gap: 12px; padding: 10px 0; border-top: 1px solid var(--border); }
|
|
175
|
+
.feature-row:first-child { border-top: none; }
|
|
176
|
+
.feature-info { flex: 1; min-width: 0; }
|
|
177
|
+
.feature-name { font-size: 0.9rem; font-weight: 500; }
|
|
178
|
+
.feature-help { font-size: 0.75rem; color: var(--text-secondary); margin-top: 2px;
|
|
179
|
+
line-height: 1.4; }
|
|
180
|
+
.feature-help code { background: #111; padding: 1px 5px; border-radius: 4px;
|
|
181
|
+
font-size: 0.72rem; }
|
|
182
|
+
.feature-locked-note { font-size: 0.72rem; color: var(--warning); margin-top: 4px;
|
|
183
|
+
font-style: italic; }
|
|
184
|
+
.feature-control { flex-shrink: 0; display: flex; align-items: center; }
|
|
185
|
+
.feature-control input[type="number"] { width: 64px; padding: 4px 8px;
|
|
186
|
+
background: var(--bg); border: 1px solid var(--border); border-radius: 6px;
|
|
187
|
+
color: var(--text); font-size: 0.85rem; }
|
|
188
|
+
.feature-control input[type="number"]:disabled { opacity: 0.4; cursor: not-allowed; }
|
|
189
|
+
.feature-row.locked .feature-name { color: var(--text-secondary); }
|
|
190
|
+
/* Beta master toggle + nested sub-rows. The master row
|
|
191
|
+
``.beta-master-row`` is visually distinguished as a section
|
|
192
|
+
header. The 5 sub-rows ``.beta-sub`` are indented with a vertical
|
|
193
|
+
connector line on the left; when master is off they get
|
|
194
|
+
``.dimmed`` (reduced opacity + disabled inputs) to make the
|
|
195
|
+
gated state visible without removing rows from the DOM. */
|
|
196
|
+
.feature-row.beta-master-row { font-weight: 600; padding-top: 16px;
|
|
197
|
+
border-top: 2px solid var(--border); margin-top: 8px; }
|
|
198
|
+
.feature-row.beta-master-row .feature-help { font-weight: 400; }
|
|
199
|
+
.feature-row.beta-sub { padding-left: 32px; position: relative; }
|
|
200
|
+
.feature-row.beta-sub::before { content: ""; position: absolute;
|
|
201
|
+
left: 12px; top: 0; bottom: 0; width: 2px; background: var(--border); }
|
|
202
|
+
.feature-row.beta-sub.dimmed { opacity: 0.55; }
|
|
203
|
+
.feature-row.beta-sub.dimmed input { cursor: not-allowed; }
|
|
204
|
+
/* Code-mode sub-numerics — second-level nesting under the
|
|
205
|
+
enable_code_mode beta sub-row. Same dimming
|
|
206
|
+
logic as beta-sub but deeper-indented and gated by
|
|
207
|
+
enable_code_mode rather than the master. */
|
|
208
|
+
.feature-row.codemode-sub { padding-left: 56px; position: relative; }
|
|
209
|
+
.feature-row.codemode-sub::before { content: ""; position: absolute;
|
|
210
|
+
left: 36px; top: 0; bottom: 0; width: 2px; background: var(--border); }
|
|
211
|
+
.feature-row.codemode-sub.dimmed { opacity: 0.55; }
|
|
212
|
+
.feature-row.codemode-sub.dimmed input { cursor: not-allowed; }
|
|
213
|
+
/* YAML packages per-key sub-rows — second-level nested under
|
|
214
|
+
enable_yaml_config_editing. Same dimming logic as codemode-sub
|
|
215
|
+
but gated by enable_yaml_config_editing (the parent flag) rather
|
|
216
|
+
than enable_code_mode. */
|
|
217
|
+
.feature-row.yaml-packages-sub { padding-left: 56px; position: relative; }
|
|
218
|
+
.feature-row.yaml-packages-sub::before { content: ""; position: absolute;
|
|
219
|
+
left: 36px; top: 0; bottom: 0; width: 2px; background: var(--border); }
|
|
220
|
+
.feature-row.yaml-packages-sub.dimmed { opacity: 0.55; }
|
|
221
|
+
.feature-row.yaml-packages-sub.dimmed input { cursor: not-allowed; }
|
|
222
|
+
/* Advanced settings sections — one row per
|
|
223
|
+
ADVANCED_SETTINGS_FIELDS entry, grouped by section. Visually
|
|
224
|
+
matches the .feature-row treatment so the Server Settings tab
|
|
225
|
+
reads as one coherent surface. */
|
|
226
|
+
.adv-section-title { font-size: 0.85rem; font-weight: 600;
|
|
227
|
+
color: var(--text-secondary); margin: 20px 0 4px; text-transform: uppercase;
|
|
228
|
+
letter-spacing: 0.05em; }
|
|
229
|
+
/* Beta section header is visually distinct (warning color, slightly
|
|
230
|
+
larger) so the dangerous-features block at the bottom is impossible
|
|
231
|
+
to miss as a category boundary. */
|
|
232
|
+
.adv-section-title.beta-section-title { color: var(--warning);
|
|
233
|
+
font-size: 0.95rem; margin-top: 32px;
|
|
234
|
+
border-top: 1px solid var(--warning); padding-top: 16px; }
|
|
235
|
+
/* Two-step save note + primary-CTA save button.
|
|
236
|
+
The default <button> in this UI is intentionally small/neutral
|
|
237
|
+
because most surfaces have many of them; the Save row gets a
|
|
238
|
+
dedicated, larger primary style so users don't miss the action.
|
|
239
|
+
Duplicated at top and bottom so scrolling either way reaches it. */
|
|
240
|
+
.adv-save-note { background: rgba(255, 152, 0, 0.08);
|
|
241
|
+
border-left: 3px solid var(--warning); padding: 10px 14px;
|
|
242
|
+
border-radius: 6px; margin: 12px 0; color: var(--text);
|
|
243
|
+
font-size: 0.85rem; line-height: 1.4; }
|
|
244
|
+
.adv-save-note strong { color: var(--warning); }
|
|
245
|
+
.adv-save-row { display: flex; align-items: center; gap: 12px;
|
|
246
|
+
margin: 16px 0; padding: 8px 0; }
|
|
247
|
+
.adv-save-btn { padding: 10px 22px; font-size: 1rem; font-weight: 600;
|
|
248
|
+
border: none; border-radius: 8px; background: var(--accent);
|
|
249
|
+
color: white; cursor: pointer; box-shadow: 0 2px 6px rgba(0,0,0,0.15);
|
|
250
|
+
transition: background 0.15s ease, transform 0.05s ease; }
|
|
251
|
+
.adv-save-btn:hover { background: var(--accent-hover); }
|
|
252
|
+
.adv-save-btn:active { transform: translateY(1px); }
|
|
253
|
+
.adv-save-btn:disabled { opacity: 0.55; cursor: not-allowed;
|
|
254
|
+
box-shadow: none; }
|
|
255
|
+
.adv-section { border-top: 1px solid var(--border); }
|
|
256
|
+
.adv-row { display: flex; align-items: flex-start; justify-content: space-between;
|
|
257
|
+
gap: 12px; padding: 10px 0; border-top: 1px solid var(--border); }
|
|
258
|
+
.adv-row:first-child { border-top: none; }
|
|
259
|
+
.adv-row.locked .adv-name { color: var(--text-secondary); }
|
|
260
|
+
.adv-info { flex: 1; min-width: 0; }
|
|
261
|
+
.adv-name { font-size: 0.9rem; font-weight: 500; }
|
|
262
|
+
.adv-help { font-size: 0.75rem; color: var(--text-secondary); margin-top: 2px;
|
|
263
|
+
line-height: 1.4; }
|
|
264
|
+
.adv-help code { background: #111; padding: 1px 5px; border-radius: 4px;
|
|
265
|
+
font-size: 0.72rem; }
|
|
266
|
+
.adv-locked-note { font-size: 0.72rem; color: var(--warning); margin-top: 4px;
|
|
267
|
+
font-style: italic; }
|
|
268
|
+
.adv-control { flex-shrink: 0; display: flex; align-items: center; }
|
|
269
|
+
.adv-control input[type="text"],
|
|
270
|
+
.adv-control input[type="number"],
|
|
271
|
+
.adv-control select { padding: 4px 8px; background: var(--bg);
|
|
272
|
+
border: 1px solid var(--border); border-radius: 6px; color: var(--text);
|
|
273
|
+
font-size: 0.85rem; min-width: 120px; }
|
|
274
|
+
.adv-control input:disabled,
|
|
275
|
+
.adv-control select:disabled { opacity: 0.4; cursor: not-allowed; }
|
|
276
|
+
.adv-control input[type="checkbox"]:disabled { opacity: 0.4; cursor: not-allowed; }
|
|
277
|
+
/* Tool Security Policies — per-tool card layout.
|
|
278
|
+
Cards reuse the surface/border variables already in use elsewhere
|
|
279
|
+
so they read consistently with backup-row / group blocks. */
|
|
280
|
+
.policy-rule-card { background: var(--surface); border: 1px solid var(--border);
|
|
281
|
+
border-radius: 10px; padding: 12px 14px; margin: 8px 0; }
|
|
282
|
+
.policy-rule-header { display: flex; justify-content: space-between;
|
|
283
|
+
align-items: center; margin-bottom: 8px; }
|
|
284
|
+
.policy-rule-header strong { font-size: 0.95rem; }
|
|
285
|
+
.policy-rule-remove { background: transparent; border: none;
|
|
286
|
+
color: var(--text-secondary); cursor: pointer; font-size: 1.1rem;
|
|
287
|
+
padding: 0 6px; }
|
|
288
|
+
.policy-rule-remove:hover { color: var(--danger); }
|
|
289
|
+
.policy-predicate-list { list-style: none; padding: 0; margin: 6px 0; }
|
|
290
|
+
.policy-predicate-row { padding: 4px 0; display: flex; align-items: center;
|
|
291
|
+
gap: 8px; flex-wrap: wrap; }
|
|
292
|
+
.policy-predicate-row code { background: var(--bg); padding: 3px 8px;
|
|
293
|
+
border-radius: 4px; font-size: 0.8rem; color: var(--text); }
|
|
294
|
+
.policy-predicate-row button { background: transparent; border: none;
|
|
295
|
+
color: var(--accent); cursor: pointer; font-size: 0.8rem; padding: 2px 4px; }
|
|
296
|
+
.policy-predicate-row button:hover { text-decoration: underline; }
|
|
297
|
+
.policy-add-predicate { background: transparent; border: 1px dashed var(--border);
|
|
298
|
+
color: var(--accent); padding: 6px 12px; border-radius: 6px;
|
|
299
|
+
cursor: pointer; font-size: 0.85rem; margin-top: 4px; }
|
|
300
|
+
.policy-add-predicate:hover { background: var(--surface-hover); }
|
|
301
|
+
.policy-predicate-form { background: var(--bg); padding: 10px;
|
|
302
|
+
margin: 6px 0; border: 1px dashed var(--border); border-radius: 6px;
|
|
303
|
+
display: flex; flex-direction: column; gap: 8px; }
|
|
304
|
+
.policy-predicate-form .policy-form-row { display: flex; flex-wrap: wrap;
|
|
305
|
+
gap: 6px; align-items: center; }
|
|
306
|
+
.policy-predicate-form .policy-form-label { min-width: 90px;
|
|
307
|
+
color: var(--text-secondary); font-size: 0.82rem; }
|
|
308
|
+
.policy-predicate-form select,
|
|
309
|
+
.policy-predicate-form input { padding: 5px 8px; border-radius: 4px;
|
|
310
|
+
border: 1px solid var(--border); background: var(--surface);
|
|
311
|
+
color: var(--text); font-size: 0.85rem; }
|
|
312
|
+
.policy-predicate-form input.policy-predicate-path-custom { min-width: 200px; }
|
|
313
|
+
.policy-predicate-form input.policy-predicate-value { min-width: 220px;
|
|
314
|
+
font-family: monospace; }
|
|
315
|
+
.policy-predicate-form .policy-form-hint { font-size: 0.75rem;
|
|
316
|
+
color: var(--text-secondary); padding-left: 96px; margin-top: -4px; }
|
|
317
|
+
.policy-predicate-form-error { color: var(--danger); font-size: 0.78rem;
|
|
318
|
+
width: 100%; margin-top: 4px; }
|
|
319
|
+
.policy-rule-lifetime { margin: 10px 0; font-size: 0.85rem;
|
|
320
|
+
color: var(--text-secondary); }
|
|
321
|
+
.policy-rule-lifetime input { width: 64px; padding: 4px 8px;
|
|
322
|
+
background: var(--bg); border: 1px solid var(--border); border-radius: 6px;
|
|
323
|
+
color: var(--text); font-size: 0.85rem; margin: 0 6px; }
|
|
324
|
+
.policy-save-status { margin-left: 10px; font-size: 0.8rem;
|
|
325
|
+
color: var(--text-secondary); }
|