/* melo website · brand: the app's apricot theme (Melo/docs/DESIGN.md: peach paper, near-white cards, one apricot fill, people colors) and the app icon's M;
 *   dark mode is a neutral charcoal with no tint, as in the app
 * type: Chillax (Indian Type Foundry, self-hosted under its Free Font License, files unmodified) for the wordmark and headlines,
 *   over the system text face for body copy
 * signature: the live Friends widget in the hero, rebuilt from Widgets/FriendsWidget.swift, and the app's own screens rebuilt
 *   in HTML from its SwiftUI views, measured against 3x simulator captures, so they stay sharp and scroll like the app; the
 *   phones have no frame, only a glass rim that catches the light as they tilt
 * critique: one apricot action (the waitlist), people colors as the only bright color, the page follows one moment (Maya's Blue Bottle run)
 * waive 30a: the emoji are melo's content (moments, reactions and challenges show them in the app itself), not icons
 * waive 7b: white is iOS's own title and badge color on the app's dark screens, and its slider thumb, measured from simulator captures */

@font-face {
  font-family: "Chillax";
  src: url("fonts/chillax-600.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Chillax";
  src: url("fonts/chillax-700.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

:root {
  color-scheme: light;

  --font-display: "Chillax", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-text: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";

  /* The apricot theme, melo's default palette (Core/ThemeChoice.swift, docs/DESIGN.md) */
  --paper: #FBF0E9;
  --paper-raised: #FEFDFC;
  --raised: #FBF0E9;
  --ink: #1E1A18;
  --ink-2: #443D39;
  --muted: #6D655F;
  --rule: #E6DCD6;
  --fill: #F2A978;
  --fill-hover: #EE9E69;
  --fill-pressed: #E8945E;
  --on-fill: #1C1A19;
  --theme-text: #924B1C;
  --wash: #FAE3D3;
  --quiet: #ECE6E1;
  /* People colors (Core/PersonPalette.swift): soft fills that always take dark text */
  --p-coral: #F09789;
  --p-periwinkle: #9BB0F3;
  --p-mint: #89CDA6;
  --p-butter: #F5CA66;
  --p-lavender: #CBA4E5;
  --p-aqua: #71C5D0;
  --p-pink: #F0A3C4;
  --p-mist: #A8B6C7;
  --on-person: #1C1A19;
  --maya: var(--p-periwinkle);
  --ellis: var(--p-lavender);
  --sam: var(--p-butter);
  --priya: var(--p-pink);
  --noor: var(--p-aqua);
  --theo: var(--p-coral);
  --jo: var(--p-mint);
  --band-warm: var(--wash);
  --band-quiet: var(--quiet);
  --lit-field: color-mix(in srgb, var(--fill) 34%, transparent);
  --lit-row: color-mix(in srgb, var(--fill) 12%, transparent);
  --lit-person: rgb(255 255 255 / 0.42);
  --track: #E6DCD6;
  --switch-off: rgb(30 26 24 / 0.2);
  --switch-thumb: #FFFDFB;
  --shadow-pop: 0 0 0 1px rgb(30 26 24 / 0.08), 0 16px 36px -16px rgb(30 26 24 / 0.4);
  --shadow-thumb: 0 2px 6px rgb(30 26 24 / 0.28);
  --tilt-shadow: rgb(30 26 24 / 0.22);
  --plate: #F2A978;
  --widget-paper: #FEFDFC;
  --widget-accent: #924B1C;
  --focus: #924B1C;
  --alert: #A8322A;
  --band-ink-bg: #1E1E1E;
  --band-ink-text: #E2E2E2;
  --band-ink-text-2: #CDCDCD;
  --band-ink-muted: #ADADAD;
  --band-ink-rule: #444444;
  --band-ink-focus: #F8BE93;
  --band-ink-switch-off: rgb(226 226 226 / 0.3);
  --card-edge: rgb(30 26 24 / 0.07);
  --shot-edge: rgb(30 26 24 / 0.09);
  --shot-shadow: 0 28px 60px -34px rgb(30 26 24 / 0.4);
  --glass-mask: #000;
  --glass-rim-lit: rgb(255 255 255 / 0.95);
  --glass-rim: rgb(255 255 255 / 0.45);
  --glass-rim-low: rgb(255 255 255 / 0.12);
  --glass-band: rgb(255 255 255 / 0.22);

  /* The app's own screens: the apricot theme as MeloTheme.swift draws it, on iOS's system colors */
  --font-app: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
  --app-bg: #FBF0E9;
  --app-surface: #FEFDFC;
  --app-ink: #1E1A18;
  --app-muted: #6D655F;
  --app-fill: #F2A978;
  --app-on-fill: #1C1A19;
  --app-accent-text: #924B1C;
  --app-wash: #FAE3D3;
  --app-quiet: #ECE6E1;
  --app-line: #E6DCD6;
  --app-title: #000000;
  --app-badge: #C93A2E;
  --app-on-badge: #FFFFFF;
  --app-separator: #E7E6E6;
  --app-tertiary: rgb(60 60 67 / 0.3);
  --app-secondary: rgb(60 60 67 / 0.6);
  --app-status: #000000;
  --app-glass: rgb(255 246 239 / 0.94);
  --app-glass-accent: #8F4819;
  --app-glass-rim: rgb(255 255 255 / 0.95);
  --app-glass-edge: rgb(150 134 124 / 0.55);
  --app-glass-shadow: rgb(70 40 20 / 0.08);
  --app-bar: rgb(252 248 247 / 0.94);
  --app-bar-edge: rgb(120 116 112 / 0.5);
  --app-lens: #FDEFE7;
  --app-lens-edge: rgb(181 160 147 / 0.8);
  --app-frost: rgb(255 246 237 / 0.88);
  --app-hairline: #E6DDD5;
  --app-material: #F8F5F4;
  --app-composer: #F9F5F2;
  --app-field: #FDFCFB;
  --app-placeholder: rgb(60 60 67 / 0.25);
  --app-cat-food: #A9472F;
  --app-cat-coffee: #87553E;
  --app-cat-groceries: #506447;
  --app-cat-shopping: #69558E;
  --app-cat-transport: #4F5F8E;
  --app-cat-entertainment: #9C536E;
  --app-cat-bills: #5E6270;
  --app-track: rgb(120 120 128 / 0.2);
  --app-divider: rgb(60 60 67 / 0.16);
  --app-grid: #D2D1D3;
  --app-mark: color-mix(in srgb, var(--app-fill) 22%, var(--app-surface));
  --app-mark-strong: color-mix(in srgb, var(--app-fill) 75%, transparent);
  --app-faded: color-mix(in srgb, var(--app-fill) 30%, transparent);
  --app-sheet-backdrop: #C8B6A9;
  --app-thumb: #FFFFFF;
  --app-thumb-shade: rgb(0 0 0 / 0.12);
  --app-invite: #E8D2C4;
  --app-over: #C93A2E;
  --app-over-text: #B3261E;
  --app-last: color-mix(in srgb, var(--app-muted) 45%, transparent);
  --app-none: color-mix(in srgb, var(--app-muted) 55%, transparent);
  --app-send: var(--app-fill);
  --app-on-send: var(--app-on-fill);
  --mask-on: #000000;

  --text-display: clamp(2.75rem, 3.6vw + 1.9rem, 5.25rem);
  --text-section: clamp(1.75rem, 1.6vw + 1.3rem, 3rem);
  --text-title: clamp(1.3125rem, 0.45vw + 1.1rem, 1.625rem);
  --text-lead: clamp(1.125rem, 0.4vw + 0.98rem, 1.375rem);
  --text-body: 1.0625rem;
  --text-small: 0.9375rem;

  --gutter: clamp(20px, 4.45vw, 64px);
  --col-gap: clamp(16px, 2.2vw, 32px);
  --section-pad: clamp(88px, 9.5vw, 144px);
  --radius-plate: clamp(28px, 3vw, 44px);
  --radius-card: 26px;
  --radius-button: 999px;
  --nav-h: 72px;
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --spring-unveil: cubic-bezier(0.25, 0.85, 0.35, 1);
  --spring-smooth: cubic-bezier(0.3, 0.9, 0.4, 1);
  --spring-snappy: cubic-bezier(0.3, 1.05, 0.5, 1);
}

/* The app's springs, sampled: unveil (smooth, 0.9 s) over 1 s, smooth (0.42 s) over 450 ms, and
   snappy (0.32 s, bounce 0.15) over 360 ms. Browsers without linear() keep the curves above. */
@supports (transition-timing-function: linear(0, 1)) {
  :root {
    --spring-unveil: linear(0, 0.048, 0.155, 0.282, 0.407, 0.521, 0.619, 0.701, 0.768, 0.821, 0.863, 0.896, 0.921, 0.941, 0.956, 0.967, 0.975, 0.982, 0.986, 0.99, 1);
    --spring-smooth: linear(0, 0.084, 0.25, 0.423, 0.573, 0.692, 0.783, 0.849, 0.897, 0.93, 0.953, 0.968, 0.979, 0.986, 1);
    --spring-snappy: linear(0, 0.096, 0.288, 0.489, 0.659, 0.789, 0.879, 0.938, 0.973, 0.992, 1.002, 1.006, 1.006, 1.005, 1);
  }
}

@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;
    --paper: #1E1E1E;
    --paper-raised: #292929;
    --raised: #353535;
    --ink: #E2E2E2;
    --ink-2: #CDCDCD;
    --muted: #ADADAD;
    --rule: #444444;
    --fill: #F3A973;
    --fill-hover: #F9B786;
    --fill-pressed: #E99D67;
    --theme-text: #F8BE93;
    --wash: #393939;
    --quiet: #353535;
    --p-coral: #D78679;
    --p-periwinkle: #899CDC;
    --p-mint: #7CB695;
    --p-butter: #D6B15C;
    --p-lavender: #B692CE;
    --p-aqua: #6CAEB7;
    --p-pink: #D68FAE;
    --p-mist: #939FAE;
    --well: #171717;
    --band-warm: var(--well);
    --band-quiet: var(--well);
    --lit-field: var(--wash);
    --lit-row: rgb(226 226 226 / 0.05);
    --lit-person: rgb(255 255 255 / 0.3);
    --track: #444444;
    --switch-off: rgb(226 226 226 / 0.28);
    --shadow-pop: 0 0 0 1px rgb(226 226 226 / 0.08), 0 16px 36px -16px rgb(0 0 0 / 0.6);
    --tilt-shadow: rgb(0 0 0 / 0.5);
    --plate: var(--well);
    --widget-paper: #292929;
    --widget-accent: #F8BE93;
    --focus: #F8BE93;
    --alert: #F4A08F;
    --band-ink-bg: #151515;
    --card-edge: rgb(226 226 226 / 0.07);
    --shot-edge: rgb(226 226 226 / 0.1);
    --shot-shadow: 0 28px 60px -34px rgb(0 0 0 / 0.7);
    --glass-rim-lit: rgb(255 255 255 / 0.55);
    --glass-rim: rgb(255 255 255 / 0.2);
    --glass-rim-low: rgb(255 255 255 / 0.06);
    --glass-band: rgb(255 255 255 / 0.05);

    --app-bg: #1E1E1E;
    --app-surface: #292929;
    --app-ink: #E2E2E2;
    --app-muted: #ADADAD;
    --app-fill: #F3A973;
    --app-accent-text: #F8BE93;
    --app-wash: #393939;
    --app-quiet: #353535;
    --app-line: #444444;
    --app-title: #FFFFFF;
    --app-separator: #404040;
    --app-tertiary: rgb(235 235 245 / 0.3);
    --app-secondary: rgb(235 235 245 / 0.6);
    --app-status: #FFFFFF;
    --app-glass: rgb(61 61 61 / 0.96);
    --app-glass-accent: #FFDCB1;
    --app-glass-rim: rgb(255 255 255 / 0.22);
    --app-glass-edge: rgb(0 0 0 / 0.8);
    --app-glass-shadow: rgb(0 0 0 / 0.35);
    --app-bar: rgb(66 66 66 / 0.95);
    --app-bar-edge: rgb(0 0 0 / 0.85);
    --app-lens: #585858;
    --app-lens-edge: rgb(0 0 0 / 0.85);
    --app-frost: rgb(42 42 42 / 0.9);
    --app-hairline: #3A3A3A;
    --app-material: #242424;
    --app-composer: #2A2A2A;
    --app-field: #282828;
    --app-placeholder: rgb(235 235 245 / 0.25);
    --app-cat-food: #F0A08E;
    --app-cat-coffee: #D4A68C;
    --app-cat-groceries: #B8C9AD;
    --app-cat-shopping: #C7BAF2;
    --app-cat-transport: #B4C0E6;
    --app-cat-entertainment: #DFABC0;
    --app-cat-bills: #B7BBC8;
    --app-track: rgb(120 120 128 / 0.36);
    --app-divider: rgb(84 84 88 / 0.2);
    --app-grid: #575757;
    --app-mark: var(--app-wash);
    --app-faded: var(--app-wash);
    --app-sheet-backdrop: #1E1E1E;
    --app-invite: #55463B;
    --app-over-text: #F2867A;
    --app-mark-strong: var(--app-fill);
    --app-send: var(--app-ink);
    --app-on-send: var(--app-bg);
  }
}

/* Base */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  overflow-x: clip;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-top: calc(var(--nav-h) + 16px);
}

