/* Helm — Logto "Bring your UI" sign-in styles. LIGHT AND DARK (HOME-6227): `:root` is the dark
 * theme (THEMES.dark) and stays the default; `:root[data-theme="light"]` is THEMES.light. The mode is
 * the APP's, not the system's: context.js reads it from the helm_ctx cookie and sets <html data-theme>
 * before the first paint — no cookie (iOS, web, an older app) means dark, the page iOS has always had.
 * Every colour a rule uses is a token here, and the light block redefines EVERY token the dark one
 * defines (test/theme.test.mjs), so nothing stays dark on a light page by omission.
 * Since HOME-5572 also HOME-5169 §3's shared tokens: screen background, secondary ink .88, #FFB454
 * warnings directly under their field, 54px buttons, the .075 card.
 * Externalized so script-src/style-src stay 'self'. */
:root {
  color-scheme: dark;
  --body: #070b16;
  /* HOME-5169 §3 screen background: a cyan glow at the top over a navy fall-off, on #0C121E. */
  --bg-base: #0c121e;
  --bg:
    radial-gradient(120% 62% at 50% -8%, rgba(91, 232, 255, 0.13), rgba(91, 232, 255, 0.045) 44%, transparent 72%),
    linear-gradient(180deg, #1e2d47 0%, #1a2740 48%, #152036 100%);
  --ink: #eaf1ff;
  --sub: rgba(234, 241, 255, 0.88);
  --faint: rgba(234, 241, 255, 0.4);
  --sep: rgba(255, 255, 255, 0.1);
  --accent: #5be8ff;
  --accent2: #4d8dff;
  --accent-text: #07101f;
  --accent-soft: rgba(91, 232, 255, 0.15);
  --accent-grad: linear-gradient(110deg, #4d8dff, #5be8ff);
  --success: #3dd2a0;
  --success-soft: rgba(61, 210, 160, 0.16);
  --warn: #ffb454;
  --danger: #ff6b6b;
  --card: rgba(255, 255, 255, 0.06);
  --card2: rgba(255, 255, 255, 0.075); /* HOME-5169 §3 card (Just subscribed?) */
  --btn2-border: rgba(255, 255, 255, 0.14); /* the design's outline: t.fieldBorder (L9) */
  --card-shadow: 0 12px 34px rgba(0, 0, 0, 0.4);
  --sheet-border: rgba(255, 255, 255, 0.12);
  --field: rgba(255, 255, 255, 0.06);
  --field-border: rgba(255, 255, 255, 0.14);
  /* HOME-6227: what used to be hard-coded in the rules below, so the light set can reach it */
  --btn-shadow: 0 4px 12px rgba(77, 141, 255, 0.18); /* theme.jsx Btn primary (L5) */
  --btn-radius: 16px;
  --btn-disabled-opacity: 0.5;
  --btn-disabled-bg: var(--accent-grad);
  --btn-disabled-ink: var(--accent-text);
  --trybtn-border: 1px solid var(--btn2-border);
  --press: rgba(255, 255, 255, 0.04);
  --menu-bg: #0e1626;
  --menu-border: rgba(255, 255, 255, 0.14);
  --menu-shadow: 0 16px 40px rgba(0, 0, 0, 0.55);
  --search-bg: rgba(255, 255, 255, 0.05);
  --row-hover: rgba(255, 255, 255, 0.07);
  --seg-bg: rgba(255, 255, 255, 0.05);
  --seg-on: rgba(255, 255, 255, 0.1);
  --seg-on-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
  --otp-filled: rgba(91, 232, 255, 0.53);
  --spinner-track: rgba(7, 16, 31, 0.4);
  --warnmsg: #e0a44d;
  --sheet-bg: rgba(16, 23, 38, 0.92);
  --sheet-shadow: 0 -10px 40px rgba(0, 0, 0, 0.55);
  --grab: rgba(255, 255, 255, 0.25);
}
/* THEMES.light (helm-bso2/theme.jsx), as the design renders it: a flat #F2F2F6 screen, white fields and
   cards, a solid blue primary with white text and NO glow, warnings in #A15C00 (warnInk — #FFB454 does
   not read on white), success ink #147A5B. The H mark is full colour in both modes (HOME-7199) — no mark token here. */
:root[data-theme="light"] {
  color-scheme: light;
  --body: #f2f2f6;
  --bg-base: #f2f2f6;
  --bg: none;
  --ink: #0e1a2e;
  --sub: rgba(14, 26, 46, 0.86);
  --faint: rgba(14, 26, 46, 0.6);
  --sep: rgba(15, 30, 60, 0.1);
  --accent: #0062d1;
  --accent2: #5be8ff;
  --accent-text: #ffffff;
  --accent-soft: rgba(0, 98, 209, 0.1);
  --accent-grad: linear-gradient(110deg, #0052bd, #0a72d9);
  --success: #147a5b;
  --success-soft: rgba(61, 210, 160, 0.16);
  --warn: #a15c00;
  --danger: #e5383b;
  --card: #ffffff;
  --card2: #ffffff;
  --btn2-border: rgba(15, 30, 60, 0.14);
  --card-shadow: 0 4px 14px rgba(30, 50, 90, 0.05);
  --sheet-border: rgba(15, 30, 60, 0.1);
  --field: #ffffff;
  --field-border: rgba(15, 30, 60, 0.14);
  --btn-shadow: none;
  --btn-radius: 15px;
  --btn-disabled-opacity: 1;
  --btn-disabled-bg: #e3e5ea;
  --btn-disabled-ink: rgba(14, 26, 46, 0.62);
  --trybtn-border: 1.5px solid rgba(12, 24, 48, 0.32);
  --press: rgba(15, 30, 60, 0.04);
  --menu-bg: #ffffff;
  --menu-border: rgba(15, 30, 60, 0.1);
  --menu-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
  --search-bg: #f5f7fa;
  --row-hover: rgba(15, 30, 60, 0.05);
  --seg-bg: rgba(15, 30, 60, 0.06);
  --seg-on: #ffffff;
  --seg-on-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
  --otp-filled: rgba(0, 98, 209, 0.53);
  --spinner-track: rgba(255, 255, 255, 0.4);
  --warnmsg: #a15c00;
  --sheet-bg: rgba(255, 255, 255, 0.92);
  --sheet-shadow: 0 -6px 20px rgba(30, 50, 90, 0.07);
  --grab: rgba(60, 60, 67, 0.22);
}
* {
  box-sizing: border-box;
}
html,
body {
  margin: 0;
}
/* L12 (HOME-6235): a column at least the screen's height — 100dvh, which the soft keyboard shrinks once the
   app hands the WebView its IME inset (HOME-6226; interactive-widget=resizes-content) — that GROWS with its
   content. So a screen fits at rest where it can, and whatever does not fit (a small phone, large text, the
   keyboard) scrolls the page: no height is capped, nothing is clipped. No `height:100%` either: it fixed the
   body at the screen's height, and a page that overflowed it lost its bottom padding (its last button ended
   flush with the screen). L6: 28px above the mark on a phone (was 54 — the whole block sat ~26px lower than
   the design), compressing on a short viewport; the same at the bottom. */
body {
  font-family: "Roboto", "Roboto Flex", system-ui, sans-serif; /* the design's Android override (L4) */
  color: var(--ink);
  background: var(--bg), var(--bg-base);
  background-attachment: fixed;
  min-height: 100vh;
  min-height: 100dvh; /* 100vh: engines without dvh */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  padding: 28px 0; /* engines without dvh drop the next line whole */
  padding: clamp(12px, 3.3dvh, 28px) 0;
}
/* A column the height of the screen, so sign in's "New to Helm?" footer sits at the bottom and stays
   there whichever channel is on screen (HOME-5169 screen 2: "Footer, fixed position"). Not
   position:fixed — the soft keyboard would park it over the fields. */
.wrap {
  width: 100%;
  max-width: 430px;
  padding: 0 25px;
  flex: 1;
  display: flex;
  flex-direction: column;
}
.screen {
  flex: 1;
  display: flex;
  flex-direction: column;
}
#view {
  flex: 1;
  display: flex;
  flex-direction: column;
}

/* Header — the same on every screen (HOME-5169 §3): mark centred, 26/600 + 16/400, left-aligned */
.brand {
  padding-bottom: 30px;
  padding-bottom: clamp(16px, 3.6dvh, 30px);
} /* 30 on a phone (≥834px tall), less on a short screen (L12); px first for engines without dvh */
/* HOME-7199: the H mark, one full-colour asset in light AND dark (no per-mode tint, no glow). It sits in a
   square box scaled to fit — the art is 1.306:1, so the 34 header box shows it at 34 × 26 and the 32
   forgot-password box (.logo.sm) at 32 × 24.5. The row is the box's height; the title starts below it. */
.logo {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 34px;
  margin-bottom: 16px;
}
.logo img {
  display: block;
  width: 34px;
  height: auto;
}
.logo.sm {
  height: 32px;
}
.logo.sm img {
  width: 32px;
}
h1 {
  font-size: 26px;
  font-weight: 600;
  letter-spacing: -0.02em;
  margin: 0;
  line-height: 1.12;
  color: var(--ink);
}
.sub {
  font-size: 16px;
  font-weight: 400;
  color: var(--sub);
  margin: 7px 0 0;
  line-height: 1.45;
}
/* Each screen's own heading: eyebrow 12.5/600 · section title 20/600 · body 15/400 */
.sectitle {
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0;
  color: var(--ink);
}
.eyebrow {
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--sub);
  margin-bottom: 6px;
}
.intro,
.dest {
  font-size: 15px;
  line-height: 1.5;
  color: var(--sub);
  margin: 8px 0 6px;
}
.dest b {
  color: var(--ink);
  font-weight: 600;
}
/* Where a code went (HOME-5773): a phone number never breaks inside itself ("+1 (212) / 555-0123" at
   375px in Spanish); a masked email may break anywhere, so a long domain cannot overflow the card. */
.destnum {
  white-space: nowrap;
}
.destmail {
  overflow-wrap: anywhere;
}

/* Glass card */
.card {
  margin-top: 22px;
  background: var(--card);
  border: 1px solid var(--sheet-border);
  border-radius: 22px;
  padding: 20px;
  box-shadow: var(--card-shadow);
  backdrop-filter: blur(26px) saturate(160%);
}

/* Segmented control */
.seg {
  display: flex;
  gap: 4px;
  padding: 4px;
  border-radius: 13px;
  background: var(--seg-bg);
  border: 1px solid var(--sep);
}
.seg button {
  flex: 1;
  height: 38px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  cursor: pointer;
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--sub);
  transition: all 0.15s;
}
.seg button.on {
  background: var(--seg-on);
  color: var(--ink);
  box-shadow: var(--seg-on-shadow);
}

