/* ============================================================
   Self-serve onboarding — signup.astro and verify.astro.

   These two screens run before a tenant exists, so they cannot use tenant
   branding: they are built from the platform tokens in base.css only. They
   are also the only pages with no navigation to escape into, which is why
   every dead end on them has an explicit way out.

   Kept as a plain stylesheet rather than a scoped <style> in each page: both
   pages inject their markup with set:html, so Astro cannot stamp its scoping
   attribute onto the elements and a scoped stylesheet would match nothing.
   ============================================================ */

.onboard {
  max-width: 34rem;
  margin: 0 auto;
  padding: 3rem 1.25rem 5rem;
}
@media (max-width: 30rem) { .onboard { padding-top: 1.75rem; } }

.onboard__badge {
  display: inline-block;
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--color-primary);
  background: color-mix(in oklab, var(--color-primary) 14%, transparent);
  border: 1px solid color-mix(in oklab, var(--color-primary) 30%, transparent);
  border-radius: 999px;
  padding: .3rem .7rem;
  margin-bottom: 1rem;
}
.onboard h1 {
  font-family: var(--font-display, inherit);
  font-size: clamp(1.75rem, 5vw, 2.4rem);
  line-height: 1.15;
  letter-spacing: -0.02em;
  margin-bottom: .75rem;
}
.onboard h1 em { font-style: normal; color: var(--color-primary); }
.onboard__lede {
  color: var(--color-text-muted);
  font-size: 1.02rem;
  margin-bottom: 1.75rem;
}

.onboard__card {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: 1.5rem;
}
@media (max-width: 30rem) { .onboard__card { padding: 1.15rem; } }

.field { margin-bottom: 1.1rem; }
.field > label {
  display: block;
  font-size: .875rem;
  font-weight: 600;
  margin-bottom: .4rem;
}
.field input {
  width: 100%;
  font: inherit;
  font-size: 1rem; /* 16px: anything smaller makes iOS zoom on focus */
  color: var(--color-text);
  background: var(--color-bg-alt);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: .7rem .85rem;
  transition: border-color .15s, box-shadow .15s;
}
.field input::placeholder { color: var(--color-text-muted); opacity: .7; }
.field input:focus-visible {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-primary) 30%, transparent);
}
.field input[aria-invalid="true"] { border-color: var(--err); }
.field input[aria-invalid="true"]:focus-visible {
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--err) 30%, transparent);
}

.field__hint, .field__err {
  font-size: .8rem;
  margin-top: .4rem;
}
.field__hint { color: var(--color-text-muted); }
.field__err  { color: var(--err); font-weight: 500; }
/* Collapsed when there is nothing to say, so an empty error does not sit
   as a blank line under every field. The address preview below keeps its
   own reserved slot, which is what stops the form jumping as you type. */
.field__err:empty { display: none; }

/* The same semantic tones base.css defines, under the shorter names these
   pages use. Aliased rather than redeclared so they cannot drift apart. */
:root { --err: var(--tone-bad); --ok: var(--tone-ok); }

/* The live address preview is a promise about what they are about to get,
   so it is given the weight of one rather than hidden in a hint. */
.addr {
  margin-top: .5rem;
  font-size: .82rem;
  color: var(--color-text-muted);
  min-height: 1.2em;
}
.addr b {
  color: var(--color-text);
  font-weight: 600;
  word-break: break-all;
}

.btn-primary {
  width: 100%;
  font: inherit;
  font-weight: 600;
  font-size: 1rem;
  color: #fff;
  background: var(--color-primary);
  border: 0;
  border-radius: var(--radius);
  padding: .8rem 1rem;
  cursor: pointer;
  transition: background .15s, opacity .15s;
}
.btn-primary:hover:not(:disabled) { background: var(--color-primary-dark); }
.btn-primary:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}
.btn-primary:disabled { opacity: .6; cursor: progress; }

.btn-quiet {
  font: inherit;
  font-size: .875rem;
  font-weight: 600;
  color: var(--color-primary);
  background: none;
  border: 0;
  padding: .25rem 0;
  cursor: pointer;
  text-decoration: underline;
}
.btn-quiet:disabled { color: var(--color-text-muted); cursor: default; text-decoration: none; }

.alert {
  border-radius: var(--radius);
  padding: .8rem .95rem;
  font-size: .9rem;
  margin-bottom: 1.1rem;
}
.alert--err {
  color: var(--err);
  background: color-mix(in oklab, var(--err) 12%, transparent);
  border: 1px solid color-mix(in oklab, var(--err) 35%, transparent);
}
.alert--ok {
  color: var(--ok);
  background: color-mix(in oklab, var(--ok) 12%, transparent);
  border: 1px solid color-mix(in oklab, var(--ok) 35%, transparent);
}

