﻿:root {
  /* phase-11-03. Drawer scrim, per theme rather than one literal: Flow's flat 30% black is a
     strong dim over a white page and a barely-visible one over a dark canvas, so a single value
     cannot serve both themes (and will not serve Dim either - see phase-11-06). Same lesson as
     --lvxd-on-accent on 2026-08-06. Light keeps Flow's 30%; dark lifts to 55% because the surface
     underneath is already near-black. */
  --lvxd-scrim: rgba(0, 0, 0, 0.30);

  /* phase-11-04. Notification tints - SIX semantic families, not twelve one-per-type colours. A
     colour that maps 1:1 to a type carries no meaning beyond the icon already sitting next to it;
     grouped by what the notification is ABOUT, colour becomes scannable ("something financial
     needs me") before any word is read.
     These are deliberately NOT the per-company accent-swatch system (phase-1-03) - a tint says what
     kind of thing this is, never which company you are. Do not wire them to AccentColor.
     Ink values are the text/icon colour ON the tinted tile, contrast-checked against the tile
     rather than against the page - the mistake --lvxd-on-accent existed to fix on 2026-08-06. */
  --lvxd-notif-people-bg: #e0f2fe;
  --lvxd-notif-people-ink: #075985;
  --lvxd-notif-access-bg: #ede9fe;
  --lvxd-notif-access-ink: #5b21b6;
  --lvxd-notif-success-bg: #dcfce7;
  --lvxd-notif-success-ink: #166534;
  --lvxd-notif-warning-bg: #fef3c7;
  --lvxd-notif-warning-ink: #92400e;
  --lvxd-notif-danger-bg: #fee2e2;
  --lvxd-notif-danger-ink: #991b1b;
  --lvxd-notif-neutral-bg: #f4f4f5;
  --lvxd-notif-neutral-ink: #3f3f46;

  --lvxd-bg-canvas: #f7f7f9;
  --lvxd-surface: #ffffff;
  --lvxd-surface-muted: #fafafa;
  --lvxd-border: #e4e4e7;
  --lvxd-border-soft: #f0f0f2;
  --lvxd-text-heading: #09090b;
  --lvxd-text-body: #18181b;
  --lvxd-text-muted: #71717a;
  --lvxd-text-faint: #a1a1aa;
  --lvxd-text-disabled: #c4c4cc;
  /* LivexHub's primary is the Hub mark's cyan (--lvxd-logo-hub-stop-4, #24cbfe). It is the ONE
     hue shared by both themes - see the .dark block, which carries the same hue at display
     lightness. Before this, light mode used Metronic's default blue #1b84ff and dark used
     #539bf5: inherited defaults, never a Hub decision, and CLAUDE.md's per-product accent list
     (LivexDesk blue / LivexAssets emerald / LivexBooks amber) has no LivexHub row at all.

     Cyan over the mark's other seven stops because it is the only one that neither collides with
     a semantic colour nor strands the existing blue-family chrome. Green was tried and rejected:
     it rendered --lvxd-form-feedback-info identical to -success (both pull their hue from
     --lvxd-accent / --lvxd-success), so "informational" and "saved OK" became one colour.

     #24cbfe itself is only 1.89:1 on white, so light mode carries the hue at a darker lightness
     (4.64:1 on white, and white-on-accent 4.64:1 so it works as fill AND as text). Do not
     "correct" this to the raw stop value - the raw stop is the DARK accent. */
  --lvxd-accent: #0b7ea3;
  --lvxd-accent-hover: #096987;
  /* Ink for anything painted ON --lvxd-accent (buttons, chips, avatars, badge counts). White works
     here because the light accent is the darkened stop; in dark it does NOT - see the .dark block. */
  --lvxd-on-accent: #fff;
  --lvxd-accent-soft: #ecf8fc;
  --lvxd-accent-soft-strong: #c6ebf6;
  /* Decorative glows/shadows use the mark's bright stop rather than --lvxd-accent: at .06-.10
     alpha the darkened accent turns muddy grey instead of reading as a tint. */
  --lvxd-accent-glow-rgb: 36, 203, 254;
  /* Two-stop ramp for the small white-ink brand pills (SSO badge, "Most popular" tier chip).
     A token pair rather than a whole gradient so each call site keeps its own angle and stop
     order. Both stops must stay dark enough to hold white text at ~3.5:1 - these pills are
     9-11px, so the stops carry the contrast, not the ink. */
  --lvxd-accent-grad-a: #0b7ea3;
  --lvxd-accent-grad-b: #7239ea;
  --lvxd-success: #17c653;
  --lvxd-success-text: #0f7a3d;
  --lvxd-success-soft: #e9fbf0;
  --lvxd-success-border: #a7f3d0;
  --lvxd-warning-text: #b45309;
  --lvxd-warning-soft: #fff7e0;
  /* Starred/favourite stars only, and deliberately NOT themed - a star should read gold on
     Light, Dim and Dark alike. It is intentionally separate from --lvxd-warning-text, which
     these stars used to borrow: that token has to stay dark enough for warning TEXT on white
     (#b45309, 5.9:1), which made the stars a muddy burnt orange. This one is a decorative
     glyph beside a heading, never text, so it is tuned for recognisability instead. */
  --lvxd-star-gold: #daaa3f;
  /* True red, same scale family as the zinc neutrals above - deliberately NOT Metronic's
     #f8285a, which read as neon/magenta against this palette and measured only 3.83:1 on
     white, failing AA for the 12.5px .lvxd-field-error text it was used for. */
  --lvxd-danger: #dc2626;
  /* phase-11-07. Ink ON a solid --lvxd-danger fill (the notification count badge). White measures
     4.83:1 on #dc2626 - AA for the 10px bold badge text it carries. Named rather than hardcoded so
     the dark stop can differ, which it must - see the .dark block. */
  --lvxd-on-danger: #ffffff;
  --lvxd-danger-text: #b91c1c;
  --lvxd-danger-soft: #fef2f2;
  --lvxd-danger-border: #fecaca;
  --lvxd-chip-bg: #f8f8f9;
  --lvxd-preview-gradient: radial-gradient(120% 90% at 70% 10%, #ecf8fc 0%, #f2fafd 42%, #fbfdfe 100%);
  --lvxd-preview-dot: rgba(var(--lvxd-accent-glow-rgb), .06);
  --lvxd-preview-glow: rgba(var(--lvxd-accent-glow-rgb), .10);
  --lvxd-card-shadow: 0 12px 40px rgba(var(--lvxd-accent-glow-rgb), .10), 0 2px 8px rgba(15, 23, 42, .04);
  --lvxd-card-shadow-done: 0 12px 40px rgba(23, 198, 83, .14), 0 2px 8px rgba(15, 23, 42, .05);

  /* The LivexHub mark palette (--lvxd-logo-hub-*) and the expressive/celebration layer built on
     it now live in lvxd-shared.css, NOT here. lvxd-onboarding.css is only loaded by _Layout, so
     anything defined here is invisible to the Storefront (_MarketingLayout loads lvxd-shared.css
     but not this file) - which is precisely why the review-form confetti had to fall back to
     semantic --lvxd-sf-* tokens and ended up firing danger red on a success screen. */
}

/* Dark theme. Same Hub cyan as :root, carried at display lightness (#24cbfe, the mark's raw
   stop-4 - it needs no darkening here, unlike light mode). The neutral ramp is tinted with that
   same hue rather than plain zinc, so dark surfaces read as "the Hub's dark" instead of a generic
   slate. It replaced a GitHub-dimmed ramp (#1c2128 / #22272e) at hue ~213 - close enough to the
   old blue accent to look accidental, and not a hue the mark contains.

   Deliberately grey-dominant, not a cyan wash - the greys below sit at ~2-4% chroma, enough to
   tint under a white text layer but not enough to read as a colour. Turn the tint up here and the
   whole app goes teal; that is the failure mode this ramp is calibrated against.

   --lvxd-dark-tint-rgb is the one place the hue lives: every rgba() tint below composes from it,
   so a re-hue is a one-line change plus the six grey hexes. The hexes cannot reference it - CSS
   has no colour-mix in the token layer here - so if you change the tint, re-derive them at the
   same chroma rather than leaving them cyan. */
.dark {
  --lvxd-dark-tint-rgb: 36, 203, 254;

  /* See the :root note. 30% over #16191a is almost invisible; 55% reads as the same separation
     light gets from 30% over white. */
  --lvxd-scrim: rgba(0, 0, 0, 0.55);

  /* Dark tints are NOT the light values darkened - a light pastel tile with dark ink inverts to a
     dark tile with light ink, so both stops move independently. Backgrounds sit near the surface
     (#1c2022) so tiles read as tinted rather than as glowing blocks; inks are the light-mode hue
     lifted until legible on that tile. Each pair was chosen against the tile it sits on, not
     against the canvas. */
  --lvxd-notif-people-bg: #12303f;
  --lvxd-notif-people-ink: #7dd3fc;
  --lvxd-notif-access-bg: #2a2245;
  --lvxd-notif-access-ink: #c4b5fd;
  --lvxd-notif-success-bg: #14321f;
  --lvxd-notif-success-ink: #86efac;
  --lvxd-notif-warning-bg: #3a2c12;
  --lvxd-notif-warning-ink: #fcd34d;
  --lvxd-notif-danger-bg: #3d1d1d;
  --lvxd-notif-danger-ink: #fca5a5;
  --lvxd-notif-neutral-bg: #262b2d;
  --lvxd-notif-neutral-ink: #b8c0c3;

  /* #16181a measured 210deg - a blue, 16deg off the 194deg accent, on the largest area on
     screen. #16191a is 195.0deg at the same 8.3% saturation and 9.4% lightness. See the
     8-bit-floor note at the end of this block before "correcting" any of the others. */
  --lvxd-bg-canvas: #16191a;
  --lvxd-surface: #1c2022;
  --lvxd-surface-muted: #23282a;
  --lvxd-border: #2f3538;
  --lvxd-border-soft: #252a2c;
  --lvxd-text-heading: #f1f4f5;
  --lvxd-text-body: #dee3e5;
  --lvxd-text-muted: #9aa1a4;
  --lvxd-text-faint: #6b7275;
  --lvxd-text-disabled: #4c5254;
  /* The mark's stop-4 unmodified. 8.59:1 on --lvxd-surface. */
  --lvxd-accent: #24cbfe;
  --lvxd-accent-hover: #5cd9fe;
  /* Dark ink, NOT white. The gradient note below already recorded that white on #24cbfe is
     unreadable, but every solid-accent surface (primary buttons, selected chips, avatars, approve
     buttons) still hardcoded #fff and shipped at ~1.9:1. This near-black carries the accent's own
     hue and holds 7.9:1 on #24cbfe and better on --lvxd-accent-hover, so hover states are safe too.
     Do not "unify" this with :root's #fff - the two accents are different lightnesses by necessity. */
  --lvxd-on-accent: #062a35;
  --lvxd-accent-soft: rgba(var(--lvxd-dark-tint-rgb), .12);
  --lvxd-accent-soft-strong: rgba(var(--lvxd-dark-tint-rgb), .28);
  --lvxd-accent-glow-rgb: var(--lvxd-dark-tint-rgb);
  /* Cyan -> the same purple :root uses, but stop-a is shifted well down from --lvxd-accent:
     white ink on #24cbfe is 1.65:1, whereas #0e7490 holds 5.36:1. Do not "tidy" this to reuse
     the accent token. */
  --lvxd-accent-grad-a: #0e7490;
  --lvxd-accent-grad-b: #6d4bd8;
  /* Green, and now safely so: with a cyan accent there is no longer an accent/success collision,
     which is what forced the muted-vs-vivid green split this token briefly carried. */
  --lvxd-success: #57ab5a;
  --lvxd-success-text: #7cc47f;
  --lvxd-success-soft: rgba(87, 171, 90, .16);
  --lvxd-success-border: rgba(87, 171, 90, .35);
  --lvxd-warning-text: #daaa3f;
  --lvxd-warning-soft: rgba(218, 170, 63, .16);
  /* Dark pairs to the same red family. -text is red-400 rather than reusing the base: the old
     shared #e5534b measured 4.06:1 on --lvxd-surface, just under AA; #f87171 is 5.43:1. */
  --lvxd-danger: #ef4444;
  /* Dark ink, NOT white - white on #ef4444 is 3.76:1, BELOW AA for small text. This is the same
     trap --lvxd-on-accent was created for on 2026-08-06, and the reason this token exists at all
     rather than the badge hardcoding #fff like the pre-08-06 accent surfaces did. #450a0a is 8.9:1. */
  --lvxd-on-danger: #450a0a;
  --lvxd-danger-text: #f87171;
  --lvxd-danger-soft: rgba(239, 68, 68, .16);
  --lvxd-danger-border: rgba(239, 68, 68, .35);
  --lvxd-chip-bg: #191d1f;
  --lvxd-preview-gradient: radial-gradient(120% 90% at 70% 10%, rgba(var(--lvxd-dark-tint-rgb), .12) 0%, rgba(var(--lvxd-dark-tint-rgb), .05) 42%, #16191a 100%);
  --lvxd-preview-dot: rgba(var(--lvxd-dark-tint-rgb), .10);
  --lvxd-preview-glow: rgba(var(--lvxd-dark-tint-rgb), .16);
  --lvxd-card-shadow: 0 12px 40px rgba(0, 0, 0, .5), 0 2px 8px rgba(0, 0, 0, .34);
  /* Green, not the tint: this shadow marks a COMPLETED card, so it tracks success, not accent. */
  --lvxd-card-shadow-done: 0 12px 40px rgba(87, 171, 90, .2), 0 2px 8px rgba(0, 0, 0, .3);

  /* 8-BIT FLOOR - read before "correcting" the grey hues above.
     Measured, the six neutrals sit at 195-200deg against the accent's 194deg. That residual few
     degrees is not sloppiness, it is the limit of the format: at ~9% saturation the R-to-B spread
     is only 4-9 steps of 256, and hue resolution scales with that spread. Landing exactly 194deg
     at this lightness needs a wider spread, i.e. MORE saturation - which is the one thing this
     ramp must not have, since the brief was dark grey with a hint of hue, not a teal wash.
     So: 195-200deg is the achievable floor here and is imperceptible in flat fills. Only
     bg-canvas was worth fixing (it had drifted to 210deg, a visibly different hue family, over
     the app's largest surface). If you re-hue the ramp, re-measure rather than hand-adjusting -
     the perceived tint comes from saturation, and the hue only needs to be in the right family. */
}

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: var(--lvxd-bg-canvas);
}

body {
  font-family: "Inter", ui-sans-serif, system-ui, sans-serif;
  color: var(--lvxd-text-body);
  -webkit-font-smoothing: antialiased;
  letter-spacing: -.006em;
}

.lvxd-onboarding {
  display: flex;
  width: 100vw;
  height: 100dvh;
  overflow: hidden;
}

/* ---- left pane: wizard flow ---- */

.lvxd-onboarding-left {
  flex: 1 1 0;
  min-width: 0;
  height: 100%;
  background: var(--lvxd-surface);
  display: flex;
  flex-direction: column;
  padding: 30px 46px 26px;
  overflow: hidden;
}

.lvxd-onboarding-body-inner {
  width: 100%;
  max-width: 520px;
  margin: 0 auto;
}

.lvxd-onboarding-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: inherit;
}

/* Height-driven - see the matching note in lvxd-login.css. */
.lvxd-onboarding-brand-mark {
  width: auto;
  height: 30px;
  flex-shrink: 0;
}

/* Weight contrast, not hue contrast - see the matching note in lvxd-login.css. */
.lvxd-onboarding-brand-name {
  font-size: 17px;
  font-weight: 400;
  letter-spacing: -.02em;
  color: var(--lvxd-text-heading);
}

.lvxd-onboarding-brand-name-accent {
  font-weight: 700;
}

.lvxd-onboarding-progress {
  margin-top: 0;
  margin-bottom: 24px;
  display: flex;
  align-items: center;
  gap: 6px;
}