body {
  overflow-x: clip;
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-text);
  font-size: var(--text-body);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

img,
svg {
  display: block;
  max-width: 100%;
}

img {
  height: auto;
}

h1,
h2,
h3 {
  margin: 0;
  font-family: var(--font-display);
  font-synthesis: none;
  font-weight: 600;
  line-height: 1.04;
  letter-spacing: -0.025em;
  overflow-wrap: break-word;
  min-width: 0;
  text-wrap: balance;
}

h2 {
  font-size: var(--text-section);
}

h3 {
  font-size: var(--text-title);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.01em;
}

p,
dl,
dd,
ul,
ol,
figure {
  margin: 0;
}

ul,
ol {
  padding: 0;
  list-style: none;
}

p,
dd {
  text-wrap: pretty;
}

a {
  color: inherit;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

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

[hidden] {
  display: none !important;
}

.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;
}

.skip-link {
  position: absolute;
  top: 12px;
  left: 16px;
  z-index: 100;
  padding: 12px 16px;
  border-radius: 12px;
  background: var(--ink);
  color: var(--paper);
  font-weight: 600;
  text-decoration: none;
  transform: translateY(-200%);
}

.skip-link:focus-visible {
  transform: none;
}

.container {
  width: 100%;
  max-width: 1440px;
  margin-inline: auto;
  padding-left: max(var(--gutter), env(safe-area-inset-left, 0px));
  padding-right: max(var(--gutter), env(safe-area-inset-right, 0px));
}

.lead {
  font-size: var(--text-lead);
  line-height: 1.45;
  color: var(--ink-2);
}

.fine {
  font-size: var(--text-small);
  color: var(--muted);
}

.emoji {
  margin-right: 0.16em;
}

.nowrap {
  white-space: nowrap;
}

.card {
  display: block;
  border-radius: var(--radius-card);
  background: var(--paper-raised);
  box-shadow: 0 0 0 1px var(--card-edge);
}

/* Buttons */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 56px;
  padding: 0 28px;
  border: 0;
  border-radius: var(--radius-button);
  background: var(--fill);
  color: var(--on-fill);
  font-family: var(--font-text);
  font-size: var(--text-body);
  font-weight: 600;
  line-height: 1.1;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 160ms ease, transform 160ms var(--ease-out);
}

.button:hover {
  background: var(--fill-hover);
}

.button:active {
  background: var(--fill-pressed);
  transform: scale(0.98);
}

.button:focus-visible {
  outline-offset: 4px;
}

.button-small {
  min-height: 44px;
  padding: 0 20px;
  border-radius: 999px;
  font-size: var(--text-small);
  white-space: nowrap;
}

/* Header */

/* With viewport-fit=cover, the sticky header sits below the status bar, and this band covers what scrolls under it. */
body::before {
  content: "";
  position: fixed;
  inset: 0 0 auto;
  z-index: 21;
  height: env(safe-area-inset-top, 0px);
  background: var(--paper);
}

.site-header {
  position: sticky;
  top: env(safe-area-inset-top, 0px);
  z-index: 20;
  background: var(--paper);
  box-shadow: 0 1px 0 transparent;
  transition: box-shadow 200ms ease;
}

.site-header[data-scrolled] {
  box-shadow: 0 1px 0 var(--rule);
}

.header-inner {
  display: flex;
  align-items: center;
  gap: 20px;
  min-height: var(--nav-h);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  margin-right: auto;
  border-radius: 12px;
  color: var(--ink);
  text-decoration: none;
}

.brand-mark {
  width: 46px;
  height: auto;
  fill: var(--fill);
}

.brand-word {
  font-family: var(--font-display);
  font-size: 30px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.045em;
}

.site-nav ul {
  display: flex;
  gap: 4px;
}

.site-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 16px;
  border-radius: 12px;
  font-size: var(--text-small);
  font-weight: 600;
  text-decoration: none;
  transition: background-color 160ms ease;
}

.site-nav a:hover {
  background: var(--wash);
}

.site-nav a:active {
  background: var(--quiet);
}

/* Hero */

.hero {
  padding-block: clamp(12px, 2.5vw, 32px) clamp(16px, 2vw, 24px);
}

/* With its two columns side by side on a landscape screen, the hero fills the first screen below
   the header and centers its content, so the next section starts below the fold. */
@media (min-width: 901px) and (orientation: landscape) {
  .hero {
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-height: calc(100svh - var(--nav-h));
  }
}

/* The hero and the first section share the cream paper, so their paddings would stack into
   one wide empty band. */
.hero + .section {
  padding-top: clamp(48px, 4.5vw, 72px);
}

.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  column-gap: clamp(40px, 5.5vw, 96px);
  align-items: center;
}

/* The headline is sized from this column's width (cqi), so each sentence fits on one line. */
.hero-text {
  container-type: inline-size;
  display: grid;
  justify-items: start;
  gap: 24px;
}

.hero h1 {
  font-size: clamp(1.75rem, 9cqi, var(--text-display));
  line-height: 1.05;
}

/* Each sentence of the headline starts its own line, with clear space between the two. */
.hero h1 .h1-line {
  display: block;
}

.hero h1 .h1-line + .h1-line {
  margin-top: 0.2em;
}

.hero .lead {
  max-width: 30ch;
}

.hero-actions {
  display: grid;
  justify-items: start;
  justify-self: stretch;
  gap: 16px;
  margin-top: 12px;
}

/* The beta waitlist: an email field beside the page's one primary action. The form posts to melo's
   waitlist Worker (waitlist/worker.js); site.js sends it in the background and answers underneath. */
#waitlist {
  scroll-margin-top: calc(var(--nav-h) + 32px);
}

.waitlist {
  display: grid;
  gap: 12px;
  width: min(100%, 32rem);
}

.waitlist-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.waitlist-input {
  flex: 999 1 15rem;
  min-width: 0;
  min-height: 56px;
  padding: 0 20px;
  border: 1px solid var(--rule);
  border-radius: var(--radius-button);
  background: var(--paper-raised);
  color: var(--ink);
  font-family: var(--font-text);
  font-size: var(--text-body);
}

.waitlist-input::placeholder {
  color: var(--muted);
  opacity: 1;
}

.waitlist-input[aria-invalid="true"] {
  border-color: var(--alert);
}

.waitlist .button {
  flex: 1 0 auto;
}

.waitlist-note {
  text-wrap: balance;
}

.waitlist .button:disabled {
  opacity: 0.6;
  cursor: progress;
}

.waitlist[data-state="invalid"] .waitlist-note,
.waitlist[data-state="busy"] .waitlist-note,
.waitlist[data-state="unverified"] .waitlist-note,
.waitlist[data-state="error"] .waitlist-note {
  color: var(--alert);
}

/* hCaptcha's invisible check lives here and takes no room; when it wants a puzzle solved, the
   puzzle opens over the page. */
.waitlist-check {
  position: absolute;
  width: 0;
  height: 0;
}

.waitlist[data-state="joined"] .waitlist-row,
.waitlist[data-state="joined"] .waitlist-check {
  display: none;
}

.waitlist[data-state="joined"] .waitlist-note {
  color: var(--ink);
  font-size: var(--text-body);
  font-weight: 600;
}

/* A field only bots fill in */
.waitlist-trap {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.hero-visual {
  container-type: inline-size;
  min-width: 0;
}

.plate {
  --bleed: min(120px, calc((100vw - min(100vw, 1440px)) / 2 + max(var(--gutter), env(safe-area-inset-right, 0px))));
  position: relative;
  isolation: isolate;
  display: grid;
  place-items: center;
  padding: clamp(28px, 8cqi, 76px) clamp(20px, 6cqi, 60px);
  padding-left: calc(clamp(20px, 6cqi, 60px) + var(--bleed));
  border-radius: var(--radius-plate);
  background: var(--plate);
}

/* The plate runs off the right edge of the page; html and body clip it. */
.plate::before {
  content: "";
  position: absolute;
  inset: 0 -100vw 0 50%;
  z-index: -1;
  background: var(--plate);
}

/* Widgets: iOS points scaled by --pt. Sizes follow FriendsWidget.swift. */

.home {
  --pt: min(1.6px, calc(100cqi / 420), calc((100svh - 250px) / 360));
  display: grid;
  gap: calc(22 * var(--pt));
  width: calc(338 * var(--pt));
}

.widget {
  position: relative;
  height: calc(158 * var(--pt));
  padding: calc(16 * var(--pt));
  overflow: hidden;
  border-radius: calc(22 * var(--pt));
  background: var(--widget-paper);
  color: var(--ink);
  font-family: var(--font-text);
}

.w-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: calc(6 * var(--pt));
  font-size: calc(12 * var(--pt));
  font-weight: 600;
  line-height: 1.3;
}

.w-title {
  overflow: hidden;
  color: var(--widget-accent);
  white-space: nowrap;
  text-overflow: ellipsis;
}

.w-brand {
  flex: none;
  color: var(--muted);
  font-family: var(--font-display);
  font-size: calc(12 * var(--pt));
  font-weight: 600;
}

.w-challenge {
  margin-top: calc(8 * var(--pt));
  overflow: hidden;
  font-size: calc(12 * var(--pt));
  font-weight: 600;
  line-height: 1.3;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.w-rows {
  position: relative;
  height: calc(94 * var(--pt));
  margin-top: calc(10 * var(--pt));
}

.w-rows-static {
  height: calc(60 * var(--pt));
}

.w-row {
  --s: 1;
  position: absolute;
  inset: 0 0 auto;
  display: flex;
  align-items: center;
  gap: calc(8 * var(--pt));
  height: calc(26 * var(--pt));
  font-size: calc(15 * var(--pt));
  line-height: 1.2;
  transform: translateY(calc(var(--i, 0) * 34 * var(--pt))) scale(var(--s));
  transform-origin: left center;
  transition: transform 700ms var(--ease-out), opacity 450ms ease;
}

.w-row.is-new {
  --s: 0.94;
  opacity: 0;
}

.w-row.is-out {
  opacity: 0;
}

.w-avatar {
  display: grid;
  flex: none;
  place-items: center;
  width: calc(26 * var(--pt));
  height: calc(26 * var(--pt));
  border-radius: 50%;
  background: var(--who, var(--quiet));
  color: var(--on-person);
  font-family: var(--font-display);
  font-size: calc(11.4 * var(--pt));
  font-weight: 600;
  line-height: 1;
}

.w-name {
  flex: none;
  font-weight: 600;
  white-space: nowrap;
}

.w-line {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.w-age {
  flex: none;
  margin-left: auto;
  padding-left: calc(4 * var(--pt));
  color: var(--muted);
  font-size: calc(12 * var(--pt));
  white-space: nowrap;
}

/* Sections */

.section {
  padding-block: var(--section-pad);
}

.section-head {
  display: grid;
  gap: 20px;
  max-width: 46rem;
  margin-bottom: clamp(40px, 5vw, 64px);
}

.section-head .lead {
  max-width: 38ch;
}

.section-head-split {
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  align-items: end;
  column-gap: var(--col-gap);
  max-width: none;
}

.band-quiet {
  background: var(--band-quiet);
}

/* Moments, never money */

/* Under the comparison: sharing is optional, and the tracker stands on its own. */
.compare-note {
  display: grid;
  gap: 8px;
  max-width: 34rem;
  margin-top: clamp(40px, 5vw, 64px);
}

.compare-note p {
  color: var(--ink-2);
}

.compare-table {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
}

.compare-table .c-label {
  width: 18%;
}

.compare-table thead th {
  padding: 0 var(--col-gap) 28px 0;
  font-weight: 400;
  text-align: left;
  vertical-align: bottom;
}

.compare-table thead th:last-child,
.compare-table tbody td:last-child {
  padding-right: 0;
}

.col-label {
  display: block;
  margin-bottom: 16px;
  color: var(--muted);
  font-size: var(--text-small);
  font-weight: 600;
}

.ledger-card,
.moment-card {
  min-height: 148px;
  padding: 24px 28px;
}

.ledger-card {
  display: grid;
  align-content: center;
  gap: 2px;
}

.ledger-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 8px;
}

.ledger-place,
.ledger-amount,
.moment-title {
  font-family: var(--font-display);
  font-size: clamp(1.375rem, 1vw + 1rem, 1.875rem);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.01em;
}

.ledger-amount {
  font-variant-numeric: tabular-nums;
}

.ledger-meta,
.moment-caption {
  display: block;
  color: var(--muted);
  font-size: var(--text-small);
}

.moment-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-content: center;
  column-gap: 20px;
  border-radius: 30px;
  background: var(--maya);
  box-shadow: none;
  color: var(--on-person);
}

.moment-card .moment-caption {
  color: var(--on-person);
}

/* The title and the emoji hug what they hold, so a lit detail lights just the words or the emoji,
   as on Maya's own card. */
.moment-title {
  justify-self: start;
}

.moment-emoji {
  grid-row: span 2;
  align-self: start;
  justify-self: start;
  font-size: 44px;
  line-height: 1;
}

.compare-table tbody th,
.compare-table tbody td {
  padding: 20px var(--col-gap) 20px 0;
  border-top: 1px solid var(--rule);
  text-align: left;
  vertical-align: baseline;
}

