/* ==========================================================================
   modal.css — the "log in to subscribe" dialog.

   IMPORTANT, because it is easy to assume otherwise: the page behind the modal
   is NOT blurred. There is no `backdrop-filter` and no `filter` anywhere on the
   page while the modal is open — the whole effect is `.modal-backdrop`, a plain
   black layer at 50% opacity. It reads as a blur at a glance because the dim
   flattens the contrast of everything behind it.

   Layering:  backdrop z-1040  <  modal z-1050
   ========================================================================== */

/* Each modal is hosted in its own absolutely-positioned wrapper with an
   INCREMENTING z-index, and that is the whole trick behind how a second modal
   softens the first.

   The wrapper creates a stacking context, so a modal and its backdrop travel
   together as one unit. Ordering the hosts 1040 < 1041 therefore paints the
   entire restore pair -- backdrop included -- above the entire subscribe pair,
   and it is that second 50% black layer landing ON the login modal that dims
   it. Without the hosts, both backdrops sit at z-1040 and both modals at
   z-1050, so the backdrops both paint underneath and the rear modal stays at
   full strength.

   Note what this is NOT: there is no blur. Verified on the live page with both
   modals open -- nothing on the page carries a `filter` or `backdrop-filter`,
   and the text of the rear modal stays perfectly sharp. It reads as soft
   because the dim flattens its contrast, the same illusion the page behind a
   single modal creates. */
.b-modal-wrapper { position: absolute; z-index: 1040; }
#restore-modal   { z-index: 1041; }

.b-modal-wrapper[hidden] { display: none; }

.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 1040;
  background-color: #000;
  opacity: .5;
}

.modal {
  position: fixed;
  inset: 0;
  z-index: 1050;
  padding: 0;
  overflow-x: hidden;
  overflow-y: auto;
}
/* only the subscribe dialog's shell carries the 12px inset */
.modal.b-modal { padding: 12px; }

/* `min/max-height: calc(100% - 12px)` + `align-items: center` is how a dialog
   centres vertically while still being able to grow past the viewport and
   scroll, rather than being clipped. Width is fluid with a per-size cap. */
.modal-dialog {
  display: flex;
  align-items: center;
  width: calc(100% - 32px);
  min-height: calc(100% - 12px);
  max-height: calc(100% - 12px);
  margin: 6px auto;
}
/* Single-class selectors on purpose. The site writes these as `.modal-sm` /
   `.modal-md`, i.e. the same (0,1,0) specificity as `.modal-dialog`, which is
   what lets the narrow-screen rule below override them on source order alone.
   Writing them as `.modal-dialog.modal-md` (0,2,0) — the obvious thing to do —
   makes them unbeatable by a media query, since media queries add no
   specificity, and the 500px dialog then never narrows. */
.modal-sm { max-width: 344px; }   /* subscribe */
.modal-md { max-width: 500px; }   /* restore access */

/* RESOLUTION CHANGE: below 560px every dialog caps at 344px regardless of size
   class, so the 500px restore dialog narrows to match the subscribe one. With
   `width: calc(100% - 32px)` that gives 334px at a 390px viewport inside
   .b-modal (which adds its own 12px inset) and 344px without it. */
@media (max-width: 559.98px) {
  .modal-dialog { max-width: 344px; }
}

.modal-content {
  display: flex;
  flex-direction: column;
  width: 100%;
  border-radius: 6px;
  overflow: hidden;
  background-color: var(--bg-color);
  box-shadow: 0 3px 6px 0 rgba(0, 0, 0, .16);
}

.modal-body { position: relative; }

/* The scroll lives on the inner block, not the dialog, so the footer stays
   pinned while the card scrolls. 112px = the modal's own padding, the dialog
   margin and the footer. */
.b-scrolled-modal-content {
  max-height: calc(100vh - 112px);
  overflow-y: auto;
  scrollbar-width: none;
}
.b-scrolled-modal-content::-webkit-scrollbar { display: none; width: 0; }

/* ---------- the mini profile card ---------- */
.b-users__item.m-modal-subscriptions {
  display: flex;
  margin-bottom: 14px;
  border-bottom: 1px solid var(--of-border-subtle);
}
.b-users__item__inner {
  position: relative;
  flex: 1;
  min-width: 0;
  padding: 0 16px;
  border-radius: 6px;
}

