/* ========= SELF-HOSTED FONTS ========= */
/* Reason: served from our own origin so privacy blockers (e.g. Brave
   Shields) that reject fonts.googleapis.com can't break the typography */
@font-face {
  font-family: 'DM Serif Display';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/dm-serif-display-latin.woff2') format('woff2');
}

@font-face {
  font-family: 'DM Serif Text';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/dm-serif-text-italic-latin.woff2') format('woff2');
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/inter-latin-var.woff2') format('woff2');
}

/* Subset containing only 異 (U+7570) and 能 (U+80FD) for the name strip */
@font-face {
  font-family: 'Noto Serif JP';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/noto-serif-jp-subset.woff2') format('woff2');
  unicode-range: U+7570, U+80FD;
}

/* Poster-weight display face, used only by the SV Dictionary headline */
@font-face {
  font-family: 'Anton';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/anton-latin.woff2') format('woff2');
}

/* ========= TOKENS: straight from the logo ========= */
:root {
  --bg: #f2ede2;
  --fg: #2b1d16;
  --coral: #ee6a4c;
  --coral-deep: #c94e33;
  --coral-wash: rgba(238, 106, 76, 0.12);
  --rule: rgba(43, 29, 22, 0.12);
  --card: rgba(255, 255, 255, 0.55);
  --shadow-soft: 0 10px 30px rgba(43, 29, 22, 0.07);
  --display: 'DM Serif Display', serif;
  --display-em: 'DM Serif Text', serif;
  --body: 'Inter', system-ui, sans-serif;
  --max-width: 1240px;

  /* SV Dictionary: warmer greys and a heavier rule than the landing page,
     so dense term rows stay readable without boxing each one in a card. */
  --svd-poster: 'Anton', system-ui, sans-serif;
  --svd-label: #7a6455;
  --svd-body: #3d2b22;
  --svd-body-soft: #5c4a40;
  --svd-dim: #8a7a6d;
  --svd-rule: rgba(43, 29, 22, 0.2);
  --svd-hairline: rgba(43, 29, 22, 0.12);
  --svd-card: #fffcf2;
  --svd-card-back: #f3ede0;
  --svd-quote: rgba(238, 106, 76, 0.12);
}

/* ========= RESET ========= */
*,
*::before,
*::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--body);
  font-size: 16px;
  line-height: 1.5;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img,
video {
  max-width: 100%;
  height: auto;
  display: block;
}

ul {
  list-style: none;
}

button {
  font: inherit;
  background: none;
  border: none;
  color: inherit;
  cursor: pointer;
}

a {
  color: var(--fg);
}

a:hover {
  color: var(--coral-deep);
}

/* Italic accent words inside display headings */
.hero h1 em,
.copy h2 em,
.anatomy-head h2 em,
.practice-head h2 em,
.installs-head h2 em {
  font-family: var(--display-em);
  font-style: italic;
  font-weight: 400;
  color: var(--coral);
}

/* ========= BACKGROUND GRAIN (home only) ========= */
body.home {
  position: relative;
  isolation: isolate;
}

body.home::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 1;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 .17 0 0 0 0 .11 0 0 0 0 .09 0 0 0 .3 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  opacity: 0.32;
  mix-blend-mode: multiply;
}

/* ========= NAV ========= */
.nav {
  padding: 26px 32px 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  max-width: var(--max-width);
  margin: 0 auto;
  position: relative;
  z-index: 3;
  gap: 20px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
}

/* Reason: the global a:hover turns link text coral; the wordmark should not
   change color on hover. */
.brand:hover {
  color: var(--fg);
}

.brand img {
  width: 42px;
  height: 42px;
}

.brand span {
  font: 400 1.6rem/1 var(--display);
  letter-spacing: -0.02em;
}

/* ========= HERO ========= */
.hero {
  padding: 80px 32px 72px;
  max-width: var(--max-width);
  margin: 0 auto;
  text-align: center;
  position: relative;
  z-index: 2;
}

.hero h1 {
  font: 400 clamp(2.6rem, 7.4vw, 5.4rem) / 1.16 var(--display);
  letter-spacing: -0.02em;
  margin: 0 auto 34px;
}

.cta-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 20px;
  flex-wrap: wrap;
}

/* ========= PRIMARY CTA ========= */
.openapp {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  background: var(--coral);
  color: #fff;
  padding: 14px 26px;
  border-radius: 999px;
  font-weight: 600;
  font-size: 0.98rem;
  letter-spacing: 0.01em;
  text-decoration: none;
  transition:
    transform 0.18s,
    background 0.18s;
}

/* Reason: the global a:hover rule outranks .openapp and would turn the
   label coral-on-coral; restate the color at higher specificity. */
.openapp:hover {
  transform: translateY(-2px);
  background: var(--coral-deep);
  color: #fff;
}

.openapp span {
  transition: transform 0.18s;
}

.openapp:hover span {
  transform: translateX(3px);
}

/* ========= ICON SPRITE ========= */
/* Holds the <symbol> definitions only; every visible mark is a <use> of one. */
.sprite {
  display: none;
}

/* ========= AVAILABILITY LINE (evidence, not entrances) ========= */
.where {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 28px;
}

.where-label {
  font: 600 0.68rem/1 var(--body);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0.42;
}

.where-pill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font: 500 0.84rem/1 var(--body);
  opacity: 0.72;
}

.where-pill svg {
  width: 16px;
  height: 16px;
  flex: none;
  color: var(--coral-deep);
  opacity: 0.85;
}

.where-pill + .where-pill {
  margin-left: 6px;
}

/* ========= NAME STRIP (異能, one quiet line) ========= */
.namestrip {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 30px 32px;
  border-top: 1px solid var(--rule);
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  flex-wrap: wrap;
  font-size: 0.95rem;
  opacity: 0.75;
  text-align: center;
}

.namestrip-kanji {
  font:
    400 1.5rem/1 'Noto Serif JP',
    serif;
  letter-spacing: 0.06em;
  color: var(--coral);
  opacity: 1;
  flex: none;
}

.namestrip-sep {
  width: 1px;
  height: 22px;
  background: var(--rule);
  flex: none;
}

.namestrip b {
  font-weight: 600;
  opacity: 1;
}

/* ========= SECTIONS ========= */
.section {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 60px 32px;
  position: relative;
  z-index: 2;
}