.lvxd-onboarding-progress-seg {
  flex: 1;
  height: 6px;
  border-radius: 5px;
  background: var(--lvxd-border);
  transition: background .45s ease, height .3s cubic-bezier(.34, 1.56, .64, 1), box-shadow .45s ease;
}

.lvxd-onboarding-progress-seg.is-active {
  height: 9px;
}

.lvxd-onboarding-steplabel {
  margin-top: 0;
  margin-bottom: 8px;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--lvxd-accent);
  letter-spacing: .06em;
  text-transform: uppercase;
}

.lvxd-onboarding-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

.lvxd-onboarding-body-inner {
  min-height: 100%;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  justify-content: safe center;
  padding: 22px 0;
}

#lvxdOnboardingStepContent {
  margin-top: 24px;
  min-height: 284px;
}

.lvxd-onboarding-title {
  margin: 0;
  font-size: 29px;
  line-height: 1.14;
  font-weight: 700;
  letter-spacing: -.028em;
  color: var(--lvxd-text-heading);
  text-wrap: balance;
}

.lvxd-onboarding-subtitle {
  margin: 11px 0 0;
  font-size: 15.5px;
  line-height: 1.5;
  color: var(--lvxd-text-muted);
  max-width: 420px;
  text-wrap: pretty;
}

.lvxd-onboarding-step {
  margin-top: 26px;
}

.lvxd-onboarding-step[hidden] {
  display: none;
}

.lvxd-onboarding-input {
  width: 100%;
  height: 54px;
  padding: 0 18px;
  font-size: 16.5px;
  border: 1.5px solid var(--lvxd-border);
  border-radius: 13px;
  outline: none;
  color: var(--lvxd-text-body);
  background: var(--lvxd-surface);
  transition: border-color .15s, box-shadow .15s;
}

.lvxd-onboarding-input:focus {
  border-color: var(--lvxd-accent);
  box-shadow: 0 0 0 4px var(--lvxd-accent-soft);
}

/* Red variant for any invalid onboarding input (owner email, and the same treatment the hex/slug
   fields already carried). The field ITSELF turns red, not only the .lvxd-field-error text beneath
   it - so a validation problem reads on the control the visitor is looking at. The focus rule keeps
   it red while they are correcting it, rather than the accent ring masking the error. */
.lvxd-onboarding-input.is-invalid {
  border-color: var(--lvxd-danger-border);
}

.lvxd-onboarding-input.is-invalid:focus {
  border-color: var(--lvxd-danger);
  box-shadow: 0 0 0 4px var(--lvxd-danger-soft);
}

.lvxd-onboarding-input.lvxd-onboarding-input-inline {
  flex: 1;
  height: 50px;
}

.lvxd-onboarding-name-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
}

.lvxd-onboarding-field-label {
  display: block;
  margin: 0 2px 6px;
  font-size: 13px;
  font-weight: 600;
  color: var(--lvxd-text-muted);
}

.lvxd-onboarding-privacy-notice {
  margin: 14px 2px 0;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--lvxd-text-muted);
}

.lvxd-onboarding-privacy-notice a {
  color: var(--lvxd-accent);
  font-weight: 600;
  text-decoration: none;
}

.lvxd-onboarding-privacy-notice a:hover {
  text-decoration: underline;
}

/* Step 1's "Already have an account?" line - a real navigation choice, not fine print, so it
   gets its own top divider and slightly more weight than the privacy notice below it. */
.lvxd-onboarding-signin-notice {
  margin: 18px 2px 0;
  padding-top: 14px;
  border-top: 1px solid var(--lvxd-border-soft);
  font-size: 13.5px;
  color: var(--lvxd-text-muted);
}

.lvxd-onboarding-signin-link {
  color: var(--lvxd-accent);
  font-weight: 600;
  text-decoration: none;
}

.lvxd-onboarding-signin-link:hover {
  text-decoration: underline;
}

/* logo colour swatches (curated palette + selection ring, per §20.5) */

.lvxd-onboarding-swatch-label {
  margin-top: 22px;
  font-size: 13px;
  font-weight: 600;
  color: var(--lvxd-text-muted);
}

.lvxd-onboarding-swatch-row {
  margin-top: 12px;
  display: flex;
  align-items: center;
  gap: 12px;
}

.lvxd-onboarding-swatch {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  cursor: pointer;
  border: none;
  padding: 0;
  transition: transform .15s, box-shadow .15s;
  box-shadow: 0 1px 2px rgba(15, 23, 42, .1);
}

.lvxd-onboarding-swatch.is-selected {
  transform: scale(1.08);
}

/* brand row: logo upload + accent colour, side by side per the handoff */

.lvxd-onboarding-brand-row {
  margin-top: 22px;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 24px;
  align-items: start;
}

.lvxd-onboarding-logo-col .lvxd-onboarding-field-label,
.lvxd-onboarding-accent-col .lvxd-onboarding-field-label {
  margin: 0 2px 10px;
}

.lvxd-onboarding-logo-upload {
  width: 62px;
  height: 62px;
  border-radius: 13px;
  border: 1.5px dashed var(--lvxd-border);
  background: var(--lvxd-surface);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  cursor: pointer;
  color: var(--lvxd-text-muted);
  transition: border-color .15s, color .15s;
  overflow: hidden;
  padding: 0;
}

.lvxd-onboarding-logo-upload:hover {
  border-color: var(--lvxd-accent);
  color: var(--lvxd-accent);
}

.lvxd-onboarding-logo-upload-icon {
  font-size: 16px;
}

.lvxd-onboarding-logo-upload-text {
  font-size: 10.5px;
  font-weight: 600;
}

.lvxd-onboarding-logo-upload-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.lvxd-onboarding-logo-file-input {
  display: none;
}

/* The company step stacks three labelled fields now (name, email, subdomain); the label rule
   above carries no top margin because it was written for a single-field step. */
.lvxd-onboarding-input + .lvxd-onboarding-field-label,
.lvxd-field-error + .lvxd-onboarding-field-label,
.lvxd-onboarding-slug-row + .lvxd-onboarding-field-label {
  margin-top: 16px;
}

/* Subdomain field: input + fixed ".livex.co.za" suffix reading as one control. */
.lvxd-onboarding-slug-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.lvxd-onboarding-slug-input.lvxd-onboarding-input {
  flex: 1 1 auto;
  min-width: 0;
  font-family: ui-monospace, "SF Mono", Consolas, monospace;
}

.lvxd-onboarding-slug-suffix {
  flex: 0 0 auto;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--lvxd-text-muted);
  font-family: ui-monospace, "SF Mono", Consolas, monospace;
}

/* Subdomain availability, on its own line under .lvxd-field-error. Three states - checking /
   available / taken - because "that address is taken" is a different problem from a format error
   and must not overwrite it. Only `taken` blocks Continue (see canContinue). */
.lvxd-onboarding-slug-status {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1.4;
}

.lvxd-onboarding-slug-status i {
  font-size: 14px;
}

.lvxd-onboarding-slug-status.is-checking {
  color: var(--lvxd-text-muted);
}

.lvxd-onboarding-slug-status.is-available {
  color: var(--lvxd-success-text);
}

.lvxd-onboarding-slug-status.is-taken {
  color: var(--lvxd-danger-text);
}

/* Matches .is-invalid's treatment so a taken subdomain reads as a blocking field state, not just a
   note underneath it - the Continue button is disabled and the field should say why. */
.lvxd-onboarding-input.lvxd-onboarding-slug-input.is-taken {
  border-color: var(--lvxd-danger-border);
}

/* Discount-code status, on the plan step. Same four-state line as .lvxd-onboarding-slug-status
   above and deliberately the same metrics, because it does the same job one step later: says
   whether the server accepted what was typed. It reuses that block's spinner element
   (.lvxd-onboarding-slug-status-spin) rather than defining a second identical one.

   NONE of these states block Continue - an optional code that failed must never strand a signup -
   which is why a rejection is styled as a status line and not as .lvxd-field-error. */
.lvxd-onboarding-discount-status {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1.4;
}

.lvxd-onboarding-discount-status i {
  font-size: 14px;
}

/* Nothing typed yet, or a code with nothing to act on. Muted and regular-weight, because this is
   the hint text the field used to carry rather than a verdict on anything. */
.lvxd-onboarding-discount-status.is-idle {
  color: var(--lvxd-text-muted);
  font-weight: 400;
}

.lvxd-onboarding-discount-status.is-checking {
  color: var(--lvxd-text-muted);
}

.lvxd-onboarding-discount-status.is-applied {
  color: var(--lvxd-success-text);
}

/* Danger TEXT, but no danger border on the input: the code is optional, so a wrong one is
   information, not a field the visitor is being stopped on. */
.lvxd-onboarding-discount-status.is-rejected {
  color: var(--lvxd-danger-text);
}

.lvxd-onboarding-slug-status-spin {
  width: 12px;
  height: 12px;
  flex: 0 0 auto;
  border-radius: 50%;
  border: 2px solid var(--lvxd-border);
  border-top-color: var(--lvxd-text-muted);
  animation: lvxdSlugStatusSpin .7s linear infinite;
}

@keyframes lvxdSlugStatusSpin {
  to { transform: rotate(360deg); }
}

/* Explanatory hint under a field. Sits above .lvxd-field-error and stays visible while the
   error shows, so the user keeps the "what is this" context while fixing the "what's wrong". */
.lvxd-onboarding-field-hint {
  display: block;
  margin-top: 6px;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--lvxd-text-muted);
}

.lvxd-onboarding-field-hint-url {
  font-weight: 600;
  color: var(--lvxd-text-body);
  font-family: ui-monospace, "SF Mono", Consolas, monospace;
  overflow-wrap: anywhere;
}

.lvxd-onboarding-hex-row {
  margin-top: 12px;
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: 180px;
}

.lvxd-onboarding-hex-chip {
  width: 22px;
  height: 22px;
  border-radius: 6px;
  flex-shrink: 0;
  box-shadow: 0 1px 2px rgba(15, 23, 42, .1);
}

.lvxd-onboarding-hex-input.lvxd-onboarding-input {
  height: 38px;
  padding: 0 12px;
  font-size: 13.5px;
  font-family: ui-monospace, "SF Mono", Consolas, monospace;
}

.lvxd-onboarding-hex-input.is-invalid {
  border-color: var(--lvxd-danger-border);
}

/* role cards */

.lvxd-onboarding-role-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 11px;
}

.lvxd-onboarding-option-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  padding: 15px;
  border-radius: 14px;
  cursor: pointer;
  transition: border-color .2s, transform .15s, background .2s;
  border: 1.5px solid var(--lvxd-border);
  background: var(--lvxd-surface);
  color: var(--lvxd-text-body);
  text-align: left;
}

.lvxd-onboarding-option-card:hover {
  transform: translateY(-3px);
}

.lvxd-onboarding-option-card.is-selected {
  border-color: var(--lvxd-accent);
  background: var(--lvxd-accent-soft);
  color: var(--lvxd-accent);
}

.lvxd-onboarding-option-icon {
  width: 34px;
  height: 34px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--lvxd-chip-bg);
  color: var(--lvxd-text-faint);
  flex-shrink: 0;
  font-size: 18px;
}

.lvxd-onboarding-option-card.is-selected .lvxd-onboarding-option-icon {
  color: var(--lvxd-accent);
}

.lvxd-onboarding-option-label {
  font-size: 13px;
  font-weight: 700;
  color: var(--lvxd-text-heading);
}

.lvxd-onboarding-option-check {
  display: none;
}

/* product / feature cards */

.lvxd-onboarding-product-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.lvxd-onboarding-product-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 11px;
}

.lvxd-onboarding-product-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px;
  border-radius: 14px;
  cursor: pointer;
  transition: border-color .2s, background .2s;
  border: 1.5px solid var(--lvxd-border);
  background: var(--lvxd-surface);
  text-align: left;
}

.lvxd-onboarding-product-card:hover {
  border-color: var(--lvxd-border-soft);
}

/* Not-yet-available products stay visible for roadmap awareness (same call as Discover's
   "Coming soon" section) but aren't pickable here - dim + block pointer/hover feedback rather
   than hiding the card outright. */
.lvxd-onboarding-product-card.is-coming-soon {
  cursor: not-allowed;
  opacity: .6;
}

.lvxd-onboarding-product-card.is-coming-soon:hover {
  border-color: var(--lvxd-border);
}

.lvxd-onboarding-product-comingsoon-badge {
  display: inline-block;
  margin-top: 4px;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .02em;
  color: var(--lvxd-text-faint);
  background: var(--lvxd-border-soft);
}

.lvxd-onboarding-tile {
  width: 42px;
  height: 42px;
  border-radius: 11px;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-size: 21px;
}

.lvxd-onboarding-tile-sm {
  width: 34px;
  height: 34px;
  border-radius: 9px;
  font-size: 16px;
}

.lvxd-onboarding-tile-md {
  width: 38px;
  height: 38px;
  border-radius: 10px;
  font-size: 18px;
}

/* real product logos (own brand colours) get a neutral tile, not the coloured-accent
   treatment used for generic Keenicon glyphs — the logo artwork is never recoloured */
.lvxd-onboarding-tile.has-logo {
  background: var(--lvxd-surface);
  border: 1.5px solid var(--lvxd-border-soft);
  padding: 6px;
}

.lvxd-onboarding-tile-logo-img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.lvxd-onboarding-product-body {
  flex: 1;
  min-width: 0;
}

.lvxd-onboarding-product-name {
  font-size: 13.5px;
  font-weight: 700;
  color: var(--lvxd-text-heading);
  letter-spacing: -.01em;
}

.lvxd-onboarding-product-desc {
  font-size: 11px;
  color: var(--lvxd-text-faint);
  margin-top: 1px;
}

.lvxd-onboarding-checkbox {
  width: 22px;
  height: 22px;
  border-radius: 7px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1.5px solid var(--lvxd-border);
  background: var(--lvxd-surface);
  color: var(--lvxd-on-accent);
  font-size: 12px;
  transition: all .15s;
}

.lvxd-onboarding-checkbox.is-selected {
  border: none;
  background: var(--lvxd-accent);
}

/* plan step */

/* phase-7-06: one plan-card set per selected product - section head repurposes the same tile/name
   pattern the removed plan-covers chip row used, just as a section header instead of a chip list. */
.lvxd-onboarding-plan-product-section {
  margin-bottom: 10px;
}

.lvxd-onboarding-plan-product-section:last-of-type {
  margin-bottom: 4px;
}

.lvxd-onboarding-plan-product-name {
  font-size: 13px;
  font-weight: 700;
  color: var(--lvxd-text-heading);
}

/* Accordion toggle row - collapsed by default so N products don't stack N full tier-card
   sets; expands one product's tier list at a time (see togglePlanSection). */
.lvxd-onboarding-plan-product-toggle {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 10px 14px;
  border-radius: 14px;
  background: var(--lvxd-surface);
  border: 1.5px solid var(--lvxd-border);
  cursor: pointer;
  text-align: left;
  transition: border-color .2s;
}

.lvxd-onboarding-plan-product-toggle.is-expanded {
  border-color: var(--lvxd-accent);
  border-radius: 14px 14px 0 0;
  margin-bottom: 7px;
}

/* Read-only variant for an all-free selection (buildFreePlanConfirmation) - no picker to open. */
.lvxd-onboarding-plan-product-toggle.is-readonly { cursor: default; }
.lvxd-onboarding-plan-product-toggle.is-readonly .lvxd-onboarding-plan-product-toggle-action {
  color: var(--lvxd-text-muted);
  font-weight: 700;
}
.lvxd-onboarding-plan-free-note { margin-top: 10px; font-size: 13px; color: var(--lvxd-text-muted); text-align: center; }

.lvxd-onboarding-plan-product-toggle:focus-visible {
  outline: 2px solid var(--lvxd-accent);
  outline-offset: 2px;
}

.lvxd-onboarding-plan-product-toggle-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}

.lvxd-onboarding-plan-product-toggle-plan {
  font-size: 12px;
  color: var(--lvxd-text-muted);
}

