/*
 * QuestWorks web sign-in pages (QUE-1054). Loaded after tokens.css, nothing else.
 *
 * Source: the "QuestWorks Design System" (Cqnp8QtRmr2F1znWaYoKh7), copy of 2026-10-29.
 *   tokens.css                vendored verbatim next to this file.
 *   components/bundle.css     NOT loaded (it imports Google Fonts and carries 87 modules).
 *                             The rules below are copied from it unchanged except where
 *                             marked "adjusted":
 *     lines 8-21     :root button and gradient variables (light theme only)
 *     lines 38-43    base: box-sizing, body, a, headings, p
 *     lines 77, 79   .qm-h3 role (size raised in .auth-card h1), .qm-muted
 *     lines 80-83    .qm-btn, .qm-btn.ghost, .qm-btn.sm, .qm-link
 *     lines 85-86    .qm-card; .qm-tag is composed (see "Coming soon")
 *     lines 97-98    .qm-header, .logo
 *     lines 274-276  .qm-cred internals (.seal, h3, p) for the /claim hero row (QUE-1055)
 *     lines 377-384  gradient text (.qm-em), .qm-btn final state, hover, ghost hover
 *     lines 620      @keyframes rise
 *     lines 1030     the shadow cancel for .qm-btn
 *     lines 1139-1143 .ff4 field, label, focus, error (adjusted: one column, strained-ink text)
 *     lines 1215     @keyframes gidot
 *     lines 2221-2223 .qm-btn.logo provider buttons
 *   colors_and_type.css lines 140-143: motion variables.
 * Drift: re-copy these rules when the Design System changes; the line numbers above are
 * from the 2026-10-29 copy.
 *
 * Rules: League Spartan 400 only, no shadows, one gradient button per screen, sky never
 * alone, no green. Only opacity, transform and colors animate.
 */

