/* Couple App landing page. Every value here is lifted from the app: Polymath
   from the bundle, ink #222222, the five brand shapes, and the sticker
   board's spring-in entrance. Buttons and notifications are iOS's Liquid
   Glass. */

@font-face {
  font-family: "Polymath Display";
  src: url("/couple-app-landing/assets/fonts/polymath-display-600.woff2") format("woff2");
  font-style: normal;
  font-weight: 600;
  font-display: swap;
}

@font-face {
  font-family: "Polymath Display";
  src: url("/couple-app-landing/assets/fonts/polymath-display-700.woff2") format("woff2");
  font-style: normal;
  font-weight: 700;
  font-display: swap;
}

@font-face {
  font-family: "Polymath";
  src: url("/couple-app-landing/assets/fonts/polymath-500.woff2") format("woff2");
  font-style: normal;
  font-weight: 500;
  font-display: swap;
}

@font-face {
  font-family: "Polymath";
  src: url("/couple-app-landing/assets/fonts/polymath-600.woff2") format("woff2");
  font-style: normal;
  font-weight: 600;
  font-display: swap;
}

:root {
  --ink: #222222;
  --ink-muted: rgba(0, 0, 0, 0.5); /* black at 50%, same as the app */
  --accent: #4f6aff;
  --paper: #ffffff;
  --display: "Polymath Display", "Polymath", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  --text: "Polymath", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
}

* {
  box-sizing: border-box;
}

html {
  min-width: 320px;
  background: var(--paper);
}

