/* Design tokens mirror computingsphere_www/style.css's :root - can't
   literally share the file across repos/containers (this is a separate
   deploy unit, see ../README.md), so the values are kept in sync by hand
   instead, same approach widgets/topbar.js already takes for its own
   shadow-DOM styles. */
:root {
  --bg: #0a0d10;
  --bg-raised: #10151a;
  --border: #1f2830;
  --text: #e6edf1;
  --text-dim: #8b9aa5;
  --accent: #00e5b4;
  --accent-dim: #00b590;
  --danger: #ff6b6b;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, sans-serif;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  display: flex;
  flex-direction: column;
}

a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-dim); }

.portal-topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 52px;
  padding: 0 16px;
  border-bottom: 1px solid var(--border);
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 600;
  color: var(--text);
  text-decoration: none;
}

.brand .dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 10px 1px rgba(0, 229, 180, .5);
}

.lang-select {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  color: var(--text-dim);
  border-radius: 4px;
  font-size: 12px;
  padding: 4px 6px;
  font: inherit;
}

.portal-main {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px 20px;
}

.portal-card {
  width: 100%;
  max-width: 360px;
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 28px;
}

.portal-card h1 {
  font-size: 1.2rem;
  margin: 0 0 6px;
}

.portal-lede {
  color: var(--text-dim);
  font-size: 0.85rem;
  margin: 0 0 22px;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 0.85rem;
  margin-bottom: 14px;
}

.field input[type="text"],
.field input[type="password"],
.field input[type="email"] {
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 6px;
  padding: 9px 10px;
  font-size: 0.9rem;
  font-family: inherit;
}

.field input:focus {
  outline: none;
  border-color: var(--accent-dim);
}

/* Password policy requirements (reset-password-step2.js) - neutral by
   default, switches to .portal-status.error's own red for the same
   text when the field doesn't meet it yet. */
.field-hint {
  color: var(--text-dim);
  font-size: 0.8rem;
}
.field-hint.error { color: var(--danger); }

.checkbox-field {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.85rem;
  margin-bottom: 18px;
}

.btn-primary {
  display: block;
  width: 100%;
  background: var(--accent);
  color: #04120d;
  border: none;
  font-size: 0.9rem;
  font-weight: 600;
  padding: 10px 18px;
  border-radius: 6px;
  cursor: pointer;
}

.btn-primary:hover { background: var(--accent-dim); }
.btn-primary:disabled { opacity: 0.6; cursor: default; }

.portal-links {
  margin-top: 16px;
  display: flex;
  justify-content: space-between;
  font-size: 0.82rem;
}

.portal-status {
  margin-top: 14px;
  font-size: 0.85rem;
  min-height: 1.2em;
}

.portal-status.error { color: var(--danger); }
.portal-status.success { color: var(--accent); }

.mono { font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace; }

.btn-ghost {
  display: inline-block;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text);
  font-size: 0.9rem;
  font-weight: 600;
  padding: 9px 16px;
  border-radius: 6px;
  cursor: pointer;
}

.btn-ghost:hover { border-color: var(--accent-dim); }

.btn-danger { background: var(--danger); color: #2a0a0a; }
.btn-danger:hover { background: var(--danger); opacity: 0.85; }

.btn-inline { display: inline-block; width: auto; }

/* two-factor.html - wider than the 360px login/reset-password cards
   (portal-card above) since it shows a TOTP secret/QR link and a code
   field side by side with labels, not one field per row. */
.portal-card-wide { max-width: 460px; }

.portal-card-wide h2 {
  font-size: 1rem;
  margin: 22px 0 4px;
}

.portal-card-wide section:first-of-type h2 { margin-top: 0; }

.tf-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

/* The heading/status block takes the slack; the action button keeps its
   intrinsic width and never wraps its label to two or three lines (which
   is what threw the button out of alignment with the text next to it). */
.tf-row > div { min-width: 0; }
.tf-row .btn-inline { flex-shrink: 0; white-space: nowrap; }

.tf-status-label {
  color: var(--text-dim);
  font-size: 0.85rem;
  margin: 2px 0 0;
}

.tf-status-label.tf-status-on { color: var(--accent); }
.tf-status-label.tf-status-error { color: var(--danger); }

/* qrcode.js's createImgTag() output (two-factor.js's renderQr) - a
   data:image/gif;base64 <img>, not inline SVG (see that function's own
   comment for why: Chromium's force-dark color inversion has been seen
   selectively breaking inline SVG QR codes). color-scheme: light is
   belt-and-suspenders on top of that - tells the browser this subtree is
   intentionally light-on-white regardless of the page's own dark theme,
   the same signal force-dark heuristics are supposed to honor. */
.tf-qr {
  display: flex;
  justify-content: center;
  margin: 4px 0 4px;
  color-scheme: light;
}

.tf-qr img {
  width: 200px;
  height: 200px;
}

.tf-field-label {
  font-size: 0.82rem;
  color: var(--text-dim);
  margin: 16px 0 8px;
}

.tf-open-link {
  display: inline-block;
  width: auto;
  text-align: center;
  text-decoration: none;
}

.tf-secret-row {
  display: flex;
  gap: 8px;
}

.tf-secret-row input {
  flex: 1;
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 6px;
  padding: 9px 10px;
  font-size: 0.85rem;
}

#tf-elevate-panel,
#tf-register-panel {
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--border);
}

/* Icon + visible text (two-factor.html's settings-management buttons
   only) - the icon is a small accent next to the label, never a
   replacement for it. Deliberately not icon-only anywhere in this
   repo: portal/ is the platform's login/2FA gate, where a misread icon
   is a real lockout risk that a dense toolbar's visual-clutter problem
   (the reason icon-only buttons exist elsewhere on the platform) simply
   doesn't apply to here. Placed after .btn-primary/.btn-ghost so it
   wins the `display` tie (same specificity, source order decides) -
   every other rule (color/padding/width/etc.) still comes from those
   base classes unchanged. */
.btn-icon-text {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
}

.btn-icon-text svg {
  flex: none;
}