.lvxd-onboarding-plan-product-toggle-action {
  font-size: 12px;
  font-weight: 600;
  color: var(--lvxd-accent);
  flex-shrink: 0;
}

.lvxd-onboarding-plan-product-toggle-chevron {
  font-size: 14px;
  color: var(--lvxd-text-faint);
  flex-shrink: 0;
}

.lvxd-onboarding-billing-row {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--lvxd-text-muted);
  margin-bottom: 10px;
}

.lvxd-onboarding-billing-label {
  color: var(--lvxd-text-faint);
}

.lvxd-onboarding-billing-label.is-active {
  color: var(--lvxd-text-heading);
}

.lvxd-onboarding-billing-save {
  color: var(--lvxd-success);
  font-weight: 700;
}

.lvxd-onboarding-billing-switch {
  position: relative;
  width: 44px;
  height: 25px;
  border-radius: 16px;
  background: var(--lvxd-border);
  padding: 0;
  cursor: pointer;
  transition: background .3s;
  flex-shrink: 0;
}

.lvxd-onboarding-billing-switch.is-annual {
  background: var(--lvxd-accent);
}

.lvxd-onboarding-billing-knob {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 19px;
  height: 19px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 2px 5px rgba(0, 0, 0, .25);
  transition: transform .32s cubic-bezier(.34, 1.56, .64, 1);
}

.lvxd-onboarding-billing-switch.is-annual .lvxd-onboarding-billing-knob {
  transform: translateX(19px);
}

.lvxd-onboarding-tier-list {
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.lvxd-onboarding-tier-card {
  position: relative;
  text-align: left;
  display: block;
  width: 100%;
  padding: 12px 14px;
  border-radius: 14px;
  background: var(--lvxd-surface);
  border: 1.5px solid var(--lvxd-border);
  cursor: pointer;
  transition: border-color .25s, box-shadow .25s, transform .18s;
}

.lvxd-onboarding-tier-card:hover {
  transform: translateX(3px);
}

.lvxd-onboarding-tier-card:focus-visible {
  outline: 2px solid var(--lvxd-accent);
  outline-offset: 2px;
}

/* Per-tier accent arrives as --lvxd-plan-accent, set per card by onboarding-wizard.js from the same
   catalogue AccentColor (dbo.LookupSubscriptionPlan.AccentColorHex) ManagePlans.cshtml's plan cards
   read, so a tier tints identically on the Launchpad and in the workspace. The fallback matters: a
   catalogue row with no colour drops the invalid custom property and the card lands on the neutral
   accent instead of on nothing. */
.lvxd-onboarding-tier-card.is-popular {
  border-color: color-mix(in srgb, var(--lvxd-plan-accent, var(--lvxd-accent)) 45%, transparent);
}

.lvxd-onboarding-tier-card.is-selected {
  border-color: var(--lvxd-plan-accent, var(--lvxd-accent));
  box-shadow: 0 10px 28px color-mix(in srgb, var(--lvxd-plan-accent, var(--lvxd-accent)) 22%, transparent);
}

.lvxd-onboarding-tier-head {
  display: flex;
  align-items: center;
  gap: 12px;
}

.lvxd-onboarding-tier-icon {
  width: 38px;
  height: 38px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-size: 19px;
  background: color-mix(in srgb, var(--lvxd-plan-accent, var(--lvxd-accent)) 12%, transparent);
  color: var(--lvxd-plan-accent, var(--lvxd-accent));
}

.lvxd-onboarding-tier-body {
  flex: 1;
  min-width: 0;
}

.lvxd-onboarding-tier-name-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.lvxd-onboarding-tier-name {
  font-size: 15px;
  font-weight: 800;
  color: var(--lvxd-text-heading);
}

.lvxd-onboarding-tier-popular {
  /* inline-flex since the star is now an SVG sibling of the word, not a character inside the string */
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: 20px;
  background: var(--lvxd-plan-accent, var(--lvxd-accent));
  color: #fff;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .3px;
}

.lvxd-onboarding-tier-popular svg {
  flex: none;
}

.lvxd-onboarding-tier-blurb {
  font-size: 11.5px;
  color: var(--lvxd-text-faint);
  margin-top: 1px;
}

.lvxd-onboarding-tier-price {
  display: flex;
  align-items: baseline;
  gap: 2px;
  flex-shrink: 0;
}

.lvxd-onboarding-tier-price-amount {
  font-size: 18px;
  font-weight: 800;
  color: var(--lvxd-text-heading);
  letter-spacing: -.4px;
}

.lvxd-onboarding-tier-price-per {
  font-size: 11px;
  color: var(--lvxd-text-faint);
  font-weight: 600;
}

.lvxd-onboarding-tier-radio {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 2px solid var(--lvxd-border-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  color: var(--lvxd-on-accent);
  font-size: 11px;
  transition: background .2s, border-color .2s;
}

.lvxd-onboarding-tier-radio.is-selected {
  border-color: var(--lvxd-plan-accent, var(--lvxd-accent));
  background: var(--lvxd-plan-accent, var(--lvxd-accent));
}

.lvxd-onboarding-tier-expand {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--lvxd-border-soft);
}

.lvxd-onboarding-tier-feats {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 14px;
  margin-bottom: 7px;
}

.lvxd-onboarding-tier-feat {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--lvxd-text-muted);
  font-weight: 500;
}

.lvxd-onboarding-tier-feat i {
  color: var(--lvxd-plan-accent, var(--lvxd-accent));
}

.lvxd-onboarding-tier-placeholder {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: .3px;
  color: var(--lvxd-warning-text);
  background: var(--lvxd-warning-soft);
  padding: 3px 8px;
  border-radius: 6px;
}

.lvxd-onboarding-plan-branch {
  margin-top: 12px;
  padding: 12px 14px;
  border-radius: 14px;
  display: flex;
  align-items: flex-start;
  gap: 12px;
  border: 1.5px solid var(--lvxd-border);
}

.lvxd-onboarding-plan-branch.is-free {
  background: var(--lvxd-success-soft);
}

.lvxd-onboarding-plan-branch.is-paid {
  background: var(--lvxd-accent-soft);
}

.lvxd-onboarding-plan-branch-icon {
  width: 34px;
  height: 34px;
  border-radius: 10px;
  background: var(--lvxd-surface);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-size: 17px;
}

.lvxd-onboarding-plan-branch.is-free .lvxd-onboarding-plan-branch-icon {
  color: var(--lvxd-success);
}

.lvxd-onboarding-plan-branch.is-paid .lvxd-onboarding-plan-branch-icon {
  color: var(--lvxd-accent);
}

.lvxd-onboarding-plan-branch-body {
  flex: 1;
  min-width: 0;
}

.lvxd-onboarding-plan-branch-title {
  font-size: 13.5px;
  font-weight: 800;
  color: var(--lvxd-text-heading);
}

.lvxd-onboarding-plan-branch-text {
  font-size: 12.5px;
  color: var(--lvxd-text-muted);
  margin-top: 3px;
  line-height: 1.5;
}

/* trial summary card */

.lvxd-onboarding-trial-card {
  border: 1.5px solid var(--lvxd-border);
  border-radius: 16px;
  padding: 20px;
  background: var(--lvxd-surface);
  box-shadow: 0 1px 2px rgba(15, 23, 42, .03);
}

.lvxd-onboarding-trial-items {
  margin-top: 18px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.lvxd-onboarding-trial-item {
  display: flex;
  align-items: center;
  gap: 12px;
}

.lvxd-onboarding-trial-item-body {
  flex: 1;
  min-width: 0;
}

.lvxd-onboarding-trial-item-name {
  font-size: 14px;
  font-weight: 600;
  color: var(--lvxd-text-heading);
}

.lvxd-onboarding-trial-item-plan {
  font-size: 12px;
  color: var(--lvxd-text-faint);
}

.lvxd-onboarding-trial-item-price {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--lvxd-text-muted);
  font-variant-numeric: tabular-nums;
}

.lvxd-onboarding-trial-divider {
  height: 1px;
  background: var(--lvxd-border-soft);
  margin: 18px 0;
}

.lvxd-onboarding-trial-summary {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
}

.lvxd-onboarding-trial-summary-label {
  font-size: 12px;
  color: var(--lvxd-text-muted);
}

.lvxd-onboarding-trial-summary-value {
  font-size: 20px;
  font-weight: 700;
  color: var(--lvxd-text-heading);
  letter-spacing: -.02em;
  margin-top: 2px;
  font-variant-numeric: tabular-nums;
}

.lvxd-onboarding-trial-end {
  font-size: 14px;
  font-weight: 600;
  color: var(--lvxd-success-text);
  margin-top: 3px;
  text-align: right;
}

.lvxd-onboarding-trial-disclaimer {
  margin: 14px 2px 0;
  font-size: 12.5px;
  color: var(--lvxd-text-faint);
  line-height: 1.5;
}

.lvxd-onboarding-trial-hero {
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 18px 20px;
  border-radius: 16px;
  /* Enterprise-tier blue (2026-09-11 owner call, superseding the same day's hub-yellow): the trial
     grants full ENTERPRISE access, so the band wears the Enterprise plan accent #1B84FF (the live
     Manage-plans palette, Schema/90) - a soft blue ground with a SOFTENED blue edge (owner call,
     same day: the solid #1B84FF edge sat too close to the flow's teal accents, so the edge is a
     40% tint - keeps the blue identity without the near-miss against the teal dot/eyebrow). The
     icon glyph stays full #1B84FF. color-mix keeps ground and edge legible on the light and dark
     app grounds without adding a new token. */
  background: color-mix(in srgb, #1b84ff 10%, transparent);
  border: 1.5px solid color-mix(in srgb, #1b84ff 30%, transparent);
  margin-bottom: 18px;
}

.lvxd-onboarding-trial-hero-icon {
  width: 46px;
  height: 46px;
  border-radius: 13px;
  background: var(--lvxd-surface);
  color: #1b84ff;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-size: 22px;
}

.lvxd-onboarding-trial-hero-body {
  flex: 1;
  min-width: 0;
}

.lvxd-onboarding-trial-hero-title {
  font-size: 16px;
  font-weight: 800;
  color: var(--lvxd-text-heading);
}

.lvxd-onboarding-trial-hero-text {
  font-size: 12.5px;
  color: var(--lvxd-text-muted);
  margin-top: 2px;
}

.lvxd-onboarding-trial-timeline {
  margin-bottom: 20px;
}

.lvxd-onboarding-trial-timeline-row {
  display: flex;
  gap: 13px;
}

.lvxd-onboarding-trial-timeline-rail {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex-shrink: 0;
}

.lvxd-onboarding-trial-timeline-dot {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--lvxd-surface);
  border: 2px solid var(--lvxd-border-soft);
  flex-shrink: 0;
}

.lvxd-onboarding-trial-timeline-dot.is-done {
  background: var(--lvxd-accent);
  border-color: var(--lvxd-accent);
  box-shadow: 0 0 0 4px var(--lvxd-accent-soft);
}

.lvxd-onboarding-trial-timeline-line {
  flex: 1;
  width: 2px;
  background: var(--lvxd-border);
  margin: 3px 0;
}

.lvxd-onboarding-trial-timeline-body {
  padding-bottom: 16px;
}

.lvxd-onboarding-trial-timeline-title {
  font-size: 13.5px;
  font-weight: 700;
  color: var(--lvxd-text-heading);
}

.lvxd-onboarding-trial-timeline-text {
  font-size: 12.5px;
  color: var(--lvxd-text-muted);
  margin-top: 2px;
}

.lvxd-onboarding-trial-activating {
  font-size: 12.5px;
  color: var(--lvxd-text-muted);
  margin-bottom: 13px;
}

.lvxd-onboarding-trial-reassurances {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  padding-top: 14px;
  margin-top: 16px;
  border-top: 1px solid var(--lvxd-border-soft);
}

.lvxd-onboarding-trial-reassurances span {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 12px;
  font-weight: 600;
  color: var(--lvxd-text-muted);
}

.lvxd-onboarding-trial-reassurances i {
  color: var(--lvxd-success);
}

/* feature / add-on cards */

.lvxd-onboarding-feature-head {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 14px;
  flex-wrap: wrap;
}

.lvxd-onboarding-feature-tailored-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  font-weight: 700;
  color: var(--lvxd-accent);
  background: var(--lvxd-accent-soft);
  padding: 5px 11px;
  border-radius: 99px;
}

.lvxd-onboarding-feature-count {
  font-size: 12px;
  color: var(--lvxd-text-faint);
}

.lvxd-onboarding-feature-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 11px;
}

.lvxd-onboarding-feature-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 15px;
  border-radius: 14px;
  background: var(--lvxd-surface);
  border: 1.5px solid var(--lvxd-border);
  transition: border-color .2s, background .2s;
}

.lvxd-onboarding-feature-card.is-added {
  background: var(--lvxd-accent-soft);
}

.lvxd-onboarding-feature-card-head {
  display: flex;
  align-items: flex-start;
  gap: 11px;
}

.lvxd-onboarding-feature-icon {
  width: 40px;
  height: 40px;
  border-radius: 11px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--lvxd-chip-bg);
  font-size: 20px;
}

.lvxd-onboarding-feature-rec-badge {
  flex-shrink: 0;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: .04em;
  text-transform: uppercase;
  padding: 3px 7px;
  border-radius: 99px;
  white-space: nowrap;
}

.lvxd-onboarding-feature-body {
  flex: 1;
  min-width: 0;
}

.lvxd-onboarding-feature-name {
  font-size: 13.5px;
  font-weight: 700;
  color: var(--lvxd-text-heading);
}

.lvxd-onboarding-feature-price {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--lvxd-text-muted);
  margin-top: 1px;
}

.lvxd-onboarding-feature-desc {
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--lvxd-text-faint);
  min-height: 33px;
}

.lvxd-onboarding-feature-toggle {
  height: 36px;
  padding: 0 9px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  cursor: pointer;
  font-size: 12.5px;
  font-weight: 700;
  transition: all .18s;
  border: 1.5px solid var(--lvxd-border);
  background: var(--lvxd-surface);
  color: var(--lvxd-accent);
}

.lvxd-onboarding-feature-toggle:hover {
  transform: translateY(-1px);
}

.lvxd-onboarding-feature-toggle.is-added {
  border-color: var(--lvxd-success-border);
  background: var(--lvxd-success-soft);
  color: var(--lvxd-success-text);
}

.lvxd-onboarding-feature-infobar {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 16px;
  padding: 11px 14px;
  border-radius: 11px;
  background: var(--lvxd-chip-bg);
  font-size: 12px;
  color: var(--lvxd-text-faint);
  line-height: 1.4;
}

/* invite step */

.lvxd-onboarding-invite-input-row {
  display: flex;
  gap: 10px;
}

.lvxd-onboarding-invite-add-btn {
  height: 50px;
  padding: 0 20px;
  border: none;
  border-radius: 12px;
  background: var(--lvxd-accent-soft);
  color: var(--lvxd-accent);
  font-size: 14.5px;
  font-weight: 600;
  cursor: pointer;
  flex-shrink: 0;
  transition: background .15s;
}

.lvxd-onboarding-invite-add-btn:hover {
  background: var(--lvxd-accent-soft-strong);
}

