/* ═══════════════════════════════════════════════════════════════════════════
   BlueOneHR · the self-service layer
   ═══════════════════════════════════════════════════════════════════════════

   The pages a stranger meets before anyone from BlueOneHR has spoken to them:
   setting a first password, accepting an invitation, reading a trial banner,
   meeting a lock page, working through the setup checklist, and the HR pages
   that send invitations out.

   TWO SURFACES, AND THEY ARE THE PRODUCT'S OWN

   `.bon-ss` is the unauthenticated surface. It is the sign-in gateway's own
   surface: same two-zone split, same deep indigo on the left, same working
   canvas on the right, same Outfit and Inter. A person who accepts an
   invitation and a person who signs in are looking at one product, so the two
   pages are one page with different work in the right-hand zone.

   Everything else here is a `.bon-set__` or `.bon-v3__` component and belongs
   inside the Settings kit's own surface. Nothing below invents a second visual
   language: every value is a token the v3 apps already define.

   HOW IT LOADS, AND WHY IT DOES NOT FIGHT THE KIT

   On the v3 shell this file is linked in the head, and a Settings page then
   links its own app sheet and `v3_settings_kit.css` inside the content block,
   so the kit still loads after the app sheet exactly as its own header
   requires. That ordering is deliberate and this file does not disturb it.

   What keeps that safe is that this file defines no class either of them
   defines. Every name below is new: `bon-tb__`, `bon-ss__`, `bon-set__step`,
   `bon-set__steps`, `bon-set__progress`, `bon-inv__`. Nothing here overrides a
   kit component, so nothing here depends on winning a cascade it would lose.
   A rule added later that DOES need to beat the kit belongs in the kit, not in
   a second link on the page.

   For the unauthenticated pages the shell is not reachable at all, so `.bon-ss`
   carries its own token block. The values are copied from the `.bon-shell`
   block in `v3_shell.css`, verbatim and for the same reason `login_v3.html`
   copies them: those pages must render before any app CSS exists. Identical
   values mean the two cannot drift without somebody editing both.

   AUTO-FILL, NEVER AUTO-FIT

   Every grid here is `repeat(auto-fill, minmax(...))`. `auto-fit` collapses the
   tracks nothing occupies and stretches the survivors across the full measure,
   so a checklist with two steps left renders as two enormous cards and a
   one-card row reads as a full-width banner. `auto-fill` keeps the track, so a
   list that shrinks looks like a list that shrank. */


/* ══════════════════════════════════════════════════════════════════════════
   1 · THE TRIAL BANNER
   ══════════════════════════════════════════════════════════════════════════

   Sticky, one line on a wide screen, and the same component on both shells.

   The phase is a data attribute rather than four class names because the phase
   is one value from `compute_trial_phase`, and a value with four possible
   states is better read as a value than reconstructed from whichever of four
   classes happens to be present. The stylesheet then has one selector per
   phase and no combination of two can exist. */

.bon-tb {
  --tb-ink: #ffffff;
  --tb-bg: #2f3ba8;
  --tb-edge: rgba(255, 255, 255, .30);
  --tb-quiet: rgba(255, 255, 255, .72);

  position: sticky;
  top: 0;
  z-index: 9998;
  display: none;                 /* the script reveals it; see bon_trial_banner.js */
  padding: 9px 20px;
  background: var(--tb-bg);
  color: var(--tb-ink);
  font-family: 'Inter', sans-serif;
  font-size: 13px;
  line-height: 1.45;
  box-shadow: 0 1px 0 rgba(0, 0, 0, .12);
}

/* Healthy is the platform saying something true and unremarkable, so it is the
   product's own indigo rather than a colour that means anything. Warning and
   urgent escalate; grace is the one state where the trial has actually ended
   and the workspace is still open, so it is the darkest of the three. */
