/* ui-signals: feedback and state animations for hand-written sites.
   Dependency free. Link after the project's own stylesheet.
   Set the first three tokens from the project's palette before shipping.
   Every signal is opt-in by class or data attribute; nothing here is global
   except the tokens. Recipes and placement rules: references/catalogue.md */

:root {
  --sig-accent: #8fd9a8;   /* Finn Cowan: mint on forest green */
  --sig-danger: #ff6b5e;
  --sig-surface: #143020;

  --sig-ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --sig-ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --sig-dur-press: 120ms;
  --sig-dur-state: 150ms;
  --sig-dur-enter: 220ms;
  --sig-dur-reveal: 400ms;
  --sig-dur-count: 2000ms;  /* Byron: numbers must load much slower than the rest, never under 2s */
  --sig-dur-hold: 600ms;    /* danger-confirm hold. The source reel used 300ms; on a phone that is a slow tap, so 600 */
  --sig-dur-sweep: 640ms;   /* auth-sweep travel. The two forms trade places at half, under the band */

  /* auth-sweep card. Set the five colours from the site's palette; the demo shows the reel's green and gold */
  --sig-auth-rake: 12deg;
  --sig-auth-band: 1.5;     /* band width as a multiple of the card. Wider than 1 so it covers the whole card for the middle fifth of the travel */
  --sig-auth-card: #f4efe6;
  --sig-auth-ink: #16201b;
  --sig-auth-band-bg: var(--sig-surface);
  --sig-auth-band-ink: #f4efe6;
  --sig-auth-seam: var(--sig-accent);

  --sig-accent-soft: color-mix(in srgb, var(--sig-accent) 22%, transparent);
  --sig-accent-faint: color-mix(in srgb, var(--sig-accent) 10%, transparent);
  --sig-danger-soft: color-mix(in srgb, var(--sig-danger) 18%, transparent);
  --sig-line: color-mix(in srgb, currentColor 14%, transparent);
  --sig-line-strong: color-mix(in srgb, currentColor 26%, transparent);
}

/* ------------------------------------------------------------------ */
/* copy-swap: one container, several [data-when] children, JS marks one
   .is-on. Old copy fades down, new copy rises in. Used by the dropzone. */

.sig-swap { display: grid; }
.sig-swap > [data-when] {
  grid-area: 1 / 1;
  opacity: 0;
  transform: translateY(4px);
  pointer-events: none;
  transition: opacity var(--sig-dur-state) var(--sig-ease-out),
              transform var(--sig-dur-state) var(--sig-ease-out);
}
.sig-swap > [data-when].is-on {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}

/* ------------------------------------------------------------------ */
/* state-glow: a soft radial behind the one element that is live.
   JS (Signals.glow) removes it from everything else first. */

.sig-glow { position: relative; isolation: isolate; }
.sig-glow::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: radial-gradient(60% 70% at 50% 50%, var(--sig-accent-soft), transparent 72%);
  opacity: 0;
  transition: opacity var(--sig-dur-state) var(--sig-ease-out);
  pointer-events: none;
}
.sig-glow.is-active::before,
.sig-glow[data-state="over"]::before,
.sig-glow[data-state="active"]::before { opacity: 1; }

/* ------------------------------------------------------------------ */
/* drop-answer: the dropzone answers a drag with border, glow and copy. */

.sig-dropzone {
  position: relative;
  border: 1.5px dashed var(--sig-line-strong);
  border-radius: 14px;
  background: var(--sig-surface);
  overflow: hidden;
  transition: border-color var(--sig-dur-state) var(--sig-ease-out);
}
.sig-dropzone[data-state="over"] { border-color: var(--sig-accent); }
.sig-dropzone .sig-icon {
  display: inline-block;
  transition: transform var(--sig-dur-state) var(--sig-ease-out), color var(--sig-dur-state) var(--sig-ease-out);
}
.sig-dropzone[data-state="over"] .sig-icon { transform: translateY(-3px); color: var(--sig-accent); }

/* ------------------------------------------------------------------ */
/* honest-progress: percent, time left, rate. Bar moves with scaleX on a
   linear curve. Never animate width. */