.points {
  list-style: none;
  margin-top: 1.75rem;
  display: grid;
  gap: .7rem;
}
.points li {
  display: flex;
  gap: .6rem;
  align-items: flex-start;
  font-size: .9rem;
  color: var(--color-text-muted);
}
.points svg { flex: 0 0 auto; margin-top: .25rem; stroke: var(--ok); }

.onboard__foot {
  margin-top: 1.75rem;
  font-size: .875rem;
  color: var(--color-text-muted);
  text-align: center;
}
/* Closed, it reads as part of the sentence; open, it becomes a block so
   the explanation gets a real box. An inline parent gives its children no
   block formatting context, which is why the open panel had no card. */
.onboard__foot details { display: inline; }
.onboard__foot details[open] { display: block; margin-top: .5rem; }
.onboard__foot summary {
  display: inline;
  list-style: none;
  cursor: pointer;
  color: var(--color-primary);
  text-decoration: underline;
}
/* Both are needed: ::marker covers Firefox and modern Chrome, the
   -webkit- pseudo-element covers Safari. Missing either leaves a
   disclosure triangle dropped into the middle of a sentence. */
.onboard__foot summary::marker { content: ""; }
.onboard__foot summary::-webkit-details-marker { display: none; }
.onboard__foot details > div {
  margin-top: .6rem;
  text-align: left;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: .8rem .95rem;
}

/* ── Sent state ── */
.sent { text-align: center; }
.seal {
  width: 3.25rem;
  height: 3.25rem;
  margin: 0 auto 1.1rem;
  border-radius: 999px;
  display: grid;
  place-items: center;
  background: var(--ok);
}
.seal--err { background: var(--err); }
.sent__to {
  display: inline-block;
  font-weight: 600;
  color: var(--color-text);
  word-break: break-all;
}
.sent__note {
  margin-top: 1.25rem;
  font-size: .85rem;
  color: var(--color-text-muted);
}
.sent__actions {
  margin-top: 1.25rem;
  display: flex;
  gap: 1.25rem;
  justify-content: center;
  flex-wrap: wrap;
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* ── Verify: the provisioned-account handover ──────────────────────────────
   Shown once, on the one screen that carries a password nothing else will
   show again — so the credentials are a table that can be read out loud and
   copied, not prose. */
.creds {
  text-align: left;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: .35rem 1.1rem;
  margin: 1.5rem 0;
}
.creds__row {
  display: flex;
  flex-wrap: wrap;
  gap: .35rem 1rem;
  align-items: baseline;
  padding: .8rem 0;
  border-bottom: 1px solid var(--color-border);
}
.creds__row:last-child { border-bottom: 0; }
.creds__k {
  flex: 0 0 9.5rem;
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.creds__v {
  flex: 1 1 12rem;
  font-weight: 600;
  /* `anywhere` rather than `break-all`: a long address should wrap at the dots
     and slashes it already has and only break mid-token as a last resort. */
  overflow-wrap: anywhere;
}
.creds__v.mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 1.05rem;
  letter-spacing: .02em;
}

.copy {
  font: inherit;
  font-size: .78rem;
  font-weight: 600;
  color: var(--color-primary);
  background: none;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: .25rem .55rem;
  cursor: pointer;
  flex: 0 0 auto;
}
.copy:hover { border-color: var(--color-primary); }
.copy[data-copied="1"] { color: var(--ok); border-color: var(--ok); }

.warn {
  text-align: left;
  font-size: .85rem;
  color: var(--color-text);
  background: color-mix(in oklab, var(--color-accent) 12%, transparent);
  border: 1px solid color-mix(in oklab, var(--color-accent) 35%, transparent);
  border-radius: var(--radius);
  padding: .8rem .95rem;
  margin-top: 1.25rem;
}

.btn-primary--link {
  display: block;
  text-align: center;
  text-decoration: none;
}
.btn-primary--link:hover { color: #fff; text-decoration: none; }

.next {
  text-align: left;
  margin-top: 1.75rem;
  font-size: .9rem;
}
.next h2 {
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: .6rem;
}
.next ol { margin: 0; padding-left: 1.2rem; color: var(--color-text-muted); }
.next li { margin-bottom: .35rem; }

/* ── Verify: waiting ── */
.spinner {
  width: 2.25rem;
  height: 2.25rem;
  margin: 0 auto 1.25rem;
  border-radius: 999px;
  border: 3px solid var(--color-border);
  border-top-color: var(--color-primary);
  animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ── Parent portal bar ───────────────────────────────────────────────────────
   The portal keeps its own session, so it carries its own sign-out control
   rather than borrowing one from the site header. */
.portal-bar {
  max-width: 46rem;
  margin: 0 auto;
  padding: .85rem 1.25rem 0;
  display: flex;
  justify-content: flex-end;
}
