/* memoe: website styles.
   Muted liquid glass over one still, nearly solid dusty blue-grey field. Grey first, one
   restrained accent, the user's own photographs are the most colorful thing on the page. Every color, radius, space
   and size comes from /assets/brand.css, which tools/brand/build.py generates from brand/brand.json
   (load it first). Nothing here uses the legacy v1 variables. The few names under "site-only" below are
   roles built from tokens or sizes only this site needs; they are not brand values.

   Reusable classes: .glass .glass-strong .hero-title .section-title
                     .button-primary .button-secondary .photo-card

   Two layouts, one rule: the demo's flanks (on either side of the centred first-screen column) appear from 1000 px
   wide; below that the demo folds under the column into one composition (see "the first screen").
   */

/* ---------- roles built from tokens (site-only) ---------- */
:root {
  --fg: var(--ink);                        /* text */
  --fg-2: var(--slate-700);                /* secondary text: slate, about 7:1 on the field */
  --fg-3: var(--slate-700);                /* secondary text on frosted glass */
  --link: var(--ink);                      /* links are underlined graphite */
  --hairline: color-mix(in srgb, var(--slate-700) 14%, transparent);
  --ease: cubic-bezier(.2, .7, .2, 1);
  --header-h: 60px;
  --gutter: clamp(var(--space-margin), 6vw, 112px);   /* about 6% either side, as in the design */
  --col: 820px;                            /* the reading column, centred */
  /* The field: an almost flat, soft cool grey, a hair darker toward the bottom, with only a whisper of light at the
     top centre. The two greys are sampled from the owner's reference picture of the card (the page around it is
     #E0E1E6, a little darker at the lower right), so the card and the page agree. The page is painted with the same
     two colours, so nothing flashes before the backdrop layer does. */
  --field-top: #E3E4E9;
  --field-bottom: #DCDDE2;
  --field: linear-gradient(to bottom, var(--field-top), var(--field-bottom));
  --field-glow: radial-gradient(ellipse 62% 46% at 50% 0%, color-mix(in srgb, var(--white) 26%, transparent), color-mix(in srgb, var(--white) 0%, transparent) 100%);
  /* Liquid glass only looks like glass when there is something behind it to bend: four large, soft pools of light and
     shade (an ice-blue pool at the left, bright light at the top right, a slate shade at the lower right, a little
     light at the lower left) over the grey. They stay grey-blue, never a colour, and the backdrop is fixed, so cards
     sweep across them as the page scrolls. */
  --field-pools:
    radial-gradient(38% 34% at 12% 26%, color-mix(in srgb, var(--ice) 38%, transparent), transparent 72%),
    radial-gradient(34% 30% at 88% 12%, color-mix(in srgb, var(--white) 78%, transparent), transparent 72%),
    radial-gradient(48% 42% at 82% 84%, color-mix(in srgb, var(--navy) 26%, transparent), transparent 72%),
    radial-gradient(34% 30% at 20% 90%, color-mix(in srgb, var(--white) 62%, transparent), transparent 72%);
  /* Titles: medium weight, tightly tracked. Inter is self-hosted as one variable file (300 to 700) and -apple-system
     gives SF as a variable weight too, so these in-between weights are real weights on both stacks. The text weights
     are a step lighter than the brand's 400 and 500 for this site only. */
  --fw-regular: 380;
  --fw-medium: 470;
  --title-weight: 400;
  --title-track: -.035em;
  /* Liquid glass on a light field: near-white frosted glass, a 1 px white rim, a soft long shadow, a faint highlight at
     the top. */
  --lg-fill: color-mix(in srgb, var(--white) 24%, transparent);             /* .glass */
  --lg-fill-strong: color-mix(in srgb, var(--white) 32%, transparent);      /* .glass-strong */
  --lg-frost: color-mix(in srgb, var(--white) 10%, transparent);            /* .glass--frost: a little more body for text */
  --lg-read: color-mix(in srgb, var(--white) 30%, transparent);             /* .glass--read: long-form text */
  --lg-sheen: color-mix(in srgb, var(--white) 62%, transparent);            /* the specular bloom, top left */
  --lg-bounce: color-mix(in srgb, var(--white) 26%, transparent);           /* light bouncing back in at the bottom right */
  --lg-blur: 26px;
  --lg-saturate: 1.8;                      /* what passes behind is bent and a little richer, as in Apple's glass */
  --lg-shadow: 0 30px 60px -22px color-mix(in srgb, var(--graphite-950) 22%, transparent), 0 10px 22px -10px color-mix(in srgb, var(--graphite-950) 12%, transparent), 0 1px 2px color-mix(in srgb, var(--graphite-950) 8%, transparent);
  --lg-hairline: 0 0 0 .5px color-mix(in srgb, var(--graphite-950) 8%, transparent);
  /* The edge: a thin white line all round, a bright lip at the top left, a softer one at the bottom right, a glow just
     inside the edge (the thick rim of a lens), and a little shade inside the bottom for weight. */
  --lg-edge:
    inset 0 0 0 1px color-mix(in srgb, var(--white) 42%, transparent),
    inset 2px 3px 3px -2px color-mix(in srgb, var(--white) 95%, transparent),
    inset -2px -3px 3px -2px color-mix(in srgb, var(--white) 70%, transparent),
    inset 0 0 26px -4px color-mix(in srgb, var(--white) 46%, transparent),
    inset 0 -22px 34px -26px color-mix(in srgb, var(--graphite-950) 14%, transparent);
  --vh: 1vh;                               /* the smallest viewport height where svh exists, so phone toolbars never resize anything */
  --hero-h: max(100vh, 560px);             /* the first screen: one viewport, taller only when its content cannot fit */
  --lockup-h: 30px;                        /* the header lockup (orb and wordmark), top left, normal size */
}
@media (min-width: 880px) { :root { --header-h: 76px; } }
@supports (height: 1svh) { :root { --vh: 1svh; --hero-h: max(100svh, 560px); } }