.sig-progress { --p: 0; }
.sig-progress-pct {
  font-variant-numeric: tabular-nums;
  color: var(--sig-accent);
  transition: color var(--sig-dur-state) var(--sig-ease-out);
}
.sig-bar {
  height: 4px;
  border-radius: 99px;
  background: var(--sig-line);
  overflow: hidden;
}
.sig-bar-fill {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--sig-accent);
  transform-origin: left center;
  transform: scaleX(var(--p));
  transition: transform 200ms linear, background-color var(--sig-dur-state) var(--sig-ease-out);
}
.sig-progress-meta {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  font-variant-numeric: tabular-nums;
}
.sig-progress-meta > span {
  opacity: 0;
  transform: translateY(4px);
  transition: opacity var(--sig-dur-enter) var(--sig-ease-out), transform var(--sig-dur-enter) var(--sig-ease-out);
}
.sig-progress-meta > span.is-on { opacity: 1; transform: none; }
.sig-progress[data-state="error"] .sig-progress-pct { color: var(--sig-danger); }
.sig-progress[data-state="error"] .sig-bar-fill { background: var(--sig-danger); }
.sig-progress[data-state="done"] .sig-bar-fill { background: var(--sig-accent); }

/* ------------------------------------------------------------------ */
/* inline-retry: the error row grows in under the bar. The file stays.
   Height via grid-template-rows is the one sanctioned height animation. */

.sig-retry-row {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--sig-dur-enter) var(--sig-ease-out);
}
.sig-retry-row > * {
  min-height: 0;
  overflow: hidden;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity var(--sig-dur-enter) var(--sig-ease-out), transform var(--sig-dur-enter) var(--sig-ease-out);
}
.sig-progress[data-state="error"] .sig-retry-row { grid-template-rows: 1fr; }
.sig-progress[data-state="error"] .sig-retry-row > * { opacity: 1; transform: none; }
.sig-retry-card {
  border: 1px solid var(--sig-danger-soft);
  background: color-mix(in srgb, var(--sig-danger) 8%, transparent);
  border-radius: 10px;
}

/* ------------------------------------------------------------------ */
/* upload-preview: the card that replaces "filename uploaded". */

.sig-preview {
  opacity: 0;
  transform: translateY(8px);
  transition: opacity var(--sig-dur-enter) var(--sig-ease-out), transform var(--sig-dur-enter) var(--sig-ease-out);
}
.sig-preview.is-in { opacity: 1; transform: none; }
.sig-preview .sig-thumb {
  background: linear-gradient(135deg, var(--sig-accent-soft), var(--sig-accent-faint));
  border-radius: 10px;
}
.sig-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 8px;
  border-radius: 6px;
  border: 1px solid var(--sig-accent-soft);
  color: var(--sig-accent);
  font-size: 0.75em;
  letter-spacing: 0.02em;
}

/* ------------------------------------------------------------------ */
/* own-lane-queue: each row owns its bar. The counter is plain text. */

.sig-queue-item { --p: 0; }
.sig-queue-item .sig-queue-pct {
  font-variant-numeric: tabular-nums;
  transition: opacity var(--sig-dur-state) var(--sig-ease-out);
}
.sig-queue-item[data-state="done"] .sig-queue-pct { opacity: 0; }
.sig-queue-item .sig-tick-wrap {
  opacity: 0;
  transition: opacity var(--sig-dur-state) var(--sig-ease-out);
}
.sig-queue-item[data-state="done"] .sig-tick-wrap { opacity: 1; }
.sig-queue-item[data-state="error"] .sig-bar-fill { background: var(--sig-danger); }
.sig-queue-item[data-state="error"] .sig-queue-pct { color: var(--sig-danger); }

/* ------------------------------------------------------------------ */
/* press: buttons and button-styled links only. */

.sig-press {
  transition: transform var(--sig-dur-press) var(--sig-ease-out),
              background-color var(--sig-dur-state) var(--sig-ease-out),
              border-color var(--sig-dur-state) var(--sig-ease-out);
}
.sig-press:active { transform: scale(0.97); }

/* ------------------------------------------------------------------ */
/* focus-glow: text inputs only. The ring replaces the outline, it does
   not remove focus visibility. */

.sig-focus {
  transition: border-color var(--sig-dur-state) var(--sig-ease-out),
              box-shadow var(--sig-dur-state) var(--sig-ease-out);
}
.sig-focus:focus-visible {
  outline: none;
  border-color: var(--sig-accent);
  box-shadow: 0 0 0 4px var(--sig-accent-soft);
}

