/* ── Component library: Button · Input · Checkbox ──────────────────────────
   All three reusable components from the Vashor global library (🟢Lib-Vashor).
   Spec: docs/components.md. Tokens: tokens.css.
   Migrated from hero.css; hero.css now holds hero-layout only.
   ────────────────────────────────────────────────────────────────────────── */


/* ══════════════════════════════════════════════════════════════════════════
   BUTTON
   6 colors × 3 sizes × Default + Hover. No Active state.
   Icon slots via markup only (no icon-variant CSS classes).
   Left icon (SealCheck) hidden in master — never render.
   ══════════════════════════════════════════════════════════════════════════ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  border-radius: var(--btn-radius);
  border: none;
  cursor: pointer;
  font-family: var(--ff-mono);
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 200ms ease-out, color 200ms ease-out;
}

/* ── Color variants ── */

.btn--yellow { background-color: var(--btn-yellow-bg); color: var(--btn-yellow-text); }
.btn--yellow:hover { background-color: var(--btn-yellow-bg-hover); color: var(--btn-yellow-text-hover); }

.btn--black  { background-color: var(--btn-black-bg);  color: var(--btn-black-text); }
.btn--black:hover  { background-color: var(--btn-black-bg-hover);  color: var(--btn-black-text-hover); }

.btn--ys { background-color: var(--btn-ys-bg); color: var(--btn-ys-text); }
.btn--ys:hover { background-color: var(--btn-ys-bg-hover); color: var(--btn-ys-text-hover); }

.btn--bs { background-color: var(--btn-bs-bg); color: var(--btn-bs-text); }
.btn--bs:hover { background-color: var(--btn-bs-bg-hover); color: var(--btn-bs-text-hover); }

.btn--sy { background-color: var(--btn-sy-bg); color: var(--btn-sy-text); }
.btn--sy:hover { background-color: var(--btn-sy-bg-hover); color: var(--btn-sy-text-hover); }

.btn--sb { background-color: var(--btn-sb-bg); color: var(--btn-sb-text); }
.btn--sb:hover { background-color: var(--btn-sb-bg-hover); color: var(--btn-sb-text-hover); }

/* ── Size variants ── */

.btn--s {
  height: var(--btn-s-h);
  padding-inline: var(--btn-s-px);
  gap: var(--btn-s-gap);
  font-size: var(--t-btn-s-size);
  line-height: var(--t-btn-s-lh);
  letter-spacing: var(--t-btn-s-ls);
}
.btn--m {
  height: var(--btn-m-h);
  padding-inline: var(--btn-m-px);
  gap: var(--btn-m-gap);
  font-size: var(--t-btn-m-size);
  line-height: var(--t-btn-m-lh);
  letter-spacing: var(--t-btn-m-ls);
}
.btn--l {
  height: var(--btn-l-h);
  padding-inline: var(--btn-l-px);
  gap: var(--btn-l-gap);
  font-size: var(--t-btn-l-size);
  line-height: var(--t-btn-l-lh);
  letter-spacing: var(--t-btn-l-ls);
}

.btn__icon {
  flex-shrink: 0;
  display: block;
}
.btn--s .btn__icon { width: var(--btn-icon-s); height: var(--btn-icon-s); }
.btn--m .btn__icon { width: var(--btn-icon-m); height: var(--btn-icon-m); }
.btn--l .btn__icon { width: var(--btn-icon-l); height: var(--btn-icon-l); }

/* ── Disabled state ── */
.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: var(--opacity-disabled); /* 40% */
  cursor: not-allowed;
  pointer-events: none;
}


/* ══════════════════════════════════════════════════════════════════════════
   INPUT — floating-label pattern (no JS)
   HTML structure (no-icon variant used on landing):

     <label class="input input--l">
       <div class="input__field-wrap">
         <input class="input__field" type="email" placeholder=" " required>
         <span class="input__label">Work Email Address</span>
       </div>
       <span class="input__support">Error message</span>
     </label>

   .input is a flex-column wrapper (Field-wrap + Supporting as siblings in flow).
   .input__field-wrap is the visual Field box: border, bg, radius, height,
   position: relative (anchors floating label + ::after error icon).
   .input__support sits BELOW Field-wrap in normal flow — takes real space,
   so parent flex layouts preserve their gap when error appears.
   ══════════════════════════════════════════════════════════════════════════ */

.input {
  display: flex;
  flex-direction: column;
  gap: 4px;
  width: 100%;
  cursor: text;
}

/* ── Field box — holds native input + floating label + error icon.
   Carries border, background, radius, and per-size height. ── */