.bon-tb[data-phase="healthy"] { --tb-bg: #2f3ba8; }
.bon-tb[data-phase="warning"] { --tb-bg: #8a5407; }
.bon-tb[data-phase="urgent"]  { --tb-bg: #a52334; }
.bon-tb[data-phase="grace"]   { --tb-bg: #7c1a28; }
/* Read-only workspace (BL-HR-077): the trial has ended and nothing was deleted, so
   a calm slate rather than the red of an ending trial. Always visible; there is
   no dismiss, because the state does not go away until the workspace is restored. */
.bon-tb[data-phase="read_only"] { --tb-bg: #3b4252; }

.bon-tb__in {
  max-width: 1320px;             /* the Settings kit measure, so the banner and
                                    the page under it share a left edge */
  margin: 0 auto;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 14px;
}

.bon-tb__msg { margin: 0; }
.bon-tb__msg b { font-weight: 700; }

/* The date the trial ends, beside the countdown rather than inside it. A
   sentence that carries both a number of days and a date reads as two claims
   about the same thing, and people check the date. */
.bon-tb__when {
  color: var(--tb-quiet);
  font-variant-numeric: tabular-nums;
}

.bon-tb__actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 12px;
  margin-left: auto;
}

.bon-tb__cta {
  display: inline-block;
  padding: 4px 12px;
  border: 1px solid var(--tb-edge);
  border-radius: 6px;
  background: rgba(255, 255, 255, .14);
  color: var(--tb-ink);
  font-size: 12.5px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.bon-tb__cta:hover,
.bon-tb__cta:focus { background: rgba(255, 255, 255, .24); color: var(--tb-ink); }
.bon-tb__cta:focus-visible { outline: 2px solid #ffffff; outline-offset: 2px; }

.bon-tb__link {
  color: var(--tb-ink);
  font-size: 12.5px;
  font-weight: 500;
  text-decoration: underline;
  white-space: nowrap;
}
.bon-tb__link:hover, .bon-tb__link:focus { color: var(--tb-ink); }

.bon-tb__phone {
  color: var(--tb-quiet);
  font-size: 12.5px;
  white-space: nowrap;
}

/* Dismissal is per session and the control says so on hover rather than in the
   banner, because a banner that explains its own close button has spent a line
   of a one-line component on itself. */
.bon-tb__close {
  flex-shrink: 0;
  padding: 2px 9px;
  border: 1px solid var(--tb-edge);
  border-radius: 6px;
  background: rgba(255, 255, 255, .12);
  color: var(--tb-ink);
  font-size: 12px;
  line-height: 1.5;
  cursor: pointer;
}
.bon-tb__close:hover { background: rgba(255, 255, 255, .22); }
.bon-tb__close:focus-visible { outline: 2px solid #ffffff; outline-offset: 2px; }

@media (max-width: 720px) {
  .bon-tb__actions { margin-left: 0; width: 100%; }
}


/* ══════════════════════════════════════════════════════════════════════════
   2 · THE UNAUTHENTICATED SURFACE
   ══════════════════════════════════════════════════════════════════════════

   Set a password, accept an invitation, read a lock page. Three pages, one
   surface, and it is the sign-in gateway's surface rather than a third look.

   The left zone carries the product and, where there is one, the thing being
   joined: the workspace name, the company, the role on the invitation. The
   right zone carries the single piece of work. A person on these pages has
   arrived from an email and has exactly one thing to do, so the right zone
   never offers a second one. */

.bon-ss {
  /* v3 tokens, verbatim from v3_shell.css .bon-shell */
  --v3-bg: #eef0f6;
  --v3-ink: #14141c;
  --v3-ink-dim: #646577;
  --v3-ink-decor: #9a9bab;
  --v3-card: #ffffff;
  --v3-card-line: #e4e5ee;
  --v3-violet: #6553e7;
  --v3-emerald: #0f7b56;
  --v3-emerald-soft: #e4f7ee;
  --v3-amber: #995f08;
  --v3-amber-soft: #fdf1de;
  --v3-rose: #c43069;
  --v3-rose-soft: #fce8f0;
  --v3-font-display: 'Outfit', sans-serif;
  --v3-font-body: 'Inter', sans-serif;

  /* the gateway's own two-zone palette, verbatim from login_v3.html */
  --gw-deep-1: #1b1546;
  --gw-deep-2: #2c2170;
  --gw-deep-3: #3d2fa8;
  --gw-on-deep: rgba(255, 255, 255, .82);
  --gw-on-deep-dim: rgba(255, 255, 255, .55);

  min-height: 100vh;
  display: grid;
  grid-template-columns: minmax(0, 1.18fr) minmax(0, 0.82fr);
  font-family: var(--v3-font-body);
  color: var(--v3-ink);
  background: var(--v3-bg);
}
.bon-ss * { box-sizing: border-box; }

.bon-ss__sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ── zone 1 · the platform ─────────────────────────────────────────────── */

.bon-ss__universe {
  position: relative;
  overflow: hidden;
  padding: 40px 44px;
  color: #ffffff;
  background:
    radial-gradient(120% 90% at 18% 8%, rgba(109, 92, 232, .30) 0%, rgba(109, 92, 232, 0) 55%),
    radial-gradient(90% 70% at 88% 92%, rgba(61, 47, 168, .42) 0%, rgba(61, 47, 168, 0) 60%),
    linear-gradient(163deg, var(--gw-deep-1) 0%, var(--gw-deep-2) 52%, var(--gw-deep-3) 100%);
  display: flex;
  flex-direction: column;
  gap: 28px;
}

.bon-ss__grid {
  position: absolute; inset: 0; pointer-events: none;
  background-image:
    linear-gradient(rgba(255, 255, 255, .045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, .045) 1px, transparent 1px);
  background-size: 46px 46px;
  mask-image: radial-gradient(80% 70% at 40% 40%, #000 30%, transparent 100%);
  -webkit-mask-image: radial-gradient(80% 70% at 40% 40%, #000 30%, transparent 100%);
}

.bon-ss__brand {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--v3-font-display);
  font-size: 16px;
  font-weight: 700;
  letter-spacing: -.01em;
}
.bon-ss__brand img { width: 26px; height: 26px; border-radius: 6px; }
.bon-ss__brand-sq {
  width: 26px; height: 26px; border-radius: 6px;
  background: rgba(255, 255, 255, .18);
}

.bon-ss__lede { position: relative; margin: auto 0; max-width: 30rem; }
.bon-ss__lede h2 {
  margin: 0 0 12px;
  font-family: var(--v3-font-display);
  font-size: clamp(24px, 2.6vw, 34px);
  font-weight: 700;
  line-height: 1.18;
  letter-spacing: -.02em;
}
.bon-ss__lede p {
  margin: 0;
  color: var(--gw-on-deep);
  font-size: 14px;
  line-height: 1.6;
}

/* The facts about the thing being joined. A definition list because that is
   what it is: a label and the value it labels, not a table of one row. */
.bon-ss__facts {
  position: relative;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: 14px 24px;
}
.bon-ss__facts > div { min-width: 0; }
.bon-ss__facts dt {
  margin: 0 0 3px;
  color: var(--gw-on-deep-dim);
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .06em;
}
.bon-ss__facts dd {
  margin: 0;
  color: #ffffff;
  font-size: 14px;
  font-weight: 600;
  overflow-wrap: anywhere;
}

/* ── zone 2 · the work ─────────────────────────────────────────────────── */

.bon-ss__panel {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px 36px;
}
.bon-ss__card {
  width: 100%;
  max-width: 25rem;
}

.bon-ss__title {
  margin: 0 0 6px;
  font-family: var(--v3-font-display);
  font-size: 23px;
  font-weight: 700;
  letter-spacing: -.02em;
}
.bon-ss__sub {
  margin: 0 0 22px;
  color: var(--v3-ink-dim);
  font-size: 13.5px;
  line-height: 1.55;
}

.bon-ss__field { position: relative; margin-bottom: 14px; }
.bon-ss__label {
  display: block;
  margin-bottom: 5px;
  font-size: 12px;
  font-weight: 600;
  color: var(--v3-ink);
}
.bon-ss__input {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid #d7d8e4;
  border-radius: 8px;
  background: var(--v3-card);
  color: var(--v3-ink);
  font-family: var(--v3-font-body);
  font-size: 14px;
}
.bon-ss__input:focus {
  outline: none;
  border-color: var(--v3-violet);
  box-shadow: 0 0 0 3px rgba(101, 83, 231, .16);
}
.bon-ss__input[readonly] { background: #f4f5fa; color: var(--v3-ink-dim); }
.bon-ss__input--pw { padding-right: 40px; }

/* The input and its reveal control, and nothing else. The control used to be
   positioned against `.bon-ss__field`, which also holds the label above and the
   password rules below it, so on the field that HAS rules the eye sat on top of
   the first line of them. Anchoring it to the input alone is correct whatever
   else the field grows. */
.bon-ss__control { position: relative; }

.bon-ss__peek {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  padding: 4px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--v3-ink-dim);
  cursor: pointer;
  line-height: 0;
}
.bon-ss__peek:hover { color: var(--v3-ink); }
.bon-ss__peek:focus-visible { outline: 2px solid var(--v3-violet); outline-offset: 1px; }

.bon-ss__hint {
  margin: 5px 0 0;
  color: var(--v3-ink-dim);
  font-size: 11.5px;
  line-height: 1.5;
}

/* What the password has to be, listed before it is typed rather than after it
   is refused. The list is server-rendered from the configured validators, so a
   deployment that changes them changes this. */
.bon-ss__rules {
  margin: 6px 0 0;
  padding-left: 1.1rem;
  color: var(--v3-ink-dim);
  font-size: 11.5px;
  line-height: 1.65;
}

.bon-ss__submit {
  width: 100%;
  margin-top: 6px;
  padding: 11px 16px;
  border: 0;
  border-radius: 8px;
  background: var(--v3-violet);
  color: #ffffff;
  font-family: var(--v3-font-body);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}
.bon-ss__submit:hover { filter: brightness(1.06); }
.bon-ss__submit:focus-visible { outline: 2px solid var(--v3-ink); outline-offset: 2px; }

.bon-ss__or {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 18px 0;
  color: var(--v3-ink-decor);
  font-size: 11.5px;
  text-transform: uppercase;
  letter-spacing: .08em;
}
.bon-ss__or::before, .bon-ss__or::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--v3-card-line);
}

.bon-ss__idp {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  width: 100%;
  margin-bottom: 8px;
  padding: 10px 14px;
  border: 1px solid var(--v3-card-line);
  border-radius: 8px;
  background: var(--v3-card);
  color: var(--v3-ink-dim);
  font-size: 13.5px;
  font-weight: 600;
  text-decoration: none;
}
.bon-ss__idp:last-child { margin-bottom: 0; }
.bon-ss__idp:hover { border-color: #c9cbdb; color: var(--v3-ink); background: #fcfcfe; }
.bon-ss__idp:focus-visible { outline: 2px solid var(--v3-violet); outline-offset: 2px; }

.bon-ss__foot {
  margin: 18px 0 0;
  color: var(--v3-ink-dim);
  font-size: 12px;
  line-height: 1.6;
}
.bon-ss__foot a { color: var(--v3-violet); font-weight: 600; }

/* A state the page is in rather than a field on it: a spent link, a revoked
   invitation, an expired trial. */
.bon-ss__note {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  margin: 0 0 18px;
  padding: 11px 13px;
  border-radius: 9px;
  font-size: 13px;
  line-height: 1.55;
}
.bon-ss__note--info    { background: #eef0fb; color: #2f3ba8; }
.bon-ss__note--good    { background: var(--v3-emerald-soft); color: var(--v3-emerald); }
.bon-ss__note--warn    { background: var(--v3-amber-soft);   color: var(--v3-amber); }
.bon-ss__note--stop    { background: var(--v3-rose-soft);    color: var(--v3-rose); }
.bon-ss__note svg { flex-shrink: 0; margin-top: 1px; }

/* The contact block on the lock page. Not a card: the page is already one. */
.bon-ss__contact {
  margin: 0 0 18px;
  padding: 14px 16px;
  border: 1px solid var(--v3-card-line);
  border-radius: 10px;
  background: var(--v3-card);
}
.bon-ss__contact h2 {
  margin: 0 0 9px;
  font-family: var(--v3-font-display);
  font-size: 13px;
  font-weight: 700;
}
.bon-ss__contact-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 6px;
  color: var(--v3-ink-dim);
  font-size: 13px;
}
.bon-ss__contact-row a { color: var(--v3-violet); font-weight: 600; }

@media (max-width: 940px) {
  .bon-ss { grid-template-columns: minmax(0, 1fr); }
  .bon-ss__universe { padding: 28px 24px; gap: 20px; }
  .bon-ss__lede { margin: 0; }
  .bon-ss__panel { padding: 28px 20px 48px; }
}


/* ══════════════════════════════════════════════════════════════════════════
   3 · THE SETUP CHECKLIST
   ══════════════════════════════════════════════════════════════════════════

   One row per step from the setup status API. A row states three things: what
   the step is, whether it is done, and whether anything is waiting on it.

   "Blocking" is deliberately not styled as an error. A step that blocks is not
   a failure, it is the next thing to do, and colouring it red teaches people to
   read the checklist as a list of problems. It gets weight instead. */

.bon-v3 .bon-set__progress {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 18px;
}
.bon-v3 .bon-set__progress-track {
  flex: 1;
  height: 6px;
  border-radius: 3px;
  background: #e4e5ee;
  overflow: hidden;
}
.bon-v3 .bon-set__progress-fill {
  display: block;
  height: 100%;
  border-radius: 3px;
  background: var(--v3-emerald);
}
.bon-v3 .bon-set__progress-count {
  color: var(--v3-ink-dim);
  font-size: 12.5px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.bon-v3 .bon-set__steps {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
  gap: 12px;
}

.bon-v3 .bon-set__step {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px 16px;
  border: 1px solid var(--v3-card-line, #e4e5ee);
  border-radius: 11px;
  background: var(--v3-card, #ffffff);
}
.bon-v3 .bon-set__step--blocking { border-color: #cfd1e4; box-shadow: 0 1px 0 #eceef8; }

/* The state mark. A ring when the step is open, a filled tick when it is done,
   so the two are distinguishable without colour. */
.bon-v3 .bon-set__step-mark {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  margin-top: 1px;
  border: 2px solid #c9cbdb;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: transparent;
}
.bon-v3 .bon-set__step--done .bon-set__step-mark {
  border-color: var(--v3-emerald);
  background: var(--v3-emerald);
  color: #ffffff;
}

.bon-v3 .bon-set__step-body { flex: 1; min-width: 0; }
.bon-v3 .bon-set__step-title {
  margin: 0;
  font-family: var(--v3-font-display, 'Outfit', sans-serif);
  font-size: 14px;
  font-weight: 600;
  color: var(--v3-ink, #14141c);
}
.bon-v3 .bon-set__step--done .bon-set__step-title { color: var(--v3-ink-dim, #646577); }
.bon-v3 .bon-set__step-note {
  margin: 3px 0 0;
  color: var(--v3-ink-dim, #646577);
  font-size: 12px;
  line-height: 1.5;
}
.bon-v3 .bon-set__step-go {
  flex-shrink: 0;
  align-self: center;
  color: var(--v3-violet, #6553e7);
  font-size: 12.5px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.bon-v3 .bon-set__step-go:hover { text-decoration: underline; }


/* ══════════════════════════════════════════════════════════════════════════
   4 · INVITATIONS
   ══════════════════════════════════════════════════════════════════════════

   The list is a kit table and needs nothing here. What it does need is a way to
   say what happened to an invitation, and a paste area for the bulk page. */

.bon-v3 .bon-inv__hint {
  margin: 0 0 14px;
  color: var(--v3-ink-dim, #646577);
  font-size: 12.5px;
  line-height: 1.6;
}

.bon-v3 .bon-inv__csv {
  width: 100%;
  min-height: 11rem;
  padding: 12px 14px;
  border: 1px solid #d7d8e4;
  border-radius: 9px;
  background: #ffffff;
  color: var(--v3-ink, #14141c);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12.5px;
  line-height: 1.7;
  resize: vertical;
}
.bon-v3 .bon-inv__csv:focus {
  outline: none;
  border-color: var(--v3-violet, #6553e7);
  box-shadow: 0 0 0 3px rgba(101, 83, 231, .16);
}

/* The header row of the sample, shown as what it is rather than described in a
   sentence. Monospace so the commas line up with the box above. */
.bon-v3 .bon-inv__sample {
  margin: 8px 0 0;
  padding: 9px 12px;
  border-radius: 8px;
  background: #f4f5fa;
  color: var(--v3-ink-dim, #646577);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 11.5px;
  line-height: 1.7;
  overflow-x: auto;
  white-space: pre;
}

/* One result line per row of a bulk paste, so a run that half worked says which
   half. */
.bon-v3 .bon-inv__results {
  margin: 14px 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
  gap: 6px;
}
.bon-v3 .bon-inv__result {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 7px 10px;
  border-radius: 7px;
  background: #f4f5fa;
  font-size: 12.5px;
}
.bon-v3 .bon-inv__result--ok   { background: var(--v3-emerald-soft, #e4f7ee); color: var(--v3-emerald, #0f7b56); }
.bon-v3 .bon-inv__result--bad  { background: var(--v3-rose-soft, #fce8f0);    color: var(--v3-rose, #c43069); }
.bon-v3 .bon-inv__result-who   { font-weight: 600; overflow-wrap: anywhere; }
.bon-v3 .bon-inv__result-why   { color: inherit; opacity: .85; }

/* The in-page tab bar the three invitation screens steer by.

   `.bon-v3__nav-tabs` already exists in four v3 app sheets and the Settings kit
   already pins its measure, but the two apps that define the tab's own look are
   Help Desk and Offboarding, and a Settings page loads neither. The values below
   are theirs, verbatim, so the bar looks the same wherever it is used rather
   than becoming a fifth copy that drifts. The measure is deliberately not
   repeated: the kit owns it. */

.bon-v3 .bon-v3__nav-tabs { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.bon-v3 .bon-v3__nav-tab {
  padding: 7px 14px;
  border: 1px solid var(--v3-line, #e4e5ee);
  border-radius: 8px;
  background: #ffffff;
  color: var(--v3-ink-dim, #646577);
  font-size: 12px;
  font-weight: 700;
  text-decoration: none;
}
.bon-v3 .bon-v3__nav-tab.active {
  background: var(--v3-violet, #6553e7);
  border-color: var(--v3-violet, #6553e7);
  color: #ffffff;
}