.compare-table tbody tr:last-child th,
.compare-table tbody tr:last-child td {
  border-bottom: 1px solid var(--rule);
}

.compare-table tbody th {
  color: var(--muted);
  font-size: var(--text-small);
  font-weight: 600;
}

.compare-table .never {
  color: var(--theme-text);
  font-weight: 600;
}

/* How a moment gets there */

.timeline {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: var(--col-gap);
}

.step {
  display: grid;
  grid-template-rows: auto auto auto 1fr;
  align-content: start;
  gap: 12px;
  padding-top: 24px;
  border-top: 2px solid var(--ink);
}

.step-time {
  margin-bottom: 8px;
  color: var(--theme-text);
  font-family: var(--font-display);
  font-size: clamp(2.75rem, 3vw + 1.25rem, 4.5rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}

.step > p:not(.step-time) {
  max-width: 34ch;
  color: var(--ink-2);
}

.step-visual {
  display: grid;
  align-content: start;
  justify-items: start;
  gap: 12px;
  margin-top: 20px;
}

.mini-ledger,
.mini-row {
  display: flex;
  align-items: center;
  gap: 16px;
  width: min(100%, 340px);
  padding: 16px 20px;
  border-radius: 22px;
}

.mini-emoji {
  font-size: 30px;
  line-height: 1;
}

.mini-text {
  display: grid;
  min-width: 0;
  line-height: 1.3;
}

.mini-text strong {
  font-weight: 600;
}

.mini-text span {
  color: var(--muted);
  font-size: var(--text-small);
}

.mini-row .mini-text span {
  color: var(--ink);
  font-size: var(--text-body);
}

.mini-amount,
.mini-age {
  margin-left: auto;
  white-space: nowrap;
}

.mini-amount {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.mini-age {
  color: var(--muted);
  font-size: var(--text-small);
}

.mini-row .w-avatar {
  --pt: 1.45px;
}

.notice {
  width: min(100%, 360px);
  padding: 16px 20px 8px;
  border-radius: 26px;
}

.notice-head {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--muted);
  font-size: 0.8125rem;
}

.notice-head img {
  width: 20px;
  height: 20px;
}

.notice-time {
  margin-left: auto;
}

.notice-title {
  margin-top: 8px;
  font-weight: 600;
}

.notice-body {
  color: var(--ink-2);
  font-size: var(--text-small);
  line-height: 1.4;
}

.notice-actions {
  display: grid;
  margin-top: 12px;
}

.notice-actions button,
.notice-undo {
  display: flex;
  align-items: center;
  width: 100%;
  min-height: 44px;
  padding: 0;
  border: 0;
  border-top: 1px solid var(--rule);
  background: none;
  color: var(--theme-text);
  font-family: var(--font-text);
  font-size: var(--text-small);
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  transition: color 160ms ease, opacity 160ms ease;
}

.notice-actions button:hover,
.notice-undo:hover {
  color: var(--ink);
}

.notice-actions button:active,
.notice-undo:active {
  opacity: 0.6;
}

.notice-done {
  display: grid;
  margin-top: 8px;
}

.notice-done[hidden] {
  display: none;
}

.notice-undo {
  width: auto;
  margin-top: 4px;
  border-top: 0;
}

.reactions {
  display: flex;
  gap: 8px;
}

.reactions {
  position: relative;
  flex-wrap: wrap;
}

.reaction,
.reaction-add {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  padding: 0 16px;
  border: 0;
  border-radius: 999px;
  background: var(--quiet);
  color: var(--ink);
  font-family: var(--font-text);
  font-size: var(--text-small);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: background-color 160ms ease, transform 160ms var(--ease-out);
}

.reaction:hover,
.reaction-add:hover {
  background: color-mix(in srgb, var(--quiet) 88%, var(--ink));
}

.reaction:active,
.reaction-add:active {
  transform: scale(0.96);
  opacity: 0.85;
}

/* The emoji springs and tilts on its own when a reaction is added. */
.reaction > [aria-hidden] {
  display: inline-block;
}

.reaction[aria-pressed="true"] {
  background: var(--wash);
  box-shadow: inset 0 0 0 1.5px var(--fill);
}

.reaction:disabled,
.reaction-add:disabled {
  background: var(--track);
  box-shadow: none;
  color: var(--muted);
  opacity: 0.7;
  cursor: not-allowed;
}

/* The reaction burst (site.js): a layer at the chip's centre, clipped only at the page's sides. */
.how {
  position: relative;
  overflow-x: clip;
}

.burst {
  position: absolute;
  z-index: 19;
  width: 0;
  height: 0;
  pointer-events: none;
}

.burst-piece,
.burst-ring,
.burst-disc {
  position: absolute;
  top: 0;
  left: 0;
  opacity: 0;
}

.burst-piece {
  line-height: 1;
  white-space: nowrap;
}

.burst-ring {
  width: 106px;
  height: 106px;
  overflow: visible;
}

.burst-ring circle {
  fill: none;
  stroke: var(--fill);
  stroke-width: 4px;
  vector-effect: non-scaling-stroke;
}

.burst-disc {
  width: 76px;
  height: 76px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--fill) 22%, transparent);
}

.reaction-add {
  justify-content: center;
  width: 40px;
  padding: 0;
}

.reaction-add svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
}

.reaction-picker {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  z-index: 5;
  display: flex;
  gap: 4px;
  padding: 4px;
  border-radius: 999px;
  background: var(--paper-raised);
  box-shadow: var(--shadow-pop);
}

.reaction-picker[hidden] {
  display: none;
}

.reaction-picker button {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: 0;
  border-radius: 50%;
  background: none;
  font-size: 20px;
  cursor: pointer;
  transition: background-color 160ms ease, transform 160ms var(--ease-out);
}

.reaction-picker button:hover {
  background: var(--wash);
  transform: scale(1.12);
}

.reaction-picker button:active {
  transform: scale(0.94);
}

.mini-row {
  transition: opacity 300ms ease;
}

.mini-row.is-hidden {
  opacity: 0.45;
}

.mini-row.is-hidden .mini-text span {
  text-decoration: line-through;
}

/* Challenges */

.challenge-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--col-gap);
}

.challenge {
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: 16px;
  padding: clamp(24px, 2.6vw, 36px);
  box-shadow: none;
}

.challenge h3 {
  font-size: clamp(1.375rem, 0.8vw + 1rem, 1.75rem);
}

.challenge > p {
  color: var(--ink-2);
}

.challenge-status {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  padding-top: 20px;
  border-top: 1px solid var(--rule);
}

.status-text {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.join {
  flex: none;
  min-height: 40px;
  padding: 0 20px;
  border: 0;
  border-radius: 999px;
  background: var(--fill);
  color: var(--on-fill);
  font-family: var(--font-text);
  font-size: var(--text-small);
  font-weight: 600;
  cursor: pointer;
  transition: background-color 160ms ease, transform 160ms var(--ease-out);
}

.join:hover {
  background: var(--fill-hover);
}

.join:active {
  transform: scale(0.96);
}

.join[aria-pressed="true"] {
  background: transparent;
  box-shadow: inset 0 0 0 1.5px var(--ink);
  color: var(--ink);
}

.challenge-status .status {
  color: var(--theme-text);
  font-weight: 600;
}

.challenge-status .who {
  color: var(--muted);
  font-size: var(--text-small);
}

/* Your group, on one screen */

.group-grid {
  display: grid;
  grid-template-columns: minmax(0, 4fr) minmax(0, 8fr);
  align-items: center;
  column-gap: clamp(40px, 6vw, 112px);
}

.group-text {
  display: grid;
  gap: 20px;
}

.facts {
  display: grid;
  gap: 20px;
  margin-top: 20px;
}

.facts div {
  display: grid;
  gap: 2px;
  padding-top: 20px;
  border-top: 1px solid var(--rule);
}

.facts dt {
  font-weight: 600;
}

.facts dd {
  color: var(--ink-2);
}

/* The group’s details lead, a little larger, so its moving picture has room. */
.group-shots {
  display: grid;
  grid-template-columns: minmax(0, 1.12fr) minmax(0, 1fr);
  align-items: start;
  gap: var(--col-gap);
  width: min(100%, 800px);
  justify-self: end;
}

.shot {
  overflow: hidden;
  border-radius: 12% / 5.53%;
  background: var(--paper-raised);
  box-shadow: 0 0 0 1px var(--shot-edge), var(--shot-shadow);
}

/* No phone frame: the screen is a pane of glass. A bright rim catches the light where it falls and
   fades opposite, a soft band inside gives the pane its thickness, and the light swings with the
   tilt, so a flat screen reads as a slab in space. */
.shot::before,
.shot::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
  pointer-events: none;
}

.shot::before {
  box-shadow: inset 0 0 0 calc(5 * var(--glass-px, 1px)) var(--glass-band);
}

.shot::after {
  padding: 1.5px;
  background: linear-gradient(calc(145deg + var(--ry, 0deg) * 4 - var(--rx, 0deg) * 4),
    var(--glass-rim-lit), var(--glass-rim) 24%, var(--glass-rim-low) 50%, var(--glass-rim) 76%, var(--glass-rim-lit));
  -webkit-mask: linear-gradient(var(--glass-mask) 0 0) content-box, linear-gradient(var(--glass-mask) 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(var(--glass-mask) 0 0) content-box exclude, linear-gradient(var(--glass-mask) 0 0);
}

.shot .phone {
  border-radius: inherit;
}

.shot-lower {
  margin-top: clamp(40px, 8vw, 112px);
}

/* The dots under the stacked screens on a phone: which screen is in front, and a way to switch. */
.stack-dots {
  display: none;
  grid-area: 2 / 1;
  justify-self: center;
  translate: 6% 0;
  gap: 2px;
}

.stack-dots button {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  cursor: pointer;
}

.stack-dots button::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--rule);
  transition: background-color 200ms ease;
}

.stack-dots button[aria-pressed="true"]::before {
  background: var(--ink);
}

.stack-dots button:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: -2px;
}

/* Comfortable by default */

.band-ink {
  --ink: var(--band-ink-text);
  --ink-2: var(--band-ink-text-2);
  --muted: var(--band-ink-muted);
  --rule: var(--band-ink-rule);
  --focus: var(--band-ink-focus);
  --switch-off: var(--band-ink-switch-off);
  background: var(--band-ink-bg);
  color: var(--ink);
}

.privacy-grid {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  align-items: start;
  column-gap: clamp(40px, 6vw, 112px);
}

.privacy-head {
  position: sticky;
  top: calc(var(--nav-h) + 32px);
  display: grid;
  gap: 20px;
}

.shot-crop {
  width: min(100%, 340px);
  margin-top: 20px;
  border-radius: 12% / 12.35%;
}

.shot-crop .phone-window {
  aspect-ratio: 420 / 408;
}

.shot-crop .phone-window::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  z-index: 8;
  height: 24%;
  background: linear-gradient(transparent, var(--app-bg) 85%);
  pointer-events: none;
}

.row {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
  gap: 8px var(--col-gap);
  padding-block: 28px;
  border-top: 1px solid var(--rule);
}

.row:last-child {
  border-bottom: 1px solid var(--rule);
}

.row dt {
  font-family: var(--font-display);
  font-size: var(--text-title);
  font-weight: 700;
  line-height: 1.2;
}

.row dd {
  color: var(--ink-2);
}

/* Close */

.close-inner {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  column-gap: clamp(28px, 5vw, 80px);
}

.close-icon {
  display: block;
  width: clamp(120px, 14vw, 200px);
  border-radius: 22.5%;
}

.close-icon img {
  width: 100%;
}

.close-text {
  display: grid;
  justify-items: start;
  gap: 20px;
  max-width: 44rem;
}

.close-text h2 {
  font-size: clamp(2rem, 2.4vw + 1.25rem, 3.75rem);
}

.close-text .lead {
  max-width: 40ch;
}

.close-text > .button,
.close-text .waitlist {
  margin-top: 8px;
}

/* Footer */

.site-footer {
  padding-block: clamp(56px, 6vw, 88px) 40px;
  box-shadow: inset 0 1px 0 var(--rule);
}

.footer-word {
  margin-bottom: clamp(24px, 3vw, 40px);
  color: var(--fill);
  font-family: var(--font-display);
  font-size: clamp(6rem, 21vw, 21rem);
  font-weight: 700;
  line-height: 0.8;
  letter-spacing: -0.06em;
}

.footer-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px 32px;
}

.site-footer nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-left: -12px;
}

.site-footer nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 12px;
  border-radius: 12px;
  font-size: var(--text-small);
  font-weight: 600;
  text-decoration: none;
  transition: background-color 160ms ease;
}

.site-footer nav a:hover {
  background: var(--wash);
}

.legal {
  color: var(--muted);
  font-size: 0.875rem;
}

/* Small widgets: Spending at a glance and Add transaction, from Widgets/MeloWidgets.swift */

.widget-pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: calc(22 * var(--pt));
}

.widget-small {
  display: flex;
  flex-direction: column;
}

.w-head-spend {
  align-items: center;
}

.w-wordmark {
  color: var(--widget-accent);
  font-family: var(--font-display);
  font-size: calc(17 * var(--pt));
  font-weight: 700;
  line-height: 1.2;
}

.w-icon {
  flex: none;
  width: calc(17 * var(--pt));
  height: calc(17 * var(--pt));
  fill: var(--widget-accent);
}