.lvxd-onboarding-invite-list {
  margin-top: 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.lvxd-onboarding-invite-row {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 9px 12px;
  border: 1px solid var(--lvxd-border);
  border-radius: 11px;
  background: var(--lvxd-surface-muted);
}

.lvxd-onboarding-avatar {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  flex-shrink: 0;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 600;
}

.lvxd-onboarding-invite-email {
  flex: 1;
  font-size: 14px;
  font-weight: 500;
  color: var(--lvxd-text-body);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.lvxd-onboarding-invite-remove {
  width: 26px;
  height: 26px;
  border: none;
  border-radius: 7px;
  background: transparent;
  color: var(--lvxd-text-faint);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background .15s;
  font-size: 13px;
}

.lvxd-onboarding-invite-remove:hover {
  background: var(--lvxd-chip-bg);
  color: var(--lvxd-text-muted);
}

.lvxd-onboarding-invite-pending {
  font-size: 11px;
  font-weight: 600;
  color: var(--lvxd-warning-text);
  flex-shrink: 0;
}

.lvxd-onboarding-invite-error {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 10px 0 0;
  padding: 9px 12px;
  border-radius: 10px;
  background: var(--lvxd-danger-soft);
  border: 1px solid var(--lvxd-danger-border);
  color: var(--lvxd-danger);
  font-size: 12px;
  font-weight: 600;
  animation: lvxdOnboardingShake .4s ease;
}

.lvxd-onboarding-invite-empty {
  margin-top: 16px;
  padding: 16px;
  border-radius: 12px;
  background: var(--lvxd-chip-bg);
  border: 1px dashed var(--lvxd-border-soft);
  font-size: 12.5px;
  color: var(--lvxd-text-faint);
  text-align: center;
}

.lvxd-onboarding-product-empty {
  margin-top: 8px;
  padding: 24px 16px;
  border-radius: 12px;
  background: var(--lvxd-chip-bg);
  border: 1px dashed var(--lvxd-border-soft);
  font-size: 13.5px;
  color: var(--lvxd-text-faint);
  text-align: center;
}

@keyframes lvxdOnboardingShake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-7px); }
  40% { transform: translateX(6px); }
  60% { transform: translateX(-4px); }
  80% { transform: translateX(3px); }
}

/* done step */

.lvxd-onboarding-done-wrap {
  max-width: 480px;
  margin: 0 auto;
  text-align: center;
  padding: 6px 0;
}

@keyframes lvxdOnboardingDonePop {
  0% { transform: scale(.5); opacity: 0; }
  100% { transform: scale(1); opacity: 1; }
}

@keyframes lvxdOnboardingDoneRowIn {
  0% { opacity: 0; transform: translateY(6px); }
  100% { opacity: 1; transform: translateY(0); }
}

.lvxd-onboarding-done-ring-wrap {
  position: relative;
  width: 88px;
  height: 88px;
  margin: 0 auto 22px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.lvxd-onboarding-done-ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 3px solid var(--lvxd-success);
  animation: lvxdOnboardingDoneRing 1.6s ease-out infinite;
}

.lvxd-onboarding-done-ring-delay {
  inset: 9px;
  opacity: .5;
  animation-delay: .4s;
}

.lvxd-onboarding-done-circle {
  position: relative;
  width: 70px;
  height: 70px;
  border-radius: 50%;
  background: var(--lvxd-success);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 34px;
  box-shadow: 0 12px 34px rgba(23, 198, 83, .4);
  animation: lvxdOnboardingDonePop .5s cubic-bezier(.34, 1.56, .64, 1) both;
}

@keyframes lvxdOnboardingDoneRing {
  0% { transform: scale(.7); opacity: .7; }
  100% { transform: scale(1.9); opacity: 0; }
}

.lvxd-onboarding-done-title {
  margin: 0 0 8px;
  font-size: 29px;
  font-weight: 800;
  letter-spacing: -.8px;
  color: var(--lvxd-text);
}

.lvxd-onboarding-done-subtitle {
  font-size: 15px;
  color: var(--lvxd-text-muted);
  line-height: 1.6;
  margin-bottom: 22px;
}

.lvxd-onboarding-done-stats {
  display: flex;
  gap: 12px;
  justify-content: center;
}

.lvxd-onboarding-done-stat {
  flex: 1;
  max-width: 130px;
  padding: 15px 10px;
  border-radius: 14px;
  background: var(--lvxd-chip-bg);
  border: 1px solid var(--lvxd-border);
  text-align: center;
  animation: lvxdOnboardingDonePop .45s ease both;
}

.lvxd-onboarding-done-stat:nth-child(1) { animation-delay: .15s; }
.lvxd-onboarding-done-stat:nth-child(2) { animation-delay: .3s; }
.lvxd-onboarding-done-stat:nth-child(3) { animation-delay: .45s; }

.lvxd-onboarding-done-stat-value {
  font-size: 26px;
  font-weight: 800;
  color: var(--lvxd-text-heading);
  line-height: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.lvxd-onboarding-done-stat-label {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--lvxd-text-faint);
  margin-top: 5px;
  letter-spacing: .3px;
}

.lvxd-onboarding-done-trial {
  display: flex;
  align-items: center;
  gap: 15px;
  margin-top: 20px;
  padding: 15px 17px;
  border-radius: 16px;
  text-align: left;
  background: var(--lvxd-success-soft);
  border: 1px solid var(--lvxd-success);
  animation: lvxdOnboardingDonePop .45s ease both;
  animation-delay: .5s;
}

.lvxd-onboarding-done-trial-badge {
  position: relative;
  width: 52px;
  height: 52px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--lvxd-surface);
  box-shadow: 0 4px 14px rgba(23, 198, 83, .25);
}

.lvxd-onboarding-done-trial-days {
  font-size: 22px;
  font-weight: 800;
  color: var(--lvxd-success);
  line-height: 1;
}

.lvxd-onboarding-done-trial-days-label {
  font-size: 8.5px;
  font-weight: 700;
  color: var(--lvxd-success);
  letter-spacing: .4px;
  text-transform: uppercase;
}

.lvxd-onboarding-done-trial-body {
  flex: 1;
  min-width: 0;
}

.lvxd-onboarding-done-trial-title {
  font-size: 13.5px;
  font-weight: 800;
  color: var(--lvxd-text-heading);
}

.lvxd-onboarding-done-trial-text {
  font-size: 12px;
  color: var(--lvxd-text-muted);
  margin-top: 2px;
  line-height: 1.5;
}

.lvxd-onboarding-done-actions {
  display: flex;
  justify-content: center;
  gap: 11px;
  margin-top: 24px;
  flex-wrap: wrap;
}

/* Shown on the Done step when a REAL tenant was provisioned. The owner is created passwordless in
   LivexID, so the emailed set-password link is the only way in - this "blue box" is the call to
   action for it. It lives in the RIGHT (preview) pane in place of the workspace-preview card (the
   .lvxd-onboarding--provisioned root class hides that card), so the celebration on the left and the
   "what to do next" on the right sit side by side.

   Bold accent fill + on-accent text so it reads as the one thing to act on. --lvxd-on-accent keeps
   the content legible in dark/dim without a second palette (accent is cyan there, on-accent dark),
   which is why every overlay below is a color-mix off --lvxd-on-accent rather than a literal white. */
.lvxd-onboarding-setpassword {
  position: relative;
  overflow: hidden;
  padding: 26px 24px 24px;
  border-radius: 20px;
  text-align: center;
  color: var(--lvxd-on-accent);
  background: linear-gradient(160deg, var(--lvxd-accent), var(--lvxd-accent-hover));
  box-shadow: 0 22px 44px -18px var(--lvxd-accent-soft-strong), 0 4px 14px rgba(15, 23, 42, .12);
  animation: lvxdOnboardingSetpwIn .5s cubic-bezier(.34, 1.4, .64, 1) both;
}

/* Corner sheen so the flat fill reads as a lit surface, not a rectangle of colour. */
.lvxd-onboarding-setpassword::before {
  content: "";
  position: absolute;
  top: -40%;
  right: -20%;
  width: 70%;
  height: 80%;
  background: radial-gradient(circle, color-mix(in srgb, var(--lvxd-on-accent) 22%, transparent), transparent 70%);
  pointer-events: none;
}

.lvxd-onboarding-setpassword > * {
  position: relative;
}

/* The envelope: a translucent disc carrying the mailer glyph, with a slow float and a pulsing ring -
   the one animated "wow" beat on the box. */
.lvxd-onboarding-setpassword-badge {
  position: relative;
  width: 58px;
  height: 58px;
  margin: 0 auto 14px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 27px;
  color: var(--lvxd-on-accent);
  background: color-mix(in srgb, var(--lvxd-on-accent) 18%, transparent);
  animation: lvxdOnboardingSetpwFloat 3.2s ease-in-out infinite;
}

.lvxd-onboarding-setpassword-badge::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 2px solid color-mix(in srgb, var(--lvxd-on-accent) 45%, transparent);
  animation: lvxdOnboardingSetpwPulse 2.4s ease-out infinite;
}

.lvxd-onboarding-setpassword-eyebrow {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--lvxd-on-accent) 82%, transparent);
}

.lvxd-onboarding-setpassword-title {
  margin-top: 5px;
  font-size: 19px;
  font-weight: 800;
  letter-spacing: -.3px;
  line-height: 1.25;
  color: var(--lvxd-on-accent);
}

.lvxd-onboarding-setpassword-body {
  margin: 9px auto 0;
  max-width: 34ch;
  font-size: 13px;
  line-height: 1.55;
  color: color-mix(in srgb, var(--lvxd-on-accent) 90%, transparent);
}

.lvxd-onboarding-setpassword-body strong {
  color: var(--lvxd-on-accent);
  font-weight: 800;
  overflow-wrap: anywhere;
}

/* Two-email timeline: set password, then verify. */
.lvxd-onboarding-setpassword-steps {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 16px;
  text-align: left;
}

.lvxd-onboarding-setpassword-step {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  padding: 11px 13px;
  border-radius: 13px;
  background: color-mix(in srgb, var(--lvxd-on-accent) 12%, transparent);
  animation: lvxdOnboardingDoneRowIn .4s ease both;
}

.lvxd-onboarding-setpassword-step:nth-child(1) { animation-delay: .18s; }
.lvxd-onboarding-setpassword-step:nth-child(2) { animation-delay: .3s; }

.lvxd-onboarding-setpassword-step-num {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 800;
  color: var(--lvxd-accent);
  background: var(--lvxd-surface);
}

.lvxd-onboarding-setpassword-step-title {
  font-size: 13px;
  font-weight: 800;
  color: var(--lvxd-on-accent);
}

.lvxd-onboarding-setpassword-step-text {
  margin-top: 1px;
  font-size: 12px;
  line-height: 1.5;
  color: color-mix(in srgb, var(--lvxd-on-accent) 82%, transparent);
}

/* The spam/junk nudge - the single most common reason for "I didn't get anything". */
.lvxd-onboarding-setpassword-spam {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-top: 12px;
  padding: 10px 13px;
  border-radius: 12px;
  text-align: left;
  font-size: 12px;
  line-height: 1.45;
  color: color-mix(in srgb, var(--lvxd-on-accent) 88%, transparent);
  background: color-mix(in srgb, var(--lvxd-on-accent) 8%, transparent);
  border: 1px dashed color-mix(in srgb, var(--lvxd-on-accent) 30%, transparent);
}

.lvxd-onboarding-setpassword-spam i {
  flex-shrink: 0;
  font-size: 16px;
  color: var(--lvxd-on-accent);
}

.lvxd-onboarding-setpassword-spam strong {
  font-weight: 800;
  color: var(--lvxd-on-accent);
}

/* Buttons stack full-width inside the narrow box and invert against the accent fill (white/surface
   primary, ghost secondary) so they read on the blue rather than vanishing into it. */
/* The panel-inner scope carries the SAME accent-surface button treatment, so the check-email
   fallback (phase-16-01 look) inverts its buttons on the accent panel exactly as the standalone
   card did - white/surface primary, ghost secondary - rather than vanishing into the fill. */
.lvxd-onboarding-setpassword .lvxd-onboarding-done-actions,
.lvxd-onboarding-setpassword-panel-inner .lvxd-onboarding-done-actions {
  flex-direction: column;
  align-items: stretch;
  gap: 9px;
  margin-top: 18px;
}

.lvxd-onboarding-setpassword .lvxd-onboarding-done-btn,
.lvxd-onboarding-setpassword-panel-inner .lvxd-onboarding-done-btn {
  width: 100%;
  justify-content: center;
}

.lvxd-onboarding-setpassword .lvxd-onboarding-done-btn-primary,
.lvxd-onboarding-setpassword-panel-inner .lvxd-onboarding-done-btn-primary {
  color: var(--lvxd-accent);
  background: var(--lvxd-surface);
  box-shadow: 0 8px 20px rgba(15, 23, 42, .18);
}

.lvxd-onboarding-setpassword .lvxd-onboarding-done-btn-secondary,
.lvxd-onboarding-setpassword-panel-inner .lvxd-onboarding-done-btn-secondary {
  color: var(--lvxd-on-accent);
  background: transparent;
  border: 1px solid color-mix(in srgb, var(--lvxd-on-accent) 42%, transparent);
}

.lvxd-onboarding-setpassword .lvxd-onboarding-done-btn-secondary:hover:not(:disabled),
.lvxd-onboarding-setpassword-panel-inner .lvxd-onboarding-done-btn-secondary:hover:not(:disabled) {
  border-color: var(--lvxd-on-accent);
}

@keyframes lvxdOnboardingSetpwIn {
  0% { opacity: 0; transform: translateY(10px) scale(.97); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes lvxdOnboardingSetpwFloat {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-4px); }
}

@keyframes lvxdOnboardingSetpwPulse {
  0% { transform: scale(1); opacity: .8; }
  100% { transform: scale(1.5); opacity: 0; }
}

/* Looping motion off for anyone who asked the OS to reduce it - the one-shot entrance stays. */
@media (prefers-reduced-motion: reduce) {
  .lvxd-onboarding-setpassword-badge,
  .lvxd-onboarding-setpassword-badge::after {
    animation: none;
  }
}

/* The set-password panel reused as a standalone PAGE (Account/SetPasswordPending), outside the
   wizard's preview pane. It no longer inherits the pane's own max-width, so this centres it as a
   hero card with breathing room - narrower than .lvxd-page-narrow's 560px, which would stretch the
   accent fill into a banner. */
.lvxd-onboarding-setpassword-standalone {
  max-width: 460px;
  margin: 56px auto;
  padding: 0 20px;
}

/* phase-16-01: the in-page set-password FORM, rendered inside the accent panel on
   Account/SetPasswordPending when the owner email is known (CanSetPasswordInline). A thin lvxd-
   layer over the theme's lvx-input / lvx-btn: labels and helper text sit on --lvxd-on-accent (the
   panel fill is accent), while the inputs keep their own light surface so they stay legible. */
.lvxd-onboarding-setpassword-form {
  margin-top: 16px;
  text-align: left;
}

.lvxd-onboarding-setpassword-form .lvxd-form-feedback {
  margin-bottom: 14px;
  text-align: left;
}

/* Display-only reminder of which account the password is being set for. */
.lvxd-onboarding-setpassword-account {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 15px;
  padding: 9px 12px;
  border-radius: 11px;
  font-size: 12.5px;
  line-height: 1.4;
  color: color-mix(in srgb, var(--lvxd-on-accent) 92%, transparent);
  background: color-mix(in srgb, var(--lvxd-on-accent) 12%, transparent);
  overflow-wrap: anywhere;
}

.lvxd-onboarding-setpassword-account i {
  flex-shrink: 0;
  font-size: 15px;
  color: var(--lvxd-on-accent);
}

.lvxd-onboarding-setpassword-account strong {
  font-weight: 800;
  color: var(--lvxd-on-accent);
}

.lvxd-onboarding-setpassword-field {
  margin-bottom: 13px;
}

.lvxd-onboarding-setpassword-field label {
  display: block;
  margin-bottom: 5px;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--lvxd-on-accent);
}

.lvxd-onboarding-setpassword-field .lvx-input {
  width: 100%;
}

/* Inline field error on the accent fill: the class's default --lvxd-danger-text is tuned for a
   neutral surface and muddies against accent, so tint toward white here to keep it legible while
   still reading as an error. */