/* 80px cover that breaks the 16px padding and rounds only its top corners */
.b-users__item__cover__wrapper.m-size-sm {
  position: relative;
  height: 80px;
  margin: 0 -16px;
  border-radius: 6px 6px 0 0;
  overflow: hidden;
}

/* pulled up 42px so the avatar straddles the cover's bottom edge */
.b-profile__user.m-inside-modelcard { margin: -42px 0 14px; }
.b-profile__user.m-inside-modelcard .g-avatar.m-w100 {
  flex: 0 0 100px;
  margin: 0 14px 0 -2px;
  background-color: var(--bg-color);
}
/* the 50px top padding is what drops the name below the avatar's midpoint */
.b-profile__user__info.m-with-status {
  position: relative;
  flex: 1;
  min-width: 0;
  padding-top: 50px;
}
/* Reset the 14px top margin .b-profile__names carries on the profile page — in
   the modal the spacing comes from the 50px padding above instead. Left in, it
   makes this row 111px instead of 100 and shifts the whole dialog by 5.5px once
   it re-centres. */
.b-modal__subscribe .b-profile__names { margin-top: 0; }
.b-profile__user.m-inside-modelcard .g-user-name.m-verified > .g-icon { width: 16px; height: 16px; }

/* ---------- benefits ---------- */
/* flow-root so the list's 12px bottom margin stays inside this box instead of
   collapsing out of it — that margin is part of the card's measured height. */
.b-modal__user__desc { display: flow-root; }

.b-modal__user__desc__title {
  margin-bottom: 10px;
  font: 500 16px/24px var(--of-font);
  color: var(--of-muted);
  text-transform: uppercase;
}
.b-modal__list { margin: 0 0 12px; padding: 0; list-style: none; }
.b-modal__list__item { display: flex; margin-bottom: 8px; font-size: 16px; line-height: 20px; }
.b-modal__list__item:last-child { margin-bottom: 0; }
/* The check sits 2px ABOVE its list item, and the site does it with a
   transform rather than a margin — computed `matrix(1, 0, 0, 1, 0, -2)`. The
   margin box stays put, so only the glyph moves; without it the tick reads as
   sitting a couple of pixels low against the text beside it. */
.b-modal__list__icon {
  flex: 0 1 auto;
  width: 24px;
  height: 24px;
  margin: 0 9px 0 -1px;
  transform: translateY(-2px);
  color: var(--of-blue);
}
.b-modal__list__icon .g-icon { width: 24px; height: 24px; }
.b-modal__list__title { flex: 1; min-width: 0; }

/* ---------- the form ----------
   login-form.css supplies the field, floating label and legal copy. Only the
   places where the modal's copy differs from the hero form are set here. */
.b-modal__subscribe .b-loginreg__form { padding: 0 16px; text-align: left; }
/* The legal copy is CENTRED in the modal, unlike the hero form where it is
   left-aligned. login-form.css sets left, so it has to be overridden here. */
.b-modal__subscribe .b-loginreg__form__issues { text-align: center; }
.b-modal__subscribe .b-loginreg__form h3 {
  font: 500 16px/20px var(--of-font);
  margin: 0 0 14px;
}
/* 72px here, not the hero form's 76 — this field reserves less message space */
.b-modal__subscribe .b-loginreg__form .g-input__wrapper { min-height: 72px; }

/* ---------- multi-step states ----------
   The modal steps email -> password, and swaps to a signup view. Only the
   email step could be observed on the live site (pressing Next there inserts a
   Cloudflare Turnstile challenge), so the later steps mirror the landing page's
   verified flow rather than being measured. Marked as inferred in the docs. */
.b-modal__subscribe .g-input__details { display: flex; padding: 0 16px; min-height: 20px; }
.b-modal__subscribe .g-input__message {
  font: 400 12px/16px var(--of-font);
  color: var(--of-danger);
  padding: 0 0 4px;
  text-align: left;
}
.b-modal__subscribe .g-input__wrapper.m-error .g-input__control { border-color: var(--of-danger); }
.b-modal__subscribe .g-input__wrapper.m-error .g-input__label   { color: var(--of-danger); }
.b-modal__subscribe .g-input__wrapper.m-error:focus-within .g-input__control { border-color: var(--of-danger); }
.b-modal__subscribe .g-input__wrapper.m-error:focus-within .g-input__label   { color: var(--of-danger); }

/* ---------- footer ----------
   Two variants: the subscribe modal's carries .g-border-top and a tighter
   vertical padding; the restore modal's is a plain 10px box with no rule. */
