panda-core 0.10.2 → 0.10.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f1ca00630306c920fd7c8b7a5c8703532d44c6f24e1960b5a070f5083ee9d467
4
- data.tar.gz: aaebba3e769ccba28420bb69680d461558b6371e88977c38846e8180d045acce
3
+ metadata.gz: 8d4b3734fe5d4d3069de18577b15798b3f298c570c2beae95a925258a18b3fda
4
+ data.tar.gz: 7919623012d8fb85284d8a36267f3839a3d0014bd079d6dd839b9ab438a30486
5
5
  SHA512:
6
- metadata.gz: 9b4235040de9088b17e648d1085c3740129dd62a0d319ff4548d32e979bf425caf1b3fe80a4491898fef8a42d61517cb5fe2d3c55f1f949f707f8708e8eabf27
7
- data.tar.gz: c4afb07c75306e2e6a2a689f3fc24c89bc62c274b71f6d5d8490d6874f5776afd318fc4dbb74bcca4f67e74ab1555d4bbb72d5704daa640eb4e6b58167ba9231
6
+ metadata.gz: 63ad835a105fe5c0570fd7d2c17ec3fcd54da14a1649cefe45af5655158bbb13fd19a07cfb1b02d8590329c5d4b4e53502e1b23e77c376e14c7698dfd876ddff
7
+ data.tar.gz: f51bf40a3a6d9c32dbea4b15bce90dec72405f694c826b3ba538e5aa26c12eb7c0465692056b46c1dcebee212458d807f310c10cd6cd1879115139696a9ae649
@@ -13,45 +13,34 @@ module Panda
13
13
  # This is the single entry point for all Panda JavaScript loading.
14
14
  # It automatically includes JavaScript from Core and all registered modules
15
15
  # via ModuleRegistry.
16
+ #
17
+ # Note: Always uses importmap (Rails 8 approach), regardless of asset source
16
18
  def panda_core_javascript
17
- # Use asset_tags for development mode (importmap) compatibility
18
- # In development, this will use importmap; in production/test, compiled bundles
19
- if Panda::Core::AssetLoader.use_github_assets?
20
- js_url = Panda::Core::AssetLoader.javascript_url
21
- return "" unless js_url
22
-
23
- if js_url.start_with?("/panda-core-assets/")
24
- javascript_include_tag(js_url)
25
- else
26
- javascript_include_tag(js_url, type: "module")
27
- end
28
- else
29
- # Development mode - Use ModuleRegistry to combine all Panda module importmaps
30
- imports = Panda::Core::ModuleRegistry.combined_importmap
19
+ # Use ModuleRegistry to combine all Panda module importmaps
20
+ imports = Panda::Core::ModuleRegistry.combined_importmap
31
21
 
32
- importmap_json = JSON.generate({"imports" => imports})
22
+ importmap_json = JSON.generate({"imports" => imports})
33
23
 
34
- # Generate entry point script tags for all registered modules (including Core)
35
- entry_points = []
24
+ # Generate entry point script tags for all registered modules (including Core)
25
+ entry_points = []
36
26
 
37
- # Add entry points for each registered module
38
- Panda::Core::ModuleRegistry.modules.each do |gem_name, info|
39
- # Extract module namespace from gem name (e.g., "panda-cms" -> "cms")
40
- module_slug = gem_name.sub(/^panda-/, "")
27
+ # Add entry points for each registered module
28
+ Panda::Core::ModuleRegistry.modules.each do |gem_name, info|
29
+ # Extract module namespace from gem name (e.g., "panda-cms" -> "cms")
30
+ module_slug = gem_name.sub(/^panda-/, "")
41
31
 
42
- # Check if the module is actually loaded
43
- module_name = info[:engine].sub(/::Engine$/, "")
44
- next unless Object.const_defined?(module_name)
32
+ # Check if the module is actually loaded
33
+ module_name = info[:engine].sub(/::Engine$/, "")
34
+ next unless Object.const_defined?(module_name)
45
35
 
46
- entry_points << %(<script type="module">import "panda/#{module_slug}/application"</script>)
47
- entry_points << %(<script type="module">import "panda/#{module_slug}/controllers/index"</script>)
48
- end
49
-
50
- <<~HTML.html_safe
51
- <script type="importmap">#{importmap_json}</script>
52
- #{entry_points.join("\n")}
53
- HTML
36
+ entry_points << %(<script type="module">import "panda/#{module_slug}/application"</script>)
37
+ entry_points << %(<script type="module">import "panda/#{module_slug}/controllers/index"</script>)
54
38
  end
39
+
40
+ <<~HTML.html_safe
41
+ <script type="importmap">#{importmap_json}</script>
42
+ #{entry_points.join("\n")}
43
+ HTML
55
44
  end
56
45
 
57
46
  # Include only Core CSS
@@ -1,8 +1,13 @@
1
- import { Application } from "@hotwired/stimulus"
2
- import "@fortawesome/fontawesome-free"
1
+ import { Application } from '@hotwired/stimulus'
2
+ import '@fortawesome/fontawesome-free'
3
3
 
4
4
  const application = Application.start()
5
5
 
6
+ // Always propagate Stimulus controller errors for better debugging
7
+ application.handleError = (error, message, detail) => {
8
+ throw error
9
+ }
10
+
6
11
  // Configure Stimulus development experience
7
12
  application.debug = false
8
13
  window.Stimulus = application
@@ -14,4 +19,4 @@ export { application }
14
19
 
15
20
  // Tailwind Plus Elements can be loaded by importing "panda/core/tailwindplus-elements"
16
21
  // or by adding the script tag directly to your HTML:
17
- // <script src="https://cdn.jsdelivr.net/npm/@tailwindplus/elements@1" type="module"></script>
22
+ // <script src="https://cdn.jsdelivr.net/npm/@tailwindplus/elements@1" type="module"></script>
@@ -43,10 +43,18 @@ module Panda
43
43
  # This allows system tests to load CSS/JS from the engine's public directory
44
44
  return false if Rails.env.test? || in_test_environment?
45
45
 
46
- # Use GitHub assets in production or when explicitly enabled
47
- Rails.env.production? ||
48
- ENV["PANDA_CORE_USE_GITHUB_ASSETS"] == "true" ||
49
- !development_assets_available?
46
+ # In production, prefer local compiled assets over GitHub
47
+ # Only use GitHub assets when explicitly enabled or when local assets aren't available
48
+ if Rails.env.production?
49
+ # Check if compiled assets exist locally
50
+ return false if compiled_assets_available?
51
+
52
+ # Only use GitHub as fallback if explicitly enabled
53
+ return ENV["PANDA_CORE_USE_GITHUB_ASSETS"] == "true"
54
+ end
55
+
56
+ # In development, use GitHub assets only when explicitly enabled or development assets unavailable
57
+ ENV["PANDA_CORE_USE_GITHUB_ASSETS"] == "true" || !development_assets_available?
50
58
  end
51
59
 
52
60
  private
@@ -57,26 +65,16 @@ module Panda
57
65
 
58
66
  tags = []
59
67
 