.input__field-wrap {
  position: relative;
  width: 100%;
  background: var(--input-bg);
  border: var(--input-border) solid var(--input-border-default);
  border-radius: var(--input-radius);
  transition: box-shadow 200ms ease-out, border-color 200ms ease-out;
}

/* Hover, Focus: 1px → 2px effective border via inset box-shadow.
   Real border-width stays 1px — no layout shift (same pattern as Checkbox hover). */
.input__field-wrap:hover {
  border-color: var(--input-border-hover);
  box-shadow: inset 0 0 0 1px var(--input-border-hover);
}
.input__field-wrap:focus-within {
  border-color: var(--input-border-focus);
  box-shadow: inset 0 0 0 1px var(--input-border-focus);
}
/* Error state — triggered manually via .input--error class
   (e.g. server-side errors) OR automatically via :user-invalid pseudo
   (browser tracks: user interacted, blurred, value still invalid).
   Same 2px effective border via inset box-shadow as Hover/Focus. */
.input--error .input__field-wrap,
.input:has(.input__field:user-invalid) .input__field-wrap {
  border-color: var(--input-border-error);
  box-shadow: inset 0 0 0 1px var(--input-border-error);
}

/* ── Size variants — height applies to Field-wrap, not the outer .input. ── */
.input--s .input__field-wrap { height: var(--input-s-h); }
.input--m .input__field-wrap { height: var(--input-m-h); }
.input--l .input__field-wrap { height: var(--input-l-h); }

/* ── Native input ── */
.input__field {
  display: block;
  width: 100%;
  height: 100%;
  background: transparent;
  border: none;
  outline: none;
  color: var(--input-text);
  font-family: var(--ff-mono);
  font-weight: 700;
}

.input--s .input__field {
  padding-inline: var(--input-s-px);
  /* pt = 2×(IV_center) − H = 2×30 − 48 = 12px, where IV_center = 9+11+10 = 30px */
  padding-top: 12px;
  font-size: var(--input-s-value-size);
  line-height: var(--input-s-value-lh);
}
.input--m .input__field {
  padding-inline: var(--input-m-px);
  /* pt = 2×(IV_center) − H = 2×38 − 64 = 12px, where IV_center = 14+12+12 = 38px */
  padding-top: 12px;
  font-size: var(--input-m-value-size);
  line-height: var(--input-m-value-lh);
}
.input--l .input__field {
  padding-inline: var(--input-l-px);
  /* pt = 2×(IV_center) − H = 2×47 − 80 = 14px, where IV_center = 20+14+13 = 47px */
  padding-top: 14px;
  font-size: var(--input-l-value-size);
  line-height: var(--input-l-value-lh);
}

/* ── Floating label ── */
.input__label {
  position: absolute;
  pointer-events: none;
  color: var(--input-label-color);
  font-family: var(--ff-mono);
  font-weight: 300; /* Label typeface = IBM Plex Mono Light */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  transition: top 0.12s ease, transform 0.12s ease,
              font-size 0.12s ease, line-height 0.12s ease;
}

/* Label at rest — centered vertically at value size */
.input--s .input__label {
  left: var(--input-s-px);
  right: var(--input-s-px);
  top: 50%;
  transform: translateY(-50%);
  font-size: var(--input-s-value-size);
  line-height: var(--input-s-value-lh);
}
.input--m .input__label {
  left: var(--input-m-px);
  right: var(--input-m-px);
  top: 50%;
  transform: translateY(-50%);
  font-size: var(--input-m-value-size);
  line-height: var(--input-m-value-lh);
}
.input--l .input__label {
  left: var(--input-l-px);
  right: var(--input-l-px);
  top: 50%;
  transform: translateY(-50%);
  font-size: var(--input-l-value-size);
  line-height: var(--input-l-value-lh);
}

/* Label floated — focus or filled (:not(:placeholder-shown) requires placeholder=" ")
   top = (H − label_lh − value_lh) / 2 so FL+IV pair is vertically centered in field:
   S: (48−11−20)/2 ≈ 9px · M: (64−12−24)/2 = 14px · L: (80−14−26)/2 = 20px          */
.input--s .input__field:focus          ~ .input__label,
.input--s .input__field:not(:placeholder-shown) ~ .input__label {
  top: 9px;
  transform: none;
  font-size: var(--input-s-label-size);
  line-height: var(--input-s-label-lh);
}
.input--m .input__field:focus          ~ .input__label,
.input--m .input__field:not(:placeholder-shown) ~ .input__label {
  top: 14px;
  transform: none;
  font-size: var(--input-m-label-size);
  line-height: var(--input-m-label-lh);
}
.input--l .input__field:focus          ~ .input__label,
.input--l .input__field:not(:placeholder-shown) ~ .input__label {
  top: 20px;
  transform: none;
  font-size: var(--input-l-label-size);
  line-height: var(--input-l-label-lh);
}

