From 3568d02d822bd7eb403c5365c87bbf0000aee782 Mon Sep 17 00:00:00 2001 From: Paul Arterburn Date: Mon, 13 Apr 2026 08:05:49 -0600 Subject: [PATCH] Rails 7.0, Tailwind app shell, remove twbs/bootstrap Replace Bootstrap/twbs with Tailwind v4 build, shared design tokens, and navbar/layout updates. Drop twbs_sass_rails; fix redirect helper clash with Rails 7; CI runs Node 22 and CSS build; tests and schema updated. Made-with: Cursor --- .github/workflows/test.yml | 11 + Gemfile | 5 +- Gemfile.lock | 212 ++++---- app/assets/javascripts/application.js.erb | 2 +- app/assets/javascripts/init.js | 94 ++-- app/assets/stylesheets/application.scss | 31 +- app/assets/stylesheets/navbar.scss | 161 +----- app/assets/stylesheets/twbs-variables.scss | 8 - app/assets/stylesheets/twbs.scss | 16 - app/controllers/application_controller.rb | 3 +- app/controllers/entries_controller.rb | 2 +- .../stylesheets/application.tailwind.css | 12 + .../stylesheets/bootstrap-grid-compat.css | 158 ++++++ .../stylesheets/dabble-design-system.css | 492 ++++++++++++++++++ .../stylesheets/marketing.tailwind.css | 345 +----------- app/views/layouts/application.html.haml | 17 +- app/views/shared/_navbar.html.haml | 161 +++--- config/application.rb | 5 +- config/initializers/assets.rb | 2 + config/initializers/cloudflare_test.rb | 7 +- .../new_framework_defaults_7_0.rb | 10 + db/schema.rb | 55 +- package-lock.json | 29 +- package.json | 9 +- public/application-tailwind.css | 2 + public/marketing.css | 2 +- spec/controllers/admin_controller_spec.rb | 8 +- 27 files changed, 1043 insertions(+), 816 deletions(-) delete mode 100644 app/assets/stylesheets/twbs-variables.scss delete mode 100644 app/assets/stylesheets/twbs.scss create mode 100644 app/frontend/stylesheets/application.tailwind.css create mode 100644 app/frontend/stylesheets/bootstrap-grid-compat.css create mode 100644 app/frontend/stylesheets/dabble-design-system.css create mode 100644 config/initializers/new_framework_defaults_7_0.rb create mode 100644 public/application-tailwind.css diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fcaa36bc..ee58e099 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -63,6 +63,17 @@ jobs: sudo apt-get install -y libpq-dev libicu-dev sudo apt-get install -y libicu74 + - name: Set up Node + uses: actions/setup-node@v6 + with: + node-version: '22' + cache: npm + + - name: Install Node and build CSS + run: | + npm ci + npm run build:css:all + - name: Build and create DB env: # use localhost for the host here because we have specified a container for the job. diff --git a/Gemfile b/Gemfile index ae77da88..3b96044e 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,7 @@ source 'https://rubygems.org' ruby File.read(File.expand_path '../.ruby-version', __FILE__).strip.sub /\-p[0-9]+$/, '' # Read the rbenv version file -gem 'rails', '~> 6.1.7.10' +gem 'rails', '~> 7.0.8' gem "concurrent-ruby", "1.3.4" # needed until https://github.com/rails/rails/pull/54264 is in Rails 7.0.8.8 gem "csv" # Ruby 3.4 stdlib extraction - required by ActiveSupport @@ -70,7 +70,6 @@ gem 'autoprefixer-rails' gem 'i18n-js' gem 'jquery-rails' gem 'sass-rails' -gem 'twbs_sass_rails' gem 'uglifier' gem "sidekiq" @@ -92,7 +91,7 @@ group :development, :test do gem 'delorean' gem 'factory_bot_rails' gem 'faker' - gem "rspec-rails" + gem 'rspec-rails', '~> 6.1' gem 'listen' end diff --git a/Gemfile.lock b/Gemfile.lock index 756349d1..4c381d41 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -9,65 +9,79 @@ GIT GEM remote: https://rubygems.org/ specs: - actioncable (6.1.7.10) - actionpack (= 6.1.7.10) - activesupport (= 6.1.7.10) + actioncable (7.0.10) + actionpack (= 7.0.10) + activesupport (= 7.0.10) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.1.7.10) - actionpack (= 6.1.7.10) - activejob (= 6.1.7.10) - activerecord (= 6.1.7.10) - activestorage (= 6.1.7.10) - activesupport (= 6.1.7.10) + actionmailbox (7.0.10) + actionpack (= 7.0.10) + activejob (= 7.0.10) + activerecord (= 7.0.10) + activestorage (= 7.0.10) + activesupport (= 7.0.10) mail (>= 2.7.1) - actionmailer (6.1.7.10) - actionpack (= 6.1.7.10) - actionview (= 6.1.7.10) - activejob (= 6.1.7.10) - activesupport (= 6.1.7.10) + net-imap + net-pop + net-smtp + actionmailer (7.0.10) + actionpack (= 7.0.10) + actionview (= 7.0.10) + activejob (= 7.0.10) + activesupport (= 7.0.10) mail (~> 2.5, >= 2.5.4) + net-imap + net-pop + net-smtp rails-dom-testing (~> 2.0) - actionpack (6.1.7.10) - actionview (= 6.1.7.10) - activesupport (= 6.1.7.10) - rack (~> 2.0, >= 2.0.9) + actionpack (7.0.10) + actionview (= 7.0.10) + activesupport (= 7.0.10) + racc + rack (~> 2.0, >= 2.2.4) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.1.7.10) - actionpack (= 6.1.7.10) - activerecord (= 6.1.7.10) - activestorage (= 6.1.7.10) - activesupport (= 6.1.7.10) + actiontext (7.0.10) + actionpack (= 7.0.10) + activerecord (= 7.0.10) + activestorage (= 7.0.10) + activesupport (= 7.0.10) + globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (6.1.7.10) - activesupport (= 6.1.7.10) + actionview (7.0.10) + activesupport (= 7.0.10) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (6.1.7.10) - activesupport (= 6.1.7.10) + activejob (7.0.10) + activesupport (= 7.0.10) globalid (>= 0.3.6) - activemodel (6.1.7.10) - activesupport (= 6.1.7.10) - activerecord (6.1.7.10) - activemodel (= 6.1.7.10) - activesupport (= 6.1.7.10) - activestorage (6.1.7.10) - actionpack (= 6.1.7.10) - activejob (= 6.1.7.10) - activerecord (= 6.1.7.10) - activesupport (= 6.1.7.10) + activemodel (7.0.10) + activesupport (= 7.0.10) + activerecord (7.0.10) + activemodel (= 7.0.10) + activesupport (= 7.0.10) + activestorage (7.0.10) + actionpack (= 7.0.10) + activejob (= 7.0.10) + activerecord (= 7.0.10) + activesupport (= 7.0.10) marcel (~> 1.0) mini_mime (>= 1.1.0) - activesupport (6.1.7.10) + activesupport (7.0.10) + base64 + benchmark (>= 0.3) + bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) + drb i18n (>= 1.6, < 2) + logger (>= 1.4.2) minitest (>= 5.1) + mutex_m + securerandom (>= 0.3) tzinfo (~> 2.0) - zeitwerk (~> 2.3) addressable (2.8.7) public_suffix (>= 2.0.2, < 7.0) android_key_attestation (0.3.0) @@ -128,7 +142,7 @@ GEM crass (1.0.6) csv (3.3.5) database_cleaner (1.8.4) - date (3.4.1) + date (3.5.1) dead_end (3.1.1) debug_inspector (1.2.0) delorean (2.1.0) @@ -157,7 +171,7 @@ GEM rotp (>= 2.0.0) devise-security (0.18.0) devise (>= 4.3.0) - diff-lcs (1.5.1) + diff-lcs (1.6.2) docile (1.3.2) domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) @@ -210,7 +224,7 @@ GEM get_process_mem (0.2.7) ffi (~> 1.0) glob (0.4.1) - globalid (1.2.1) + globalid (1.3.0) activesupport (>= 6.1) griddler (1.5.2) htmlentities @@ -276,10 +290,11 @@ GEM logtail (~> 0.1) logtail-rack (~> 0.1) railties (>= 5.0.0) - loofah (2.25.0) + loofah (2.25.1) crass (~> 1.0.2) nokogiri (>= 1.12.0) - mail (2.8.1) + mail (2.9.0) + logger mini_mime (>= 0.1.1) net-imap net-pop @@ -305,7 +320,8 @@ GEM logger mini_mime (1.1.5) mini_portile2 (2.8.9) - minitest (6.0.1) + minitest (6.0.3) + drb (~> 2.0) prism (~> 1.5) msgpack (1.6.0) multi_json (1.15.0) @@ -313,18 +329,18 @@ GEM mutex_m (0.2.0) net-http (0.9.1) uri (>= 0.11.1) - net-imap (0.3.9) + net-imap (0.6.3) date net-protocol net-pop (0.1.2) net-protocol net-protocol (0.2.2) timeout - net-smtp (0.3.3) + net-smtp (0.5.1) net-protocol netrc (0.11.0) - nio4r (2.7.4) - nokogiri (1.19.1) + nio4r (2.7.5) + nokogiri (1.19.2) mini_portile2 (~> 2.8.2) racc (~> 1.4) openssl (4.0.0) @@ -333,12 +349,12 @@ GEM orm_adapter (0.5.0) ostruct (0.6.3) pg (1.6.1) - prism (1.7.0) + prism (1.9.0) public_suffix (6.0.2) puma (6.6.1) nio4r (~> 2.0) racc (1.8.1) - rack (2.2.22) + rack (2.2.23) rack-affiliates (0.4.0) rack rack-attack (6.6.1) @@ -350,34 +366,34 @@ GEM rack-timeout (0.6.0) rack-utf8_sanitizer (1.8.0) rack (>= 1.0, < 4.0) - rails (6.1.7.10) - actioncable (= 6.1.7.10) - actionmailbox (= 6.1.7.10) - actionmailer (= 6.1.7.10) - actionpack (= 6.1.7.10) - actiontext (= 6.1.7.10) - actionview (= 6.1.7.10) - activejob (= 6.1.7.10) - activemodel (= 6.1.7.10) - activerecord (= 6.1.7.10) - activestorage (= 6.1.7.10) - activesupport (= 6.1.7.10) + rails (7.0.10) + actioncable (= 7.0.10) + actionmailbox (= 7.0.10) + actionmailer (= 7.0.10) + actionpack (= 7.0.10) + actiontext (= 7.0.10) + actionview (= 7.0.10) + activejob (= 7.0.10) + activemodel (= 7.0.10) + activerecord (= 7.0.10) + activestorage (= 7.0.10) + activesupport (= 7.0.10) bundler (>= 1.15.0) - railties (= 6.1.7.10) - sprockets-rails (>= 2.0.0) + railties (= 7.0.10) rails-dom-testing (2.3.0) activesupport (>= 5.0.0) minitest nokogiri (>= 1.6) - rails-html-sanitizer (1.6.2) - loofah (~> 2.21) + rails-html-sanitizer (1.7.0) + loofah (~> 2.25) nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) - railties (6.1.7.10) - actionpack (= 6.1.7.10) - activesupport (= 6.1.7.10) + railties (7.0.10) + actionpack (= 7.0.10) + activesupport (= 7.0.10) method_source rake (>= 12.2) thor (~> 1.0) + zeitwerk (~> 2.5) rake (13.3.1) randomized_field (1.0.0) activerecord (>= 4.0.0) @@ -404,25 +420,25 @@ GEM rinku (2.0.6) rotp (6.3.0) rouge (4.2.0) - rspec-core (3.10.2) - rspec-support (~> 3.10.0) - rspec-expectations (3.10.1) + rspec-core (3.13.6) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.5) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.10.0) - rspec-mocks (3.10.3) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.8) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.10.0) - rspec-rails (5.1.2) - actionpack (>= 5.2) - activesupport (>= 5.2) - railties (>= 5.2) - rspec-core (~> 3.10) - rspec-expectations (~> 3.10) - rspec-mocks (~> 3.10) - rspec-support (~> 3.10) + rspec-support (~> 3.13.0) + rspec-rails (6.1.5) + actionpack (>= 6.1) + activesupport (>= 6.1) + railties (>= 6.1) + rspec-core (~> 3.13) + rspec-expectations (~> 3.13) + rspec-mocks (~> 3.13) + rspec-support (~> 3.13) rspec-retry (0.6.2) rspec-core (> 3.3) - rspec-support (3.10.2) + rspec-support (3.13.7) ruby-openai (8.1.0) event_stream_parser (>= 0.3.0, < 2.0.0) faraday (>= 1) @@ -445,6 +461,7 @@ GEM sprockets (> 3.0) sprockets-rails tilt + securerandom (0.4.1) selenium-webdriver (4.39.0) base64 (~> 0.2) logger (~> 1.4) @@ -475,12 +492,13 @@ GEM spring (2.1.0) spring-commands-rspec (1.0.4) spring (>= 0.9.1) - sprockets (4.2.0) + sprockets (4.2.2) concurrent-ruby (~> 1.0) + logger rack (>= 2.2.4, < 4) - sprockets-rails (3.4.2) - actionpack (>= 5.2) - activesupport (>= 5.2) + sprockets-rails (3.5.2) + actionpack (>= 6.1) + activesupport (>= 6.1) sprockets (>= 3.0.0) ssrf_filter (1.3.0) stackprof (0.2.19) @@ -491,7 +509,7 @@ GEM temple (0.8.2) thor (1.5.0) tilt (2.0.10) - timeout (0.4.3) + timeout (0.6.1) tpm-key_attestation (0.14.1) bindata (~> 2.4) openssl (> 2.0) @@ -500,10 +518,6 @@ GEM faraday hashie rails (>= 6.1.0) - twbs_sass_rails (10.2.0) - autoprefixer-rails (>= 9.0, < 11) - rails (>= 4.2, < 6.2) - sassc-rails (~> 2.1) tzinfo (2.0.6) concurrent-ruby (~> 1.0) tzinfo-data (1.2024.2) @@ -530,13 +544,14 @@ GEM crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) websocket (1.2.11) - websocket-driver (0.7.6) + websocket-driver (0.8.0) + base64 websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) words_counted (1.0.3) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.7.4) + zeitwerk (2.7.5) PLATFORMS ruby @@ -593,7 +608,7 @@ DEPENDENCIES rack-attack rack-timeout rack-utf8_sanitizer (~> 1.8) - rails (~> 6.1.7.10) + rails (~> 7.0.8) rails-html-sanitizer (~> 1.6) randomized_field (~> 1.0) redcarpet @@ -601,7 +616,7 @@ DEPENDENCIES rest-client reverse_markdown rinku - rspec-rails + rspec-rails (~> 6.1) rspec-retry ruby-openai ruby-vips @@ -621,7 +636,6 @@ DEPENDENCIES summernote-rails (~> 0.8.20.0)! tilt (~> 2.0, >= 2.0.10) turnstile-captcha - twbs_sass_rails tzinfo-data uglifier webauthn diff --git a/app/assets/javascripts/application.js.erb b/app/assets/javascripts/application.js.erb index 0f89a946..453cd08d 100644 --- a/app/assets/javascripts/application.js.erb +++ b/app/assets/javascripts/application.js.erb @@ -1,6 +1,6 @@ //= require jquery //= require rails-ujs -//= require twbs/bootstrap +//= require tippy-bundle.umd.min //= require_true ./lib //= require summernote //= require devise-otp diff --git a/app/assets/javascripts/init.js b/app/assets/javascripts/init.js index a25279cf..66b84870 100644 --- a/app/assets/javascripts/init.js +++ b/app/assets/javascripts/init.js @@ -7,9 +7,10 @@ var didScroll; var lastScrollTop = 0; var delta = 20; - var navbarHeight = $('.navbar-fixed-top').outerHeight(); + var $nav = $('#app-nav'); + var navbarHeight = $nav.length ? $nav.outerHeight() : 56; - $(window).scroll(function(event){ + $(window).scroll(function(){ didScroll = true; }); @@ -21,59 +22,75 @@ }, 250); function hasScrolled() { - var st = $(this).scrollTop(); - - // Make sure they scroll more than delta + var st = $(window).scrollTop(); + if(Math.abs(lastScrollTop - st) <= delta) return; - - // If they scrolled down and are past the navbar, add class .nav-up. - // This is necessary so you never see what is "behind" the navbar. + if (st > lastScrollTop && st > navbarHeight && $(window).width() > 768){ - // Scroll Down - $('.navbar-fixed-top').addClass('nav-up'); + $nav.addClass('nav-up'); $(".j-back-to-top").fadeOut(); } else { - // Scroll Up if(st + $(window).height() < $(document).height()) { - $('.navbar-fixed-top').removeClass('nav-up'); + $nav.removeClass('nav-up'); if ((window.innerHeight + window.scrollY) >= 1600 && $(window).width() > 768) { $(".j-back-to-top").fadeIn(); } } } - + lastScrollTop = st; } - $("[rel='popover']").popover({ - trigger: "hover", - container: "body", - html: true - }); - - $("[rel='tooltip-mobile-friendly']").tooltip({ - container: "body" - }); - - if ($(window).width() > 768) { - $("[rel='popover_settings']").popover({ - trigger: "hover", - container: "body", - html: true - }).popover('show'); + if (typeof tippy !== 'undefined') { + tippy('[rel="popover"]', { + content: function(reference) { + return reference.getAttribute('data-content'); + }, + allowHTML: true, + interactive: true, + theme: 'light-border', + placement: 'auto', + trigger: 'mouseenter focus', + }); - $("[rel='tooltip']").tooltip({ - container: "body" + tippy('[rel="tooltip-mobile-friendly"]', { + content: function(reference) { + return reference.getAttribute('title'); + }, + placement: 'top', + theme: 'light-border', }); + + if ($(window).width() > 768) { + var settingsEls = document.querySelectorAll('[rel="popover_settings"]'); + tippy(settingsEls, { + content: function(reference) { + return reference.getAttribute('data-content'); + }, + allowHTML: true, + interactive: true, + theme: 'light-border', + placement: 'bottom', + trigger: 'mouseenter focus', + showOnCreate: true, + }); + + tippy('[rel="tooltip"]', { + content: function(reference) { + return reference.getAttribute('title'); + }, + placement: 'top', + theme: 'light-border', + }); + } } - $("[rel='popover']").click(function (e) { - //e.stopPropagation(); - $(this).popover('hide'); + $(document).on('click', "[rel='popover']", function () { + if (this._tippy) { this._tippy.hide(); } }); - $(".j-entry-link").click(function(e) { + $(".j-entry-link").on('click', function() { var $entry = $("#entry-"+$(this).attr('data-id')); $('body,html').animate({scrollTop: $entry.offset().top - 70}, 600); $entry.addClass("pulse"); @@ -82,11 +99,12 @@ }, 2000); }); - $(".pictureFrame img").unveil(300); - $(".navbar-toggle").on("click", function () { - $(this).toggleClass("active"); + $('#mobile-menu-toggle').on('click', function() { + $('#mobile-menu').toggleClass('hidden'); + var expanded = !$('#mobile-menu').hasClass('hidden'); + $(this).attr('aria-expanded', expanded); }); $(document).on('click', '.j-copy-to-clipboard', function(e) { diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 33d3c7c0..9197a68d 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -10,8 +10,6 @@ * defined in the other CSS/SCSS files in this directory. It is generally better to create a new * file per style scope. * - *= stub twbs-variables - *= require twbs *= require_self *= require_tree ./lib *= require_tree . @@ -30,8 +28,7 @@ html, body { body { background: $cream; - padding-top: 70px; - font-family: "Raleway", sans-serif; + font-family: "Instrument Sans", "Raleway", sans-serif; font-weight: 400; } @@ -203,36 +200,10 @@ label { height: 575px !important; } -.form-control { - height: 45px; - border-radius: 4px; - font-size: 16px; - border: 2px solid $light-gray; - box-shadow: none; - outline: none; - -webkit-transition: all 0.3s; - transition: all 0.3s; - &:hover { - border-color: #999999; - box-shadow: none; - } - &:focus { - border-color: $olive; - box-shadow: none; - } -} input[type="submit"].form-control { border: 0px; } -.btn-lg, .btn-group-lg>.btn { - border-radius: 4px; -} - -.input-group-addon { - border-width: 2px; -} - .alert-warning.force-links a { color: #66512c !important; text-decoration: underline !important; diff --git a/app/assets/stylesheets/navbar.scss b/app/assets/stylesheets/navbar.scss index 50598643..3735904e 100644 --- a/app/assets/stylesheets/navbar.scss +++ b/app/assets/stylesheets/navbar.scss @@ -1,160 +1 @@ -@import 'vars'; - -.navbar-default { - background-color: $olive; - color:whiteSmoke; - z-index: 1000; - top: 0px; - -webkit-transition: all 0.2s ease-out; - transition: all 0.2s ease-out; - &.nav-up { - top: -51px; - } - li.dropdown.open > .dropdown-toggle { - color: white; - padding-top: 17px; - padding-bottom: 13px; - background-color: darken($olive,20); - text-shadow: 0px 0px 3px darken($olive,40); - } - .navbar-nav > li > a { - color:whiteSmoke; - letter-spacing: 0.5px; - -webkit-transition: all 0.3s; - transition: all 0.3s; - &:hover, &:active, &:focus { - color:white; - padding-top: 17px; - padding-bottom: 13px; - background-color: darken($olive,20); - text-shadow: 0px 0px 3px darken($olive,40); - } - } - .navbar-nav > .active >a { - color: whiteSmoke; - background-color: darken($olive,10); - &:hover, &:active, &:focus { - color: white; - background-color: darken($olive,20); - text-shadow: 0px 0px 3px darken($olive,40); - } - } - .navbar-brand { - font-weight: 400 !important; - -webkit-font-smoothing:antialiased; - letter-spacing: -1px; - color:whiteSmoke; - font-family: "Instrument Serif", Georgia, Cambria, "Times New Roman", Times, serif; - font-size: 20px; - text-shadow: 0px 0px 1px darken($olive,20); - display: inline-block; - -webkit-transition: all 0.3s; - transition: all 0.3s; - &:hover, &:active, &:focus { - color: white; - padding-top: 17px; - padding-bottom: 13px; - background-color: darken($olive,20); - text-shadow: 0px 0px 3px darken($olive,40); - } - span { - font-weight: 400; - letter-spacing: 0; - font-size: 26px; - } - } -} - -.s-write-icon { - float: right; - font-size: 15px; - color: whiteSmoke; - padding: 15px 15px; - text-decoration: none !important; - height: 50px; - -webkit-transition: all 0.3s; - transition: all 0.3s; - &.active { - background-color: darken($olive,10); - } - &:hover, &:active, &:focus { - color:white; - padding-top: 17px; - padding-bottom: 13px; - background-color: darken($olive,20); - text-shadow: 0px 0px 3px darken($olive,40); - } -} - -.navbar-toggle { - border-color: transparent !important; - background: transparent !important; - height: 50px; - padding: 15px; - margin: 0px; - border-radius: 0px; - &:hover, &.active { - color:white; - background-color: darken($olive,20) !important; - } -} - -.navbar-default .navbar-toggle .icon-bar { - background-color: whiteSmoke; - &:active { - background-color: white; - } -} - -.navbar-collapse { - border-top: none; -} - -.navbar-toggle .icon-bar:nth-of-type(2) { - top: 1px; -} - -.navbar-toggle .icon-bar:nth-of-type(3) { - top: 2px; -} - -.navbar-toggle .icon-bar { - position: relative; - -webkit-transition: all 500ms ease-in-out; - transition: all 500ms ease-in-out; -} - -.navbar-toggle.active .icon-bar:nth-of-type(1) { - top: 6px; - transform: rotate(45deg); -} - -.navbar-toggle.active .icon-bar:nth-of-type(2) { - background-color: transparent; -} - -.navbar-toggle.active .icon-bar:nth-of-type(3) { - top: -6px; - transform: rotate(-45deg); -} - -@media (max-width: 767px) { - .navbar-default .navbar-nav .open .dropdown-menu > li > a { - color: white; - } - - .navbar-fixed-top { - position: absolute; - top:0; - } - - .navbar-default { - .navbar-nav > li > a { - &:hover, &:active, &:focus { - padding-top: 10px; - padding-bottom: 10px; - } - } - } - -} +/* Navbar styles live in Tailwind (application-tailwind.css). Legacy rules removed. */ diff --git a/app/assets/stylesheets/twbs-variables.scss b/app/assets/stylesheets/twbs-variables.scss deleted file mode 100644 index eb1f0652..00000000 --- a/app/assets/stylesheets/twbs-variables.scss +++ /dev/null @@ -1,8 +0,0 @@ -@import 'vars'; - -.text-primary { - color: $olive-950 !important; -} - -/* Do not edit below this line */ -@import "twbs/bootstrap/variables"; diff --git a/app/assets/stylesheets/twbs.scss b/app/assets/stylesheets/twbs.scss deleted file mode 100644 index 0d341fb2..00000000 --- a/app/assets/stylesheets/twbs.scss +++ /dev/null @@ -1,16 +0,0 @@ -/* Use twbs-variables to define new variables and override Bootstrap defaults. - * Import "twbs-variables" instead of "twbs/bootstrap/variables" - * in each new stylesheet. - */ -@import "twbs-variables"; - -/* Start editing below this line */ -@import "twbs/bootstrap"; - -/* Glyphs */ -@import "fontawesome/font-awesome"; - -/* Standard Rails form errors */ -.field_with_errors { - @extend .has-error; -} diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 3e39d598..168e58fd 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -9,7 +9,8 @@ class ApplicationController < ActionController::Base rescue_from Rack::Timeout::RequestTimeoutException, with: :handle_timeout - def redirect_back_or_to(default) + # Custom name avoids clashing with Rails 7's `redirect_back_or_to` (used by `redirect_back`). + def redirect_to_return_or(default) redirect_to session&.delete(:return_to) || session&.delete(:user_return_to) || default end diff --git a/app/controllers/entries_controller.rb b/app/controllers/entries_controller.rb index aefb061e..c2047590 100644 --- a/app/controllers/entries_controller.rb +++ b/app/controllers/entries_controller.rb @@ -213,7 +213,7 @@ def update elsif params[:entry][:entry].blank? @entry.destroy flash[:notice] = 'Entry deleted!' - redirect_back_or_to entries_path + redirect_to_return_or entries_path else update_params = if @entry.image_url_cdn.present? && entry_params[:remove_image] == "0" @entry.remote_image_url = @entry.image_url_cdn(cloudflare: false) diff --git a/app/frontend/stylesheets/application.tailwind.css b/app/frontend/stylesheets/application.tailwind.css new file mode 100644 index 00000000..9303987c --- /dev/null +++ b/app/frontend/stylesheets/application.tailwind.css @@ -0,0 +1,12 @@ +@import "tailwindcss"; + +/* Authenticated app + all non-marketing templates */ +@source "../../../app/views/**/*.haml"; +@source "../../../app/views/**/*.erb"; + +@import "./dabble-design-system.css"; +@import "./bootstrap-grid-compat.css"; + +@import "../../../node_modules/font-awesome/css/font-awesome.min.css"; +@import "../../../node_modules/tippy.js/dist/tippy.css"; +@import "../../../node_modules/tippy.js/themes/light-border.css"; diff --git a/app/frontend/stylesheets/bootstrap-grid-compat.css b/app/frontend/stylesheets/bootstrap-grid-compat.css new file mode 100644 index 00000000..b1b5fb1b --- /dev/null +++ b/app/frontend/stylesheets/bootstrap-grid-compat.css @@ -0,0 +1,158 @@ +/* Flexbox 12-column grid compatible with Bootstrap 3 class names (layout only). */ +.container { width: 100%; max-width: 1170px; margin-left: auto; margin-right: auto; padding-left: 15px; padding-right: 15px; box-sizing: border-box; } +.container-fluid { width: 100%; padding-left: 15px; padding-right: 15px; box-sizing: border-box; } +.row { display: flex; flex-wrap: wrap; margin-left: -15px; margin-right: -15px; box-sizing: border-box; } +.row > [class*="col-"] { box-sizing: border-box; padding-left: 15px; padding-right: 15px; min-width: 0; } +.clearfix::before, .clearfix::after, .row::before, .row::after { content: " "; display: table; } +.clearfix::after, .row::after { clear: both; } + +/* Below md: md width stacks; md offsets cleared (Bootstrap 3 behavior) */ +@media (max-width: 991px) { + .col-md-1 { flex: 0 0 100%; max-width: 100%; } + .col-md-2 { flex: 0 0 100%; max-width: 100%; } + .col-md-3 { flex: 0 0 100%; max-width: 100%; } + .col-md-4 { flex: 0 0 100%; max-width: 100%; } + .col-md-5 { flex: 0 0 100%; max-width: 100%; } + .col-md-6 { flex: 0 0 100%; max-width: 100%; } + .col-md-7 { flex: 0 0 100%; max-width: 100%; } + .col-md-8 { flex: 0 0 100%; max-width: 100%; } + .col-md-9 { flex: 0 0 100%; max-width: 100%; } + .col-md-10 { flex: 0 0 100%; max-width: 100%; } + .col-md-11 { flex: 0 0 100%; max-width: 100%; } + .col-md-12 { flex: 0 0 100%; max-width: 100%; } + .col-md-offset-1 { margin-left: 0; } + .col-md-offset-2 { margin-left: 0; } + .col-md-offset-3 { margin-left: 0; } + .col-md-offset-4 { margin-left: 0; } + .col-md-offset-5 { margin-left: 0; } + .col-md-offset-6 { margin-left: 0; } + .col-md-offset-7 { margin-left: 0; } + .col-md-offset-8 { margin-left: 0; } + .col-md-offset-9 { margin-left: 0; } + .col-md-offset-10 { margin-left: 0; } + .col-md-offset-11 { margin-left: 0; } + .col-md-offset-12 { margin-left: 0; } +} +/* col-xs-* (applies all breakpoints; wins over md stack when combined) */ +.col-xs-1 { flex: 0 0 8.33333333%; max-width: 8.33333333%; } +.col-xs-2 { flex: 0 0 16.66666667%; max-width: 16.66666667%; } +.col-xs-3 { flex: 0 0 25.0%; max-width: 25.0%; } +.col-xs-4 { flex: 0 0 33.33333333%; max-width: 33.33333333%; } +.col-xs-5 { flex: 0 0 41.66666667%; max-width: 41.66666667%; } +.col-xs-6 { flex: 0 0 50.0%; max-width: 50.0%; } +.col-xs-7 { flex: 0 0 58.33333333%; max-width: 58.33333333%; } +.col-xs-8 { flex: 0 0 66.66666667%; max-width: 66.66666667%; } +.col-xs-9 { flex: 0 0 75.0%; max-width: 75.0%; } +.col-xs-10 { flex: 0 0 83.33333333%; max-width: 83.33333333%; } +.col-xs-11 { flex: 0 0 91.66666667%; max-width: 91.66666667%; } +.col-xs-12 { flex: 0 0 100.0%; max-width: 100.0%; } +.col-xs-offset-1 { margin-left: 8.33333333%; } +.col-xs-offset-2 { margin-left: 16.66666667%; } +.col-xs-offset-3 { margin-left: 25.0%; } +.col-xs-offset-4 { margin-left: 33.33333333%; } +.col-xs-offset-5 { margin-left: 41.66666667%; } +.col-xs-offset-6 { margin-left: 50.0%; } +.col-xs-offset-7 { margin-left: 58.33333333%; } +.col-xs-offset-8 { margin-left: 66.66666667%; } +.col-xs-offset-9 { margin-left: 75.0%; } +.col-xs-offset-10 { margin-left: 83.33333333%; } +.col-xs-offset-11 { margin-left: 91.66666667%; } +.col-xs-offset-12 { margin-left: 100.0%; } +@media (min-width: 768px) { + .col-sm-1 { flex: 0 0 8.33333333%; max-width: 8.33333333%; } + .col-sm-2 { flex: 0 0 16.66666667%; max-width: 16.66666667%; } + .col-sm-3 { flex: 0 0 25.0%; max-width: 25.0%; } + .col-sm-4 { flex: 0 0 33.33333333%; max-width: 33.33333333%; } + .col-sm-5 { flex: 0 0 41.66666667%; max-width: 41.66666667%; } + .col-sm-6 { flex: 0 0 50.0%; max-width: 50.0%; } + .col-sm-7 { flex: 0 0 58.33333333%; max-width: 58.33333333%; } + .col-sm-8 { flex: 0 0 66.66666667%; max-width: 66.66666667%; } + .col-sm-9 { flex: 0 0 75.0%; max-width: 75.0%; } + .col-sm-10 { flex: 0 0 83.33333333%; max-width: 83.33333333%; } + .col-sm-11 { flex: 0 0 91.66666667%; max-width: 91.66666667%; } + .col-sm-12 { flex: 0 0 100.0%; max-width: 100.0%; } + .col-sm-offset-1 { margin-left: 8.33333333%; } + .col-sm-offset-2 { margin-left: 16.66666667%; } + .col-sm-offset-3 { margin-left: 25.0%; } + .col-sm-offset-4 { margin-left: 33.33333333%; } + .col-sm-offset-5 { margin-left: 41.66666667%; } + .col-sm-offset-6 { margin-left: 50.0%; } + .col-sm-offset-7 { margin-left: 58.33333333%; } + .col-sm-offset-8 { margin-left: 66.66666667%; } + .col-sm-offset-9 { margin-left: 75.0%; } + .col-sm-offset-10 { margin-left: 83.33333333%; } + .col-sm-offset-11 { margin-left: 91.66666667%; } + .col-sm-offset-12 { margin-left: 100.0%; } +} +@media (min-width: 992px) { + .col-md-1 { flex: 0 0 8.33333333%; max-width: 8.33333333%; } + .col-md-2 { flex: 0 0 16.66666667%; max-width: 16.66666667%; } + .col-md-3 { flex: 0 0 25.0%; max-width: 25.0%; } + .col-md-4 { flex: 0 0 33.33333333%; max-width: 33.33333333%; } + .col-md-5 { flex: 0 0 41.66666667%; max-width: 41.66666667%; } + .col-md-6 { flex: 0 0 50.0%; max-width: 50.0%; } + .col-md-7 { flex: 0 0 58.33333333%; max-width: 58.33333333%; } + .col-md-8 { flex: 0 0 66.66666667%; max-width: 66.66666667%; } + .col-md-9 { flex: 0 0 75.0%; max-width: 75.0%; } + .col-md-10 { flex: 0 0 83.33333333%; max-width: 83.33333333%; } + .col-md-11 { flex: 0 0 91.66666667%; max-width: 91.66666667%; } + .col-md-12 { flex: 0 0 100.0%; max-width: 100.0%; } + .col-md-offset-1 { margin-left: 8.33333333%; } + .col-md-offset-2 { margin-left: 16.66666667%; } + .col-md-offset-3 { margin-left: 25.0%; } + .col-md-offset-4 { margin-left: 33.33333333%; } + .col-md-offset-5 { margin-left: 41.66666667%; } + .col-md-offset-6 { margin-left: 50.0%; } + .col-md-offset-7 { margin-left: 58.33333333%; } + .col-md-offset-8 { margin-left: 66.66666667%; } + .col-md-offset-9 { margin-left: 75.0%; } + .col-md-offset-10 { margin-left: 83.33333333%; } + .col-md-offset-11 { margin-left: 91.66666667%; } + .col-md-offset-12 { margin-left: 100.0%; } +} +@media (min-width: 1200px) { + .col-lg-1 { flex: 0 0 8.33333333%; max-width: 8.33333333%; } + .col-lg-2 { flex: 0 0 16.66666667%; max-width: 16.66666667%; } + .col-lg-3 { flex: 0 0 25.0%; max-width: 25.0%; } + .col-lg-4 { flex: 0 0 33.33333333%; max-width: 33.33333333%; } + .col-lg-5 { flex: 0 0 41.66666667%; max-width: 41.66666667%; } + .col-lg-6 { flex: 0 0 50.0%; max-width: 50.0%; } + .col-lg-7 { flex: 0 0 58.33333333%; max-width: 58.33333333%; } + .col-lg-8 { flex: 0 0 66.66666667%; max-width: 66.66666667%; } + .col-lg-9 { flex: 0 0 75.0%; max-width: 75.0%; } + .col-lg-10 { flex: 0 0 83.33333333%; max-width: 83.33333333%; } + .col-lg-11 { flex: 0 0 91.66666667%; max-width: 91.66666667%; } + .col-lg-12 { flex: 0 0 100.0%; max-width: 100.0%; } + .col-lg-offset-1 { margin-left: 8.33333333%; } + .col-lg-offset-2 { margin-left: 16.66666667%; } + .col-lg-offset-3 { margin-left: 25.0%; } + .col-lg-offset-4 { margin-left: 33.33333333%; } + .col-lg-offset-5 { margin-left: 41.66666667%; } + .col-lg-offset-6 { margin-left: 50.0%; } + .col-lg-offset-7 { margin-left: 58.33333333%; } + .col-lg-offset-8 { margin-left: 66.66666667%; } + .col-lg-offset-9 { margin-left: 75.0%; } + .col-lg-offset-10 { margin-left: 83.33333333%; } + .col-lg-offset-11 { margin-left: 91.66666667%; } + .col-lg-offset-12 { margin-left: 100.0%; } +} +.pull-left { float: left; } +.pull-right { float: right; } +.center { text-align: center; margin-left: auto; margin-right: auto; } +@media (max-width: 767px) { + .hidden-xs { display: none !important; } +} +@media (min-width: 768px) { + .visible-xs { display: none !important; } +} +@media (min-width: 768px) and (max-width: 991px) { + .hidden-sm { display: none !important; } +} +.visible-xs.visible-sm { + display: none !important; +} +@media (max-width: 991px) { + .visible-xs.visible-sm { + display: block !important; + } +} diff --git a/app/frontend/stylesheets/dabble-design-system.css b/app/frontend/stylesheets/dabble-design-system.css new file mode 100644 index 00000000..8d14679d --- /dev/null +++ b/app/frontend/stylesheets/dabble-design-system.css @@ -0,0 +1,492 @@ +/* Shared @theme, base, components, utilities for marketing + app Tailwind builds */ + +@theme { + --color-olive-50: oklch(98.8% 0.003 106.5); + --color-olive-100: oklch(96.6% 0.005 106.5); + --color-olive-150: oklch(94.5% 0.006 106.5); + --color-olive-200: oklch(93% 0.007 106.5); + --color-olive-300: oklch(88% 0.011 106.6); + --color-olive-400: oklch(73.7% 0.021 106.9); + --color-olive-500: oklch(58% 0.031 107.3); + --color-olive-600: oklch(46.6% 0.025 107.3); + --color-olive-700: oklch(39.4% 0.023 107.4); + --color-olive-800: oklch(28.6% 0.016 107.4); + --color-olive-900: oklch(22.8% 0.013 107.4); + --color-olive-950: oklch(15.3% 0.006 107.1); + + --color-cream-50: #fdfcfa; + --color-cream-100: #f9f7f3; + --color-cream-200: #f3f1ec; + --color-cream-300: #edeae3; + --color-cream-400: #e0dcd2; + --color-cream-500: #d0cbc0; + --color-cream-600: #b8b2a5; + --color-cream-700: #9a9388; + --color-cream-800: #7f796f; + --color-cream-900: #69645c; + --color-cream-950: #37342f; + + --color-dark-950: #0a0a0a; + --color-dark-900: #0f0f0f; + --color-dark-800: #171717; + --color-dark-700: #1f1f1f; + --color-dark-600: #2a2a2a; + --color-dark-500: #3d3d3d; + --color-dark-400: #525252; + --color-dark-300: #6b6b6b; + --color-dark-200: #a3a3a3; + --color-dark-100: #d4d4d4; + + --font-serif: "Instrument Serif", Georgia, serif; + --font-sans: "Instrument Sans", system-ui, sans-serif; +} + +@layer base { + :root { + --color-bg: var(--color-olive-100); + --color-surface: #ffffff; + --color-surface-elevated: var(--color-cream-200); + --color-primary: var(--color-olive-950); + --color-primary-hover: var(--color-olive-900); + --color-accent: var(--color-olive-600); + --color-accent-hover: var(--color-olive-700); + --color-text: var(--color-olive-950); + --color-text-muted: var(--color-olive-800); + --color-text-subtle: var(--color-olive-600); + --color-border: var(--color-cream-400); + --color-border-subtle: var(--color-cream-300); + + --color-hero-bg: var(--color-olive-800); + --color-hero-text: var(--color-white); + --color-hero-muted: var(--color-cream-100); + --color-hero-accent: var(--color-olive-300); + + --color-btn-primary-bg: var(--color-olive-900); + --color-btn-primary-text: var(--color-cream-100); + --color-btn-primary-hover: var(--color-olive-950); + + --color-footer-bg: var(--color-olive-150); + } + + @media (prefers-color-scheme: dark) { + :root { + --color-bg: var(--color-dark-950); + --color-surface: var(--color-dark-900); + --color-surface-elevated: var(--color-dark-800); + --color-primary: var(--color-cream-100); + --color-primary-hover: #ffffff; + --color-accent: var(--color-olive-400); + --color-accent-hover: var(--color-olive-300); + --color-text: var(--color-cream-100); + --color-text-muted: var(--color-dark-200); + --color-text-subtle: var(--color-dark-300); + --color-border: var(--color-dark-500); + --color-border-subtle: var(--color-dark-600); + + --color-hero-bg: var(--color-olive-800); + --color-hero-text: var(--color-cream-100); + --color-hero-muted: var(--color-cream-300); + --color-hero-accent: var(--color-olive-500); + + --color-btn-primary-bg: var(--color-cream-100); + --color-btn-primary-text: var(--color-olive-950); + --color-btn-primary-hover: #ffffff; + + --color-footer-bg: var(--color-olive-900); + } + } + + html { + font-family: var(--font-sans); + scroll-behavior: smooth; + } + + body { + background-color: var(--color-bg); + color: var(--color-text); + } + + h1, h2, h3, h4, h5, h6 { + font-family: var(--font-serif); + } + + details summary { + list-style: none; + } + + details summary::-webkit-details-marker { + display: none; + } +} + +@layer components { + .btn { + @apply inline-flex items-center justify-center px-6 py-3 font-medium rounded-full transition-colors duration-200 cursor-pointer; + } + + .btn-primary { + background-color: var(--color-btn-primary-bg); + color: var(--color-btn-primary-text); + } + + @media (prefers-color-scheme: dark) { + .btn-primary { + background-color: #f9f7f3; + color: #1f231c; + } + } + + .btn-primary:hover { + background-color: var(--color-btn-primary-hover); + } + + .btn-secondary { + background-color: transparent; + color: var(--color-text); + border: 1px solid var(--color-border); + } + + .btn-secondary:hover { + background-color: var(--color-surface); + border-color: var(--color-text-muted); + } + + .card { + background-color: var(--color-surface); + border: 1px solid var(--color-border-subtle); + border-radius: 0.75rem; + } + + .section-heading { + font-family: var(--font-serif); + font-size: 2.5rem; + line-height: 1.2; + color: var(--color-text); + } + + .text-muted { + color: var(--color-text-muted); + } + + .text-subtle { + color: var(--color-text-subtle); + } + + .accordion-item { + border-bottom: 1px solid var(--color-border-subtle); + } + + .accordion-trigger { + @apply flex w-full items-center justify-between pb-4 pt-4 text-left font-medium; + color: var(--color-text); + } + + .accordion-trigger:hover { + color: var(--color-primary); + } + + .accordion-content { + @apply overflow-hidden transition-all duration-300; + color: var(--color-text-muted); + } + + .badge { + @apply inline-flex items-center gap-1.5 px-3 py-1 text-sm font-medium rounded-full; + background-color: var(--color-surface-elevated); + color: var(--color-text-muted); + } + + .badge-accent { + background-color: var(--color-accent); + color: var(--color-cream-100); + } + + /* App shell: flash + form helpers (non-Bootstrap class names) */ + .alert-app-success { + @apply rounded-lg border px-4 py-3 text-center; + background-color: color-mix(in oklab, var(--color-olive-600) 12%, transparent); + border-color: var(--color-olive-400); + color: var(--color-olive-950); + } + + .alert-app-danger { + @apply rounded-lg border px-4 py-3 text-center; + background-color: color-mix(in oklab, #9e0812 12%, transparent); + border-color: #c53030; + color: var(--color-olive-950); + } + + @media (prefers-color-scheme: dark) { + .alert-app-success { + color: var(--color-cream-100); + } + .alert-app-danger { + color: var(--color-cream-100); + } + } + + .input-app { + @apply w-full rounded-md border px-3 py-2 text-base outline-none transition; + border-color: var(--color-border); + background-color: var(--color-surface); + color: var(--color-text); + } + + .input-app:focus { + border-color: var(--color-olive-600); + box-shadow: 0 0 0 2px color-mix(in oklab, var(--color-olive-600) 35%, transparent); + } + + /* Legacy Bootstrap 3–named helpers (no Bootstrap CSS; class names only) */ + .form-control { + @apply w-full rounded-md border px-3 py-2 text-base outline-none transition; + border-color: var(--color-border); + background-color: var(--color-surface); + color: var(--color-text); + } + + .form-control:focus { + border-color: var(--color-olive-600); + box-shadow: 0 0 0 2px color-mix(in oklab, var(--color-olive-600) 35%, transparent); + } + + .well { + @apply rounded-lg border p-4 shadow-sm; + border-color: var(--color-border-subtle); + background-color: var(--color-surface); + } + + .alert.alert-success { + @apply rounded-lg border px-4 py-3; + background-color: color-mix(in oklab, var(--color-olive-600) 12%, transparent); + border-color: var(--color-olive-400); + color: var(--color-olive-950); + } + + .alert.alert-danger { + @apply rounded-lg border px-4 py-3; + background-color: color-mix(in oklab, #9e0812 15%, transparent); + border-color: #c53030; + color: var(--color-olive-950); + } + + .alert.alert-info { + @apply rounded-lg border px-4 py-3; + background-color: color-mix(in oklab, #31708f 12%, transparent); + border-color: #31708f; + color: var(--color-olive-950); + } + + .alert.alert-warning { + @apply rounded-lg border px-4 py-3; + background-color: color-mix(in oklab, var(--color-olive-500) 18%, transparent); + border-color: var(--color-olive-400); + color: var(--color-olive-950); + } + + @media (prefers-color-scheme: dark) { + .alert.alert-success, + .alert.alert-danger, + .alert.alert-info, + .alert.alert-warning { + color: var(--color-cream-100); + } + } + + .btn-default { + @apply inline-flex items-center justify-center rounded-md border px-4 py-2 text-sm font-medium; + border-color: var(--color-border); + background-color: var(--color-surface); + color: var(--color-text); + } + + .btn-default:hover { + background-color: var(--color-surface-elevated); + } + + .btn-danger { + @apply inline-flex items-center justify-center rounded-md px-4 py-2 text-sm font-medium text-white; + background-color: #9e0812; + } + + .btn-danger:hover { + background-color: #7a060e; + } + + .btn-warning { + @apply inline-flex items-center justify-center rounded-md px-4 py-2 text-sm font-medium; + background-color: #f0ad4e; + color: #1a1a1a; + } + + .btn-success { + @apply inline-flex items-center justify-center rounded-md px-4 py-2 text-sm font-medium text-white; + background-color: var(--color-olive-800); + } + + .btn-info { + @apply inline-flex items-center justify-center rounded-md px-4 py-2 text-sm font-medium text-white; + background-color: #5bc0de; + } + + .btn-link { + @apply inline-flex items-center justify-center border-0 bg-transparent px-2 py-1 text-sm underline; + color: var(--color-accent); + } + + .btn-xs { + @apply px-2 py-1 text-xs; + } + + .btn-sm { + @apply px-3 py-1.5 text-sm; + } + + .btn-lg { + @apply px-6 py-3 text-lg; + } + + .btn-block { + @apply w-full justify-center; + } + + .label.label-default { + @apply inline-block rounded px-2 py-0.5 text-xs font-normal; + background-color: var(--color-surface-elevated); + color: var(--color-text-muted); + } +} + +@layer utilities { + .bg-page { + background-color: var(--color-bg); + } + + .bg-surface { + background-color: var(--color-surface); + } + + .hover\:bg-surface:hover { + background-color: var(--color-surface); + } + + .bg-surface-elevated { + background-color: var(--color-surface-elevated); + } + + .hover\:bg-surface-elevated:hover { + background-color: var(--color-surface-elevated); + } + + .bg-footer { + background-color: var(--color-footer-bg); + } + + .bg-bg { + background-color: var(--color-bg); + } + + .text-primary { + color: var(--color-primary); + } + + .hover\:text-primary:hover { + color: var(--color-primary); + } + + .text-accent { + color: var(--color-accent); + } + + .hover\:text-accent:hover { + color: var(--color-accent); + } + + .border-default { + border-color: var(--color-border); + } + + .border-subtle { + border-color: var(--color-border-subtle); + } + + .bg-hero { + background: linear-gradient(to bottom, #5c6654, #333a2b); + } + + @media (prefers-color-scheme: dark) { + .bg-hero { + background: linear-gradient(to bottom, #5c6654, #333a2b); + } + } + + .text-hero { + color: var(--color-hero-text); + } + + .text-hero-muted { + color: var(--color-hero-muted); + } + + .text-hero-accent { + color: var(--color-hero-accent); + } + + .bg-grain { + position: absolute; + inset: 0; + border-radius: inherit; + background-position: center; + pointer-events: none; + opacity: 0.3; + mix-blend-mode: overlay; + } + + @media (prefers-color-scheme: dark) { + .bg-grain { + opacity: 0.25; + } + } + + .bg-grain > * { + position: relative; + z-index: 1; + } + + .animate-fade-in { + animation: fadeIn 0.5s ease-out forwards; + } + + .animate-slide-up { + animation: slideUp 0.5s ease-out forwards; + } + + @keyframes fadeIn { + from { opacity: 0; } + to { opacity: 1; } + } + + @keyframes slideUp { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } + } + + .blinking-cursor { + animation: blink 1.3s step-end infinite; + } + + @keyframes blink { + 0%, 100% { opacity: 1; } + 50% { opacity: 0; } + } + + #app-nav.nav-up { + transform: translateY(-100%); + } +} diff --git a/app/frontend/stylesheets/marketing.tailwind.css b/app/frontend/stylesheets/marketing.tailwind.css index 3f16fa67..334d4b8c 100644 --- a/app/frontend/stylesheets/marketing.tailwind.css +++ b/app/frontend/stylesheets/marketing.tailwind.css @@ -6,350 +6,7 @@ @source "../../../app/views/shared/_marketing_*.erb"; @source "../../../app/views/devise/**/*.erb"; -/* Custom theme configuration for Dabble Me Oatmeal design */ -@theme { - --color-olive-50: oklch(98.8% 0.003 106.5); - --color-olive-100: oklch(96.6% 0.005 106.5); - --color-olive-150: oklch(94.5% 0.006 106.5); - --color-olive-200: oklch(93% 0.007 106.5); - --color-olive-300: oklch(88% 0.011 106.6); - --color-olive-400: oklch(73.7% 0.021 106.9); - --color-olive-500: oklch(58% 0.031 107.3); - --color-olive-600: oklch(46.6% 0.025 107.3); - --color-olive-700: oklch(39.4% 0.023 107.4); - --color-olive-800: oklch(28.6% 0.016 107.4); - --color-olive-900: oklch(22.8% 0.013 107.4); - --color-olive-950: oklch(15.3% 0.006 107.1); - - /* Cream/Warm neutrals - exactly matching Oatmeal */ - --color-cream-50: #fdfcfa; - --color-cream-100: #f9f7f3; - --color-cream-200: #f3f1ec; - --color-cream-300: #edeae3; - --color-cream-400: #e0dcd2; - --color-cream-500: #d0cbc0; - --color-cream-600: #b8b2a5; - --color-cream-700: #9a9388; - --color-cream-800: #7f796f; - --color-cream-900: #69645c; - --color-cream-950: #37342f; - - /* Dark mode neutrals (charcoal, not olive) */ - --color-dark-950: #0a0a0a; - --color-dark-900: #0f0f0f; - --color-dark-800: #171717; - --color-dark-700: #1f1f1f; - --color-dark-600: #2a2a2a; - --color-dark-500: #3d3d3d; - --color-dark-400: #525252; - --color-dark-300: #6b6b6b; - --color-dark-200: #a3a3a3; - --color-dark-100: #d4d4d4; - - /* Font families */ - --font-serif: "Instrument Serif", Georgia, serif; - --font-sans: "Instrument Sans", system-ui, sans-serif; -} - -/* Base layer for light/dark mode */ -@layer base { - :root { - --color-bg: var(--color-olive-100); - --color-surface: #ffffff; - --color-surface-elevated: var(--color-cream-200); - /* Primary text is the darkest olive for maximum readability */ - --color-primary: var(--color-olive-950); - --color-primary-hover: var(--color-olive-900); - --color-accent: var(--color-olive-600); - --color-accent-hover: var(--color-olive-700); - --color-text: var(--color-olive-950); - --color-text-muted: var(--color-olive-800); - --color-text-subtle: var(--color-olive-600); - --color-border: var(--color-cream-400); - --color-border-subtle: var(--color-cream-300); - - /* Hero section colors (dark olive with texture) */ - --color-hero-bg: var(--color-olive-800); - --color-hero-text: var(--color-white); - --color-hero-muted: var(--color-cream-100); - --color-hero-accent: var(--color-olive-300); - - /* Primary button colors - dark olive bg, cream text in light mode */ - --color-btn-primary-bg: var(--color-olive-900); - --color-btn-primary-text: var(--color-cream-100); - --color-btn-primary-hover: var(--color-olive-950); - - /* Footer colors */ - --color-footer-bg: var(--color-olive-150); - } - - @media (prefers-color-scheme: dark) { - :root { - --color-bg: var(--color-dark-950); - --color-surface: var(--color-dark-900); - --color-surface-elevated: var(--color-dark-800); - --color-primary: var(--color-cream-100); - --color-primary-hover: #ffffff; - --color-accent: var(--color-olive-400); - --color-accent-hover: var(--color-olive-300); - --color-text: var(--color-cream-100); - --color-text-muted: var(--color-dark-200); - --color-text-subtle: var(--color-dark-300); - --color-border: var(--color-dark-500); - --color-border-subtle: var(--color-dark-600); - - /* Hero in dark mode - keep the olive hero for visual pop */ - --color-hero-bg: var(--color-olive-800); - --color-hero-text: var(--color-cream-100); - --color-hero-muted: var(--color-cream-300); - --color-hero-accent: var(--color-olive-500); - - /* Primary button in dark mode - cream bg, dark olive text for contrast */ - --color-btn-primary-bg: var(--color-cream-100); - --color-btn-primary-text: var(--color-olive-950); - --color-btn-primary-hover: #ffffff; - - /* Footer colors */ - --color-footer-bg: var(--color-olive-900); - } - } - - html { - font-family: var(--font-sans); - scroll-behavior: smooth; - } - - body { - background-color: var(--color-bg); - color: var(--color-text); - } - - h1, h2, h3, h4, h5, h6 { - font-family: var(--font-serif); - } -} - -/* Component layer for reusable components */ -@layer components { - .btn { - @apply inline-flex items-center justify-center px-6 py-3 font-medium rounded-full transition-colors duration-200 cursor-pointer; - } - - /* Primary button - uses CSS custom properties that switch with dark mode */ - .btn-primary { - background-color: var(--color-btn-primary-bg); - color: var(--color-btn-primary-text); - } - - @media (prefers-color-scheme: dark) { - .btn-primary { - /* Explicit dark mode override to ensure text is visible */ - background-color: #f9f7f3; /* cream-100 */ - color: #1f231c; /* olive-950 - dark text for contrast */ - } - } - - .btn-primary:hover { - background-color: var(--color-btn-primary-hover); - } - - .btn-secondary { - background-color: transparent; - color: var(--color-text); - border: 1px solid var(--color-border); - } - - .btn-secondary:hover { - background-color: var(--color-surface); - border-color: var(--color-text-muted); - } - - .card { - background-color: var(--color-surface); - border: 1px solid var(--color-border-subtle); - border-radius: 0.75rem; - } - - .section-heading { - font-family: var(--font-serif); - font-size: 2.5rem; - line-height: 1.2; - color: var(--color-text); - } - - .text-muted { - color: var(--color-text-muted); - } - - .text-subtle { - color: var(--color-text-subtle); - } - - /* Accordion styles for FAQ */ - .accordion-item { - border-bottom: 1px solid var(--color-border-subtle); - } - - .accordion-trigger { - @apply flex w-full items-center justify-between pb-4 pt-4 text-left font-medium; - color: var(--color-text); - } - - .accordion-trigger:hover { - color: var(--color-primary); - } - - .accordion-content { - @apply overflow-hidden transition-all duration-300; - color: var(--color-text-muted); - } - - /* Badge/pill styles */ - .badge { - @apply inline-flex items-center gap-1.5 px-3 py-1 text-sm font-medium rounded-full; - background-color: var(--color-surface-elevated); - color: var(--color-text-muted); - } - - .badge-accent { - background-color: var(--color-accent); - color: var(--color-cream-100); - } -} - -/* Utility layer for custom utilities */ -@layer utilities { - .bg-page { - background-color: var(--color-bg); - } - - .bg-surface { - background-color: var(--color-surface); - } - - .hover\:bg-surface:hover { - background-color: var(--color-surface); - } - - .bg-surface-elevated { - background-color: var(--color-surface-elevated); - } - - .hover\:bg-surface-elevated:hover { - background-color: var(--color-surface-elevated); - } - - .bg-footer { - background-color: var(--color-footer-bg); - } - - .bg-bg { - background-color: var(--color-bg); - } - - .text-primary { - color: var(--color-primary); - } - - .hover\:text-primary:hover { - color: var(--color-primary); - } - - .text-accent { - color: var(--color-accent); - } - - .hover\:text-accent:hover { - color: var(--color-accent); - } - - .border-default { - border-color: var(--color-border); - } - - .border-subtle { - border-color: var(--color-border-subtle); - } - - /* Hero section utilities - gradient matching Oatmeal's green theme */ - .bg-hero { - background: linear-gradient(to bottom, #5C6654, #333a2b); - } - - @media (prefers-color-scheme: dark) { - .bg-hero { - background: linear-gradient(to bottom, #5C6654, #333a2b); - } - } - - .text-hero { - color: var(--color-hero-text); - } - - .text-hero-muted { - color: var(--color-hero-muted); - } - - .text-hero-accent { - color: var(--color-hero-accent); - } - - .bg-grain { - position: absolute; - inset: 0; - border-radius: inherit; - background-position: center; - pointer-events: none; - opacity: 0.3; - mix-blend-mode: overlay; - } - - @media (prefers-color-scheme: dark) { - .bg-grain { - opacity: 0.25; - } - } - - .bg-grain > * { - position: relative; - z-index: 1; - } - - /* Animation utilities */ - .animate-fade-in { - animation: fadeIn 0.5s ease-out forwards; - } - - .animate-slide-up { - animation: slideUp 0.5s ease-out forwards; - } - - @keyframes fadeIn { - from { opacity: 0; } - to { opacity: 1; } - } - - @keyframes slideUp { - from { - opacity: 0; - transform: translateY(20px); - } - to { - opacity: 1; - transform: translateY(0); - } - } - - /* Blinking cursor animation */ - .blinking-cursor { - animation: blink 1.3s step-end infinite; - } - - @keyframes blink { - 0%, 100% { opacity: 1; } - 50% { opacity: 0; } - } -} +@import "./dabble-design-system.css"; .twitter-tweet-rendered { margin-top: 40px; diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index ff0aade8..8bac8816 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -9,6 +9,7 @@ = csrf_meta_tags = yield :head = render 'shared/favicons_and_metatags' + = stylesheet_link_tag '/application-tailwind.css', media: 'all' = stylesheet_link_tag 'application', media: 'all' = javascript_include_tag 'application' @@ -30,21 +31,21 @@ 'anonymize_ip': true }); - %body - #wrap + %body.bg-page.min-h-screen + #wrap.min-h-screen = render 'shared/navbar' - #main-container.clear-top{class: "#{params[:controller].in?(['admin', 'payments', 'inspirations']) ? 'container-fluid' : 'container'}"} + #main-container.mx-auto.max-w-6xl.px-4.pb-40.pt-16{class: "#{params[:controller].in?(['admin', 'payments', 'inspirations']) ? 'max-w-full' : ''}"} - if notice - .col-md-8.col-md-offset-2.alert.alert-success= notice.html_safe - .clearfix + .mx-auto.mb-4.max-w-2xl + .alert.alert-success= notice.html_safe - if alert && alert.class == Array - alert.each do |message| - .col-md-8.col-md-offset-2 + .mx-auto.mb-4.max-w-2xl .alert.alert-danger= message - elsif alert - .col-md-8.col-md-offset-2.alert.alert-danger= alert.html_safe - .clearfix + .mx-auto.mb-4.max-w-2xl + .alert.alert-danger= alert.html_safe = yield diff --git a/app/views/shared/_navbar.html.haml b/app/views/shared/_navbar.html.haml index 6b95187e..f18ab768 100644 --- a/app/views/shared/_navbar.html.haml +++ b/app/views/shared/_navbar.html.haml @@ -1,78 +1,107 @@ -%nav.navbar.navbar-default.navbar-fixed-top{ role: 'navigation', style: "font-family: 'Instrument Sans', sans-serif;" } - .container - .navbar-header - %button.navbar-toggle{ type: 'button', data: { toggle: 'collapse', target: '.navbar-collapse' } } - %span.icon-bar - %span.icon-bar - %span.icon-bar +%nav#app-nav{ role: 'navigation', style: "font-family: 'Instrument Sans', sans-serif;", class: 'fixed top-0 z-[1000] w-full border-b border-olive-700 bg-olive-600 text-cream-100 shadow-sm transition-transform duration-200 ease-out' } + .mx-auto.flex.max-w-7xl.flex-wrap.items-center.justify-between.gap-2.px-3.py-2{ class: 'sm:px-4' } + .flex.min-w-0.flex-1.items-center.gap-2 - if user_signed_in? && current_user.is_pro? - =link_to "Write", new_entry_path, class: "s-write-icon visible-xs #{'active' if params[:controller] == 'entries' && params[:action].in?(['new', 'create'])}" - = link_to root_path, class: 'navbar-brand', title: "Dabble me." do - %span - Dabble me. + = link_to 'Write', new_entry_path, class: "s-write-icon rounded px-3 py-2 text-sm font-medium text-cream-100 hover:bg-black/20 md:hidden #{'bg-black/10' if params[:controller] == 'entries' && params[:action].in?(['new', 'create'])}" + = link_to root_path, class: 'font-serif text-xl tracking-tight text-cream-100 hover:bg-black/20 rounded px-2 py-1', title: 'Dabble me.' do + %span Dabble me. - .collapse.navbar-collapse - %ul.nav.navbar-nav - %li{class: "#{'hidden-xs' if user_signed_in? && current_user.is_pro?} #{'active' if params[:controller] == 'entries' && params[:action].in?(['new', 'create'])}"} - =link_to new_entry_path do + .hidden.flex-1.items-center.justify-center{ class: 'md:flex' } + %ul.flex.flex-wrap.items-center.justify-center.gap-1 + %li + - active = params[:controller] == 'entries' && params[:action].in?(['new', 'create']) + = link_to new_entry_path, class: "rounded px-3 py-2 text-sm font-medium text-cream-100 hover:bg-black/20 #{'bg-black/10' if active} #{'hidden' if user_signed_in? && current_user.is_pro?}" do %span Write - - %li{class: "#{'active' if params[:controller] == 'entries' && params[:action] == 'index'}"} - =link_to entries_path do + %li + - active = params[:controller] == 'entries' && params[:action] == 'index' + = link_to entries_path, class: "rounded px-3 py-2 text-sm font-medium text-cream-100 hover:bg-black/20 #{'bg-black/10' if active}" do %span Entries - - %li{class: "#{'active' if params[:action] == "review"}"} - =link_to review_path(Date.today.year), title: "Analytics" do + %li + - active = params[:action] == 'review' + = link_to review_path(Date.today.year), title: 'Analytics', class: "rounded px-3 py-2 text-sm font-medium text-cream-100 hover:bg-black/20 #{'bg-black/10' if active}" do %span Stats - - %li{class: "#{'active' if current_page?(entries_calendar_path)}"} - = link_to entries_calendar_path, title: "Calendar View" do - %i.fa.fa-calendar.hidden-xs - %span.visible-xs-inline-block Calendar - - %li{class: "#{'active' if current_page?(search_path)}"} - = link_to search_path, title: "Search" do - %i.fa.fa-search.hidden-xs - %span.visible-xs-inline-block Search - + %li + - active = current_page?(entries_calendar_path) + = link_to entries_calendar_path, title: 'Calendar View', class: "rounded px-3 py-2 text-sm font-medium text-cream-100 hover:bg-black/20 #{'bg-black/10' if active}" do + %i.fa.fa-calendar{ class: 'mr-0 sm:mr-1' } + %span{ class: 'hidden sm:inline' } Calendar + %li + - active = current_page?(search_path) + = link_to search_path, title: 'Search', class: "rounded px-3 py-2 text-sm font-medium text-cream-100 hover:bg-black/20 #{'bg-black/10' if active}" do + %i.fa.fa-search{ class: 'mr-0 sm:mr-1' } + %span{ class: 'hidden sm:inline' } Search - if user_signed_in? && current_user.admin? - %li.dropdown{class: "#{'active' if params[:controller].in?(['admin', 'inspirations', 'payments'])}"} - %a.dropdown-toggle{data: { toggle: "dropdown"}, href: "#"} - %i.fa.fa-lock.hidden-xs - %span.visible-xs-inline-block Admin - %ul.dropdown-menu{role: "menu"} - %li{class: "#{'active' if current_page?(inspirations_path)}"} - =link_to inspirations_path, title: "Inspirations" do - %i.fa.fa-lightbulb-o -  Inspirations - %li{class: "#{'active' if current_page?(payments_path)}"} - =link_to payments_path, title: "Payments" do - %i.fa.fa-usd -  Payments - %li{class: "#{'active' if current_page?(admin_stats_path)}"} - =link_to admin_stats_path, title: "Admin Stats" do - %i.fa.fa-bar-chart -  Stats - %li{class: "#{'active' if current_page?(admin_photos_path)}"} - =link_to admin_photos_path, title: "Admin Photos" do - %i.fa.fa-picture-o -  Photos - %li{class: "#{'active' if current_page?(admin_users_path)}"} - =link_to admin_users_path, title: "Admin Users" do - %i.fa.fa-users -  Users + %li.relative + %details.group.relative + %summary{ class: "flex cursor-pointer list-none items-center gap-1 rounded px-3 py-2 text-sm font-medium text-cream-100 hover:bg-black/20 #{'bg-black/10' if params[:controller].in?(['admin', 'inspirations', 'payments'])}" } + %span{ class: 'fa fa-lock hidden sm:inline' } + %span Admin + %span.text-xs.opacity-80 ▾ + %div{ class: 'absolute left-0 top-full z-[1001] mt-1 min-w-[12rem] rounded-md border border-olive-800 bg-olive-700 py-1 shadow-lg' } + = link_to inspirations_path, title: 'Inspirations', class: 'block px-4 py-2 text-sm text-cream-100 hover:bg-black/20' do + %span.fa.fa-lightbulb-o + Inspirations + = link_to payments_path, title: 'Payments', class: 'block px-4 py-2 text-sm text-cream-100 hover:bg-black/20' do + %span.fa.fa-usd + Payments + = link_to admin_stats_path, title: 'Admin Stats', class: 'block px-4 py-2 text-sm text-cream-100 hover:bg-black/20' do + %span.fa.fa-bar-chart + Stats + = link_to admin_photos_path, title: 'Admin Photos', class: 'block px-4 py-2 text-sm text-cream-100 hover:bg-black/20' do + %span.fa.fa-picture-o + Photos + = link_to admin_users_path, title: 'Admin Users', class: 'block px-4 py-2 text-sm text-cream-100 hover:bg-black/20' do + %span.fa.fa-users + Users - %ul.nav.navbar-nav.navbar-right + .hidden.items-center{ class: 'md:flex' } + %ul.flex.items-center.gap-1 + - add_popover = nil + - current_settings = nil - if user_signed_in? && current_user.sign_in_count < 10 && !cookies[:viewed_settings] && (current_page?(entries_path) || current_page?(root_path)) - - add_popover = "popover_settings" + - add_popover = 'popover_settings' - if current_user.frequency.count > 0 - current_settings = "You will be emailed at #{current_user.send_time.strftime("%-I %P")} #{current_user.send_timezone} on #{current_user.frequencies}." - else - - current_settings = "Email reminders are currently disabled." - %li{class: "#{'active' if current_page?(edit_user_registration_path)}", rel: "#{add_popover}", title: "", data: { content: "#{current_settings}", placement: "bottom"}} - = link_to edit_user_registration_path do - %span Settings + - current_settings = 'Email reminders are currently disabled.' %li - = link_to destroy_user_session_path, method: :delete, title: "Logout" do - %i.fa.fa-sign-out.hidden-xs - %span.visible-xs-inline-block Logout + - active = current_page?(edit_user_registration_path) + - if add_popover + = link_to edit_user_registration_path, rel: add_popover, title: '', data: { content: current_settings }, class: "rounded px-3 py-2 text-sm font-medium text-cream-100 hover:bg-black/20 #{'bg-black/10' if active}" do + %span Settings + - else + = link_to edit_user_registration_path, class: "rounded px-3 py-2 text-sm font-medium text-cream-100 hover:bg-black/20 #{'bg-black/10' if active}" do + %span Settings + %li + = link_to destroy_user_session_path, method: :delete, title: 'Logout', class: 'rounded px-3 py-2 text-sm font-medium text-cream-100 hover:bg-black/20' do + %i.fa.fa-sign-out{ class: 'hidden sm:inline' } + %span{ class: 'sm:hidden' } Logout + %span{ class: 'hidden sm:inline' } Logout + + %button#mobile-menu-toggle{ class: 'rounded p-2 text-cream-100 hover:bg-black/20 md:hidden', type: 'button', 'aria-expanded': 'false', 'aria-controls': 'mobile-menu' } + %span.sr-only Toggle menu + %svg.h-6.w-6{ fill: 'none', stroke: 'currentColor', viewBox: '0 0 24 24' } + %path{ 'stroke-linecap': 'round', 'stroke-linejoin': 'round', 'stroke-width': '2', d: 'M4 6h16M4 12h16M4 18h16' } + + #mobile-menu.hidden.w-full.border-t.border-olive-700.bg-olive-600{ class: 'md:hidden' } + .flex.flex-col.px-3.py-2 + = link_to new_entry_path, class: "rounded px-3 py-2 text-sm font-medium text-cream-100 hover:bg-black/20 #{'bg-black/10' if params[:controller] == 'entries' && params[:action].in?(['new', 'create'])}" do + Write + = link_to entries_path, class: "rounded px-3 py-2 text-sm font-medium text-cream-100 hover:bg-black/20 #{'bg-black/10' if params[:controller] == 'entries' && params[:action] == 'index'}" do + Entries + = link_to review_path(Date.today.year), class: "rounded px-3 py-2 text-sm font-medium text-cream-100 hover:bg-black/20 #{'bg-black/10' if params[:action] == 'review'}" do + Stats + = link_to entries_calendar_path, class: "rounded px-3 py-2 text-sm font-medium text-cream-100 hover:bg-black/20 #{'bg-black/10' if current_page?(entries_calendar_path)}" do + Calendar + = link_to search_path, class: "rounded px-3 py-2 text-sm font-medium text-cream-100 hover:bg-black/20 #{'bg-black/10' if current_page?(search_path)}" do + Search + - if user_signed_in? && current_user.admin? + %p.mt-2.text-xs.font-semibold.uppercase.tracking-wide.text-cream-200 Admin + = link_to 'Inspirations', inspirations_path, class: 'rounded px-3 py-2 text-sm text-cream-100 hover:bg-black/20' + = link_to 'Payments', payments_path, class: 'rounded px-3 py-2 text-sm text-cream-100 hover:bg-black/20' + = link_to 'Admin Stats', admin_stats_path, class: 'rounded px-3 py-2 text-sm text-cream-100 hover:bg-black/20' + = link_to 'Admin Photos', admin_photos_path, class: 'rounded px-3 py-2 text-sm text-cream-100 hover:bg-black/20' + = link_to 'Admin Users', admin_users_path, class: 'rounded px-3 py-2 text-sm text-cream-100 hover:bg-black/20' + = link_to edit_user_registration_path, class: "rounded px-3 py-2 text-sm font-medium text-cream-100 hover:bg-black/20 #{'bg-black/10' if current_page?(edit_user_registration_path)}" do + Settings + = link_to 'Logout', destroy_user_session_path, method: :delete, class: 'rounded px-3 py-2 text-sm font-medium text-cream-100 hover:bg-black/20' diff --git a/config/application.rb b/config/application.rb index 842bb5d7..69ad7d97 100644 --- a/config/application.rb +++ b/config/application.rb @@ -25,7 +25,7 @@ class Application < Rails::Application # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers # -- all .rb files in that directory are automatically loaded. - config.load_defaults 6.1 + config.load_defaults 7.0 # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. @@ -37,9 +37,6 @@ class Application < Rails::Application # config.autoload_paths << "#{config.root}/lib" - # Devise - config.assets.initialize_on_precompile = false - config.active_job.queue_adapter = :sidekiq if ENV["REDIS_URL"].present? config.cache_store = :redis_cache_store, { diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index fe48fc34..f119e581 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -3,6 +3,8 @@ # Version of your assets, change this if you want to expire all your assets. Rails.application.config.assets.version = '1.0' +Rails.application.config.assets.paths << Rails.root.join('node_modules/tippy.js/dist') + # Add additional assets to the asset load path. # Rails.application.config.assets.paths << Emoji.images_path diff --git a/config/initializers/cloudflare_test.rb b/config/initializers/cloudflare_test.rb index 6c088d04..5f557a97 100644 --- a/config/initializers/cloudflare_test.rb +++ b/config/initializers/cloudflare_test.rb @@ -1,6 +1,9 @@ if Rails.env.test? - # Set CloudflareRails IPs manually to avoid external HTTP requests during tests + # Skip live Cloudflare IP fetches (avoids Net::HTTP during tests and WebMock conflicts). Rails.application.config.after_initialize do - CloudflareRails::VALID_CLOUDFLARE_CIDRS = ['127.0.0.1/32', '::1/128'] + CloudflareRails::Importer.define_singleton_method(:cloudflare_ips) do |refresh: false| + @ips = nil if refresh + @ips ||= (CloudflareRails::FallbackIps::IPS_V4 + CloudflareRails::FallbackIps::IPS_V6).freeze + end end end diff --git a/config/initializers/new_framework_defaults_7_0.rb b/config/initializers/new_framework_defaults_7_0.rb new file mode 100644 index 00000000..6ab8f79b --- /dev/null +++ b/config/initializers/new_framework_defaults_7_0.rb @@ -0,0 +1,10 @@ +# Be sure to restart your server when you modify this file. +# +# This file eases your Rails 7.0 framework defaults upgrade. +# +# Uncomment each configuration one by one to switch to the new default. +# Once your application is ready to run with all new defaults, you can remove +# this file and rely on `config.load_defaults 7.0` only. +# +# Read the Guide for Upgrading Ruby on Rails for more info on each option. +# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html diff --git a/db/schema.rb b/db/schema.rb index 17652a6a..12c5b62e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,20 +10,19 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2026_02_08_172837) do - +ActiveRecord::Schema[7.0].define(version: 2026_02_08_172837) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" create_table "entries", id: :serial, force: :cascade do |t| - t.datetime "date", null: false + t.datetime "date", precision: nil, null: false t.text "body" t.text "filepicker_url" t.text "original_email_body" t.integer "inspiration_id" t.integer "user_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil t.string "image" t.jsonb "songs", default: [], array: true t.jsonb "original_email", default: {} @@ -36,25 +35,25 @@ t.bigint "user_id" t.string "tag" t.date "date" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["user_id"], name: "index_hashtags_on_user_id" end create_table "inspirations", id: :serial, force: :cascade do |t| t.string "category" t.text "body" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil end create_table "payments", id: :serial, force: :cascade do |t| t.integer "user_id" t.decimal "amount", precision: 8, scale: 2, default: "0.0" t.text "comments" - t.datetime "date" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "date", precision: nil + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil t.index ["user_id"], name: "index_payments_on_user_id" end @@ -62,15 +61,15 @@ t.string "email", default: "", null: false t.string "encrypted_password", default: "", null: false t.string "reset_password_token" - t.datetime "reset_password_sent_at" - t.datetime "remember_created_at" + t.datetime "reset_password_sent_at", precision: nil + t.datetime "remember_created_at", precision: nil t.integer "sign_in_count", default: 0, null: false - t.datetime "current_sign_in_at" - t.datetime "last_sign_in_at" + t.datetime "current_sign_in_at", precision: nil + t.datetime "last_sign_in_at", precision: nil t.inet "current_sign_in_ip" t.inet "last_sign_in_ip" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil t.string "first_name" t.string "last_name" t.string "send_timezone", default: "Mountain Time (US & Canada)" @@ -88,11 +87,11 @@ t.string "stripe_id" t.string "failed_attempts", default: "0", null: false t.string "unlock_token" - t.datetime "locked_at" + t.datetime "locked_at", precision: nil t.integer "emails_bounced", default: 0 t.text "frequency", default: ["Sun"], array: true t.text "previous_frequency", default: [], array: true - t.datetime "last_sent_at" + t.datetime "last_sent_at", precision: nil t.boolean "admin", default: false t.boolean "ai_opt_in", default: false t.boolean "send_as_ai", default: false @@ -100,16 +99,16 @@ t.string "otp_recovery_secret" t.boolean "otp_enabled", default: false, null: false t.boolean "otp_mandatory", default: false, null: false - t.datetime "otp_enabled_on" + t.datetime "otp_enabled_on", precision: nil t.integer "otp_failed_attempts", default: 0, null: false t.integer "otp_recovery_counter", default: 0, null: false t.string "otp_persistence_seed" t.string "otp_session_challenge" - t.datetime "otp_challenge_expires" + t.datetime "otp_challenge_expires", precision: nil t.text "otp_auth_secret_ciphertext" t.text "otp_recovery_secret_ciphertext" t.text "otp_persistence_seed_ciphertext" - t.datetime "deleted_at" + t.datetime "deleted_at", precision: nil t.string "x_username" t.string "x_uid" t.text "x_access_token" @@ -129,8 +128,8 @@ t.string "public_key" t.string "nickname" t.bigint "sign_count" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["external_id"], name: "index_webauthn_credentials_on_external_id" t.index ["user_id"], name: "index_webauthn_credentials_on_user_id" end @@ -142,12 +141,12 @@ t.string "author_username" t.string "author_name" t.text "text" - t.datetime "tweeted_at" + t.datetime "tweeted_at", precision: nil t.string "url" t.jsonb "entities", default: {} t.jsonb "public_metrics", default: {} - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["user_id", "tweet_id"], name: "index_x_bookmarks_on_user_id_and_tweet_id", unique: true t.index ["user_id"], name: "index_x_bookmarks_on_user_id" end diff --git a/package-lock.json b/package-lock.json index 8575b9c4..a061ed51 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,8 +11,10 @@ "dependencies": { "@tailwindcss/cli": "^4.2.1", "autoprefixer": "^10.4.27", + "font-awesome": "^4.7.0", "postcss": "^8.5.8", - "tailwindcss": "^4.2.1" + "tailwindcss": "^4.2.1", + "tippy.js": "^6.3.7" } }, "node_modules/@jridgewell/gen-mapping": { @@ -355,6 +357,15 @@ "url": "https://opencollective.com/parcel" } }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, "node_modules/@tailwindcss/cli": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/@tailwindcss/cli/-/cli-4.2.1.tgz", @@ -778,6 +789,14 @@ "node": ">=8" } }, + "node_modules/font-awesome": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz", + "integrity": "sha512-U6kGnykA/6bFmg1M/oT9EkFeIYv7JlX3bozwQJWiiLz6L0w3F5vBVPxHlwyX/vtNq1ckcpRKOB9f2Qal/VtFpg==", + "engines": { + "node": ">=0.10.3" + } + }, "node_modules/fraction.js": { "version": "5.3.4", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", @@ -1235,6 +1254,14 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/tippy.js": { + "version": "6.3.7", + "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz", + "integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==", + "dependencies": { + "@popperjs/core": "^2.9.0" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", diff --git a/package.json b/package.json index b37f8965..0a404f55 100644 --- a/package.json +++ b/package.json @@ -5,13 +5,18 @@ "dependencies": { "@tailwindcss/cli": "^4.2.1", "autoprefixer": "^10.4.27", + "font-awesome": "^4.7.0", "postcss": "^8.5.8", - "tailwindcss": "^4.2.1" + "tailwindcss": "^4.2.1", + "tippy.js": "^6.3.7" }, "scripts": { "build:css": "tailwindcss -i ./app/frontend/stylesheets/marketing.tailwind.css -o ./public/marketing.css --minify", "watch:css": "tailwindcss -i ./app/frontend/stylesheets/marketing.tailwind.css -o ./public/marketing.css --watch", - "heroku-postbuild": "npm run build:css" + "build:css:app": "tailwindcss -i ./app/frontend/stylesheets/application.tailwind.css -o ./public/application-tailwind.css --minify", + "watch:css:app": "tailwindcss -i ./app/frontend/stylesheets/application.tailwind.css -o ./public/application-tailwind.css --watch", + "build:css:all": "npm run build:css && npm run build:css:app", + "heroku-postbuild": "npm run build:css:all" }, "repository": { "type": "git", diff --git a/public/application-tailwind.css b/public/application-tailwind.css new file mode 100644 index 00000000..1a5e15ea --- /dev/null +++ b/public/application-tailwind.css @@ -0,0 +1,2 @@ +/*! tailwindcss v4.2.1 | MIT License | https://tailwindcss.com */ +@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-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-divide-y-reverse:0;--tw-border-style:solid;--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-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme{:root,:host{--font-sans:"Instrument Sans", system-ui, sans-serif;--font-serif:"Instrument Serif", Georgia, 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-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-red-800:oklch(44.4% .177 26.899);--color-red-900:oklch(39.6% .141 25.723);--color-yellow-400:oklch(85.2% .199 91.936);--color-green-400:oklch(79.2% .209 151.711);--color-olive-100:oklch(96.6% .005 106.5);--color-olive-300:oklch(88% .011 106.6);--color-olive-400:oklch(73.7% .021 106.9);--color-olive-500:oklch(58% .031 107.3);--color-olive-600:oklch(46.6% .025 107.3);--color-olive-700:oklch(39.4% .023 107.4);--color-olive-800:oklch(28.6% .016 107.4);--color-olive-900:oklch(22.8% .013 107.4);--color-olive-950:oklch(15.3% .006 107.1);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-md:28rem;--container-lg:32rem;--container-xl:36rem;--container-2xl:42rem;--container-3xl:48rem;--container-4xl:56rem;--container-5xl:64rem;--container-6xl:72rem;--container-7xl:80rem;--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-5xl:3rem;--text-5xl--line-height:1;--text-6xl:3.75rem;--text-6xl--line-height:1;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-wider:.05em;--leading-tight:1.25;--leading-relaxed:1.625;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--radius-3xl:1.5rem;--ease-out:cubic-bezier(0, 0, .2, 1);--blur-sm:8px;--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-olive-150:oklch(94.5% .006 106.5);--color-cream-100:#f9f7f3;--color-cream-200:#f3f1ec;--color-cream-300:#edeae3;--color-cream-400:#e0dcd2;--color-dark-950:#0a0a0a;--color-dark-900:#0f0f0f;--color-dark-800:#171717;--color-dark-700:#1f1f1f;--color-dark-600:#2a2a2a;--color-dark-500:#3d3d3d;--color-dark-300:#6b6b6b;--color-dark-200:#a3a3a3}}@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}:root{--color-bg:var(--color-olive-100);--color-surface:#fff;--color-surface-elevated:var(--color-cream-200);--color-primary:var(--color-olive-950);--color-primary-hover:var(--color-olive-900);--color-accent:var(--color-olive-600);--color-accent-hover:var(--color-olive-700);--color-text:var(--color-olive-950);--color-text-muted:var(--color-olive-800);--color-text-subtle:var(--color-olive-600);--color-border:var(--color-cream-400);--color-border-subtle:var(--color-cream-300);--color-hero-bg:var(--color-olive-800);--color-hero-text:var(--color-white);--color-hero-muted:var(--color-cream-100);--color-hero-accent:var(--color-olive-300);--color-btn-primary-bg:var(--color-olive-900);--color-btn-primary-text:var(--color-cream-100);--color-btn-primary-hover:var(--color-olive-950);--color-footer-bg:var(--color-olive-150)}@media (prefers-color-scheme:dark){:root{--color-bg:var(--color-dark-950);--color-surface:var(--color-dark-900);--color-surface-elevated:var(--color-dark-800);--color-primary:var(--color-cream-100);--color-primary-hover:#fff;--color-accent:var(--color-olive-400);--color-accent-hover:var(--color-olive-300);--color-text:var(--color-cream-100);--color-text-muted:var(--color-dark-200);--color-text-subtle:var(--color-dark-300);--color-border:var(--color-dark-500);--color-border-subtle:var(--color-dark-600);--color-hero-bg:var(--color-olive-800);--color-hero-text:var(--color-cream-100);--color-hero-muted:var(--color-cream-300);--color-hero-accent:var(--color-olive-500);--color-btn-primary-bg:var(--color-cream-100);--color-btn-primary-text:var(--color-olive-950);--color-btn-primary-hover:#fff;--color-footer-bg:var(--color-olive-900)}}html{font-family:var(--font-sans);scroll-behavior:smooth}body{background-color:var(--color-bg);color:var(--color-text)}h1,h2,h3,h4,h5,h6{font-family:var(--font-serif)}details summary{list-style:none}details summary::-webkit-details-marker{display:none}}@layer components{.btn{cursor:pointer;padding-inline:calc(var(--spacing) * 6);padding-block:calc(var(--spacing) * 3);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);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:3.40282e38px;justify-content:center;align-items:center;transition-duration:.2s;display:inline-flex}.btn-primary{background-color:var(--color-btn-primary-bg);color:var(--color-btn-primary-text)}@media (prefers-color-scheme:dark){.btn-primary{color:#1f231c;background-color:#f9f7f3}}.btn-primary:hover{background-color:var(--color-btn-primary-hover)}.btn-secondary{color:var(--color-text);border:1px solid var(--color-border);background-color:#0000}.btn-secondary:hover{background-color:var(--color-surface);border-color:var(--color-text-muted)}.card{background-color:var(--color-surface);border:1px solid var(--color-border-subtle);border-radius:.75rem}.section-heading{font-family:var(--font-serif);color:var(--color-text);font-size:2.5rem;line-height:1.2}.text-muted{color:var(--color-text-muted)}.text-subtle{color:var(--color-text-subtle)}.accordion-item{border-bottom:1px solid var(--color-border-subtle)}.accordion-trigger{width:100%;padding-top:calc(var(--spacing) * 4);padding-bottom:calc(var(--spacing) * 4);text-align:left;--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--color-text);justify-content:space-between;align-items:center;display:flex}.accordion-trigger:hover{color:var(--color-primary)}.accordion-content{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.3s;color:var(--color-text-muted);transition-duration:.3s;overflow:hidden}.badge{align-items:center;gap:calc(var(--spacing) * 1.5);padding-inline:calc(var(--spacing) * 3);padding-block: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);background-color:var(--color-surface-elevated);color:var(--color-text-muted);border-radius:3.40282e38px;display:inline-flex}.badge-accent{background-color:var(--color-accent);color:var(--color-cream-100)}.alert-app-success{border-radius:var(--radius-lg);border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 3);text-align:center;background-color:#5b5b4b1f;border-width:1px}@supports (color:color-mix(in lab, red, red)){.alert-app-success{background-color:color-mix(in oklab, var(--color-olive-600) 12%, transparent)}}.alert-app-success{border-color:var(--color-olive-400);color:var(--color-olive-950)}.alert-app-danger{border-radius:var(--radius-lg);border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 3);text-align:center;color:var(--color-olive-950);background-color:oklab(44.2929% .157181 .0795491/.12);border-width:1px;border-color:#c53030}@media (prefers-color-scheme:dark){.alert-app-success,.alert-app-danger{color:var(--color-cream-100)}}.input-app{border-radius:var(--radius-md);border-style:var(--tw-border-style);width:100%;padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));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));--tw-outline-style:none;border-width:1px;border-color:var(--color-border);background-color:var(--color-surface);color:var(--color-text);outline-style:none}.input-app:focus{border-color:var(--color-olive-600);box-shadow:0 0 0 2px #5b5b4b59}@supports (color:color-mix(in lab, red, red)){.input-app:focus{box-shadow:0 0 0 2px color-mix(in oklab, var(--color-olive-600) 35%, transparent)}}.form-control{border-radius:var(--radius-md);border-style:var(--tw-border-style);width:100%;padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));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));--tw-outline-style:none;border-width:1px;border-color:var(--color-border);background-color:var(--color-surface);color:var(--color-text);outline-style:none}.form-control:focus{border-color:var(--color-olive-600);box-shadow:0 0 0 2px #5b5b4b59}@supports (color:color-mix(in lab, red, red)){.form-control:focus{box-shadow:0 0 0 2px color-mix(in oklab, var(--color-olive-600) 35%, transparent)}}.well{border-radius:var(--radius-lg);border-style:var(--tw-border-style);padding:calc(var(--spacing) * 4);--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);border-width:1px;border-color:var(--color-border-subtle);background-color:var(--color-surface)}.alert.alert-success{border-radius:var(--radius-lg);border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 3);background-color:#5b5b4b1f;border-width:1px}@supports (color:color-mix(in lab, red, red)){.alert.alert-success{background-color:color-mix(in oklab, var(--color-olive-600) 12%, transparent)}}.alert.alert-success{border-color:var(--color-olive-400);color:var(--color-olive-950)}.alert.alert-danger{border-radius:var(--radius-lg);border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 3);color:var(--color-olive-950);background-color:oklab(44.2929% .157181 .0795491/.15);border-width:1px;border-color:#c53030}.alert.alert-info{border-radius:var(--radius-lg);border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 3);color:var(--color-olive-950);background-color:oklab(51.7668% -.0488637 -.0642039/.12);border-width:1px;border-color:#31708f}.alert.alert-warning{border-radius:var(--radius-lg);border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 3);background-color:#7c7c672e;border-width:1px}@supports (color:color-mix(in lab, red, red)){.alert.alert-warning{background-color:color-mix(in oklab, var(--color-olive-500) 18%, transparent)}}.alert.alert-warning{border-color:var(--color-olive-400);color:var(--color-olive-950)}@media (prefers-color-scheme:dark){.alert.alert-success,.alert.alert-danger,.alert.alert-info,.alert.alert-warning{color:var(--color-cream-100)}}.btn-default{border-radius:var(--radius-md);border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2);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);border-width:1px;border-color:var(--color-border);background-color:var(--color-surface);color:var(--color-text);justify-content:center;align-items:center;display:inline-flex}.btn-default:hover{background-color:var(--color-surface-elevated)}.btn-danger{border-radius:var(--radius-md);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2);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-white);background-color:#9e0812;justify-content:center;align-items:center;display:inline-flex}.btn-danger:hover{background-color:#7a060e}.btn-warning{border-radius:var(--radius-md);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2);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:#1a1a1a;background-color:#f0ad4e;justify-content:center;align-items:center;display:inline-flex}.btn-success{border-radius:var(--radius-md);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2);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-white);background-color:var(--color-olive-800);justify-content:center;align-items:center;display:inline-flex}.btn-info{border-radius:var(--radius-md);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2);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-white);background-color:#5bc0de;justify-content:center;align-items:center;display:inline-flex}.btn-link{border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * 1);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--color-accent);background-color:#0000;border-width:0;justify-content:center;align-items:center;text-decoration-line:underline;display:inline-flex}.btn-xs{padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * 1);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.btn-sm{padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 1.5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.btn-lg{padding-inline:calc(var(--spacing) * 6);padding-block:calc(var(--spacing) * 3);font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.btn-block{justify-content:center;width:100%}.label.label-default{padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * .5);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal);background-color:var(--color-surface-elevated);color:var(--color-text-muted);border-radius:.25rem;display:inline-block}}@layer utilities{.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}.inset-0{inset:calc(var(--spacing) * 0)}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.-top-3{top:calc(var(--spacing) * -3)}.top-0{top:calc(var(--spacing) * 0)}.top-20{top:calc(var(--spacing) * 20)}.top-full{top:100%}.right-0{right:calc(var(--spacing) * 0)}.left-0{left:calc(var(--spacing) * 0)}.left-1\/2{left:50%}.z-50{z-index:50}.float-left{float:left}.float-right{float:right}.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-2{margin-inline:calc(var(--spacing) * -2)}.mx-auto{margin-inline:auto}.my-6{margin-block:calc(var(--spacing) * 6)}.mt-0{margin-top:calc(var(--spacing) * 0)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-2\.5{margin-top:calc(var(--spacing) * 2.5)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.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-12{margin-top:calc(var(--spacing) * 12)}.mt-16{margin-top:calc(var(--spacing) * 16)}.mr-0{margin-right:calc(var(--spacing) * 0)}.mb-0{margin-bottom:calc(var(--spacing) * 0)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.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-8{margin-bottom:calc(var(--spacing) * 8)}.mb-10{margin-bottom:calc(var(--spacing) * 10)}.mb-12{margin-bottom:calc(var(--spacing) * 12)}.mb-16{margin-bottom:calc(var(--spacing) * 16)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-3{margin-left:calc(var(--spacing) * 3)}.ml-4{margin-left:calc(var(--spacing) * 4)}.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}.h-3{height:calc(var(--spacing) * 3)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-10{height:calc(var(--spacing) * 10)}.h-12{height:calc(var(--spacing) * 12)}.h-15{height:calc(var(--spacing) * 15)}.h-16{height:calc(var(--spacing) * 16)}.h-52{height:calc(var(--spacing) * 52)}.h-full{height:100%}.h-px{height:1px}.min-h-screen{min-height:100vh}.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-16{width:calc(var(--spacing) * 16)}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-5xl{max-width:var(--container-5xl)}.max-w-6xl{max-width:var(--container-6xl)}.max-w-7xl{max-width:var(--container-7xl)}.max-w-\[150px\]{max-width:150px}.max-w-full{max-width:100%}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.max-w-none{max-width:none}.max-w-xl{max-width:var(--container-xl)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing) * 0)}.flex-1{flex:1}.flex-shrink{flex-shrink:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.grow{flex-grow:1}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-pointer{cursor:pointer}.touch-manipulation{touch-action:manipulation}.resize{resize:both}.list-disc{list-style-type:disc}.list-none{list-style-type: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-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-8{gap:calc(var(--spacing) * 8)}.gap-12{gap:calc(var(--spacing) * 12)}: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-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * 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-5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-8>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 8) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 8) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-4{column-gap:calc(var(--spacing) * 4)}.gap-x-6{column-gap:calc(var(--spacing) * 6)}.gap-x-12{column-gap:calc(var(--spacing) * 12)}.gap-y-10{row-gap:calc(var(--spacing) * 10)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}.self-end{align-self:flex-end}.overflow-hidden{overflow:hidden}.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-xl{border-radius:var(--radius-xl)}.rounded-t-3xl{border-top-left-radius:var(--radius-3xl);border-top-right-radius:var(--radius-3xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-y{border-block-style:var(--tw-border-style);border-block-width:1px}.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-cream-300{border-color:var(--color-cream-300)}.border-olive-700{border-color:var(--color-olive-700)}.border-olive-800{border-color:var(--color-olive-800)}.border-red-200{border-color:var(--color-red-200)}.border-white\/30{border-color:#ffffff4d}@supports (color:color-mix(in lab, red, red)){.border-white\/30{border-color:color-mix(in oklab, var(--color-white) 30%, transparent)}}.bg-black\/10{background-color:#0000001a}@supports (color:color-mix(in lab, red, red)){.bg-black\/10{background-color:color-mix(in oklab, var(--color-black) 10%, transparent)}}.bg-green-400{background-color:var(--color-green-400)}.bg-olive-100{background-color:var(--color-olive-100)}.bg-olive-600{background-color:var(--color-olive-600)}.bg-olive-700{background-color:var(--color-olive-700)}.bg-olive-800{background-color:var(--color-olive-800)}.bg-olive-900{background-color:var(--color-olive-900)}.bg-olive-950\/20{background-color:#0c0c0933}@supports (color:color-mix(in lab, red, red)){.bg-olive-950\/20{background-color:color-mix(in oklab, var(--color-olive-950) 20%, transparent)}}.bg-red-50{background-color:var(--color-red-50)}.bg-red-400{background-color:var(--color-red-400)}.bg-white{background-color:var(--color-white)}.bg-white\/20{background-color:#fff3}@supports (color:color-mix(in lab, red, red)){.bg-white\/20{background-color:color-mix(in oklab, var(--color-white) 20%, transparent)}}.bg-yellow-400{background-color:var(--color-yellow-400)}.fill-current{fill:currentColor}.object-cover{object-fit:cover}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-6{padding:calc(var(--spacing) * 6)}.p-8{padding:calc(var(--spacing) * 8)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-10{padding-inline:calc(var(--spacing) * 10)}.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-12{padding-block:calc(var(--spacing) * 12)}.py-16{padding-block:calc(var(--spacing) * 16)}.py-20{padding-block:calc(var(--spacing) * 20)}.py-24{padding-block:calc(var(--spacing) * 24)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pt-7{padding-top:calc(var(--spacing) * 7)}.pt-8{padding-top:calc(var(--spacing) * 8)}.pt-16{padding-top:calc(var(--spacing) * 16)}.pt-20{padding-top:calc(var(--spacing) * 20)}.pt-24{padding-top:calc(var(--spacing) * 24)}.pb-7{padding-bottom:calc(var(--spacing) * 7)}.pb-10{padding-bottom:calc(var(--spacing) * 10)}.pb-12{padding-bottom:calc(var(--spacing) * 12)}.pb-40{padding-bottom:calc(var(--spacing) * 40)}.pl-0{padding-left:calc(var(--spacing) * 0)}.pl-1\.5{padding-left:calc(var(--spacing) * 1.5)}.pl-2{padding-left:calc(var(--spacing) * 2)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-5{padding-left:calc(var(--spacing) * 5)}.pl-6{padding-left:calc(var(--spacing) * 6)}.text-center{text-align:center}.font-sans{font-family:var(--font-sans)}.font-serif{font-family:var(--font-serif)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.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-5xl{font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--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-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-\[30px\]{font-size:30px}.leading-7{--tw-leading:calc(var(--spacing) * 7);line-height:calc(var(--spacing) * 7)}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.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)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.text-cream-100{color:var(--color-cream-100)}.text-cream-200{color:var(--color-cream-200)}.text-olive-800{color:var(--color-olive-800)}.text-olive-900{color:var(--color-olive-900)}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-red-700{color:var(--color-red-700)}.text-white{color:var(--color-white)}.uppercase{text-transform:uppercase}.italic{font-style:italic}.underline{text-decoration-line:underline}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-30{opacity:.3}.opacity-80{opacity:.8}.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-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)}.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)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.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,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.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-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-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.select-all{-webkit-user-select:all;user-select:all}@media (hover:hover){.hover\:scale-105:hover{--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x) var(--tw-scale-y)}.hover\:scale-125:hover{--tw-scale-x:125%;--tw-scale-y:125%;--tw-scale-z:125%;scale:var(--tw-scale-x) var(--tw-scale-y)}.hover\:bg-black\/20:hover{background-color:#0003}@supports (color:color-mix(in lab, red, red)){.hover\:bg-black\/20:hover{background-color:color-mix(in oklab, var(--color-black) 20%, transparent)}}.hover\:bg-cream-100:hover{background-color:var(--color-cream-100)}.hover\:bg-olive-800:hover{background-color:var(--color-olive-800)}.hover\:bg-olive-950:hover{background-color:var(--color-olive-950)}.hover\:bg-olive-950\/30:hover{background-color:#0c0c094d}@supports (color:color-mix(in lab, red, red)){.hover\:bg-olive-950\/30:hover{background-color:color-mix(in oklab, var(--color-olive-950) 30%, transparent)}}.hover\:bg-white\/10:hover{background-color:#ffffff1a}@supports (color:color-mix(in lab, red, red)){.hover\:bg-white\/10:hover{background-color:color-mix(in oklab, var(--color-white) 10%, transparent)}}.hover\:opacity-50:hover{opacity:.5}}.focus\:border-transparent:focus{border-color:#0000}.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-olive-500:focus{--tw-ring-color:var(--color-olive-500)}.focus\:ring-olive-600:focus{--tw-ring-color:var(--color-olive-600)}.focus\:ring-offset-2:focus{--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)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}@media (min-width:40rem){.sm\:mx-0{margin-inline:calc(var(--spacing) * 0)}.sm\:mr-1{margin-right:calc(var(--spacing) * 1)}.sm\:hidden{display:none}.sm\:inline{display:inline}.sm\:inline-flex{display:inline-flex}.sm\:h-6{height:calc(var(--spacing) * 6)}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:gap-16{gap:calc(var(--spacing) * 16)}.sm\:gap-x-16{column-gap:calc(var(--spacing) * 16)}.sm\:rounded-3xl{border-radius:var(--radius-3xl)}.sm\:p-6{padding:calc(var(--spacing) * 6)}.sm\:p-8{padding:calc(var(--spacing) * 8)}.sm\:px-4{padding-inline:calc(var(--spacing) * 4)}.sm\:px-6{padding-inline:calc(var(--spacing) * 6)}.sm\:px-10{padding-inline:calc(var(--spacing) * 10)}.sm\:py-32{padding-block:calc(var(--spacing) * 32)}.sm\:pt-16{padding-top:calc(var(--spacing) * 16)}.sm\:pb-14{padding-bottom:calc(var(--spacing) * 14)}.sm\:pb-20{padding-bottom:calc(var(--spacing) * 20)}.sm\:pl-0{padding-left:calc(var(--spacing) * 0)}.sm\:text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.sm\:text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.sm\:text-5xl{font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--line-height))}}@media (min-width:48rem){.md\:block{display:block}.md\:flex{display:flex}.md\:hidden{display:none}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:64rem){.lg\:mx-0{margin-inline:calc(var(--spacing) * 0)}.lg\:flex{display:flex}.lg\:hidden{display:none}.lg\:inline-flex{display:inline-flex}.lg\:h-64{height:calc(var(--spacing) * 64)}.lg\:max-w-\[300px\]{max-width:300px}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-\[220px_1fr\]{grid-template-columns:220px 1fr}.lg\:items-center{align-items:center}.lg\:justify-start{justify-content:flex-start}.lg\:gap-0{gap:calc(var(--spacing) * 0)}.lg\:gap-x-8{column-gap:calc(var(--spacing) * 8)}.lg\:gap-x-20{column-gap:calc(var(--spacing) * 20)}.lg\:px-8{padding-inline:calc(var(--spacing) * 8)}.lg\:px-12{padding-inline:calc(var(--spacing) * 12)}.lg\:py-16{padding-block:calc(var(--spacing) * 16)}.lg\:py-20{padding-block:calc(var(--spacing) * 20)}.lg\:py-28{padding-block:calc(var(--spacing) * 28)}.lg\:pt-28{padding-top:calc(var(--spacing) * 28)}.lg\:text-left{text-align:left}.lg\:text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.lg\:text-5xl{font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--line-height))}.lg\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}@media (prefers-color-scheme:dark){.dark\:border-dark-700{border-color:var(--color-dark-700)}.dark\:border-red-800{border-color:var(--color-red-800)}.dark\:bg-olive-300{background-color:var(--color-olive-300)}.dark\:bg-olive-950{background-color:var(--color-olive-950)}.dark\:bg-red-900\/20{background-color:#82181a33}@supports (color:color-mix(in lab, red, red)){.dark\:bg-red-900\/20{background-color:color-mix(in oklab, var(--color-red-900) 20%, transparent)}}.dark\:text-olive-100{color:var(--color-olive-100)}.dark\:text-olive-300{color:var(--color-olive-300)}.dark\:text-olive-800{color:var(--color-olive-800)}.dark\:text-red-300{color:var(--color-red-300)}.dark\:text-red-400{color:var(--color-red-400)}}.bg-page{background-color:var(--color-bg)}.bg-surface,.hover\:bg-surface:hover{background-color:var(--color-surface)}.bg-surface-elevated,.hover\:bg-surface-elevated:hover{background-color:var(--color-surface-elevated)}.bg-footer{background-color:var(--color-footer-bg)}.bg-bg{background-color:var(--color-bg)}.text-primary,.hover\:text-primary:hover{color:var(--color-primary)}.text-accent,.hover\:text-accent:hover{color:var(--color-accent)}.border-default{border-color:var(--color-border)}.border-subtle{border-color:var(--color-border-subtle)}.bg-hero{background:linear-gradient(#5c6654,#333a2b)}@media (prefers-color-scheme:dark){.bg-hero{background:linear-gradient(#5c6654,#333a2b)}}.text-hero{color:var(--color-hero-text)}.text-hero-muted{color:var(--color-hero-muted)}.text-hero-accent{color:var(--color-hero-accent)}.bg-grain{border-radius:inherit;pointer-events:none;opacity:.3;mix-blend-mode:overlay;background-position:50%;position:absolute;inset:0}@media (prefers-color-scheme:dark){.bg-grain{opacity:.25}}.bg-grain>*{z-index:1;position:relative}.animate-fade-in{animation:.5s ease-out forwards fadeIn}.animate-slide-up{animation:.5s ease-out forwards slideUp}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}.blinking-cursor{animation:1.3s step-end infinite blink}@keyframes blink{0%,to{opacity:1}50%{opacity:0}}#app-nav.nav-up{transform:translateY(-100%)}}.container{box-sizing:border-box;width:100%;max-width:1170px;margin-left:auto;margin-right:auto;padding-left:15px;padding-right:15px}.container-fluid{box-sizing:border-box;width:100%;padding-left:15px;padding-right:15px}.row{box-sizing:border-box;flex-wrap:wrap;margin-left:-15px;margin-right:-15px;display:flex}.row>[class*=col-]{box-sizing:border-box;min-width:0;padding-left:15px;padding-right:15px}.clearfix:before,.clearfix:after,.row:before,.row:after{content:" ";display:table}.clearfix:after,.row:after{clear:both}@media (max-width:991px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{flex:0 0 100%;max-width:100%}.col-md-offset-1,.col-md-offset-2,.col-md-offset-3,.col-md-offset-4,.col-md-offset-5,.col-md-offset-6,.col-md-offset-7,.col-md-offset-8,.col-md-offset-9,.col-md-offset-10,.col-md-offset-11,.col-md-offset-12{margin-left:0}}.col-xs-1{flex:0 0 8.33333%;max-width:8.33333%}.col-xs-2{flex:0 0 16.6667%;max-width:16.6667%}.col-xs-3{flex:0 0 25%;max-width:25%}.col-xs-4{flex:0 0 33.3333%;max-width:33.3333%}.col-xs-5{flex:0 0 41.6667%;max-width:41.6667%}.col-xs-6{flex:0 0 50%;max-width:50%}.col-xs-7{flex:0 0 58.3333%;max-width:58.3333%}.col-xs-8{flex:0 0 66.6667%;max-width:66.6667%}.col-xs-9{flex:0 0 75%;max-width:75%}.col-xs-10{flex:0 0 83.3333%;max-width:83.3333%}.col-xs-11{flex:0 0 91.6667%;max-width:91.6667%}.col-xs-12{flex:0 0 100%;max-width:100%}.col-xs-offset-1{margin-left:8.33333%}.col-xs-offset-2{margin-left:16.6667%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-4{margin-left:33.3333%}.col-xs-offset-5{margin-left:41.6667%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-7{margin-left:58.3333%}.col-xs-offset-8{margin-left:66.6667%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-10{margin-left:83.3333%}.col-xs-offset-11{margin-left:91.6667%}.col-xs-offset-12{margin-left:100%}@media (min-width:768px){.col-sm-1{flex:0 0 8.33333%;max-width:8.33333%}.col-sm-2{flex:0 0 16.6667%;max-width:16.6667%}.col-sm-3{flex:0 0 25%;max-width:25%}.col-sm-4{flex:0 0 33.3333%;max-width:33.3333%}.col-sm-5{flex:0 0 41.6667%;max-width:41.6667%}.col-sm-6{flex:0 0 50%;max-width:50%}.col-sm-7{flex:0 0 58.3333%;max-width:58.3333%}.col-sm-8{flex:0 0 66.6667%;max-width:66.6667%}.col-sm-9{flex:0 0 75%;max-width:75%}.col-sm-10{flex:0 0 83.3333%;max-width:83.3333%}.col-sm-11{flex:0 0 91.6667%;max-width:91.6667%}.col-sm-12{flex:0 0 100%;max-width:100%}.col-sm-offset-1{margin-left:8.33333%}.col-sm-offset-2{margin-left:16.6667%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-4{margin-left:33.3333%}.col-sm-offset-5{margin-left:41.6667%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-7{margin-left:58.3333%}.col-sm-offset-8{margin-left:66.6667%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-10{margin-left:83.3333%}.col-sm-offset-11{margin-left:91.6667%}.col-sm-offset-12{margin-left:100%}}@media (min-width:992px){.col-md-1{flex:0 0 8.33333%;max-width:8.33333%}.col-md-2{flex:0 0 16.6667%;max-width:16.6667%}.col-md-3{flex:0 0 25%;max-width:25%}.col-md-4{flex:0 0 33.3333%;max-width:33.3333%}.col-md-5{flex:0 0 41.6667%;max-width:41.6667%}.col-md-6{flex:0 0 50%;max-width:50%}.col-md-7{flex:0 0 58.3333%;max-width:58.3333%}.col-md-8{flex:0 0 66.6667%;max-width:66.6667%}.col-md-9{flex:0 0 75%;max-width:75%}.col-md-10{flex:0 0 83.3333%;max-width:83.3333%}.col-md-11{flex:0 0 91.6667%;max-width:91.6667%}.col-md-12{flex:0 0 100%;max-width:100%}.col-md-offset-1{margin-left:8.33333%}.col-md-offset-2{margin-left:16.6667%}.col-md-offset-3{margin-left:25%}.col-md-offset-4{margin-left:33.3333%}.col-md-offset-5{margin-left:41.6667%}.col-md-offset-6{margin-left:50%}.col-md-offset-7{margin-left:58.3333%}.col-md-offset-8{margin-left:66.6667%}.col-md-offset-9{margin-left:75%}.col-md-offset-10{margin-left:83.3333%}.col-md-offset-11{margin-left:91.6667%}.col-md-offset-12{margin-left:100%}}@media (min-width:1200px){.col-lg-1{flex:0 0 8.33333%;max-width:8.33333%}.col-lg-2{flex:0 0 16.6667%;max-width:16.6667%}.col-lg-3{flex:0 0 25%;max-width:25%}.col-lg-4{flex:0 0 33.3333%;max-width:33.3333%}.col-lg-5{flex:0 0 41.6667%;max-width:41.6667%}.col-lg-6{flex:0 0 50%;max-width:50%}.col-lg-7{flex:0 0 58.3333%;max-width:58.3333%}.col-lg-8{flex:0 0 66.6667%;max-width:66.6667%}.col-lg-9{flex:0 0 75%;max-width:75%}.col-lg-10{flex:0 0 83.3333%;max-width:83.3333%}.col-lg-11{flex:0 0 91.6667%;max-width:91.6667%}.col-lg-12{flex:0 0 100%;max-width:100%}.col-lg-offset-1{margin-left:8.33333%}.col-lg-offset-2{margin-left:16.6667%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-4{margin-left:33.3333%}.col-lg-offset-5{margin-left:41.6667%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-7{margin-left:58.3333%}.col-lg-offset-8{margin-left:66.6667%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-10{margin-left:83.3333%}.col-lg-offset-11{margin-left:91.6667%}.col-lg-offset-12{margin-left:100%}}.center{text-align:center;margin-left:auto;margin-right:auto}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px){.visible-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}.visible-xs.visible-sm{display:none!important}@media (max-width:991px){.visible-xs.visible-sm{display:block!important}}@font-face{font-family:FontAwesome;src:url(../fonts/fontawesome-webfont.eot?v=4.7.0);src:url(../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0)format("embedded-opentype"),url(../fonts/fontawesome-webfont.woff2?v=4.7.0)format("woff2"),url(../fonts/fontawesome-webfont.woff?v=4.7.0)format("woff"),url(../fonts/fontawesome-webfont.ttf?v=4.7.0)format("truetype"),url(../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular)format("svg");font-weight:400;font-style:normal}.fa{font:14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:inline-block}.fa-lg{vertical-align:-15%;font-size:1.33333em;line-height:.75em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{text-align:center;width:1.28571em}.fa-ul{margin-left:2.14286em;padding-left:0;list-style-type:none}.fa-ul>li{position:relative}.fa-li{text-align:center;width:2.14286em;position:absolute;top:.142857em;left:-2.14286em}.fa-li.fa-lg{left:-1.85714em}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{animation:2s linear infinite fa-spin}.fa-pulse{animation:1s steps(8,end) infinite fa-spin}@keyframes fa-spin{0%{transform:rotate(0)}to{transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";transform:scaleY(-1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{vertical-align:middle;width:2em;height:2em;line-height:2em;display:inline-block;position:relative}.fa-stack-1x,.fa-stack-2x{text-align:center;width:100%;position:absolute;left:0}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-remove:before,.fa-close:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-gear:before,.fa-cog:before{content:""}.fa-trash-o:before{content:""}.fa-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-rotate-right:before,.fa-repeat:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before{content:""}.fa-check-circle:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-warning:before,.fa-exclamation-triangle:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-gears:before,.fa-cogs:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before{content:""}.fa-arrow-circle-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-save:before,.fa-floppy-o:before{content:""}.fa-square:before{content:""}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-unsorted:before,.fa-sort:before{content:""}.fa-sort-down:before,.fa-sort-desc:before{content:""}.fa-sort-up:before,.fa-sort-asc:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-legal:before,.fa-gavel:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-flash:before,.fa-bolt:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-paste:before,.fa-clipboard:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-unlink:before,.fa-chain-broken:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:""}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:""}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:""}.fa-euro:before,.fa-eur:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-rupee:before,.fa-inr:before{content:""}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:""}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:""}.fa-won:before,.fa-krw:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-turkish-lira:before,.fa-try:before{content:""}.fa-plus-square-o:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-institution:before,.fa-bank:before,.fa-university:before{content:""}.fa-mortar-board:before,.fa-graduation-cap:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:""}.fa-file-zip-o:before,.fa-file-archive-o:before{content:""}.fa-file-sound-o:before,.fa-file-audio-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:""}.fa-ge:before,.fa-empire:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-send:before,.fa-paper-plane:before{content:""}.fa-send-o:before,.fa-paper-plane-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-hotel:before,.fa-bed:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-yc:before,.fa-y-combinator:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-tv:before,.fa-television:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:""}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-signing:before,.fa-sign-language:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-vcard:before,.fa-address-card:before{content:""}.fa-vcard-o:before,.fa-address-card-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{clip:rect(0, 0, 0, 0);border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;width:auto;height:auto;margin:0;position:static;overflow:visible}.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{color:#fff;white-space:normal;background-color:#333;border-radius:4px;outline:0;font-size:14px;line-height:1.4;transition-property:transform,visibility,opacity;position:relative}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{border-width:8px 8px 0;border-top-color:initial;transform-origin:top;bottom:-7px;left:0}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{border-width:0 8px 8px;border-bottom-color:initial;transform-origin:bottom;top:-7px;left:0}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;transform-origin:0;right:-7px}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:100%;left:-7px}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{color:#333;width:16px;height:16px}.tippy-arrow:before{content:"";border-style:solid;border-color:#0000;position:absolute}.tippy-content{z-index:1;padding:5px 9px;position:relative}.tippy-box[data-theme~=light-border]{color:#333;background-color:#fff;background-clip:padding-box;border:1px solid #00081026;box-shadow:0 4px 14px -2px #00081014}.tippy-box[data-theme~=light-border]>.tippy-backdrop{background-color:#fff}.tippy-box[data-theme~=light-border]>.tippy-arrow:after,.tippy-box[data-theme~=light-border]>.tippy-svg-arrow:after{content:"";z-index:-1;position:absolute}.tippy-box[data-theme~=light-border]>.tippy-arrow:after{border-style:solid;border-color:#0000}.tippy-box[data-theme~=light-border][data-placement^=top]>.tippy-arrow:before{border-top-color:#fff}.tippy-box[data-theme~=light-border][data-placement^=top]>.tippy-arrow:after{border-width:7px 7px 0;border-top-color:#00081033;top:17px;left:1px}.tippy-box[data-theme~=light-border][data-placement^=top]>.tippy-svg-arrow>svg{top:16px}.tippy-box[data-theme~=light-border][data-placement^=top]>.tippy-svg-arrow:after{top:17px}.tippy-box[data-theme~=light-border][data-placement^=bottom]>.tippy-arrow:before{border-bottom-color:#fff;bottom:16px}.tippy-box[data-theme~=light-border][data-placement^=bottom]>.tippy-arrow:after{border-width:0 7px 7px;border-bottom-color:#00081033;bottom:17px;left:1px}.tippy-box[data-theme~=light-border][data-placement^=bottom]>.tippy-svg-arrow>svg{bottom:16px}.tippy-box[data-theme~=light-border][data-placement^=bottom]>.tippy-svg-arrow:after{bottom:17px}.tippy-box[data-theme~=light-border][data-placement^=left]>.tippy-arrow:before{border-left-color:#fff}.tippy-box[data-theme~=light-border][data-placement^=left]>.tippy-arrow:after{border-width:7px 0 7px 7px;border-left-color:#00081033;top:1px;left:17px}.tippy-box[data-theme~=light-border][data-placement^=left]>.tippy-svg-arrow>svg{left:11px}.tippy-box[data-theme~=light-border][data-placement^=left]>.tippy-svg-arrow:after{left:12px}.tippy-box[data-theme~=light-border][data-placement^=right]>.tippy-arrow:before{border-right-color:#fff;right:16px}.tippy-box[data-theme~=light-border][data-placement^=right]>.tippy-arrow:after{border-width:7px 7px 7px 0;border-right-color:#00081033;top:1px;right:17px}.tippy-box[data-theme~=light-border][data-placement^=right]>.tippy-svg-arrow>svg{right:11px}.tippy-box[data-theme~=light-border][data-placement^=right]>.tippy-svg-arrow:after{right:12px}.tippy-box[data-theme~=light-border]>.tippy-svg-arrow{fill:#fff}.tippy-box[data-theme~=light-border]>.tippy-svg-arrow:after{background-image:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMCA2czEuNzk2LS4wMTMgNC42Ny0zLjYxNUM1Ljg1MS45IDYuOTMuMDA2IDggMGMxLjA3LS4wMDYgMi4xNDguODg3IDMuMzQzIDIuMzg1QzE0LjIzMyA2LjAwNSAxNiA2IDE2IDZIMHoiIGZpbGw9InJnYmEoMCwgOCwgMTYsIDAuMikiLz48L3N2Zz4=);background-size:16px 6px;width:16px;height:6px}@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-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-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@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:"";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:"";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:"";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:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@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} \ No newline at end of file diff --git a/public/marketing.css b/public/marketing.css index afb95a4b..a2b376da 100644 --- a/public/marketing.css +++ b/public/marketing.css @@ -1,2 +1,2 @@ /*! tailwindcss v4.2.1 | MIT License | https://tailwindcss.com */ -@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-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-divide-y-reverse:0;--tw-border-style:solid;--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-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme{:root,:host{--font-sans:"Instrument Sans", system-ui, sans-serif;--font-serif:"Instrument Serif", Georgia, 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-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-red-800:oklch(44.4% .177 26.899);--color-red-900:oklch(39.6% .141 25.723);--color-yellow-400:oklch(85.2% .199 91.936);--color-green-400:oklch(79.2% .209 151.711);--color-olive-100:oklch(96.6% .005 106.5);--color-olive-300:oklch(88% .011 106.6);--color-olive-400:oklch(73.7% .021 106.9);--color-olive-500:oklch(58% .031 107.3);--color-olive-600:oklch(46.6% .025 107.3);--color-olive-700:oklch(39.4% .023 107.4);--color-olive-800:oklch(28.6% .016 107.4);--color-olive-900:oklch(22.8% .013 107.4);--color-olive-950:oklch(15.3% .006 107.1);--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-md:28rem;--container-lg:32rem;--container-xl:36rem;--container-2xl:42rem;--container-3xl:48rem;--container-4xl:56rem;--container-5xl:64rem;--container-7xl:80rem;--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-5xl:3rem;--text-5xl--line-height:1;--text-6xl:3.75rem;--text-6xl--line-height:1;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wider:.05em;--leading-tight:1.25;--leading-relaxed:1.625;--radius-lg:.5rem;--radius-xl:.75rem;--radius-3xl:1.5rem;--ease-out:cubic-bezier(0, 0, .2, 1);--blur-sm:8px;--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-olive-150:oklch(94.5% .006 106.5);--color-cream-100:#f9f7f3;--color-cream-200:#f3f1ec;--color-cream-300:#edeae3;--color-cream-400:#e0dcd2;--color-dark-950:#0a0a0a;--color-dark-900:#0f0f0f;--color-dark-800:#171717;--color-dark-700:#1f1f1f;--color-dark-600:#2a2a2a;--color-dark-500:#3d3d3d;--color-dark-300:#6b6b6b;--color-dark-200:#a3a3a3}}@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}:root{--color-bg:var(--color-olive-100);--color-surface:#fff;--color-surface-elevated:var(--color-cream-200);--color-primary:var(--color-olive-950);--color-primary-hover:var(--color-olive-900);--color-accent:var(--color-olive-600);--color-accent-hover:var(--color-olive-700);--color-text:var(--color-olive-950);--color-text-muted:var(--color-olive-800);--color-text-subtle:var(--color-olive-600);--color-border:var(--color-cream-400);--color-border-subtle:var(--color-cream-300);--color-hero-bg:var(--color-olive-800);--color-hero-text:var(--color-white);--color-hero-muted:var(--color-cream-100);--color-hero-accent:var(--color-olive-300);--color-btn-primary-bg:var(--color-olive-900);--color-btn-primary-text:var(--color-cream-100);--color-btn-primary-hover:var(--color-olive-950);--color-footer-bg:var(--color-olive-150)}@media (prefers-color-scheme:dark){:root{--color-bg:var(--color-dark-950);--color-surface:var(--color-dark-900);--color-surface-elevated:var(--color-dark-800);--color-primary:var(--color-cream-100);--color-primary-hover:#fff;--color-accent:var(--color-olive-400);--color-accent-hover:var(--color-olive-300);--color-text:var(--color-cream-100);--color-text-muted:var(--color-dark-200);--color-text-subtle:var(--color-dark-300);--color-border:var(--color-dark-500);--color-border-subtle:var(--color-dark-600);--color-hero-bg:var(--color-olive-800);--color-hero-text:var(--color-cream-100);--color-hero-muted:var(--color-cream-300);--color-hero-accent:var(--color-olive-500);--color-btn-primary-bg:var(--color-cream-100);--color-btn-primary-text:var(--color-olive-950);--color-btn-primary-hover:#fff;--color-footer-bg:var(--color-olive-900)}}html{font-family:var(--font-sans);scroll-behavior:smooth}body{background-color:var(--color-bg);color:var(--color-text)}h1,h2,h3,h4,h5,h6{font-family:var(--font-serif)}}@layer components{.btn{cursor:pointer;padding-inline:calc(var(--spacing) * 6);padding-block:calc(var(--spacing) * 3);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);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:3.40282e38px;justify-content:center;align-items:center;transition-duration:.2s;display:inline-flex}.btn-primary{background-color:var(--color-btn-primary-bg);color:var(--color-btn-primary-text)}@media (prefers-color-scheme:dark){.btn-primary{color:#1f231c;background-color:#f9f7f3}}.btn-primary:hover{background-color:var(--color-btn-primary-hover)}.btn-secondary{color:var(--color-text);border:1px solid var(--color-border);background-color:#0000}.btn-secondary:hover{background-color:var(--color-surface);border-color:var(--color-text-muted)}.card{background-color:var(--color-surface);border:1px solid var(--color-border-subtle);border-radius:.75rem}.section-heading{font-family:var(--font-serif);color:var(--color-text);font-size:2.5rem;line-height:1.2}.text-muted{color:var(--color-text-muted)}.text-subtle{color:var(--color-text-subtle)}.accordion-item{border-bottom:1px solid var(--color-border-subtle)}.accordion-trigger{width:100%;padding-top:calc(var(--spacing) * 4);padding-bottom:calc(var(--spacing) * 4);text-align:left;--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--color-text);justify-content:space-between;align-items:center;display:flex}.accordion-trigger:hover{color:var(--color-primary)}.accordion-content{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.3s;color:var(--color-text-muted);transition-duration:.3s;overflow:hidden}.badge{align-items:center;gap:calc(var(--spacing) * 1.5);padding-inline:calc(var(--spacing) * 3);padding-block: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);background-color:var(--color-surface-elevated);color:var(--color-text-muted);border-radius:3.40282e38px;display:inline-flex}.badge-accent{background-color:var(--color-accent);color:var(--color-cream-100)}}@layer utilities{.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}.inset-0{inset:calc(var(--spacing) * 0)}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.-top-3{top:calc(var(--spacing) * -3)}.top-0{top:calc(var(--spacing) * 0)}.top-20{top:calc(var(--spacing) * 20)}.right-0{right:calc(var(--spacing) * 0)}.left-0{left:calc(var(--spacing) * 0)}.left-1\/2{left:50%}.z-50{z-index:50}.float-left{float:left}.float-right{float:right}.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-2{margin-inline:calc(var(--spacing) * -2)}.mx-auto{margin-inline:auto}.my-6{margin-block:calc(var(--spacing) * 6)}.mt-0{margin-top:calc(var(--spacing) * 0)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-2\.5{margin-top:calc(var(--spacing) * 2.5)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.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-12{margin-top:calc(var(--spacing) * 12)}.mt-16{margin-top:calc(var(--spacing) * 16)}.mb-0{margin-bottom:calc(var(--spacing) * 0)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.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-8{margin-bottom:calc(var(--spacing) * 8)}.mb-10{margin-bottom:calc(var(--spacing) * 10)}.mb-12{margin-bottom:calc(var(--spacing) * 12)}.mb-16{margin-bottom:calc(var(--spacing) * 16)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-3{margin-left:calc(var(--spacing) * 3)}.ml-4{margin-left:calc(var(--spacing) * 4)}.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}.h-3{height:calc(var(--spacing) * 3)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-10{height:calc(var(--spacing) * 10)}.h-12{height:calc(var(--spacing) * 12)}.h-15{height:calc(var(--spacing) * 15)}.h-16{height:calc(var(--spacing) * 16)}.h-52{height:calc(var(--spacing) * 52)}.h-full{height:100%}.h-px{height:1px}.min-h-screen{min-height:100vh}.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-16{width:calc(var(--spacing) * 16)}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-5xl{max-width:var(--container-5xl)}.max-w-7xl{max-width:var(--container-7xl)}.max-w-\[150px\]{max-width:150px}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.max-w-none{max-width:none}.max-w-xl{max-width:var(--container-xl)}.max-w-xs{max-width:var(--container-xs)}.flex-shrink{flex-shrink:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.grow{flex-grow:1}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-pointer{cursor:pointer}.touch-manipulation{touch-action:manipulation}.resize{resize:both}.list-disc{list-style-type:disc}.list-none{list-style-type: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-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-8{gap:calc(var(--spacing) * 8)}.gap-12{gap:calc(var(--spacing) * 12)}: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-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * 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-5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-8>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 8) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 8) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-4{column-gap:calc(var(--spacing) * 4)}.gap-x-6{column-gap:calc(var(--spacing) * 6)}.gap-x-12{column-gap:calc(var(--spacing) * 12)}.gap-y-10{row-gap:calc(var(--spacing) * 10)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}.self-end{align-self:flex-end}.overflow-hidden{overflow:hidden}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-t-3xl{border-top-left-radius:var(--radius-3xl);border-top-right-radius:var(--radius-3xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-y{border-block-style:var(--tw-border-style);border-block-width:1px}.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-cream-300{border-color:var(--color-cream-300)}.border-red-200{border-color:var(--color-red-200)}.border-white\/30{border-color:#ffffff4d}@supports (color:color-mix(in lab, red, red)){.border-white\/30{border-color:color-mix(in oklab, var(--color-white) 30%, transparent)}}.bg-green-400{background-color:var(--color-green-400)}.bg-olive-100{background-color:var(--color-olive-100)}.bg-olive-800{background-color:var(--color-olive-800)}.bg-olive-900{background-color:var(--color-olive-900)}.bg-olive-950\/20{background-color:#0c0c0933}@supports (color:color-mix(in lab, red, red)){.bg-olive-950\/20{background-color:color-mix(in oklab, var(--color-olive-950) 20%, transparent)}}.bg-red-50{background-color:var(--color-red-50)}.bg-red-400{background-color:var(--color-red-400)}.bg-white{background-color:var(--color-white)}.bg-white\/20{background-color:#fff3}@supports (color:color-mix(in lab, red, red)){.bg-white\/20{background-color:color-mix(in oklab, var(--color-white) 20%, transparent)}}.bg-yellow-400{background-color:var(--color-yellow-400)}.fill-current{fill:currentColor}.object-cover{object-fit:cover}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-6{padding:calc(var(--spacing) * 6)}.p-8{padding:calc(var(--spacing) * 8)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-10{padding-inline:calc(var(--spacing) * 10)}.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-12{padding-block:calc(var(--spacing) * 12)}.py-16{padding-block:calc(var(--spacing) * 16)}.py-20{padding-block:calc(var(--spacing) * 20)}.py-24{padding-block:calc(var(--spacing) * 24)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pt-7{padding-top:calc(var(--spacing) * 7)}.pt-8{padding-top:calc(var(--spacing) * 8)}.pt-20{padding-top:calc(var(--spacing) * 20)}.pt-24{padding-top:calc(var(--spacing) * 24)}.pb-7{padding-bottom:calc(var(--spacing) * 7)}.pb-10{padding-bottom:calc(var(--spacing) * 10)}.pb-12{padding-bottom:calc(var(--spacing) * 12)}.pl-0{padding-left:calc(var(--spacing) * 0)}.pl-1\.5{padding-left:calc(var(--spacing) * 1.5)}.pl-2{padding-left:calc(var(--spacing) * 2)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-5{padding-left:calc(var(--spacing) * 5)}.pl-6{padding-left:calc(var(--spacing) * 6)}.text-center{text-align:center}.font-sans{font-family:var(--font-sans)}.font-serif{font-family:var(--font-serif)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.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-5xl{font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--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-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[30px\]{font-size:30px}.leading-7{--tw-leading:calc(var(--spacing) * 7);line-height:calc(var(--spacing) * 7)}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.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-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.text-cream-100{color:var(--color-cream-100)}.text-olive-800{color:var(--color-olive-800)}.text-olive-900{color:var(--color-olive-900)}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-red-700{color:var(--color-red-700)}.text-white{color:var(--color-white)}.uppercase{text-transform:uppercase}.italic{font-style:italic}.underline{text-decoration-line:underline}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-30{opacity:.3}.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-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)}.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)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.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,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.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-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-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.select-all{-webkit-user-select:all;user-select:all}@media (hover:hover){.hover\:scale-105:hover{--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x) var(--tw-scale-y)}.hover\:scale-125:hover{--tw-scale-x:125%;--tw-scale-y:125%;--tw-scale-z:125%;scale:var(--tw-scale-x) var(--tw-scale-y)}.hover\:bg-cream-100:hover{background-color:var(--color-cream-100)}.hover\:bg-olive-800:hover{background-color:var(--color-olive-800)}.hover\:bg-olive-950:hover{background-color:var(--color-olive-950)}.hover\:bg-olive-950\/30:hover{background-color:#0c0c094d}@supports (color:color-mix(in lab, red, red)){.hover\:bg-olive-950\/30:hover{background-color:color-mix(in oklab, var(--color-olive-950) 30%, transparent)}}.hover\:bg-white\/10:hover{background-color:#ffffff1a}@supports (color:color-mix(in lab, red, red)){.hover\:bg-white\/10:hover{background-color:color-mix(in oklab, var(--color-white) 10%, transparent)}}.hover\:opacity-50:hover{opacity:.5}}.focus\:border-transparent:focus{border-color:#0000}.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-olive-500:focus{--tw-ring-color:var(--color-olive-500)}.focus\:ring-olive-600:focus{--tw-ring-color:var(--color-olive-600)}.focus\:ring-offset-2:focus{--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)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}@media (min-width:40rem){.sm\:mx-0{margin-inline:calc(var(--spacing) * 0)}.sm\:hidden{display:none}.sm\:inline-flex{display:inline-flex}.sm\:h-6{height:calc(var(--spacing) * 6)}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:gap-16{gap:calc(var(--spacing) * 16)}.sm\:gap-x-16{column-gap:calc(var(--spacing) * 16)}.sm\:rounded-3xl{border-radius:var(--radius-3xl)}.sm\:p-6{padding:calc(var(--spacing) * 6)}.sm\:p-8{padding:calc(var(--spacing) * 8)}.sm\:px-6{padding-inline:calc(var(--spacing) * 6)}.sm\:px-10{padding-inline:calc(var(--spacing) * 10)}.sm\:py-32{padding-block:calc(var(--spacing) * 32)}.sm\:pt-16{padding-top:calc(var(--spacing) * 16)}.sm\:pb-14{padding-bottom:calc(var(--spacing) * 14)}.sm\:pb-20{padding-bottom:calc(var(--spacing) * 20)}.sm\:pl-0{padding-left:calc(var(--spacing) * 0)}.sm\:text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.sm\:text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.sm\:text-5xl{font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--line-height))}}@media (min-width:48rem){.md\:block{display:block}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:64rem){.lg\:mx-0{margin-inline:calc(var(--spacing) * 0)}.lg\:flex{display:flex}.lg\:hidden{display:none}.lg\:inline-flex{display:inline-flex}.lg\:h-64{height:calc(var(--spacing) * 64)}.lg\:max-w-\[300px\]{max-width:300px}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-\[220px_1fr\]{grid-template-columns:220px 1fr}.lg\:items-center{align-items:center}.lg\:justify-start{justify-content:flex-start}.lg\:gap-0{gap:calc(var(--spacing) * 0)}.lg\:gap-x-8{column-gap:calc(var(--spacing) * 8)}.lg\:gap-x-20{column-gap:calc(var(--spacing) * 20)}.lg\:px-8{padding-inline:calc(var(--spacing) * 8)}.lg\:px-12{padding-inline:calc(var(--spacing) * 12)}.lg\:py-16{padding-block:calc(var(--spacing) * 16)}.lg\:py-20{padding-block:calc(var(--spacing) * 20)}.lg\:py-28{padding-block:calc(var(--spacing) * 28)}.lg\:pt-28{padding-top:calc(var(--spacing) * 28)}.lg\:text-left{text-align:left}.lg\:text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.lg\:text-5xl{font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--line-height))}.lg\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}@media (prefers-color-scheme:dark){.dark\:border-dark-700{border-color:var(--color-dark-700)}.dark\:border-red-800{border-color:var(--color-red-800)}.dark\:bg-olive-300{background-color:var(--color-olive-300)}.dark\:bg-olive-950{background-color:var(--color-olive-950)}.dark\:bg-red-900\/20{background-color:#82181a33}@supports (color:color-mix(in lab, red, red)){.dark\:bg-red-900\/20{background-color:color-mix(in oklab, var(--color-red-900) 20%, transparent)}}.dark\:text-olive-100{color:var(--color-olive-100)}.dark\:text-olive-300{color:var(--color-olive-300)}.dark\:text-olive-800{color:var(--color-olive-800)}.dark\:text-red-300{color:var(--color-red-300)}.dark\:text-red-400{color:var(--color-red-400)}}.bg-page{background-color:var(--color-bg)}.bg-surface,.hover\:bg-surface:hover{background-color:var(--color-surface)}.bg-surface-elevated,.hover\:bg-surface-elevated:hover{background-color:var(--color-surface-elevated)}.bg-footer{background-color:var(--color-footer-bg)}.bg-bg{background-color:var(--color-bg)}.text-primary,.hover\:text-primary:hover{color:var(--color-primary)}.text-accent,.hover\:text-accent:hover{color:var(--color-accent)}.border-default{border-color:var(--color-border)}.border-subtle{border-color:var(--color-border-subtle)}.bg-hero{background:linear-gradient(#5c6654,#333a2b)}@media (prefers-color-scheme:dark){.bg-hero{background:linear-gradient(#5c6654,#333a2b)}}.text-hero{color:var(--color-hero-text)}.text-hero-muted{color:var(--color-hero-muted)}.text-hero-accent{color:var(--color-hero-accent)}.bg-grain{border-radius:inherit;pointer-events:none;opacity:.3;mix-blend-mode:overlay;background-position:50%;position:absolute;inset:0}@media (prefers-color-scheme:dark){.bg-grain{opacity:.25}}.bg-grain>*{z-index:1;position:relative}.animate-fade-in{animation:.5s ease-out forwards fadeIn}.animate-slide-up{animation:.5s ease-out forwards slideUp}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}.blinking-cursor{animation:1.3s step-end infinite blink}@keyframes blink{0%,to{opacity:1}50%{opacity:0}}}.twitter-tweet-rendered{text-align:center;margin-top:40px;margin-left:auto;margin-right:auto}@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-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-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@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:"";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:"";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:"";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:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@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} \ No newline at end of file +@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-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-divide-y-reverse:0;--tw-border-style:solid;--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-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme{:root,:host{--font-sans:"Instrument Sans", system-ui, sans-serif;--font-serif:"Instrument Serif", Georgia, 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-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-red-800:oklch(44.4% .177 26.899);--color-red-900:oklch(39.6% .141 25.723);--color-yellow-400:oklch(85.2% .199 91.936);--color-green-400:oklch(79.2% .209 151.711);--color-olive-100:oklch(96.6% .005 106.5);--color-olive-300:oklch(88% .011 106.6);--color-olive-400:oklch(73.7% .021 106.9);--color-olive-500:oklch(58% .031 107.3);--color-olive-600:oklch(46.6% .025 107.3);--color-olive-700:oklch(39.4% .023 107.4);--color-olive-800:oklch(28.6% .016 107.4);--color-olive-900:oklch(22.8% .013 107.4);--color-olive-950:oklch(15.3% .006 107.1);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-md:28rem;--container-lg:32rem;--container-xl:36rem;--container-2xl:42rem;--container-3xl:48rem;--container-4xl:56rem;--container-5xl:64rem;--container-6xl:72rem;--container-7xl:80rem;--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-5xl:3rem;--text-5xl--line-height:1;--text-6xl:3.75rem;--text-6xl--line-height:1;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-wider:.05em;--leading-tight:1.25;--leading-relaxed:1.625;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--radius-3xl:1.5rem;--ease-out:cubic-bezier(0, 0, .2, 1);--blur-sm:8px;--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-olive-150:oklch(94.5% .006 106.5);--color-cream-100:#f9f7f3;--color-cream-200:#f3f1ec;--color-cream-300:#edeae3;--color-cream-400:#e0dcd2;--color-dark-950:#0a0a0a;--color-dark-900:#0f0f0f;--color-dark-800:#171717;--color-dark-700:#1f1f1f;--color-dark-600:#2a2a2a;--color-dark-500:#3d3d3d;--color-dark-300:#6b6b6b;--color-dark-200:#a3a3a3}}@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}:root{--color-bg:var(--color-olive-100);--color-surface:#fff;--color-surface-elevated:var(--color-cream-200);--color-primary:var(--color-olive-950);--color-primary-hover:var(--color-olive-900);--color-accent:var(--color-olive-600);--color-accent-hover:var(--color-olive-700);--color-text:var(--color-olive-950);--color-text-muted:var(--color-olive-800);--color-text-subtle:var(--color-olive-600);--color-border:var(--color-cream-400);--color-border-subtle:var(--color-cream-300);--color-hero-bg:var(--color-olive-800);--color-hero-text:var(--color-white);--color-hero-muted:var(--color-cream-100);--color-hero-accent:var(--color-olive-300);--color-btn-primary-bg:var(--color-olive-900);--color-btn-primary-text:var(--color-cream-100);--color-btn-primary-hover:var(--color-olive-950);--color-footer-bg:var(--color-olive-150)}@media (prefers-color-scheme:dark){:root{--color-bg:var(--color-dark-950);--color-surface:var(--color-dark-900);--color-surface-elevated:var(--color-dark-800);--color-primary:var(--color-cream-100);--color-primary-hover:#fff;--color-accent:var(--color-olive-400);--color-accent-hover:var(--color-olive-300);--color-text:var(--color-cream-100);--color-text-muted:var(--color-dark-200);--color-text-subtle:var(--color-dark-300);--color-border:var(--color-dark-500);--color-border-subtle:var(--color-dark-600);--color-hero-bg:var(--color-olive-800);--color-hero-text:var(--color-cream-100);--color-hero-muted:var(--color-cream-300);--color-hero-accent:var(--color-olive-500);--color-btn-primary-bg:var(--color-cream-100);--color-btn-primary-text:var(--color-olive-950);--color-btn-primary-hover:#fff;--color-footer-bg:var(--color-olive-900)}}html{font-family:var(--font-sans);scroll-behavior:smooth}body{background-color:var(--color-bg);color:var(--color-text)}h1,h2,h3,h4,h5,h6{font-family:var(--font-serif)}details summary{list-style:none}details summary::-webkit-details-marker{display:none}}@layer components{.btn{cursor:pointer;padding-inline:calc(var(--spacing) * 6);padding-block:calc(var(--spacing) * 3);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);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:3.40282e38px;justify-content:center;align-items:center;transition-duration:.2s;display:inline-flex}.btn-primary{background-color:var(--color-btn-primary-bg);color:var(--color-btn-primary-text)}@media (prefers-color-scheme:dark){.btn-primary{color:#1f231c;background-color:#f9f7f3}}.btn-primary:hover{background-color:var(--color-btn-primary-hover)}.btn-secondary{color:var(--color-text);border:1px solid var(--color-border);background-color:#0000}.btn-secondary:hover{background-color:var(--color-surface);border-color:var(--color-text-muted)}.card{background-color:var(--color-surface);border:1px solid var(--color-border-subtle);border-radius:.75rem}.section-heading{font-family:var(--font-serif);color:var(--color-text);font-size:2.5rem;line-height:1.2}.text-muted{color:var(--color-text-muted)}.text-subtle{color:var(--color-text-subtle)}.accordion-item{border-bottom:1px solid var(--color-border-subtle)}.accordion-trigger{width:100%;padding-top:calc(var(--spacing) * 4);padding-bottom:calc(var(--spacing) * 4);text-align:left;--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--color-text);justify-content:space-between;align-items:center;display:flex}.accordion-trigger:hover{color:var(--color-primary)}.accordion-content{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.3s;color:var(--color-text-muted);transition-duration:.3s;overflow:hidden}.badge{align-items:center;gap:calc(var(--spacing) * 1.5);padding-inline:calc(var(--spacing) * 3);padding-block: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);background-color:var(--color-surface-elevated);color:var(--color-text-muted);border-radius:3.40282e38px;display:inline-flex}.badge-accent{background-color:var(--color-accent);color:var(--color-cream-100)}.alert-app-success{border-radius:var(--radius-lg);border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 3);text-align:center;background-color:#5b5b4b1f;border-width:1px}@supports (color:color-mix(in lab, red, red)){.alert-app-success{background-color:color-mix(in oklab, var(--color-olive-600) 12%, transparent)}}.alert-app-success{border-color:var(--color-olive-400);color:var(--color-olive-950)}.alert-app-danger{border-radius:var(--radius-lg);border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 3);text-align:center;color:var(--color-olive-950);background-color:oklab(44.2929% .157181 .0795491/.12);border-width:1px;border-color:#c53030}@media (prefers-color-scheme:dark){.alert-app-success,.alert-app-danger{color:var(--color-cream-100)}}.input-app{border-radius:var(--radius-md);border-style:var(--tw-border-style);width:100%;padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));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));--tw-outline-style:none;border-width:1px;border-color:var(--color-border);background-color:var(--color-surface);color:var(--color-text);outline-style:none}.input-app:focus{border-color:var(--color-olive-600);box-shadow:0 0 0 2px #5b5b4b59}@supports (color:color-mix(in lab, red, red)){.input-app:focus{box-shadow:0 0 0 2px color-mix(in oklab, var(--color-olive-600) 35%, transparent)}}.form-control{border-radius:var(--radius-md);border-style:var(--tw-border-style);width:100%;padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));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));--tw-outline-style:none;border-width:1px;border-color:var(--color-border);background-color:var(--color-surface);color:var(--color-text);outline-style:none}.form-control:focus{border-color:var(--color-olive-600);box-shadow:0 0 0 2px #5b5b4b59}@supports (color:color-mix(in lab, red, red)){.form-control:focus{box-shadow:0 0 0 2px color-mix(in oklab, var(--color-olive-600) 35%, transparent)}}.well{border-radius:var(--radius-lg);border-style:var(--tw-border-style);padding:calc(var(--spacing) * 4);--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);border-width:1px;border-color:var(--color-border-subtle);background-color:var(--color-surface)}.alert.alert-success{border-radius:var(--radius-lg);border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 3);background-color:#5b5b4b1f;border-width:1px}@supports (color:color-mix(in lab, red, red)){.alert.alert-success{background-color:color-mix(in oklab, var(--color-olive-600) 12%, transparent)}}.alert.alert-success{border-color:var(--color-olive-400);color:var(--color-olive-950)}.alert.alert-danger{border-radius:var(--radius-lg);border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 3);color:var(--color-olive-950);background-color:oklab(44.2929% .157181 .0795491/.15);border-width:1px;border-color:#c53030}.alert.alert-info{border-radius:var(--radius-lg);border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 3);color:var(--color-olive-950);background-color:oklab(51.7668% -.0488637 -.0642039/.12);border-width:1px;border-color:#31708f}.alert.alert-warning{border-radius:var(--radius-lg);border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 3);background-color:#7c7c672e;border-width:1px}@supports (color:color-mix(in lab, red, red)){.alert.alert-warning{background-color:color-mix(in oklab, var(--color-olive-500) 18%, transparent)}}.alert.alert-warning{border-color:var(--color-olive-400);color:var(--color-olive-950)}@media (prefers-color-scheme:dark){.alert.alert-success,.alert.alert-danger,.alert.alert-info,.alert.alert-warning{color:var(--color-cream-100)}}.btn-default{border-radius:var(--radius-md);border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2);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);border-width:1px;border-color:var(--color-border);background-color:var(--color-surface);color:var(--color-text);justify-content:center;align-items:center;display:inline-flex}.btn-default:hover{background-color:var(--color-surface-elevated)}.btn-danger{border-radius:var(--radius-md);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2);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-white);background-color:#9e0812;justify-content:center;align-items:center;display:inline-flex}.btn-danger:hover{background-color:#7a060e}.btn-warning{border-radius:var(--radius-md);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2);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:#1a1a1a;background-color:#f0ad4e;justify-content:center;align-items:center;display:inline-flex}.btn-success{border-radius:var(--radius-md);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2);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-white);background-color:var(--color-olive-800);justify-content:center;align-items:center;display:inline-flex}.btn-info{border-radius:var(--radius-md);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2);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-white);background-color:#5bc0de;justify-content:center;align-items:center;display:inline-flex}.btn-link{border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * 1);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--color-accent);background-color:#0000;border-width:0;justify-content:center;align-items:center;text-decoration-line:underline;display:inline-flex}.btn-xs{padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * 1);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.btn-sm{padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 1.5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.btn-lg{padding-inline:calc(var(--spacing) * 6);padding-block:calc(var(--spacing) * 3);font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.btn-block{justify-content:center;width:100%}.label.label-default{padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * .5);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal);background-color:var(--color-surface-elevated);color:var(--color-text-muted);border-radius:.25rem;display:inline-block}}@layer utilities{.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}.inset-0{inset:calc(var(--spacing) * 0)}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.-top-3{top:calc(var(--spacing) * -3)}.top-0{top:calc(var(--spacing) * 0)}.top-20{top:calc(var(--spacing) * 20)}.top-full{top:100%}.right-0{right:calc(var(--spacing) * 0)}.left-0{left:calc(var(--spacing) * 0)}.left-1\/2{left:50%}.z-50{z-index:50}.z-\[1000\]{z-index:1000}.z-\[1001\]{z-index:1001}.float-left{float:left}.float-right{float:right}.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-2{margin-inline:calc(var(--spacing) * -2)}.mx-auto{margin-inline:auto}.my-6{margin-block:calc(var(--spacing) * 6)}.mt-0{margin-top:calc(var(--spacing) * 0)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-2\.5{margin-top:calc(var(--spacing) * 2.5)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.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-12{margin-top:calc(var(--spacing) * 12)}.mt-16{margin-top:calc(var(--spacing) * 16)}.mr-0{margin-right:calc(var(--spacing) * 0)}.mb-0{margin-bottom:calc(var(--spacing) * 0)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.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-8{margin-bottom:calc(var(--spacing) * 8)}.mb-10{margin-bottom:calc(var(--spacing) * 10)}.mb-12{margin-bottom:calc(var(--spacing) * 12)}.mb-16{margin-bottom:calc(var(--spacing) * 16)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-3{margin-left:calc(var(--spacing) * 3)}.ml-4{margin-left:calc(var(--spacing) * 4)}.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}.h-3{height:calc(var(--spacing) * 3)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-10{height:calc(var(--spacing) * 10)}.h-12{height:calc(var(--spacing) * 12)}.h-15{height:calc(var(--spacing) * 15)}.h-16{height:calc(var(--spacing) * 16)}.h-52{height:calc(var(--spacing) * 52)}.h-full{height:100%}.h-px{height:1px}.min-h-screen{min-height:100vh}.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-16{width:calc(var(--spacing) * 16)}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-5xl{max-width:var(--container-5xl)}.max-w-6xl{max-width:var(--container-6xl)}.max-w-7xl{max-width:var(--container-7xl)}.max-w-\[150px\]{max-width:150px}.max-w-full{max-width:100%}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.max-w-none{max-width:none}.max-w-xl{max-width:var(--container-xl)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-\[12rem\]{min-width:12rem}.flex-1{flex:1}.flex-shrink{flex-shrink:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.grow{flex-grow:1}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-pointer{cursor:pointer}.touch-manipulation{touch-action:manipulation}.resize{resize:both}.list-disc{list-style-type:disc}.list-none{list-style-type: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-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-8{gap:calc(var(--spacing) * 8)}.gap-12{gap:calc(var(--spacing) * 12)}: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-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * 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-5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-8>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 8) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 8) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-4{column-gap:calc(var(--spacing) * 4)}.gap-x-6{column-gap:calc(var(--spacing) * 6)}.gap-x-12{column-gap:calc(var(--spacing) * 12)}.gap-y-10{row-gap:calc(var(--spacing) * 10)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}.self-end{align-self:flex-end}.overflow-hidden{overflow:hidden}.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-xl{border-radius:var(--radius-xl)}.rounded-t-3xl{border-top-left-radius:var(--radius-3xl);border-top-right-radius:var(--radius-3xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-y{border-block-style:var(--tw-border-style);border-block-width:1px}.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-cream-300{border-color:var(--color-cream-300)}.border-olive-700{border-color:var(--color-olive-700)}.border-olive-800{border-color:var(--color-olive-800)}.border-red-200{border-color:var(--color-red-200)}.border-white\/30{border-color:#ffffff4d}@supports (color:color-mix(in lab, red, red)){.border-white\/30{border-color:color-mix(in oklab, var(--color-white) 30%, transparent)}}.bg-black\/10{background-color:#0000001a}@supports (color:color-mix(in lab, red, red)){.bg-black\/10{background-color:color-mix(in oklab, var(--color-black) 10%, transparent)}}.bg-green-400{background-color:var(--color-green-400)}.bg-olive-100{background-color:var(--color-olive-100)}.bg-olive-600{background-color:var(--color-olive-600)}.bg-olive-700{background-color:var(--color-olive-700)}.bg-olive-800{background-color:var(--color-olive-800)}.bg-olive-900{background-color:var(--color-olive-900)}.bg-olive-950\/20{background-color:#0c0c0933}@supports (color:color-mix(in lab, red, red)){.bg-olive-950\/20{background-color:color-mix(in oklab, var(--color-olive-950) 20%, transparent)}}.bg-red-50{background-color:var(--color-red-50)}.bg-red-400{background-color:var(--color-red-400)}.bg-white{background-color:var(--color-white)}.bg-white\/20{background-color:#fff3}@supports (color:color-mix(in lab, red, red)){.bg-white\/20{background-color:color-mix(in oklab, var(--color-white) 20%, transparent)}}.bg-yellow-400{background-color:var(--color-yellow-400)}.fill-current{fill:currentColor}.object-cover{object-fit:cover}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-6{padding:calc(var(--spacing) * 6)}.p-8{padding:calc(var(--spacing) * 8)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-10{padding-inline:calc(var(--spacing) * 10)}.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-12{padding-block:calc(var(--spacing) * 12)}.py-16{padding-block:calc(var(--spacing) * 16)}.py-20{padding-block:calc(var(--spacing) * 20)}.py-24{padding-block:calc(var(--spacing) * 24)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pt-7{padding-top:calc(var(--spacing) * 7)}.pt-8{padding-top:calc(var(--spacing) * 8)}.pt-16{padding-top:calc(var(--spacing) * 16)}.pt-20{padding-top:calc(var(--spacing) * 20)}.pt-24{padding-top:calc(var(--spacing) * 24)}.pb-7{padding-bottom:calc(var(--spacing) * 7)}.pb-10{padding-bottom:calc(var(--spacing) * 10)}.pb-12{padding-bottom:calc(var(--spacing) * 12)}.pb-40{padding-bottom:calc(var(--spacing) * 40)}.pl-0{padding-left:calc(var(--spacing) * 0)}.pl-1\.5{padding-left:calc(var(--spacing) * 1.5)}.pl-2{padding-left:calc(var(--spacing) * 2)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-5{padding-left:calc(var(--spacing) * 5)}.pl-6{padding-left:calc(var(--spacing) * 6)}.text-center{text-align:center}.font-sans{font-family:var(--font-sans)}.font-serif{font-family:var(--font-serif)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.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-5xl{font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--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-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-\[30px\]{font-size:30px}.leading-7{--tw-leading:calc(var(--spacing) * 7);line-height:calc(var(--spacing) * 7)}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.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)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.text-cream-100{color:var(--color-cream-100)}.text-cream-200{color:var(--color-cream-200)}.text-olive-800{color:var(--color-olive-800)}.text-olive-900{color:var(--color-olive-900)}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-red-700{color:var(--color-red-700)}.text-white{color:var(--color-white)}.uppercase{text-transform:uppercase}.italic{font-style:italic}.underline{text-decoration-line:underline}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-30{opacity:.3}.opacity-80{opacity:.8}.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-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)}.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)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.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,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.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-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-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.select-all{-webkit-user-select:all;user-select:all}@media (hover:hover){.hover\:scale-105:hover{--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x) var(--tw-scale-y)}.hover\:scale-125:hover{--tw-scale-x:125%;--tw-scale-y:125%;--tw-scale-z:125%;scale:var(--tw-scale-x) var(--tw-scale-y)}.hover\:bg-black\/20:hover{background-color:#0003}@supports (color:color-mix(in lab, red, red)){.hover\:bg-black\/20:hover{background-color:color-mix(in oklab, var(--color-black) 20%, transparent)}}.hover\:bg-cream-100:hover{background-color:var(--color-cream-100)}.hover\:bg-olive-800:hover{background-color:var(--color-olive-800)}.hover\:bg-olive-950:hover{background-color:var(--color-olive-950)}.hover\:bg-olive-950\/30:hover{background-color:#0c0c094d}@supports (color:color-mix(in lab, red, red)){.hover\:bg-olive-950\/30:hover{background-color:color-mix(in oklab, var(--color-olive-950) 30%, transparent)}}.hover\:bg-white\/10:hover{background-color:#ffffff1a}@supports (color:color-mix(in lab, red, red)){.hover\:bg-white\/10:hover{background-color:color-mix(in oklab, var(--color-white) 10%, transparent)}}.hover\:opacity-50:hover{opacity:.5}}.focus\:border-transparent:focus{border-color:#0000}.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-olive-500:focus{--tw-ring-color:var(--color-olive-500)}.focus\:ring-olive-600:focus{--tw-ring-color:var(--color-olive-600)}.focus\:ring-offset-2:focus{--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)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}@media (min-width:40rem){.sm\:mx-0{margin-inline:calc(var(--spacing) * 0)}.sm\:mr-1{margin-right:calc(var(--spacing) * 1)}.sm\:hidden{display:none}.sm\:inline{display:inline}.sm\:inline-flex{display:inline-flex}.sm\:h-6{height:calc(var(--spacing) * 6)}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:gap-16{gap:calc(var(--spacing) * 16)}.sm\:gap-x-16{column-gap:calc(var(--spacing) * 16)}.sm\:rounded-3xl{border-radius:var(--radius-3xl)}.sm\:p-6{padding:calc(var(--spacing) * 6)}.sm\:p-8{padding:calc(var(--spacing) * 8)}.sm\:px-4{padding-inline:calc(var(--spacing) * 4)}.sm\:px-6{padding-inline:calc(var(--spacing) * 6)}.sm\:px-10{padding-inline:calc(var(--spacing) * 10)}.sm\:py-32{padding-block:calc(var(--spacing) * 32)}.sm\:pt-16{padding-top:calc(var(--spacing) * 16)}.sm\:pb-14{padding-bottom:calc(var(--spacing) * 14)}.sm\:pb-20{padding-bottom:calc(var(--spacing) * 20)}.sm\:pl-0{padding-left:calc(var(--spacing) * 0)}.sm\:text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.sm\:text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.sm\:text-5xl{font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--line-height))}}@media (min-width:48rem){.md\:block{display:block}.md\:flex{display:flex}.md\:hidden{display:none}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:64rem){.lg\:mx-0{margin-inline:calc(var(--spacing) * 0)}.lg\:flex{display:flex}.lg\:hidden{display:none}.lg\:inline-flex{display:inline-flex}.lg\:h-64{height:calc(var(--spacing) * 64)}.lg\:max-w-\[300px\]{max-width:300px}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-\[220px_1fr\]{grid-template-columns:220px 1fr}.lg\:items-center{align-items:center}.lg\:justify-start{justify-content:flex-start}.lg\:gap-0{gap:calc(var(--spacing) * 0)}.lg\:gap-x-8{column-gap:calc(var(--spacing) * 8)}.lg\:gap-x-20{column-gap:calc(var(--spacing) * 20)}.lg\:px-8{padding-inline:calc(var(--spacing) * 8)}.lg\:px-12{padding-inline:calc(var(--spacing) * 12)}.lg\:py-16{padding-block:calc(var(--spacing) * 16)}.lg\:py-20{padding-block:calc(var(--spacing) * 20)}.lg\:py-28{padding-block:calc(var(--spacing) * 28)}.lg\:pt-28{padding-top:calc(var(--spacing) * 28)}.lg\:text-left{text-align:left}.lg\:text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.lg\:text-5xl{font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--line-height))}.lg\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}@media (prefers-color-scheme:dark){.dark\:border-dark-700{border-color:var(--color-dark-700)}.dark\:border-red-800{border-color:var(--color-red-800)}.dark\:bg-olive-300{background-color:var(--color-olive-300)}.dark\:bg-olive-950{background-color:var(--color-olive-950)}.dark\:bg-red-900\/20{background-color:#82181a33}@supports (color:color-mix(in lab, red, red)){.dark\:bg-red-900\/20{background-color:color-mix(in oklab, var(--color-red-900) 20%, transparent)}}.dark\:text-olive-100{color:var(--color-olive-100)}.dark\:text-olive-300{color:var(--color-olive-300)}.dark\:text-olive-800{color:var(--color-olive-800)}.dark\:text-red-300{color:var(--color-red-300)}.dark\:text-red-400{color:var(--color-red-400)}}.bg-page{background-color:var(--color-bg)}.bg-surface,.hover\:bg-surface:hover{background-color:var(--color-surface)}.bg-surface-elevated,.hover\:bg-surface-elevated:hover{background-color:var(--color-surface-elevated)}.bg-footer{background-color:var(--color-footer-bg)}.bg-bg{background-color:var(--color-bg)}.text-primary,.hover\:text-primary:hover{color:var(--color-primary)}.text-accent,.hover\:text-accent:hover{color:var(--color-accent)}.border-default{border-color:var(--color-border)}.border-subtle{border-color:var(--color-border-subtle)}.bg-hero{background:linear-gradient(#5c6654,#333a2b)}@media (prefers-color-scheme:dark){.bg-hero{background:linear-gradient(#5c6654,#333a2b)}}.text-hero{color:var(--color-hero-text)}.text-hero-muted{color:var(--color-hero-muted)}.text-hero-accent{color:var(--color-hero-accent)}.bg-grain{border-radius:inherit;pointer-events:none;opacity:.3;mix-blend-mode:overlay;background-position:50%;position:absolute;inset:0}@media (prefers-color-scheme:dark){.bg-grain{opacity:.25}}.bg-grain>*{z-index:1;position:relative}.animate-fade-in{animation:.5s ease-out forwards fadeIn}.animate-slide-up{animation:.5s ease-out forwards slideUp}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}.blinking-cursor{animation:1.3s step-end infinite blink}@keyframes blink{0%,to{opacity:1}50%{opacity:0}}#app-nav.nav-up{transform:translateY(-100%)}}.twitter-tweet-rendered{text-align:center;margin-top:40px;margin-left:auto;margin-right:auto}@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-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-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@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:"";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:"";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:"";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:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@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} \ No newline at end of file diff --git a/spec/controllers/admin_controller_spec.rb b/spec/controllers/admin_controller_spec.rb index 9545ea46..a9305b17 100644 --- a/spec/controllers/admin_controller_spec.rb +++ b/spec/controllers/admin_controller_spec.rb @@ -48,7 +48,8 @@ it 'should show Admin Stats to superusers' do require 'webmock/rspec' WebMock.enable! - + WebMock.disable_net_connect!(allow_localhost: true) + # Stub Mailgun API requests stub_request(:get, /api\.mailgun\.net\/v3\/.+\/stats\/total/) .to_return( @@ -71,8 +72,9 @@ get :stats expect(response.status).to eq 200 expect(response.body).to have_content('Admin Stats') - - WebMock.disable! + ensure + WebMock.reset! + WebMock.allow_net_connect! end end end