60
- # JavaScript tag with integrity check
61
- js_url = "#{base_url}panda-core-#{version}.js"
62
-
63
- js_attrs = {
64
- src: js_url
68
+ # CSS tag - load from main branch (always latest)
69
+ css_url = "#{base_url}panda-core.css"
70
+ css_attrs = {
71
+ rel: "stylesheet",
72
+ href: css_url
65
73
  }
66
- # In CI environment, don't use defer to ensure immediate execution
67
- js_attrs[:defer] = true unless ENV["GITHUB_ACTIONS"] == "true"
68
-
69
- tags << content_tag(:script, "", js_attrs)
74
+ tags << tag(:link, css_attrs)
70
75
 
71
- # CSS tag if CSS bundle exists
72
- css_url = "#{base_url}panda-core-#{version}.css"
73
- if github_asset_exists?(version, "panda-core-#{version}.css")
74
- css_attrs = {
75
- rel: "stylesheet",
76
- href: css_url
77
- }
78
- tags << tag(:link, css_attrs)
79
- end
76
+ # Note: JavaScript uses importmap (no bundled file needed)
77
+ # The importmap is generated in panda_core_javascript helper
80
78
 
81
79
  tags.join("\n").html_safe
82
80
  end
@@ -126,13 +124,9 @@ module Panda
126
124
  end
127
125
 
128
126
  def github_javascript_url
129
- version = asset_version
130
- # In test environment with local compiled assets, use local URL
131
- if Rails.env.test? && compiled_assets_available?
132
- "/panda-core-assets/panda-core-#{version}.js"
133
- else
134
- "#{github_base_url(version)}panda-core-#{version}.js"
135
- end
127
+ # JavaScript uses importmap - no bundled file needed
128
+ # This method is kept for compatibility but shouldn't be used
129
+ nil
136
130
  end
137
131
 
138
132
  def github_css_url
@@ -142,7 +136,8 @@ module Panda
142
136
  css_file = "/panda-core-assets/panda-core-#{version}.css"
143
137
  File.exist?(Rails.root.join("public#{css_file}")) ? css_file : nil
144
138
  else
145
- "#{github_base_url(version)}panda-core-#{version}.css"
139
+ # Load unversioned CSS from main branch (always latest)
140
+ "#{github_base_url(version)}panda-core.css"
146
141
  end
147
142
  end
148
143
 
@@ -189,7 +184,7 @@ module Panda
189
184
  end
190
185
 
191
186
  def github_base_url(version)
192
- "https://github.com/tastybamboo/panda-core/releases/download/v#{version}/"
187
+ "https://raw.githubusercontent.com/tastybamboo/panda-core/main/public/panda-core-assets/"
193
188
  end
194
189
 
195
190
  def github_asset_exists?(_version, _filename)
@@ -204,10 +199,18 @@ module Panda
204
199
  end
205
200
 
206
201
  def compiled_assets_available?
207
- # Check if compiled assets exist in test location
202
+ # Check if compiled assets exist
208
203
  version = asset_version
209
- js_file = Rails.public_path.join("panda-core-assets", "panda-core-#{version}.js")
210
- js_file.exist?
204
+
205
+ # In production/hosting app, check the app's public directory first
206
+ if defined?(Rails.public_path)
207
+ app_js_file = Rails.public_path.join("panda-core-assets", "panda-core-#{version}.js")
208
+ return true if app_js_file.exist?
209
+ end
210
+
211
+ # Fall back to checking the engine's public directory
212
+ engine_js_file = Panda::Core::Engine.root.join("public", "panda-core-assets", "panda-core-#{version}.js")
213
+ engine_js_file.exist?
211
214
  end
212
215
 
213
216
  def in_test_environment?
@@ -8,6 +8,24 @@ module Panda
8
8
  extend ActiveSupport::Concern
9
9
 
10
10
  included do
11
+ # Exclude preview paths from production eager loading
12
+ # Preview classes should only be loaded in development/test environments
13
+ initializer "panda_core.exclude_previews_from_production", before: :set_autoload_paths do |app|
14
+ if Rails.env.production?
15
+ # Prevent eager loading of preview files in production
16
+ preview_paths = [
17
+ root.join("spec/components/previews").to_s
18
+ ]
19
+
20
+ preview_paths.each do |preview_path|
21
+ if Dir.exist?(preview_path)
22
+ app.config.eager_load_paths.delete(preview_path)
23
+ ActiveSupport::Dependencies.autoload_paths.delete(preview_path)
24
+ end
25
+ end
26
+ end
27
+ end
28
+
11
29
  # Load Phlex base component after Rails application is initialized
12
30
  # This ensures Rails.application.routes is available
13
31
  initializer "panda_core.phlex_base", after: :load_config_initializers do
@@ -1,6 +1,5 @@
1
1
  require "rubygems"
2
2
  require "stringio"
3
-
4
3
  require "rails/engine"
5
4
  require "omniauth"
6
5
 
@@ -24,7 +23,6 @@ require_relative "shared/inflections_config"
24
23
  require_relative "shared/generator_config"
25
24
 
26
25
  # Load engine configuration modules
27
- require_relative "engine/test_config"
28
26
  require_relative "engine/autoload_config"
29
27
  require_relative "engine/middleware_config"
30
28
  require_relative "engine/importmap_config"
@@ -45,7 +43,6 @@ module Panda
45
43
  include Shared::GeneratorConfig
46
44
 
47
45
  # Include engine-specific configuration modules
48
- include TestConfig
49
46
  include AutoloadConfig
50
47
  include MiddlewareConfig
51
48
  include ImportmapConfig
@@ -58,10 +55,12 @@ module Panda
58
55
  end
59
56
 
60
57
  # Static asset middleware for serving public files and JavaScript modules
61
- # Must run before Propshaft to intercept /panda/* requests
58
+ # Must run before Propshaft to intercept /panda/* requests, but we can't
59
+ # guarantee Propshaft is in the host application, so just insert it
60
+ # high up in the middleware stack
62
61
  initializer "panda.core.static_assets" do |app|
63
62
  # Serve public assets (CSS, images, etc.)
64
- app.config.middleware.insert_before Propshaft::Server, Rack::Static,
63
+ app.config.middleware.insert_before ActionDispatch::Static, Rack::Static,
65
64
  urls: ["/panda-core-assets"],
66
65
  root: Panda::Core::Engine.root.join("public"),
67
66
  header_rules: [
@@ -71,48 +70,7 @@ module Panda
71
70
 
72
71
  # Use ModuleRegistry's custom middleware to serve JavaScript from all registered modules
73
72
  # This middleware checks all modules and serves from the first matching location
74
- app.config.middleware.insert_before Propshaft::Server, Panda::Core::ModuleRegistry::JavaScriptMiddleware
75
- end
76
-
77
- # Auto-compile CSS for test/development environments
78
- initializer "panda_core.auto_compile_assets", after: :load_config_initializers do |app|
79
- # Only auto-compile in test or when explicitly requested
80
- next unless Rails.env.test? || ENV["PANDA_CORE_AUTO_COMPILE"] == "true"
81
-
82
- # Use timestamp for cache busting in dev/test
83
- timestamp = Time.now.to_i
84
- assets_dir = Panda::Core::Engine.root.join("public", "panda-core-assets")
85
- timestamped_css = assets_dir.join("panda-core-#{timestamp}.css")
86
-
87
- # Check if any compiled CSS exists (timestamp-based)
88
- existing_css = Dir[assets_dir.join("panda-core-*.css")].reject { |f| File.symlink?(f) }
89
-
90
- if existing_css.empty?
91
- warn "🐼 [Panda Core] Auto-compiling CSS for test environment..."
92
-
93
- # Compile CSS with timestamp
94
- require "open3"
95
-
96
- content_paths = Panda::Core::ModuleRegistry.tailwind_content_paths
97
- content_flags = content_paths.map { |path| "--content '#{path}'" }.join(" ")
98
-
99
- # Compile directly to timestamped file with all registered module content
100
- input_file = Panda::Core::Engine.root.join("app/assets/tailwind/application.css")
101
- cmd = "bundle exec tailwindcss -i #{input_file} -o #{timestamped_css} #{content_flags} --minify"
102
-
103
- _, stderr, status = Open3.capture3(cmd)
104
-
105
- if status.success?
106
- # Create unversioned symlink for fallback
107
- symlink = assets_dir.join("panda-core.css")
108
- FileUtils.rm_f(symlink) if File.exist?(symlink)
109
- FileUtils.ln_sf(File.basename(timestamped_css), symlink)
110
-
111
- warn "🐼 [Panda Core] CSS compilation successful (#{timestamped_css.size} bytes)"
112
- else
113
- warn "🐼 [Panda Core] CSS compilation failed: #{stderr}"
114
- end
115
- end
73
+ app.config.middleware.insert_before ActionDispatch::Static, Panda::Core::ModuleRegistry::JavaScriptMiddleware
116
74
  end
117
75
  end
118
76
  end
@@ -61,8 +61,11 @@ RSpec.configure do |config|
61
61
  if ENV["GITHUB_ACTIONS"] == "true"
62
62
  require "rspec/github"
63
63
  config.add_formatter RSpec::Github::Formatter
64
- # Also add documentation formatter for colored real-time output in CI logs
65
- config.add_formatter RSpec::Core::Formatters::DocumentationFormatter, $stdout
64
+ # Also add documentation formatter for colored real-time output in CI logs,
65
+ # but avoid double-printing when one is already configured (e.g. via CLI).
66
+ unless config.formatters.any? { |formatter| formatter.is_a?(RSpec::Core::Formatters::DocumentationFormatter) }
67
+ config.add_formatter RSpec::Core::Formatters::DocumentationFormatter, $stdout
68
+ end
66
69
  end
67
70
 
68
71
  # Controller testing support (if rails-controller-testing is available)
@@ -134,13 +134,13 @@ module Panda
134
134
  visit "/admin/test_login/#{user.id}?return_to=#{return_path}"
135
135
 
136
136
  # Wait briefly for session to be set
137
- sleep 0.2
137
+ # sleep 0.2
138
138
 
139
139
  # Manually visit the destination since Cuprite doesn't reliably follow redirects
140
140
  if expect_success
141
141
  visit return_path
142
142
  # Wait for page to load
143
- sleep 0.2
143
+ # sleep 0.2
144
144
 
145
145
  # Verify we're on the expected path
146
146
  expect(page).to have_current_path(return_path, wait: 2)
@@ -114,7 +114,7 @@ module Panda
114
114
  end
115
115
 
116
116
  # Wait for DOM to be ready
117
- sleep 0.5
117
+ # sleep 0.5
118
118
 
119
119
  # Get comprehensive page info
120
120
  page_html = begin
@@ -9,7 +9,15 @@ module BrowserConsoleLogger
9
9
 
10
10
  if respond_to?(:page) && page.driver.is_a?(Capybara::Cuprite::Driver)
11
11
  begin
12
- console_logs = page.driver.browser.console_messages
12
+ # Access the console logger via the CupriteSetup module
13
+ console_logger = Panda::Core::Testing::CupriteSetup.console_logger
14
+
15
+ unless console_logger
16
+ puts "\n⚠️ Console logger not available"
17
+ next
18
+ end
19
+
20
+ console_logs = console_logger.logs
13
21
 
14
22
  if console_logs.any?
15
23
  puts "\n" + "=" * 80
@@ -17,17 +25,15 @@ module BrowserConsoleLogger
17
25
  puts "=" * 80
18
26
 
19
27
  console_logs.each_with_index do |msg, index|
20
- type_icon = case msg["type"]
28
+ level = msg.level.downcase
29
+ type_icon = case level
21
30
  when "error" then "❌"
22
31
  when "warning" then "⚠️"
23
32
  when "info" then "ℹ️"
24
33
  else "📝"
25
34
  end
26
35
 
27
- puts "#{index + 1}. [#{msg["type"].upcase}] #{type_icon}"
28
- puts " Message: #{msg["message"]}"
29
- puts " Source: #{msg["source"]}" if msg["source"]
30
- puts " Line: #{msg["line"]}" if msg["line"]
36
+ puts "#{index + 1}. #{type_icon} #{msg}"
31
37
  puts ""
32
38
  end
33
39
 
@@ -37,6 +43,7 @@ module BrowserConsoleLogger
37
43
  end
38
44
  rescue => e
39
45
  puts "\n⚠️ Failed to capture console logs: #{e.message}"
46
+ puts " #{e.class}: #{e.backtrace.first(3).join("\n ")}" if ENV["DEBUG"]
40
47
  end
41
48
  end
42
49
  end
@@ -47,13 +47,16 @@ Capybara.register_server :puma_ci do |app, port, host|
47
47
  raise e
48
48
  end
49
49
 
50
+ # Allow conditional silencing of server logs via CAPYBARA_SERVER_VERBOSE
51
+ verbose = ENV.fetch("CAPYBARA_SERVER_VERBOSE", "false") == "true"
52
+
50
53
  options = {
51
54
  Host: host,
52
55
  Port: port,
53
56
  Threads: "#{min_threads}:#{max_threads}",
54
57
  Workers: 0,
55
- Silent: false, # Always verbose in CI to catch startup errors
56
- Verbose: true,
58
+ Silent: !verbose,
59
+ Verbose: verbose,
57
60
  PreloadApp: false
58
61
  }
59
62
 
@@ -44,7 +44,7 @@ module Panda
44
44
  ready = page.evaluate_script("document.readyState")
45
45
  break if ready == "complete"
46
46
 
47
- sleep 0.1
47
+ # sleep 0.1
48
48
  end
49
49
  end
50
50
  rescue Timeout::Error
@@ -64,7 +64,7 @@ module Panda
64
64
  end
65
65
  break if loaded
66
66
 
67
- sleep 0.1
67
+ # sleep 0.1
68
68
  end
69
69
  end
70
70
  true
@@ -82,7 +82,7 @@ module Panda
82
82
  while Time.now - start_time < timeout
83
83
  return true if page.has_css?(selector, visible: true)
84
84
 
85
- sleep 0.1
85
+ # sleep 0.1
86
86
  end
87
87
  false
88
88
  end
@@ -96,7 +96,7 @@ module Panda
96
96
  while Time.now - start_time < timeout
97
97
  return true if page.has_text?(text)
98
98
 
99
- sleep 0.1
99
+ # sleep 0.1
100
100
  end
101
101
  false
102
102
  end
@@ -122,7 +122,7 @@ module Panda
122
122
  while Time.now - start_time < timeout
123
123
  return true if page.html != initial_dom
124
124
 
125
- sleep 0.1
125
+ # sleep 0.1
126
126
  end
127
127
  false
128
128
  end
@@ -147,7 +147,7 @@ module Panda
147
147
  def click_on_selectors(*css_selectors)
148
148
  css_selectors.each do |selector|
149
149
  find(selector).click
150
- sleep 0.1 # Add a small delay to allow JavaScript to run
150
+ # sleep 0.1 # Add a small delay to allow JavaScript to run
151
151
  end
152
152
  end
153
153
 
@@ -160,7 +160,7 @@ module Panda
160
160
  while Time.now - start_time < timeout
161
161
  return true if page.has_field?(field_name, with: value)
162
162
 
163
- sleep 0.1
163
+ # sleep 0.1
164
164
  end
165
165
  false
166
166
  end
@@ -179,7 +179,7 @@ module Panda
179
179
 
180
180
  if retries <= 2 && elapsed < max_duration && ENV["GITHUB_ACTIONS"]
181
181
  puts "[CI] Element not found on fill_in '#{locator}', retry #{retries}/2 (#{elapsed.round(1)}s elapsed)"
182
- sleep 0.5
182
+ # sleep 0.5
183
183
  retry
184
184
  else
185
185
  puts "[CI] Giving up on fill_in '#{locator}' after #{retries} retries and #{elapsed.round(1)}s" if ENV["GITHUB_ACTIONS"]
@@ -201,7 +201,7 @@ module Panda
201
201
 
202
202
  if retries <= 2 && elapsed < max_duration && ENV["GITHUB_ACTIONS"]
203
203
  puts "[CI] Element not found on select '#{value}' from '#{from}', retry #{retries}/2 (#{elapsed.round(1)}s elapsed)"
204
- sleep 0.5
204
+ # sleep 0.5
205
205
  retry
206
206
  else
207
207
  puts "[CI] Giving up on select '#{value}' from '#{from}' after #{retries} retries and #{elapsed.round(1)}s" if ENV["GITHUB_ACTIONS"]
@@ -223,7 +223,7 @@ module Panda
223
223
 
224
224
  if retries <= 2 && elapsed < max_duration && ENV["GITHUB_ACTIONS"]
225
225
  puts "[CI] Element not found on click_button '#{locator}', retry #{retries}/2 (#{elapsed.round(1)}s elapsed)"
226
- sleep 0.5
226
+ # sleep 0.5
227
227
  retry
228
228
  else
229
229
  puts "[CI] Giving up on click_button '#{locator}' after #{retries} retries and #{elapsed.round(1)}s" if ENV["GITHUB_ACTIONS"]
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "ferrum"
4
4
  require "capybara/cuprite"
5
+ require_relative "ferrum_console_logger"
5
6
 
6
7
  # Shared Cuprite driver configuration for all Panda gems
7
8
  # This provides standard Cuprite setup with sensible defaults that work across gems
@@ -17,6 +18,14 @@ module Panda
17
18
  module Core
18
19
  module Testing
19
20
  module CupriteSetup
21
+ # Class variable to store the console logger instance
22
+ # This allows tests to access console logs after they run
23
+ @console_logger = nil
24
+
25
+ class << self
26
+ attr_accessor :console_logger
27
+ end
28
+
20
29
  # Base Cuprite options shared across all drivers
21
30
  def self.base_options
22
31
  default_timeout = 2
@@ -46,7 +55,8 @@ module Panda
46
55
  "ignore-certificate-errors": nil,
47
56
  "allow-insecure-localhost": nil,
48
57
  "enable-features": "NetworkService,NetworkServiceInProcess",
49
- "disable-blink-features": "AutomationControlled"
58
+ "disable-blink-features": "AutomationControlled",
59
+ "no-dbus": true
50
60
  }
51
61
  }