/* ── Supporting / error text — sits in normal flow below Field-wrap.
   No absolute positioning; takes real space so parent gap is preserved. ── */
.input__support {
  display: none;
  font-family: var(--ff-mono);
  font-weight: 700;
  color: var(--input-text);
  transition: opacity 200ms ease-out;
}
.input--s .input__support { padding-inline: var(--input-s-px); font-size: var(--input-s-label-size); line-height: var(--input-s-label-lh); }
.input--m .input__support { padding-inline: var(--input-m-px); font-size: var(--input-m-label-size); line-height: var(--input-m-label-lh); }
.input--l .input__support { padding-inline: var(--input-l-px); font-size: var(--input-l-label-size); line-height: var(--input-l-label-lh); }
.input--error .input__support,
.input:has(.input__field:user-invalid) .input__support {
  display: block;
  color: var(--input-support-error);
  opacity: 1;
}
/* @starting-style — initial value when element transitions FROM display:none to display:block.
   Browser uses this as the "from" state for the opacity transition on first render.
   Supported Chrome 117+, Firefox 129+, Safari 17.5+; gracefully degrades (instant show). */
@starting-style {
  .input--error .input__support,
  .input:has(.input__field:user-invalid) .input__support {
    opacity: 0;
  }
}

/* ── Error icon (X-Circle) — appears on right side of Field-wrap in Error state.
   Same trigger as border + supporting text: manual .input--error class OR
   automatic :user-invalid pseudo. The CSS-native glyph inherits the error color.
   Centered vertically via top: 50% on .input__field-wrap (its position context). ── */
.input--s { --input-error-icon-size: 20px; --input-error-icon-offset: var(--input-s-px); }
.input--m { --input-error-icon-size: 24px; --input-error-icon-offset: var(--input-m-px); }
.input--l { --input-error-icon-size: 26px; --input-error-icon-offset: var(--input-l-px); }

/* Always-present ::after — invisible by default; fades to opacity:1 on error.
   All styling defined here so the transition plays. Error state only sets opacity. */
.input__field-wrap::after {
  content: '×';
  position: absolute;
  right: var(--input-error-icon-offset, 14px);
  top: 50%;
  display: grid;
  place-items: center;
  transform: translateY(-50%);
  width: var(--input-error-icon-size, 20px);
  height: var(--input-error-icon-size, 20px);
  color: var(--input-border-error);
  font-family: var(--ff-display);
  font-size: var(--input-error-icon-size, 20px);
  font-weight: 700;
  line-height: 1;
  border: 1.5px solid currentColor;
  border-radius: 50%;
  pointer-events: none;
  opacity: 0;
  transition: opacity 200ms ease-out;
}

.input--error .input__field-wrap::after,
.input:has(.input__field:user-invalid) .input__field-wrap::after {
  opacity: 1;
}


/* ── Autofill quirk fix — Chrome/Safari ────────────────────────────────
   Browsers paint a non-overridable background (#eaf0fd-ish in Chrome 2026)
   on <input> when autofilling. Chrome's UA stylesheet uses !important on
   background-color, background-image, and color — direct overrides are
   ignored. Two-layer fix:
   (a) overflow: hidden on .input__field-wrap clips the autofill rectangle
       past the wrap's border-radius. Without it, the input element itself
       has no radius — its rectangular fill leaks past rounded corners
       regardless of any color override.
   (b) :-webkit-autofill / :autofill override repaints the background via
       inset box-shadow (the only mechanism that bypasses Chrome UA's
       !important), locks text and caret colors, and uses transition:
       background-color 9999s — Chrome only repaints the autofill bg "after"
       the transition completes, effectively suppressing the flash on focus.
       :is() makes the selector list forgiving: if a browser doesn't
       recognize one of the pseudo-classes the rule still applies.
   ─────────────────────────────────────────────────────────────────────── */

.input__field:is(:-webkit-autofill, :autofill),
.input__field:is(:-webkit-autofill, :autofill):hover,
.input__field:is(:-webkit-autofill, :autofill):focus,
.input__field:is(:-webkit-autofill, :autofill):active {
  -webkit-box-shadow: 0 0 0 1000px var(--input-bg) inset !important;
  -webkit-text-fill-color: var(--input-text) !important;
  caret-color: var(--input-text);
  border-radius: var(--input-radius);
  transition: background-color 9999s ease-in-out 0s;
}