/* Verification-code Phone ↔ Email inline toggle link (HOME-1830) — 15/600 (HOME-5169) */
/* L6: the design puts sign in's T&C row 42px under the helper line (18 + the link + 6) — the row below this
   one had 14px more (a 4px bottom here + the consent row's own 10). The 36px row keeps the link's touch height. */
.togglerow {
  margin: 6px 0 0;
  min-height: 36px;
}
.togglerow + .consent {
  margin-top: 0;
}
.linktoggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  padding: 6px 0;
  background: none;
  border: 0;
  cursor: pointer;
  font-family: inherit;
  font-size: 15px;
  font-weight: 600;
  color: var(--accent);
}
.linktoggle svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

/* Fields — label 13/600 (sign in's own label 15/600) */
.lab {
  display: block;
  font-size: 13px;
  font-weight: 600;
  color: var(--sub);
  margin: 14px 0 8px;
}
.lab-lg {
  font-size: 15px;
  margin: 22px 0 9px;
}
.field {
  height: 50px;
  border-radius: 12px;
  background: var(--field);
  border: 1px solid var(--field-border);
  display: flex;
  align-items: center;
  padding: 0 14px;
  gap: 10px;
}
.field:focus-within,
.field.open {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
/* An errored field is outlined in the warning colour, cleared with its message (HOME-5169 §3) */
.field.bad {
  border-color: var(--warn);
  box-shadow: none;
}
.field input {
  flex: 1;
  min-width: 0;
  font-size: 16px;
  color: var(--ink);
  background: transparent;
  border: 0;
  outline: none;
  font-family: inherit;
  caret-color: var(--accent);
}
#phfield input,
#emfield input {
  font-size: 15.5px;
}
.field input::placeholder {
  color: var(--faint);
}
.field .ic {
  color: var(--faint);
  display: flex;
  flex-shrink: 0;
}
/* Password show/hide eye toggle */
.eye {
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  display: flex;
  flex-shrink: 0;
  cursor: pointer;
  color: var(--faint);
}
.eye.on {
  color: var(--accent);
}
.dialcode {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 15.5px;
  font-weight: 600;
  color: var(--ink);
  padding: 0 11px 0 0;
  margin: 0;
  border: 0;
  border-right: 1px solid var(--field-border);
  height: 24px;
  background: none;
  font-family: inherit;
  cursor: pointer;
  flex-shrink: 0;
}
.dialcode .flag {
  font-size: 17px;
  line-height: 1;
}
.dialcode:hover {
  color: var(--accent);
}