.lvxd-onboarding-setpassword-form .lvxd-field-error {
  color: color-mix(in srgb, #ffffff 78%, var(--lvxd-danger, #e5484d));
  font-weight: 700;
}

/* Empty error spans still take layout; collapse them so two stacked spans don't add dead gaps. */
.lvxd-onboarding-setpassword-form .lvxd-field-error:empty {
  display: none;
}

/* Primary submit: keep the theme's lvx-btn lvx-btn-primary but invert it to a surface fill on the
   accent panel (the same treatment .lvxd-onboarding-done-btn-primary gets here) so it reads as the
   one action instead of blending into the accent gradient. */
.lvxd-onboarding-setpassword-form .lvxd-onboarding-setpassword-submit {
  width: 100%;
  justify-content: center;
  margin-top: 4px;
  color: var(--lvxd-accent);
  background: var(--lvxd-surface);
  border-color: var(--lvxd-surface);
  box-shadow: 0 8px 20px rgba(15, 23, 42, .18);
}

.lvxd-onboarding-setpassword-form .lvxd-onboarding-setpassword-submit:hover:not(:disabled) {
  color: var(--lvxd-accent-hover);
  background: var(--lvxd-surface);
}

.lvxd-onboarding-setpassword-form .lvxd-onboarding-setpassword-submit:disabled {
  opacity: .65;
}

/* ==========================================================================
   phase-16-01 (full-screen redesign): Account/SetPasswordPending's inline
   (CanSetPasswordInline) branch as a FULL-VIEWPORT two-panel "wow" surface,
   matching the wizard done-step language. LEFT = the form on the accent panel;
   RIGHT = a celebratory "Workspace created" preview (soft gradient + green tick
   + clapping Nib + confetti). A thin lvxd- layer over the existing --lvxd-*
   tokens and the reused .lvxd-onboarding-done-* / .lvxd-onboarding-confetti
   classes; no new .lvx-* theme classes. Light + dark both ride the tokens.
   ========================================================================== */
.lvxd-onboarding-setpassword-page {
  display: flex;
  width: 100%;
  /* Pinned to exactly the viewport and clipped, so neither column's content can grow the document
     and raise a window scrollbar (owner call 2026-08-28: the page scroll is not needed here). Each
     column keeps its own overflow-y:auto, so a genuinely tall form/preview scrolls WITHIN its panel
     instead. The <=768px stacked layout restores natural page scroll (see the media query below). */
  height: 100dvh;
  overflow: hidden;
}

/* LEFT column: the accent panel. Same accent gradient + on-accent ink the
   set-password card uses, but flush to the viewport edge as a full-height
   column rather than a rounded card. */
.lvxd-onboarding-setpassword-panel {
  position: relative;
  /* Scroll y / clip x: contains the decorative ::before sheen AND lets a tall form (error banner +
     both fields on a short viewport) scroll rather than clip. Matches the wizard pane's stance. */
  overflow-x: hidden;
  overflow-y: auto;
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  padding: 30px 46px 34px;
  color: var(--lvxd-on-accent);
  background: linear-gradient(160deg, var(--lvxd-accent), var(--lvxd-accent-hover));
}

/* Corner sheen so the flat fill reads as a lit surface (mirrors the card's ::before). */
.lvxd-onboarding-setpassword-panel::before {
  content: "";
  position: absolute;
  top: -30%;
  right: -12%;
  width: 62%;
  height: 72%;
  background: radial-gradient(circle, color-mix(in srgb, var(--lvxd-on-accent) 16%, transparent), transparent 70%);
  pointer-events: none;
}

.lvxd-onboarding-setpassword-panel > * {
  position: relative;
}

/* Brand lockup, top-left of the accent panel (a "back to Hub" affordance). On-accent ink
   rather than the wizard brand's dark heading colour, since this sits on the accent fill. */
.lvxd-onboarding-setpassword-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--lvxd-on-accent);
  flex-shrink: 0;
}

.lvxd-onboarding-setpassword-brand-mark {
  width: auto;
  height: 30px;
  flex-shrink: 0;
}

.lvxd-onboarding-setpassword-brand-name {
  font-size: 17px;
  font-weight: 400;
  letter-spacing: -.02em;
  color: var(--lvxd-on-accent);
}

.lvxd-onboarding-setpassword-brand-name-accent {
  font-weight: 700;
}

/* Brand lockup hidden on this surface (owner call 2026-08-28). visibility, NOT display: the mark's
   space stays reserved so the badge/title/copy below hold the exact position they had with the logo
   visible - the spacing matches the reference screen. Applies to both the inline-form and
   check-email branches. Flip back to `visible` to restore the "back to Hub" mark. */
.lvxd-onboarding-setpassword-brand {
  visibility: hidden;
}

/* Centres the form block in the remaining column height, capped to a readable measure.
   Left-aligned (the panel sets no text-align), so labels, badge and copy line up with the
   inputs rather than sitting centred as they do in the standalone card. */
.lvxd-onboarding-setpassword-panel-inner {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  /* safe center: centred normally, but falls back to top-aligned (not clipped) when the form is
     taller than the column on a short viewport - the panel's overflow-y:auto then scrolls it. */
  justify-content: safe center;
  width: 100%;
  max-width: 400px;
  margin: 0 auto;
  padding: 28px 0;
  animation: lvxdOnboardingSetpwIn .5s cubic-bezier(.34, 1.4, .64, 1) both;
}

/* The reused badge/body default to auto side-margins (centred in the card); pin them left
   here so they align with the left-aligned form. */
.lvxd-onboarding-setpassword-panel-inner .lvxd-onboarding-setpassword-badge {
  margin-left: 0;
  margin-right: 0;
}

.lvxd-onboarding-setpassword-panel-inner .lvxd-onboarding-setpassword-body {
  margin-left: 0;
  margin-right: 0;
  max-width: none;
}

/* The form inside the panel already carries its own top margin; keep the inputs full-width. */
.lvxd-onboarding-setpassword-panel-inner .lvxd-onboarding-setpassword-form {
  margin-top: 20px;
}

/* "Sign in instead" footnote on the accent panel: on-accent ink (the neutral-surface
   .lvxd-page-narrow-footnote used by the fallback would be low-contrast on accent). */
.lvxd-onboarding-setpassword-footnote {
  margin-top: 18px;
  font-size: 12.5px;
  line-height: 1.5;
  color: color-mix(in srgb, var(--lvxd-on-accent) 80%, transparent);
}

.lvxd-onboarding-setpassword-footnote a {
  color: var(--lvxd-on-accent);
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* Eye toggle: a borderless button over the right edge of each password input. A CSS-grid overlay
   rather than absolute positioning - the input and the button share grid cell row1/col1, so the
   button matches the input's height exactly with no hardcoded pixel value, while the
   .lvxd-field-error spans flow into the rows below AND stay forward DOM siblings of the input
   (lvxd-form.js's errorSpanFor walks forward from the control to find them). The inputs keep their
   own light surface (see the -form note above), so the glyph uses --lvxd-text-muted, not on-accent,
   to read against the input fill in both themes. */
.lvxd-onboarding-setpassword-input-wrap {
  display: grid;
  grid-template-columns: 1fr;
}

.lvxd-onboarding-setpassword-input-wrap .lvx-input {
  grid-row: 1;
  grid-column: 1;
  width: 100%;
  padding-right: 44px;
}

.lvxd-onboarding-setpassword-eye {
  grid-row: 1;
  grid-column: 1;
  justify-self: end;
  align-self: stretch;
  width: 42px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--lvxd-text-muted);
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
  border-radius: 0 8px 8px 0;
}

.lvxd-onboarding-setpassword-eye:hover {
  color: var(--lvxd-text-body);
}

.lvxd-onboarding-setpassword-eye:focus-visible {
  outline: 2px solid var(--lvxd-accent);
  outline-offset: -2px;
}

/* RIGHT column: the celebratory preview. Same soft preview gradient, dotted texture and corner
   glow the wizard's preview pane uses, so the two screens read as one product. */
.lvxd-onboarding-setpassword-aside {
  position: relative;
  overflow-x: hidden;
  overflow-y: auto;
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: safe center;
  padding: 48px 40px;
  background: var(--lvxd-preview-gradient);
}

.lvxd-onboarding-setpassword-aside::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(circle, var(--lvxd-preview-dot) 1px, transparent 1px);
  background-size: 26px 26px;
  pointer-events: none;
}

.lvxd-onboarding-setpassword-aside::after {
  content: "";
  position: absolute;
  width: 520px;
  height: 520px;
  border-radius: 50%;
  background: radial-gradient(circle, var(--lvxd-preview-glow), transparent 70%);
  top: -120px;
  right: -80px;
  pointer-events: none;
}

.lvxd-onboarding-setpassword-celebrate {
  position: relative;
  width: 100%;
  max-width: 380px;
  text-align: center;
}

/* The reused done-title colours off --lvxd-text, which is undefined (it inherits in the wizard);
   pin it to the heading token here so it reads on the preview gradient in both themes. */
.lvxd-onboarding-setpassword-celebrate .lvxd-onboarding-done-title {
  color: var(--lvxd-text-heading);
}

/* Nib closes out the preview column, below the celebration copy. No greeting bubble here (the
   headline already says it), so he is just the clapping figure - centred rather than the
   wrapper's default right-hug. */
.lvxd-onboarding-setpassword-nib {
  position: relative;
  align-items: center;
  margin-top: 30px;
}

/* Responsive: single column at/below the tablet breakpoint. Form first (the primary action),
   preview below it. Nib drops out to keep the band compact. */
@media (max-width: 768px) {
  .lvxd-onboarding-setpassword-page {
    flex-direction: column;
    /* Stacked: the two panels sit one above the other and can legitimately exceed the viewport, so
       the fixed-height clip from the base rule must NOT apply - let the page scroll normally. */
    height: auto;
    min-height: 100dvh;
    overflow: visible;
  }

  .lvxd-onboarding-setpassword-panel {
    flex: none;
    width: 100%;
    padding: 26px 22px 30px;
  }

  .lvxd-onboarding-setpassword-panel-inner {
    max-width: 440px;
    padding: 24px 0 8px;
  }

  .lvxd-onboarding-setpassword-aside {
    flex: none;
    width: 100%;
    padding: 40px 24px;
  }

  .lvxd-onboarding-setpassword-nib {
    display: none;
  }
}

/* Smallest screens: the celebratory panel is pure decoration, so drop it entirely and let the
   form own the viewport - no dead scroll below the fold. */
@media (max-width: 480px) {
  .lvxd-onboarding-setpassword-aside {
    display: none;
  }
}

/* Shown on the Done step when a real provisioning attempt was REJECTED. Replaces the whole success
   card (ring, headline, stats, trial banner) rather than sitting under it - those all describe a
   tenant that was never created. Uses the shared --lvxd-danger-* tokens so it reads as a failure in
   both themes.

   Laid out as a centred state card: a solid circular danger badge is the anchor, the copy stacks
   below it in a fixed reading measure, and the single action spans the card. This replaces the old
   left-aligned block whose lone left-hugging button read as lopsided against the wide card. Still no
   pop-in: an error should not animate in like a reward. */
.lvxd-onboarding-failed {
  padding: 28px 24px 22px;
  border: 1px solid var(--lvxd-danger-border);
  border-radius: 16px;
  background: var(--lvxd-danger-soft);
  text-align: center;
}

.lvxd-onboarding-failed-head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
}

/* The visual anchor: a solid circular danger badge, not a tinted inline glyph. Gives the card a
   centre of gravity and reads as a real state at a glance. The soft ring is a colour-mix off the
   same token, so it tracks the danger colour in both themes. */
.lvxd-onboarding-failed-head i {
  width: 52px;
  height: 52px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--lvxd-danger);
  color: var(--lvxd-on-danger);
  font-size: 26px;
  box-shadow: 0 0 0 6px color-mix(in srgb, var(--lvxd-danger) 14%, transparent);
}

/* Inline exclamation SVG (warningGlyph) rather than a Keenicon: ki-information-5 is duotone and
   paints nothing without its .path spans, which is why the badge showed as an empty disc. */
.lvxd-onboarding-failed-head i svg {
  width: 26px;
  height: 26px;
  display: block;
}

.lvxd-onboarding-failed-title {
  font-size: 16px;
  font-weight: 800;
  line-height: 1.35;
  color: var(--lvxd-text-heading);
}

/* LivexID's own words where it had any (e.g. "This subdomain is already taken.") - the one line the
   user can actually act on, so it gets the emphasis. Capped to a comfortable measure and centred as
   a block so the multi-line copy stays readable inside the centred card. */
.lvxd-onboarding-failed-reason {
  margin: 12px auto 0;
  max-width: 44ch;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.55;
  color: var(--lvxd-danger-text);
}

.lvxd-onboarding-failed-body {
  margin: 8px auto 0;
  max-width: 44ch;
  font-size: 13px;
  line-height: 1.55;
  color: var(--lvxd-text-body);
}

/* One primary action, so it spans the card - a full-width button reads as intentional where a
   mid-width button stranded against an edge reads as a layout bug. The reward pop-in is dropped
   here for the same reason the card has none. */
.lvxd-onboarding-failed .lvxd-onboarding-done-actions {
  margin-top: 22px;
}

.lvxd-onboarding-failed .lvxd-onboarding-done-btn {
  width: 100%;
  justify-content: center;
  animation: none;
}

/* Scoped to the failure card ONLY - the recovery action reads red to match the error state, while
   every other .lvxd-onboarding-done-btn-primary (set-password panel, Done step) keeps the brand
   accent. Ink is --lvxd-on-danger, the token tuned to stay legible on the danger fill in both
   themes (white on light, dark-red on dark). */