.section.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 80px;
  align-items: center;
}

.copy {
  max-width: 470px;
}

.kicker {
  font: 600 0.78rem/1 var(--body);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--coral-deep);
  margin-bottom: 16px;
}

.copy h2 {
  font: 400 clamp(2rem, 3.6vw, 2.8rem) / 1.08 var(--display);
  letter-spacing: -0.02em;
  margin-bottom: 20px;
}

.copy > p {
  font-size: 1.08rem;
  line-height: 1.6;
  opacity: 0.78;
  text-wrap: pretty;
}

/* ========= RAYCAST SHOT ========= */
.platforms {
  position: relative;
}

.platform-mac > img,
.platform-mac > .shot-clip {
  border-radius: 16px;
  box-shadow: 0 26px 60px rgba(43, 29, 22, 0.2);
  width: 100%;
}

/* ========= ANNOTATED CARD SPECIMEN (Anatomy) ========= */
.anatomy {
  text-align: center;
}

.anatomy-head {
  max-width: 600px;
  margin: 0 auto 64px;
}

.anatomy-head h2 {
  font: 400 clamp(2rem, 3.8vw, 2.9rem) / 1.08 var(--display);
  letter-spacing: -0.02em;
}

.anatomy-head p {
  margin-top: 16px;
  font-size: 1.08rem;
  line-height: 1.6;
  opacity: 0.78;
}

.specimen {
  position: relative;
  width: min(340px, 100%);
  margin: 0 auto;
  border-radius: 20px;
  overflow: visible;
  filter: drop-shadow(0 26px 50px rgba(43, 29, 22, 0.16));
}

.specimen img {
  border-radius: 20px;
  width: 100%;
}

.tag {
  position: absolute;
  font-size: 0.82rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  white-space: nowrap;
  opacity: 0.72;
  display: flex;
  align-items: center;
  gap: 10px;
}

.tag span {
  position: relative;
}

.tag::before {
  content: '';
  height: 1px;
  width: 46px;
  background: var(--coral);
  opacity: 0.55;
  flex: none;
}

.tag::after {
  content: '';
  position: absolute;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--coral);
  top: 50%;
  margin-top: -3px;
}

/* right-side tags */
.tag-audio,
.tag-pic {
  left: 100%;
  margin-left: 14px;
}

.tag-audio::after,
.tag-pic::after {
  left: -3px;
}

.tag-audio {
  top: 8%;
}

.tag-pic {
  top: 54%;
}

/* left-side tags */
.tag-def,
.tag-ex {
  right: 100%;
  margin-right: 14px;
  flex-direction: row-reverse;
}

.tag-def::after,
.tag-ex::after {
  right: -3px;
}

.tag-def {
  top: 21%;
}

.tag-ex {
  top: 86%;
}

/* ========= PRACTICE: alternating screenshot / explainer rows ========= */
.practice-head {
  text-align: center;
  max-width: 760px;
  margin: 0 auto 76px;
}

.practice-head h2 {
  font: 400 clamp(2.1rem, 4.4vw, 3.4rem) / 1.14 var(--display);
  letter-spacing: -0.02em;
}

.practice-head h2 span {
  display: block;
}

.prow {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1fr);
  gap: 78px;
  align-items: center;
  max-width: 1080px;
  margin: 0 auto;
}

.prow + .prow {
  margin-top: 104px;
  padding-top: 104px;
  border-top: 1px solid var(--rule);
}

.prow-flip .prow-shot {
  order: 2;
}

.prow-shot {
  display: flex;
  justify-content: center;
}

/* App screen panel (platform-neutral, no device bezel) */
.app-shot {
  width: min(300px, 100%);
  border-radius: 22px;
  overflow: hidden;
  border: 1px solid var(--rule);
  box-shadow: 0 26px 55px rgba(43, 29, 22, 0.16);
  background: #eef1f5;
  transition: transform 0.35s ease;
}

.app-shot img,
.app-shot .shot-clip {
  width: 100%;
  display: block;
}

.app-shot:hover {
  transform: translateY(-4px);
}

.prow-copy {
  max-width: 470px;
}

.prow-tag {
  display: inline-block;
  font: 600 0.74rem/1 var(--body);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--coral-deep);
  background: var(--coral-wash);
  padding: 8px 13px;
  border-radius: 999px;
  margin-bottom: 20px;
}

.prow-copy h3 {
  font: 400 clamp(1.55rem, 2.6vw, 2.1rem) / 1.2 var(--display);
  letter-spacing: -0.015em;
  margin-bottom: 16px;
  text-wrap: pretty;
}

.prow-copy > p {
  font-size: 1.04rem;
  line-height: 1.65;
  opacity: 0.75;
  text-wrap: pretty;
}

/* Widening-interval schedule: each step fades as the gap grows */
.schedule {
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  margin-top: 34px;
  padding-bottom: 2px;
}

.sch-line {
  position: absolute;
  left: 5px;
  right: 5px;
  bottom: 9px;
  height: 2px;
  background: linear-gradient(90deg, var(--coral) 0%, rgba(238, 106, 76, 0.22) 100%);
  border-radius: 2px;
}

.sch-step {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 11px;
  flex: 1;
}

.sch-step i {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--bg);
  border: 2.5px solid var(--coral);
  order: 2;
  opacity: calc(1 - var(--i) * 0.13);
}

.sch-step b {
  font: 600 0.84rem/1 var(--body);
  letter-spacing: 0.02em;
  opacity: calc(0.85 - var(--i) * 0.1);
}

/* ========= OBSIDIAN NOTE MOCK (dark theme, matching the real plugin) ========= */
.note-mock {
  width: min(470px, 100%);
  background: #1e212b;
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 14px;
  overflow: hidden;
  box-shadow: 0 28px 60px rgba(43, 29, 22, 0.3);
  text-align: left;
}