/* Country dial-code picker */
.ccbackdrop {
  position: fixed;
  inset: 0;
  z-index: 200;
}
/* L9: the design's 16px corners and #0E1626, and its 232px cap on the LIST (the search sits above it) */
.ccmenu {
  position: fixed;
  z-index: 201;
  display: flex;
  flex-direction: column;
  background: var(--menu-bg);
  border: 1px solid var(--menu-border);
  border-radius: 16px;
  overflow: hidden;
  box-shadow: var(--menu-shadow);
}
/* Focused on open (L10) so keyboard / screen-reader users land in the picker: no ring after a tap, a
   ring when the keyboard brought focus here (:focus-visible — review cycle 2). */
.ccmenu:focus {
  outline: none;
}
.ccmenu:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.ccsearch {
  border: 0;
  outline: none;
  background: var(--search-bg);
  color: var(--ink);
  font-family: inherit;
  font-size: 14px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--sep);
  caret-color: var(--accent);
}
.ccsearch::placeholder {
  color: var(--faint);
}
.cclist {
  overflow-y: auto;
  max-height: 232px;
}
.ccrow {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  cursor: pointer;
  font-size: 14px;
  color: var(--ink);
}
.ccrow:hover {
  background: var(--row-hover);
}
.ccrow.active {
  background: var(--accent-soft);
} /* the selected country has a cyan tint (screen 11) */
.ccrow .flag {
  font-size: 18px;
  line-height: 1;
  flex-shrink: 0;
}
.ccrow .nm {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ccrow .dial {
  color: var(--sub);
  font-weight: 600;
}
.ccempty {
  padding: 16px 14px;
  font-size: 13px;
  color: var(--faint);
  text-align: center;
}

/* Row: remember + forgot */
.row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin: 14px 0 18px;
}
.row.end {
  justify-content: flex-end;
  margin: 4px 0 18px;
}
.remember {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--sub);
  cursor: pointer;
  user-select: none;
}
.box {
  width: 18px;
  height: 18px;
  border-radius: 5px;
  border: 1.5px solid var(--field-border);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--accent-text);
  transition: background 0.15s;
}
.box.on {
  background: var(--accent);
  border-color: transparent;
}
.linkaccent {
  font-size: 13px;
  color: var(--accent);
  font-weight: 600;
  cursor: pointer;
  background: none;
  border: 0;
  font-family: inherit;
  padding: 0;
}

