/* The redesigned sign-in / request-access screen (design 16 Sept 2026, owner’s corrections in the brief).
   Loaded after login.css and applied to #entry once entry.js has rebuilt it (<main id="entry" class="entry entry2">).
   Everything here is scoped to .entry2, so the old rules in login.css stay inert rather than fighting these.

   Two rules shape the whole file:
   - The screen is one viewport tall. Signup uses one full-width row per field without scrolling.
     The promise panel yields to smaller windows.
   - Colours are the website’s, not the app’s navy: --accent is #315fe5 in tokens.css already. */

.entry.entry2 {
  height: 100dvh;
  min-height: 0;
  overflow: hidden;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  background: var(--card);
  --e-gap: 18px;
  --e-field: 48px;
  --e-otp-box: 52px;
  --e-otp-space: 12px;
  --e-card: 430px; /* DocVoc Redesign: one column width in every state the form fills on its own (source 161) */
}

/* ---- the promise panel (left) ------------------------------------------------------------------------------ */
/* DocVoc Redesign (23 Sept, source 139-158): one flex column, the design’s own 52px/60px padding and 26px gap between
   the brand, the headline, the sub and the points — nothing else in the column, nothing measured or pinned. */
.entry2 .e-panel {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
  gap: 26px;
  padding: 52px 60px;
  background: var(--row-highlight);
  border-right: 1px solid var(--border);
  color: var(--ink);
}
.entry2 .brand { display: flex; flex-direction: row; align-items: center; gap: 10px; color: var(--ink); font-size: var(--text-appbar); font-weight: var(--weight-brand); letter-spacing: var(--track-h1); text-decoration: none; }
.entry2 .brand img { border-radius: 9px; }
.entry2 .e-panel > .brand img { width: 32px; height: 32px; border-radius: 8px; }
.entry2 .e-panel > .brand { font-size: 18px; font-weight: 700; letter-spacing: -.02em; }
.entry2 .e-eyebrow { display: flex; flex-direction: row; align-items: center; gap: 9px; margin: 0 0 18px; color: var(--secondary); font-size: var(--text-meta); font-weight: 600; letter-spacing: .14em; text-transform: uppercase; }
/* The dot is the shared .eyebrow motif from controls.css, whose `> span` rule draws every span as the dot: the label
   beside it has to say it is text. */
.entry2 .e-eyebrow > span:first-child { margin-right: 0; flex: none; }
.entry2 .e-eyebrow > span + span { width: auto; height: auto; margin: 0; border-radius: 0; background: none; }
/* "number" is part of the word beside it, not a second item in the row, so it must not take the row’s gap. */
.entry2 .e-wide { display: inline; }
.entry2 .e-headline { margin: 0; font-size: 52px; font-weight: 700; line-height: 1.02; letter-spacing: -.04em; max-width: 9ch; }
.entry2 .e-sub { margin: 0; max-width: 42ch; color: var(--secondary); font-size: 15.5px; line-height: 1.6; }
.entry2 .e-points { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--border); max-width: 46ch; }
.entry2 .e-points li { display: grid; grid-template-columns: 20px 1fr; gap: 13px; padding: 15px 0; border-bottom: 1px solid var(--row-border); border-top: 0; }
.entry2 .e-points li::before { content: none; }
.entry2 .e-points strong { display: block; font-size: 14.5px; font-weight: 600; color: var(--ink); line-height: 1.4; }
.entry2 .e-points span { display: block; margin-top: 3px; font-size: 13.5px; color: var(--secondary); line-height: 1.5; }
/* The one reassurance the recovery and request states carry: nothing already recorded is at risk. */
.entry2 .e-reassure { margin: 26px 0 0; padding: 14px 18px; border-radius: var(--radius-card); background: var(--card); color: var(--secondary); font-size: var(--text-ui); line-height: 1.5; display: flex; flex-direction: row; gap: 10px; align-items: flex-start; }
.entry2 .e-reassure::before { content: ''; width: 8px; height: 8px; margin-top: 7px; border-radius: 50%; background: var(--signed-accent); flex: none; }

/* ---- the form column (right) -------------------------------------------------------------------------------- */
/* The design’s own padding (source 160), matching the left panel’s so both columns share one inset (INPUT-047). */
.entry2 .e-form { display: flex; flex-direction: column; align-items: center; justify-content: center; min-width: 0; min-height: 0; padding: 52px 60px; }
.entry2 .e-mobile-brand { display: none; }
/* The legacy names (.auth-card, .auth-heading, .entry-form, .auth-terms) are kept on this markup because android.js
   pages the card by them and two suites reach for them; the spacing they carry in login.css is replaced here. */
.entry2 #unlock-form { width: 100%; max-width: var(--e-card); margin: 0; padding: 0; display: flex; flex-direction: column; }
.entry2 .e-back { align-self: flex-start; margin: 0 0 16px; padding: 0; min-height: 0; border: 0; background: none; color: var(--accent-text); font-size: var(--text-ui); font-weight: 500; cursor: pointer; }
.entry2 .e-back:hover { background: none; text-decoration: underline; text-underline-offset: 3px; }
.entry2 .e-heading { margin: 0 0 var(--form-heading-gap); }
.entry2 .e-heading-row { display: flex; flex-direction: row; align-items: flex-start; justify-content: space-between; gap: 16px; }
.entry2 #entry-title { margin: 0; font-size: var(--text-page-heading); font-weight: var(--weight-heading); line-height: 1.18; letter-spacing: var(--track-h1); color: var(--ink); }
.entry2 #entry-description { margin: 10px 0 0; color: var(--muted); font-size: var(--text-ui); line-height: 1.55; }
.entry2 #entry-description:empty { display: none; }
/* Request access / Sign in instead. It is the same control app.js already drives; the pill sits beside the title
   while creating an account (source 244-268 has no switcher, so this is the product’s own need, kept quiet). */
.entry2 #signup-switch { flex: none; min-height: 36px; padding: 0 14px; border-radius: 999px; border: 1px solid var(--border); background: var(--card); color: var(--ink); font-size: var(--text-secondary); font-weight: 600; white-space: nowrap; }
.entry2[data-state="signup"] .e-heading-row { flex-wrap: wrap; gap: 8px; }
.entry2[data-state="signup"] #entry-title { white-space: nowrap; }
/* Signin keeps the same way in, but as one plain line under the footnote — not a pill beside the title and a second
   "New clinic?" card (design source 168-198 shows neither; owner correction, 16 Sept, superseded 22 Sept). */
/* order:6 keeps it after .e-terms (order:5) wherever #unlock-form’s children share one flex context (some widths
   flatten .e-alt into it, above); within .e-heading-row it only means "after the title", which is already where it sits. */
.entry2[data-state="signin"] #signup-switch { order: 6; align-self: center; margin-top: 10px; min-height: 0; padding: 0; border: 0; border-radius: 0; background: none; color: var(--accent-text); font-size: 13px; font-weight: 500; }
.entry2[data-state="signin"] #signup-switch:hover { background: none; text-decoration: underline; text-underline-offset: 3px; }

