/* Landing page (getnota.ch/) — single-viewport hero.
   Layout and entrance motion follow the "Vesper.ai" reference; everything
   that carries identity (brand, badge, headline, buttons) is Nota's own
   language from style.css: Fraunces headline, IBM Plex Mono labels, the
   green "chiffré · privé" pill, the violet accent gradient on 12px-radius
   buttons. Own file because the CSP in server.js only allows style-src
   'self' (no inline styles, no style="" attributes). */

/* Force dark immediately so the page can never flash white. */
html, body { background: #09080d !important; color: #ffffff; }

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/fonts/inter-variable.woff2") format("woff2");
}
@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/fonts/fraunces-variable.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/ibm-plex-mono-400.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/fonts/ibm-plex-mono-500.woff2") format("woff2");
}

:root {
  --bg: #09080d;
  --text: #ffffff;
  --muted: #a59fb6;
  --lede-color: #dcd6ea;
  --accent: #6a4ce0;
  --accent-2: #8f6cff;
  --accent-dim: #5a36d6;
  --accent-soft: #b9a8ff;
  --accent-grad: linear-gradient(150deg, #8f6cff 0%, #5a36d6 100%);
  --green: #6fcf9f;
  --green-dot: #3f9a72;
  --stat: #ece8f6;
  --border: rgba(255, 255, 255, 0.16);
  --radius: 12px;

  --logo: 22px;
  --logo-mark: 24px;
  --link: 12px;
  --btn: 14.5px;
  --btn-h: 48px;
  --btn-pad: 0 28px;
  --h1: 52px;
  --lede: 17px;
  --badge: 12.5px;
  --badge-mb: 22px;
  --lede-mt: 18px;
  --actions-mt: 28px;
  --actions-gap: 12px;
  --stat-size: 14px;
  --icon: 20px;
  --icon-wide-w: 38px;
  --icon-wide-h: 21px;
  --header-y: 22px;
  --header-x: 40px;
  --stats-x: 72px;
  --stats-y: 36px;
  --hero-gap: 85px;
  --copy-max: 860px;
  --lede-max: 540px;

  --ui: "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --serif: "Fraunces", Georgia, "Times New Roman", serif;
  --mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}

html, body {
  background: #09080d;
  background: var(--bg, #09080d);
  color: #ffffff;
  color: var(--text, #ffffff);
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body {
  font-family: var(--ui);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  position: relative;
}
a { color: inherit; text-decoration: none; }
button { font-family: inherit; }

/* ------------------------------------------------------------ layers */
.hero-photo {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  /* No entrance fade/scale on the video's container (removed 2026-10-01):
     iOS Safari won't autoplay a video it considers invisible (opacity 0
     at the first keyframe) and didn't always start it once the fade
     ended, and a scale transform on a video's parent can leave WebKit
     painting the video at the wrong size. Seen on Bryan's iPhone: no
     video until a refresh, sometimes a tiny one. */
}
.hero-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  /* No CSS filter: the Nota violet grade is baked into the file with
     ffmpeg (from the 10-bit source, ping-pong looped so the loop point is
     seamless). Filtering in the browser amplified compression blocks into
     a mottled texture — Bryan, 2026-10-01: "vraiment de très basse
     qualité". */
}

.page {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-rows: auto 1fr auto;
  min-height: 100vh;
  min-height: 100dvh;
}

/* No .grain noise layer (it was in the Vesper reference): drawn over the
   smooth violet ribbon it read as heavy pixelation (Bryan, 2026-10-01). */

/* ------------------------------------------------------------ header */
.header {
  position: relative;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: var(--header-y) var(--header-x) 10px;
}

/* Brand exactly as in the app: logo + Fraunces "Nota" + mono "PRIVATE AI". */
.logo {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: #fff;
}
.logo-mark {
  width: var(--logo-mark);
  height: var(--logo-mark);
  border-radius: 8px;
  display: block;
  /* The N in logo-icon.png sits low in its canvas (sparkle takes the top
     right), so centred boxes still read as "icon below the word". Lifting
     it puts the N's foot on the text baseline. */
  transform: translateY(-2px);
}
.logo-text {
  display: inline-block;
  line-height: 1;
  font-family: var(--serif);
  font-size: var(--logo);
  font-weight: 400;
  letter-spacing: -0.01em;
}

/* Header sign-in: the old landing-nav-link (mono, thin border), on dark. */
.header-link {
  display: inline-flex;
  align-items: center;
  font-family: var(--mono);
  font-size: var(--link);
  letter-spacing: 0.04em;
  color: #e4e0ef;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: var(--radius);
  padding: 9px 16px;
  background: rgba(9, 8, 13, 0.35);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease;
}
.header-link:hover {
  color: #fff;
  border-color: var(--accent-2);
  background: rgba(106, 76, 224, 0.16);
}

/* ------------------------------------------------------------ buttons */
.btn {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: var(--btn-h);
  padding: var(--btn-pad);
  border-radius: var(--radius);
  font-size: var(--btn);
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transition: transform 0.25s ease, box-shadow 0.3s ease, border-color 0.25s ease, background 0.25s ease, color 0.25s ease;
}

/* Primary: Nota's .landing-cta (violet gradient, soft violet shadow),
   with a light sweep on hover. */
.btn-primary {
  background: var(--accent-grad);
  color: #fff;
  border: 1px solid rgba(190, 172, 255, 0.45);
  box-shadow: 0 10px 28px -10px rgba(124, 58, 237, 0.65), inset 0 1px 0 rgba(255, 255, 255, 0.22);
}
.btn-primary::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(115deg, transparent 25%, rgba(255, 255, 255, 0.28) 50%, transparent 75%);
  transform: translateX(-130%);
  transition: transform 0.7s ease;
  pointer-events: none;
}
.btn-primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 16px 36px -12px rgba(124, 58, 237, 0.8), 0 0 28px rgba(143, 108, 255, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.3);
}
.btn-primary:hover::after { transform: translateX(130%); }
.btn-primary:active { transform: translateY(0); }

/* Secondary: Nota's quiet .landing-cta-secondary — no fill competing with
   the primary, just a thin border that warms to violet on hover. */
.btn-secondary {
  background: rgba(9, 8, 13, 0.35);
  color: #e4e0ef;
  border: 1px solid rgba(255, 255, 255, 0.2);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
}
.btn-secondary:hover {
  color: #fff;
  border-color: var(--accent-2);
  background: rgba(106, 76, 224, 0.16);
}

.btn:focus-visible,
.header-link:focus-visible,
.logo:focus-visible {
  outline: 2px solid var(--accent-soft);
  outline-offset: 3px;
}

/* ------------------------------------------------------------ hero */
.hero {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 8px 24px var(--hero-gap);
  min-height: 0;
}
.hero-copy {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  max-width: var(--copy-max);
  width: 100%;
}

/* The app's "chiffré · privé" pill, in the page's violet (Bryan: the
   green one stood out from the rest of the site). */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin-bottom: var(--badge-mb);
  padding: 8px 16px;
  border-radius: 999px;
  border: 1px solid rgba(185, 168, 255, 0.38);
  background: rgba(42, 30, 84, 0.6);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  color: #e2daff;
  font-size: var(--badge);
  font-weight: 500;
  letter-spacing: 0.01em;
}
.badge-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent-2);
  box-shadow: 0 0 10px rgba(143, 108, 255, 0.9);
  flex: none;
}