/* ══════════════════════════════════════════════════════════════════════════
   CHECKBOX
   HTML structure:

     <label class="checkbox">
       <input class="checkbox__input" type="checkbox">
       <span class="checkbox__box"></span>
       <span class="checkbox__label">Label text</span>
     </label>

   Check icon via CSS mask-image on ::after (no inline SVG needed).
   ══════════════════════════════════════════════════════════════════════════ */

.checkbox {
  display: flex;
  align-items: flex-start;
  gap: var(--cb-gap);
  cursor: pointer;
}

/* Visually hidden but focusable native input */
.checkbox__input {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Styled box */
.checkbox__box {
  flex-shrink: 0;
  width: var(--cb-box);
  height: var(--cb-box);
  border-radius: var(--cb-radius);
  border: var(--cb-border) solid var(--cb-border-color);
  background: var(--cb-bg-off);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background-color 200ms ease-out, box-shadow 200ms ease-out, border-color 200ms ease-out;
}

/* Hover: border weight 1px → 2px via inset shadow (avoids layout shift) */
.checkbox:hover .checkbox__box {
  box-shadow: inset 0 0 0 1px var(--cb-border-color); /* total effective = 2px */
}

/* Check icon stays CSS-native so both root and /v2 static exports work
   without a basePath-dependent asset URL. */
.checkbox__box::after {
  content: '✓';
  display: grid;
  place-items: center;
  width: var(--cb-icon);
  height: var(--cb-icon);
  color: var(--cb-check);
  font-family: var(--ff-display);
  font-size: var(--cb-icon);
  font-weight: 700;
  line-height: 1;
  opacity: 0;
  transition: opacity 200ms ease-out;
}

.checkbox__input:checked + .checkbox__box {
  background-color: var(--cb-bg-on);
}
.checkbox__input:checked + .checkbox__box::after {
  opacity: 1;
}

/* Keyboard focus ring on the box (native input is hidden) */
.checkbox__input:focus-visible + .checkbox__box {
  outline: 2px solid var(--color-accent-4);
  outline-offset: 2px;
}

.checkbox__label {
  flex: 1 0 0;
  min-width: 0;
  color: var(--cb-label-color);
  font-family: var(--ff-mono);
  font-weight: 400;
  font-size: var(--t-caption-size);
  line-height: var(--t-caption-lh);
  letter-spacing: var(--t-caption-ls);
}


/* ══════════════════════════════════════════════════════════════════════════
   MOBILE ≤767 — L → M size swap for Button and Input
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Reduced motion — disable all component state transitions ──────────────
   Animations in animations.css reset there; this covers Button/Input/Checkbox.
   ─────────────────────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .btn,
  .input__field-wrap,
  .input__field-wrap::after,
  .input__label,
  .input__support,
  .checkbox__box,
  .checkbox__box::after {
    transition: none;
  }
}


@media (max-width: 767px) {
  /* Button L → M */
  .btn--l {
    height: var(--btn-m-h);
    padding-inline: var(--btn-m-px);
    gap: var(--btn-m-gap);
    font-size: var(--t-btn-m-size);
    line-height: var(--t-btn-m-lh);
    letter-spacing: var(--t-btn-m-ls);
  }
  .btn--l .btn__icon {
    width: var(--btn-icon-m);
    height: var(--btn-icon-m);
  }

  /* Input L → M */
  .input--l .input__field-wrap {
    height: var(--input-m-h);
  }
  .input--l {
    --input-error-icon-size: 24px;
    --input-error-icon-offset: var(--input-m-px);
  }

  .input--l .input__field {
    padding-inline: var(--input-m-px);
    padding-top: 12px; /* M value: 2×38 − 64 */
    font-size: var(--input-m-value-size);
    line-height: var(--input-m-value-lh);
  }
  .input--l .input__label {
    left: var(--input-m-px);
    right: var(--input-m-px);
    font-size: var(--input-m-value-size);
    line-height: var(--input-m-value-lh);
  }
  .input--l .input__field:focus ~ .input__label,
  .input--l .input__field:not(:placeholder-shown) ~ .input__label {
    top: 14px; /* M value: (64−12−24)/2 */
    font-size: var(--input-m-label-size);
    line-height: var(--input-m-label-lh);
  }
  .input--l .input__support {
    padding-inline: var(--input-m-px);
    font-size: var(--input-m-label-size);
    line-height: var(--input-m-label-lh);
  }
}