/* ------------------------------------------------------------------ */
/* submit-states: idle, loading, done, error. Width is locked by JS so
   the button never jumps. Label, spinner and tick share one grid cell. */

.sig-submit { position: relative; }
.sig-submit .sig-submit-stack { display: grid; place-items: center; }
.sig-submit .sig-submit-stack > * {
  grid-area: 1 / 1;
  transition: opacity var(--sig-dur-state) var(--sig-ease-out), transform var(--sig-dur-state) var(--sig-ease-out);
}
.sig-submit .sig-submit-label { opacity: 1; }
.sig-submit .sig-spinner,
.sig-submit .sig-submit-done,
.sig-submit .sig-submit-error { opacity: 0; transform: translateY(4px); }
.sig-submit[data-state="loading"] .sig-submit-label,
.sig-submit[data-state="done"] .sig-submit-label,
.sig-submit[data-state="error"] .sig-submit-label { opacity: 0; transform: translateY(-4px); }
.sig-submit[data-state="loading"] .sig-spinner,
.sig-submit[data-state="done"] .sig-submit-done,
.sig-submit[data-state="error"] .sig-submit-error { opacity: 1; transform: none; }
.sig-submit[data-state="error"] {
  animation: sig-shake 300ms var(--sig-ease-out);
  background: var(--sig-danger);
  border-color: var(--sig-danger);
}
.sig-submit[data-state="loading"] { cursor: progress; }
@keyframes sig-shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-3px); }
  75% { transform: translateX(3px); }
}

/* spinner: a ring. Constant motion, linear. */
.sig-spinner {
  width: 1.1em;
  height: 1.1em;
  border-radius: 50%;
  border: 2px solid color-mix(in srgb, currentColor 30%, transparent);
  border-top-color: currentColor;
  animation: sig-spin 700ms linear infinite;
}
@keyframes sig-spin { to { transform: rotate(360deg); } }

/* ------------------------------------------------------------------ */
/* field-error: the message grows under the field. Only that field. */

.sig-field .sig-field-msg {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--sig-dur-enter) var(--sig-ease-out);
}
.sig-field .sig-field-msg > * {
  min-height: 0;
  overflow: hidden;
  color: var(--sig-danger);
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity var(--sig-dur-enter) var(--sig-ease-out), transform var(--sig-dur-enter) var(--sig-ease-out);
}
.sig-field[data-state="error"] .sig-field-msg { grid-template-rows: 1fr; }
.sig-field[data-state="error"] .sig-field-msg > * { opacity: 1; transform: none; }
.sig-field[data-state="error"] .sig-focus { border-color: var(--sig-danger); }
.sig-field[data-state="error"] .sig-focus:focus-visible { box-shadow: 0 0 0 4px var(--sig-danger-soft); }

/* ------------------------------------------------------------------ */
/* tick-draw: a checkmark that draws itself on success. */

.sig-tick { overflow: visible; }
.sig-tick .sig-tick-path {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 24;
  stroke-dashoffset: 24;
  transition: stroke-dashoffset 300ms var(--sig-ease-out) 60ms;
}
.sig-tick .sig-tick-ring {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  opacity: 0.6;
  transform: scale(0.9);
  transform-origin: center;
  transition: transform var(--sig-dur-enter) var(--sig-ease-out);
}
.sig-tick.is-on .sig-tick-path,
.is-in .sig-tick .sig-tick-path,
.is-on .sig-tick .sig-tick-path,
[data-state="done"] .sig-tick .sig-tick-path { stroke-dashoffset: 0; }
.sig-tick.is-on .sig-tick-ring,
.is-in .sig-tick .sig-tick-ring,
.is-on .sig-tick .sig-tick-ring,
[data-state="done"] .sig-tick .sig-tick-ring { transform: none; }

/* ------------------------------------------------------------------ */
/* toast: enters from the bottom, leaves the same way. Transition, not
   keyframes, so a second toast retargets instead of restarting. */

.sig-toast {
  position: fixed;
  left: 50%;
  bottom: 24px;
  transform: translate(-50%, 16px);
  opacity: 0;
  pointer-events: none;
  transition: transform var(--sig-dur-enter) var(--sig-ease-out), opacity var(--sig-dur-enter) var(--sig-ease-out);
  z-index: 50;
}
.sig-toast.is-on { transform: translate(-50%, 0); opacity: 1; pointer-events: auto; }
.sig-toast[data-kind="error"] { border-color: var(--sig-danger-soft); }

