/* HYP waitlist.
   Colors are the Undefeated v2 Figma variables (Color collection, Dark mode),
   with sRGB fallbacks first and the file's Display P3 values where supported.
   Type sizes are the file's text styles: Title 22/28, Headline and Body 17/22,
   Caption 13/18. Layout follows the Turf measurements in notes/turf-reference.md. */

:root {
  color-scheme: dark;

  --bg-page: #050506;          /* bg/page, neutral/950 */
  --text-primary: #f4f4f7;     /* text/primary, neutral/50 */
  --text-secondary: #b6b6b9;   /* text/secondary, neutral/300 */
  --accent: #07c3f5;           /* accent/default, cyan/500 */
  --error: #fd604f;            /* status/live, red/500 (the file's only red) */
  --field-fill: rgb(255 255 255 / 0.12);  /* chat "Message capsule" 484:5715 fill */
  --field-edge: rgb(255 255 255 / 0.2);   /* chat "Message capsule" 484:5715 stroke */
  --field-autofill: #232324;   /* the capsule fill flattened onto bg/page */
  /* Keyboard focus on the button and links. Cyan on the cyan button would
     read as a thicker edge, so it is neutral/300 (about 10:1 on bg/page). */
  --focus-ring: var(--text-secondary);

  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, sans-serif;
  /* Figma's SF Pro Semibold is wght 590 on the font's own axis. In CSS it is
     600: Chrome on macOS draws the system font at 590 heavier than Bold
     (2.8 px stems at 17 px against Figma's 2.1), while 600 matches. */
  --semibold: 600;
}

@supports (color: color(display-p3 0 0 0)) {
  :root {
    --bg-page: color(display-p3 0.0197 0.0197 0.0242);
    --text-primary: color(display-p3 0.9581 0.9582 0.969);
    --text-secondary: color(display-p3 0.7135 0.7136 0.7238);
    --accent: color(display-p3 0.3461 0.7515 0.9391);
    --error: color(display-p3 0.9202 0.4164 0.3435);
  }
}

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

[hidden] {
  display: none !important;
}

html {
  background: var(--bg-page);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  position: relative;
  margin: 0;
  min-height: 100vh;
  min-height: 100svh;
  background: var(--bg-page);
  color: var(--text-primary);
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* The group sits in the middle of the whole viewport, as on Turf. The equal
   top and bottom padding keeps it clear of the footer on short screens, and
   the side padding clears a landscape notch. */
.page {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  min-height: 100svh;
  padding-block: 72px;
  padding-left: max(16px, env(safe-area-inset-left, 0px));
  padding-right: max(16px, env(safe-area-inset-right, 0px));
}

.group {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.logo-heading {
  margin: 0;
  line-height: 0;
}

/* Scoped to the heading so the ticker's team .logo class can't resize it. */
.logo-heading .logo {
  display: block;
  width: 102px;
  height: 64px;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}

/* Title: SF Pro Semibold 22/28 */
.tagline {
  margin: 18px 0 0;
  font-size: 22px;
  line-height: 28px;
  font-weight: var(--semibold);
  color: var(--text-primary);
}

/* Holds the form at one fixed size, so nothing above or below moves when
   the state changes. */
.slot {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 240px;
  height: 104px;
  margin-top: 14px;
}

/* Two fixed rows: the field, then the button. On success the confirmation
   takes the button's row, so the slot stays full and nothing moves. */
.form {
  display: grid;
  grid-template-rows: 48px 48px;
  row-gap: 8px;
  align-self: stretch;
}

.form > .field {
  grid-area: 1 / 1;
}

.form > .button,
.form > .done {
  grid-area: 2 / 1;
}

/* The chat composer's "Message capsule": 48 tall, white 12% fill,
   0.5 px white 20% inside stroke, Body 17/22, placeholder in text/secondary.
   Left aligned like that capsule; the 20 px inset keeps text off the end curves. */
.field {
  display: block;
  width: 100%;
  height: 48px;
  margin: 0;
  padding: 0 20px;
  border: 0;
  border-radius: 24px;
  background: var(--field-fill);
  box-shadow: inset 0 0 0 0.5px var(--field-edge);
  color: var(--text-primary);
  caret-color: var(--accent);
  font: 400 17px/22px var(--font);
  letter-spacing: 0;
  text-align: left;
  text-overflow: ellipsis;
  appearance: none;
  -webkit-appearance: none;
}

.field::placeholder {
  color: var(--text-secondary);
  opacity: 1;
}

.field:focus {
  outline: none;
}

/* On the field's own edge, like the Figma "Selected control" 1.5 pt stroke. */
.field:focus-visible {
  outline: 1.5px solid var(--accent);
  outline-offset: -1.5px;
}

.field[aria-invalid="true"] {
  box-shadow: inset 0 0 0 1px var(--error);
}

/* While focused, the ring alone carries the error, so it never doubles up. */
.field[aria-invalid="true"]:focus-visible {
  outline-color: var(--error);
  box-shadow: inset 0 0 0 0.5px var(--field-edge);
}

.field:-webkit-autofill,
.field:-webkit-autofill:hover,
.field:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--text-primary);
  box-shadow: inset 0 0 0 0.5px var(--field-edge), inset 0 0 0 48px var(--field-autofill);
  transition: background-color 600000s 0s;
}

.field[aria-invalid="true"]:-webkit-autofill {
  box-shadow: inset 0 0 0 1px var(--error), inset 0 0 0 48px var(--field-autofill);
}