.w-caption {
  margin-top: calc(9 * var(--pt));
  color: var(--muted);
  font-size: calc(12 * var(--pt));
  line-height: 1.25;
}

.w-amount {
  margin-top: calc(2 * var(--pt));
  font-size: calc(28 * var(--pt));
  font-weight: 600;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
}

.w-foot {
  margin-top: calc(7 * var(--pt));
  overflow: hidden;
  color: var(--muted);
  font-size: calc(11 * var(--pt));
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* Add transaction: a large plus in the theme fill, with its name under it, centred. */
.widget-add {
  align-items: center;
  justify-content: center;
  gap: calc(12 * var(--pt));
}

.w-add {
  display: grid;
  place-items: center;
  width: calc(88 * var(--pt));
  height: calc(88 * var(--pt));
  border-radius: 50%;
  background: var(--fill);
  color: var(--on-fill);
}

/* The sprite's plus drawn 48 points wide matches SF Symbols' semibold plus at 40. */
.w-add svg {
  width: calc(48 * var(--pt));
  height: calc(48 * var(--pt));
}

.w-add-label {
  overflow: hidden;
  font-size: calc(15 * var(--pt));
  font-weight: 600;
  line-height: calc(20 / 15);
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* Tilt: site.js sets --rx and --ry (degrees) and --lift from the cursor, a finger, the scroll or the
   phone's motion, so cards move only when someone does. Everything rests flat without script. */

[data-tilt] {
  transform: perspective(1000px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateY(calc(var(--lift, 0) * -6px)) scale(calc(1 + var(--lift, 0) * var(--lift-scale, 0.03)));
}

/* Only cards with floating inner layers keep a 3D context. Phones, tiles and widgets stay flat
   planes, which also keeps Safari clipping them to their rounded corners. */
.card[data-tilt],
.close-icon[data-tilt] {
  transform-style: preserve-3d;
}

[data-tilt].is-lifted {
  z-index: 3;
}

.widget {
  --lift-scale: 0.05;
}

.shot[data-tilt] {
  --lift-scale: 0.025;
}

.tile[data-tilt] {
  --lift-scale: 0.012;
}

.close-icon[data-tilt] {
  --lift-scale: 0.08;
}

/* Flat planes: a shadow that slides opposite the tilt, and inner layers that float above the card. */
.card[data-tilt],
.tile[data-tilt],
.shot[data-tilt],
.close-icon[data-tilt] {
  box-shadow: var(--edge, 0 0 0 0 transparent), calc(var(--sx, 0) * 1px) calc(var(--sy, 0) * 1px + 22px + var(--lift, 0) * 16px) calc(44px + var(--lift, 0) * 24px) -22px var(--tilt-shadow);
}

.card[data-tilt] {
  --edge: 0 0 0 1px var(--card-edge);
}

.moment-card[data-tilt],
.challenge[data-tilt] {
  --edge: 0 0 0 0 transparent;
}

.shot[data-tilt] {
  --edge: 0 0 0 1px var(--shot-edge);
}

.widget {
  box-shadow: calc(var(--sx, 0) * 1px) calc(var(--sy, 0) * 1px + 16px + var(--lift, 0) * 14px) calc(36px + var(--lift, 0) * 22px) -18px var(--tilt-shadow);
}

.challenge[data-tilt] > *,
.ledger-card[data-tilt] > *,
.moment-card[data-tilt] > *,
.notice[data-tilt] > *,
.mini-ledger[data-tilt] > *,
.mini-row[data-tilt] > * {
  transform: translateZ(18px);
}

.challenge[data-tilt] > h3,
.moment-card[data-tilt] > .moment-emoji {
  transform: translateZ(34px);
}

.close-icon[data-tilt] img {
  transform: translateZ(28px);
}

[data-tilt] {
  position: relative;
}

/* Hover a row of the comparison to light up the same detail on both cards. */

[data-field] {
  border-radius: 6px;
  transition: background-color 200ms ease, box-shadow 200ms ease;
}

[data-field].is-lit {
  background: var(--lit-field);
  box-shadow: 0 0 0 4px var(--lit-field);
}

/* On a friend's card, the lit detail turns a lighter shade of the card's own color: the theme's
   highlight would clash with the person's color. */
.moment-card [data-field].is-lit {
  background: var(--lit-person);
  box-shadow: 0 0 0 4px var(--lit-person);
}

.compare-table tbody tr {
  transition: background-color 200ms ease;
}

.compare-table tbody tr.is-lit {
  background: var(--lit-row);
}

/* The logo's dot hops on hover. */

.brand-mark circle {
  transform-box: fill-box;
  transform-origin: 50% 100%;
}

@media (prefers-reduced-motion: no-preference) {
  .brand:hover .brand-mark circle {
    animation: hop 640ms var(--ease-out);
  }
}

@keyframes hop {
  30% {
    transform: translateY(-80%) scaleY(1.06);
  }

  55% {
    transform: translateY(0) scaleY(0.9);
  }

  72% {
    transform: translateY(-20%);
  }
}

/* A spending tracker that fills itself in */

.band-warm {
  background: var(--band-warm);
}

.bento {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--col-gap);
}

.tile {
  display: grid;
  align-content: start;
  gap: 24px;
  padding: clamp(24px, 2.8vw, 40px);
  overflow: hidden;
  border-radius: var(--radius-card);
  background: var(--paper-raised);
}

.tile-week {
  grid-column: span 7;
}

.tile-where {
  grid-column: span 5;
}

.tile-plan {
  grid-column: span 5;
}

.tile-subs {
  grid-column: span 7;
}

.tile-text {
  display: grid;
  gap: 8px;
  max-width: 34rem;
}

.tile-text p {
  color: var(--ink-2);
}

.tile-shot {
  grid-template-rows: auto 1fr;
  padding-bottom: 0;
}

.tile-screen {
  align-self: end;
  justify-self: center;
  width: min(100%, var(--shot-w, 360px));
  margin: 0;
}

.tile-screen .phone {
  border-radius: 12% 12% 0 0 / var(--corner-y) var(--corner-y) 0 0;
  box-shadow: 0 0 0 1px var(--shot-edge);
}

.tile-shot .tile-screen {
  --shot-w: 380px;
}

.tile-shot .phone-window {
  --corner-y: 10.72%;
  aspect-ratio: 420 / 470;
}

.subs {
  display: grid;
  gap: 12px;
  padding: 20px;
  border-radius: 22px;
  background: var(--paper);
  box-shadow: 0 0 0 1px var(--card-edge);
}

/* The Monthly plan sheet, from MonthlyPlanView, once it has a total: a pinned header with what's left
   beside a bar in the categories' colors, and a slider under each category (site.js monthlyPlan()). */
.tile-plan .phone-window {
  aspect-ratio: 420 / 530;
}

.ios.ios-backdrop-screen {
  background: var(--app-sheet-backdrop);
}

.ios-sheet {
  position: absolute;
  inset: calc(68 * var(--pt)) 0 0;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  border-radius: calc(38 * var(--pt)) calc(38 * var(--pt)) 0 0;
  background: var(--app-bg);
}

.ios-sheet-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: calc(19.7 * var(--pt)) calc(20 * var(--pt)) 0;
  height: calc(64 * var(--pt));
}

.ios-text-button {
  padding: 0 calc(17.3 * var(--pt));
}

.plan-scroll {
  position: relative;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: none;
}

.plan-scroll::-webkit-scrollbar {
  display: none;
}

.plan-sheet {
  display: grid;
  padding: calc(21.7 * var(--pt)) calc(20 * var(--pt)) calc(24 * var(--pt));
}

.plan-total {
  display: flex;
  align-items: baseline;
  gap: calc(6 * var(--pt));
  height: calc(44.6 * var(--pt));
  padding: calc(11.3 * var(--pt)) calc(16 * var(--pt)) 0;
  border-radius: calc(22 * var(--pt));
  background: var(--app-surface);
}

.plan-total-value {
  margin-left: auto;
  font-variant-numeric: tabular-nums;
}

/* The header pins under the sheet's bar while the categories scroll, on the sheet's paper. */
.plan-head {
  position: sticky;
  top: 0;
  z-index: 1;
  display: grid;
  gap: calc(10 * var(--pt));
  margin: calc(26 * var(--pt)) calc(-20 * var(--pt)) 0;
  padding: calc(1 * var(--pt)) calc(36 * var(--pt)) calc(12 * var(--pt));
  background: var(--app-bg);
}

.plan-meter {
  display: flex;
  align-items: center;
  gap: calc(12 * var(--pt));
}

.plan-bar {
  position: relative;
  flex: 1;
  height: calc(8 * var(--pt));
  overflow: hidden;
  border-radius: calc(4 * var(--pt));
  background: var(--app-line);
}

.plan-seg,
.plan-over {
  position: absolute;
  inset: 0;
  transform-origin: 0 50%;
}

@media (prefers-reduced-motion: no-preference) {
  .plan-seg,
  .plan-over {
    transition: transform 360ms var(--spring-snappy), opacity 180ms ease-out;
  }
}

.plan-seg {
  background: var(--c);
}

.plan-over {
  background: var(--app-over);
  opacity: 0;
  transform-origin: 100% 50%;
}

.plan-left {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.plan-left.is-over {
  color: var(--app-over-text);
}

.plan-cats {
  display: grid;
  border-radius: calc(26 * var(--pt));
  background: var(--app-surface);
}

.plan-cat {
  display: grid;
  gap: calc(2 * var(--pt));
  padding: calc(12 * var(--pt)) calc(16 * var(--pt));
}

.plan-cat-line {
  display: grid;
  grid-template-columns: calc(23 * var(--pt)) minmax(0, 1fr) auto;
  align-items: center;
  gap: calc(12 * var(--pt));
}

.plan-cat-line svg {
  justify-self: center;
  width: calc(23 * var(--pt));
  height: calc(23 * var(--pt));
  color: var(--c);
}

.plan-cat-line output {
  font-variant-numeric: tabular-nums;
}

.plan-cat-line output.is-empty {
  color: var(--app-tertiary);
}

.plan-divider {
  height: calc(1 * var(--pt) / 3);
  margin: 0 calc(16 * var(--pt)) 0 calc(51 * var(--pt));
  border: 0;
  background: var(--app-separator);
}

/* iOS's slider: a thin track filled in the category's color up to a white capsule thumb. */
.plan-slider {
  --thumb-w: calc(37 * var(--pt));
  width: calc(100% - 35 * var(--pt));
  height: calc(31 * var(--pt));
  margin: 0 0 0 calc(35 * var(--pt));
  background: transparent;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}

.plan-slider::-webkit-slider-runnable-track {
  height: calc(5.6 * var(--pt));
  border-radius: calc(2.8 * var(--pt));
  background: linear-gradient(to right, var(--c) calc(var(--thumb-w) / 2 + (100% - var(--thumb-w)) * var(--p, 0)), var(--app-track) 0);
}

.plan-slider::-webkit-slider-thumb {
  width: var(--thumb-w);
  height: calc(24 * var(--pt));
  margin-top: calc(-9.2 * var(--pt));
  border: 0;
  border-radius: calc(12 * var(--pt));
  background: var(--app-thumb);
  box-shadow: 0 calc(0.5 * var(--pt)) calc(4 * var(--pt)) var(--app-thumb-shade), 0 calc(6 * var(--pt)) calc(13 * var(--pt)) var(--app-thumb-shade);
  -webkit-appearance: none;
  appearance: none;
}

.plan-slider::-moz-range-track {
  height: calc(5.6 * var(--pt));
  border-radius: calc(2.8 * var(--pt));
  background: var(--app-track);
}

.plan-slider::-moz-range-progress {
  height: calc(5.6 * var(--pt));
  border-radius: calc(2.8 * var(--pt));
  background: var(--c);
}

.plan-slider::-moz-range-thumb {
  width: var(--thumb-w);
  height: calc(24 * var(--pt));
  border: 0;
  border-radius: calc(12 * var(--pt));
  background: var(--app-thumb);
  box-shadow: 0 calc(0.5 * var(--pt)) calc(4 * var(--pt)) var(--app-thumb-shade), 0 calc(6 * var(--pt)) calc(13 * var(--pt)) var(--app-thumb-shade);
}

.plan-slider:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: calc(16 * var(--pt));
}

.sub-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 16px;
}

.sub-logo {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--quiet);
  color: var(--ink);
  font-family: var(--font-display);
  font-weight: 600;
}

.sub-text,
.sub-due {
  display: grid;
  min-width: 0;
  line-height: 1.3;
}

.sub-text span,
.sub-due span {
  color: var(--muted);
  font-size: var(--text-small);
}

.sub-due {
  text-align: right;
}

.sub-due strong {
  font-weight: 600;
}

.reminder {
  min-width: 0;
  margin: 0;
  padding: 16px 0;
  border: 0;
  border-block: 1px solid var(--rule);
}

.reminder legend {
  float: left;
  width: 100%;
  margin-bottom: 12px;
  padding: 0;
  color: var(--ink-2);
  font-size: var(--text-small);
  font-weight: 600;
}

.chips {
  display: flex;
  flex-wrap: wrap;
  clear: both;
  gap: 8px;
}

.chip {
  position: relative;
  display: inline-flex;
}

