.login-wrap { max-width: 360px; margin: 14vh auto 0; padding: 0 20px; }
.login-card { background: var(--surface); border: 1px solid var(--border);
              border-radius: 12px; padding: 26px 26px 22px; }
.brandrow { display: flex; align-items: center; gap: 9px; margin-bottom: 2px; }
/* the tagline carries the gap above the form; where there is none, the lockup
   has to carry it instead */
.brandrow.nosub { margin-bottom: 18px; }
.brandrow .mark { display: block; flex: 0 0 auto; }
.login-card h1 { font-size: 19px; font-weight: 650; margin: 0; letter-spacing: -.012em; }
.login-card .sub { color: var(--ink-2); font-size: 13px; margin-bottom: 18px; }
.field { margin-bottom: 12px; }
.field label { display: block; color: var(--ink-2); font-size: 12.5px; margin-bottom: 4px; }
.field input { width: 100%; box-sizing: border-box; background: var(--page);
               color: var(--ink); border: 1px solid var(--border); border-radius: 8px;
               padding: 9px 11px; font: inherit; }
/* Not button.signin: the install prompt's "Go to the dashboard" is a link, and
   a tag-qualified selector silently dropped every visual property, leaving the
   page's one call to action looking like body text that happened to be blue. */
.signin { width: 100%; margin-top: 6px; background: var(--ink); color: var(--surface);
          border: 0; border-radius: 8px; padding: 10px; font: inherit;
          font-weight: 600; cursor: pointer; }
.err { display: none; background: var(--danger-bg); color: var(--ink);
       border: 1px solid var(--danger-edge); border-radius: 8px;
       padding: 8px 11px; font-size: 12.5px; margin-bottom: 12px; }
.err.show { display: block; }
.alt { margin-top: 14px; color: var(--ink-2); font-size: 12.5px; text-align: center; }
.alt a { color: var(--ink); }
.hint { display: none; color: var(--ink-2); font-size: 12.5px; margin: -6px 0 12px; }
.hint.show { display: block; }
.field input[readonly] { color: var(--ink-2); background: var(--surface); }
.devtext { color: var(--ink-2); font-size: 13px; line-height: 1.5; margin: 0 0 12px; }
.devtext b { color: var(--ink); }
.devcode { font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
           font-size: 22px; letter-spacing: 2px; text-align: center;
           background: var(--page); border: 1px solid var(--border);
           border-radius: 8px; padding: 12px; margin-bottom: 16px; }
/* The machine's own name for itself, shown as a value and never as prose: it
   arrives from the collector unchecked, so it gets quotes, a monospace face
   and a box, the way any other untrusted string is displayed. */
.devhost { font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
           font-size: 12.5px; color: var(--ink); background: var(--page);
           border: 1px solid var(--border); border-radius: 6px;
           /* anywhere, not break-all: a hostname only has to break when it
              genuinely cannot fit, and break-all split "Divyas-MacBook-Air"
              mid-word on a phone while the hyphens it could have used sat
              unused */
           padding: 1px 6px; overflow-wrap: anywhere; }
.devhost::before, .devhost::after { content: "\201C"; color: var(--muted); }
.devhost::after { content: "\201D"; }
/* the typed approval code: same field as everywhere, spaced out to be read
   character by character against the machine's screen */
.devinput { font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
            letter-spacing: 2px; text-transform: uppercase; }

/* ---- the install prompt ----
   Wider than the other auth cards because it carries a shell command that must
   not wrap: a broken install line is one someone pastes in two halves. */
.install-wrap { max-width: 560px; margin-top: 10vh; }
.cmdrow { display: flex; align-items: stretch; gap: 8px; margin-bottom: 14px; }
.cmd { flex: 1 1 auto; min-width: 0; overflow-x: auto; white-space: nowrap;
       background: var(--page); border: 1px solid var(--border);
       border-radius: 8px; padding: 10px 11px; color: var(--ink);
       font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
       font-size: 12.5px; }
.copy { flex: 0 0 auto; background: var(--surface); color: var(--ink);
        border: 1px solid var(--border); border-radius: 8px; padding: 0 12px;
        font: inherit; font-size: 12.5px; cursor: pointer; }
.copy:hover { border-color: var(--muted); }
/* the wait line is the only thing here that changes on its own, so it reads as
   live rather than as one more paragraph */
.waitline { color: var(--muted); }
.waitline::before { content: "\25CF"; margin-right: 7px; font-size: 9px;
                    vertical-align: 1px; animation: waitpulse 1.6s ease-in-out infinite; }
@keyframes waitpulse { 0%, 100% { opacity: .25 } 50% { opacity: 1 } }
@media (prefers-reduced-motion: reduce) {
  .waitline::before { animation: none; opacity: .6; }
}
a.signin.cta { display: block; box-sizing: border-box; text-align: center;
               text-decoration: none; color: var(--surface); margin-top: 4px; }
.alt code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
            font-size: 11.5px; }

/* ---- narrow viewports ----
   These pages are a single column already, so the only thing that goes wrong on
   a phone is proportion: 14vh above the card and 26px of padding inside it are
   measured against a desktop window. /device is the one that matters -- it is
   approved from a phone while the machine asking sits in front of you -- and it
   is also the tallest, so the space it wastes is space you have to scroll past
   to reach the button. */
@media (max-width: 430px) {
  .login-wrap { margin-top: 5vh; padding: 0 14px; }
  .login-card { padding: 20px 18px 18px; }
  .devcode { font-size: 19px; padding: 11px 6px; }
  /* the command and its Copy button stop sharing a line well before the card
     runs out of room, and the command is the half that must keep its width */
  .cmdrow { flex-direction: column; }
  .copy { padding: 8px 12px; }
}