52
62
  end
@@ -67,8 +77,15 @@ module Panda
67
77
  # Add CI-specific options
68
78
  if ENV["GITHUB_ACTIONS"] == "true"
69
79
  options[:browser_options].merge!(ci_browser_options)
80
+
81
+ # Ensure CI uses xvfb to run the browser
82
+ options[:browser_options][:xvfb] = true
70
83
  end
71
84
 
85
+ # Create console logger for capturing browser console messages
86
+ self.console_logger = Panda::Core::Testing::Support::System::FerrumConsoleLogger.new
87
+ options[:logger] = console_logger
88
+
72
89
  Capybara.register_driver :cuprite do |app|
73
90
  Capybara::Cuprite::Driver.new(app, **options)
74
91
  end
@@ -83,6 +100,9 @@ module Panda
83
100
  options[:browser_options].merge!(ci_browser_options)
84
101
  end
85
102
 
103
+ # Use the same console logger instance for mobile driver
104
+ options[:logger] = console_logger if console_logger
105
+
86
106
  Capybara.register_driver :cuprite_mobile do |app|
87
107
  Capybara::Cuprite::Driver.new(app, **options)
88
108
  end
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+
5
+ module Panda
6
+ module Core
7
+ module Testing
8
+ module Support
9
+ module System
10
+ # Custom logger for capturing browser console messages via Ferrum/Cuprite
11
+ # Ferrum doesn't provide a direct API for console messages - instead it uses
12
+ # Chrome DevTools Protocol (CDP) events that are sent to a logger object
13
+ class FerrumConsoleLogger
14
+ attr_reader :logs
15
+
16
+ def initialize
17
+ @logs = []
18
+ end
19
+
20
+ # Ferrum calls this method with CDP protocol events
21
+ # Format: "SEND message_id {json}" or "RECV message_id {json}"
22
+ def puts(log_str)
23
+ return unless log_str.is_a?(String)
24
+
25
+ parts = log_str.strip.split(" ", 3)
26
+ return if parts.size < 3
27
+
28
+ # Parse the JSON data from CDP event
29
+ data = JSON.parse(parts[2])
30
+
31
+ # Only capture console-related events
32
+ if console_event?(data)
33
+ @logs << Message.new(log_str)
34
+ end
35
+ rescue JSON::ParserError
36
+ # Silently ignore malformed JSON
37
+ end
38
+
39
+ def clear
40
+ @logs.clear
41
+ end
42
+
43
+ private
44
+
45
+ def console_event?(data)
46
+ %w[
47
+ Runtime.exceptionThrown
48
+ Log.entryAdded
49
+ Runtime.consoleAPICalled
50
+ ].include?(data["method"])
51
+ end
52
+
53
+ # Wrapper for a single console message
54
+ class Message
55
+ def initialize(log_str)
56
+ parts = log_str.strip.split(" ", 3)
57
+ @raw = log_str
58
+ @data = JSON.parse(parts[2])
59
+ end
60
+
61
+ # Get the log level (error, warning, info, etc.)
62
+ def level
63
+ # Different CDP events structure level differently
64
+ @data.dig("params", "entry", "level") ||
65
+ @data.dig("params", "type") ||
66
+ "log"
67
+ end
68
+
69
+ # Get the message text
70
+ def message
71
+ # Handle different CDP event types
72
+ if @data["method"] == "Runtime.exceptionThrown"
73
+ exception = @data.dig("params", "exceptionDetails")
74
+ if exception
75
+ text = exception.dig("exception", "description") || exception["text"]
76
+ location = "#{exception.dig("url")}:#{exception.dig("lineNumber")}"
77
+ "#{text} (#{location})"
78
+ else
79
+ "Unknown exception"
80
+ end
81
+ elsif @data["method"] == "Log.entryAdded"
82
+ @data.dig("params", "entry", "text") || ""
83
+ elsif @data["method"] == "Runtime.consoleAPICalled"
84
+ # Console API calls have arguments that need to be extracted
85
+ args = @data.dig("params", "args") || []
86
+ args.map { |arg| format_argument(arg) }.join(" ")
87
+ else
88
+ @raw
89
+ end
90
+ end
91
+
92
+ # Format a CDP RemoteObject argument
93
+ def format_argument(arg)
94
+ case arg["type"]
95
+ when "string"
96
+ arg["value"]
97
+ when "number", "boolean"
98
+ arg["value"].to_s
99
+ when "undefined"
100
+ "undefined"
101
+ when "object"
102
+ if arg["subtype"] == "null"
103
+ "null"
104
+ else
105
+ arg["description"] || "[Object]"
106
+ end
107
+ else
108
+ arg["description"] || arg.inspect
109
+ end
110
+ end
111
+
112
+ def to_s
113
+ "[#{level.upcase}] #{message}"
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
@@ -102,7 +102,7 @@ RSpec.configure do |config|
102
102
  nil
103
103
  end
104
104
 
105
- sleep 0.5
105
+ # sleep 0.5
106
106
 
107
107
  # Get comprehensive page info
108
108
  page_html = begin
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Panda
4
4
  module Core
5
- # Version 0.10.2 - Fix JavaScript middleware fallback for CI environments
6
- VERSION = "0.10.2"
5
+ # Version 0.10.5 - Fix browser startup in CI with --no-dbus flag
6
+ VERSION = "0.10.5"
7
7
  end
8
8
  end
data/lib/panda/core.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "rails"
4
+ # require "active_support/core_ext/module/attribute_accessors"
4
5
 
5
6
  module Panda
6
7
  module Core
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: panda-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.2
4
+ version: 0.10.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Otaina Limited
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2025-11-16 00:00:00.000000000 Z
12
+ date: 2025-11-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: image_processing
@@ -500,7 +500,6 @@ files:
500
500
  - lib/panda/core/engine/middleware_config.rb
501
501
  - lib/panda/core/engine/omniauth_config.rb
502
502
  - lib/panda/core/engine/phlex_config.rb
503
- - lib/panda/core/engine/test_config.rb
504
503
  - lib/panda/core/media.rb
505
504
  - lib/panda/core/module_registry.rb
506
505
  - lib/panda/core/notifications.rb
@@ -527,13 +526,13 @@ files:
527
526
  - lib/panda/core/testing/support/system/cuprite_helpers.rb
528
527
  - lib/panda/core/testing/support/system/cuprite_setup.rb
529
528
  - lib/panda/core/testing/support/system/database_connection_helpers.rb
529
+ - lib/panda/core/testing/support/system/ferrum_console_logger.rb
530
530
  - lib/panda/core/testing/support/system/system_test_helpers.rb
531
531
  - lib/panda/core/version.rb
532
532
  - lib/tasks/panda/core/migrations.rake
533
533
  - lib/tasks/panda_core.rake
534
534
  - lib/tasks/panda_core_tasks.rake
535
535
  - lib/tasks/panda_core_users.rake
536
- - public/panda-core-assets/panda-core-0.7.5.css
537
536
  - public/panda-core-assets/panda-core-0.8.0.css
538
537
  - public/panda-core-assets/panda-core.css