.hero h1 {
  display: flex;
  flex-direction: column;
  align-items: center;
  font-family: var(--serif);
  font-size: var(--h1);
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.12;
  color: #fff;
}
.headline-line {
  display: block;
  overflow: hidden;
  padding: 0.06em 0.15em 0.14em;
}
.headline-line > span { display: inline-block; text-wrap: balance; }
.hero h1 em {
  font-style: normal;
  color: #fff;
  /* White like the rest of the title, marked by a Nota-violet underline
     bar: lavender text vanished whenever the ribbon passed behind it, and
     a dark halo around it looked dirty. */
  position: relative;
  white-space: nowrap;
  padding: 0 0.04em;
  animation: in-em 1.2s cubic-bezier(0.16, 1, 0.3, 1) 0.72s both;
}
/* The underline is a pseudo-element rather than a background gradient so
   its ends can be rounded. z-index -1 keeps it under the letters (still
   above the video: .hero-copy is its own stacking context). */
.hero h1 em::after {
  content: "";
  position: absolute;
  left: 0.04em;
  right: 0.04em;
  bottom: 0.04em;
  height: 0.12em;
  border-radius: 999px;
  background: linear-gradient(90deg, #8f6cff, #5a36d6);
  z-index: -1;
}

.lede {
  max-width: var(--lede-max);
  margin-top: var(--lede-mt);
  color: var(--lede-color);
  font-size: var(--lede);
  font-weight: 450;
  line-height: 1.65;
  letter-spacing: -0.005em;
  /* Legibility where the ribbon passes behind the text — a text shadow,
     not an overlay on the video. */
  text-shadow: 0 1px 12px rgba(9, 8, 13, 0.85);
}
.hero h1 { text-shadow: 0 2px 18px rgba(14, 10, 32, 0.5); }

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--actions-gap);
  margin-top: var(--actions-mt);
}