.note-bar {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 11px 15px;
  background: #15171f;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}

.note-lights {
  display: flex;
  gap: 6px;
}

.note-lights i {
  width: 10px;
  height: 10px;
  border-radius: 50%;
}

.note-lights i:nth-child(1) {
  background: #ff5f57;
}

.note-lights i:nth-child(2) {
  background: #febc2e;
}

.note-lights i:nth-child(3) {
  background: #28c840;
}

.note-tab {
  font: 500 0.8rem/1 var(--body);
  color: #f8737f;
  letter-spacing: 0.01em;
}

.note-body {
  position: relative;
  padding: 22px 24px 30px;
}

.note-body h4 {
  font: 700 1.35rem/1.2 var(--body);
  color: #f8737f;
  letter-spacing: -0.01em;
  margin-bottom: 14px;
}

.note-body p {
  font-size: 0.94rem;
  line-height: 1.72;
  color: #b6bdd2;
  text-wrap: pretty;
}

.deckword {
  position: relative;
  color: #c8cfe4;
  text-decoration: none;
  box-shadow: inset 0 -2px 0 #4cc46a;
  padding-bottom: 1px;
}

.note-cursor {
  position: absolute;
  left: 58%;
  top: 78%;
  width: 12px;
  height: 17px;
  pointer-events: none;
  filter: drop-shadow(0 3px 7px rgba(0, 0, 0, 0.55));
}

.note-cursor path {
  fill: #fff;
  stroke: #12141b;
  stroke-width: 1;
}

.note-tip {
  position: absolute;
  right: 14px;
  bottom: 22px;
  width: 270px;
  background: #12141b;
  border: 1px solid rgba(255, 255, 255, 0.72);
  border-radius: 13px;
  padding: 14px 15px;
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.45);
}

.note-tip-top {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 7px;
  flex-wrap: wrap;
}

.note-tip-top b {
  font: 700 0.96rem/1 var(--body);
  color: #fff;
}

.note-audio {
  color: #c8cfe4;
  display: flex;
  flex: none;
}

.note-audio svg {
  width: 15px;
  height: 15px;
}

.note-phon {
  font: 400 0.82rem/1 var(--body);
  color: #b6bdd2;
}

/* Reason: doubled class specificity so these beat the .note-body p defaults */
.note-body .note-def {
  font-size: 0.88rem;
  line-height: 1.5;
  color: #c8cfe4;
  margin-bottom: 4px;
}

.note-body .note-ex {
  font-size: 0.86rem;
  line-height: 1.5;
  font-style: italic;
  color: #b6bdd2;
  margin-bottom: 9px;
}

.note-body .note-state {
  font-size: 0.8rem;
  line-height: 1.4;
  color: #767f95;
}

/* ========= PRICING ========= */
.pricing {
  text-align: center;
}

.pricing .kicker {
  margin-bottom: 12px;
}

.pricing-title {
  font: 400 clamp(2rem, 4vw, 3.2rem) / 1.06 var(--display);
  letter-spacing: -0.02em;
  margin-bottom: 28px;
}

.toggle {
  display: inline-flex;
  background: rgba(43, 29, 22, 0.09);
  border-radius: 999px;
  padding: 5px;
  gap: 4px;
  margin-bottom: 40px;
}

.toggle button {
  padding: 11px 26px;
  border-radius: 999px;
  font-size: 0.95rem;
  font-weight: 600;
  opacity: 0.6;
  transition:
    background 0.2s,
    opacity 0.2s;
}

.toggle button.on {
  background: #fff;
  opacity: 1;
  box-shadow: 0 2px 8px rgba(43, 29, 22, 0.1);
}

.toggle .save {
  color: var(--coral-deep);
  font-size: 0.85rem;
  margin-left: 8px;
  font-weight: 600;
}

.price-wrap {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 340px));
  gap: 24px;
  justify-content: center;
  align-items: stretch;
}

.price {
  position: relative;
  background: rgba(255, 255, 255, 0.6);
  border: 1px solid var(--rule);
  border-radius: 24px;
  padding: 34px;
  display: flex;
  flex-direction: column;
  text-align: left;
}

.price.pro {
  background: var(--fg);
  color: var(--bg);
  border-color: var(--fg);
}

.price h3 {
  font: 400 1.6rem/1 var(--display);
  margin-bottom: 10px;
}

.price .amount {
  font: 400 3rem/1 var(--display);
  letter-spacing: -0.02em;
}

.price .amount small {
  font-size: 1rem;
  opacity: 0.6;
  font-family: var(--body);
  font-weight: 500;
}

.price .sub {
  font-size: 0.95rem;
  opacity: 0.7;
  margin-top: 8px;
  margin-bottom: 26px;
  min-height: 2.6em;
}

/* Reason: the Free plan carries no billing note, so its feature list would sit
   ~80px above the paid plans' lists. Reserve what their two-line note occupies
   so the three columns read across. Reset once the cards stack. */
.price:not(:has(.sub)) .amount {
  margin-bottom: 80px;
}

.price ul li {
  padding: 11px 0;
  border-bottom: 1px solid var(--rule);
  font-size: 0.98rem;
  opacity: 0.88;
  display: flex;
  gap: 11px;
  align-items: baseline;
}

.price.pro ul li {
  border-bottom-color: rgba(255, 255, 255, 0.12);
}

.price ul li:last-child {
  border-bottom: none;
}

.price ul li::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--coral);
  flex: none;
  margin-top: 0.45em;
}

.price ul {
  margin-bottom: 22px;
}

.price-cta {
  display: block;
  /* Reason: the cards stretch to equal height; pushing the CTA down with the
     leftover space keeps all three buttons on one line across the row. */
  margin-top: auto;
  padding: 12px 0;
  border: 1px solid var(--rule);
  border-radius: 999px;
  text-align: center;
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--fg);
  text-decoration: none;
  transition:
    transform 0.18s,
    background 0.18s,
    color 0.18s;
}

/* Reason: the global a:hover rule outranks .price-cta and would turn the
   label coral; restate the color at higher specificity (same as .openapp). */
.price-cta:hover {
  transform: translateY(-2px);
  color: var(--fg);
}

.price.pro .price-cta {
  background: var(--coral);
  border-color: var(--coral);
  color: #fff;
}

.price.pro .price-cta:hover {
  background: var(--coral-deep);
  color: #fff;
}

.badge {
  position: absolute;
  top: -12px;
  right: 20px;
  background: var(--coral);
  color: #fff;
  font: 700 0.7rem/1 var(--body);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 7px 13px;
  border-radius: 999px;
}

.badge[hidden] {
  display: none;
}

/* ========= INSTALL CARDS (after the primary ask) ========= */
.installs {
  text-align: center;
}