/* Primary button — HOME-5169 §3: 54 high, radius 16, 16/600 */
.btn {
  width: 100%;
  height: 54px;
  border: 0;
  border-radius: var(--btn-radius);
  cursor: pointer;
  margin-top: 2px;
  background: var(--accent-grad);
  color: var(--accent-text);
  font-family: inherit;
  font-size: 16px;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  box-shadow: var(--btn-shadow);
  transition:
    transform 0.12s,
    opacity 0.2s;
}
.btn:active {
  transform: scale(0.985);
}
/* Disabled (the resend cooldown): dark dims the gradient; light greys it out (the design's #E3E5EA). A
   request in flight keeps the gradient in both modes, so its spinner stays readable. */
.btn[disabled] {
  opacity: var(--btn-disabled-opacity);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
  cursor: default;
  box-shadow: none;
}
.btn.loading[disabled] {
  opacity: 0.5;
  background: var(--accent-grad);
  color: var(--accent-text);
}

/* T&C consent row (HOME-1718). HOME-5572: the whole row is the control (≥44px tall), and its error
   sits BELOW it, indented under the sentence, in a slot reserved whether or not it shows. */
.consent {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 10px 0 0;
  min-height: 44px;
}
.consent .box {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border-radius: 6px;
  border-width: 2px;
  cursor: pointer;
  background: transparent;
  padding: 0;
}
.consent .box.on {
  background: var(--accent);
}
.consent .box svg {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
} /* the design's I.check s:14 (L9) — checksm's own 12px read too small; flex-shrink:0 stops the flex box squeezing its width */
.consent.invalid .box {
  border-color: var(--warn);
}
.consenttext {
  font-size: 15px;
  line-height: 1.5;
  color: var(--sub);
  cursor: pointer;
}
.consenttext .linkaccent {
  font-size: 15px;
  text-decoration: none;
}
.err.consenterr {
  display: block;
  min-height: 20px;
  margin: 2px 0 14px 32px;
  font-size: 13px;
}