/* ------------------------------------------------------------ stats */
.stats {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 0 var(--stats-x) var(--stats-y);
  padding-bottom: max(var(--stats-y), env(safe-area-inset-bottom));
  color: var(--stat);
}
.stat {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-size: var(--stat-size);
  font-weight: 500;
  text-shadow: 0 1px 10px rgba(9, 8, 13, 0.9);
  letter-spacing: -0.015em;
  white-space: nowrap;
}
.stat-icon { width: var(--icon); height: var(--icon); flex: none; color: #e8e8e8; }
.stat-icon-wide { width: var(--icon-wide-w); height: var(--icon-wide-h); }

/* ------------------------------------------------------------ entrance motion */
.appear {
  opacity: 1;
  animation-duration: 1.05s;
  animation-fill-mode: both;
  animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
  animation-delay: var(--d, 0.08s);
}
/* Per-element delays as classes: CSP forbids style="--d: …" attributes. */
.d-08 { --d: 0.08s; }
.d-22 { --d: 0.22s; }
.d-34 { --d: 0.34s; }
.d-42 { --d: 0.42s; }
.d-62 { --d: 0.62s; }
.d-82 { --d: 0.82s; }
.d-96 { --d: 0.96s; }
.d-110 { --d: 1.10s; }
.d-112 { --d: 1.12s; }
.d-128 { --d: 1.28s; }
.d-144 { --d: 1.44s; }

.appear--scale { animation-name: in-scale; }
.appear--soft { animation-name: in-soft; }
.appear--mask { animation-name: in-mask; }
.appear--pop { animation-name: in-pop; }
.appear--btn { animation-name: in-btn; }
.appear--side { animation-name: in-side; }
.appear--stat { animation-name: in-stat; }
.lede.appear { animation-duration: 1.25s; }

.appear.is-in,
.hero-photo.is-in {
  animation: none;
  opacity: 1;
  transform: none;
  clip-path: none;
  filter: none;
}

@keyframes in-scale { from { opacity: 0; transform: scale(0.84); } to { opacity: 1; transform: scale(1); } }
@keyframes in-soft { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: translateY(0); } }
@keyframes in-mask { from { opacity: 0; transform: translateY(40%); } to { opacity: 1; transform: translateY(0); } }
@keyframes in-pop {
  0% { opacity: 0; transform: scale(0.9); }
  70% { opacity: 1; transform: scale(1.03); }
  100% { opacity: 1; transform: scale(1); }
}
@keyframes in-btn { from { opacity: 0; transform: translateY(18px) scale(0.94); } to { opacity: 1; transform: none; } }
@keyframes in-side { from { opacity: 0; transform: translateX(22px); } to { opacity: 1; transform: translateX(0); } }
@keyframes in-stat { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }
@keyframes in-em { from { opacity: 0.35; filter: blur(4px); } to { opacity: 1; filter: blur(0); } }

