/* static/css/landing.css — Session 2 shell (HISTORY_ORBIT_LANDING_MASTER_PROMPT.md)
   Self-hosted fonts only. No cross-origin requests. Zero raw hex values below
   this point — every color is a var(--bento-*) token from tokens.css. */

/* ---- Type: the landing page's three voices ----------------------------
   The rest of the site is one face - Times New Roman - because the reading
   pages want to get out of the way. The landing page is the one place that
   is doing the talking, so it gets three, each with one job:

     Fraunces    display   headlines, card titles, prices. An old-style serif
                           with an optical-size axis, so a 3rem headline is
                           cut tighter than a 1rem one without being told to.
     Newsreader  prose     the sentences a reader actually reads. It is the
                           same family the event pages set their essays in.
     Karla       interface nav, buttons, chips, labels, figures. A grotesque,
                           so nothing in the furniture can be mistaken for
                           something to read.

   These override the tokens.css defaults for this page only - landing.css is
   loaded by landing.html and nothing else. Faces live in fonts.css. */
:root {
  --font-display: 'Fraunces', Georgia, 'Times New Roman', serif;
  --font-body: 'Karla', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --lp-prose: 'Newsreader', Georgia, 'Times New Roman', serif;
}

/* ============================================================
   Session 3 — landing page layout & components
   Zero raw hex below this point; every color is var(--bento-*).
   ============================================================ */

body {
  font-family: var(--font-body);
  color: var(--bento-ink);
  background: var(--bento-cream);
  margin: 0;
}
h1, h2, h3 { font-family: var(--font-display); color: var(--bento-ink); margin: 0; }
a { color: inherit; }
.container { max-width: 1200px; margin: 0 auto; padding: 0 var(--sp-5); }

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--bento-ink);
  color: var(--bento-white);
  padding: var(--sp-3) var(--sp-5);
  border-radius: var(--r-sm);
  z-index: 100;
}
.skip-link:focus { left: var(--sp-4); top: var(--sp-4); }

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

/* Permanent island nav: the header is always a floating pill and always
   sticky, so it stays visible for the whole scroll. The bar itself is
   transparent and click-through; only the pill takes pointer events. */
.lp-head {
  position: sticky;
  top: 0;
  z-index: var(--z-nav);
  background: transparent;
  padding: var(--sp-3) var(--sp-4);
  pointer-events: none;
}
.lp-head-row {
  pointer-events: auto;
  max-width: 1080px;
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  min-height: 64px;
  padding-top: var(--sp-3);
  padding-bottom: var(--sp-3);
  border-radius: var(--r-pill);
  background: var(--bento-white);
  border: 1px solid var(--bento-line);
  box-shadow: var(--shadow-card);
  transition: box-shadow var(--dur-base) ease, transform var(--dur-base) ease;
}
.lp-brand {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.125rem;
  letter-spacing: -0.01em;
  text-decoration: none;
  color: var(--bento-ink);
  flex-shrink: 0;
}
/* The brand is the shared logo_nav() lockup (mark + animated wordmark), so
   the landing header reads the same as the island nav on every other page —
   sizing included: logo-mark.css owns it, this file does not override it. */
.lp-nav { display: flex; align-items: center; gap: var(--sp-2); margin-left: auto; }
.lp-nav a {
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--bento-ink-soft);
  text-decoration: none;
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-sm);
  min-height: 44px;
  display: flex;
  align-items: center;
  transition: color var(--dur-fast) ease, background var(--dur-fast) ease;
}
.lp-nav a:hover { color: var(--bento-ink); background: var(--bento-sand); }
.lp-head-cta { display: flex; align-items: center; gap: var(--sp-3); flex-shrink: 0; }

@media (max-width: 1080px) {
  .lp-nav a[href="#tools"] { display: none; }
}
@media (max-width: 860px) {
  .lp-nav { display: none; }
  /* The section links were what pushed Sign in to the right (their
     margin-left: auto). With them hidden, the button takes that job itself
     so it sits at the far right end of the pill, not beside the logo. */
  .lp-head-cta { margin-left: auto; }
}

@media (max-width: 420px) {
  .lp-head-row { gap: var(--sp-3); }
}

/* ---- Utilities ---- */

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* The island is permanent; scrolling only deepens its shadow so the pill
   reads as lifted off the content passing underneath it. */
.lp-head.is-scrolled .lp-head-row {
  box-shadow: var(--shadow-card-hover);
}
/* On phones and tablets the soft drop shadow read as a blurred halo around
   the pill at the top of the screen. There the pill is drawn crisp: its
   1px rule and white fill only, at rest and while scrolling. */
@media (max-width: 860px), (hover: none) and (pointer: coarse) {
  .lp-head-row,
  .lp-head.is-scrolled .lp-head-row { box-shadow: none; }
}

/* ---- Section rhythm ---- */

/* One rhythm for every transition on the page. This was a flat 80px top and
   bottom, so any two neighbouring sections put 160px of empty page between
   them — heavy on a wide screen and most of a phone screen spent on nothing.
   A clamp instead of a token because the gap should scale with the viewport:
   72px between sections on a phone, 104px at desktop width. */
.lp section, .lp-hero, .lp-band, .lp-removed { padding: clamp(36px, 5vw, 52px) 0; }
.lp-band { background: var(--bento-sand); }

/* The mark and the headline are one opening, not two sections. They sit
   closer than a section transition so the logo introduces the sentence
   beneath it rather than floating alone above a gap.
   Both are qualified by .lp because the rule above them is `.lp section`,
   which outranks a lone class and would otherwise win. */
.lp .lp-brandmark { padding-bottom: var(--sp-5); }
.lp .lp-hero { padding-top: var(--sp-6); }
.lp-removed { background: var(--bento-tan-100); }

.lp-sec-head { max-width: 640px; margin: 0 0 var(--sp-7); }
.lp-sec-head h2 { font-size: 2rem; font-weight: 600; letter-spacing: -0.02em; line-height: 1.2; }
.lp-sec-head p { font-family: var(--font-body); color: var(--bento-ink-soft); font-size: 1.0625rem; margin-top: var(--sp-3); line-height: 1.6; }

.lp-actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin-top: var(--sp-5); }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: 44px;
  padding: 0 var(--sp-5);
  border-radius: var(--r-pill);
  border: 1px solid transparent;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.9375rem;
  text-decoration: none;
  cursor: pointer;
  color: var(--bento-btn-text);
  transition: background var(--dur-fast) ease, transform var(--dur-fast) ease, border-color var(--dur-fast) ease;
}

/* ---- Hero ---- */

/* The copy sits above a full-width bento grid, so the hero's cards are the
   same size as every other card on the page. */
.lp-hero-copy { max-width: 760px; margin-bottom: var(--sp-8); }
.lp-hero h1 { font-size: 3rem; line-height: 1.12; font-weight: 600; letter-spacing: -0.025em; }
.lp-lede { font-family: var(--font-body); font-weight: 400; font-size: 1.1875rem; color: var(--bento-ink-soft); line-height: 1.6; margin-top: var(--sp-4); max-width: 60ch; }
.lp-promise { font-size: 1rem; line-height: 1.6; color: var(--bento-ink-soft); margin-top: var(--sp-5); max-width: 55ch; }

@media (max-width: 860px) {
  .lp-hero h1 { font-size: 2.125rem; }
  .lp-hero-copy { margin-bottom: var(--sp-6); }
}

/* ---- Numbers ---- */

.lp-stat-num {
  font-family: var(--font-display);
  font-size: clamp(3.5rem, 8vw, 5.5rem);
  line-height: 1;
  font-weight: 600;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  margin: var(--sp-2) 0 0;
}