.chip input {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.chip span {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: 0 16px;
  border-radius: 999px;
  background: var(--quiet);
  color: var(--ink-2);
  font-size: var(--text-small);
  font-weight: 600;
  transition: background-color 160ms ease, color 160ms ease;
}

.chip:hover span {
  background: color-mix(in srgb, var(--quiet) 88%, var(--ink));
}

/* A selection takes the theme's fill, as in the app. */
.chip input:checked + span {
  background: var(--fill);
  color: var(--on-fill);
}

.chip input:focus-visible + span {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
}

/* Ghost mode, switched for real between two captures */

.ghost-demo {
  display: grid;
  justify-items: start;
  gap: 20px;
  margin-top: 8px;
}

.switch {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  padding: 0 8px 0 0;
  border: 0;
  border-radius: 12px;
  background: none;
  color: var(--ink);
  font-family: var(--font-text);
  font-size: var(--text-body);
  font-weight: 600;
  cursor: pointer;
}

.switch-track {
  position: relative;
  width: 52px;
  height: 32px;
  border-radius: 999px;
  background: var(--switch-off);
  transition: background-color 200ms ease;
}

.switch-thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--switch-thumb);
  box-shadow: var(--shadow-thumb);
  transition: transform 220ms var(--ease-out);
}

.switch[aria-checked="true"] .switch-track {
  background: var(--fill);
}

.switch[aria-checked="true"] .switch-thumb {
  transform: translateX(20px);
}

.switch:active .switch-thumb {
  transform: scaleX(1.15);
}

.switch[aria-checked="true"]:active .switch-thumb {
  transform: translateX(16px) scaleX(1.15);
}

.ghost-demo .shot-crop {
  margin-top: 0;
}

/* App screens: the app's own screens rebuilt in HTML from its SwiftUI views, so they stay sharp at
   any size and scroll like the app. Sizes are iOS points of a 420-point iPhone Air screen: --pt is one
   point at the frame's current width. Measured against 3x simulator captures of the Debug build. */

.sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

.phone {
  position: relative;
  container-type: inline-size;
  overflow: hidden;
  aspect-ratio: 420 / 912;
  background: var(--app-bg);
}

.ios {
  --pt: calc(100cqw / 420);
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: var(--app-bg);
  color: var(--app-ink);
  font-family: var(--font-app);
  font-size: calc(17 * var(--pt));
  font-synthesis: none;
  line-height: calc(20.3 * var(--pt));
  text-align: left;
  -webkit-font-smoothing: antialiased;
}

:where(.ios) p,
:where(.ios) ul,
:where(.ios) ol {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* SF Pro tracks small sizes looser than large ones, so a scaled-down screen would set its text wider
   than the app does and break lines differently. Each text size gives back its own share of that. */
:where(.ios, .ios *) {
  letter-spacing: calc((var(--pt) - 1px) * var(--trk, 1.16));
}

.ios-sub {
  --trk: 1;
}

.ios-caption,
.ios-stamp,
.ios-event,
.ios-pill {
  --trk: 0.75;
}

.ios-caption2,
.ios-badge,
.ios-day-label,
.ios-ylabels,
.ios-xlabels,
.ios-title,
.ios-large-inline,
.ios-amount {
  --trk: 0.4;
}

/* Text styles at the default size. A single line takes the font's own height, as SwiftUI lays it
   out; wrapped lines sit the HIG's leading apart, so the line box is the leading and the margins
   give back the difference. */

.ios-headline,
.ios-body {
  margin-block: calc(-0.85 * var(--pt));
  font-size: calc(17 * var(--pt));
  line-height: calc(22 * var(--pt));
}

.ios-headline {
  font-weight: 600;
}

.ios-sub {
  margin-block: calc(-1.05 * var(--pt));
  font-size: calc(15 * var(--pt));
  line-height: calc(20 * var(--pt));
}

.ios-caption {
  margin-block: calc(-0.84 * var(--pt));
  font-size: calc(12 * var(--pt));
  line-height: calc(16 * var(--pt));
}

.ios-caption2 {
  font-size: calc(11 * var(--pt));
  line-height: calc(13.1 * var(--pt));
}

.ios-foot {
  --trk: 0.85;
  margin-block: calc(-1.25 * var(--pt));
  font-size: calc(13 * var(--pt));
  line-height: calc(18 * var(--pt));
}

.ios-title3 {
  margin-block: calc(-0.56 * var(--pt));
  font-size: calc(20 * var(--pt));
  font-weight: 600;
  line-height: calc(25 * var(--pt));
}

.ios-strong {
  font-weight: 600;
}

.ios-medium {
  font-weight: 500;
}

.ios-tertiary {
  color: var(--app-tertiary);
}

.ios-center {
  text-align: center;
}

.ios-muted {
  color: var(--app-muted);
}

.ios-accent {
  color: var(--app-accent-text);
}

/* Status bar, with the clock and system icons a screenshot shows */

.ios-status {
  position: absolute;
  inset: 0 0 auto;
  z-index: 6;
  display: flex;
  align-items: center;
  height: calc(76 * var(--pt));
  padding: 0 calc(32.3 * var(--pt)) 0 calc(56.8 * var(--pt));
  color: var(--app-status);
  pointer-events: none;
}

.ios-time {
  font-size: calc(19 * var(--pt));
  font-weight: 600;
  line-height: calc(22.7 * var(--pt));
}

.ios-sys {
  display: flex;
  align-items: center;
  gap: calc(8.3 * var(--pt));
  margin-left: auto;
}

.ios-sys .i-cellular {
  width: calc(22.3 * var(--pt));
  height: calc(14.2 * var(--pt));
}

.ios-sys .i-wifi {
  width: calc(20.6 * var(--pt));
  height: calc(14.9 * var(--pt));
}

.ios-sys .i-battery {
  width: calc(32.3 * var(--pt));
  height: calc(14.7 * var(--pt));
}

/* Navigation bars: a large inline title with glass buttons, or an inline title with a back button.
   Content scrolls underneath, fading out like iOS 26's soft scroll edge. */

.ios-bar {
  position: absolute;
  inset: 0 0 auto;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: calc(12 * var(--pt));
  height: calc(126 * var(--pt));
  padding: calc(68 * var(--pt)) calc(20 * var(--pt)) calc(14 * var(--pt));
  pointer-events: none;
}

.ios-bar::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  z-index: -1;
  height: calc(122 * var(--pt));
  background: var(--app-frost);
  box-shadow: 0 calc(0.7 * var(--pt)) 0 var(--app-hairline);
  -webkit-backdrop-filter: blur(calc(10 * var(--pt))) saturate(1.2);
  backdrop-filter: blur(calc(10 * var(--pt))) saturate(1.2);
  opacity: 0;
  transition: opacity 160ms ease;
}

.ios-bar.is-scrolled::before {
  opacity: 1;
}

/* A pushed page without a title lets its content run under the back button, fading out at the
   top edge the way iOS 26's soft scroll edge does. */