/* ---------- base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html {
  background: var(--field-top) var(--field) fixed;   /* the backdrop's own colours, behind it until it is painted */
  color: var(--fg);
  color-scheme: light;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
  scroll-padding-top: calc(var(--header-h) + 16px);
  scroll-behavior: smooth;
}
html:has(dialog[open]) { overflow: hidden; }
body {
  margin: 0;
  min-height: 100vh; min-height: 100dvh;
  font-family: var(--font);
  font-weight: var(--fw-regular);
  font-size: var(--fs-body);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
h1, h2, h3, h4, p, ul, ol, dl, dd, figure, blockquote { margin: 0; }
ul, ol { padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }
img, svg { display: block; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
b, strong { font-weight: var(--fw-medium); }
/* A graphite ring with a white halo, so it reads on the field and on glass alike. */
:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; box-shadow: 0 0 0 3px var(--white); }
.skip {
  position: absolute; left: var(--space-control); top: var(--space-control); z-index: 60; transform: translateY(-200%);
  padding: 12px 20px; min-height: 44px; display: inline-flex; align-items: center;
  border-radius: var(--radius-control); background: var(--surface-elevated); color: var(--ink);
  border: 1px solid var(--mist-300); font-size: 15px; font-weight: var(--fw-medium); transition: transform .15s;
}
.skip:focus { transform: none; }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ---------- the backdrop: fixed, still, behind everything ---------- */
/* One almost flat light grey. No photograph, no image file: the field is a CSS gradient with one soft bloom of white at
   the top centre (--field-glow), and the grain is a tiny inline SVG. It is position: fixed and has no animation,
   parallax or zoom. It is as tall as the smallest viewport (svh), so it never resizes when a phone's toolbars come
   and go. */
.backdrop {
  position: fixed; inset: 0 0 auto 0; z-index: -2; pointer-events: none;
  width: 100%; height: 100vh; height: 100svh; overflow: hidden;
  background: var(--field-glow), var(--field-pools), var(--field);
}
/* A very faint, fine grain (4.5%): grey noise centred on the field's own lightness, so it only varies the lightness a
   little and never shifts the colour. It keeps a large flat colour from looking plastic and the bloom from banding.
   The same 240 px tile repeats; stitchTiles keeps its seams invisible. The loading animation's veil wears it too. */
.backdrop::before, .intro::before {
  content: ""; position: absolute; inset: 0; opacity: .045;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n' x='0' y='0' width='100%25' height='100%25' color-interpolation-filters='sRGB'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.2' numOctaves='2' seed='7' stitchTiles='stitch'/%3E%3CfeColorMatrix type='matrix' values='.33 .33 .33 0 0 .33 .33 .33 0 0 .33 .33 .33 0 0 0 0 0 0 1'/%3E%3CfeComponentTransfer%3E%3CfeFuncR type='linear' slope='1.5' intercept='.1'/%3E%3CfeFuncG type='linear' slope='1.5' intercept='.1'/%3E%3CfeFuncB type='linear' slope='1.5' intercept='.1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)'/%3E%3C/svg%3E") 0 0 / 240px 240px;
}

/* ---------- type ---------- */
/* The headline: large, medium weight, tightly tracked. */
.hero-title {
  font-size: var(--fs-hero);
  font-weight: var(--title-weight);
  line-height: 1.02;
  letter-spacing: var(--title-track);
  font-optical-sizing: auto;
  font-kerning: normal;
  text-rendering: optimizeLegibility;
  text-wrap: balance;
}
.section-title {
  font-size: var(--fs-section);
  font-weight: var(--title-weight);
  line-height: 1.06;
  letter-spacing: var(--title-track);
  text-wrap: balance;
}
.lede {
  font-size: clamp(19px, 1.7vw, 24px);
  font-weight: var(--fw-regular);
  line-height: 1.4;
  letter-spacing: -.01em;
  text-wrap: pretty;
  color: var(--fg-2);
}
.fine { font-size: var(--fs-micro); line-height: 1.5; color: var(--fg-2); }
.link, .prose a, .faq-a a {
  color: var(--link);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
  text-decoration-color: color-mix(in srgb, var(--link) 45%, transparent);
  transition: text-decoration-color .2s var(--ease);
}
.link:hover, .prose a:hover, .faq-a a:hover { text-decoration-color: var(--link); }

/* ---------- glass ---------- */
@property --glass-fill { syntax: "<color>"; inherits: true; initial-value: transparent; }
/* One material, three weights: frosted white-ish glass with a translucent pale fill, a strong blur and saturation
   lift (so whatever passes behind is visibly bent), a faint highlight gradient in the top-left, a specular
   rim (a 1 px line, bright at the top-left, fading to almost nothing at the bottom-right), a graphite hairline
   outside it and a soft shadow. .glass is the lightest, .glass-strong the default for panels, .glass--frost adds a little body
   for panels that carry text, .glass--read a little more for the long legal pages. None of them is a card. */
.glass, .glass-strong {
  position: relative;
  --glass-fill: var(--lg-fill);
  --glass-under: transparent;
  background:
    radial-gradient(120% 84% at 0% 0%, var(--lg-sheen), transparent 58%),
    radial-gradient(70% 56% at 100% 100%, var(--lg-bounce), transparent 70%),
    linear-gradient(var(--glass-fill), var(--glass-fill)),
    var(--glass-under);
  border: 0;
  box-shadow: var(--lg-shadow), var(--lg-hairline), var(--lg-edge);
  -webkit-backdrop-filter: blur(var(--lg-blur)) saturate(var(--lg-saturate)) brightness(1.05);
  backdrop-filter: blur(var(--lg-blur)) saturate(var(--lg-saturate)) brightness(1.05);
  color: var(--fg);
}
.glass-strong { --glass-fill: var(--lg-fill-strong); }
.glass--frost { --glass-under: var(--lg-frost); }
.glass--read { --glass-under: var(--lg-read); }
.glass::before, .glass-strong::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit; padding: 1px; pointer-events: none;
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--white) 98%, transparent) 0%,
    color-mix(in srgb, var(--white) 50%, transparent) 16%,
    color-mix(in srgb, var(--white) 8%, transparent) 40%,
    color-mix(in srgb, var(--white) 6%, transparent) 60%,
    color-mix(in srgb, var(--white) 46%, transparent) 86%,
    color-mix(in srgb, var(--white) 84%, transparent) 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
}

/* Without backdrop-filter, or when asked for less transparency or more contrast: an opaque surface, so
   nothing depends on what is behind it. */
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .glass, .glass-strong { background: var(--surface-elevated); box-shadow: 0 0 0 1px var(--mist-300); }
  .glass::before, .glass-strong::before { display: none; }
}
@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
  .glass, .glass-strong {
    background: var(--surface-elevated);
    box-shadow: 0 0 0 1px var(--slate-500);
    -webkit-backdrop-filter: none; backdrop-filter: none;
  }
  .glass::before, .glass-strong::before { display: none; }
}
@media (forced-colors: active) {
  .glass, .glass-strong { background: Canvas; border: 1px solid CanvasText; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; }
  .glass::before, .glass-strong::before { display: none; }
  .backdrop { display: none; }
}

/* ---------- buttons ---------- */
/* A pill, 44 px high, medium off-white text on graphite. One primary per view. */
.button-primary, .button-secondary {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: 44px; padding: 0 22px; border-radius: 999px;
  font-family: inherit; font-size: 14.5px; font-weight: var(--fw-medium); line-height: 1.2; letter-spacing: 0;
  text-align: center; user-select: none; cursor: pointer;
  transition: background-color .25s var(--ease), border-color .25s var(--ease), transform .25s var(--ease);
}
.button-primary:active, .button-secondary:active { transform: scale(.99); }
.button-primary { background: var(--graphite-800); color: var(--text-on-image); border: 0; }
.button-primary:hover { background: var(--graphite-950); }
.button-secondary { color: var(--ink); border: 1px solid color-mix(in srgb, var(--slate-600) 45%, transparent); background: color-mix(in srgb, var(--white) 40%, transparent); }
.button-secondary:hover { background: color-mix(in srgb, var(--white) 75%, transparent); border-color: var(--slate-700); }
@media (forced-colors: active) { .button-primary, .button-secondary { border: 1px solid ButtonText; } }

/* ---------- header and menu ---------- */
.site-header { position: relative; z-index: 20; }
/* The lockup (orb and wordmark) at the top left at its normal size; the nav at the top right (a Menu button on small
   screens). The same layout is used by the menu's own header, so the lockup does not move when the menu opens. */
.bar, .menu-top { display: flex; align-items: center; justify-content: space-between; gap: 24px; min-height: var(--header-h); padding-inline: var(--gutter); }
.menu-top { flex: none; }
.brand { display: inline-flex; align-items: center; min-height: 44px; margin-block: -4px; border-radius: var(--radius-sm); }
.brand img { height: 32px; width: auto; }   /* the lockup (orb and wordmark): sized by height, its width follows its shape */
.bar .brand img, .menu-top .brand img { height: var(--lockup-h); }
/* A dark high-contrast theme paints the page black, and an <img> keeps its own colors: show the lockup in white, in grey. */
@media (forced-colors: active) and (prefers-color-scheme: dark) { .brand img { filter: grayscale(1) invert(1); } }
.nav { display: none; }
.nav ul { display: flex; align-items: center; gap: 2px; margin-right: -14px; }
.nav a {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 14px; border-radius: var(--radius-sm);
  font-size: 13px; font-weight: var(--fw-regular); letter-spacing: .005em; color: var(--slate-700); transition: color .2s var(--ease);
}
.nav a:hover { color: var(--ink); }
.nav a[aria-current="page"] { color: var(--ink); font-weight: var(--fw-medium); }
.menu-btn { display: inline-flex; align-items: center; min-height: 44px; margin-right: -14px; padding: 0 14px; border-radius: var(--radius-sm); font-size: 13px; font-weight: var(--fw-medium); color: var(--ink); }
@media (min-width: 760px) {
  .nav { display: block; }
  .bar > .menu-btn { display: none; }
}