/* In-app legal-doc overlay (Terms & Conditions) — device BACK closes it and returns to sign-in (HOME-1718) */
.legaldoc {
  position: fixed;
  inset: 0;
  z-index: 300;
  background: var(--body);
  display: flex;
  flex-direction: column;
}
.legaltop {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--sep);
  flex-shrink: 0;
}
.legalback {
  background: none;
  border: 0;
  padding: 4px;
  margin: -4px;
  display: flex;
  color: var(--ink);
  cursor: pointer;
}
.legaltitle {
  font-size: 16px;
  font-weight: 600;
  color: var(--ink);
}
.legalframe {
  flex: 1;
  width: 100%;
  border: 0;
  background: #fff;
}

/* Divider */
.or {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 16px 2px;
}
.or .ln {
  flex: 1;
  height: 1px;
  background: var(--sep);
}
.or span {
  font-size: 12px;
  color: var(--faint);
}

/* Secondary — HOME-5169 §3: 54 high, radius 16, transparent, 1px .14 (L9), 16/600 (Try free 15.5/600) */
.btn2 {
  width: 100%;
  height: 54px;
  border-radius: var(--btn-radius);
  border: 1px solid var(--btn2-border);
  background: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  color: var(--ink);
  font-weight: 600;
  font-size: 16px;
  font-family: inherit;
  cursor: pointer;
  margin-top: 12px;
}
.btn2:active {
  background: var(--press);
}
.btn2 svg {
  color: var(--accent);
}
.btn2.trybtn {
  font-size: 15.5px;
  margin-top: 0;
  border: var(--trybtn-border);
}
/* "Sign up for temporary access" under the Just subscribed? card (HOME-6711): the design's own 52px outline
   button — a variant, so every other outline button keeps HOME-5169's 54. */
.btn2.cardcta {
  height: 52px;
  margin-top: 14px;
}
/* HOME-6711: "number not found" ended in place (an edit, Send a new code) — the card and its CTA leave. */
.subcard.gone,
.btn2.cardcta.gone {
  display: none;
}

/* Sign in's footer: "New to Helm?" + Try free, at the bottom of the screen */
.signupfoot {
  margin-top: auto;
  padding-top: 22px;
  border-top: 1px solid var(--sep);
  text-align: center;
}
.signupfoot p {
  font-size: 15px;
  color: var(--sub);
  margin: 0 0 14px;
}
.btn:has(+ .signupfoot) {
  margin-bottom: 28px;
} /* at least this much air when the screen is short */

/* OTP — one autofillable input rendered as six boxes (HOME-2160). The boxes are display-only; the
   visually-hidden .otpfield is the real one-time-code input that owns the value, caret, paste and the
   OS SMS-code autofill. A single field (vs. six separate boxes) is what lets the in-app WebView
   surface the keyboard's SMS-code suggestion again. */
.otp {
  display: flex;
  gap: 9px;
  margin-bottom: 18px;
  position: relative;
}
.otpcell {
  flex: 1;
  width: 0;
  height: 56px;
  border-radius: 13px;
  background: var(--field);
  border: 1.5px solid var(--field-border);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 22px;
  font-weight: 600;
  color: var(--ink);
  font-family: inherit;
  cursor: text;
  transition:
    border-color 0.12s,
    box-shadow 0.12s;
}
.otpcell.filled {
  border-color: var(--otp-filled);
}
.otpcell.active {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
/* A wrong / expired code: every box in the warning colour, no focus glow (HOME-5169 screens 4/5) */
.otp.warn .otpcell,
.otp.warn .otpcell.active,
.otp.warn .otpcell.filled {
  border-color: var(--warn);
  box-shadow: none;
}
.otp {
  margin-bottom: 0;
}
.otpfield {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  outline: none;
  background: transparent;
  color: transparent;
  caret-color: transparent;
  font: inherit;
}

/* Helper / hint text — body 15/400 */
.hint {
  font-size: 15px;
  color: var(--sub);
  line-height: 1.55;
  margin: 0 2px 0;
}
.center {
  text-align: center;
  margin-top: 14px;
  font-size: 14.5px;
  color: var(--sub);
}
.center .linkaccent {
  font-size: 14.5px;
}
.linkaccent[disabled] {
  color: var(--faint);
  cursor: default;
}

/* Reserved message slots (HOME-5572): the space under a field is there whether or not its error is,
   so an error never pushes the screen down. On sign in the slot is SHARED with the helper line, which
   the error replaces — directly under the field (signin/06 had it under Send code). */
.slot {
  min-height: 47px;
  margin: 8px 0 0;
}
.slot1 {
  min-height: 20px;
  margin: 4px 0 0;
}
.slot1 + .lab {
  margin-top: 10px;
} /* the reserved slot already spaces the next field */
.slot .err {
  margin: 0;
}
.slot .err.show + .hint {
  display: none;
}
#view > .hint {
  margin-top: 10px;
}
.invisible {
  visibility: hidden;
}