539
538
  homepage: https://github.com/tastybamboo/panda-core
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Panda
4
- module Core
5
- class Engine < ::Rails::Engine
6
- # Test environment configuration
7
- module TestConfig
8
- extend ActiveSupport::Concern
9
-
10
- included do
11
- # For testing: Don't expose engine migrations since we use "copy to host app" strategy
12
- # In test environment, migrations should be copied to the host app
13
- if Rails.env.test?
14
- config.paths["db/migrate"] = []
15
- end
16
- end
17
- end
18
- end
19
- end
20
- end
@@ -1,2 +0,0 @@
1
- /*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */
2
- @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-space-x-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-ease:initial;--tw-content:""}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-serif:ui-serif,Georgia,Cambria,"Times New Roman",Times,serif;--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-100:oklch(93.6% .032 17.717);--color-red-200:oklch(88.5% .062 18.334);--color-red-300:oklch(80.8% .114 19.571);--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-yellow-50:oklch(98.7% .026 102.212);--color-yellow-400:oklch(85.2% .199 91.936);--color-yellow-500:oklch(79.5% .184 86.047);--color-yellow-600:oklch(68.1% .162 75.834);--color-yellow-700:oklch(55.4% .135 66.442);--color-yellow-800:oklch(47.6% .114 61.907);--color-green-50:oklch(98.2% .018 155.826);--color-green-100:oklch(96.2% .044 156.743);--color-green-400:oklch(79.2% .209 151.711);--color-green-500:oklch(72.3% .219 149.579);--color-green-600:oklch(62.7% .194 149.214);--color-green-700:oklch(52.7% .154 150.069);--color-sky-50:oklch(97.7% .013 236.62);--color-sky-700:oklch(50% .134 242.749);--color-blue-50:oklch(97% .014 254.604);--color-blue-100:oklch(93.2% .032 255.585);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-indigo-300:var(--color-primary-300);--color-indigo-400:var(--color-primary-400);--color-indigo-500:var(--color-primary-500);--color-indigo-600:var(--color-primary-600);--color-indigo-900:var(--color-primary-900);--color-purple-100:oklch(94.6% .033 307.174);--color-purple-400:oklch(71.4% .203 305.504);--color-purple-500:oklch(62.7% .265 303.9);--color-purple-600:oklch(55.8% .288 302.321);--color-purple-700:oklch(49.6% .265 301.924);--color-gray-50:var(--color-gray-50);--color-gray-100:var(--color-gray-100);--color-gray-200:var(--color-gray-200);--color-gray-300:var(--color-gray-300);--color-gray-400:var(--color-gray-400);--color-gray-500:var(--color-gray-500);--color-gray-600:var(--color-gray-600);--color-gray-700:var(--color-gray-700);--color-gray-800:var(--color-gray-800);--color-gray-900:var(--color-gray-900);--color-gray-950:var(--color-gray-950);--color-neutral-400:oklch(70.8% 0 0);--color-black:var(--color-black);--color-white:var(--color-white);--spacing:.25rem;--container-xs:20rem;--container-sm:24rem;--container-md:28rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height:calc(1.5/1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25/1.875);--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5/2.25);--text-6xl:3.75rem;--text-6xl--line-height:1;--font-weight-light:300;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wide:.025em;--radius-md:.375rem;--radius-lg:.5rem;--ease-in:cubic-bezier(.4,0,1,1);--ease-out:cubic-bezier(0,0,.2,1);--ease-in-out:cubic-bezier(.4,0,.2,1);--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-light:var(--color-light);--color-mid:var(--color-mid);--color-dark:var(--color-dark);--color-highlight:var(--color-highlight);--color-active:var(--color-active);--color-inactive:var(--color-inactive);--color-warning:var(--color-warning);--color-error:var(--color-error);--color-primary-50:var(--color-primary-50);--color-primary-100:var(--color-primary-100);--color-primary-200:var(--color-primary-200);--color-primary-300:var(--color-primary-300);--color-primary-400:var(--color-primary-400);--color-primary-500:var(--color-primary-500);--color-primary-600:var(--color-primary-600);--color-primary-700:var(--color-primary-700);--color-primary-800:var(--color-primary-800);--color-primary-900:var(--color-primary-900);--color-primary-950:var(--color-primary-950)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}html[data-theme=default]{--color-white:#f9f9f9;--color-black:#1a161d;--color-light:#eecee6;--color-mid:#8d5eb7;--color-dark:#211d49;--color-highlight:#d04014;--color-active:#008755;--color-warning:#facf8e;--color-inactive:#d8f7f5;--color-error:#f58181;--color-primary-50:#faf5ff;--color-primary-100:#f3e8ff;--color-primary-200:#e9d5ff;--color-primary-300:#d8b4fe;--color-primary-400:#c084fc;--color-primary-500:#8d5eb7;--color-primary-600:#7850a0;--color-primary-700:#64418c;--color-primary-800:#3c2d64;--color-primary-900:#211d49;--color-primary-950:#181432;--color-gray-50:#f9fafb;--color-gray-100:#f3f4f6;--color-gray-200:#e5e7eb;--color-gray-300:#d1d5db;--color-gray-400:#9ca3af;--color-gray-500:#6b7280;--color-gray-600:#4b5563;--color-gray-700:#374151;--color-gray-800:#1f2937;--color-gray-900:#111827;--color-gray-950:#030712}html[data-theme=sky]{--color-white:#f9f9f9;--color-black:#1a161d;--color-light:#cceef2;--color-mid:#2a669f;--color-dark:#14204a;--color-highlight:#d04014;--color-active:#459a59;--color-warning:#f4be66;--color-inactive:#d8f7f5;--color-error:#d04014;--color-primary-50:#f0f9ff;--color-primary-100:#e0f2fe;--color-primary-200:#bae6fd;--color-primary-300:#7dd3fc;--color-primary-400:#38bdf8;--color-primary-500:#2a669f;--color-primary-600:#235584;--color-primary-700:#1c446a;--color-primary-800:#163452;--color-primary-900:#14204a;--color-primary-950:#0f1837;--color-gray-50:#f9fafb;--color-gray-100:#f3f4f6;--color-gray-200:#e5e7eb;--color-gray-300:#d1d5db;--color-gray-400:#9ca3af;--color-gray-500:#6b7280;--color-gray-600:#4b5563;--color-gray-700:#374151;--color-gray-800:#1f2937;--color-gray-900:#111827;--color-gray-950:#030712}a.block-link:after{content:"";position:absolute;inset:0}html[data-theme=default] .bg-gradient-admin{background:linear-gradient(to bottom right,#211d49,#8d5eb7)}html[data-theme=sky] .bg-gradient-admin{background:linear-gradient(to bottom right,#14204a,#2a669f)}}@layer components{input[type=text],input[type=email],input[type=password],input[type=url],input[type=tel],input[type=number],input[type=date],input[type=datetime-local],input[type=month],input[type=week],input[type=time],input[type=search],textarea{border-radius:var(--radius-md);border-style:var(--tw-border-style);background-color:var(--color-white);width:100%;padding:calc(var(--spacing)*2);color:var(--color-gray-900);--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--color-mid);--tw-ring-inset:inset;border-width:0;display:block}:is(input[type=text],input[type=email],input[type=password],input[type=url],input[type=tel],input[type=number],input[type=date],input[type=datetime-local],input[type=month],input[type=week],input[type=time],input[type=search],textarea)::placeholder{color:var(--color-gray-300)}:is(input[type=text],input[type=email],input[type=password],input[type=url],input[type=tel],input[type=number],input[type=date],input[type=datetime-local],input[type=month],input[type=week],input[type=time],input[type=search],textarea):focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--color-dark);--tw-ring-inset:inset}@media (hover:hover){:is(input[type=text],input[type=email],input[type=password],input[type=url],input[type=tel],input[type=number],input[type=date],input[type=datetime-local],input[type=month],input[type=week],input[type=time],input[type=search],textarea):hover{cursor:pointer}}@media (min-width:40rem){input[type=text],input[type=email],input[type=password],input[type=url],input[type=tel],input[type=number],input[type=date],input[type=datetime-local],input[type=month],input[type=week],input[type=time],input[type=search],textarea{--tw-leading:calc(var(--spacing)*6);line-height:calc(var(--spacing)*6)}}:is(input[type=text],input[type=email],input[type=password],input[type=url],input[type=tel],input[type=number],input[type=date],input[type=datetime-local],input[type=month],input[type=week],input[type=time],input[type=search],textarea):disabled{cursor:not-allowed;background-color:var(--color-gray-50);--tw-ring-color:var(--color-gray-300)}:is(input[type=text],input[type=email],input[type=password],input[type=url],input[type=tel],input[type=number],input[type=date],input[type=datetime-local],input[type=month],input[type=week],input[type=time],input[type=search],textarea):disabled:focus{--tw-ring-color:var(--color-gray-300)}select{border-radius:var(--radius-md);border-style:var(--tw-border-style);background-color:var(--color-white);width:100%;padding-block:calc(var(--spacing)*1.5);padding-right:calc(var(--spacing)*10);padding-left:calc(var(--spacing)*3);color:var(--color-gray-900);--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--color-mid);--tw-ring-inset:inset;border-width:0;display:block}select:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--color-dark);--tw-ring-inset:inset}@media (hover:hover){select:hover{cursor:pointer}}@media (min-width:40rem){select{--tw-leading:calc(var(--spacing)*6);line-height:calc(var(--spacing)*6)}}select:disabled{cursor:not-allowed;background-color:var(--color-gray-50);--tw-ring-color:var(--color-gray-300)}select:disabled:focus{--tw-ring-color:var(--color-gray-300)}select{appearance:none;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");background-position:right .5rem center;background-repeat:no-repeat;background-size:1.5em 1.5em}input[type=checkbox],input[type=radio]{height:calc(var(--spacing)*4);width:calc(var(--spacing)*4);border-color:var(--color-gray-300);background-color:var(--color-white);color:var(--color-indigo-600);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.2s;border-radius:.25rem;transition-duration:.2s}:is(input[type=checkbox],input[type=radio]):focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--color-indigo-500);--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}:is(input[type=checkbox],input[type=radio]):disabled{cursor:not-allowed;background-color:var(--color-gray-100)}input[type=radio]{border-radius:3.40282e38px}label{margin-bottom:calc(var(--spacing)*1);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--color-gray-700);display:block}.field{margin-bottom:calc(var(--spacing)*4)}input.error,textarea.error,select.error,:is(input.error,textarea.error,select.error):focus{--tw-ring-color:var(--color-red-500)}.field-error{margin-top:calc(var(--spacing)*1);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--color-red-600)}.btn{border-radius:var(--radius-md);padding-inline:calc(var(--spacing)*6);padding-block:calc(var(--spacing)*3);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.2s;justify-content:center;align-items:center;transition-duration:.2s;display:inline-flex}.btn:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color);--tw-outline-style:none;outline-style:none}.btn:disabled{cursor:not-allowed;opacity:.5}.btn-primary{background-color:var(--color-mid);color:var(--color-white)}@media (hover:hover){.btn-primary:hover{opacity:.9}}.btn-primary:focus{--tw-ring-color:var(--color-mid)}.btn-secondary{background-color:var(--color-gray-200);color:var(--color-gray-900)}@media (hover:hover){.btn-secondary:hover{background-color:var(--color-gray-300)}}.btn-secondary:focus{--tw-ring-color:var(--color-gray-500)}.btn-danger{background-color:var(--color-red-600);color:var(--color-white)}@media (hover:hover){.btn-danger:hover{background-color:var(--color-red-700)}}.btn-danger:focus{--tw-ring-color:var(--color-red-500)}:where(.codex-editor__redactor .ce-block .ce-block__content>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(1.6rem*var(--tw-space-y-reverse));margin-block-end:calc(1.6rem*calc(1 - var(--tw-space-y-reverse)))}.codex-editor__redactor .ce-block .ce-block__content{font-family:var(--font-sans);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-leading:1.6;--tw-font-weight:var(--font-weight-normal);line-height:1.6;font-weight:var(--font-weight-normal);color:var(--color-dark)}.codex-editor__redactor .ce-block .ce-block__content h1.ce-header{font-family:var(--font-sans);font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height));--tw-leading:1.2;--tw-font-weight:var(--font-weight-semibold);line-height:1.2;font-weight:var(--font-weight-semibold)}@media (min-width:48rem){.codex-editor__redactor .ce-block .ce-block__content h1.ce-header{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}}.codex-editor__redactor .ce-block .ce-block__content h2.ce-header{margin-top:calc(var(--spacing)*8);margin-bottom:calc(var(--spacing)*4);font-family:var(--font-sans);font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height));--tw-leading:1.3;--tw-font-weight:var(--font-weight-medium);line-height:1.3;font-weight:var(--font-weight-medium)}.codex-editor__redactor .ce-block .ce-block__content h3.ce-header{margin-top:calc(var(--spacing)*6);margin-bottom:calc(var(--spacing)*4);font-family:var(--font-sans);font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height));--tw-leading:1.3;--tw-font-weight:var(--font-weight-normal);line-height:1.3;font-weight:var(--font-weight-normal)}.codex-editor__redactor .ce-block .ce-block__content p,.codex-editor__redactor .ce-block .ce-block__content li{--tw-leading:1.6;--tw-tracking:var(--tracking-wide);max-width:85ch;letter-spacing:var(--tracking-wide);line-height:1.6}:is(.codex-editor__redactor .ce-block .ce-block__content p,.codex-editor__redactor .ce-block .ce-block__content li) a{color:#1a9597;text-underline-offset:2px;text-decoration-line:underline}@media (hover:hover){:is(.codex-editor__redactor .ce-block .ce-block__content p,.codex-editor__redactor .ce-block .ce-block__content li) a:hover{color:#158486}}:is(.codex-editor__redactor .ce-block .ce-block__content p,.codex-editor__redactor .ce-block .ce-block__content li) a:focus{outline-style:var(--tw-outline-style);outline-offset:2px;outline-width:2px;outline-color:#1a9597}:is(.codex-editor__redactor .ce-block .ce-block__content p,.codex-editor__redactor .ce-block .ce-block__content li) strong,:is(.codex-editor__redactor .ce-block .ce-block__content p,.codex-editor__redactor .ce-block .ce-block__content li) b{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.codex-editor__redactor .ce-block .ce-block__content p{margin-bottom:calc(var(--spacing)*4)}.codex-editor__redactor .ce-block .ce-block__content .cdx-quote{margin-bottom:calc(var(--spacing)*4);border-left-style:var(--tw-border-style);border-left-width:8px;border-left-color:var(--color-inactive);padding:calc(var(--spacing)*6);background-color:#eef0f3}.codex-editor__redactor .ce-block .ce-block__content .cdx-quote .cdx-quote__caption{margin-top:calc(var(--spacing)*2);margin-left:calc(var(--spacing)*6);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--color-dark);display:block}.codex-editor__redactor .ce-block .ce-block__content .cdx-quote .cdx-quote__text{quotes:"“" "”" "‘" "’";padding-left:calc(var(--spacing)*6)}.codex-editor__redactor .ce-block .ce-block__content .cdx-quote .cdx-quote__text:before{margin-right:calc(var(--spacing)*2);margin-left:calc(var(--spacing)*-8);vertical-align:text-bottom;font-family:var(--font-serif);font-size:var(--text-6xl);line-height:var(--tw-leading,var(--text-6xl--line-height));--tw-leading:calc(var(--spacing)*4);line-height:calc(var(--spacing)*4);color:var(--color-dark);content:open-quote}.codex-editor__redactor .ce-block .ce-block__content .cdx-quote .cdx-quote__text p{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height));font-style:italic;display:inline}.codex-editor__redactor .ce-block .ce-block__content .cdx-list{margin-bottom:calc(var(--spacing)*4);padding-left:calc(var(--spacing)*6)}--ordered:is(.codex-editor__redactor .ce-block .ce-block__content .cdx-list){list-style-type:decimal}--unordered:is(.codex-editor__redactor .ce-block .ce-block__content .cdx-list){list-style-type:disc}.codex-editor__redactor .ce-block .ce-block__content .cdx-list .cdx-list{margin-top:calc(var(--spacing)*2);margin-bottom:calc(var(--spacing)*0)}.codex-editor__redactor .ce-block .ce-block__content .cdx-list .cdx-list__item{margin-bottom:calc(var(--spacing)*2);padding-left:calc(var(--spacing)*2)}.codex-editor__redactor .ce-block .ce-block__content .cdx-nested-list{margin-bottom:calc(var(--spacing)*4);padding-left:calc(var(--spacing)*6)}--ordered:is(.codex-editor__redactor .ce-block .ce-block__content .cdx-nested-list){list-style-type:decimal}--unordered:is(.codex-editor__redactor .ce-block .ce-block__content .cdx-nested-list){list-style-type:disc}.codex-editor__redactor .ce-block .ce-block__content .cdx-nested-list .cdx-nested-list{margin-top:calc(var(--spacing)*2);margin-bottom:calc(var(--spacing)*0)}.codex-editor__redactor .ce-block .ce-block__content .cdx-nested-list .cdx-nested-list__item{margin-bottom:calc(var(--spacing)*2);padding-left:calc(var(--spacing)*2)}.codex-editor__redactor .ce-block .ce-block__content .cdx-table{margin-block:calc(var(--spacing)*6);border-collapse:collapse;border-style:var(--tw-border-style);border-width:2px;border-color:var(--color-dark);width:100%}__head:is(.codex-editor__redactor .ce-block .ce-block__content .cdx-table){border-right-style:var(--tw-border-style);border-right-width:2px;border-color:var(--color-dark);background-color:var(--color-light);padding:calc(var(--spacing)*3);--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}__row:is(.codex-editor__redactor .ce-block .ce-block__content .cdx-table){border-bottom-style:var(--tw-border-style);border-bottom-width:2px;border-color:var(--color-dark)}__cell:is(.codex-editor__redactor .ce-block .ce-block__content .cdx-table){border-right-style:var(--tw-border-style);border-right-width:2px;border-color:var(--color-dark);padding:calc(var(--spacing)*3)}.codex-editor__redactor .ce-block .ce-block__content .cdx-embed iframe{--tw-border-style:none;border-style:none;width:100%}}@layer utilities{.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.-inset-2\.5{inset:calc(var(--spacing)*-2.5)}.inset-0{inset:calc(var(--spacing)*0)}.inset-y-0{inset-block:calc(var(--spacing)*0)}.top-0{top:calc(var(--spacing)*0)}.top-1\/2{top:50%}.right-0{right:calc(var(--spacing)*0)}.right-3{right:calc(var(--spacing)*3)}.z-10{z-index:10}.z-40{z-index:40}.z-50{z-index:50}.col-span-3{grid-column:span 3/span 3}.col-span-full{grid-column:1/-1}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.-mx-4{margin-inline:calc(var(--spacing)*-4)}.mx-auto{margin-inline:auto}.-mt-1{margin-top:calc(var(--spacing)*-1)}.-mt-2{margin-top:calc(var(--spacing)*-2)}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-3{margin-top:calc(var(--spacing)*3)}.mt-4{margin-top:calc(var(--spacing)*4)}.mt-5{margin-top:calc(var(--spacing)*5)}.mt-6{margin-top:calc(var(--spacing)*6)}.mt-8{margin-top:calc(var(--spacing)*8)}.mt-10{margin-top:calc(var(--spacing)*10)}.mt-16{margin-top:calc(var(--spacing)*16)}.mt-auto{margin-top:auto}.-mr-1{margin-right:calc(var(--spacing)*-1)}.-mr-12{margin-right:calc(var(--spacing)*-12)}.mr-1{margin-right:calc(var(--spacing)*1)}.-mb-px{margin-bottom:-1px}.mb-0\.5{margin-bottom:calc(var(--spacing)*.5)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-3{margin-bottom:calc(var(--spacing)*3)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-5{margin-bottom:calc(var(--spacing)*5)}.mb-6{margin-bottom:calc(var(--spacing)*6)}.mb-12{margin-bottom:calc(var(--spacing)*12)}.-ml-1{margin-left:calc(var(--spacing)*-1)}.ml-0{margin-left:calc(var(--spacing)*0)}.ml-0\.5{margin-left:calc(var(--spacing)*.5)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-2{margin-left:calc(var(--spacing)*2)}.ml-3{margin-left:calc(var(--spacing)*3)}.ml-4{margin-left:calc(var(--spacing)*4)}.ml-5{margin-left:calc(var(--spacing)*5)}.ml-6{margin-left:calc(var(--spacing)*6)}.ml-8{margin-left:calc(var(--spacing)*8)}.ml-12{margin-left:calc(var(--spacing)*12)}.ml-16{margin-left:calc(var(--spacing)*16)}.ml-24{margin-left:calc(var(--spacing)*24)}.ml-auto{margin-left:auto}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.table-cell{display:table-cell}.table-header-group{display:table-header-group}.table-row{display:table-row}.table-row-group{display:table-row-group}.aspect-10\/7{aspect-ratio:10/7}.size-4{width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.size-5{width:calc(var(--spacing)*5);height:calc(var(--spacing)*5)}.size-6{width:calc(var(--spacing)*6);height:calc(var(--spacing)*6)}.size-12{width:calc(var(--spacing)*12);height:calc(var(--spacing)*12)}.size-full{width:100%;height:100%}.h-3{height:calc(var(--spacing)*3)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-7{height:calc(var(--spacing)*7)}.h-10{height:calc(var(--spacing)*10)}.h-12{height:calc(var(--spacing)*12)}.h-16{height:calc(var(--spacing)*16)}.h-20{height:calc(var(--spacing)*20)}.h-32{height:calc(var(--spacing)*32)}.h-48{height:calc(var(--spacing)*48)}.h-\[calc\(100vh-9rem\)\]{height:calc(100vh - 9rem)}.h-full{height:100%}.max-h-16{max-height:calc(var(--spacing)*16)}.max-h-60{max-height:calc(var(--spacing)*60)}.max-h-full{max-height:100%}.min-h-0{min-height:calc(var(--spacing)*0)}.min-h-32{min-height:calc(var(--spacing)*32)}.min-h-\[2\.5rem\]{min-height:2.5rem}.min-h-full{min-height:100%}.min-h-screen{min-height:100vh}.w-0{width:calc(var(--spacing)*0)}.w-3{width:calc(var(--spacing)*3)}.w-4{width:calc(var(--spacing)*4)}.w-5{width:calc(var(--spacing)*5)}.w-6{width:calc(var(--spacing)*6)}.w-10{width:calc(var(--spacing)*10)}.w-12{width:calc(var(--spacing)*12)}.w-48{width:calc(var(--spacing)*48)}.w-56{width:calc(var(--spacing)*56)}.w-96{width:calc(var(--spacing)*96)}.w-auto{width:auto}.w-full{width:100%}.max-w-48{max-width:calc(var(--spacing)*48)}.max-w-full{max-width:100%}.max-w-md{max-width:var(--container-md)}.max-w-sm{max-width:var(--container-sm)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing)*0)}.min-w-56{min-width:calc(var(--spacing)*56)}.flex-1{flex:1}.flex-auto{flex:auto}.flex-shrink-0,.shrink-0{flex-shrink:0}.flex-grow,.grow{flex-grow:1}.origin-top-right{transform-origin:100% 0}.translate-x-0{--tw-translate-x:calc(var(--spacing)*0);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-full{--tw-translate-x:100%;translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-y-0{--tw-translate-y:calc(var(--spacing)*0);translate:var(--tw-translate-x)var(--tw-translate-y)}.scale-95{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x)var(--tw-scale-y)}.scale-100{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x)var(--tw-scale-y)}.rotate-90{rotate:90deg}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.cursor-default{cursor:default}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.list-inside{list-style-position:inside}.list-disc{list-style-type:disc}.appearance-none{appearance:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-2{gap:calc(var(--spacing)*2)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-5{gap:calc(var(--spacing)*5)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*6)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*6)*calc(1 - var(--tw-space-y-reverse)))}.gap-x-1\.5{column-gap:calc(var(--spacing)*1.5)}.gap-x-2{column-gap:calc(var(--spacing)*2)}.gap-x-3{column-gap:calc(var(--spacing)*3)}.gap-x-4{column-gap:calc(var(--spacing)*4)}:where(.space-x-4>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*4)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-x-reverse)))}:where(.space-x-6>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*6)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*6)*calc(1 - var(--tw-space-x-reverse)))}.gap-y-5{row-gap:calc(var(--spacing)*5)}.gap-y-8{row-gap:calc(var(--spacing)*8)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-s-md{border-start-start-radius:var(--radius-md);border-end-start-radius:var(--radius-md)}.rounded-l-none{border-top-left-radius:0;border-bottom-left-radius:0}.rounded-tl-md{border-top-left-radius:var(--radius-md)}.rounded-tr-md{border-top-right-radius:var(--radius-md)}.rounded-b-lg{border-bottom-right-radius:var(--radius-lg);border-bottom-left-radius:var(--radius-lg)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-dark,.border-dark\/20{border-color:var(--color-dark)}@supports (color:color-mix(in lab, red, red)){.border-dark\/20{border-color:color-mix(in oklab,var(--color-dark)20%,transparent)}}.border-gray-200{border-color:var(--color-gray-200)}.border-gray-300{border-color:var(--color-gray-300)}.border-gray-500{border-color:var(--color-gray-500)}.border-gray-900\/25{border-color:var(--color-gray-900)}@supports (color:color-mix(in lab, red, red)){.border-gray-900\/25{border-color:color-mix(in oklab,var(--color-gray-900)25%,transparent)}}.border-mid{border-color:var(--color-mid)}.border-neutral-400{border-color:var(--color-neutral-400)}.border-red-200{border-color:var(--color-red-200)}.border-red-600{border-color:var(--color-red-600)}.border-transparent{border-color:#0000}.border-white\/20{border-color:var(--color-white)}@supports (color:color-mix(in lab, red, red)){.border-white\/20{border-color:color-mix(in oklab,var(--color-white)20%,transparent)}}.bg-black\/5{background-color:var(--color-black)}@supports (color:color-mix(in lab, red, red)){.bg-black\/5{background-color:color-mix(in oklab,var(--color-black)5%,transparent)}}.bg-blue-50{background-color:var(--color-blue-50)}.bg-blue-100{background-color:var(--color-blue-100)}.bg-blue-600{background-color:var(--color-blue-600)}.bg-dark{background-color:var(--color-dark)}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-100{background-color:var(--color-gray-100)}.bg-gray-200{background-color:var(--color-gray-200)}.bg-gray-400{background-color:var(--color-gray-400)}.bg-gray-500\/5{background-color:var(--color-gray-500)}@supports (color:color-mix(in lab, red, red)){.bg-gray-500\/5{background-color:color-mix(in oklab,var(--color-gray-500)5%,transparent)}}.bg-gray-500\/75{background-color:var(--color-gray-500)}@supports (color:color-mix(in lab, red, red)){.bg-gray-500\/75{background-color:color-mix(in oklab,var(--color-gray-500)75%,transparent)}}.bg-gray-600{background-color:var(--color-gray-600)}.bg-gray-700{background-color:var(--color-gray-700)}.bg-gray-800{background-color:var(--color-gray-800)}.bg-green-50{background-color:var(--color-green-50)}.bg-green-100{background-color:var(--color-green-100)}.bg-green-600{background-color:var(--color-green-600)}.bg-indigo-600{background-color:var(--color-indigo-600)}.bg-mid{background-color:var(--color-mid)}.bg-purple-100{background-color:var(--color-purple-100)}.bg-purple-500{background-color:var(--color-purple-500)}.bg-red-50{background-color:var(--color-red-50)}.bg-red-100{background-color:var(--color-red-100)}.bg-red-600{background-color:var(--color-red-600)}.bg-sky-50{background-color:var(--color-sky-50)}.bg-transparent{background-color:#0000}.bg-white,.bg-white\/10{background-color:var(--color-white)}@supports (color:color-mix(in lab, red, red)){.bg-white\/10{background-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.bg-yellow-50{background-color:var(--color-yellow-50)}.bg-yellow-400{background-color:var(--color-yellow-400)}.bg-gradient-to-br{--tw-gradient-position:to bottom right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-r{--tw-gradient-position:to right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-blue-500{--tw-gradient-from:var(--color-blue-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-light{--tw-gradient-from:var(--color-light);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-light\/20{--tw-gradient-from:var(--color-light)}@supports (color:color-mix(in lab, red, red)){.from-light\/20{--tw-gradient-from:color-mix(in oklab,var(--color-light)20%,transparent)}}.from-light\/20{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-light{--tw-gradient-to:var(--color-light);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-purple-600{--tw-gradient-to:var(--color-purple-600);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.object-cover{object-fit:cover}.p-0{padding:calc(var(--spacing)*0)}.p-0\.5{padding:calc(var(--spacing)*.5)}.p-1\.5{padding:calc(var(--spacing)*1.5)}.p-2{padding:calc(var(--spacing)*2)}.p-4{padding:calc(var(--spacing)*4)}.p-6{padding:calc(var(--spacing)*6)}.p-8{padding:calc(var(--spacing)*8)}.px-1{padding-inline:calc(var(--spacing)*1)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-2\.5{padding-inline:calc(var(--spacing)*2.5)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-3\.5{padding-inline:calc(var(--spacing)*3.5)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-6{padding-inline:calc(var(--spacing)*6)}.py-0\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-2\.5{padding-block:calc(var(--spacing)*2.5)}.py-3{padding-block:calc(var(--spacing)*3)}.py-4{padding-block:calc(var(--spacing)*4)}.py-5{padding-block:calc(var(--spacing)*5)}.py-6{padding-block:calc(var(--spacing)*6)}.py-10{padding-block:calc(var(--spacing)*10)}.py-12{padding-block:calc(var(--spacing)*12)}.pt-0\.5{padding-top:calc(var(--spacing)*.5)}.pt-2{padding-top:calc(var(--spacing)*2)}.pr-2{padding-right:calc(var(--spacing)*2)}.pr-8{padding-right:calc(var(--spacing)*8)}.pr-9{padding-right:calc(var(--spacing)*9)}.pr-10{padding-right:calc(var(--spacing)*10)}.pb-4{padding-bottom:calc(var(--spacing)*4)}.pl-1{padding-left:calc(var(--spacing)*1)}.pl-3{padding-left:calc(var(--spacing)*3)}.pl-9{padding-left:calc(var(--spacing)*9)}.pl-11{padding-left:calc(var(--spacing)*11)}.text-center{text-align:center}.text-left{text-align:left}.align-middle{vertical-align:middle}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-2xl\/7{font-size:var(--text-2xl);line-height:calc(var(--spacing)*7)}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-sm\/6{font-size:var(--text-sm);line-height:calc(var(--spacing)*6)}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-xs\/5{font-size:var(--text-xs);line-height:calc(var(--spacing)*5)}.leading-6{--tw-leading:calc(var(--spacing)*6);line-height:calc(var(--spacing)*6)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-light{--tw-font-weight:var(--font-weight-light);font-weight:var(--font-weight-light)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.break-keep{word-break:keep-all}.whitespace-nowrap{white-space:nowrap}.text-black,.text-black\/60{color:var(--color-black)}@supports (color:color-mix(in lab, red, red)){.text-black\/60{color:color-mix(in oklab,var(--color-black)60%,transparent)}}.text-blue-400{color:var(--color-blue-400)}.text-blue-600{color:var(--color-blue-600)}.text-blue-700{color:var(--color-blue-700)}.text-dark{color:var(--color-dark)}.text-gray-300{color:var(--color-gray-300)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-700{color:var(--color-gray-700)}.text-gray-900{color:var(--color-gray-900)}.text-green-400{color:var(--color-green-400)}.text-green-700{color:var(--color-green-700)}.text-indigo-600{color:var(--color-indigo-600)}.text-purple-700{color:var(--color-purple-700)}.text-red-400{color:var(--color-red-400)}.text-red-600{color:var(--color-red-600)}.text-red-700{color:var(--color-red-700)}.text-sky-700{color:var(--color-sky-700)}.text-white,.text-white\/80{color:var(--color-white)}@supports (color:color-mix(in lab, red, red)){.text-white\/80{color:color-mix(in oklab,var(--color-white)80%,transparent)}}.text-yellow-400{color:var(--color-yellow-400)}.text-yellow-700{color:var(--color-yellow-700)}.text-yellow-800{color:var(--color-yellow-800)}.uppercase{text-transform:uppercase}.opacity-0{opacity:0}.opacity-100{opacity:1}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring,.ring-1{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.inset-ring{--tw-inset-ring-shadow:inset 0 0 0 1px var(--tw-inset-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-black,.ring-black\/30{--tw-ring-color:var(--color-black)}@supports (color:color-mix(in lab, red, red)){.ring-black\/30{--tw-ring-color:color-mix(in oklab,var(--color-black)30%,transparent)}}.ring-blue-400\/20{--tw-ring-color:#54a2ff33}@supports (color:color-mix(in lab, red, red)){.ring-blue-400\/20{--tw-ring-color:color-mix(in oklab,var(--color-blue-400)20%,transparent)}}.ring-blue-600\/20{--tw-ring-color:#155dfc33}@supports (color:color-mix(in lab, red, red)){.ring-blue-600\/20{--tw-ring-color:color-mix(in oklab,var(--color-blue-600)20%,transparent)}}.ring-blue-700\/10{--tw-ring-color:#1447e61a}@supports (color:color-mix(in lab, red, red)){.ring-blue-700\/10{--tw-ring-color:color-mix(in oklab,var(--color-blue-700)10%,transparent)}}.ring-gray-300{--tw-ring-color:var(--color-gray-300)}.ring-gray-400\/10{--tw-ring-color:var(--color-gray-400)}@supports (color:color-mix(in lab, red, red)){.ring-gray-400\/10{--tw-ring-color:color-mix(in oklab,var(--color-gray-400)10%,transparent)}}.ring-gray-500\/10{--tw-ring-color:var(--color-gray-500)}@supports (color:color-mix(in lab, red, red)){.ring-gray-500\/10{--tw-ring-color:color-mix(in oklab,var(--color-gray-500)10%,transparent)}}.ring-gray-600\/20{--tw-ring-color:var(--color-gray-600)}@supports (color:color-mix(in lab, red, red)){.ring-gray-600\/20{--tw-ring-color:color-mix(in oklab,var(--color-gray-600)20%,transparent)}}.ring-green-400\/20{--tw-ring-color:#05df7233}@supports (color:color-mix(in lab, red, red)){.ring-green-400\/20{--tw-ring-color:color-mix(in oklab,var(--color-green-400)20%,transparent)}}.ring-green-600\/20{--tw-ring-color:#00a54433}@supports (color:color-mix(in lab, red, red)){.ring-green-600\/20{--tw-ring-color:color-mix(in oklab,var(--color-green-600)20%,transparent)}}.ring-mid{--tw-ring-color:var(--color-mid)}.ring-purple-600\/20{--tw-ring-color:#9810fa33}@supports (color:color-mix(in lab, red, red)){.ring-purple-600\/20{--tw-ring-color:color-mix(in oklab,var(--color-purple-600)20%,transparent)}}.ring-red-400\/20{--tw-ring-color:#ff656833}@supports (color:color-mix(in lab, red, red)){.ring-red-400\/20{--tw-ring-color:color-mix(in oklab,var(--color-red-400)20%,transparent)}}.ring-red-600\/10{--tw-ring-color:#e400141a}@supports (color:color-mix(in lab, red, red)){.ring-red-600\/10{--tw-ring-color:color-mix(in oklab,var(--color-red-600)10%,transparent)}}.ring-red-600\/20{--tw-ring-color:#e4001433}@supports (color:color-mix(in lab, red, red)){.ring-red-600\/20{--tw-ring-color:color-mix(in oklab,var(--color-red-600)20%,transparent)}}.ring-sky-700\/10{--tw-ring-color:#0069a41a}@supports (color:color-mix(in lab, red, red)){.ring-sky-700\/10{--tw-ring-color:color-mix(in oklab,var(--color-sky-700)10%,transparent)}}.ring-yellow-400\/20{--tw-ring-color:#fac80033}@supports (color:color-mix(in lab, red, red)){.ring-yellow-400\/20{--tw-ring-color:color-mix(in oklab,var(--color-yellow-400)20%,transparent)}}.ring-yellow-600\/20{--tw-ring-color:#cd890033}@supports (color:color-mix(in lab, red, red)){.ring-yellow-600\/20{--tw-ring-color:color-mix(in oklab,var(--color-yellow-600)20%,transparent)}}.inset-ring-gray-300{--tw-inset-ring-color:var(--color-gray-300)}.outline,.outline-1{outline-style:var(--tw-outline-style);outline-width:1px}.outline-2{outline-style:var(--tw-outline-style);outline-width:2px}.-outline-offset-1{outline-offset:calc(1px*-1)}.outline-offset-2{outline-offset:2px}.outline-black\/5{outline-color:var(--color-black)}@supports (color:color-mix(in lab, red, red)){.outline-black\/5{outline-color:color-mix(in oklab,var(--color-black)5%,transparent)}}.outline-gray-200{outline-color:var(--color-gray-200)}.outline-gray-300{outline-color:var(--color-gray-300)}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-75{--tw-duration:75ms;transition-duration:75ms}.duration-100{--tw-duration:.1s;transition-duration:.1s}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.duration-500{--tw-duration:.5s;transition-duration:.5s}.ease-in{--tw-ease:var(--ease-in);transition-timing-function:var(--ease-in)}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.select-none{-webkit-user-select:none;user-select:none}.ring-inset{--tw-ring-inset:inset}@media (hover:hover){.group-hover\:opacity-75:is(:where(.group):hover *){opacity:.75}}.file\:rounded::file-selector-button{border-radius:.25rem}.file\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\:bg-white::file-selector-button{background-color:var(--color-white)}.file\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.file\:text-gray-500::file-selector-button{color:var(--color-gray-500)}.placeholder\:text-gray-300::placeholder{color:var(--color-gray-300)}.placeholder\:text-gray-400::placeholder{color:var(--color-gray-400)}.focus-within\:outline-2:focus-within{outline-style:var(--tw-outline-style);outline-width:2px}.focus-within\:outline-offset-2:focus-within{outline-offset:2px}.focus-within\:outline-indigo-600:focus-within{outline-color:var(--color-indigo-600)}@media (hover:hover){.hover\:cursor-pointer:hover{cursor:pointer}.hover\:border-gray-300:hover{border-color:var(--color-gray-300)}.hover\:bg-blue-500:hover{background-color:var(--color-blue-500)}.hover\:bg-blue-600:hover{background-color:var(--color-blue-600)}.hover\:bg-gray-50:hover{background-color:var(--color-gray-50)}.hover\:bg-gray-100:hover{background-color:var(--color-gray-100)}.hover\:bg-gray-500\/20:hover{background-color:var(--color-gray-500)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-gray-500\/20:hover{background-color:color-mix(in oklab,var(--color-gray-500)20%,transparent)}}.hover\:bg-gray-800:hover{background-color:var(--color-gray-800)}.hover\:bg-green-500:hover{background-color:var(--color-green-500)}.hover\:bg-indigo-500:hover{background-color:var(--color-indigo-500)}.hover\:bg-mid\/60:hover{background-color:var(--color-mid)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-mid\/60:hover{background-color:color-mix(in oklab,var(--color-mid)60%,transparent)}}.hover\:bg-mid\/80:hover{background-color:var(--color-mid)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-mid\/80:hover{background-color:color-mix(in oklab,var(--color-mid)80%,transparent)}}.hover\:bg-red-200:hover{background-color:var(--color-red-200)}.hover\:bg-red-500:hover{background-color:var(--color-red-500)}.hover\:bg-white:hover,.hover\:bg-white\/20:hover{background-color:var(--color-white)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-white\/20:hover{background-color:color-mix(in oklab,var(--color-white)20%,transparent)}}.hover\:text-black\/80:hover{color:var(--color-black)}@supports (color:color-mix(in lab, red, red)){.hover\:text-black\/80:hover{color:color-mix(in oklab,var(--color-black)80%,transparent)}}.hover\:text-gray-500:hover{color:var(--color-gray-500)}.hover\:text-gray-700:hover{color:var(--color-gray-700)}.hover\:text-indigo-500:hover{color:var(--color-indigo-500)}.hover\:text-indigo-900:hover{color:var(--color-indigo-900)}.hover\:text-red-700:hover{color:var(--color-red-700)}.hover\:text-white:hover{color:var(--color-white)}.hover\:opacity-70:hover{opacity:.7}.hover\:shadow-sm:hover{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hover\:file\:bg-gray-50:hover::file-selector-button{background-color:var(--color-gray-50)}}.focus\:ring-1:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-dark:focus{--tw-ring-color:var(--color-dark)}.focus\:ring-gray-300:focus{--tw-ring-color:var(--color-gray-300)}.focus\:ring-indigo-600:focus{--tw-ring-color:var(--color-indigo-600)}.focus\:ring-white:focus{--tw-ring-color:var(--color-white)}.focus\:outline-hidden:focus{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.focus\:outline-hidden:focus{outline-offset:2px;outline:2px solid #0000}}.focus\:outline-2:focus{outline-style:var(--tw-outline-style);outline-width:2px}.focus\:outline-offset-2:focus{outline-offset:2px}.focus\:outline-blue-600:focus{outline-color:var(--color-blue-600)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus\:ring-inset:focus{--tw-ring-inset:inset}.focus-visible\:outline:focus-visible{outline-style:var(--tw-outline-style);outline-width:1px}.focus-visible\:outline-0:focus-visible{outline-style:var(--tw-outline-style);outline-width:0}.focus-visible\:outline-2:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px}.focus-visible\:-outline-offset-2:focus-visible{outline-offset:calc(2px*-1)}.focus-visible\:outline-offset-2:focus-visible{outline-offset:2px}.focus-visible\:outline-blue-600:focus-visible{outline-color:var(--color-blue-600)}.focus-visible\:outline-gray-700:focus-visible{outline-color:var(--color-gray-700)}.focus-visible\:outline-green-600:focus-visible{outline-color:var(--color-green-600)}.focus-visible\:outline-indigo-600:focus-visible{outline-color:var(--color-indigo-600)}.focus-visible\:outline-red-300:focus-visible{outline-color:var(--color-red-300)}.focus-visible\:outline-red-600:focus-visible{outline-color:var(--color-red-600)}.focus-visible\:outline-white:focus-visible{outline-color:var(--color-white)}.active\:bg-gray-200:active{background-color:var(--color-gray-200)}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}@media (min-width:40rem){.sm\:-mx-6{margin-inline:calc(var(--spacing)*-6)}.sm\:mx-auto{margin-inline:auto}.sm\:mt-2{margin-top:calc(var(--spacing)*2)}.sm\:block{display:block}.sm\:flex{display:flex}.sm\:hidden{display:none}.sm\:w-full{width:100%}.sm\:max-w-sm{max-width:var(--container-sm)}.sm\:translate-x-0{--tw-translate-x:calc(var(--spacing)*0);translate:var(--tw-translate-x)var(--tw-translate-y)}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:items-end{align-items:flex-end}.sm\:items-start{align-items:flex-start}.sm\:gap-x-6{column-gap:calc(var(--spacing)*6)}.sm\:truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.sm\:p-6{padding:calc(var(--spacing)*6)}.sm\:px-6{padding-inline:calc(var(--spacing)*6)}.sm\:text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.sm\:text-sm\/6{font-size:var(--text-sm);line-height:calc(var(--spacing)*6)}.sm\:leading-6{--tw-leading:calc(var(--spacing)*6);line-height:calc(var(--spacing)*6)}.sm\:tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.sm\:duration-700{--tw-duration:.7s;transition-duration:.7s}}@media (min-width:48rem){.md\:mt-0{margin-top:calc(var(--spacing)*0)}.md\:ml-4{margin-left:calc(var(--spacing)*4)}.md\:flex{display:flex}.md\:items-center{align-items:center}.md\:justify-between{justify-content:space-between}}@media (min-width:64rem){.lg\:fixed{position:fixed}.lg\:inset-y-0{inset-block:calc(var(--spacing)*0)}.lg\:z-50{z-index:50}.lg\:mt-0{margin-top:calc(var(--spacing)*0)}.lg\:ml-72{margin-left:calc(var(--spacing)*72)}.lg\:flex{display:flex}.lg\:hidden{display:none}.lg\:max-h-full{max-height:100%}.lg\:w-72{width:calc(var(--spacing)*72)}.lg\:flex-shrink-0{flex-shrink:0}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:flex-col{flex-direction:column}.lg\:px-6{padding-inline:calc(var(--spacing)*6)}.lg\:px-8{padding-inline:calc(var(--spacing)*8)}}@media (min-width:80rem){.xl\:gap-x-8{column-gap:calc(var(--spacing)*8)}:where(.xl\:space-x-8>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*8)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*8)*calc(1 - var(--tw-space-x-reverse)))}}@media (prefers-color-scheme:dark){.dark\:border-white\/10{border-color:var(--color-white)}@supports (color:color-mix(in lab, red, red)){.dark\:border-white\/10{border-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.dark\:border-white\/25{border-color:var(--color-white)}@supports (color:color-mix(in lab, red, red)){.dark\:border-white\/25{border-color:color-mix(in oklab,var(--color-white)25%,transparent)}}.dark\:bg-blue-400\/10{background-color:#54a2ff1a}@supports (color:color-mix(in lab, red, red)){.dark\:bg-blue-400\/10{background-color:color-mix(in oklab,var(--color-blue-400)10%,transparent)}}.dark\:bg-blue-500{background-color:var(--color-blue-500)}.dark\:bg-gray-400\/10{background-color:var(--color-gray-400)}@supports (color:color-mix(in lab, red, red)){.dark\:bg-gray-400\/10{background-color:color-mix(in oklab,var(--color-gray-400)10%,transparent)}}.dark\:bg-gray-600{background-color:var(--color-gray-600)}.dark\:bg-gray-700{background-color:var(--color-gray-700)}.dark\:bg-gray-800{background-color:var(--color-gray-800)}.dark\:bg-gray-900\/50{background-color:var(--color-gray-900)}@supports (color:color-mix(in lab, red, red)){.dark\:bg-gray-900\/50{background-color:color-mix(in oklab,var(--color-gray-900)50%,transparent)}}.dark\:bg-green-400\/10{background-color:#05df721a}@supports (color:color-mix(in lab, red, red)){.dark\:bg-green-400\/10{background-color:color-mix(in oklab,var(--color-green-400)10%,transparent)}}.dark\:bg-green-500{background-color:var(--color-green-500)}.dark\:bg-purple-400\/10{background-color:#c07eff1a}@supports (color:color-mix(in lab, red, red)){.dark\:bg-purple-400\/10{background-color:color-mix(in oklab,var(--color-purple-400)10%,transparent)}}.dark\:bg-red-400\/10{background-color:#ff65681a}@supports (color:color-mix(in lab, red, red)){.dark\:bg-red-400\/10{background-color:color-mix(in oklab,var(--color-red-400)10%,transparent)}}.dark\:bg-red-500{background-color:var(--color-red-500)}.dark\:bg-white\/5{background-color:var(--color-white)}@supports (color:color-mix(in lab, red, red)){.dark\:bg-white\/5{background-color:color-mix(in oklab,var(--color-white)5%,transparent)}}.dark\:bg-white\/10{background-color:var(--color-white)}@supports (color:color-mix(in lab, red, red)){.dark\:bg-white\/10{background-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.dark\:text-blue-400{color:var(--color-blue-400)}.dark\:text-blue-500{color:var(--color-blue-500)}.dark\:text-gray-100{color:var(--color-gray-100)}.dark\:text-gray-300{color:var(--color-gray-300)}.dark\:text-gray-400{color:var(--color-gray-400)}.dark\:text-gray-500{color:var(--color-gray-500)}.dark\:text-gray-600{color:var(--color-gray-600)}.dark\:text-green-400{color:var(--color-green-400)}.dark\:text-green-500{color:var(--color-green-500)}.dark\:text-indigo-400{color:var(--color-indigo-400)}.dark\:text-purple-400{color:var(--color-purple-400)}.dark\:text-red-400{color:var(--color-red-400)}.dark\:text-red-500{color:var(--color-red-500)}.dark\:text-white{color:var(--color-white)}.dark\:text-yellow-500{color:var(--color-yellow-500)}.dark\:shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.dark\:ring-blue-500\/30{--tw-ring-color:#3080ff4d}@supports (color:color-mix(in lab, red, red)){.dark\:ring-blue-500\/30{--tw-ring-color:color-mix(in oklab,var(--color-blue-500)30%,transparent)}}.dark\:ring-gray-500\/20{--tw-ring-color:var(--color-gray-500)}@supports (color:color-mix(in lab, red, red)){.dark\:ring-gray-500\/20{--tw-ring-color:color-mix(in oklab,var(--color-gray-500)20%,transparent)}}.dark\:ring-green-500\/30{--tw-ring-color:#00c7584d}@supports (color:color-mix(in lab, red, red)){.dark\:ring-green-500\/30{--tw-ring-color:color-mix(in oklab,var(--color-green-500)30%,transparent)}}.dark\:ring-red-500\/30{--tw-ring-color:#fb2c364d}@supports (color:color-mix(in lab, red, red)){.dark\:ring-red-500\/30{--tw-ring-color:color-mix(in oklab,var(--color-red-500)30%,transparent)}}.dark\:ring-yellow-500\/30{--tw-ring-color:#edb2004d}@supports (color:color-mix(in lab, red, red)){.dark\:ring-yellow-500\/30{--tw-ring-color:color-mix(in oklab,var(--color-yellow-500)30%,transparent)}}.dark\:inset-ring-white\/5{--tw-inset-ring-color:var(--color-white)}@supports (color:color-mix(in lab, red, red)){.dark\:inset-ring-white\/5{--tw-inset-ring-color:color-mix(in oklab,var(--color-white)5%,transparent)}}.dark\:outline-white\/5{outline-color:var(--color-white)}@supports (color:color-mix(in lab, red, red)){.dark\:outline-white\/5{outline-color:color-mix(in oklab,var(--color-white)5%,transparent)}}.dark\:outline-white\/10{outline-color:var(--color-white)}@supports (color:color-mix(in lab, red, red)){.dark\:outline-white\/10{outline-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.dark\:placeholder\:text-gray-500::placeholder{color:var(--color-gray-500)}.dark\:after\:absolute:after{content:var(--tw-content);position:absolute}.dark\:after\:inset-y-0:after{content:var(--tw-content);inset-block:calc(var(--spacing)*0)}.dark\:after\:left-0:after{content:var(--tw-content);left:calc(var(--spacing)*0)}.dark\:after\:w-px:after{content:var(--tw-content);width:1px}.dark\:after\:bg-white\/10:after{content:var(--tw-content);background-color:var(--color-white)}@supports (color:color-mix(in lab, red, red)){.dark\:after\:bg-white\/10:after{background-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.dark\:focus-within\:outline-indigo-500:focus-within{outline-color:var(--color-indigo-500)}@media (hover:hover){.dark\:hover\:bg-blue-400:hover{background-color:var(--color-blue-400)}.dark\:hover\:bg-gray-500:hover{background-color:var(--color-gray-500)}.dark\:hover\:bg-gray-800:hover{background-color:var(--color-gray-800)}.dark\:hover\:bg-green-400:hover{background-color:var(--color-green-400)}.dark\:hover\:bg-red-400:hover{background-color:var(--color-red-400)}.dark\:hover\:bg-white\/5:hover{background-color:var(--color-white)}@supports (color:color-mix(in lab, red, red)){.dark\:hover\:bg-white\/5:hover{background-color:color-mix(in oklab,var(--color-white)5%,transparent)}}.dark\:hover\:bg-white\/20:hover{background-color:var(--color-white)}@supports (color:color-mix(in lab, red, red)){.dark\:hover\:bg-white\/20:hover{background-color:color-mix(in oklab,var(--color-white)20%,transparent)}}.dark\:hover\:text-gray-300:hover{color:var(--color-gray-300)}.dark\:hover\:text-indigo-300:hover{color:var(--color-indigo-300)}.dark\:hover\:text-white:hover{color:var(--color-white)}}.dark\:focus\:outline-blue-500:focus{outline-color:var(--color-blue-500)}.dark\:focus\:outline-indigo-500:focus{outline-color:var(--color-indigo-500)}.dark\:focus-visible\:outline-blue-500:focus-visible{outline-color:var(--color-blue-500)}.dark\:focus-visible\:outline-gray-600:focus-visible{outline-color:var(--color-gray-600)}.dark\:focus-visible\:outline-green-500:focus-visible{outline-color:var(--color-green-500)}.dark\:focus-visible\:outline-red-500:focus-visible{outline-color:var(--color-red-500)}}@starting-style{.starting\:translate-y-2{--tw-translate-y:calc(var(--spacing)*2);translate:var(--tw-translate-x)var(--tw-translate-y)}}@starting-style{.starting\:opacity-0{opacity:0}}@starting-style{@media (min-width:40rem){.starting\:sm\:translate-x-2{--tw-translate-x:calc(var(--spacing)*2);translate:var(--tw-translate-x)var(--tw-translate-y)}}}@starting-style{@media (min-width:40rem){.starting\:sm\:translate-y-0{--tw-translate-y:calc(var(--spacing)*0);translate:var(--tw-translate-x)var(--tw-translate-y)}}}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-space-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"<length-percentage>";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"<length-percentage>";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"<length-percentage>";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}