.installs-head {
  max-width: 640px;
  margin: 0 auto 44px;
}

.installs-head h2 {
  font: 400 clamp(1.9rem, 3.6vw, 2.7rem) / 1.1 var(--display);
  letter-spacing: -0.02em;
  margin-bottom: 14px;
}

.installs-head p {
  font-size: 1rem;
  opacity: 0.6;
}

.ic-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
  max-width: 1000px;
  margin: 0 auto;
}

.ic {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 7px;
  background: rgba(255, 255, 255, 0.55);
  border: 1px solid var(--rule);
  border-radius: 18px;
  padding: 22px;
  text-decoration: none;
  text-align: left;
  transition:
    border-color 0.18s,
    background 0.18s,
    transform 0.18s,
    box-shadow 0.18s;
}

/* Reason: same as .openapp — the global a:hover rule would recolor the label. */
a.ic:hover {
  border-color: var(--coral);
  background: #fff;
  color: var(--fg);
  transform: translateY(-3px);
  box-shadow: 0 14px 30px rgba(43, 29, 22, 0.1);
}

.ic-icon {
  width: 38px;
  height: 38px;
  border-radius: 11px;
  background: var(--coral-wash);
  color: var(--coral-deep);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  margin-bottom: 4px;
}

.ic-icon svg {
  width: 19px;
  height: 19px;
}

.ic b {
  font-weight: 600;
  font-size: 1.04rem;
}

.ic-foot {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
}

.ic-meta {
  font: 500 0.74rem/1 var(--body);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  opacity: 0.42;
}

.ic-action {
  font: 600 0.86rem/1 var(--body);
  color: var(--coral-deep);
}

.ic-action i {
  font-style: normal;
  display: inline-block;
  transition: transform 0.18s;
}

a.ic:hover .ic-action i {
  transform: translateX(3px);
}

.installs-alt {
  margin-top: 26px;
  font-size: 0.94rem;
  opacity: 0.6;
}

