/* ============================================================
   /hi — bio-link capture page.
   Brand tokens mirrored from ../styles.css (same palette + type).
   Mobile-first. Whole page fits one phone viewport, no scroll to the field.
   ============================================================ */

:root {
  --bg:        #fbfaf7;
  --surface:   #ffffff;
  --ink-hi:    #161616;
  --ink-body:  #3a3a3a;
  --ink-mute:  #77736c;
  --divider:   #ded8cc;
  --divider-2: #e7e1d6;
  --accent:    #0066ff;
  --ok:        #0f9d58;
  --err:       #d13438;

  --serif: 'Instrument Serif', Georgia, serif;
  --sans:  'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  --mono:  'JetBrains Mono', ui-monospace, monospace;
}

* { margin: 0; padding: 0; box-sizing: border-box; }
/* the full-bleed footer band overhangs by design — clip it, don't scroll */
html { -webkit-text-size-adjust: 100%; overflow-x: hidden; }

body {
  /* page bg on top, footer-band bg underneath: when content is shorter
     than the viewport the leftover space below the footer is already
     the band colour, with no filler element to create phantom scroll */
  background: linear-gradient(var(--bg) 0 0) top / 100% 100% no-repeat, #f9f5f2;
  color: var(--ink-body);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;

  min-height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* top-aligned, not centered: keeps the email field above the fold and
     lets the app cards fall just below it on short phones */
  justify-content: flex-start;
  /* no bottom padding — the footer band supplies its own and must run
     all the way to the bottom edge, like the mock */
  padding: 36px 24px 0;
}

.wrap {
  width: 100%;
  max-width: 420px;
  text-align: center;
  /* Natural document flow. An earlier version stretched .wrap and grew
     the cards to force the footer onto the bottom edge; that inflated
     the cards into hollow boxes with a void between the name and the
     CTA. Content sets its own height and the page scrolls if it needs
     to — the footer sits under the content, wherever that lands. */
  display: flex;
  flex-direction: column;
}


/* ---- mark ---- */
.mark {
  font-family: var(--serif);
  font-size: 3.1rem;
  line-height: 1;
  color: var(--ink-hi);
  letter-spacing: -0.015em;
  display: inline-block;
}
.mark em { font-style: italic; }
/* the wordmark links to IG — inherit type/color so it still reads as a mark, not a link */
.mark a { color: inherit; text-decoration: none; }
.mark a:hover { opacity: 0.7; }

