/* Vendored Cylinder design tokens. See ./README.md before editing. */

:root {
  /* background.page */
  --color-page: #f6f7f4;
  /* background.surface.primary */
  --color-surface: #ffffff;

  /* border.input.default */
  --color-border: #dcddd3;
  /* border.input.focused */
  --color-border-focus: #000000;
  /* border.input.error */
  --color-border-error: #cd3824;

  /* text.strong */
  --color-text-strong: #000000;
  /* text.default */
  --color-text-default: #363636;
  /* text.subtle, also text.input.placeholder */
  --color-text-subtle: #666666;

  /* background.action.default */
  --color-action-bg: #ff7d4d;
  /* background.action.hover */
  --color-action-bg-hover: #ff5c21;
  /* background.action.disabled */
  --color-action-bg-disabled: #a9a9a9;
  /* text.action.default -- black label on the orange fill, not white */
  --color-action-text: #000000;
  /* text.action.disabledOnFill */
  --color-action-text-disabled: #ffffff;

  /* palette.red.100 */
  --color-error-surface: #fae7e8;
  /* text.error */
  --color-error-text: #7c1d10;
  /* palette.green.100 */
  --color-success-surface: #f4fcf2;
  /* text.success */
  --color-success-text: #194711;

  /* radius.radius3 */
  --radius-input: 12px;
  /* radius.radius4 */
  --radius-card: 16px;
  /* radius.radiusFull */
  --radius-pill: 999px;
}

/*
 * PP Neue Montreal, vendored. Only the two weights this page uses.
 * `font-display: swap` is deliberate -- see ./README.md.
 */
@font-face {
  font-family: "PP Neue Montreal";
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  src: url(assets/PPNeueMontreal-Regular.37c2c7c3b4643502f5db.woff2) format("woff2");
}

@font-face {
  font-family: "PP Neue Montreal";
  font-weight: 500;
  font-style: normal;
  font-display: swap;
  src: url(assets/PPNeueMontreal-Medium.832351e3e033a5b328e6.woff2) format("woff2");
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  padding: 20px;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-page);
  /* The fallback matters: without one, a failed font fetch drops to serif. */
  font-family: "PP Neue Montreal", sans-serif;
  font-size: 1rem;
  line-height: 1.5rem;
  font-weight: 400;
  color: var(--color-text-default);
  -webkit-font-smoothing: antialiased;
}

.card {
  width: 450px;
  padding: 24px 16px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-card);
}

@media (max-width: 520px) {
  .card {
    width: calc(100% - 20px);
  }
}

.logo {
  display: block;
  margin: 0 auto 24px;
  color: var(--color-text-strong);
}

.title {
  margin: 0 0 8px;
  font-size: 1.25rem;
  line-height: 1.5rem;
  font-weight: 500;
  color: var(--color-text-strong);
}

.instruction {
  margin: 0 0 4px;
}

.email {
  margin: 0 0 24px;
  font-weight: 500;
  color: var(--color-text-strong);
  /* A long address must not widen the card or spill outside it. */
  overflow-wrap: break-word;
}

/*
 * Clipped rather than display:none or the hidden attribute. The element keeps
 * layout, which is what password managers look for when deciding whether a form
 * has a username; display:none would drop it from their heuristics entirely.
 */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.field {
  margin-bottom: 16px;
}

.field > label {
  display: block;
  margin-bottom: 4px;
  font-size: 0.75rem;
  line-height: 1rem;
  font-weight: 500;
  color: var(--color-text-strong);
}

.field-hint {
  margin: 0 0 4px;
  font-size: 0.875rem;
  line-height: 1.25rem;
  color: var(--color-text-subtle);
}

.input-group {
  display: flex;
  /* stretch, so the reveal button matches the input's height and clears the
     44px minimum touch target without being sized separately. */
  align-items: stretch;
  gap: 8px;
}

.input-group > input {
  /*
   * min-width overrides the flex default of auto, which refuses to shrink an
   * item below its content width and would push the button out of the card on a
   * narrow screen.
   */
  flex: 1;
  min-width: 0;
}

.reveal {
  flex: none;
  min-width: 44px;
  padding: 0 12px;
  font: inherit;
  font-weight: 500;
  color: var(--color-text-strong);
  background: none;
  /* Invisible normally, but forced-colors mode gives it a system colour, so the
     button keeps a discernible shape when backgrounds are stripped. */
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: underline;
}

.reveal:focus-visible {
  outline: 2px solid var(--color-border-focus);
  outline-offset: 2px;
}

.field input {
  width: 100%;
  padding: 12px;
  font: inherit;
  color: var(--color-text-default);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-input);
}

.field input::placeholder {
  color: var(--color-text-subtle);
}

/* The token border change is only 1px, so the outline carries the indicator. */
.field input:focus-visible {
  border-color: var(--color-border-focus);
  outline: 2px solid var(--color-border-focus);
  outline-offset: 1px;
}

/* Keyed off aria-invalid so visual and assistive states cannot disagree. */
.field input[aria-invalid="true"] {
  border-color: var(--color-border-error);
}

/*
 * The alert regions stay in the DOM, rendered and empty, so a screen reader has
 * a live region to observe before any message exists. Box metrics are applied
 * only via :not(:empty) rather than collapsing with display:none -- a hidden
 * element is absent from the accessibility tree, and re-inserting a live region
 * is less reliably announced than mutating a present one. An empty block has
 * zero height, so this costs no layout. The logic layer only sets textContent.
 */
.field-error {
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.25rem;
  color: var(--color-error-text);
}

.field-error:not(:empty) {
  margin-top: 4px;
}

.form-message {
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.25rem;
}

.form-message:not(:empty) {
  margin-bottom: 16px;
  padding: 12px;
  border-radius: var(--radius-input);
}

/*
 * The logic layer moves focus here when the form is hidden, so a sighted
 * keyboard user needs to see where focus landed. :focus-visible rather than
 * :focus keeps the ring off a plain mouse click -- tabindex="-1" elements are
 * click-focusable, and a ring on clicked text reads as a rendering bug.
 */
.form-message:focus-visible {
  outline: 2px solid var(--color-border-focus);
  outline-offset: 2px;
}

.form-message.is-error {
  background: var(--color-error-surface);
  color: var(--color-error-text);
}

.form-message.is-success {
  background: var(--color-success-surface);
  color: var(--color-success-text);
}

.submit {
  width: 100%;
  padding: 12px 24px;
  font: inherit;
  font-weight: 500;
  /* Explicit so a future reset stylesheet cannot uppercase the label. */
  text-transform: none;
  color: var(--color-action-text);
  background: var(--color-action-bg);
  border: none;
  border-radius: var(--radius-pill);
  cursor: pointer;
}

.submit:hover:not(:disabled) {
  background: var(--color-action-bg-hover);
}

.submit:focus-visible {
  outline: 2px solid var(--color-border-focus);
  outline-offset: 2px;
}

.submit:disabled {
  color: var(--color-action-text-disabled);
  background: var(--color-action-bg-disabled);
  cursor: default;
}

