.auth { max-width: 26rem; }
.auth h1 { font-size: clamp(1.8rem, 5vw, 2.4rem); margin: 0 0 .75rem; }
.auth form { display: flex; flex-direction: column; gap: .35rem; margin-top: 1.5rem; }
.auth label {
  font: 600 .78rem/1.4 "Segoe UI", system-ui, sans-serif;
  color: var(--soft); margin-top: .8rem;
}
.auth input {
  font: 1rem/1.4 "Cascadia Mono", Consolas, monospace;
  padding: .6rem .7rem;
  border: 1px solid var(--rule);
  border-radius: 3px;
  background: var(--paper);
  color: var(--ink);
}
.auth input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.auth button {
  margin-top: 1.4rem;
  font: 600 .95rem/1 "Segoe UI", system-ui, sans-serif;
  padding: .75rem 1rem;
  border: 1px solid var(--accent);
  border-radius: 3px;
  background: var(--accent);
  color: var(--paper);
  cursor: pointer;
}
.auth button:disabled { opacity: .6; cursor: progress; }
.hint, .switch, .warn, .status {
  font: .85rem/1.55 "Segoe UI", system-ui, sans-serif;
  color: var(--muted);
}
.hint { margin: .4rem 0 0; }

/* Password feedback, shown against the field rather than only in the
   shared status line at the foot of the section. */