body {
  margin: 0;
  color: var(--ink);
  background: var(--paper);
  font-family: var(--text);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.sticker-filters {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

.landing-page {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  overflow: hidden;
}

.wordmark {
  position: absolute;
  z-index: 6;
  top: 40px;
  left: 48px;
  display: flex;
  align-items: center;
  gap: 0.36em;
  color: var(--ink);
  font-family: var(--display);
  font-size: 28px;
  font-weight: 700;
  line-height: 32px;
  letter-spacing: -0.01em;
  text-decoration: none;
}

/* The app's icon leads the name, on iOS's rounded square. */
.wordmark img {
  width: 1.3em;
  height: 1.3em;
  border-radius: 22.5%;
  box-shadow: 0 0 0 0.5px rgba(0, 0, 0, 0.08);
}

/* The wall ------------------------------------------------------------- */

.wall {
  position: absolute;
  z-index: 1;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.seat {
  position: absolute;
  top: var(--y);
  left: var(--x);
  transform: translate(-50%, -50%) rotate(var(--r, 0deg));
  /* The wall ignores the pointer; the pieces themselves answer to hover. */
  pointer-events: auto;
}

.seat img {
  display: block;
  -webkit-user-drag: none;
  -webkit-touch-callout: none;
  user-select: none;
}

.seat.shape img {
  width: var(--w);
  height: auto;
}

.seat.cutout img {
  width: auto;
  height: var(--h);
  filter: url("#sticker");
}

/* A Polaroid is already paper: it skips the die-cut margin and casts the
   soft shadow of a print taped to the page. */
.seat.snapshot img {
  filter: drop-shadow(0 0 0.5px rgba(0, 0, 0, 0.16)) drop-shadow(0 3px 4px rgba(58, 48, 40, 0.2));
}

/* The app pieces (assets/app-elements) animate, and the #sticker filter
   over a moving image redraws every frame, so each draws its own die-cut
   edge instead. */
.seat.widget img {
  filter: none;
}

/* Hover: a brand shape spins clockwise (script-driven so it finishes its
   turn on the way out); a photo sticker tilts a touch and springs back. */
.seat.cutout {
  transition: transform 520ms cubic-bezier(0.34, 1.56, 0.64, 1);
}

.seat.cutout:hover {
  transform: translate(-50%, -50%) rotate(calc(var(--r, 0deg) + 7deg));
}

@keyframes pop {
  0% {
    opacity: 0;
    transform: translate(var(--dx, 0px), var(--dy, 0px)) scale(var(--s0, 0.3));
  }

  30% {
    opacity: 1;
  }

  100% {
    opacity: 1;
    transform: translate(0, 0) scale(1);
  }
}

.pop {
  animation: pop 300ms cubic-bezier(0.2, 1.25, 0.4, 1) both;
  animation-delay: var(--d, 0s);
}

.pop.pending {
  animation-play-state: paused;
}

/* The copy ------------------------------------------------------------- */

.hero {
  position: absolute;
  z-index: 5;
  top: 50%;
  left: 50%;
  display: flex;
  width: min(800px, calc(100% - 48px));
  flex-direction: column;
  align-items: center;
  gap: 24px;
  transform: translate(-50%, -50%);
  text-align: center;
}

h1,
.hero p {
  margin: 0;
}

h1 {
  width: 100%;
  font-family: var(--display);
  /* Tracks the viewport's short side too, so laptop windows keep one screen. */
  font-size: clamp(64px, min(7.8vw, 12.4vh), 112px);
  font-weight: 600;
  line-height: 1.02;
  letter-spacing: -0.015em;
}

h1 span {
  display: block;
  white-space: nowrap;
}

/* The homepage's headline is a sentence rather than two set lines: it
   wraps, balanced, at a size that keeps the page one screen tall. */
h1.statement {
  font-size: clamp(52px, min(5.3vw, 8.8vh), 80px);
  line-height: 1.04;
  text-wrap: balance;
}

.hero p {
  max-width: 600px;
  color: var(--ink-muted);
  font-size: 20px;
  font-weight: 500;
  line-height: 28px;
  text-wrap: pretty;
}

/* The homepage's subtitle runs long enough to strand a last word or two;
   balancing evens its lines out. */
.hero p.balanced {
  text-wrap: balance;
}

/* Liquid glass --------------------------------------------------------- */

/* iOS's Liquid Glass. A pane is nearly clear: it frosts what is behind it
   only a little and, in Chromium, bends it at the rim through a lens filter
   glass.js draws for each pane (other browsers keep the frost alone). Its
   rim catches the light on the side facing the pointer (--rim), and a soft
   sheen sits under the pointer (--lx, --ly), the way the real thing answers
   the tilt of the phone. A pane needs a position for its two layers. */
.glass {
  --glass-tint: rgba(255, 255, 255, 0.4);
  --glass-frost: 2px;
  --glass-lift: 0 1px 2px rgba(0, 0, 0, 0.06), 0 10px 28px -8px rgba(0, 0, 0, 0.18);
  --rim: -40deg;
  --lx: 30%;
  --ly: -10%;
  --sheen: 0.4;
  isolation: isolate;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.45), rgba(255, 255, 255, 0) 60%),
    var(--glass-tint);
  -webkit-backdrop-filter: blur(var(--glass-frost)) saturate(1.8) brightness(1.05);
  backdrop-filter: blur(var(--glass-frost)) saturate(1.8) brightness(1.05);
  box-shadow:
    inset 0 1px 1px rgba(255, 255, 255, 0.9),
    inset 0 -1px 2px rgba(255, 255, 255, 0.45),
    inset 0 0 0 0.5px rgba(0, 0, 0, 0.07),
    inset 0 -10px 18px -12px rgba(0, 0, 0, 0.08),
    var(--glass-lift);
}

.glass::before,
.glass::after {
  position: absolute;
  z-index: -1;
  inset: 0;
  border-radius: inherit;
  content: "";
  pointer-events: none;
}

/* The rim: white where the light falls, a faint grey across the sides and a
   weaker catch opposite, so the edge reads on the white page as well as on
   a photo. */
.glass::before {
  padding: 1.25px;
  background: conic-gradient(
    from var(--rim),
    rgba(255, 255, 255, 1),
    rgba(255, 255, 255, 0.35) 15%,
    rgba(0, 0, 0, 0.12) 28%,
    rgba(0, 0, 0, 0.05) 42%,
    rgba(255, 255, 255, 0.8) 50%,
    rgba(0, 0, 0, 0.05) 58%,
    rgba(0, 0, 0, 0.12) 72%,
    rgba(255, 255, 255, 0.35) 85%,
    rgba(255, 255, 255, 1)
  );
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
}

/* The sheen: a soft bloom of light under the pointer, bright while pressed. */
.glass::after {
  background: radial-gradient(110px circle at var(--lx) var(--ly), rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0));
  opacity: var(--sheen);
  transition: opacity 260ms ease;
}