/* L12 (HOME-6235): sign-up's contact details is the one screen taller than a phone — three fields, each with
   its reserved error slot (HOME-5572), and the T&C row (D3): 913px of page on a 393×852 screen. Below 952px
   of height its gaps shrink linearly, from the values above (≥952px) to compact ones reached at 852px, so it
   fits there at rest (English; the longer Spanish copy scrolls a little). Shorter still — a small phone, the
   keyboard — they stay compact and the page scrolls. Every value: clamp(compact, compact + (100dvh − 852px)
   × slope, full), slope = (full − compact) / 100. Sign in and the code step fit as they are. */
body:has(#nmfield) {
  padding-bottom: clamp(16px, 16px + (100dvh - 852px) * 0.12, 28px);
}
.wrap:has(#nmfield) .brand {
  padding-bottom: clamp(20px, 20px + (100dvh - 852px) * 0.1, 30px);
}
#view:has(#nmfield) .lab {
  margin-top: clamp(10px, 10px + (100dvh - 852px) * 0.04, 14px);
  margin-bottom: clamp(6px, 6px + (100dvh - 852px) * 0.02, 8px);
}
#view:has(#nmfield) .slot1 {
  margin-top: clamp(2px, 2px + (100dvh - 852px) * 0.02, 4px);
}
#view:has(#nmfield) .slot1 + .lab {
  margin-top: clamp(6px, 6px + (100dvh - 852px) * 0.04, 10px);
} /* ≥4px under a shown error */
#view:has(#nmfield) > .hint {
  margin-top: clamp(4px, 4px + (100dvh - 852px) * 0.06, 10px);
}
#view:has(#nmfield) .consent {
  margin-top: clamp(2px, 2px + (100dvh - 852px) * 0.08, 10px);
}
#view:has(#nmfield) .err.consenterr {
  margin-bottom: clamp(8px, 8px + (100dvh - 852px) * 0.06, 14px);
}
#view:has(#nmfield) .btn2 {
  margin-top: clamp(8px, 8px + (100dvh - 852px) * 0.04, 12px);
}

/* "A new code has been sent" — its row is rendered before any resend; hidden, it takes no space (below) */
.banner {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  margin-top: 14px;
  padding: 11px 14px;
  border-radius: 12px;
  background: var(--success-soft);
  color: var(--ink);
  font-size: 14.5px;
  line-height: 1.45;
}
.banner svg {
  color: var(--success);
  flex-shrink: 0;
  margin-top: 2px;
}
/* HOME-6517: the design shows the banner only after a resend, with Change phone number 12px under Send a new
   code. `visibility:hidden` kept the hidden banner's box — a ~60px hole between the links — so hidden, it
   takes no space; its row stays in the markup. */
.banner.invisible {
  display: none;
}
.center[data-row="resend"] {
  margin-top: 16px;
}
.banner + .center[data-row="change"] {
  margin-top: 12px;
}

/* "Just subscribed?" card — on the phone no-account state since HOME-6689 (HOME-5169 screen 4 had it on a wrong code) */
.subcard {
  margin-top: 18px;
  padding: 16px 18px;
  border-radius: 16px;
  background: var(--card2);
  border: 1px solid var(--sheet-border);
}
.subcardtitle {
  font-size: 15.5px;
  font-weight: 600;
  color: var(--ink);
}
.subcardtext {
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--ink);
  opacity: 0.85;
  margin-top: 6px;
}

/* HOME-6762: contact details' Try again (the reuse path) — its error takes the hint's row, where the hint sits */
#view:has(#nmfield) > #retryerr {
  margin: clamp(4px, 4px + (100dvh - 852px) * 0.06, 10px) 2px 0;
}
.noacct {
  margin: 14px 0 18px;
}

/* Footer */
.foot {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  font-size: 11.5px;
  color: var(--sub);
  margin-top: 22px;
}
.foot svg {
  flex-shrink: 0;
}