/* ---- Fonts: the Latin 400 subset replaces tokens.css's @font-face (declared later wins). */
@font-face {
  font-family: "League Spartan";
  src: url("/auth/assets/LeagueSpartan-400-latin.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
/* Fallback tuned so the swap to League Spartan does not move the heading. */
@font-face {
  font-family: "League Spartan Fallback";
  src: local("Arial"), local("Helvetica Neue"), local("Helvetica"), local("Liberation Sans");
  size-adjust: 97%;
  ascent-override: 70%;
  descent-override: 22%;
  line-gap-override: 0%;
}

/* ---- bundle.css 8-21, colors_and_type.css 140-143 */
:root {
  --font-sans: "League Spartan", "League Spartan Fallback", system-ui, -apple-system, "Segoe UI", sans-serif;
  --btn-bg: linear-gradient(99deg, #3079AE, #7ABDED);
  --btn-ink: #FFFFFF;
  --btn2-bg: transparent;
  --btn2-ink: #296590;
  --btn2-line: #CFDDEA;
  --grad: linear-gradient(117deg, #3079AE 24%, #7ABDED);
  --grad-text: linear-gradient(97deg, #3079AE, #7ABDED);
  --grad-line: linear-gradient(90deg, #3079AE, #7ABDED);
  --qw-ease: cubic-bezier(0.25, 0.46, 0.45, 0.94);
  --qw-ease-snap: cubic-bezier(0.2, 0.9, 0.3, 1);
  --qw-dur-fast: 200ms;
  --qw-dur-med: 300ms;
  --qw-dur-draw: 1400ms;
  --qw-tap: 44px;
  color-scheme: light;
}

/* ---- bundle.css 38-43 */
* { box-sizing: border-box; }
body { margin: 0; font-family: var(--font-sans); color: var(--ink); background: var(--bg-alt); font-size: 17px; line-height: 1.55; -webkit-font-smoothing: antialiased; }
img { max-width: 100%; display: block; }
a { color: var(--core); text-decoration: none; }
h1, h2, h3, h4 { margin: 0; font-weight: 400; color: var(--head); letter-spacing: -0.015em; text-wrap: balance; }
p { margin: 0; }
b, strong { font-weight: inherit; }
button, input { font-family: inherit; font-weight: 400; }

/* ---- bundle.css 79-83, 85, 97-98 */
.qm-muted { color: var(--ink-2); }
.qm-btn { display: inline-flex; align-items: center; gap: 8px; font: inherit; font-size: 16px; font-weight: 400; padding: 13px 22px; border-radius: 10px; background: var(--btn-bg); color: var(--btn-ink); border: 1px solid transparent; cursor: pointer; white-space: nowrap; }
.qm-btn.ghost { background: var(--btn2-bg); color: var(--btn2-ink); border-color: var(--btn2-line); }
.qm-btn.sm { font-size: 14px; padding: 9px 14px; }
.qm-link { color: var(--core); font-weight: 400; } .qm-link::after { content: " \2192"; }
.qm-card { background: var(--surface); border: 1px solid var(--line); border-radius: 16px; }
.qm-header { display: flex; align-items: center; gap: 28px; height: 68px; padding: 0 32px; border-bottom: 1px solid var(--line); background: var(--bg); }
.qm-header .logo { height: 28px; width: auto; }

/* ---- bundle.css 274-276 (hero row for /claim, PR C) */
.qm-cred h3 { font-size: 20px; } .qm-cred p { font-size: 14px; color: var(--ink-2); }

/* ---- bundle.css 377-384, 1030 (the final .qm-btn state carries no shadow) */
.qm-em, .qm-link {
  background: var(--grad-text); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.qm-em { font-style: normal; -webkit-box-decoration-break: clone; box-decoration-break: clone; }
.qm-btn { background: var(--btn-bg); color: var(--btn-ink); box-shadow: none; }
.qm-btn:hover { background: linear-gradient(99deg, #1F7FC7, #6BAFE0); }
.qm-btn.ghost { background: transparent; box-shadow: none; color: var(--btn2-ink); }
.qm-btn.ghost:hover { background: var(--alice); }
/* Phase 2 W5: the gradient paints from the border box, so the 1px transparent border shows no dark edge. */
.qm-btn:not(.ghost):not(.logo) { background-origin: border-box; }

/* ---- bundle.css 2221-2223 */
.qm-btn.logo, .qm-btn:has(> img) { background: linear-gradient(#fff, #fff) padding-box, linear-gradient(117deg, #3079AE, #7ABDED) border-box !important; border: 1px solid transparent !important; color: #1E4E70 !important; }
.qm-btn.logo:hover, .qm-btn:has(> img):hover { background: linear-gradient(#F5FAFF, #F5FAFF) padding-box, linear-gradient(117deg, #3079AE, #7ABDED) border-box !important; }
.qm-btn.logo img, .qm-btn:has(> img) img { filter: none !important; }

/* ---- bundle.css 1139-1143, adjusted: one column; message text in strained-ink (5.0:1) */
.ff4 { display: grid; grid-template-columns: 1fr; gap: 6px; }
.ff4 label { display: flex; flex-direction: column; gap: 6px; font-size: 14px; color: var(--ink-2); }
/* One field rhythm for every form on the auth-shell pages (/join, /settings, /start, /team, /billing; Asa, 2026-11-02):
   the label is 16px ink, its hint 14px ink-2 directly under it (4px), the control 8px under that, and the message slot 4px
   under the control. Fields sit 24px or more apart (the form's gap plus the message slot), clearly more than inside one. */
:is(div.ff4, .set-field) { gap: 0; }
:is(div.ff4, .set-field) > label:not(.ch):not(.inline) { font-size: 16px; line-height: 1.3; color: var(--ink); }
:is(div.ff4, .set-field) > .hint, :is(div.ff4, .set-field) > .st2-hint { margin: 4px 0 0; font-size: 14px; line-height: 1.4; color: var(--ink-2); }
:is(div.ff4, .set-field) > :is(input, textarea, select, .copy-row, .pick-row) { margin-top: 8px; }
:is(div.ff4, .set-field) > :is(.slot20, .msg, .counter) { margin-top: 4px; }
:is(div.ff4, .set-field) > * + :not(label, .hint, .st2-hint, input, textarea, select, .copy-row, .pick-row, .slot20, .msg, .counter) { margin-top: 6px; }
.ff4 input:not([type=checkbox]) { font: inherit; font-size: 16px; padding: 11px 14px; border-radius: 10px; border: 1px solid var(--line-2); background: var(--surface); color: var(--ink); min-height: 44px; width: 100%; }
.ff4 input:focus-visible { outline: 2px solid var(--core); outline-offset: 2px; }
.ff4 input::placeholder { color: var(--ink-3); opacity: 1; }
.ff4 .err input { border-color: var(--strained); }

/* ---- bundle.css 620, 1215 */
@keyframes rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes gidot { 0%, 100% { opacity: .3; } 50% { opacity: 1; } }

/* =========================================================================
   AuthShell (new layout; no library module is a standalone auth page)
   ========================================================================= */
.qm-header .logo-link { display: inline-flex; border-radius: 4px; }
.shell { display: flex; flex-direction: column; align-items: center; min-height: calc(100vh - 68px); padding: clamp(32px, 10vh, 96px) 20px 56px; }
.auth-card { position: relative; width: 100%; max-width: 440px; padding: 32px; overflow: hidden; opacity: 0; }
.auth-card[data-ready] { opacity: 1; animation: rise var(--qw-dur-med) var(--qw-ease) both; }
.auth-foot { margin-top: 24px; display: flex; flex-flow: row wrap; justify-content: center; gap: 16px; font-size: 14px; color: var(--ink-2); }
.auth-foot a, .legal a { color: var(--core); text-decoration: underline; text-underline-offset: 3px; }

/* Panels share one grid cell while they swap; only the active one keeps its room afterwards. */
.stack { display: grid; }
.stack.sizing { overflow: clip; transition: height var(--qw-dur-fast) var(--qw-ease); }
.panel { grid-area: 1 / 1; align-self: start; visibility: hidden; opacity: 0; pointer-events: none; min-width: 0; }
.panel:not([data-active]):not(.leaving) { display: none; }
.panel[data-active] { visibility: visible; opacity: 1; pointer-events: auto; }
.panel.entering { animation: panel-in var(--qw-dur-med) var(--qw-ease-snap) 120ms both; }
.panel.leaving { visibility: visible; animation: panel-out var(--qw-dur-fast) var(--qw-ease) both; }
@keyframes panel-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes panel-out { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateY(-6px); } }

.auth-card h1 { font-size: 30px; line-height: 1.1; letter-spacing: -0.02em; outline: none; }
.auth-card .lead { margin-top: 12px; color: var(--ink-2); }
.auth-card .body { margin-top: 24px; display: grid; gap: 16px; }
.group { display: grid; gap: 8px; }
.qm-btn.block { display: flex; width: 100%; justify-content: center; min-height: 51px; transition: border-color var(--qw-dur-fast) var(--qw-ease), background-color var(--qw-dur-fast) var(--qw-ease); }
.qm-btn.ghost:hover { border-color: var(--core); }
.qm-btn.logo img { width: 18px; height: 18px; flex: none; }
.qm-btn[aria-busy="true"] { cursor: default; }
.qm-btn[aria-disabled="true"] { cursor: default; }
.qm-btn.ghost.cool { opacity: .45; cursor: default; transition: opacity var(--qw-dur-fast) var(--qw-ease); }

/* Label and busy label share a cell: the button keeps its width. */
.swap { display: inline-grid; justify-items: center; }
.swap > * { grid-area: 1 / 1; transition: opacity 150ms var(--qw-ease); }
.swap .busy { opacity: 0; display: inline-flex; align-items: center; }
/* An idle button's busy label is hidden, not just transparent: it stays out of copy-paste, find-in-page and the reading order. */
.qm-btn:not([aria-busy="true"]):not(.copied) .swap .busy { visibility: hidden; }
.qm-btn[aria-busy="true"] .swap .lbl { opacity: 0; }
.qm-btn[aria-busy="true"] .swap .busy { opacity: 1; }
.dots { display: inline-flex; gap: 4px; margin-left: 8px; }
.dots i { width: 5px; height: 5px; border-radius: 50%; background: currentColor; opacity: .3; animation: gidot 900ms ease infinite; }
.dots i:nth-child(2) { animation-delay: 150ms; }
.dots i:nth-child(3) { animation-delay: 300ms; }

.qm-btn.copied .swap .lbl { opacity: 0; }
.qm-btn.copied .swap .busy { opacity: 1; }

/* SSO (brief "SSO"): selected = 1px core line, no fill. Disabled providers sit at 45% (M11). */
.qm-btn.logo.sso[aria-pressed="true"] { background: linear-gradient(#fff, #fff) padding-box, linear-gradient(#3079AE, #3079AE) border-box !important; }
.qm-btn.logo { transition: opacity var(--qw-dur-fast) var(--qw-ease), border-color var(--qw-dur-fast) var(--qw-ease); }
.qm-btn.logo[aria-disabled="true"] { opacity: .45; cursor: default; }
/* The ghost link takes no room until it is needed, then eases in. */
.ghost-row { height: 0; margin-top: -6px; overflow: hidden; display: flex; align-items: center; transition: height 200ms var(--qw-ease), margin-top 200ms var(--qw-ease); }
.ghost-row .qm-btn { opacity: 0; transition: opacity 200ms var(--qw-ease); }
.ghost-row[data-show] { height: 38px; margin-top: 0; overflow: visible; }
.ghost-row[data-show] .qm-btn { opacity: 1; }
/* The SSO button leaves once the primary reads "Continue with SSO". */
.sso-wrap { display: grid; grid-template-rows: 1fr; opacity: 1; transition: grid-template-rows 200ms var(--qw-ease), opacity 200ms var(--qw-ease), margin-top 200ms var(--qw-ease); }
.sso-wrap > .sso-inner { min-height: 0; overflow: hidden; padding: 3px; margin: -3px; }
.sso-wrap[data-hidden] { grid-template-rows: 0fr; opacity: 0; margin-top: -8px; pointer-events: none; }
.swap .lbl { transition: opacity 150ms var(--qw-ease); }

.divider { display: flex; align-items: center; gap: 12px; font-size: 14px; color: var(--ink-2); }
.divider::before, .divider::after { content: ""; flex: 1; height: 1px; background: var(--line); }

/* Message slot: 20px is always reserved, so an error never moves anything. */
.msg { height: 20px; overflow: hidden; font-size: 14px; line-height: 20px; color: var(--strained-ink); opacity: 0; transform: translateY(-4px); transition: opacity var(--qw-dur-fast) var(--qw-ease), transform var(--qw-dur-fast) var(--qw-ease), height var(--qw-dur-fast) var(--qw-ease); overflow-wrap: anywhere; }
.msg[data-show] { opacity: 1; transform: none; }
/* One line is reserved under the email field. A longer message eases the slot open (showMsg). */
#msg-provider { height: 0; margin-top: -8px; }
#btn-email { margin-top: 4px; }
.msg[data-tone="ok"] { color: var(--ink-2); }
.ff4 .err input { transition: border-color var(--qw-dur-fast) var(--qw-ease); }
.ff4 input { transition: border-color var(--qw-dur-fast) var(--qw-ease); }
.ff4 input:hover:not([readonly]) { border-color: var(--core); }
.ff4 input[readonly] { background: var(--surface-2); }
.ff4 input[type="text"].code { font-size: 24px; letter-spacing: .3em; text-align: center; padding-left: calc(14px + .3em); min-height: 56px; font-variant-numeric: tabular-nums; }
.ff4 input.code::placeholder { letter-spacing: .3em; }
.addr { overflow-wrap: anywhere; color: var(--ink); }
.actions { display: flex; flex-wrap: wrap; gap: 8px; }
.legal { font-size: 14px; color: var(--ink-2); }
.small-line { font-size: 14px; color: var(--ink-2); margin-top: 16px; overflow-wrap: anywhere; }

/* /claim hero row (QUE-1055). The seal is bundle.css 274-276 (.qm-cred .seal, h3, p) with a photo variant. */
.hero-row { display: grid; grid-template-columns: 64px 1fr; gap: 16px; align-items: center; padding: 16px 0; border-block: 1px solid var(--line); min-width: 0; }
.hero-row .who { min-width: 0; }
.hero-row h3 { font-size: 20px; line-height: 1.2; overflow-wrap: anywhere; }
.hero-row p { font-size: 14px; color: var(--ink-2); overflow-wrap: anywhere; }
.hero-row p[hidden] { display: none; }
.stackbtn { display: grid; gap: 6px; }
.auth-card h1 .addr { color: inherit; }
.qm-link.support { background: none; color: var(--core); -webkit-text-fill-color: currentColor; text-decoration: underline; text-underline-offset: 3px; }
.qm-link.support::after { content: none; }

/* Focus rings (bundle.css has none for buttons and links). */
.qm-btn:focus-visible, .qm-link:focus-visible, .auth-foot a:focus-visible, .legal a:focus-visible, .logo-link:focus-visible, .copy-field input:focus-visible { outline: 2px solid var(--core); outline-offset: 2px; }

/* Coming soon tag: 11px caps, core-ink on alice, pill (README, Buttons, links and fields). */
.tag-soon { display: inline-block; font-size: 11px; line-height: 1.4; letter-spacing: .08em; text-transform: uppercase; color: var(--core-ink); background: var(--alice); border-radius: 999px; padding: 3px 10px; margin-bottom: 16px; }

/* Success mark (ic-yes): gradient disc, white check. M5 draws it. */
.mark { width: 24px; height: 24px; margin-bottom: 8px; display: block; }
/* A success mark and its heading on one line (auth/ui.js injectMarks): the mark is 24px, the heading carries the moment. */
.mark-head { display: flex; align-items: center; gap: 8px; }
.mark-head > [data-mark] { flex: none; display: inline-flex; margin: 0; }
.mark-head .mark { width: 24px; height: 24px; margin: 0; }
.mark-head > h1, .mark-head > h2 { flex: 1; min-width: 0; margin: 0; }
.mark .disc { transform-origin: 9px 9px; }
.mark .tick { stroke-dasharray: 11; stroke-dashoffset: 0; }
.panel[data-active] .mark .disc { animation: mark-pop 200ms var(--qw-ease-snap) both; }
.panel[data-active] .mark .tick { animation: mark-draw 300ms var(--qw-ease) 120ms both; }
@keyframes mark-pop { from { opacity: 0; transform: scale(.85); } to { opacity: 1; transform: none; } }
@keyframes mark-draw { from { stroke-dashoffset: 11; } to { stroke-dashoffset: 0; } }

/* M4: working line along the card's top edge. */
.progress { position: absolute; top: 0; left: 0; right: 0; height: 2px; opacity: 0; transition: opacity var(--qw-dur-fast) var(--qw-ease); pointer-events: none; }
.auth-card[data-working] .progress { opacity: 1; }
.progress::before { content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 40%; background: var(--grad-line); animation: travel var(--qw-dur-draw) var(--qw-ease) infinite; }
@keyframes travel { from { transform: translateX(-100%); } to { transform: translateX(250%); } }

/* Copy-link field (admin approval, M8). */
.copy-field { display: grid; gap: 8px; margin-top: 16px; }
.copy-field label { font-size: 14px; color: var(--ink-2); }
.copy-field input { font: inherit; font-size: 14px; padding: 11px 14px; border-radius: 10px; border: 1px solid var(--line-2); background: var(--surface-2); color: var(--ink); min-height: 44px; width: 100%; text-overflow: ellipsis; }
.copy-btn { min-width: 118px; justify-content: center; }
.copy-btn svg { width: 16px; height: 16px; flex: none; }
.copy-row { display: flex; gap: 8px; align-items: stretch; }
.copy-row input { flex: 1; min-width: 0; }
.copy-row .qm-btn { min-height: 44px; }

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

@media (max-width: 480px) {
  .qm-header { padding: 0 20px; }
  .shell { padding-top: 32px; }
  .auth-card { padding: 24px; }
  .copy-row { flex-direction: column; }
  .copy-row .qm-btn { width: 100%; justify-content: center; }
}

/* Reduced motion: opacity-only entry, instant swaps, static dots and line. */
@media (prefers-reduced-motion: reduce) {
  .auth-card[data-ready], .panel.entering, .panel.leaving, .panel[data-active] .mark .disc, .panel[data-active] .mark .tick { animation: none; }
  .progress::before { animation: none; transform: none; }
  .dots i { animation: none; }
  .dots i:nth-child(1) { opacity: .3; }
  .dots i:nth-child(2) { opacity: .65; }
  .dots i:nth-child(3) { opacity: 1; }
  .msg { transform: none; }
  .stack.sizing, .ghost-row, .sso-wrap, .ghost-row .qm-btn, .qm-btn.logo, .msg, .swap > *, .progress, .qm-btn.block, .ff4 input, .qm-btn.ghost.cool { transition: none; }
}

.nw { white-space: nowrap; }
#linked-go { margin-top: 20px; }
#linked-go[hidden] { display: none; }

/* ---- The initials avatar, one look everywhere (Asa, 2026-11-02): brand gradient, white League Spartan 400 at 40% of the
   circle, centered; a photo fills the circle. .qw-av is the class; the older seal classes take the same rule and only set
   their size (--av). dash.css carries the same rule for the dash (.dx-av, .sc-avatar). ---- */
:where(.qw-av, .seal40, .seal64, .hero-row .seal, .qm-cred .seal, .seated .seal) {
  --av: 40px; width: var(--av); height: var(--av); border-radius: 50%; flex: none; position: relative; overflow: hidden;
  display: inline-grid; place-items: center; background: linear-gradient(117deg, #3079AE, #7ABDED); color: #fff;
  font-family: var(--font-sans); font-weight: 400; font-size: calc(var(--av) * .4); line-height: 1; letter-spacing: .02em;
}
:where(.qw-av, .seal40, .seal64, .hero-row .seal, .qm-cred .seal, .seated .seal).photo { background: var(--surface-2); }
:where(.qw-av, .seal40, .seal64, .hero-row .seal, .qm-cred .seal, .seated .seal) img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.seal64, .hero-row .seal, .qm-cred .seal { --av: 64px; }
.qw-av.lg { --av: 96px; }

/* ---- Loading skeletons, one look everywhere (Asa, 2026-11-02): grey shapes the size of what is coming, a slow pulse, none
   with reduced motion. .qw-skel is the class; the older .skel-block and .set-skel take the same rule (dash.css mirrors it). ---- */
:is(.qw-skel, .skel-block, .set-skel) { display: block; background: var(--surface-2); border-radius: 8px; animation: qw-skel 1.6s ease-in-out infinite; }
.qw-skel.line { height: 14px; }
.qw-skel.title { height: 28px; width: 45%; }
.qw-skel.short { width: 30%; }
.qw-skel.mid { width: 60%; }
.qw-skel.card { height: 184px; border-radius: 18px; }
.qw-skel.round { border-radius: 50%; }
.qw-skel-row { display: grid; grid-template-columns: 40px minmax(0, 1fr); gap: 16px; align-items: center; min-height: 64px; border-bottom: 1px solid var(--line); }
.qw-skel-row > .qw-skel.round { width: 40px; height: 40px; }
.qw-skel-row > div { display: grid; gap: 8px; }
.qw-skel-stack { display: grid; gap: 12px; }
@keyframes qw-skel { 50% { opacity: .5; } }
@media (prefers-reduced-motion: reduce) { :is(.qw-skel, .skel-block, .set-skel) { animation: none; } }