.tiedye {
  height: 4px;
  width: 132px;
  margin: 18px auto 30px;
  border-radius: 3px;
  background: linear-gradient(90deg,#ff2d95,#ff7a1a,#ffd23f,#22d96e,#00d5ff,#0066ff,#8a55ff);
}

/* ---- headline ---- */
.headline {
  font-family: var(--serif);
  font-size: clamp(1.7rem, 7vw, 2.15rem);
  line-height: 1.2;
  color: var(--ink-hi);
  letter-spacing: -0.005em;
  margin-bottom: 12px;
}

.sub {
  font-size: 1rem;
  line-height: 1.55;
  color: var(--ink-mute);
  /* wide enough to keep the sub on one line on desktop; it still wraps on phones */
  max-width: 54ch;
  margin: 0 auto 30px;
}

/* ---- form ---- */
form { display: block; }

.field-wrap { position: relative; }

.field-icon {
  position: absolute;
  left: 17px;
  top: 50%;
  transform: translateY(-50%);
  width: 21px; height: 21px;
  color: #a9a49c;
  pointer-events: none;
  transition: color .15s ease;
}
.field-wrap:focus-within .field-icon { color: var(--accent); }

.field {
  width: 100%;
  height: 64px;
  padding: 0 18px 0 52px;
  font-family: var(--sans);
  font-size: 17px;              /* 16px+ prevents iOS zoom-on-focus */
  color: var(--ink-hi);
  background: var(--surface);
  border: 1px solid var(--divider);
  border-radius: 12px;
  outline: none;
  transition: border-color .15s ease, box-shadow .15s ease;
  -webkit-appearance: none;
}
.field::placeholder { color: #a9a49c; }
.field:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(0,102,255,.13);
}
.field[aria-invalid="true"] {
  border-color: var(--err);
  box-shadow: 0 0 0 3px rgba(209,52,56,.12);
}
.field:disabled { background: #f4f2ee; color: var(--ink-mute); }

.btn {
  width: 100%;
  height: 64px;
  margin-top: 14px;
  font-family: var(--sans);
  font-size: 17px;
  font-weight: 600;
  color: #fff;
  background: var(--ink-hi);
  border: 0;
  border-radius: 12px;
  cursor: pointer;
  transition: background .15s ease, opacity .15s ease, transform .08s ease;
  -webkit-appearance: none;
}
.btn:active { transform: scale(.985); }
.btn:disabled { cursor: default; opacity: 1; }
.btn.is-done { background: var(--ok); }

/* arrow sits next to the label, both centred as a unit */
.btn { display: flex; align-items: center; justify-content: center; gap: 10px; }
.btn-arrow {
  width: 20px; height: 20px;
  flex: none;
  transition: transform .15s ease, opacity .15s ease;
}
.btn:active .btn-arrow { transform: translateX(2px); }
.btn.is-done .btn-arrow { opacity: 0; }

/* Honeypot. MUST be display:none, not an off-screen position.
   Off-screen (left:-9999px) still counts as a rendered, labelled text
   input, so Chrome autofill and password managers happily fill it —
   which tripped the bot check and silently discarded a real signup.
   display:none is skipped by autofill; naive bots parsing the HTML
   still see it. */
.hp { display: none; }

/* collapses when empty so it doesn't reserve dead space under the button */
.note:empty { display: none; }
.note {
  margin-top: 10px;
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.02em;
  color: var(--ink-mute);
}
.note.is-err { color: var(--err); }
.note.is-ok  { color: var(--ok); }

/* ---- trust row ---- */
/* 3 equal columns — a wrapping flex row breaks 2+1 and reads ragged */
.trust {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px 8px;
  /* 26 not 14: the harness measured the trust row landing 48px high
     against the mock — the largest single drift on the page. */
  margin-top: 26px;
}
.trust li {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  font-size: 0.74rem;
  line-height: 1.3;
  color: var(--ink-mute);
  text-align: center;
  text-wrap: balance;
}
.trust-icon { width: 16px; height: 16px; flex: none; }
.trust-check { color: var(--ok); }
.trust-lock  { color: var(--accent); }
.trust-star  { color: #e0a020; }

/* ---- section label above the cards ---- */
.apps-label {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 36px;
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-mute);
  white-space: nowrap;
}
.apps-label::before,
.apps-label::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--divider-2);
}

/* ---- app icons ---- */
.apps {
  display: flex;
  justify-content: center;
  gap: 14px;
  margin-top: 26px;
}

.app {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  /* generous, deliberate padding — the card is a product tile, not a
     favicon in a box. Bottom is lighter than top because the CTA row
     carries its own padding-top. */
  padding: 22px 14px 18px;
  text-decoration: none;
  background: var(--surface);
  border: 1px solid var(--divider-2);
  border-radius: 14px;
  transition: border-color .15s ease, transform .08s ease;
}
.app:active { transform: scale(.98); }
.app:hover { border-color: var(--divider); }

.app .glyph {
  width: 64px; height: 64px;
  border-radius: 16px;
  display: grid;
  place-items: center;
  font-family: var(--serif);
  font-size: 1.28rem;
  color: #fff;
  line-height: 1;
}

/* Real app icons. Some source favicons ship a baked-in white square
   (MightyMouse) while others are transparent (CoT). Giving every icon
   the same white rounded tile makes them read as one set instead of
   one floating logo next to one visible square. */
.app .glyph-img {
  object-fit: contain;
  border-radius: 10px;
  background: #fff;
  padding: 3px;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.06);
}
.app .name {
  font-size: 0.84rem;
  font-weight: 600;
  color: var(--ink-hi);
  line-height: 1.25;
  text-wrap: balance;
}

/* equal-height cards regardless of how each name/caption wraps */
.apps { align-items: stretch; }
/* Real sentence, not a mono tag — uppercase mono can't carry a
   descriptive line at this size without turning into noise. */