/* ---- Chips (formats) ---- */

.chip--free { background: var(--bento-success); color: var(--bento-white); }
.chip--paid { background: var(--bento-tan-200); color: var(--bento-btn-text); }

/* ---- Timeline (matches .au-tl-* on the results page) ---- */

.au-tl-list {
  list-style: none;
  margin: 0;
  padding: 0 0 0 var(--sp-6);
  position: relative;
  max-width: 760px;
}
.au-tl-list::before {
  content: "";
  position: absolute;
  left: 7px;
  top: 4px;
  bottom: 4px;
  width: 2px;
  background: linear-gradient(180deg, var(--bento-tan-200), var(--bento-line));
}
.au-tl-item { margin-bottom: var(--sp-3); position: relative; }
.au-tl-card {
  background: var(--bento-white);
  border: 1px solid var(--bento-line);
  border-radius: var(--r-sm);
  padding: var(--sp-4);
  transition: border-color var(--dur-fast) ease, box-shadow var(--dur-fast) ease;
}
.au-tl-card:hover { border-color: var(--bento-tan-300); box-shadow: var(--shadow-card); }
.au-tl-head {
  display: grid;
  grid-template-columns: auto auto 1fr auto;
  align-items: baseline;
  gap: var(--sp-3);
  cursor: pointer;
  list-style: none;
}
.au-tl-head::-webkit-details-marker { display: none; }
.au-tl-node {
  position: absolute;
  left: calc(var(--sp-6) * -1 + 1px);
  top: var(--sp-4);
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--bento-white);
  border: 2px solid var(--bento-tan-300);
}
.au-tl-item[data-significance="critical"] .au-tl-node { background: var(--bento-ink); border-color: var(--bento-ink); }
.au-tl-date {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--bento-tan-300);
  font-variant-numeric: tabular-nums;
}
.au-tl-headline { font-family: var(--font-display); font-size: 1.1875rem; }
.au-tl-flag {
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  background: var(--bento-ink);
  color: var(--bento-white);
  padding: 2px var(--sp-2);
  border-radius: var(--r-pill);
}
.au-tl-detail {
  margin-top: var(--sp-3);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--bento-line);
  color: var(--bento-ink-soft);
  font-size: 1rem;
  line-height: 1.6;
}
.lp-tl-note { color: var(--bento-ink-soft); font-size: 0.9375rem; margin-top: var(--sp-5); }

@media (max-width: 640px) {
  .au-tl-list { padding-left: var(--sp-5); }
  .au-tl-head { grid-template-columns: 1fr; gap: var(--sp-1); }
  .au-tl-node { display: none; }
}

/* ---- Tools ---- */

.lp-toolbox { gap: var(--sp-4); }
.lp-toolbox__head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); }
.lp-toolrow { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); }
.lp-toolrow span { font-size: 1rem; font-weight: 500; display: flex; flex-direction: column; gap: var(--sp-1); }
.lp-toolrow small { font-weight: 400; color: var(--bento-ink-soft); font-size: 0.9375rem; line-height: 1.5; }
.lp-toolrow[hidden], .lp-toolrow [hidden] { display: none; }
.lp-listen { min-height: 44px; min-width: 6.5em; flex: none; }
.lp-sample { font-family: var(--font-display); font-size: 1.0625rem; line-height: 1.7; color: var(--bento-ink); transition: font-size var(--dur-fast) ease; }
/* The highlight is a background image so it can be swept on like a marker. */
.lp-sample mark {
  background: linear-gradient(var(--bento-highlight), var(--bento-highlight)) 0 0 / 100% 100% no-repeat;
  color: var(--bento-ink);
  padding: 0 2px;
  border-radius: 3px;
}
.lp-reader-status { color: var(--bento-ink-soft); font-size: 0.9375rem; margin-top: var(--sp-4); }

.lp-reader.demo-fs-s .lp-sample { font-size: 0.9375rem; }
.lp-reader.demo-fs-l .lp-sample { font-size: 1.3125rem; }
.lp-reader.demo-contrast { background: var(--bento-ink); border-color: var(--bento-ink); }
.lp-reader.demo-contrast h3, .lp-reader.demo-contrast .lp-sample, .lp-reader.demo-contrast .lp-reader-status { color: var(--bento-white); }
.lp-reader.demo-contrast .lp-sample mark { background-image: linear-gradient(var(--bento-tan-200), var(--bento-tan-200)); color: var(--bento-ink); }
.lp-reader.demo-contrast .bento-card__eyebrow { color: var(--bento-tan-200); }
.lp-reader.demo-contrast .fx-wave span { background: var(--bento-tan-200); }
.lp-reader.demo-dyslexia .lp-sample { font-family: 'OpenDyslexic', 'Comic Sans MS', cursive; letter-spacing: 0.05em; word-spacing: 0.12em; line-height: 1.9; }
.lp-reader.demo-colorblind .lp-sample mark {
  position: relative;
  overflow: hidden;
}
.lp-reader.demo-colorblind .lp-sample mark::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image: repeating-linear-gradient(45deg, transparent, transparent 4px, rgba(0, 0, 0, 0.13) 4px, rgba(0, 0, 0, 0.13) 8px);
}

/* ---- Pricing ---- */
/* The plan cards, the billing switch and the offer card live in
   plan_tiers.css, which /settings loads too. */

/* ---- FAQ ---- */

.lp-faq { max-width: 720px; }
.lp-faq details {
  border-top: 1px solid var(--bento-line);
  padding: var(--sp-4) 0;
}
.lp-faq details:last-child { padding-bottom: 0; }
.lp-faq summary {
  font-family: var(--font-display);
  font-size: 1.0625rem;
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}
.lp-faq summary::-webkit-details-marker { display: none; }
.lp-faq summary::before { content: "+ "; color: var(--bento-ink-soft); }
.lp-faq details[open] summary::before { content: "\2212 "; }
.lp-faq p { color: var(--bento-ink-soft); margin: var(--sp-3) 0 0; line-height: 1.6; }

/* ---- Brand mark (first section on the page) ---- */

.lp-card--logo {
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--sp-7) var(--sp-6);
}
.lp-card--logo .logo-lockup { width: 100%; }

/* ---- Contact ---- */

.lp-contact {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-5);
  flex-wrap: wrap;
}
.lp-contact__text {
  font-family: var(--font-body);
  color: var(--bento-ink-soft);
  font-size: 1.0625rem;
  line-height: 1.6;
  max-width: 560px;
  margin: 0;
}
.lp-contact__text a { color: var(--bento-ink); font-weight: 600; text-decoration: underline; text-underline-offset: 2px; }

/* ---- Final CTA ---- */

.lp-final {
  background: var(--bento-tan-100);
  border-radius: var(--r-lg);
  padding: var(--sp-8) var(--sp-7);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-6);
  flex-wrap: wrap;
}
.lp-final h2 { font-size: 1.75rem; font-weight: 600; letter-spacing: -0.02em; }
.lp-final p { color: var(--bento-ink-soft); margin-top: var(--sp-2); }

/* ---- Footer ---- */

.lp-foot { background: var(--bento-white); border-top: 1px solid var(--bento-line); padding: var(--sp-9) 0 var(--sp-6); }
.lp-foot-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
  gap: var(--sp-7);
}
.lp-tagline { color: var(--bento-ink-soft); font-size: 1rem; line-height: 1.6; margin-top: var(--sp-3); max-width: 40ch; }
.lp-foot h4 { font-family: var(--font-body); font-size: 0.8125rem; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--bento-ink-soft); margin-bottom: var(--sp-3); }
.lp-foot ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-2); }
.lp-foot a { text-decoration: none; color: var(--bento-ink-soft); font-size: 1rem; }
.lp-foot a:hover { color: var(--bento-ink); }
.lp-legal { color: var(--bento-ink-soft); font-size: 0.9375rem; margin-top: var(--sp-8); }