.menu-dialog {
  position: fixed; inset: 0; width: 100%; height: 100%; max-width: none; max-height: none; margin: 0; padding: 0;
  border: 0; overflow: auto; color: var(--ink);
  /* The same glass, over the whole screen: a little more fill than a panel, since big type sits straight on it. */
  background:
    linear-gradient(180deg, var(--lg-sheen) 0%, transparent 60%),
    color-mix(in srgb, var(--field-top) 78%, transparent);
  -webkit-backdrop-filter: blur(40px) saturate(var(--lg-saturate)); backdrop-filter: blur(40px) saturate(var(--lg-saturate));
}
.menu-dialog::backdrop { background: transparent; }
.menu-dialog[open] { animation: fade-in .25s var(--ease); }
.menu-inner { display: flex; flex-direction: column; min-height: 100%; padding-bottom: max(32px, env(safe-area-inset-bottom)); }
.menu-links { padding: 24px var(--gutter) 0; }
.menu-links a {
  display: block; padding: 10px 0; font-size: var(--fs-hero-l); font-weight: var(--title-weight);
  line-height: 1.1; letter-spacing: var(--title-track);
}
.menu-links a[aria-current="page"] { color: var(--ink); }
.menu-links a:not([aria-current="page"]) { color: var(--slate-700); }
.menu-foot { display: flex; flex-wrap: wrap; gap: 0 24px; margin-top: auto; padding: 48px var(--gutter) 0; }
.menu-foot a { display: inline-flex; align-items: center; min-height: 44px; font-size: 14px; color: var(--fg-2); }
.menu-foot a:hover { color: var(--ink); }
@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
  .menu-dialog { background: var(--bg); -webkit-backdrop-filter: none; backdrop-filter: none; }
}
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) { .menu-dialog { background: var(--bg); } }

/* ---------- the first screen ---------- */
/* Two columns: the headline, one line, one button and its small print on the left; on the right one frosted glass
   card, a quiet phone window, in which the conversation plays (six examples, one after another, in place), with its
   dots and pause button under it. Below 1000 px the card folds under the text. The two social links sit at the bottom
   centre. The hero is exactly one viewport tall and clips the rest. */
.page-home .site-header { position: absolute; inset: 0 0 auto 0; }
.hero {
  --card-w: min(100%, 380px);
  position: relative; isolation: isolate; overflow: clip;
  display: flex; flex-direction: column; align-items: stretch; gap: clamp(14px, calc(var(--vh) * 3), 28px);
  height: var(--hero-h);
  padding: calc(var(--header-h) + clamp(0px, calc(var(--vh) * 2), 16px)) var(--gutter) 0;
}
.hero-copy { position: relative; z-index: 2; flex: none; display: grid; justify-items: start; gap: 14px; text-align: left; }
.hero-copy .hero-title { font-size: clamp(44px, min(5.4vw, calc(var(--vh) * 10)), 80px); }
/* The line under the headline: two lines on a computer (28em is as wide as it needs to be), a few more on a phone. */
.hero-sub { max-width: 28em; font-size: clamp(18px, 1.55vw, 22px); font-weight: var(--fw-regular); line-height: 1.45; letter-spacing: -.008em; color: var(--fg-2); text-wrap: balance; }
.hero-cta { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; margin-top: 8px; }
.hero-cta .fine { font-size: 12px; color: var(--fg-2); }
/* The one button of the first screen is the biggest thing on it after the headline: a 56 px pill. */
.hero-cta .button-primary { min-height: 56px; padding: 0 36px; font-size: 17px; }

/* The social links at the bottom centre of the first screen: below the demo on small screens, at the foot of the screen
   from 1000 px. Never over the demo. */
.social--hero { position: relative; z-index: 2; flex: none; padding-bottom: max(8px, env(safe-area-inset-bottom)); }

/* ---- the demo: the card, and its controls under it ---- */
.demo { position: relative; z-index: 1; flex: 1 1 0; min-height: 0; width: var(--card-w); align-self: center; display: grid; align-content: start; justify-items: stretch; gap: 6px; }
/* The card is liquid glass, not paint: a thin tint of the brand's cool blues over the page's own pale grey, which shows
   through (and is blurred and enriched by the backdrop filter of .glass-strong), as in the owner's reference: a soft
   field seen through fluted glass, so wide, blurred, vertical bands of light and shade run down it. Lighter at the top
   (where the "memoe" label sits), slate toward the lower left, steel blue at the lower right. Every colour is mixed with
   transparent, so none of it hides what is behind. The rim, the lens glow and the shade inside the bottom are --lg-edge.
   Made only of the brand's cool tokens (ice, steel, navy, slate); the warm tones stay in the photographs.
   Top to bottom: the bands, the lift at the top, the slate bloom, the blue tint. The bubbles on it are the white.
   The light on top of all this (the bloom, the rim, the glint) is the glare, below. */
.demo-card {
  --glass-fill: transparent;
  --glass-under: transparent;
  border-radius: 28px; padding: 14px 14px 14px;
  background:
    linear-gradient(90deg,
      color-mix(in srgb, var(--white) 8%, transparent) 0%,
      color-mix(in srgb, var(--white) 32%, transparent) 12%,
      color-mix(in srgb, var(--navy) 16%, transparent) 30%,
      color-mix(in srgb, var(--white) 24%, transparent) 47%,
      color-mix(in srgb, var(--navy) 24%, transparent) 63%,
      color-mix(in srgb, var(--navy) 12%, transparent) 77%,
      color-mix(in srgb, var(--white) 32%, transparent) 100%),
    linear-gradient(180deg, color-mix(in srgb, var(--white) 22%, transparent) 0%, color-mix(in srgb, var(--white) 0%, transparent) 30%),
    radial-gradient(92% 72% at 0% 100%, color-mix(in srgb, var(--slate-600) 30%, transparent), color-mix(in srgb, var(--slate-600) 0%, transparent) 72%),
    linear-gradient(172deg,
      color-mix(in srgb, var(--ice) 54%, transparent) 0%,
      color-mix(in srgb, var(--steel) 40%, transparent) 52%,
      color-mix(in srgb, color-mix(in srgb, var(--steel) 62%, var(--navy)) 46%, transparent) 100%);
  box-shadow: var(--lg-shadow), 0 36px 60px -28px color-mix(in srgb, var(--navy) 30%, transparent), var(--lg-hairline), var(--lg-edge);
  isolation: isolate;
}

/* ---- the glare: light on the card's glass ---- */
/* One empty layer (.demo-glare, the card's first child) holds everything that catches light, so the thread above it is
   never washed out and its contrast stays what it is. The light is white only, never a colour:
     the layer      a soft bloom of light at --glare-x / --glare-y (top left at rest) and a faint diagonal streak
     ::before       the rim: a crisp 1.5 px ring with two bright highlights on opposite edges, facing --glare-angle
                    (the top left and the bottom right at rest, as on Apple's glass); it replaces the card's generic rim
     ::after        a glint: one narrow feathered band that crosses the card once, top left to bottom right
   site.js (wireGlare) leans the bloom and the highlights toward a mouse on the first screen, and plays the glint once
   when the first example starts to type (.is-glint). The three --glare properties are registered so they ease; the layer
   is clipped to the card's rounded corners (overflow, isolation and a mask, the way the loading animation is). */
@property --glare-x { syntax: "<percentage>"; inherits: true; initial-value: 16%; }
@property --glare-y { syntax: "<percentage>"; inherits: true; initial-value: 9%; }
@property --glare-angle { syntax: "<angle>"; inherits: true; initial-value: -45deg; }
.demo-card::before { display: none; }
.demo-glare {
  position: absolute; inset: 0; z-index: -1; isolation: isolate; overflow: hidden; border-radius: inherit; pointer-events: none;
  -webkit-mask-image: linear-gradient(#000, #000); mask-image: linear-gradient(#000, #000);
  background:
    radial-gradient(ellipse 52% 42% at var(--glare-x, 16%) var(--glare-y, 9%), color-mix(in srgb, var(--white) 50%, transparent), color-mix(in srgb, var(--white) 0%, transparent) 100%),
    linear-gradient(112deg, transparent 20%, color-mix(in srgb, var(--white) 18%, transparent) 33%, transparent 46%);
  transition: --glare-x .7s var(--ease), --glare-y .7s var(--ease), --glare-angle .9s var(--ease);
}
.demo-glare::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit; padding: 1.5px; pointer-events: none;
  background: conic-gradient(from var(--glare-angle, -45deg),
    var(--white) 0deg,
    color-mix(in srgb, var(--white) 72%, transparent) 14deg,
    color-mix(in srgb, var(--white) 16%, transparent) 56deg,
    color-mix(in srgb, var(--white) 8%, transparent) 104deg,
    color-mix(in srgb, var(--white) 52%, transparent) 166deg,
    color-mix(in srgb, var(--white) 84%, transparent) 180deg,
    color-mix(in srgb, var(--white) 52%, transparent) 194deg,
    color-mix(in srgb, var(--white) 8%, transparent) 256deg,
    color-mix(in srgb, var(--white) 16%, transparent) 304deg,
    color-mix(in srgb, var(--white) 72%, transparent) 346deg,
    var(--white) 360deg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
}
.demo-glare::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0; transform: translate(-60%, -8%);
  background: linear-gradient(112deg,
    transparent 36%,
    color-mix(in srgb, var(--white) 22%, transparent) 43%,
    color-mix(in srgb, var(--white) 64%, transparent) 50%,
    color-mix(in srgb, var(--white) 22%, transparent) 57%,
    transparent 64%);
}
.demo-card.is-glint .demo-glare::after { animation: glare-sweep 1.1s var(--ease) 1 both; }
@keyframes glare-sweep {
  0% { opacity: 0; transform: translate(-60%, -8%); }
  18%, 76% { opacity: 1; }
  100% { opacity: 0; transform: translate(60%, 8%); }
}