/* Error — one solid colour at Regular weight, no icon, no container (HOME-1358). HOME-5169 §3 sets
   it: #FFB454, 14.5/400, directly under its field. */
.err {
  display: none;
  margin-top: 12px;
  color: var(--warn);
  font-weight: 400;
  font-size: 14.5px;
  line-height: 1.45;
}
.err.show {
  display: block;
}
/* Per-field variant: rendered directly under its input (Password / 6-digit code) */
.fielderr {
  margin-top: 8px;
}

/* Spinner / states */
.spinner {
  width: 18px;
  height: 18px;
  border: 2.4px solid var(--spinner-track);
  border-top-color: var(--accent-text);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
  display: none;
}
.btn.loading .spinner {
  display: inline-block;
}
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
@keyframes pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.35;
  }
}
.statebox {
  padding: 24px 6px 8px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
.bigspin {
  width: 44px;
  height: 44px;
  border: 3px solid var(--accent-soft);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
.checkmark {
  width: 62px;
  height: 62px;
  border-radius: 50%;
  background: var(--success-soft);
  color: var(--success);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 0 0 6px var(--success-soft);
}
.statetitle {
  font-size: 18px;
  font-weight: 600;
  color: var(--ink);
  margin-top: 20px;
  letter-spacing: -0.01em;
}
.statesub {
  font-size: 13px;
  color: var(--sub);
  margin-top: 8px;
  line-height: 1.45;
  max-width: 240px;
}

/* Back chevron (forgot overlay) */
.back {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--field);
  border: 1px solid var(--field-border);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--accent);
  cursor: pointer;
  margin-bottom: 8px;
}
/* Reset-screen error / mismatch — below the Confirm password field, #E0A44D Regular (HOME-1358) */
.warnmsg {
  min-height: 16px;
  font-size: 13px;
  font-weight: 400;
  color: var(--warnmsg);
  margin-bottom: 8px;
  line-height: 1.4;
}
.hidden {
  display: none !important;
}

/* Password-rules checklist (forgot → reset) */
.pwrules {
  list-style: none;
  margin: 0 0 16px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.pwrules li {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--sub);
  transition: color 0.2s;
}
.pwrules li .dot {
  width: 17px;
  height: 17px;
  border-radius: 50%;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--field);
  position: relative;
  transition: all 0.2s;
}
.pwrules li .dot::before {
  content: "";
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--faint);
}
.pwrules li.ok {
  color: var(--ink);
}
.pwrules li.ok .dot {
  background: var(--success-soft);
}
.pwrules li.ok .dot::before {
  content: "";
  width: 9px;
  height: 9px;
  background: none;
  border-right: 2.4px solid var(--success);
  border-bottom: 2.4px solid var(--success);
  transform: rotate(45deg) translate(-1px, -1px);
  border-radius: 0;
}

/* Biometric (Face ID / fingerprint) scanning overlay */
.bioback {
  position: fixed;
  inset: 0;
  z-index: 80;
  background: rgba(0, 0, 0, 0.22);
  animation: fade 0.3s ease both;
}
.biopod {
  position: fixed;
  top: 14px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 90;
  width: 108px;
  height: 30px;
  border-radius: 18px;
  background: #000;
  overflow: hidden;
  transition:
    width 0.44s cubic-bezier(0.2, 0.9, 0.3, 1.25),
    height 0.44s cubic-bezier(0.2, 0.9, 0.3, 1.25),
    border-radius 0.44s cubic-bezier(0.2, 0.9, 0.3, 1.25);
}
.biopod.open {
  width: 122px;
  height: 108px;
  border-radius: 34px;
  box-shadow: 0 14px 36px rgba(0, 0, 0, 0.5);
}
.biocam {
  position: absolute;
  top: 9px;
  right: 12px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #2b3a4a, #05080c);
  box-shadow: inset 0 0 2px rgba(120, 160, 200, 0.6);
  transition: all 0.44s;
}
.biopod.open .biocam {
  top: 13px;
  right: 16px;
}
.bioglyph {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #30d158;
  opacity: 0;
  transition: opacity 0.25s ease;
}
.biopod.open .bioglyph {
  opacity: 1;
}
.bioglyph .glyph {
  filter: drop-shadow(0 0 10px rgba(48, 209, 88, 0.4));
}
.bioglyph.scanning {
  animation: bioPulse 1.5s ease-in-out infinite;
}
.bioscan {
  display: none;
}
.bioglyph.scanning .bioscan {
  display: block;
  position: absolute;
  left: 38%;
  right: 38%;
  top: 32%;
  height: 5px;
  border-radius: 6px;
  background: linear-gradient(#30d15800, #30d158, #30d15800);
  box-shadow: 0 0 12px 2px rgba(48, 209, 88, 0.7);
  animation: bioScan 1.5s cubic-bezier(0.5, 0, 0.5, 1) infinite;
}
.biocheck {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: 2.6px solid #30d158;
  color: #30d158;
  display: flex;
  align-items: center;
  justify-content: center;
  animation: bioPop 0.5s cubic-bezier(0.2, 0.9, 0.3, 1.4) both;
}
.biocheck svg {
  width: 26px;
  height: 26px;
}
.biofallback {
  position: fixed;
  bottom: 30px;
  left: 0;
  right: 0;
  z-index: 90;
  text-align: center;
  background: none;
  border: 0;
  font-family: inherit;
  font-size: 15px;
  font-weight: 600;
  color: var(--accent);
  cursor: pointer;
}
@keyframes fade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
@keyframes bioPulse {
  0%,
  100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.04);
  }
}
@keyframes bioScan {
  0% {
    transform: translateY(-220%);
    opacity: 0;
  }
  12% {
    opacity: 1;
  }
  88% {
    opacity: 1;
  }
  100% {
    transform: translateY(220%);
    opacity: 0;
  }
}
@keyframes bioPop {
  0% {
    transform: scale(0.4);
    opacity: 0;
  }
  55% {
    transform: scale(1.12);
    opacity: 1;
  }
  100% {
    transform: scale(1);
    opacity: 1;
  }
}

