/*
 * site.css: the Tide website. Mobile first; wide layouts from 960 px.
 * Three parts on one soft, light page (js/kit/sea.js draws it, its colours drifting slowly with the
 * scroll position, never switching, with a fine grain in it): the hero, a panel; one grid of tiles
 * with everything Tide does; and the way to get it, a panel again. The tiles share the panels'
 * edges, rounding and gap, so the page reads as one set: twelve columns from 960 px, one below.
 * Room: one space (--space) on every side of every panel and between all tiles, 18 px on a phone,
 * growing evenly with the window to 64 px.
 * Dark tiles and panels (.is-dark) have their own gradient, glow and grain; Make it yours is a tile
 * in the look chosen there. Each tile's theme arrives as --tide-* variables (js/kit/colors.js
 * applyTheme), and each light tile's words as --ink and --quiet.
 *
 * The phones stand in 3D: .scene holds the camera (perspective), .rig turns the whole group, each
 * .p3 places one phone in depth, and .p3-edge gives the phone its thickness (six thin layers behind
 * the screen). A soft shadow (.p3-shade) falls behind each phone onto the page.
 */

/* Inter Tight and Inter, served from this site (variable fonts, Latin). */
@font-face { font-family: "Inter Tight"; font-style: normal; font-weight: 100 900; font-display: swap; src: url("../fonts/inter-tight.woff2") format("woff2"); }
@font-face { font-family: Inter; font-style: normal; font-weight: 100 900; font-display: swap; src: url("../fonts/inter.woff2") format("woff2"); }

/* Lenis smooth scroll: its own rules (from lenis 1.3.26, dist/lenis.css), kept here so no stylesheet loads from elsewhere. */
html.lenis, html.lenis body { height: auto; }
.lenis:not(.lenis-autoToggle).lenis-stopped { overflow: clip; }
.lenis [data-lenis-prevent], .lenis [data-lenis-prevent-wheel], .lenis [data-lenis-prevent-touch],
.lenis [data-lenis-prevent-vertical], .lenis [data-lenis-prevent-horizontal] { overscroll-behavior: contain; }
.lenis.lenis-smooth iframe { pointer-events: none; }
.lenis.lenis-autoToggle { transition-property: overflow; transition-duration: 1ms; transition-behavior: allow-discrete; }