.ios-bar-inline::before {
  height: calc(112 * var(--pt));
  background: linear-gradient(var(--app-bg) 45%, transparent);
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

.ios-title {
  flex: 1;
  min-width: 0;
  color: var(--app-title);
  font-family: var(--font-display);
  font-size: calc(34 * var(--pt));
  font-weight: 700;
  line-height: calc(40.6 * var(--pt));
}

.ios-title-small {
  position: absolute;
  top: calc(68 * var(--pt));
  right: calc(76 * var(--pt));
  left: calc(76 * var(--pt));
  color: var(--app-title);
  font-size: calc(17 * var(--pt));
  font-weight: 600;
  line-height: calc(44.7 * var(--pt));
  text-align: center;
  opacity: 0;
}

.ios-title,
.ios-title-small {
  transition: opacity 160ms ease;
}

.ios-bar.is-collapsed .ios-title {
  opacity: 0;
}

.ios-bar.is-collapsed .ios-title-small {
  opacity: 1;
}

.ios-tools {
  display: flex;
  gap: calc(11.3 * var(--pt));
}

.ios-inline-title {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  color: var(--app-title);
  font-size: calc(17 * var(--pt));
  font-weight: 600;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.ios-back svg {
  width: calc(30 * var(--pt));
  height: calc(30 * var(--pt));
  translate: calc(-1.8 * var(--pt)) 0;
}

.ios-glass.ios-pair {
  gap: 0;
  padding: 0;
  margin-left: auto;
  color: var(--app-glass-accent);
}

.ios-pair > span {
  display: grid;
  place-items: center;
  width: calc(52.7 * var(--pt));
}

.ios-pair svg {
  width: calc(27 * var(--pt));
  height: calc(27 * var(--pt));
}

.ios-round {
  width: calc(44.7 * var(--pt));
  padding: 0;
}

.ios-round svg {
  width: calc(25 * var(--pt));
  height: calc(25 * var(--pt));
}

.ios-round.is-off svg {
  opacity: 0.25;
}

.ios-glass {
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  gap: calc(4 * var(--pt));
  min-width: calc(44.7 * var(--pt));
  height: calc(44.7 * var(--pt));
  padding: 0 calc(10 * var(--pt));
  border-radius: calc(22.4 * var(--pt));
  background: var(--app-glass);
  box-shadow:
    inset 0 calc(0.8 * var(--pt)) 0 var(--app-glass-rim),
    inset 0 calc(-0.8 * var(--pt)) 0 var(--app-glass-rim),
    0 0 0 calc(0.7 * var(--pt)) var(--app-glass-edge),
    0 calc(3 * var(--pt)) calc(10 * var(--pt)) calc(-4 * var(--pt)) var(--app-glass-shadow);
  color: var(--app-ink);
  pointer-events: auto;
}

.ios-glass svg {
  width: calc(25 * var(--pt));
  height: calc(25 * var(--pt));
}

.ios-glass .i-chart {
  width: calc(29 * var(--pt));
  height: calc(29 * var(--pt));
}

.ios-glass .ios-count {
  font-size: calc(12 * var(--pt));
  font-weight: 600;
}

/* Scrolling content */

.ios-scroll {
  position: absolute;
  inset: 0;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior-x: none;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}

.ios-scroll::-webkit-scrollbar {
  display: none;
}

.ios-scroll:focus {
  outline: none;
}

.ios-scroll.is-dragging {
  -webkit-user-select: none;
  user-select: none;
}

@media (hover: hover) and (pointer: fine) {
  .ios-scroll {
    cursor: grab;
  }

  .ios-scroll.is-dragging {
    cursor: grabbing;
  }

  .ios [data-ios-moon],
  .ios [data-ios-ghost-off],
  .ios [data-ios-join] {
    cursor: pointer;
  }
}

/* A thin indicator that shows while the screen scrolls, and flashes once when it comes into view. */
.ios-indicator {
  position: absolute;
  top: 0;
  right: calc(3 * var(--pt));
  z-index: 7;
  width: calc(3 * var(--pt));
  border-radius: calc(1.5 * var(--pt));
  background: var(--app-tertiary);
  opacity: 0;
  pointer-events: none;
  transition: opacity 400ms ease 500ms;
}

.ios-indicator.is-on {
  opacity: 1;
  transition-delay: 0ms;
  transition-duration: 120ms;
}

/* Inset grouped lists */

.ios-list {
  padding: calc(104.3 * var(--pt)) calc(20 * var(--pt)) calc(132 * var(--pt));
}

.ios-list-head {
  padding: calc(27.8 * var(--pt)) calc(20 * var(--pt)) calc(9.9 * var(--pt));
  font-size: calc(17 * var(--pt));
  font-weight: 600;
  line-height: calc(20.3 * var(--pt));
}

.ios-group {
  overflow: hidden;
  border-radius: calc(26 * var(--pt));
  background: var(--app-surface);
}

.ios-group + .ios-group {
  margin-top: calc(32 * var(--pt));
}

.ios-cell {
  position: relative;
  display: flex;
  align-items: center;
  gap: calc(14 * var(--pt));
  padding: calc(20 * var(--pt));
}

/* A separator starts where its row's first text does: the initial on a friend's avatar, or the
   name beside a group's symbol. */
.ios-cell + .ios-cell::before {
  content: "";
  position: absolute;
  top: calc(-1 * var(--pt));
  right: calc(20 * var(--pt));
  left: var(--sep, calc(78 * var(--pt)));
  height: calc(1 * var(--pt));
  background: var(--app-separator);
}

.ios-cell-friend + .ios-cell-friend {
  --sep: calc(32 * var(--pt));
}

.ios-cell-text {
  display: grid;
  flex: 1;
  gap: calc(3 * var(--pt));
  min-width: 0;
}

.ios-cell-top {
  display: flex;
  align-items: baseline;
  gap: calc(8 * var(--pt));
  min-width: 0;
}

.ios-cell-top > :first-child,
.ios-line {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.ios-cell-top > :first-child {
  flex: 1;
  min-width: 0;
}

.ios-challenge-line {
  display: flex;
  align-items: baseline;
  gap: calc(6 * var(--pt));
  white-space: nowrap;
}

.ios-chev {
  width: calc(18 * var(--pt));
  height: calc(18 * var(--pt));
  margin-right: calc(-2 * var(--pt));
  color: var(--app-tertiary);
}

/* MeloAvatar: a circle in the person's own color, with their initial in Chillax at 0.44 of its size */
.ios-avatar {
  display: grid;
  flex: none;
  place-items: center;
  width: calc(44 * var(--pt));
  height: calc(44 * var(--pt));
  border-radius: 50%;
  background: var(--who, var(--app-quiet));
  color: var(--app-on-fill);
  font-family: var(--font-display);
  font-size: calc(19.36 * var(--pt));
  font-weight: 600;
  line-height: 1;
}

.ios-avatar-group {
  color: var(--app-ink);
}

.ios-avatar svg {
  width: calc(21.6 * var(--pt));
  height: calc(14.4 * var(--pt));
}

.ios-cell-action {
  padding-block: calc(15 * var(--pt));
}

.ios-cell-action svg {
  width: calc(28 * var(--pt));
  height: calc(28 * var(--pt));
  margin-block: calc(-2.9 * var(--pt));
}

/* Ghost mode's banner slides in at the top of the list, as the List row does in the app. */
.ios-ghost {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition: grid-template-rows 320ms var(--ease-out), opacity 220ms ease;
}

.ios-ghost > * {
  overflow: hidden;
}

.ios-ghost.is-on {
  grid-template-rows: 1fr;
  opacity: 1;
}

.ios-ghost-inner {
  padding-top: calc(52.7 * var(--pt));
}

.ios-ghost-row {
  display: flex;
  align-items: center;
  gap: calc(12 * var(--pt));
  padding: calc(15 * var(--pt)) calc(20 * var(--pt));
  background: var(--app-quiet);
}

.ios-ghost-row svg {
  flex: none;
  width: calc(17.6 * var(--pt));
  height: calc(17.6 * var(--pt));
  margin-inline: calc(1.2 * var(--pt));
  color: var(--app-accent-text);
}

.ios-ghost-row .ios-sub {
  flex: 1;
}

/* The app's spacer between the message and Turn off takes the row's spacing on both sides. */
.ios-ghost-row .ios-ghost-off {
  flex: none;
  margin-left: calc(12 * var(--pt));
  font-weight: 600;
  cursor: pointer;
}

/* The frosted backdrop and the floating section bar from SectionNavigationBackdrop and SectionTabBar */

.ios-backdrop {
  position: absolute;
  inset: auto 0 0;
  z-index: 4;
  height: calc(184 * var(--pt));
  background: var(--app-material);
  -webkit-mask-image: linear-gradient(transparent, color-mix(in srgb, var(--mask-on) 6%, transparent) 12%, color-mix(in srgb, var(--mask-on) 28%, transparent) 28%, color-mix(in srgb, var(--mask-on) 70%, transparent) 46%, var(--mask-on) 64%);
  mask-image: linear-gradient(transparent, color-mix(in srgb, var(--mask-on) 6%, transparent) 12%, color-mix(in srgb, var(--mask-on) 28%, transparent) 28%, color-mix(in srgb, var(--mask-on) 70%, transparent) 46%, var(--mask-on) 64%);
  pointer-events: none;
}

.ios-tabbar {
  --slot: calc((388 * var(--pt) - 10 * var(--pt) - 3 * 4 * var(--pt)) / 4);
  position: absolute;
  right: calc(16 * var(--pt));
  bottom: calc(42 * var(--pt));
  left: calc(16 * var(--pt));
  z-index: 6;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: calc(4 * var(--pt));
  height: calc(62 * var(--pt));
  padding: calc(5 * var(--pt));
  border-radius: calc(31 * var(--pt));
  background: var(--app-bar);
  box-shadow:
    inset 0 calc(1 * var(--pt)) 0 var(--app-glass-rim),
    inset 0 calc(-0.8 * var(--pt)) 0 var(--app-glass-rim),
    0 0 0 calc(0.7 * var(--pt)) var(--app-bar-edge),
    0 calc(8 * var(--pt)) calc(24 * var(--pt)) calc(-10 * var(--pt)) var(--app-glass-shadow);
  -webkit-backdrop-filter: blur(calc(12 * var(--pt))) saturate(1.3);
  backdrop-filter: blur(calc(12 * var(--pt))) saturate(1.3);
}

.ios-tabbar::before {
  content: "";
  position: absolute;
  top: calc(5 * var(--pt));
  bottom: calc(5 * var(--pt));
  left: calc(5 * var(--pt) + var(--tab, 0) * (var(--slot) + 4 * var(--pt)));
  width: var(--slot);
  border-radius: calc(26 * var(--pt));
  background: var(--app-lens);
  box-shadow: inset 0 0 0 calc(0.7 * var(--pt)) var(--app-lens-edge), inset 0 calc(1.4 * var(--pt)) 0 var(--app-glass-rim);
}

.ios-tab {
  position: relative;
  display: grid;
  place-items: center;
  color: var(--app-ink);
}

.ios-tab.is-on {
  color: var(--app-accent-text);
}

.ios-tab svg {
  width: calc(34 * var(--pt));
  height: calc(34 * var(--pt));
}

.ios-tab .i-person2,
.ios-tab .i-person2-fill {
  width: calc(34.6 * var(--pt));
  height: calc(23 * var(--pt));
  translate: 0 calc(-1.5 * var(--pt));
}

.ios-tab .i-person-circle {
  width: calc(31 * var(--pt));
  height: calc(31 * var(--pt));
}

.ios-tab .i-stack {
  width: calc(26 * var(--pt));
  height: calc(27.7 * var(--pt));
  translate: 0 calc(-0.7 * var(--pt));
}

.ios-tab .i-wallet {
  width: calc(30.4 * var(--pt));
  height: calc(25.3 * var(--pt));
  translate: calc(0.4 * var(--pt)) calc(0.5 * var(--pt));
}

.ios-badge {
  position: absolute;
  top: calc(1.5 * var(--pt));
  left: calc(50% + 6.3 * var(--pt));
  display: grid;
  place-items: center;
  min-width: calc(19 * var(--pt));
  height: calc(19 * var(--pt));
  padding: 0 calc(5 * var(--pt));
  border-radius: calc(9.5 * var(--pt));
  background: var(--app-badge);
  box-shadow: inset 0 0 0 calc(1.5 * var(--pt)) var(--app-bg);
  color: var(--app-on-badge);
  font-size: calc(12 * var(--pt));
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* A pushed group conversation, from GroupConversationView, ChallengeViews and DirectConversationView */

.ios-chat-layout {
  position: absolute;
  inset: calc(122 * var(--pt)) 0 calc(112 * var(--pt));
  z-index: 1;
  display: flex;
  flex-direction: column;
}

.ios-challenge {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: flex-start;
  gap: calc(12 * var(--pt));
  margin: calc(8 * var(--pt)) calc(16 * var(--pt)) 0;
  padding: calc(14 * var(--pt));
  border-radius: calc(18 * var(--pt));
  background: var(--app-surface);
}

.ios-challenge-emoji {
  font-size: calc(22 * var(--pt));
  line-height: calc(26.2 * var(--pt));
}

.ios-challenge-text {
  display: grid;
  flex: 1;
  gap: calc(3 * var(--pt));
  min-width: 0;
}

.ios-join {
  display: inline-flex;
  flex: none;
  align-items: center;
  height: calc(34 * var(--pt));
  margin-left: calc(8 * var(--pt));
  padding: 0 calc(14 * var(--pt));
  border-radius: calc(17 * var(--pt));
  background: var(--app-fill);
  color: var(--app-on-fill);
  cursor: pointer;
}

.ios-chat.ios-scroll {
  position: relative;
  inset: auto;
  flex: 1;
  min-height: 0;
  -webkit-mask-image: linear-gradient(transparent, var(--mask-on) calc(16 * var(--pt)));
  mask-image: linear-gradient(transparent, var(--mask-on) calc(16 * var(--pt)));
}

.ios-chat-inner {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: calc(16 * var(--pt));
  min-height: 100%;
  padding: calc(20 * var(--pt)) calc(20 * var(--pt)) calc(37 * var(--pt));
}

.ios-entry {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: calc(12 * var(--pt));
}

.ios-stamp,
.ios-event {
  color: var(--app-muted);
  font-size: calc(12 * var(--pt));
  line-height: calc(14.3 * var(--pt));
  text-align: center;
}

.ios-stamp {
  padding-block: calc(4 * var(--pt));
  font-weight: 500;
}

.ios-event {
  padding-block: calc(2 * var(--pt));
}

.ios-msg {
  display: flex;
}

.ios-msg.is-mine {
  justify-content: flex-end;
}

.ios-bubble-wrap {
  position: relative;
  max-width: calc(100% - 32 * var(--pt));
}

.ios-bubble-wrap.has-reactions {
  padding-top: calc(21.8 * var(--pt));
}

.ios-bubble {
  display: grid;
  justify-items: start;
  gap: calc(8 * var(--pt));
  width: fit-content;
  max-width: 100%;
  padding: calc(14 * var(--pt));
  border-radius: calc(20 * var(--pt));
  background: var(--app-surface);
}

/* Your own words wear your color; other people's bubbles stay plain cards with a dot of theirs. */
.is-mine .ios-bubble {
  background: var(--app-fill);
  color: var(--app-on-fill);
}


/* A friend's name above the first message of each run: lined up with the bubble's text, 4 points
   above it, with their reactions on the same line at the bubble's far end. */
.ios-msg-name {
  display: flex;
  align-items: center;
  gap: calc(6 * var(--pt));
  margin-bottom: calc(4 * var(--pt));
  padding-left: calc(14 * var(--pt));
  color: var(--app-muted);
  font-weight: 600;
  white-space: nowrap;
}

.ios-bubble-wrap.has-name {
  padding-top: 0;
}

.has-name > .ios-reactions {
  top: calc(6 * var(--pt));
}

.ios-dot {
  flex: none;
  width: calc(8 * var(--pt));
  height: calc(8 * var(--pt));
  border-radius: 50%;
  background: var(--who);
}

.ios-label {
  display: inline-flex;
  align-items: center;
  gap: calc(6 * var(--pt));
}

.ios-label svg {
  width: calc(17 * var(--pt));
  height: calc(17 * var(--pt));
}

.ios-reply svg {
  width: calc(19 * var(--pt));
  height: calc(19 * var(--pt));
}

.ios-reactions {
  position: absolute;
  top: calc(8 * var(--pt));
  right: 0;
  display: flex;
  gap: calc(4 * var(--pt));
}

.ios-reaction {
  display: inline-flex;
  align-items: center;
  gap: calc(3 * var(--pt));
  height: calc(28 * var(--pt));
  padding: 0 calc(6 * var(--pt));
  border-radius: calc(14 * var(--pt));
  background: var(--app-surface);
  box-shadow: inset 0 0 0 calc(1 * var(--pt)) var(--app-line);
  color: var(--app-accent-text);
  font-size: calc(15 * var(--pt));
  line-height: 1;
}

.ios-reaction small {
  font-size: calc(11 * var(--pt));
  font-variant-numeric: tabular-nums;
}

.ios-reaction.is-mine {
  background: var(--app-wash);
  box-shadow: inset 0 0 0 calc(1 * var(--pt)) var(--app-fill);
}

.ios-composer {
  display: flex;
  flex: none;
  align-items: flex-end;
  gap: calc(12 * var(--pt));
  padding: calc(12 * var(--pt)) calc(16 * var(--pt));
  background: var(--app-composer);
}

.ios-field {
  flex: 1;
  min-height: calc(46 * var(--pt));
  padding: calc(12 * var(--pt)) calc(14 * var(--pt));
  border-radius: calc(20 * var(--pt));
  background: var(--app-field);
  color: var(--app-placeholder);
  line-height: calc(22 * var(--pt));
}

/* MeloSendGlyph: a circle in your color with the arrow in its text color, faint until there's
   something to send */
.ios-send {
  display: grid;
  flex: none;
  place-items: center;
  width: calc(40 * var(--pt));
  height: calc(44 * var(--pt));
  opacity: 0.14;
}

.ios-send::before {
  content: "";
  grid-area: 1 / 1;
  width: calc(34 * var(--pt));
  height: calc(34 * var(--pt));
  border-radius: 50%;
  background: var(--app-send);
}

.ios-send svg {
  grid-area: 1 / 1;
  width: calc(15 * var(--pt));
  height: calc(17 * var(--pt));
  color: var(--app-on-send);
}

/* Spending, from HomeView, CaptureOptionRow, ExpenseRowView and WeeklySpendingCard */

.ios-stack {
  display: grid;
  gap: calc(24 * var(--pt));
  padding: calc(130 * var(--pt)) calc(20 * var(--pt)) calc(124 * var(--pt));
}

.ios-auto {
  display: flex;
  align-items: center;
  gap: calc(14 * var(--pt));
  padding: calc(20 * var(--pt));
  border-radius: calc(22 * var(--pt));
  background: var(--app-surface);
}

.ios-auto-icon {
  display: grid;
  flex: none;
  place-items: center;
  width: calc(28 * var(--pt));
}

.ios-auto-icon svg {
  width: calc(25 * var(--pt));
  height: calc(25 * var(--pt));
}

.ios-auto-text {
  display: grid;
  flex: 1;
  gap: calc(6 * var(--pt));
  min-width: 0;
}

.ios-auto-arrow {
  width: calc(22.8 * var(--pt));
  height: calc(22.8 * var(--pt));
  margin-right: calc(-3.4 * var(--pt));
}

/* Private money, kept quiet: ink on a plain card, tabular digits, no gradient. */
.ios-balance {
  display: grid;
  gap: calc(18 * var(--pt));
  padding: calc(22 * var(--pt));
  border-radius: calc(26 * var(--pt));
  background: var(--app-surface);
}

.ios-balance-head,
.ios-plan-row,
.ios-card-head,
.ios-section-row,
.ios-cat-limit {
  display: flex;
  justify-content: space-between;
  gap: calc(8 * var(--pt));
}

.ios-section-row {
  align-items: center;
}

.ios-balance-head,
.ios-plan-row,
.ios-card-head {
  align-items: baseline;
}

.ios-amount {
  font-size: calc(44 * var(--pt));
  font-weight: 600;
  line-height: calc(52.5 * var(--pt));
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.ios-plan {
  display: grid;
  gap: calc(10 * var(--pt));
}

.ios-plan-row > :first-child {
  font-variant-numeric: tabular-nums;
}

.ios-progress {
  display: block;
  height: calc(4 * var(--pt));
  overflow: hidden;
  border-radius: calc(2 * var(--pt));
  background: var(--app-track);
}

.ios-progress > span {
  display: block;
  width: max(calc(var(--p) * 100%), calc(4 * var(--pt)));
  height: 100%;
  border-radius: inherit;
  background: var(--c, var(--app-fill));
}

.ios-progress-plan {
  height: calc(6 * var(--pt));
  border-radius: calc(3 * var(--pt));
  background: var(--app-line);
}

.ios-progress-plan > span {
  width: max(calc(var(--p) * 100%), calc(6 * var(--pt)));
}

/* Three ways to add, in the theme color: typing it in leads, scanning and describing follow. */
.ios-actions {
  display: grid;
  gap: calc(10 * var(--pt));
}

.ios-primary,
.ios-wash-button {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(8 * var(--pt));
  border-radius: calc(30 * var(--pt));
  font-weight: 600;
  white-space: nowrap;
}

.ios-primary {
  padding: calc(17 * var(--pt));
  background: var(--app-fill);
  color: var(--app-on-fill);
}

.ios-primary svg {
  width: calc(20 * var(--pt));
  height: calc(20 * var(--pt));
  margin-block: calc(-1 * var(--pt));
}

.ios-duo {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: calc(10 * var(--pt));
}

.ios-wash-button {
  --trk: 1;
  min-height: calc(46 * var(--pt));
  background: var(--app-wash);
  color: var(--app-accent-text);
  font-size: calc(15 * var(--pt));
}

.ios-wash-button svg {
  width: calc(19 * var(--pt));
  height: calc(19 * var(--pt));
}

.ios-wash-button .i-doc-scan {
  width: calc(18.2 * var(--pt));
  height: calc(18.2 * var(--pt));
}

/* MeloRowGroup: places to go, as rows in one card with dividers inset past their symbols */
.ios-rows {
  overflow: hidden;
  border-radius: calc(22 * var(--pt));
  background: var(--app-surface);
}

.ios-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: calc(16 * var(--pt));
  padding: calc(13 * var(--pt)) calc(16 * var(--pt));
}

.ios-row + .ios-row::before {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  left: calc(58 * var(--pt));
  height: 1px;
  background: var(--app-divider);
}

.ios-row-icon {
  flex: none;
  width: calc(26 * var(--pt));
  height: calc(26 * var(--pt));
}

.ios-row-text {
  display: grid;
  flex: 1;
  gap: calc(3 * var(--pt));
  min-width: 0;
}

.ios-row-chev {
  flex: none;
  width: calc(17 * var(--pt));
  height: calc(17 * var(--pt));
  margin-right: calc(-4.5 * var(--pt));
  color: var(--app-tertiary);
  translate: 0 calc(1 * var(--pt));
}

.ios-card {
  display: grid;
  padding: calc(20 * var(--pt));
  border-radius: calc(24 * var(--pt));
  background: var(--app-surface);
}

.ios-week {
  gap: calc(20 * var(--pt));
}

.ios-week-chart {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  height: calc(110 * var(--pt));
}

.ios-day {
  position: relative;
}

.ios-mark {
  position: absolute;
  bottom: calc(18 * var(--pt));
  left: 15%;
  width: 70%;
  height: calc(var(--h) * 92 * var(--pt));
  border-radius: calc(5 * var(--pt)) calc(5 * var(--pt)) 0 0;
  background: var(--app-mark);
}

.is-today .ios-mark {
  background: var(--app-fill);
}

.ios-day-label,
.ios-ylabels span,
.ios-xlabels span {
  position: absolute;
  color: var(--app-secondary);
  font-size: calc(11 * var(--pt));
  line-height: calc(13.1 * var(--pt));
}

.ios-day-label {
  top: calc(95.6 * var(--pt));
  left: calc(4.2 * var(--pt));
}

.ios-recent {
  display: grid;
  gap: calc(16 * var(--pt));
}

.ios-expenses {
  gap: calc(10 * var(--pt));
}

.ios-expense {
  display: flex;
  align-items: center;
  gap: calc(14 * var(--pt));
  padding-block: calc(6 * var(--pt));
}

/* A category's symbol in its own color, with no tile behind it */
.ios-cat {
  display: grid;
  flex: none;
  place-items: center;
  width: calc(26 * var(--pt));
  color: var(--c);
}

.ios-cat svg {
  width: calc(22 * var(--pt));
  height: calc(22 * var(--pt));
}

.ios-expense-text,
.ios-expense-amount {
  display: grid;
  gap: calc(3 * var(--pt));
}

.ios-expense-text {
  flex: 1;
  min-width: 0;
}

.ios-expense-amount {
  justify-items: end;
  font-variant-numeric: tabular-nums;
}

.ios-amount-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(10 * var(--pt));
}

.ios-amount-chevron {
  flex: none;
  width: calc(17 * var(--pt));
  height: calc(17 * var(--pt));
  color: var(--app-muted);
}

.ios-divider {
  height: 1px;
  margin: 0;
  border: 0;
  background: var(--app-divider);
}

/* Insights, from InsightsView and MonthNavigator */

.ios-stack-insights {
  gap: calc(20 * var(--pt));
  padding-top: calc(129.2 * var(--pt));
}

.ios-large-inline {
  font-size: calc(34 * var(--pt));
  font-weight: 700;
  line-height: calc(40.6 * var(--pt));
}

.ios-month-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-inline: calc(-0.7 * var(--pt));
}

/* The statistic cards, from InsightsView and Core/SpendingStats.swift. Each picture draws once it's
   fully in view inside the phone (site.js insights()), the way the app waits for it to clear the tab
   bar, and then stays drawn. Without script, or for people who ask for less motion, they're drawn. */

.ins-pace {
  gap: calc(18 * var(--pt));
}

.ins-head {
  display: grid;
  gap: calc(6 * var(--pt));
}

.ins-picture-group {
  display: grid;
  gap: calc(12 * var(--pt));
}

.ins-chart {
  display: block;
  width: calc(340 * var(--pt));
  height: calc(140 * var(--pt));
  overflow: visible;
}

.ins-zero {
  stroke: var(--app-line);
  stroke-width: 1;
}

.ins-line-now,
.ins-line-last,
.ins-line-plan {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.ins-line-now {
  stroke: var(--app-ink);
  stroke-width: 2.5;
}

.ins-line-last {
  stroke: var(--app-last);
  stroke-width: 2;
}

.ins-line-plan {
  stroke: var(--app-fill);
  stroke-width: 2;
  stroke-dasharray: 1 6;
}

.ins-end {
  fill: var(--app-ink);
}

.ins-legend,
.ins-facts {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
}

.ins-legend {
  gap: calc(16 * var(--pt));
}

.ins-key {
  display: inline-flex;
  align-items: center;
  gap: calc(6 * var(--pt));
}

.ins-key svg {
  width: calc(16 * var(--pt));
  height: calc(4 * var(--pt));
  overflow: visible;
}

.ins-key .ins-line-last {
  stroke-width: 2.5;
}

.ins-key .ins-key-plan {
  stroke-dasharray: 1 5;
}

.ins-facts {
  gap: calc(18 * var(--pt));
  font-variant-numeric: tabular-nums;
}

.ins-plan-row {
  display: flex;
  justify-content: space-between;
  gap: calc(12 * var(--pt));
  padding-top: calc(14 * var(--pt));
  border-top: calc(1 * var(--pt)) solid var(--app-line);
  font-variant-numeric: tabular-nums;
}

.ins-where {
  gap: calc(20 * var(--pt));
}

.ins-ring {
  position: relative;
  justify-self: center;
  width: calc(140 * var(--pt));
  height: calc(140 * var(--pt));
}

/* Arcs start at 12 o'clock and run clockwise; site.js sets each one's dashes as the ring sweeps. */
.ins-ring svg {
  display: block;
  width: 100%;
  height: 100%;
  transform: rotate(-90deg);
}

.ins-track,
.ins-arc {
  fill: none;
  stroke-width: 16;
}

.ins-track {
  stroke: var(--app-line);
}

.ins-arc {
  stroke: var(--c);
}

.ins-ring-label {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: calc(2 * var(--pt));
}

.ins-ring-share {
  font-size: calc(22 * var(--pt));
  font-weight: 600;
  line-height: calc(28 * var(--pt));
  font-variant-numeric: tabular-nums;
}

.ins-cats {
  display: grid;
  grid-template-columns: calc(22 * var(--pt)) minmax(0, 1fr) auto auto;
  align-items: center;
  gap: calc(14 * var(--pt)) calc(11 * var(--pt));
}

.ins-cat {
  display: contents;
}

.ins-cat svg {
  justify-self: center;
  width: calc(23 * var(--pt));
  height: calc(23 * var(--pt));
  color: var(--c);
}

.ins-cat > :last-child {
  justify-self: end;
  font-variant-numeric: tabular-nums;
}

.ins-days {
  gap: calc(16 * var(--pt));
}

.ins-calendar {
  display: grid;
  grid-template-columns: repeat(7, calc(48.6 * var(--pt)));
  row-gap: calc(4 * var(--pt));
}

.ins-weekday {
  color: var(--app-muted);
  font-size: calc(11 * var(--pt));
  font-weight: 600;
  line-height: calc(13.1 * var(--pt));
  text-align: center;
}

.ins-day {
  position: relative;
  display: grid;
  place-items: center;
  height: calc(38 * var(--pt));
}

.ins-day > * {
  position: relative;
  border-radius: 50%;
}

.ins-bubble {
  width: calc(var(--d) * var(--pt));
  height: calc(var(--d) * var(--pt));
  background: var(--app-fill);
}

.ins-none {
  width: calc(4 * var(--pt));
  height: calc(4 * var(--pt));
  background: var(--app-none);
}

/* The longest break sits on a pale wash, and today wears a ring. */
.ins-day.is-break::before,
.ins-day.is-today::before {
  content: "";
  position: absolute;
  width: calc(34 * var(--pt));
  height: calc(34 * var(--pt));
  border-radius: 50%;
}

.ins-day.is-break::before {
  background: var(--app-wash);
}

.ins-day.is-today::before {
  box-shadow: inset 0 0 0 calc(1.5 * var(--pt)) var(--app-ink);
}

.ins-facts-wide {
  gap: calc(28 * var(--pt));
}

.ins-fact {
  display: grid;
  gap: calc(4 * var(--pt));
}

.ins-title {
  font-family: var(--font-display);
  font-weight: 600;
}

.ins-title-24 {
  font-size: calc(24 * var(--pt));
  line-height: calc(29 * var(--pt));
}

.ins-title-30 {
  font-size: calc(30 * var(--pt));
  line-height: calc(36 * var(--pt));
}

.ins-rhythm {
  gap: calc(18 * var(--pt));
}

.ins-bars {
  display: grid;
  grid-template-columns: repeat(7, calc(40 * var(--pt)));
  align-items: end;
  column-gap: calc(10 * var(--pt));
  height: calc(154 * var(--pt));
}

.ins-column {
  display: grid;
  justify-items: center;
  gap: calc(6 * var(--pt));
}

.ins-bar {
  width: 100%;
  height: calc(var(--h) * var(--pt));
  border-radius: calc(6 * var(--pt));
  background: var(--app-faded);
  transform-origin: 50% 100%;
}

.is-busiest .ins-bar {
  background: var(--app-fill);
}

.ins-bar-label {
  font-size: calc(12 * var(--pt));
  font-weight: 600;
  line-height: calc(16 * var(--pt));
  font-variant-numeric: tabular-nums;
}

.is-busiest .ins-weekday {
  color: var(--app-ink);
}

.ins-place,
.ins-small {
  gap: calc(14 * var(--pt));
}

.ins-dots {
  display: flex;
  flex-wrap: wrap;
  gap: calc(7 * var(--pt));
}

.ins-dots > span {
  width: calc(16 * var(--pt));
  height: calc(16 * var(--pt));
  border-radius: 50%;
  background: var(--c);
}

.ins-bubbles {
  display: grid;
  grid-template-columns: repeat(11, calc(26 * var(--pt)));
  gap: calc(4 * var(--pt));
}

.ins-bubbles > span {
  display: grid;
  place-items: center;
  height: calc(26 * var(--pt));
}

.ins-bubbles > span > span {
  width: calc(var(--d) * var(--pt));
  height: calc(var(--d) * var(--pt));
  border-radius: 50%;
  background: var(--app-fill);
}

.ins-sum {
  display: flex;
  gap: calc(5 * var(--pt));
}

/* A counting number rolls up glyph by glyph, as SwiftUI's numeric text does. */
.ins-glyph {
  display: inline-block;
}

/* Drawing. Each part starts the way the app shows it before its card is reached, and settles on
   the app's springs: unveil for the lines, ring and legend, snappy for what pops, smooth for bars. */
@media (prefers-reduced-motion: no-preference) {
  .js [data-drawing] .ins-reveal {
    transform-box: fill-box;
    transform-origin: 0 50%;
    transition: transform 1s var(--spring-unveil);
  }

  .js [data-drawing] .ins-card:not(.is-drawn) .ins-reveal {
    transform: scaleX(0);
  }

  .js [data-drawing] .ins-end {
    transform-box: fill-box;
    transform-origin: 50% 50%;
    transition: transform 360ms var(--spring-snappy) 700ms, opacity 360ms var(--spring-snappy) 700ms;
  }

  .js [data-drawing] .ins-legend {
    transition: opacity 1s var(--spring-unveil);
  }

  .js [data-drawing] .ins-day,
  .js [data-drawing] .ins-dots > span,
  .js [data-drawing] .ins-bubbles > span > span {
    transition: transform 360ms var(--spring-snappy) var(--delay), opacity 360ms var(--spring-snappy) var(--delay);
  }

  .js [data-drawing] .ins-day {
    --delay: calc(var(--i) * 18ms);
  }

  .js [data-drawing] .ins-dots > span {
    --delay: calc(var(--i) * 60ms);
  }

  .js [data-drawing] .ins-bubbles > span > span {
    --delay: calc(var(--i) * 40ms);
  }

  .js [data-drawing] .ins-bar,
  .js [data-drawing] .ins-bar-label {
    transition: transform 450ms var(--spring-smooth) calc(var(--i) * 50ms), opacity 450ms var(--spring-smooth) calc(var(--i) * 50ms);
  }

  .js [data-drawing] .ins-card:not(.is-drawn) .ins-end,
  .js [data-drawing] .ins-card:not(.is-drawn) .ins-dots > span,
  .js [data-drawing] .ins-card:not(.is-drawn) .ins-bubbles > span > span {
    opacity: 0;
    transform: scale(0.01);
  }

  .js [data-drawing] .ins-card:not(.is-drawn) .ins-day:not(.is-blank) {
    opacity: 0;
    transform: scale(0.2);
  }

  .js [data-drawing] .ins-card:not(.is-drawn) .ins-legend,
  .js [data-drawing] .ins-card:not(.is-drawn) .ins-bar-label {
    opacity: 0;
  }

  /* Before a card is reached its bars are 4-point stubs. */
  .js [data-drawing] .ins-card:not(.is-drawn) .ins-bar {
    transform: scaleY(calc(4 / var(--h)));
  }
}

/* Group details, from GroupDetailsView: the group's picture (OrbitArt, drawn by assets/orbit.js and
   site.js orbits()), then its name, Invite, its rows and what the circle shares. */

.ios-details {
  display: grid;
  padding: calc(146 * var(--pt)) calc(24 * var(--pt)) calc(140 * var(--pt));
}

.ios-orbit {
  position: relative;
  height: calc(var(--orbit-h) * var(--pt));
  touch-action: pan-y;
}

/* A face: the person's color with their initial, ringed in the page's paper, and veiled toward the back. */
.ios-face {
  position: absolute;
  top: 0;
  left: 0;
  display: grid;
  place-items: center;
  width: calc(var(--face) * var(--pt));
  height: calc(var(--face) * var(--pt));
  border-radius: 50%;
  background: var(--who);
  box-shadow: 0 0 0 calc(2.5 * var(--pt)) var(--app-bg);
  color: var(--on-person);
  font-family: var(--font-display);
  font-size: calc(var(--face) * 0.44 * var(--pt));
  font-weight: 600;
  line-height: 1;
  transform-origin: 50% 50%;
  will-change: transform, opacity;
}

.ios-face::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--app-bg);
  opacity: var(--veil, 0);
}

.ios-face.is-me {
  background: var(--app-fill);
  color: var(--app-on-fill);
}

.ios-details-head {
  display: flex;
  align-items: center;
  gap: calc(12 * var(--pt));
  margin-top: calc(4 * var(--pt));
}

.ios-details-name {
  display: grid;
  flex: 1;
  gap: calc(4 * var(--pt));
  min-width: 0;
}

.ios-group-name {
  font-family: var(--font-display);
  font-size: calc(30 * var(--pt));
  font-weight: 700;
  line-height: calc(36 * var(--pt));
}

.ios-quiet-button {
  flex: none;
  padding: calc(7 * var(--pt)) calc(12 * var(--pt));
  border-radius: calc(18 * var(--pt));
  background: var(--app-invite);
  font-size: calc(15 * var(--pt));
  font-weight: 500;
  line-height: calc(20 * var(--pt));
}

.ios-details-rows {
  display: grid;
  margin-top: calc(18 * var(--pt));
}

.ios-details-row {
  display: flex;
  align-items: center;
  gap: calc(10 * var(--pt));
  height: calc(42.7 * var(--pt));
}

.ios-details-row svg {
  flex: none;
  width: calc(20 * var(--pt));
  height: calc(20 * var(--pt));
}

.ios-circle {
  gap: calc(10 * var(--pt));
  margin-top: calc(16 * var(--pt));
}

.ios-circle .ios-label svg {
  width: calc(24 * var(--pt));
  height: calc(24 * var(--pt));
}

.ios-details-link {
  justify-content: space-between;
  margin-top: calc(16 * var(--pt));
}

.ios-details-link svg {
  width: calc(15 * var(--pt));
  height: calc(15 * var(--pt));
}

.ios-details-section {
  margin-top: calc(10 * var(--pt));
}

.ios-bar-inline > .ios-round:last-child {
  margin-left: auto;
}

.ios-center-title {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
}

/* Privacy and support pages */

.doc {
  padding-block: clamp(48px, 6vw, 96px) var(--section-pad);
}

.doc .container > * {
  max-width: 46rem;
}

.doc-head {
  display: grid;
  gap: 20px;
  margin-bottom: clamp(40px, 5vw, 64px);
}

.doc-head h1 {
  font-size: var(--text-display);
  letter-spacing: -0.035em;
}

.doc-section {
  display: grid;
  gap: 16px;
  padding-block: 32px;
  border-top: 1px solid var(--rule);
}

.doc-section h2 {
  font-size: var(--text-title);
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -0.01em;
}

.doc-section p,
.doc-list li {
  color: var(--ink-2);
}

.doc-list {
  display: grid;
  gap: 12px;
  padding-left: 1.2em;
  list-style: disc;
}

.doc-list li::marker {
  color: var(--theme-text);
}

.site-footer nav a[aria-current="page"] {
  background: var(--wash);
}

/* On touch screens a press is for tilting and tapping, not selecting: no text selection, no
   long-press menu and no grey tap flash on the home page. The footer and the Privacy and Support
   pages stay selectable, so the support address can still be copied. */

@media (hover: none), (pointer: coarse) {
  .site-header,
  main:not(.doc) {
    -webkit-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
  }

  main:not(.doc) img {
    -webkit-user-drag: none;
  }

  a,
  button,
  label,
  input {
    -webkit-tap-highlight-color: transparent;
  }
}

/* Smaller screens */

@media (max-width: 880px) {
  .site-nav {
    display: none;
  }
}

/* Side by side next to the text, the two group phones would be smaller than on a phone. */
@media (max-width: 1180px) {
  .group-grid {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 48px;
  }

  .group-shots {
    justify-self: start;
  }
}

@media (max-width: 1100px) {
  .section-head-split {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 20px;
  }

  .row {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 900px) {
  .hero-grid,
  .privacy-grid {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 48px;
  }

  .hero-grid {
    padding-top: 24px;
  }

  .hero .lead {
    max-width: 36ch;
  }

  .plate {
    margin-left: calc(-1 * max(var(--gutter), env(safe-area-inset-left, 0px)));
    margin-right: calc(-1 * max(var(--gutter), env(safe-area-inset-right, 0px)));
    border-radius: 0;
  }

  .plate::before {
    display: none;
  }

  .plate {
    --bleed: 0px;
  }

  .home {
    --pt: min(1.25px, calc((100vw - 40px) / 338));
  }

  .timeline {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 56px;
  }

  .challenge-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .privacy-head {
    position: static;
  }
}

@media (max-width: 720px) {
  :root {
    --nav-h: 64px;
  }

  .site-nav {
    display: none;
  }

  .brand-mark {
    width: 40px;
  }

  .brand-word {
    font-size: 26px;
  }

  .compare-table .c-label {
    width: 26%;
  }

  .compare-table thead th {
    padding-right: 12px;
  }

  .compare-table tbody th,
  .compare-table tbody td {
    padding-right: 12px;
  }

  .ledger-card,
  .moment-card {
    min-height: 0;
    padding: 16px;
  }

  .ledger-top {
    flex-direction: column;
    gap: 0;
  }

  .moment-card {
    grid-template-columns: minmax(0, 1fr);
  }

  .moment-emoji {
    grid-row: auto;
    margin-bottom: 8px;
    font-size: 32px;
  }

  .close-inner {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 28px;
  }
}

@media (max-width: 600px) {
  .compare-table,
  .compare-table thead,
  .compare-table tbody,
  .compare-table tr,
  .compare-table th,
  .compare-table td {
    display: block;
  }

  .compare-table colgroup,
  .compare-table thead td {
    display: none;
  }

  .compare-table tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: 12px;
  }

  .compare-table thead th {
    padding: 0 0 24px;
  }

  .compare-table tbody tr {
    padding-block: 16px;
    border-top: 1px solid var(--rule);
  }

  .compare-table tbody tr:last-child {
    border-bottom: 1px solid var(--rule);
  }

  .compare-table tbody th,
  .compare-table tbody td,
  .compare-table tbody tr:last-child th,
  .compare-table tbody tr:last-child td {
    padding: 0;
    border: 0;
  }

  .compare-table tbody th {
    grid-column: 1 / -1;
    padding-bottom: 4px;
  }

  /* Side by side, the two screens would be too small to read on a phone, so they stack like cards:
     the one behind peeks out on the right, and a sideways swipe, a tap on it or the dots bring it
     forward (site.js). The stack sits a little left of center, so the pair looks centered. */
  .group-shots {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 18px;
    width: min(72vw, 290px);
    margin-top: 8px;
    justify-self: center;
    translate: -6% 0;
    touch-action: pan-y;
  }

  .group-shots .shot {
    z-index: 1;
    grid-area: 1 / 1;
    touch-action: pan-y;
    transition: translate 0.5s var(--ease-out), scale 0.5s var(--ease-out), rotate 0.5s var(--ease-out), filter 0.5s var(--ease-out);
  }

  .group-shots .ios-scroll {
    touch-action: pan-y;
  }

  .group-shots:not([data-front="2"]) .shot:nth-child(2),
  .group-shots[data-front="2"] .shot:nth-child(1) {
    z-index: 0;
    translate: 16% 4%;
    scale: 0.88;
    rotate: 3deg;
    filter: brightness(0.9);
    cursor: pointer;
  }

  /* The screen behind takes a tap as a whole; its own buttons wait until it's in front. */
  .group-shots:not([data-front="2"]) .shot:nth-child(2) .phone,
  .group-shots[data-front="2"] .shot:nth-child(1) .phone {
    pointer-events: none;
  }

  /* The screen in front follows the finger, turning a little as it goes. */
  .group-shots .shot.is-swiping {
    z-index: 2;
    translate: calc(var(--swipe, 0) * 1px) 0;
    rotate: calc(var(--swipe, 0) * 0.03deg);
    transition: none;
  }

  .stack-dots {
    display: flex;
  }

  .shot-lower {
    margin-top: 0;
  }
}

@media (max-width: 900px) {
  .tile-week,
  .tile-where,
  .tile-plan,
  .tile-subs {
    grid-column: 1 / -1;
  }
}

@media (max-width: 480px) {
  .chip span {
    padding: 0 12px;
    font-size: 0.875rem;
    white-space: nowrap;
  }

  .sub-row {
    grid-template-columns: auto minmax(0, 1fr);
  }

  .sub-due {
    grid-column: 2;
    text-align: left;
  }
}

@media (prefers-reduced-motion: reduce) {
  .w-row,
  .button,
  .site-nav a,
  .site-footer nav a,
  .site-header,
  .bar-fill,
  .reaction,
  .reaction-add,
  .reaction-picker button,
  .join,
  .switch-track,
  .switch-thumb,
  .ios-ghost,
  .ios-indicator,
  .ios-title,
  .ios-title-small,
  .mini-row,
  .chip span,
  .notice-actions button,
  .notice-undo,
  [data-field],
  .compare-table tbody tr,
  .group-shots .shot,
  .stack-dots button::before {
    transition: none;
  }

  .reaction.is-popped {
    animation: none;
  }

  [data-tilt] {
    transform: none;
  }

  .button:active,
  .reaction:active,
  .reaction-add:active,
  .reaction-picker button:active,
  .reaction-picker button:hover,
  .join:active {
    transform: none;
  }
}