.lvxd-onboarding-failed .lvxd-onboarding-done-btn-primary {
  color: var(--lvxd-on-danger);
  background: linear-gradient(135deg, var(--lvxd-danger), color-mix(in srgb, var(--lvxd-danger) 76%, #000));
  box-shadow: 0 6px 18px color-mix(in srgb, var(--lvxd-danger) 30%, transparent);
}

/* It's an <a>, not a <button> - keep it visually identical to the primary button. */
a.lvxd-onboarding-done-btn {
  text-decoration: none;
}

.lvxd-onboarding-done-btn {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 13px 22px;
  border-radius: 12px;
  font-size: 13.5px;
  font-weight: 700;
  cursor: pointer;
  border: none;
  transition: transform .2s, box-shadow .2s, border-color .2s;
  animation: lvxdOnboardingDonePop .45s ease both;
}

.lvxd-onboarding-done-btn-primary {
  color: var(--lvxd-on-accent);
  background: linear-gradient(135deg, var(--lvxd-accent), var(--lvxd-accent-hover));
  box-shadow: 0 6px 18px var(--lvxd-accent-soft-strong);
  animation-delay: .55s;
}

.lvxd-onboarding-done-btn-primary:hover:not(:disabled) {
  transform: translateY(-2px);
}

/* Held disabled while the completion POST is in flight - navigating away mid-commit is what
   stranded tenant 5 without an owner member row. */
.lvxd-onboarding-done-btn:disabled {
  cursor: default;
  opacity: .55;
  box-shadow: none;
}

.lvxd-onboarding-done-btn-secondary {
  color: var(--lvxd-text-heading);
  background: var(--lvxd-surface);
  border: 1px solid var(--lvxd-border);
  animation-delay: .65s;
}

.lvxd-onboarding-done-btn-secondary:hover:not(:disabled) {
  border-color: var(--lvxd-accent);
  transform: translateY(-1px);
}

/* auto-redirect clock */

.lvxd-onboarding-redirect-widget {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 20px;
  padding: 13px 15px;
  border-radius: 13px;
  background: var(--lvxd-chip-bg);
  border: 1px solid var(--lvxd-border);
  animation: lvxdOnboardingDoneRowIn .4s ease both;
  text-align: left;
}

.lvxd-onboarding-redirect-clock {
  position: relative;
  width: 40px;
  height: 40px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.lvxd-onboarding-redirect-clock-track {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 3px solid var(--lvxd-border);
}

.lvxd-onboarding-redirect-clock-spin {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 3px solid transparent;
  border-top-color: var(--lvxd-accent);
  animation: lvxdOnboardingRedirectSpin 1s linear infinite;
}

.lvxd-onboarding-redirect-clock-number {
  font-size: 15px;
  font-weight: 800;
  color: var(--lvxd-accent);
}

@keyframes lvxdOnboardingRedirectSpin {
  to { transform: rotate(360deg); }
}

.lvxd-onboarding-redirect-body {
  flex: 1;
  min-width: 0;
}

.lvxd-onboarding-redirect-title {
  font-size: 13.5px;
  font-weight: 700;
  color: var(--lvxd-text-heading);
}

.lvxd-onboarding-redirect-text {
  font-size: 12px;
  color: var(--lvxd-text-muted);
  margin-top: 1px;
}

.lvxd-onboarding-redirect-progress {
  height: 4px;
  border-radius: 999px;
  background: var(--lvxd-border);
  margin-top: 8px;
  overflow: hidden;
}

.lvxd-onboarding-redirect-progress-fill {
  height: 100%;
  width: 0%;
  background: linear-gradient(90deg, var(--lvxd-accent), var(--lvxd-accent-hover));
  transition: width 1s linear;
}

.lvxd-onboarding-redirect-stay {
  flex-shrink: 0;
  padding: 9px 13px;
  border-radius: 10px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--lvxd-text-muted);
  background: var(--lvxd-surface);
  border: 1px solid var(--lvxd-border);
  cursor: pointer;
  transition: color .2s;
}

.lvxd-onboarding-redirect-stay:hover {
  color: var(--lvxd-text-heading);
}

/* footer nav */

.lvxd-onboarding-footer {
  margin-top: 22px;
  display: flex;
  align-items: center;
  gap: 14px;
}

.lvxd-onboarding-btn {
  height: 48px;
  padding: 0 22px;
  border-radius: 11px;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  border: none;
  transition: background .15s, opacity .15s, transform .2s, box-shadow .2s;
}

.lvxd-onboarding-btn-back {
  background: var(--lvxd-surface-muted);
  color: var(--lvxd-text-muted);
  font-weight: 600;
  font-size: 13px;
}

.lvxd-onboarding-btn-back:hover {
  color: var(--lvxd-text-heading);
}

.lvxd-onboarding-btn-primary {
  flex: 1;
  background: linear-gradient(135deg, var(--lvxd-accent), var(--lvxd-accent-hover));
  color: var(--lvxd-on-accent);
  box-shadow: 0 6px 18px var(--lvxd-accent-soft-strong);
}

.lvxd-onboarding-btn-primary:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 0 10px 26px var(--lvxd-accent-soft-strong);
}

.lvxd-onboarding-btn-primary:disabled {
  opacity: .5;
  cursor: not-allowed;
}

.lvxd-onboarding-btn-text {
  height: 52px;
  padding: 0 12px;
  border: none;
  background: transparent;
  color: var(--lvxd-text-muted);
  font-size: 14.5px;
  font-weight: 500;
  cursor: pointer;
}

.lvxd-onboarding-btn-text:hover {
  color: var(--lvxd-text-heading);
}

/* ---- right pane: live preview ---- */

.lvxd-onboarding-right {
  flex: 1;
  min-width: 0;
  height: 100%;
  position: relative;
  overflow-y: auto;
  overflow-x: hidden;
  background: var(--lvxd-preview-gradient);
  display: flex;
  align-items: safe center;
  justify-content: center;
  padding: 40px;
}

.lvxd-onboarding-right::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(circle, var(--lvxd-preview-dot) 1px, transparent 1px);
  background-size: 26px 26px;
  pointer-events: none;
}

.lvxd-onboarding-right::after {
  content: "";
  position: absolute;
  width: 520px;
  height: 520px;
  border-radius: 50%;
  background: radial-gradient(circle, var(--lvxd-preview-glow), transparent 70%);
  top: -120px;
  right: -80px;
  pointer-events: none;
}

.lvxd-onboarding-preview {
  position: relative;
  width: 100%;
  max-width: 420px;
}

.lvxd-onboarding-preview-chip {
  position: absolute;
  top: -54px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 8px;
  white-space: nowrap;
  padding: 8px 14px;
  border-radius: 99px;
  background: var(--lvxd-surface);
  border: 1px solid var(--lvxd-border-soft);
  box-shadow: 0 4px 16px rgba(15, 23, 42, .06);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--lvxd-text-body);
}

.lvxd-onboarding-preview-chip-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--lvxd-success);
  box-shadow: 0 0 0 3px rgba(5, 150, 105, .15);
}

.lvxd-onboarding-preview-ghost {
  position: absolute;
  inset: 0;
  transform: translateY(18px) scale(.94);
  background: var(--lvxd-surface);
  border: 1px solid var(--lvxd-border-soft);
  border-radius: 20px;
  opacity: .55;
}

.lvxd-onboarding-preview-card {
  position: relative;
  background: var(--lvxd-surface);
  border-radius: 20px;
  border: 1px solid var(--lvxd-border-soft);
  box-shadow: var(--lvxd-card-shadow);
  transition: border-color .4s, box-shadow .4s;
}

.lvxd-onboarding-preview-card.is-done {
  border-color: var(--lvxd-success-border);
  box-shadow: var(--lvxd-card-shadow-done);
}

.lvxd-onboarding-preview-header {
  display: flex;
  align-items: center;
  gap: 15px;
  padding: 22px;
}

.lvxd-onboarding-preview-monogram {
  width: 54px;
  height: 54px;
  border-radius: 15px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 23px;
  font-weight: 800;
  color: #fff;
  background: var(--lvxd-chip-bg);
  box-shadow: 0 6px 16px rgba(0, 0, 0, .12);
  transition: background .35s;
  overflow: hidden;
}

.lvxd-onboarding-preview-monogram-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.lvxd-onboarding-preview-company {
  flex: 1;
  min-width: 0;
}

.lvxd-onboarding-preview-company-name {
  font-size: 16px;
  font-weight: 700;
  letter-spacing: -.01em;
  color: var(--lvxd-text-disabled);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  transition: color .3s;
}

.lvxd-onboarding-preview-company-name.is-filled {
  color: var(--lvxd-text-heading);
}

.lvxd-onboarding-preview-workspace-label {
  font-size: 12px;
  color: var(--lvxd-text-faint);
  margin-top: 2px;
}

.lvxd-onboarding-preview-divider {
  height: 1px;
  background: var(--lvxd-border-soft);
}

.lvxd-onboarding-preview-section {
  padding: 16px 20px;
}

.lvxd-onboarding-preview-section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}

.lvxd-onboarding-preview-eyebrow {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--lvxd-text-faint);
}

.lvxd-onboarding-preview-count {
  font-size: 11px;
  font-weight: 600;
  color: var(--lvxd-text-muted);
  background: var(--lvxd-chip-bg);
  padding: 2px 8px;
  border-radius: 99px;
  font-variant-numeric: tabular-nums;
}

.lvxd-onboarding-preview-apps {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.lvxd-onboarding-preview-app-chip {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 12px 7px 7px;
  border: 1px solid var(--lvxd-border-soft);
  border-radius: 10px;
  background: var(--lvxd-surface-muted);
}

.lvxd-onboarding-preview-app-tile {
  width: 26px;
  height: 26px;
  border-radius: 7px;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-size: 14px;
}

.lvxd-onboarding-preview-app-tile.has-logo {
  background: var(--lvxd-surface);
  border: 1px solid var(--lvxd-border-soft);
  padding: 3px;
}

.lvxd-onboarding-preview-app-tile-logo-img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.lvxd-onboarding-preview-app-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--lvxd-text-heading);
}

.lvxd-onboarding-preview-addons {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 10px;
}

.lvxd-onboarding-preview-addon-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  font-weight: 500;
  color: var(--lvxd-text-muted);
  background: var(--lvxd-chip-bg);
  padding: 4px 10px;
  border-radius: 99px;
}

.lvxd-onboarding-preview-addon-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex-shrink: 0;
}

.lvxd-onboarding-preview-member-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 0;
}

.lvxd-onboarding-preview-avatar-you {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: linear-gradient(135deg, #f6b100, #f8285a);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: 700;
  flex-shrink: 0;
}

.lvxd-onboarding-preview-avatar-invite {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: 700;
  flex-shrink: 0;
}

.lvxd-onboarding-preview-member-body {
  flex: 1;
  min-width: 0;
}

.lvxd-onboarding-preview-member-name {
  font-size: 14px;
  font-weight: 600;
  color: var(--lvxd-text-disabled);
  transition: color .3s;
}

.lvxd-onboarding-preview-member-name.is-filled {
  color: var(--lvxd-text-heading);
}

.lvxd-onboarding-preview-member-role {
  font-size: 12px;
  color: var(--lvxd-text-muted);
  margin-top: 1px;
}

.lvxd-onboarding-preview-member-role.is-muted {
  color: var(--lvxd-text-disabled);
}

.lvxd-onboarding-preview-owner-badge {
  font-size: 11.5px;
  font-weight: 700;
  color: var(--lvxd-accent);
  background: var(--lvxd-accent-soft);
  padding: 4px 10px;
  border-radius: 8px;
}

.lvxd-onboarding-preview-invite-email {
  flex: 1;
  min-width: 0;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--lvxd-text-body);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.lvxd-onboarding-preview-pending-badge {
  font-size: 10.5px;
  font-weight: 600;
  color: var(--lvxd-warning-text);
  background: var(--lvxd-warning-soft);
  padding: 3px 9px;
  border-radius: 99px;
}

.lvxd-onboarding-preview-invite-placeholder {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 10px 0;
  opacity: .9;
}

.lvxd-onboarding-preview-invite-placeholder-icon {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 1.5px dashed var(--lvxd-text-disabled);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--lvxd-text-disabled);
  flex-shrink: 0;
  font-size: 16px;
}

.lvxd-onboarding-preview-invite-placeholder-text {
  font-size: 13px;
  color: var(--lvxd-text-disabled);
}

/* The preview card and Nib stack in this column so he sits under the card without being inside
   the preview's own (inset:0) ghost layer. */
.lvxd-onboarding-preview-col {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 420px;
}

/* The set-password box's slot in the right pane. Empty and hidden until a real tenant is
   provisioned, at which point showPreviewNotice() fills it and adds the root class below - the box
   then takes the workspace-preview card's place, directly above Nib. */
.lvxd-onboarding-preview-notice {
  width: 100%;
}

.lvxd-onboarding--provisioned .lvxd-onboarding-preview {
  display: none;
}

/* The Done step's footer buttons (Back / Continue / Skip) are ALL hidden - the step's own actions
   (Share your launch / Explore the Hub) live inside the celebration card instead. The footer element
   and its 22px top margin then sit as dead vertical space below the card, padding the left column's
   content past the pane on shorter laptop heights and raising a scrollbar even when the card itself
   fits. It holds nothing on this step, so collapse it and reclaim the space. */
.lvxd-onboarding--provisioned .lvxd-onboarding-footer {
  display: none;
}

/* Stacked layout: the right pane is a fixed 420px band above the form. The taller set-password box
   would clip inside it, so let the band grow to its content once provisioned. */
@media (max-width: 980px) {
  .lvxd-onboarding--provisioned .lvxd-onboarding-right {
    height: auto;
    min-height: 360px;
  }
}

/* Nib closes out the preview pane, under the workspace card - he carries the step caption as his
   second line, which is why there is no caption element here any more. */
/* fit-content, not the pane's full width: the speech card is positioned off the wrapper's right
   edge (below), so a full-width wrapper would throw it clean off the left of the pane. */
.lvxd-onboarding-nib {
  width: fit-content;
  margin: 34px 24px 0 auto;
}

/* The card speaks from his side, not from overhead: the default overhead placement lands on top
   of the workspace preview card directly above him. */
.lvxd-onboarding-nib .lvxd-nib-bubble-card {
  top: 50%;
  bottom: auto;
  right: calc(100% + 14px);
  transform: translateY(-58%);
}

/* Laptop heights: with the done step's fuller card the chip + card + Nib column overflows the pane
   by ~33px at a 560px pane, and his feet end up against the bottom edge. Measured, not guessed -
   the space comes back from the pane padding and his own top margin, rather than from shrinking
   him past the design system's 120px floor. */
@media (max-height: 820px) {
  .lvxd-onboarding-right {
    padding: 28px;
  }

  .lvxd-onboarding-nib {
    margin-top: 16px;
  }
}

@media (max-width: 980px) {
  /* The preview pane collapses to a 420px band above the form here - the card alone fills it. */
  .lvxd-onboarding-nib {
    display: none;
  }
}

/* Provisioned (Done) step, wide layout only (>=981px - below that the responsive stack above
   still applies and hides Nib). Two problems on this step share one fix: Nib was STACKED under the
   "check your email" box, and the box + 34px margin + 150px Nib made the preview column taller than
   the pane, so .lvxd-onboarding-right overflowed into a scrollbar. Sitting the box and Nib in a ROW
   instead removes ~190px of column height (killing that scrollbar at normal window heights) and puts
   Nib beside the box, which is where he should read on the celebration screen. The right pane takes
   a little more of the split so the row has room; flex-wrap lets Nib fall back under the box if a
   narrow-but->980 window can't fit both. */
@media (min-width: 981px) {
  .lvxd-onboarding--provisioned .lvxd-onboarding-right {
    flex: 1.3 1 0;
    align-items: center;
  }

  .lvxd-onboarding--provisioned .lvxd-onboarding-preview-col {
    flex-direction: row;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 26px;
    max-width: 560px;
  }

  .lvxd-onboarding--provisioned .lvxd-onboarding-preview-notice {
    flex: 1 1 300px;
    max-width: 340px;
  }

  .lvxd-onboarding--provisioned .lvxd-onboarding-nib {
    margin: 0;
    flex: 0 0 auto;
  }

  /* He now stands to the RIGHT of the box, so the left/overhead speech card (positioned above) would
     cross the box. The box already carries every word of the message, so retire the persistent
     greeting card on this step rather than fight it into a gap too narrow to hold it. */
  .lvxd-onboarding--provisioned .lvxd-onboarding-nib .lvxd-nib-bubble-card {
    display: none;
  }
}

/* confetti (done step) */

.lvxd-onboarding-confetti {
  position: absolute;
  border-radius: 2px;
  pointer-events: none;
  will-change: transform, opacity;
}

@keyframes lvxdOnboardingConfettiFall {
  0% { transform: translateY(0) rotate(0deg); opacity: 1; }
  100% { transform: translateY(420px) rotate(var(--lvxd-confetti-rot, 360deg)); opacity: 0; }
}

/* responsive: stack panes below a fluid breakpoint (fluid/responsive requirement) */

@media (max-width: 980px) {
  .lvxd-onboarding {
    flex-direction: column;
    /* width:100%, NOT the base rule's 100vw: once this block flips overflow to visible, 100vw
       (which counts the vertical scrollbar gutter) spills ~one scrollbar-width past the content box
       and the page scrolls sideways. 100% resolves to the scrollbar-excluded client width. */
    width: 100%;
    height: auto;
    min-height: 100dvh;
    overflow: visible;
  }

  .lvxd-onboarding-left {
    flex: none;
    max-width: none;
    min-width: 0;
    width: 100%;
    height: auto;
    padding: 28px 24px 24px;
  }

  /* Stacked above the form. The desktop `height: 420px` never took effect here - this pane's base
     `flex: 1` becomes flex-basis:0 in the now-column container, so it always sized to the preview
     card; make that explicit with flex:none + height:auto. padding-top clears the -54px "Live
     preview" chip, which the pane's top edge would otherwise cut off once the band is only as tall
     as its content. */
  .lvxd-onboarding-right {
    flex: none;
    height: auto;
    order: -1;
    padding-top: 64px;
  }
}

/* phase-17 (onboarding): on a phone the right "Live preview" panel is decorative on the wizard steps
   and, stacked above the form (order:-1 in the 980 block), pushes the primary form below the fold.
   Hide it so the form is full-width and first. EXCLUDES .lvxd-onboarding--provisioned: on the Done
   step this same panel holds the set-password box (Home/Index.cshtml), which must stay. Nib is
   already hidden at <=980px. */
@media (max-width: 639.98px) {
  .lvxd-onboarding:not(.lvxd-onboarding--provisioned) .lvxd-onboarding-right {
    display: none;
  }
}