/* ---- fields -------------------------------------------------------------------------------------------------- */
.entry2 .e-fields { display: flex; flex-direction: column; gap: var(--e-gap); }
.entry2 .e-fields label, .entry2 .e-label { display: block; margin: 0; color: var(--secondary); font-size: var(--text-ui); font-weight: 500; line-height: 1.4; }
.entry2 .e-fields label > input { margin-top: var(--field-label-gap); }
.entry2 .e-fields label > .e-inputwrap { margin-top: var(--field-label-gap); }
.entry2 .e-label { margin-bottom: var(--field-label-gap); }
.entry2 .e-fields input[type="text"], .entry2 .e-fields input[type="email"], .entry2 .e-fields input[type="password"], .entry2 .e-fields input[type="tel"] {
  width: 100%; height: var(--e-field); min-height: var(--e-field); padding: 0 14px; border: 1px solid var(--input-border); border-radius: 10px;
  background: var(--input-bg); color: var(--ink); font: inherit; font-size: var(--text-ui); font-weight: 400;
}
.entry2 .e-fields input::placeholder { color: var(--hint); opacity: 1; }
.entry2 .e-fields input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--focus-ring); }
.entry2 .e-fields input.invalid { border-color: var(--danger); box-shadow: 0 0 0 3px color-mix(in srgb, var(--danger) 18%, transparent); }
.entry2 .e-field-error { height: 1.45em; margin: 8px 0 0; color: var(--danger); font-size: var(--text-secondary); line-height: 1.45; }
.entry2 .e-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.entry2 .e-contact-group, .entry2 .e-password-group { display: contents; }
.entry2[data-state="signup"] .e-contact-group, .entry2[data-state="signup"] .e-password-group {
  display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--e-gap);
  border-top: 1px solid var(--border); padding-top: 16px;
}
.entry2[data-state="signup"] .e-phone .e-cc select { max-width: 98px; }
/* India is the default; the selector supports international phone numbers. */
.entry2 .e-phone { display: grid; grid-template-columns: auto 1fr; gap: 8px; }
.entry2 .e-phone .e-cc { display: inline-flex; align-items: center; justify-content: center; min-height: var(--e-field); padding: 0 8px 0 12px; border-radius: 10px; background: var(--accent-tint); color: var(--secondary); font-size: var(--text-ui); font-weight: 600; }
.entry2 .e-phone .e-cc select { max-width: 132px; border: 0; background: transparent; color: inherit; font: inherit; cursor: pointer; }
/* Password. "Forgot password?" reads beside the label but follows the field in the DOM, so the keyboard goes
   password -> Show -> forgot password -> sign in (test_verification_entry_browser.cjs asserts that order). */
.entry2 .e-password { display: grid; grid-template-columns: 1fr auto; align-items: baseline; column-gap: 12px; }
.entry2 .e-password > label { grid-area: 1 / 1; margin-bottom: var(--field-label-gap); }
.entry2 .e-password > #forgot-password { grid-area: 1 / 2; justify-self: end; }
.entry2 .e-password > .e-inputwrap { grid-area: 2 / 1 / auto / -1; position: relative; }
.entry2 .e-password > #password-rule { grid-area: 3 / 1 / auto / -1; }
.entry2 #forgot-password { padding: 0; min-height: 0; border: 0; background: none; color: var(--accent-text); font-size: var(--text-secondary); font-weight: 500; text-decoration: none; cursor: pointer; }
.entry2 #forgot-password:hover { background: none; text-decoration: underline; text-underline-offset: 3px; }
.entry2 .e-fields .e-inputwrap input { padding-right: 52px; }
.entry2 #confirm-password-field .e-inputwrap { position: relative; }
.entry2 .e-show { position: absolute; right: 8px; top: 0; height: var(--e-field); padding: 0 8px; min-height: 0; border: 0; background: none; color: var(--accent-text); font-size: var(--text-secondary); font-weight: 600; cursor: pointer; }
.entry2 .e-show { width: 42px; padding: 0; font-size: 18px; }
.entry2 .e-show:hover { background: none; }
.entry2 .e-show:disabled { cursor: default; opacity: .45; }
.entry2 .e-show svg { display: block; margin: auto; pointer-events: none; }
.entry2 .e-show .eye-slash { display: none; }
.entry2 .e-show[aria-pressed="true"] .eye-slash { display: block; }
.entry2 #password-rule, .entry2 #confirm-password-error { height: 2.9em; margin: 8px 0 0; font-size: var(--text-secondary); line-height: 1.45; }
.entry2 #password-rule { color: var(--muted); }
.entry2 #password-rule.invalid { color: var(--danger); }
.entry2 .e-notice { height: 124px; display: flex; flex-direction: column; flex: none; }
.entry2[data-state="signup"] .e-notice { height: 104px; }

/* ---- the code field ------------------------------------------------------------------------------------------- */
/* DocVoc Redesign (source 200-211): one field, not six painted boxes — the design’s own mono, wide-spaced, centred
   digits on the same field every other input uses. */
