/* The plucked-string field: a minimal newsletter sign-up on a white page. No box round the field: its underline is
   a hairline string held between two small pegs, and the only colour is the accent the string takes when it is in
   tune. */
:root {
  --page: #ffffff;          /* the page */
  --ink: #141414;           /* the letters, and the string while you type */
  --muted: #8a8a86;         /* the label at rest, and the line under the field */
  --rest: #b9b8b3;          /* the string at rest */
  --peg: #cfcec9;           /* the two pegs that hold the string */
  --accent: #e8461f;        /* the string in tune: a valid address, and the confirmation */
  --send: #141414;          /* the button */
  --send-ink: #ffffff;      /* the button's word */
}

* {
  box-sizing: border-box;
}

html {
  touch-action: manipulation;
}

html,
body {
  margin: 0;
  overflow-x: clip;
}

body {
  min-height: 100svh;
  background: var(--page);
  color: var(--ink);
  font-family: 'Roboto Flex Variable', system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
}

.stage {
  min-height: 100svh;
  display: grid;
  place-items: center;
  padding: 40px 16px;
}

.pluck {
  position: relative;
  width: min(440px, 100%);
  margin: 0;
}

/* ---------------------------------------------------------------- the row: the field and the button */
.pluck__row {
  position: relative;
  display: flex;
  align-items: flex-end;
  gap: 16px;
  height: 60px;
}

.pluck__field {
  position: relative;
  flex: 1 1 auto;
  min-width: 0;
  height: 60px;
  cursor: text;
}

/* the label rests on the line where the address goes, and rises when the field is in use: smaller, heavier and a
   little wider, with the optical size of the typeface following the size (font-optical-sizing) */
.pluck__label {
  --fs: 20;
  --wg: 380;
  --wd: 100;
  position: absolute;
  left: 0;
  top: 0;
  display: block;
  font-size: calc(var(--fs) * 1px);
  font-weight: var(--wg);
  font-stretch: calc(var(--wd) * 1%);
  font-optical-sizing: auto;
  line-height: 1;
  letter-spacing: 0.005em;
  color: var(--muted);
  white-space: nowrap;
  transform-origin: 0 50%;
  will-change: transform;
  user-select: none;
  -webkit-user-select: none;
}

.pluck__input {
  position: absolute;
  left: 0;
  right: 0;
  top: 22px;
  height: 36px;
  width: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  outline: none;
  background: transparent;
  color: var(--ink);
  caret-color: var(--accent);
  font: 420 20px/36px 'Roboto Flex Variable', system-ui, sans-serif;
  font-kerning: normal;
  font-variant-ligatures: none;
  letter-spacing: 0;
  -webkit-tap-highlight-color: transparent;
}

.pluck__input:-webkit-autofill {
  -webkit-text-fill-color: var(--ink);
  -webkit-box-shadow: 0 0 0 60px var(--page) inset;
}

/* the caret of the library's preview, which types without taking the focus */
.pluck__caret {
  position: absolute;
  left: 0;
  top: 29px;
  width: 1.5px;
  height: 22px;
  background: var(--accent);
  opacity: 0;
  pointer-events: none;
}

.pluck__caret.is-on {
  animation: blink 1.06s steps(1) infinite;
}

@keyframes blink {
  0%,
  50% {
    opacity: 1;
  }

  50.01%,
  100% {
    opacity: 0;
  }
}

/* the confirmation, written where the address was */
.pluck__done {
  position: absolute;
  left: 0;
  top: 22px;
  display: flex;
  height: 36px;
  margin: 0;
  font-size: 20px;
  font-weight: 560;
  line-height: 36px;
  white-space: pre;
  pointer-events: none;
  visibility: hidden;
}

/* a letter's box keeps the width of the letter at its final weight; the glyph inside may be thinner on its way in */
.done__box {
  display: flex;
  justify-content: center;
  flex: none;
}

.done__g {
  --wg: 560;
  --wd: 100;
  display: block;
  font-weight: var(--wg);
  font-stretch: calc(var(--wd) * 1%);
  will-change: transform;
}

/* ---------------------------------------------------------------- the button: the elastic pill */
.send {
  position: relative;
  flex: none;
  display: grid;
  place-items: center;
  height: 42px;
  margin: 0 0 0 0;
  padding: 0 22px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--send-ink);
  font: 560 15px/1 'Roboto Flex Variable', system-ui, sans-serif;
  cursor: pointer;
  isolation: isolate;
  -webkit-tap-highlight-color: transparent;
}

/* the colour is a layer of its own: it swells under the pointer while the word widens */
.send__bg {
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: var(--send);
  transition: inset 0.6s cubic-bezier(0.3, 1.7, 0.45, 1), transform 0.16s ease-out;
}

.send__label {
  display: block;
  font-stretch: 100%;
  white-space: nowrap;
  transition: font-stretch 0.6s cubic-bezier(0.3, 1.7, 0.45, 1);
}

@media (hover: hover) and (pointer: fine) {
  .send:not([aria-disabled='true']):hover .send__bg {
    inset: -2px -4px;
  }

  .send:not([aria-disabled='true']):hover .send__label {
    font-stretch: 116%;
  }
}

.send:not([aria-disabled='true']):active .send__bg,
.send.is-pressed .send__bg {
  transform: scale(0.95);
}

.send[aria-disabled='true'] {
  cursor: default;
}

.send:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
}

/* ---------------------------------------------------------------- the string */
.pluck__lane {
  position: relative;
  height: 32px;
  margin-top: -6px;
  pointer-events: none;
}

.pluck__string {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.string__line,
.string__tick {
  fill: none;
  stroke: var(--rest);
  stroke-width: 1;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.string__tick {
  stroke: var(--accent);
  stroke-width: 1.6;
  opacity: 0;
}

.string__pegs {
  fill: none;
  stroke: var(--peg);
  stroke-width: 1;
  stroke-linecap: round;
}

/* ---------------------------------------------------------------- the line under the field */
.pluck__note {
  position: relative;
  min-height: 20px;
  margin: 2px 0 0;
  font-size: 14px;
  font-weight: 400;
  line-height: 20px;
  color: var(--muted);
}

.note__line {
  display: block;
  overflow-wrap: anywhere;
}

.note__line.is-going {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  pointer-events: none;
}

.note__line.is-wrong {
  color: var(--ink);
}

.note__line b {
  font-weight: 560;
  color: var(--ink);
}

/* the way back from the confirmation: a word that widens, never an underline */
.note__change {
  margin: 0;
  padding: 2px 0;
  border: 0;
  background: none;
  color: var(--ink);
  font: inherit;
  font-weight: 600;
  font-stretch: 100%;
  cursor: pointer;
  transition: font-stretch 0.5s cubic-bezier(0.3, 1.7, 0.45, 1), color 0.2s ease;
  -webkit-tap-highlight-color: transparent;
}

@media (hover: hover) and (pointer: fine) {
  .note__change:hover {
    font-stretch: 122%;
    color: var(--accent);
  }
}

.note__change:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 3px;
}

/* for screen readers only */
.sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

@media (max-width: 440px) {
  .pluck__row {
    gap: 12px;
  }

  .pluck__input,
  .pluck__done {
    font-size: 18px;
  }

  .pluck__caret {
    top: 30px;
    height: 20px;
  }

  .send {
    height: 40px;
    padding: 0 18px;
    font-size: 14px;
  }
}