@media (max-width: 560px) {
  .lvxd-onboarding-role-grid {
    grid-template-columns: 1fr;
  }

  .lvxd-onboarding-name-row {
    grid-template-columns: 1fr;
  }

  .lvxd-onboarding-brand-row {
    grid-template-columns: 1fr;
  }

  .lvxd-onboarding-product-grid {
    grid-template-columns: 1fr;
  }

  .lvxd-onboarding-feature-grid {
    grid-template-columns: 1fr;
  }

  /* Tighter gutters for phones. The right pane keeps a top pad >= the -54px chip's reach (see the
     980 block) while trimming the sides; this shorthand re-states top because it overrides the
     980 block's padding-top here. */
  .lvxd-onboarding-left {
    padding: 24px 20px 20px;
  }

  .lvxd-onboarding-right {
    padding: 60px 20px 24px;
  }

  .lvxd-onboarding-title {
    font-size: 26px;
  }

  .lvxd-onboarding-preview {
    width: 92%;
  }
}

/* ===========================================================================
   phase-11-06 - DIM: dark sidebar, light content.
   ===========================================================================

   Dim is NOT "halfway between Light and Dark". It is the LIGHT palette everywhere except the
   sidebar, which takes Dark's. So `.dim` deliberately defines nothing at the root: :root is already
   light, and re-listing every light token under .dim would be a third copy to keep in step with the
   first two for no behavioural gain.

   The whole theme is therefore one scoped block. Custom properties INHERIT, so redefining them on
   the sidebar element cascades to every descendant automatically - which is why this needed no
   changes at all to the ~60 existing .lvxd-hub-sidebar-* rules in lvxd-hub-shell.css. They already
   consume these tokens; they simply resolve to different values inside the sidebar.

   The values below are Dark's, verbatim from the .dark block above - deliberately copied rather
   than invented, because Dim's sidebar IS Dark's sidebar. If a value here diverges from .dark, that
   is a bug, not a refinement: two dark sidebars that differ slightly read as a rendering fault.

   Verified from source before building: .lvxd-hub-sidebar sets `background: var(--lvxd-surface)`,
   and :root's --lvxd-surface is #ffffff - so Hub's Light theme has a WHITE sidebar and Dim really is
   a third distinct look. (A live browser pass is still worth doing, but this particular question was
   a direct token lookup rather than a cascade judgement.) */
.dim .lvxd-hub-sidebar {
  --lvxd-surface: #1c2022;
  --lvxd-surface-muted: #23282a;
  --lvxd-border: #2f3538;
  --lvxd-border-soft: #252a2c;
  --lvxd-text-heading: #f1f4f5;
  --lvxd-text-body: #dee3e5;
  --lvxd-text-muted: #9aa1a4;
  --lvxd-text-faint: #6b7275;
  --lvxd-text-disabled: #4c5254;

  /* Dark's accent stop, not Light's. #0b7ea3 is chosen to sit on white and measures poorly on
     #1c2022; the raw mark stop is what Dark uses on this surface for that reason. */
  --lvxd-accent: #24cbfe;
  --lvxd-accent-hover: #5cd9fe;
  --lvxd-accent-soft: rgba(36, 203, 254, .12);
  --lvxd-on-accent: #062a35;
}

/* The sidebar's right border is drawn by the sidebar itself, so it picks up the override above and
   needs no rule here. The topbar sits OUTSIDE the sidebar and stays light in Dim - that is the
   point of the theme, and is why the toggle button (which straddles the two, see phase-11-07) is
   the one control that must be checked in this theme specifically. */

/* Notification tints inside a Dim sidebar would be the light values on a dark tile. Nothing in the
   sidebar renders them today, but scoping them here keeps that true if anything ever does, rather
   than leaving a latent contrast bug for whoever adds it. */
.dim .lvxd-hub-sidebar .lvxd-notif-drawer-item-tile {
  --lvxd-notif-people-bg: #12303f;
  --lvxd-notif-people-ink: #7dd3fc;
  --lvxd-notif-access-bg: #2a2245;
  --lvxd-notif-access-ink: #c4b5fd;
  --lvxd-notif-success-bg: #14321f;
  --lvxd-notif-success-ink: #86efac;
  --lvxd-notif-warning-bg: #3a2c12;
  --lvxd-notif-warning-ink: #fcd34d;
  --lvxd-notif-danger-bg: #3d1d1d;
  --lvxd-notif-danger-ink: #fca5a5;
  --lvxd-notif-neutral-bg: #262b2d;
  --lvxd-notif-neutral-ink: #b8c0c3;
}

/* ===== plan step: trial vs subscribe ===== */

/* The two ways to start, on the plan step. Reuses .lvxd-onboarding-plan-branch-icon/-body/-title/
   -text inside each card, so the selected option looks exactly like the single informational card
   that used to sit here - what changed is that there are now two of them and one is chosen.

   Buttons, not labels around hidden radios: every other choice in this wizard (tier cards, role
   cards) is a <button role="radio"> with a roving tabindex, and a second mechanism for the same
   interaction is how keyboard behaviour ends up inconsistent between two adjacent controls. */
.lvxd-onboarding-pay-options {
  margin-top: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.lvxd-onboarding-pay-option {
  width: 100%;
  padding: 12px 14px;
  border-radius: 14px;
  display: flex;
  align-items: flex-start;
  gap: 12px;
  text-align: left;
  cursor: pointer;
  background: var(--lvxd-surface);
  border: 1.5px solid var(--lvxd-border);
  transition: border-color .2s, background .2s, transform .15s;
}

.lvxd-onboarding-pay-option:hover {
  border-color: var(--lvxd-accent-soft-strong);
}

/* Accent fill on the chosen option only - the same signal .lvxd-onboarding-plan-branch.is-paid
   carried when this was one static card, so a selected trial card is visually identical to the
   card that used to be here unconditionally. */
.lvxd-onboarding-pay-option.is-selected {
  border-color: var(--lvxd-accent);
  background: var(--lvxd-accent-soft);
}

.lvxd-onboarding-pay-option.is-selected .lvxd-onboarding-plan-branch-icon {
  color: var(--lvxd-accent);
}

.lvxd-onboarding-pay-option:focus-visible {
  outline: 2px solid var(--lvxd-accent);
  outline-offset: 2px;
}

/* One payment vs one per product. Indented under the subscribe option it belongs to, and lighter
   than the cards above: this is a detail OF a choice already made, not a third top-level option
   competing with the two above it. */
.lvxd-onboarding-pay-splits {
  margin: 8px 0 0 14px;
  padding-left: 14px;
  border-left: 2px solid var(--lvxd-border);
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.lvxd-onboarding-pay-split {
  width: 100%;
  padding: 9px 11px;
  border-radius: 11px;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  text-align: left;
  cursor: pointer;
  background: transparent;
  border: 1.5px solid transparent;
  transition: border-color .2s, background .2s;
}

.lvxd-onboarding-pay-split:hover {
  background: var(--lvxd-surface-muted);
}

.lvxd-onboarding-pay-split.is-selected {
  border-color: var(--lvxd-accent-soft-strong);
  background: var(--lvxd-surface);
}

.lvxd-onboarding-pay-split:focus-visible {
  outline: 2px solid var(--lvxd-accent);
  outline-offset: 2px;
}

/* Slightly smaller type than the top-level cards, for the same reason the container is indented. */
.lvxd-onboarding-pay-split .lvxd-onboarding-plan-branch-title {
  font-size: 12.5px;
}

.lvxd-onboarding-pay-split .lvxd-onboarding-plan-branch-text {
  font-size: 11.5px;
}

/* ==== Step 6 seat selection (2026-08-23, purchased-licence model) ====
   One row per product section, under the tier accordion toggle: label + bounds hint on the left,
   minus/count/plus stepper and the seat-multiplied line total on the right. Bounds come from
   dbo.SubscriptionRate via the card (minimumUsers / includedUsers); the disabled state on the
   stepper buttons is the visual form of that data floor/ceiling. */

.lvxd-onboarding-seat-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  margin-top: 6px;
  border: 1px solid var(--lvxd-border);
  border-radius: 10px;
  background: var(--lvxd-surface);
}

.lvxd-onboarding-seat-row-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  flex: 1;
}

.lvxd-onboarding-seat-row-label {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--lvxd-text);
}

.lvxd-onboarding-seat-row-hint {
  font-size: 11.5px;
  color: var(--lvxd-text-muted);
}

.lvxd-onboarding-seat-stepper {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}

.lvxd-onboarding-seat-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: 1px solid var(--lvxd-border);
  border-radius: 8px;
  background: var(--lvxd-surface);
  color: var(--lvxd-text);
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, transform 0.1s ease;
}

.lvxd-onboarding-seat-btn:hover:not(:disabled) {
  border-color: var(--lvxd-accent);
  color: var(--lvxd-accent);
}

.lvxd-onboarding-seat-btn:active:not(:disabled) {
  transform: scale(0.92);
}

.lvxd-onboarding-seat-btn:focus-visible {
  outline: 2px solid var(--lvxd-accent);
  outline-offset: 2px;
}

/* A disabled end of the stepper IS the stated bound - it must read as "can't", not "broken". */
.lvxd-onboarding-seat-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.lvxd-onboarding-seat-input {
  width: 58px;
  height: 28px;
  text-align: center;
  font-size: 13px;
  font-weight: 600;
  color: var(--lvxd-text);
  border: 1px solid var(--lvxd-border);
  border-radius: 8px;
  background: var(--lvxd-surface);
  -moz-appearance: textfield;
  appearance: textfield;
}

.lvxd-onboarding-seat-input::-webkit-outer-spin-button,
.lvxd-onboarding-seat-input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.lvxd-onboarding-seat-input:focus-visible {
  outline: 2px solid var(--lvxd-accent);
  outline-offset: 1px;
}

.lvxd-onboarding-seat-row-total {
  font-size: 12.5px;
  color: var(--lvxd-text-muted);
  flex-shrink: 0;
}

/* The "Sizing your team" (user-count) step card - a designed panel rather than the plan step's bare
   rows: product header, a row of seat avatars that fill in the workspace accent as the count grows,
   then the stepper. See renderStep_users. */
.lvxd-onboarding-seats-card {
  border: 1.5px solid var(--lvxd-border);
  border-radius: 18px;
  padding: 20px;
  background: var(--lvxd-preview-gradient);
  box-shadow: var(--lvxd-card-shadow);
}

.lvxd-onboarding-seats-card + .lvxd-onboarding-seats-card {
  margin-top: 14px;
}

.lvxd-onboarding-seats-head {
  display: flex;
  align-items: center;
  gap: 13px;
  margin-bottom: 18px;
}

.lvxd-onboarding-seats-head-body {
  min-width: 0;
}

.lvxd-onboarding-seats-product {
  font-size: 16px;
  font-weight: 800;
  letter-spacing: -.01em;
  color: var(--lvxd-text-heading);
}

.lvxd-onboarding-seats-sub {
  font-size: 12.5px;
  color: var(--lvxd-text-muted);
  margin-top: 1px;
}

.lvxd-onboarding-seats-dots {
  display: flex;
  flex-wrap: wrap;
  gap: 9px;
  margin-bottom: 16px;
}

/* Empty seat: dashed outline, faint glyph. The filled state takes the workspace accent inline
   (a user-chosen colour, not a token) - only the treatment lives here. */
.lvxd-onboarding-seats-dot {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 1.5px dashed var(--lvxd-border);
  background: var(--lvxd-surface);
  color: var(--lvxd-text-faint);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform .28s cubic-bezier(.34, 1.56, .64, 1), background-color .2s ease, border-color .2s ease, color .2s ease, box-shadow .2s ease;
}

.lvxd-onboarding-seats-dot i {
  font-size: 15px;
}

.lvxd-onboarding-seats-dot.is-filled {
  border-style: solid;
  color: #fff;
  transform: scale(1.05);
  box-shadow: 0 3px 10px rgba(15, 23, 42, .14);
}

/* Overflow beyond the ten drawn dots (a large or unlimited user count). */
.lvxd-onboarding-seats-more {
  display: inline-flex;
  align-items: center;
  height: 34px;
  padding: 0 12px;
  border-radius: 17px;
  font-size: 13px;
  font-weight: 700;
  color: var(--lvxd-text-muted);
  background: var(--lvxd-chip-bg);
}

.lvxd-onboarding-seat-row-total strong {
  color: var(--lvxd-text);
  font-size: 13px;
}

/* Narrow viewports: hint wraps under the label, stepper and total stay on one row. */
@media (max-width: 480px) {
  .lvxd-onboarding-seat-row {
    flex-wrap: wrap;
  }

  .lvxd-onboarding-seat-row-body {
    flex-basis: 100%;
  }
}

/* ==========================================================================
   Auth split layout (lvxd-authsplit-*)

   Generalised from the set-password two-panel surface (lvxd-onboarding-setpassword-*)
   so every standalone auth screen - No access, Sign-in unavailable, Choose workspace,
   Log in - shares ONE format: an accent panel carrying the page content on the left,
   a soft "mood" panel on the right. The right panel's TONE is set per page with a
   modifier on .lvxd-authsplit-mood: .is-welcome celebrates (success green), while
   .is-blocked / .is-neutral stay calm (brand accent). A celebration surface would
   read as broken on an access-denied page, so the tone is deliberately not shared.
   ========================================================================== */
.lvxd-authsplit-page {
  display: flex;
  width: 100%;
  min-height: 100dvh;
}

/* LEFT column: the accent panel, flush to the viewport edge as a full-height column. */
.lvxd-authsplit-panel {
  position: relative;
  overflow-x: hidden;
  overflow-y: auto;
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  padding: 30px 46px 34px;
  color: var(--lvxd-on-accent);
  background: linear-gradient(160deg, var(--lvxd-accent), var(--lvxd-accent-hover));
}

.lvxd-authsplit-panel::before {
  content: "";
  position: absolute;
  top: -30%;
  right: -12%;
  width: 62%;
  height: 72%;
  background: radial-gradient(circle, color-mix(in srgb, var(--lvxd-on-accent) 16%, transparent), transparent 70%);
  pointer-events: none;
}

.lvxd-authsplit-panel > * {
  position: relative;
}

.lvxd-authsplit-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--lvxd-on-accent);
  flex-shrink: 0;
}

.lvxd-authsplit-brand-mark {
  width: auto;
  height: 30px;
  flex-shrink: 0;
}

.lvxd-authsplit-brand-name {
  font-size: 17px;
  font-weight: 400;
  letter-spacing: -.02em;
  color: var(--lvxd-on-accent);
}

.lvxd-authsplit-brand-name-accent {
  font-weight: 700;
}

.lvxd-authsplit-panel-inner {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: safe center;
  width: 100%;
  max-width: 400px;
  margin: 0 auto;
  padding: 28px 0;
  animation: lvxdOnboardingSetpwIn .5s cubic-bezier(.34, 1.4, .64, 1) both;
}

.lvxd-authsplit-badge {
  position: relative;
  width: 58px;
  height: 58px;
  margin: 0 0 14px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 27px;
  color: var(--lvxd-on-accent);
  background: color-mix(in srgb, var(--lvxd-on-accent) 18%, transparent);
}

.lvxd-authsplit-eyebrow {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--lvxd-on-accent) 82%, transparent);
}

.lvxd-authsplit-title {
  margin-top: 5px;
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -.3px;
  line-height: 1.25;
  color: var(--lvxd-on-accent);
}

.lvxd-authsplit-body {
  margin: 10px 0 0;
  max-width: 42ch;
  font-size: 13.5px;
  line-height: 1.6;
  color: color-mix(in srgb, var(--lvxd-on-accent) 90%, transparent);
}

.lvxd-authsplit-body strong {
  color: var(--lvxd-on-accent);
  font-weight: 800;
  overflow-wrap: anywhere;
}

.lvxd-authsplit-actions {
  margin-top: 22px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* Primary CTA on the accent panel: an on-accent (light) fill so it reads as the main
   action against the accent background, mirroring the set-password submit button. */
.lvxd-authsplit-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px 18px;
  border-radius: 10px;
  font-size: 14px;
  font-weight: 700;
  text-decoration: none;
  border: 0;
  cursor: pointer;
}

.lvxd-authsplit-btn-primary {
  background: var(--lvxd-on-accent);
  color: var(--lvxd-accent);
}