@media (max-width: 720px) {
  .lp-foot-grid { grid-template-columns: 1fr; gap: var(--sp-5); }
}

@media (prefers-reduced-motion: reduce) {
  .lp * { transition: none !important; }
}

/* ============================================================
   Landing bento system
   One grid (.lp-bento) and one card shell (.lp-card) for every section:
   four equal columns and one row height on desktop, two on tablet, one on
   phones. Each card holds a drawing (.lp-fx, templates/_landing_fx.html)
   with its own motion; no two cards share one. Drawings rest on their
   finished frame and only move once the grid has scrolled in (.in).
   ============================================================ */
.lp .lp-depth { padding: 0; }

/* Nothing on the page may scroll sideways; every grid keeps the container's
   equal side gutters. */
.lp { overflow-x: clip; }
.lp .lp-bento > .bento-cell { min-width: 0; }

.lp .lp-bento {
  width: 100%;
  margin-inline: auto;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-auto-rows: minmax(300px, auto);
  gap: var(--sp-5);
}

.lp-card {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding: var(--sp-6);
  gap: var(--sp-3);
}
.lp-card .bento-card__title { font-size: 1.5rem; line-height: 1.2; }
.lp-card .bento-card__body { line-height: 1.55; }
/* Reading passages are set in the prose face, not the interface one. */
.lp .bento-card__body,
.lp-card__text .bento-card__body,
.lp-sec-head p,
.lp-lede { font-family: var(--lp-prose); }

/* Warm light that follows the pointer (position set by landing.js). */
.lp-card::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(340px circle at var(--mx, 50%) var(--my, 0%),
              color-mix(in srgb, var(--bento-highlight) 30%, transparent), transparent 70%);
  opacity: 0;
  transition: opacity var(--dur-base) ease;
}
@media (hover: hover) {
  .lp-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-card-hover); }
  .lp-card:hover::before { opacity: 1; }
}
.lp-card:focus-within { border-color: var(--bento-tan-300); }

/* Card with text on one side and a larger drawing on the other. */
.lp-card--split { flex-direction: row; align-items: stretch; gap: var(--sp-6); }
.lp-card__text { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: var(--sp-3); }
.lp-card--split > .lp-fx {
  flex: 0 0 38%;
  height: auto;
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.lp-card--wide > .lp-fx { flex-basis: 30%; }

@media (max-width: 1024px) {
  .lp .lp-bento { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-rows: minmax(280px, auto); }
  .lp .lp-bento > .bento-cell[data-span="2x1"],
  .lp .lp-bento > .bento-cell[data-span="4x1"] { grid-column: span 2; }
}
@media (max-width: 640px) {
  /* minmax(0, 1fr), not 1fr: a plain 1fr track grows to its widest
     unbreakable content (the ticker's no-wrap titles did), which pushed two
     cards past the right edge of the screen. */
  .lp .lp-bento { grid-template-columns: minmax(0, 1fr); grid-auto-rows: minmax(260px, auto); gap: var(--sp-4); }
  .lp .lp-bento > .bento-cell,
  .lp .lp-bento > .bento-cell[data-span] { grid-column: auto; grid-row: auto; }
  .lp-card { padding: var(--sp-5); }
  .lp-card .bento-card__title { font-size: 1.3125rem; }
  .lp-card--split { flex-direction: column; gap: var(--sp-4); }
  .lp-card--split > .lp-fx { flex-basis: auto; height: 150px; order: -1; }
  /* One card per row: centre each drawing in its card. (fill and track span
     the card on purpose; blocks stack from the bottom.) */
  .lp-card > .lp-fx:not(.fx-blocks, .fx-fill, .fx-track) { justify-content: center; }
  .lp-card > .fx-type,
  .lp-card > .fx-radar { margin-inline: auto; }
}

/* Drawing box, shared keyframes and the plan drawings (coin, path, burst,
   radar and the annual-plan set) live in card_fx.css, which /pricing loads too. */

/* 1. orbit: two moons on an elliptical path around the event */
.fx-orbit__tilt { position: relative; width: 180px; height: 80px; transform: rotate(-12deg); }
.fx-orbit .fx-orbit__ring ellipse { stroke-width: 1.5; stroke-dasharray: 4 6; opacity: .6; }
.fx-orbit__core {
  position: absolute; left: 50%; top: 50%;
  width: 34px; height: 34px; margin: -17px 0 0 -17px;
  border-radius: 50%;
  background: var(--bento-ink);
  box-shadow: 0 0 0 6px color-mix(in srgb, var(--bento-highlight) 45%, transparent);
}
.fx-orbit__moon {
  position: absolute; left: 0; top: 0;
  width: 14px; height: 14px;
  border-radius: 50%;
  background: var(--bento-highlight);
  border: 2px solid var(--bento-ink);
  offset-path: path('M 10 40 A 80 28 0 1 1 170 40 A 80 28 0 1 1 10 40');
  offset-rotate: 0deg;
  offset-distance: 18%;
}
.fx-orbit__moon--late { width: 9px; height: 9px; background: var(--bento-white); offset-distance: 68%; }
@keyframes fx-orbit { from { offset-distance: 0%; } to { offset-distance: 100%; } }
@keyframes fx-dash { to { stroke-dashoffset: -40; } }
@keyframes fx-core { 50% { box-shadow: 0 0 0 12px color-mix(in srgb, var(--bento-highlight) 15%, transparent); } }
.lp-bento.in .fx-orbit__moon { animation: fx-orbit 9s linear infinite; }
.lp-bento.in .fx-orbit__moon--late { animation-duration: 14s; animation-delay: -5s; }
.lp-bento.in .fx-orbit__ring ellipse { animation: fx-dash 4s linear infinite; }
.lp-bento.in .fx-orbit__core { animation: fx-core 3s ease-in-out infinite; }

/* 2. type: lines typed out, one of them highlighted */
.fx-type { display: flex; flex-direction: column; justify-content: center; gap: 10px; max-width: 260px; }
.fx-type span { position: relative; height: 8px; border-radius: 4px; background: var(--bento-tan-300); }
.fx-type span:nth-child(2) { width: 86%; }
.fx-type span:nth-child(3) { width: 94%; background: var(--bento-ink-soft); }
.fx-type span:nth-child(4) { width: 58%; }
.fx-type .is-marked::before {
  content: ""; position: absolute; inset: -4px -5px; z-index: -1;
  border-radius: 5px;
  background: var(--bento-highlight);
  transform-origin: left center;
}
@keyframes fx-type {
  0% { clip-path: inset(0 100% 0 0); }
  28%, 88% { clip-path: inset(0 0 0 0); opacity: 1; }
  100% { clip-path: inset(0 0 0 0); opacity: 0; }
}
@keyframes fx-type-mark { 0%, 40% { transform: scaleX(0); } 55%, 100% { transform: scaleX(1); } }
.lp-bento.in .fx-type span { animation: fx-type 6s steps(14, end) calc(var(--i) * .45s) infinite both; }
.lp-bento.in .fx-type .is-marked::before { animation: fx-type-mark 6s ease-out .9s infinite both; }

/* 3. fill: a meter filling to the 200-word mark */
.fx-fill { display: flex; flex-wrap: wrap; align-content: center; justify-content: space-between; row-gap: 8px; }
.fx-fill span {
  position: relative; flex: 0 0 100%;
  height: 14px; overflow: hidden;
  border-radius: var(--r-pill);
  background: var(--bento-sand);
  border: 1px solid var(--bento-line);
}
.fx-fill span::before {
  content: ""; position: absolute; top: 0; bottom: 0; left: 0;
  width: var(--pct);
  border-radius: inherit;
  background: var(--bento-ink);
  transform-origin: left center;
}
.fx-fill span::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--bento-white) 70%, transparent), transparent);
  transform: translateX(-100%);
}
.fx-fill small { font-size: .75rem; font-weight: 600; color: var(--bento-ink-soft); }
@keyframes fx-fill { 0% { transform: scaleX(0); } 30%, 85% { transform: scaleX(1); opacity: 1; } 100% { transform: scaleX(1); opacity: 0; } }
@keyframes fx-shine { 0%, 40% { transform: translateX(-100%); } 80%, 100% { transform: translateX(100%); } }
.lp-bento.in .fx-fill span::before { animation: fx-fill 4.5s cubic-bezier(.3, .8, .3, 1) infinite both; }
.lp-bento.in .fx-fill span::after { animation: fx-shine 3s ease-in-out infinite; }