.entry2 .e-otp { position: relative; }
.entry2 .e-fields #otp-code { font-family: var(--font-mono); font-size: 19px; font-weight: 500; letter-spacing: .5em; text-align: center; font-variant-numeric: tabular-nums; padding-left: calc(13px + .5em); caret-color: var(--accent); }
/* Expiry and resend sit in one row under Sign in (source 206-209), not under the field. */
.entry2 .e-code-row { display: flex; flex-direction: row; align-items: center; justify-content: space-between; gap: 12px; margin-top: 12px; font-size: var(--text-secondary); color: var(--secondary); }
.entry2 #otp-expiry { font-variant-numeric: tabular-nums; }
.entry2 #otp-resend { padding: 0; min-height: 0; border: 0; background: none; color: var(--accent-text); font-size: var(--text-secondary); font-weight: 600; font-variant-numeric: tabular-nums; cursor: pointer; }
.entry2 #otp-resend:hover:not(:disabled) { background: none; text-decoration: underline; text-underline-offset: 3px; }
.entry2 #otp-resend:disabled { opacity: 1; color: var(--hint); cursor: default; }
/* A thumb needs more than the line of text it sits in. */
@media (max-width: 860px), (max-height: 779px) { .entry2 #otp-resend { min-height: 44px; padding: 0 6px; margin: -12px -6px; } }

/* ---- the primary button, the message, and the ways out ------------------------------------------------------- */
.entry2 #unlock { width: 100%; min-height: 52px; margin-top: 24px; border: 0; border-radius: 10px; background: var(--accent); color: var(--on-accent); font-size: var(--text-patient); font-weight: 600; white-space: nowrap; }
.entry2 #unlock:hover:not(:disabled) { background: var(--accent-hover); }
.entry2 #unlock:disabled { opacity: .55; }
.entry2 #unlock.is-processing:disabled { opacity: 1; cursor: progress; }
.entry2 #desktop-unlock, .entry2 #desktop-start-fresh { width: 100%; min-height: 44px; margin-top: 10px; border: 1px solid var(--input-border); border-radius: 10px; background: var(--card); color: var(--secondary); font-size: var(--text-ui); font-weight: 500; }
/* The secondary action every finished/waiting card offers (Back to sign in, Send it again, Contact support, Sign out
   instead — source 219, 228, 276, 284, 297): the same 46px quiet button as the code alternative. */
.entry2 .e-secondary { width: 100%; min-height: 46px; margin-top: 10px; border: 1px solid var(--input-border); border-radius: 10px; background: var(--card); color: var(--ink); font-size: var(--text-ui); font-weight: 550; }
.entry2 .e-secondary:hover { background: var(--accent-tint); }
/* Long or short, one line: a server sentence never wraps the button out of place (the full text sits in `title`). */
.entry2 #entry-message { min-height: 20px; margin: 12px 0 0; color: var(--muted); font-size: var(--text-secondary); line-height: 1.5; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.entry2[data-tone="bad"] #entry-message { color: var(--danger); }
.entry2[data-tone="good"] #entry-message { color: var(--signed-text); }
.entry2[data-tone="card"] #entry-message { color: var(--ink); white-space: normal; overflow: visible; text-overflow: clip; }
/* The wrong-password / sign-in-lock alert card (design source 173-178): the same #entry-message and #entry-ways, only
   moved above the fields and framed, so nothing about the message itself has to change for every suite that reads it. */
.entry2 .e-notice-icon { display: none; width: 17px; height: 17px; margin-top: 1px; flex: none; color: var(--danger); }
.entry2[data-state="signin"][data-tone="card"] .e-heading { order: -2; }
/* [data-state="signin"] doubles the attribute selector so this beats the plain-signin `.e-notice{height:104px}`
   fixed reservation below, regardless of source order (both rules would otherwise tie on specificity). */
.entry2[data-state="signin"][data-tone="card"] .e-notice {
  order: -1; display: flex; flex-direction: row; flex-wrap: wrap; align-items: flex-start; gap: 10px;
  min-height: 0; height: auto; margin-bottom: 4px; padding: 11px 13px;
  border: 1px solid var(--danger-border); border-radius: var(--r-control); background: var(--danger-bg);
}
.entry2[data-state="signin"][data-tone="card"] .e-notice-icon { display: block; }
.entry2[data-state="signin"][data-tone="card"] #entry-message { flex: 1; min-width: 0; margin: 0; }
.entry2[data-state="signin"][data-tone="card"] .e-ways { flex: 0 0 100%; margin-top: 0; }
/* Never a dead end: whatever refused the clinician, the row under the message says what they can do next. */
.entry2 .e-ways { display: flex; flex-direction: row; flex-wrap: wrap; gap: 10px; margin-top: 10px; }
.entry2 .e-ways:empty { display: none; }
.entry2 .e-ways button { min-height: 40px; padding: 0 14px; border: 1px solid var(--input-border); border-radius: 9px; background: var(--card); color: var(--ink); font-size: var(--text-secondary); font-weight: 600; }
.entry2 .e-ways button:hover { background: var(--accent-tint); }
/* Stay signed in, beside the reason codes are off when there is one. */
.entry2 .e-aside { display: flex; flex-direction: row; align-items: center; justify-content: space-between; gap: 16px; margin-top: 12px; }
.entry2 .e-stay { display: flex; flex-direction: row; align-items: center; gap: 10px; margin: 0; color: var(--muted); font-size: var(--text-secondary); line-height: 1.4; cursor: pointer; }
.entry2 .e-stay input { width: 18px; height: 18px; min-height: 0; margin: 0; accent-color: var(--accent); flex: none; }
.entry2 .e-stay strong { color: var(--ink); font-weight: 600; }
/* Beside the code button it explains, not off by the Stay signed in checkbox (gap: codes-unavailable note placement). */
.entry2 #otp-note { margin: 6px 0 0; text-align: left; color: var(--muted); font-size: 12px; line-height: 1.4; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.entry2 .auth-divider { display: flex; flex-direction: row; align-items: center; gap: 14px; margin: 18px 0; color: var(--hint); font-size: var(--text-meta); }
.entry2 .auth-divider::before, .entry2 .auth-divider::after { content: ''; flex: 1; height: 1px; background: var(--border); }
.entry2 #signin-otp { width: 100%; min-height: 46px; border: 1px solid var(--input-border); border-radius: 10px; background: var(--card); color: var(--secondary); font-size: var(--text-ui); font-weight: 500; }
.entry2 #signin-otp:disabled { opacity: 1; color: var(--disabled); cursor: not-allowed; }
/* Both wrappers are invisible to layout until a short, wide window needs two columns. */
.entry2 .e-body, .entry2 .e-main, .entry2 .e-alt { display: contents; }
.entry2 .e-footer { display: flex; flex-direction: row; flex-wrap: wrap; justify-content: center; gap: 12px; margin-top: 14px; }
.entry2 .e-footer:not(:has(button:not([hidden]))) { display: none; }
.entry2 .e-footer button { min-height: 36px; padding: 0 10px; border: 0; background: none; color: var(--accent-text); font-size: var(--text-secondary); font-weight: 500; }
.entry2[data-state="code"] .e-footer { flex-direction: column; align-items: center; gap: 2px; }
/* The footnote (design source 300): the last in-flow line of the form, not pinned to the window’s edge. */
.entry2 .e-terms { position: static; width: auto; max-width: none; margin: 24px 0 0; padding-top: 14px; border-top: 1px solid var(--row-border); text-align: left; color: var(--hint); font-size: 12px; line-height: 1.65; }
.entry2 .e-terms a { color: var(--secondary); text-decoration: underline; text-underline-offset: 3px; }

/* A finished or waiting state (link sent, confirmation sent, pending verification, that link has expired): an icon,
   a sentence, in a bordered card (design source 222-229, 270-277, 279-285). */
.entry2 .e-mark { align-self: flex-start; width: 52px; height: 52px; margin-bottom: 20px; border-radius: 14px; display: inline-flex; align-items: center; justify-content: center; font-size: 24px; background: var(--accent-tint); color: var(--accent); }
.entry2 .e-panelnote {
  display: flex; flex-direction: row; align-items: flex-start; gap: 12px;
  margin: 0 0 16px; padding: 15px; border-radius: var(--r-card); border: 1px solid var(--border); background: var(--card);
}
.entry2 .e-panelnote-icon { width: 20px; height: 20px; flex: none; color: var(--accent-text); }
.entry2 .e-panelnote p { margin: 0; color: var(--secondary); font-size: var(--text-secondary); line-height: 1.65; }
.entry2 .e-panelnote p strong { color: var(--ink); font-weight: 550; }
.entry2 .e-panelnote[data-tone="warn"] { border-color: var(--warn-line); background: var(--warn-bg); }
.entry2 .e-panelnote[data-tone="warn"] .e-panelnote-icon { color: var(--warn); }
.entry2 .e-panelnote[data-tone="warn"] p { color: var(--ink); }

.entry2 .e-sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.entry2 [hidden] { display: none !important; }
/* Keep feedback space even while its message is hidden. Errors never move the
   next field, and matching the two password rows also keeps their eyes aligned. */
.entry2 .e-field-error[hidden] { display: block !important; visibility: hidden; }
.entry2[data-state="signup"] .e-fields { gap: 8px; }
.entry2 .e-switch-context { display: inline; }

/* ---- phones, and any window too short for the promise ------------------------------------------------------- */
/* The promise sells DocVoc on docvoc.com; a clinician on the sign-in screen has already decided. Dropping it is what
   makes 390x844 fit without scrolling — the delivered design stacked it and came out 1800px tall. */
@media (max-width: 860px), (max-height: 779px) {
  .entry.entry2 { display: flex; flex-direction: column; --e-gap: 14px; --e-field: 46px; --e-otp-box: 46px; --e-otp-space: 9px; }
  .entry2 .e-panel { display: none; }
  .entry2 .e-form { flex: 1; min-height: 0; justify-content: flex-start; padding: max(20px, env(safe-area-inset-top)) max(20px, env(safe-area-inset-right)) max(18px, env(safe-area-inset-bottom)) max(20px, env(safe-area-inset-left)); }
  .entry2 .e-mobile-brand { display: flex; width: 100%; max-width: var(--e-card); margin-bottom: 22px; font-size: var(--text-phone-heading); }
  /* Top-aligned under the brand mark, so the card sits in the same place whichever state is showing. */
  .entry2 #unlock-form { margin: 0; }
  .entry2 #entry-title { font-size: var(--text-recorded-heading); }
  .entry2 #unlock { min-height: 50px; margin-top: 20px; }
  .entry2 .e-heading { margin-bottom: 18px; }
  .entry2 .auth-divider { margin: 14px 0; }
  .entry2 .e-terms { width: calc(100% - 40px); margin: 20px 0 0; }
  /* "Already have an account? Sign in" needs a pill’s worth of height beside a heading on a phone, and requesting access is
     the tallest state there is. Under the heading, as plain text, it costs a line instead. */
  .entry2[data-state="signup"] .e-heading-row { flex-direction: column; align-items: flex-start; gap: 12px; }
  .entry2[data-state="signup"] #signup-switch { padding: 0 12px; min-height: 34px; border-color: var(--border); background: var(--accent-tint); color: var(--accent-text); font-size: var(--text-secondary); white-space: nowrap; text-align: center; }
  .entry2[data-state="signup"] .e-fields { gap: 4px; }
  .entry2[data-state="signup"] #unlock { margin-top: 14px; }
  .entry2[data-state="signup"] .e-terms { margin: 0; }
  /* A refusal adds a row of ways out; on a phone that row is what pushes a state over the viewport, so it is the
     one that gets tighter rather than the content above it. */
  .entry2 .e-ways { margin-top: 8px; gap: 8px; }
  .entry2 .e-ways button { min-height: 36px; padding: 0 12px; }
  .entry2 .e-aside { margin-top: 12px; }
}
/* A wide but short window — 1280x720 and most laptops — has room across, not down. Above it drops the promise panel and
   falls into the one-column phone layout, which needs 844px of height it does not have, so the form takes two columns
   instead: what you fill in on the left, the ways in and the alternatives on the right. Nothing is clipped and nothing
   is paged. This block follows the phone block deliberately, so it wins where both apply. */
@media (min-width: 761px) and (max-height: 779px) {
  .entry.entry2 { --e-gap: 14px; --e-field: 46px; --e-card: 760px; }
  .entry2 .e-form { justify-content: center; padding-block: 22px; }
  .entry2 .e-mobile-brand { margin-bottom: 16px; }
  /* The form on the left, the other ways in on the right, each a column of its own and both centred against each
     other — so "or … Email me a sign-in code … New clinic?" reads as the choice beside the form, not after it. */
  .entry2 #unlock-form { display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; column-gap: 44px; row-gap: 0; }
  .entry2 .e-main { display: flex; flex-direction: column; flex: 1 1 0; min-width: 0; }
  .entry2 .e-alt { display: flex; flex-direction: column; flex: 0 1 300px; min-width: 0; }
  .entry2 .auth-divider { margin: 14px 0; }
  .entry2 .e-notice { flex: 0 0 100%; }
  .entry2 .e-terms { max-width: var(--e-card); margin: 20px 0 0; }
  /* Signup stays a single column even when the other entry states use this wider layout. */
  .entry2[data-state="signup"] .e-main, .entry2[data-state="signup"] .e-alt { display: contents; }
}

@media (max-width: 860px) {
  .entry2[data-state="signup"] { --e-field: 44px; }
  .entry2[data-state="signup"] .e-form { padding-block: 16px; }
  .entry2[data-state="signup"] .e-mobile-brand { margin-bottom: 12px; }
  .entry2[data-state="signup"] .e-heading { margin-bottom: 18px; }
  .entry2[data-state="signup"] .e-heading-row { flex-direction: row; align-items: center; }
  .entry2[data-state="signup"] .e-switch-context { display: none; }
  .entry2[data-state="signup"] #entry-description { margin-top: 6px; }
  .entry2[data-state="signup"] #unlock { min-height: 44px; margin-top: 8px; }
  .entry2[data-state="signup"] .e-notice { height: 84px; }
  .entry2[data-state="signup"] #entry-message { margin-top: 8px; }
  .entry2[data-state="signup"] .e-ways { margin-top: 4px; }
  .entry2[data-state="signup"] .e-ways button { min-height: 32px; }
  .entry2[data-state="signup"] .e-contact-group, .entry2[data-state="signup"] .e-password-group { padding-top: 8px; }
}

/* A short desktop window (1280x800 and the rest): tighten before anything is taken away. */
@media (min-width: 861px) and (max-height: 900px) { .entry2 .e-form { padding-block: 24px; } .entry2 .e-panel { padding-block: 32px; } }
@media (max-height: 700px) { .entry.entry2 { --e-gap: 12px; --e-field: 44px; } .entry2 .e-heading { margin-bottom: 14px; } .entry2 #unlock { margin-top: 16px; min-height: 46px; } .entry2 .e-mobile-brand { margin-bottom: 14px; } }
@media (max-width: 360px) { .entry.entry2 { --e-otp-box: 42px; --e-otp-space: 7px; } .entry2 .e-pair { grid-template-columns: 1fr; } }
/* Signup: one full-width field per row, no group separators and no scrolling.
   Compact feedback reservations keep the submit button visible without layout shifts. */
/* DocVoc Redesign (source 161): the account-creation form shares the one 430px column width every other state uses
   (fields already stack full-width, one per row, so the narrower column only tightens that, nothing breaks). */
.entry.entry2[data-state="signup"] { --e-gap: 2px; --e-card: 430px; --e-field: 44px; }
/* The narrower 430px column (above) wraps a little more text than the old 520px one, so signup’s own content is a
   little taller: a bigger top reservation keeps its centred overflow (content taller than the window) shared evenly
   instead of eating into the heading’s clearance (INPUT-042). */
.entry2[data-state="signup"] .e-form { justify-content: center; padding-block: 52px 60px; }
.entry2[data-state="signup"] .e-mobile-brand { flex: none; margin-bottom: 16px; }
.entry2[data-state="signup"] #unlock-form { display: block; flex: none; overflow: visible; padding: 0; }
.entry2[data-state="signup"] .e-fields { display: flex; align-items: stretch; gap: var(--e-gap); }
.entry2[data-state="signup"] #identity-fields,
.entry2[data-state="signup"] .e-contact-group,
.entry2[data-state="signup"] .e-password-group { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--e-gap); border: 0; padding: 0; }
.entry2[data-state="signup"] .e-field-error,
.entry2[data-state="signup"] #password-rule,
.entry2[data-state="signup"] #confirm-password-error { height: 1.3em; margin: 4px 0 0; font-size: 12px; line-height: 1.3; }
.entry2[data-state="signup"] #password-rule,
.entry2[data-state="signup"] #confirm-password-error { height: 2.6em; }
.entry2[data-state="signup"] .e-phone .e-cc select { min-height: 0; height: var(--e-field); }
.entry2[data-state="signup"] #unlock { min-height: 44px; margin-top: 8px; }
.entry2[data-state="signup"] .e-notice { height: 56px; }
@media (max-width: 860px) {
  .entry.entry2[data-state="signup"] { --e-field: 38px; --e-gap: 1px; }
  .entry2[data-state="signup"] .e-form { justify-content: flex-start; padding-block: 12px 60px; }
  .entry2[data-state="signup"] #entry-description { display: none; }
  .entry2[data-state="signup"] .e-notice { height: 48px; }
}
@media (min-width: 861px) and (max-height: 879px) {
  .entry.entry2[data-state="signup"] { --e-field: 34px; --e-gap: 0px; }
  .entry2[data-state="signup"] .e-form { justify-content: flex-start; padding-block: 32px 56px; }
  .entry2[data-state="signup"] .e-mobile-brand,
  .entry2[data-state="signup"] #entry-description { display: none; }
  .entry2[data-state="signup"] .e-heading-row { flex-direction: row; flex-wrap: nowrap; align-items: center; gap: 8px; }
  .entry2[data-state="signup"] .e-field-error,
  .entry2[data-state="signup"] #password-rule,
  .entry2[data-state="signup"] #confirm-password-error { font-size: 11px; }
  .entry2[data-state="signup"] #password-rule,
  .entry2[data-state="signup"] #confirm-password-error { height: 1.3em; }
  .entry2[data-state="signup"] .e-notice { height: 48px; }
  .entry2[data-state="signup"] #entry-message { margin-top: 8px; }
}
/* Code errors precede the password alternative. Keep the feedback area reserved
   so showing or clearing an error never shifts the divider or password button. */
.entry2[data-state="code"] #unlock-form { display: flex; flex-direction: column; flex-wrap: nowrap; align-items: stretch; gap: 0; }
.entry2[data-state="code"] .e-main { display: contents; }
.entry2[data-state="code"] .e-notice { order: 1; flex: none; height: 104px; }
.entry2[data-state="code"] .e-alt { display: flex; flex-direction: column; order: 2; flex: none; border-top: 1px solid var(--border); padding-top: 18px; }
.entry2[data-state="code"] .auth-divider { display: none; }
/* A fixed reservation (not min-height): so a status line or an unverified-email "way" button appearing or clearing
   never nudges the centred heading above it (the tone="card" alert overrides this to grow with its own content). */
.entry2[data-state="signin"] .e-notice { flex: none; height: 104px; }
/* DocVoc Redesign (23 Sept): the heading is always the first in-flow block of the form, in every state and every
   window — no measured top, no absolute position, no grid row reserved for it (source 160-171). Its own base rule
   (margin: 0 0 var(--form-heading-gap)) sets the space below it. Both columns share the design’s fixed 60px inset
   (.e-panel and .e-form padding, above) rather than a width-responsive one, so they always match (INPUT-047). */
/* Keep full country names in the native menu; the closed control shows its code. */
.entry2 .e-phone .e-cc { position: relative; padding: 0; }
.entry2 .e-phone .e-cc select { appearance: none; width: 88px; max-width: none; padding: 0; color: transparent; }
.entry2 .e-phone .e-cc select option { color: var(--ink); background: var(--card); }
.entry2 #phone-dial-code { position: absolute; left: 12px; pointer-events: none; }
.entry2 .e-phone .e-cc::after { content: ''; position: absolute; right: 12px; width: 6px; height: 6px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: translateY(-2px) rotate(45deg); pointer-events: none; }
@media (prefers-reduced-motion: reduce) { .entry2 * { transition: none; } }
/* DocVoc Redesign (22 Sept): the account screens' fields — 46px, 8px corners, the quiet filled ground, 13px labels, a 48px
   primary action and 46px secondary ones. The same size is used for inputs across the app (studio.css). */
.entry2 { --e-field: 46px !important; }
.entry2 .e-fields label, .entry2 .e-label { color: var(--ink); font-size: 13px; font-weight: 550; }
.entry2 .e-fields input[type="text"], .entry2 .e-fields input[type="email"], .entry2 .e-fields input[type="password"], .entry2 .e-fields input[type="tel"] { border-radius: 8px; background: var(--row-highlight); padding: 0 13px; font-size: 14px; }
.entry2 .e-fields input:focus { background: var(--input-bg); }
.entry2 #entry-title { font-size: 30px; font-weight: 700; letter-spacing: -.03em; }
.entry2 #entry-description { font-size: 14px; color: var(--secondary); }
.entry2 #unlock { min-height: 48px; height: 48px; border-radius: 8px; font-size: 15px; font-weight: 600; }
.entry2 #signin-otp { min-height: 46px; height: 46px; border-radius: 8px; border: 1px solid var(--border); background: var(--row-highlight); color: var(--ink); font-size: 14px; font-weight: 550; }
.entry2 .e-inputwrap input { background: var(--row-highlight); }
/* The desktop’s Unlock on this Mac belongs with the other ways in, after them: "or · Email me a sign-in code · Unlock on
   this Mac" — never above the "or" (22 Sept). In the one-column layouts it follows the code button the same way. */
.entry2 .e-alt { display: flex; flex-direction: column; }
.entry2 .e-alt > .auth-divider { order: 1; }
.entry2 .e-alt > #signin-otp { order: 2; }
.entry2 .e-alt > #desktop-unlock { order: 3; margin-top: 12px; }
.entry2 .e-alt > :not(.auth-divider):not(#signin-otp):not(#desktop-unlock) { order: 4; }
/* .e-alt collapses to display:contents at some widths (below), putting its children in the same flex context as
   .e-terms: its order (default 0) must stay above the highest one used inside .e-alt (4) so the footnote is still
   the very last line, not pulled ahead of the divider it otherwise follows in the markup. */
.entry2 .e-terms { order: 5; }
/* One column in every window, as the design draws it (22 Sept): the fields, Sign in, "or" and the other ways in stack
   under each other, so a field’s message always sits beside its field. A short window keeps the column and tightens
   the spacing instead of moving the alternatives into a second column. */
@media (min-width: 761px) and (max-height: 779px) {
  .entry2 #unlock-form { display: flex; flex-direction: column; flex-wrap: nowrap; align-items: stretch; column-gap: 0; }
  .entry2 .e-main, .entry2 .e-alt { display: contents; }
  .entry.entry2 { --e-card: 460px; --e-gap: 10px; --e-field: 42px; }
  .entry2 .e-form { justify-content: center; padding-block: 16px 44px; }
  .entry2 .e-heading { margin-bottom: 12px; }
  .entry2 #entry-title { font-size: 26px; }
  .entry2 #unlock { margin-top: 12px; min-height: 44px; height: 44px; }
  .entry2 .auth-divider { margin: 10px 0; }
  .entry2 #signin-otp, .entry2 #desktop-unlock { min-height: 42px; height: 42px; }
  .entry2 .e-mobile-brand { margin-bottom: 10px; }
}
@media (min-width: 761px) and (max-height: 779px) {
  .entry2 #unlock-form > *, .entry2 #unlock-form .e-heading, .entry2 #unlock-form .e-notice { flex: 0 0 auto !important; }
  .entry2[data-state="signin"] .e-heading { flex: 0 0 auto !important; }
}
@media (min-width: 761px) and (max-height: 619px) {
  .entry2 .e-mobile-brand { display: none; }
  .entry2 .e-form { padding-block: 8px 36px; }
}

/* The three promises lead with the design’s icons, accent-text so they read in dark mode too (source 150). */
.entry2 .e-points .e-point-icon { width: 20px; height: 20px; margin-top: 1px; color: var(--accent-text); }
@media (min-width: 761px) {
  .entry2 .e-main > .e-aside { margin: 14px 0 0; }
  .entry2 .e-stay strong { color: inherit; font-weight: inherit; }
}
/* A sign-in error sits under Sign in, before "or" (the answer to the button just pressed); empty, it takes no room. Only where the
   sign-in controls are anchored: short windows start the form at the top, so an answer only moves what is below it. */
@media (min-width: 761px) and (max-height: 779px) { .entry2[data-state="signin"] .e-form { justify-content: flex-start; } }
@media (min-width: 761px) {
  .entry2[data-state="signin"] #unlock-form .e-alt > .e-notice { order: 0 !important; height: auto; min-height: 0; margin-bottom: 4px; }
  .entry2[data-state="signin"] #unlock-form .e-alt > .e-notice:has(#entry-message:empty):has(#entry-ways:empty):not(:has(#desktop-unlock:not([hidden]))) { display: none; }
}
@media (max-width: 760px) {
  .entry2[data-state="signin"] #unlock-form .e-alt > .e-notice { order: 0 !important; height: auto; min-height: 0; margin-bottom: 4px; }
  .entry2[data-state="signin"] #unlock-form .e-alt > .e-notice:has(#entry-message:empty):has(#entry-ways:empty):not(:has(#desktop-unlock:not([hidden]))) { display: none; }
  .entry2[data-state="signin"] .e-form { justify-content: flex-start; }
}

/* Phone-only pieces of the markup (the code boxes, the password’s own error line): never on desktop or the wide web. */
.entry2 .e-otp-boxes, .entry2 #password-error { display: none !important; }
:root:is(.ios,.android) .entry2 .e-otp-boxes { display: flex !important; }
:root:is(.ios,.android) .entry2 #password-error:not([hidden]) { display: block !important; }

/* ---- phones: the Mobile auth stack (html.ios / html.android only) ------------------------------------------------ */
/* MOBILE_STYLE_GUIDE §6 and Source 654-715, with the rulebook’s values where §13 of DESIGN_GUIDE overrides the prototype: platform
   radii from mobile.css (--m-btn-r / --m-field-r: 8 on iOS, a pill on Android), inputs 16, body 15, secondary 13.5, meta 12, targets
   ≥ 44. One column: brand → title/sub → notice → fields → Sign in → the other way in → the fine print at the foot. No page scroll;
   a state taller than the screen scrolls inside the column, never a pager. Desktop and the wide web never match these rules. */
:root:is(.ios,.android) .entry.entry2 { --e-gap: 16px; --e-field: 46px; background: var(--panel); }
:root:is(.ios,.android) .entry2 .e-form {
  flex: 1; min-height: 0; align-items: stretch; justify-content: flex-start; background: var(--panel);
  padding: calc(env(safe-area-inset-top, 0px) + 20px) max(20px, env(safe-area-inset-right)) max(16px, env(safe-area-inset-bottom)) max(20px, env(safe-area-inset-left));
}
:root.ios .entry2 .e-form { padding-top: calc(var(--m-status) + 20px); }
/* The app bar of Source 2c/2d: full width above the column, the status inset above it on iOS. */
:root:is(.ios,.android) .entry2 .e-appbar { margin: calc(-20px - env(safe-area-inset-top, 0px)) -20px 20px; }
:root.ios .entry2 .e-appbar { margin-top: calc(-20px - var(--m-status)); padding-top: calc(var(--m-status) + 6px); }
:root:is(.ios,.android) .entry2 .e-appbar .m-back svg { width: 20px; height: 20px; }
:root:is(.ios,.android) .entry2 .e-appbar .m-appbar__title { margin: 0; }
:root:is(.ios,.android) .entry2 .e-mobile-brand { display: flex; align-items: center; gap: 9px; align-self: flex-start; width: auto; min-height: 44px; max-width: none; margin: -7px 0 9px; font-size: 17px; font-weight: 650; letter-spacing: -.02em; }
:root:is(.ios,.android) .entry2 .e-mobile-brand img { width: 30px; height: 30px; border-radius: 9px; }
:root:is(.ios,.android) .entry2 #unlock-form { flex: 1 1 auto; min-height: 0; max-width: none; margin: 0; overflow-x: hidden; overflow-y: auto; display: flex; flex-direction: column; gap: 0; padding: 0; }
:root:is(.ios,.android) .entry2 .e-body, :root:is(.ios,.android) .entry2 .e-main, :root:is(.ios,.android) .entry2 .e-alt { display: contents; }
/* Order: heading → fields (the notice first inside them) → the code’s expiry row → Stay signed in → Sign in → the secondary → the
   other way in → the message → the fine print → Create an account. */
:root:is(.ios,.android) .entry2 :is(.e-back, .e-mark) { order: -4; }
:root:is(.ios,.android) .entry2 .e-heading { order: -3; margin: 0 0 16px; flex: none; }
:root:is(.ios,.android) .entry2 .e-fields { order: 0; gap: 16px; flex: none; }
:root:is(.ios,.android) .entry2 #otp-status { order: 1; }
:root:is(.ios,.android) .entry2[data-state="code"] .e-notice { order: 2; }
:root:is(.ios,.android) .entry2 .e-aside { order: 3; }
:root:is(.ios,.android) .entry2 #unlock { order: 4; }
:root:is(.ios,.android) .entry2 :is(#entry-secondary, #use-password, #lock-other-account) { order: 5; }
:root:is(.ios,.android) .entry2 :is(.auth-divider, #signin-otp, #otp-note, .e-footer, #desktop-unlock) { order: 6; }
:root:is(.ios,.android) .entry2 .e-notice { order: 7; }
/* Beats the desktop “.e-alt > :not(…)” order (two ids) so the code’s reason follows the button it explains. */
:root:is(.ios,.android) #entry.entry2 .e-alt > :is(#otp-note, .e-footer) { order: 6; }
:root:is(.ios,.android) .entry2[data-state="signin"] #unlock-form .e-notice { order: 5 !important; }
:root:is(.ios,.android) .entry2[data-state="signin"][data-tone="card"] .e-notice { order: -1 !important; margin: 0 0 16px; }
:root:is(.ios,.android) .entry2 .e-terms { order: 8; }
:root:is(.ios,.android) .entry2 #signup-switch { order: 9; }
/* Type (Source 656-663; §3.1): title 26/700, sub 13.5 --ink2, fine print 12 --ink3 at the foot of the screen, no rule above it. */
:root:is(.ios,.android) .entry2 #entry-title { font-size: 26px; font-weight: 700; letter-spacing: -.03em; line-height: 1.15; }
:root:is(.ios,.android) .entry2 #entry-description { display: block; margin: 7px 0 0; font-size: 13.5px; line-height: 1.6; color: var(--ink2); }
:root:is(.ios,.android) .entry2 .e-terms { width: auto; max-width: none; margin: auto 0 0; padding: 16px 0 0; border: 0; color: var(--ink3); font-size: 12px; line-height: 1.6; }
:root:is(.ios,.android) .entry2 .e-terms:empty { display: none; }
/* The Terms and Privacy links keep their line but take a 44px target (H-2): the padding is outside the line box. */
:root:is(.ios,.android) .entry2 .e-terms a { padding: 15px 5px; margin: 0 -5px; }
/* Fields: 46 tall, the platform radius, 16px text (no zoom on focus), labels 13/550; a field’s error takes no room until shown. */
:root:is(.ios,.android) .entry2 .e-fields :is(input[type="text"], input[type="email"], input[type="password"], input[type="tel"]) { height: 46px; min-height: 46px; border-radius: var(--m-field-r); border-color: var(--line); background: var(--panel2); padding: 0 14px; font-size: 16px; }
:root:is(.ios,.android) .entry2 .e-fields .e-inputwrap input { padding-right: 52px; }
:root:is(.ios,.android) .entry2 .e-fields input:focus { border-color: var(--accent); }
:root:is(.ios,.android) .entry2 .e-fields input.invalid { border-color: var(--danger); }
:root:is(.ios,.android) .entry2 .e-fields label > :is(input, .e-inputwrap) { margin-top: 7px; }
:root:is(.ios,.android) .entry2 .e-password > label { margin-bottom: 7px; }
:root:is(.ios,.android) .entry2 .e-field-error[hidden] { display: none !important; }
:root:is(.ios,.android) .entry2 .e-field-error { height: auto; margin: 6px 0 0; font-size: 12.5px; line-height: 1.45; }
:root:is(.ios,.android) .entry2 .e-password > #password-error { grid-area: 4 / 1 / auto / -1; }
:root:is(.ios,.android) .entry2 #password-rule, :root:is(.ios,.android) .entry2 #confirm-password-error { height: auto; min-height: 0; margin: 6px 0 0; font-size: 12px; line-height: 1.5; }
:root:is(.ios,.android) .entry2 #password-rule:not(.invalid) { color: var(--ink3); }
:root:is(.ios,.android) .entry2 .e-show { width: 44px; height: 46px; right: 4px; }
:root:is(.ios,.android) .entry2 #forgot-password { display: inline-flex; align-items: center; min-height: 44px; margin: -12px -8px -12px 0; padding: 0 8px; font-size: 13.5px; font-weight: 550; }
/* Create account: name, email, password, confirm (the clinic is set later in Settings, Source 927). */
:root:is(.ios,.android) .entry.entry2[data-state="signup"] { --e-gap: 16px; --e-field: 46px; }
:root:is(.ios,.android) .entry2[data-state="signup"] .e-form { justify-content: flex-start; padding-block: calc(env(safe-area-inset-top, 0px) + 20px) max(16px, env(safe-area-inset-bottom)); }
:root.ios .entry2[data-state="signup"] .e-form { padding-top: calc(var(--m-status) + 20px); }
:root:is(.ios,.android) .entry2[data-state="signup"] .e-fields { gap: 14px; }
:root:is(.ios,.android) .entry2[data-state="signup"] :is(#identity-fields, .e-contact-group, .e-password-group) { display: contents; }
:root:is(.ios,.android) .entry2[data-state="signup"] .e-heading-row { flex-direction: row; align-items: flex-start; flex-wrap: nowrap; }
:root:is(.ios,.android) .entry2[data-state="signup"] #unlock { margin-top: 18px; }
/* The ways between states (Create an account / Sign in): plain accent text with a 44px target. */
:root:is(.ios,.android) .entry2 #signup-switch { align-self: center; min-height: 44px; margin: 4px 0 0; padding: 0 10px; border: 0; border-radius: var(--m-btn-r); background: none; color: var(--accent-text); font-size: 13.5px; font-weight: 550; }
:root:is(.ios,.android) .entry2[data-state="signup"] #signup-switch { margin: -8px -10px 0 0; }
/* Stay signed in: one 44px row (the checkbox and its words are one target). */
:root:is(.ios,.android) .entry2 .e-aside { margin: 12px 0 0; }
:root:is(.ios,.android) .entry2 .e-stay { min-height: 44px; font-size: 13.5px; }
:root:is(.ios,.android) .entry2 .e-stay input { width: 22px; height: 22px; }
/* Buttons (Source 707/709): the primary 48, the one secondary style 48 / --panel2 / --line / --ink 15/550, 9px apart. */
:root:is(.ios,.android) .entry2 #unlock { height: 48px; min-height: 48px; margin-top: 18px; border-radius: var(--m-btn-r); font-size: 15px; font-weight: 600; }
:root:is(.ios,.android) .entry2 :is(#signin-otp, .e-secondary, #desktop-unlock) { width: 100%; height: 48px; min-height: 48px; margin: 9px 0 0; border: 1px solid var(--line); border-radius: var(--m-btn-r); background: var(--panel2); color: var(--ink); font-size: 15px; font-weight: 550; }
:root:is(.ios,.android) .entry2 #signin-otp:disabled { color: var(--disabled); }
:root:is(.ios,.android) .entry2 .auth-divider { display: none; }
:root:is(.ios,.android) .entry2 #otp-note { margin: 6px 0 0; white-space: normal; font-size: 12px; color: var(--ink3); }
@media (hover: none) { :root:is(.ios,.android) .entry2 #unlock:hover:not(:disabled) { background: var(--accent); } :root:is(.ios,.android) .entry2 .e-secondary:hover { background: var(--panel2); } }
/* The notice (Source 665-670): radius 10, 11px 12px, 17px icon, 13.5 --ink; info in --accent-soft, warn in --warn-bg. First in the
   fields, so it follows the title and precedes the boxes or the password (Locked: lock callout, password, Unlock). */
:root:is(.ios,.android) .entry2 .e-panelnote { order: -1; gap: 10px; margin: 0; padding: 11px 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--panel2); }
:root:is(.ios,.android) .entry2 .e-panelnote[data-tone="info"], :root:is(.ios,.android) .entry2 .e-panelnote[data-tone=""] { border-color: var(--accent-line); background: var(--accent-soft); }
:root:is(.ios,.android) .entry2 .e-panelnote[data-tone="warn"] { border-color: var(--warn-line); background: var(--warn-bg); }
:root:is(.ios,.android) .entry2 .e-panelnote-icon { width: 17px; height: 17px; margin-top: 1px; color: var(--accent-text); }
:root:is(.ios,.android) .entry2 .e-panelnote[data-tone="warn"] .e-panelnote-icon { color: var(--warn); }
:root:is(.ios,.android) .entry2 .e-panelnote p { color: var(--ink); font-size: 13.5px; line-height: 1.55; }
/* The one-time code (Source 672-678): six boxes over the real field, the expiry row directly under them. */
:root:is(.ios,.android) .entry2 #otp-label { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
:root:is(.ios,.android) .entry2 .e-otp { position: relative; }
:root:is(.ios,.android) .entry2 .e-otp-boxes { display: flex; gap: 7px; }
:root:is(.ios,.android) .entry2 .e-otp-boxes span { flex: 1; min-width: 0; height: 52px; display: flex; align-items: center; justify-content: center; border: 1.5px solid var(--line); border-radius: var(--m-field-r); background: var(--panel2); color: var(--ink); font-family: var(--font-mono); font-size: 20px; font-weight: 600; }
:root:is(.ios,.android) .entry2 .e-otp-boxes span.is-current { border-color: var(--accent); background: var(--accent-soft); }
:root:is(.ios,.android) .entry2 .e-otp-boxes span.is-invalid { border-color: var(--danger); }
:root:is(.ios,.android) .entry2 .e-fields #otp-code { position: absolute; inset: 0; width: 100%; height: 52px; min-height: 52px; margin: 0; padding: 0; border: 0; border-radius: 0; background: transparent; color: transparent; caret-color: transparent; font-size: 16px; letter-spacing: 0; opacity: 0; box-shadow: none; }
:root:is(.ios,.android) .entry2 .e-code-row { margin-top: 9px; gap: 10px; font-size: 12px; }
:root:is(.ios,.android) .entry2 #otp-expiry { font-family: var(--font-mono); font-size: 12px; color: var(--ink2); }
:root:is(.ios,.android) .entry2 #otp-resend { min-height: 44px; margin: -12px -8px; padding: 0 8px; font-size: 13.5px; font-weight: 550; }
/* The message and its ways: the whole sentence wraps (never an ellipsis), the ways are 44px buttons. Empty, it takes no room. */
:root:is(.ios,.android) .entry2 .e-notice { height: auto; min-height: 0; margin: 12px 0 0; flex: none; }
:root:is(.ios,.android) .entry2 .e-notice:has(#entry-message:empty):has(#entry-ways:empty) { display: none; }
:root:is(.ios,.android) .entry2 #entry-message { min-height: 0; margin: 0; white-space: normal; overflow: visible; text-overflow: clip; font-size: 13.5px; }
:root:is(.ios,.android) .entry2 .e-ways { margin-top: 9px; gap: 9px; }
:root:is(.ios,.android) .entry2 .e-ways button { min-height: 44px; padding: 0 14px; border: 1px solid var(--line); border-radius: var(--m-btn-r); background: var(--panel2); color: var(--ink); font-size: 13.5px; font-weight: 550; }
:root:is(.ios,.android) .entry2[data-state="signin"][data-tone="card"] .e-notice { padding: 11px 12px; border-radius: 10px; }
:root:is(.ios,.android) .entry2[data-state="code"] .e-alt { border: 0; padding: 0; }
/* Phone fit (owner, 24 Sept 2026): the 44 hit areas of the small text actions stay inside their rows — nothing sticks out past the
   column’s edge (it was cut off there) or into the field or line next to it. */
:root:is(.ios,.android) .entry2 #forgot-password { margin: -16px 0 0 0; padding: 0 0 0 8px; }   /* 44 tall, clear of the field under it */
:root:is(.ios,.android) .entry2[data-state="signup"] #signup-switch { margin: -8px 0 0 0; }
:root:is(.ios,.android) .entry2 #otp-resend { margin: -9px 0 -12px 0; padding: 0 0 0 8px; }
/* Forgot password and the code steps: the app bar names the step and goes back, so the logo and the repeated title step aside and
   the heading is the instruction alone (the title stays for screen readers). */
:root:is(.ios,.android) .entry2:has(#entry-appbar:not([hidden])) .e-mobile-brand { display: none; }
:root:is(.ios,.android) .entry2:has(#entry-appbar:not([hidden])) #entry-title { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
:root:is(.ios,.android) .entry2:has(#entry-appbar:not([hidden])) #entry-description { margin-top: 0; font-size: 15px; color: var(--ink); }
/* The foot: the fine print and Create an account share the left edge. */
:root:is(.ios,.android) .entry2[data-state="signin"] #signup-switch { align-self: flex-start; padding-inline: 0; }
/* Landscape and a raised keyboard: the column is one scroll region that starts at its top (never centred past the top edge), so
   the title, every field and every action can be reached. */
:root:is(.ios,.android) .entry2 #unlock-form { justify-content: flex-start; overscroll-behavior: contain; }
/* The scroll region clips sideways, and the fine print's links take their 44 target 5px past their words (above): the region
   reaches 5px into the 20px gutter on each side, so a link that starts or ends a line (“Terms” at 412 wide) is not cut off, while
   every child keeps its place and width. */
:root:is(.ios,.android) .entry2 #unlock-form { width: calc(100% + 10px); margin-inline: -5px; padding-inline: 5px; }
:root:is(.ios,.android) .entry2 .e-form { overflow: hidden; }
@media (orientation: landscape) and (max-height: 500px) {
  :root:is(.ios,.android) .entry2 .e-form { padding-top: calc(env(safe-area-inset-top, 0px) + 8px); padding-bottom: 8px; }
  :root:is(.ios,.android) .entry2 .e-mobile-brand { margin: 0 0 4px; min-height: 36px; }
  :root:is(.ios,.android) .entry2 .e-terms { margin-top: 16px; }
  :root:is(.ios,.android) dialog.m-auth { overflow-y: auto; }
  :root:is(.ios,.android) dialog.m-auth :is(.av-mic-actions,.iv-mic-actions) { margin-top: 8px; }
}
:root:is(.ios,.android) .entry2[data-state="signup"] #signup-switch { min-width: 48px; padding-inline: 2px; }
/* The fine print’s links keep their 44 targets clear of Create an account under them (the space comes from above the fine print). */
:root:is(.ios,.android) .entry2 .e-terms { padding-top: 6px; }
:root:is(.ios,.android) .entry2[data-state="signin"] #signup-switch { margin-top: 14px; }

/* ---- Sept 2026 redesign (Auth board): the brand panel ------------------------------------------------------------
   A fixed 43% deep-navy column in both themes: the brand at the top, the promise centred, one footnote at the foot.
   The headline is Newsreader at display size and breaks after "time" by its measure, not a <br>. */
@media (min-width: 861px) {
  .entry.entry2 { grid-template-columns: minmax(420px, 43%) minmax(0, 1fr); }
  .entry2 .e-panel { justify-content: flex-start; gap: 24px; padding: 48px 64px; background: var(--brand-panel); border-right: 0; color: var(--brand-panel-ink); }
  .entry2 .e-panel > .brand { color: var(--brand-panel-ink); font-family: var(--font-serif); font-size: 26px; font-weight: 500; letter-spacing: 0; }
  .entry2 .e-panel > .brand img { width: 36px; height: 36px; border-radius: 10px; }
  .entry2 .e-headline { margin: auto 0 0; font-family: var(--font-serif); font-size: clamp(48px, 4.7vw, 68px); font-weight: 400; line-height: 1.02; letter-spacing: -.025em; max-width: 4.9em; color: var(--brand-panel-ink); }
  .entry2 .e-sub { max-width: 420px; color: var(--brand-panel-sub); font-size: 18px; line-height: 1.55; text-wrap: pretty; }
  .entry2 .e-points { display: flex; flex-direction: column; gap: 22px; margin: 16px 0 auto; padding: 28px 0 0; border-top: 1px solid var(--brand-panel-line); max-width: 460px; }
  .entry2 .e-points li { grid-template-columns: 28px minmax(0, 1fr); gap: 14px; padding: 0; border-bottom: 0; }
  .entry2 .e-points strong { font-size: 16px; color: var(--brand-panel-ink); }
  .entry2 .e-points span { font-size: 15px; color: var(--brand-panel-muted); }
  .entry2 .e-points .e-point-icon { width: 22px; height: 22px; color: var(--brand-panel-icon); }
  .entry2 .e-panel-foot { margin: 0; color: var(--brand-panel-muted); font-size: 13px; }
}
.entry2 .e-panel-foot { margin: 0; }
/* An answer under Sign in reads in full: it wraps rather than ending in an ellipsis. */
.entry2 #entry-message { white-space: normal; overflow: visible; text-overflow: clip; }
/* The design's tighter form: a field's error line sits in the gap under its field instead of reserving its own row,
   so nothing moves when it appears and the form keeps the board's rhythm. */
@media (min-width: 761px) {
  .entry.entry2:not([data-state="signup"]) { --e-gap: 24px; }
  .entry.entry2 { --e-card: 400px; }
  .entry.entry2[data-state="signup"] { --e-card: 400px; }
  .entry2 .e-field-error { height: 18px; margin: 3px 0 -21px; overflow: visible; text-overflow: clip; line-height: 18px; white-space: nowrap; }
  .entry2:not([data-state="signup"]) #entry-title { font-size: 40px; letter-spacing: -.015em; }
}
