/* Tessera Labs — design tokens and shared styles.
   Dark, high-contrast, one metallic accent.  Motion is slow and optional. */

:root {
  --bg:        #06070c;
  --bg-2:      #0a0c14;
  --ink:       #eceef6;
  --ink-2:     #a8adc2;
  --ink-3:     #6e7490;
  --line:      rgba(255, 255, 255, .09);
  --line-2:    rgba(255, 255, 255, .055);
  --glass:     rgba(255, 255, 255, .028);
  --glass-2:   rgba(255, 255, 255, .045);

  /* the lustre: champagne into rose into violet */
  --lustre:    linear-gradient(104deg, #fbeed6 0%, #ecc9a2 26%, #dda9b6 55%, #b6a5e6 82%, #9fc8f0 100%);
  --lustre-dim:linear-gradient(104deg, #cbb996 0%, #b99a7c 30%, #a9808c 60%, #8b7fb4 100%);
  --gold:      #e9c9a0;
  --cyan:      #8fd0f0;
  --violet:    #b6a5e6;

  --serif: "Instrument Serif", "Iowan Old Style", Palatino, Georgia, serif;
  --sans:  "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Helvetica, sans-serif;
  --mono:  "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  --max: 1180px;
  --r:   14px;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  font-feature-settings: "kern" 1, "liga" 1, "cv05" 1;
  overflow-x: hidden;
}

/* Fine grain over everything: kills gradient banding, reads as expensive. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  opacity: .5;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.35'/%3E%3C/svg%3E");
}

.wrap { width: 100%; max-width: var(--max); margin: 0 auto; padding: 0 28px; }

/* ---------- type ---------- */

h1, h2, h3 { font-family: var(--serif); font-weight: 400; letter-spacing: -.015em; line-height: 1.08; margin: 0; }

h1 { font-size: clamp(2.9rem, 7.2vw, 5.4rem); }
h2 { font-size: clamp(2rem, 4.4vw, 3.2rem); }
h3 { font-size: 1.32rem; letter-spacing: -.01em; }

p { margin: 0 0 1.1em; color: var(--ink-2); }

a { color: var(--gold); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 3px; }

.lustre {
  background: var(--lustre);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  background-size: 220% 100%;
  animation: sheen 14s ease-in-out infinite;
}
@keyframes sheen {
  0%, 100% { background-position: 0% 50%; }
  50%      { background-position: 100% 50%; }
}

.eyebrow {
  /* line-height was 1, which is fine while the text fits on one line and wrong the moment it
     does not: the flex line stays one line tall and the second line of text renders outside it,
     overlapping whatever follows.  At 320px the lifecycle page's eyebrow is long enough to wrap,
     so this was two lines of text inside a 23px box.  Seventh defect found by looking at a phone
     render rather than at a status code. */
  font: 500 .72rem/1.35 var(--sans);
  letter-spacing: .19em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin: 0 0 22px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 12px;
}
/* A date must never break across lines.  "2026-09-" on one line and "09" on the next is not a
   date, and this is the same class of break as the price that read "From £300 per" / "month". */
.eyebrow time, .eyebrow .nowrap, #gen { white-space: nowrap; }
.eyebrow::before {
  content: "";
  width: 26px;
  height: 1px;
  background: linear-gradient(90deg, var(--gold), transparent);
}

.lede { font-size: 1.18rem; color: var(--ink-2); max-width: 62ch; }
.muted { color: var(--ink-3); }
.num { font-family: var(--mono); font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }

/* ---------- nav ---------- */

.nav {
  position: sticky;
  top: 0;
  z-index: 60;
  backdrop-filter: blur(16px) saturate(150%);
  -webkit-backdrop-filter: blur(16px) saturate(150%);
  background: rgba(6, 7, 12, .68);
  border-bottom: 1px solid var(--line-2);
}
.nav .wrap { display: flex; align-items: center; justify-content: space-between; height: 66px; }
.brand { display: flex; align-items: center; gap: 11px; font-family: var(--serif); font-size: 1.3rem; color: var(--ink); }
.brand:hover { text-decoration: none; }
.mark { width: 19px; height: 19px; flex: none; }
.nav nav { display: flex; gap: 28px; align-items: center; }
.nav nav a { color: var(--ink-2); font-size: .92rem; }
.nav nav a:hover { color: var(--ink); text-decoration: none; }

/* ---------- buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 13px 24px;
  border-radius: 100px;
  font: 500 .95rem/1 var(--sans);
  border: 1px solid var(--line);
  transition: transform .25s cubic-bezier(.2,.8,.2,1), border-color .25s, background .25s;
}
.btn:hover { text-decoration: none; transform: translateY(-2px); }
.btn-primary { background: var(--lustre); color: #0a0a10; border-color: transparent; font-weight: 600; }
.btn-primary:hover { box-shadow: 0 12px 34px -14px rgba(233, 201, 160, .6); }
.btn-ghost { color: var(--ink); background: var(--glass); }
.btn-ghost:hover { background: var(--glass-2); border-color: rgba(255,255,255,.16); }

/* ---------- layout ---------- */

section { position: relative; padding: 116px 0; }
.rule { height: 1px; background: linear-gradient(90deg, transparent, var(--line), transparent); border: 0; margin: 0; }

.grid { display: grid; gap: 20px; }
.g3 { grid-template-columns: repeat(3, 1fr); }
.g2 { grid-template-columns: repeat(2, 1fr); }

.card {
  background: var(--glass);
  border: 1px solid var(--line-2);
  border-radius: var(--r);
  padding: 30px;
  position: relative;
  overflow: hidden;
  transition: border-color .3s, background .3s, transform .3s cubic-bezier(.2,.8,.2,1);
}
.card::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.22), transparent);
  opacity: 0;
  transition: opacity .35s;
}
.card:hover { border-color: rgba(255,255,255,.14); background: var(--glass-2); transform: translateY(-3px); }
.card:hover::before { opacity: 1; }
.card h3 { margin-bottom: 12px; }
.card p:last-child { margin-bottom: 0; }
.card .num-big {
  font-family: var(--serif);
  font-size: 3.1rem;
  line-height: 1;
  display: block;
  margin-bottom: 14px;
  font-variant-numeric: tabular-nums;
}

/* ---------- reveal ----------
   Hidden only when scripting is available to bring it back.  Without JS the page
   is fully readable, which is also why the class is set inline in the head. */

.js .reveal { opacity: 0; transform: translateY(22px); transition: opacity .8s cubic-bezier(.2,.8,.2,1), transform .8s cubic-bezier(.2,.8,.2,1); }
.js .reveal.in { opacity: 1; transform: none; }

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

footer { padding: 76px 0 54px; border-top: 1px solid var(--line-2); }
footer .wrap { display: flex; justify-content: space-between; gap: 40px; flex-wrap: wrap; align-items: flex-end; }
footer a { color: var(--ink-2); }

@media (max-width: 880px) {
  .g3, .g2 { grid-template-columns: 1fr; }
  section { padding: 78px 0; }
  .nav nav { gap: 18px; }
  .nav nav a.hide-sm { display: none; }
  .wrap { padding: 0 20px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
  html { scroll-behavior: auto; }
  .js .reveal { opacity: 1; transform: none; }
}