/* 4. blocks: bricks dropping into a stack */
.fx-blocks { display: flex; flex-direction: column-reverse; align-items: flex-start; gap: 3px; }
.fx-blocks span {
  width: 58px; height: 11px;
  margin-left: calc(var(--i) * 5px);
  border-radius: 3px;
  background: var(--bento-tan-200);
  border: 1.5px solid var(--bento-ink);
}
.fx-blocks span:nth-child(3) { background: var(--bento-highlight); }
@keyframes fx-drop {
  0% { transform: translateY(-70px); opacity: 0; }
  10% { transform: translateY(0); opacity: 1; }
  14% { transform: translateY(-5px); }
  18%, 84% { transform: translateY(0); opacity: 1; }
  100% { transform: translateY(0); opacity: 0; }
}
.lp-bento.in .fx-blocks span { animation: fx-drop 5s cubic-bezier(.5, 0, .6, 1) calc(var(--i) * .3s) infinite both; }

/* 5. flip: a page turning in an open book */
.fx-flip { display: flex; align-items: center; perspective: 420px; }
.fx-flip__book {
  position: relative; box-sizing: border-box;
  width: 104px; height: 64px; padding: 10px 8px;
  border: 2px solid var(--bento-ink);
  border-radius: 4px;
  background:
    linear-gradient(90deg, transparent 49%, var(--bento-ink) 49% 51%, transparent 51%),
    repeating-linear-gradient(transparent 0 8px, var(--bento-tan-200) 8px 10px) content-box,
    var(--bento-white);
  transform-style: preserve-3d;
}
.fx-flip__book span {
  position: absolute; box-sizing: border-box;
  top: -2px; bottom: -2px; left: 50%; width: calc(50% + 2px);
  padding: 10px 8px;
  border: 2px solid var(--bento-ink);
  border-radius: 0 4px 4px 0;
  background: repeating-linear-gradient(transparent 0 8px, var(--bento-tan-300) 8px 10px) content-box, var(--bento-sand);
  transform-origin: left center;
}
@keyframes fx-flip { 0%, 15% { transform: rotateY(0); } 60%, 100% { transform: rotateY(-180deg); } }
.lp-bento.in .fx-flip__book span { animation: fx-flip 3.4s cubic-bezier(.45, 0, .25, 1) infinite; }

/* 6. fan: essay pages fanning open */
.fx-fan span {
  position: absolute; box-sizing: border-box;
  left: 34px; bottom: 2px;
  width: 46px; height: 62px; padding: 10px 7px;
  border: 2px solid var(--bento-ink);
  border-radius: 4px;
  background: repeating-linear-gradient(transparent 0 7px, var(--bento-tan-200) 7px 9px) content-box, var(--bento-white);
  transform-origin: 50% 100%;
  transform: translateX(var(--x)) rotate(var(--r));
}
.fx-fan span:nth-child(1) { --r: -18deg; --x: -16px; }
.fx-fan span:nth-child(2) { --r: 0deg; --x: 0px; background-color: var(--bento-sand); }
.fx-fan span:nth-child(3) { --r: 18deg; --x: 16px; }
@keyframes fx-fan { 0%, 100% { transform: none; } 40%, 70% { transform: translateX(var(--x)) rotate(var(--r)); } }
.lp-bento.in .fx-fan span { animation: fx-fan 4s cubic-bezier(.34, 1.4, .64, 1) infinite; }