.glass.is-pressed::after {
  opacity: 1;
}

@media (prefers-reduced-transparency: reduce) {
  .glass {
    --glass-tint: rgba(255, 255, 255, 0.92);
  }
}

/* The button: a liquid glass capsule. With a mouse it grows into a card
   holding the App Store QR code — the same reveal as trysabbath.com. */

.cta-shell {
  position: relative;
  z-index: 5;
  width: 244px;
  height: 66px;
  margin-top: 12px;
}

/* A glow of the brand's colours behind the button: four soft blobs, each
   wandering on its own path. They only move and scale (no blur filter, no
   repainting), so it costs the page nothing to keep them going. It steps
   back while the button is open as the QR card. */
.cta-glow {
  position: absolute;
  z-index: -1;
  inset: -14px -24px -20px;
  opacity: 0.36;
  pointer-events: none;
  transition: opacity 200ms ease;
}

.cta-glow i {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 46%;
  background: radial-gradient(closest-side, var(--blob), rgba(255, 255, 255, 0) 100%);
  animation: cta-blob 7s ease-in-out infinite;
}

.cta-glow i:nth-child(1) {
  --blob: rgba(255, 111, 181, 0.75);
  left: -2%;
  animation-duration: 6.4s;
}

.cta-glow i:nth-child(2) {
  --blob: rgba(255, 207, 106, 0.75);
  left: 20%;
  animation-duration: 7.6s;
  animation-delay: -2.1s;
  animation-direction: reverse;
}

.cta-glow i:nth-child(3) {
  --blob: rgba(95, 224, 176, 0.75);
  left: 36%;
  animation-duration: 6.9s;
  animation-delay: -4.3s;
}

.cta-glow i:nth-child(4) {
  --blob: rgba(140, 156, 255, 0.75);
  left: 56%;
  animation-duration: 8.2s;
  animation-delay: -1.2s;
  animation-direction: reverse;
}

@keyframes cta-blob {
  0%,
  100% {
    transform: translate(0, 0) scale(1);
  }

  25% {
    transform: translate(26%, -12%) scale(1.14);
  }

  50% {
    transform: translate(6%, 10%) scale(0.88);
  }

  75% {
    transform: translate(-22%, -5%) scale(1.06);
  }
}

.cta {
  position: absolute;
  z-index: 1;
  right: 50%;
  bottom: 0;
  display: inline-flex;
  width: 244px;
  height: 66px;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  color: var(--ink);
  border-radius: 1000px;
  text-decoration: none;
  white-space: nowrap;
  isolation: isolate;
  transform: translateX(50%);
  /* glass.js scales the button with the `scale` property, which applies
     after this transform: pivot on the button's visible center. */
  transform-origin: 100% 50%;
  transition:
    width 280ms cubic-bezier(0.34, 1.56, 0.64, 1),
    height 280ms cubic-bezier(0.34, 1.56, 0.64, 1),
    border-radius 220ms cubic-bezier(0.22, 1, 0.36, 1),
    box-shadow 280ms ease;
}

.cta:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 3px;
}

.cta-text {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 21px;
  font-weight: 600;
  line-height: 26px;
  letter-spacing: -0.005em;
  transition: opacity 140ms ease;
}

.cta-apple {
  width: 21px;
  height: 21px;
  margin-top: -2px;
  flex: 0 0 auto;
}

.cta-qr {
  position: absolute;
  z-index: 1;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 24px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 160ms ease 80ms;
}

/* The code sits on a white tile so any phone camera reads it off the glass card. */
.qr-tile {
  display: block;
  padding: 8px;
  background: #ffffff;
  border-radius: 16px;
}

