/* Auth dialog states the ported design system did not need for its stub modals:
   server-rendered error banners, the terms row, and the reset-sent confirmation. */
.auth-error,
.auth-msg {
  margin: 0 0 16px;
  padding: 11px 14px;
  border-radius: 8px;
  font-size: 15px;
  line-height: 1.45;
}
.auth-error {
  color: #8a1c20;
  background: #fdecec;
  border: 1px solid #f3c2c2;
}
.auth-error a { color: #8a1c20; text-decoration: underline; }
.auth-msg {
  color: var(--navy);
  background: var(--paper-alt);
  border: 1px solid #dfe2ea;
}
#fpEmailError { margin-top: -6px; }

.mform .check.terms-check {
  display: flex;
  gap: 9px;
  align-items: flex-start;
  margin: 2px 0 20px;
  font-size: 15px;
  line-height: 1.45;
}
.mform .check.terms-check input { margin-top: 3px; flex: 0 0 auto; }
/* the copy is one run of text with an inline link, so it must not become a row of
   flex items — that breaks "Terms of Service" across a gap mid-phrase */
.mform .check.terms-check > span { display: inline; }
.mform .check.terms-check a { color: var(--red); white-space: nowrap; }

.fp-tick {
  width: 54px;
  height: 54px;
  margin: 4px auto 18px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  color: #1c7a4a;
  background: #e7f6ee;
}
.fp-tick svg { width: 26px; height: 26px; }
#fpSuccessView { text-align: center; }
/* the message ran straight into the button; give it room to breathe */
#fpSuccessView .modal-sub { margin-bottom: 4px; }
#fpSuccessView .btn { margin-top: 22px; }
#fpSuccessView .mform-foot { margin-top: 16px; }

.mform button[disabled] { opacity: .65; cursor: default; }

/* the real reCAPTCHA widget replaces the preview's dashed placeholder box */
.captcha { border: 0; background: none; padding: 0; min-height: 0; color: inherit; font: inherit; }
.form-status.is-ok  { color: #1c7a4a; }
/* .form-status's base panel in site.css is green — the success treatment. Recolouring
   only the text left a validation error ("Please accept Terms of Service") sitting in a
   green panel, so the error state repaints the whole panel. */
.form-status.is-err { background: #FBECEC; border-left-color: #C0392B; color: #8a1c20; }

/* The v2 checkbox widget is a fixed 304px iframe, which overflows a 360px
   viewport once page padding is taken off. Scale it down rather than let the
   whole document scroll sideways. */
@media (max-width:400px){
  /* the widget is still laid out as a 304px box, so centring it pushed the
     scaled result off the right edge — pin it left and scale from that edge */
  .captcha{display:flex;justify-content:flex-start;overflow:hidden}
  .captcha .g-recaptcha{
    transform:scale(.84);
    transform-origin:0 50%;
    height:66px;
  }
}

/* long-form legal copy: the legacy pages carried their own fonts and colours
   inline, which were stripped on port, so set readable defaults here */
.legal .legal-body{max-width:78ch;margin-top:30px}
.legal .legal-body h2{font-size:20px;font-weight:800;color:var(--navy);margin:34px 0 10px}
.legal .legal-body h3{font-size:18px;font-weight:800;color:var(--red);margin:28px 0 8px}
.legal .legal-body p{font-size:16.5px;line-height:1.7;margin:0 0 12px;color:var(--gray)}
.legal .legal-body ul,.legal .legal-body ol{margin:0 0 14px 22px;font-size:16.5px;line-height:1.7;color:var(--gray)}
.legal .legal-body li{margin-bottom:6px}
.legal .legal-body a{color:var(--red);text-decoration:underline;text-underline-offset:2px}
.legal .legal-body strong,.legal .legal-body b{color:var(--navy)}

/* Numbered legal clauses. The legacy page drew these with inline Open Sans and
   #B42914 circles; here they carry the 2026 navy and type scale. Three levels:
   numbered clauses, lettered sub-points (a-g), roman sub-sub-points (i-viii). */
.legal .lg-intro{
  margin-top:30px;padding:26px 30px;border-radius:8px;
  background:var(--paper-2);border:1px solid var(--line);
  font-size:15.5px;line-height:1.7;color:var(--gray);
}
.legal .lg-intro b,.legal .lg-intro strong{color:var(--navy)}
.legal .lg-item{display:grid;grid-template-columns:52px 1fr;gap:22px;margin-top:32px}
.legal .lg-num{
  width:52px;height:52px;border-radius:50%;background:var(--navy);color:#fff;
  display:grid;place-items:center;font-size:22px;font-weight:700;
}
.legal .lg-item.l2{grid-template-columns:38px 1fr;gap:18px;margin-top:22px;margin-left:74px}
.legal .lg-item.l2 .lg-num{width:38px;height:38px;font-size:16px;background:#2C3D74}
.legal .lg-item.l3{grid-template-columns:32px 1fr;gap:16px;margin-top:16px;margin-left:130px}
.legal .lg-item.l3 .lg-num{
  width:32px;height:32px;font-size:13px;background:#fff;color:var(--navy);
  border:1px solid #C3CADC;
}
.legal .lg-close{margin-top:26px;font-size:15.5px;line-height:1.7;color:var(--gray)}
.legal .lg-close:first-of-type{margin-top:40px;padding-top:26px;border-top:1px solid var(--line)}
.legal .lg-txt p{font-size:16.5px;line-height:1.7;margin:0 0 12px;color:var(--gray)}
.legal .lg-txt p:last-child{margin-bottom:0}
.legal .lg-txt b,.legal .lg-txt strong{color:var(--navy)}
.legal .lg-txt ul{margin:0 0 14px 22px;padding:0;font-size:16.5px;line-height:1.7;color:var(--gray)}
.legal .lg-txt li{margin-bottom:6px}
.legal .lg-item.l2 .lg-txt p,.legal .lg-item.l2 .lg-txt li{font-size:16px}
.legal .lg-item.l3 .lg-txt p,.legal .lg-item.l3 .lg-txt li{font-size:15.5px}
@media(max-width:980px){
  .legal .lg-item.l2{margin-left:26px}
  .legal .lg-item.l3{margin-left:48px}
}
@media(max-width:700px){
  .legal .lg-item{grid-template-columns:42px 1fr;gap:14px}
  .legal .lg-num{width:42px;height:42px;font-size:19px}
  .legal .lg-item.l2,.legal .lg-item.l3{margin-left:14px}
}


/* ---------- a single CRE Insights article ---------- */
/* Body copy comes from the blog, so style by element rather than by class. */
.article .wrap{max-width:820px}
.article h1{font-size:clamp(28px,2.8vw,40px);line-height:1.15}
.art-back{margin-bottom:22px;font-size:15px;font-weight:700}
.art-back a{color:var(--navy);text-decoration:none}
.art-back a:hover{color:var(--red)}
.art-meta{margin-top:14px;font-size:15.5px;color:var(--gray)}
.art-dot{margin:0 4px}
.art-labels{margin-top:16px;display:flex;flex-wrap:wrap;gap:8px}
.art-labels span{
  font-size:12.5px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;
  color:var(--navy);background:#EEF0F4;border-radius:3px;padding:5px 11px;
}
.art-body{margin-top:30px}
.art-body p{font-size:17px;line-height:1.75;margin:0 0 18px;color:var(--gray)}
.art-body h1,.art-body h2,.art-body h3,.art-body h4{
  color:var(--navy);margin:34px 0 12px;line-height:1.25;
}
.art-body h1{font-size:26px}
.art-body h2{font-size:23px}
.art-body h3{font-size:20px}
.art-body h4{font-size:18px}
.art-body b,.art-body strong{color:var(--navy)}
.art-body a{color:var(--red);text-decoration:underline;text-underline-offset:2px}
.art-body ul,.art-body ol{margin:0 0 18px 24px;padding:0;font-size:17px;line-height:1.75;color:var(--gray)}
.art-body li{margin-bottom:8px}
/* the blog sets pixel widths and table layouts inline; keep them contained */
.art-body img{max-width:100%;height:auto;display:block;margin:24px auto;border-radius:6px}
.art-body iframe,.art-body table{max-width:100%}
.art-body table{display:block;overflow-x:auto}
.art-body blockquote{
  margin:24px 0;padding:4px 0 4px 22px;border-left:3px solid var(--red);
  font-size:18px;line-height:1.7;color:var(--navy);
}
.art-body div[style]{max-width:100% !important}
/* Post callouts colour themselves inline on a wrapper — a dark card carrying
   color:white. Every rule above is an element rule on a descendant, which beats
   that inherited colour, so the card's own text was repainted var(--gray) and
   its heading var(--navy): the paragraph ended up rgb(71,83,98) on a rgb(71,83,98)
   card, i.e. a solid empty-looking rectangle in a published article, and the hero
   card's h1 came out navy on slate (UI review, 8/24).
   So: wherever the post states a colour, that colour wins for what is inside it.
   Links keep their red — a link is a control, not body copy — but if a future
   post puts one inside a dark card it will need its own inline colour. */
.art-body [style*="color"] p,
.art-body [style*="color"] h1,
.art-body [style*="color"] h2,
.art-body [style*="color"] h3,
.art-body [style*="color"] h4,
.art-body [style*="color"] ul,
.art-body [style*="color"] ol,
.art-body [style*="color"] li,
.art-body [style*="color"] b,
.art-body [style*="color"] strong,
.art-body [style*="color"] blockquote{color:inherit}


/* ---------- Set Password (reset-password.php) ---------- */
/* The card is centred in whatever height is left over between the header and
   the footer rather than sitting on fixed padding, so the page sizes itself to
   the screen instead of scrolling on a short one (TAP-509). main is the flex
   child that takes up the slack — the body is already a flex column for the
   sticky footer — and flex-shrink stays 0 so a viewport too short to hold the
   card scrolls rather than squashing it. */
.sp-main{flex:1 0 auto;display:flex;flex-direction:column}
.setpass{flex:1 0 auto;display:flex;align-items:center;padding:clamp(18px,4vh,70px) 0}
.setpass > .wrap{width:100%}
.sp-card{
  max-width:520px;margin:0 auto;background:#fff;border:1px solid var(--line);
  border-radius:10px;padding:38px 40px 40px;box-shadow:0 10px 34px rgba(19,33,86,.08);
}
.sp-card h1{font-size:clamp(26px,2.4vw,34px);text-align:center}
.sp-card .modal-sub{text-align:center;margin-top:10px}
.sp-card .mform{margin-top:26px}
/* The hint is a caption for the fields above it, so it stays close to them —
   but `p{margin:0}` left it sitting flush on top of the button. The button
   carries its own headroom instead, which also holds when a status panel
   (margin-top:16px, collapsed against this) appears between the two. */
.sp-req{margin-top:2px;font-size:13.5px;color:var(--gray)}
.sp-card .mform > .btn{margin-top:24px}
.field-err{margin-top:6px;font-size:13.5px;color:#c0392b}
.form-status.is-err{color:#c0392b}
#m-setpass-done .modal-box{text-align:center}
#m-setpass-done .fp-tick{margin:4px auto 16px}
#m-setpass-done .btn{margin-top:22px}
@media(max-width:560px){
  .sp-card{padding:28px 22px 30px}
}
/* Short viewport — a laptop, or a window that is not full height. The card
   gives back its own breathing room before the page resorts to a scrollbar;
   the proportions are the same, just tighter. */
@media (max-height:820px){
  .setpass{padding:clamp(12px,2.2vh,22px) 0}
  .sp-card{padding:26px 34px 28px}
  .sp-card h1{font-size:clamp(24px,2vw,28px)}
  .sp-card .mform{margin-top:18px}
  .sp-card .field{margin-bottom:13px}
  .sp-card .mform > .btn{margin-top:18px}
}
@media (max-height:820px) and (max-width:560px){
  .sp-card{padding:22px 20px 24px}
}
/* Shorter still: a landscape phone, or a window pulled down to a strip. Last
   tier — below this the fields themselves would have to shrink, and a password
   box that changes height is worse than a short scroll. */
@media (max-height:620px){
  .setpass{padding:10px 0}
  .sp-card{padding:20px 30px 22px}
  .sp-card h1{font-size:22px}
  .sp-card .mform{margin-top:14px}
  .sp-card .field{margin-bottom:10px}
  .sp-card .mform > .btn{margin-top:14px}
}
@media (max-height:620px) and (max-width:560px){
  .setpass{padding:6px 0}
  .sp-card{padding:18px 16px 20px}
  .sp-card h1{font-size:21px}
  .sp-card .mform{margin-top:12px}
  .sp-card .field{margin-bottom:9px}
  .sp-card .mform > .btn{margin-top:13px}
}


/* ---------- password reveal toggle ---------- */
/* The button sits inside the field box, so the input gives up the space on its
   right rather than the icon covering typed characters. Only one of the two
   icons is in the flow at a time; .is-on marks "password is visible". */
/* .pass-box wraps the input and the button only — it is deliberately not the
   whole .field, because a field can also carry a label above it and an inline
   error below (both Set Password fields do), and `bottom` measured against the
   field would drop the icon onto the error line instead of into the input. */
.pass-box{position:relative;display:block}
.pass-box input{padding-right:46px}
.pass-eye{
  position:absolute;right:6px;bottom:6px;
  width:34px;height:34px;padding:0;display:flex;align-items:center;justify-content:center;
  border:0;border-radius:6px;background:transparent;color:#8C97AE;cursor:pointer;
  transition:color .16s ease, background-color .16s ease;
}
.pass-eye:hover{color:var(--navy);background:rgba(19,33,86,.06)}
.pass-eye:focus-visible{outline:3px solid var(--red);outline-offset:1px}
.pass-eye svg{width:20px;height:20px;display:block}
.pass-eye .eye-off{display:none}
.pass-eye.is-on{color:var(--red)}
.pass-eye.is-on .eye-on{display:none}
.pass-eye.is-on .eye-off{display:block}
@media (prefers-reduced-motion:reduce){
  .pass-eye{transition:none}
}


/* ---------- field with an icon and a floating label ---------- */
/* The label starts inside the field, as placeholder text beside the icon, and
   animates up to a caption when the field is focused or holds a value. Uses
   :placeholder-shown, so it needs the input to carry placeholder=" ". */
.field-float{position:relative;display:block}
.field-float input{
  width:100%;padding:16px 14px 16px 46px;   /* room for the icon */
  transition:border-color .18s ease, box-shadow .18s ease;
}
.field-float .fi-icon{
  position:absolute;left:15px;top:50%;transform:translateY(-50%);
  width:19px;height:19px;color:#8C97AE;pointer-events:none;
  transition:color .18s ease, transform .18s ease;
}
.field-float .fi-icon svg{width:100%;height:100%;display:block}
.field-float label{
  position:absolute;left:46px;top:50%;transform:translateY(-50%);
  margin:0;padding:0 4px;background:#fff;color:#8C97AE;
  font-size:16px;font-weight:400;pointer-events:none;
  transition:transform .16s ease, font-size .16s ease, color .16s ease, left .16s ease;
}
/* focused, or filled: label rises to the top edge of the field */
.field-float input:focus + label,
.field-float input:not(:placeholder-shown) + label{
  transform:translateY(-34px);
  left:12px;font-size:12.5px;font-weight:700;color:var(--navy);
  letter-spacing:.02em;
}
.field-float input:focus ~ .fi-icon,
.field-float:focus-within .fi-icon{color:var(--red);transform:translateY(-50%) scale(1.06)}
.field-float{margin-top:26px}          /* the risen label needs headroom */
@media (prefers-reduced-motion:reduce){
  .field-float label,.field-float .fi-icon{transition:none}
}


/* ---------- animated envelope (ported from the legacy modal) ---------- */
/* Structure and timings are the legacy site's, so the two behave identically;
   only the red comes from the 2026 token instead of --color-red. */
.fp-mail-icon svg{width:100%;height:100%;overflow:visible}
.fp-env-shell{transform-box:fill-box;transform-origin:50% 55%}
.fp-env-body{fill:none;stroke:currentColor;stroke-width:1.6}
.fp-env-flap{fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
.fp-env-letter{opacity:0;transform-box:fill-box;transform-origin:50% 50%}
.fp-env-letter rect{fill:var(--red)}
.fp-env-letter line{stroke:#fff;stroke-width:.7}
.fp-env-spark{fill:var(--red);opacity:0;transform-box:fill-box;transform-origin:50% 50%}
.fp-field.sending .fp-env-shell{animation:fp-env-wobble 1.2s ease-in-out}
.fp-field.sending .fp-env-letter{animation:fp-env-send 1.2s cubic-bezier(.3,.6,.25,1) forwards}
.fp-field.sending .spark-1{animation:fp-env-spark 1.2s ease-out .16s}
.fp-field.sending .spark-2{animation:fp-env-spark 1.2s ease-out .30s}
.fp-field.sending .spark-3{animation:fp-env-spark 1.2s ease-out .44s}
@keyframes fp-env-wobble{
  0%,32%{transform:rotate(0)}
  48%{transform:rotate(-6deg)}
  64%{transform:rotate(4deg)}
  80%{transform:rotate(-2deg)}
  100%{transform:rotate(0)}
}
@keyframes fp-env-send{
  0%{opacity:0;transform:translate(0,0) scale(.6)}
  14%{opacity:1;transform:translate(0,-1px) scale(.88)}
  42%{opacity:1;transform:translate(1px,-8px) scale(.95) rotate(4deg)}
  76%{opacity:1;transform:translate(11px,-19px) scale(.7) rotate(16deg)}
  100%{opacity:0;transform:translate(20px,-30px) scale(.4) rotate(26deg)}
}
@keyframes fp-env-spark{
  0%{opacity:0;transform:scale(.4) translate(0,0)}
  35%{opacity:1;transform:scale(1) translate(0,0)}
  100%{opacity:0;transform:scale(.3) translate(5px,-7px)}
}
@media (prefers-reduced-motion:reduce){
  .fp-field.sending .fp-env-shell,
  .fp-field.sending .fp-env-letter,
  .fp-field.sending .spark-1,
  .fp-field.sending .spark-2,
  .fp-field.sending .spark-3{animation-duration:.001ms !important}
}


/* ---------- Multi-Factor Authentication (otp_verification.php) ---------- */
/* Framing copy, one centred card, closing note, on the 2026 tokens. The form
   is a card so the code field reads as the one thing to act on. The layout was
   two columns with an illustration beside the form until review asked for the
   artwork gone and the card centred (TAP-507 #4) — which is also why nothing
   here has to be hidden on a narrow window any more. */
/* Centred in the height that is left over between the header and the footer,
   on the body flex column the sticky footer set up, rather than on fixed
   padding — same treatment as .setpass, so the page sizes itself to the screen
   (TAP-509). flex-shrink:0: when there is genuinely not enough room the page
   scrolls instead of squeezing the code field. */
.mfa-main{flex:1 0 auto;display:flex;flex-direction:column}
.mfa{flex:1 0 auto;display:flex;align-items:center;padding:clamp(16px,2.6vh,44px) 0}
.mfa .wrap{max-width:1120px;width:100%}
.mfa-top{max-width:760px;margin:0 auto;text-align:center}
.mfa-top h1{font-size:clamp(25px,2.5vw,36px);line-height:1.18}
.mfa-lead{margin-top:14px;font-size:17px;line-height:1.6;color:var(--gray)}

/* one column, and the card centres itself in it via its own auto margins —
   a flex/grid centring container would fight the card's max-width on the
   narrowest screens */
.mfa-grid{margin-top:40px}

.mfa-card{
  background:#fff;border:1px solid var(--line);border-radius:10px;
  padding:34px 36px 32px;box-shadow:0 10px 34px rgba(19,33,86,.08);
  width:100%;max-width:460px;margin:0 auto;
}
/* centred over a centred field and a full-width button (TAP-507 #3) */
.mfa-card h2{font-size:clamp(21px,1.9vw,26px);line-height:1.2;text-align:center}
.mfa-form{margin-top:22px}
.mfa-form .field{margin-bottom:18px}

/* the code itself: large, centred, spaced, so six digits are easy to read back
   from an email and easy to check for a typo */
input.mfa-code{
  width:100%;padding:15px 14px;text-align:center;
  font-size:26px;font-weight:700;color:var(--navy);
  letter-spacing:.34em;text-indent:.34em;   /* indent cancels the trailing gap */
  font-variant-numeric:tabular-nums;
}
input.mfa-code::placeholder{
  font-size:16px;font-weight:400;letter-spacing:normal;text-indent:0;
  color:#8C97AE;
}

/* visually hidden, still read out — the field has never had a visible label,
   only a placeholder, and a placeholder is not a label */
.mfa-vh{
  position:absolute;width:1px;height:1px;margin:-1px;padding:0;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}

/* Resend is a link-weight control, not a second primary button: one action on
   this page should look like the action. */
.mfa-resend{margin-top:16px;text-align:center}
.mfa-resend-link{
  border:0;background:none;padding:4px 2px;font:inherit;
  font-size:15.5px;font-weight:700;color:var(--navy);
  text-decoration:underline;text-underline-offset:3px;cursor:pointer;
}
.mfa-resend-link:hover:not([disabled]){color:var(--red)}
.mfa-resend-link[disabled]{color:#8C97AE;text-decoration:none;cursor:default}

/* black, not the red it used to be (TAP-507 #5): it is a housekeeping note
   about spam folders and preferences, not a warning */
.mfa-note{
  margin-top:20px;padding-top:18px;border-top:1px solid var(--line);
  font-size:13.5px;line-height:1.55;color:#000;
}
.mfa-support{margin-top:12px;font-size:14.5px;line-height:1.55}
.mfa-support a{color:var(--navy);font-weight:700;text-decoration:underline;text-underline-offset:3px}
.mfa-support a:hover{color:var(--red)}

.mfa-foot{
  margin:44px auto 0;max-width:860px;text-align:center;
  font-size:14.5px;line-height:1.65;color:var(--gray);
}

/* the invalid-code banner fades rather than vanishing under the cursor */
.mfa .auth-error{transition:opacity .5s ease}
.mfa .auth-error.is-out{opacity:0}

/* resend confirmation, bottom-right, out of the form's way */
.mfa-toast{
  position:fixed;right:22px;bottom:22px;z-index:70;max-width:min(360px,calc(100vw - 44px));
  padding:13px 18px;border-radius:8px;
  background:var(--navy);color:#fff;font-size:15px;line-height:1.45;
  box-shadow:0 10px 30px rgba(19,33,86,.28);
  opacity:0;transform:translateY(8px);transition:opacity .4s ease,transform .4s ease;
}
.mfa-toast.is-in{opacity:1;transform:none}
.mfa-toast[hidden]{display:none}

/* the column is already one card wide, so narrowing only tightens spacing */
@media(max-width:900px){
  .mfa{padding:clamp(14px,2.2vh,34px) 0}
  .mfa-grid{margin-top:32px}
}
@media(max-width:620px){
  .mfa-card{padding:26px 22px 24px}
  input.mfa-code{font-size:22px;letter-spacing:.24em;text-indent:.24em}
  .mfa-toast{left:22px;right:22px;max-width:none}
}
/* Short viewport. This page carries far more than the Set Password card does —
   a heading, a lead paragraph, the card, and a closing paragraph — so it gives
   that spacing back in three tiers before it resorts to a scrollbar. Tier one
   is spacing only; type sizes start moving in tier two. */
@media (max-height:940px){
  .mfa{padding:clamp(12px,2vh,22px) 0}
  .mfa-lead{margin-top:10px;font-size:16px}
  .mfa-grid{margin-top:24px}
  .mfa-card{padding:26px 30px 26px}
  .mfa-form{margin-top:18px}
  .mfa-form .field{margin-bottom:14px}
  .mfa-note{margin-top:16px;padding-top:14px}
  .mfa-support{margin-top:10px}
  .mfa-foot{margin-top:26px}
}
@media (max-height:840px){
  .mfa{padding:clamp(10px,1.6vh,16px) 0}
  .mfa-top h1{font-size:clamp(23px,2vw,27px)}
  .mfa-lead{margin-top:8px;font-size:15px;line-height:1.5}
  .mfa-grid{margin-top:16px}
  .mfa-card{padding:20px 26px 20px}
  .mfa-card h2{font-size:clamp(19px,1.6vw,22px)}
  .mfa-form{margin-top:14px}
  .mfa-form .field{margin-bottom:11px}
  input.mfa-code{padding:12px 14px;font-size:23px}
  .mfa-resend{margin-top:12px}
  .mfa-note{margin-top:12px;padding-top:11px;font-size:13px}
  .mfa-support{margin-top:8px}
  .mfa-foot{margin-top:18px;font-size:13.5px;line-height:1.55}
}
/* Third tier — a 1366x768 laptop lands here. This is as tight as the page goes;
   below it the two long paragraphs would have to shrink past readable, so the
   page scrolls a little instead. */
@media (max-height:720px){
  .mfa{padding:clamp(8px,1.2vh,12px) 0}
  .mfa-top h1{font-size:clamp(21px,1.8vw,24px)}
  .mfa-lead{margin-top:6px;font-size:14.5px;line-height:1.45}
  .mfa-grid{margin-top:10px}
  .mfa-card{padding:18px 24px 18px}
  .mfa-form{margin-top:12px}
  .mfa-form .field{margin-bottom:9px}
  input.mfa-code{padding:10px 14px;font-size:22px}
  .mfa-resend{margin-top:9px}
  .mfa-note{margin-top:10px;padding-top:9px;font-size:12.5px;line-height:1.5}
  .mfa-support{margin-top:6px;font-size:14px}
  .mfa-foot{margin-top:14px;font-size:13px;line-height:1.5}
  /* the invalid-code / code-resent banner is the one thing that can appear
     mid-session and push the page over; it tightens with everything else */
  .mfa .auth-error,.mfa .auth-msg{margin-bottom:9px;padding:8px 12px;font-size:14px}
}
@media (prefers-reduced-motion:reduce){
  .mfa .auth-error,.mfa-toast{transition:none}
}


/* ---------- minimal chrome (auth interstitials) ---------- */
/* No nav to hold, so the bar can be shorter than the marketing header's 96px.
   The mark is a <span>, not a link — nothing here should lead off the page. */
.head-min .head-in{height:76px;justify-content:center}
.head-min .brand{display:block}
.head-min .brand img{height:clamp(48px,4vw,58px);width:auto}
.foot-min{border-top:0}
/* .foot-bar carries no side padding — harmless on the marketing footer, whose
   line is short, but this one also holds the two legal links and wrapped
   flush to both screen edges on a phone. */
.foot-min .foot-bar{font-size:14.5px;padding-left:20px;padding-right:20px}
.foot-min .foot-bar a{color:#fff;text-decoration:underline;text-underline-offset:3px}
.foot-min .foot-bar a:hover{color:#fff;opacity:.8}


/* ---------- "Processing…" overlay (TAP-505) ---------- */
/* Above .modal (z-index 130) — a login is submitted from inside the dialog, so
   the overlay has to cover the dialog too. Same scrim family as .modal so the
   two read as one stack rather than two competing sheets. */
.tap-loading{
  position:fixed;inset:0;z-index:200;display:flex;align-items:center;justify-content:center;
  background:rgba(10,16,40,.82);padding:24px;
  animation:tapLoadIn .18s ease;
}
.tap-loading[hidden]{display:none}
.tap-loading-box{
  background:#fff;border-radius:14px;padding:34px 42px;text-align:center;
  box-shadow:0 30px 80px rgba(5,10,30,.45);
  display:flex;flex-direction:column;align-items:center;gap:18px;
  min-width:min(260px,100%);
}
.tap-loading-txt{
  margin:0;font-size:17px;font-weight:700;color:var(--navy);letter-spacing:.01em;
}
/* Ring rather than the legacy 12-blade sk-circle: one element, no extra markup,
   and it reads at any size. */
.tap-spinner{
  width:46px;height:46px;border-radius:50%;display:block;
  border:4px solid var(--line);border-top-color:var(--red);
  animation:tapSpin .8s linear infinite;
}
@keyframes tapSpin{to{transform:rotate(360deg)}}
@keyframes tapLoadIn{from{opacity:0}to{opacity:1}}
/* Reduced motion still needs to show that something is happening, so the ring
   pulses in place instead of spinning. */
@media (prefers-reduced-motion:reduce){
  .tap-loading{animation:none}
  .tap-spinner{
    animation:tapPulse 1.4s ease-in-out infinite;
    border-top-color:var(--red);
  }
  @keyframes tapPulse{0%,100%{opacity:1}50%{opacity:.35}}
}

/* the submit button keeps its own state as well: the overlay covers it, but if
   the overlay is ever suppressed the button must still read as busy */
.mform button[aria-busy="true"]{opacity:.65;cursor:default}


/* ---------- inline button spinner (TAP-505) ---------- */
/* For in-place fetch actions — forgot password, set password — where the dialog
   stays open and the result appears in it. Those must NOT raise .tap-loading:
   a full-screen scrim would cover the very animation that reports progress.
   Navigating actions (login, MFA verify) get the overlay; in-place ones get this.
   The legacy forgot-password modal had exactly this (`.fp-spinner`); the port
   dropped it and left the label change on its own. */
.btn-spinner{
  display:inline-block;width:15px;height:15px;margin-right:9px;
  vertical-align:-2px;border-radius:50%;
  border:2px solid rgba(255,255,255,.4);border-top-color:#fff;
  animation:tapSpin .7s linear infinite;
}
/* on a light button the white ring would vanish */
.btn-outline .btn-spinner{border-color:rgba(19,33,86,.25);border-top-color:var(--navy)}
@media (prefers-reduced-motion:reduce){
  .btn-spinner{animation:tapPulseSpin 1.4s ease-in-out infinite}
  @keyframes tapPulseSpin{0%,100%{opacity:1}50%{opacity:.35}}
}