/* 7. themes: columns rising to each theme's share, then lit in turn */
.lp-stat-row { display: flex; align-items: baseline; flex-wrap: wrap; column-gap: var(--sp-4); }
.lp-stat-row .lp-stat-num { margin: 0; }
.fx-themes.lp-fx {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  align-items: end;
  gap: var(--sp-3);
  height: auto;
  margin: auto 0 0;
  padding: var(--sp-4) 0 0;
  border-top: 1px solid var(--bento-line);
}
.fx-themes li { display: flex; flex-direction: column; align-items: center; gap: 6px; min-width: 0; }
.fx-themes b { font-size: .9375rem; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; }
.fx-themes span {
  position: relative;
  width: 100%; max-width: 48px; height: 120px;
  overflow: hidden;
  border-radius: var(--r-xs);
  background: var(--bento-sand);
}
.fx-themes span::before {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0;
  height: var(--h);
  border-radius: inherit;
  background: var(--bento-tan-300);
  transform-origin: center bottom;
}
.fx-themes li:first-child span::before { background: var(--bento-ink); }
.fx-themes small { max-width: 100%; font-size: .75rem; color: var(--bento-ink-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
@keyframes fx-rise { 0% { transform: scaleY(0); } 70% { transform: scaleY(1.06); } 100% { transform: scaleY(1); } }
@keyframes fx-spot { 0%, 18%, 100% { background-color: var(--bento-sand); } 6%, 12% { background-color: var(--bento-highlight); } }
.lp-bento.in .fx-themes span::before { animation: fx-rise .9s cubic-bezier(.3, .7, .4, 1) calc(var(--i) * 110ms) both; }
.lp-bento.in .fx-themes span { animation: fx-spot 6s ease-in-out calc(var(--i) * 1s + 1.2s) infinite; }
@media (max-width: 640px) {
  .fx-themes.lp-fx { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .fx-themes li:nth-child(n+5) { display: none; }
  .fx-themes span { height: 96px; }
}

/* 8. ticker: every event title rolling past (pauses on hover) */
.fx-ticker.lp-fx {
  display: block;
  align-self: stretch;
  min-height: 170px;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(transparent, black 22%, black 78%, transparent);
  mask-image: linear-gradient(transparent, black 22%, black 78%, transparent);
}
/* Absolutely placed so the full list never sets the card's height. */
.fx-ticker__roll { position: absolute; top: 0; left: 0; right: 0; list-style: none; margin: 0; padding: 0; }
.fx-ticker__roll li {
  margin: 0 0 8px;
  padding: 8px 12px;
  border-radius: var(--r-xs);
  background: color-mix(in srgb, var(--bento-white) 75%, transparent);
  font-size: .875rem;
  line-height: 1.35;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.fx-ticker__roll li:nth-child(4n+1) { background: var(--bento-highlight); }
@keyframes fx-roll { to { transform: translateY(-50%); } }
.lp-bento.in .fx-ticker__roll { animation: fx-roll calc(var(--n) * 2.2s) linear infinite; }
.lp-card:hover .fx-ticker__roll { animation-play-state: paused; }

/* 9. scan: a lens sweeping a single cut-off line */
.fx-scan { display: flex; align-items: center; gap: 6px; container-type: inline-size; }
.fx-scan i { width: 60%; height: 10px; border-radius: 5px; background: var(--bento-tan-300); transform-origin: left center; }
.fx-scan b { display: flex; gap: 4px; }
.fx-scan b span { width: 6px; height: 6px; border-radius: 50%; background: var(--bento-ink); }
.fx-scan svg { position: absolute; left: 0; top: 19px; }
.fx-scan svg circle { fill: color-mix(in srgb, var(--bento-white) 55%, transparent); stroke-width: 2.5; }
.fx-scan svg path { stroke-width: 3; }
@keyframes fx-lens { 0%, 100% { transform: translateX(-6px); } 50% { transform: translateX(calc(60cqw - 22px)); } }
@keyframes fx-cut { 0%, 100% { transform: scaleX(.45); } 50% { transform: scaleX(1); } }
@keyframes fx-blink { 0%, 100% { opacity: .2; } 50% { opacity: 1; } }
.lp-bento.in .fx-scan svg { animation: fx-lens 4s ease-in-out infinite; }
.lp-bento.in .fx-scan i { animation: fx-cut 4s ease-in-out infinite; }
.lp-bento.in .fx-scan b span { animation: fx-blink 1.2s ease-in-out infinite both; }
.lp-bento.in .fx-scan b span:nth-child(2) { animation-delay: .2s; }
.lp-bento.in .fx-scan b span:nth-child(3) { animation-delay: .4s; }

/* 10. hinge: a reference volume's cover swinging open */
.fx-hinge { display: flex; align-items: center; padding-left: 44px; perspective: 500px; }
.fx-hinge__book {
  position: relative; box-sizing: border-box;
  width: 54px; height: 66px; padding: 12px 8px;
  border: 2px solid var(--bento-ink);
  border-radius: 2px 6px 6px 2px;
  background: repeating-linear-gradient(transparent 0 8px, var(--bento-tan-200) 8px 10px) content-box, var(--bento-white);
  transform-style: preserve-3d;
}
.fx-hinge__book span {
  position: absolute; inset: -2px;
  border-radius: 2px 6px 6px 2px;
  background: var(--bento-ink);
  transform-origin: left center;
}
.fx-hinge__book span::after {
  content: ""; position: absolute; left: 10px; right: 10px; top: 14px;
  height: 8px; border-radius: 2px;
  background: var(--bento-highlight);
}
@keyframes fx-hinge { 0%, 20% { transform: rotateY(0); } 70%, 100% { transform: rotateY(-150deg); } }
.lp-bento.in .fx-hinge__book span { animation: fx-hinge 2.8s cubic-bezier(.5, 0, .3, 1) infinite alternate; }

/* 11. riffle: a thick stack of sheets riffling */
.fx-riffle span {
  position: absolute;
  left: calc(8px + var(--i) * 2px);
  bottom: calc(4px + var(--i) * 2px);
  width: 76px; height: 50px;
  border: 1.5px solid var(--bento-ink);
  border-radius: 3px;
  background: var(--bento-white);
  transform-origin: 0 100%;
}
.fx-riffle span:last-child { background: var(--bento-sand); }
@keyframes fx-riffle { 0%, 30%, 100% { transform: none; } 12% { transform: translate(-3px, -8px) rotate(-14deg); } }
.lp-bento.in .fx-riffle span { animation: fx-riffle 3.2s ease-in-out calc((7 - var(--i)) * .12s) infinite; }

/* 12. chat: typing dots, then a reply that keeps changing shape */
.fx-chat { display: flex; flex-direction: column; justify-content: center; gap: 8px; }
.fx-chat__bubble {
  align-self: flex-start; display: flex; gap: 5px;
  padding: 9px 12px;
  border-radius: 14px 14px 14px 4px;
  background: var(--bento-sand);
  border: 1px solid var(--bento-line);
}
.fx-chat__bubble span { width: 7px; height: 7px; border-radius: 50%; background: var(--bento-ink-soft); }
.fx-chat__reply {
  align-self: flex-end; display: flex; flex-direction: column; gap: 5px;
  width: 58%; padding: 9px 12px;
  border-radius: 14px 14px 4px 14px;
  background: var(--bento-ink);
}
.fx-chat__reply i { height: 5px; border-radius: 3px; background: var(--bento-tan-200); transform-origin: left center; }
.fx-chat__reply i:last-child { width: 65%; }
@keyframes fx-bounce { 0%, 60%, 100% { transform: translateY(0); } 30% { transform: translateY(-5px); } }
@keyframes fx-morph { 0% { transform: scaleX(.3); } 50% { transform: scaleX(1); } 100% { transform: scaleX(.55); } }
.lp-bento.in .fx-chat__bubble span { animation: fx-bounce 1.2s ease-in-out infinite; }
.lp-bento.in .fx-chat__bubble span:nth-child(2) { animation-delay: .15s; }
.lp-bento.in .fx-chat__bubble span:nth-child(3) { animation-delay: .3s; }
.lp-bento.in .fx-chat__reply i { animation: fx-morph 2.4s ease-in-out infinite alternate; }
.lp-bento.in .fx-chat__reply i:last-child { animation-delay: -.8s; }

/* 13. astro: counter-rotating rings around the History Orbit mark */
.fx-astro .fx-astro__a > circle:first-child { stroke-width: 1.5; stroke-dasharray: 2 6; opacity: .7; }
.fx-astro .fx-astro__b > circle:first-child { stroke-width: 1.5; opacity: .45; }
.fx-astro .fx-astro__planet { fill: var(--bento-highlight); stroke-width: 2; }
.fx-astro .fx-astro__core { fill: var(--bento-ink); }
.fx-astro .fx-astro__h { stroke: var(--bento-highlight); stroke-width: 3; }
.fx-astro__a, .fx-astro__b, .fx-astro__core { transform-box: view-box; transform-origin: 75px 75px; }
@keyframes fx-breathe { 50% { transform: scale(1.12); } }
.lp-bento.in .fx-astro__a { animation: fx-spin 16s linear infinite; }
.lp-bento.in .fx-astro__b { animation: fx-spin-back 9s linear infinite; }
.lp-bento.in .fx-astro__core { animation: fx-breathe 3.2s ease-in-out infinite; }
@media (max-width: 640px) { .fx-astro svg { width: 130px; height: 130px; } }

/* 14. shuffle: two cards trading places */
.fx-shuffle span {
  position: absolute; box-sizing: border-box;
  top: 6px; left: 44px;
  width: 80px; height: 56px; padding: 11px 10px;
  border: 2px solid var(--bento-ink);
  border-radius: 6px;
}
.fx-shuffle span:nth-child(1) {
  z-index: 2;
  background: repeating-linear-gradient(transparent 0 7px, var(--bento-tan-300) 7px 9px) content-box, var(--bento-white);
}
.fx-shuffle span:nth-child(2) {
  z-index: 1;
  background: var(--bento-tan-200);
  transform: translate(26px, 8px) rotate(6deg);
}
@keyframes fx-shuffle-a {
  0%, 20% { transform: none; z-index: 2; }
  35% { transform: translate(-40px, -2px) rotate(-10deg); z-index: 2; }
  36% { z-index: 0; }
  50%, 70% { transform: translate(26px, 8px) rotate(6deg); z-index: 0; }
  85% { transform: translate(70px, 4px) rotate(12deg); z-index: 0; }
  86% { z-index: 2; }
  100% { transform: none; z-index: 2; }
}
@keyframes fx-shuffle-b {
  0%, 20% { transform: translate(26px, 8px) rotate(6deg); z-index: 1; }
  35% { transform: translate(70px, 4px) rotate(12deg); z-index: 1; }
  36% { z-index: 3; }
  50%, 70% { transform: none; z-index: 3; }
  85% { transform: translate(-40px, -2px) rotate(-10deg); z-index: 3; }
  86% { z-index: 1; }
  100% { transform: translate(26px, 8px) rotate(6deg); z-index: 1; }
}
.lp-bento.in .fx-shuffle span:nth-child(1) { animation: fx-shuffle-a 5s ease-in-out infinite; }
.lp-bento.in .fx-shuffle span:nth-child(2) { animation: fx-shuffle-b 5s ease-in-out infinite; }

/* 15. cascade: the essay's numbered sections growing in, then read down */
.fx-cascade.lp-fx { list-style: none; padding: 0; flex-direction: column; justify-content: center; align-items: stretch; gap: 5px; }
.fx-cascade li {
  display: grid; grid-template-columns: 20px 1fr; align-items: center; gap: 6px;
  height: 14px; padding: 0 6px;
  border-radius: 4px;
}
.fx-cascade b { font-size: .625rem; font-weight: 700; line-height: 1; color: var(--bento-ink-soft); }
.fx-cascade li span { height: 6px; border-radius: 3px; background: var(--bento-ink-soft); transform-origin: left center; }
.fx-cascade li:nth-child(3n+1) span { width: 92%; }
.fx-cascade li:nth-child(3n+2) span { width: 70%; }
.fx-cascade li:nth-child(3n) span { width: 82%; }
@keyframes fx-grow { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes fx-readline { 0%, 12%, 100% { background-color: transparent; } 5% { background-color: var(--bento-highlight); } }
.lp-bento.in .fx-cascade li span { animation: fx-grow .6s cubic-bezier(.2, .8, .2, 1) calc(var(--i) * 80ms) both; }
.lp-bento.in .fx-cascade li { animation: fx-readline 4s ease-in-out calc(var(--i) * .3s + 1s) infinite; }
@media (max-width: 640px) {
  .fx-cascade.lp-fx { gap: 3px; }
  .fx-cascade li { height: 11px; }
}

/* 16. ring: a one-minute dial filling */
.fx-ring { display: flex; align-items: center; }
.fx-ring svg { transform: rotate(-90deg); }
.fx-ring .fx-ring__track { stroke: var(--bento-tan-100); stroke-width: 4; }
.fx-ring .fx-ring__fill { stroke-width: 4; stroke-dasharray: 100; stroke-dashoffset: 25; }
.fx-ring b { position: absolute; left: 0; top: 50%; width: 56px; transform: translateY(-50%); text-align: center; font-size: .9375rem; font-weight: 700; }
@keyframes fx-dial { 0% { stroke-dashoffset: 100; } 75%, 88% { stroke-dashoffset: 0; opacity: 1; } 100% { stroke-dashoffset: 0; opacity: 0; } }
@keyframes fx-tick { 0%, 72% { transform: translateY(-50%) scale(1); } 80% { transform: translateY(-50%) scale(1.25); } 88%, 100% { transform: translateY(-50%) scale(1); } }
.lp-bento.in .fx-ring__fill { animation: fx-dial 3.6s cubic-bezier(.4, 0, .2, 1) infinite; }
.lp-bento.in .fx-ring b { animation: fx-tick 3.6s ease-out infinite; }

/* 17. hourglass: sand draining, then the glass turns over */
.fx-hourglass { display: flex; align-items: center; }
.fx-hourglass .fx-hourglass__frame { stroke-width: 2.5; }
.fx-hourglass .fx-hourglass__top,
.fx-hourglass .fx-hourglass__bottom { fill: var(--bento-tan-300); stroke: none; }
.fx-hourglass .fx-hourglass__stream { stroke: var(--bento-tan-300); stroke-width: 1.5; stroke-dasharray: 2 3; }
.fx-hourglass__top, .fx-hourglass__bottom { transform-box: fill-box; transform-origin: 50% 100%; }
.fx-hourglass__bottom { transform: scaleY(.4); }
.fx-hourglass__glass { transform-box: view-box; transform-origin: 20px 28px; }
@keyframes fx-drain { 0% { transform: scaleY(1); } 80%, 100% { transform: scaleY(0); } }
@keyframes fx-pile { 0% { transform: scaleY(0); } 80%, 100% { transform: scaleY(1); } }
@keyframes fx-flow { to { stroke-dashoffset: -5; } }
@keyframes fx-stream { 0%, 78% { opacity: 1; } 80%, 100% { opacity: 0; } }
@keyframes fx-turn { 0%, 85% { transform: rotate(0); } 100% { transform: rotate(180deg); } }
.lp-bento.in .fx-hourglass__top { animation: fx-drain 4s linear infinite; }
.lp-bento.in .fx-hourglass__bottom { animation: fx-pile 4s linear infinite; }
.lp-bento.in .fx-hourglass__stream { animation: fx-flow .5s linear infinite, fx-stream 4s linear infinite; }
.lp-bento.in .fx-hourglass__glass { animation: fx-turn 4s cubic-bezier(.6, 0, .3, 1) infinite; }

/* 18. stopwatch: a ticking hand and a pressed crown */
.fx-stopwatch { display: flex; align-items: center; }
.fx-stopwatch .fx-stopwatch__face { fill: var(--bento-white); stroke-width: 2.5; }
.fx-stopwatch .fx-stopwatch__button { fill: var(--bento-ink); stroke: none; }
.fx-stopwatch .fx-stopwatch__ticks { stroke: var(--bento-tan-300); }
.fx-stopwatch .fx-stopwatch__hand { stroke-width: 2.5; }
.fx-stopwatch .fx-stopwatch__pin { fill: var(--bento-highlight); stroke-width: 1.5; }
.fx-stopwatch__hand { transform-box: view-box; transform-origin: 24px 32px; }
.fx-stopwatch__button { transform-box: fill-box; transform-origin: 50% 100%; }
@keyframes fx-press { 0%, 8%, 100% { transform: none; } 3% { transform: translateY(2px) scaleY(.6); } }
.lp-bento.in .fx-stopwatch__hand { animation: fx-spin 4.8s steps(24, end) infinite; }
.lp-bento.in .fx-stopwatch__button { animation: fx-press 4.8s ease-out infinite; }

/* 19. track: a marker travelling a timeline, lighting each point */
.fx-track { display: flex; align-items: center; justify-content: space-between; container-type: inline-size; }
.fx-track::before { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 2px; margin-top: -1px; background: var(--bento-tan-300); }
.fx-track i {
  position: absolute; left: -5px; top: 50%;
  width: 22px; height: 22px; margin-top: -11px;
  border-radius: 50%;
  background: var(--bento-highlight);
  transform: translateX(calc(100cqw - 12px));
}
.fx-track span { position: relative; width: 12px; height: 12px; border-radius: 50%; background: var(--bento-ink); border: 2px solid var(--bento-ink); }
@keyframes fx-travel { 0% { transform: translateX(0); opacity: 1; } 80% { transform: translateX(calc(100cqw - 12px)); opacity: 1; } 100% { transform: translateX(calc(100cqw - 12px)); opacity: 0; } }
@keyframes fx-node {
  0% { background: var(--bento-cream); transform: scale(1); }
  5% { background: var(--bento-ink); transform: scale(1.4); }
  15%, 75% { background: var(--bento-ink); transform: scale(1); }
  90%, 100% { background: var(--bento-cream); }
}
.lp-bento.in .fx-track i { animation: fx-travel 5s cubic-bezier(.45, 0, .55, 1) infinite; }
.lp-bento.in .fx-track span { animation: fx-node 5s ease-out calc(var(--i) * 1s) infinite both; }

/* 20. aa: text size stepping S, M, L beside a toggling switch */
.lp-toolbox__head .lp-fx { width: auto; height: 44px; margin: 0; }
.fx-aa { display: flex; align-items: center; gap: var(--sp-3); }
.fx-aa b { width: 44px; text-align: center; font-family: var(--font-display); font-size: 1.5rem; line-height: 1; }
.fx-aa__switch { position: relative; width: 36px; height: 20px; border-radius: var(--r-pill); background: var(--bento-ink); }
.fx-aa__switch > span {
  position: absolute; left: 3px; top: 3px;
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--bento-white);
  transform: translateX(16px);
}
@keyframes fx-sizes { 0%, 25% { transform: scale(.7); } 33%, 58% { transform: scale(1); } 66%, 91% { transform: scale(1.3); } 100% { transform: scale(.7); } }
@keyframes fx-knob { 0%, 40% { transform: translateX(0); } 50%, 90% { transform: translateX(16px); } 100% { transform: translateX(0); } }
@keyframes fx-track-bg { 0%, 40% { background: var(--bento-tan-200); } 50%, 90% { background: var(--bento-ink); } 100% { background: var(--bento-tan-200); } }
.lp-bento.in .fx-aa b { animation: fx-sizes 4.5s cubic-bezier(.34, 1.4, .64, 1) infinite; }
.lp-bento.in .fx-aa__switch > span { animation: fx-knob 3s var(--ease-spring) infinite; }
.lp-bento.in .fx-aa__switch { animation: fx-track-bg 3s ease infinite; }

/* 21. wave: a voice level meter (quickens while reading aloud) */
.fx-wave { display: flex; align-items: center; gap: 5px; height: 56px; }
.fx-wave span { width: 6px; height: 100%; border-radius: 3px; background: var(--bento-ink); transform: scaleY(var(--h, .6)); }
.fx-wave span:nth-child(1) { --h: .35; }
.fx-wave span:nth-child(2) { --h: .7; }
.fx-wave span:nth-child(3) { --h: 1; }
.fx-wave span:nth-child(4) { --h: .55; }
.fx-wave span:nth-child(5) { --h: .85; }
.fx-wave span:nth-child(6) { --h: .4; }
.fx-wave span:nth-child(7) { --h: .65; }
@keyframes fx-eq { from { transform: scaleY(.2); } to { transform: scaleY(1); } }
.lp-bento.in .fx-wave span { animation: fx-eq 1.1s ease-in-out calc(var(--i) * -.17s) infinite alternate; }
.lp-bento.in .fx-wave span:nth-child(odd) { animation-duration: .85s; }
/* Quicker while the sample is being read aloud (static/js/read-aloud.js). */
.lp-bento.in .lp-reader.is-speaking .fx-wave span { animation-duration: .42s; }
.lp-bento.in .lp-reader.is-speaking .fx-wave span:nth-child(odd) { animation-duration: .33s; }
.lp-bento.in .lp-reader.demo-contrast .fx-wave span { background: var(--bento-tan-200); }

/* 22. cap: a mortarboard tossed and caught */
.fx-cap { display: flex; align-items: flex-end; }
.fx-cap .fx-cap__board { fill: var(--bento-ink); }
.fx-cap .fx-cap__band { fill: var(--bento-tan-200); }
.fx-cap .fx-cap__tassel { stroke: var(--bento-highlight); stroke-width: 3; }
.fx-cap .fx-cap__shadow { fill: var(--bento-tan-300); stroke: none; opacity: .6; }
.fx-cap__hat, .fx-cap__shadow { transform-box: fill-box; transform-origin: 50% 50%; }
@keyframes fx-toss {
  0%, 60%, 100% { transform: none; }
  25% { transform: translateY(-20px) rotate(-14deg); }
  44% { transform: translateY(0) rotate(4deg); }
  51% { transform: translateY(-4px) rotate(0); }
}
@keyframes fx-shadow { 0%, 60%, 100% { transform: scaleX(1); opacity: .6; } 25% { transform: scaleX(.55); opacity: .3; } }
.lp-bento.in .fx-cap__hat { animation: fx-toss 3.2s ease-in-out infinite; }
.lp-bento.in .fx-cap__shadow { animation: fx-shadow 3.2s ease-in-out infinite; }

/* 23. stamp: a checklist ticked off row by row */
.fx-stamp { display: flex; flex-direction: column; justify-content: center; gap: 9px; }
.fx-stamp div { display: flex; align-items: center; gap: 10px; }
.fx-stamp b { position: relative; width: 16px; height: 16px; border: 2px solid var(--bento-ink); border-radius: 4px; background: var(--bento-highlight); }
.fx-stamp b::after {
  content: ""; position: absolute; left: 3px; top: -1px;
  width: 5px; height: 9px;
  border: solid var(--bento-ink);
  border-width: 0 2.5px 2.5px 0;
  transform: rotate(45deg);
}
.fx-stamp span { width: 120px; max-width: 70%; height: 7px; border-radius: 4px; background: var(--bento-tan-300); }
.fx-stamp div:nth-child(2) span { width: 90px; }
.fx-stamp div:nth-child(3) span { width: 105px; }
@keyframes fx-stamp { 0% { transform: rotate(45deg) scale(2.4); opacity: 0; } 8%, 82% { transform: rotate(45deg) scale(1); opacity: 1; } 100% { transform: rotate(45deg) scale(1); opacity: 0; } }
@keyframes fx-box { 0%, 6% { background: transparent; } 9%, 82% { background: var(--bento-highlight); } 100% { background: transparent; } }
.lp-bento.in .fx-stamp b::after { animation: fx-stamp 4.2s cubic-bezier(.5, 0, .2, 1.4) calc(var(--i) * .6s) infinite both; }
.lp-bento.in .fx-stamp b { animation: fx-box 4.2s ease calc(var(--i) * .6s) infinite both; }

/* 24. chalk: a line drawn across a blackboard, the chalk following it */
.fx-chalk { display: flex; align-items: flex-start; }
.fx-chalk .fx-chalk__board { fill: var(--bento-ink); stroke: var(--bento-tan-300); stroke-width: 3; }
.fx-chalk .fx-chalk__line { stroke: var(--bento-white); stroke-width: 2.5; stroke-dasharray: 1; stroke-dashoffset: 0; }
.fx-chalk .fx-chalk__legs { stroke: var(--bento-tan-300); stroke-width: 3; }
.fx-chalk__stick {
  position: absolute; left: 0; top: 0;
  width: 14px; height: 5px;
  border-radius: 2px;
  background: var(--bento-white);
  box-shadow: 0 0 0 1px var(--bento-ink-soft);
  offset-path: path('M14 36c8-14 14-14 18 0s12 12 18-2 12-12 18 0 10 6 26-10');
  offset-rotate: -35deg;
  offset-distance: 100%;
}
@keyframes fx-draw { 0% { stroke-dashoffset: 1; opacity: 1; } 60%, 85% { stroke-dashoffset: 0; opacity: 1; } 100% { stroke-dashoffset: 0; opacity: 0; } }
@keyframes fx-chalk { 0% { offset-distance: 0%; } 60%, 100% { offset-distance: 100%; } }
.lp-bento.in .fx-chalk__line { animation: fx-draw 4.5s ease-in-out infinite; }
.lp-bento.in .fx-chalk__stick { animation: fx-chalk 4.5s ease-in-out infinite; }

/* 25. lamp: a reading lamp flickering on and swaying */
.fx-lamp { display: flex; align-items: flex-end; }
.fx-lamp .fx-lamp__light { fill: var(--bento-highlight); stroke: none; opacity: .6; }
.fx-lamp .fx-lamp__pole, .fx-lamp .fx-lamp__base { stroke-width: 3; }
.fx-lamp .fx-lamp__shade { fill: var(--bento-ink); }
.fx-lamp .fx-lamp__page { stroke: var(--bento-ink-soft); stroke-width: 3; }
.fx-lamp__arm, .fx-lamp__light { transform-box: view-box; transform-origin: 16px 60px; }
@keyframes fx-sway { from { transform: rotate(-3deg); } to { transform: rotate(3deg); } }
@keyframes fx-flicker { 0% { opacity: 0; } 20% { opacity: .6; } 30% { opacity: .1; } 45% { opacity: .6; } 55% { opacity: .2; } 100% { opacity: .6; } }
@keyframes fx-glow { from { opacity: .6; } to { opacity: .35; } }
.lp-bento.in .fx-lamp__arm { animation: fx-sway 2.6s ease-in-out infinite alternate; }
.lp-bento.in .fx-lamp__light {
  animation:
    fx-sway 2.6s ease-in-out infinite alternate,
    fx-flicker 1.2s linear both,
    fx-glow 2s ease-in-out 1.2s infinite alternate;
}

/* ---- Reader highlight sweep ---- */
@keyframes fx-mark { from { background-size: 0% 100%; } to { background-size: 100% 100%; } }
.lp-bento.in .lp-sample mark { animation: fx-mark .9s ease-out .6s both; }
.lp-bento.in .lp-sample mark:last-of-type { animation-delay: 1.2s; }

/* ---- Pause drawings the reader can't see; stop them for reduced motion ---- */
.lp-bento.is-offscreen .lp-fx,
.lp-bento.is-offscreen .lp-fx *,
.lp-bento.is-offscreen .lp-fx *::before,
.lp-bento.is-offscreen .lp-fx *::after,
.lp-bento.is-offscreen .lp-offer, .lp-bento.is-offscreen .lp-offer *,
.lp-bento.is-offscreen .lp-offer *::before, .lp-bento.is-offscreen .lp-offer::after,
.lp-bento.is-offscreen .lp-plan--offer, .lp-bento.is-offscreen .lp-plan--offer::after { animation-play-state: paused; }

@media (prefers-reduced-motion: reduce) {
  .lp-fx, .lp-fx *, .lp-fx *::before, .lp-fx *::after,
  .lp-sample mark,
  .lp-plan__ribbon, .lp-plan__ribbon::after, .lp-offer__badge::after,
  .lp-plan-price s::after, .lp-plan__save,
  .lp-card--offer, .lp-card--offer::after, .lp-plan--offer, .lp-plan--offer::after,
  .lp-offer__badge::before, .lp-offer__pct, .lp-offer__was::after,
  .lp-offer__cta::before,
  .lp-billing__save, .lp-billing__save::after, .lp-notice span:first-child,
  .lp-plans .lp-bento > .bento-cell { animation: none !important; }
  .lp-billing__thumb { transition: none; }
  .lp-plan__save { clip-path: none; }
  .lp-card:hover { transform: none; }
}

/* ---- Scroll reveal (Part 7B) ---- */
/* --ease-out is not defined in tokens.css; using the literal ease-out keyword. */

/* Shorter travel and quicker settle than before (.8s / 36px), so sections
   land while the reader is still scrolling rather than after. The blur is a
   desktop nicety: on touch screens it costs a repaint per frame for an effect
   too small to see, so phones get the plain rise. */
html.js .reveal{opacity:0;transform:translateY(22px);transition:opacity .6s cubic-bezier(.16,1,.3,1),transform .7s cubic-bezier(.16,1,.3,1),filter .6s cubic-bezier(.16,1,.3,1)}
html.js .reveal.in{opacity:1;transform:none;filter:none}
html.js .reveal-grid > *{opacity:0;transform:translateY(18px) scale(.97);transition:opacity .5s cubic-bezier(.16,1,.3,1),transform .6s cubic-bezier(.22,1.2,.36,1),filter .5s cubic-bezier(.16,1,.3,1)}
html.js .reveal-grid.in > *{opacity:1;transform:none;filter:none}
@media (hover:hover) and (pointer:fine){
  html.js .reveal{filter:blur(4px)}
  html.js .reveal-grid > *{filter:blur(3px)}
  html.js .reveal.in, html.js .reveal-grid.in > *{filter:none}
}
/* A 50ms cascade, capped, so a long grid never keeps its last card waiting. */
html.js .reveal-grid > *:nth-child(2){transition-delay:50ms}
html.js .reveal-grid > *:nth-child(3){transition-delay:100ms}
html.js .reveal-grid > *:nth-child(4){transition-delay:150ms}
html.js .reveal-grid > *:nth-child(5){transition-delay:200ms}
html.js .reveal-grid > *:nth-child(6){transition-delay:250ms}
html.js .reveal-grid > *:nth-child(7){transition-delay:300ms}
html.js .reveal-grid > *:nth-child(n+8){transition-delay:340ms}
/* Once a card has arrived its hover and press must answer at once, not wait
   out the stagger delay that brought it in. */
html.js .reveal-grid.is-settled > *{transition-delay:0ms}

/* Press feedback on touch: the card gives under the finger like a key. */
.lp-card{transition:transform var(--dur-base) var(--ease-spring),box-shadow var(--dur-base) ease,border-color var(--dur-fast) ease}
.lp-card:has(a, button):active{transform:scale(.985);transition-duration:var(--dur-fast)}

/* The drawing leans a few pixels toward the pointer (--px/--py are -1..1,
   set by landing.js on fine pointers only), which reads as depth. */
.lp-card > .lp-fx, .lp-card .lp-card__text + .lp-fx{
  transform:translate3d(calc(var(--px, 0) * 6px), calc(var(--py, 0) * 5px), 0);
  transition:transform .5s cubic-bezier(.16,1,.3,1);
}

@media (prefers-reduced-motion:reduce){
  html.js .reveal, html.js .reveal-grid > *{opacity:1!important;transform:none!important;filter:none!important}
  .lp-card > .lp-fx, .lp-card:has(a, button):active{transform:none}
}

/* ---- One-time page notice (landing.html, {% if page_notice %}) ----
   Today only the "account unsuspended" notice. It sits in the flow directly
   under the island nav, so it is the first thing read and pushes the page
   down rather than covering it. Good news, so it is tinted with the success
   accent, not the highlighter the page uses for offers. */
.lp-alert-wrap { max-width: 1080px; padding-top: var(--sp-2); }
.lp-alert {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-3) var(--sp-3) var(--sp-4);
  background: color-mix(in srgb, var(--bento-success) 9%, var(--bento-white));
  border: 1px solid color-mix(in srgb, var(--bento-success) 35%, var(--bento-line));
  border-radius: var(--r-md);
  box-shadow: var(--shadow-card);
  color: var(--bento-ink);
}
.lp-alert__icon { width: 24px; height: 24px; flex: none; color: var(--bento-success); }
.lp-alert__text {
  flex: 1;
  margin: 0;
  font-family: var(--font-ui);
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.45;
}
.lp-alert__cta { flex: none; min-height: 44px; }
.lp-alert__close {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--bento-ink-soft);
  cursor: pointer;
}
.lp-alert__close svg { width: 18px; height: 18px; }
.lp-alert__close:hover,
.lp-alert__close:focus-visible { background: color-mix(in srgb, var(--bento-success) 14%, transparent); }
@media (max-width: 560px) {
  .lp-alert { flex-wrap: wrap; }
  .lp-alert__text { flex-basis: calc(100% - 92px); }
  .lp-alert__cta { width: 100%; justify-content: center; order: 3; }
}