.app .what {
  font-family: var(--sans);
  font-size: 0.7rem;
  line-height: 1.3;
  color: var(--ink-mute);
  text-wrap: balance;
}

/* CTA at the bottom of each card — makes it read as a product, not a
   favicon. `margin-top:auto` only aligns the two CTAs when one card's
   description wraps to more lines than the other; the padding-top is
   what supplies the actual breathing room. */
.app-cta {
  margin-top: auto;
  padding-top: 14px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 0.74rem;
  font-weight: 500;
  color: var(--ink-body);
}
.app-cta svg { width: 13px; height: 13px; flex: none; }
.app:hover .app-cta { color: var(--accent); }

/* ---- footer ----
   The mock closes the page on a warm band rather than letting the
   footer float on the page background: 1px rule, then a #f9f5f2 tint
   that runs to the bottom edge. Both sampled off the mock.
   Full-bleed via a negative inline margin — .wrap is max-width 420
   and centred, so the band has to escape it to reach the edges. */
.foot {
  /* Real separation between the cards and the band. `auto` used to live
     here to pin the band to the bottom edge; that fought the content and
     left the cards touching the rule with zero breathing room. */
  margin: 40px 0 0;
  padding: 26px 0 calc(22px + env(safe-area-inset-bottom));
  position: relative;
  font-family: var(--mono);
  z-index: 0;
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  color: var(--ink-mute);
}
.foot-note {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  font-family: var(--sans);
  font-size: 0.76rem;
  letter-spacing: 0;
  margin-bottom: 8px;
}
/* The warm closing band, sampled off the mock (#f9f5f2 + a 1px rule).
   Painted as a pseudo-element rather than a -100vw full-bleed margin:
   the margin trick inflated the layout viewport, which made 100svh
   resolve to ~2x and doubled the page height. This paints wide and
   costs nothing in layout. */
.foot::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 100vw;
  height: 100%;
  background: #f9f5f2;
  border-top: 1px solid var(--divider-2);
  z-index: -1;
}

.foot-heart { width: 14px; height: 14px; flex: none; color: #c9a08f; }
.foot a { color: var(--ink-mute); text-decoration: none; }
.foot a:hover { color: var(--ink-body); }
/* the @techguyver byline is the footer's only link — underline it so it reads as tappable */
.foot-note a { text-decoration: underline; text-underline-offset: 2px; }

/* short phones — tighten the top block so the email field stays
   above the fold; the cards are allowed to sit below it */
/* Short phones (iPhone SE 667, older Androids). The cards were getting
   clipped mid-card, which reads as broken rather than as "scroll for
   more". Everything below the button tightens and the cards shrink to
   a compact row so a whole card is visible without scrolling. */
@media (max-height: 740px) {
  body { padding-top: 20px; }
  .mark { font-size: 2.2rem; }
  .tiedye { margin: 12px auto 16px; }
  .headline { font-size: clamp(1.5rem, 6.4vw, 1.8rem); margin-bottom: 8px; }
  .sub { font-size: 0.92rem; margin-bottom: 18px; }

  .field, .btn { height: 54px; }
  .btn { margin-top: 10px; font-size: 16px; }

  .trust { margin-top: 16px; gap: 6px; }
  .trust li { font-size: 0.68rem; gap: 5px; }
  .trust-icon { width: 14px; height: 14px; }

  .apps-label { margin-top: 20px; }
  .apps { margin-top: 16px; gap: 10px; }

  /* Cards keep the full stacked layout — icon, name, description and
     "Learn more" — just at tighter sizes. Dropping the description
     saved height but removed the reason to tap. */
  .app { padding: 14px 10px 12px; gap: 7px; }
  .app .glyph { width: 46px; height: 46px; border-radius: 12px; }
  .app .name { font-size: 0.8rem; }
  .app .what { font-size: 0.66rem; }
  .app-cta { padding-top: 9px; font-size: 0.7rem; }

  .foot {
    margin-top: 28px;
    padding: 16px 0 calc(14px + env(safe-area-inset-bottom));
  }
  .foot-note { font-size: 0.72rem; margin-bottom: 5px; }
}