.modal-footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  padding: 10px;
}
.modal-footer.g-border-top {
  padding: 5px 10px 6px;
  border-top: 1px solid var(--of-border-subtle);
}
.modal-footer .g-btn { margin: 0 0 0 4px; }
.modal-footer .g-btn:last-child { margin-right: -4px; }

/* ==========================================================================
   The alert dialog (after Restore Access sends). Measured live 2026-09-08:
   modal-sm (344), no header, body 15px 16px with the message at 16px/21.33,
   footer 6px 10px with one flat button.
   ========================================================================== */
.modal-alert .modal-body { padding: 15px 16px; }
.modal-alert .dialog_message { font: 16px/21.3344px var(--of-font); color: var(--text-color, var(--of-text)); overflow-wrap: break-word; }
.modal-alert .modal-footer { padding: 6px 10px; }

/* ==========================================================================
   Restore Access (forgot password), stacked over the subscribe modal
   ========================================================================== */
.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 48px;
  padding: 14px 16px;
  border-radius: 2px 2px 0 0;
  z-index: 1;
}
.modal-title {
  margin: 0;
  font: 500 14px/20px var(--of-font);
  color: var(--text-color);
  text-transform: uppercase;
}

.modal-restore .modal-body.m-footer-inside-body > form > .modal-body { padding: 15px 16px; }
.modal-restore p.m-mb-20 { margin: 0 0 20px; font-size: 16px; }

/* 68px = a 48px control plus the 20px counter row under it */
.modal-restore .g-input__wrapper { position: relative; min-height: 68px; }
.modal-restore .g-input__control {
  position: relative;
  display: flex;
  align-items: center;
  height: 48px;
  padding: 0 16px;
  border: 1px solid var(--of-border);
  border-radius: 6px;
  background-color: var(--bg-color);
  transition: border-color var(--of-t-input);
}
.modal-restore .g-input__control input {
  width: 100%;
  padding: 14px 0;
  font: 400 16px/20px var(--of-font);
  color: var(--text-color);
  border: none;
  background: none;
  outline: none;
}
.modal-restore .g-input__control input::placeholder { color: transparent; opacity: 0; }
.modal-restore .g-input__label {
  position: absolute;
  top: 14px;
  left: 16px;
  font: 400 16px/20px var(--of-font);
  color: var(--of-muted);
  background-color: var(--bg-color);
  padding: 0 4px;
  margin-left: -4px;
  pointer-events: none;
  transform-origin: top left;
  transition: transform var(--of-t-input);
}
.modal-restore .g-input__wrapper:focus-within .g-input__control { border-color: rgba(0, 175, 240, .75); }
.modal-restore .g-input__wrapper:focus-within .g-input__label,
.modal-restore .g-input__wrapper.m-filled .g-input__label { transform: translateY(-21px) scale(.75); }
.modal-restore .g-input__wrapper:focus-within .g-input__label { color: var(--of-blue); }
.modal-restore .g-input__wrapper.m-error .g-input__control { border-color: var(--of-danger); }
.modal-restore .g-input__wrapper.m-error .g-input__label   { color: var(--of-danger); }

/* the counter row: 16px side padding, counter pushed right, 4px above it */
.v-text-field__details { display: flex; padding: 0 16px; min-height: 20px; }
.v-text-field__details .g-input__message {
  font: 400 12px/16px var(--of-font);
  color: var(--of-danger);
  padding-top: 4px;
}
.v-counter {
  margin-left: auto;
  padding-top: 4px;
  font: 400 12px/16px var(--of-font);
  color: var(--of-muted);
  white-space: nowrap;
}

/* ---------- page state while open ----------
   Locking the page with `overflow: hidden` destroys the scrollbar, the viewport
   gets ~15px wider, and every centred thing on the page jumps right by half of
   that as the modal opens. The site's answer is to hand that width straight
   back to the body:

       body { padding-right: var(--scrollbar-width, 0) }

   JS measures the scrollbar and sets --scrollbar-width at the moment it locks,
   then clears it on unlock. The property is 0 the rest of the time, so this
   rule costs nothing when no overlay is open. */
:root.m-prevent-scrolling { overflow: hidden !important; }

/* superseded: base.css keeps the gutter with scrollbar-gutter: stable, so the
   layout never moves under a lock and no padding is needed (the JS still sets
   --scrollbar-width; nothing reads it for layout any more). */
body.p-profile { padding-right: 0; }