.cta-qr img {
  display: block;
  width: 184px;
  height: 184px;
}

.cta-caption {
  color: var(--ink);
  font-size: 13px;
  font-weight: 600;
  line-height: 16px;
}

/* The footer ----------------------------------------------------------- */

.site-footer {
  position: absolute;
  z-index: 6;
  right: 0;
  bottom: 28px;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 28px;
  font-size: 13px;
  font-weight: 500;
  line-height: 16px;
}

.site-footer a {
  color: var(--ink-muted);
  text-decoration: none;
}

.site-footer a:hover,
.site-footer a:focus-visible {
  color: var(--accent);
}

/* Pointer devices: the QR reveal --------------------------------------- */

@media (hover: hover) and (pointer: fine) {
  .cta-shell::before {
    position: absolute;
    z-index: 0;
    right: 50%;
    bottom: -4px;
    width: 252px;
    height: 74px;
    border-radius: 1000px;
    content: "";
    transform: translateX(50%);
  }

  .cta-shell:hover::before,
  .cta-shell:has(:focus-visible)::before {
    width: 272px;
    height: 312px;
    border-radius: 32px;
  }

  /* Open, the card frosts more, so the headline behind it softens and the
     caption stays readable; its rim still bends what passes under it. */
  .cta-shell:hover .cta,
  .cta-shell:has(:focus-visible) .cta {
    --glass-tint: rgba(255, 255, 255, 0.5);
    --glass-frost: 14px;
    --glass-lift:
      0 60px 140px -20px rgba(34, 34, 34, 0.32),
      0 30px 80px -10px rgba(34, 34, 34, 0.2),
      0 8px 24px rgba(34, 34, 34, 0.16);
    width: 264px;
    height: 304px;
    border-radius: 28px;
  }

  .cta-shell:hover .cta-text,
  .cta-shell:has(:focus-visible) .cta-text {
    opacity: 0;
  }

  .cta-shell:hover .cta-qr,
  .cta-shell:has(:focus-visible) .cta-qr {
    opacity: 1;
  }

  .cta-shell:hover .cta-glow,
  .cta-shell:has(:focus-visible) .cta-glow {
    opacity: 0;
  }
}

/* Desktop: one screen, no scroll ---------------------------------------- */

@media (min-width: 1024px) {
  html,
  body {
    overscroll-behavior-y: none;
  }

  .landing-page {
    height: 100vh;
    height: 100svh;
    min-height: 560px;
  }
}

/* Phones and small tablets ---------------------------------------------- */

@media (max-width: 1023px) {
  .wordmark {
    top: 24px;
    left: 24px;
    font-size: 24px;
    line-height: 28px;
  }

  .seat {
    top: var(--my, var(--y));
    left: var(--mx, var(--x));
  }

  .seat.desktop-only {
    display: none;
  }

  .seat.shape img {
    width: var(--mw, var(--w));
  }

  .seat.cutout img {
    height: var(--mh, var(--h));
  }

  .hero {
    width: calc(100% - 48px);
    gap: 18px;
  }

  h1 {
    font-size: clamp(42px, 13.5vw, 64px);
    line-height: 1.04;
    letter-spacing: -0.02em;
  }

  h1.statement {
    font-size: clamp(34px, 10.8vw, 48px);
    line-height: 1.06;
  }

  .hero p {
    max-width: 420px;
    font-size: 17px;
    line-height: 24px;
  }

  .cta-shell {
    margin-top: 10px;
  }

  .site-footer {
    bottom: max(20px, env(safe-area-inset-bottom));
  }
}

@media (prefers-reduced-motion: reduce) {
  .pop {
    animation: none;
  }

  .seat.cutout {
    transition: none;
  }

  .seat.cutout:hover {
    transform: translate(-50%, -50%) rotate(var(--r, 0deg));
  }

  .cta,
  .cta-text,
  .cta-qr {
    transition: none;
  }

  .cta-glow i {
    animation: none;
  }
}