/* Reduced motion: entrance effects off. The background video keeps
   playing on purpose (Bryan, 2026-10-01: "l'image doit bouger") — it's a
   slow ambient loop, not a flashing or parallax effect. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
  .appear, .hero-photo, .hero h1 em { opacity: 1; transform: none; clip-path: none; filter: none; }
}

/* ------------------------------------------------------------ responsive */
@media (min-width: 1600px) {
  :root {
    --logo: 24px; --logo-mark: 26px; --link: 13px;
    --btn: 15.5px; --btn-h: 52px; --btn-pad: 0 32px;
    --h1: 68px; --lede: 19px; --badge: 13.5px; --stat-size: 15px;
    --header-y: 28px; --header-x: 64px; --stats-x: 96px; --stats-y: 44px;
    --copy-max: 980px; --lede-max: 600px;
    --badge-mb: 26px; --lede-mt: 22px; --actions-mt: 32px; --actions-gap: 14px;
    --icon: 22px; --icon-wide-w: 45px; --icon-wide-h: 24px;
  }
}
@media (min-width: 1920px) {
  :root {
    --logo: 26px; --logo-mark: 28px; --link: 14px;
    --btn: 16px; --btn-h: 56px; --btn-pad: 0 36px;
    --h1: 80px; --lede: 21px; --badge: 14.5px; --stat-size: 16px;
    --header-y: 32px; --header-x: 80px; --stats-x: 120px; --stats-y: 52px;
    --copy-max: 1120px; --lede-max: 680px;
    --icon-wide-w: 48px; --icon-wide-h: 26px;
  }
}
@media (min-width: 2560px) {
  :root { --h1: 92px; --lede: 23px; --header-x: 120px; --stats-x: 160px; --copy-max: 1280px; --lede-max: 740px; }
}
@media (min-width: 1280px) and (max-width: 1599px) {
  :root { --h1: 58px; --lede: 17px; --header-x: 48px; --stats-x: 80px; --copy-max: 900px; }
}
@media (min-width: 901px) and (max-width: 1279px) {
  :root {
    --btn: 14px; --btn-h: 46px;
    --h1: 46px; --lede: 16px; --stat-size: 13px;
    --header-y: 16px; --header-x: 28px; --stats-x: 36px; --stats-y: 28px;
    --hero-gap: 64px; --copy-max: 760px; --lede-max: 500px;
    --badge-mb: 16px; --lede-mt: 14px; --actions-mt: 22px;
  }
}
@media (min-width: 901px) and (max-height: 850px) {
  :root {
    --header-y: 14px; --stats-y: 24px; --hero-gap: 48px; --h1: 44px;
    --badge-mb: 12px; --lede-mt: 12px; --actions-mt: 18px;
  }
}
@media (min-width: 901px) and (max-height: 720px) {
  :root {
    --h1: 36px; --lede: 15px; --hero-gap: 32px; --stats-y: 18px;
    --btn-h: 42px; --badge-mb: 8px;
  }
}

/* Desktop: one frame, no scroll. */
@media (min-width: 901px) {
  html, body { height: 100%; overflow: hidden; }
  .page { height: 100vh; height: 100dvh; overflow: hidden; }
}

/* Phone / small tablet */
@media (max-width: 900px) {
  :root {
    --logo: 21px; --btn: 15px; --btn-h: 50px;
    --h1: 38px; --lede: 16.5px; --badge: 13px; --stat-size: 15px;
    --header-y: 16px; --header-x: 18px; --stats-x: 20px; --stats-y: 28px;
    --hero-gap: 36px; --copy-max: 100%; --lede-max: 100%;
  }
  html, body { height: auto; overflow-y: auto; }
  .header {
    padding-top: max(var(--header-y), env(safe-area-inset-top));
    padding-left: max(var(--header-x), env(safe-area-inset-left));
    padding-right: max(var(--header-x), env(safe-area-inset-right));
  }
  .hero { padding: 20px 20px var(--hero-gap); }
  .stats { flex-direction: column; justify-content: center; gap: 16px; }
  .stat { white-space: normal; text-align: left; }
}

@media (max-width: 560px) {
  :root { --h1: 34px; --lede: 16.5px; --header-x: 16px; }
  .hero-actions { flex-direction: column; width: 100%; }
  .hero-actions .btn { width: 100%; }
}