/* Passkey enrollment bottom sheet (offer → enrolling → done) */
.enrollback {
  position: fixed;
  inset: 0;
  z-index: 70;
  background: rgba(4, 7, 14, 0.5);
  animation: fade 0.3s ease both;
}
.enrollsheet {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 71;
  max-width: 430px;
  margin: 0 auto;
  background: var(--sheet-bg);
  backdrop-filter: blur(26px) saturate(160%);
  -webkit-backdrop-filter: blur(26px) saturate(160%);
  border-top: 1px solid var(--sheet-border);
  border-radius: 26px 26px 0 0;
  box-shadow: var(--sheet-shadow);
  padding: 10px 26px 38px;
  text-align: center;
  animation: sheetUp 0.42s cubic-bezier(0.2, 0.8, 0.25, 1) both;
}
.enrollsheet .grab {
  width: 38px;
  height: 5px;
  border-radius: 3px;
  background: var(--grab);
  margin: 6px auto 14px;
}
.enrollglyph {
  width: 96px;
  height: 96px;
  border-radius: 26px;
  background: var(--accent-soft);
  color: var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 6px auto 0;
}
.enrolltitle {
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin-top: 22px;
}
.enrollsub {
  font-size: 14.5px;
  color: var(--sub);
  line-height: 1.5;
  margin: 9px auto 0;
  max-width: 300px;
}
.enrollnote {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  font-size: 12px;
  color: var(--faint);
  margin: 16px 0 22px;
}
.enrollnote svg {
  width: 13px;
  height: 13px;
  flex-shrink: 0;
}
.enrollskip {
  display: block;
  width: 100%;
  margin-top: 14px;
  background: none;
  border: 0;
  font-family: inherit;
  font-size: 15.5px;
  font-weight: 600;
  color: var(--sub);
  cursor: pointer;
  padding: 6px 0;
}
.enrollring {
  position: relative;
  width: 120px;
  height: 120px;
  margin: 8px auto 0;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--accent);
  border: 2px solid var(--accent-soft);
  animation: bioPulse 1.5s ease-in-out infinite;
}
.enrollring::before {
  content: "";
  position: absolute;
  inset: -2px;
  border-radius: 50%;
  border: 2px solid transparent;
  border-top-color: var(--accent);
  animation: spin 1.1s linear infinite;
}
.enrollring .glyph {
  filter: drop-shadow(0 0 10px var(--accent-soft));
}
#enrollbody .checkmark {
  margin: 6px auto 0;
}
.enrolltaking {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-size: 13px;
  color: var(--sub);
  margin-top: 18px;
}
.spinner2 {
  width: 14px;
  height: 14px;
  border: 2px solid var(--accent-soft);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
  display: inline-block;
}
@keyframes sheetUp {
  from {
    transform: translateY(102%);
  }
  to {
    transform: translateY(0);
  }
}