.card-head { display: grid; justify-items: center; gap: 3px; padding-bottom: 10px; margin-bottom: 12px; border-bottom: 1px solid color-mix(in srgb, var(--white) 46%, transparent); }
.card-head img { width: 36px; height: 36px; border-radius: 50%; box-shadow: 0 2px 6px color-mix(in srgb, var(--graphite-950) 18%, transparent); }
.card-head span { font-size: 11px; font-weight: var(--fw-medium); line-height: 1.2; color: var(--ink); }

/* The six scenes share one cell, so the card keeps the height of the tallest and nothing moves when one replaces another. */
.demo-stage { display: grid; }
.demo-scene { grid-area: 1 / 1; display: flex; flex-direction: column; gap: 8px; min-width: 0; visibility: hidden; }
.demo-scene.is-active { visibility: visible; }
.demo-scene > * { margin: 0; }

/* Your message: a graphite bubble, right. memoe's reply: a near-white bubble, left. */
.demo .msg-out { align-self: flex-end; max-width: 88%; padding: 7px 12px 8px; border-radius: 15px 15px 5px 15px; background: var(--graphite-800); font-size: 14px; line-height: 1.35; letter-spacing: -.005em; box-shadow: 0 3px 10px color-mix(in srgb, var(--graphite-950) 10%, transparent); }
.demo .msg-in { align-self: flex-start; max-width: 92%; display: grid; grid-template-columns: minmax(0, 1fr); justify-items: start; align-items: center; }
.demo .msg-in > * { grid-area: 1 / 1; }
.demo .bubble { display: block; padding: 7px 12px 8px; border-radius: 15px 15px 15px 5px; background: color-mix(in srgb, var(--white) 92%, transparent); border: 0; box-shadow: 0 1px 2px color-mix(in srgb, var(--graphite-950) 8%, transparent), 0 0 0 1px color-mix(in srgb, var(--graphite-950) 4%, transparent); }
.demo .reply { padding: 0; font-size: 14px; line-height: 1.35; letter-spacing: -.005em; color: var(--ink); }
.typing { display: none; }

/* The photographs: three small tiles in a row. */
.demo .tiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-top: 2px; }
.demo .tiles li { aspect-ratio: 1 / 1.12; }
.demo .tiles .photo-card { height: 100%; border-radius: 11px; box-shadow: 0 4px 10px color-mix(in srgb, var(--graphite-950) 10%, transparent); }
.demo .tiles .photo-card::after { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--white) 40%, transparent); }

/* The quiet controls under the card: six dots (the current one a longer graphite pill) and pause/play at the right end. */
.demo-controls { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; }
.demo-controls[hidden] { display: grid; visibility: hidden; } /* keeps its space, so nothing shifts when it appears */
.demo-dots { display: flex; align-items: center; grid-column: 2; }
.demo-dot, .demo-toggle { position: relative; display: grid; place-items: center; height: 44px; color: var(--ink); }
.demo-dot { width: 26px; }
.demo-toggle { width: 44px; grid-column: 3; justify-self: end; margin-right: -10px; }
.demo-dot::before {
  content: ""; width: 6px; height: 6px; border-radius: 3px; background: color-mix(in srgb, var(--slate-600) 42%, transparent);
  transition: width .35s var(--ease), background-color .35s var(--ease);
}
.demo-dot:hover::before { background: color-mix(in srgb, var(--slate-600) 70%, transparent); }
.demo-dot[aria-current="true"]::before { width: 22px; background: var(--graphite-800); }
.demo-toggle svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.demo-toggle .i-play { display: none; }
.demo-toggle[aria-pressed="true"] .i-play { display: block; }
.demo-toggle[aria-pressed="true"] .i-pause { display: none; }
.demo-controls[data-reduced] .demo-toggle { display: none; }

/* ---- two columns (1000 px and wider) ---- */
@media (min-width: 1000px) {
  .hero {
    --card-w: clamp(340px, 34vw, 500px);
    /* The text and the card sit close together: the first screen's content is at most 1120 px wide and centred, and the
       header's lockup and nav line up with it. The text column takes what the card leaves. */
    display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; column-gap: clamp(40px, 4.5vw, 72px);
    height: auto; min-height: var(--hero-h);
    --home-w: 1120px;
    padding: var(--header-h) max(var(--gutter), calc((100% - var(--home-w)) / 2)) clamp(72px, calc(var(--vh) * 10), 104px);
  }
  .page-home .bar { width: 100%; max-width: calc(1120px + 2 * var(--gutter)); margin-inline: auto; }
  .hero-copy { gap: 20px; }
  .demo { flex: none; justify-self: end; align-self: center; }
  .demo-card { border-radius: 32px; padding: 18px; }
  .card-head { padding-bottom: 12px; margin-bottom: 14px; }
  .card-head img { width: 44px; height: 44px; }
  .card-head span { font-size: 12px; }
  .demo .msg-out, .demo .reply { font-size: 15px; }
  .demo .tiles li { aspect-ratio: 3 / 4; }
  .social--hero { position: absolute; inset: auto 0 clamp(14px, calc(var(--vh) * 4), 40px); padding-bottom: 0; pointer-events: none; }
  .social--hero a { pointer-events: auto; }
}