.hp {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Figma node 6:37 "Follow", at Turf's 240 x 48: cyan gradient lit from above,
   1 px highlight inside the top edge, 0.5 px dark outside stroke, Headline label. */
.button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 48px;
  margin: 0;
  padding: 0 28px;
  border: 0;
  border-radius: 24px;
  background: linear-gradient(180deg, #84e0ff 0%, #22c6f5 85%, #5ed5fe 100%);
  background: linear-gradient(180deg in display-p3,
      color(display-p3 0.6027 0.8687 0.9859) 0%,
      color(display-p3 0.3713 0.7658 0.9431) 85%,
      color(display-p3 0.4958 0.8236 0.977) 100%);
  box-shadow: inset 0 1px 0 0 #caedff, 0 0 0 0.5px #001c24;
  box-shadow: inset 0 1px 0 0 color(display-p3 0.8193 0.9242 0.9919),
    0 0 0 0.5px color(display-p3 0.0269 0.1082 0.1395);
  color: #000;
  /* His call 2026-10-15: the label read too bold at semibold, so medium. */
  font: 500 17px/22px var(--font);
  letter-spacing: 0;
  white-space: nowrap;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  transition: transform 160ms ease-out, filter 160ms ease-out;
}

/* Figma defines no hover or pressed state. These are ours: a slight lift on
   hover (1.06, since the gradient's top stop is nearly white), and on press
   the shared scale 0.96 with the existing darken. */
@media (hover: hover) {
  .button:hover {
    filter: brightness(1.06);
  }
}

.button:active {
  transform: scale(0.96);
  filter: brightness(0.9);
}

/* Same specificity as :hover and :active, so it has to come after them. */
.button[aria-disabled="true"] {
  cursor: progress;
  filter: none;
  transform: none;
}

.button:focus {
  outline: none;
}

.button:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* Headline: SF Pro Semibold 17/22, in the button's row. Visibility flips at
   once (only opacity eases), so done.focus() works on the same frame. */
.done {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 48px;
  margin: 0;
  font: var(--semibold) 17px/22px var(--font);
  color: var(--text-primary);
  opacity: 0;
  visibility: hidden;
}

.done:focus {
  outline: none;
}

.form.is-done > .done {
  opacity: 1;
  visibility: visible;
  transition: opacity 200ms ease-out 80ms;
}

.form.is-done > .button {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 150ms ease-out, visibility 0s linear 150ms;
}

/* The field stays, read only, so the saved address can be checked for typos. */
.form.is-done > .field {
  color: var(--text-secondary);
  outline: none;
  pointer-events: none;
}

.form.is-done > .field:-webkit-autofill {
  -webkit-text-fill-color: var(--text-secondary);
}

/* Without JavaScript the slot holds only this line, at its own height.
   It breaks into two balanced lines at 320 and fits on one from 375 up. */
.nojs {
  display: flex;
  align-items: center;
  justify-content: center;
  width: max-content;
  max-width: calc(100vw - 32px);
  min-height: 48px;
  margin: 0;
  text-wrap: balance;
  font: var(--semibold) 17px/22px var(--font);
  color: var(--text-primary);
}

/* Caption: SF Pro Regular 13/18 */
.note {
  margin: 14px 0 0;
  font-size: 13px;
  line-height: 18px;
  color: var(--text-secondary);
}

.note.is-error {
  color: var(--error);
}

/* Turf's footer: one centered row whose middle sits 36 px above the bottom.
   Each icon link is a 44 x 44 target, so the icons sit 44 apart. */
.footer {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(14px + env(safe-area-inset-bottom, 0px));
  display: flex;
  align-items: center;
  justify-content: center;
}

/* The end margin makes the label-to-X gap match the gaps between icons
   (about 28 px of ink each). The start padding mirrors the empty space after
   the Instagram ink, so the row stays centered. */
.follow {
  margin: 0;
  padding-inline-start: 14px;
  margin-inline-end: 14px;
  font-size: 13px;
  line-height: 18px;
  color: var(--text-secondary);
}

.social {
  display: flex;
  margin: 0;
  padding: 0;
  list-style: none;
}

.social a {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 22px;
  color: var(--text-secondary);
  -webkit-tap-highlight-color: transparent;
  transition: color 150ms ease-out;
}

/* Tabler outline brand icons in 20 px boxes. stroke-width 2 in the 24 unit
   viewBox draws 1.67 px, close to Turf's measured 1.7 px. TikTok's viewBox is
   padded so its ink matches X and Instagram; 2.2 keeps the same 1.67 px there. */
.social svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.social .tiktok {
  stroke-width: 2.2;
}

@media (hover: hover) {
  .social a:hover {
    color: var(--text-primary);
  }
}

.social a:active {
  color: var(--text-primary);
  transition-duration: 0s;
}

.social a:focus {
  outline: none;
}

.social a:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: -4px;
}

/* Below 421 px tall (phones in landscape) the footer joins the flow under the
   group, so the page does not scroll. Taller screens keep Turf's centering. */
@media (max-height: 420px) {
  body {
    display: flex;
    flex-direction: column;
  }

  .page {
    flex: 1;
    min-height: 0;
    padding-block: 24px;
  }

  .footer {
    position: static;
    padding-bottom: calc(14px + env(safe-area-inset-bottom, 0px));
  }
}

.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 (prefers-reduced-motion: reduce) {
  .button {
    transition: none;
  }

  .button:active {
    transform: none;
  }

  .form.is-done > .done,
  .form.is-done > .button {
    transition: none;
  }
}

/* Windows contrast themes drop the inset shadows that draw the field and
   button edges, so give them real borders in system colors. */
@media (forced-colors: active) {
  .field {
    border: 1px solid FieldText;
  }

  .field[aria-invalid="true"] {
    border-width: 2px;
  }

  .button {
    border: 1px solid ButtonText;
  }
}
