diff --git a/Gemfile b/Gemfile
index 0dc8c27..4136965 100755
--- a/Gemfile
+++ b/Gemfile
@@ -12,7 +12,8 @@ gem 'jekyll-redirect-from'
gem 'jekyll-extlinks'
gem 'jekyll-toc'
- group :jekyll_plugins do
- # (other jekyll plugins)
- gem 'jekyll_picture_tag', '~> 2.0'
- end
+group :jekyll_plugins do
+ # (other jekyll plugins)
+ gem 'jekyll_picture_tag', '~> 2.0'
+ gem "jekyll-admin", "~> 0.11.1"
+end
diff --git a/Gemfile.lock b/Gemfile.lock
index e346761..9800b0c 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -36,6 +36,10 @@ GEM
rouge (~> 3.0)
safe_yaml (~> 1.0)
terminal-table (~> 1.8)
+ jekyll-admin (0.11.1)
+ jekyll (>= 3.7, < 5.0)
+ sinatra (>= 1.4)
+ sinatra-contrib (>= 1.4)
jekyll-extlinks (0.0.5)
jekyll (~> 4.0)
nokogiri (~> 1.10.4)
@@ -70,6 +74,8 @@ GEM
mini_portile2 (2.4.0)
minitest (5.14.0)
multi_json (1.14.1)
+ mustermann (3.0.0)
+ ruby2_keywords (~> 0.0.1)
nokogiri (1.10.10)
mini_portile2 (~> 2.4.0)
objective_elements (1.1.2)
@@ -78,6 +84,9 @@ GEM
public_suffix (4.0.4)
pygments.rb (1.2.1)
multi_json (>= 1.0.0)
+ rack (2.2.8)
+ rack-protection (3.1.0)
+ rack (~> 2.2, >= 2.2.4)
rainbow (3.1.1)
rake (13.0.1)
rb-fsevent (0.10.4)
@@ -87,14 +96,27 @@ GEM
rouge (3.18.0)
ruby-vips (2.0.17)
ffi (~> 1.9)
+ ruby2_keywords (0.0.5)
safe_yaml (1.0.5)
sassc (2.3.0)
ffi (~> 1.9)
+ sinatra (3.1.0)
+ mustermann (~> 3.0)
+ rack (~> 2.2, >= 2.2.4)
+ rack-protection (= 3.1.0)
+ tilt (~> 2.0)
+ sinatra-contrib (3.1.0)
+ multi_json
+ mustermann (~> 3.0)
+ rack-protection (= 3.1.0)
+ sinatra (= 3.1.0)
+ tilt (~> 2.0)
stringex (2.8.5)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
thor (1.0.1)
thread_safe (0.3.6)
+ tilt (2.3.0)
tzinfo (1.2.7)
thread_safe (~> 0.1)
unicode-display_width (1.7.0)
@@ -107,6 +129,7 @@ DEPENDENCIES
activesupport
coderay
jekyll
+ jekyll-admin (~> 0.11.1)
jekyll-extlinks
jekyll-redirect-from
jekyll-toc
diff --git a/_includes/seeking_dev_help_magnete.html b/_includes/seeking_dev_help_magnete.html
new file mode 100644
index 0000000..e445c18
--- /dev/null
+++ b/_includes/seeking_dev_help_magnete.html
@@ -0,0 +1,6 @@
+
+ Are you seeking assistance with Ruby on Rails development?
+
+
diff --git a/_layouts/post.html b/_layouts/post.html
index 00f7f43..9cf0de3 100755
--- a/_layouts/post.html
+++ b/_layouts/post.html
@@ -90,12 +90,7 @@
{% if page.headline %}{{ page.headline }}{% else %}{{ pa
{% endfor %}
-
- Are you seeking assistance with Ruby on Rails development?
-
-
+ {% include seeking_dev_help_magnete.html %}
Read also
diff --git a/_posts/2024-01-30-reconcile-app-users-against-stripe-and-prevent-financial-losses.md b/_posts/2024-01-30-reconcile-app-users-against-stripe-and-prevent-financial-losses.md
new file mode 100644
index 0000000..5ca69a2
--- /dev/null
+++ b/_posts/2024-01-30-reconcile-app-users-against-stripe-and-prevent-financial-losses.md
@@ -0,0 +1,342 @@
+---
+title: Reconcile app users vs Stripe and prevent financial losses
+layout: post
+headline: How we reconciled app users with Stripe and prevented financial losses
+modified: '2023-01-30 18:23:20 +0100'
+description: Read the story of how we managed to prevent financial losses within an app for one of our clients.
+tags:
+- stripe
+- sql
+- ruby
+- data-analysis
+featured_post: false
+toc: true
+image: reconcile-stripe.jpg
+---
+
+## Possible discrepancies in Stripe integrations
+
+Stripe integrations often experience data consistency issues, such as users being on different subscription plans in the app compared to Stripe. This misalignment can lead to lost revenue or jeopardize customer success stories.
+
+For example, a customer may have a premium status within the app, while Stripe shows no active subscription. This type of discrepancy can lead to lost revenue for the business. Another potential issue occurs when a customer overpays. In this case, the customer is on the free plan within the app but has an active subscription to the premium plan in Stripe, jeopardizing the customer success story.
+
+## Stripe integration state of our application
+
+This blog post outlines the approach we took to resolve such issues in our app, which had around 80k users, with 10% on the premium plan. We identified instances of both overpayment and underpayment, which could be attributed to manual data manipulation in Stripe, missing webhooks, or bugs in our system.
+
+{% include seeking_dev_help_magnete.html %}
+
+## The plan to reconciliate data with Stripe
+
+While we used Ruby for scripting, this solution is universal and can be applied to applications written in other languages like Python, Node.js, Java, Rust, and Go.
+
+Our plan is the following:
+
+1. Fetch all relevant data from Stripe via Stripe REST API. In our case that included all customer entities and their subscriptions.
+2. Put the fetched data into our database. To avoid polluting the main database schema, use a separate namespace for these tables. In fact, PostgreSQL refers to this namespace concept as `schema`. The default schema is `public`. We create the `stripe` schema and necessary tables inside it.
+3. Analyze the discrepancies using SQL queries. SQL is not only faster and less prone to bugs for this kind of task in terms of data processing but also in development. This means we will obtain results faster with fewer expenses for the business.
+4. Configure Metabase for these reports. Metabase is the system we use to write SQL and build reports. Set up notifications for data discrepancies so that we receive alerts about new cases and can react to them as soon as possible. Luckily, it was already set up for this project. The good news is that its setup takes very little time.
+5. Schedule the data scraper from Step 1 to run automatically every week.
+
+![Shining plan](/images/shining-plan.jpg)
+
+## Stripe data store preparation
+
+First, we need to create the DB schema along with the Stripe tables. This is the SQL script we used for that:
+
+```sql
+create schema stripe;
+create table stripe.customers (
+ id serial not null,
+ stripe_id varchar(250),
+ email varchar(250) not null,
+ created_in_stripe timestamp,
+ description varchar(250),
+ metadata jsonb,
+ deleted boolean,
+ created_at timestamp default current_timestamp,
+ updated_at timestamp default current_timestamp
+);
+create table stripe.subscriptions (
+ id serial not null,
+ stripe_id varchar(250),
+ stripe_customer_id varchar(250),
+ plan_id varchar(250),
+ status varchar(250),
+ created_at timestamp default current_timestamp,
+ updated_at timestamp default current_timestamp
+);
+```
+
+> Inside the Rails app, data migrations could be created for this purpose. However, as we are unsure whether these tables are permanent at the moment, we use SQL and execute it manually on the server.
+
+Our app uses Rails, so it has `ActiveRecord`, and we can point our models to these tables. These are the `ActiveRecord` models we created for our convenience while working with these tables in the Ruby script:
+
+```ruby
+class StripeSchema < ActiveRecord::Base
+ self.abstract_class = true
+ establish_connection :stripe
+end
+
+class StripeCustomer < StripeSchema
+ self.table_name = :customers
+ self.primary_key = :id
+end
+
+class StripeSubscription < StripeSchema
+ self.table_name = :subscriptions
+ self.primary_key = :id
+
+ belongs_to :stripe_customer, foreign_key: :stripe_id
+end
+```
+
+We have a special folder in the app, `app/scripts`, where we put this kind of ad-hoc code. Later, we use Rails runner to execute them on the production server against the real data. They can also be run locally for testing purposes during script development. This script code was put into `app/scripts/stripe_classes.rb` file.
+
+{% include seeking_dev_help_magnete.html %}
+
+## The Stripe data scrapper
+
+And this is the script we've come up with:
+
+```ruby
+starting_after = nil
+
+loop do
+ params = {expand: ['data.subscriptions'], limit: 100}
+ params[:starting_after] = starting_after if starting_after
+
+ customers = Stripe::Customer.list(params)
+
+ customers.each do |cus|
+ ApplicationRecord.transaction do
+ StripeCustomer.create(
+ email: cus["email"],
+ stripe_id: cus["id"],
+ description: cus["description"],
+ created_in_stripe: cus["created"] ? Time.zone.at(cus["created"]) : nil,
+ metadata: cus["metadata"],
+ subscriptions: customer_subscriptions,
+ deleted: cus["deleted"]
+ )
+
+ cus.subscriptions.each do |sub|
+ StripeSubscription.create(
+ stripe_customer_id: cus["id"],
+ stripe_id: sub["id"],
+ plan_id: sub["plan"]["id"],
+ status: sub["status"]
+ )
+ end
+ end
+
+ starting_after = cus["id"]
+ end
+ break if customers.count < 100
+end
+```
+
+This script fetches all Stripe customers along with their subscriptions. Later, using this data, we can compare it against our app's database and identify any deviations.
+
+We run this script on the server with the [rails runner](https://guides.rubyonrails.org/command_line.html#bin-rails-runner). Its run can take a while. Not to get the process killed with a closed SSH connection to the server, we use [screen](https://www.gnu.org/software/screen/) utility. At least for the first time, we have to run it manually and monitor for any failures. If there are any issues, we fix them. This way, we verify that the script is valid and reliable. Later, we can automate it to run on a schedule. We've collected data on 85k customers and 8.5k subscriptions, and it took around 1 hour. Not bad for this amount of data.
+
+![Collected data from Stripe](/images/data-stripe.jpg)
+
+## Run the script automatically
+
+After some preliminary data analysis and verification of its correctness, we can set up this script to run automatically on the server. We use sidekiq and its extension sidekiq-scheduler for this, as it's already in place. The app also has Rollbar configured to monitor exceptions and errors, so if something goes wrong, we can be notified.
+
+This is the job:
+
+```ruby
+class UpdateStripeData
+ include Sidekiq::Worker
+
+ require_relative '../../scripts/stripe_classes'
+
+ def perform
+ drop_old_data
+ record_stripe_data
+ end
+
+ private
+
+ def record_stripe_data
+ starting_after = nil
+
+ loop do
+ params = {expand: ['data.subscriptions'], limit: 100}
+ params[:starting_after] = starting_after if starting_after
+
+ customers = Stripe::Customer.list(params)
+
+ customers.each do |cus|
+ ApplicationRecord.transaction do
+ StripeCustomer.create(
+ email: cus["email"],
+ stripe_id: cus["id"],
+ description: cus["description"],
+ created_in_stripe: cus["created"] ? Time.zone.at(cus["created"]) : nil,
+ metadata: cus["metadata"],
+ subscriptions: customer_subscriptions,
+ deleted: cus["deleted"]
+ )
+
+ cus.subscriptions.each do |sub|
+ StripeSubscription.create(
+ stripe_customer_id: cus["id"],
+ stripe_id: sub["id"],
+ plan_id: sub["plan"]["id"],
+ status: sub["status"]
+ )
+ end
+ end
+
+ starting_after = cus["id"]
+ end
+ break if customers.count < 100
+ end
+ end
+
+ def drop_old_data
+ ActiveRecord::Base.connection.execute(<<~SQL)
+ delete from stripe.customers;
+ delete from stripe.subscriptions;
+ SQL
+ end
+end
+```
+
+And this is the configuration defined in `config/sidekiq_scheduler.yml` to run it every Saturday at 12:00PM in UTC time zone:
+
+```yaml
+production:
+ update_stripe_data:
+ class: UpdateStripeData
+ cron: '0 12 * * 6'
+```
+
+We chose that time as the servers are less loaded during those hours.
+
+{% include seeking_dev_help_magnete.html %}
+
+## Analyze Stripe data discrepancies with SQL
+
+We are all set. With the data in place, we can use SQL to identify all deviations. This will involve using common table expression (CTE), views, joins, filters, and aggregation functions.
+
+Note that the script fetches the Stripe data once a week, and it takes around 1 hour to run. Consequently, the app data will always be ahead of the Stripe data. This is crucial to understand because we cannot join the current app data against the cached Stripe data due to this time lag. Therefore, we need the app data snapshot at the moment the script was run.
+
+Creating a real data snapshot is an option, but it would significantly complicate our architectural story. Fortunately, we have Papertrail configured in the app, a gem that stores all changes to users. This means we can reinstall actual data at the moment the script fetched Stripe data was run. The only field of interest for us is `plan_id`. Therefore, we reinstall only this field. To reuse the reinstalled data, we utilize views. These are kind of virtual tables inside SQL but don't store the collected data:
+
+```sql
+create view stripe.users_with_actual_plan as (
+ with stripe_update as (
+ select created_at as ts from stripe.subscriptions limit 1
+ ),
+ recent_versions as (
+ select * from versions where created_at >= (select ts - interval '1 day' from stripe_update)
+ ),
+ data as (
+ select
+ u.*,
+ coalesce (
+ coalesce(
+ coalesce(
+ (substring((vp.object_changes->>'plan_id') from ', (\d+)'))::int,
+ (substring(vp.object from '\nplan_id: (\d+)'))::int
+ ),
+ coalesce(
+ (substring((vf.object_changes->>'plan_id') from '(\d+),'))::int,
+ (substring(vf.object from '\nplan_id: (\d+)'))::int
+ )
+ ),
+ u.plan_id
+ ) as actual_plan_id,
+ rank() over (partition by u.id order by vp.created_at desc nulls last, vf.created_at asc) as version_rank
+ from users u
+ left join stripe.customers c on c.stripe_id = u.stripe_customer_id
+ left join recent_versions vp on vp.item_id = u.id and vp.created_at < coalesce(c.created_at, (select ts from stripe_update))
+ left join recent_versions vf on vf.item_id = u.id and vf.created_at >= coalesce(c.created_at, (select ts from stripe_update))
+ ) select * from data where version_rank = 1
+);
+ ```
+
+This SQL query might look intimidating, and that's okay. It's not essential for understanding everything here. All you need to know is what it does, and you already have that knowledge. It creates a virtual table of users with the actual `plan_id` that was set just before the script fetched Stripe data.
+
+> One might ask, "How do we end up creating SQL queries that appear so complicated and intimidating?" The answer is simple: through small steps, selecting one field at a time, joining step by step, and eventually combining them into a single query using the CTE construction.
+
+And now, we are ready to join these users with the actual plan data from Stripe.
+
+This time, the SQL looks much easier:
+
+```sql
+with stripe_update as (
+ select created_at ts from stripe.subscriptions limit 1
+)
+select u.* from
+stripe.users_with_actual_plan u
+left join stripe.subscriptions s on s.stripe_customer_id = u.stripe_customer_id
+where u.actual_plan_id is not null and u.actual_plan_id not in (6, 121)
+ and u.created_at < (select ts from stripe_update)
+ and s.id is null
+;
+```
+
+The plan with ID = 6 is the free plan, and 121 is a technical one used only for internal purposes. Therefore, the entire expression `u.actual_plan_id is not null and u.actual_plan_id not in (6, 121)` indicates that the user is on a paid plan.
+
+We inputted this SQL into Metabase, and this is what it looks like:
+
+![SQL inside Metabase](/images/reported-users.png)
+
+> Optionally, we can configure notifications to be sent even when a new record is added to these results. See the bell icon at the bottom right; it's intended for this purpose.
+
+Metabase comes in handy for exporting data into CSV and Excel with just one click. We do that often. That simplifies communication with the business a lot. It's also possible to share the reports right away with the team via a direct link.
+
+As we can see, there were 983 instances of user data discrepancies found. It's a significant amount of data among all active subscriptions that match the app user data, which is 8,488. That represents roughly a 10% margin of error! Too much!
+
+We found the number of subscriptions that match user data using this SQL:
+
+```sql
+with stripe_update as (
+ select created_at ts from stripe.subscriptions limit 1
+)
+select count(u.*) from stripe.users_with_actual_plan u
+ join stripe.subscriptions s on s.stripe_customer_id = u.stripe_customer_id
+ join plans p on p.stripe_price_id = s.plan_id
+ where u.created_at < (select ts from stripe_update)
+;
+```
+
+> See how the created view "users_with_actual_plan" becomes handy here as well. It's a very powerful tool that can save a ton of code and coding time!
+
+Further data analysis shows that 514 of these 983 discrepancies are related to deleted users. It turns out our app employs a so-called soft delete feature, meaning they are not actually deleted but marked as such, preventing them from using the app anymore. Well, now the situation looks much better. It's just a 5% margin of error, not the 10% we initially thought. It's almost within 3% of the standard deviation. Not so bad.
+
+{% include seeking_dev_help_magnete.html %}
+
+## Fixing the data deviations between the app and Stripe
+
+All actions related to fixing data require a thorough understanding of the app at a good level. We can either examine the instances of discrepancies one by one, allowing us to understand what happened to each of them. When we analyze each instance of discrepancy, we check the app database, logs, Papertrail records, Stripe logs, Rollbar, and any other data sources that could help us determine what happened to a certain user.
+
+By simply looking into the app database, we noticed those 514 softly deleted users. This can be easily done by examining the `deleted_at` column in the report. Any Excel-like tool can allow us to filter this information, or we can accomplish this in Metabase.
+
+![Filter by non-null deleted_at column in Metabase](/images/metabase-filter-by-deleted-at.png)
+
+We can move these users to free plan right away by writing a Ruby script that was successfully done.
+
+Now, there are only 469 records with data discrepancies remaining. Randomly going through some of them shows that all of them indeed have data discrepancies. Simultaneously, by delving into the codebase with certain hypotheses about what happened, we identify a serious breach inside the app. The issue stems from the fact that the app uses Sidekiq, which doesn't guarantee the order of incoming webhook processing. Each webhook has its own handler with specific code manipulating user subscription plans, all processed by Sidekiq.
+
+At this point, we decide to address this issue by making slight adjustments to the architecture. From now on, all webhooks will be processed by one handler that consistently checks the actual Stripe subscription state before changing the user's plan within the app. Hence, the multiple webhooks that used to process subscription-related actions will now utilize only one blocking handler, ensuring it cannot run in parallel for several requests for one user.
+
+The specific code for this solution is too app-specific and will be omitted in this post. It's also a topic for another post.
+
+{% include seeking_dev_help_magnete.html %}
+
+After fixing the bug and discussing it with the business owner, we decide to move all users who have not used the app in the last 30 days to the free plan and issue additional invoices for the underpayment for the others. This time, the changes will be made in closer collaboration with the business owner. First, we are going to calculate the underpayments for each user and generate a report. Then, each instance will be reviewed, approved, and fixed through a Ruby ad-hoc script. This is still an ongoing process, but we see the finish line.
+
+After fixing the bug, we have noticed new occurrences of data deviation. No users have reported new instances, and our customer success team is also satisfied. These are our results, and we are pleased with the work done.
+
+## Conclusion
+
+Asynchronous communication between services is a painful point. It can lead to customer dissatisfaction, losses to the business, and increased workload for the customer support team. This post shows how we deal with these kinds of issues. Efficiently solving them requires deep expertise in SQL, the business, tech stack, data analysis, and scripting.
+
+Happy coding and bug-free apps to you, our reader!
diff --git a/_posts/metabase-filter-by-deleted-at.png b/_posts/metabase-filter-by-deleted-at.png
new file mode 100644
index 0000000..c9aca1c
Binary files /dev/null and b/_posts/metabase-filter-by-deleted-at.png differ
diff --git a/_posts/reported-users.png b/_posts/reported-users.png
new file mode 100644
index 0000000..1aea523
Binary files /dev/null and b/_posts/reported-users.png differ
diff --git a/about-author.md b/about-author.md
index 18c8e74..3a4e69f 100755
--- a/about-author.md
+++ b/about-author.md
@@ -12,4 +12,4 @@ I'm Andrei Kaleshka, a Ruby/Rails developer working with the technology since 20
With my extensive Ruby on Rails experience, I can confidently assist you in developing exceptional web applications that exceed your expectations. My dedication to delivering high-quality results ensures your complete satisfaction.
-Want to talk about how we can help you? [Schedule](https://calendly.com/andrei-kaleshka/30min){:ref="nofollow" target="_blank"} a meeting with me today!
+{% include seeking_dev_help_magnete.html %}
diff --git a/assets/css/main.min.css b/assets/css/main.min.css
index 0dcdf00..977529f 100644
--- a/assets/css/main.min.css
+++ b/assets/css/main.min.css
@@ -10,4 +10,4 @@ article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display
*/@font-face{font-family:'Font Awesome 5 Free';font-style:normal;font-weight:900;src:url('../fonts/webfonts/fa-solid-900.eot');src:url('../fonts/webfonts/fa-solid-900.eot?#iefix') format('embedded-opentype'),url('../fonts/webfonts/fa-solid-900.woff2') format('woff2'),url('../fonts/webfonts/fa-solid-900.woff') format('woff'),url('../fonts/webfonts/fa-solid-900.ttf') format('truetype'),url('../fonts/webfonts/fa-solid-900.svg#fontawesome') format('svg');font-display:block}.fa,.fas{font-family:'Font Awesome 5 Free';font-weight:900}/*!
* Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
- */@font-face{font-family:'Font Awesome 5 Free';font-style:normal;font-weight:400;src:url('../fonts/webfonts/fa-regular-400.eot');src:url('../fonts/webfonts/fa-regular-400.eot?#iefix') format('embedded-opentype'),url('../fonts/webfonts/fa-regular-400.woff2') format('woff2'),url('../fonts/webfonts/fa-regular-400.woff') format('woff'),url('../fonts/webfonts/fa-regular-400.ttf') format('truetype'),url('../fonts/webfonts/fa-regular-400.svg#fontawesome') format('svg');font-display:block}.far{font-family:'Font Awesome 5 Free';font-weight:400}form{margin:0 0 5px 0}form fieldset{padding:0;margin-bottom:5px;border-width:0}form legend{display:block;width:100%;padding:0;margin-bottom:10px;*margin-left:-7px;color:#222;white-space:normal;border:0;border-bottom:1px solid rgba(204,204,204,0.84)}form p{margin-bottom:2.5px}form ul{padding:0;margin:0 0 5px 0;list-style-type:none}form br{display:none}label,input,button,select,textarea{vertical-align:baseline;*vertical-align:middle}input,button,select,textarea{font-family:Georgia,Times,"Times New Roman",serif;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}label{display:block;margin-bottom:1.25px;font-weight:bold;color:#222;cursor:pointer}label input,label textarea,label select{display:block}input,textarea,select{display:inline-block;width:100%;padding:4px;margin-bottom:1.25px;color:#222;background-color:#fff;border:1px solid rgba(204,204,204,0.84)}input:hover,textarea:hover,select:hover{border-color:rgba(128,128,128,0.84)}.input-mini{width:60px}.input-small{width:90px}input[type="image"],input[type="checkbox"],input[type="radio"]{width:auto;height:auto;padding:0;margin:3px 0;*margin-top:0;line-height:normal;cursor:pointer;border:0 \9;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}input[type="checkbox"],input[type="radio"]{*width:13px;*height:13px;padding:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}input[type="image"]{border:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}input[type="file"]{width:auto;padding:initial;line-height:initial;background-color:transparent;background-color:initial;border:initial;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}input[type="button"],input[type="reset"],input[type="submit"]{width:auto;height:auto;*overflow:visible;cursor:pointer}select,input[type="file"]{*margin-top:4px}select{width:auto;background-color:#fff}select[multiple],select[size]{height:auto}textarea{height:auto;overflow:auto;vertical-align:top;resize:vertical}input[type="hidden"]{display:none}.radio,.checkbox{padding-left:18px;font-weight:normal}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-18px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;-webkit-opacity:.5;-moz-opacity:.5;opacity:.5}input:focus,textarea:focus{border-color:rgba(0,0,0,0.84);outline:0;outline:thin dotted \9}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus,select:focus{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.help-block,.help-inline{color:rgba(128,128,128,0.84)}.help-block{display:block;margin-bottom:1em;line-height:1em}.help-inline{display:inline-block;padding-left:5px;vertical-align:middle}.form-inline input,.form-inline textarea,.form-inline select{display:inline-block;margin-bottom:0}.form-inline label{display:inline-block}.form-inline .radio,.form-inline .checkbox,.form-inline .radio{padding-left:0;margin-bottom:0;vertical-align:middle}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}.dosearch{display:block;padding:6px 10px;color:#fff;cursor:pointer;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;transform:translateY(-2px)}.dosearch:hover{background-color:rgba(26,26,26,0.84);-webkit-box-shadow:inset 0 0 1px #fff;-moz-box-shadow:inset 0 0 1px #fff;box-shadow:inset 0 0 1px #fff}.feed{transform:translateY(-2px)}.search-form{position:relative;top:0;left:-200px;z-index:9002;width:100%;opacity:0;transition:all 200ms 100ms cubic-bezier(0,0.6,0.4,1)}.search-form .search-field{width:100%;font-family:"Lucida Grande",Arial,sans-serif;font-size:32px;font-size:2rem;line-height:36px;color:#fff;background-color:transparent;border:0;border-bottom:1px solid #fff;border-radius:0;box-shadow:none;background-clip:padding-box;-webkit-appearance:none}.search-form .search-field:focus{outline:0;box-shadow:none}.search-form.active{top:0;left:0;opacity:1}.search-form.hidden{display:none}.search-form ::-webkit-input-placeholder{font-size:32px;font-size:2rem}.search-form .fa-times-circle{position:absolute;top:.4rem;right:1rem;z-index:1;display:block;margin-bottom:2px;color:#fff;text-align:center;cursor:pointer}.search-form .search-field::-webkit-search-decoration,.search-form .search-field::-webkit-search-cancel-button,.search-form .search-field::-webkit-search-results-button,.search-form .search-field::-webkit-search-results-decoration{display:none}.search-form .post-list{position:absolute;width:100%}.search-form .post-list h4,.search-form .post-list li,.search-form .post-list p,.search-form .post-list a{color:#fff}.search-form .post-list li{line-height:30px;border-bottom:1px solid #fff}body.search-overlay{overflow:hidden}body.search-overlay:after{position:absolute;top:0;left:0;z-index:9001;width:100%;height:100%;min-height:100%;background-color:#2a79c9;background-color:rgba(38,108,180,0.95);content:''}.no-js .dosearch{display:none}body{width:100%;padding:0;margin:0;background-color:#fff;border-top:3px solid #266cb4}p{margin-top:1em;margin-bottom:-0.46em;font-size:21px;line-height:32px;letter-spacing:-0.003em}.navigation-wrapper{text-align:center;*zoom:1}.navigation-wrapper:before,.navigation-wrapper:after{display:table;line-height:0;content:""}.navigation-wrapper:after{clear:both}.navigation-wrapper ul{display:flex;padding:4px 20px;margin:0 0 5px;vertical-align:top;background-color:#266cb4;-webkit-border-radius:0 0 10px 10px;-moz-border-radius:0 0 10px 10px;border-radius:0 0 10px 10px;*zoom:1;justify-content:center}.navigation-wrapper ul:before,.navigation-wrapper ul:after{display:table;line-height:0;content:""}.navigation-wrapper ul:after{clear:both}@media only screen and (max-width:727px){.navigation-wrapper ul{display:block}}.navigation-wrapper li{display:block;float:left;font-family:"Lucida Grande",Arial,sans-serif;font-size:15px;font-size:.9375rem;color:#fff;text-align:center;text-transform:uppercase;list-style:none}.navigation-wrapper li a:hover{-webkit-box-shadow:inset 0 0 1px #fff;-moz-box-shadow:inset 0 0 1px #fff;box-shadow:inset 0 0 1px #fff}.navigation-wrapper a{display:block;padding:6px 10px;color:#fff;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.navigation-wrapper a:hover{background-color:#3885d5}#site-nav{z-index:9000;display:none}@media only screen and (min-width:830px){#site-nav{-webkit-animation-duration:1s;-moz-animation-duration:1s;-o-animation-duration:1s;animation-duration:1s}}@media only screen and (min-width:830px){#site-nav.closed{display:block}}#site-nav.opened{display:block;max-height:100%}#site-nav.opened li{float:none}@media only screen and (min-width:830px){#site-nav.opened li{float:left}}.no-js #site-nav{display:block}#nav-toggle{z-index:9999;display:block;padding:5px 20px;margin:0;font-family:"Lucida Grande",Arial,sans-serif;font-size:14px;font-size:.875rem;text-transform:capitalize;vertical-align:top;background-color:#266cb4;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}@media only screen and (min-width:830px){#nav-toggle{display:none}}.masthead{margin-top:40px;*zoom:1}.masthead:before,.masthead:after{display:table;line-height:0;content:""}.masthead:after{clear:both}@media only screen and (max-width:727px){.masthead{margin-top:0}}.masthead .wrap{width:100%;max-width:690px;margin-right:auto;margin-left:auto}@media only screen and (min-width:728px){.masthead .wrap{float:left}}.site-title{margin-bottom:0;-webkit-animation-delay:.75s;-moz-animation-delay:.75s;-o-animation-delay:.75s;animation-delay:.75s;-webkit-animation-duration:1s;-moz-animation-duration:1s;-o-animation-duration:1s;animation-duration:1s}.site-title a{color:rgba(0,0,0,0.84)}.site-description{margin-top:0;font-family:Georgia,Times,"Times New Roman",serif;font-size:16px;font-size:1rem;font-style:italic;font-weight:400;-webkit-animation-delay:1s;-moz-animation-delay:1s;-o-animation-delay:1s;animation-delay:1s;-webkit-animation-duration:1s;-moz-animation-duration:1s;-o-animation-duration:1s;animation-duration:1s}@media only screen and (max-width:727px){.site-description{font-size:20px;font-size:1.25rem}}#main{*zoom:1}#main:before,#main:after{display:table;line-height:0;content:""}#main:after{clear:both}.display-flex{display:flex}.flex-self{margin-bottom:-3px;align-self:flex-end}@media only screen and (max-width:727px){.flex-self{margin-bottom:30px;align-self:unset}}.entry,.hentry{border-bottom:2px solid #266cb4;*zoom:1}.entry:before,.hentry:before,.entry:after,.hentry:after{display:table;line-height:0;content:""}.entry:after,.hentry:after{clear:both}.entry-feature-image{width:100%;margin:20px 0 0}@media only screen and (max-width:727px){.entry-feature-image{margin-top:-75px}}@media only screen and (min-width:728px){.entry-feature-image{margin-top:-145px}}.entry-header{width:100%;max-width:690px;margin-right:auto;margin-left:auto}@media only screen and (min-width:728px){.entry-header{max-width:100%;margin-right:0;margin-left:0}}.entry-running{display:flex;margin-bottom:25px;justify-content:space-between}@media only screen and (max-width:727px){.entry-running{flex-direction:column-reverse}}.entry-tags{display:flex;display:block;margin-top:4em;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;font-size:11px;font-size:.6875rem;font-weight:400;flex-wrap:wrap}.entry-tags a{padding:5px 10px;margin-right:5px;line-height:22px;color:rgba(0,0,0,0.54);background-color:rgba(0,0,0,0.05);border-radius:3px}.entry-tags a:hover{color:#fff;background-color:rgba(0,0,0,0.84)}span+.entry-title{margin-top:0}.entry-title{margin-bottom:35px;font-family:Georgia,Times,"Times New Roman",serif;font-size:3rem;font-weight:400;line-height:53px;letter-spacing:.5px}.entry-title a{color:rgba(0,0,0,0.84);text-decoration:underline}@media only screen and (max-width:727px){.entry-title{max-width:600px;font-size:24px;font-size:1.5rem;font-size:1.7rem;line-height:33px}}.entry-wrapper{padding-right:20px;padding-left:20px;margin:0 auto 3em;*zoom:1}.entry-wrapper:before,.entry-wrapper:after{display:table;line-height:0;content:""}.entry-wrapper:after{clear:both}@media only screen and (max-width:727px){.entry-wrapper{padding:0;margin:0 15px}}@media only screen and (min-width:728px){.entry-wrapper{max-width:690px}}@media only screen and (min-width:1200px){.entry-wrapper{max-width:1000px}}.entry-meta{display:block;width:100%;max-width:690px;margin-right:auto;margin-bottom:30px;margin-left:auto;font-size:14px;font-size:.875rem;text-transform:uppercase}.entry-meta a{color:#222}@media only screen and (min-width:728px){.entry-meta{float:left;width:160px;padding:0;margin:0 40px 40px 0}}.entry-meta>span{display:inline-block;padding:0 20px 10px 0}@media only screen and (min-width:728px){.entry-meta>span{display:block;padding:8px 0;border-bottom:1px solid rgba(204,204,204,0.84);border-bottom:1px solid rgba(0,0,0,0.1)}}.author-data{margin:-2px 0 0 15px}.author-data *{line-height:20px}.author-photo{width:60px;height:60px;border-radius:50%}.entry-content{width:100%;max-width:690px;margin-right:auto;margin-left:auto}@media only screen and (min-width:728px){.entry-content{float:left}}@media only screen and (min-width:1200px){.entry-content{max-width:1000px}}.entry-content li{margin-left:-15px;font-size:21px;line-height:32px;letter-spacing:-0.003em}.entry-content p>a,.entry-content li>a{border-bottom:1px dotted #808080}.entry-content p>a:hover,.entry-content li>a:hover{border-bottom-style:solid}.entry-content h2{margin-top:25px;margin-bottom:-10px;font-size:1.9em;font-weight:bold}.entry-content h3{margin-top:25px;margin-bottom:-10px;font-size:1.6em;font-weight:bold}.entry-content h4{margin:30px 0 -5px;font-size:1.5em;font-weight:bold}@media only screen and (max-width:727px){.entry-content li{margin-left:-20px;font-size:18px}.entry-content h1{margin-bottom:25px}.entry-content h2{font-weight:500}.entry-content h2.recent-posts{font-size:23px}.entry-content h3{font-size:1.7em}.entry-content h4{margin:25px 0 -10px}.entry-content p{margin-top:1.3em;font-size:18px;line-height:30px}}li.remove-li-margin{margin-left:0}@media only screen and (max-width:727px){li.remove-li-margin{margin-left:0}}.fn{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;font-size:14px;letter-spacing:.02em}.fn:hover{text-decoration:underline}#disqus_thread{margin-top:2em}.pagination{text-align:center}#home .entry-title,#page .entry-title{max-width:100%}@media only screen and (min-width:728px){#home .entry-content,#page .entry-content{float:none}}h2.slogan{margin-top:-1.05em;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;font-size:1.6em}@media only screen and (max-width:727px){h2.slogan{font-size:1.3em}}.entry-title.home-page{margin-bottom:48px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;font-size:3rem}@media only screen and (max-width:727px){.entry-title.home-page{margin-top:20px;margin-bottom:36px;font-size:2.3em;line-height:1em}}.entry-tags.static-tags{margin:0 0 44px}@media only screen and (max-width:727px){.entry-tags.static-tags{margin:0 0 33px}}.post-list{padding:0;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;list-style-type:none}.post-list li{border-bottom:1px solid rgba(204,204,204,0.84);border-bottom:1px solid rgba(0,0,0,0.1);*zoom:1}.post-list li:before,.post-list li:after{display:table;line-height:0;content:""}.post-list li:after{clear:both}.post-list li>a{border-bottom-width:0}.post-list li.main-list{position:relative;margin:12px 0;border:1px solid #d9d9d9}.post-list li.main-list:hover{bottom:.25rem;box-shadow:-0.25rem .25rem .625rem 0 rgba(0,0,0,0.2);transition-duration:.4s}@media only screen and (max-width:727px){.post-list li.main-list{margin:8px 0}}.post-list li.main-list.featured-post{margin:40px 0;background-color:#63ffc7}@media only screen and (max-width:727px){.post-list li.main-list.featured-post{margin:25px 0}}.post-list li.articles-index{margin-left:0}.post-list h2{margin:5px 0}.post-list p{margin:0;font-size:18px;line-height:23px}.post-list a>span{float:right}.post-list .preview{min-height:80px;padding-right:10px;padding-left:10px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif}.post-list .preview h2{font-size:1.2em!important}.post-list .display-flex{padding-right:10px;padding-bottom:10px;padding-left:10px;margin-top:20px;justify-content:space-between}.post-list .entry-tags{display:flex;margin-top:0}.post-list .entry-date{font-size:14px;font-size:.875rem;text-transform:capitalize;white-space:nowrap}@media only screen and (max-width:727px){.post-list .entry-date{display:inline}}.entry-date time{font-family:"Lucida Grande",Arial,sans-serif;font-size:14px;letter-spacing:.02em;color:rgba(0,0,0,0.54)}.tag-box{padding:4px 0;margin:0;overflow:hidden;list-style:none;*zoom:1}.tag-box:before,.tag-box:after{display:table;line-height:0;content:""}.tag-box:after{clear:both}.tag-box.inline li{float:left;font-size:14px;font-size:.875rem;line-height:2.5}.tag-box a{padding:4px 6px;margin:2px;text-decoration:none;background-color:rgba(230,230,230,0.84);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.tag-box a span{font-size:10px;font-size:.625rem;vertical-align:super}.search-wrapper{position:absolute;top:50px;display:none;width:90%;padding-right:5%;padding-left:5%;*zoom:1}.search-wrapper:before,.search-wrapper:after{display:table;line-height:0;content:""}.search-wrapper:after{clear:both}@media only screen and (max-width:727px){.search-wrapper{top:100px}}.footer-wrapper{margin:2em auto;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;font-size:14px;font-size:.875rem;*zoom:1}.footer-wrapper:before,.footer-wrapper:after{display:table;line-height:0;content:""}.footer-wrapper:after{clear:both}.footer-wrapper .display-flex{max-width:670px;margin:0 auto;justify-content:space-between}@media only screen and (max-width:727px){.footer-wrapper .display-flex{margin:0 15px}}.social-icons,.social-share,.social-author{color:rgba(0,0,0,0.84)}.social-icons a,.social-share a,.social-author a{color:rgba(0,0,0,0.84)}.social-icons a:hover,.social-share a:hover,.social-author a:hover{color:#000}.social-icons a:visited,.social-share a:visited,.social-author a:visited{color:rgba(0,0,0,0.84)}.social-author{margin:0 2px;font-size:1.1em}.social-author:first-child{margin-left:0}.social-author:last-child{margin-right:0}.social-share{margin:0 3px;font-size:1.6em}.social-icons{font-size:1.2em;white-space:nowrap;transform:translateY(-3px)}.social-icons a{padding-left:8px}.share-word{position:relative;bottom:1.5px;left:5px;font-family:"Lucida Grande Bold",Arial,sans-serif;font-size:16px;letter-spacing:.02em;color:rgba(0,0,0,0.4);text-transform:uppercase;vertical-align:text-top}.first{font-size:1.6em;color:rgba(0,0,0,0.4)}.upgrade{padding:10px;text-align:center}#goog-fixurl ul{padding-left:0;margin-left:0;list-style:none}#goog-fixurl ul li{list-style-type:none}#goog-wm-qt{width:auto;margin-right:10px}#goog-wm-sb{display:inline-block;padding:8px 20px;color:#fff;background-color:rgba(0,0,0,0.84);border:2px solid rgba(0,0,0,0.84)!important;-webkit-border-radius:20px;-moz-border-radius:20px;border-radius:20px}#goog-wm-sb:visited{color:#fff}#goog-wm-sb:hover{color:rgba(0,0,0,0.84);background-color:#fff}.ad-vertical{display:none;margin-top:10px}@media only screen and (min-width:728px){.ad-vertical{display:block}}@media only screen and (max-width:727px){.ad-horizontal{max-width:600px}}@media only screen and (min-width:728px){.ad-horizontal{max-width:800px}}.widefix-ad{margin-bottom:0!important;font-family:BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;text-transform:uppercase}.widefix-ad h2{font-size:32px}.widefix-ad a{color:#266cb4!important;background-color:white}.widefix-ad a:hover{color:black!important}.schedule-button{display:inline-block;width:30%;height:52px;padding:0 24px;font:500 18px/28px Inter;line-height:52px;color:#fff!important;text-align:center;text-decoration:none;-webkit-text-size-adjust:100%;background-color:#f04338;border:0;border-radius:100px;transition:background-color .3s;flex-direction:row;align-items:flex-start}@media only screen and (max-width:727px){.schedule-button{width:70%}}.schedule-button:hover{background-color:#e53b30}
\ No newline at end of file
+ */@font-face{font-family:'Font Awesome 5 Free';font-style:normal;font-weight:400;src:url('../fonts/webfonts/fa-regular-400.eot');src:url('../fonts/webfonts/fa-regular-400.eot?#iefix') format('embedded-opentype'),url('../fonts/webfonts/fa-regular-400.woff2') format('woff2'),url('../fonts/webfonts/fa-regular-400.woff') format('woff'),url('../fonts/webfonts/fa-regular-400.ttf') format('truetype'),url('../fonts/webfonts/fa-regular-400.svg#fontawesome') format('svg');font-display:block}.far{font-family:'Font Awesome 5 Free';font-weight:400}form{margin:0 0 5px 0}form fieldset{padding:0;margin-bottom:5px;border-width:0}form legend{display:block;width:100%;padding:0;margin-bottom:10px;*margin-left:-7px;color:#222;white-space:normal;border:0;border-bottom:1px solid rgba(204,204,204,0.84)}form p{margin-bottom:2.5px}form ul{padding:0;margin:0 0 5px 0;list-style-type:none}form br{display:none}label,input,button,select,textarea{vertical-align:baseline;*vertical-align:middle}input,button,select,textarea{font-family:Georgia,Times,"Times New Roman",serif;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}label{display:block;margin-bottom:1.25px;font-weight:bold;color:#222;cursor:pointer}label input,label textarea,label select{display:block}input,textarea,select{display:inline-block;width:100%;padding:4px;margin-bottom:1.25px;color:#222;background-color:#fff;border:1px solid rgba(204,204,204,0.84)}input:hover,textarea:hover,select:hover{border-color:rgba(128,128,128,0.84)}.input-mini{width:60px}.input-small{width:90px}input[type="image"],input[type="checkbox"],input[type="radio"]{width:auto;height:auto;padding:0;margin:3px 0;*margin-top:0;line-height:normal;cursor:pointer;border:0 \9;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}input[type="checkbox"],input[type="radio"]{*width:13px;*height:13px;padding:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}input[type="image"]{border:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}input[type="file"]{width:auto;padding:initial;line-height:initial;background-color:transparent;background-color:initial;border:initial;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}input[type="button"],input[type="reset"],input[type="submit"]{width:auto;height:auto;*overflow:visible;cursor:pointer}select,input[type="file"]{*margin-top:4px}select{width:auto;background-color:#fff}select[multiple],select[size]{height:auto}textarea{height:auto;overflow:auto;vertical-align:top;resize:vertical}input[type="hidden"]{display:none}.radio,.checkbox{padding-left:18px;font-weight:normal}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-18px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;-webkit-opacity:.5;-moz-opacity:.5;opacity:.5}input:focus,textarea:focus{border-color:rgba(0,0,0,0.84);outline:0;outline:thin dotted \9}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus,select:focus{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.help-block,.help-inline{color:rgba(128,128,128,0.84)}.help-block{display:block;margin-bottom:1em;line-height:1em}.help-inline{display:inline-block;padding-left:5px;vertical-align:middle}.form-inline input,.form-inline textarea,.form-inline select{display:inline-block;margin-bottom:0}.form-inline label{display:inline-block}.form-inline .radio,.form-inline .checkbox,.form-inline .radio{padding-left:0;margin-bottom:0;vertical-align:middle}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}.dosearch{display:block;padding:6px 10px;color:#fff;cursor:pointer;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;transform:translateY(-2px)}.dosearch:hover{background-color:rgba(26,26,26,0.84);-webkit-box-shadow:inset 0 0 1px #fff;-moz-box-shadow:inset 0 0 1px #fff;box-shadow:inset 0 0 1px #fff}.feed{transform:translateY(-2px)}.search-form{position:relative;top:0;left:-200px;z-index:9002;width:100%;opacity:0;transition:all 200ms 100ms cubic-bezier(0,0.6,0.4,1)}.search-form .search-field{width:100%;font-family:"Lucida Grande",Arial,sans-serif;font-size:32px;font-size:2rem;line-height:36px;color:#fff;background-color:transparent;border:0;border-bottom:1px solid #fff;border-radius:0;box-shadow:none;background-clip:padding-box;-webkit-appearance:none}.search-form .search-field:focus{outline:0;box-shadow:none}.search-form.active{top:0;left:0;opacity:1}.search-form.hidden{display:none}.search-form ::-webkit-input-placeholder{font-size:32px;font-size:2rem}.search-form .fa-times-circle{position:absolute;top:.4rem;right:1rem;z-index:1;display:block;margin-bottom:2px;color:#fff;text-align:center;cursor:pointer}.search-form .search-field::-webkit-search-decoration,.search-form .search-field::-webkit-search-cancel-button,.search-form .search-field::-webkit-search-results-button,.search-form .search-field::-webkit-search-results-decoration{display:none}.search-form .post-list{position:absolute;width:100%}.search-form .post-list h4,.search-form .post-list li,.search-form .post-list p,.search-form .post-list a{color:#fff}.search-form .post-list li{line-height:30px;border-bottom:1px solid #fff}body.search-overlay{overflow:hidden}body.search-overlay:after{position:absolute;top:0;left:0;z-index:9001;width:100%;height:100%;min-height:100%;background-color:#2a79c9;background-color:rgba(38,108,180,0.95);content:''}.no-js .dosearch{display:none}body{width:100%;padding:0;margin:0;background-color:#fff;border-top:3px solid #266cb4}p{margin-top:1em;margin-bottom:-0.46em;font-size:21px;line-height:32px;letter-spacing:-0.003em}.navigation-wrapper{text-align:center;*zoom:1}.navigation-wrapper:before,.navigation-wrapper:after{display:table;line-height:0;content:""}.navigation-wrapper:after{clear:both}.navigation-wrapper ul{display:flex;padding:4px 20px;margin:0 0 5px;vertical-align:top;background-color:#266cb4;-webkit-border-radius:0 0 10px 10px;-moz-border-radius:0 0 10px 10px;border-radius:0 0 10px 10px;*zoom:1;justify-content:center}.navigation-wrapper ul:before,.navigation-wrapper ul:after{display:table;line-height:0;content:""}.navigation-wrapper ul:after{clear:both}@media only screen and (max-width:727px){.navigation-wrapper ul{display:block}}.navigation-wrapper li{display:block;float:left;font-family:"Lucida Grande",Arial,sans-serif;font-size:15px;font-size:.9375rem;color:#fff;text-align:center;text-transform:uppercase;list-style:none}.navigation-wrapper li a:hover{-webkit-box-shadow:inset 0 0 1px #fff;-moz-box-shadow:inset 0 0 1px #fff;box-shadow:inset 0 0 1px #fff}.navigation-wrapper a{display:block;padding:6px 10px;color:#fff;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.navigation-wrapper a:hover{background-color:#3885d5}#site-nav{z-index:9000;display:none}@media only screen and (min-width:830px){#site-nav{-webkit-animation-duration:1s;-moz-animation-duration:1s;-o-animation-duration:1s;animation-duration:1s}}@media only screen and (min-width:830px){#site-nav.closed{display:block}}#site-nav.opened{display:block;max-height:100%}#site-nav.opened li{float:none}@media only screen and (min-width:830px){#site-nav.opened li{float:left}}.no-js #site-nav{display:block}#nav-toggle{z-index:9999;display:block;padding:5px 20px;margin:0;font-family:"Lucida Grande",Arial,sans-serif;font-size:14px;font-size:.875rem;text-transform:capitalize;vertical-align:top;background-color:#266cb4;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}@media only screen and (min-width:830px){#nav-toggle{display:none}}.masthead{margin-top:40px;*zoom:1}.masthead:before,.masthead:after{display:table;line-height:0;content:""}.masthead:after{clear:both}@media only screen and (max-width:727px){.masthead{margin-top:0}}.masthead .wrap{width:100%;max-width:690px;margin-right:auto;margin-left:auto}@media only screen and (min-width:728px){.masthead .wrap{float:left}}.site-title{margin-bottom:0;-webkit-animation-delay:.75s;-moz-animation-delay:.75s;-o-animation-delay:.75s;animation-delay:.75s;-webkit-animation-duration:1s;-moz-animation-duration:1s;-o-animation-duration:1s;animation-duration:1s}.site-title a{color:rgba(0,0,0,0.84)}.site-description{margin-top:0;font-family:Georgia,Times,"Times New Roman",serif;font-size:16px;font-size:1rem;font-style:italic;font-weight:400;-webkit-animation-delay:1s;-moz-animation-delay:1s;-o-animation-delay:1s;animation-delay:1s;-webkit-animation-duration:1s;-moz-animation-duration:1s;-o-animation-duration:1s;animation-duration:1s}@media only screen and (max-width:727px){.site-description{font-size:20px;font-size:1.25rem}}#main{*zoom:1}#main:before,#main:after{display:table;line-height:0;content:""}#main:after{clear:both}.display-flex{display:flex}.flex-self{margin-bottom:-3px;align-self:flex-end}@media only screen and (max-width:727px){.flex-self{margin-bottom:30px;align-self:unset}}.entry,.hentry{border-bottom:2px solid #266cb4;*zoom:1}.entry:before,.hentry:before,.entry:after,.hentry:after{display:table;line-height:0;content:""}.entry:after,.hentry:after{clear:both}.entry-feature-image{width:100%;margin:20px 0 0}@media only screen and (max-width:727px){.entry-feature-image{margin-top:-75px}}@media only screen and (min-width:728px){.entry-feature-image{margin-top:-145px}}.entry-header{width:100%;max-width:690px;margin-right:auto;margin-left:auto}@media only screen and (min-width:728px){.entry-header{max-width:100%;margin-right:0;margin-left:0}}.entry-running{display:flex;margin-bottom:25px;justify-content:space-between}@media only screen and (max-width:727px){.entry-running{flex-direction:column-reverse}}.entry-tags{display:flex;display:block;margin-top:4em;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;font-size:11px;font-size:.6875rem;font-weight:400;flex-wrap:wrap}.entry-tags a{padding:5px 10px;margin-right:5px;line-height:22px;color:rgba(0,0,0,0.54);background-color:rgba(0,0,0,0.05);border-radius:3px}.entry-tags a:hover{color:#fff;background-color:rgba(0,0,0,0.84)}span+.entry-title{margin-top:0}.entry-title{margin-bottom:35px;font-family:Georgia,Times,"Times New Roman",serif;font-size:3rem;font-weight:400;line-height:53px;letter-spacing:.5px}.entry-title a{color:rgba(0,0,0,0.84);text-decoration:underline}@media only screen and (max-width:727px){.entry-title{max-width:600px;font-size:24px;font-size:1.5rem;font-size:1.7rem;line-height:33px}}.entry-wrapper{padding-right:20px;padding-left:20px;margin:0 auto 3em;*zoom:1}.entry-wrapper:before,.entry-wrapper:after{display:table;line-height:0;content:""}.entry-wrapper:after{clear:both}@media only screen and (max-width:727px){.entry-wrapper{padding:0;margin:0 15px}}@media only screen and (min-width:728px){.entry-wrapper{max-width:690px}}@media only screen and (min-width:1200px){.entry-wrapper{max-width:1000px}}.entry-meta{display:block;width:100%;max-width:690px;margin-right:auto;margin-bottom:30px;margin-left:auto;font-size:14px;font-size:.875rem;text-transform:uppercase}.entry-meta a{color:#222}@media only screen and (min-width:728px){.entry-meta{float:left;width:160px;padding:0;margin:0 40px 40px 0}}.entry-meta>span{display:inline-block;padding:0 20px 10px 0}@media only screen and (min-width:728px){.entry-meta>span{display:block;padding:8px 0;border-bottom:1px solid rgba(204,204,204,0.84);border-bottom:1px solid rgba(0,0,0,0.1)}}.author-data{margin:-2px 0 0 15px}.author-data *{line-height:20px}.author-photo{width:60px;height:60px;border-radius:50%}.entry-content{width:100%;max-width:690px;margin-right:auto;margin-left:auto}@media only screen and (min-width:728px){.entry-content{float:left}}@media only screen and (min-width:1200px){.entry-content{max-width:1000px}}.entry-content li{margin-left:-15px;font-size:21px;line-height:32px;letter-spacing:-0.003em}.entry-content p>a,.entry-content li>a{border-bottom:1px dotted #808080}.entry-content p>a:hover,.entry-content li>a:hover{border-bottom-style:solid}.entry-content h2{margin-top:25px;margin-bottom:-10px;font-size:1.9em;font-weight:bold}.entry-content h3{margin-top:25px;margin-bottom:-10px;font-size:1.6em;font-weight:bold}.entry-content h4{margin:30px 0 -5px;font-size:1.5em;font-weight:bold}@media only screen and (max-width:727px){.entry-content li{margin-left:-20px;font-size:18px}.entry-content h1{margin-bottom:25px}.entry-content h2{font-weight:500}.entry-content h2.recent-posts{font-size:23px}.entry-content h3{font-size:1.7em}.entry-content h4{margin:25px 0 -10px}.entry-content p{margin-top:1.3em;font-size:18px;line-height:30px}}li.remove-li-margin{margin-left:0}@media only screen and (max-width:727px){li.remove-li-margin{margin-left:0}}.fn{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;font-size:14px;letter-spacing:.02em}.fn:hover{text-decoration:underline}#disqus_thread{margin-top:2em}.pagination{text-align:center}#home .entry-title,#page .entry-title{max-width:100%}@media only screen and (min-width:728px){#home .entry-content,#page .entry-content{float:none}}h2.slogan{margin-top:-1.05em;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;font-size:1.6em}@media only screen and (max-width:727px){h2.slogan{font-size:1.3em}}.entry-title.home-page{margin-bottom:48px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;font-size:3rem}@media only screen and (max-width:727px){.entry-title.home-page{margin-top:20px;margin-bottom:36px;font-size:2.3em;line-height:1em}}.entry-tags.static-tags{margin:0 0 44px}@media only screen and (max-width:727px){.entry-tags.static-tags{margin:0 0 33px}}.post-list{padding:0;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;list-style-type:none}.post-list li{border-bottom:1px solid rgba(204,204,204,0.84);border-bottom:1px solid rgba(0,0,0,0.1);*zoom:1}.post-list li:before,.post-list li:after{display:table;line-height:0;content:""}.post-list li:after{clear:both}.post-list li>a{border-bottom-width:0}.post-list li.main-list{position:relative;margin:12px 0;border:1px solid #d9d9d9}.post-list li.main-list:hover{bottom:.25rem;box-shadow:-0.25rem .25rem .625rem 0 rgba(0,0,0,0.2);transition-duration:.4s}@media only screen and (max-width:727px){.post-list li.main-list{margin:8px 0}}.post-list li.main-list.featured-post{margin:40px 0;background-color:#63ffc7}@media only screen and (max-width:727px){.post-list li.main-list.featured-post{margin:25px 0}}.post-list li.articles-index{margin-left:0}.post-list h2{margin:5px 0}.post-list p{margin:0;font-size:18px;line-height:23px}.post-list a>span{float:right}.post-list .preview{min-height:80px;padding-right:10px;padding-left:10px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif}.post-list .preview h2{font-size:1.2em!important}.post-list .display-flex{padding-right:10px;padding-bottom:10px;padding-left:10px;margin-top:20px;justify-content:space-between}.post-list .entry-tags{display:flex;margin-top:0}.post-list .entry-date{font-size:14px;font-size:.875rem;text-transform:capitalize;white-space:nowrap}@media only screen and (max-width:727px){.post-list .entry-date{display:inline}}.entry-date time{font-family:"Lucida Grande",Arial,sans-serif;font-size:14px;letter-spacing:.02em;color:rgba(0,0,0,0.54)}.tag-box{padding:4px 0;margin:0;overflow:hidden;list-style:none;*zoom:1}.tag-box:before,.tag-box:after{display:table;line-height:0;content:""}.tag-box:after{clear:both}.tag-box.inline li{float:left;font-size:14px;font-size:.875rem;line-height:2.5}.tag-box a{padding:4px 6px;margin:2px;text-decoration:none;background-color:rgba(230,230,230,0.84);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.tag-box a span{font-size:10px;font-size:.625rem;vertical-align:super}.search-wrapper{position:absolute;top:50px;display:none;width:90%;padding-right:5%;padding-left:5%;*zoom:1}.search-wrapper:before,.search-wrapper:after{display:table;line-height:0;content:""}.search-wrapper:after{clear:both}@media only screen and (max-width:727px){.search-wrapper{top:100px}}.footer-wrapper{margin:2em auto;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;font-size:14px;font-size:.875rem;*zoom:1}.footer-wrapper:before,.footer-wrapper:after{display:table;line-height:0;content:""}.footer-wrapper:after{clear:both}.footer-wrapper .display-flex{max-width:670px;margin:0 auto;justify-content:space-between}@media only screen and (max-width:727px){.footer-wrapper .display-flex{margin:0 15px}}.social-icons,.social-share,.social-author{color:rgba(0,0,0,0.84)}.social-icons a,.social-share a,.social-author a{color:rgba(0,0,0,0.84)}.social-icons a:hover,.social-share a:hover,.social-author a:hover{color:#000}.social-icons a:visited,.social-share a:visited,.social-author a:visited{color:rgba(0,0,0,0.84)}.social-author{margin:0 2px;font-size:1.1em}.social-author:first-child{margin-left:0}.social-author:last-child{margin-right:0}.social-share{margin:0 3px;font-size:1.6em}.social-icons{font-size:1.2em;white-space:nowrap;transform:translateY(-3px)}.social-icons a{padding-left:8px}.share-word{position:relative;bottom:1.5px;left:5px;font-family:"Lucida Grande Bold",Arial,sans-serif;font-size:16px;letter-spacing:.02em;color:rgba(0,0,0,0.4);text-transform:uppercase;vertical-align:text-top}.first{font-size:1.6em;color:rgba(0,0,0,0.4)}.upgrade{padding:10px;text-align:center}#goog-fixurl ul{padding-left:0;margin-left:0;list-style:none}#goog-fixurl ul li{list-style-type:none}#goog-wm-qt{width:auto;margin-right:10px}#goog-wm-sb{display:inline-block;padding:8px 20px;color:#fff;background-color:rgba(0,0,0,0.84);border:2px solid rgba(0,0,0,0.84)!important;-webkit-border-radius:20px;-moz-border-radius:20px;border-radius:20px}#goog-wm-sb:visited{color:#fff}#goog-wm-sb:hover{color:rgba(0,0,0,0.84);background-color:#fff}.ad-vertical{display:none;margin-top:10px}@media only screen and (min-width:728px){.ad-vertical{display:block}}@media only screen and (max-width:727px){.ad-horizontal{max-width:600px}}@media only screen and (min-width:728px){.ad-horizontal{max-width:800px}}.widefix-ad{margin-bottom:0!important;font-family:BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;text-transform:uppercase}.widefix-ad h2{font-size:32px}.widefix-ad a{color:#266cb4!important;background-color:white}.widefix-ad a:hover{color:black!important}.schedule-button{display:inline-block;width:30%;height:52px;padding:0 24px;font:500 18px/28px Inter;line-height:52px;color:#fff!important;text-align:center;text-decoration:none;-webkit-text-size-adjust:100%;background-color:#f04338;border:0;border-radius:100px;transition:background-color .3s;flex-direction:row;align-items:flex-start}@media only screen and (max-width:727px){.schedule-button{width:70%}}.schedule-button:hover{background-color:#e53b30}.seeking-assistance-magnete{display:block;margin:15px 0 -5px;font-size:1.5em;font-weight:bold}
\ No newline at end of file
diff --git a/assets/less/page.less b/assets/less/page.less
index 0e9e9fb..14c4b96 100755
--- a/assets/less/page.less
+++ b/assets/less/page.less
@@ -713,3 +713,10 @@ h2.slogan {
.schedule-button:hover {
background-color: #e53b30;
}
+
+.seeking-assistance-magnete {
+ font-size: 1.5em;
+ font-weight: bold;
+ margin: 15px 0 -5px;
+ display: block;
+}
diff --git a/images/data-stripe.jpg b/images/data-stripe.jpg
new file mode 100644
index 0000000..f850dbc
Binary files /dev/null and b/images/data-stripe.jpg differ
diff --git a/images/metabase-filter-by-deleted-at.png b/images/metabase-filter-by-deleted-at.png
new file mode 100644
index 0000000..c9aca1c
Binary files /dev/null and b/images/metabase-filter-by-deleted-at.png differ
diff --git a/images/reconcile-stripe.jpg b/images/reconcile-stripe.jpg
new file mode 100644
index 0000000..4700d43
Binary files /dev/null and b/images/reconcile-stripe.jpg differ
diff --git a/images/reported-users.png b/images/reported-users.png
new file mode 100644
index 0000000..7496641
Binary files /dev/null and b/images/reported-users.png differ
diff --git a/images/shining-plan.jpg b/images/shining-plan.jpg
new file mode 100644
index 0000000..edf9213
Binary files /dev/null and b/images/shining-plan.jpg differ