.installs-alt a {
  color: var(--coral-deep);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ========= FINAL ========= */
.final {
  text-align: center;
  padding: 110px 32px 90px;
  max-width: 900px;
  margin: 0 auto;
  position: relative;
  z-index: 2;
}

.final-mark {
  width: 84px;
  margin: 0 auto 30px;
  animation: bob 7s ease-in-out infinite;
}

.final h2 {
  font: 400 clamp(2rem, 4vw, 3rem) / 1.08 var(--display);
  letter-spacing: -0.02em;
  margin-bottom: 30px;
}

@keyframes bob {
  0%,
  100% {
    transform: translateY(0) rotate(0);
  }

  50% {
    transform: translateY(-14px) rotate(-2deg);
  }
}

.footer {
  text-align: center;
  padding: 24px 32px 44px;
  font-size: 0.88rem;
  opacity: 0.6;
  position: relative;
  z-index: 2;
}

.footer-apps {
  margin-bottom: 8px;
}

.footer a {
  text-decoration: none;
}

.footer a:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ========= REVEAL ========= */
.reveal {
  opacity: 0;
  transform: translateY(24px);
  transition:
    opacity 0.8s ease,
    transform 0.8s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.reveal.in {
  opacity: 1;
  transform: translateY(0);
}

/* Staggered child reveals: cards settle in just after their section */
.reveal .price {
  opacity: 0;
  transform: translateY(16px);
  transition:
    opacity 0.6s ease,
    transform 0.6s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.reveal.in .price {
  opacity: 1;
  transform: translateY(0);
}

.reveal.in .price:nth-child(2) {
  transition-delay: 0.15s;
}

/* Anatomy: the card settles first, then each callout draws itself in three
   beats -- dot at the card edge, connector line, label -- one tag at a time. */
.specimen.reveal {
  opacity: 0;
  transform: scale(0.965);
  transition:
    opacity 0.7s ease,
    transform 0.7s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.specimen.reveal.in {
  opacity: 1;
  transform: scale(1);
}

/* One start time per tag; the three beats stagger relative to it. */
.specimen.reveal .tag-def {
  --tag-delay: 0.5s;
}

.specimen.reveal .tag-audio {
  --tag-delay: 0.68s;
}

.specimen.reveal .tag-pic {
  --tag-delay: 0.86s;
}

.specimen.reveal .tag-ex {
  --tag-delay: 1.04s;
}

/* Beat 1: the dot pops onto the card edge. */
.specimen.reveal .tag::after {
  transform: scale(0);
  transition: transform 0.34s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.specimen.reveal.run .tag::after {
  transform: scale(1);
  transition-delay: var(--tag-delay);
}

/* Beat 2: the connector line draws away from the card. */
.specimen.reveal .tag::before {
  transform: scaleX(0);
  transition: transform 0.42s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.specimen.reveal.run .tag::before {
  transform: scaleX(1);
  transition-delay: calc(var(--tag-delay) + 0.12s);
}

.specimen.reveal .tag-audio::before,
.specimen.reveal .tag-pic::before {
  transform-origin: left center;
}

.specimen.reveal .tag-def::before,
.specimen.reveal .tag-ex::before {
  transform-origin: right center;
}

/* Beat 3: the label fades in, drifting outward behind the line. */
.specimen.reveal .tag span {
  opacity: 0;
  transition:
    opacity 0.45s ease,
    transform 0.45s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.specimen.reveal.run .tag span {
  opacity: 1;
  transform: none;
  transition-delay: calc(var(--tag-delay) + 0.22s);
}

.specimen.reveal .tag-audio span,
.specimen.reveal .tag-pic span {
  transform: translateX(-8px);
}

.specimen.reveal .tag-def span,
.specimen.reveal .tag-ex span {
  transform: translateX(8px);
}

/* Reason: a replay has to wind the choreography back in a single frame. Without
   this the removal of .run would transition every staged property backwards,
   and the reader would watch the animation run in reverse before it replays.
   Pseudo-elements are named because the universal selector does not match them. */
.reveal.rewind *,
.reveal.rewind *::before,
.reveal.rewind *::after {
  transition: none !important;
}

/* ========= PRACTICE ROWS =========
   Each row carries its own reveal, so its animation plays when the reader
   reaches that row rather than when the section clears the fold.
   Reason: wrapped in no-preference instead of being undone in the
   reduced-motion block below, because several resting values are per-step
   calc()s that would be lossy to restate. */
@media (prefers-reduced-motion: no-preference) {
  .prow.reveal {
    opacity: 0;
    transform: translateY(18px);
    transition:
      opacity 0.7s ease,
      transform 0.7s cubic-bezier(0.2, 0.8, 0.2, 1);
  }

  .prow.reveal.in {
    opacity: 1;
    transform: none;
  }

  /* Spaced repetition: the interval line draws, then each return lands on it. */
  .prow.reveal .sch-line {
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 0.8s cubic-bezier(0.2, 0.8, 0.2, 1) 0.25s;
  }

  .prow.reveal.run .sch-line {
    transform: scaleX(1);
  }

  .prow.reveal .sch-step i {
    opacity: 0;
    transform: scale(0);
    transition:
      opacity 0.3s ease,
      transform 0.38s cubic-bezier(0.34, 1.56, 0.64, 1);
  }

  .prow.reveal.run .sch-step i {
    opacity: calc(1 - var(--i) * 0.13);
    transform: scale(1);
    transition-delay: calc(0.45s + var(--i) * 0.13s);
  }

  .prow.reveal .sch-step b {
    opacity: 0;
    transform: translateY(6px);
    transition:
      opacity 0.35s ease,
      transform 0.35s cubic-bezier(0.2, 0.8, 0.2, 1);
  }

  .prow.reveal.run .sch-step b {
    opacity: calc(0.85 - var(--i) * 0.1);
    transform: none;
    transition-delay: calc(0.55s + var(--i) * 0.13s);
  }

  /* Contextual recall: the pointer arrives at a deck word, the underline warms
     up, and the card rises out from under it. */
  .prow.reveal .note-cursor {
    opacity: 0;
    transform: translate(-30px, 26px);
    transition:
      opacity 0.3s ease 0.35s,
      transform 0.8s cubic-bezier(0.3, 0.9, 0.25, 1) 0.35s;
  }

  .prow.reveal.run .note-cursor {
    opacity: 1;
    transform: none;
  }

  .prow.reveal .deckword-hot {
    border-radius: 3px;
    transition:
      box-shadow 0.4s ease,
      background-color 0.4s ease;
  }

  .prow.reveal.run .deckword-hot {
    background-color: rgba(76, 196, 106, 0.15);
    box-shadow: inset 0 -2px 0 #6fe08d;
    transition-delay: 1s;
  }

  .prow.reveal .note-tip {
    opacity: 0;
    transform: translateY(12px) scale(0.98);
    transition:
      opacity 0.5s ease,
      transform 0.6s cubic-bezier(0.2, 0.8, 0.2, 1);
  }

  .prow.reveal.run .note-tip {
    opacity: 1;
    transform: none;
    transition-delay: 1.15s;
  }
}

/* ========= POLICY PAGES (container) ========= */
.container {
  max-width: 800px;
  margin: 0 auto;
  padding: 4rem 2rem;
  min-height: 100vh;
}

.container header {
  text-align: center;
  margin-bottom: 3rem;
}

.container h1 {
  font-family: 'DM Serif Display', serif;
  font-size: 3rem;
  font-weight: 400;
  margin-bottom: 0.5rem;
}

.container .subtitle {
  font-size: 1.2rem;
  opacity: 0.6;
  margin-bottom: 0.5rem;
}

.container .date {
  font-size: 0.9rem;
  opacity: 0.4;
}

.container section {
  background: rgba(255, 255, 255, 0.5);
  border-radius: 16px;
  padding: 2rem;
  margin-bottom: 1.5rem;
  border: 1px solid rgba(255, 255, 255, 0.8);
  max-width: none;
}

.container h2 {
  font-family: 'DM Serif Display', serif;
  font-size: 1.5rem;
  font-weight: 400;
  margin-bottom: 0.75rem;
}

.container h3 {
  font-size: 1.1rem;
  font-weight: 600;
  margin-top: 1.25rem;
  margin-bottom: 0.5rem;
}

.container p {
  line-height: 1.7;
  opacity: 0.8;
  margin-bottom: 0.75rem;
}

.container ul {
  list-style-position: inside;
  margin-left: 0.5rem;
}

.container li {
  margin-bottom: 0.5rem;
  line-height: 1.7;
  opacity: 0.8;
}

.container a {
  color: var(--fg);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: rgba(43, 29, 22, 0.3);
  transition: text-decoration-color 0.2s;
}

.container a:hover {
  text-decoration-color: rgba(43, 29, 22, 0.8);
}

.container footer {
  margin-top: 2rem;
  border-top: none;
  text-align: center;
}

.container footer a {
  font-weight: 500;
}

/* ========= RESPONSIVE ========= */
@media (max-width: 980px) {
  .section.split {
    grid-template-columns: 1fr;
    gap: 44px;
  }

  .price-wrap {
    grid-template-columns: 1fr;
    max-width: 420px;
    margin: 0 auto;
  }

  .price:not(:has(.sub)) .amount {
    margin-bottom: 26px;
  }

  .ic-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    max-width: 560px;
  }

  .nav {
    padding: 20px 24px 0;
    flex-wrap: wrap;
    gap: 16px;
  }

  .hero {
    padding: 40px 24px 56px;
  }

  .section,
  .namestrip {
    padding-left: 24px;
    padding-right: 24px;
  }

  .copy {
    max-width: none;
  }

  .prow {
    grid-template-columns: 1fr;
    gap: 44px;
  }

  .prow-flip .prow-shot {
    order: 0;
  }

  .prow + .prow {
    margin-top: 72px;
    padding-top: 72px;
  }

  .prow-copy {
    max-width: none;
  }

  .practice-head {
    margin-bottom: 56px;
  }

  .specimen {
    width: min(300px, 100%);
  }

  .tag {
    font-size: 0.76rem;
    gap: 7px;
  }

  .tag::before {
    width: 24px;
  }

  .tag-audio,
  .tag-pic {
    margin-left: 9px;
  }

  .tag-def,
  .tag-ex {
    margin-right: 9px;
  }

  .anatomy-head {
    margin-bottom: 44px;
  }
}

@media (max-width: 640px) {
  .app-shot {
    width: min(260px, 100%);
  }

  .note-mock {
    width: 100%;
  }

  .note-body {
    padding: 18px 18px 24px;
  }

  .note-tip {
    position: static;
    width: auto;
    margin-top: 16px;
    bottom: auto;
  }

  .schedule {
    margin-top: 28px;
  }

  .sch-step b {
    font-size: 0.78rem;
  }

  .anatomy-head {
    margin-bottom: 40px;
  }

  .namestrip {
    font-size: 0.88rem;
    gap: 12px;
    padding-top: 18px;
    padding-bottom: 18px;
  }

  .namestrip-sep {
    display: none;
  }

  .price {
    padding: 26px 22px;
  }

  .final {
    padding: 80px 24px;
  }

  .container h1 {
    font-size: 2.25rem;
  }

  .container h2 {
    font-size: 1.3rem;
  }

  .container section {
    padding: 1.5rem;
  }
}

/* Reason: below this width there are no margins left to point into, so the
   leader lines become a two-column key under the card rather than vanishing. */
@media (max-width: 680px) {
  .specimen {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px 20px;
    width: min(320px, 100%);
    align-items: start;
  }

  .specimen img {
    grid-column: 1 / -1;
    margin-bottom: 6px;
  }

  .tag {
    position: static;
    margin: 0;
    flex-direction: row;
    gap: 9px;
    font-size: 0.8rem;
  }

  /* The leader line becomes the bullet; the anchor dot has nothing to anchor to. */
  .tag::before {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    opacity: 1;
  }

  .tag::after {
    display: none;
  }

  /* With no anchor dot, the bullet takes the dot's beat: it pops in place
     instead of drawing sideways, and every label drifts the same way. */
  .specimen.reveal .tag::before {
    transform: scale(0);
    transform-origin: center;
    transition: transform 0.34s cubic-bezier(0.34, 1.56, 0.64, 1);
  }

  .specimen.reveal.run .tag::before {
    transform: scale(1);
    transition-delay: var(--tag-delay);
  }

  .specimen.reveal .tag span {
    transform: translateX(-6px);
  }

  /* Stacked as a key, the tags read in DOM order, so they light up that way. */
  .specimen.reveal .tag-ex {
    --tag-delay: 0.68s;
  }

  .specimen.reveal .tag-audio {
    --tag-delay: 0.86s;
  }

  .specimen.reveal .tag-pic {
    --tag-delay: 1.04s;
  }
}

@media (prefers-reduced-motion: reduce) {
  .reveal {
    opacity: 1;
    transform: none;
  }

  .reveal .prow,
  .reveal .price {
    opacity: 1;
    transform: none;
  }

  .specimen.reveal,
  .specimen.reveal .tag span {
    opacity: 1;
    transform: none;
  }

  .specimen.reveal .tag::before,
  .specimen.reveal .tag::after {
    transform: none;
  }

  .final-mark {
    animation: none;
  }
}

/* =========================================================================
   SV DICTIONARY (/sv)
   A dense reference page: poster headline, then one row per term. Scoped
   under .svd so none of it can leak into the landing page.
   ========================================================================= */
.svd {
  --svd-gutter: 48px;
}

.svd .svd-shell {
  max-width: 1440px;
  margin: 0 auto;
}

/* ---------- header ---------- */
.svd-nav {
  display: flex;
  align-items: center;
  padding: 22px var(--svd-gutter) 4px;
}

/* ---------- hero ---------- */
.svd-hero {
  position: relative;
  overflow: hidden;
  border-bottom: 3px solid var(--fg);
  padding: 56px var(--svd-gutter) 0;
  min-height: 632px;
}

.svd-hero-copy {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  gap: 22px;
  max-width: 720px;
}

/* Reason: the headline carries explicit line breaks and is allowed to run
   past the 720px copy column, matching the poster proportions in the design.
   Without nowrap the clamp size wraps "how much valley" onto two lines. */
@media (min-width: 821px) {
  .svd-hero h1 {
    white-space: nowrap;
  }
}

.svd-eyebrow {
  font-weight: 600;
  font-size: 13px;
  line-height: 16px;
  letter-spacing: 0.12em;
  color: var(--svd-label);
}

.svd-hero h1 {
  font-family: var(--svd-poster);
  font-weight: 400;
  font-size: clamp(3.25rem, 7.5vw, 6.75rem);
  line-height: 0.93;
  letter-spacing: 0;
  color: var(--fg);
  text-transform: uppercase;
}

.svd-hero-sub {
  max-width: 560px;
  font-size: 19px;
  line-height: 30px;
  color: var(--svd-body-soft);
}

.svd-hero-cta {
  display: flex;
  align-items: center;
  gap: 22px;
  padding-top: 6px;
}

/* Squared-off variant of .openapp: the poster headline wants a hard edge. */
.svd-btn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 14px 24px;
  border-radius: 8px;
  background: var(--coral);
  color: #fff;
  font-weight: 600;
  font-size: 19px;
  line-height: 24px;
  letter-spacing: 0.01em;
  text-decoration: none;
  transition:
    transform 0.18s,
    background 0.18s;
}

.svd-btn:hover {
  transform: translateY(-2px);
  background: var(--coral-deep);
  color: #fff;
}

/* ---------- hero card stack ---------- */
.svd-hero-art {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 640px;
  height: 600px;
  z-index: 1;
  pointer-events: none;
}

.svd-hero-art img {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 520px;
  height: auto;
}

.svd-cards {
  position: absolute;
  left: 0;
  /* Sits below the headline's second line; the poster type is allowed to run
     past the copy column, so the stack has to start clear of it. */
  top: 164px;
  width: 262px;
  /* Reason: .svd-hero-art turns pointer events off so the illustration cannot
     eat clicks meant for the hero. The stack is the one part of it that is a
     link, so it has to opt back in. */
  pointer-events: auto;
  text-decoration: none;
}

/* Reason: the global a:hover recolours link text, which reached inside and
   turned "burn rate" coral while the card behind it kept its own colour. The
   lift and the shadow carry the hover instead. */
.svd-cards,
.svd-cards:hover {
  color: var(--fg);
}

/* Reason: a focus ring on the anchor would trace the front card's upright box
   and ignore its tilt, so the card wears the ring itself. */
.svd-cards:focus-visible {
  outline: none;
}

.svd-cards:focus-visible .svd-card-front {
  outline: 3px solid var(--coral);
  outline-offset: 6px;
}

.svd-card {
  position: absolute;
  display: flex;
  flex-direction: column;
  width: 262px;
  padding: 22px 20px 20px;
  border: 3px solid var(--fg);
  border-radius: 6px;
  background: var(--svd-card);
}

/* Reason: the tilt uses `rotate` rather than `transform` so the swipe-hint
   keyframes own translate/rotate while hover keeps `scale` to itself. Sharing
   one `transform` between the two means whichever loses the cascade is simply
   dropped. */
.svd-card-front {
  gap: 14px;
  /* Reason: in flow rather than absolute, unlike the card behind it, so the
     link wrapping the stack takes the front card's height. Absolutely
     positioning both leaves the anchor an empty box, which reads as a
     zero-size target to anything measuring the link. */
  position: relative;
  box-shadow: 7px 7px 0 var(--fg);
  rotate: -4deg;
  z-index: 2;
  /* Reason: translate and rotate are here for the way out, not the way in. The
     hint below is dropped the moment the pointer leaves, and without these the
     card would snap upright from wherever the loop had got to. */
  transition:
    translate 0.24s,
    rotate 0.24s,
    scale 0.18s,
    box-shadow 0.18s;
}

/*
 * The card is swipe-to-answer in the app, and nothing on a static page says so.
 * The loop nudges it toward the tick and then toward the cross, the two answers
 * a real swipe picks between.
 */
@keyframes svd-card-swipe {
  0% {
    translate: 0 0;
    rotate: -4deg;
  }
  22% {
    translate: 18px 0;
    rotate: 0deg;
  }
  44% {
    translate: 0 0;
    rotate: -4deg;
  }
  66% {
    translate: -18px 0;
    rotate: -8deg;
  }
  88%,
  100% {
    translate: 0 0;
    rotate: -4deg;
  }
}

/*
 * The hint answers the pointer rather than running on its own: a card that
 * rocks unprompted next to a static headline pulls the eye off the words. It
 * covers focus too, because a keyboard cannot hover.
 */
.svd-cards:hover .svd-card-front,
.svd-cards:focus-visible .svd-card-front {
  scale: 1.03;
  box-shadow: 10px 10px 0 var(--fg);
  animation: svd-card-swipe 2.6s ease-in-out infinite;
}

.svd-card-back {
  gap: 10px;
  top: 64px;
  left: 22px;
  height: 300px;
  justify-content: flex-end;
  border-color: rgba(43, 29, 22, 0.6);
  background: var(--svd-card-back);
  rotate: 5deg;
  z-index: 1;
}

.svd-card-meta {
  font-weight: 600;
  font-size: 12px;
  line-height: 16px;
  letter-spacing: 0.12em;
  color: var(--svd-label);
}

.svd-card-back .svd-card-meta,
.svd-card-back .svd-card-ipa {
  color: #a99a8b;
}

.svd-card-term {
  font-family: var(--display);
  font-size: 40px;
  line-height: 44px;
  letter-spacing: -0.01em;
}

.svd-card-back .svd-card-term {
  color: var(--svd-dim);
}

.svd-card-head {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.svd-card-ipa-row {
  display: flex;
  align-items: center;
  gap: 10px;
}

.svd-card-ipa {
  font-size: 14px;
  line-height: 18px;
  color: var(--svd-label);
}

.svd-card-rule {
  height: 1px;
  background: #dcd3c0;
}

.svd-card-actions {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 28px;
  padding-top: 4px;
}

.svd-swipe {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border: 1.5px solid var(--fg);
  border-radius: 999px;
  background: #fffdf8;
}

.svd-swipe-yes {
  border: 0;
  background: var(--coral);
}

/* ---------- ticker ---------- */
.svd-ticker {
  display: flex;
  overflow: hidden;
  padding: 16px 0;
  background: var(--fg);
  border-bottom: 3px solid var(--fg);
  /* Reason: the strip is decorative; a marquee would fight a screen reader. */
  user-select: none;
}

.svd-ticker-track {
  display: flex;
  flex: none;
  gap: 36px;
  padding-right: 36px;
  white-space: nowrap;
  font-weight: 700;
  font-size: 18px;
  line-height: 22px;
  letter-spacing: 0.1em;
  color: var(--coral);
  animation: svd-marquee 60s linear infinite;
}

@keyframes svd-marquee {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-50%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .svd-ticker-track,
  .svd-cards:hover .svd-card-front,
  .svd-cards:focus-visible .svd-card-front {
    animation: none;
  }
}

/* ---------- controls ---------- */
.svd-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 20px var(--svd-gutter);
  border-bottom: 3px solid var(--fg);
}

.svd-sort {
  display: flex;
  align-items: center;
  gap: 6px;
}

.svd-sort-label {
  padding-right: 12px;
  font-weight: 600;
  font-size: 13px;
  line-height: 16px;
  letter-spacing: 0.06em;
  color: var(--svd-label);
}

.svd-pill {
  padding: 9px 16px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  font-family: inherit;
  font-weight: 600;
  font-size: 13px;
  line-height: 16px;
  letter-spacing: 0.06em;
  color: var(--svd-body-soft);
  cursor: pointer;
}

.svd-pill[aria-pressed='true'] {
  background: var(--fg);
  color: var(--bg);
}

.svd-search {
  width: 220px;
  padding: 9px 16px;
  border: 1px solid var(--fg);
  border-radius: 999px;
  background: transparent;
  font-family: inherit;
  font-weight: 500;
  font-size: 14px;
  line-height: 18px;
  color: var(--fg);
}

.svd-search::placeholder {
  color: var(--fg);
  opacity: 0.55;
}

.svd-search:focus-visible {
  outline: 2px solid var(--coral);
  outline-offset: 2px;
}

.svd-search-field {
  position: relative;
  display: inline-flex;
  align-items: center;
}

/* Room for the chip so a long term never runs underneath it. */
.svd-search-field .svd-search {
  padding-right: 40px;
}

/*
 * The "/" hint. Ships hidden and is shown by script only where a key can
 * actually be pressed, so a phone is never told to press one.
 */
.svd-key {
  position: absolute;
  right: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border: 1px solid var(--svd-rule);
  border-radius: 6px;
  background: transparent;
  font-family: inherit;
  font-weight: 600;
  font-size: 12px;
  line-height: 16px;
  color: var(--svd-label);
  pointer-events: none;
  transition: opacity 0.15s;
}

/* Reason: `display: flex` above outranks the browser's own `[hidden]` rule, so
   without this the chip shows on a phone despite shipping hidden. */
.svd-key[hidden] {
  display: none;
}

/*
 * Once the field has focus the shortcut has done its job, and a literal "/"
 * sitting in the box while someone types reads like part of the query. It also
 * clears out for a query typed and then left behind, because the browser parks
 * its own clear button in exactly this corner as soon as there is text.
 */
.svd-search:focus + .svd-key,
.svd-search:not(:placeholder-shown) + .svd-key {
  opacity: 0;
}

/* ---------- term list ---------- */
.svd-terms {
  padding: 0 var(--svd-gutter);
  list-style: none;
}

.svd-term {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 28px 0 30px;
  border-bottom: 1px solid var(--svd-rule);
}

.svd-term[hidden] {
  display: none;
}

.svd-term-head {
  display: flex;
  align-items: center;
  gap: 16px;
}

.svd-term-no {
  flex: none;
  width: 44px;
  font-weight: 600;
  font-size: 15px;
  line-height: 38px;
  letter-spacing: 0.06em;
  color: var(--svd-label);
  font-variant-numeric: tabular-nums;
}

.svd-term-word {
  font-family: var(--display);
  font-size: 32px;
  line-height: 38px;
  letter-spacing: -0.01em;
  color: var(--fg);
}

.svd-term-ipa {
  font-size: 14px;
  line-height: 18px;
  color: var(--svd-dim);
}

.svd-say {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--svd-label);
  cursor: pointer;
}

.svd-say:hover {
  color: var(--coral);
}

.svd-say:focus-visible {
  outline: 2px solid var(--coral);
  outline-offset: 2px;
}

.svd-say[data-playing='true'] {
  color: var(--coral);
}

.svd-term-def {
  max-width: 860px;
  padding-left: 60px;
  font-size: 19px;
  line-height: 30px;
  color: var(--svd-body);
}

.svd-term-quote {
  padding-left: 60px;
}

.svd-term-quote q {
  display: inline;
  padding: 0 8px;
  background: var(--svd-quote);
  font-style: italic;
  font-size: 17px;
  line-height: 28px;
  color: var(--fg);
  box-decoration-break: clone;
}

/* ---------- load more ---------- */
.svd-more {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 12px var(--svd-gutter) 72px;
}

/* Reason: an author `display` beats the [hidden] attribute's UA `display: none`,
   so every flex container the script hides needs this restated explicitly. */
.svd-more[hidden] {
  display: none;
}

.svd-more-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 12px 16px;
  border: 1px solid var(--svd-hairline);
  border-radius: 8px;
  background: #fffdf8;
  font-family: inherit;
  font-weight: 600;
  font-size: 16px;
  line-height: 20px;
  color: var(--fg);
  cursor: pointer;
}

.svd-more-btn:hover {
  border-color: var(--fg);
}

.svd-more-count {
  font-size: 13px;
  line-height: 18px;
  color: var(--svd-dim);
}

.svd-empty {
  padding: 48px 0 72px;
  text-align: center;
  font-size: 17px;
  color: var(--svd-body-soft);
}

/* ---------- mobile ---------- */
@media (max-width: 820px) {
  .svd {
    --svd-gutter: 20px;
  }

  .svd-hero {
    min-height: 0;
    padding-top: 20px;
  }

  .svd-hero-copy {
    max-width: none;
    gap: 16px;
  }

  .svd-eyebrow {
    font-size: 12px;
  }

  .svd-hero-sub {
    max-width: none;
    font-size: 16px;
    line-height: 25px;
  }

  /* The art stops being a background and becomes a block in the flow, so the
     card stack can sit over it without the two overlapping the headline. */
  .svd-hero {
    display: flex;
    flex-direction: column;
  }

  .svd-hero-copy {
    order: 1;
  }

  .svd-hero-art {
    order: 2;
    position: relative;
    width: auto;
    height: 372px;
    margin: 4px -20px 0;
  }

  .svd-hero-cta {
    order: 3;
  }

  .svd-hero-art img {
    right: -70px;
    width: 260px;
  }

  .svd-cards {
    left: 20px;
    top: 8px;
    width: 240px;
  }

  .svd-card {
    width: 240px;
    padding: 20px 18px 18px;
  }

  .svd-card-front {
    box-shadow: 6px 6px 0 var(--fg);
  }

  .svd-card-back {
    top: 52px;
    left: 14px;
    height: 264px;
  }

  .svd-card-term {
    font-size: 34px;
    line-height: 38px;
  }

  .svd-card-meta {
    font-size: 11px;
    line-height: 14px;
  }

  .svd-card-ipa {
    font-size: 13px;
    line-height: 16px;
  }

  .svd-swipe {
    width: 42px;
    height: 42px;
  }

  .svd-hero-cta {
    padding-bottom: 28px;
  }

  .svd-btn {
    justify-content: center;
    width: 100%;
    font-size: 17px;
    line-height: 22px;
  }

  .svd-ticker-track {
    gap: 24px;
    padding-right: 24px;
    font-size: 14px;
    line-height: 18px;
  }

  .svd-controls {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
  }

  .svd-search-field,
  .svd-search {
    width: 100%;
  }

  /* Number and word stack: at 390px a single row would truncate the term. */
  .svd-term {
    padding: 22px 0 24px;
    gap: 8px;
  }

  .svd-term-head {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 8px;
  }

  .svd-term-no {
    width: auto;
    font-size: 12px;
    line-height: 16px;
  }

  .svd-term-word {
    grid-column: 1;
    grid-row: 2;
    font-size: 28px;
    line-height: 34px;
  }

  .svd-say {
    grid-column: 2;
    grid-row: 2;
    align-self: center;
  }

  .svd-term-ipa {
    grid-column: 1 / -1;
    grid-row: 3;
    font-size: 13px;
    line-height: 16px;
  }

  .svd-term-def,
  .svd-term-quote {
    padding-left: 0;
    font-size: 16px;
    line-height: 25px;
  }

  .svd-term-quote q {
    font-size: 15px;
    line-height: 24px;
  }
}