.hint.strength-weak { color: var(--danger, #b3392f); font-weight: 600; }
.hint.strength-ok { color: var(--ok, #2f6f4f); }
.switch { margin-top: 1.75rem; }
.switch a { color: var(--accent); }
.warn {
  margin-top: 1.5rem; padding: .8rem 1rem;
  border-left: 3px solid var(--accent);
  background: var(--surface-sunk, rgba(127,127,127,.08));
  color: var(--soft);
}
.status { margin-top: 1.25rem; min-height: 1.4em; }
.status.error { color: #b3392f; }
@media (prefers-color-scheme: dark) { .status.error { color: #de7a6e; } }
.secret {
  font: 1.05rem/1.6 "Cascadia Mono", Consolas, monospace;
  letter-spacing: .08em;
  padding: .8rem 1rem;
  border: 1px dashed var(--rule);
  border-radius: 3px;
  word-break: break-all;
  margin: 1rem 0 0;
}
#session-detail {
  display: flex; flex-direction: column; gap: .8rem;
  margin: 1.5rem 0 0; padding-top: 1.25rem;
  border-top: 1px solid var(--rule);
  font: .85rem/1.5 "Segoe UI", system-ui, sans-serif;
}
#session-detail div { display: flex; flex-direction: column; gap: .15rem; }
#session-detail dt {
  font-size: .66rem; letter-spacing: .13em; text-transform: uppercase;
  color: var(--muted);
}
#session-detail dd { margin: 0; font-family: "Cascadia Mono", Consolas, monospace; }

.qr {
  margin: 1.25rem 0;
  /* White ground regardless of theme — scanners cope badly with inverted
     codes, and this element has to work on the first attempt. */
  background: #fff;
  padding: .75rem;
  border-radius: 4px;
  display: inline-block;
  line-height: 0;
}
.qr svg { width: 200px; height: 200px; display: block; }

.check {
  display: flex; align-items: center; gap: .5rem;
  margin-top: .9rem; font-weight: 500; color: var(--ink);
  text-transform: none; letter-spacing: 0; font-size: .88rem;
}
.check input { width: auto; margin: 0; }
.subhead {
  font: 700 .72rem/1 "Segoe UI", system-ui, sans-serif;
  letter-spacing: .13em; text-transform: uppercase; color: var(--muted);
  margin: 2rem 0 .75rem; padding-top: 1.25rem;
  border-top: 1px solid var(--rule);
}
.devices { list-style: none; margin: 0; padding: 0; }
.devices li {
  display: grid; grid-template-columns: 1fr auto auto;
  gap: .75rem; align-items: baseline;
  padding: .55rem 0; border-bottom: 1px solid var(--rule);
  font: .85rem/1.4 "Segoe UI", system-ui, sans-serif;
}
.device-name { color: var(--ink); font-weight: 600; }
.device-meta { color: var(--muted); font-size: .78rem; }
button.link {
  background: none; border: none; padding: 0; margin: 0;
  color: var(--accent); cursor: pointer; font: inherit;
  text-decoration: underline;
}
.actions { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: 1.75rem; }
.actions button { margin-top: 0; flex: 0 0 auto; }
.actions #sign-out, .actions #lock-now {
  background: none; color: var(--accent);
}

/* SEC-4.10: shown once, so they need to be legible enough to copy by hand
   and unambiguous enough to transcribe correctly. */
.codes {
  list-style: none; margin: 1.5rem 0; padding: 1.25rem;
  border: 1px dashed var(--rule); border-radius: 4px;
  display: grid; grid-template-columns: repeat(2, 1fr); gap: .55rem 1.5rem;
  font: 1rem/1.5 "Cascadia Mono", Consolas, monospace;
  letter-spacing: .06em;
}
#view-recovery .actions { margin-top: 0; }
#view-recovery .actions button {
  background: none; border: 1px solid var(--rule); color: var(--ink);
  padding: .45rem .8rem; margin: 0;
  font: 600 .82rem/1 "Segoe UI", system-ui, sans-serif; border-radius: 3px;
  cursor: pointer;
}
#recovery-continue {
  margin-top: 1.5rem; width: 100%;
  background: var(--accent); border: 1px solid var(--accent); color: var(--paper);
  padding: .75rem 1rem; border-radius: 3px; cursor: pointer;
  font: 600 .95rem/1 "Segoe UI", system-ui, sans-serif;
}
#recovery-continue:disabled { opacity: .45; cursor: not-allowed; }

/* Printing the page would carry the whole interface onto the paper, which
   is both useless and a way to print things the user did not intend. */
@media print {
  body.printing-codes > *:not(#view-recovery) { display: none !important; }
  body.printing-codes #view-recovery .actions,
  body.printing-codes #view-recovery .check,
  body.printing-codes #recovery-continue { display: none !important; }
  body.printing-codes .codes { border-color: #000; }
}

/* A pressed button must look pressed.
 *
 * Reported as "it doesn't look like anything happens": the work behind a
 * press can take a second or more, and without this the only feedback was
 * a status line at the foot of the section, which is easy to miss and can
 * be below the fold entirely.
 *
 * The pulse is deliberately obvious rather than tasteful. A user who is not
 * sure whether their click registered will click again, and a second
 * submission of a signup form is its own problem.
 */
button.is-working {
  position: relative;
  opacity: .85;
  cursor: progress;
  animation: working-pulse 1.1s ease-in-out infinite;

  /* The label changes while it works - "Saving." to "Saving..." and
     between whole messages - and a button that resizes on every tick is
     worse than no animation at all. The trailing figure spaces in the JS
     keep the width steady; this stops the box itself from shrinking back
     when a shorter message comes round. */
  min-width: max-content;
  font-variant-numeric: tabular-nums;
}

@keyframes working-pulse {
  0%, 100% { filter: brightness(1); }
  50%      { filter: brightness(1.35); }
}

/* Respects a user who has asked for less motion; the dimming and the
   changed label still say the same thing without the animation. */
@media (prefers-reduced-motion: reduce) {
  button.is-working { animation: none; }
}

/* Work in progress.
 *
 * Argon2id blocks for the better part of a second, and on a phone rather
 * longer. Reported as being stuck on a dialogue with no sign anything was
 * happening - a spinner is the difference between waiting and giving up.
 */
.status.working {
  color: var(--muted);
}

.status.working::before {
  content: '';
  display: inline-block;
  width: .75rem;
  height: .75rem;
  margin-right: .5rem;
  vertical-align: -1px;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  animation: spin .7s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

/* The dimming and the changed label still carry the meaning without it. */
@media (prefers-reduced-motion: reduce) {
  .status.working::before { animation: none; opacity: .5; }
}

/* Password strength, as a traffic light.
 *
 * Red always means the password will be refused, in both tiers. That is
 * what keeps the colour meaningful - amber says "accepted, thin margin"
 * and never "rejected", so nobody has to read the text to know whether
 * they can continue.
 *
 * Colour is never the only signal: the verdict is spelled out beside it,
 * for anyone who cannot distinguish the two warm colours.
 */
.signal {
  display: flex; align-items: center; gap: .5rem;
  margin: .5rem 0 0;
  font: 600 .85rem/1.4 "Segoe UI", system-ui, sans-serif;
}

.lamp {
  flex: none;
  width: .8rem; height: .8rem;
  border-radius: 50%;
  background: var(--rule);
  transition: background .15s ease;
}

.signal.red    .lamp { background: #c0392b; }
.signal.amber  .lamp { background: #d99a1a; }
.signal.green  .lamp { background: #2f7d4f; }

.signal.red    strong { color: #c0392b; }
.signal.amber  strong { color: #8a6410; }
.signal.green  strong { color: #2f7d4f; }

/* Choosing a second factor.
 *
 * Cards rather than radio buttons: each option needs a sentence explaining
 * what it costs, and a radio label that long stops reading like a choice.
 *
 * Scoped under .auth throughout, because `.auth button` sets a solid accent
 * background and white text on every button in this section. Without
 * matching that specificity these rendered as dark teal cards with dark
 * text on them - unreadable, which is exactly how it was reported.
 */
.auth .choices { display: grid; gap: .75rem; margin: 1.5rem 0; }

.auth .factor-choice {
  display: block; width: 100%; text-align: left;
  margin-top: 0;
  padding: 1rem 1.1rem;
  border: 1px solid var(--rule); border-radius: 6px;
  background: var(--paper);
  color: var(--ink);
  font: inherit;
  cursor: pointer;
}
.auth .factor-choice:hover:not(:disabled) {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 5%, var(--paper));
}
.auth .factor-choice:disabled { opacity: .55; cursor: default; }

.auth .factor-choice strong {
  display: inline;
  font: 600 1rem/1.3 "Segoe UI", system-ui, sans-serif;
  color: var(--ink);
}
.auth .factor-choice em {
  display: block; margin-top: .4rem;
  font-style: normal; font-size: .85rem; line-height: 1.5;
  color: var(--soft);
}

/* Available, not encouraged. */
.auth .factor-choice.risky { border-style: dashed; }
.auth .factor-choice.risky strong { color: var(--soft); }

.auth .pill {
  display: inline-block; margin-left: .5rem;
  padding: .12rem .5rem; border-radius: 999px;
  background: var(--accent); color: var(--paper);
  font: 600 .66rem/1.6 "Segoe UI", system-ui, sans-serif;
  text-transform: uppercase; letter-spacing: .06em;
  vertical-align: 1px;
}
.auth .pill.muted { background: var(--rule); color: var(--soft); }