/* ------------------------------------------------------------------ */
/* chip-stagger: tags arrive in sequence, once, when the list enters view.
   JS sets --i on each child. */

.sig-chips > * {
  opacity: 0;
  transform: translateY(6px);
  transition: opacity var(--sig-dur-enter) var(--sig-ease-out), transform var(--sig-dur-enter) var(--sig-ease-out);
  transition-delay: calc(var(--i, 0) * 40ms);
}
.sig-chips.is-in > * { opacity: 1; transform: none; }

/* ------------------------------------------------------------------ */
/* headline-emphasis: the hero H1 settles, then one phrase takes the
   accent. Once per load. Wrap the phrase in <em>. */

[data-sig-headline] {
  opacity: 0;
  transform: translateY(8px);
  transition: opacity var(--sig-dur-reveal) var(--sig-ease-out), transform var(--sig-dur-reveal) var(--sig-ease-out);
}
[data-sig-headline] em {
  font-style: normal;
  color: inherit;
  transition: color var(--sig-dur-reveal) var(--sig-ease-out) 350ms;
}
[data-sig-headline].is-in { opacity: 1; transform: none; }
[data-sig-headline].is-in em { color: var(--sig-accent); }

/* ------------------------------------------------------------------ */
/* section-reveal: below-fold sections only. JS refuses above-fold ones. */

[data-sig-reveal] {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity var(--sig-dur-reveal) var(--sig-ease-out), transform var(--sig-dur-reveal) var(--sig-ease-out);
}
[data-sig-reveal].is-in { opacity: 1; transform: none; }

/* ------------------------------------------------------------------ */
/* card-lift: clickable cards, hover gated. */

@media (hover: hover) and (pointer: fine) {
  .sig-card {
    transition: transform var(--sig-dur-state) var(--sig-ease-out),
                box-shadow var(--sig-dur-state) var(--sig-ease-out),
                border-color var(--sig-dur-state) var(--sig-ease-out);
  }
  .sig-card:hover {
    transform: translateY(-2px);
    border-color: var(--sig-line-strong);
    box-shadow: 0 10px 30px -12px color-mix(in srgb, #000 60%, transparent);
  }
}

/* ------------------------------------------------------------------ */
/* nav-underline: grows from the left on hover, stays on the active link. */

.sig-nav a { position: relative; text-decoration: none; }
.sig-nav a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -4px;
  height: 1.5px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 180ms var(--sig-ease-out);
}
.sig-nav a[aria-current="page"]::after { transform: scaleX(1); }
@media (hover: hover) and (pointer: fine) {
  .sig-nav a:hover::after { transform: scaleX(1); }
}

/* ------------------------------------------------------------------ */
/* count-up: stats only. JS animates the number; CSS keeps it steady. */

[data-sig-count] { font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------------ */
/* skeleton: for content that arrives after first paint. */

.sig-skeleton {
  position: relative;
  overflow: hidden;
  border-radius: 8px;
  background: var(--sig-line);
  color: transparent;
}
.sig-skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, currentColor 10%, transparent), transparent);
  transform: translateX(-100%);
  animation: sig-shimmer 1.4s linear infinite;
}
@keyframes sig-shimmer { to { transform: translateX(100%); } }

/* ------------------------------------------------------------------ */
/* danger-confirm: hold to delete. The ring is the confirmation; release
   early and nothing fires. JS drives --hold from 0 to 1 over
   --sig-dur-hold. Red lives here and in .sig-danger-zone and nowhere else. */