@property --ink { syntax: '<color>'; inherits: true; initial-value: #1F1E1B; }
@property --quiet { syntax: '<color>'; inherits: true; initial-value: #4F4C46; }

:root {
  --paper: #F5F3EE;
  --ink: #1F1E1B;
  --quiet: #4F4C46;
  --shade-rgb: 16 22 38;
  --shade-a: 0.42;
  --gutter: clamp(16px, 4.6vw, 72px);
  --max: 1400px;
  --head: "Inter Tight", Inter, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --sans: Inter, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --sine: cubic-bezier(0.37, 0, 0.63, 1);
  --out: cubic-bezier(0.16, 1, 0.3, 1);
  --phone-ratio: calc(2474 / 1154);
  /* One space round and between everything: the panels' margins on every side and the gaps between
     tiles are the same, growing evenly with the window. */
  --space: clamp(18px, 2.4vw, 64px);
  --panel-m: var(--space);
  --tile-gap: var(--space);
  --panel-r: clamp(28px, 3.2vw, 56px);
  --tile-pad: clamp(28px, 3.8vw, 72px);
  /* The wordmark: its height, and the room above the hero's words (as far in from the panel's top as
     the wordmark sits from its left, then the wordmark itself). */
  --brand-h: clamp(26px, 22px + 0.65vw, 34px);
  --top-h: calc(var(--tile-pad) + var(--brand-h));
  /* Film grain: fine grey noise, laid over the page and inside the panels. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
  color-scheme: light;
  background: #D0F5F1;
}
/* Dark panels (and Make it yours in Dark or Black): light words, deeper shadows. */
.is-dark {
  --ink: #F6F4EF;
  --quiet: #D9D6CF;
  --shade-rgb: 0 0 0;
  --shade-a: 0.7;
  color-scheme: dark;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body {
  margin: 0;
  min-height: 100vh;
  color: var(--ink);
  background: transparent;
  font: 450 1rem/1.55 var(--sans);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: clip;
  font-optical-sizing: auto;
}
h1, h2, h3, p, ul, ol, figure, fieldset { margin: 0; }
ul, ol { padding: 0; list-style: none; }
a { color: inherit; }
/* Three large, very soft glows in the page's theme colours (set as the page scrolls, main.js),
   drifting on loops of a minute or more: the light page has depth but never pulls the eye. They stay
   under everything else. Once WebGL runs, js/kit/sea.js draws the same glows into the page's
   background, and these fade out (html.sea-glows) and then leave the page (main.js). */
.ambient {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  overflow: hidden;
  contain: strict;
  transition: opacity 0.8s ease;
}
.sea-glows .ambient { opacity: 0; }
.sea-glows .ambient i { animation-play-state: paused; }
.ambient i {
  position: absolute;
  width: 78vmax;
  height: 78vmax;
  border-radius: 50%;
  background: radial-gradient(closest-side, var(--c), transparent);
  opacity: 0.75;
  will-change: transform;
  animation: drift-a 74s var(--sine) infinite alternate;
}
.ambient i:nth-child(1) { --c: var(--glow-1, #9BDCD5); left: 48%; top: -34vmax; }
.ambient i:nth-child(2) { --c: var(--glow-2, #A5DDE9); left: -30vmax; top: 34%; width: 70vmax; height: 70vmax; animation-name: drift-b; animation-duration: 88s; }
.ambient i:nth-child(3) { --c: var(--glow-3, #F2FBF9); left: 30%; top: 58%; width: 64vmax; height: 64vmax; opacity: 0.9; animation-name: drift-c; animation-duration: 66s; }
@keyframes drift-a { to { transform: translate(-12vmax, 10vmax) scale(1.1); } }
@keyframes drift-b { to { transform: translate(14vmax, -8vmax) scale(0.92); } }
@keyframes drift-c { to { transform: translate(-10vmax, -12vmax) scale(1.08); } }
/* The breath's light over the whole page, round the breathing phone: it follows the recording's own
   light, softly while it plays and fuller while breathing along (main.js sets the strength). */
.page-breath {
  position: fixed;
  inset: 0;
  z-index: 45;
  pointer-events: none;
  background: radial-gradient(circle at var(--bx, 50%) var(--by, 50%), rgb(120 236 222 / 0.6), rgb(44 196 184 / 0.22) 34%, rgb(0 92 115 / 0.08) 58%, transparent 78%);
  mix-blend-mode: screen;
  opacity: var(--breath-light, 0);
  visibility: hidden;
  transition: opacity 0.3s linear, visibility 0s linear 0.3s;
}
.page-breath.is-lit { visibility: visible; transition: opacity 0.3s linear; }
/* Phones and tablets scroll natively; a jump to a part glides there (Lenis does it with a mouse). */
@media (prefers-reduced-motion: no-preference) { html:not(.lenis) { scroll-behavior: smooth; } }
img, video, canvas, svg { display: block; max-width: 100%; }
button { font: inherit; color: inherit; }
:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; border-radius: 8px; }
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
/* A word joined with a hyphen that should not break at it, such as "App-Symbole". */
.nobr { white-space: nowrap; }
.skip { position: absolute; left: var(--gutter); top: -60px; z-index: 100; padding: 10px 16px; border-radius: 999px; background: var(--ink); color: var(--paper); text-decoration: none; font-weight: 600; }
.skip:focus { top: 12px; }
.wrap { width: min(100% - 2 * var(--gutter), var(--max)); margin-inline: auto; }

/* ---- Type ---------------------------------------------------------------------------------- */

/* Bold and large, with room under every line so g, p and y are never cut: line-height 1.04 or
   more, padding under the last line, and nothing around them clips. */
.hero-title, .h-xl {
  font-family: var(--head);
  font-weight: 700;
  text-wrap: balance;
  padding-bottom: 0.1em;
  word-spacing: 0.04em;
}
.h-xl {
  font-size: clamp(2.625rem, 1.3rem + 5vw, 6rem);
  line-height: 1.02;
  letter-spacing: -0.034em;
  max-width: 11ch;
}
.lead {
  font-size: clamp(1.1875rem, 1.05rem + 0.55vw, 1.5rem);
  line-height: 1.45;
  font-weight: 450;
  color: var(--quiet);
  max-width: 28ch;
  text-wrap: pretty;
}
.h-xl + .lead { margin-top: clamp(12px, 2.2svh, 24px); }
.note { font-size: 1rem; line-height: 1.5; text-wrap: pretty; }

/* ---- Buttons ------------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 58px;
  padding: 0 2em;
  border: 0;
  border-radius: 999px;
  background: #13201F;
  color: #F5F3EE;
  font: 600 1.125rem/1 var(--sans);
  letter-spacing: -0.005em;
  text-decoration: none;
  cursor: pointer;
  box-shadow: 0 1px 0 rgb(255 255 255 / 0.14) inset, 0 18px 36px -16px rgb(10 40 38 / 0.6);
  transition: background-color 0.35s var(--sine);
}
.btn:hover { background: #24423F; }

/* ---- Header: the wordmark alone, no box; light while a dark panel is behind it ------------- */

.top {
  position: fixed;
  /* The wordmark sits as far into the hero panel from its top edge as from its left edge (the
     tiles' padding), so its corner of the panel has the same room both ways, at every width. Its
     own layer in the look switch's circle (view-transition-name), so it stays on top throughout. */
  inset: 0 0 auto;
  z-index: 50;
  display: flex;
  padding: calc(var(--panel-m) + var(--tile-pad)) calc(var(--panel-m) + var(--tile-pad)) 0;
  pointer-events: none;
  transition: translate 0.6s var(--out);
  view-transition-name: top;
}
.top.is-away { translate: 0 -100%; }
/* The wordmark (design/brand/wordmark.svg) as outlines: Inter Tight Bold, each pair of letters
   spaced by eye for this size, the same in every browser and before the fonts arrive. Its box is
   the letters' own edges, so it lines up exactly with the words below it. */
.brand {
  pointer-events: auto;
  display: block;
  color: var(--brand-ink, #1C424E);
  border-radius: 6px;
  transition: color 0.35s var(--sine);
}
.brand-mark { display: block; height: var(--brand-h); width: auto; overflow: visible; }
.top.on-dark .brand { color: #F6F4EF; }
.brand:focus-visible { outline-offset: 6px; }

/* ---- Parts --------------------------------------------------------------------------------- */

.part {
  position: relative;
  color: var(--ink);
  min-height: 100svh;
  display: grid;
  align-items: center;
  padding-block: calc(var(--top-h) + clamp(28px, 4.4svh, 56px)) clamp(40px, 7svh, 88px);
}

/* The panels: nearly the page's width, generously rounded, each with its own ground, glow and
   grain. Scrolling into one is a panel arriving, not the page changing colour. */
.panel {
  --gutter: max(var(--tile-pad), clamp(16px, 4.6vw, 72px));
  margin: var(--space);
  min-height: calc(100svh - 2 * var(--space));
  border-radius: var(--panel-r);
  isolation: isolate;
  overflow: clip;
  background: var(--panel-bg);
  box-shadow: 0 40px 90px -50px rgb(var(--panel-shadow, 14 40 44) / 0.55);
}
.panel::before, .tile.is-dark::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -2;
  border-radius: inherit;
  background: var(--grain);
  background-size: 180px;
  opacity: 0.16;
  mix-blend-mode: soft-light;
  pointer-events: none;
}
@media (hover: none) { .panel::before, .tile.is-dark::before { content: none; } }
/* A slow glow drifting inside each dark panel and tile. */
.panel.is-dark::after, .tile.is-dark::after {
  content: "";
  position: absolute;
  z-index: -3;
  width: 90%;
  height: 90%;
  left: var(--glow-x, 50%);
  top: var(--glow-y, 40%);
  translate: -50% -50%;
  background: radial-gradient(closest-side, var(--panel-glow), transparent);
  pointer-events: none;
  animation: panel-glow 40s var(--sine) infinite alternate;
}
@keyframes panel-glow { 50% { transform: translate(5%, 4%) scale(1.08); } 100% { transform: translate(-4%, 2%) scale(0.96); } }
.breathe {
  --panel-bg: radial-gradient(70% 60% at 0% 100%, color-mix(in oklab, var(--tide-shallow, #2CC4B8) 10%, transparent), transparent 70%),
    linear-gradient(165deg, var(--tide-top, #002826), var(--tide-bottom, #001112) 62%, #050807);
  --panel-glow: color-mix(in oklab, var(--tide-deep, #005C73) 48%, transparent);
  --panel-shadow: 0 30 34;
  --glow-x: 66%; --glow-y: 48%;
}
.insights {
  --panel-bg: radial-gradient(60% 50% at 100% 0%, color-mix(in oklab, var(--tide-shallow, #4F9CEB) 12%, transparent), transparent 70%),
    linear-gradient(200deg, var(--tide-top, #081C36), var(--tide-bottom, #03091E) 70%);
  --panel-glow: color-mix(in oklab, var(--tide-deep, #2043A3) 50%, transparent);
  --panel-shadow: 6 14 40;
  --glow-x: 34%; --glow-y: 50%;
}
.close {
  --panel-bg: radial-gradient(80% 60% at 50% 100%, color-mix(in oklab, var(--tide-deep, #2043A3) 26%, transparent), transparent 75%),
    linear-gradient(180deg, #05080F, #020306);
  --panel-glow: color-mix(in oklab, var(--tide-deep, #2043A3) 30%, transparent);
  --panel-shadow: 4 8 20;
  --glow-x: 50%; --glow-y: 60%;
}
@media (max-width: 959.98px) { .breathe, .insights { --glow-y: 64%; --glow-x: 50%; } }

/* ---- The 3D phones ------------------------------------------------------------------------- */

.stage { position: relative; display: grid; place-items: center; width: 100%; }
.scene {
  position: relative;
  width: 100%;
  height: 100%;
  perspective: var(--persp, 2000px);
  perspective-origin: 50% 45%;
  display: grid;
  place-items: center;
}
.rig, .p3, .p3-body, .p3-edge { transform-style: preserve-3d; }
.p3 {
  --u: calc(var(--device-w) / 1154);
  --h: calc(var(--device-w) * var(--phone-ratio));
  grid-area: 1 / 1;
  position: relative;
  width: var(--device-w);
  height: var(--h);
  transform:
    translate3d(calc(var(--x, 0) * var(--device-w)), calc(var(--y, 0) * var(--h) + var(--lift, 0px)), calc(var(--z, 0) * var(--device-w)))
    rotateX(var(--rx, 0deg))
    rotateY(calc(var(--ry, 0deg) + var(--sp, 0) * var(--spin, 0deg)))
    rotateZ(var(--rz, 0deg));
}
.p3-body { position: absolute; inset: 0; }
.p3-body > .device { position: absolute; inset: 0; }
/* Six thin layers behind the screen: the phone's side, light at the top and darker below. */
.p3-edge, .p3-edge::before, .p3-edge::after {
  position: absolute;
  inset: 0;
  border-radius: calc(var(--u) * 141);
  background: linear-gradient(180deg, #8C8F96, #45474D 45%, #2A2B30);
  transform: translateZ(calc(var(--u) * -11));
}
.p3-edge::before, .p3-edge::after { content: ""; }
.p3-edge::after { transform: translateZ(calc(var(--u) * -22)); }
.p3-edge--2 { transform: translateZ(calc(var(--u) * -44)); }
/* The shadow on the page behind the phone: soft and wide, falling down and a little right. */
.p3-shade {
  position: absolute;
  inset: 3% 5% 1%;
  border-radius: calc(var(--u) * 200);
  background: rgb(var(--shade-rgb) / var(--shade-a));
  filter: blur(calc(var(--u) * 70));
  transform: translate3d(calc(var(--u) * 70), calc(var(--u) * 150), calc(var(--u) * -320));
  transition: background 0.6s var(--sine);
}
.p3 .device { box-shadow: 0 0 0 calc(var(--u) * 1.6) rgb(30 31 35); }

/* ---- 1. Hero: a still black panel, the brand's own night, and three real phones rising out of
   its lower edge in the breath's light ------------------------------------------------------- */

.hero {
  --panel-bg: radial-gradient(70% 55% at 50% 78%, color-mix(in oklab, var(--tide-deep, #005C73) 34%, transparent), transparent 75%),
    linear-gradient(180deg, #030607, #000);
  --panel-glow: color-mix(in oklab, var(--tide-deep, #005C73) 34%, transparent);
  --panel-shadow: 0 20 24;
  --glow-x: 50%; --glow-y: 72%;
  /* Framed by the same space on every side; the wordmark sits inside it. */
  padding-bottom: 0;
  align-items: stretch;
}
.hero-grid { display: flex; flex-direction: column; align-items: center; text-align: center; }
.hero-copy { display: grid; justify-items: center; position: relative; z-index: 3; }
/* Always one line: three words never leave one alone on a second line. The size follows the
   width (the line is about 7.9 times its size, 9.1 in German) and the height, so the phones still
   rise below. */
.hero-title {
  --fit: 8.2;
  position: relative;
  z-index: 3;
  font-size: min(11.5rem, calc((min(100vw, var(--max) + 2 * var(--gutter)) - 2 * var(--gutter) - 2 * var(--panel-m)) / var(--fit)), 17svh);
  line-height: 1.04;
  letter-spacing: -0.046em;
  white-space: nowrap;
}
:lang(de) .hero-title { --fit: 9.4; }
.hero-lead { margin: clamp(10px, 1.8svh, 20px) auto 0; max-width: 30ch; }
.hero-copy .btn { margin-top: clamp(22px, 3.4svh, 36px); }
/* The call to action on the dark panels: light, with a soft glow of the brand's teal. */
.btn--light { background: #F2F0EA; color: #0E1716; box-shadow: 0 18px 40px -16px rgb(44 196 184 / 0.45); }
.btn--light:hover { background: #FFFFFF; }

/* The phones stand from the top of the space left under the words; the panel cuts them off. */
.trio {
  --device-w: min(330px, 58vw);
  position: relative;
  width: 100%;
  flex: 1 0 calc(var(--device-w) * 1.5);
  margin-top: clamp(20px, 4svh, 48px);
  isolation: isolate;
}
.trio .scene { position: absolute; inset: 0; --persp: 1500px; place-items: start center; }
.trio .rig { grid-area: 1 / 1; display: grid; place-items: center; align-self: start; }
.trio-front { --x: 0.04; --y: 0.04; --z: 0; --rx: 7deg; --ry: -22deg; --rz: 4deg; --lift: calc(var(--sp, 0) * -40px); }
.trio-left  { --x: -0.5; --y: -0.05; --z: -0.9; --rx: 7deg; --ry: -22deg; --rz: 4deg; --lift: calc(var(--sp, 0) * 50px); }
.trio-right { --x: 0.54; --y: -0.1; --z: -1.6; --rx: 7deg; --ry: -22deg; --rz: 4deg; --lift: calc(var(--sp, 0) * 110px); }
.glow-canvas { position: absolute; z-index: -1; pointer-events: none; }
/* A still halo of the theme's colour behind the phones, under the breath's moving light. */
.trio::before {
  content: "";
  position: absolute;
  z-index: -2;
  left: 50%;
  top: 55%;
  width: calc(var(--device-w) * 5);
  height: calc(var(--device-w) * 4);
  translate: -50% -50%;
  background: radial-gradient(closest-side, rgb(44 196 184 / 0.22), rgb(0 92 115 / 0.12) 50%, transparent);
  pointer-events: none;
}
.hero-glow { left: 50%; top: 45%; width: min(1100px, 190vw); height: min(1100px, 190vw); translate: -50% -50%; }

@media (min-width: 960px) {
  .hero-lead { font-size: clamp(1.375rem, 1rem + 0.7vw, 1.75rem); max-width: 34ch; }
  .trio { --device-w: min(420px, 26svh + 140px); flex-basis: calc(var(--device-w) * 1.1); }
  .trio-left { --x: -0.85; --y: -0.04; }
  .trio-right { --x: 0.95; --y: -0.08; }
  .hero-glow { width: min(1300px, 150svh); height: min(1300px, 150svh); }
}

/* The hero comes in once: words, then the phones rising into their light. */
@keyframes rise-in { from { opacity: 0; translate: 0 30px; } }
@keyframes fade-in { from { opacity: 0; } }
@keyframes stand-up { from { opacity: 0; transform: translateY(60px) scale(0.96); } }
.js .hero-title, .js .hero-copy > * { animation: rise-in 1.2s var(--out) both; }
.js .hero-copy > :nth-child(1) { animation-delay: 0.08s; }
.js .hero-copy > :nth-child(2) { animation-delay: 0.16s; }
.js .trio .scene { animation: stand-up 1.8s var(--out) 0.25s both; }
.js .hero-glow { animation: fade-in 2.4s var(--sine) 0.2s both; }
/* Then they float, very slowly, as if on water. */
@keyframes float { 50% { translate: 0 calc(var(--device-w) * -0.035); } }
.js .trio .rig { animation: float 7s var(--sine) 2s infinite; }

/* ---- 2. The tiles: one grid, on the panels' edges, rounding and gap ------------------------ */

.features { min-height: 0; display: block; padding: 0; }
.tiles {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space);
  margin: var(--space);
}
.tile {
  position: relative;
  container-type: inline-size;
  isolation: isolate;
  overflow: clip;
  min-width: 0;
  padding: var(--tile-pad);
  border-radius: var(--panel-r);
  color: var(--ink);
  background: var(--tile-bg, linear-gradient(170deg, rgb(255 255 255 / 0.62), rgb(255 255 255 / 0.4)));
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.6), 0 34px 70px -50px rgb(var(--panel-shadow, 30 60 60) / 0.5);
}
.tile.is-dark {
  --tile-bg: var(--panel-bg);
  box-shadow: 0 40px 90px -50px rgb(var(--panel-shadow, 14 40 44) / 0.55);
}
@media (min-width: 960px) {
  .tiles { grid-template-columns: repeat(12, minmax(0, 1fr)); }
  .tile--12 { grid-column: span 12; }
  .tile--7 { grid-column: span 7; }
  .tile--5 { grid-column: span 5; }
  .tile--4 { grid-column: span 4; }
}

/* One type scale for every tile: a title, one line under it. */
.h-tile {
  font: 700 clamp(2rem, 1.25rem + 2.3vw, 3.5rem)/1.04 var(--head);
  letter-spacing: -0.032em;
  word-spacing: 0.04em;
  text-wrap: balance;
  padding-bottom: 0.08em;
  max-width: 14ch;
}
.h-tile--small { font-size: clamp(1.5rem, 1.2rem + 0.9vw, 2.125rem); letter-spacing: -0.024em; }
.tile-lead {
  margin-top: clamp(12px, 1.4vw, 20px);
  font-size: clamp(1.0625rem, 0.98rem + 0.3vw, 1.25rem);
  line-height: 1.45;
  color: var(--quiet);
  max-width: 32ch;
  text-wrap: pretty;
}
.tile-text { position: relative; z-index: 2; }

/* Words beside a phone once the tile is wide enough, above it before that. */
.tile-split { display: grid; gap: clamp(28px, 5cqi, 56px); align-items: center; height: 100%; }
@container (min-width: 600px) {
  .tile-split { grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); }
}

/* ---- Breathe first ------------------------------------------------------------------------- */

.breath-stage {
  --device-w: min(290px, 62cqi);
  height: calc(var(--device-w) * var(--phone-ratio) * 1.04);
}
.breath-stage .scene { position: absolute; inset: 0; --persp: 1400px; }
.breath-phone { --spin: 10deg; --rx: 5deg; --ry: -14deg; --rz: 2deg; --lift: calc(var(--sp, 0) * 30px); }
/* The light of the breath itself, taken from the video as it plays and spread wide behind it. */
.spill {
  position: absolute;
  z-index: -1;
  left: 50%;
  top: 50%;
  width: calc(var(--device-w) * 3.4);
  height: calc(var(--device-w) * 3.4);
  translate: -50% -50%;
  filter: blur(calc(var(--device-w) * 0.16)) saturate(1.9) brightness(1.9) contrast(1.15);
  opacity: 0.95;
  pointer-events: none;
  mask-image: radial-gradient(circle closest-side, #000 30%, transparent);
}
.device > video { background: #072523; }
/* The screen is a button: a tap pauses the recording, or plays it where motion is reduced. */
.screen-tap {
  position: absolute;
  inset: calc(var(--u) * 37);
  z-index: 3;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: calc(var(--u) * 104);
  background: transparent;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.screen-tap:focus-visible { outline: 2px solid #F6F4EF; outline-offset: 4px; }
.breathe-along { margin-top: clamp(24px, 5cqi, 36px); min-height: 52px; font-size: 1.0625rem; }
.breath-cue {
  min-height: 1.2em;
  margin-top: clamp(14px, 3cqi, 22px);
  font: 700 clamp(1.75rem, 1.2rem + 2.2cqi, 2.75rem)/1.1 var(--head);
  letter-spacing: -0.025em;
  color: var(--ink);
  transition: opacity 0.6s var(--sine);
}
.breath-cue:empty { opacity: 0; }

/* ---- Mood ---------------------------------------------------------------------------------- */

/* A chosen face tints this tile only: a soft wash of its colour, fading out before the edges. */
@property --mood-tint { syntax: '<color>'; inherits: true; initial-value: transparent; }
.mood { transition: --mood-tint 1.2s var(--sine); }
.mood::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: radial-gradient(80% 60% at 50% 30%, var(--mood-tint), transparent 72%);
  pointer-events: none;
}
.faces {
  margin-top: clamp(16px, 4cqi, 28px);
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: clamp(2px, 1.2cqi, 12px);
  width: min(100%, 460px);
}
.face {
  display: grid;
  justify-items: center;
  gap: 8px;
  padding: 8px 0 6px;
  border: 0;
  border-radius: 22px;
  background: transparent;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.face svg {
  width: clamp(44px, 12cqi, 72px);
  height: auto;
  filter: drop-shadow(0 10px 14px rgb(96 43 50 / 0.18));
  transition: scale 0.6s var(--out), opacity 0.5s var(--sine), translate 0.6s var(--out);
}
.faces.has-choice .face svg { opacity: 0.45; scale: 0.9; }
.faces.has-choice .face[aria-checked="true"] svg { opacity: 1; scale: 1.14; translate: 0 -4px; }
.face span { font: 550 0.875rem/1.2 var(--sans); color: var(--quiet); transition: color 0.4s; }
.face[aria-checked="true"] span { color: var(--ink); }
.face:focus-visible { outline-offset: 0; }
.try {
  position: relative;
  isolation: isolate;
  margin-top: clamp(20px, 4cqi, 28px);
  display: flex;
  align-items: center;
  gap: 10px;
  font: 600 0.9375rem/1.3 var(--sans);
  color: var(--ink);
  transition: opacity 0.5s var(--sine);
}
.try::before {
  content: "";
  flex: none;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--ink);
}
.try::after {
  content: "";
  position: absolute;
  z-index: -1;
  left: 0;
  top: 50%;
  width: 9px;
  height: 9px;
  margin-top: -4.5px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--ink) 35%, transparent);
  pointer-events: none;
  animation: ping 2.2s var(--sine) infinite;
}
@keyframes ping {
  0% { transform: scale(1); opacity: 1; }
  70%, 100% { transform: scale(3.7); opacity: 0; }
}
.tile:has(.faces.has-choice) .try { opacity: 0; }
.tile:has(.faces.has-choice) .try::after { animation: none; }
@keyframes nudge { 40% { translate: 0 -8px; } }
.js .mood.is-in .face svg { animation: nudge 0.9s var(--out) calc(0.7s + var(--i, 0) * 0.11s); }
/* The two phones rise out of the tile's lower edge, which cuts them off, as in the hero. */
.duo {
  --device-w: min(220px, 40cqi);
  height: calc(var(--device-w) * var(--phone-ratio) * 0.62);
  margin: clamp(24px, 6cqi, 44px) 0 calc(-1 * var(--tile-pad));
}
.duo .scene { position: absolute; inset: 0; --persp: 1600px; place-items: start center; }
/* Far enough apart that the month behind shows almost whole beside the question in front. */
.duo-front { --spin: 8deg; --x: -0.5; --y: 0.05; --z: 0; --rx: 4deg; --ry: 16deg; --rz: -2deg; --lift: calc(var(--sp, 0) * -30px); }
.duo-back  { --spin: 8deg; --x: 0.62; --y: -0.08; --z: -0.7; --rx: 4deg; --ry: 16deg; --rz: -2deg; --lift: calc(var(--sp, 0) * 60px); }

/* ---- Just words ---------------------------------------------------------------------------- */

.words { display: grid; justify-items: center; text-align: center; }
.words-title { max-width: none; }
.words-tour {
  --device-w: min(250px, 52vw);
  --annot-gap: 14px;
  --annot-min-room: 8.5rem;
  position: relative;
  margin-top: clamp(24px, 4cqi, 44px);
  width: 100%;
  justify-items: start;
}
.words-tour .annotated-notes { text-align: left; }
@media (max-width: 379.98px) { .words-tour { --device-w: min(250px, 50vw); --annot-gap: 10px; --annot-min-room: 7.25rem; } .words-tour.annotated[data-mode="wide"] .annotated-notes b { font-size: 0.9375rem; } }
.words-tour.annotated[data-mode="wide"] .annotated-notes b { font-size: 1rem; line-height: 1.25; }
.words-tour.annotated[data-mode="wide"] .annotated-notes span { font-size: 0.875rem; }
@media (min-width: 960px) {
  .words-tour {
    --device-w: min(320px, 24vw);
    --annot-gap: clamp(28px, 3vw, 56px);
    --annot-label-w: 16rem;
    width: min(100%, calc(var(--device-w) + 2 * 20rem));
    justify-items: center;
  }
  .words-tour.annotated[data-mode="wide"] .annotated-notes b { font-size: 1.375rem; line-height: 1.25; }
  .words-tour.annotated[data-mode="wide"] .annotated-notes span { font-size: 1.0625rem; }
  .words-tour [data-placed="left"] { text-align: right; }
}
.annotated { --annot-dot: var(--tide-key, #1F1E1B); --annot-dot-ink: var(--tide-on-key, #F5F3EE); }
.annotated-notes b { font-family: var(--head); font-weight: 650; letter-spacing: -0.015em; }
.words-tour.annotated { --annot-dot: #ECE9E2; --annot-dot-ink: #121211; --annot-quiet: var(--quiet); }
.words .device { --device-shadow-rgb: 18 60 36; }

/* ---- Focus, Slow mornings, Notes: tiles set in words --------------------------------------- */

.tile--type {
  /* A faint wash of the tile's own colour over the light tile. */
  --tile-bg: linear-gradient(165deg, color-mix(in oklab, var(--figure) 10%, rgb(255 255 255 / 0.74)), color-mix(in oklab, var(--figure) 4%, rgb(255 255 255 / 0.42)));
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: clamp(28px, 6cqi, 48px);
  min-height: clamp(220px, 21vw, 320px);
}
.tile-figure {
  font: 700 clamp(3rem, 2.2rem + 2.4vw, 4.75rem)/1 var(--head);
  letter-spacing: -0.045em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--figure, var(--ink));
}
.todo { display: grid; gap: 12px; font: 500 clamp(1.0625rem, 1rem + 0.4vw, 1.3125rem)/1.3 var(--sans); }
.todo li { display: flex; gap: 12px; align-items: center; }
.todo li::before {
  content: "";
  flex: none;
  width: 1.1em;
  height: 1.1em;
  border-radius: 0.3em;
  box-shadow: inset 0 0 0 2px var(--quiet);
}
.todo .is-done { color: var(--quiet); text-decoration: line-through; text-decoration-thickness: 1.5px; }
.todo .is-done::before {
  box-shadow: none;
  background: var(--figure, var(--ink)) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-7' fill='none' stroke='%23fff' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 72% no-repeat;
}
#focus { --figure: #0E6B63; }
#mornings { --figure: #8A5A1E; }
#notes { --figure: #2F6B3A; }

/* ---- Insights: the chart, lifted out of the phone ------------------------------------------ */

.insight-stage {
  --device-w: min(260px, 54cqi);
  height: calc(var(--device-w) * var(--phone-ratio) * 1.04);
}
.insight-stage .scene { position: absolute; inset: 0; --persp: 1300px; }
.insight-phone { --spin: -10deg; --x: 0.1; --rx: 8deg; --ry: 26deg; --rz: -3deg; --lift: calc(var(--sp, 0) * 30px); }
.pop {
  /* The card "When you use your phone": x 56 to 1024 and y 852 to 2088 of the capture. */
  position: absolute;
  left: calc(var(--u) * (37 + 56));
  top: calc(var(--u) * (37 + 852));
  width: calc(var(--u) * 968);
  aspect-ratio: 968 / 1236;
  overflow: hidden;
  border-radius: calc(var(--u) * 52);
  transform: translateZ(calc(var(--u) * 300)) translateX(calc(var(--u) * 150));
  box-shadow: 0 2px 6px rgb(0 0 0 / 0.3), 0 calc(var(--u) * 60) calc(var(--u) * 140) calc(var(--u) * -20) rgb(0 0 0 / 0.75);
  outline: 1px solid rgb(255 255 255 / 0.08);
}
.slot {
  /* Where the card was: the screen's own background, so the card reads as lifted out of it. */
  position: absolute;
  left: calc(var(--u) * (37 + 56));
  top: calc(var(--u) * (37 + 852));
  width: calc(var(--u) * 968);
  aspect-ratio: 968 / 1236;
  border-radius: calc(var(--u) * 52);
  background: linear-gradient(#07152E, #040B22);
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.07);
  transform: translateZ(calc(var(--u) * 1));
}
.pop img {
  position: absolute;
  max-width: none;
  height: auto;
  width: calc(100% * 1080 / 968);
  left: calc(-100% * 56 / 968);
  top: 0;
  margin-top: calc(-100% * 852 / 968);
}

/* ---- Private ------------------------------------------------------------------------------- */

.private {
  --panel-bg: radial-gradient(80% 60% at 50% 100%, color-mix(in oklab, var(--tide-deep, #2043A3) 24%, transparent), transparent 75%),
    linear-gradient(180deg, #070B14, #020306);
  --panel-glow: color-mix(in oklab, var(--tide-deep, #2043A3) 26%, transparent);
  --panel-shadow: 4 8 20;
  --glow-x: 50%; --glow-y: 70%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(14px, 2.5cqi, 22px);
}
.private-list {
  display: grid;
  font: 700 clamp(2.5rem, 1.4rem + 2.8vw, 4.25rem)/1.03 var(--head);
  letter-spacing: -0.04em;
  padding-bottom: 0.08em;
}
.private .tile-lead { max-width: 26ch; }

/* ---- Make it yours ------------------------------------------------------------------------- */

/* The tile wears Plain in the chosen look (four colours from js/kit/colors.js seaColors). */
.yours {
  --panel-bg: radial-gradient(70% 60% at 12% 8%, var(--yours-2, #FAF6ED), transparent 70%),
    radial-gradient(60% 55% at 92% 30%, var(--yours-3, #F2EBDD), transparent 70%),
    radial-gradient(70% 55% at 70% 100%, var(--yours-1, #EFE2CA), transparent 72%), var(--yours-0, #F6EEDF);
  --tile-bg: var(--panel-bg);
  --panel-shadow: 70 60 40;
  view-transition-name: yours;
  padding-inline: 0;
}
.yours:not(.is-dark) { box-shadow: 0 40px 90px -50px rgb(70 60 40 / 0.35), inset 0 0 0 1px rgb(255 255 255 / 0.5); }
.yours.is-dark { --panel-shadow: 0 0 0; }
.yours-inner { display: grid; justify-items: center; text-align: center; width: 100%; }
.center-head { display: grid; justify-items: center; }
.center-head > :not(.looks-switch) { margin-inline: var(--tile-pad); }
.center-head .h-tile { max-width: none; }
.center-head .tile-lead { max-width: 34ch; }
.looks-switch {
  margin-top: clamp(22px, 3.5cqi, 32px);
  max-width: calc(100% - 24px);
  display: inline-flex;
  padding: 5px;
  border: 0;
  border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 9%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 8%, transparent);
}
.looks-switch label { position: relative; }
.looks-switch input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.looks-switch span { display: block; padding: 0.875em 1.35em; border-radius: 999px; font: 600 1rem/1 var(--sans); color: var(--ink); opacity: 0.78; transition: background 0.35s ease, color 0.35s ease, opacity 0.35s; }
@media (max-width: 379.98px) { .looks-switch span { padding-inline: 1em; } }
/* The German names are longer, so the switch tightens sooner to stay inside the tile. */
@media (max-width: 439.98px) { :lang(de) .looks-switch span { padding-inline: 1em; } }
@media (max-width: 399.98px) { :lang(de) .looks-switch span { padding-inline: 0.75em; } }
.looks-switch input:checked + span { background: var(--ink); color: var(--paper); opacity: 1; }
.is-dark .looks-switch input:checked + span { color: #121211; }
.looks-switch input:focus-visible + span { outline: 2px solid var(--ink); outline-offset: 2px; }

/* Phones: a swipe row; once the tile is wide enough, all seven stand in one calm arc, turned a little
   towards the middle. */
.row {
  --device-w: min(220px, 58cqi);
  width: 100%;
  margin-top: clamp(24px, 4.5cqi, 44px);
  display: flex;
  gap: 18px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding: 10px calc(50% - var(--device-w) / 2) 8px;
  scrollbar-width: none;
  outline: none;
}
.row::-webkit-scrollbar { display: none; }
.row-phone {
  scroll-snap-align: center;
  --device-shadow-rgb: var(--shade-rgb);
}
.row-phone img { transition: opacity 0.4s var(--sine); }
@container (min-width: 900px) {
  .row {
    --device-w: min(200px, calc((100cqi - 2 * var(--tile-pad) - 6 * 24px) / 7));
    overflow: visible;
    justify-content: center;
    gap: clamp(16px, 2cqi, 32px);
    padding: 20px var(--tile-pad) 18px;
    perspective: 2400px;
  }
  .row-phone { transform: translateY(var(--arc-y, 0)) rotateY(var(--arc-r, 0deg)); }
  .row-phone:nth-child(1) { --arc-r: 18deg; --arc-y: 30px; }
  .row-phone:nth-child(2) { --arc-r: 12deg; --arc-y: 13px; }
  .row-phone:nth-child(3) { --arc-r: 6deg; --arc-y: 3px; }
  .row-phone:nth-child(5) { --arc-r: -6deg; --arc-y: 3px; }
  .row-phone:nth-child(6) { --arc-r: -12deg; --arc-y: 13px; }
  .row-phone:nth-child(7) { --arc-r: -18deg; --arc-y: 30px; }
}

/* ---- 3. The way to get it ------------------------------------------------------------------ */

.close { text-align: center; padding-bottom: 0; grid-template-rows: 1fr auto; min-height: clamp(520px, 78svh, 860px); }
.close-glow { left: 50%; top: 58%; width: min(1300px, 190vw); height: min(1300px, 190vw); translate: -50% -50%; }
.close-inner { position: relative; z-index: 1; display: grid; justify-items: center; align-self: center; }
.close-mark { width: clamp(84px, 9vw, 120px); height: auto; overflow: visible; }
.close-title { margin-top: clamp(8px, 1.6svh, 18px); max-width: 12ch; }
.close-inner .btn { margin-top: clamp(26px, 4svh, 40px); }
.close-inner .note { margin-top: 18px; }
.fine { position: relative; z-index: 1; padding: 0 0 max(18px, env(safe-area-inset-bottom)); }
.fine-line {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: baseline;
  gap: 0 28px;
  padding-top: 8px;
  border-top: 1px solid rgb(246 244 239 / 0.16);
  font-size: 0.875rem;
  line-height: 1.5;
  letter-spacing: 0.005em;
}
/* Each link as tall as a finger needs (44 px), though the words stay small. */
.fine a { display: inline-flex; align-items: center; min-height: 44px; padding-inline: 2px; text-decoration: none; font-weight: 550; }
.fine a:hover { text-decoration: underline; text-underline-offset: 0.2em; }
@media (min-width: 960px) { .fine-line { justify-content: flex-start; } }

/* ---- Without script: one soft gradient down the page; the panels bring their own ----------- */

html:not(.js) body { background: linear-gradient(180deg, #D0F5F1, #DAF4E2 30%, #FFE7DF 60%, #F0E9FB); }

/* ---- Off screen, nothing moves by itself (main.js sets .is-off on each part and tile) ------- */

.is-off::after, .is-off .rig, .is-off .try::after { animation-play-state: paused; }

/* ---- Reveals -------------------------------------------------------------------------------- */

.js .rise { opacity: 0; translate: 0 32px; transition: opacity 1s var(--sine), translate 1.3s var(--out); }
.js .rise.is-in { opacity: 1; translate: 0 0; }
@media (prefers-reduced-motion: reduce) {
  .js .rise { opacity: 1; translate: none; transition: none; }
  .js .hero-title, .js .hero-copy > *, .js .trio .scene, .js .hero-glow, .js .trio .rig { animation: none; }
  .btn { transition: none; }
  .panel.is-dark::after, .tile.is-dark::after, .ambient i, .try::after, .js .mood.is-in .face svg { animation: none; }
}

/* The circle that opens into a new look in Make it yours (a view transition of that panel only).
   The old panel stays as it was and the new one, in its final colours, opens over it: no crossfade.
   The rest of the page does not change. */
::view-transition-old(root), ::view-transition-new(root),
::view-transition-old(yours), ::view-transition-new(yours) { animation: none; mix-blend-mode: normal; }
::view-transition-group(yours) { animation: none; }
/* The wordmark stays above the circle the whole time, and takes its new colour as the circle
   passes over it (main.js opens its new state with the same circle). */
::view-transition-old(top), ::view-transition-new(top) { animation: none; mix-blend-mode: normal; }
::view-transition-group(top) { animation: none; }
:active-view-transition .brand { transition: none; }