/* ---- changing the scene, in place: a calm rise in, typed texts, a soft fade out ---- */
@keyframes develop { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes dot { from { opacity: .35; transform: translateY(0); } to { opacity: 1; transform: translateY(-2px); } }
@keyframes caret-blink { 0%, 40% { opacity: 1; } 60%, 100% { opacity: 0; } }
/* One example plays in steps, about 5 to 6 s in all. site.js (wireDemo) adds a class to the scene at each step and decides
   when each starts (the pace is at the top of that file); this section only says what each step looks like:
     is-in        your bubble rises in and your message is typed, letter by letter, behind a cursor
     is-thinking  memoe's three dots
     is-replying  the dots give way to memoe's bubble and its reply is typed, faster
     is-shown     the three photographs come in, 90 ms apart
     is-out       the whole example fades and lifts out (below)
   Without the script, and under reduced motion, no step class is ever added: the example is simply there, whole.
   Only opacity and transform animate. */
.demo-scene.is-waiting > * { opacity: 0; }   /* the first example, while the loading veil is still over the page */
.demo-scene.is-in .msg-out { animation: develop .6s var(--ease) 0s backwards; }
.demo-scene.is-in:not(.is-replying) .bubble { opacity: 0; }
.demo-scene.is-in:not(.is-shown) .tiles li { opacity: 0; }
.demo-scene.is-thinking:not(.is-replying) .typing {
  display: flex; align-items: center; gap: 4px; justify-self: start; padding: 0 12px; height: 30px; border-radius: 15px;
  pointer-events: none; background: color-mix(in srgb, var(--white) 92%, transparent); box-shadow: 0 0 0 1px color-mix(in srgb, var(--graphite-950) 4%, transparent);
  animation: fade-in .2s ease backwards;
}
.typing i { width: 5px; height: 5px; border-radius: 50%; background: var(--slate-600); animation: dot .5s ease-in-out infinite alternate; }
.typing i:nth-child(2) { animation-delay: .1s; }
.typing i:nth-child(3) { animation-delay: .2s; }
.demo-scene.is-replying .bubble { animation: develop .45s var(--ease) 0s backwards; }
.demo-scene.is-shown .tiles li { animation: develop .6s var(--ease) 0s backwards; }
.demo-scene.is-shown .tiles li:nth-child(2) { animation-delay: .09s; }
.demo-scene.is-shown .tiles li:nth-child(3) { animation-delay: .18s; }
/* The typed texts. The whole sentence stays in the page for readers (a .visually-hidden span, put there by the script
   beside this copy, which is aria-hidden); this copy is what is seen. Its untyped rest is hidden but still laid out, so a
   bubble has its final size and shape from the start (the card never changes size, no word jumps to the next line as it
   is typed). The cursor is a hair-thin bar with no width of its own, so it moves nothing: it blinks before the first
   letter, stays solid while letters come and is gone when the sentence is done. */
.typed-rest { visibility: hidden; }
.typed.is-typing .typed-done::after {
  content: ""; display: inline-block; width: 1.5px; height: 1.1em; margin-right: -1.5px; vertical-align: text-bottom;
  border-radius: 1px; background: currentColor;
}
.typed.is-typing.is-blinking .typed-done::after { animation: caret-blink 1s ease-in-out infinite; }
/* The exit: a soft reverse, 0.4 s, before the next scene. */
.demo[data-ready] .msg-out, .demo[data-ready] .bubble, .demo[data-ready] .tiles li { transition: opacity .3s ease, transform .3s ease; }
.demo-scene.is-out .msg-out, .demo-scene.is-out .bubble, .demo-scene.is-out .tiles li {
  opacity: 0; transform: translateY(-4px);
  transition: opacity .4s ease, transform .4s ease;
}

/* ---- the loading animation: liquid light, then the first screen ---- */
/* While the first screen loads, the orb sits alone on a veil that is a copy of the backdrop (the app shows the orb alone
   while it starts, too). Then light wakes inside it: slow grey-blue light flowing around a graphite core, held in a
   rounded shape that stretches from the orb into a pill ("memoe is looking", with a ring of dots), swells into a card
   the size of the demo's and dissolves. The veil lifts and the first screen rises into place under it: readable from
   about 1.1 s, still by 1.6 s. The light's colours are the brand's greys and blues (never a purple), and nothing is lit
   outside the shape. The words and dots are gone before the veil starts to lift, so they never float over the headline.
   It is CSS only and waits for nothing, so it can't hang: every animation is finite. The veil never takes a click, and it
   is hidden unless its animation runs, so a browser that runs no animations shows the page at once. Not under reduced
   motion or forced colours, and not when the address points further down the page (/#faq). Timeline (seconds):
     0 - .4      the orb comes into focus                    (intro-focus)
     .2 - .55    the orb gives way to the light              (intro-away, intro-wake)
     .38 - .74   it stretches into a pill                    (intro-shape)
     .6 - 1.0    the dots and "memoe is looking"             (intro-status, intro-spin)
     .98 - 1.28  it swells into a card                       (intro-shape)
     1.0 - 1.3   the light dissolves                         (intro-dissolve)
     1.0 - 1.4   the veil lifts; the first screen rises      (intro-lift, intro-rise) */
.intro {
  position: fixed; inset: 0; z-index: 50; pointer-events: none; contain: strict;
  display: grid; place-items: center;
  background: var(--field-glow), var(--field-pools), var(--field);
  visibility: hidden; opacity: 0;
  animation: intro-lift .4s ease 1s both;
}
/* The shape: a round orb that becomes a pill and then a card. Its children are laid out in a row and centred, so the dots
   and the words stay in the middle of whatever shape it is. isolation and the wide mask keep the blurred light inside the
   rounded corners in Safari (the mask is bigger than the shape, so the soft shadow outside it is not cut off). */
.intro-light {
  position: relative; isolation: isolate; overflow: hidden;
  display: flex; align-items: center; justify-content: center; gap: 12px;
  width: 64px; height: 64px; border-radius: 32px;
  box-shadow: 0 22px 44px -20px color-mix(in srgb, var(--graphite-950) 46%, transparent), 0 6px 14px -6px color-mix(in srgb, var(--graphite-950) 24%, transparent);
  -webkit-mask-image: linear-gradient(#000, #000); mask-image: linear-gradient(#000, #000);
  -webkit-mask-size: 640px 640px; mask-size: 640px 640px;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  animation: intro-focus .4s var(--ease) both, intro-shape 1.28s linear both, intro-dissolve .3s ease-in 1s forwards;
}
/* The light: a conic wash of the brand's blues around the middle, blurred, with one bright bloom that orbits it. It is a
   fixed square, big enough that the card's corners never leave it (so it is only rotated, never re-blurred), and it
   turns about two thirds of a turn while the shape changes. */
.intro-light::before {
  content: ""; position: absolute; z-index: 0; left: 50%; top: 50%; width: 440px; height: 440px; margin: -220px 0 0 -220px;
  background:
    radial-gradient(circle 104px at 74% 32%, color-mix(in srgb, var(--white) 96%, transparent), transparent),
    conic-gradient(var(--navy), var(--ice) 14%, var(--steel) 28%, var(--navy) 40%, var(--glass-blue) 52%, color-mix(in srgb, var(--white) 88%, var(--glass-blue)) 58%, var(--ice) 66%, var(--navy) 80%, var(--steel) 92%, var(--navy));
  filter: blur(14px);
  animation: intro-wake .35s ease .2s both, intro-flow 1.3s linear both;
}
/* The graphite core, darkest in the middle where the words are, and the bright feathered rim. */
.intro-light::after {
  content: ""; position: absolute; z-index: 1; inset: 0; border-radius: inherit; pointer-events: none;
  background: radial-gradient(closest-side, var(--graphite-950), color-mix(in srgb, var(--graphite-950) 94%, transparent) 50%, color-mix(in srgb, var(--graphite-950) 26%, transparent) 82%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--white) 72%, transparent), inset 0 0 16px 2px color-mix(in srgb, var(--white) 52%, transparent);
  animation: intro-wake .35s ease .2s both;
}
.intro-light img {
  position: absolute; z-index: 2; left: 50%; top: 50%; width: 64px; height: 64px; margin: -32px 0 0 -32px; border-radius: 50%;
  animation: intro-away .35s ease .2s forwards;
}
/* Eight dots in a ring (a 3 px dot with seven copies cast around it, each a little fainter), turning slowly. */
.intro-dots {
  position: relative; z-index: 2; flex: none; width: 3px; height: 3px; margin: 0 7px; border-radius: 50%;
  box-shadow:
    0 -6.5px 0 0 var(--text-on-image),
    4.6px -4.6px 0 0 color-mix(in srgb, var(--text-on-image) 86%, transparent),
    6.5px 0 0 0 color-mix(in srgb, var(--text-on-image) 72%, transparent),
    4.6px 4.6px 0 0 color-mix(in srgb, var(--text-on-image) 58%, transparent),
    0 6.5px 0 0 color-mix(in srgb, var(--text-on-image) 46%, transparent),
    -4.6px 4.6px 0 0 color-mix(in srgb, var(--text-on-image) 36%, transparent),
    -6.5px 0 0 0 color-mix(in srgb, var(--text-on-image) 28%, transparent),
    -4.6px -4.6px 0 0 color-mix(in srgb, var(--text-on-image) 20%, transparent);
  opacity: 0;
  animation: intro-status .4s ease .6s both, intro-spin .8s linear .6s both;
}
.intro-label {
  position: relative; z-index: 2; flex: none; white-space: nowrap;
  font-size: 14px; font-weight: var(--fw-medium); line-height: 1; letter-spacing: -.005em; color: var(--text-on-image);
  opacity: 0;
  animation: intro-status .4s ease .6s both;
}
@keyframes intro-lift { from { opacity: 1; visibility: visible; } to { opacity: 0; visibility: hidden; } }
@keyframes intro-focus { from { opacity: 0; transform: scale(.92); filter: blur(6px); } }
@keyframes intro-shape {
  0%, 30% { width: 64px; height: 64px; border-radius: 32px; animation-timing-function: cubic-bezier(.3, .7, .2, 1); }
  58%, 76% { width: 236px; height: 52px; border-radius: 26px; animation-timing-function: cubic-bezier(.5, 0, .2, 1); }
  100% { width: 300px; height: 256px; border-radius: 32px; }
}
@keyframes intro-wake { from { opacity: 0; } to { opacity: 1; } }
@keyframes intro-away { to { opacity: 0; } }
@keyframes intro-flow { from { transform: rotate(0deg); } to { transform: rotate(240deg); } }
@keyframes intro-status { 0% { opacity: 0; } 22%, 72% { opacity: 1; } 100% { opacity: 0; } }
@keyframes intro-spin { from { transform: rotate(0deg); } to { transform: rotate(270deg); } }
@keyframes intro-dissolve { to { opacity: 0; transform: scale(1.05); } }
@keyframes intro-rise { from { transform: translateY(16px); } }
.intro ~ main :is(.hero-copy > *, .demo, .social--hero) { animation: intro-rise .5s var(--ease) 1s backwards; }
.intro ~ main .hero-sub { animation-delay: 1.04s; }
.intro ~ main :is(.hero-cta, .demo) { animation-delay: 1.08s; }
.intro ~ main .social--hero { animation-delay: 1.12s; }
html:has(:target) .intro { display: none; }
@media (prefers-reduced-motion: reduce) {
  .intro { display: none; }
  .intro ~ main :is(.hero-copy > *, .demo, .social--hero) { animation: none; }
}
@media (forced-colors: active) { .intro { display: none; } }

/* ---- the thread: the conversation's building blocks (also used by the features page) ---- */
/* What you text is the star: a large graphite bubble. memoe's reply is a glass bubble with the orb as its avatar. */
.msg-out {
  align-self: flex-end; max-width: 90%; padding: .5em .85em .55em;
  border-radius: 16px 16px 5px 16px;
  background: var(--ink); color: var(--text-on-image);
  box-shadow: 0 5px 14px color-mix(in srgb, var(--graphite-950) 10%, transparent);
  font-size: 18px; font-weight: var(--fw-regular); line-height: 1.22; letter-spacing: -.015em; text-wrap: pretty;
}
.msg-in { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: end; column-gap: 8px; min-height: 0; }
.avatar { width: 28px; height: 28px; margin-bottom: 4px; border-radius: 50%; box-shadow: 0 2px 6px color-mix(in srgb, var(--graphite-950) 20%, transparent); }
.bubble {
  min-width: 0; padding: 12px; border-radius: 16px 16px 16px 5px;
  background: color-mix(in srgb, var(--white) 56%, transparent);
  border: var(--glass-border-width) solid color-mix(in srgb, var(--slate-500) 30%, transparent);
  box-shadow: inset 1px 1px 0 var(--white);
}
.reply { padding: 2px 4px 0; font-size: 16px; line-height: 1.3; letter-spacing: -.005em; color: var(--ink); }

/* A short thread on the features page: one message, one reply. */
.thread { display: grid; gap: 10px; max-width: 30em; margin-top: 20px; }
.thread .msg-out { justify-self: end; font-size: 20px; }
.thread .msg-in { grid-template-columns: auto auto; justify-content: start; }
.thread .reply { font-size: 17px; }
.thread .bubble { padding: 12px 16px; }
.thread .msg-in { align-items: center; }
.thread .avatar { margin: 0; }

/* ---------- photo-card ---------- */
/* A photograph with rounded corners, a soft shadow and no border. If the photo is missing, the cool grey
   gradient is what you see. */
.photo-card {
  position: relative; isolation: isolate; overflow: hidden; border-radius: var(--radius-card);
  background: linear-gradient(160deg, var(--mist-300), var(--slate-500));
}
.photo-card img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.photo-card--tile { border-radius: var(--radius-sm); box-shadow: 0 6px 16px color-mix(in srgb, var(--graphite-950) 14%, transparent); }

/* ---------- pages below the first screen ---------- */
.page { display: grid; gap: 16px; justify-items: center; padding: clamp(16px, 4vw, 40px) var(--gutter) 0; }
.page > * { width: 100%; max-width: var(--col); }
.page-home .page { padding-top: clamp(32px, calc(var(--vh) * 14), 150px); }

.panel { padding: clamp(24px, 4vw, 48px); border-radius: var(--radius-panel); }
.page-title { font-size: var(--fs-section); font-weight: var(--title-weight); line-height: 1.04; letter-spacing: var(--title-track); font-optical-sizing: auto; text-rendering: optimizeLegibility; text-wrap: balance; }   /* every page's h1 matches the home headline */
.panel .lede { margin-top: 16px; max-width: 34em; }
.panel .section-title { font-size: clamp(30px, 3.4vw, 48px); }
.panel-meta { margin-top: 16px; font-size: var(--fs-micro); color: var(--fg-3); }

/* Facts: quiet rows with a hairline between them. */
.facts { margin-top: clamp(20px, 3vw, 32px); }
.facts li { padding-block: 20px; border-top: 1px solid var(--hairline); }
.facts li:first-child { border-top: 0; padding-top: 4px; }
.facts li:last-child { padding-bottom: 0; }
.facts h3 { font-size: var(--fs-body); font-weight: var(--fw-medium); line-height: 1.3; }
.facts p { max-width: 52ch; margin-top: 6px; color: var(--fg-3); }
.facts q { quotes: "\201C" "\201D"; color: var(--fg); }
.facts b, .facts strong { color: var(--fg); }
.facts .status { margin-top: 2px; font-size: var(--fs-micro); font-weight: var(--fw-medium); letter-spacing: .02em; color: var(--fg-3); }
/* Facts as tiles (the features page): the same list drawn as small frost cards in a grid, so it can be scanned instead of read;
   the tabs are one row each with an outline icon (drawn as a mask, so the markup stays heading and line). */
.facts.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); gap: 12px; }
.facts.tiles li, .facts.tiles li:first-child, .facts.tiles li:last-child { padding: 18px 18px 20px; border: 1px solid color-mix(in srgb, var(--slate-600) 18%, transparent); border-radius: var(--radius-card); background: color-mix(in srgb, var(--white) 52%, transparent); }
.facts.tiles h3 { font-size: 18px; letter-spacing: -.01em; }
.facts.tiles p { margin-top: 6px; font-size: 15px; line-height: 1.4; color: var(--fg-2); }
.facts.tiles .status { display: inline-block; width: fit-content; margin: 8px 0 0; padding: 2px 11px; border-radius: 999px; font-size: 12px; font-weight: var(--fw-medium); letter-spacing: .02em; color: var(--ink); background: color-mix(in srgb, var(--white) 72%, transparent); border: 1px solid color-mix(in srgb, var(--slate-600) 22%, transparent); }
.facts.tiles .status + p { margin-top: 8px; }
.facts.tabs { display: grid; gap: 0; }
.facts.tabs li, .facts.tabs li:first-child, .facts.tabs li:last-child { display: grid; grid-template-columns: 28px minmax(0, 1fr); column-gap: 16px; align-items: center; padding: 14px 0; border-top: 1px solid var(--hairline); }
.facts.tabs li:first-child { border-top: 0; }
.facts.tabs li::before { content: ""; grid-row: 1 / span 2; width: 28px; height: 28px; background: var(--graphite-950); -webkit-mask: var(--tab-icon) center / contain no-repeat; mask: var(--tab-icon) center / contain no-repeat; }
.facts.tabs h3 { font-size: 20px; letter-spacing: -.01em; }
.facts.tabs p { margin-top: 2px; font-size: 16px; color: var(--fg-2); }
.facts.tabs li:nth-child(1) { --tab-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 11.5 12 5l8 6.5V19a1 1 0 0 1-1 1h-4v-5H9v5H5a1 1 0 0 1-1-1z'/%3E%3C/svg%3E"); }
.facts.tabs li:nth-child(2) { --tab-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='8.5' r='3.2'/%3E%3Cpath d='M3.5 19c.6-3.4 2.9-5.2 5.5-5.2s4.9 1.8 5.5 5.2'/%3E%3Ccircle cx='17' cy='9.5' r='2.4'/%3E%3Cpath d='M16.2 14.4c2.3.2 3.9 1.6 4.3 4.1'/%3E%3C/svg%3E"); }
.facts.tabs li:nth-child(3) { --tab-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m4.5 7 1.5 1.5L8.5 5.5M4.5 13l1.5 1.5 2.5-3M4.5 19l1.5 1.5 2.5-3M12 7h7.5M12 13h7.5M12 19h7.5'/%3E%3C/svg%3E"); }
.facts.tabs li:nth-child(4) { --tab-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='4' y='9' width='16' height='10.5' rx='2.5'/%3E%3Cpath d='M7 6h10M9.5 3.5h5'/%3E%3C/svg%3E"); }
.facts.tabs li:nth-child(5) { --tab-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='8.5' r='3.5'/%3E%3Cpath d='M5 20c.7-3.8 3.4-5.8 7-5.8s6.3 2 7 5.8'/%3E%3C/svg%3E"); }
@media (forced-colors: active) { .facts.tabs li::before { background: CanvasText; } }
.panel .button-primary { margin-top: 24px; }
.panel-actions { display: flex; flex-wrap: wrap; gap: 12px 16px; align-items: center; margin-top: 24px; }
.panel-actions .button-primary { margin-top: 0; }

/* ---------- faq: glass rows ---------- */
.faq-section { display: grid; gap: 10px; }
.faq-list { display: grid; gap: 10px; }
.faq { border-radius: var(--radius-control); transition: --glass-fill .35s var(--ease); }
.faq summary {
  display: flex; align-items: center; justify-content: space-between; gap: 24px; min-height: 64px; padding: 16px 22px;
  border-radius: var(--radius-control); cursor: pointer; list-style: none;
  font-size: clamp(18px, 1.7vw, 22px); font-weight: var(--fw-regular); line-height: 1.3; letter-spacing: -.01em;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary:focus-visible { outline-offset: -4px; }
.faq summary::after {
  content: ""; flex: none; width: 16px; height: 16px;
  background:
    linear-gradient(currentColor, currentColor) center / 100% 1.5px no-repeat,
    linear-gradient(currentColor, currentColor) center / 1.5px 100% no-repeat;
  color: var(--fg-2); transition: transform .45s var(--ease);
}
.faq[open] summary::after { transform: rotate(45deg); }
.faq[open], .faq:hover { --glass-fill: color-mix(in srgb, var(--white) 38%, transparent); }
.faq-a { max-width: 62ch; padding: 0 22px 22px; color: var(--fg-2); }
.faq-a p + p { margin-top: 12px; }
.faq-a .button-primary { margin-top: 20px; }
.faq-a b, .faq-a strong { color: var(--fg); }
/* Opening a row eases its height and fades the answer in where the browser can animate it (Chrome 131+, Safari
   18.4+); anywhere else the answer simply fades in. */
@supports selector(::details-content) {
  :root { interpolate-size: allow-keywords; }
  .faq::details-content {
    block-size: 0; opacity: 0; overflow: clip;
    transition: block-size .5s var(--ease), opacity .35s ease, content-visibility .5s allow-discrete;
  }
  .faq[open]::details-content { block-size: auto; opacity: 1; transition-delay: 0s, .08s, 0s; }
}
@supports not selector(::details-content) {
  .faq-a { animation: fade-in .3s var(--ease); }
}

/* ---------- social links ---------- */
/* Instagram and LinkedIn as two plain glyphs (currentColor, no tile, no colour): 24 px drawn, 44 px to hit, in ink so they
   read clearly on the field. Twice on the home page: the bottom centre of the first screen (.social--hero, below)
   and the footer; once everywhere else (.social--footer). */
.social { display: flex; align-items: center; justify-content: center; gap: 4px; }
.social a {
  display: grid; place-items: center; width: 44px; height: 44px; border-radius: var(--radius-sm); color: var(--ink);
  transition: opacity .2s var(--ease), transform .3s var(--ease);
}
.social a:hover { opacity: .6; transform: translateY(-2px); }
.social svg { width: 24px; height: 24px; fill: currentColor; }
@media (prefers-reduced-motion: reduce) { .social a { transition: opacity .2s var(--ease); } .social a:hover { transform: none; } }

/* ---------- footer ---------- */
.site-footer { display: grid; justify-items: center; padding: clamp(16px, 3vw, 24px) var(--gutter) max(24px, env(safe-area-inset-bottom)); }
.footer-panel { width: 100%; max-width: var(--col); padding: clamp(24px, 4vw, 44px); border-radius: var(--radius-panel); display: grid; gap: clamp(20px, 2.4vw, 28px); }
.footer-top { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 24px; }
.footer-links { display: flex; flex-wrap: wrap; gap: 0 4px; margin-inline: -10px; }
.footer-top .brand img { width: auto; height: 40px; }
.footer-links a { display: inline-flex; align-items: center; min-height: 44px; padding: 0 10px; border-radius: var(--radius-sm); font-size: clamp(15px, 1.3vw, 17px); color: var(--ink); transition: opacity .2s var(--ease); }
.footer-links a:hover { opacity: .65; }
.footer-links a[aria-current="page"] { color: var(--ink); font-weight: var(--fw-medium); }
/* what memoe is, said once, large: the footer's headline */
.footer-about { max-width: 34ch; margin: 0; font-size: clamp(22px, 2.6vw, 32px); line-height: 1.28; letter-spacing: -.012em; color: var(--ink); }
.footer-panel .social { justify-content: flex-start; margin: -4px 0 -4px -10px; } /* under the statement, on its left edge (the icons' tap area is 44 pt, 24 of it drawn) */
.footer-bottom { display: grid; gap: 4px; padding-top: 20px; border-top: 1px solid var(--hairline); font-size: 13px; line-height: 1.5; color: var(--fg-2); }
.footer-bottom a { display: inline-flex; align-items: center; min-height: 44px; color: var(--ink); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px; text-decoration-color: color-mix(in srgb, var(--ink) 45%, transparent); }
.footer-bottom a:hover { text-decoration-color: var(--ink); }

/* ---------- privacy, terms and support ---------- */
.legal-section { padding-block: 28px; border-top: 1px solid var(--hairline); scroll-margin-top: 24px; }
.legal-section:first-child { border-top: 0; padding-top: 0; }
.panel-meta + .legal-section { margin-top: 28px; padding-top: 28px; border-top: 1px solid var(--hairline); }
.legal-section:last-child { padding-bottom: 0; }
.legal-section h2 { margin-bottom: 14px; font-size: clamp(22px, 2.2vw, 28px); font-weight: var(--fw-regular); line-height: 1.2; letter-spacing: -.02em; }
.prose { max-width: 40em; font-size: var(--fs-body); line-height: 1.6; color: var(--fg-3); }
.prose strong, .prose b, .prose em { color: var(--fg); }
.prose em { font-style: normal; font-weight: var(--fw-medium); }
.prose p + p, .prose p + ul, .prose ul + p { margin-top: 14px; }
.prose ul { padding-left: 1.2em; list-style: disc; }
.prose ol { padding-left: 1.4em; list-style: decimal; }
.prose li { margin-top: 8px; padding-left: 4px; }
.prose li::marker { color: var(--slate-700); }
.toc ul { display: grid; gap: 0 32px; }
.toc a { display: inline-flex; align-items: center; min-height: 44px; font-size: 15px; color: var(--ink); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px; text-decoration-color: color-mix(in srgb, var(--ink) 45%, transparent); }
.toc a:hover { text-decoration-color: var(--ink); }
@media (min-width: 640px) { .toc ul { grid-template-columns: repeat(2, 1fr); } }
.legal-back { margin-top: 32px; }
.contact { display: grid; gap: 20px; }
.contact p { max-width: 34em; margin-top: 12px; color: var(--fg-3); }
.contact h2 { font-size: clamp(30px, 3.4vw, 48px); font-weight: var(--fw-regular); line-height: 1.08; letter-spacing: -.025em; }
.contact .button-primary { justify-self: start; }
.help-title { font-size: clamp(30px, 3.4vw, 48px); font-weight: var(--fw-regular); line-height: 1.08; letter-spacing: -.025em; }

/* ---------- pricing ---------- */
/* Two plans side by side, set as type: a name, large light numerals, a short list with thin checkmarks, and a
   hairline between the columns. Below 720 px they stack, free first. */
.plans { display: grid; gap: clamp(28px, 4vw, 40px); }
.plan { display: grid; align-content: start; gap: 20px; }
.plan + .plan { padding-top: clamp(28px, 4vw, 40px); border-top: 1px solid var(--hairline); }
.plan-name { font-size: clamp(22px, 2.2vw, 28px); font-weight: var(--fw-regular); line-height: 1.2; letter-spacing: -.02em; }
.price { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 10px; }
.price-num { font-size: clamp(40px, 4.6vw, 56px); font-weight: var(--fw-regular); line-height: 1.08; letter-spacing: -.035em; }
.price-per { font-size: var(--fs-body); color: var(--fg-3); }
.price-note { max-width: 30ch; margin-top: 8px; font-size: 15px; line-height: 1.45; color: var(--fg-3); }
.rate-name { margin-bottom: 2px; font-size: 15px; font-weight: var(--fw-medium); line-height: 1.3; }
.rates li + li { margin-top: 22px; padding-top: 22px; border-top: 1px solid var(--hairline); }
.checks { display: grid; gap: 14px; }
.checks li { position: relative; padding-left: 30px; line-height: 1.45; color: var(--fg); }
.checks li::before {
  content: ""; position: absolute; left: 6px; top: .34em; width: 6px; height: 12px;
  border: solid currentColor; border-width: 0 1.5px 1.5px 0; rotate: 40deg;
}
.small-print { display: grid; gap: 8px; margin-top: clamp(28px, 4vw, 40px); padding-top: 24px; border-top: 1px solid var(--hairline); font-size: 15px; line-height: 1.5; color: var(--fg-3); }
.small-print b { color: var(--fg); }
@media (min-width: 720px) {
  .plans { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0; }
  .plan { padding-inline: clamp(24px, 4vw, 48px); }
  .plan:first-child { padding-left: 0; }
  .plan + .plan { padding-top: 0; padding-right: 0; border-top: 0; border-left: 1px solid var(--hairline); }
}

/* ---------- motion ---------- */
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }

/* The reply pill and the card are glass: when asked for less transparency, more contrast, or without backdrop blur, they
   are solid, and the card's light (the glare) is not drawn. (The card's own gradient background is written after the
   generic .glass-strong rules, so it would otherwise keep showing through in these modes.) */
@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
  .demo .bubble { background: var(--surface-elevated); box-shadow: 0 0 0 1px var(--slate-500); -webkit-backdrop-filter: none; backdrop-filter: none; }
  .demo .bubble::before { display: none; }
  .demo .demo-card { background: var(--surface-elevated); }
  .demo-glare { display: none; }
}
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .demo .bubble { background: var(--surface-elevated); box-shadow: 0 0 0 1px var(--mist-300); }
  .demo .bubble::before { display: none; }
  .demo .demo-card { background: var(--surface-elevated); }
  .demo-glare { display: none; }
}
@media (forced-colors: active) {
  .demo .demo-card { background: Canvas; }
  .demo-glare { display: none; }
  .msg-out, .bubble, .demo .bubble { border: 1px solid CanvasText; }
  .demo .tiles .photo-card { box-shadow: none; }
  .demo-dot::before { background: GrayText; }
  .demo-dot[aria-current="true"]::before { background: CanvasText; }
}

/* ---------- reduced motion: nothing moves; the examples are stepped by hand with the dots ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .menu-dialog[open], .faq-a { animation: none; }
  .demo *, .demo-dot::before { animation: none !important; transition: none !important; }
  .demo-scene .typing { display: none !important; }
  .demo-scene .msg-out, .demo-scene .bubble, .demo-scene .tiles li { opacity: 1 !important; }
  .demo-glare { transition: none; }   /* the light stays at rest (and site.js does not move it) */
  .demo-glare::after { display: none; }
  .button-primary, .button-secondary, .faq, .faq summary::after { transition: none; }
  .faq::details-content { transition: none; }
}

/* ---------- waitlist dialog ---------- */
/* "sign up for beta" opens Tally's form in a glass panel (markup next to the menu <dialog>, wiring in site.js:
   wireWaitlist). The iframe has no src until the first open, so nothing is requested from tally.so on load.
   The panel is the site's own glass (.glass-strong .glass--frost) with a little extra body under it, because
   Tally's text sits straight on it. On a phone it is a sheet along the bottom. */
.waitlist-dialog {
  position: fixed; inset: 0; width: 100%; height: 100%; max-width: none; max-height: none; margin: 0; padding: 0;
  border: 0; overflow: hidden; background: transparent; color: var(--ink);
}
.waitlist-dialog[open] {
  display: grid; place-items: center;
  padding: max(16px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right)) max(16px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
}
.waitlist-dialog::backdrop {
  background: color-mix(in srgb, var(--graphite-950) 22%, transparent);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.waitlist-dialog[open] .waitlist-panel { animation: waitlist-in .3s var(--ease); }
@keyframes waitlist-in { from { opacity: 0; transform: translate3d(0, 12px, 0); } to { opacity: 1; transform: none; } }
.waitlist-panel {
  --glass-under: color-mix(in srgb, var(--cloud) 68%, transparent);
  display: grid; gap: 12px; align-content: start;
  width: 100%; max-width: 560px; max-height: 100%; overflow-y: auto; overscroll-behavior: contain;
  padding: clamp(20px, 4vw, 32px); border-radius: var(--radius-panel);
}
.waitlist-top { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.waitlist-panel .section-title { font-size: clamp(28px, 3.4vw, 40px); }
.waitlist-close {
  display: inline-flex; align-items: center; justify-content: center; flex: none; min-width: 44px; min-height: 44px;
  margin-right: -14px; padding: 0 14px; border-radius: var(--radius-sm);
  font-size: 15px; font-weight: var(--fw-medium); color: var(--ink); transition: opacity .2s var(--ease);
}
.waitlist-close:hover { opacity: .65; }
/* The form and the "loading" line share one box of a fixed height, so nothing jumps when the form arrives.
   The form scrolls inside its frame if it is taller. */
.waitlist-frame { display: grid; height: min(56dvh, 400px); min-height: 300px; }
.waitlist-frame > * { grid-area: 1 / 1; min-width: 0; }
.waitlist-frame iframe { display: block; width: 100%; height: 100%; border: 0; background: transparent; opacity: 0; transition: opacity .3s var(--ease); }
.waitlist-frame.is-loaded iframe { opacity: 1; }
.waitlist-status { align-self: start; padding-top: 8px; font-size: var(--fs-body); color: var(--fg-2); }
.waitlist-frame.is-loaded .waitlist-status { display: none; }
.waitlist-help { display: flex; flex-wrap: wrap; align-items: center; gap: 0 .4em; font-size: 15px; color: var(--fg-2); }
.waitlist-help a { display: inline-flex; align-items: center; min-height: 44px; }
/* After the form is sent the frame and the help line give way to the thank-you: a share card and one primary
   button (site.js: submitted, wireShare). The hidden rules are needed because these have a display of their own. */
.waitlist-frame[hidden], .waitlist-help[hidden], .waitlist-thanks[hidden] { display: none; }
.waitlist-thanks { display: grid; justify-items: center; gap: 14px; text-align: center; }
.waitlist-thanks .lede { max-width: 26em; font-size: var(--fs-body); color: var(--fg-2); text-wrap: balance; }
.share-card {
  width: min(100%, 280px, calc(36dvh * .8)); aspect-ratio: 4 / 5; border-radius: 22px; overflow: hidden;
  background: var(--field-bottom);
  box-shadow: 0 22px 44px -22px color-mix(in srgb, var(--graphite-950) 45%, transparent), 0 0 0 1px color-mix(in srgb, var(--white) 60%, transparent);
}
.share-card img { display: block; width: 100%; height: 100%; object-fit: cover; }
.thanks-actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 0 22px; }
.thanks-actions .link, .share-link .link { display: inline-flex; align-items: center; min-height: 44px; font-size: 15px; }
.share-link { display: flex; align-items: center; justify-content: center; gap: 0 22px; margin-top: -6px; }
.share-status { min-height: 1.4em; margin: 0; font-size: 15px; color: var(--fg-2); }
@media (max-width: 599px) {
  .waitlist-dialog[open] { align-items: end; }
  .waitlist-panel { padding: 20px; }
}
@media (prefers-reduced-motion: reduce) {
  .waitlist-dialog[open] .waitlist-panel { animation: none; }
  .waitlist-frame iframe, .waitlist-close { transition: none; }
}