@property --hold { syntax: "<number>"; inherits: true; initial-value: 0; }
.sig-hold {
  --hold: 0;
  --hold-dur: 0ms;
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px 10px 12px;
  border: 1px solid var(--sig-danger-soft);
  border-radius: 12px;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  touch-action: none;
  transition: --hold var(--hold-dur) linear,
              border-color var(--sig-dur-state) var(--sig-ease-out),
              background-color var(--sig-dur-state) var(--sig-ease-out);
}
.sig-hold-ring {
  position: relative;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: conic-gradient(var(--sig-danger) calc(var(--hold) * 360deg), var(--sig-danger-soft) 0);
  display: grid;
  place-items: center;
}
.sig-hold-ring::after {
  content: "";
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--sig-surface);
}
.sig-hold-ring > svg {
  position: absolute;
  width: 12px;
  height: 12px;
  color: var(--sig-danger);
}
.sig-hold-label { display: grid; line-height: 1.2; }
.sig-hold-label small { opacity: 0.6; font-size: 0.8em; }
.sig-hold-pct { margin-left: auto; opacity: 0.5; font-variant-numeric: tabular-nums; font-size: 0.85em; }
.sig-hold[data-state="holding"] { border-color: var(--sig-danger); background: var(--sig-danger-soft); }
.sig-hold[data-state="done"] { border-color: var(--sig-danger); background: var(--sig-danger); color: #fff; }
.sig-hold[data-state="done"] .sig-hold-ring::after { background: var(--sig-danger); }
.sig-hold[data-state="done"] .sig-hold-ring > svg { color: #fff; }
.sig-hold:focus-visible { outline: 2px solid var(--sig-danger); outline-offset: 2px; }

/* danger zone: bordered, labelled, last on the page. Geography is friction. */
.sig-danger-zone {
  border: 1px solid var(--sig-danger-soft);
  border-radius: 14px;
  padding: 16px;
  margin-top: 48px;
}
.sig-danger-zone > h2,
.sig-danger-zone > h3 {
  margin: 0 0 4px;
  font-size: 0.8em;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sig-danger);
}
.sig-danger-zone .sig-hold { margin-top: 12px; }

/* ------------------------------------------------------------------ */
/* empty-state: why it is empty, what to do next, never looks broken.
   One rise on entry. Copy does the work; the motion just says "on purpose". */

.sig-empty {
  display: grid;
  justify-items: center;
  text-align: center;
  gap: 8px;
  padding: 40px 24px;
  border: 1px dashed var(--sig-line);
  border-radius: 14px;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity var(--sig-dur-enter) var(--sig-ease-out),
              transform var(--sig-dur-enter) var(--sig-ease-out);
}
.sig-empty.is-on { opacity: 1; transform: none; }
.sig-empty > .sig-icon { width: 36px; height: 36px; opacity: 0.55; }
.sig-empty > h3 { margin: 4px 0 0; font-size: 1.05em; }
.sig-empty > p { margin: 0; opacity: 0.7; max-width: 36ch; }
.sig-empty > .sig-empty-cta { margin-top: 8px; }
.sig-empty[data-kind="achievement"] { border-style: solid; border-color: var(--sig-accent-soft); background: var(--sig-accent-faint); }
.sig-empty[data-kind="achievement"] > .sig-icon { opacity: 1; color: var(--sig-accent); }
.sig-empty[data-kind="search"] > p > a { color: var(--sig-accent); text-decoration: underline; text-underline-offset: 2px; }

/* first-run checklist: the gamified steps. Fill moves with scaleX. */
.sig-empty-steps { --p: 0; width: 100%; max-width: 360px; margin-top: 12px; text-align: left; }
.sig-empty-steps > .sig-bar { margin-bottom: 10px; }
.sig-empty-steps > ol { margin: 0; padding: 0 0 0 20px; display: grid; gap: 4px; }
.sig-empty-steps > ol > li[data-done] { opacity: 0.5; text-decoration: line-through; }

/* ------------------------------------------------------------------ */
/* auth-sweep: login and sign-up on one card, swapped by one raked band.
   The band is a window (overflow hidden) over a fixed brand layer: its
   inner counter-transform puts that layer back in card co-ordinates, so
   the copy under it never skews. The band is wider than the card, so at
   mid-travel it covers all of it, and that is where the two forms trade
   places. Transform and opacity only, no fade between states.
   From Code & Chill, Verso component 91 (references/source-reel.md). */

.sig-auth {
  --sweep: 0%;
  position: relative;
  overflow: hidden;
  isolation: isolate;
  min-height: 440px;
  border-radius: 18px;
  background: var(--sig-auth-card);
  color: var(--sig-auth-ink);
}
.sig-auth[data-mode="signup"] { --sweep: -100%; }

.sig-auth-band {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: calc(var(--sig-auth-band) * 100%);
  overflow: hidden;
  z-index: 2;
  background: var(--sig-auth-band-bg);
  color: var(--sig-auth-band-ink);
  transform: skewX(var(--sig-auth-rake)) translateX(var(--sweep));
  transition: transform var(--sig-dur-sweep) var(--sig-ease-in-out);
  will-change: transform;
}
.sig-auth-band-inner {
  position: absolute;
  inset: 0;
  transform: translateX(calc(-1 * var(--sweep))) skewX(calc(-1 * var(--sig-auth-rake)));
  transition: transform var(--sig-dur-sweep) var(--sig-ease-in-out);
}
.sig-auth-band-page {
  position: absolute;
  top: 0;
  bottom: 0;
  width: calc(100% / var(--sig-auth-band));
  left: calc(-50% / var(--sig-auth-band));
}
.sig-auth-seam {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 2px;
  z-index: 1;
  background: linear-gradient(180deg, transparent 0%, var(--sig-auth-seam) 18%, var(--sig-auth-seam) 82%, transparent 100%);
  box-shadow: 0 0 14px color-mix(in srgb, var(--sig-auth-seam) 55%, transparent);
}
.sig-auth-seam[data-edge="lead"] { left: 0; }
.sig-auth-seam[data-edge="trail"] { right: 0; }

.sig-auth-brand {
  position: absolute;
  top: 50%;
  width: 38%;
  padding: 0 6%;
  transform: translateY(-50%);
}
.sig-auth-brand[data-side="right"] { right: 0; }
.sig-auth-brand[data-side="left"] { left: 0; }
.sig-auth-brand > small { display: block; margin: 0 0 14px; font-size: 11px; letter-spacing: 0.22em; text-transform: uppercase; color: var(--sig-auth-seam); }
.sig-auth-brand > h3 { margin: 0 0 12px; font: 400 34px/1.1 Georgia, "Times New Roman", serif; letter-spacing: -0.01em; }
.sig-auth-brand > h3 em { font-style: italic; color: var(--sig-auth-seam); }
.sig-auth-brand > p { margin: 0; font-size: 14px; line-height: 1.5; opacity: 0.8; }

.sig-auth-pane {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 50%;
  z-index: 1;
  display: grid;
  align-content: center;
  padding: 36px 8%;
  margin: 0;
  opacity: 0;              /* no transition on purpose: the swap happens under the band */
  visibility: hidden;
}
.sig-auth-pane.is-on { opacity: 1; visibility: visible; }
.sig-auth-pane[data-mode="signin"] { left: 0; }
.sig-auth-pane[data-mode="signup"] { right: 0; }

/* one column: the band starts fully off the right edge (the rake leans in by
   half the card height times tan(rake), so it parks at 120%), wipes the whole
   card and leaves off the left. The brand copy steps aside. */
@media (max-width: 640px) {
  .sig-auth { --sig-auth-band: 2; --sig-auth-rake: 8deg; min-height: 0; }
  .sig-auth-band { left: 120%; }
  .sig-auth[data-mode="signup"] { --sweep: -170%; } /* band width 2, so the covered window is again the middle fifth */
  .sig-auth-band-page { width: calc(100% / var(--sig-auth-band)); left: calc(-120% / var(--sig-auth-band)); }
  .sig-auth-brand { display: none; }
  .sig-auth-pane { position: relative; width: 100%; padding: 28px 22px; }
  .sig-auth-pane:not(.is-on) { display: none; }
}

/* ------------------------------------------------------------------ */
/* reduced motion: keep colour and opacity, drop movement. Not zero. */

@media (prefers-reduced-motion: reduce) {
  .sig-swap > [data-when],
  .sig-progress-meta > span,
  .sig-retry-row > *,
  .sig-field .sig-field-msg > *,
  .sig-preview,
  .sig-chips > *,
  [data-sig-headline],
  [data-sig-reveal],
  .sig-toast,
  .sig-empty,
  .sig-submit .sig-submit-stack > * { transform: none !important; transition-duration: 1ms !important; transition-delay: 0ms !important; }
  .sig-press:active,
  .sig-card:hover,
  .sig-dropzone[data-state="over"] .sig-icon { transform: none; }
  .sig-submit[data-state="error"] { animation: none; }
  .sig-skeleton::after { animation: none; }
  .sig-bar-fill { transition-duration: 1ms; }
  .sig-tick .sig-tick-path { transition-duration: 1ms; stroke-dashoffset: 0; }
  .sig-tick .sig-tick-ring { transform: none; }
  .sig-hold { transition-duration: 1ms; } /* ring jumps to full at confirm; the timer still takes the full hold */
  .sig-auth-band, .sig-auth-band-inner { transition-duration: 1ms; } /* the band jumps; the transform itself must stay, it is the layout */
}