.lvxd-authsplit-btn-primary:hover {
  background: color-mix(in srgb, var(--lvxd-on-accent) 90%, var(--lvxd-accent));
}

/* Secondary CTA on the accent panel: outlined in on-accent ink so it reads as the
   quieter of two actions (e.g. Choose-workspace's "continue" next to "open picker"). */
.lvxd-authsplit-btn-ghost {
  background: transparent;
  color: var(--lvxd-on-accent);
  border: 1.5px solid color-mix(in srgb, var(--lvxd-on-accent) 55%, transparent);
}

.lvxd-authsplit-btn-ghost:hover {
  border-color: var(--lvxd-on-accent);
  background: color-mix(in srgb, var(--lvxd-on-accent) 12%, transparent);
}

/* Live-region status line under the actions (aria-live), on-accent ink. */
.lvxd-authsplit-status {
  margin-top: 14px;
  min-height: 1.2em;
  font-size: 12.5px;
  color: color-mix(in srgb, var(--lvxd-on-accent) 80%, transparent);
}

/* Price summary box on the accent panel (e.g. the PayFast handoff): a translucent on-accent
   surface rather than the light card the in-app billing uses, so it reads on the accent fill. */
.lvxd-authsplit-summary {
  margin-top: 20px;
  padding: 14px 16px;
  border-radius: 12px;
  background: color-mix(in srgb, var(--lvxd-on-accent) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--lvxd-on-accent) 22%, transparent);
  text-align: left;
}

.lvxd-authsplit-summary-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
}

.lvxd-authsplit-summary-label {
  font-size: 13px;
  line-height: 1.45;
  color: color-mix(in srgb, var(--lvxd-on-accent) 88%, transparent);
}

.lvxd-authsplit-summary-value {
  flex: 0 0 auto;
  font-size: 17px;
  font-weight: 800;
  color: var(--lvxd-on-accent);
  font-variant-numeric: tabular-nums;
}

.lvxd-authsplit-summary-note {
  margin: 4px 0 0;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .3px;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--lvxd-on-accent) 70%, transparent);
}

/* Indeterminate progress bar on the accent panel - translucent track, on-accent runner. */
.lvxd-authsplit-progress {
  position: relative;
  overflow: hidden;
  height: 4px;
  margin-top: 20px;
  border-radius: 99px;
  background: color-mix(in srgb, var(--lvxd-on-accent) 22%, transparent);
}

.lvxd-authsplit-progress::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 34%;
  border-radius: 99px;
  background: var(--lvxd-on-accent);
  animation: lvxdAuthsplitSlide 1.2s ease-in-out infinite;
}

@keyframes lvxdAuthsplitSlide {
  0% { transform: translateX(-110%); }
  100% { transform: translateX(320%); }
}

/* Trust line on the accent panel (shield + copy), on-accent ink. */
.lvxd-authsplit-secure {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 16px;
  font-size: 12px;
  line-height: 1.5;
  color: color-mix(in srgb, var(--lvxd-on-accent) 84%, transparent);
}

.lvxd-authsplit-secure i {
  font-size: 14px;
  color: var(--lvxd-on-accent);
}

@media (prefers-reduced-motion: reduce) {
  .lvxd-authsplit-progress::after {
    animation: none;
    width: 100%;
    opacity: .5;
  }
}

/* A two-panel page hidden via the [hidden] attribute (e.g. the PlanCheckoutReturn states the
   poller toggles): the base .lvxd-authsplit-page display:flex would otherwise beat the UA hidden
   rule and keep it on screen, so restate the hide at the same specificity. */
.lvxd-authsplit-page[hidden] {
  display: none;
}

/* Confetti overlay for a celebration on the aside - a full-panel layer, clipped and click-through.
   Pieces are .lvxd-onboarding-confetti spawned by the page's own script. */
.lvxd-authsplit-confetti {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.lvxd-authsplit-footnote {
  margin-top: 20px;
  font-size: 12.5px;
  line-height: 1.6;
  color: color-mix(in srgb, var(--lvxd-on-accent) 80%, transparent);
}

.lvxd-authsplit-signout {
  display: inline;
}

.lvxd-authsplit-footnote button,
.lvxd-authsplit-footnote a {
  color: var(--lvxd-on-accent);
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 2px;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  cursor: pointer;
  font: inherit;
}

/* RIGHT column: the soft mood panel - same preview gradient, dotted texture and corner
   glow the set-password aside uses, so the two screens read as one product. */
.lvxd-authsplit-aside {
  position: relative;
  overflow-x: hidden;
  overflow-y: auto;
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: safe center;
  padding: 48px 40px;
  background: var(--lvxd-preview-gradient);
}

.lvxd-authsplit-aside::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(circle, var(--lvxd-preview-dot) 1px, transparent 1px);
  background-size: 26px 26px;
  pointer-events: none;
}

.lvxd-authsplit-aside::after {
  content: "";
  position: absolute;
  width: 520px;
  height: 520px;
  border-radius: 50%;
  background: radial-gradient(circle, var(--lvxd-preview-glow), transparent 70%);
  top: -120px;
  right: -80px;
  pointer-events: none;
}

.lvxd-authsplit-aside-inner {
  position: relative;
  width: 100%;
  max-width: 380px;
  text-align: center;
}

/* Mood carries the per-page tone as a custom property the circle + ring read from. */
.lvxd-authsplit-mood.is-welcome { --lvxd-mood-color: var(--lvxd-success); }
.lvxd-authsplit-mood.is-blocked { --lvxd-mood-color: var(--lvxd-accent); }
.lvxd-authsplit-mood.is-neutral { --lvxd-mood-color: var(--lvxd-accent); }

.lvxd-authsplit-mood-ring {
  position: relative;
  width: 88px;
  height: 88px;
  margin: 0 auto 22px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.lvxd-authsplit-mood-ring::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 3px solid var(--lvxd-mood-color, var(--lvxd-accent));
  opacity: .35;
}

.lvxd-authsplit-mood-circle {
  position: relative;
  width: 70px;
  height: 70px;
  border-radius: 50%;
  background: var(--lvxd-mood-color, var(--lvxd-accent));
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 32px;
  box-shadow: 0 12px 34px color-mix(in srgb, var(--lvxd-mood-color, var(--lvxd-accent)) 40%, transparent);
  animation: lvxdOnboardingDonePop .5s cubic-bezier(.34, 1.56, .64, 1) both;
}

.lvxd-authsplit-mood-title {
  margin: 0 0 8px;
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -.6px;
  color: var(--lvxd-text-heading);
}

.lvxd-authsplit-mood-subtitle {
  font-size: 15px;
  color: var(--lvxd-text-muted);
  line-height: 1.6;
}

/* Compound selector (.lvxd-nib-wrap.lvxd-authsplit-nib) so align-items:center wins over the base
   .lvxd-nib-wrap { align-items: flex-end } at equal (single-class) specificity - otherwise, since
   lvxd-nib.css loads after this file, the base right-alignment won and Nib sat off to the right
   instead of centred under the panel copy (fix, 2026-09-01). */
.lvxd-nib-wrap.lvxd-authsplit-nib {
  position: relative;
  align-items: center;
  margin-top: 28px;
}

/* Responsive: single column at/below the tablet breakpoint, content first. */
@media (max-width: 768px) {
  .lvxd-authsplit-page {
    flex-direction: column;
  }

  .lvxd-authsplit-panel {
    flex: none;
    width: 100%;
    padding: 26px 22px 30px;
  }

  .lvxd-authsplit-panel-inner {
    max-width: 440px;
    padding: 24px 0 8px;
  }

  .lvxd-authsplit-aside {
    flex: none;
    width: 100%;
    padding: 40px 24px;
  }

  .lvxd-authsplit-nib {
    display: none;
  }
}

/* Smallest screens: the mood panel is pure decoration, so drop it and let the
   content own the viewport. */
@media (max-width: 480px) {
  .lvxd-authsplit-aside {
    display: none;
  }
}

/* Final-step consent gate (Terms & Conditions + Privacy Policy). Sits at the bottom of whichever
   step is the finish line (plan for a free/subscribe selection, trial for a paid one), above the
   shared footer's create-workspace button. The checkbox gates that button (see canContinue) - the
   visitor agrees here before any account is created. */
.lvxd-onboarding-consent {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--lvxd-border-soft);
}

/* Drawn rather than a native checkbox (appearance:none): a native control ignores a custom border
   colour - accent-color only paints the CHECKED fill - so the unchecked box could not be given the
   system's soft-grey border. Same visual language as .lvxd-onboarding-checkbox (surface fill, soft
   border, accent fill + on-accent check when ticked), just sized for this smaller consent row. */
.lvxd-onboarding-consent-check {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  margin-top: 1px;
  appearance: none;
  -webkit-appearance: none;
  /* Medium grey, not --lvxd-border-soft: the consent tick is a required gate, so its box stays
     clearly visible in both themes (owner ask 2026-09-11) instead of near-invisible until ticked. */
  border: 1.5px solid var(--lvxd-text-muted);
  border-radius: 6px;
  background: var(--lvxd-surface);
  cursor: pointer;
  display: grid;
  place-content: center;
  transition: background .15s, border-color .15s;
}

.lvxd-onboarding-consent-check::before {
  content: "";
  width: 10px;
  height: 10px;
  transform: scale(0);
  transition: transform .15s;
  background: var(--lvxd-on-accent);
  clip-path: polygon(14% 44%, 0 65%, 40% 100%, 100% 16%, 82% 0, 38% 65%);
}

.lvxd-onboarding-consent-check:checked {
  border-color: var(--lvxd-accent);
  background: var(--lvxd-accent);
}

.lvxd-onboarding-consent-check:checked::before {
  transform: scale(1);
}

.lvxd-onboarding-consent-check:focus-visible {
  outline: 2px solid var(--lvxd-accent);
  outline-offset: 2px;
}

.lvxd-onboarding-consent-text {
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--lvxd-text-muted);
  cursor: pointer;
}

.lvxd-onboarding-consent-link {
  color: var(--lvxd-accent);
  font-weight: 600;
  text-decoration: none;
}

.lvxd-onboarding-consent-link:hover {
  text-decoration: underline;
}

/* The "not wired yet" state: still reads as a link so the sentence is honest, but the cursor says
   it doesn't go anywhere yet. Give the catalog a real URL (termsUrl / privacyPolicyUrl) and the
   is-placeholder class is gone - it becomes an ordinary link with no other change. */
.lvxd-onboarding-consent-link.is-placeholder {
  cursor: default;
}

/* ============================================================================
   Check-your-email surface (Account/SetPasswordPending fallback)
   ----------------------------------------------------------------------------
   A full-viewport accent screen: the provisioned owner is passwordless in
   LivexID, so this is the expected stop between "workspace created" and "you can
   sign in". Replaces the older two-panel setpassword surface for this state with
   a single centred screen. All colour comes from the theme tokens
   (--lvxd-accent / --lvxd-accent-hover / --lvxd-on-accent), so light / dark / dim
   all resolve from one rule set. Confetti reuses .lvxd-onboarding-confetti +
   lvxdOnboardingConfettiFall, spawned by the page's shared celebrate script.
   ============================================================================ */
.lvxd-onboarding-checkemail {
  position: relative;
  width: 100%;
  min-height: 100dvh;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 96px 24px;
  background: linear-gradient(160deg, var(--lvxd-accent), var(--lvxd-accent-hover));
  color: var(--lvxd-on-accent);
}

/* Drifting glows for depth. On-accent based, so they read as soft light in every theme. */
.lvxd-onboarding-checkemail-aurora {
  position: absolute;
  border-radius: 50%;
  filter: blur(34px);
  pointer-events: none;
}

.lvxd-onboarding-checkemail-aurora-1 {
  top: -12%;
  left: -8%;
  width: 44%;
  height: 52%;
  background: radial-gradient(circle at 50% 50%, color-mix(in srgb, var(--lvxd-on-accent) 26%, transparent), transparent 66%);
  animation: lvxdCheckDrift1 18s ease-in-out infinite;
}

.lvxd-onboarding-checkemail-aurora-2 {
  bottom: -16%;
  right: -10%;
  width: 50%;
  height: 58%;
  background: radial-gradient(circle at 50% 50%, color-mix(in srgb, var(--lvxd-on-accent) 20%, transparent), transparent 68%);
  animation: lvxdCheckDrift2 22s ease-in-out infinite;
}

.lvxd-onboarding-checkemail-aurora-3 {
  top: 30%;
  right: 22%;
  width: 30%;
  height: 34%;
  background: radial-gradient(circle at 50% 50%, color-mix(in srgb, var(--lvxd-on-accent) 16%, transparent), transparent 70%);
  animation: lvxdCheckDrift1 26s ease-in-out infinite reverse;
}

/* Soft central spotlight behind the copy. */
.lvxd-onboarding-checkemail-spot {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 760px;
  height: 760px;
  transform: translate(-50%, -50%);
  background: radial-gradient(circle, color-mix(in srgb, var(--lvxd-on-accent) 10%, transparent), transparent 60%);
  pointer-events: none;
}

.lvxd-onboarding-checkemail-inner {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: 560px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.lvxd-onboarding-checkemail-inner > * {
  animation: lvxdCheckRise .6s cubic-bezier(.34, 1.2, .64, 1) both;
}

.lvxd-onboarding-checkemail-title {
  margin: 0;
  font-size: 40px;
  font-weight: 800;
  line-height: 1.14;
  letter-spacing: -.9px;
  color: var(--lvxd-on-accent);
  text-shadow: 0 2px 30px color-mix(in srgb, var(--lvxd-accent) 40%, transparent);
  animation-delay: .12s;
}

.lvxd-onboarding-checkemail-sub {
  margin: 16px 0 0;
  max-width: 42ch;
  font-size: 15.5px;
  line-height: 1.55;
  color: color-mix(in srgb, var(--lvxd-on-accent) 90%, transparent);
  animation-delay: .2s;
}

.lvxd-onboarding-checkemail-sub strong {
  font-weight: 800;
  color: var(--lvxd-on-accent);
  overflow-wrap: anywhere;
}

.lvxd-onboarding-checkemail-notice {
  display: flex;
  align-items: center;
  gap: 11px;
  margin-top: 28px;
  padding: 14px 18px;
  border-radius: 14px;
  max-width: 480px;
  background: color-mix(in srgb, var(--lvxd-on-accent) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--lvxd-on-accent) 18%, transparent);
  text-align: left;
  font-size: 13px;
  line-height: 1.5;
  color: color-mix(in srgb, var(--lvxd-on-accent) 92%, transparent);
  animation-delay: .28s;
}

.lvxd-onboarding-checkemail-notice i {
  flex-shrink: 0;
  font-size: 17px;
  color: var(--lvxd-on-accent);
}

.lvxd-onboarding-checkemail-notice strong {
  font-weight: 800;
  color: var(--lvxd-on-accent);
}

/* Inline "Request new email" link, sitting inside the notice text. Hands off to LivexID. */
.lvxd-onboarding-checkemail-link {
  font-weight: 800;
  color: var(--lvxd-on-accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.lvxd-onboarding-checkemail-link:hover {
  color: var(--lvxd-on-accent);
  text-decoration: none;
}

.lvxd-onboarding-checkemail-foot {
  margin: 26px 0 0;
  font-size: 12px;
  color: color-mix(in srgb, var(--lvxd-on-accent) 66%, transparent);
  animation-delay: .44s;
}

@keyframes lvxdCheckRise {
  0% { opacity: 0; transform: translateY(14px) scale(.98); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes lvxdCheckDrift1 {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(30px, 26px) scale(1.12); }
}

@keyframes lvxdCheckDrift2 {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(-34px, -22px) scale(1.14); }
}

@media (max-width: 640px) {
  .lvxd-onboarding-checkemail {
    padding: 72px 20px 56px;
  }

  .lvxd-onboarding-checkemail-title {
    font-size: 28px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .lvxd-onboarding-checkemail-inner > *,
  .lvxd-onboarding-checkemail-aurora {
    animation: none;
  }
}
