:root {
  color-scheme: light;
  --bg: #f4f0e8;
  --paper: #fffdf7;
  --paper-2: #f9f4eb;
  --ink: #23211f;
  --body: #5b564e;
  --muted: #726a5d;
  --line: rgba(36, 33, 31, 0.14);
  --line-strong: rgba(36, 33, 31, 0.24);
  --accent: #764239;
  --accent-dark: #57312d;
  --sage: #5f7165;
  --blue: #3f5867;
  --gold: #caa765;
  --danger: #a54848;
  --radius: 8px;
  --shadow: 0 28px 90px rgba(56, 44, 29, 0.16);
  font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  min-height: 100vh; min-height: 100dvh;
  background:
    radial-gradient(circle at 78% 7%, rgba(172, 146, 102, 0.12), transparent 22rem),
    linear-gradient(180deg, #fffdf7 0, #f4f0e8 760px),
    var(--bg);
  color: var(--ink);
}

button,
input,
textarea,
select {
  font: inherit;
}

button {
  cursor: pointer;
}

button:disabled {
  cursor: not-allowed;
  opacity: 0.52;
}

button:focus-visible,
a:focus-visible,
input:focus-visible,
textarea:focus-visible {
  outline: 3px solid rgba(127, 73, 63, 0.24);
  outline-offset: 3px;
}

.shell {
  min-height: 100vh; min-height: 100dvh;
}

.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  min-height: 84px;
  padding: 0 clamp(1rem, 4vw, 4rem);
  border-bottom: 1px solid rgba(36, 33, 31, 0.1);
  background: rgba(255, 253, 247, 0.93);
  -webkit-backdrop-filter: blur(18px);
  backdrop-filter: blur(18px);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.85rem;
  min-width: max-content;
  border: 0;
  padding: 0;
  background: transparent;
  color: var(--ink);
}

.brand-mark {
  display: grid;
  place-items: center;
  width: 2.65rem;
  height: 2.65rem;
  border: 1px solid rgba(118, 66, 57, 0.28);
  border-radius: 6px;
  background: #f1e7da;
  color: var(--accent-dark);
  font-size: 0.78rem;
  font-weight: 850;
  letter-spacing: 0.06em;
}

.brand-name {
  color: var(--ink);
  font-family: Georgia, "Times New Roman", serif;
  font-size: 1.12rem;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
}

.nav {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 1.1rem;
}

.nav a,
.nav button:not(.primary-btn) {
  min-height: auto;
  border: 0;
  padding: 0.3rem 0;
  background: transparent;
  color: var(--body);
  font-size: 0.92rem;
  font-weight: 650;
  text-decoration: none;
}

.nav a:hover,
.nav button:not(.primary-btn):hover,
.nav button.active {
  color: var(--ink);
}

.primary-btn,
.ghost-btn,
.quiet-btn,
.danger-btn {
  min-height: 2.75rem;
  border-radius: 6px;
  border: 1px solid var(--line);
  padding: 0.75rem 1.05rem;
  font-weight: 760;
  letter-spacing: 0;
  transition: 140ms ease;
}

.primary-btn {
  border-color: var(--accent);
  background: var(--accent);
  color: #fffdf8;
  box-shadow: 0 12px 24px rgba(127, 73, 63, 0.18);
}

.primary-btn:hover {
  border-color: var(--accent-dark);
  background: var(--accent-dark);
}

.ghost-btn,
.quiet-btn {
  background: var(--paper);
  color: var(--ink);
}

.ghost-btn:hover,
.quiet-btn:hover {
  border-color: var(--line-strong);
  background: #f4eee4;
}

.compact {
  min-height: 2.55rem;
  padding: 0.65rem 0.95rem;
}

.website-main,
.main {
  width: min(1240px, calc(100% - 2rem));
  margin: 0 auto;
}

.main {
  padding: 3rem 0 4rem;
}

.site-hero {
  display: grid;
  grid-template-columns: minmax(0, 1.18fr) minmax(340px, 0.82fr);
  gap: clamp(2rem, 4.8vw, 5rem);
  align-items: center;
  min-height: calc(100vh - 84px); min-height: calc(100dvh - 84px);
  padding: clamp(2.2rem, 5vw, 4.8rem) 0 clamp(2.5rem, 5vw, 4rem);
}

.eyebrow {
  margin: 0 0 0.85rem;
  color: var(--accent);
  font-size: 0.72rem;
  font-weight: 850;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

h1,
h2,
h3,
.page-title,
.section-title,
.modal-title {
  margin: 0;
  color: var(--ink);
  font-family: Georgia, "Times New Roman", serif;
  font-weight: 500;
  letter-spacing: 0;
}

.hero-copy-block h1 {
  max-width: 560px;
  font-size: clamp(2.9rem, 4.1vw, 4.55rem);
  line-height: 1.01;
}

.hero-copy {
  max-width: 560px;
  margin: 1.25rem 0 0;
  color: var(--body);
  font-size: clamp(1.07rem, 1.45vw, 1.18rem);
  line-height: 1.72;
}

.studio-note {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.85rem;
  max-width: 520px;
  margin-top: 2rem;
  padding-top: 1.05rem;
  border-top: 1px solid var(--line);
}

.studio-note span {
  color: var(--accent);
  font-size: 0.74rem;
  font-weight: 850;
  letter-spacing: 0.16em;
}

.studio-note p {
  margin: 0;
  color: var(--body);
  line-height: 1.56;
}

.hero-actions,
.row-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.85rem;
  margin-top: 1.6rem;
}

.text-link {
  color: var(--accent-dark);
  font-weight: 800;
  text-decoration: none;
  border-bottom: 1px solid rgba(127, 73, 63, 0.34);
}

.text-link:hover {
  border-bottom-color: var(--accent-dark);
}

.service-points span,
.badge,
.chip,
.segment,
.form-status span,
.form-status-step {
  display: inline-flex;
  align-items: center;
  min-height: 2rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0.42rem 0.68rem;
  background: rgba(255, 253, 248, 0.74);
  color: var(--body);
  font-size: 0.85rem;
  font-weight: 650;
}

/* Step indicator chips at the top of the form panel are now buttons so
   the user can click any prior step to jump back. State-driven look:
   active (current), completed (past), reachable (future-unlocked),
   locked (not yet unlocked). */
.form-status-step {
  cursor: pointer;
  transition: background-color 0.18s ease, border-color 0.18s ease, color 0.18s ease;
  font-family: inherit;
  line-height: 1;
}

.form-status-step.completed {
  background: rgba(96, 115, 101, 0.08);
  border-color: rgba(96, 115, 101, 0.28);
  color: #2d3d2f;
}

.form-status-step.completed:hover,
.form-status-step.reachable:hover {
  border-color: rgba(96, 115, 101, 0.4);
  background: #f3f7f3;
  color: #405846;
}

.form-status-step.locked,
.form-status-step:disabled:not(.active) {
  cursor: not-allowed;
  opacity: 0.5;
}

.form-status-step.active:disabled {
  cursor: default;
}

.film-artboard {
  position: relative;
  display: grid;
  gap: 0.9rem;
}

.artboard-meta {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  color: var(--body);
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.artboard-meta span {
  color: var(--muted);
}

.artboard-meta strong {
  color: var(--ink);
}

.cinema-still {
  position: relative;
  overflow: hidden;
  min-height: clamp(500px, 54vw, 690px);
  border: 1px solid rgba(255, 253, 247, 0.4);
  border-radius: 1px;
  background:
    linear-gradient(180deg, rgba(17, 16, 15, 0.02) 18%, rgba(17, 16, 15, 0.5) 62%, rgba(17, 16, 15, 0.86)),
    radial-gradient(circle at 50% 30%, rgba(242, 213, 174, 0.86), rgba(129, 86, 59, 0.4) 30%, rgba(31, 29, 27, 0.96) 72%),
    linear-gradient(135deg, #4d6671, #2d2a25 56%, #11100f);
  box-shadow:
    0 36px 100px rgba(56, 44, 29, 0.18),
    inset 0 0 0 1px rgba(255, 255, 255, 0.08);
}

.cinema-still::before,
.cinema-still::after {
  content: "";
  position: absolute;
  pointer-events: none;
  z-index: 1;
}

.cinema-still::before {
  inset: 0;
  background:
    linear-gradient(90deg, rgba(255,255,255,.08), transparent 12%, transparent 88%, rgba(255,255,255,.06)),
    radial-gradient(ellipse at center, transparent 42%, rgba(0,0,0,.28) 100%);
  mix-blend-mode: screen;
  opacity: 0.7;
}

.cinema-still::after {
  inset: 1rem;
  border: 1px solid rgba(255, 253, 247, 0.12);
}

.film-grain {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.34;
  background-image:
    radial-gradient(circle at 20% 30%, rgba(255,255,255,.16) 0 1px, transparent 1px),
    radial-gradient(circle at 80% 70%, rgba(255,255,255,.12) 0 1px, transparent 1px);
  background-size: 7px 7px, 11px 11px;
  mix-blend-mode: overlay;
}

.hero-portrait-still {
  position: absolute;
  left: 50%;
  top: 10%;
  width: min(35vw, 305px);
  min-width: 210px;
  aspect-ratio: 4 / 5.25;
  transform: translateX(-50%);
  border: 10px solid rgba(255, 253, 247, 0.9);
  border-bottom-width: 22px;
  background:
    linear-gradient(180deg, transparent 49%, rgba(44, 30, 24, 0.45)),
    radial-gradient(circle at 50% 30%, #efcfaa 0 15%, #7b5140 16% 28%, transparent 29%),
    radial-gradient(ellipse at 50% 63%, #50372f 0 29%, transparent 30%),
    linear-gradient(145deg, #d4d5c9, #6c8177 54%, #2b3535);
  box-shadow:
    0 30px 75px rgba(0, 0, 0, 0.42),
    0 0 0 1px rgba(0,0,0,.08);
}

.memory-print {
  position: absolute;
  width: min(16vw, 150px);
  min-width: 92px;
  aspect-ratio: 4 / 3.2;
  border: 7px solid rgba(255, 253, 247, 0.9);
  border-bottom-width: 13px;
  background: #bfa36f;
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.34);
}

.print-one {
  top: 15%;
  left: 6%;
  transform: rotate(-3deg);
  background:
    radial-gradient(circle at 34% 34%, #e2c18d 0 14%, transparent 15%),
    linear-gradient(135deg, #8ca08f, #263a38);
}

.print-two {
  top: 20%;
  right: 6%;
  transform: rotate(2deg);
  background:
    radial-gradient(circle at 63% 32%, #ead1a7 0 12%, transparent 13%),
    linear-gradient(135deg, #c2a76f, #5f4134);
}

.print-three {
  right: 14%;
  bottom: 23%;
  transform: rotate(-1deg);
  background:
    radial-gradient(circle at 42% 36%, #dfb78e 0 13%, transparent 14%),
    linear-gradient(135deg, #b77768, #344e5c);
}

.still-caption {
  position: absolute;
  left: clamp(1.2rem, 4vw, 2.5rem);
  bottom: clamp(1.2rem, 4vw, 2.5rem);
  z-index: 3;
  max-width: 34rem;
}

.still-caption small {
  display: block;
  margin-bottom: 0.45rem;
  color: rgba(255, 253, 247, 0.66);
  font-size: 0.72rem;
  font-weight: 850;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.still-caption b {
  display: block;
  color: #fffdf7;
  font-family: Georgia, "Times New Roman", serif;
  font-size: clamp(2.4rem, 4.2vw, 4.7rem);
  font-weight: 500;
  line-height: 0.96;
  text-shadow: 0 12px 36px rgba(0,0,0,.42);
}

.film-caption-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  border-top: 0;
  background: transparent;
}

.film-caption-row span {
  padding: 0.8rem 0;
  border-bottom: 1px solid var(--line);
  background: transparent;
  color: var(--body);
  font-size: 0.78rem;
  font-weight: 750;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.stage-photo {
  position: absolute;
  width: clamp(5.2rem, 9.5vw, 7.8rem);
  height: clamp(4.4rem, 7.6vw, 6.25rem);
  border: 0.32rem solid rgba(255, 253, 248, 0.9);
  border-radius: 3px;
  box-shadow: 0 14px 38px rgba(0, 0, 0, 0.32);
}

.photo-a {
  left: 7%;
  top: 18%;
  background: linear-gradient(135deg, #9aa990, #2d3f3c);
}

.photo-b {
  right: 8%;
  top: 25%;
  background: linear-gradient(135deg, #c7ab71, #614131);
}

.photo-c {
  right: 16%;
  bottom: 23%;
  background: linear-gradient(135deg, #b97869, #344f5d);
}

.proof-bar {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  overflow: hidden;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  background: transparent;
}

.proof-bar span {
  min-height: 7rem;
  padding: 1.1rem 1.2rem;
  border-right: 1px solid var(--line);
  background: transparent;
  color: var(--body);
  font-weight: 500;
  line-height: 1.45;
}

.proof-bar span:last-child {
  border-right: 0;
}

.proof-bar b {
  display: block;
  margin-bottom: 0.35rem;
  color: var(--ink);
  font-family: Georgia, "Times New Roman", serif;
  font-size: 1.35rem;
  font-weight: 500;
  line-height: 1.05;
}

.included-section,
.process-section,
.trust-section,
.final-cta {
  padding: clamp(4.75rem, 9vw, 7.25rem) 0;
  border-top: 1px solid var(--line);
}

.section-intro {
  display: grid;
  grid-template-columns: minmax(0, 0.82fr) minmax(300px, 0.68fr);
  gap: 2rem;
  align-items: end;
  margin-bottom: 1.75rem;
}

.section-intro.narrow {
  display: block;
  max-width: 760px;
}

.section-intro h2,
.process-section h2,
.trust-section h2,
.final-cta h2 {
  max-width: 780px;
  font-size: clamp(2.2rem, 3.7vw, 4rem);
  line-height: 1.03;
}

.section-intro p:not(.eyebrow),
.trust-copy p,
.final-cta p,
.section-copy {
  margin: 0;
  color: var(--body);
  font-size: 1rem;
  line-height: 1.68;
}

.included-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px;
  overflow: hidden;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  background: transparent;
}

.included-card {
  min-height: 14.5rem;
  padding: 1.25rem;
  border-right: 1px solid var(--line);
  background: transparent;
}

.included-card:last-child {
  border-right: 0;
}

.included-card h3,
.card h3,
.process-row h3 {
  font-size: 1.72rem;
  line-height: 1.1;
}

.included-card p,
.card p,
.chapter p {
  margin: 0.75rem 0 0;
  color: var(--body);
  line-height: 1.58;
}

.process-list {
  margin-top: 1.7rem;
  border-top: 1px solid var(--line);
}

.process-row {
  display: grid;
  grid-template-columns: 4rem minmax(0, 1fr);
  gap: clamp(1rem, 3vw, 3rem);
  padding: 1.4rem 0;
  border-bottom: 1px solid var(--line);
}

.process-row > span,
.step-num {
  display: grid;
  place-items: center;
  width: 2.6rem;
  height: 2.6rem;
  border: 1px solid rgba(96, 115, 101, 0.28);
  border-radius: 50%;
  color: var(--sage);
  font-weight: 850;
}

.process-row p {
  max-width: 760px;
  margin: 0.45rem 0 0;
  color: var(--body);
  line-height: 1.62;
}

.trust-section {
  display: grid;
  grid-template-columns: minmax(0, 0.86fr) minmax(320px, 0.64fr);
  gap: 2rem;
  align-items: start;
}

.trust-copy {
  display: grid;
  gap: 1.2rem;
  justify-items: start;
}

.final-cta {
  margin-bottom: 4rem;
  text-align: center;
}

.final-cta h2,
.final-cta p {
  margin-left: auto;
  margin-right: auto;
}

.final-cta p {
  max-width: 680px;
  margin-top: 1rem;
}

.final-cta .primary-btn {
  margin-top: 1.35rem;
}

.page-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.3rem;
}

.page-title {
  font-size: clamp(2.3rem, 4vw, 3.8rem);
  line-height: 1.03;
}

.page-subtitle {
  max-width: 720px;
  margin: 0.75rem 0 0;
  color: var(--body);
  line-height: 1.65;
}

.wizard,
.lab-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: 1rem;
  align-items: start;
}

.lab-layout {
  grid-template-columns: 290px minmax(0, 1fr) 290px;
}

.form-panel,
.side-panel,
.lab-panel,
.card,
.project-card,
.chapter,
.intake-banner {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: rgba(255, 253, 248, 0.88);
}

.form-panel,
.side-panel,
.lab-panel {
  padding: 1.2rem;
}

.form-status,
.chips,
.segmented {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.tone-card.active {
  border-color: rgba(96, 115, 101, 0.42);
  background: #edf3ec;
  box-shadow: 0 0 0 3px rgba(96, 115, 101, 0.12);
}

.form-status {
  margin-bottom: 1.2rem;
}

.form-status span.active,
.form-status-step.active,
.segment.active,
.chip.active,
.feature-btn.active,
.badge.good {
  border-color: rgba(96, 115, 101, 0.35);
  background: #edf3ec;
  color: #405846;
}

.grid {
  display: grid;
  gap: 1rem;
}

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

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

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

.field {
  display: grid;
  gap: 0.45rem;
  margin-bottom: 1rem;
}

.field label {
  color: var(--ink);
  font-size: 0.88rem;
  font-weight: 780;
}

.field input,
.field textarea,
.field select {
  width: 100%;
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 0.78rem 0.85rem;
  background: var(--paper);
  color: var(--ink);
}

.field textarea {
  min-height: 7.5rem;
  resize: vertical;
}

.intake-banner {
  display: grid;
  gap: 0.25rem;
  margin-bottom: 1rem;
  padding: 1rem;
  background: #f7f2e8;
}

.intake-banner strong {
  color: var(--ink);
}

.intake-banner span {
  color: var(--body);
  line-height: 1.5;
}

.module-stack {
  display: grid;
  gap: 0.85rem;
}

.module-card {
  display: grid;
  grid-template-columns: minmax(240px, 0.72fr) minmax(0, 1fr);
  gap: clamp(1rem, 3vw, 2rem);
  align-items: start;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1rem;
  background: rgba(255, 253, 248, 0.72);
}

.module-card.primary-module {
  border-color: rgba(96, 115, 101, 0.32);
  background: #f4f8f2;
}

.module-kicker {
  display: block;
  margin-bottom: 0.45rem;
  color: var(--accent);
  font-size: 0.7rem;
  font-weight: 850;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.module-card h3 {
  margin: 0;
  font-family: Georgia, "Times New Roman", serif;
  font-size: 1.55rem;
  font-weight: 500;
  line-height: 1.1;
}

.module-card p {
  margin: 0.55rem 0 0;
  color: var(--body);
  line-height: 1.55;
}

.module-card .field {
  margin-bottom: 0;
}

.compact-fields .field {
  margin-bottom: 0;
  min-width: 0;
}

.module-card .compact-fields {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.module-card input[type="datetime-local"] {
  min-width: 0;
  font-size: clamp(0.9rem, 1.4vw, 1rem);
}

@media (max-width: 1180px) {
  .module-card .compact-fields {
    grid-template-columns: 1fr;
  }
}

.dropzone {
  display: grid;
  place-items: center;
  min-height: 13rem;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius);
  padding: 1.2rem;
  background: #fffdf8;
  color: var(--body);
  text-align: center;
  cursor: pointer;
  transition: 140ms ease;
}

.dropzone input {
  display: none;
}

.dropzone strong,
.dropzone span span {
  display: block;
}

.dropzone:hover {
  border-color: var(--accent);
  background: #f8f0e8;
}

.dropzone-content {
  display: grid;
  justify-items: center;
  gap: 0.55rem;
}

.upload-icon {
  display: grid;
  place-items: center;
  width: 2.6rem;
  height: 2.6rem;
  border-radius: 50%;
  background: var(--accent);
  color: #fffdf8;
  font-size: 1.45rem;
  font-weight: 700;
  line-height: 1;
}

.dropzone-content em {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 2.55rem;
  margin-top: 0.35rem;
  border-radius: 6px;
  padding: 0.65rem 1rem;
  background: var(--accent);
  color: #fffdf8;
  font-style: normal;
  font-weight: 800;
}

.dropzone.dragging {
  border-color: var(--accent);
  background: #f8eee8;
}

.thumb-grid,
.chapter-photos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(118px, 1fr));
  gap: 0.75rem;
  margin-top: 1rem;
}

/* Photo upload progress (Photos step). */
.upload-progress {
  margin-top: 0.85rem;
  display: grid;
  gap: 0.4rem;
}
.upload-progress-track {
  height: 8px;
  border-radius: 999px;
  background: rgba(127, 73, 63, 0.14);
  overflow: hidden;
}
.upload-progress-fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--accent, #6b4f2a);
  transition: width 160ms ease;
}
.upload-progress-label {
  margin: 0;
  font-size: 0.82rem;
  color: var(--muted, #8a7f6f);
}

/* Uncertain photos awaiting placement — thumbnail + inline "Set age" control. */
.unassigned-photos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(118px, 1fr));
  gap: 0.9rem;
  margin-top: 1rem;
}
.unassigned-photo {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.4rem;
}
.unassigned-photo img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 8px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
}
.unassigned-photo .badge.badge-edit {
  text-align: center;
  justify-content: center;
}
.unassigned-photo .age-input {
  width: 100%;
  text-align: center;
}

.main-photo-summary {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.9rem;
  text-align: center;
  margin-top: 1rem;
  border: 1px solid rgba(96, 115, 101, 0.32);
  border-radius: var(--radius);
  padding: 1.5rem 1rem;
  background: #f4f8f2;
}

.main-summary-head {
  max-width: 620px;
}

.main-photo-summary:not(:has(img)) {
  background: #f8f0e8;
  border-color: rgba(127, 73, 63, 0.28);
}

.main-photo-summary strong,
.main-photo-summary p {
  display: block;
}

.main-photo-summary strong {
  color: var(--ink);
  font-size: 1rem;
}

.main-photo-summary p {
  margin: 0.25rem 0 0;
  color: var(--body);
  line-height: 1.45;
}

/* Original + cropped previews render at their TRUE aspect (fixed height, natural
   width) so the cropped image shows exactly what the film will use — same top /
   bottom spacing as the full-screen view, not a re-cropped square. Big + centered
   because the main portrait is the star of this step. Scoped selector so it beats
   any generic .main-photo-summary img rule. */
/* Both previews the SAME height (balanced, like the full-screen viewer), sized
   big so the full crop reads clearly. Widths follow each image's true aspect. */
.main-photo-summary .main-summary-preview-img {
  display: block;
  height: clamp(240px, 36vh, 360px);
  width: auto;
  max-width: 30vw;
  border: 1px solid rgba(96, 115, 101, 0.32);
  border-radius: 10px;
}

/* The cropped preview is draggable to reposition the crop. */
.main-summary-preview-img.is-cropped {
  cursor: grab;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
}

/* Full-screen photo viewer. */
.lm-lightbox {
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: rgba(20, 14, 12, 0.88);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 3rem 2rem;
}

.lm-lightbox-body {
  display: flex;
  gap: 1.5rem;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  max-width: 100%;
  max-height: 100%;
}

.lm-lightbox-fig {
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
}

.lm-lightbox-fig img {
  max-width: 42vw;
  max-height: 82vh;
  border-radius: 8px;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
  object-fit: contain;
  background: #000;
}

/* Height-driven with width following the crop's true aspect (object-view-box
   sets the intrinsic ratio), so the full-screen shows EXACTLY the crop — same
   as the Photos-tab preview, with no surrounding background leaking in from a
   mismatched box + object-fit: contain. */
.lm-lightbox-fig img.is-cropped {
  height: 78vh;
  width: auto;
  max-width: none;
  object-fit: fill;
}

.lm-lightbox-fig figcaption {
  color: rgba(255, 255, 255, 0.82);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.lm-lightbox-close {
  position: absolute;
  top: 1.1rem;
  right: 1.4rem;
  width: 2.4rem;
  height: 2.4rem;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.14);
  color: #fff;
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
}

.lm-lightbox-close:hover {
  background: rgba(255, 255, 255, 0.28);
}

/* Original + cropped previews side by side, image tops aligned (crop tiles are
   taller because they carry a Zoom slider underneath). */
.main-summary-previews {
  display: flex;
  gap: 1.25rem;
  align-items: flex-start;
  justify-content: center;
  flex-wrap: wrap;
  max-width: 100%;
}

/* Per-tile Zoom slider sitting directly under each crop preview. */
.pv-zoom-row {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  width: 100%;
  margin-top: 0.15rem;
}

.pv-zoom-label {
  font-size: 0.6rem;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--body);
}

.pv-zoom {
  flex: 1 1 auto;
  min-width: 0;
  accent-color: var(--accent);
  cursor: pointer;
}

/* Per-photo "pick this framing" control, sitting right under each caption so it
   lines up with the photo above it. */
.pv-pick {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.4rem;
  padding: 0.28rem 0.7rem;
  border: 1.5px solid rgba(96, 115, 101, 0.4);
  border-radius: 999px;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--body);
  background: #fff;
  cursor: pointer;
}

.pv-pick input {
  accent-color: var(--accent);
  cursor: pointer;
  margin: 0;
}

.pv-pick.is-picked {
  border-color: var(--accent);
  background: rgba(127, 73, 63, 0.08);
  color: var(--accent);
}

/* Per-tile "Reset this one" link — appears only once that portrait is adjusted. */
.pv-reset {
  margin-top: 0.25rem;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  color: var(--accent);
  text-decoration: underline;
  font: inherit;
  font-size: 0.72rem;
}

/* Plain-language guidance above the framing choice. */
.portrait-help {
  max-width: 560px;
  margin: 0.6rem auto 0.1rem;
  text-align: center;
  font-size: 0.92rem;
  line-height: 1.4;
  color: var(--body);
}

.main-summary-pv {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  margin: 0;
}

.main-summary-pv figcaption {
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--body);
}

/* Selected framing (crop vs original) gets an accent ring + label. */
.main-summary-pv.is-selected .main-summary-preview-img {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(127, 73, 63, 0.28);
}

.main-summary-pv.is-selected figcaption {
  color: var(--accent);
}

.portrait-choice .seg-btn.active {
  background: var(--accent);
  color: #fffdf8;
}

/* "Enhanced later" flag + hint. */
.lm-enhance-flag {
  display: inline-block;
  background: rgba(127, 73, 63, 0.12);
  color: var(--accent);
  font-weight: 800;
  font-size: 0.66rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  padding: 0.1rem 0.4rem;
  border-radius: 999px;
}

.portrait-enhance-hint {
  margin: 0.45rem 0 0;
  font-size: 0.76rem;
  color: var(--body);
  line-height: 1.4;
}

.portrait-original-slide {
  display: flex;
  align-items: flex-start;
  gap: 0.45rem;
  margin: 0.5rem 0 0;
  font-size: 0.82rem;
  color: var(--ink);
  cursor: pointer;
  line-height: 1.35;
}

.portrait-original-slide input {
  margin-top: 0.15rem;
  flex: 0 0 auto;
}

.lm-lightbox-note {
  margin: 0;
  max-width: 42vw;
  text-align: center;
  color: rgba(255, 255, 255, 0.82);
  font-size: 0.8rem;
  line-height: 1.4;
}

.lm-lightbox-note .lm-enhance-flag {
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
}

/* Dev-only re-run row under the main summary. */
.dev-rerun-row {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.5rem;
}

.dev-rerun-row .dev-tag {
  font-size: 0.6rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #fff;
  background: #7f493f;
  border-radius: 4px;
  padding: 0.08rem 0.32rem;
  opacity: 0.7;
}

.portrait-zoom-control .text-link {
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  color: var(--accent);
  text-decoration: underline;
  font: inherit;
  font-size: 0.76rem;
}

.main-photo-summary .photo-fallback {
  width: 104px;
  height: 104px;
}

.upload-thumb,
.chapter-photo,
.source-thumb,
.history-thumb {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: #eee7dc;
}

.upload-thumb {
  aspect-ratio: 1;
  transform-origin: center;
  transition: transform 0.45s ease, box-shadow 0.45s ease, border-color 0.45s ease;
}

/* Set-main hover — combined preview: the tile lifts into a gentle zoom while
   the accent ring a chosen main portrait wears fades in and the badge fills
   clay. The hover intentionally mirrors .is-main-photo so it reads as "click
   and this becomes the opening portrait"; the badge label ("Set main" vs
   "Main portrait") is what keeps a hover distinct from the committed main.
   Slow easing + no bounce to suit the memorial tone. */
.upload-thumb:hover {
  transform: scale(1.02);
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(127, 73, 63, 0.16);
}

.upload-thumb:hover img {
  transform: scale(1.1);
}

.upload-thumb img,
.chapter-photo img,
.source-thumb img,
.history-thumb img,
.lab-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.photo-fallback {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  padding: 0.65rem;
  color: var(--body);
  font-size: 0.78rem;
  font-weight: 750;
  line-height: 1.25;
  text-align: center;
  overflow-wrap: anywhere;
}

.photo-fallback[hidden] {
  display: none !important;
}

.upload-thumb.is-main-photo {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(127, 73, 63, 0.16);
}

.upload-thumb.is-main-photo img {
  display: block;
}

/* Eased zoom target for the set-main hover (clipped by the thumb's
   overflow:hidden, so the photo scales within its frame). */
.upload-thumb img {
  transition: transform 0.5s ease;
}

.upload-thumb img[src=""],
.main-photo-summary img[src=""] {
  display: none;
}

.upload-thumb > button {
  position: absolute;
  top: 0.4rem;
  right: 0.4rem;
  width: 1.75rem;
  height: 1.75rem;
  border: 0;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.62);
  color: white;
}

.main-badge {
  position: absolute;
  left: 0.45rem;
  bottom: 0.45rem;
  border-radius: 999px;
  padding: 0.3rem 0.55rem;
  background: rgba(255, 253, 248, 0.92);
  color: var(--ink);
  font-size: 0.78rem;
  font-weight: 800;
  transition: transform 0.4s ease, background 0.4s ease, color 0.4s ease;
}

.upload-thumb.is-main-photo .main-badge {
  background: var(--accent);
  color: #fffdf8;
}

/* AI-suggested main — a softer, dashed ring than the solid committed-main ring,
   so a suggestion reads as "we picked this for you, change it if you like"
   rather than a locked choice. */
.upload-thumb.is-suggested-main {
  border-color: var(--accent);
  border-style: dashed;
  box-shadow: 0 0 0 3px rgba(127, 73, 63, 0.12);
}

.suggested-tag {
  display: inline-block;
  letter-spacing: 0.01em;
}

.upload-thumb.is-suggested-main .main-badge {
  background: var(--accent);
  color: #fffdf8;
}

/* Hover fills the "Set main" badge clay and lifts it slightly, in step with
   the tile's zoom + ring. */
.upload-thumb:hover .main-badge {
  background: var(--accent);
  color: #fffdf8;
  transform: translateY(-2px);
}

/* Respect reduced-motion: keep the accent-ring/badge state change (it carries
   meaning) but drop all movement. */
@media (prefers-reduced-motion: reduce) {
  .upload-thumb,
  .upload-thumb img,
  .main-badge {
    transition: border-color 0.2s ease, background 0.2s ease, color 0.2s ease;
  }

  .upload-thumb:hover,
  .upload-thumb:hover img,
  .upload-thumb:hover .main-badge {
    transform: none;
  }
}

.badge.badge-edit {
  cursor: pointer;
  border: 1px dashed rgba(127, 73, 63, 0.45);
  background: transparent;
  font: inherit;
  color: inherit;
  padding: 0.25rem 0.55rem;
}

.badge.badge-edit:hover {
  background: rgba(127, 73, 63, 0.08);
  border-color: var(--accent);
}

.age-input {
  width: 5.25rem;
  padding: 0.2rem 0.5rem;
  border-radius: 999px;
  border: 1px solid var(--accent);
  background: #fffdf8;
  font: inherit;
  font-size: 0.85rem;
  outline: none;
}

.age-input:focus {
  box-shadow: 0 0 0 3px rgba(127, 73, 63, 0.18);
}

.restore-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.25rem 0.6rem;
  border-radius: 999px;
  background: rgba(127, 73, 63, 0.08);
  border: 1px solid rgba(127, 73, 63, 0.25);
  font-size: 0.82rem;
  font-weight: 700;
  cursor: pointer;
  user-select: none;
}

.restore-toggle.checked {
  background: rgba(96, 115, 101, 0.15);
  border-color: var(--sage);
  color: #3f4d3a;
}

.restore-toggle input[type="checkbox"] {
  width: 0.95rem;
  height: 0.95rem;
  margin: 0;
  cursor: pointer;
  accent-color: var(--sage);
}

.film-style-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid rgba(127, 73, 63, 0.18);
  margin-bottom: 1.25rem;
}
.composition-subtab.active {
  background: var(--accent);
  color: #fff;
}

.film-style-tab {
  appearance: none;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 999px;
  padding: 0.45rem 1rem;
  font: inherit;
  font-weight: 700;
  font-size: 0.92rem;
  color: var(--muted);
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}

.film-style-tab:hover {
  background: rgba(127, 73, 63, 0.06);
  color: var(--ink);
}

.film-style-tab.active {
  background: var(--accent);
  color: #fffdf8;
  border-color: var(--accent);
}

.film-style-tab.tab-soon {
  color: rgba(127, 73, 63, 0.55);
}

.film-style-tab.tab-soon em {
  font-style: normal;
  margin-left: 0.35rem;
  font-size: 0.7rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  opacity: 0.75;
}

.film-style-body {
  display: grid;
  gap: 1rem;
}

.option-card.active {
  background: rgba(127, 73, 63, 0.1);
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(127, 73, 63, 0.15);
}

.checkbox-list {
  display: grid;
  gap: 0.75rem;
}

.checkbox-row {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.75rem;
  align-items: start;
  padding: 0.85rem 1rem;
  background: #fffdf8;
  border: 1px solid rgba(127, 73, 63, 0.2);
  border-radius: 14px;
  cursor: pointer;
}

.checkbox-row:hover {
  border-color: var(--accent);
}

.checkbox-row input[type="checkbox"] {
  width: 1.1rem;
  height: 1.1rem;
  margin-top: 0.2rem;
  cursor: pointer;
  accent-color: var(--accent);
}

.checkbox-row strong {
  display: block;
  font-size: 1rem;
}

.checkbox-row span {
  display: block;
  margin-top: 0.2rem;
  font-size: 0.85rem;
  color: var(--muted);
  line-height: 1.45;
}

/* ============================================================
   Film Style step — Editorial direction
   Cream background, white inner cards, serif headers, warm brown
   accents. Scoped to .film-style-editorial so nothing leaks out
   to other wizard steps.
   ============================================================ */

.film-style-editorial {
  background: #faf6ea;
  border-radius: 16px;
  padding: 1.5rem 1.5rem 1.25rem;
  color: #2a2218;
  margin: -0.5rem 0 0; /* tucks under the wizard's H1 cleanly */
}

.film-style-editorial .module-card {
  background: #ffffff;
  border: 0.5px solid rgba(60, 40, 20, 0.08);
  border-radius: 12px;
  box-shadow: none;
}

.film-style-editorial .module-card-header h3 {
  font-family: "Cormorant Garamond", "EB Garamond", Georgia, serif;
  font-weight: 500;
  font-size: 1.2rem;
  color: #2a2218;
  letter-spacing: 0.005em;
}

.film-style-editorial .module-hint,
.film-style-editorial .subsection-hint {
  color: #8a7553;
}

.film-style-editorial .module-subsection-header span {
  color: #5a4520;
}

.film-style-editorial .module-subsection-value {
  color: #8a7553;
}

.film-style-editorial .film-style-tabs {
  /* The tab strip blends with the cream surround rather than sitting
     in white-on-white. */
  background: transparent;
}

.film-style-editorial .film-style-tab {
  font-family: "Cormorant Garamond", "EB Garamond", Georgia, serif;
  font-weight: 500;
  font-size: 1.05rem;
  color: rgba(60, 40, 20, 0.55);
}

.film-style-editorial .film-style-tab.active {
  color: #2a2218;
  background: #ffffff;
  border-color: rgba(60, 40, 20, 0.1);
}

/* Compact template rows — replaces the old 2-up word-heavy cards.
   Each row is a horizontal flex: small thumbnail swatch + name &
   tagline + optional Selected eyebrow on the right. */
.template-row-list {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.template-row {
  appearance: none;
  display: flex;
  align-items: center;
  gap: 0.85rem;
  width: 100%;
  padding: 0.7rem 0.85rem;
  background: #ffffff;
  border: 0.5px solid rgba(60, 40, 20, 0.08);
  border-radius: 10px;
  text-align: left;
  cursor: pointer;
  font-family: inherit;
  color: inherit;
  transition: background 140ms ease, border-color 140ms ease;
}

.template-row:hover:not(:disabled) {
  background: rgba(201, 149, 74, 0.04);
  border-color: rgba(60, 40, 20, 0.16);
}

.template-row.is-active {
  background: rgba(201, 149, 74, 0.08);
  border: 1.5px solid #c9954a;
  padding: 0.625rem 0.775rem; /* compensate for thicker border */
}

.template-row.is-soon {
  opacity: 0.55;
  cursor: not-allowed;
}

.template-row-swatch {
  width: 56px;
  height: 38px;
  flex-shrink: 0;
  border-radius: 5px;
  box-shadow: inset 0 0 0 0.5px rgba(0, 0, 0, 0.12);
}

.template-row-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.template-row-title {
  font-family: "Cormorant Garamond", "EB Garamond", Georgia, serif;
  font-weight: 500;
  font-size: 1.05rem;
  color: #2a2218;
  line-height: 1.2;
}

.template-row-tagline {
  font-size: 0.78rem;
  color: #8a7553;
  line-height: 1.35;
}

.template-row-state {
  flex-shrink: 0;
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #6b4b1e;
}

/* (Title card grid override removed — base .backdrop-library-grid is
   now 3-up for both Template's Backdrop library and Opening's title
   card picker.) */

.film-style-layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
  align-items: start;
}

.film-style-layout.with-preview {
  grid-template-columns: minmax(0, 1fr) 340px;
}

@media (max-width: 960px) {
  .film-style-layout.with-preview {
    grid-template-columns: 1fr;
  }
}

.film-style-body {
  display: grid;
  gap: 1rem;
  min-width: 0;
}

.preview-pane {
  position: sticky;
  /* The .topbar above is also sticky with min-height: 84px, so the preview
     needs to sit below it with a small gap. */
  top: calc(84px + 1rem);
  display: grid;
  gap: 0.5rem;
}

@media (max-width: 960px) {
  .preview-pane {
    position: static;
  }
}

.preview-stage {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border-radius: 14px;
  background: var(--stage-bg, #f5ecd5);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
  /* Containment context so children can size in stage-relative units
     (cqi = % of inline / width). Year overlays use this to scale
     consistently between the small preview and the expanded view. */
  container-type: inline-size;
}

/* Video-mode whole-frame cross-fade (managePreviewVideoCycle). Two
   stacked .cycle-frame divs each hold a fully-rendered Path A or Path
   B stage. Inactive frame fades to 0; active fades to 1. */
.cycle-frame {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity var(--transition-duration, 600ms) ease;
  pointer-events: none;
}
.cycle-frame.is-active {
  opacity: 1;
  pointer-events: auto;
}

/* Per-element text-shadow halo overrides. Default behavior (no class)
   is a 3-layer dark halo for legibility on busy backdrops — tuned for
   light/cream text. When the author flips text color to dark
   (charcoal), the dark halo blends into the glyphs and reads as
   blurry; .text-shadow-light replaces the dark halo with an
   inverted-luminance cream halo for that case. .text-shadow-off
   removes the halo entirely. Both Path A (.titlecard-*) and Path B
   (.backdrop-text-*) use the same modifier classes via the floating
   toolbar's Shadow segment, and !important wins over the brightness-
   conditioned base rules. */
.backdrop-text-preamble.text-shadow-off,
.backdrop-text-name.text-shadow-off,
.backdrop-text-dates.text-shadow-off,
.lm-chapter-card-eyebrow.text-shadow-off,
.lm-chapter-card-title.text-shadow-off {
  text-shadow: none !important;
}
/* OFF MEANS THE HALO, NOT EVERY SHADOW (K). On a title card two different
   things write text-shadow: the legibility halo, which is the brightness rule
   further down, and a LOOK'S OWN GLOW, which the renderer writes inline. The
   blanket `none !important` above could not tell them apart, so turning the
   halo off also destroyed the glow the look was designed around — Warm
   Candlelight's warm gold one vanished from every card that had "off" saved.
   The two live in different layers here, so they can be separated: the halo
   rules simply stop matching when this class is present (see :not below), and
   this needs no !important, which leaves the inline glow standing. Path B and
   the chapter cards keep the blunt rule above: their halo is written inline
   too, so nothing weaker could ever turn it off. */
.titlecard-preamble.text-shadow-off,
.titlecard-name.text-shadow-off,
.titlecard-dates.text-shadow-off {
  text-shadow: none;
}
.backdrop-text-preamble.text-shadow-light,
.backdrop-text-name.text-shadow-light,
.backdrop-text-dates.text-shadow-light,
.titlecard-preamble.text-shadow-light,
.titlecard-name.text-shadow-light,
.titlecard-dates.text-shadow-light,
.lm-chapter-card-eyebrow.text-shadow-light,
.lm-chapter-card-title.text-shadow-light {
  text-shadow:
    0 0 0.4cqi rgba(255, 255, 255, calc(0.95 * var(--ts-a, 1))),
    0 0 1.2cqi rgba(255, 255, 255, calc(0.7 * var(--ts-a, 1))),
    0 0 2.2cqi rgba(255, 255, 255, calc(0.4 * var(--ts-a, 1))) !important;
}
/* "Soft" — a gentler dark halo (~half the default opacity) for when the
   default Dark reads too heavy. */
.backdrop-text-preamble.text-shadow-soft,
.backdrop-text-name.text-shadow-soft,
.backdrop-text-dates.text-shadow-soft,
.titlecard-preamble.text-shadow-soft,
.titlecard-name.text-shadow-soft,
.titlecard-dates.text-shadow-soft,
.lm-chapter-card-eyebrow.text-shadow-soft,
.lm-chapter-card-title.text-shadow-soft {
  text-shadow:
    0 0 0.4cqi rgba(0, 0, 0, calc(0.72 * var(--ts-a, 1))),
    0 0 1.2cqi rgba(0, 0, 0, calc(0.5 * var(--ts-a, 1))),
    0 0 2.2cqi rgba(0, 0, 0, calc(0.28 * var(--ts-a, 1))) !important;
}

/* Elements checklist — sidebar panel listing each text/year element
   with a checkbox to show/hide it. Companion to the trash button on
   the floating element toolbar; both write cfg.elementHidden[kind]. */
.backdrop-elements-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.backdrop-element-row {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  padding: 0.55rem 0.7rem;
  border: 1px solid rgba(0, 0, 0, 0.08);
  border-radius: 8px;
  background: #fff;
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.backdrop-element-row:hover {
  background: #fbf8ef;
  border-color: rgba(0, 0, 0, 0.16);
}
.backdrop-element-row input[type="checkbox"] {
  margin-top: 0.18rem;
  flex-shrink: 0;
  accent-color: var(--accent, #6b4226);
}
.backdrop-element-row-text {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  font-size: 0.9rem;
}
.backdrop-element-row-text strong {
  font-weight: 600;
  color: var(--text, #222);
}
.backdrop-element-row-hint {
  font-size: 0.78rem;
  color: var(--muted, #777);
}

/* Trash button on the floating element toolbar — hides the selected
   element on the current photo. Uses a muted-red accent so it reads
   as a destructive action without looking alarming. */
.bft-trash-chip {
  color: #8a2f2f;
}
.bft-trash-chip:hover {
  background: #fbeded;
  color: #6f1f1f;
}

/* Video transport controls — play/pause + restart for the Backdrop
   slideshow. Sits below the preview stage similar to the REVIEW
   chevrons; expanded variant gets larger sizing for the lightbox. */
.preview-video-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  margin: 0.75rem 0 0.25rem;
  user-select: none;
}
.preview-video-btn {
  appearance: none;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px solid rgba(0, 0, 0, 0.12);
  background: #fff;
  color: var(--text, #111);
  font-size: 1.05rem;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s ease, transform 0.1s ease, box-shadow 0.15s ease;
}
.preview-video-btn:hover {
  background: #f7f5ef;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}
.preview-video-btn:active {
  transform: scale(0.96);
}
.preview-video-btn-primary {
  width: 44px;
  height: 44px;
  font-size: 1.2rem;
  background: var(--text, #222);
  color: #fff;
  border-color: transparent;
}
.preview-video-btn-primary:hover {
  background: #000;
}
.preview-video-controls.is-expanded {
  gap: 1rem;
  margin: 1rem 0 0.5rem;
}
.preview-video-controls.is-expanded .preview-video-btn {
  width: 42px;
  height: 42px;
  font-size: 1.15rem;
}
.preview-video-controls.is-expanded .preview-video-btn-primary {
  width: 52px;
  height: 52px;
  font-size: 1.4rem;
}

.preview-slide {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  /* Default to letterbox behavior so a missing/unexpected framing class
     never falls back to the stretchy CSS default of object-fit: fill. */
  object-fit: contain;
  transition: opacity var(--transition-duration, 600ms) ease;
  display: block;
}

.preview-stage.framing-fullbleed .preview-slide {
  object-fit: cover;
  /* Honor the AI / user face focus point so portrait crops keep the face in frame.
     Default y of 30% biases the crop toward the upper portion of the photo
     so heads stay visible when no focus point is provided. */
  object-position: var(--focus-x, 50%) var(--focus-y, 30%);
}

.preview-slide.active {
  opacity: 1;
}

/* Cross-fade and fade-through-background use the default opacity transition
   driven by --transition-duration. Fade-through-background's sequential
   timing is handled in JS (waits transition + small gap before fading the
   next photo in). Zoom dissolve adds a slow scale to the active slide. */

.preview-stage.transition-zoom-dissolve .preview-slide.active,
.preview-stage.transition-zoom-dissolve .lantern-polaroid.active img {
  animation: preview-zoom var(--hold, 5000ms) linear forwards;
}

/* ---------- Lantern template ---------- */

.preview-stage.template-lantern {
  background: #15110d; /* deep chapel dark, overrides --stage-bg */
}

.lantern-vignette {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(
      ellipse at center,
      rgba(217, 139, 67, 0) 35%,
      rgba(217, 139, 67, 0.08) 60%,
      rgba(217, 139, 67, 0.18) 82%,
      rgba(217, 139, 67, 0.28) 100%
    );
}

.lantern-composition {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: center;
  padding: 6% 5%;
  gap: 3%;
  z-index: 2;
}

.lantern-text {
  display: grid;
  gap: 0.45rem;
  color: #ecd2a0;
  text-align: left;
  font-family: Georgia, "Times New Roman", serif;
}

.lantern-text em {
  font-style: italic;
  font-size: 0.78rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.78;
  font-weight: 400;
}

.lantern-text h2 {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 1.55rem;
  font-weight: 500;
  line-height: 1.15;
  margin: 0;
  color: #f4dca8;
  letter-spacing: 0.01em;
}

.lantern-text span {
  font-style: italic;
  font-size: 0.82rem;
  opacity: 0.88;
  color: #e0c48d;
}

.lantern-photo-area {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.lantern-polaroid {
  position: absolute;
  width: 78%;
  aspect-ratio: 3 / 4;
  background: #f3ead4;
  padding: 5% 5% 14% 5%;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.55), 0 2px 6px rgba(0, 0, 0, 0.4);
  border-radius: 2px;
  opacity: 0;
  transform: rotate(var(--tilt, 0deg));
  transition: opacity var(--transition-duration, 600ms) ease;
  box-sizing: border-box;
}

.lantern-polaroid.active {
  opacity: 1;
}

.lantern-polaroid img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  object-position: var(--focus-x, 50%) var(--focus-y, 30%);
}

/* On very narrow preview panes the text column gets tight, so lean a bit
   smaller. */
@media (max-width: 380px) {
  .lantern-text h2 {
    font-size: 1.2rem;
  }
  .lantern-text em,
  .lantern-text span {
    font-size: 0.72rem;
  }
}

/* ---------- Heritage template ---------- */

.preview-stage.template-heritage {
  /* Layered aged cream paper. Multiple radial blooms add tonal variation
     across the surface so it doesn't read as a flat color field. */
  background:
    /* Warm bloom in upper-left where light might catch */
    radial-gradient(ellipse 60% 50% at 25% 30%, rgba(220, 175, 105, 0.16) 0%, transparent 60%),
    /* Cooler aged stain in lower-right */
    radial-gradient(ellipse 55% 50% at 78% 75%, rgba(110, 70, 25, 0.10) 0%, transparent 55%),
    /* Edge darkening — worn perimeter */
    radial-gradient(ellipse at center, transparent 38%, rgba(80, 45, 15, 0.32) 100%),
    /* Soft directional gradient through the base */
    linear-gradient(125deg, #e6d2a7 0%, #ddc89c 55%, #d4be91 100%);
}

.heritage-grain {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 1;
  mix-blend-mode: multiply;
  /* Two noise layers — finer grain on top of a coarser fiber pattern — give
     the paper a real textile feel rather than uniform speckle. */
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='2.4' numOctaves='1' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.32 0 0 0 0 0.20 0 0 0 0 0.08 0 0 0 0.34 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>"),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='320' height='320'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.38 0 0 0 0 0.26 0 0 0 0 0.10 0 0 0 0.22 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  background-size: 140px 140px, 320px 320px;
}

/* Decorative side flourishes — uses flourish-vertical.png (cropped + rotated
   from the user's source ornament). Positioned in the margin between the
   photo and the stage edge. */
.heritage-flourish {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  height: 84%;
  width: 8%;
  pointer-events: none;
  z-index: 1;
}

.heritage-flourish-left {
  left: 8%;
}

.heritage-flourish-right {
  right: 8%;
}

.heritage-flourish img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  /* Multiply blend mode lets the warm-brown ink "sink" into the cream paper
     and the grain texture, so it reads as drawn on the page rather than
     pasted on top. */
  mix-blend-mode: multiply;
  opacity: 0.92;
}

.heritage-page {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1;
}

/* Slot is sized only to the photo frame. The caption hangs absolutely below.
   Shift the slot up by ~0.65rem so the photo+caption composition sits visually
   centered in the 16:9 stage and the caption never gets clipped at the bottom. */
.heritage-slot {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, calc(-50% - 0.65rem));
  width: 42%;
  opacity: 0;
  transition: opacity var(--transition-duration, 600ms) ease;
}

.heritage-slot.active {
  opacity: 1;
}

.heritage-photo-frame {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
  /* Clip the zoom-dissolve animation to the frame so the corners stay
     anchored at the frame edges instead of being pushed by a scaling img. */
  overflow: hidden;
}

.heritage-photo-frame img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  /* Bias y toward the upper third so heads stay visible when AI focus is
     missing or off. The square crop is aggressive — small y values are safer. */
  object-position: var(--focus-x, 50%) var(--focus-y, 25%);
  /* Heavy sepia processing — this is where Heritage earns its name. */
  filter: sepia(0.7) contrast(0.92) brightness(0.94) saturate(0.7);
  box-shadow: 0 6px 16px rgba(60, 40, 20, 0.45), 0 2px 4px rgba(40, 25, 10, 0.3);
}

/* The four album corners — real paper is almost monochrome. The depth comes
   from a soft drop shadow underneath them, not painted-on light/dark bands. */
.heritage-corner {
  position: absolute;
  width: 16%;
  aspect-ratio: 1;
  pointer-events: none;
  filter: drop-shadow(0 1.5px 2.5px rgba(40, 25, 8, 0.42));
}

/* Just a base color triangle and a barely-perceptible darkening right at the
   cut edge so the triangle has a hint of three-dimensionality without
   looking like CSS shading. */

.heritage-corner-tl {
  top: 0;
  left: 0;
  background:
    linear-gradient(135deg, transparent 47%, rgba(0, 0, 0, 0.07) 50%, transparent 50%),
    linear-gradient(135deg, var(--corner-color, #fbf3dc) 50%, transparent 50%);
}
.heritage-corner-tr {
  top: 0;
  right: 0;
  background:
    linear-gradient(225deg, transparent 47%, rgba(0, 0, 0, 0.07) 50%, transparent 50%),
    linear-gradient(225deg, var(--corner-color, #fbf3dc) 50%, transparent 50%);
}
.heritage-corner-bl {
  bottom: 0;
  left: 0;
  background:
    linear-gradient(45deg, transparent 47%, rgba(0, 0, 0, 0.07) 50%, transparent 50%),
    linear-gradient(45deg, var(--corner-color, #fbf3dc) 50%, transparent 50%);
}
.heritage-corner-br {
  bottom: 0;
  right: 0;
  background:
    linear-gradient(315deg, transparent 47%, rgba(0, 0, 0, 0.07) 50%, transparent 50%),
    linear-gradient(315deg, var(--corner-color, #fbf3dc) 50%, transparent 50%);
}

.heritage-caption {
  /* Position the caption absolutely below the photo so the photo itself is
     what gets centered in the stage, not photo + caption combined. */
  position: absolute;
  top: calc(100% + 0.4rem);
  left: 0;
  right: 0;
  font-family: "Brush Script MT", "Snell Roundhand", "Apple Chancery", "Lucida Handwriting", cursive;
  font-size: 1.15rem;
  /* Aged bronze ink to match the scrollwork tone. */
  color: #6b4e2d;
  letter-spacing: 0.02em;
  line-height: 1;
  text-align: center;
  min-height: 1.2em;
  /* Letterpress effect — dark above the strokes (top edge of the impression
     in shadow), light below (where the paper rebounds and catches light).
     Makes the year read as pressed into the paper rather than printed on top. */
  text-shadow:
    0 -1px 0 rgba(40, 22, 8, 0.35),
    0 1px 0 rgba(255, 250, 225, 0.75);
}

.heritage-caption:empty::before {
  /* Reserve the space so the photo position doesn't jump between captioned
     and uncaptioned photos. */
  content: "";
  display: inline-block;
}

/* Honor zoom-dissolve transition on Heritage too. */
.preview-stage.transition-zoom-dissolve .heritage-slot.active img {
  animation: preview-zoom var(--hold, 5000ms) linear forwards;
}

@media (max-width: 380px) {
  .heritage-caption {
    font-size: 1rem;
  }
  .heritage-slot {
    width: 55%;
  }
}

@keyframes preview-zoom {
  from { transform: scale(1); }
  to { transform: scale(1.05); }
}

.preview-caption {
  margin: 0;
  font-size: 0.78rem;
  color: var(--muted);
  line-height: 1.45;
}
/* Gentle "Reset to default" beside the opening caption (guided editor). */
.fs-comp-reset {
  border: 0; background: none; cursor: pointer; font: inherit; font-size: 0.74rem;
  color: #8a7d64; text-decoration: underline; text-underline-offset: 2px;
  padding: 0 0 0 0.5rem; margin-left: 0.25rem;
}
.fs-comp-reset:hover { color: #5c5240; }

.preview-empty {
  width: 100%;
  aspect-ratio: 16 / 9;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 14px;
  background: rgba(127, 73, 63, 0.06);
  border: 1px dashed rgba(127, 73, 63, 0.25);
  padding: 1rem;
  text-align: center;
  color: var(--muted);
  font-size: 0.9rem;
}

.color-swatches {
  display: flex;
  flex-wrap: wrap;
  gap: 0.55rem;
}

.color-swatch {
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 50%;
  border: 2px solid transparent;
  cursor: pointer;
  padding: 0;
  transition: transform 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), inset 0 0 0 1px rgba(0, 0, 0, 0.06);
}

.color-swatch:hover {
  transform: scale(1.08);
}

.color-swatch.active {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent), 0 1px 3px rgba(0, 0, 0, 0.12);
}

.active-swatch-label {
  margin-top: 0.6rem;
  margin-bottom: 0;
  font-size: 0.85rem;
  color: var(--muted);
}

.analysis-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid rgba(127, 73, 63, 0.18);
  margin-bottom: 1.25rem;
}

.analysis-tab {
  appearance: none;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 999px;
  padding: 0.45rem 1rem;
  font: inherit;
  font-weight: 700;
  font-size: 0.92rem;
  color: var(--muted);
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}

.analysis-tab:hover {
  background: rgba(127, 73, 63, 0.06);
  color: var(--ink);
}

.analysis-tab.active {
  background: var(--accent);
  color: #fffdf8;
  border-color: var(--accent);
}

.crops-summary {
  margin: 0.5rem 0 1rem;
  font-size: 0.92rem;
  color: var(--muted);
}

.crops-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 1.5rem;
}

.crop-card {
  display: grid;
  gap: 0.5rem;
}

.crop-stage {
  position: relative;
  width: 100%;
  overflow: hidden;
  border-radius: 12px;
  cursor: crosshair;
  background: #1a1410;
  user-select: none;
}

.crop-stage img {
  width: 100%;
  display: block;
  pointer-events: none;
  -webkit-user-drag: none;
}

.crop-viewport {
  position: absolute;
  border: 2px solid #fffdf8;
  /* The shadow extends 9999px outward from the viewport, painting everything
     outside the box with the dim color. Combined with overflow:hidden on the
     stage, this creates the spotlight crop UI. */
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.55);
  pointer-events: none;
  display: flex;
  align-items: center;
  justify-content: center;
}

.crop-viewport::after {
  content: "";
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid #fffdf8;
  box-shadow: 0 0 4px rgba(0, 0, 0, 0.4);
}

.crop-meta {
  display: grid;
  gap: 0.3rem;
}

.crop-meta strong {
  font-size: 0.95rem;
  line-height: 1.3;
}

.crop-status {
  font-size: 0.82rem;
  color: var(--muted);
}

.ghost-btn.small {
  padding: 0.35rem 0.75rem;
  font-size: 0.82rem;
  justify-self: start;
}

/* ---------- Lightbox ---------- */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: rgba(20, 14, 10, 0.88);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 3rem;
  cursor: zoom-out;
  animation: lightbox-fade 0.18s ease;
}

@keyframes lightbox-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}

.lightbox-image {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 6px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6);
  cursor: default;
  user-select: none;
}

.lightbox-close {
  position: absolute;
  top: 1.2rem;
  right: 1.2rem;
  width: 2.8rem;
  height: 2.8rem;
  border-radius: 50%;
  background: rgba(255, 253, 247, 0.92);
  border: 0;
  color: var(--ink);
  font-size: 1.8rem;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: inherit;
}

.lightbox-close:hover {
  background: #fff;
}

[data-lightbox-photo] {
  cursor: zoom-in;
}

[data-preview-expand] {
  cursor: zoom-in;
}

/* ---------- Expanded lightbox layout (image area + meta strip) ---------- */

/* New: the lightbox now wraps an image area on top with a meta/actions
   strip below it. The image area can hold a plain <img>, a loading
   shell during restoration, or the before/after slider after the
   pipeline completes. */
.lightbox-wrapper {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  width: min(100%, 900px);
  max-height: calc(100vh - 6rem); max-height: calc(100dvh - 6rem);
  cursor: default;
}

.lightbox-image-area {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  overflow: hidden;
  background: #1b1612;
  max-height: calc(100vh - 12rem); max-height: calc(100dvh - 12rem);
}

.lightbox-image-area .lightbox-image {
  width: 100%;
  height: 100%;
  max-height: calc(100vh - 12rem); max-height: calc(100dvh - 12rem);
  object-fit: contain;
  border-radius: 0;
  box-shadow: none;
}
@keyframes lightbox-spin {
  to { transform: rotate(360deg); }
}

/* Meta strip below the image: name + era/age on the left, action(s)
   on the right. Cream parchment surface so it reads as a "card" the
   buttons sit on, rather than floating dark over the backdrop. */
.lightbox-meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  padding: 1rem 1.25rem;
  background: #fbf6ec;
  border-radius: 12px;
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.28);
}
.lightbox-meta-text {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  min-width: 0;
  flex: 1 1 auto;
}
.lightbox-meta-text strong {
  font-size: 1rem;
  color: #2a221a;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.lightbox-meta-text span {
  font-size: 0.82rem;
  color: #6b5a3a;
}
.lightbox-restored-badge {
  display: inline-block;
  margin-top: 0.2rem;
  padding: 0.15rem 0.55rem;
  background: linear-gradient(135deg, rgba(201, 162, 90, 0.2) 0%, rgba(110, 79, 26, 0.2) 100%);
  color: #6e4f1a;
  border-radius: 999px;
  font-size: 0.72rem !important;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  width: fit-content;
}
.primary-btn.is-active {
  background: #6e4f1a;
}

@media (max-width: 720px) {
  .lightbox-meta {
    flex-direction: column;
    align-items: stretch;
  }
}

/* ---------- Before/after slider ---------- */

.ba-slider {
  position: relative;
  /* Width fills the flex parent (up to the parent's max-width). Height
     is derived from inline `aspect-ratio` set per-photo so we never
     collapse to 0 inside the flex column. max-height caps it so very
     tall portrait photos don't overflow the lightbox vertically. */
  width: 100%;
  max-height: 100%;
  aspect-ratio: 3 / 2; /* default, overridden inline per photo */
  background: #1b1612;
  overflow: hidden;
  cursor: ew-resize;
  user-select: none;
  touch-action: none;
  margin: 0 auto;
}
.ba-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  pointer-events: none;
  user-select: none;
}
.ba-img-before {
  z-index: 1;
}
/* Top layer is the restored image, clipped from the LEFT up to the
   divider position. Beyond the divider it's visible; before it, the
   original shows through. */
.ba-img-after {
  z-index: 2;
  clip-path: inset(0 0 0 var(--reveal-pct, 50%));
}

/* The vertical divider that marks the boundary between before and
   after. translate(-50%) centers the 2px line on the boundary X. */
.ba-divider {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--reveal-pct, 50%);
  width: 2px;
  background: rgba(255, 255, 255, 0.92);
  transform: translateX(-50%);
  pointer-events: none;
  z-index: 3;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.2);
}
.ba-handle {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: #fff;
  color: #1b1612;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 2px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
  pointer-events: none;
}
.ba-handle-arrow {
  font-size: 1.4rem;
  font-weight: 600;
  line-height: 1;
}
.ba-label {
  position: absolute;
  top: 12px;
  padding: 0.3rem 0.7rem;
  background: rgba(0, 0, 0, 0.65);
  color: #fff;
  border-radius: 999px;
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  z-index: 4;
  pointer-events: none;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
.ba-label-before {
  left: 12px;
}
.ba-label-after {
  right: 12px;
}

/* ---------- Expanded preview ---------- */

.preview-expanded {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: rgba(20, 14, 10, 0.92);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 3rem;
  cursor: zoom-out;
  animation: lightbox-fade 0.2s ease;
}

.preview-expanded-wrapper {
  width: min(92vw, 1400px);
  max-height: 86vh;
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  cursor: default;
  position: relative; /* anchor for .preview-expanded-toolbar absolute pos */
}

/* When the side editor is on (Backdrop edit mode), the wrapper becomes
   2-column: stage on left, sidebar on right. Stage stays vertically
   centered; sidebar scrolls independently if its content is tall. */
.preview-expanded-wrapper.has-side-editor {
  width: min(94vw, 1600px);
  max-height: 90vh;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 360px;
  gap: 1rem;
  align-items: stretch;
}
.preview-expanded-wrapper.has-side-editor .preview-expanded-stage-col {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  min-width: 0;
  justify-content: center;
}

@media (max-width: 900px) {
  .preview-expanded-wrapper.has-side-editor {
    grid-template-columns: 1fr;
    grid-template-rows: minmax(0, 1fr) auto;
    max-height: 92vh;
  }
}

.backdrop-text-editor {
  background: #faf6ea;
  color: #2a2218;
  border-radius: 14px;
  padding: 1rem 0.9rem 1.2rem;
  overflow-y: auto;
  max-height: 90vh;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.38), 0 0 0 0.5px rgba(0, 0, 0, 0.08);
}

/* Header — photo thumbnail + serif name/era + eye visibility button.
   Replaces the older title-row + checkbox layout with a more
   informative "you are editing THIS photo" presentation. */
.backdrop-text-editor-header {
  padding-bottom: 0.75rem;
  margin-bottom: 0.7rem;
  border-bottom: 0.5px solid rgba(60, 40, 20, 0.1);
}
.backdrop-text-editor-photo-id {
  display: flex;
  align-items: center;
  gap: 0.65rem;
}
.backdrop-text-editor-thumb {
  display: inline-block;
  width: 38px;
  height: 38px;
  flex-shrink: 0;
  border-radius: 6px;
  background-color: #c9954a;
  background-size: cover;
  background-position: center;
  box-shadow: inset 0 0 0 0.5px rgba(0, 0, 0, 0.12);
}
.backdrop-text-editor-photo-meta {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}
.backdrop-text-editor-eyebrow {
  font-size: 0.65rem;
  color: #8a7553;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 500;
}
.backdrop-text-editor-name {
  font-family: var(--serif, "Cormorant Garamond", "EB Garamond", serif);
  font-size: 0.95rem;
  color: #2a2218;
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.backdrop-text-editor-visibility {
  appearance: none;
  flex-shrink: 0;
  height: 26px;
  padding: 0 0.65rem;
  border-radius: 999px;
  border: 0.5px solid rgba(60, 40, 20, 0.16);
  background: transparent;
  cursor: pointer;
  color: #6b5538;
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s ease, color 0.15s ease;
}
.backdrop-text-editor-visibility:hover {
  background: rgba(60, 40, 20, 0.06);
  color: #2a2218;
}
.backdrop-text-editor-visibility.is-hidden {
  background: rgba(60, 40, 20, 0.12);
  color: #2a2218;
}

/* Accordion sections — each major editor area collapses into a card
   so the sidebar is shorter and the user can focus on one block at
   a time. Default-open section is "Text content". */
.backdrop-text-section {
  background: #fff;
  border: 0.5px solid rgba(60, 40, 20, 0.08);
  border-radius: 10px;
  margin-bottom: 0.45rem;
  overflow: hidden;
}
.backdrop-text-section-toggle {
  appearance: none;
  width: 100%;
  background: transparent;
  border: 0;
  padding: 0.7rem 0.85rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  cursor: pointer;
  font-family: var(--serif, "Cormorant Garamond", "EB Garamond", serif);
  color: #2a2218;
  transition: background 0.15s ease;
}
.backdrop-text-section-toggle:hover {
  background: rgba(60, 40, 20, 0.03);
}
.backdrop-text-section-title {
  font-size: 0.98rem;
  font-weight: 500;
  letter-spacing: 0.005em;
}
.backdrop-text-section-chevron {
  font-size: 0.95rem;
  color: #8a7553;
  font-family: monospace;
  line-height: 1;
  width: 16px;
  text-align: center;
}
.backdrop-text-section-body {
  padding: 0 0.85rem 0.85rem;
  display: none;
}
.backdrop-text-section.is-open .backdrop-text-section-body {
  display: block;
}
.backdrop-text-section.is-open .backdrop-text-section-toggle {
  border-bottom: 0.5px solid rgba(60, 40, 20, 0.08);
}

.backdrop-text-editor-body {
  transition: opacity 0.15s ease;
}
.backdrop-typo-grid-font .backdrop-typo-font-name {
  font-family: var(--sans, -apple-system, "Inter", sans-serif);
  font-size: 0.66rem;
  font-weight: 500;
  color: #8a7553;
  letter-spacing: 0.01em;
  line-height: 1.15;
  text-align: center;
  white-space: normal;
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  max-width: 100%;
  word-break: break-word;
}
.backdrop-typo-grid-font .backdrop-typo-chip-font.is-on .backdrop-typo-font-name {
  color: #6e4d1a;
  font-weight: 600;
}

/* Caption-mode checkbox row — Name / Chapter / Custom are independent
   toggles; checking multiple stacks them on the photo. Sample text
   under each label so family knows what they'll get. */
/* Layout templates — preset compositions for the Backdrop stage.
 * Each tile is a button with a small SVG diagram on top + label below.
 * Active tile = closest match to the currently-saved photo + text
 * positions (within ~4-unit tolerance). */
.backdrop-layout-template-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.55rem;
}
.backdrop-layout-template-tile {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.5rem;
  padding: 0.55rem 0.55rem 0.6rem;
  border: 1px solid rgba(120, 100, 80, 0.28);
  border-radius: 9px;
  background: #fff;
  cursor: pointer;
  text-align: center;
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}
.backdrop-layout-template-tile:hover {
  background: #faf6e9;
  border-color: rgba(120, 100, 80, 0.45);
}
.backdrop-layout-template-tile:active {
  transform: scale(0.98);
}
.backdrop-layout-template-tile.is-active {
  background: rgba(96, 115, 101, 0.16);
  border-color: rgba(96, 115, 101, 0.6);
  box-shadow: 0 0 0 1px rgba(96, 115, 101, 0.5) inset;
}
.backdrop-layout-template-diagram {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 10;
  border-radius: 6px;
  overflow: hidden;
}
.backdrop-layout-template-diagram svg {
  width: 100%;
  height: 100%;
  display: block;
}
.backdrop-layout-template-diagram .lt-stage {
  fill: #fdfaf2;
  stroke: rgba(120, 100, 80, 0.45);
  stroke-width: 0.6;
}
.backdrop-layout-template-diagram .lt-box {
  stroke: rgba(96, 115, 101, 0.85);
  stroke-width: 0.5;
  fill: rgba(96, 115, 101, 0.16);
}
.backdrop-layout-template-diagram .lt-box.lt-text {
  fill: rgba(120, 100, 80, 0.10);
  stroke: rgba(120, 100, 80, 0.55);
}
.backdrop-layout-template-diagram .lt-box.lt-photo {
  fill: rgba(96, 115, 101, 0.22);
}
.backdrop-layout-template-diagram .lt-line {
  stroke: rgba(120, 100, 80, 0.7);
  stroke-width: 0.7;
  stroke-linecap: round;
}
.backdrop-layout-template-diagram .lt-line.lt-line-strong {
  stroke-width: 1.4;
  stroke: rgba(70, 55, 40, 0.85);
}
.backdrop-layout-template-tile.is-active .lt-box.lt-photo {
  fill: rgba(96, 115, 101, 0.35);
}
.backdrop-layout-template-tile.is-active .lt-stage {
  stroke: rgba(96, 115, 101, 0.8);
}
.backdrop-layout-template-label {
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: var(--text, #2c2620);
  line-height: 1.15;
}
.backdrop-layout-template-tile.is-active .backdrop-layout-template-label {
  color: #3f4a3f;
}
/* Recommended badge — sits in the upper-right of a composition tile
 * when the active emotional style recommends that composition. */
.backdrop-layout-template-tile {
  position: relative;
}
.backdrop-layout-template-badge {
  position: absolute;
  top: 0.32rem;
  right: 0.32rem;
  background: #3f4a3f;
  color: #f5ecd5;
  font-size: 0.56rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 0.18rem 0.42rem;
  border-radius: 999px;
  line-height: 1;
  z-index: 2;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
}
.backdrop-layout-template-tile.is-recommended:not(.is-active) {
  border-color: rgba(96, 115, 101, 0.4);
}

/* Backdrop library — emotional-style filter banner. Shown when an
 * emotional style is active AND its backdropTags filter the catalog. */
.backdrop-library-style-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.65rem;
  margin: 0.35rem 0 0.7rem;
  padding: 0.45rem 0.7rem;
  background: rgba(96, 115, 101, 0.1);
  border: 1px solid rgba(96, 115, 101, 0.3);
  border-radius: 8px;
  font-size: 0.76rem;
  color: var(--text, #2c2620);
}
.backdrop-library-style-banner strong {
  font-weight: 700;
  color: #3f4a3f;
}
/* Template tab — Advanced disclosure (Finding #3). Hides legacy
 * template picker + pacing + display options behind a single fold
 * when the guided emotional/composition flow is active. */
.template-advanced-toggle {
  width: 100%;
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 0.5rem;
  align-items: center;
  padding: 0.85rem 1.05rem;
  background: transparent;
  border: 0;
  border-radius: 12px;
  cursor: pointer;
  text-align: left;
  transition: background 0.15s ease;
}
.template-advanced-toggle:hover { background: #faf6e9; }
.template-advanced-toggle.is-open { background: #faf5e8; }
.template-advanced-label {
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}
.template-advanced-hint {
  font-size: 0.78rem;
  color: var(--text, #2c2620);
  font-style: italic;
}
.template-advanced-chevron {
  color: var(--muted);
  font-size: 1.05rem;
}
.template-advanced-body {
  padding: 0.45rem 0.25rem 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}

/* Phase 6 — Review sidebar. Calm verification surface that replaces
 * the precision editor when state.preview.mode === "review". */
.review-sidebar .review-sidebar-body {
  padding: 0.6rem 1.05rem 1.05rem;
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
}
.review-sidebar-prompt {
  font-family: var(--serif, "Cormorant Garamond", "EB Garamond", Georgia, serif);
  font-size: 1.25rem;
  font-weight: 500;
  margin: 0;
  color: var(--text, #2c2620);
}
.review-status-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.55rem;
}
.review-status-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  padding: 1rem 0.5rem;
  border: 1px solid rgba(120, 100, 80, 0.28);
  border-radius: 12px;
  background: #fff;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}
.review-status-btn:hover {
  background: #faf6e9;
}
.review-status-btn:active {
  transform: scale(0.97);
}
.review-status-icon {
  font-size: 1.6rem;
  line-height: 1;
}
.review-status-label {
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--text, #2c2620);
}
.review-status-good.is-active {
  background: rgba(96, 115, 101, 0.18);
  border-color: rgba(96, 115, 101, 0.7);
  color: #3f4a3f;
}
.review-status-good.is-active .review-status-icon,
.review-status-good.is-active .review-status-label {
  color: #3f4a3f;
}
.review-status-needs.is-active {
  background: rgba(176, 110, 60, 0.16);
  border-color: rgba(176, 110, 60, 0.65);
}
.review-status-needs.is-active .review-status-icon,
.review-status-needs.is-active .review-status-label {
  color: #8a4f24;
}
.review-apply-card {
  padding: 0.75rem 0.85rem;
  background: #faf5e8;
  border: 1px solid rgba(120, 100, 80, 0.22);
  border-radius: 10px;
}
.review-apply-title {
  margin: 0 0 0.15rem;
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--text, #2c2620);
}
.review-apply-desc {
  margin: 0 0 0.55rem;
  font-size: 0.72rem;
  color: var(--muted);
  line-height: 1.35;
}
.review-apply-btn {
  width: 100%;
  font-size: 0.78rem;
}
.review-orientation-summary {
  padding-top: 0.6rem;
  border-top: 1px solid rgba(120, 100, 80, 0.18);
}
.review-summary-title {
  margin: 0 0 0.55rem;
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}
.review-summary-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.4rem 0;
  font-size: 0.8rem;
}
.review-summary-label {
  font-weight: 700;
  color: var(--text, #2c2620);
}
.review-summary-total {
  font-weight: 500;
  color: var(--muted);
  font-size: 0.72rem;
}
.review-summary-chips {
  display: inline-flex;
  gap: 0.3rem;
  align-items: center;
}
.review-chip {
  font-size: 0.7rem;
  font-weight: 700;
  padding: 0.12rem 0.42rem;
  border-radius: 999px;
  letter-spacing: 0.02em;
}
.review-chip-good {
  background: rgba(96, 115, 101, 0.18);
  color: #3f4a3f;
}
.review-chip-needs {
  background: rgba(176, 110, 60, 0.16);
  color: #8a4f24;
}
.review-chip-rest {
  color: var(--muted);
}
.review-sidebar-footer {
  padding-top: 0.6rem;
  border-top: 1px solid rgba(120, 100, 80, 0.18);
  text-align: center;
}

/* Phase 4 — Editor sidebar reorder.
 * HTML order: Simple, Backdrop, Composition, Words, Spacing, Style.
 * Visual order via flex order: Simple → Composition → Words → ADVANCED
 *   divider → Backdrop → Spacing → Style. The divider is a pseudo-element
 *   on .backdrop-text-editor-body so we don't need a separate DOM node. */
.backdrop-text-editor-body {
  display: flex;
  flex-direction: column;
}
/* Advanced divider removed — Spacing + Style sections no longer
   exist (toolbar handles those now), so the divider has nothing
   to divide. */
.backdrop-text-section[data-section="simple"]    { order: 1; }
.backdrop-text-section[data-section="layout"]    { order: 2; }
.backdrop-text-section[data-section="text"]      { order: 3; }
.backdrop-text-section[data-section="backdrop"]  { order: 5; }
.backdrop-text-section[data-section="spacing"]   { order: 6; }
.backdrop-text-section[data-section="style"]     { order: 7; }

/* Emotional Style step — Level 1 of the guided memorial flow.
 * Big calm rows, one per emotional direction. Family picks how the
 * film should FEEL; the click applies typography + matte + dim +
 * shadow defaults underneath. */
.emotional-style-step {
  padding: 0.5rem 0;
}
.emotional-style-grid {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}
.emotional-style-row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 0.9rem;
  align-items: center;
  padding: 0.85rem 1.05rem;
  border: 1px solid rgba(120, 100, 80, 0.22);
  border-radius: 12px;
  background: #fff;
  text-align: left;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
}
.emotional-style-row:hover {
  background: #faf6e9;
  border-color: rgba(120, 100, 80, 0.45);
}
.emotional-style-row.is-active {
  background: rgba(96, 115, 101, 0.12);
  border-color: rgba(96, 115, 101, 0.6);
  box-shadow: 0 0 0 1px rgba(96, 115, 101, 0.5) inset;
}
.emotional-style-swatch {
  display: block;
  width: 3.4rem;
  height: 3.4rem;
  border-radius: 10px;
  flex: 0 0 auto;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.18) inset, 0 1px 2px rgba(0, 0, 0, 0.1);
}
.emotional-style-body {
  display: flex;
  flex-direction: column;
  min-width: 0;
  gap: 0.15rem;
}
.emotional-style-label {
  font-family: var(--serif, "Cormorant Garamond", "EB Garamond", Georgia, serif);
  font-size: 1.15rem;
  font-weight: 600;
  letter-spacing: 0.005em;
  color: var(--text, #2c2620);
  line-height: 1.15;
}
.emotional-style-row.is-active .emotional-style-label {
  color: #3f4a3f;
}
.emotional-style-desc {
  font-size: 0.82rem;
  color: var(--text, #2c2620);
  line-height: 1.35;
  opacity: 0.85;
}
.emotional-style-hint {
  font-size: 0.72rem;
  color: var(--muted);
  font-style: italic;
}
.emotional-style-check {
  flex: 0 0 auto;
  width: 1.8rem;
  height: 1.8rem;
  border-radius: 999px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  color: transparent;
  font-weight: 800;
  font-size: 0.95rem;
  transition: background 0.15s ease, color 0.15s ease;
}
.emotional-style-row.is-active .emotional-style-check {
  background: #3f4a3f;
  color: #fff;
}
.emotional-style-actions {
  margin-top: 1.1rem;
  display: flex;
  justify-content: flex-end;
}
.emotional-style-actions .primary-btn[disabled] {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}

/* Emotional-style item wrapper — groups the row + its thumbnail strip
 * so they read as one unit when the style is active. */
.emotional-style-item {
  display: flex;
  flex-direction: column;
}
.emotional-style-item.is-active .emotional-style-row {
  /* Soften the bottom edge of the row so the thumb strip below
   * visually connects to it. */
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
  border-bottom-color: transparent;
}

/* Thumbnail strip — surfaces 3 backdrops matching the active style's
 * tags so the family can see the feel and swap to alternates with one
 * click. Sits flush under the active row. */
.emotional-style-thumbs {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.7rem 1.05rem 0.9rem;
  background: rgba(96, 115, 101, 0.07);
  border: 1px solid rgba(96, 115, 101, 0.6);
  border-top: none;
  border-radius: 0 0 12px 12px;
  box-shadow: 0 0 0 1px rgba(96, 115, 101, 0.5) inset;
}
.emotional-style-thumbs-label {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  font-weight: 600;
}
.emotional-style-thumbs-loading,
.emotional-style-thumbs-empty {
  font-size: 0.78rem;
  color: var(--muted);
  font-style: italic;
}
.emotional-style-thumbs-row {
  display: grid;
  /* Auto-fill so the row holds many thumbnails — wraps to multiple
     lines as needed. Min thumb width keeps them tappable. */
  grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
  gap: 0.55rem;
}
.emotional-style-thumb {
  position: relative;
  aspect-ratio: 16 / 10;
  border: 1px solid rgba(120, 100, 80, 0.28);
  border-radius: 8px;
  background: #fff;
  overflow: hidden;
  cursor: pointer;
  padding: 0;
  transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}
.emotional-style-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.emotional-style-thumb:hover {
  border-color: rgba(96, 115, 101, 0.55);
  transform: translateY(-1px);
}
.emotional-style-thumb.is-selected {
  border-color: #3f4a3f;
  box-shadow: 0 0 0 2px #3f4a3f, 0 2px 8px rgba(63, 74, 63, 0.18);
}
.emotional-style-thumb-check {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 1.2rem;
  height: 1.2rem;
  border-radius: 999px;
  background: #3f4a3f;
  color: #fff;
  font-weight: 800;
  font-size: 0.7rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
}

/* Template tab three-step progress strip — Style → Composition → Review.
 * Phase 2 of the memorial UX overhaul: family sees a calm guided flow
 * at the top of the Template tab. Steps are clickable but only
 * Composition has full content for now; Style + Review are phase 3+. */
.template-progress-strip {
  background: #faf5e8;
  border: 1px solid rgba(120, 100, 80, 0.18);
  border-radius: 14px;
  padding: 1.2rem 1.4rem 1rem;
  margin-bottom: 1.1rem;
}
.template-progress-header {
  margin-bottom: 0.85rem;
}
.template-progress-sub {
  margin: 0;
  font-size: 0.82rem;
  color: var(--muted);
}
.template-progress-steps {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}
.template-progress-step {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.55rem 0.75rem;
  border: 1px solid rgba(120, 100, 80, 0.22);
  border-radius: 10px;
  background: #fff;
  cursor: pointer;
  text-align: left;
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}
.template-progress-step:hover {
  background: #faf6e9;
  border-color: rgba(120, 100, 80, 0.42);
}
.template-progress-step.is-active {
  background: rgba(96, 115, 101, 0.12);
  border-color: rgba(96, 115, 101, 0.55);
}
.template-progress-step.is-past .template-progress-num {
  background: rgba(96, 115, 101, 0.85);
  color: #fff;
}
.template-progress-num {
  flex: 0 0 auto;
  width: 1.9rem;
  height: 1.9rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: #efe7d4;
  color: var(--text, #2c2620);
  font-size: 0.82rem;
  font-weight: 700;
}
.template-progress-step.is-active .template-progress-num {
  background: #3f4a3f;
  color: #fff;
}
.template-progress-meta {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.template-progress-label {
  font-size: 0.84rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--text, #2c2620);
}
.template-progress-step.is-active .template-progress-label {
  color: #3f4a3f;
}
.template-progress-desc {
  font-size: 0.7rem;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.template-progress-sep {
  color: rgba(120, 100, 80, 0.45);
  font-size: 1.1rem;
  font-weight: 400;
  flex: 0 0 auto;
}

/* Variant pills — Top / Center / Bottom row beneath the template grid.
 * Each pill selects a vertical-alignment variant for the active layout.
 * Active pill is highlighted sage green to match the active template tile. */
.backdrop-layout-variant-row {
  display: flex;
  gap: 0.4rem;
  margin-top: 0.7rem;
}
.backdrop-layout-variant-pill {
  flex: 1;
  padding: 0.4rem 0.5rem;
  border: 1px solid rgba(120, 100, 80, 0.28);
  border-radius: 999px;
  background: #fff;
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--text, #2c2620);
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.backdrop-layout-variant-pill:hover {
  background: #faf6e9;
  border-color: rgba(120, 100, 80, 0.45);
}
.backdrop-layout-variant-pill.is-active {
  background: rgba(96, 115, 101, 0.16);
  border-color: rgba(96, 115, 101, 0.6);
  color: #3f4a3f;
}

/* "Save as layout default" button row — appears beneath the template
 * grid when a layout is active. Bakes positions + spacing + font/color
 * into the layout's defaults via /api/layout-save-defaults. */
.backdrop-layout-save-row {
  margin-top: 0.85rem;
  padding-top: 0.85rem;
  border-top: 1px solid rgba(120, 100, 80, 0.18);
}
.backdrop-layout-save-btn {
  width: 100%;
}

/* Style calibration card — developer tool that saves the current full
 * editor look into the active emotional style's saved bucket, scoped
 * to the current photo's orientation. Sits at the bottom of the
 * editor sidebar in a distinct dev-tool treatment so it's obvious
 * this isn't end-user UI. */
.style-calibration-card {
  margin: 1rem 0.85rem 0.85rem;
  padding: 0.85rem 0.95rem;
  background: rgba(255, 220, 130, 0.13);
  border: 1px dashed rgba(150, 110, 40, 0.55);
  border-radius: 10px;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.style-calibration-header {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}
.style-calibration-eyebrow {
  font-size: 0.65rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-weight: 700;
  color: #8a5a1a;
}
.style-calibration-title {
  font-family: var(--serif, "Cormorant Garamond", Georgia, serif);
  font-size: 1rem;
  font-weight: 600;
  color: var(--text, #2c2620);
}
.style-calibration-save {
  width: 100%;
}
.style-calibration-hint {
  margin: 0;
  font-size: 0.7rem;
  color: var(--muted);
  line-height: 1.4;
}

.backdrop-caption-mode-checks {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}
.backdrop-caption-mode-check {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto auto;
  column-gap: 0.6rem;
  align-items: center;
  padding: 0.5rem 0.6rem;
  border: 1px solid rgba(120, 100, 80, 0.25);
  border-radius: 8px;
  cursor: pointer;
  background: #fff;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.backdrop-caption-mode-check:hover {
  background: #faf6e9;
}
.backdrop-caption-mode-check.is-on {
  background: rgba(96, 115, 101, 0.14);
  border-color: rgba(96, 115, 101, 0.55);
}
.backdrop-caption-mode-check input {
  grid-row: span 2;
  grid-column: 1;
  cursor: pointer;
}
.backdrop-caption-mode-check .backdrop-caption-mode-label {
  grid-row: 1;
  grid-column: 2;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--text, #2c2620);
}
.backdrop-caption-mode-check .backdrop-caption-mode-sample {
  grid-row: 2;
  grid-column: 2;
  font-size: 0.72rem;
  color: var(--muted);
  font-style: italic;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.backdrop-caption-mode-check.is-on .backdrop-caption-mode-sample {
  color: #3f4a3f;
}

/* Custom-lines list — multiple inputs with drag handles + delete. */
.backdrop-custom-lines-list {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-top: 0.5rem;
  padding-left: 0.4rem;
  border-left: 2px solid rgba(96, 115, 101, 0.25);
}
.backdrop-custom-line-row {
  display: grid;
  grid-template-columns: 1.1rem 1fr 1.6rem;
  gap: 0.35rem;
  align-items: center;
  transition: opacity 0.15s ease;
}
.backdrop-custom-line-row.is-dragging {
  opacity: 0.4;
}
.backdrop-custom-line-row.is-drop-target {
  outline: 2px dashed rgba(201, 162, 90, 0.7);
  outline-offset: 2px;
  border-radius: 6px;
}
.backdrop-custom-line-drag {
  cursor: grab;
  user-select: none;
  color: var(--muted);
  font-size: 0.7rem;
  letter-spacing: -0.15em;
  text-align: center;
}
.backdrop-custom-line-drag:hover {
  color: var(--text);
}
.backdrop-custom-line-input {
  font-size: 0.85rem;
  width: 100%;
  min-width: 0; /* lets grid cell shrink the input rather than overflow */
  padding: 0.45rem 0.55rem;
}
.backdrop-custom-line-delete {
  appearance: none;
  border: 1px solid rgba(120, 100, 80, 0.2);
  background: transparent;
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 50%;
  cursor: pointer;
  color: var(--muted);
  font-size: 0.95rem;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  transition: color 0.12s ease, border-color 0.12s ease, background 0.12s ease;
}
.backdrop-custom-line-delete:hover {
  color: #b04848;
  border-color: #b04848;
  background: rgba(176, 72, 72, 0.06);
}
.backdrop-custom-line-add {
  appearance: none;
  align-self: flex-start;
  border: 1px dashed rgba(96, 115, 101, 0.5);
  background: transparent;
  color: #3f4a3f;
  padding: 0.35rem 0.7rem;
  border-radius: 6px;
  font-size: 0.75rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease;
  margin-top: 0.15rem;
}
.backdrop-custom-line-add:hover {
  background: rgba(96, 115, 101, 0.1);
  border-color: rgba(96, 115, 101, 0.85);
  border-style: solid;
}

/* On-photo custom line element — same look as the name line but each
   one is independently draggable. The drag handle styles come from
   .backdrop-text-name.is-editable; this just adds a small affordance
   marker for clarity. */
.backdrop-text-custom-line.is-editable,
.backdrop-text-chapter.is-editable {
  z-index: 6; /* above the regular name line in case they overlap */
}

/* Resize handle — small gold dot at the bottom-right corner of
   chapter + custom text lines. Hidden until the parent is hovered or
   actively dragging/resizing; same affordance pattern as the year
   resize handle. */
.backdrop-text-resize-handle {
  position: absolute;
  width: 11px;
  height: 11px;
  background: #c9a25a;
  border: 2px solid #fff;
  border-radius: 50%;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
  cursor: nwse-resize;
  /* Always visible when the parent is editable so users can see the
     grab handle without needing to hover-discover it. */
  opacity: 0.75;
  transform: scale(0.9);
  transition: opacity 120ms ease, transform 80ms ease;
  pointer-events: auto;
  z-index: 8;
}
/* Per-element resize circles — one at each corner of the text element.
   Default (no corner class) falls back to bottom-right for back-compat
   with the chapter / custom-line handles that still emit a single dot. */
.backdrop-text-resize-handle:not(.corner-tl):not(.corner-tr):not(.corner-bl):not(.corner-br) {
  bottom: -6px;
  right: -6px;
}
.backdrop-text-resize-handle.corner-tl { top: -6px; left: -6px; cursor: nwse-resize; }
.backdrop-text-resize-handle.corner-tr { top: -6px; right: -6px; cursor: nesw-resize; }
.backdrop-text-resize-handle.corner-bl { bottom: -6px; left: -6px; cursor: nesw-resize; }
.backdrop-text-resize-handle.corner-br { bottom: -6px; right: -6px; cursor: nwse-resize; }
.backdrop-text-name.is-editable:hover .backdrop-text-resize-handle,
.backdrop-text-name.is-editable.is-resizing .backdrop-text-resize-handle,
.backdrop-text-name.is-editable.is-dragging .backdrop-text-resize-handle {
  opacity: 1;
  transform: scale(1);
}
/* Per-element resize affordance on preamble / dates (Path B) and on all
   three title-card text elements (Path A). The handle visibility and
   hover-scale mirror the chapter handle's behavior so the family sees a
   consistent affordance on any text element they can resize. */
.backdrop-text-preamble.is-editable:hover .backdrop-text-resize-handle,
.backdrop-text-preamble.is-editable.is-resizing .backdrop-text-resize-handle,
.backdrop-text-dates.is-editable:hover .backdrop-text-resize-handle,
.backdrop-text-dates.is-editable.is-resizing .backdrop-text-resize-handle,
.titlecard-preamble:hover .backdrop-text-resize-handle,
.titlecard-preamble.is-resizing .backdrop-text-resize-handle,
.titlecard-name:hover .backdrop-text-resize-handle,
.titlecard-name.is-resizing .backdrop-text-resize-handle,
.titlecard-dates:hover .backdrop-text-resize-handle,
.titlecard-dates.is-resizing .backdrop-text-resize-handle {
  opacity: 1;
  transform: scale(1);
}
.backdrop-text-resize-handle:hover {
  transform: scale(1.2);
}

/* Text element groups — link multiple text elements so dragging any
   one moves the rest. Sits in the Words accordion under Date format. */
.text-groups-list {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}
.text-groups-group {
  padding: 0.55rem 0.6rem;
  background: #faf6e9;
  border: 1px solid rgba(120, 100, 80, 0.22);
  border-radius: 8px;
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}
.text-groups-group-header {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}
.text-groups-group-label {
  flex: 1 1 auto;
  font-family: var(--sans, "Inter", sans-serif);
  font-size: 0.82rem;
  font-weight: 600;
  background: transparent;
  border: 0;
  border-bottom: 1px dashed rgba(120, 100, 80, 0.35);
  color: var(--text, #2c2620);
  padding: 0.1rem 0.2rem;
  outline: none;
}
.text-groups-group-label:focus {
  border-bottom-color: rgba(96, 115, 101, 0.7);
  border-bottom-style: solid;
}
.text-groups-group-delete {
  appearance: none;
  background: transparent;
  border: 0;
  color: var(--muted);
  cursor: pointer;
  font-size: 1.1rem;
  line-height: 1;
  padding: 0.2rem 0.35rem;
  border-radius: 4px;
  transition: background 0.12s ease, color 0.12s ease;
}
.text-groups-group-delete:hover {
  background: rgba(180, 80, 60, 0.12);
  color: #8a3a28;
}
.text-groups-chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
}
.text-groups-chip {
  appearance: none;
  padding: 0.25rem 0.55rem;
  font-size: 0.72rem;
  font-family: var(--sans, "Inter", sans-serif);
  background: #fff;
  border: 1px solid rgba(120, 100, 80, 0.28);
  border-radius: 999px;
  color: var(--text, #2c2620);
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.text-groups-chip:hover {
  border-color: rgba(96, 115, 101, 0.55);
}
.text-groups-chip.is-on {
  background: #3f4a3f;
  color: #fff;
  border-color: #3f4a3f;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}
.text-groups-chip-order {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.15rem;
  height: 1.15rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.95);
  color: #3f4a3f;
  font-weight: 800;
  font-size: 0.65rem;
  line-height: 1;
}

/* Text-group box — one per group with 2+ members in Edit mode.
   Wraps the union bounds of all members. Hover shows a dashed outline,
   click+drag the body moves the whole group (group anchor), drag a
   corner resizes all members uniformly (group.scale). */
.backdrop-group-box {
  position: absolute;
  /* Faint visible default border so the user can see WHERE each
     group's drag region sits (was transparent — too easy to miss). */
  border: 1px dashed rgba(201, 162, 90, 0.35);
  border-radius: 4px;
  cursor: grab;
  pointer-events: auto;
  /* Sit ABOVE the photo's interactive frame (z-5) so dragging in the
     group box's gap space — common when the group box overlaps the
     photo — does the group drag instead of falling through to the
     photo drag. Member text elements live at z-index 5 too, so they
     stack at the same level; the per-element resize handles inside
     each text live at z-index 10 and stay reachable. Group drag IS
     what a text-glyph click triggers anyway (text drag delegates to
     applyGroupedDragMove), so even if the group box wins same-level
     ties over text, the visible behavior is identical. */
  z-index: 6;
  transition: border-color 0.15s ease, background 0.15s ease;
  padding: 0;
  box-sizing: border-box;
}
.backdrop-group-box:hover,
.backdrop-group-box.is-active {
  border-color: rgba(201, 162, 90, 0.75);
  background: rgba(201, 162, 90, 0.06);
}
.backdrop-group-box.is-dragging {
  cursor: grabbing;
  border-color: rgba(201, 162, 90, 0.95);
  border-style: solid;
}
/* LO76 — THE GROUP BOX IS A FRAME, NOT A PANE.
   Its middle no longer takes the pointer, so a press inside reaches the piece
   that is actually there. The grab moved to four edge strips and the four
   corners, which are the only children with pointer-events back on. This is
   what retires the LO67/LO73 class of bug — a piece buried under the group
   rectangle — at the root instead of one piece kind at a time.
   The strips are 14px so the frame is as easy to hit as the corners, and they
   reach 7px outside the border so the grab is not a hairline. */
.backdrop-group-box { pointer-events: none; }
.backdrop-group-box-edge {
  position: absolute;
  pointer-events: auto;
  cursor: grab;
  background: transparent;
}
.backdrop-group-box.is-dragging .backdrop-group-box-edge { cursor: grabbing; }
.backdrop-group-box-edge.edge-t { top: -7px; left: -7px; right: -7px; height: 14px; }
.backdrop-group-box-edge.edge-b { bottom: -7px; left: -7px; right: -7px; height: 14px; }
.backdrop-group-box-edge.edge-l { left: -7px; top: -7px; bottom: -7px; width: 14px; }
.backdrop-group-box-edge.edge-r { right: -7px; top: -7px; bottom: -7px; width: 14px; }

.backdrop-group-box-corner {
  position: absolute;
  pointer-events: auto;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: #c9a25a;
  border: 2px solid rgba(255, 250, 240, 0.9);
  opacity: 0;
  pointer-events: auto;
  transition: opacity 0.15s ease, transform 0.15s ease;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
  /* Sit ABOVE the text elements (z-5) so the corner dot always wins
     clicks even when the dashed box is small enough that a text
     element's bounding rect overlaps the corner position. Without
     this, dragging the corner falls through to a text drag and the
     resize never starts. */
  z-index: 10;
}
.backdrop-group-box:hover .backdrop-group-box-corner,
.backdrop-group-box.is-active .backdrop-group-box-corner,
.backdrop-group-box.is-dragging .backdrop-group-box-corner {
  opacity: 1;
}
.backdrop-group-box-corner:hover {
  transform: scale(1.18);
}
.backdrop-group-box-corner.corner-tl { top: -7px; left: -7px; cursor: nwse-resize; }
.backdrop-group-box-corner.corner-tr { top: -7px; right: -7px; cursor: nesw-resize; }
.backdrop-group-box-corner.corner-bl { bottom: -7px; left: -7px; cursor: nesw-resize; }
.backdrop-group-box-corner.corner-br { bottom: -7px; right: -7px; cursor: nwse-resize; }

/* Date format radios — compact 3-row layout (Show / Between / Lines).
   Replaces the bulky preset chips. Live sample renders below in a
   small italic preview. */
.backdrop-date-radio-group {
  display: grid;
  grid-template-columns: 4.5rem 1fr;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.4rem;
}
.backdrop-date-radio-label {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--muted);
}
.backdrop-date-radio-row {
  display: inline-flex;
  background: rgba(120, 100, 80, 0.08);
  border: 1px solid rgba(120, 100, 80, 0.18);
  border-radius: 999px;
  padding: 2px;
  gap: 0;
}
.backdrop-date-radio {
  appearance: none;
  border: 0;
  background: transparent;
  padding: 4px 10px;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  border-radius: 999px;
  cursor: pointer;
  color: var(--muted);
  transition: background 0.12s ease, color 0.12s ease;
  min-width: 2rem;
  text-align: center;
}
.backdrop-date-radio:hover {
  color: var(--text);
}
.backdrop-date-radio.is-on {
  background: rgba(96, 115, 101, 0.85);
  color: #fff;
}

/* Live preview of the assembled date string — small, italic, dim. */
.backdrop-date-preview {
  margin-top: 0.6rem;
  padding: 0.5rem 0.75rem;
  background: rgba(255, 255, 255, 0.6);
  border-radius: 6px;
  font-size: 0.78rem;
  font-style: italic;
  color: var(--text, #2c2620);
  line-height: 1.4;
  border-left: 2px solid rgba(96, 115, 101, 0.5);
}
.backdrop-date-preview-empty {
  color: var(--muted);
  font-style: italic;
}
.backdrop-typo-chip-font.is-on {
  border-color: #a17b3e;
  box-shadow: 0 0 0 2px rgba(201, 162, 90, 0.35);
}

/* Color swatch — circle with the theme's name color outside and accent
   color in a tiny inner ring (so 2-tone themes are visible at a glance). */
.backdrop-typo-swatch {
  appearance: none;
  width: 1.7rem;
  height: 1.7rem;
  border-radius: 50%;
  border: 1px solid rgba(120, 100, 80, 0.22);
  cursor: pointer;
  padding: 0;
  background:
    radial-gradient(circle at center, var(--swatch-accent, var(--swatch)) 0 35%, transparent 36%),
    var(--swatch, #f5e9d0);
  transition: transform 0.08s ease, box-shadow 0.12s ease, border-color 0.12s ease;
}
.backdrop-typo-swatch:hover {
  transform: translateY(-1px) scale(1.04);
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.12);
}
.backdrop-typo-swatch.is-on {
  border-color: #a17b3e;
  box-shadow: 0 0 0 2px rgba(201, 162, 90, 0.45);
}

/* Custom color swatch — wraps a hidden native color input. Shows a
   small "+" icon overlay so the family knows it's not a preset. */
.backdrop-typo-swatch-custom {
  position: relative;
  overflow: hidden;
  background:
    conic-gradient(from 0deg, #c9a25a, #b04848, #4a5448, #607365, #c9a25a),
    var(--swatch, #c9a25a);
  /* Layered conic gives the swatch a multi-color "pick any" look. */
}
.backdrop-typo-swatch-custom .backdrop-typo-swatch-custom-icon {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.85rem;
  font-weight: 700;
  color: #fff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
  pointer-events: none;
}
.backdrop-typo-swatch-custom input[type="color"] {
  /* Hide the native input behind the swatch — clicks bubble through
     from the label so the native picker opens, but the swatch is
     what the user sees. */
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
  border: 0;
  padding: 0;
}

.preview-expanded .preview-stage {
  width: 100%;
  /* Stage stays 16:9 but can grow much bigger inside the modal. */
}

.preview-expanded-caption {
  margin: 0;
  text-align: center;
  font-size: 0.95rem;
  color: rgba(255, 253, 247, 0.75);
}

.preview-expanded-close {
  position: absolute;
  top: 1.2rem;
  right: 1.2rem;
  /* LB7 — the enlarged .preview-stage is a positioned sibling rendered AFTER
     this button, so with both at z-index:auto the stage painted on top and
     swallowed every click on the ×; Escape was the only way out. An explicit
     z-index (above the .preview-expanded-toolbar's 12) puts the button back
     on top wherever it is used. Harmless for the toolbar variant, which sets
     position:static on this class. */
  z-index: 20;
  width: 2.8rem;
  height: 2.8rem;
  border-radius: 50%;
  background: rgba(255, 253, 247, 0.92);
  border: 0;
  color: var(--ink);
  font-size: 1.8rem;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: inherit;
}

.preview-expanded-close:hover {
  background: #fff;
}

.preview-pane-hint {
  font-size: 0.72rem;
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
  color: var(--muted);
  margin-left: 0.4rem;
}

/* Preview pane header — wraps the eyebrow + Mode toggle on the same row. */
.preview-pane-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.5rem;
}
.preview-pane-header .eyebrow {
  margin: 0;
}

/* === Backdrop preview rail: 3 orientation cards + global actions === */
.preview-rail-actions {
  display: flex;
  gap: 0.4rem;
}
.preview-rail-btn {
  font: inherit;
  font-size: 0.78rem;
  font-weight: 600;
  padding: 0.32rem 0.78rem;
  border-radius: 999px;
  border: 1px solid var(--border, rgba(0, 0, 0, 0.16));
  background: transparent;
  color: var(--text, #2c2620);
  cursor: pointer;
  transition: background 80ms ease, border-color 80ms ease, filter 80ms ease;
}
.preview-rail-btn:hover { background: rgba(0, 0, 0, 0.05); }
.preview-rail-btn.is-primary {
  background: var(--accent, #6b4f2a);
  border-color: var(--accent, #6b4f2a);
  color: #fff;
}
.preview-rail-btn.is-primary:hover { filter: brightness(1.06); }

.preview-rail-cards {
  display: grid;
  gap: 0.7rem;
}
.preview-rail-card {
  display: grid;
  gap: 0.3rem;
  padding: 0;
  border: none;
  background: transparent;
  cursor: pointer;
  text-align: left;
  font: inherit;
  width: 100%;
}
.preview-rail-card-label {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--muted, #8a7f6f);
}
.preview-rail-card-stage {
  position: relative;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
  transition: box-shadow 110ms ease, transform 110ms ease;
}
.preview-rail-card:hover .preview-rail-card-stage {
  box-shadow: 0 5px 16px rgba(0, 0, 0, 0.22);
  transform: translateY(-1px);
}
.preview-rail-card-stage .preview-stage { border-radius: 12px; }
.preview-rail-card-empty {
  display: grid;
  place-items: center;
  aspect-ratio: 16 / 9;
  border-radius: 12px;
  border: 1px dashed var(--border, rgba(0, 0, 0, 0.22));
  background: rgba(0, 0, 0, 0.02);
  color: var(--muted, #8a7f6f);
  font-size: 0.8rem;
  font-style: italic;
  text-align: center;
  padding: 0 1rem;
}

/* Stack wrapper — holds the toggle-row + optional orientation row
   in a deterministic column. Centers the rows in the expanded
   lightbox toolbar (absolutely positioned, content-sized). */
.preview-toggle-stack {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.45rem;
}

/* Wraps the Video/Edit segmented control + optional Snap toggle on
   the same row in the preview header / lightbox toolbar. */
.preview-toggle-row {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

/* Orientation filter row — sits directly UNDER the Video/Edit toggle
   in edit mode. 3 pills (Portrait / Square / Landscape) with a count
   chip showing how many photos of each orientation exist. */
.preview-orientation-toggle {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.45rem;
}
.preview-orientation-btn {
  appearance: none;
  border: 1px solid rgba(15, 15, 15, 0.12);
  background: #fff;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
  color: var(--muted, #6a6a6a);
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}
.preview-orientation-btn:hover:not(.is-disabled) {
  color: var(--text, #111);
}
.preview-orientation-btn.is-active {
  background: rgba(96, 115, 101, 0.16);
  border-color: rgba(96, 115, 101, 0.45);
  color: #2d3a31;
}
.preview-orientation-btn.is-disabled {
  opacity: 0.4;
  cursor: not-allowed;
  background: #f7f5ef;
}
.preview-orientation-count {
  display: inline-block;
  font-size: 0.68rem;
  background: rgba(15, 15, 15, 0.08);
  padding: 1px 6px;
  border-radius: 999px;
  letter-spacing: 0;
  font-weight: 700;
}
.preview-orientation-btn.is-active .preview-orientation-count {
  background: rgba(96, 115, 101, 0.32);
  color: #1d2520;
}
/* Dark variant for the expanded lightbox toolbar. */
.preview-expanded-toolbar .preview-orientation-btn {
  background: rgba(255, 255, 255, 0.1);
  border-color: rgba(255, 255, 255, 0.18);
  color: rgba(255, 255, 255, 0.72);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.preview-expanded-toolbar .preview-orientation-btn.is-active {
  background: rgba(160, 200, 175, 0.32);
  border-color: rgba(160, 200, 175, 0.55);
  color: #f1faf3;
}
.preview-expanded-toolbar .preview-orientation-count {
  background: rgba(255, 255, 255, 0.18);
  color: rgba(255, 255, 255, 0.85);
}

/* Enlarge button — shown on the small preview pane when in EDIT mode,
   since the stage click is hijacked by drag interactions and the
   normal click-to-enlarge stops working. */
.preview-enlarge-btn {
  appearance: none;
  border: 1px solid rgba(15, 15, 15, 0.12);
  background: #fff;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
  color: var(--muted, #6a6a6a);
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
  line-height: 1.4;
}
.preview-enlarge-btn:hover {
  background: #f7f5ef;
  color: #2a2a2a;
  border-color: rgba(15, 15, 15, 0.2);
}

/* Snap on/off pill. Subtle gold accent when on (matches snap guide
   color), neutral gray when off. */
.snap-toggle {
  appearance: none;
  border: 1px solid rgba(15, 15, 15, 0.12);
  background: #fff;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
  color: var(--muted, #6a6a6a);
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
  line-height: 1.4;
}
.snap-toggle.is-on {
  background: rgba(201, 162, 90, 0.14);
  border-color: rgba(201, 162, 90, 0.5);
  color: #5a4220;
}
.snap-toggle.is-off {
  background: #f7f5ef;
  color: var(--muted, #888);
  border-color: rgba(15, 15, 15, 0.1);
}
.snap-toggle:hover {
  filter: brightness(0.97);
}
/* Dark-background variant for the expanded lightbox toolbar. */
.preview-expanded-toolbar .snap-toggle {
  background: rgba(255, 255, 255, 0.12);
  border-color: rgba(255, 255, 255, 0.2);
  color: rgba(255, 255, 255, 0.72);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.preview-expanded-toolbar .snap-toggle.is-on {
  background: rgba(201, 162, 90, 0.35);
  border-color: rgba(201, 162, 90, 0.6);
  color: #fff7e0;
}

/* Mode toggle — segmented control switching between Video (cycle) and
   Edit (frozen, draggable). Same component in the small pane and the
   expanded lightbox toolbar. */
.preview-mode-toggle {
  display: inline-flex;
  padding: 2px;
  border-radius: 999px;
  background: rgba(15, 15, 15, 0.06);
  border: 1px solid rgba(15, 15, 15, 0.1);
  gap: 0;
}
.preview-mode-btn {
  appearance: none;
  border: 0;
  background: transparent;
  padding: 4px 12px;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  border-radius: 999px;
  cursor: pointer;
  color: var(--muted, #6a6a6a);
  transition: background 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
}
.preview-mode-btn:hover {
  color: var(--text, #111);
}
.preview-mode-btn.is-active {
  background: #fff;
  color: var(--text, #111);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08), 0 0 0 1px rgba(0, 0, 0, 0.04);
}

/* The expanded preview gets a darker on-image toolbar treatment so the
   toggle reads against the lightbox backdrop. Now a single horizontal
   pill that wraps the mode toggle + snap + filter + close button into
   one cohesive control. */
.preview-expanded-toolbar {
  position: absolute;
  top: 1.1rem;
  left: 50%;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.5rem 0.4rem 0.65rem;
  background: rgba(20, 16, 12, 0.55);
  border: 0.5px solid rgba(255, 253, 247, 0.12);
  border-radius: 999px;
  backdrop-filter: blur(12px) saturate(140%);
  -webkit-backdrop-filter: blur(12px) saturate(140%);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.35);
  /* Above the photo's interactive overlay (z:5) + corner handles (z:6)
     so the pills stay clickable even when the photo extends behind them.
     The dashed frame + handles only need to be on top of the photo, not
     on top of the toolbar. */
  z-index: 12;
  max-width: calc(100% - 2.5rem);
  flex-wrap: nowrap;
  white-space: nowrap;
}

/* Flat-row mode collapses the toggle stack into a single horizontal
   strip so VIDEO/EDIT, snap, and orientation filter all live on one
   line with thin dividers between groups. */
.preview-toggle-stack.is-flat-row {
  flex-direction: row;
  align-items: center;
  gap: 0;
}
.preview-toggle-stack.is-flat-row .preview-toggle-row {
  gap: 0.45rem;
}

/* Thin vertical separator between toolbar groups. */
.preview-toolbar-divider {
  display: inline-block;
  width: 1px;
  height: 14px;
  background: rgba(255, 253, 247, 0.18);
  margin: 0 0.2rem;
}

/* Inline mode for the orientation filter — drops the wrap div's
   margin so it sits flush with neighbors on the same row. */
.preview-orientation-toggle.is-inline {
  margin-top: 0;
  flex-wrap: nowrap;
}

/* Close button INSIDE the toolbar (edit mode) — smaller, transparent
   pill that sits at the right edge of the toolbar instead of floating
   in the corner. */
.preview-expanded-toolbar .preview-expanded-close {
  position: static;
  width: 1.85rem;
  height: 1.85rem;
  font-size: 1.15rem;
  background: rgba(255, 253, 247, 0.1);
  border: 0.5px solid rgba(255, 253, 247, 0.16);
  color: rgba(255, 253, 247, 0.85);
  margin-left: 0.2rem;
}
.preview-expanded-toolbar .preview-expanded-close:hover {
  background: rgba(255, 253, 247, 0.2);
  color: #fff;
}

/* Standalone close (non-edit mode, no toolbar wrapper) keeps the
   original floating treatment. */
.preview-expanded-close-standalone {
  /* All the original .preview-expanded-close rules apply via the base
     class. LB7: guarantee a 44px touch target on small screens, where
     2.8rem can fall under it. */
  min-width: 44px;
  min-height: 44px;
}
.preview-expanded-toolbar .preview-mode-toggle {
  /* The outer toolbar pill already provides the dark blurred backdrop.
     The inner mode toggle just needs a faint inset so its active state
     pops without re-doing the glass effect. */
  background: rgba(0, 0, 0, 0.25);
  border: 0.5px solid rgba(255, 255, 255, 0.08);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
.preview-expanded-toolbar .preview-mode-btn {
  color: rgba(255, 255, 255, 0.7);
}
.preview-expanded-toolbar .preview-mode-btn:hover {
  color: #fff;
}
.preview-expanded-toolbar .preview-mode-btn.is-active {
  background: #fff;
  color: #111;
}

/* Prev / next arrows + counter shown below the stage in edit mode. */
.preview-edit-arrows {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  margin: 0.75rem 0 0.25rem;
  user-select: none;
}
.preview-edit-arrows-single {
  color: var(--muted, #6a6a6a);
  font-size: 0.85rem;
  letter-spacing: 0.03em;
}
.preview-edit-arrow {
  appearance: none;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px solid rgba(0, 0, 0, 0.12);
  background: #fff;
  color: var(--text, #111);
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s ease, transform 0.1s ease, box-shadow 0.15s ease;
}
.preview-edit-arrow:hover {
  background: #f7f5ef;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}
.preview-edit-arrow:active {
  transform: scale(0.96);
}
.preview-edit-counter {
  font-size: 0.85rem;
  letter-spacing: 0.05em;
  color: var(--text, #222);
  min-width: 6rem;
  text-align: center;
}

/* Restart button — REVIEW only, sits to the right of the next-arrow.
   Same shape + size as the chevron arrows so it reads as a third
   peer control. Slightly muted color signals it's a secondary action
   (jump-to-start) not a primary navigation step. */
.preview-edit-restart {
  appearance: none;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px solid rgba(0, 0, 0, 0.12);
  background: #fff;
  color: var(--muted, #6a6a6a);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-left: 0.5rem;
  transition: background 0.15s ease, transform 0.1s ease, box-shadow 0.15s ease, color 0.15s ease;
}
.preview-edit-restart:hover {
  background: #f7f5ef;
  color: var(--text, #111);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}
.preview-edit-restart:active {
  transform: scale(0.96);
}
.preview-expanded-wrapper .preview-edit-restart {
  background: rgba(255, 255, 255, 0.92);
  border-color: rgba(255, 255, 255, 0.5);
  color: rgba(0, 0, 0, 0.55);
}
.preview-expanded-wrapper .preview-edit-restart:hover {
  color: rgba(0, 0, 0, 0.85);
}

/* In the expanded preview, the arrows sit on the dark backdrop. */
.preview-expanded-wrapper .preview-edit-arrows {
  margin-top: 1rem;
}
.preview-expanded-wrapper .preview-edit-arrow {
  background: rgba(255, 255, 255, 0.92);
  border-color: rgba(255, 255, 255, 0.5);
}
.preview-expanded-wrapper .preview-edit-counter {
  color: rgba(255, 255, 255, 0.85);
}
.preview-expanded-wrapper .preview-edit-arrows-single {
  color: rgba(255, 255, 255, 0.7);
}

/* In edit mode, the stage gets a dashed outline to signal "you're
   editing" — but the cursor stays default outside the photo so the
   family doesn't think they can drag the empty backdrop. Cursor:grab
   only appears on the photo itself (.backdrop-interactive-frame). */
.preview-stage.is-edit-mode {
  outline: 2px dashed rgba(180, 140, 60, 0.5);
  outline-offset: 4px;
}
/* The frame sits exactly on the photo's visible bounds (driven by
   --photo-extent-x/y), so making it the grab cursor is pixel-accurate
   to the actual hit zone. pointer-events: auto so the cursor applies,
   but pointerdown bubbles up to the stage-area drag handler anyway. */
.backdrop-stage-area.is-edit-mode .backdrop-interactive-frame {
  cursor: grab;
  pointer-events: auto;
}
.backdrop-stage-area.is-dragging .backdrop-interactive-frame {
  cursor: grabbing;
}

/* Scale template text/caption up in the expanded preview, otherwise the
   small-preview type sizes look tiny relative to the huge stage. */

.preview-stage.expanded.template-heritage .heritage-caption {
  font-size: 4.5rem;
  top: calc(100% + 1.5rem);
  text-shadow:
    0 -2px 0 rgba(40, 22, 8, 0.32),
    0 2px 0 rgba(255, 250, 225, 0.7);
}

.preview-stage.expanded.template-heritage .heritage-slot {
  /* Recenter so the bigger caption doesn't push the photo above midline. */
  transform: translate(-50%, calc(-50% - 3rem));
}

.preview-stage.expanded.template-lantern .lantern-text em {
  font-size: 1.4rem;
  letter-spacing: 0.2em;
}

.preview-stage.expanded.template-lantern .lantern-text h2 {
  font-size: 3.2rem;
}

.preview-stage.expanded.template-lantern .lantern-text span {
  font-size: 1.5rem;
}

/* ---------- Analyzing card ---------- */

.analyzing-card {
  position: relative;
  padding: 3rem 2.5rem 2.5rem;
  border-radius: 20px;
  background:
    radial-gradient(ellipse at top, rgba(217, 139, 67, 0.10) 0%, transparent 60%),
    #fffbf2;
  border: 1px solid rgba(127, 73, 63, 0.16);
  box-shadow: 0 8px 32px rgba(60, 40, 20, 0.08);
  overflow: hidden;
  text-align: center;
  display: grid;
  gap: 1.5rem;
  justify-items: center;
}

.analyzing-glow {
  position: absolute;
  inset: -50% -20%;
  background: radial-gradient(
    ellipse at center,
    rgba(217, 139, 67, 0.18) 0%,
    rgba(217, 139, 67, 0.08) 30%,
    transparent 60%
  );
  pointer-events: none;
  animation: analyzing-breathe 3.5s ease-in-out infinite;
}

@keyframes analyzing-breathe {
  0%, 100% { opacity: 0.55; transform: scale(0.95); }
  50% { opacity: 1; transform: scale(1.05); }
}

.analyzing-thumbs {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  height: 4.5rem;
}

.analyzing-thumb {
  width: 3.5rem;
  height: 3.5rem;
  border-radius: 8px;
  overflow: hidden;
  position: relative;
  opacity: 0.28;
  transform: scale(0.92);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
  animation: analyzing-scan var(--scan-cycle, 5000ms) ease-in-out infinite;
  /* Each thumb has its own animation-delay set inline so the bright moment
     moves sequentially across the row. */
}

.analyzing-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

@keyframes analyzing-scan {
  /* Dim resting state for ~88% of the cycle, then a clear "this one's being
     read right now" spike with a glow ring and lift. */
  0%, 100% {
    opacity: 0.28;
    transform: scale(0.92);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
  }
  4% {
    opacity: 1;
    transform: scale(1.18) translateY(-3px);
    box-shadow: 0 0 0 3px rgba(217, 139, 67, 0.5), 0 8px 20px rgba(0, 0, 0, 0.3);
  }
  8% {
    opacity: 1;
    transform: scale(1.18) translateY(-3px);
    box-shadow: 0 0 0 3px rgba(217, 139, 67, 0.5), 0 8px 20px rgba(0, 0, 0, 0.3);
  }
  13% {
    opacity: 0.28;
    transform: scale(0.92);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
  }
}

.analyzing-text {
  position: relative;
  z-index: 1;
  max-width: 36rem;
  display: grid;
  gap: 0.5rem;
}

.analyzing-text h2 {
  font-family: var(--serif, Georgia, "Times New Roman", serif);
  font-size: 2rem;
  font-weight: 500;
  margin: 0;
  line-height: 1.15;
  color: var(--ink);
}

.analyzing-text p {
  margin: 0;
  color: var(--muted);
  font-size: 0.98rem;
  line-height: 1.5;
}

.analyzing-progress {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 28rem;
  height: 6px;
  border-radius: 999px;
  background: rgba(127, 73, 63, 0.12);
  overflow: hidden;
}

.analyzing-progress-bar {
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, #c97a3a 0%, #e0a05a 50%, #c97a3a 100%);
  background-size: 200% 100%;
  transition: width 0.6s ease;
  animation: analyzing-shimmer 2.2s linear infinite;
}

@keyframes analyzing-shimmer {
  from { background-position: 100% 0; }
  to { background-position: -100% 0; }
}

.wizard-steps,
.feature-list,
.history-list,
.chapter-list {
  display: grid;
  gap: 0.75rem;
}

.mini-step {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.7rem;
  align-items: center;
  padding: 0.7rem 0.85rem;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--paper);
  font: inherit;
  color: inherit;
  text-align: left;
  width: 100%;
  transition: background-color 0.18s ease, border-color 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
}

/* Step number circle inside the mini-step. The outer .mini-step rule
   sets the typographic weight; this overrides .step-num's larger
   defaults from the .process-row context. */
.mini-step .step-num {
  width: 2rem;
  height: 2rem;
  font-size: 0.95rem;
  font-weight: 700;
  margin: 0;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid rgba(96, 115, 101, 0.3);
  color: var(--sage);
  background: transparent;
  transition: background-color 0.18s ease, border-color 0.18s ease, color 0.18s ease;
  flex-shrink: 0;
}

.mini-step-body b {
  display: block;
  font-size: 0.95rem;
  color: var(--ink);
  line-height: 1.25;
}

.mini-step-body span {
  display: block;
  margin-top: 0.18rem;
  font-size: 0.82rem;
  color: var(--body);
  line-height: 1.35;
}

/* ----- Active (current step) ----- */
.mini-step.active {
  border-color: rgba(96, 115, 101, 0.55);
  background: #edf3ec;
  box-shadow: 0 1px 0 rgba(96, 115, 101, 0.08), inset 0 0 0 1px rgba(96, 115, 101, 0.1);
}

.mini-step.active .step-num {
  background: var(--sage);
  border-color: var(--sage);
  color: #fffaf3;
}

.mini-step.active .mini-step-body b {
  color: #2d3d2f;
}

/* ----- Completed (a finished step the user can revisit) ----- */
.mini-step.completed {
  cursor: pointer;
  border-color: rgba(96, 115, 101, 0.25);
  background: var(--paper);
}

.mini-step.completed .step-num {
  background: rgba(96, 115, 101, 0.85);
  border-color: rgba(96, 115, 101, 0.85);
  color: #fffaf3;
}

.mini-step.completed:hover {
  background: #f3f7f3;
  border-color: rgba(96, 115, 101, 0.4);
  transform: translateY(-1px);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04);
}

/* ----- Reachable (a future step the user has already unlocked) ----- */
.mini-step.reachable {
  cursor: pointer;
}

.mini-step.reachable:hover {
  background: #f7f3eb;
  border-color: rgba(96, 115, 101, 0.32);
  transform: translateY(-1px);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04);
}

/* ----- Locked (not yet reachable) ----- */
.mini-step.locked,
.mini-step:disabled:not(.active) {
  cursor: not-allowed;
  opacity: 0.55;
}

.mini-step.locked .step-num {
  border-style: dashed;
}

/* Active step is still :disabled (so it can't be re-clicked into self),
   but we don't want to dim it visually. The :not(.active) above handles
   the opacity; this keeps the cursor a hint that it's the current step. */
.mini-step.active:disabled {
  cursor: default;
  opacity: 1;
}

.card,
.chapter,
.project-card {
  padding: 1rem;
}

.chapter-photo {
  aspect-ratio: 4 / 3;
}

.photo-analysis-list {
  display: grid;
  gap: 0.75rem;
  margin-top: 1rem;
}

.photo-analysis-row {
  display: grid;
  grid-template-columns: 104px 1fr;
  gap: 0.85rem;
  align-items: start;
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 0.75rem;
  background: rgba(255, 253, 248, 0.72);
}

.photo-analysis-row .chapter-photo {
  margin: 0;
}

.photo-analysis-row strong {
  color: var(--ink);
}

.photo-analysis-row p {
  margin: 0.25rem 0 0.65rem;
}

.badge.warn {
  border-color: rgba(202, 167, 101, 0.45);
  background: #f7efd9;
  color: #755a24;
}

.cost-panel {
  display: grid;
  grid-template-columns: minmax(260px, 0.7fr) minmax(0, 1fr);
  gap: 1rem;
  align-items: start;
  margin-top: 1rem;
  border: 1px solid rgba(96, 115, 101, 0.22);
  border-radius: var(--radius);
  padding: 1.15rem 1.25rem;
  background: linear-gradient(180deg, #eef3ea, #f4f2e9);
  position: relative;
}
.cost-panel::after {
  content: ""; position: absolute; top: 12px; right: 14px; width: 26px; height: 26px;
  background: url(/icons/lm-ai-sparkle.png?v=1) no-repeat center / contain; opacity: 0.9; pointer-events: none;
}

.cost-panel h3 {
  margin: 0;
  font-family: Georgia, "Times New Roman", serif;
  font-size: 1.55rem;
  font-weight: 500;
}

.cost-panel p {
  margin: 0.45rem 0 0;
  color: var(--body);
  line-height: 1.5;
}

.cost-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px;
  overflow: hidden;
  border: 1px solid rgba(63, 88, 103, 0.18);
  border-radius: 6px;
  background: rgba(63, 88, 103, 0.18);
}

.cost-grid div {
  padding: 0.75rem;
  background: rgba(255, 253, 248, 0.78);
}

.cost-grid b,
.cost-grid span {
  display: block;
}

.cost-grid b {
  color: var(--ink);
  font-size: 1.05rem;
}

.cost-grid span {
  margin-top: 0.2rem;
  color: var(--body);
  font-size: 0.78rem;
  line-height: 1.25;
}

.source-thumb,
.history-thumb {
  aspect-ratio: 4 / 3;
}

.feature-btn {
  width: 100%;
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 0.85rem;
  background: var(--paper);
  color: var(--ink);
  text-align: left;
}

.feature-btn span {
  color: var(--body);
  line-height: 1.45;
}

.lab-preview {
  position: relative;
  overflow: hidden;
  min-height: 420px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: #111;
}

.lab-preview.depth img,
.lab-preview.presence img {
  animation: slowPush 7s ease-in-out infinite alternate;
}

.lab-preview.restore::after {
  content: "";
  position: absolute;
  inset: 0 48% 0 0;
  border-right: 1px solid rgba(255, 255, 255, 0.7);
  background: rgba(255, 253, 248, 0.2);
  -webkit-backdrop-filter: saturate(0.2) blur(1px);
  backdrop-filter: saturate(0.2) blur(1px);
  animation: reveal 5s ease-in-out infinite alternate;
}

.lab-preview.marble img {
  filter: grayscale(1) contrast(1.1) brightness(1.08);
}

.lab-preview.wall {
  box-shadow: inset 0 0 90px rgba(202, 167, 101, 0.26);
}

@keyframes slowPush {
  from { transform: scale(1); }
  to { transform: scale(1.055); }
}

@keyframes reveal {
  from { inset-right: 78%; }
  to { inset-right: 12%; }
}

.history-item {
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 0.75rem;
  background: var(--paper);
}

.project-card {
  overflow: hidden;
  padding: 0;
}

.toast {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  display: flex;
  align-items: center;
  gap: 0.9rem;
  /* Above all modals (lightbox is 100, draft player lightbox is 100,
     restore review is 100). Toasts about background work should always
     be visible — they're the only feedback for async operations. */
  z-index: 200;
  border-radius: 6px;
  padding: 0.85rem 1rem;
  background: var(--ink);
  color: var(--paper);
  box-shadow: var(--shadow);
  max-width: 90vw;
}

.toast-action {
  flex: 0 0 auto;
  border: 1px solid rgba(255, 255, 255, 0.4);
  background: transparent;
  color: var(--paper);
  font: inherit;
  font-weight: 800;
  font-size: 0.82rem;
  padding: 0.3rem 0.7rem;
  border-radius: 999px;
  cursor: pointer;
}

.toast-action:hover {
  background: rgba(255, 255, 255, 0.16);
}

/* Branded confirmation dialog. */
.lm-modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 9998;
  background: rgba(20, 14, 12, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}

.lm-modal {
  background: var(--paper, #fffdf8);
  border-radius: 14px;
  padding: 1.5rem 1.6rem 1.3rem;
  max-width: 27rem;
  width: 100%;
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.35);
}

.lm-modal-title {
  margin: 0 0 0.5rem;
  font-size: 1.25rem;
  color: var(--ink);
}

.lm-modal-body {
  margin: 0 0 1.3rem;
  color: var(--body);
  line-height: 1.5;
  font-size: 0.95rem;
}

.lm-modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.6rem;
  flex-wrap: wrap;
}

.primary-btn.is-danger {
  background: #9a3b30;
  border-color: #9a3b30;
}

.primary-btn.is-danger:hover {
  background: #7f2f26;
}

@media (max-width: 1020px) {
  .site-hero,
  .section-intro,
  .trust-section,
  .wizard,
  .lab-layout,
  .module-card,
  .cost-panel {
    grid-template-columns: 1fr;
  }

  .site-hero {
    min-height: auto;
    align-items: start;
  }

  .hero-copy-block {
    max-width: 760px;
  }

  .included-grid,
  .grid.four {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 720px) {
  .topbar {
    position: static;
    align-items: center;
    flex-direction: row;
    gap: 0.75rem;
    padding-top: 0.9rem;
    padding-bottom: 0.9rem;
  }

  .nav {
    width: auto;
    margin-left: auto;
    gap: 0.6rem;
  }

  .nav a,
  .nav button:not(.primary-btn) {
    display: none;
  }

  .brand-mark {
    width: 2.45rem;
    height: 2.45rem;
  }

  .brand-name {
    font-size: 1rem;
  }

  .nav .primary-btn {
    flex: 0 0 auto;
    min-height: 2.35rem;
    padding: 0.58rem 0.72rem;
    font-size: 0.82rem;
  }

  .site-hero {
    gap: 1.65rem;
    padding-top: 1.35rem;
  }

  .hero-copy-block h1 {
    font-size: clamp(2.2rem, 9.8vw, 3rem);
    line-height: 1.04;
  }

  .hero-copy {
    margin-top: 0.95rem;
    font-size: 1rem;
    line-height: 1.62;
  }

  .hero-actions {
    align-items: center;
    flex-direction: row;
  }

  .hero-actions .primary-btn {
    width: auto;
  }

  .studio-note {
    margin-top: 1.5rem;
  }

  .hero-actions {
    align-items: stretch;
    flex-direction: column;
  }

  .hero-actions .primary-btn {
    width: 100%;
  }

  .service-points,
  .proof-bar,
  .film-caption-row,
  .deliverable-panel,
  .tone-cards,
  .cost-grid,
  .included-grid,
  .grid.two,
  .grid.three,
  .grid.four,
  .analysis-grid {
    grid-template-columns: 1fr;
  }

  .cinema-still {
    min-height: 340px;
  }

  .hero-portrait-still {
    min-width: 142px;
    top: 12%;
  }

  .memory-print {
    min-width: 78px;
  }

  .print-three {
    right: 8%;
  }

  .still-caption b {
    font-size: clamp(1.8rem, 9vw, 2.7rem);
  }

  .film-caption-row span,
  .proof-bar span,
  .included-card {
    border-right: 0;
    border-bottom: 1px solid var(--line);
  }

  .film-caption-row span:last-child,
  .proof-bar span:last-child,
  .included-card:last-child {
    border-bottom: 0;
  }

  .proof-bar span {
    min-height: auto;
  }

  .preview-label,
  .page-head,
  .chapter-top {
    flex-direction: column;
    align-items: flex-start;
  }

  .process-row {
    grid-template-columns: 1fr;
    gap: 0.75rem;
  }

  .photo-analysis-row {
    grid-template-columns: 1fr;
  }
}

/* ---------- Missing-year review modal ---------- */

.missing-year-backdrop {
  position: fixed;
  inset: 0;
  z-index: 110;
  background: rgba(20, 14, 10, 0.78);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  animation: lightbox-fade 0.2s ease;
}

.missing-year-modal {
  position: relative;
  width: min(820px, 100%);
  max-height: 88vh;
  overflow-y: auto;
  background: var(--paper);
  border-radius: 12px;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.4);
  padding: 1.5rem 1.6rem 1.6rem;
  font-family: inherit;
  color: var(--ink);
}

.missing-year-close {
  position: absolute;
  top: 0.7rem;
  right: 0.8rem;
  width: 2.2rem;
  height: 2.2rem;
  border-radius: 50%;
  background: rgba(255, 253, 247, 0.92);
  border: 1px solid var(--line);
  color: var(--ink);
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: inherit;
}

.missing-year-close:hover {
  background: #f3eee4;
}

.missing-year-header {
  margin-bottom: 1rem;
  padding-right: 2.5rem;
}

.missing-year-header h3 {
  margin: 0.2rem 0 0.35rem;
  font-family: Georgia, "Times New Roman", serif;
  font-size: 1.4rem;
  font-weight: 500;
}

.missing-year-header p {
  margin: 0;
  color: var(--body);
  line-height: 1.45;
}

.missing-year-body {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.1rem;
  align-items: start;
}

.missing-year-photo {
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #1a1410;
  overflow: hidden;
  aspect-ratio: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

.missing-year-photo img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

.missing-year-form {
  display: grid;
  gap: 0.7rem;
}

.missing-year-guess {
  margin: 0 0 0.2rem;
  color: var(--body);
  font-size: 0.92rem;
}

.missing-year-field {
  display: grid;
  gap: 0.3rem;
}

.missing-year-field span {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--body);
}

.missing-year-field input {
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: #fff;
  font-family: inherit;
  font-size: 1rem;
  color: var(--ink);
}

.missing-year-field input:focus {
  outline: none;
  border-color: rgba(96, 115, 101, 0.55);
  box-shadow: 0 0 0 3px rgba(96, 115, 101, 0.12);
}

.missing-year-or {
  margin: 0;
  text-align: center;
  color: var(--body);
  font-size: 0.82rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.missing-year-actions {
  display: flex;
  gap: 0.55rem;
  justify-content: flex-end;
  margin-top: 0.4rem;
}

.missing-year-done {
  text-align: center;
  padding: 1rem 0.5rem 0.3rem;
}

.missing-year-done h3 {
  margin: 0 0 0.4rem;
  font-family: Georgia, "Times New Roman", serif;
  font-size: 1.5rem;
  font-weight: 500;
}

.missing-year-done p {
  margin: 0 0 1.1rem;
  color: var(--body);
}

@media (max-width: 720px) {
  .missing-year-body {
    grid-template-columns: 1fr;
  }
}

/* ---------- Backdrop template ---------- */
/* The user uploads any image as the background — landscape, paper,
   painting, solid color, anything — and each slideshow photo plays in
   front of it in a cream matte. A configurable dim + static vignette
   keep the slideshow photo as the focal point. */

.preview-stage.template-backdrop {
  background: #1a130d;
  overflow: hidden;
  position: relative;
}

/* The uploaded backdrop fills the entire stage via cover. */
.backdrop-image {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  pointer-events: none;
}

/* The configurable flat dim. Inline style sets opacity per the slider
   value. Sits above the backdrop, below the vignette. */
.backdrop-dim {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: #0a0704;
}

/* A static soft vignette on top of the dim — pulls the corners down a
   touch so the slideshow photo (which sits center) has a quiet pocket
   around it. Doesn't scale with the dim slider. */
.backdrop-vignette {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(
    ellipse at center,
    rgba(0, 0, 0, 0) 40%,
    rgba(0, 0, 0, 0.35) 100%
  );
}

/* Empty state: no backdrop uploaded yet. Sized for the small preview
   pane first (the common case) and scaled up via the expanded-modal
   override below. */
.backdrop-empty {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  background:
    repeating-linear-gradient(
      45deg,
      rgba(255, 250, 240, 0.04),
      rgba(255, 250, 240, 0.04) 16px,
      rgba(255, 250, 240, 0) 16px,
      rgba(255, 250, 240, 0) 32px
    ),
    linear-gradient(to bottom, #2a2118 0%, #1a130d 100%);
  color: #f3ead2;
  text-align: center;
}

.backdrop-empty-inner {
  max-width: 24rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
}

.backdrop-empty-inner .eyebrow {
  color: rgba(243, 234, 210, 0.7);
  font-size: 0.65rem;
  margin: 0;
}

.backdrop-empty-inner h3 {
  margin: 0;
  font-family: Georgia, "Times New Roman", serif;
  font-size: 1rem;
  font-weight: 500;
  line-height: 1.2;
  color: #f3ead2;
}

.backdrop-empty-inner p {
  margin: 0;
  color: rgba(243, 234, 210, 0.78);
  font-size: 0.78rem;
  line-height: 1.4;
}

.backdrop-empty-btn {
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.4rem;
  font-size: 0.82rem;
  padding: 0.5rem 0.95rem;
}

/* Expanded preview (full-screen modal): scale the empty state up so it
   doesn't look comically small inside the big stage. */
.preview-stage.expanded .backdrop-empty {
  padding: 2rem;
}

.preview-stage.expanded .backdrop-empty-inner {
  max-width: 32rem;
  gap: 0.6rem;
}

.preview-stage.expanded .backdrop-empty-inner .eyebrow {
  font-size: 0.8rem;
}

.preview-stage.expanded .backdrop-empty-inner h3 {
  font-size: 1.7rem;
}

.preview-stage.expanded .backdrop-empty-inner p {
  font-size: 1rem;
  line-height: 1.55;
}

.preview-stage.expanded .backdrop-empty-btn {
  margin-top: 0.6rem;
  font-size: 0.95rem;
  padding: 0.65rem 1.2rem;
}

/* The stage area holds the photo slots, centered. */
.backdrop-stage-area {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}

/* Edit mode re-enables pointer events so the drag handler (bound on
   the stage-area) actually fires. Without this the .backdrop-image,
   .backdrop-dim and .backdrop-vignette siblings sit underneath but
   pointer-events: none on stage-area swallowed the click silently. */
.backdrop-stage-area.is-edit-mode {
  pointer-events: auto;
  touch-action: none;
}

/* In edit mode the slot's default 0.4s top/left easing makes the
   photo lag behind the cursor during drag (CSS vars change every
   pointermove → transition kicks in). Also kill the opacity fade so
   the photo doesn't ghost-fade when nav-arrows swap it. */
.backdrop-stage-area.is-edit-mode .backdrop-photo-slot {
  transition: none;
}

/* Slot is a flex bounding box. The inner photo uses object-fit: contain
   so portrait and landscape photos both show in full without cropping.
   For the matte variant, the .backdrop-photo shrinks to the photo's
   actual aspect ratio (set per-photo as a CSS variable on the slot) so
   the matte hugs the photo instead of being a fixed rectangle.

   Opacity defaults to 0; the .active class (added/removed by the
   preview controller for cross-fades) is what reveals a slot. Without
   this rule the transitions wouldn't render — the controller toggles
   .active, not .slot-a/.slot-b. */
.backdrop-photo-slot {
  position: absolute;
  /* Position from the stage-area's CSS vars; for uploads these default
     to 50% / 50% (center), for library backdrops the AI vision pass
     determined the quiet zone and set these per-backdrop. */
  top: var(--photo-pos-y, 50%);
  left: var(--photo-pos-x, 50%);
  width: var(--photo-slot-width, 65%);
  /* Slot height is driven by the same photoSize slider as width — so
     dragging size actually changes the visible photo proportions for
     both portrait and landscape photos (previously height was fixed,
     which made the slider feel dead for portraits). */
  height: var(--photo-slot-height, 65%);
  transform: translate(-50%, -50%);
  opacity: 0;
  transition: opacity var(--transition-duration, 600ms) ease, top 0.4s ease, left 0.4s ease;
  display: flex;
  align-items: center;
  justify-content: center;
}

.backdrop-photo-slot.active {
  opacity: 1;
}

/* Inactive slots are invisible but still in the DOM — without this,
   slot-b / slot-c silently intercept pointer events meant for the
   active slot-a (their photo divs cover slot-a in single-photo
   layouts), and a click on the visible photo gets swallowed. */
.backdrop-photo-slot:not(.active) {
  pointer-events: none;
}

/* Two-photo split — slot-b becomes a real second photo using its own
 * CSS vars. Slot-a continues to use --photo-pos-x/y; slot-b switches
 * to --photo-pos-x-b/y-b/slot-width-b/slot-height-b so the two photos
 * sit independently side by side. */
.backdrop-stage-area.is-two-photo .backdrop-photo-slot.slot-b,
.backdrop-stage-area.is-three-photo .backdrop-photo-slot.slot-b {
  top: var(--photo-pos-y-b, 50%);
  left: var(--photo-pos-x-b, 73%);
  width: var(--photo-slot-width-b, 40%);
  height: var(--photo-slot-height-b, 40%);
}
/* Three-photo collage — slot-c becomes the third photo. Same pattern
 * as slot-b: switches to --photo-pos-x-c/y-c/slot-width-c/slot-height-c
 * so three photos can be positioned independently across the stage. */
.backdrop-stage-area.is-three-photo .backdrop-photo-slot.slot-c {
  top: var(--photo-pos-y-c, 50%);
  left: var(--photo-pos-x-c, 82%);
  width: var(--photo-slot-width-c, 30%);
  height: var(--photo-slot-height-c, 30%);
}

/* Reverted to fill-slot. Year overlays now position at the stage
   level (siblings of slots, not children of .backdrop-photo) so they
   don't depend on this wrapper matching the photo aspect. */
.backdrop-photo {
  width: 100%;
  height: 100%;
  display: block;
  filter:
    drop-shadow(0 var(--shadow-y-1, 14px) var(--shadow-blur-1, 30px) rgba(0, 0, 0, var(--shadow-alpha-1, 0.55)))
    drop-shadow(0 var(--shadow-y-2, 3px) var(--shadow-blur-2, 8px) rgba(0, 0, 0, var(--shadow-alpha-2, 0.4)));
}

.backdrop-photo img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

/* With-matte variant: the .backdrop-photo shrinks to wrap the photo via
   aspect-ratio (set on the slot per-photo). The matte hugs the photo —
   no oversized rectangle around a portrait image. The IMG fills the
   padded inner area via cover. Color and thickness are driven by CSS
   variables set on the stage (.preview-stage.template-backdrop). */
.backdrop-photo.has-matte {
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
  aspect-ratio: var(--photo-aspect, 3 / 2);
  background: var(--matte-color, #f3ead2);
  /* Slightly more padding on the bottom for the classic memorial-print
     proportions — but only enough to read at every thickness. */
  padding:
    var(--matte-size, 4px)
    var(--matte-size, 4px)
    calc(var(--matte-size, 4px) * 1.4)
    var(--matte-size, 4px);
  box-sizing: border-box;
}

.backdrop-photo.has-matte img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Photo treatment — clip + frame variants. The class is computed from
   the active backdrop's photoTreatment (title-card-sourced backdrops
   come pre-baked; the toolbar Shape chip overrides). ornate_frame and
   clean_rectangle are no-ops (no clip) because the frame is part of
   the backdrop image itself. */
.backdrop-photo.treatment-oval {
  border-radius: 50%;
  overflow: hidden;
}
.backdrop-photo.treatment-oval img,
.backdrop-photo.treatment-oval .backdrop-dim {
  border-radius: 50%;
}
.backdrop-photo.treatment-circular {
  border-radius: 50%;
  overflow: hidden;
  aspect-ratio: 1 / 1;
}
.backdrop-photo.treatment-circular img,
.backdrop-photo.treatment-circular .backdrop-dim {
  border-radius: 50%;
}
.backdrop-photo.treatment-polaroid {
  background: #fafaf3;
  padding: 4% 4% 16% 4%;
  border-radius: 2px;
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.32), 0 1px 3px rgba(0, 0, 0, 0.18);
  transform: rotate(-1.4deg);
  transform-origin: center;
}
.backdrop-photo.treatment-polaroid img {
  border-radius: 1px;
}

/* Expanded view used to force the slot to 60% × 63%, which ignored
   the user's photo-size slider and made expanded ≠ small preview. Now
   we let --photo-slot-width / --photo-slot-height (set inline from
   photoSize) drive both views identically. */

/* === Title card preview (Opening / Closing tabs) ===
   Renders a 16:9 stage at full width of the card with the AI
   backdrop, the family's portrait, and the typography overlaid at
   the AI-determined coordinates. Same compositional fidelity as a
   pro After Effects template, built with CSS. */
.titlecard-preview-wrap {
  display: block;
  width: 100%;
  min-width: 100%;
  margin-top: 0.5rem;
  cursor: zoom-in;
}
.titlecard-preview-wrap:hover .titlecard-stage {
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.25);
}
/* Expanded title card lightbox (click preview → modal). Now includes
   a side panel of editable controls so the family can tweak the card
   and see the change live in the big preview. */
.titlecard-expanded {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: rgba(0, 0, 0, 0.92);
  display: flex;
  align-items: stretch;
  justify-content: stretch;
  cursor: zoom-out;
}
.titlecard-expanded-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 380px;
  width: 100%;
  height: 100%;
  cursor: default;
}
@media (max-width: 900px) {
  .titlecard-expanded-layout {
    grid-template-columns: 1fr;
    grid-template-rows: 1fr auto;
  }
}
.titlecard-expanded-stage-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2.5vw;
  min-width: 0;
  min-height: 0;
}
.titlecard-expanded-stage {
  width: 100%;
  max-width: calc((100vh - 5vw) * 16 / 9); max-width: calc((100dvh - 5vw) * 16 / 9);
  max-height: calc(100vh - 5vw); max-height: calc(100dvh - 5vw);
}
.titlecard-expanded-controls {
  background: var(--bg-soft, #f5efe1);
  color: var(--text, #2c2620);
  overflow-y: auto;
  padding: 1.25rem 1.25rem 2rem;
  border-left: 1px solid rgba(120, 100, 80, 0.2);
}
.titlecard-expanded-controls-title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  /* Clear room for the floating close X (top: 1rem; right: 1rem; 40px wide).
     Without this padding the snap toggle pill ends up hiding behind the X. */
  padding-right: 3.25rem;
}
.titlecard-expanded-controls-title-row h3 {
  margin: 0;
}
.titlecard-expanded-controls-header kbd {
  display: inline-block;
  padding: 1px 6px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.72em;
  background: rgba(120, 100, 80, 0.12);
  border: 1px solid rgba(120, 100, 80, 0.25);
  border-radius: 4px;
  color: var(--body);
  line-height: 1.4;
}

.titlecard-expanded-controls-header {
  position: sticky;
  top: 0;
  background: var(--bg-soft, #f5efe1);
  padding-bottom: 0.75rem;
  margin-bottom: 0.5rem;
  border-bottom: 1px solid rgba(120, 100, 80, 0.18);
  z-index: 2;
}
.titlecard-expanded-controls-header h3 {
  margin: 0;
  font-size: 1.1rem;
}
.titlecard-expanded-controls-header p {
  margin: 0.25rem 0 0;
  font-size: 0.85rem;
  opacity: 0.7;
}
.titlecard-expanded-controls-body .matte-control {
  margin-top: 0.75rem !important;
}
.titlecard-expanded-close {
  position: absolute;
  top: 1rem;
  right: 1rem;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: none;
  background: white;
  color: #222;
  font-size: 1.6rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  z-index: 10;
}
.titlecard-stage {
  position: relative;
  display: block;
  width: 100%;
  /* 7/4 (1.75:1) matches gpt-image-1's native 1792×1024 output exactly.
     Using 16/9 (1.78:1) caused either letterbox bars (object-fit:
     contain) or top/bottom cropping of painted frames (object-fit:
     cover). Matching the image's real aspect lets the background fill
     the stage edge-to-edge with no bars and no cropping. */
  aspect-ratio: 7 / 4;
  border-radius: 12px;
  overflow: hidden;
  background: #1b1612;
  container-type: inline-size;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.18);
}

/* Edit-mode affordances on the title card stage:
   - portrait + text name get cursor:grab + hover outline so the family
     sees they're interactive
   - 4 gold corner handles on the portrait flow from --portrait-size /
     --portrait-height (which already drive the portrait's visible bounds) */
.titlecard-stage.is-edit-mode {
  outline: 2px dashed rgba(180, 140, 60, 0.5);
  outline-offset: 4px;
}

.titlecard-portrait.is-editable {
  cursor: grab;
  outline: 1px dashed rgba(201, 162, 90, 0);
  outline-offset: 2px;
  transition: outline-color 120ms ease;
  touch-action: none;
}
.titlecard-portrait.is-editable:hover {
  outline-color: rgba(201, 162, 90, 0.85);
}
.titlecard-portrait.is-editable.is-dragging,
.titlecard-portrait.is-editable.is-resizing {
  cursor: grabbing;
  outline-color: rgba(201, 162, 90, 1);
}

.titlecard-name.is-editable {
  cursor: grab;
  padding: 0.05em 0.3em;
  border-radius: 4px;
  outline: 1px dashed rgba(201, 162, 90, 0);
  transition: outline-color 120ms ease, background-color 120ms ease;
  touch-action: none;
}
.titlecard-name.is-editable:hover {
  outline-color: rgba(201, 162, 90, 0.85);
  background-color: rgba(201, 162, 90, 0.08);
}
.titlecard-name.is-editable.is-dragging {
  cursor: grabbing;
  outline-color: rgba(201, 162, 90, 1);
  background-color: rgba(201, 162, 90, 0.14);
}

/* Path A (titlecard) per-element z-index lift in EDIT mode. Same
   fix as #36 but for the title card renderer — the .backdrop-group-box
   sits at z-index 6 (above the interactive frame at 5), and without
   this lift the editable title card elements get covered by the group
   box and can't be clicked / dragged / resized. Lift to 7 so per-
   element interaction wins over the group box, while group-body drag
   still works because the group box's body region is outside each
   element's bounding rect.
   Note: only .titlecard-name gets an .is-editable class in EDIT mode;
   preamble and dates rely on selection/drag data attributes instead,
   so we target the elements unconditionally inside .is-edit-mode.

   LO67 — AND THE OTHER TWO KINDS OF PIECE. K: "cant grab this ttext to move
   it", with the group box selected and the sentiment line inside it.
   This lift listed the name, the preamble and the dates and stopped there, so
   the two pieces added to the card LATER were left under the box: a family
   line (.titlecard-extra, z-5) and an ornament (.titlecard-div, z-3). Both are
   pointer-events:auto in the studio and both sit in the middle of the block,
   which is exactly where the group box lies — so every press on them hit the
   box instead and the piece could not be grabbed at all. It also explains
   "hard to hover line ornament" from earlier: LO55 sharpened the ornament's
   hit test while the box was still lying on top of it, which is why that only
   half-worked. Same lift, same reason, all four kinds of piece. An ornament
   drawn behind the portrait now paints in front of it while Move things around
   is on; that is the same thing already happening the moment it is selected
   (z-8 below), and being reachable is worth more than the paint order of a
   hairline in edit mode. */
.titlecard-stage.is-edit-mode .titlecard-name,
.titlecard-stage.is-edit-mode .titlecard-preamble,
.titlecard-stage.is-edit-mode .titlecard-dates,
.titlecard-stage.is-edit-mode .titlecard-extra,
.titlecard-stage.is-edit-mode .titlecard-div {
  z-index: 7;
}

/* WHAT IS SELECTED IS ON TOP (LO27a).
   K: "if i have an elemnt clicked ... it should be on top of the others so i
   should be able to click and drag here not click the name."
   The photo sits at z-index 2 — under the text (7) and under the name's dashed
   group box (6) — so wherever the group box lay across the photograph, a press
   meant to grab the picture grabbed the name instead. Selecting a piece now
   lifts it over its neighbours, which is both what the eye expects of the thing
   it just chose and what makes the next press land on it.
   The photo's FRAME (z-index 3) has to come with it, or the picture would be
   drawn over the gold arch the moment it was selected; the frame keeps its
   place just above the picture. The handles and the reframe chip ride above
   both so they stay grabbable. Every piece plays by the same rule, so nothing
   is trapped: click the name and the name comes up instead. */
.titlecard-stage.is-edit-mode .titlecard-name.is-selected,
.titlecard-stage.is-edit-mode .titlecard-preamble.is-selected,
.titlecard-stage.is-edit-mode .titlecard-dates.is-selected,
.titlecard-stage.is-edit-mode .titlecard-extra.is-selected,
.titlecard-stage.is-edit-mode .titlecard-div.is-selected {
  z-index: 8;
}

/* Photo layering is an authored choice, not a temporary selection effect.
   Default photos remain behind foreground scenery; Front raises the photo and
   its frame above scenery while text (also z-index 5, later in DOM order)
   remains readable above them. */
.titlecard-portrait.tc-photo-front {
  z-index: 5;
}

/* Corner handles on the portrait. Gold dots like the backdrop handles
   so the visual language stays consistent. Positioned at the 4 corners
   of the portrait via its CSS positioning context. */
.titlecard-handle {
  position: absolute;
  width: 12px;
  height: 12px;
  background: #c9a25a;
  border: 2px solid #fff;
  border-radius: 50%;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.35);
  pointer-events: auto;
  opacity: 0;
  transform: scale(0.8);
  transition: opacity 120ms ease, transform 80ms ease;
  z-index: 6;
}
/* HANDLES-OUT — the dots' box: laid over the portrait by JS, nothing of its
   own to hit (the dots are), above the photo and the words. Hidden until
   placed so a fresh paint never shows eight dots in the stage's corner. */
.titlecard-handles{position:absolute;left:0;top:0;width:0;height:0;pointer-events:none;z-index:12;transform:none;}
.titlecard-handles:not(.is-placed){display:none;}
.titlecard-handles .titlecard-handle{pointer-events:auto;}
.titlecard-stage:has(.titlecard-portrait.is-editable.is-selected) .titlecard-handles .titlecard-handle,
.titlecard-stage:has(.titlecard-portrait.is-editable:hover) .titlecard-handles .titlecard-handle,
.titlecard-stage:has(.titlecard-portrait.is-editable.is-dragging) .titlecard-handles .titlecard-handle,
.titlecard-stage:has(.titlecard-portrait.is-editable.is-resizing) .titlecard-handles .titlecard-handle,
.titlecard-handles:hover .titlecard-handle,
.titlecard-portrait.is-editable:hover .titlecard-handle,
.titlecard-portrait.is-editable.is-dragging .titlecard-handle,
.titlecard-portrait.is-editable.is-resizing .titlecard-handle {
  opacity: 1;
  transform: scale(1);
}
.titlecard-handle:hover {
  transform: scale(1.25);
}
/* Corner positions — the portrait is anchored at its CENTER via
   translate(-50%,-50%) (set by .titlecard-portrait). Children placed
   at 0%/100% top/left sit at the portrait's actual corners. */
.titlecard-handle-nw {
  top: -6px; left: -6px; cursor: nwse-resize;
}
.titlecard-handle-ne {
  top: -6px; right: -6px; cursor: nesw-resize;
}
.titlecard-handle-sw {
  bottom: -6px; left: -6px; cursor: nesw-resize;
}
.titlecard-handle-se {
  bottom: -6px; right: -6px; cursor: nwse-resize;
}

/* Edge handles — pills centered along each edge. Wider pill on top/bottom
   (drag up/down to scale height), tall pill on left/right (drag in/out
   to scale width). Bigger hit target than the corner dots so they're
   easy to grab. */
.titlecard-handle-n,
.titlecard-handle-s {
  left: 50%;
  width: 32px;
  height: 8px;
  border-radius: 6px;
  transform: translate(-50%, 0);
  cursor: ns-resize;
}
.titlecard-handle-n { top: -5px; }
.titlecard-handle-s { bottom: -5px; }
.titlecard-handle-e,
.titlecard-handle-w {
  top: 50%;
  width: 8px;
  height: 32px;
  border-radius: 6px;
  transform: translate(0, -50%);
  cursor: ew-resize;
}
.titlecard-handle-e { right: -5px; }
.titlecard-handle-w { left: -5px; }
.titlecard-handle-n:hover,
.titlecard-handle-s:hover { transform: translate(-50%, 0) scale(1.15); }
.titlecard-handle-e:hover,
.titlecard-handle-w:hover { transform: translate(0, -50%) scale(1.15); }

.titlecard-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  /* cover is safe now that the stage aspect (7:4) matches the image
     aspect (1792×1024). Any minor pixel-level rounding gets clipped
     rather than letterboxed. */
  object-fit: cover;
  pointer-events: none;
}

/* Portrait. CSS variable --portrait-size sets the wrapper's width as
   a % of stage width. translate(-50%,-50%) centers on the AI coords.
   Each photo_treatment adds its own framing. */
.titlecard-portrait {
  position: absolute;
  width: var(--portrait-size, 30%);
  height: var(--portrait-height, 40%);
  transform: translate(-50%, -50%);
  overflow: hidden;
  z-index: 2;
  /* LO-REFRAME-2 — the box is a size container so the picture's pan can be
     written in its own units (cqw/cqh) without knowing the box's pixels. */
  container-type: size;
}
.titlecard-portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  /* Portrait crop for the main hero comes from an inline object-view-box
     (the AI's exact rectangle). No crop set → the full photo shows. */
}

/* PHOTO EDGE TINT — the warm lift that sits INSIDE the photo's mask.

   The earlier candlelit attempt put a heavily blurred copy of the cutout
   BEHIND the picture, screened, as "the light around her". Measured against
   the reference that is the wrong operation: in the dissolve band the
   reference both lifts (43% of it) and darkens (42%) relative to the picture,
   and where it darkens it pulls blue out fastest — it warms WHILE it darkens.
   A screen-blend halo can only do the lifting half, and no tuning buys the
   other half. So the halo is gone. Three things replace it, each doing one
   job: maskSrc takes the picture away at the edge, the photo's `grade` filter
   warms the whole picture, and this layer — inside the mask, over the
   picture, screened — puts the warm light back into the band.

   isolation:isolate keeps the screen against the PICTURE. Without it the
   blend reaches the backdrop and the candles behind glow through her. */
.titlecard-portrait.tc-ptint { isolation: isolate; }
.titlecard-portrait.tc-ptint > .tc-photo-tint {
  position: absolute;
  inset: 0;
  background-position: center;
  background-size: 100% 100%;
  background-repeat: no-repeat;
  pointer-events: none;
  z-index: 2;
}
/* The "ornate_frame" backdrops already have a painted decorative
   frame baked into the image. We do NOT add a CSS frame on top —
   that would produce a frame-in-frame look. The portrait just sits
   bare at the AI-determined coordinates, filling the painted frame's
   interior. A very faint shadow blends the photo edge against the
   backdrop without competing with the painted frame. */
.titlecard-portrait.treatment-ornate_frame {
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);
}
.titlecard-portrait.treatment-clean_rectangle,
.titlecard-portrait.treatment-rectangular {
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.5);
}
.titlecard-portrait.treatment-circular {
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.55);
}
.titlecard-portrait.treatment-oval {
  aspect-ratio: 3 / 4;
  border-radius: 50%;
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.55);
}
.titlecard-portrait.treatment-polaroid {
  padding: 0.8cqi 0.8cqi 2.4cqi 0.8cqi;
  background: #f8f3e6;
  border-radius: 2px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
  transform: translate(-50%, -50%) rotate(-2deg);
}

/* Vintage photo-album corner mounts — the Polaroid looks tucked into an
   album page by four triangular paper corners. Drawn as four corner
   triangles via background gradients (one overlay element, no extra DOM),
   sized in cqi so they scale with the stage like everything else. */
.titlecard-portrait.treatment-polaroid::after,
.backdrop-photo.treatment-polaroid::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 4;
  background-image:
    linear-gradient(135deg, var(--album-corner-color, #7a5f3c) 50%, transparent 50%),
    linear-gradient(225deg, var(--album-corner-color, #7a5f3c) 50%, transparent 50%),
    linear-gradient(45deg,  var(--album-corner-color, #7a5f3c) 50%, transparent 50%),
    linear-gradient(315deg, var(--album-corner-color, #7a5f3c) 50%, transparent 50%);
  background-repeat: no-repeat;
  background-position: top left, top right, bottom left, bottom right;
  background-size: 3.2cqi 3.2cqi;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.25));
}

/* Text overlays. All position with translate(-50%,-50%) center
   anchor. Font feel maps to one of a few aesthetic variants. */
.titlecard-preamble,
.titlecard-name,
.titlecard-dates {
  position: absolute;
  /* --fit-scale is set by fitTitlecardText() to shrink a line just enough
     to sit inside its composition text frame (never overflow the card edge
     or the portrait). Defaults to 1 (no scaling). Scaling from the box
     center keeps the line centered on its anchor. --fit-shift nudges a
     line up/down to make room when the name wraps to two lines, so the
     block doesn't collide with its neighbors. */
  transform: translate(-50%, -50%) translateY(var(--fit-shift, 0px)) scale(var(--fit-scale, 1));
  pointer-events: none;
  /* Sit ABOVE .backdrop-group-box (z-index 3) so clicks on individual
     text elements switch selection to that element instead of the group.
     Mirrors Path B's .backdrop-text-* z-index — without this, the group
     box (emitted later in the title-card stage DOM) eats every click
     inside its bounds and selection sticks on the group. */
  z-index: 5;
  text-align: center;
}

/* Path A — when the title card is being used as the main photo's
   renderer inside the main editor, the text elements need to accept
   pointer events so the family can click them to open the floating
   toolbar and drag them around. The base rule above is `pointer-events:
   none` because in playback mode (Draft player, watch surface) text is
   purely decorative. In Path A we re-enable pointer events on the
   preamble / name / dates so all three behave like the other editable
   text blocks. Same hover affordance as the backdrop text. */
.titlecard-stage.backdrop-stage-area .titlecard-preamble,
.titlecard-stage.backdrop-stage-area .titlecard-name,
.titlecard-stage.backdrop-stage-area .titlecard-dates {
  pointer-events: auto;
  cursor: grab;
  /* Horizontal padding for clickability around the text edges, but
     NO vertical padding — vertical padding grows each element's
     bounding box and makes adjacent elements visually overlap (since
     they're absolutely positioned around their text center). Without
     vertical padding the text sits exactly where REVIEW mode renders
     it; with it the boxes squish into each other on entering EDIT. */
  padding: 0 0.35em;
  border-radius: 4px;
  outline: 1px dashed rgba(201, 162, 90, 0);
  transition: outline-color 120ms ease, background-color 120ms ease;
  touch-action: none;
}

/* Path A multi-line dates: anchor the box at TOP-center (not center-center)
   so the FIRST date line stays where the configured `top: Y%` puts it,
   and the second line extends BELOW. Without this, adding a second line
   pushes the first line upward (because translate(-50%, -50%) centers
   the whole block on the anchor). Marked with .dates-multiline by the
   renderer when the resolved dates text contains a \n. Scoped to title
   card stages (.titlecard-dates is title-card-specific) so it applies
   in both the small preview pane and the lightbox. */
.titlecard-dates.dates-multiline {
  transform: translate(-50%, 0) translateY(var(--fit-shift, 0px)) scale(var(--fit-scale, 1));
  transform-origin: top center;
}

/* Multi-line preamble — the family pressed Enter in the custom-wording box.
   pre-line renders the newline as a break; the element is auto-width so it
   only breaks at real newlines, not mid-phrase. fitTitlecardText scales it
   to fit and pushes the name + dates down to clear the extra lines. */
/* Removed element (trash button / Customize "Show" chip off). */
.titlecard-preamble.tc-el-hidden,
.titlecard-name.tc-el-hidden,
.titlecard-dates.tc-el-hidden,
.titlecard-extra.tc-el-hidden { display: none !important; }

/* TEXT-BACKING — a soft shape behind a line of the opening card. A child of
   the line at z-index −1: the line already forms a stacking context
   (position + z-index 5), so the backing paints above the card and below the
   words without touching the line's box. --bk-a is the strength (0..1). */
.tc-backing {
  position: absolute;
  z-index: -1;
  pointer-events: none;
  left: 0; top: 0; right: 0; bottom: 0;
}
.tc-backing-pill {
  left: -0.6em; right: -0.6em; top: -0.12em; bottom: -0.12em;
  border-radius: 999px;
  background: rgba(12, 9, 6, calc(0.55 * var(--bk-a, 0.6)));
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
}
.tc-backing-pill.tc-backing-light {
  background: rgba(255, 250, 240, calc(0.7 * var(--bk-a, 0.6)));
}
.tc-backing-glow {
  left: -2em; right: -2em; top: -0.9em; bottom: -0.9em;
  border-radius: 50%;
  /* closest-side: the ellipse touches every edge of the span, so the haze
     is gone by the time it reaches them — no box, however wide the line. */
  background: radial-gradient(ellipse closest-side at center,
    rgba(12, 9, 6, calc(0.85 * var(--bk-a, 0.6))) 0%,
    rgba(12, 9, 6, calc(0.55 * var(--bk-a, 0.6))) 45%,
    rgba(12, 9, 6, 0) 100%);
}
/* ORN-EFFECTS — an ornament's shadow (a drop shadow under the ink, so it
   reads on a busy picture) and its backing, sized in card units because the
   ornament box has no type size of its own. */
/* The shadow goes on the INK (the children), never on the box — a filter on
   the box would shadow the backing too and turn a light glow muddy. Rules
   whose ink is the box's own background take a box-shadow instead. */
.titlecard-div.tc-div-sh-soft > :not(.tc-backing):not(.tc-div-grip) { filter: drop-shadow(0 0.15cqi 0.35cqi rgba(12, 8, 4, 0.55)); }
.titlecard-div.tc-div-sh-strong > :not(.tc-backing):not(.tc-div-grip) { filter: drop-shadow(0 0.2cqi 0.3cqi rgba(12, 8, 4, 0.85)) drop-shadow(0 0 1.2cqi rgba(12, 8, 4, 0.55)); }
.titlecard-div.tc-div-sh-light > :not(.tc-backing):not(.tc-div-grip) { filter: drop-shadow(0 0 0.3cqi rgba(255, 250, 240, 0.95)) drop-shadow(0 0 1.2cqi rgba(255, 250, 240, 0.6)); }
.tc-div-hair.tc-div-sh-soft, .tc-div-double.tc-div-sh-soft, .tc-div-taper.tc-div-sh-soft { box-shadow: 0 0.15cqi 0.35cqi rgba(12, 8, 4, 0.55); }
.tc-div-hair.tc-div-sh-strong, .tc-div-double.tc-div-sh-strong, .tc-div-taper.tc-div-sh-strong { box-shadow: 0 0.2cqi 0.3cqi rgba(12, 8, 4, 0.85), 0 0 1.2cqi rgba(12, 8, 4, 0.55); }
.tc-div-hair.tc-div-sh-light, .tc-div-double.tc-div-sh-light, .tc-div-taper.tc-div-sh-light { box-shadow: 0 0 0.3cqi rgba(255, 250, 240, 0.95), 0 0 1.2cqi rgba(255, 250, 240, 0.6); }
.titlecard-div .tc-backing-pill { left: -1.4cqi; right: -1.4cqi; top: -0.9cqi; bottom: -0.9cqi; }
.titlecard-div .tc-backing-glow { left: -3cqi; right: -3cqi; top: -2.2cqi; bottom: -2.2cqi; }
.tc-backing-glow.tc-backing-light {
  background: radial-gradient(ellipse closest-side at center,
    rgba(255, 250, 240, calc(0.95 * var(--bk-a, 0.6))) 0%,
    rgba(255, 250, 240, calc(0.65 * var(--bk-a, 0.6))) 45%,
    rgba(255, 250, 240, 0) 100%);
}

/* Family-added free line ("Add a line"). Mirrors the other opening text
   blocks: point-anchored, centered, fit-shift/scale aware. */
.titlecard-extra {
  position: absolute;
  transform: translate(-50%, -50%) translateY(var(--fit-shift, 0px)) scale(var(--fit-scale, 1));
  pointer-events: none;
  z-index: 5;
  text-align: center;
  /* `pre`, not `nowrap`: a family line still never wraps on its own (which is
     what nowrap was for), but an authored "\n" now breaks where it is written.
     The preamble already honoured newlines; extras went through escapeHtml into
     nowrap, so a two-line sentiment could not be expressed at all. */
  white-space: pre;
  font-family: "Cormorant Garamond", Georgia, serif;
  font-size: 3.1cqi;
  line-height: 1.38;
  color: #fffaf0;
  text-shadow: 0 1px 3px rgba(40, 28, 14, 0.55);
  letter-spacing: 0.02em;
}
.titlecard-stage.brightness-light .titlecard-extra { color: #4a3f2c; text-shadow: 0 1px 2px rgba(255,255,255,0.5); }
/* EXTRA-SHADOW — a line of their own takes the same halo model as the other
   lines: contrast-correct by ink colour, Off / Light / Soft picks, --ts-a. */
.titlecard-extra.tc-halo-light {
  text-shadow:
    0 0 0.4cqi rgba(255, 255, 255, calc(0.95 * var(--ts-a, 1))),
    0 0 1.2cqi rgba(255, 255, 255, calc(0.7 * var(--ts-a, 1))),
    0 0 2.2cqi rgba(255, 255, 255, calc(0.4 * var(--ts-a, 1))) !important;
}
.titlecard-extra.tc-halo-dark {
  text-shadow:
    0 0 0.28cqi rgba(12, 8, 4, calc(0.99 * var(--ts-a, 1))),
    0 0 0.7cqi  rgba(12, 8, 4, calc(0.95 * var(--ts-a, 1))),
    0 0 1.7cqi  rgba(12, 8, 4, calc(0.82 * var(--ts-a, 1))),
    0 0 3.4cqi  rgba(12, 8, 4, calc(0.62 * var(--ts-a, 1))),
    0 0 6.2cqi  rgba(12, 8, 4, calc(0.42 * var(--ts-a, 1))) !important;
}
.titlecard-extra.text-shadow-off { text-shadow: none !important; }
.titlecard-extra.text-shadow-light {
  text-shadow:
    0 0 0.4cqi rgba(255, 255, 255, calc(0.95 * var(--ts-a, 1))),
    0 0 1.2cqi rgba(255, 255, 255, calc(0.7 * var(--ts-a, 1))),
    0 0 2.2cqi rgba(255, 255, 255, calc(0.4 * var(--ts-a, 1))) !important;
}
.titlecard-extra.text-shadow-soft {
  text-shadow:
    0 0 0.4cqi rgba(0, 0, 0, calc(0.72 * var(--ts-a, 1))),
    0 0 1.2cqi rgba(0, 0, 0, calc(0.5 * var(--ts-a, 1))),
    0 0 2.2cqi rgba(0, 0, 0, calc(0.28 * var(--ts-a, 1))) !important;
}
.titlecard-stage.backdrop-stage-area .titlecard-extra {
  pointer-events: auto; cursor: grab; padding: 0 0.35em; border-radius: 4px;
  outline: 1px dashed rgba(96,115,101,0);
  transition: outline-color 120ms ease, background-color 120ms ease;
  touch-action: none;
}
.fs-customize .titlecard-extra:hover { outline-color: rgba(96,115,101,.7) !important; background-color: rgba(96,115,101,.08); }
.fs-customize .titlecard-extra.is-selected { outline: 2px solid #607365 !important; outline-offset: 3px; background-color: rgba(96,115,101,.1); }
.fs-customize .titlecard-extra.is-selected .backdrop-text-resize-handle { opacity: 1; }

/* "+ Add a line" chip in the Show row. */
.fs-el-addline {
  display: inline-flex; align-items: center; cursor: pointer;
  padding: 0.32rem 0.8rem; border-radius: 999px; font-size: 0.82rem; font-weight: 600;
  background: rgba(255,255,255,.08); border: 1px dashed rgba(255,255,255,.4); color: rgba(255,255,255,.78);
  transition: background .14s ease, border-color .14s ease, color .14s ease;
}
.fs-el-addline:hover { background: rgba(255,255,255,.16); border-color: rgba(255,255,255,.65); color: #fff; }

/* Smoothly glide the vertical rebalance (recenter + gap-close) that
   fitTitlecardText() applies when the family shows/hides an element in the
   Customize / guided editor. Registering --fit-shift as an animatable
   <length> lets the transform animate off just that variable — scale
   (--fit-scale, font fitting) is NOT transitioned, so refits don't zoom.
   Scoped to edit-mode stages so playback/first-paint never animates. */
@property --fit-shift {
  syntax: "<length>";
  inherits: false;
  initial-value: 0px;
}
.titlecard-stage.is-edit-mode .titlecard-preamble,
.titlecard-stage.is-edit-mode .titlecard-name,
.titlecard-stage.is-edit-mode .titlecard-dates {
  transition: --fit-shift 280ms cubic-bezier(0.22, 0.61, 0.36, 1),
              outline-color 120ms ease, background-color 120ms ease;
}
/* LO54 — nor while the fit pass is measuring. It clears --fit-shift to read the
   type where it is authored, and that zero is a real committed value the
   transition will happily glide to and back: the bounce K caught when he armed
   the pencil. tcQuietFit holds this class across the pass and restores the old
   shift under it, so the browser only ever sees where the block WAS and where
   it ENDS UP. */
.titlecard-stage.tc-fit-quiet .titlecard-preamble,
.titlecard-stage.tc-fit-quiet .titlecard-name,
.titlecard-stage.tc-fit-quiet .titlecard-dates {
  transition: none !important;
}
/* Never animate while an element is being dragged — the shift must track the
   pointer 1:1. */
.titlecard-stage.is-edit-mode .titlecard-preamble.is-dragging,
.titlecard-stage.is-edit-mode .titlecard-name.is-dragging,
.titlecard-stage.is-edit-mode .titlecard-dates.is-dragging {
  transition: none;
}

/* A look that sets its preamble's last line differently (see `emphasis` on the
   composition cell). Each line becomes its own block inside the ONE preamble
   element, so every pass that queries `.titlecard-preamble` — fit, evening,
   drag, selection, ink measurement — still finds exactly one node and measures
   the whole phrase. The emphasised line's size is an `em` multiple set inline,
   so it scales with the family's own resize instead of drifting out of it. */
.titlecard-preamble.tc-pre-styled { white-space: nowrap; line-height: 1.15; }
.titlecard-preamble .tc-pre-line { display: block; }
.titlecard-preamble .tc-pre-emph { line-height: 1; }

.titlecard-preamble.tc-pre-multiline {
  /* `pre` breaks ONLY at the family's explicit newlines (never auto-wraps at
     the box edge), so they get exactly the lines they typed; the fit engine
     scales the widest line to fit. */
  white-space: pre;
  text-align: center;
  line-height: 1.25;
}

/* Graceful floor for fitTitlecardText(): when a name/phrase is SO long that
   shrink-to-fit would make it uncomfortably small, we let it wrap to a
   second line instead of going microscopic. The JS sets the max-width (as
   a % of the stage, so it stays correct at any size) and toggles this class
   to release the single-line lock. */
.titlecard-preamble.fit-wrap,
.titlecard-name.fit-wrap {
  white-space: normal;
  /* Break only at spaces — never mid-word (no "MARGARE / THA"). A single
     over-long word simply gets width-scaled instead. */
  overflow-wrap: normal;
  word-break: keep-all;
  line-height: 1.08;
}
.titlecard-stage.backdrop-stage-area .titlecard-preamble:hover,
.titlecard-stage.backdrop-stage-area .titlecard-name:hover,
.titlecard-stage.backdrop-stage-area .titlecard-dates:hover {
  outline-color: rgba(201, 162, 90, 0.85);
  background-color: rgba(201, 162, 90, 0.08);
}
.titlecard-stage.backdrop-stage-area .titlecard-preamble.is-selected,
.titlecard-stage.backdrop-stage-area .titlecard-name.is-selected,
.titlecard-stage.backdrop-stage-area .titlecard-dates.is-selected {
  outline-color: var(--sel-accent, rgba(201, 162, 90, 1));
  background-color: rgba(201, 162, 90, 0.16);
  background-color: color-mix(in srgb, var(--sel-accent, #c9a25a) 16%, transparent);
}
/* Selected photo gets the same accent ring as the text elements. !important so
   the accent wins even while the cursor hovers the photo (the is-editable:hover
   rule would otherwise repaint the ring gold). */
.titlecard-portrait.is-selected,
.titlecard-portrait.is-editable.is-selected,
.titlecard-portrait.is-editable.is-selected:hover {
  outline: 2.5px solid var(--sel-accent, #c9a25a) !important;
  outline-offset: 4px;
}
.titlecard-preamble {
  font-family: "Cormorant Garamond", "Cormorant", "Playfair Display", Georgia, serif;
  font-style: italic;
  font-size: 2.6cqi;
  letter-spacing: 0.04em;
  /* The preamble was the ONE of the three opening lines with no line-height of
     its own (.titlecard-name sets 1.05, .titlecard-dates 1.4), so it inherited
     whatever its container had. `.fsv2-look-stage` sets `line-height: 0` to kill
     the inline-image gap, and that cascaded straight into this element: on every
     surface outside Fine-tune the preamble's box collapsed to ZERO height. Two
     things broke at once. `translate(-50%, -50%)` resolved its vertical half to
     0px, so the line was positioned by its TOP instead of its centre and sat
     half a line low; and fitOneTitlecardStage read the collapsed box as "the
     preamble lost a whole line" and pulled the name and dates up ~2% of the card
     to close a gap that was never there. Fine-tune, which sits under a container
     with a normal line-height, rendered the same card correctly — which is why
     the live preview and Fine-tune disagreed. `normal` is the initial value, so
     this changes nothing where the element already computed `normal` (Fine-tune
     is byte-identical) and only stops the collapse everywhere else. */
  line-height: normal;
  /* Keep the preamble on a single line so resize-bigger doesn't wrap
     to two lines unexpectedly. Same reason as on .titlecard-name —
     the family is sizing the text, not asking for a paragraph. The
     group box wraps the wider rendered text automatically. */
  white-space: nowrap;
}
.titlecard-name {
  font-family: "Cormorant Garamond", "Cormorant", "Playfair Display", Georgia, serif;
  font-weight: 600;
  font-size: 7cqi;
  line-height: 1.05;
  letter-spacing: 0.02em;
  /* Keep the name on a single line in Path A edit mode so corner-drag
     scaling stays uniform: when the catalog's max-width forces a wrap
     (e.g. "Sue Bone" at large sizes), the rendered box height grows
     non-linearly with font-size, and the proportional position scaling
     in the group-box corner drag stops keeping siblings clear. Nowrap
     means the box height tracks the font perfectly. */
  white-space: nowrap;
}
.titlecard-name.font-serif-uppercase,
.titlecard-name.font-serif-caps {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 6cqi;
}
.titlecard-name.font-sans-serif-caps,
.titlecard-name.font-thin-display {
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  font-weight: 300;
  text-transform: uppercase;
  letter-spacing: 0.15em;
  font-size: 5cqi;
}
.titlecard-name.font-script {
  font-family: "Caveat", "Brush Script MT", cursive;
  font-style: normal;
  letter-spacing: 0;
  font-size: 8cqi;
}
.titlecard-name.font-serif-italic {
  font-style: italic;
  font-weight: 500;
}
.titlecard-dates {
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  font-weight: 500;
  font-size: 2.2cqi;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  /* Multi-line date formats (Sunrise/Sunset etc.) use \n in the string;
     pre-line renders those as actual line breaks. Override the base
     .backdrop-year nowrap as well so wrapping works. */
  white-space: pre-line;
  line-height: 1.4;
}

/* Strong legibility on ANY background — text can land on the portrait
   (which has varying colors) or on plain backdrop. We use a halo-style
   shadow that creates a soft contrasting border around each glyph so
   the text reads cleanly whether the area beneath is light or dark. */
.titlecard-stage.brightness-dark .titlecard-preamble:not(.text-shadow-off),
.titlecard-stage.brightness-dark .titlecard-name:not(.text-shadow-off),
.titlecard-stage.brightness-dark .titlecard-dates:not(.text-shadow-off) {
  text-shadow:
    0 0 0.4cqi rgba(0, 0, 0, calc(0.95 * var(--ts-a, 1))),
    0 0 1.2cqi rgba(0, 0, 0, calc(0.7 * var(--ts-a, 1))),
    0 0 2.2cqi rgba(0, 0, 0, calc(0.4 * var(--ts-a, 1)));
}
.titlecard-stage.brightness-light .titlecard-preamble:not(.text-shadow-off),
.titlecard-stage.brightness-light .titlecard-name:not(.text-shadow-off),
.titlecard-stage.brightness-light .titlecard-dates:not(.text-shadow-off) {
  text-shadow:
    0 0 0.4cqi rgba(255, 255, 255, calc(0.95 * var(--ts-a, 1))),
    0 0 1.2cqi rgba(255, 255, 255, calc(0.7 * var(--ts-a, 1))),
    0 0 2.2cqi rgba(255, 255, 255, calc(0.4 * var(--ts-a, 1)));
}

/* Luminance-aware halo: LIGHT-colored text (cream/gold/rose/white) needs a
   DARK halo to read on a bright background — a white halo would erase it. The
   renderer adds .tc-halo-dark to any light-colored text element; this wins over
   the background-brightness default above. A crisp inner ring plus soft outer
   glow gives clean, professional separation on any photo. */
/* Mirror of tc-halo-dark for DARK glyphs: a soft WHITE halo (identical to the
   brightness-light default) so dark text reads on ANY stage — including one the
   engine classed brightness-dark, where the background default would otherwise
   wrap dark text in a black smudge. Wins over the brightness-* defaults. */
.titlecard-preamble.tc-halo-light,
.titlecard-name.tc-halo-light,
.titlecard-dates.tc-halo-light,
.titlecard-chapter.tc-halo-light,
.lm-chapter-card-eyebrow.tc-halo-light,
.lm-chapter-card-title.tc-halo-light {
  text-shadow:
    0 0 0.4cqi rgba(255, 255, 255, calc(0.95 * var(--ts-a, 1))),
    0 0 1.2cqi rgba(255, 255, 255, calc(0.7 * var(--ts-a, 1))),
    0 0 2.2cqi rgba(255, 255, 255, calc(0.4 * var(--ts-a, 1))) !important;
}
.titlecard-preamble.tc-halo-dark,
.titlecard-name.tc-halo-dark,
.titlecard-dates.tc-halo-dark,
.titlecard-chapter.tc-halo-dark,
.lm-chapter-card-eyebrow.tc-halo-dark,
.lm-chapter-card-title.tc-halo-dark {
  /* Text-protection halo: a crisp near-black outline for edge definition, then
     progressively larger soft dark layers that pool into a gentle "cloud" behind
     each line — so even a mid-tone accent stays legible over a busy, light photo
     (built for older eyes, not just aesthetics). */
  text-shadow:
    0 0 0.28cqi rgba(12, 8, 4, calc(0.99 * var(--ts-a, 1))),
    0 0 0.7cqi  rgba(12, 8, 4, calc(0.95 * var(--ts-a, 1))),
    0 0 1.7cqi  rgba(12, 8, 4, calc(0.82 * var(--ts-a, 1))),
    0 0 3.4cqi  rgba(12, 8, 4, calc(0.62 * var(--ts-a, 1))),
    0 0 6.2cqi  rgba(12, 8, 4, calc(0.42 * var(--ts-a, 1))) !important;
}

/* === Title-card YEAR + CHAPTER (cover-native; render on the unified cover
   engine like preamble/name/dates). === */
.titlecard-year,
.titlecard-chapter {
  position: absolute;
  transform: translate(-50%, -50%);
  pointer-events: none;
  z-index: 5;
  text-align: center;
  white-space: nowrap;
}
.titlecard-chapter {
  font-family: "Cormorant Garamond", "Cormorant", "Playfair Display", Georgia, serif;
  font-weight: 600;
  font-size: 3.4cqi;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.titlecard-year {
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  font-weight: 500;
  font-size: 2.4cqi;
  letter-spacing: 0.15em;
}
.titlecard-stage.brightness-dark .titlecard-year,
.titlecard-stage.brightness-dark .titlecard-chapter {
  text-shadow:
    0 0 0.4cqi rgba(0, 0, 0, calc(0.95 * var(--ts-a, 1))),
    0 0 1.2cqi rgba(0, 0, 0, calc(0.7 * var(--ts-a, 1))),
    0 0 2.2cqi rgba(0, 0, 0, calc(0.4 * var(--ts-a, 1)));
}
.titlecard-stage.brightness-light .titlecard-year,
.titlecard-stage.brightness-light .titlecard-chapter {
  text-shadow:
    0 0 0.4cqi rgba(255, 255, 255, calc(0.95 * var(--ts-a, 1))),
    0 0 1.2cqi rgba(255, 255, 255, calc(0.7 * var(--ts-a, 1))),
    0 0 2.2cqi rgba(255, 255, 255, calc(0.4 * var(--ts-a, 1)));
}
.titlecard-year.text-shadow-off,
.titlecard-chapter.text-shadow-off { text-shadow: none !important; }
.titlecard-year.text-shadow-light,
.titlecard-chapter.text-shadow-light {
  text-shadow:
    0 0 0.4cqi rgba(255, 255, 255, calc(0.95 * var(--ts-a, 1))),
    0 0 1.2cqi rgba(255, 255, 255, calc(0.7 * var(--ts-a, 1))),
    0 0 2.2cqi rgba(255, 255, 255, calc(0.4 * var(--ts-a, 1))) !important;
}
.titlecard-year.text-shadow-soft,
.titlecard-chapter.text-shadow-soft {
  text-shadow:
    0 0 0.4cqi rgba(0, 0, 0, calc(0.72 * var(--ts-a, 1))),
    0 0 1.2cqi rgba(0, 0, 0, calc(0.5 * var(--ts-a, 1))),
    0 0 2.2cqi rgba(0, 0, 0, calc(0.28 * var(--ts-a, 1))) !important;
}
.titlecard-stage.backdrop-stage-area .titlecard-year,
.titlecard-stage.backdrop-stage-area .titlecard-chapter {
  pointer-events: auto;
  cursor: grab;
  padding: 0 0.35em;
}
.titlecard-year:hover .backdrop-text-resize-handle,
.titlecard-year.is-resizing .backdrop-text-resize-handle,
.titlecard-chapter:hover .backdrop-text-resize-handle,
.titlecard-chapter.is-resizing .backdrop-text-resize-handle {
  opacity: 1;
}

/* "Matched bookend" tile mood label uses a softer accent. */
.backdrop-library-tile.opposite-bookend {
  outline: 2px dashed rgba(120, 90, 50, 0.45);
}

/* === Title card preamble text picker (chips that show the actual
   preset text so the family can preview before selecting). === */
.titlecard-preamble-picker {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.4rem;
}
/* Plural variant used in the Backdrop sidebar — chips render in a
   2-col wrapping grid for legibility (the full preamble text fits
   on one chip line at this width instead of getting elided). */
.titlecard-preamble-chips {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.35rem;
  margin-top: 0.4rem;
}
.titlecard-preamble-chips .titlecard-preamble-chip {
  text-align: center;
  font-size: 0.78rem;
  padding: 0.4rem 0.55rem;
}
.titlecard-preamble-chip {
  padding: 0.45rem 0.7rem;
  background: rgba(255, 250, 240, 0.5);
  border: 1px solid var(--border, rgba(120, 100, 80, 0.3));
  border-radius: 14px;
  cursor: pointer;
  font-size: 0.85rem;
  font-family: "Cormorant Garamond", "Cormorant", Georgia, serif;
  font-style: italic;
  color: inherit;
  transition: background 0.15s, border-color 0.15s;
}
.titlecard-preamble-chip:hover {
  background: rgba(255, 250, 240, 0.9);
}
.titlecard-preamble-chip.active {
  background: var(--accent, #8a6536);
  border-color: var(--accent, #8a6536);
  color: white;
}

/* === Title card date format picker (chips with a label + live
   preview rendered from the family's actual birth + death dates). === */
.titlecard-date-picker {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.4rem;
  margin-top: 0.4rem;
}
.titlecard-date-chip {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.15rem;
  padding: 0.55rem 0.75rem;
  background: rgba(255, 250, 240, 0.5);
  border: 1px solid var(--border, rgba(120, 100, 80, 0.3));
  border-radius: 6px;
  cursor: pointer;
  text-align: left;
  transition: background 0.15s, border-color 0.15s;
}
.titlecard-date-chip:hover {
  background: rgba(255, 250, 240, 0.9);
}
.titlecard-date-chip.active {
  background: var(--accent, #8a6536);
  border-color: var(--accent, #8a6536);
  color: white;
}
.titlecard-date-chip-label {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  opacity: 0.85;
}
.titlecard-date-chip-preview {
  font-size: 0.85rem;
  opacity: 0.95;
  white-space: pre-line;
  line-height: 1.35;
  max-width: 100%;
}

/* === Title card font + color picker chips === */
.titlecard-font-picker,
.titlecard-color-picker {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.4rem;
  margin-top: 0.4rem;
}
@media (max-width: 720px) {
  .titlecard-font-picker,
  .titlecard-color-picker {
    grid-template-columns: repeat(2, 1fr);
  }
}
.titlecard-font-chip {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.15rem;
  padding: 0.5rem 0.4rem;
  background: rgba(255, 250, 240, 0.5);
  border: 1px solid var(--border, rgba(120, 100, 80, 0.3));
  border-radius: 6px;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}
.titlecard-font-chip:hover {
  background: rgba(255, 250, 240, 0.9);
}
.titlecard-font-chip.active {
  background: var(--accent, #8a6536);
  border-color: var(--accent, #8a6536);
  color: white;
}
.titlecard-font-sample {
  font-size: 1.5rem;
  line-height: 1;
  color: inherit;
}
.titlecard-font-label {
  font-size: 0.7rem;
  letter-spacing: 0.03em;
  opacity: 0.8;
}

/* Color swatch: two horizontal bars showing name color + accent. */
.titlecard-color-swatch {
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  height: 48px;
  background: rgba(40, 30, 20, 0.85);
  border: 1px solid var(--border, rgba(120, 100, 80, 0.3));
  border-radius: 6px;
  cursor: pointer;
  transition: border-color 0.15s, transform 0.1s;
  padding: 0;
}
.titlecard-color-swatch:hover {
  transform: translateY(-1px);
}
.titlecard-color-swatch.active {
  border-color: var(--accent, #8a6536);
  border-width: 2px;
  box-shadow: 0 0 0 1px var(--accent, #8a6536);
}
.titlecard-color-bar {
  flex: 1;
  width: 100%;
}
.titlecard-color-bar.primary {
  background: var(--swatch-name, #ccc);
}
.titlecard-color-bar.accent {
  background: var(--swatch-accent, #888);
}

/* === Font preset classes — applied to .titlecard-name when the
   family picks a font from the picker. Each maps to a specific
   font-family / weight / style combo. ALSO used by the picker chip
   sample so the preview matches what the title card will render. */
.font-preset-garamond-italic,
.titlecard-name.font-preset-garamond-italic {
  font-family: "Cormorant Garamond", "Cormorant", Georgia, serif;
  font-style: italic;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0.02em;
}
.font-preset-playfair,
.titlecard-name.font-preset-playfair {
  font-family: "Playfair Display", "Playfair", "Cormorant Garamond", Georgia, serif;
  font-weight: 700;
  text-transform: none;
  letter-spacing: 0.01em;
}
.font-preset-cinzel,
.titlecard-name.font-preset-cinzel {
  font-family: "Cinzel", "Trajan Pro", "Cormorant Garamond", Georgia, serif;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}
.font-preset-inter-caps,
.titlecard-name.font-preset-inter-caps {
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  font-weight: 300;
  text-transform: uppercase;
  letter-spacing: 0.18em;
}
.font-preset-eb-garamond,
.titlecard-name.font-preset-eb-garamond {
  font-family: "EB Garamond", "Garamond", "Adobe Garamond Pro", "Palatino Linotype", Palatino, "Cormorant Garamond", Georgia, serif;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0.02em;
}
.font-preset-lora-italic,
.titlecard-name.font-preset-lora-italic {
  font-family: "Lora", "Cormorant Garamond", Georgia, serif;
  font-style: italic;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
}
.font-preset-caveat-script,
.titlecard-name.font-preset-caveat-script {
  font-family: "Caveat", "Brush Script MT", cursive;
  font-style: normal;
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0;
}
.font-preset-garamond-uppercase,
.titlecard-name.font-preset-garamond-uppercase {
  font-family: "Cormorant Garamond", "Cormorant", Georgia, serif;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

/* Additional memorial-appropriate font presets.
   Two cursive scripts (Pinyon Script, Great Vibes) for elegant
   handwritten name treatments. Three serif presets (Cormorant,
   Spectral, Cardo) for classical book-style typography. */
.font-preset-pinyon-script,
.titlecard-name.font-preset-pinyon-script {
  font-family: "Pinyon Script", "Great Vibes", "Segoe Script", "Brush Script MT", cursive;
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0.01em;
}
.font-preset-great-vibes,
.titlecard-name.font-preset-great-vibes {
  font-family: "Great Vibes", "Snell Roundhand", "Edwardian Script ITC", "Palace Script MT", "French Script MT", "Pinyon Script", cursive;
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0.01em;
}
/* Italianno. Snell Roundhand ships with macOS and Edwardian Script ITC with
   Office on Windows; Palace Script MT and French Script MT are the older
   Windows fallbacks. All four are formal scripts at a similar weight, so a
   card drawn before the webfont arrives is the right shape, not a serif. */
.font-preset-italianno,
.titlecard-name.font-preset-italianno {
  font-family: "Italianno", "Snell Roundhand", "Edwardian Script ITC", "Palace Script MT", "French Script MT", cursive;
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0.01em;
}
/* Lavishly Yours — a Google face, so unlike Edwardian Script ITC and Bickham it
   is ours to ship rather than only to name. The stack behind it is still worth
   having: until the fonts are vendored the webfont has to arrive over the
   network, and a card that never gets it should land on a formal copperplate
   rather than on whatever the browser calls "cursive" (Comic Sans, on Windows).
   Palace Script MT and Edwardian Script ITC both come with Office on Windows
   AND macOS; Vivaldi is on every Windows install. Tracking stays at 0 — a
   script's letters are drawn to join, and any letter-spacing at all breaks the
   joins open. */
.font-preset-lavishly-yours,
.titlecard-name.font-preset-lavishly-yours,
.backdrop-text-name.font-preset-lavishly-yours,
.backdrop-text-preamble.font-preset-lavishly-yours,
.backdrop-text-dates.font-preset-lavishly-yours {
  font-family: "Lavishly Yours", "Palace Script MT", "Edwardian Script ITC", "Vivaldi", "Ephesis", cursive;
  font-weight: 400;
  font-style: normal;
  text-transform: none;
  letter-spacing: 0;
}

/* Whisper — lighter and rounder than Lavishly Yours, less steeply sloped. Same
   arrangement: the Google face first, then the closest things a machine already
   has. French Script MT is the nearest Office match for Whisper's softer hand;
   Palace Script is the formal fallback; Lucida Handwriting is on both Windows
   and macOS as a last resort before the generic. */
.font-preset-whisper,
.titlecard-name.font-preset-whisper,
.backdrop-text-name.font-preset-whisper,
.backdrop-text-preamble.font-preset-whisper,
.backdrop-text-dates.font-preset-whisper {
  font-family: "Whisper", "French Script MT", "Palace Script MT", "Lucida Handwriting", "Ephesis", cursive;
  font-weight: 400;
  font-style: normal;
  text-transform: none;
  letter-spacing: 0;
}

.font-preset-cormorant,
.titlecard-name.font-preset-cormorant {
  font-family: "Cormorant Garamond", Georgia, serif;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0.02em;
}
.font-preset-spectral,
.titlecard-name.font-preset-spectral {
  font-family: "Spectral", "EB Garamond", Georgia, serif;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0.02em;
}
/* Montserrat — a geometric sans. Set LIGHT and tracked very wide it reads as
   quiet and modern rather than corporate, which is what a pale sunrise ground
   wants; the dates take the Medium cut so they hold their own at a third the
   size. Two presets because the weight difference between them is the point. */
.font-preset-montserrat-light,
.titlecard-name.font-preset-montserrat-light {
  font-family: "Montserrat", "Inter", "Helvetica Neue", Arial, sans-serif;
  font-weight: 300;
  text-transform: none;
  letter-spacing: 0.16em;
}
.backdrop-text-name.font-preset-montserrat-light,
.backdrop-text-preamble.font-preset-montserrat-light,
.backdrop-text-dates.font-preset-montserrat-light {
  font-family: "Montserrat", "Inter", "Helvetica Neue", Arial, sans-serif;
  font-weight: 300; letter-spacing: 0.16em;
}
.font-preset-montserrat-medium,
.titlecard-name.font-preset-montserrat-medium {
  font-family: "Montserrat", "Inter", "Helvetica Neue", Arial, sans-serif;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0.115em;
}
.backdrop-text-name.font-preset-montserrat-medium,
.backdrop-text-preamble.font-preset-montserrat-medium,
.backdrop-text-dates.font-preset-montserrat-medium {
  font-family: "Montserrat", "Inter", "Helvetica Neue", Arial, sans-serif;
  font-weight: 500; letter-spacing: 0.115em;
}

/* Didot — the name face. Didot proper ships with macOS, so on the user's own
   machine the real thing resolves; the web faces after it are the closest
   free stand-ins for everyone else, in descending order of fidelity. Set
   REGULAR and tracked wide — the elegance is in the tracking, not the weight. */
.font-preset-didot,
.titlecard-name.font-preset-didot {
  font-family: "Didot", "Didot LT STD", "Bodoni 72", "GFS Didot", "Bodoni Moda", "Playfair Display", Georgia, serif;
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0.10em;
}
.backdrop-text-name.font-preset-didot,
.backdrop-text-preamble.font-preset-didot,
.backdrop-text-dates.font-preset-didot {
  font-family: "Didot", "Didot LT STD", "Bodoni 72", "GFS Didot", "Bodoni Moda", "Playfair Display", Georgia, serif;
  font-weight: 400;
  letter-spacing: 0.10em;
}

/* Edwardian Script ITC — the preamble face. Ships with Microsoft Office, so it
   resolves locally where that is installed; Mrs Saint Delafield is the closest
   free English-roundhand fallback, then Great Vibes. */
.font-preset-edwardian-script,
.titlecard-name.font-preset-edwardian-script {
  font-family: "Edwardian Script ITC", "Edwardian Script", "Ephesis", "Petit Formal Script", "Great Vibes", cursive;
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
}
.backdrop-text-name.font-preset-edwardian-script,
.backdrop-text-preamble.font-preset-edwardian-script,
.backdrop-text-dates.font-preset-edwardian-script {
  font-family: "Edwardian Script ITC", "Edwardian Script", "Ephesis", "Petit Formal Script", "Great Vibes", cursive;
  font-weight: 400;
}

/* Bickham Script Pro — the formal English roundhand K specified for
   elegant-paper-texture. It is an Adobe commercial face: we do NOT ship it, we
   only name it first, so it resolves for anyone who already owns it (same
   arrangement as Didot and Edwardian Script above). Great Vibes is the closest
   free relative and is what everyone else will see. Semibold where the family
   has it; the tight tracking K asked for is set here rather than per-look. */
.font-preset-bickham-script,
.titlecard-name.font-preset-bickham-script {
  font-family: "Bickham Script Pro 3", "Bickham Script Pro", "Bickham Script",
               "Edwardian Script ITC", "Great Vibes", "Pinyon Script", cursive;
  font-weight: 600;
  text-transform: none;
  letter-spacing: -0.012em;
}
.backdrop-text-name.font-preset-bickham-script,
.backdrop-text-preamble.font-preset-bickham-script,
.backdrop-text-dates.font-preset-bickham-script {
  font-family: "Bickham Script Pro 3", "Bickham Script Pro", "Bickham Script",
               "Edwardian Script ITC", "Great Vibes", "Pinyon Script", cursive;
  font-weight: 600;
  letter-spacing: -0.012em;
}

/* Imperial Script — K's pick (23 Sep) for elegant-paper-texture's name, in
   place of Bickham, which the app cannot ship: a free Google roundhand, the
   closest of twenty to the Edwardian Script ITC his own Mac was drawing. Set
   as he chose it from the specimen: semibold (synthesised — the face has one
   weight) and the same tight tracking the look had. The fallbacks are formal
   roundhands already on the machine: Snell Roundhand (every Mac and iPhone),
   Edwardian Script ITC (Office, Windows and Mac), Gabriola (every Windows). */
.font-preset-imperial-script,
.titlecard-name.font-preset-imperial-script,
.backdrop-text-name.font-preset-imperial-script,
.backdrop-text-preamble.font-preset-imperial-script,
.backdrop-text-dates.font-preset-imperial-script {
  font-family: "Imperial Script", "Snell Roundhand", "Edwardian Script ITC", "Gabriola", "Great Vibes", cursive;
  font-weight: 600;
  font-style: normal;
  text-transform: none;
  letter-spacing: -0.012em;
}

/* Bodoni Moda — a true Didone: vertical stress, hairline serifs, extreme
   thick/thin. Set REGULAR and tracked wide, it reads as engraved formality
   rather than weight, which is what a memorial name wants. The optical-size
   axis is left to the browser so large settings get the finer cut. */
.font-preset-bodoni-moda,
.titlecard-name.font-preset-bodoni-moda {
  font-family: "Bodoni Moda", "Bodoni MT", "Didot", "Bodoni 72", "Playfair Display", Georgia, serif;
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0.08em;
}
.backdrop-text-name.font-preset-bodoni-moda,
.backdrop-text-preamble.font-preset-bodoni-moda,
.backdrop-text-dates.font-preset-bodoni-moda {
  font-family: "Bodoni Moda", "Bodoni MT", "Didot", "Bodoni 72", "Playfair Display", Georgia, serif;
  font-weight: 400;
  letter-spacing: 0.08em;
}
.font-preset-cardo,
.titlecard-name.font-preset-cardo {
  font-family: "Cardo", "EB Garamond", Georgia, serif;
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0.015em;
}

/* Path B (backdrop-text-*) font-preset variants. Mirror the
   .titlecard-name.font-preset-X selectors so the family's chosen
   preset wins the cascade tie-break against the .backdrop-text-name
   base defaults (font-weight: 600, text-transform: uppercase,
   letter-spacing: 0.05em). Without these, picking "Italic Serif" on
   an other photo got weight 600 from the base class instead of the
   preset's 500 — visually different from the same preset on main p1
   (where the .titlecard-name two-class selector already won). Each
   preset duplicates name/preamble/dates with the same property set
   it gave the title-card name; selector specificity 0,0,2,0 beats
   .backdrop-text-* (0,0,1,0). */
.backdrop-text-name.font-preset-garamond-italic,
.backdrop-text-preamble.font-preset-garamond-italic,
.backdrop-text-dates.font-preset-garamond-italic {
  font-family: "Cormorant Garamond", "Cormorant", Georgia, serif;
  font-style: italic;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0.02em;
}
.backdrop-text-name.font-preset-playfair,
.backdrop-text-preamble.font-preset-playfair,
.backdrop-text-dates.font-preset-playfair {
  font-family: "Playfair Display", "Playfair", "Cormorant Garamond", Georgia, serif;
  font-weight: 700;
  text-transform: none;
  letter-spacing: 0.01em;
}
.backdrop-text-name.font-preset-cinzel,
.backdrop-text-preamble.font-preset-cinzel,
.backdrop-text-dates.font-preset-cinzel {
  font-family: "Cinzel", "Trajan Pro", "Cormorant Garamond", Georgia, serif;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}
.backdrop-text-name.font-preset-inter-caps,
.backdrop-text-preamble.font-preset-inter-caps,
.backdrop-text-dates.font-preset-inter-caps {
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  font-weight: 300;
  text-transform: uppercase;
  letter-spacing: 0.18em;
}
.backdrop-text-name.font-preset-eb-garamond,
.backdrop-text-preamble.font-preset-eb-garamond,
.backdrop-text-dates.font-preset-eb-garamond {
  font-family: "EB Garamond", "Garamond", "Adobe Garamond Pro", "Palatino Linotype", Palatino, "Cormorant Garamond", Georgia, serif;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0.02em;
}
.backdrop-text-name.font-preset-lora-italic,
.backdrop-text-preamble.font-preset-lora-italic,
.backdrop-text-dates.font-preset-lora-italic {
  font-family: "Lora", "Cormorant Garamond", Georgia, serif;
  font-style: italic;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
}
.backdrop-text-name.font-preset-caveat-script,
.backdrop-text-preamble.font-preset-caveat-script,
.backdrop-text-dates.font-preset-caveat-script {
  font-family: "Caveat", "Brush Script MT", cursive;
  font-style: normal;
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0;
}
.backdrop-text-name.font-preset-garamond-uppercase,
.backdrop-text-preamble.font-preset-garamond-uppercase,
.backdrop-text-dates.font-preset-garamond-uppercase {
  font-family: "Cormorant Garamond", "Cormorant", Georgia, serif;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.backdrop-text-name.font-preset-pinyon-script,
.backdrop-text-preamble.font-preset-pinyon-script,
.backdrop-text-dates.font-preset-pinyon-script {
  font-family: "Pinyon Script", "Great Vibes", "Segoe Script", "Brush Script MT", cursive;
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0.01em;
}
.backdrop-text-name.font-preset-great-vibes,
.backdrop-text-preamble.font-preset-great-vibes,
.backdrop-text-dates.font-preset-great-vibes {
  font-family: "Great Vibes", "Snell Roundhand", "Edwardian Script ITC", "Palace Script MT", "French Script MT", "Pinyon Script", cursive;
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0.01em;
}
.backdrop-text-name.font-preset-italianno,
.backdrop-text-preamble.font-preset-italianno,
.backdrop-text-dates.font-preset-italianno {
  font-family: "Italianno", "Snell Roundhand", "Edwardian Script ITC", "Palace Script MT", "French Script MT", cursive;
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0.01em;
}
.backdrop-text-name.font-preset-cormorant,
.backdrop-text-preamble.font-preset-cormorant,
.backdrop-text-dates.font-preset-cormorant {
  font-family: "Cormorant Garamond", Georgia, serif;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0.02em;
}
.backdrop-text-name.font-preset-spectral,
.backdrop-text-preamble.font-preset-spectral,
.backdrop-text-dates.font-preset-spectral {
  font-family: "Spectral", "EB Garamond", Georgia, serif;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0.02em;
}
.backdrop-text-name.font-preset-cardo,
.backdrop-text-preamble.font-preset-cardo,
.backdrop-text-dates.font-preset-cardo {
  font-family: "Cardo", "EB Garamond", Georgia, serif;
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0.015em;
}

/* Compact number input that sits inside a matte-control-label
   (replaces the read-only .matte-control-value span when the value
   needs to be typeable — e.g. portrait Width / Height). */
.matte-control-input {
  width: 4.5rem;
  padding: 0.18rem 0.4rem;
  font-size: 0.85rem;
  text-align: right;
  border: 1px solid var(--border, rgba(120, 100, 80, 0.3));
  border-radius: 4px;
  background: rgba(255, 250, 240, 0.6);
  color: inherit;
  font-family: inherit;
}
.matte-control-input:focus {
  outline: none;
  border-color: var(--accent, #8a6536);
  background: rgba(255, 250, 240, 0.9);
}

/* Closing-line text input. Minimal styling to match the rest of the
   inline controls in the wizard. */
.text-input {
  width: 100%;
  padding: 0.55rem 0.7rem;
  font-size: 0.95rem;
  border: 1px solid var(--border, rgba(120, 100, 80, 0.3));
  border-radius: 6px;
  background: rgba(255, 250, 240, 0.5);
  color: inherit;
  font-family: inherit;
  margin-top: 0.3rem;
}
.text-input:focus {
  outline: none;
  border-color: var(--accent, #8a6536);
  background: rgba(255, 250, 240, 0.9);
}

/* === Backdrop template: optional year overlay ===
   Year elements live as siblings of .backdrop-photo-slot inside
   .backdrop-stage-area, NOT inside the slot. That way left/top
   percentages are stage-relative (consistent between small preview
   and expanded view) and we can position the year in the open
   whitespace anywhere on the stage.

   Each slot has a matching .backdrop-year[data-slot="a"|"b"] element.
   Fade is synced via the .active class added/removed by the slideshow
   controller alongside the slot's own .active toggle.

   Font size uses cqi (% of stage inline-size) so it scales with the
   stage — same proportional weight in small preview and expanded. */
.backdrop-year {
  position: absolute;
  transform: translate(-50%, -50%);
  pointer-events: none;
  font-family: "Cormorant Garamond", "Cormorant", "Playfair Display", Georgia, serif;
  white-space: nowrap;
  opacity: 0;
  transition: opacity 0.4s ease;
  z-index: 4;
}

/* Editable year in edit mode — draggable, cursor:grab, dashed outline
   on hover so the family knows it's interactive. The .is-editable
   class is added by renderBackdropYearForSlot when in edit mode. */
.backdrop-year.is-editable {
  pointer-events: auto;
  cursor: grab;
  padding: 0.1em 0.3em;
  border-radius: 4px;
  outline: 1px dashed rgba(201, 162, 90, 0);
  z-index: 7; /* above corner handles so it's always grabbable */
}
.backdrop-year.is-editable:hover {
  outline-color: rgba(201, 162, 90, 0.85);
  background-color: rgba(201, 162, 90, 0.08);
}
.backdrop-year.is-editable.is-dragging,
.backdrop-year.is-editable.is-resizing {
  cursor: grabbing;
  outline-color: rgba(201, 162, 90, 1);
  background-color: rgba(201, 162, 90, 0.14);
}

/* Resize handle — small gold dot at the bottom-right corner of the
   year text. Sits outside the text padding so it's easy to grab even
   on a short year string ("1985"). Hidden until hover or while resizing. */
.backdrop-year-resize-handle {
  position: absolute;
  bottom: -6px;
  right: -6px;
  width: 12px;
  height: 12px;
  background: #c9a25a;
  border: 2px solid #fff;
  border-radius: 50%;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.35);
  cursor: nwse-resize;
  opacity: 0;
  transform: scale(0.8);
  transition: opacity 120ms ease, transform 80ms ease;
  pointer-events: auto;
}
.backdrop-year.is-editable:hover .backdrop-year-resize-handle,
.backdrop-year.is-editable.is-resizing .backdrop-year-resize-handle,
.backdrop-year.is-editable.is-dragging .backdrop-year-resize-handle {
  opacity: 1;
  transform: scale(1);
}
.backdrop-year-resize-handle:hover {
  transform: scale(1.25);
}
.backdrop-year.active {
  opacity: 1;
}
.backdrop-year.is-hidden {
  display: none !important;
}

/* === Backdrop per-photo text block (preamble / name / dates) ===
   Opening-style 3-line stack overlaid on the Backdrop stage. Each
   line is individually absolutely-positioned via inline left/top;
   the container .backdrop-text-block fades in/out via .active (same
   pattern as .backdrop-year). */
.backdrop-text-block {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.4s ease;
  /* Above the group box (z-6) so individual member elements inside
     (preamble, name, dates — at z-7 within this block's stacking
     context) actually win clicks over the group box. Without this,
     the block at z-4 capped its children at z-4 in the parent context
     so group at z-6 caught everything. */
  z-index: 7;
}
.backdrop-text-block.active {
  opacity: 1;
}
.backdrop-text-block.is-hidden {
  display: none !important;
}

.backdrop-text-preamble,
.backdrop-text-name,
.backdrop-text-dates {
  position: absolute;
  transform: translate(-50%, -50%);
  font-family: "Cormorant Garamond", "Cormorant", "Playfair Display", Georgia, serif;
  white-space: nowrap;
  /* Halo to match the .titlecard-* (Path A) rendering — three layers
     of soft black glow that read as a contrasting outline against
     any backdrop. K wants the family's "Italic Serif" pick on main
     p1 and other photos to look IDENTICAL, and main p1 (which goes
     through the title-card render with brightness-dark halo) is the
     reference. Without this, other photos rendered with the regular
     backdrop-text path got only a flat drop shadow and read as
     "different font" even when the same preset was active. */
  text-shadow:
    0 0 0.4cqi rgba(0, 0, 0, calc(0.95 * var(--ts-a, 1))),
    0 0 1.2cqi rgba(0, 0, 0, calc(0.7 * var(--ts-a, 1))),
    0 0 2.2cqi rgba(0, 0, 0, calc(0.4 * var(--ts-a, 1)));
  pointer-events: none;
}
.backdrop-text-preamble {
  font-size: 2.4cqi;
  font-style: italic;
  letter-spacing: 0.08em;
  text-transform: none;
}
.backdrop-text-name {
  font-size: 5cqi;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.backdrop-text-dates {
  font-size: 2.4cqi;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* Edit mode — each text element is its own drag handle. Dashed gold
   outline on hover, soft amber wash, grab cursor. Applies to the
   name, preamble, and the first dates line. */
.backdrop-text-name.is-editable,
.backdrop-text-preamble.is-editable,
.backdrop-text-dates.is-editable {
  pointer-events: auto;
  cursor: grab;
  padding: 0.05em 0.4em;
  border-radius: 6px;
  outline: 1px dashed rgba(201, 162, 90, 0);
  transition: outline-color 120ms ease, background-color 120ms ease;
  /* Above the group box (z-6) so clicks on individual text glyphs go
     to the member's own drag handler instead of being swallowed by
     the group-box drag. Still below the per-element resize handles
     (z-10) and the group-box corner handles (z-10) so those win for
     resize. Layer order in EDIT mode:
       photo frame      (z-5)
       group box        (z-6)
       text members     (z-7)  ← this rule
       all corner dots  (z-10)
     Group-box drag still fires when the user clicks the gap between
     members (no text element there to catch the event). */
  z-index: 7;
}
.backdrop-text-name.is-editable:hover,
.backdrop-text-preamble.is-editable:hover,
.backdrop-text-dates.is-editable:hover {
  outline-color: rgba(201, 162, 90, 0.85);
  background-color: rgba(201, 162, 90, 0.08);
}
.backdrop-text-name.is-editable.is-dragging,
.backdrop-text-preamble.is-editable.is-dragging,
.backdrop-text-dates.is-editable.is-dragging {
  cursor: grabbing;
  outline-color: rgba(201, 162, 90, 1);
  background-color: rgba(201, 162, 90, 0.14);
}

/* Selected element — brighter dashed outline + amber wash so the
   user knows which element the floating toolbar is editing. */
.backdrop-text-preamble.is-selected,
.backdrop-text-name.is-selected,
.backdrop-text-dates.is-selected,
.backdrop-year.is-selected {
  outline-color: #c9a25a !important;
  background-color: rgba(201, 162, 90, 0.18) !important;
}
.backdrop-year.is-selected {
  outline: 1px dashed #c9a25a;
  outline-offset: 2px;
  border-radius: 4px;
}

/* Floating selection toolbar — Figma/Notion-style dark pill that
   appears above the selected element. Positioned absolutely
   inside .backdrop-stage-area; top/left set by JS. */
.backdrop-floating-toolbar {
  position: absolute;
  z-index: 20;
  pointer-events: auto;
  user-select: none;
  font-family: "Inter", system-ui, sans-serif;
}
.bft-pill {
  display: inline-flex;
  align-items: stretch;
  background: #1f1a14;
  border: 0.5px solid rgba(255, 250, 240, 0.14);
  border-radius: 22px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.45);
  color: #f4e9d4;
  white-space: nowrap;
  overflow: hidden;
}
.bft-element-label {
  display: inline-flex;
  align-items: center;
  font-size: 11px;
  color: #a89878;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 500;
  padding: 8px 14px;
  border-right: 1px solid rgba(255, 250, 240, 0.14);
}
/* Each top-level cell in the pill — chip OR segment — owns its
   horizontal padding, fills the pill's full height, and carries
   its own right border. No gaps between cells, so the entire
   visible region is clickable. Last cell drops its border so the
   pill ends cleanly. */
.bft-chip,
.bft-segment {
  display: inline-flex;
  align-items: center;
  background: transparent;
  border: none;
  color: #f4e9d4;
  padding: 8px 14px;
  border-right: 1px solid rgba(255, 250, 240, 0.14);
  cursor: pointer;
  font-size: 12px;
  line-height: 1.2;
  transition: background-color 0.12s ease;
  gap: 6px;
}
.bft-pill > :last-child,
.bft-pill > :last-child.bft-chip,
.bft-pill > :last-child.bft-segment {
  border-right: none;
}
.bft-chip:hover { background: rgba(255, 250, 240, 0.08); }
.bft-chip.is-open { background: rgba(201, 162, 90, 0.18); }
.bft-chip-label { color: #a89878; font-size: 11px; }
.bft-chip-value { color: #f4e9d4; font-weight: 500; max-width: 100px; overflow: hidden; text-overflow: ellipsis; }
.bft-chip-caret { color: #a89878; font-size: 10px; margin-left: 2px; }
.bft-color-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  border: 1px solid rgba(255, 250, 240, 0.35);
  flex-shrink: 0;
}
.bft-segment { cursor: default; }
.bft-segment-item {
  background: transparent;
  border: none;
  color: #a89878;
  font-size: 12px;
  font-weight: 500;
  min-width: 24px;
  height: 22px;
  padding: 0 8px;
  border-radius: 5px;
  cursor: pointer;
  transition: background-color 0.12s, color 0.12s;
  white-space: nowrap;
}
.bft-segment-item:hover { color: #f4e9d4; }
.bft-segment-item.is-active { background: rgba(201, 162, 90, 0.7); color: #1f1a14; }

/* Pointer arrow below the pill, pointing down at the element. */
.bft-arrow {
  width: 12px;
  height: 8px;
  background: #1f1a14;
  margin: -1px auto 0;
  clip-path: polygon(50% 100%, 0 0, 100% 0);
}

/* Popovers — sit below the pill, one open at a time. */
.bft-popover {
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  margin-top: 12px;
  min-width: 210px;
  background: #1f1a14;
  border: 0.5px solid rgba(255, 250, 240, 0.14);
  border-radius: 10px;
  padding: 6px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.55);
  z-index: 21;
  max-height: 280px;
  overflow-y: auto;
}
/* Flipped: when the toolbar is in the lower half of the stage, the
   popover renders ABOVE the toolbar pill instead of below — keeps it
   from getting clipped by .preview-stage's overflow:hidden. JS adds
   this class when there's more room above the toolbar than below. */
.bft-popover.flip-up {
  top: auto;
  bottom: 100%;
  margin-top: 0;
  margin-bottom: 12px;
}
.bft-popover-head {
  font-size: 10px;
  letter-spacing: 0.08em;
  color: #a89878;
  padding: 6px 10px 8px;
  font-weight: 500;
}
.bft-popover-divider {
  height: 1px;
  background: rgba(255, 250, 240, 0.12);
  margin: 4px 0;
}
.bft-popover-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  background: transparent;
  border: none;
  color: #e8dcc2;
  padding: 8px 10px;
  border-radius: 6px;
  font-size: 13px;
  cursor: pointer;
  text-align: left;
  transition: background-color 0.12s;
}
.bft-popover-item:hover { background: rgba(255, 250, 240, 0.08); }
.bft-popover-item.is-active { background: rgba(201, 162, 90, 0.22); color: #f4e9d4; }
.bft-popover-hint {
  margin-left: auto;
  font-size: 10px;
  color: #6e6354;
}

/* Custom-value slider at the bottom of Border / Shadow / Dim popovers.
   Sits below the preset items, separated by a thin divider line. */
.bft-popover-slider-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  margin-top: 4px;
  border-top: 1px solid rgba(255, 250, 240, 0.12);
  font-size: 12px;
  color: #b9a989;
}
.bft-popover-slider-row.is-active { color: #f4e9d4; }
.bft-slider-label {
  flex: 0 0 auto;
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.bft-popover-slider-row input[type="range"] {
  flex: 1 1 auto;
  min-width: 100px;
  margin: 0;
  cursor: pointer;
  accent-color: #c9a25a;
}
.bft-slider-value {
  flex: 0 0 auto;
  min-width: 32px;
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  color: #e8dcc2;
}

/* Custom color row — uses a <label> wrapping a hidden-ish native
   color input, so clicking anywhere on the row opens the OS picker. */
.bft-popover-custom-color {
  position: relative;
  cursor: pointer;
}
.bft-popover-custom-color input[type="color"] {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
  border: none;
  padding: 0;
  background: transparent;
}

/* Inline text-input popover used for Custom preamble. */
.bft-popover-text-input {
  min-width: 260px;
  padding: 6px 10px 8px;
}
.bft-text-input {
  width: 100%;
  background: rgba(0, 0, 0, 0.35);
  border: 1px solid rgba(255, 250, 240, 0.22);
  border-radius: 6px;
  color: #f4e9d4;
  font-size: 14px;
  padding: 8px 10px;
  font-family: inherit;
  outline: none;
  box-sizing: border-box;
}
.bft-text-input:focus {
  border-color: rgba(201, 162, 90, 0.7);
  background: rgba(0, 0, 0, 0.5);
}
.bft-text-input::selection {
  background: rgba(201, 162, 90, 0.4);
  color: #fff;
}
.bft-text-input-hint {
  font-size: 10px;
  color: #6e6354;
  margin-top: 6px;
  padding: 0 2px;
}
.main-photo-composition-tile.is-active {
  border-color: #3f4a3f;
  box-shadow: 0 0 0 2px #3f4a3f, 0 2px 8px rgba(63, 74, 63, 0.18);
}

/* Pencil chip — small square button with just the icon inside.
   Overrides the chip's default padding so the icon sits tight. */
.bft-pencil-chip {
  padding: 0 10px !important;
  color: #c9a25a;
  display: inline-flex;
  align-items: center;
}
.bft-pencil-chip:hover {
  color: #f4e9d4;
  background: rgba(255, 250, 240, 0.06);
}
/* "Copy from main / others" chip — only appears when current photo's
   settings differ from the reference. Soft gold accent so the family
   notices it as a one-click sync action without it stealing focus. */
.bft-copy-from-chip {
  color: #c9a25a;
  border-left: 1px solid rgba(255, 250, 240, 0.08);
  padding: 0 12px !important;
}
.bft-copy-from-chip:hover {
  color: #f4e9d4;
  background: rgba(201, 162, 90, 0.12);
}
.bft-pencil-numbered {
  gap: 4px;
}
.bft-pencil-num {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: inherit;
}

/* Active in-place text editing — soft gold outline + cursor visible.
   contentEditable elements get this class while the user is typing. */
.is-text-editing {
  outline: 2px solid rgba(201, 162, 90, 0.85);
  outline-offset: 4px;
  border-radius: 2px;
  cursor: text;
  caret-color: #c9a25a;
}
.is-text-editing::selection {
  background: rgba(201, 162, 90, 0.45);
  color: #fff;
}

/* All three styles share the .backdrop-year base above (position:
   absolute, translate(-50%,-50%), cqi sizing). Inline left/top is
   set by JS from stage-coord calculations — same for every style. */

/* Engraved: elegant italic serif. Free-move via X/Y sliders;
   defaults to centered below the photo. */
.backdrop-year.style-engraved {
  font-size: 5cqi;
  color: rgba(70, 50, 30, 0.82);
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
}
.backdrop-year.style-engraved:not(.is-opening-type-matched) {
  font-style: italic;
  letter-spacing: 0.04em;
}

/* Stamp: clean modern date marker in a corner of the photo. Inter
   medium with wide tracking — reads like the date metadata in pro
   photo software (Lightroom / Apple Photos). Quiet white-on-photo
   with a soft shadow so it sits cleanly on any background.
   Corner-anchored (overrides the base translate(-50%,-50%) center
   anchor) so the stamp's own corner sits at the specified position. */
.backdrop-year.style-stamp {
  transform: none;
  font-size: 1.5cqi;
  color: rgba(255, 255, 255, 0.92);
  text-shadow:
    0 0 0.3cqi rgba(0, 0, 0, 0.6),
    0 1px 0.2cqi rgba(0, 0, 0, 0.5);
}
.backdrop-year.style-stamp:not(.is-opening-type-matched) {
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  font-weight: 600;
  letter-spacing: 0.15em;
}

/* Caption: italic year sitting just below the photo, centered. */
.backdrop-year.style-caption {
  font-size: 3.5cqi;
  color: rgba(60, 40, 20, 0.9);
}
.backdrop-year.style-caption:not(.is-opening-type-matched) {
  font-style: italic;
  letter-spacing: 0.06em;
}

@media (max-width: 720px) {
  .backdrop-photo-slot {
    width: 82%;
  }
}

/* ---------- Backdrop template-tab controls ---------- */

.backdrop-upload-btn {
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

.backdrop-preview {
  display: grid;
  grid-template-columns: 160px 1fr;
  gap: 1rem;
  align-items: center;
  margin-top: 0.4rem;
  padding: 0.75rem;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--paper);
}

.backdrop-preview img {
  width: 100%;
  height: 100px;
  object-fit: cover;
  border-radius: 4px;
  display: block;
  border: 1px solid var(--line);
}

.backdrop-preview-meta {
  display: grid;
  gap: 0.6rem;
  /* min-width:0 on a grid child lets it shrink below its content's
     natural minimum — without this, a long unbreakable filename pushes
     the column wider than its 1fr allotment and overflows the card. */
  min-width: 0;
}

.backdrop-preview-meta strong {
  font-size: 0.95rem;
  color: var(--ink);
  /* Long filenames get truncated with an ellipsis instead of breaking
     character-by-character (which was producing the column-wide stair
     step we saw in the screenshot). */
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.backdrop-preview-actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.backdrop-preview-actions label {
  cursor: pointer;
  display: inline-flex;
  align-items: center;
}

/* Matte controls (size slider + color swatches) — appear nested inside
   the Photo border card when the matte toggle is on. */
.matte-controls {
  display: grid;
  gap: 1rem;
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--line);
}

.matte-control {
  display: grid;
  gap: 0.4rem;
}

.matte-control-label {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--ink);
}

.matte-control-value {
  font-weight: 500;
  color: var(--body);
  font-variant-numeric: tabular-nums;
}

.matte-size-slider {
  width: 100%;
  accent-color: #607365;
}

.matte-control-hints {
  display: flex;
  justify-content: space-between;
  font-size: 0.78rem;
  color: var(--body);
}

/* ---------- Compact module-card pattern (Template tab restructure) ----------
   The classic .module-card was a two-column grid (text left, controls right).
   When the card uses the new <header class="module-card-header"> pattern, we
   flip to a single-column flow so subsections stack cleanly underneath the
   title. Old cards (Details step etc.) without a module-card-header keep the
   grid. :has() ships in every modern browser. */

.module-card:has(.module-card-header) {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  padding: 1rem 1.1rem;
}

.module-card-header {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.module-card-header h3 {
  margin: 0;
  font-family: Georgia, "Times New Roman", serif;
  font-size: 1.2rem;
  font-weight: 500;
  line-height: 1.2;
  color: var(--ink);
}

/* One-line hint under the card title. Replaces the verbose paragraph
   each card used to have, and reads as supportive context rather than
   a tutorial sentence. */
.module-hint {
  margin: 0;
  font-size: 0.85rem;
  color: var(--body);
  line-height: 1.4;
}

/* Subsections inside a grouped card. Top border separator between rows
   gives visual rhythm without needing a full nested card. */
.module-subsection {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  padding-top: 0.85rem;
  border-top: 1px solid rgba(96, 115, 101, 0.14);
}

.module-card .module-subsection:first-of-type {
  padding-top: 0;
  border-top: 0;
}

.module-subsection-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--ink);
  gap: 0.5rem;
}

.module-subsection-value {
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--body);
  font-variant-numeric: tabular-nums;
}

.subsection-hint {
  margin: 0.35rem 0 0;
  font-size: 0.8rem;
  color: var(--body);
  line-height: 1.4;
}

/* ---------- Inline toggle (checkbox + label, no separate row card) ---------- */
/* Used inside subsections where the toggle IS the subsection (e.g. shadow,
   border). Cleaner than the bordered .checkbox-row pattern when nested. */

.inline-toggle-row {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.65rem;
  align-items: start;
  cursor: pointer;
  margin: 0;
}

.inline-toggle-row input[type="checkbox"] {
  margin-top: 0.18rem;
  accent-color: #607365;
  width: 1.1rem;
  height: 1.1rem;
  flex-shrink: 0;
}

.inline-toggle-row strong {
  display: block;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--ink);
  line-height: 1.3;
}

.inline-toggle-row span {
  display: block;
  margin-top: 0.18rem;
  font-size: 0.82rem;
  color: var(--body);
  line-height: 1.4;
}

/* ---------- Segmented control rows (Pacing card) ---------- */

.segmented-rows {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}

.segmented-row {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.segmented-row-label {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--ink);
}

.segmented-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
  background: var(--paper);
  width: fit-content;
  max-width: 100%;
}

.segmented-btn {
  appearance: none;
  flex: 1 0 auto;
  padding: 0.55rem 1rem;
  border: 0;
  border-right: 1px solid var(--line);
  background: transparent;
  color: var(--body);
  font: inherit;
  font-size: 0.88rem;
  font-weight: 500;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
  white-space: nowrap;
}

.segmented-btn:last-child {
  border-right: 0;
}

.segmented-btn:hover:not(.active) {
  background: rgba(96, 115, 101, 0.05);
  color: var(--ink);
}

.segmented-btn.active {
  background: #edf3ec;
  color: #2d3d2f;
  font-weight: 700;
}

/* ---------- Heritage year banner (inlined into Heritage details card) ---------- */

.heritage-year-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.85rem;
  padding: 0.8rem 0.95rem;
  border-radius: 8px;
  border: 1px solid rgba(187, 122, 64, 0.4);
  background: #fbf1e4;
}

.heritage-year-banner-info {
  border-color: rgba(96, 115, 101, 0.3);
  background: #f4f6ec;
}

.heritage-year-banner strong {
  display: block;
  font-size: 0.92rem;
  color: var(--ink);
  margin-bottom: 0.15rem;
}

.heritage-year-banner span {
  display: block;
  font-size: 0.8rem;
  color: var(--body);
  line-height: 1.4;
}

.heritage-year-banner > div {
  flex: 1 1 auto;
  min-width: 0;
}

.heritage-year-banner button {
  flex-shrink: 0;
}

@media (max-width: 720px) {
  .heritage-year-banner {
    flex-direction: column;
    align-items: stretch;
  }
}

/* ---------- Music step ---------- */

.music-step {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

/* Selected-track card (shown above the search when something is picked) */
.selected-track-card {
  border-color: rgba(96, 115, 101, 0.4);
  background: #edf3ec;
}

.selected-track {
  display: grid;
  grid-template-columns: 80px 1fr auto;
  gap: 1rem;
  align-items: center;
}

.selected-track.manual-track {
  grid-template-columns: 56px 1fr auto;
}

.selected-track-art {
  width: 80px;
  height: 80px;
  border-radius: 6px;
  object-fit: cover;
  display: block;
  border: 1px solid var(--line);
  background: var(--paper);
}

.selected-track-art-empty,
.selected-track-manual-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--body);
  font-size: 1.4rem;
}

.selected-track-manual-icon {
  width: 56px;
  height: 56px;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--paper);
  font-size: 1.5rem;
}

.selected-track-info {
  display: flex;
  flex-direction: column;
  gap: 0.18rem;
  min-width: 0;
}

.selected-track-info strong {
  font-size: 1.05rem;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.selected-track-info span {
  color: var(--body);
  font-size: 0.9rem;
}

.selected-track-source {
  color: var(--body);
  font-size: 0.78rem;
  opacity: 0.8;
}

.selected-track-actions {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  align-items: stretch;
}

.selected-track-actions .ghost-btn {
  text-align: center;
  white-space: nowrap;
  font-size: 0.82rem;
  padding: 0.45rem 0.75rem;
  text-decoration: none;
}

/* Search form + results */
.music-search-form {
  display: flex;
  gap: 0.6rem;
  margin-top: 0.6rem;
}

.music-search-input {
  flex: 1;
  padding: 0.6rem 0.8rem;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: #fff;
  font-family: inherit;
  font-size: 0.95rem;
  color: var(--ink);
}

.music-search-input:focus {
  outline: none;
  border-color: rgba(96, 115, 101, 0.55);
  box-shadow: 0 0 0 3px rgba(96, 115, 101, 0.12);
}

.music-search-error {
  margin-top: 0.6rem;
  padding: 0.6rem 0.8rem;
  border-radius: 6px;
  background: #f9e2dc;
  border: 1px solid rgba(180, 80, 60, 0.3);
  color: #6b2a1a;
  font-size: 0.88rem;
}

.music-no-results {
  margin: 0.75rem 0 0;
  padding: 0.6rem 0.8rem;
  border-radius: 6px;
  background: var(--paper);
  border: 1px dashed var(--line);
  color: var(--body);
  font-size: 0.88rem;
}

.music-results {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-top: 0.75rem;
}

.music-result {
  display: grid;
  grid-template-columns: 56px 1fr auto;
  gap: 0.85rem;
  align-items: center;
  padding: 0.55rem 0.75rem;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--paper);
  transition: background-color 0.15s ease, border-color 0.15s ease;
}

.music-result:hover {
  background: #f7f3eb;
  border-color: rgba(96, 115, 101, 0.32);
}

.music-result.selected {
  background: #edf3ec;
  border-color: rgba(96, 115, 101, 0.45);
}

.music-result-art {
  width: 56px;
  height: 56px;
  border-radius: 4px;
  object-fit: cover;
  display: block;
  border: 1px solid var(--line);
}

.music-result-art-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--paper);
  color: var(--body);
  font-size: 1.2rem;
}

.music-result-info {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  min-width: 0;
}

.music-result-info strong {
  font-size: 0.95rem;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.music-result-info span {
  color: var(--body);
  font-size: 0.85rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.music-result-meta {
  font-size: 0.76rem;
  opacity: 0.8;
}

.music-result-actions {
  display: flex;
  gap: 0.4rem;
  align-items: center;
}

.music-result-preview {
  padding: 0.4rem 0.75rem;
  font-size: 0.82rem;
  white-space: nowrap;
}

.music-result-no-preview {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.2rem;
  height: 2.2rem;
  color: var(--body);
  opacity: 0.4;
}

/* Wrapper around each result + its expanded preview iframe so the iframe
   appears immediately below its row in the results list. */
.music-result-wrap {
  display: flex;
  flex-direction: column;
  gap: 0;
}

/* Spotify's embeddable preview player. Lives on open.spotify.com/embed,
   works without auth, plays a 30s preview free. Replaces the dropped
   preview_url field that Spotify removed from the Web API in late 2024. */
.spotify-embed {
  width: 100%;
  height: 80px;
  border: 0;
  border-radius: 12px;
  display: block;
  margin-top: 0.55rem;
}

.spotify-embed-result {
  border: 1px solid var(--line);
  border-top: 0;
  border-radius: 0 0 8px 8px;
  margin-top: 0;
}

.music-result-select {
  font-size: 0.82rem;
  padding: 0.45rem 0.85rem;
}

/* Manual-entry prompt + form */
.music-manual-prompt {
  border-style: dashed;
}

.manual-entry-form {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.manual-entry-fields {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
}

.manual-entry-fields .field {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.manual-entry-fields .field span {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--ink);
}

.manual-entry-fields .field input {
  padding: 0.5rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: #fff;
  font-family: inherit;
  font-size: 0.95rem;
  color: var(--ink);
}

.manual-entry-fields .field input:focus {
  outline: none;
  border-color: rgba(96, 115, 101, 0.55);
  box-shadow: 0 0 0 3px rgba(96, 115, 101, 0.12);
}

.manual-entry-actions {
  display: flex;
  gap: 0.5rem;
}

.text-link {
  background: none;
  border: 0;
  padding: 0;
  color: var(--accent);
  text-decoration: underline;
  cursor: pointer;
  font: inherit;
}

@media (max-width: 720px) {
  .manual-entry-fields {
    grid-template-columns: 1fr;
  }
  .selected-track {
    grid-template-columns: 64px 1fr;
  }
  .selected-track-actions {
    grid-column: 1 / -1;
    flex-direction: row;
    flex-wrap: wrap;
  }
  .music-result {
    grid-template-columns: 48px 1fr;
  }
  .music-result-actions {
    grid-column: 1 / -1;
    justify-content: flex-end;
  }
}

/* ---------- Music chips (badges + genres) ---------- */

.music-result-title-row {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  flex-wrap: wrap;
  min-width: 0;
}

.music-result-title-row strong {
  /* Allow truncation when chips push the row tight. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.music-chip-row {
  display: inline-flex;
  gap: 0.3rem;
  flex-wrap: wrap;
}

.music-chip {
  display: inline-flex;
  align-items: center;
  padding: 0.12rem 0.5rem;
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: nowrap;
  line-height: 1.4;
  border: 1px solid transparent;
}

.music-chip-popular {
  background: rgba(96, 115, 101, 0.14);
  color: #2d3d2f;
  border-color: rgba(96, 115, 101, 0.32);
}

.music-chip-live {
  background: #f3eed8;
  color: #6b5328;
  border-color: rgba(155, 130, 78, 0.4);
}

.music-chip-explicit {
  background: #f9e2dc;
  color: #6b2a1a;
  border-color: rgba(180, 80, 60, 0.4);
}

.music-chip-genre {
  background: rgba(96, 115, 101, 0.06);
  color: var(--body);
  border-color: rgba(96, 115, 101, 0.2);
  font-weight: 500;
  font-size: 0.68rem;
  text-transform: capitalize;
}

.music-result-genres {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  margin-top: 0.3rem;
}

/* Selected track card genres get a touch more breathing room. */
.selected-track-info .music-result-genres {
  margin-top: 0.4rem;
}

/* ---------- Music: pre-filter genre dropdown + post-filter chip bar ---------- */

/* iTunes Buy button — accent color to distinguish from the other ghost
   buttons (Open in Spotify, Find instrumental, Remove). Loading state
   appears while we hit the lookup endpoint. */
.itunes-buy-btn {
  background: #fa57c1;
  background: linear-gradient(135deg, #fa57c1 0%, #5a5cf5 100%);
  color: #fff !important;
  border-color: transparent !important;
  text-decoration: none;
  white-space: nowrap;
}

.itunes-buy-btn:hover {
  filter: brightness(1.08);
}

.itunes-loading {
  opacity: 0.65;
  font-style: italic;
  font-size: 0.82rem;
  display: inline-flex;
  align-items: center;
  padding: 0.5rem 0.95rem;
}

.music-search-instrumental {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  margin-top: 0.55rem;
  font-size: 0.85rem;
  color: var(--ink);
  cursor: pointer;
}

.music-search-instrumental input {
  accent-color: #607365;
  width: 1rem;
  height: 1rem;
}

.music-search-instrumental-hint {
  color: var(--body);
  font-size: 0.8rem;
  font-style: italic;
}

.music-search-genre {
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: #fff;
  font-family: inherit;
  font-size: 0.95rem;
  color: var(--ink);
  cursor: pointer;
  min-width: 8rem;
}

.music-search-genre:focus {
  outline: none;
  border-color: rgba(96, 115, 101, 0.55);
  box-shadow: 0 0 0 3px rgba(96, 115, 101, 0.12);
}

.genre-filter-chip.active {
  background: #edf3ec;
  border-color: rgba(96, 115, 101, 0.45);
  color: #2d3d2f;
  font-weight: 700;
}

.genre-filter-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.2rem;
  padding: 0 0.35rem;
  border-radius: 999px;
  background: rgba(96, 115, 101, 0.12);
  color: var(--body);
  font-size: 0.7rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.genre-filter-chip.active .genre-filter-count {
  background: rgba(96, 115, 101, 0.25);
  color: #2d3d2f;
}

.genre-filter-clear {
  display: inline-flex;
  align-items: center;
  padding: 0.3rem 0.55rem;
  border: 0;
  background: none;
  color: var(--accent);
  cursor: pointer;
  font: inherit;
  font-size: 0.8rem;
  text-decoration: underline;
}

@media (max-width: 720px) {
  .music-search-form {
    flex-wrap: wrap;
  }
  .music-search-input {
    flex: 1 1 100%;
  }
  .music-search-genre {
    flex: 1 1 auto;
  }
}

.suggestions-form {
  display: flex;
  flex-direction: column;
  gap: 0.95rem;
  padding-top: 0.5rem;
  border-top: 1px solid rgba(187, 122, 64, 0.18);
  margin-top: 0.5rem;
}

.suggestions-row {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}

/* Instrumental-only toggle at the top of the form. Styled as a soft
   bordered prompt with the hint visible so families understand why this
   matters for slideshow scoring. */
.suggestions-instrumental-toggle {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.7rem;
  align-items: start;
  padding: 0.7rem 0.85rem;
  border: 1px solid rgba(187, 122, 64, 0.32);
  border-radius: 8px;
  background: #fffaef;
  cursor: pointer;
  transition: background-color 0.15s ease;
}

.suggestions-instrumental-toggle:hover {
  background: #fff5e0;
}

.suggestions-instrumental-toggle:has(input:checked) {
  background: #edf3ec;
  border-color: rgba(96, 115, 101, 0.45);
}

.suggestions-instrumental-toggle input {
  margin-top: 0.18rem;
  accent-color: #607365;
  width: 1.1rem;
  height: 1.1rem;
  flex-shrink: 0;
}

.suggestions-instrumental-toggle strong {
  display: block;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--ink);
  line-height: 1.3;
}

.suggestions-instrumental-toggle span {
  display: block;
  margin-top: 0.2rem;
  font-size: 0.82rem;
  color: var(--body);
  line-height: 1.4;
}

.suggestions-label {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--ink);
}

.suggestions-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.suggestions-chip {
  display: inline-flex;
  align-items: center;
  padding: 0.32rem 0.75rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--paper);
  color: var(--body);
  font-size: 0.82rem;
  font-weight: 500;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.suggestions-chip:hover {
  border-color: rgba(96, 115, 101, 0.32);
  background: #f7f3eb;
}

/* Selected state. :has(input:checked) lets the label restyle the moment
   the inner checkbox is toggled — no JS re-render needed. The .active
   class is kept for the initial server-render path. */
.suggestions-chip:has(input:checked),
.suggestions-chip.active {
  background: #edf3ec;
  border-color: rgba(96, 115, 101, 0.45);
  color: #2d3d2f;
  font-weight: 700;
}

.suggestions-chip input {
  /* Hide the actual checkbox; the whole label is the visible chip. */
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

/* MA6 — the input is the thing that takes focus, but it's invisible, so focus
   was invisible too. Put the ring on the chip when its input has it. */
.suggestions-chip:has(input:focus-visible) {
  outline: 3px solid var(--accent, #764239);
  outline-offset: 2px;
}

.suggestions-radio-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
}

.suggestions-radio {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  cursor: pointer;
  font-size: 0.88rem;
  color: var(--ink);
}

.suggestions-radio input {
  accent-color: #607365;
}

.suggestions-input,
.suggestions-textarea {
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: #fff;
  font-family: inherit;
  font-size: 0.92rem;
  color: var(--ink);
  width: 100%;
  box-sizing: border-box;
}

.suggestions-textarea {
  resize: vertical;
  min-height: 4rem;
}

.suggestions-input:focus,
.suggestions-textarea:focus {
  outline: none;
  border-color: rgba(96, 115, 101, 0.55);
  box-shadow: 0 0 0 3px rgba(96, 115, 101, 0.12);
}

.suggestions-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  margin-top: 0.4rem;
}

/* Loading state */
.suggestions-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.65rem;
  padding: 2rem 1rem;
  color: var(--body);
}

.suggestions-spinner {
  width: 1.2rem;
  height: 1.2rem;
  border-radius: 50%;
  border: 2px solid rgba(96, 115, 101, 0.25);
  border-top-color: var(--sage);
  animation: suggestions-spin 0.9s linear infinite;
}

@keyframes suggestions-spin {
  to { transform: rotate(360deg); }
}

/* Suggestion result cards */
.suggestions-results {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  margin-top: 1rem;
  padding-top: 0.85rem;
  border-top: 1px solid rgba(187, 122, 64, 0.2);
}

.suggestions-results-heading {
  margin: 0 0 0.4rem;
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--body);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.suggestion-card.selected {
  background: #edf3ec;
  border-color: rgba(96, 115, 101, 0.45);
}

.suggestion-reason {
  margin: 0.3rem 0 0;
  font-size: 0.83rem;
  color: var(--body);
  line-height: 1.4;
  font-style: italic;
}

.suggestion-actions .ghost-btn,
.suggestion-actions .primary-btn {
  padding: 0.4rem 0.85rem;
  font-size: 0.82rem;
  white-space: nowrap;
  text-align: center;
}

@media (max-width: 720px) {
}

.audio-upload-dropzone {
  display: block;
  width: 100%;
  padding: 1.4rem 1rem;
  border: 2px dashed rgba(96, 115, 101, 0.35);
  border-radius: 8px;
  background: var(--paper);
  color: var(--body);
  text-align: center;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}

/* MA5 — was a <label> (not focusable, no role); now role="button" tabindex="0". */
.audio-upload-dropzone:focus-visible {
  outline: 3px solid var(--accent, #764239);
  outline-offset: 2px;
}
.audio-upload-dropzone:hover,
.audio-upload-dropzone.dragging {
  background: #f3f7f3;
  border-color: rgba(96, 115, 101, 0.55);
}

.audio-upload-dropzone-inner strong {
  display: block;
  font-size: 1rem;
  color: var(--ink);
  margin-bottom: 0.25rem;
}

.audio-upload-dropzone-inner span {
  display: block;
  font-size: 0.82rem;
  color: var(--body);
}

.audio-upload-preview {
  display: grid;
  grid-template-columns: 48px 1fr auto;
  gap: 0.85rem;
  align-items: center;
  padding: 0.7rem 0.85rem;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--paper);
}

.audio-upload-icon {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: rgba(96, 115, 101, 0.85);
  color: #fffaf3;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.5rem;
  flex-shrink: 0;
}

.audio-upload-info {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}

.audio-upload-info strong {
  font-size: 0.95rem;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.audio-upload-info span {
  font-size: 0.82rem;
  color: var(--body);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.audio-upload-actions {
  display: flex;
  gap: 0.4rem;
  flex-shrink: 0;
}

.audio-upload-actions label,
.audio-upload-actions button {
  font-size: 0.82rem;
  padding: 0.4rem 0.75rem;
}

.audio-upload-actions label {
  cursor: pointer;
  display: inline-flex;
  align-items: center;
}

.audio-upload-player {
  width: 100%;
  margin-top: 0.65rem;
  border-radius: 8px;
}

@media (max-width: 720px) {
  .audio-upload-preview {
    grid-template-columns: 48px 1fr;
  }
  .audio-upload-actions {
    grid-column: 1 / -1;
    justify-content: flex-end;
  }
}

/* ---------- Music: free royalty-free library (Pixabay-curated) ---------- */

.free-library-card {
  border-color: rgba(96, 115, 101, 0.32);
  background: #f4f7f1;
}

.free-library-filter {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.5rem;
  padding-bottom: 0.6rem;
  border-bottom: 1px solid rgba(96, 115, 101, 0.14);
}

.free-library-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.32rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--paper);
  color: var(--body);
  font: inherit;
  font-size: 0.8rem;
  font-weight: 500;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.free-library-chip:hover {
  background: #fff;
  border-color: rgba(96, 115, 101, 0.32);
  color: var(--ink);
}

.free-library-chip.active {
  background: #edf3ec;
  border-color: rgba(96, 115, 101, 0.45);
  color: #2d3d2f;
  font-weight: 700;
}

.free-library-list {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-top: 0.85rem;
  /* Cap height so the catalog doesn't blow out the page; scroll inside. */
  max-height: 28rem;
  overflow-y: auto;
  padding-right: 0.4rem;
}

.free-library-track {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  padding: 0.6rem 0.8rem;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--paper);
  transition: background-color 0.15s ease, border-color 0.15s ease;
}

.free-library-track:hover {
  background: #fff;
  border-color: rgba(96, 115, 101, 0.32);
}

.free-library-track.selected {
  background: #edf3ec;
  border-color: rgba(96, 115, 101, 0.5);
}

.free-library-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.85rem;
  align-items: start;
}

.free-library-info {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.free-library-info strong {
  font-size: 0.95rem;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.free-library-actions {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  flex-shrink: 0;
}

.free-library-actions .ghost-btn,
.free-library-actions .primary-btn {
  white-space: nowrap;
  font-size: 0.8rem;
  padding: 0.38rem 0.75rem;
  text-decoration: none;
  text-align: center;
}

/* In-app audio player on each row. preload="none" so we don't fetch 92
   MP3s eagerly; the browser loads on first play. */
.free-library-player {
  width: 100%;
  height: 36px;
  margin-top: 0.15rem;
}

.selected-track-player {
  width: 100%;
  margin-top: 0.75rem;
  border-radius: 8px;
}

@media (max-width: 720px) {
  .free-library-row {
    grid-template-columns: 1fr;
  }
  .free-library-actions {
    flex-direction: row;
    justify-content: flex-end;
  }
}

/* ---------- Music badge under the live preview ---------- */

.preview-music-badge {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-top: 0.55rem;
  padding: 0.55rem 0.75rem;
  border: 1px solid rgba(96, 115, 101, 0.32);
  border-radius: 8px;
  background: #f4f7f1;
}

.preview-music-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.85rem;
  height: 1.85rem;
  border-radius: 50%;
  background: rgba(96, 115, 101, 0.85);
  color: #fffaf3;
  font-size: 1rem;
  flex-shrink: 0;
}

.preview-music-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.preview-music-text strong {
  font-size: 0.88rem;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.preview-music-text span {
  font-size: 0.76rem;
  color: var(--body);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---------- Expanded preview music player ---------- */

.preview-expanded-music {
  margin-top: 0.85rem;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.preview-expanded-audio {
  width: 100%;
  border-radius: 8px;
}

.preview-expanded-music-manual {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.7rem 0.9rem;
  border-radius: 8px;
  background: rgba(255, 253, 247, 0.12);
  color: rgba(255, 253, 247, 0.92);
}

.preview-expanded-music-manual strong {
  display: block;
  font-size: 0.95rem;
  margin-bottom: 0.15rem;
}

.preview-expanded-music-manual span {
  display: block;
  font-size: 0.82rem;
  color: rgba(255, 253, 247, 0.7);
}

.preview-expanded-music-manual .preview-music-icon {
  background: rgba(255, 253, 247, 0.85);
  color: #2a2118;
}

/* ---------- Music step: hero "Discover" card + secondary "Use my own" ---------- */

.music-discover-card {
  border-color: rgba(96, 115, 101, 0.32);
}

.music-discover-header h3 {
  margin: 0;
}

/* Segmented control across the top of the Discover card. */
.music-discover-segments {
  display: flex;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 3px;
  margin-top: 0.4rem;
  gap: 0;
}

.music-discover-segment {
  flex: 1 1 0;
  padding: 0.55rem 0.85rem;
  background: transparent;
  border: 0;
  border-radius: 7px;
  color: var(--body);
  font: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.music-discover-segment:hover:not(.active) {
  background: rgba(96, 115, 101, 0.06);
  color: var(--ink);
}

.music-discover-segment.active {
  background: var(--ink);
  color: var(--paper);
}

.music-discover-body {
  margin-top: 0.85rem;
}

.music-discover-intro {
  margin: 0 0 0.85rem;
  font-size: 0.88rem;
  color: var(--body);
  line-height: 1.45;
}

/* AI form: "More options" toggle styling. */
.suggestions-advanced-toggle {
  align-self: flex-start;
  margin: 0.2rem 0;
  font-size: 0.85rem;
}

.use-my-own-divider {
  margin: 1rem 0 0.6rem;
  font-size: 0.78rem;
  color: var(--body);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-align: center;
  position: relative;
}

.use-my-own-divider::before,
.use-my-own-divider::after {
  content: "";
  position: absolute;
  top: 50%;
  width: calc(50% - 5rem);
  height: 1px;
  background: rgba(96, 115, 101, 0.18);
}
.use-my-own-divider::before { left: 0; }
.use-my-own-divider::after { right: 0; }

.use-my-own-manual-link {
  display: block;
  margin-top: 0.75rem;
  font-size: 0.85rem;
}

/* ---------- Library inline play (one player at a time) ---------- */

.library-play-btn {
  flex-shrink: 0;
  width: 2.4rem;
  height: 2.4rem;
  padding: 0;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink);
  font-size: 0.85rem;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.library-play-btn:hover {
  background: #fff;
  border-color: rgba(96, 115, 101, 0.4);
}

.library-play-btn.playing {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}

.free-library-row {
  grid-template-columns: auto 1fr auto !important;
  gap: 0.7rem !important;
  align-items: center;
}

.free-library-track.playing {
  border-color: rgba(96, 115, 101, 0.5);
  background: rgba(96, 115, 101, 0.05);
}

.free-library-list {
  max-height: 36rem;
}

/* Compact library rows — drop tags, smaller buttons, tighter padding. */
.free-library-track {
  padding: 0.55rem 0.75rem;
  gap: 0.3rem;
}

.library-play-btn {
  width: 2.1rem;
  height: 2.1rem;
  font-size: 0.78rem;
}

.library-pick-btn {
  font-size: 0.8rem !important;
  padding: 0.4rem 0.85rem !important;
  min-width: 4rem;
}

/* Inline player when expanded — shorter than before. */
.free-library-track .free-library-player {
  height: 32px;
  margin-top: 0.5rem;
}

/* ---------- Library row redesign (clean list, not cards) ---------- */

/* Override the earlier card-per-row treatment. The list now reads as a
   single scrollable surface with subtle row separators. */
.free-library-list {
  display: block !important;
  flex-direction: unset !important;
  gap: 0 !important;
  max-height: 32rem !important;
  overflow-y: auto;
  margin-top: 0.85rem;
  border-top: 1px solid rgba(96, 115, 101, 0.18);
}

.free-library-track {
  display: block !important;
  flex-direction: unset !important;
  padding: 0.45rem 0.5rem !important;
  border: 0 !important;
  border-bottom: 1px solid rgba(96, 115, 101, 0.1) !important;
  border-radius: 0 !important;
  background: transparent !important;
  transition: background-color 0.12s ease;
}

.free-library-track:last-child {
  border-bottom: 0 !important;
}

.free-library-track:hover {
  background: rgba(96, 115, 101, 0.04) !important;
}

.free-library-track.playing {
  background: rgba(96, 115, 101, 0.07) !important;
}

.free-library-track.selected {
  background: rgba(96, 115, 101, 0.1) !important;
}

.free-library-row {
  display: flex !important;
  align-items: center !important;
  gap: 0.7rem !important;
  grid-template-columns: unset !important;
}

/* Compact play button — small icon, not a chunky control. */
.library-play-btn {
  width: 1.85rem !important;
  height: 1.85rem !important;
  font-size: 0.72rem !important;
  flex-shrink: 0;
  border-color: rgba(96, 115, 101, 0.22) !important;
}

.library-play-btn:hover {
  background: var(--ink) !important;
  color: var(--paper) !important;
  border-color: var(--ink) !important;
}

.library-play-btn.playing {
  background: var(--ink) !important;
  color: var(--paper) !important;
  border-color: var(--ink) !important;
}

/* Title + subtle category text inline. */
.free-library-info {
  flex: 1 1 auto !important;
  min-width: 0;
  display: flex !important;
  align-items: baseline !important;
  gap: 0.55rem;
  flex-direction: row !important;
}

.free-library-info strong {
  font-size: 0.92rem !important;
  font-weight: 600;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.free-library-category {
  font-size: 0.74rem;
  color: var(--body);
  opacity: 0.7;
  white-space: nowrap;
  flex-shrink: 0;
  text-transform: capitalize;
}

/* Inline action group — download icon + pick button, side by side. */
.free-library-actions {
  display: flex !important;
  flex-direction: row !important;
  align-items: center !important;
  gap: 0.35rem !important;
  flex-shrink: 0;
}

/* Pick / Selected buttons — small, refined. */
.library-pick-btn {
  padding: 0.32rem 0.85rem;
  background: var(--ink);
  color: var(--paper);
  border: 0;
  border-radius: 999px;
  font: inherit;
  font-size: 0.78rem;
  font-weight: 600;
  cursor: pointer;
  transition: filter 0.12s ease;
}

.library-pick-btn:hover {
  filter: brightness(1.15);
}

.library-pick-selected {
  padding: 0.32rem 0.85rem;
  background: rgba(96, 115, 101, 0.15);
  color: #2d3d2f;
  border: 1px solid rgba(96, 115, 101, 0.35);
  border-radius: 999px;
  font: inherit;
  font-size: 0.78rem;
  font-weight: 600;
  cursor: pointer;
}

/* Inline audio player when expanded — compact and indented. */
.free-library-track .free-library-player {
  height: 32px !important;
  margin: 0.35rem 0 0.1rem 2.55rem;
  width: calc(100% - 2.55rem) !important;
}

/* Tighter filter chip area. */
.free-library-filter {
  padding-top: 0 !important;
  padding-bottom: 0.5rem !important;
  border-top: 0 !important;
}

/* ============================================================
   Music page redesign — continuous one-page flow.
   ============================================================ */

/* Wider page + roomy sidebar, consistent with the other redesigned steps. */
.main:has(.music-discover-card) { width: min(1560px, calc(100% - 2rem)); }
.main:has(.music-discover-card) .wizard { grid-template-columns: minmax(0, 1fr) 360px; }

/* Source tabs: green active state + leading icons. */
.music-discover-segment.active { background: var(--sage); color: #fff; }
.mds-ico {
  display: inline-block; width: 15px; height: 15px; vertical-align: -2px; margin-right: 7px;
  background-color: currentColor;
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
}
.mds-ico-library { -webkit-mask-image: url(/icons/music-note.png?v=1); mask-image: url(/icons/music-note.png?v=1); }
.mds-ico-ai { -webkit-mask-image: url(/icons/music-sparkle.png?v=1); mask-image: url(/icons/music-sparkle.png?v=1); }
.mds-ico-own { -webkit-mask-image: url(/icons/music-upload.png?v=1); mask-image: url(/icons/music-upload.png?v=1); }
.mds-ico-none { -webkit-mask-image: url(/icons/music-no-audio.png?v=1); mask-image: url(/icons/music-no-audio.png?v=1); }

/* Search field under the source tabs. */
.music-search-field { position: relative; margin: 0.9rem 0 0.75rem; }
.music-search-ico {
  position: absolute; left: 14px; top: 50%; transform: translateY(-50%);
  width: 16px; height: 16px; opacity: 0.55; background-color: var(--muted);
  -webkit-mask: url(/icons/music-search.png?v=1) center / contain no-repeat;
  mask: url(/icons/music-search.png?v=1) center / contain no-repeat;
}
.music-search-input {
  width: 100%; box-sizing: border-box;
  padding: 0.7rem 0.95rem 0.7rem 2.5rem;
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--paper); color: var(--ink);
  font: inherit; font-size: 0.92rem;
}
.music-search-input::placeholder { color: var(--muted); opacity: 0.8; }
.music-search-input:focus {
  outline: none; border-color: var(--sage);
  box-shadow: 0 0 0 3px rgba(95, 113, 101, 0.12);
}
.music-library-empty { padding: 1.4rem 0.5rem; color: var(--body); font-size: 0.9rem; }

/* Shared grid columns for the list header + each row. */
.free-library-listhead {
  display: grid;
  grid-template-columns: 1.85rem minmax(0, 1fr) 144px 62px auto; /* MUSIC-CATS: 144px fits "Cinematic & Solemn" */
  align-items: center; gap: 0.7rem;
  padding: 0 0.5rem 0.5rem;
  font-size: 0.68rem; letter-spacing: 0.07em; text-transform: uppercase;
  color: var(--muted); font-weight: 600;
  border-bottom: 1px solid rgba(95, 113, 101, 0.18);
}
.free-library-listhead .flh-song { grid-column: 1 / 3; }

.music-step .free-library-row {
  display: grid !important;
  grid-template-columns: 1.85rem minmax(0, 1fr) 144px 62px auto !important;
  align-items: center !important; gap: 0.7rem !important;
}
.music-mood-tag {
  justify-self: start;
  font-size: 0.72rem; font-weight: 600; color: #4f5f52;
  background: rgba(95, 113, 101, 0.1);
  padding: 0.2rem 0.6rem; border-radius: 999px;
  white-space: nowrap; text-transform: capitalize;
}
.music-track-dur {
  justify-self: start;
  font-size: 0.82rem; color: var(--body); opacity: 0.75;
  font-variant-numeric: tabular-nums;
}

/* Pick buttons → green. */
.library-pick-btn { background: var(--sage); }
.library-pick-btn:hover { filter: brightness(1.08); }

/* Pagination. */
.music-pagination {
  display: flex; align-items: center; justify-content: center;
  gap: 0.35rem; padding: 1rem 0 0.2rem;
}
.music-page-num {
  min-width: 2rem; height: 2rem; padding: 0 0.5rem;
  border: 1px solid var(--line); background: var(--paper);
  border-radius: 8px; font: inherit; font-size: 0.85rem;
  color: var(--body); cursor: pointer;
  transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.music-page-num:hover:not(.active) { border-color: var(--sage); color: var(--ink); }
.music-page-num.active { background: var(--sage); color: #fff; border-color: var(--sage); }
.music-page-ellipsis { padding: 0 0.2rem; color: var(--muted); }
.music-page-arrow {
  width: 2rem; height: 2rem; border: 1px solid var(--line);
  background: var(--paper); border-radius: 8px; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.music-page-arrow:hover:not(:disabled) { border-color: var(--sage); }
.music-page-arrow:disabled { opacity: 0.4; cursor: default; }
.music-page-arrow-ico {
  width: 14px; height: 14px; background-color: var(--body);
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
}
.music-page-arrow-ico.prev { -webkit-mask-image: url(/icons/music-arrow-left.png?v=1); mask-image: url(/icons/music-arrow-left.png?v=1); }
.music-page-arrow-ico.next { -webkit-mask-image: url(/icons/music-arrow-right.png?v=1); mask-image: url(/icons/music-arrow-right.png?v=1); }

/* Inline tintable icons used in teaser/tip buttons + headings. */
.music-inline-ico {
  display: inline-block; width: 16px; height: 16px; vertical-align: -3px; margin-right: 7px;
  background-color: currentColor;
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
}
.music-ico-sparkle { -webkit-mask-image: url(/icons/music-sparkle.png?v=1); mask-image: url(/icons/music-sparkle.png?v=1); }
.music-ico-upload { -webkit-mask-image: url(/icons/music-upload.png?v=1); mask-image: url(/icons/music-upload.png?v=1); }
.music-ico-tip { -webkit-mask-image: url(/icons/music-tip-bulb.png?v=1); mask-image: url(/icons/music-tip-bulb.png?v=1); }

/* Teaser + tip cards below the library. (.module-card is a 2-col grid —
   force block so headings/copy stack instead of splitting into columns.) */
.music-teaser-card { display: block; margin-top: 1rem; }
.music-tip-card { display: block; }
.music-teaser-title { margin: 0 0 0.3rem; font-family: "Cormorant Garamond", Georgia, serif; font-size: 1.4rem; font-weight: 600; color: var(--ink); }
.music-teaser-sub { margin: 0 0 0.9rem; color: var(--body); font-size: 0.9rem; }
.music-teaser-chips { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.music-teaser-chip {
  padding: 0.42rem 0.9rem; border: 1px solid var(--line);
  background: var(--paper); border-radius: 999px; font: inherit;
  font-size: 0.85rem; color: var(--body); cursor: pointer;
  transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.music-teaser-chip:hover { border-color: var(--sage); color: var(--ink); }
.music-teaser-chip.active { background: var(--sage); color: #fff; border-color: var(--sage); }
.music-ai-teaser .music-teaser-body {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.4rem; flex-wrap: nowrap;
}
.music-ai-teaser .music-teaser-chips { flex: 1 1 auto; min-width: 0; }
@media (max-width: 720px) {
  .music-ai-teaser .music-teaser-body { flex-wrap: wrap; align-items: flex-start; }
}
.music-teaser-cta { flex-shrink: 0; white-space: nowrap; }

.music-upload-teaser {
  position: relative; display: flex; align-items: center; gap: 1rem;
  padding-right: 150px; overflow: hidden;
}
.music-upload-teaser-text { flex: 1 1 auto; }
.music-upload-teaser .music-teaser-title,
.music-upload-teaser .music-teaser-sub { margin-bottom: 0.2rem; }
.music-upload-teaser-cta { flex-shrink: 0; z-index: 1; white-space: nowrap; }
.music-upload-teaser-decor {
  position: absolute; right: 10px; bottom: -6px; width: 120px;
  opacity: 0.95; pointer-events: none;
}

.music-tip-card {
  position: relative; overflow: hidden;
  background: #faf4e8; border-color: rgba(120, 100, 70, 0.18);
  padding-right: 170px;
}
.music-tip-head { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.4rem; }
.music-tip-title { margin: 0; font-family: "Cormorant Garamond", Georgia, serif; font-size: 1.3rem; font-weight: 600; color: var(--ink); }
.music-tip-copy { margin: 0.25rem 0; color: var(--body); font-size: 0.9rem; line-height: 1.5; }
.music-tip-decor { position: absolute; right: 12px; bottom: 0; width: 150px; pointer-events: none; }

@media (max-width: 720px) {
  .music-upload-teaser, .music-tip-card { padding-right: 1.1rem; }
  .music-upload-teaser-decor, .music-tip-decor { display: none; }
  .music-step .free-library-row {
    grid-template-columns: 1.85rem minmax(0, 1fr) auto !important;
  }
  .free-library-listhead { display: none; }
  .music-mood-tag, .music-track-dur { display: none; }
}

/* ---------- Selected track header with inline Continue button ---------- */

.selected-track-header {
  display: flex !important;
  flex-direction: row !important;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
}

.selected-track-header > div {
  flex: 1 1 auto;
  min-width: 0;
}

.selected-track-continue {
  flex-shrink: 0;
  white-space: nowrap;
  padding: 0.55rem 1rem !important;
}

/* ---------- No-audio panel ---------- */

.no-audio-panel {
  padding: 1.5rem 1rem;
  text-align: center;
}

.no-audio-panel h4 {
  margin: 0 0 0.5rem;
  font-family: Georgia, "Times New Roman", serif;
  font-size: 1.3rem;
  font-weight: 500;
  color: var(--ink);
}

.no-audio-panel p {
  max-width: 32rem;
  margin: 0 auto 1.25rem;
  color: var(--body);
  font-size: 0.92rem;
  line-height: 1.55;
}

.no-audio-confirm,
.no-audio-continue {
  padding: 0.6rem 1.4rem !important;
}

@media (max-width: 720px) {
  .selected-track-header {
    flex-direction: column !important;
    align-items: stretch;
  }
}

/* ---------- 5-tab segmented control ---------- */
/* The discover segments grew from 3 to 5 tabs. Tighter padding +
   slightly smaller font so they fit comfortably on a desktop layout. */
.music-discover-segments .music-discover-segment {
  padding: 0.5rem 0.7rem;
  font-size: 0.84rem;
}

@media (max-width: 880px) {
  .music-discover-segments {
    flex-wrap: wrap;
  }
  .music-discover-segments .music-discover-segment {
    flex: 1 1 calc(50% - 4px);
  }
}

/* ---------- Photo Motion (Ken Burns drift) ---------- */
/* Per-photo zoom animation. transform-origin is set per-slot via the
   existing --focus-x / --focus-y face-focus variables, so each photo
   zooms toward where the face actually is, not the geometric center.
   Animation duration matches the photo's hold time so the motion
   completes exactly when the photo is about to transition out. */

/* Whisper ~3% zoom — barely perceptible. Adds the faintest hint of life
   to a photo without ever drawing attention to itself. */
.preview-stage.motion-whisper .preview-slide.active,
.preview-stage.motion-whisper .lantern-polaroid.active img,
.preview-stage.motion-whisper .heritage-slot.active img,
.preview-stage.motion-whisper .backdrop-photo-slot.active img,
.preview-stage.motion-whisper .backdrop-photo-slot.active .backdrop-photo {
  animation: motion-ken-burns-whisper var(--hold, 5000ms) ease-out forwards;
  transform-origin: var(--focus-x, 50%) var(--focus-y, 30%);
}

/* Gentle ~6% zoom — the memorial-film default. Enough motion to feel
   "alive" without competing with the photos. */
.preview-stage.motion-subtle .preview-slide.active,
.preview-stage.motion-subtle .lantern-polaroid.active img,
.preview-stage.motion-subtle .heritage-slot.active img,
.preview-stage.motion-subtle .backdrop-photo-slot.active img,
.preview-stage.motion-subtle .backdrop-photo-slot.active .backdrop-photo {
  animation: motion-ken-burns-subtle var(--hold, 5000ms) ease-out forwards;
  transform-origin: var(--focus-x, 50%) var(--focus-y, 30%);
}

/* Dramatic ~12% zoom — more cinematic. Use sparingly; with fast hold
   times this can feel busy for a memorial. */
.preview-stage.motion-dramatic .preview-slide.active,
.preview-stage.motion-dramatic .lantern-polaroid.active img,
.preview-stage.motion-dramatic .heritage-slot.active img,
.preview-stage.motion-dramatic .backdrop-photo-slot.active img,
.preview-stage.motion-dramatic .backdrop-photo-slot.active .backdrop-photo {
  animation: motion-ken-burns-dramatic var(--hold, 5000ms) ease-out forwards;
  transform-origin: var(--focus-x, 50%) var(--focus-y, 30%);
}

@keyframes motion-ken-burns-whisper {
  from { transform: scale(1); }
  to { transform: scale(1.03); }
}

@keyframes motion-ken-burns-subtle {
  from { transform: scale(1); }
  to { transform: scale(1.06); }
}

@keyframes motion-ken-burns-dramatic {
  from { transform: scale(1); }
  to { transform: scale(1.12); }
}

/* When the existing zoom-dissolve transition is also active, prefer
   the per-photo motion (more useful). The transition's zoom is a
   one-shot effect at the transition point; the motion runs through the
   whole hold. */
.preview-stage.motion-subtle.transition-zoom-dissolve .preview-slide.active,
.preview-stage.motion-dramatic.transition-zoom-dissolve .preview-slide.active {
  animation-name: motion-ken-burns-subtle;
}
.preview-stage.motion-dramatic.transition-zoom-dissolve .preview-slide.active {
  animation-name: motion-ken-burns-dramatic;
}

/* ---------- Backdrop library (AI-generated thumbnails) ---------- */

.backdrop-library-section {
  margin-bottom: 0.5rem;
}

.backdrop-library-filter {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin: 0.65rem 0 0.85rem;
}

.backdrop-library-grid {
  display: grid;
  /* Three columns — used by both the Template tab's Backdrop library
     and the Opening tab's title card picker. */
  grid-template-columns: repeat(3, 1fr);
  gap: 0.55rem;
  /* Roughly four rows tall before scrolling kicks in. The exact
     height depends on tile aspect ratio + mood badge, but ~21rem hits
     the right "show four rows" feel at typical body widths. */
  max-height: 21rem;
  overflow-y: auto;
  padding: 0.25rem;
}
@media (max-width: 720px) {
  .backdrop-library-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

.backdrop-library-tile {
  position: relative;
  display: block;
  /* Padding-bottom trick locks the tile to 16:9 regardless of grid /
     flex / button quirks — height = width * 9/16 = 56.25%. The img
     fills via absolute positioning. */
  width: 100%;
  height: 0;
  padding: 0 0 56.25% 0;
  border: 2px solid transparent;
  border-radius: 8px;
  overflow: hidden;
  cursor: pointer;
  background: var(--paper);
  transition: transform 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease;
}

.backdrop-library-tile:hover {
  transform: translateY(-2px);
  border-color: rgba(96, 115, 101, 0.5);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.backdrop-library-tile.selected {
  border-color: var(--sage);
  box-shadow: 0 4px 12px rgba(96, 115, 101, 0.3);
}

.backdrop-library-tile img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.backdrop-library-selected-badge {
  position: absolute;
  top: 0.4rem;
  right: 0.4rem;
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 50%;
  background: var(--sage);
  color: #fffaf3;
  font-size: 0.85rem;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* Title-card-sourced backdrops carry an "OPENING" badge to signal
   they're meant primarily for the main photo / film opening slide. */
.backdrop-library-opening-badge {
  position: absolute;
  top: 0.4rem;
  left: 0.4rem;
  padding: 0.18rem 0.5rem;
  border-radius: 4px;
  background: rgba(201, 162, 90, 0.92);
  color: #1a1410;
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.06em;
}

.backdrop-library-mood {
  position: absolute;
  left: 0.4rem;
  bottom: 0.4rem;
  padding: 0.15rem 0.45rem;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.55);
  color: #fffaf3;
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: capitalize;
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}

/* "Save to v2" curation control on each backdrop tile. */
.backdrop-save-v2 {
  position: absolute;
  top: 0.4rem;
  left: 0.4rem;
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 0.2rem 0.5rem;
  border-radius: 999px;
  background: rgba(118, 66, 57, 0.92);
  color: #fff;
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.12s ease;
  z-index: 2;
}
.backdrop-save-v2 i { font-style: normal; font-size: 0.85rem; line-height: 1; }
.backdrop-library-tile:hover .backdrop-save-v2,
.emotional-style-thumb:hover .backdrop-save-v2,
.backdrop-save-v2:focus-visible { opacity: 1; }
.backdrop-library-tile.v2-saved .backdrop-save-v2,
.emotional-style-thumb.v2-saved .backdrop-save-v2 { background: rgba(63, 90, 55, 0.95); }
/* "Already saved to v2" badge — shows which feeling(s) it's filed under. */
.backdrop-v2-badge {
  position: absolute;
  right: 0.35rem;
  bottom: 0.35rem;
  max-width: calc(100% - 0.7rem);
  padding: 0.15rem 0.45rem;
  border-radius: 999px;
  background: rgba(63, 90, 55, 0.95);
  color: #fff;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  z-index: 2;
  pointer-events: none;
}

/* Anchored feeling-picker popover for Save to v2. */
.save-v2-pop {
  position: fixed;
  z-index: 9998;
  width: 250px;
  background: #fffdf8;
  border: 1px solid rgba(96, 90, 80, 0.25);
  border-radius: 12px;
  box-shadow: 0 12px 34px rgba(30, 20, 16, 0.28);
  padding: 12px;
}
.save-v2-title { font-size: 0.82rem; font-weight: 600; color: #33302b; margin-bottom: 9px; line-height: 1.3; }
.save-v2-feels { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.save-v2-feel {
  font: inherit;
  font-size: 0.75rem;
  padding: 5px 10px;
  border-radius: 999px;
  border: 1px solid rgba(96, 90, 80, 0.28);
  background: #fff;
  color: #7c766c;
  cursor: pointer;
}
.save-v2-feel.on { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }
.save-v2-star { display: flex; align-items: center; gap: 8px; font-size: 0.78rem; color: #4a463f; cursor: pointer; margin-bottom: 11px; }
.save-v2-actions { display: flex; justify-content: flex-end; gap: 8px; }
.primary-btn.small, .ghost-btn.small { padding: 5px 12px; font-size: 0.8rem; }

@media (max-width: 720px) {
  .backdrop-library-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* ---------- Backdrop placement override sliders ---------- */

.placement-slider-row {
  display: grid;
  gap: 0.3rem;
  margin-top: 0.7rem;
}

.placement-slider-row:first-of-type {
  margin-top: 0.5rem;
}

/* ---------- Drag interaction on the backdrop preview ---------- */

/* The whole .backdrop-stage-area becomes interactive on library
   backdrops — handlers live here so they're reachable regardless of
   which slot (a or b) is currently visible during the preview cycle. */
.backdrop-stage-area.is-interactive {
  /* No global cursor — the .backdrop-interactive-frame (which sits
     exactly on the photo's visible bounds) sets cursor:grab so the
     family only feels grabby ON the photo, not on empty backdrop. */
  touch-action: none;
}

/* Overlay containing the interactive frame outline + 4 corner handles.
   Positioned absolutely inside the stage area, sized + positioned via
   CSS calc() against the same --photo-pos-x/y/--photo-slot-width/height
   vars that drive the actual photo slot. So no matter which slot is
   visible, the frame and handles align with the current photo. */
.backdrop-interactive-overlay {
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none; /* default — only the frame and handles take events */
}

.backdrop-interactive-frame {
  position: absolute;
  /* Position + size from the photo's REAL visible extent (after
     object-fit:contain letterboxes a portrait/landscape photo inside
     the square-in-% slot), not the slot's bounding box. Falls back to
     slot bounds if --photo-extent-* isn't set. */
  top:    calc(var(--photo-pos-y) - var(--photo-extent-y, var(--photo-slot-height)) / 2);
  left:   calc(var(--photo-pos-x) - var(--photo-extent-x, var(--photo-slot-width))  / 2);
  width:  var(--photo-extent-x, var(--photo-slot-width));
  height: var(--photo-extent-y, var(--photo-slot-height));
  outline: 1px dashed rgba(201, 162, 90, 0.55);
  outline-offset: -1px;
  pointer-events: none;
  transition: outline-color 140ms ease;
}
.backdrop-stage-area.is-interactive:hover .backdrop-interactive-frame,
.backdrop-stage-area.is-dragging .backdrop-interactive-frame,
.backdrop-stage-area.is-resizing .backdrop-interactive-frame {
  outline: 2px solid rgba(201, 162, 90, 0.9);
  outline-offset: -1px;
}

/* Corner handles — gold dots at the 4 photo corners. Positioned via
   CSS calc() using the photo center + half-extent. */
.backdrop-handle {
  position: absolute;
  width: 14px;
  height: 14px;
  background: #c9a25a;
  border: 2px solid #fff;
  border-radius: 50%;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.35);
  z-index: 6;
  opacity: 0;
  pointer-events: auto;
  transition: opacity 140ms ease, transform 80ms ease;
}
.backdrop-stage-area.is-interactive:hover .backdrop-handle,
.backdrop-stage-area.is-edit-mode .backdrop-handle,
.backdrop-stage-area.is-dragging .backdrop-handle,
.backdrop-stage-area.is-resizing .backdrop-handle {
  opacity: 1;
}
/* Same for the dashed frame — visible whenever edit mode is on so the
   family sees the editable area without having to hover. */
.backdrop-stage-area.is-edit-mode .backdrop-interactive-frame {
  outline: 2px solid rgba(201, 162, 90, 0.9);
  outline-offset: -1px;
}
.backdrop-handle:hover {
  transform: translate(-50%, -50%) scale(1.2);
}

/* Snap guide lines — flash across the stage when the photo's X or Y
   locks to 0 / 50 / 100. Vertical guide for X-snap, horizontal for
   Y-snap. Sits inside .backdrop-interactive-overlay so it shows
   above the photo but below the resize handles. */
.backdrop-snap-guide {
  position: absolute;
  background: rgba(201, 162, 90, 0.85);
  pointer-events: none;
  opacity: 0;
  transition: opacity 80ms ease;
  z-index: 5; /* below handles (6), above frame */
  box-shadow: 0 0 6px rgba(201, 162, 90, 0.5);
}
.backdrop-snap-guide.is-active {
  opacity: 1;
}
.backdrop-snap-guide-v {
  /* Vertical line — full stage height at the snapped X position. */
  top: 0;
  bottom: 0;
  width: 1px;
  transform: translateX(-0.5px);
}
.backdrop-snap-guide-h {
  /* Horizontal line — full stage width at the snapped Y position. */
  left: 0;
  right: 0;
  height: 1px;
  transform: translateY(-0.5px);
}

/* Size readout chip flashes gold when photoSizePct snaps to a
   milestone (50 / 75 / 100). Quick feedback without needing a guide
   line for the size axis. */
.placement-readout-value.is-snapped {
  background: rgba(201, 162, 90, 0.18);
  color: #5a4220;
  transition: background 80ms ease, color 80ms ease;
}
/* Handle positions use the photo's real extent (--photo-extent-x/y)
   so they sit at the photo's visible corners, not the slot's wider
   bounding box. Falls back to slot bounds if extent vars aren't set. */
.backdrop-handle-nw {
  top:  calc(var(--photo-pos-y) - var(--photo-extent-y, var(--photo-slot-height)) / 2);
  left: calc(var(--photo-pos-x) - var(--photo-extent-x, var(--photo-slot-width))  / 2);
  transform: translate(-50%, -50%);
  cursor: nwse-resize;
}
.backdrop-handle-ne {
  top:  calc(var(--photo-pos-y) - var(--photo-extent-y, var(--photo-slot-height)) / 2);
  left: calc(var(--photo-pos-x) + var(--photo-extent-x, var(--photo-slot-width))  / 2);
  transform: translate(-50%, -50%);
  cursor: nesw-resize;
}
.backdrop-handle-sw {
  top:  calc(var(--photo-pos-y) + var(--photo-extent-y, var(--photo-slot-height)) / 2);
  left: calc(var(--photo-pos-x) - var(--photo-extent-x, var(--photo-slot-width))  / 2);
  transform: translate(-50%, -50%);
  cursor: nesw-resize;
}
.backdrop-handle-se {
  top:  calc(var(--photo-pos-y) + var(--photo-extent-y, var(--photo-slot-height)) / 2);
  left: calc(var(--photo-pos-x) + var(--photo-extent-x, var(--photo-slot-width))  / 2);
  transform: translate(-50%, -50%);
  cursor: nwse-resize;
}
.placement-save-row .primary-btn {
  display: inline-block;
}

/* ============================================================================
 * Draft tab — Player + timing controls + summary
 *
 * The Draft tab is the family's "rough cut" review: a watchable end-to-end
 * preview of the film with everything chosen so far. Layout is:
 *
 *   [ Banner ]
 *   [ Player card — big 7:4 stage + transport controls ]
 *   [ Two columns: timing controls | film summary ]
 *   [ Actions ]
 *
 * The player stage reuses the same 7:4 aspect as the title card (which is
 * what gpt-image-1 actually outputs). Controls bar sits below the stage,
 * not overlaid — easier to read and doesn't compete with the film.
 * ========================================================================= */

.draft-secondary {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 1rem;
  margin-top: 1rem;
}
@media (max-width: 900px) {
  .draft-secondary { grid-template-columns: minmax(0, 1fr); }
}
/* Timing card now stands alone (Film at a glance moved to the Payment step). */
.draft-secondary-single { grid-template-columns: minmax(0, 1fr); }
/* Film at a glance shown beside the bundle card on the Payment step. */
.payment-step .draft-summary-card { margin: 0; }
/* Small auto-playing rough-cut preview, bottom-right of the summary card.
   Reuses the inline cinema engine (silent, transitions); click opens Draft. */
.draft-summary-card { position: relative; }
.glance-preview .slideshow-controls { display: none !important; }
@media (max-width: 900px) { }

/* ---------- Cinematic hero card (Draft tab centerpiece) ----------
 * The Draft tab is laid out as a centered column rather than full-width
 * so the hero card reads as a poster, not a banner. The column max-width
 * is shared by the secondary row + actions so everything stays vertically
 * aligned. Tune --draft-column to widen/narrow the whole tab. */

.draft-hero,
.draft-secondary,
.draft-actions {
  --draft-column: 920px;
  max-width: var(--draft-column);
  margin-left: auto;
  margin-right: auto;
}

/* Warm cream backdrop card. Inside it sits the dark cinematic mat
   (.draft-marquee) that frames the poster like a private screening. */
.draft-hero {
  background: linear-gradient(180deg, #fbf6ec 0%, #f3ead4 100%);
  border-radius: 18px;
  padding: 1.15rem 1.75rem 1.5rem;
  border: 1px solid rgba(0, 0, 0, 0.06);
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.05);
  margin-top: 1rem;
}
.draft-hero-header .eyebrow {
  font-size: 0.72rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #8a6b3a;
  margin: 0;
}
.draft-hero-title {
  font-family: "Cormorant Garamond", "EB Garamond", Georgia, serif;
  font-weight: 500;
  font-size: 2rem;
  letter-spacing: 0;
  margin: 0.5rem 0 0.6rem;
  color: #1f1813;
}
.draft-hero-subtitle {
  margin: 0;
  font-size: 0.95rem;
  line-height: 1.55;
  color: #5a4a35;
}
.draft-poster-stage > .draft-player-stage-inner,
.draft-poster-stage > .preview-stage,
.draft-poster-stage > .titlecard-stage,
.draft-poster-stage .draft-player-stage-inner > .preview-stage,
.draft-poster-stage .draft-player-stage-inner > .titlecard-stage {
  position: absolute !important;
  inset: 0 !important;
  width: 100% !important;
  height: 100% !important;
  aspect-ratio: auto !important;
  border-radius: 0 !important;
  box-shadow: none !important;
}

@media (max-width: 640px) {
  .draft-hero {
    padding: 1.25rem 1rem 1.5rem;
  }
  .draft-hero-title {
    font-size: 1.6rem;
  }
}

.draft-player {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.draft-player-stage {
  position: relative;
  width: 100%;
  aspect-ratio: 7 / 4;
  border-radius: 14px;
  overflow: hidden;
  background: #1b1612;
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.24);
  container-type: inline-size;
}

.draft-player-stage-inner {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* Two stacked stage slots crossfade between scenes. Both are absolutely
   positioned, opacity:0 by default. paintDraftPlayer swaps `.active`
   between them when the timeline advances — CSS handles the fade at the
   family's chosen transition speed (--transition-duration on the parent
   stage). Variants:
   - cross-fade / zoom-dissolve: both slots animate simultaneously
   - fade-background: outgoing finishes its fade before incoming starts
     (handled by setTimeout in paintDraftPlayer) */
.draft-player-stage-slot {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity var(--transition-duration, 600ms) ease;
  /* Zoom-dissolve adds a tiny scale lift on top of the opacity fade.
     For the inactive slot we hold it scaled slightly larger so when it
     becomes active it eases back toward neutral. */
}
.draft-player-stage-slot.active {
  opacity: 1;
}

/* Zoom-dissolve: each slot has a subtle scale animation timed with its
   opacity fade. Outgoing eases up slightly as it disappears; incoming
   eases down to neutral as it appears. */
.draft-player.transition-zoom-dissolve .draft-player-stage-slot {
  transition: opacity var(--transition-duration, 600ms) ease,
              transform var(--transition-duration, 600ms) ease;
  transform: scale(1.02);
}
.draft-player.transition-zoom-dissolve .draft-player-stage-slot.active {
  transform: scale(1);
}

/* The inner stage often contains another aspect-ratio'd element
   (preview-stage, titlecard-stage). Make sure those fill our box. */
.draft-player-stage-inner > .preview-stage,
.draft-player-stage-inner > .titlecard-stage {
  position: absolute !important;
  inset: 0 !important;
  width: 100% !important;
  height: 100% !important;
  aspect-ratio: auto !important;
  border-radius: 0 !important;
  box-shadow: none !important;
}

/* Big centered Play overlay shown on the poster frame (and any time the
   player is paused). The player JS toggles a `.is-playing` class on
   .draft-player to hide it during playback. */
.draft-player-play-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  cursor: pointer;
  transition: background 160ms ease;
  z-index: 5;
}
.draft-player.is-playing .draft-player-play-overlay {
  opacity: 0;
  pointer-events: none;
}

/* Restore badge — small chip in the bottom-left during playback of any
   photo flagged needsRestoration && willRestore. Tells the family the
   final cut will have a cleaned-up version. */
.draft-player-restore-badge {
  position: absolute;
  bottom: 12px;
  left: 12px;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.35rem 0.7rem;
  background: rgba(0, 0, 0, 0.65);
  color: #f5ecd5;
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border-radius: 999px;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  z-index: 6;
}

/* A colorized photograph is an AI interpretation, not a factual recovery of
   the original colors. Keep that disclosure on the colorized film frame. */
.draft-player-colorization-badge {
  position: absolute;
  right: 12px;
  bottom: 12px;
  display: inline-flex;
  align-items: center;
  padding: 0.35rem 0.7rem;
  background: rgba(0, 0, 0, 0.72);
  color: #fff7df;
  font-size: 0.8rem;
  letter-spacing: 0.02em;
  text-transform: none;
  border: 1px solid rgba(255, 247, 223, 0.36);
  border-radius: 999px;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  z-index: 6;
}

/* Life Scroll captures scene 0's background once and reuses it behind every
   scene. The disclosure is foreground content for one photo, never part of
   that reusable backdrop. */
.lm-bg-only .draft-player-colorization-badge {
  visibility: hidden !important;
}

/* This label must remain the exact disclosure text, including its casing. */
.restoration-tile-badge.colorization-disclosure-badge {
  font-size: 0.76rem;
  letter-spacing: 0.02em;
  text-transform: none;
}

/* Placeholder for "no opening title card picked yet". */
.draft-player-no-titlecard {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  background: #1b1612;
  color: #c7bfa9;
  text-align: center;
  padding: 1.5rem;
}
.draft-player-no-titlecard .eyebrow {
  color: #8a7e63;
}

/* Era chapter card — simple typography on a soft warm background, same
   font family as the opening title card so the film feels unified. */
.draft-player-chapter-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  background: linear-gradient(135deg, #2a221a 0%, #1f1813 100%);
  color: #f5ecd5;
  text-align: center;
  padding: 0;
  gap: 1.5cqi;
}
.draft-player-chapter-eyebrow {
  font-size: 2cqi;
  color: #c9a25a;
  margin: 0;
}
.draft-player-chapter-eyebrow:not([class*="font-preset-"]) {
  font-family: "Inter", sans-serif;
  letter-spacing: 0.4em;
  text-transform: uppercase;
}
.draft-player-chapter-title {
  font-size: 8cqi;
  line-height: 1.1;
  margin: 0;
  color: #f5ecd5;
}
.draft-player-chapter-title:not([class*="font-preset-"]) {
  font-family: "Cormorant Garamond", "EB Garamond", serif;
  font-style: italic;
  font-weight: 500;
}
.draft-player-chapter-sub {
  font-family: "Inter", sans-serif;
  font-size: 2.2cqi;
  letter-spacing: 0.2em;
  color: #a89878;
  margin: 0;
}

/* End card — quiet, same family as the chapter card. */
.draft-player-end-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, #2a221a 0%, #1f1813 100%);
  color: #f5ecd5;
  text-align: center;
  padding: 8cqi;
  gap: 2cqi;
}
.draft-player-end-preamble {
  font-family: "Cormorant Garamond", "EB Garamond", serif;
  font-style: italic;
  font-size: 4cqi;
  color: #c9a25a;
  margin: 0;
  letter-spacing: 0.05em;
}
.draft-player-end-name {
  font-family: "Cinzel", "EB Garamond", serif;
  font-weight: 600;
  font-size: 7cqi;
  letter-spacing: 0.12em;
  margin: 0;
  text-transform: uppercase;
}
.draft-player-end-dates {
  font-family: "Inter", sans-serif;
  font-size: 2.4cqi;
  letter-spacing: 0.18em;
  color: #c7bfa9;
  margin: 0;
  text-transform: uppercase;
}

.draft-player-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  color: #c7bfa9;
  background: #1b1612;
}

/* Scrub bar — invisible <input type="range"> overlaid on a styled track
   so we get native interaction (drag, keyboard) with our own visuals. */
.draft-player-scrub {
  position: relative;
  flex: 1 1 auto;
  height: 36px;
  display: flex;
  align-items: center;
}
.draft-player-scrub-fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: 0%;
  background: #2a221a;
  border-radius: 999px;
  transition: width 80ms linear;
}
.draft-player-scrub-input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.draft-player-scrub-input:focus + .draft-player-scrub-track .draft-player-scrub-fill {
  outline: 2px solid rgba(0, 0, 0, 0.25);
  outline-offset: 2px;
}
.draft-player-music .eyebrow {
  margin-bottom: 0.35rem;
}
.draft-player-audio {
  display: none;
}

/* ---------- Timing controls ---------- */

.draft-timing-card {
  min-width: 0;
}

.draft-duration-controls {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin-top: 0.9rem;
}
.draft-duration-row {
  display: grid;
  grid-template-columns: 8rem minmax(0, 1fr) 4.5rem 2rem;
  align-items: center;
  gap: 0.6rem;
}
.draft-duration-label {
  font-size: 0.9rem;
  color: #3a2f24;
}
.draft-duration-slider {
  width: 100%;
  accent-color: #2a221a;
}
.draft-duration-input {
  width: 100%;
  padding: 0.3rem 0.4rem;
  border-radius: 6px;
  border: 1px solid rgba(0, 0, 0, 0.18);
  font-size: 0.9rem;
  text-align: right;
  font-variant-numeric: tabular-nums;
  background: #fff;
}
.draft-duration-input:focus {
  outline: 2px solid #c9a25a;
  outline-offset: 1px;
}
.draft-duration-unit {
  font-size: 0.8rem;
  color: #8a7e63;
}
.draft-duration-disabled {
  font-size: 0.85rem;
  color: #8a7e63;
  font-style: italic;
  margin: 0.3rem 0 0;
}

@media (max-width: 640px) {
  .draft-duration-row {
    grid-template-columns: 1fr;
    gap: 0.3rem;
  }
}

/* ---------- Film summary card (rebuilt) ----------
 * Compact, scannable identity at the top; below, three small "blocks"
 * (Chapters / Music / Style) each with a header row + content + edit link.
 * Restoration gets its own gold-accented callout when it applies.
 */

.draft-summary-card {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.draft-summary-identity {
  display: flex;
  align-items: center;
  gap: 1rem;
}
.draft-summary-portrait {
  position: relative;
  width: 4.5rem;
  height: 4.5rem;
  flex: 0 0 auto;
  border-radius: 50%;
  overflow: hidden;
  background: #ede4cd;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}
.draft-summary-portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.draft-summary-portrait-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  font-size: 0.7rem;
  color: #8a7e63;
  text-align: center;
}
.draft-summary-identity-text {
  min-width: 0;
}
.draft-summary-name {
  margin: 0;
  font-family: "Cormorant Garamond", "EB Garamond", Georgia, serif;
  font-weight: 500;
  font-size: 1.25rem;
  color: #2a221a;
  line-height: 1.1;
}
.draft-summary-lifespan {
  margin: 0.2rem 0 0;
  font-size: 0.82rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #6b5a3a;
}

/* Generic "block" — a labeled section inside the summary card. */
.draft-summary-block {
  border-top: 1px solid rgba(0, 0, 0, 0.07);
  padding-top: 0.85rem;
}
.draft-summary-block-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 0.55rem;
}
.draft-summary-block-head .eyebrow {
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #8a7e63;
  margin: 0;
}
.draft-summary-edit {
  background: none;
  border: 0;
  padding: 0;
  color: #6b5a3a;
  font-size: 0.78rem;
  cursor: pointer;
  font-family: inherit;
}
.draft-summary-edit:hover {
  color: #2a221a;
  text-decoration: underline;
}

/* Chapter pills — compact horizontal row. Title + count baked into one
   chip so a family can scan the whole arc at a glance. */
.draft-chapter-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
}
.draft-chapter-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.3rem 0.65rem 0.3rem 0.7rem;
  background: rgba(0, 0, 0, 0.035);
  border: 1px solid rgba(0, 0, 0, 0.07);
  border-radius: 999px;
  font-size: 0.84rem;
  color: #2a221a;
}
.draft-chapter-pill em {
  font-style: normal;
  font-variant-numeric: tabular-nums;
  font-size: 0.74rem;
  color: #6b5a3a;
  padding: 0.05rem 0.4rem;
  background: rgba(0, 0, 0, 0.05);
  border-radius: 999px;
}

/* Music row — visual mini-card with a glyph, track + artist, and a
   source badge. */
.draft-music-row {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.55rem 0.7rem;
  background: rgba(0, 0, 0, 0.025);
  border: 1px solid rgba(0, 0, 0, 0.06);
  border-radius: 10px;
}
.draft-music-row-empty {
  background: transparent;
  border-style: dashed;
}
.draft-music-glyph {
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: linear-gradient(135deg, #c9a25a 0%, #8a6b3a 100%);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.15rem;
  line-height: 1;
}
.draft-music-row-empty .draft-music-glyph {
  background: rgba(0, 0, 0, 0.08);
  color: #8a7e63;
}
.draft-music-info {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}
.draft-music-info strong {
  font-size: 0.92rem;
  color: #2a221a;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.draft-music-info span {
  font-size: 0.78rem;
  color: #6b5a3a;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}
.draft-music-badge {
  display: inline-block;
  padding: 0.1rem 0.5rem;
  background: rgba(201, 162, 90, 0.15);
  color: #6e4f1a;
  border-radius: 999px;
  font-size: 0.7rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

/* Style line — single horizontal sentence with dot separators. */
.draft-summary-style-line {
  margin: 0;
  font-size: 0.9rem;
  color: #2a221a;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.35rem;
}
.draft-summary-style-sep {
  color: #b8a883;
}
.draft-restore-callout .draft-summary-edit {
  flex: 0 0 auto;
  align-self: center;
}

/* Disabled primary button (used for the "Generate final film" placeholder
   so the family sees where the flow is heading). */
.primary-btn.is-disabled,
.primary-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  pointer-events: none;
}

/* Bottom actions row on the Draft tab — give it some breathing room
   relative to the summary cards. */
.draft-actions {
  margin-top: 1.5rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  align-items: center;
}

/* ---------- Payment step ---------- */

/* Payment step (Step 9) — hero on the page, compact left-aligned bundle,
   no giant outer card. */
.main:has(.payment-step) { width: min(1560px, calc(100% - 2rem)); }
.main:has(.payment-step) .wizard { grid-template-columns: minmax(0, 1fr) 360px; align-items: start; }
.form-panel:has(.payment-step) { border: none; background: none; box-shadow: none; padding: 0; }
.payment-step { display: block; }

.payment-card {
  max-width: 460px;
  margin: 0 0 1.25rem;
  background: linear-gradient(180deg, #fdfaf3 0%, #ffffff 100%);
  border-radius: 16px;
  padding: 1.6rem 1.7rem;
  border: 1px solid rgba(120, 100, 70, 0.16);
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
}
.payment-card-header {
  text-align: center;
  margin-bottom: 0.1rem;
}
.payment-card-header .eyebrow {
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: #8a6b3a;
  margin: 0 0 0.4rem;
}
.payment-price {
  font-family: "Cormorant Garamond", "EB Garamond", Georgia, serif;
  font-size: 2.6rem;
  font-weight: 500;
  color: #1f1813;
  line-height: 1.05;
  letter-spacing: -0.02em;
}
.payment-tag {
  margin: 0.15rem 0 0;
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #6b5a3a;
}
.payment-divider {
  height: 1px;
  margin: 1.1rem 0;
  background: rgba(120, 100, 70, 0.18);
}
.payment-features {
  list-style: none;
  margin: 0 0 1.3rem;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
}
.payment-features li {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
}
.payment-check {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  margin-top: 0.1rem;
  background: url(/icons/pay-check.png?v=1) center / contain no-repeat;
}
.payment-features strong {
  display: block;
  font-size: 0.92rem;
  color: #2a221a;
}
.payment-features span {
  display: block;
  font-size: 0.8rem;
  color: #6b5a3a;
  line-height: 1.45;
  margin-top: 0.15rem;
}
.payment-actions {
  text-align: center;
}
.payment-pay-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  width: 100%;
  font: inherit;
  font-size: 1rem;
  font-weight: 600;
  padding: 0.9rem 1.5rem;
  border: 0;
  border-radius: 12px;
  cursor: pointer;
  color: #fff;
  background: #46604f;
  box-shadow: 0 4px 14px rgba(70, 96, 79, 0.28);
  transition: background 0.15s ease, box-shadow 0.15s ease;
}
.payment-pay-btn:hover { background: #3c5344; box-shadow: 0 6px 18px rgba(70, 96, 79, 0.34); }
.pay-lock-ico, .pay-arrow-ico {
  display: inline-block; background-color: #fff; flex-shrink: 0;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-size: contain; mask-size: contain;
}
.pay-lock-ico { width: 15px; height: 15px; -webkit-mask-image: url(/icons/pay-lock.png?v=1); mask-image: url(/icons/pay-lock.png?v=1); }
.pay-arrow-ico { width: 16px; height: 14px; -webkit-mask-image: url(/icons/arrow-forward.png?v=5); mask-image: url(/icons/arrow-forward.png?v=5); }
.payment-fineprint {
  margin: 0.8rem 0 0;
  font-size: 0.74rem;
  color: #9a8e73;
  font-style: italic;
  line-height: 1.5;
}
.payment-back-row { margin-top: 0; }

/* ---------- Master "no restoration" toggle ---------- */

.restore-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  flex-wrap: wrap;
}
.restore-banner-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.85rem;
  color: #4a3614;
  cursor: pointer;
  background: rgba(255, 255, 255, 0.5);
  padding: 0.4rem 0.8rem;
  border-radius: 999px;
  border: 1px solid rgba(0, 0, 0, 0.1);
  flex: 0 0 auto;
}
.restore-banner-toggle input {
  margin: 0;
  cursor: pointer;
}
.restore-banner-off {
  opacity: 0.85;
}

/* On/off switch used for the master restoration / colorization toggles, so the
   copy ("use the toggle") matches the control. */
.lm-switch {
  position: relative;
}
.lm-switch input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
  margin: 0;
}
.lm-switch .lm-switch-track {
  position: relative;
  width: 38px;
  height: 22px;
  border-radius: 999px;
  background: #bdb6a8;
  transition: background 0.15s ease;
  flex: 0 0 auto;
}
.lm-switch .lm-switch-track::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
  transition: transform 0.15s ease;
}
.lm-switch input:checked + .lm-switch-track {
  background: var(--accent);
}
.lm-switch input:checked + .lm-switch-track::after {
  transform: translateX(16px);
}
.lm-switch input:focus-visible + .lm-switch-track {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ---------- Restoration step ---------- */

/* Disclaimer banner — visible across all states (idle, running, complete)
   so the family is reminded to verify each restored photo. Gold accent
   to match the rest of the restoration UX without screaming. */
.restoration-disclaimer {
  display: flex;
  align-items: flex-start;
  gap: 0.85rem;
  padding: 0.95rem 1.1rem;
  margin-bottom: 1rem;
  background: linear-gradient(180deg, rgba(201, 162, 90, 0.16) 0%, rgba(201, 162, 90, 0.08) 100%);
  border: 1px solid rgba(201, 162, 90, 0.45);
  border-radius: 12px;
}
.restoration-disclaimer-icon {
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: linear-gradient(135deg, #c9a25a 0%, #8a6b3a 100%);
  color: #fff;
  font-weight: 700;
  font-size: 1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: 0.1rem;
}
.restoration-disclaimer-text {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  min-width: 0;
}
.restoration-disclaimer-text strong {
  font-size: 0.95rem;
  color: #4a3614;
}
.restoration-disclaimer-text span {
  font-size: 0.85rem;
  color: #6b5a3a;
  line-height: 1.5;
}
.restoration-run-btn {
  font-size: 1.05rem;
  padding: 0.9rem 1.5rem;
}
.restoration-cta-hint {
  margin: 0.7rem 0 0;
  font-size: 0.82rem;
  color: #6b5a3a;
  line-height: 1.4;
}

/* ============================================================
   Restoration (Step 10) — unified workflow card
   ============================================================ */
.main:has(.restoration-workflow-card) { width: min(1560px, calc(100% - 2rem)); }
.main:has(.restoration-workflow-card) .wizard { grid-template-columns: minmax(0, 1fr) 360px; align-items: start; }
.restoration-disclaimer { margin-bottom: 0.85rem; }

.restoration-workflow-card { display: block; padding: 1.4rem 1.5rem; }
.restoration-workflow-head { display: flex; align-items: flex-start; gap: 0.9rem; margin-bottom: 1.1rem; }
.rwf-icon { flex: 0 0 auto; width: 46px; height: 46px; display: inline-flex; align-items: center; justify-content: center; }
.rwf-icon img { width: 100%; height: 100%; object-fit: contain; }
.restoration-workflow-head h3 { margin: 0 0 0.25rem; font-size: 1.15rem; }
.restoration-workflow-head .module-hint { margin: 0; }

/* Action zone — beige box with spinner + green button + hint. */
.restoration-action-zone {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 0.55rem 0.9rem;
  padding: 1.1rem 1.2rem;
  background: #faf5ea;
  border: 1px solid rgba(120, 100, 70, 0.14);
  border-radius: 12px;
}
.restoration-run-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  width: 100%; font: inherit; font-size: 1rem; font-weight: 600;
  padding: 0.85rem 1.4rem; border: 0; border-radius: 11px; cursor: pointer;
  color: #fff; background: #46604f;
  box-shadow: 0 4px 14px rgba(70, 96, 79, 0.26);
  transition: background 0.15s ease, box-shadow 0.15s ease;
}
.restoration-run-btn:hover { background: #3c5344; box-shadow: 0 6px 18px rgba(70, 96, 79, 0.32); }
.restoration-run-sparkle {
  width: 16px; height: 16px; background-color: #fff; flex-shrink: 0;
  -webkit-mask: url(/icons/restore-sparkle.png?v=1) center/contain no-repeat;
  mask: url(/icons/restore-sparkle.png?v=1) center/contain no-repeat;
}
.restoration-action-zone .restoration-cta-hint {
  grid-column: 1 / -1; text-align: center; margin: 0.1rem 0 0;
}

/* Support row — 3 equal info items above a divider. */
.restoration-support-divider { height: 1px; margin: 1.2rem 0; background: rgba(120, 100, 70, 0.16); }
.restoration-support-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; }
.rsr-item { display: flex; align-items: center; gap: 0.6rem; }
.rsr-ico { flex: 0 0 auto; width: 26px; height: 26px; background-color: #a5894f; }
.rsr-ico-clock { -webkit-mask: url(/icons/restore-clock.png?v=1) center/contain no-repeat; mask: url(/icons/restore-clock.png?v=1) center/contain no-repeat; }
.rsr-ico-shield { -webkit-mask: url(/icons/restore-shield.png?v=1) center/contain no-repeat; mask: url(/icons/restore-shield.png?v=1) center/contain no-repeat; }
.rsr-ico-rerun { -webkit-mask: url(/icons/restore-rerun.png?v=1) center/contain no-repeat; mask: url(/icons/restore-rerun.png?v=1) center/contain no-repeat; }
.rsr-text { display: flex; flex-direction: column; min-width: 0; }
.rsr-text strong { font-size: 0.82rem; color: var(--ink); font-weight: 600; }
.rsr-text span { font-size: 0.8rem; color: var(--body); line-height: 1.35; }
.restoration-back-row { margin-top: 1.1rem; }

@media (max-width: 720px) {
  .restoration-support-row { grid-template-columns: 1fr; gap: 0.7rem; }
}

.restoration-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.25rem;
  margin: 1rem 0 1.5rem;
}
@media (max-width: 700px) {
  .restoration-grid {
    grid-template-columns: 1fr;
  }
}

.restoration-tile {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-width: 0;
}
.restoration-tile .ba-slider {
  border-radius: 10px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
}
.restoration-tile-state {
  position: relative;
  width: 100%;
  background: #1b1612;
  border-radius: 10px;
  overflow: hidden;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
}
.restoration-tile-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.restoration-tile-img.dim {
  filter: brightness(0.45) saturate(0.55);
}
.restoration-tile-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  color: #f5ecd5;
  text-align: center;
  padding: 1rem;
}
.restoration-tile-overlay span {
  font-size: 0.78rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #c7bfa9;
}
.restoration-tile-queued span {
  background: rgba(0, 0, 0, 0.6);
  padding: 0.35rem 0.8rem;
  border-radius: 999px;
}
.restoration-tile-spinner {
  width: 32px;
  height: 32px;
  border: 3px solid rgba(245, 236, 213, 0.18);
  border-top-color: #c9a25a;
  border-radius: 50%;
  animation: lightbox-spin 0.9s linear infinite;
}
.restoration-tile-fail-msg {
  color: #ffd1c0;
  text-transform: none !important;
  letter-spacing: 0 !important;
  font-size: 0.85rem !important;
  max-width: 24ch;
  line-height: 1.4;
}
.restoration-tile-meta {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.6rem;
  padding: 0 0.2rem;
}
.restoration-tile-meta strong {
  font-size: 0.88rem;
  color: #2a221a;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1 1 auto;
  min-width: 0;
}
.restoration-tile-badge {
  display: inline-block;
  padding: 0.1rem 0.55rem;
  background: rgba(201, 162, 90, 0.15);
  color: #6e4f1a;
  border-radius: 999px;
  font-size: 0.7rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  flex: 0 0 auto;
}
.restoration-tile-badge-muted {
  background: rgba(0, 0, 0, 0.06);
  color: #5a4f3a;
}
.restoration-tile-badge-warn {
  background: rgba(180, 60, 40, 0.12);
  color: #6b2a1a;
  border: 1px solid rgba(180, 60, 40, 0.32);
}

/* Per-photo control row: choice toggle (3 segments) + Re-run button.
   Renders only on completed tiles (those with a restoredUrl). */
.restoration-tile-controls {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-top: 0.4rem;
}
.restoration-tile-choice {
  display: flex;
  gap: 0;
  background: rgba(0, 0, 0, 0.04);
  border-radius: 8px;
  padding: 3px;
}
.restoration-tile-choice button {
  flex: 1 1 0;
  padding: 0.35rem 0.4rem;
  background: transparent;
  border: 0;
  border-radius: 6px;
  font-size: 0.72rem;
  color: #5a4f3a;
  cursor: pointer;
  font-family: inherit;
  transition: background 120ms ease, color 120ms ease;
  letter-spacing: 0.02em;
}
.restoration-tile-choice button:hover {
  background: rgba(0, 0, 0, 0.05);
}
.restoration-tile-choice button.active {
  background: #fff;
  color: #2a221a;
  font-weight: 500;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
/* Special "active" state colors for the destructive option */
.restoration-tile-choice button.active[data-restoration-choice$="::removed"] {
  background: linear-gradient(135deg, #6b2a1a 0%, #4a1d10 100%);
  color: #fff;
}

.restoration-rerun-btn {
  font-size: 0.78rem;
  padding: 0.45rem 0.7rem;
  background: rgba(0, 0, 0, 0.03);
  border: 1px solid rgba(0, 0, 0, 0.1);
  border-radius: 8px;
  color: #4a3614;
  cursor: pointer;
  font-family: inherit;
  transition: background 120ms ease;
}
.restoration-rerun-btn:hover:not(:disabled) {
  background: rgba(201, 162, 90, 0.12);
  border-color: rgba(201, 162, 90, 0.45);
}
.restoration-rerun-btn:disabled,
.restoration-rerun-btn.is-exhausted {
  opacity: 0.45;
  cursor: not-allowed;
  background: rgba(0, 0, 0, 0.04);
}

/* Removed-from-film state: gentle fade + a dashed border so the family
   knows the photo's been excluded but the controls stay clickable
   (in case they change their mind). */
.restoration-tile.is-removed .ba-slider,
.restoration-tile.is-removed .restoration-tile-state {
  opacity: 0.4;
  filter: saturate(0.5);
}
.restoration-tile.is-removed {
  position: relative;
}
.restoration-tile.is-removed::after {
  content: "Will be excluded from the final cut";
  position: absolute;
  top: 12px;
  left: 50%;
  transform: translateX(-50%);
  padding: 0.35rem 0.85rem;
  background: rgba(180, 60, 40, 0.85);
  color: #fff;
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border-radius: 999px;
  pointer-events: none;
  z-index: 5;
}

/* "Using original" state: subtle desaturation on the slider to signal
   the restored version isn't being used. */
.restoration-tile.is-original-chosen .ba-slider .ba-img-after {
  opacity: 0.45;
}

.restoration-actions {
  margin-top: 1rem;
  display: flex;
  justify-content: space-between;
  gap: 0.6rem;
}
.animation-pick-tile {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  font-family: inherit;
  text-align: left;
}
.animation-pick-img {
  position: relative;
  width: 100%;
  border-radius: 10px;
  overflow: hidden;
  background: #1b1612;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.08);
  transition: box-shadow 140ms ease, transform 80ms ease;
}
.animation-pick-tile:hover .animation-pick-img {
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.18);
}
.animation-pick-tile:active .animation-pick-img {
  transform: scale(0.99);
}
.animation-pick-img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.animation-pick-check {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.5);
  color: transparent;
  border: 2px solid rgba(255, 255, 255, 0.9);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 0.95rem;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  transition: background 140ms ease, color 140ms ease, border-color 140ms ease;
}
.animation-pick-tile.is-flagged .animation-pick-check {
  background: linear-gradient(135deg, #c9a25a 0%, #8a6b3a 100%);
  color: #fff;
  border-color: #fff;
  box-shadow: 0 4px 12px rgba(201, 162, 90, 0.5);
}
.animation-pick-tile.is-flagged .animation-pick-img {
  outline: 3px solid #c9a25a;
  outline-offset: -3px;
}
.animation-pick-main-badge {
  position: absolute;
  bottom: 8px;
  left: 8px;
  padding: 0.2rem 0.55rem;
  background: rgba(0, 0, 0, 0.65);
  color: #f5ecd5;
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border-radius: 999px;
}
.animation-pick-name {
  font-size: 0.78rem;
  color: #5a4f3a;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Result tile: looping video instead of before/after slider. Same
   per-photo controls (animated/still/remove) and rerun budget as
   restoration tiles. */
.animation-tile-video {
  width: 100%;
  border-radius: 10px;
  overflow: hidden;
  background: #1b1612;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
}
.animation-tile-video video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.animation-tile.is-still-chosen .animation-tile-video video {
  opacity: 0.45;
  filter: saturate(0.6);
}

/* "Use still" choice button takes a slightly muted-active tint */
.restoration-tile-choice button.active[data-animation-choice$="::still"] {
  background: rgba(0, 0, 0, 0.08);
  color: #2a221a;
}
.restoration-tile-choice button.active[data-animation-choice$="::removed"] {
  background: linear-gradient(135deg, #6b2a1a 0%, #4a1d10 100%);
  color: #fff;
}

/* Animation tier picker (Whisper / Subtle / Cinematic). Same segmented
   control pattern as the decision toggle but with a small leading label
   so families see what the row controls. */
.animation-tier-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.3rem;
}
.animation-tier-label {
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #8a7e63;
  flex: 0 0 auto;
}
.animation-tier-segments {
  flex: 1 1 auto;
  display: flex;
  gap: 0;
  background: rgba(0, 0, 0, 0.04);
  border-radius: 8px;
  padding: 3px;
}
.animation-tier-segments button {
  flex: 1 1 0;
  padding: 0.3rem 0.4rem;
  background: transparent;
  border: 0;
  border-radius: 6px;
  font-size: 0.72rem;
  color: #5a4f3a;
  cursor: pointer;
  font-family: inherit;
  transition: background 120ms ease, color 120ms ease;
}
.animation-tier-segments button:hover:not(:disabled):not(.active) {
  background: rgba(0, 0, 0, 0.05);
}
.animation-tier-segments button.active {
  background: linear-gradient(135deg, #c9a25a 0%, #8a6b3a 100%);
  color: #fff;
  font-weight: 500;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
.animation-tier-segments button:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* ---------- Restoration review modal ----------
 * Quick-view popup opened from the Draft tab's restoration callout.
 * Shows a grid of every photo flagged for AI restoration with a button
 * to jump back to the Legacy Map for editing the flags. Same backdrop
 * pattern as the Draft player lightbox. */
.restore-review {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: rgba(0, 0, 0, 0.78);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 3rem 1.5rem;
  cursor: zoom-out;
}
.restore-review-close {
  position: absolute;
  top: 1rem;
  right: 1.2rem;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.12);
  color: #f5ecd5;
  border: 0;
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 102;
}
.restore-review-close:hover {
  background: rgba(255, 255, 255, 0.22);
}
.restore-review-panel {
  background: #fbf6ec;
  border-radius: 18px;
  width: min(100%, 1040px);
  max-height: calc(100vh - 6rem); max-height: calc(100dvh - 6rem);
  overflow-y: auto;
  padding: 1.75rem;
  cursor: default;
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.4);
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}
.restore-review-header {
  text-align: left;
}
.restore-review-header .eyebrow {
  font-size: 0.72rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #8a6b3a;
  margin: 0 0 0.3rem;
}
.restore-review-header h2 {
  font-family: "Cormorant Garamond", "EB Garamond", Georgia, serif;
  font-weight: 500;
  font-size: 1.6rem;
  color: #1f1813;
  margin: 0 0 0.6rem;
}
.restore-review-header p {
  margin: 0;
  font-size: 0.92rem;
  line-height: 1.55;
  color: #5a4a35;
}

.restore-review-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 1.1rem;
}
.restore-review-tile {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-width: 0;
  transition: opacity 0.15s ease;
}
.restore-review-tile.is-off { opacity: 0.6; }
.restore-review-thumb {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: 10px;
  overflow: hidden;
  background: #1f1813;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.16);
}
.restore-review-thumb img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}
.restore-review-tile.is-off .restore-review-thumb img { filter: grayscale(0.3) brightness(0.9); }
.restore-review-badge {
  position: absolute;
  top: 8px;
  left: 8px;
  padding: 3px 9px;
  border-radius: 999px;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: #fff;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}
.restore-review-badge.on { background: linear-gradient(135deg, #c9a25a 0%, #8a6b3a 100%); }
.restore-review-badge.off { background: rgba(40, 32, 24, 0.72); }
.restore-review-toggle {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: #2a221a;
  cursor: pointer;
}
/* Visible on/off switch: gray when keeping the original, green when restoring. */
.restore-review-toggle input { position: absolute; opacity: 0; width: 0; height: 0; margin: 0; pointer-events: none; }
.restore-review-switch {
  position: relative;
  flex-shrink: 0;
  width: 40px;
  height: 23px;
  border-radius: 999px;
  background: #b6ada0;
  transition: background 0.18s ease;
}
.restore-review-switch::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 19px;
  height: 19px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  transition: transform 0.18s ease;
}
.restore-review-toggle input:checked + .restore-review-switch { background: #3ea865; }
.restore-review-toggle input:checked + .restore-review-switch::after { transform: translateX(17px); }
.restore-review-toggle input:focus-visible + .restore-review-switch { outline: 2px solid #46604f; outline-offset: 2px; }
.restore-review-toggle-label { min-width: 6.5rem; }
.restore-review-metaline { font-size: 0.74rem; color: #6b5a3a; }
/* "Review photos" button in the restoration header. */
.restoration-workflow-head { position: relative; }
.restore-preview-btn { margin-left: auto; align-self: center; display: inline-flex; align-items: center; gap: 0.4rem; padding: 0.5rem 0.85rem; border: 1px solid var(--line); border-radius: 10px; background: #fff; color: #46604f; font: inherit; font-size: 0.85rem; font-weight: 600; cursor: pointer; transition: border-color 0.14s ease, background 0.14s ease; }
.restore-preview-btn:hover { border-color: #46604f; background: #f2f6f1; }
.restore-preview-ico { display: block; }

.restore-review-empty {
  text-align: center;
  color: #8a7e63;
  padding: 1.5rem;
  font-style: italic;
}

.restore-review-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.6rem;
  padding-top: 1rem;
  border-top: 1px solid rgba(0, 0, 0, 0.08);
}
.composition-cycler-card .backdrop-layout-template-diagram {
  width: 100%;
  max-width: 13rem;
}
.composition-cycler-card .backdrop-layout-template-label {
  font-size: 0.86rem;
  font-weight: 500;
  color: #4a3c2c;
  text-align: center;
}

/* MAIN (cover) chip in the edit-mode orientation strip. */
.preview-orientation-btn.is-main {
  font-weight: 500;
  border-color: rgba(180, 150, 90, 0.55);
}
.preview-orientation-btn.is-main::before {
  content: "★";
  margin-right: 0.3em;
  font-size: 0.85em;
  opacity: 0.8;
}
.preview-orientation-btn.is-main.is-active {
  background: rgba(180, 150, 90, 0.18);
  border-color: rgba(180, 150, 90, 0.8);
}

/* Floating toolbar: wrap to a second row instead of running off the
   stage edge (which clipped Font/Color on wide toolbars like dates). */
.backdrop-floating-toolbar { display: flex; }
.backdrop-floating-toolbar .bft-pill {
  flex-wrap: wrap;
  white-space: normal;
  overflow: visible;
  max-width: 100%;
  row-gap: 2px;
}

/* Matte border on the cover (title-card) photo — ring on circle/oval,
   frame on rectangle. box-sizing keeps the photo inside the border. */
.titlecard-portrait.has-matte {
  border: var(--matte-size, 6px) solid var(--matte-color, #f5e9d0);
  box-sizing: border-box;
}

/* Text-shadow intensity slider in the floating toolbar. */
.bft-shadow-intensity .bft-inline-slider {
  width: 96px;
  margin: 0 6px;
  accent-color: #c9a96a;
  vertical-align: middle;
}
.bft-shadow-intensity .bft-slider-value {
  min-width: 26px;
  font-size: 12px;
  color: #d8c7a4;
}

/* Newly added photos awaiting review on the Legacy Map (added after the last
   AI analysis run). Highlighted so the family checks aging/placement before
   continuing to Film Style. */
.badge-new {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
  font-weight: 600;
}
.photo-analysis-row.is-new {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 10px;
}
.intake-banner-new strong {
  color: var(--accent);
}

/* Indeterminate analyzing bar — the AI returns all photos at once, so we sweep
   a segment instead of faking a numeric fill. */
.analyzing-progress-indeterminate { overflow: hidden; }
.analyzing-progress-indeterminate .analyzing-progress-bar {
  width: 38%;
  animation: analyzing-sweep 1.4s ease-in-out infinite;
}
@keyframes analyzing-sweep {
  0%   { transform: translateX(-120%); }
  100% { transform: translateX(320%); }
}

/* Actionable review cards pulled to the top of the Legacy Map. */
.review-priority-card { border-left: 3px solid var(--accent); }
.restore-review-photo .restore-toggle { margin-top: .4rem; }

/* Legacy Map thumbnails open the enlarged lightbox on click. */
img[data-lightbox-photo] { cursor: zoom-in; }

/* Trim & fade editor on the selected-track card (Phase 7). */
.trim-editor {
  margin-top: .85rem;
  padding: .85rem 1rem 1rem;
  border: 1px solid var(--border, rgba(0,0,0,.12));
  border-radius: 12px;
  background: var(--surface-2, rgba(0,0,0,.02));
}
.trim-editor-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: .75rem;
  margin-bottom: .6rem;
}
.trim-editor-head strong { font-size: .95rem; }
.trim-editor-sub { font-size: .8rem; opacity: .65; }
.trim-row { display: grid; gap: .25rem; margin-bottom: .55rem; }
.trim-row label {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: .82rem;
  opacity: .85;
}
.trim-row .trim-val { font-variant-numeric: tabular-nums; opacity: .7; font-size: .8rem; }
.trim-row input[type="range"] { width: 100%; accent-color: var(--accent); }
.trim-row input[type="range"]:disabled { opacity: .4; }
.trim-actions {
  display: flex;
  align-items: center;
  gap: .9rem;
  margin-top: .7rem;
}
.trim-preview-btn { min-width: 9.5rem; }

/* Trim & fade editor sitting inside the fullscreen film player (dark overlay):
   readable on dark, sized to sit under the controls. */
.trim-editor-in-player {
  margin-top: .75rem;
  background: rgba(255, 255, 255, .06);
  border-color: rgba(255, 255, 255, .14);
  color: #f3f1ee;
}
.trim-editor-in-player .trim-editor-sub,
.trim-editor-in-player .trim-row label { color: rgba(243, 241, 238, .82); }
.trim-editor-in-player .trim-row .trim-val { color: rgba(243, 241, 238, .6); }
.trim-editor-in-player .trim-hint { font-size: .8rem; opacity: .7; }

/* ── Page-turn transition ──────────────────────────────────────────────
   The outgoing slide is a page that turns around the left "spine",
   revealing the next slide sitting flat underneath. Applies to both the
   draft player stage and the live-preview stage. */
.transition-page-turn .draft-player-stage,
.transition-page-turn.preview-stage,
.transition-page-turn .preview-stage {
  perspective: 2200px;
  perspective-origin: 0% 50%;
}
.transition-page-turn .draft-player-stage-slot,
.transition-page-turn .slot-a,
.transition-page-turn .slot-b {
  transform-origin: left center;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  transition: none;
}
.transition-page-turn .draft-player-stage-slot.active,
.transition-page-turn .slot-a.active,
.transition-page-turn .slot-b.active {
  z-index: 1;
  transform: none;
  opacity: 1;
}
.transition-page-turn .draft-player-stage-slot:not(.active):not(.page-turning),
.transition-page-turn .slot-a:not(.active):not(.page-turning),
.transition-page-turn .slot-b:not(.active):not(.page-turning) {
  opacity: 0;
}
.transition-page-turn .draft-player-stage-slot.page-turning,
.transition-page-turn .slot-a.page-turning,
.transition-page-turn .slot-b.page-turning {
  z-index: 3;
  opacity: 1;
  animation: lm-page-turn var(--transition-duration, 700ms) cubic-bezier(.45, .05, .25, 1) forwards;
}
/* curve sheen + curl shadow that sweeps across the page as it turns */
.transition-page-turn .draft-player-stage-slot.page-turning::after,
.transition-page-turn .slot-a.page-turning::after,
.transition-page-turn .slot-b.page-turning::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(105deg,
    rgba(0,0,0,0.30) 0%,
    rgba(0,0,0,0.00) 34%,
    rgba(255,255,255,0.13) 60%,
    rgba(0,0,0,0.24) 100%);
  opacity: 0;
  animation: lm-page-sheen var(--transition-duration, 700ms) ease-in forwards;
}
@keyframes lm-page-turn {
  0%   { transform: rotateY(0deg); box-shadow: 0 0 0 rgba(0,0,0,0); }
  30%  { box-shadow: -22px 0 44px rgba(0,0,0,0.30); }
  100% { transform: rotateY(-180deg); box-shadow: 0 0 0 rgba(0,0,0,0); }
}
@keyframes lm-page-sheen {
  0%   { opacity: 0; }
  48%  { opacity: 1; }
  100% { opacity: 0; }
}

/* Render-mode capture stage (Phase A): force a clean full 16:9 frame,
   overriding the player's 7:4 preview aspect + rounded corners/shadow. */
#lm-render-frame .lm-render-stage {
  width: 1920px !important;
  height: 1080px !important;
  aspect-ratio: auto !important;
  border-radius: 0 !important;
  box-shadow: none !important;
}
.trans-preview-status.is-done { opacity: 0; pointer-events: none; }
@keyframes lm-trans-spin { to { transform: rotate(360deg); } }

/* Anti-flash placeholder: backdrop shown alone while the composition catalog
   loads on a resumed draft, so the player never flashes the legacy layout. */
.draft-player-stage-inner.lm-comp-loading { position: relative; overflow: hidden; background: #1b1612; }
.lm-comp-loading-bg {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; animation: lm-comp-pulse 1.2s ease-in-out infinite;
}
@keyframes lm-comp-pulse { 0%,100% { opacity: 0.78; } 50% { opacity: 0.92; } }

/* ── Draft cinema: inline canvas player with instant transition switching ── */
.draft-cinema {
  position: relative; width: 100%; aspect-ratio: 16 / 9;
  border-radius: 12px; overflow: hidden; background: #15110e;
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.45);
}
.draft-cinema-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.draft-reveal-canvas { pointer-events: none; }
.draft-cinema:hover .draft-cinema-toggle,
.draft-cinema.is-paused .draft-cinema-toggle { opacity: 1; }
.draft-cinema-loader {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 14px;
  color: #e7dcc8; font-size: 0.9rem; text-align: center; padding: 1.5rem;
}
.draft-cinema-spinner {
  width: 34px; height: 34px; border-radius: 50%;
  border: 3px solid rgba(231, 220, 200, 0.22); border-top-color: #e7dcc8;
  animation: lm-comp-spin 0.8s linear infinite;
}
@keyframes lm-comp-spin { to { transform: rotate(360deg); } }

/* ── Fullscreen cinema (Watch the rough cut) — canvas player + scrub bar ── */
.cinema-fs {
  position: fixed; inset: 0; z-index: 9000;
  background: rgba(10, 8, 6, 0.92); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  display: flex; align-items: center; justify-content: center; padding: 3vmin;
}
.cinema-fs-close {
  position: absolute; top: 18px; right: 22px; z-index: 2;
  width: 44px; height: 44px; border-radius: 50%; border: none; cursor: pointer;
  background: rgba(40, 32, 24, 0.7); color: #f3ead8; font-size: 1.5rem; line-height: 1;
}
.cinema-fs-inner { width: min(1280px, 94vw); display: flex; flex-direction: column; gap: 14px; }
.cinema-fs-stage {
  width: 100%; aspect-ratio: 16 / 9; max-height: 78vh;
  box-shadow: 0 30px 90px rgba(0, 0, 0, 0.6);
}
.cinema-fs-controls { display: flex; align-items: center; gap: 14px; }
.cinema-fs-btn {
  width: 42px; height: 42px; border-radius: 50%; border: none; cursor: pointer; flex: none;
  background: rgba(60, 48, 36, 0.85); color: #f3ead8; font-size: 0.8rem;
  display: flex; align-items: center; justify-content: center;
}
.cinema-fs-time { color: #cdbfa8; font-size: 0.82rem; font-variant-numeric: tabular-nums; flex: none; min-width: 86px; }
/* FA1 — 10px of padding gave a 26px active height on a 6px track: a fine
   target for a mouse, a poor one for a trackpad or an unsteady hand. */
.cinema-fs-scrub { flex: 1; padding: 13px 0; cursor: pointer; touch-action: none; }
.cinema-fs-scrub:focus-visible { outline: 2px solid #e7dcc8; outline-offset: 4px; border-radius: 6px; }
.cinema-fs-scrub-track { position: relative; height: 6px; border-radius: 3px; background: rgba(231, 220, 200, 0.22); }
.cinema-fs-scrub-fill { position: absolute; inset: 0 auto 0 0; width: 0%; border-radius: 3px; background: #e7dcc8; }
.cinema-fs-scrub-fill::after {
  content: ""; position: absolute; right: -7px; top: 50%; transform: translateY(-50%);
  width: 14px; height: 14px; border-radius: 50%; background: #fff; box-shadow: 0 1px 4px rgba(0,0,0,.4);
}

/* ── Transition sliders (under the transition choices) ── */
/* Single-column card so the header, transition grid, and sliders each span the
   full width (the base module-card lays children into a 0.72fr column). */
.module-card.draft-transition-card { display: block; }
/* Sync toggle + speed/hold sliders share one polished row; hints/warnings wrap
   onto their own full-width line beneath. */
.transition-sliders { margin-top: 14px; display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; gap: 12px 22px; }
.transition-sliders > p { flex-basis: 100%; margin: 0.1rem 0 0; }
.trans-slider-row { display: flex; flex-direction: column; gap: 6px; flex: 1 1 170px; min-width: 150px; }
.trans-slider-label { font-size: 0.78rem; color: #6b5a45; display: flex; justify-content: space-between; align-items: baseline; gap: 0.5rem; }
.trans-slider-label strong { color: #3a2c20; font-variant-numeric: tabular-nums; font-weight: 600; }
.trans-slider-row input[type="range"] { width: 100%; accent-color: #8a6f53; }
/* The sync toggle sits inline (label + checkbox) and hugs its content so the
   sliders take the remaining width. */
.trans-toggle-row { flex: 0 0 auto; flex-direction: row; align-items: center; gap: 0.55rem; padding: 0.45rem 0.7rem; background: rgba(138, 111, 83, 0.06); border: 1px solid var(--line); border-radius: 10px; cursor: pointer; }
.trans-toggle-row .trans-slider-label { justify-content: flex-start; font-weight: 600; color: #3a2c20; }
.trans-toggle-row input[type="checkbox"] { flex-shrink: 0; width: 17px; height: 17px; accent-color: #5f7165; cursor: pointer; margin: 0; }
.trans-toggle-row:has(input:disabled) { opacity: 0.6; cursor: default; }

/* ── Inline slideshow controls (arrows + play) overlaid on the cinema ── */
.slideshow-controls {
  position: absolute; left: 0; right: 0; bottom: 14px; z-index: 2;
  display: flex; align-items: center; justify-content: center; gap: 18px;
  opacity: 0; transition: opacity 0.2s ease; pointer-events: none;
}
.draft-cinema:hover .slideshow-controls,
.draft-cinema.is-paused .slideshow-controls { opacity: 1; }
.slideshow-controls > * { pointer-events: auto; }
.slideshow-arrow, .slideshow-play {
  border: none; cursor: pointer; color: #f3ead8; background: rgba(20, 16, 12, 0.62);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px); display: flex; align-items: center; justify-content: center;
}
.slideshow-arrow { width: 42px; height: 42px; border-radius: 50%; font-size: 1.6rem; line-height: 1; }
.slideshow-arrow:hover, .slideshow-play:hover { background: rgba(40, 32, 24, 0.85); }
.slideshow-play { width: 46px; height: 46px; border-radius: 50%; font-size: 0.85rem; }
.chapter-title-input { flex: 1; padding: 8px 10px; border: 1px solid rgba(40, 32, 24, 0.2); border-radius: 8px; font: inherit; font-size: 0.95rem; background: #fff; }
.chapter-title-input:focus { outline: none; border-color: rgba(40, 32, 24, 0.5); }

/* Restoration reveal: per-photo toggle on the restoration tile. */
.restoration-reveal-toggle { display: flex; align-items: center; gap: 8px; margin-top: 8px; font-size: 0.86rem; cursor: pointer; color: rgba(40, 32, 24, 0.8); }
.restoration-reveal-toggle input { width: 15px; height: 15px; accent-color: #7a5c3e; }
.restoration-reveal-toggle.checked { color: rgba(40, 32, 24, 1); font-weight: 500; }

/* B&W colorize panel in the Restoration step. */
.colorize-panel { margin-bottom: 18px; }
.colorize-tile-img { position: relative; width: 100%; overflow: hidden; border-radius: 8px; background: #2a2420; }
.colorize-tile-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.colorize-btn { width: 100%; margin-top: 8px; }

/* Dedicated Chapters step. */
.chapter-step-list { display: flex; flex-direction: column; gap: 8px; }
/* Compact single-line rows: small card preview + name + count + thumbs all
   on one horizontal line, in a light bordered row. */
.chapter-step-row { display: flex; gap: 14px; align-items: center; padding: 8px 12px; border: 1px solid var(--line, #e9e2d6); border-radius: 12px; background: #fff; }
.chapter-step-thumbs { display: flex; gap: 4px; flex-shrink: 0; }
/* CB5 — each thumbnail is a <button> wrapping the <img> now, so it can be
   tapped and focused. Size the button; the image fills it. */
.chapter-step-thumbs .chapter-drag-thumb { width: 38px; height: 38px; padding: 0; border: 0; background: none; border-radius: 6px; display: block; flex-shrink: 0; }
.chapter-step-thumbs .chapter-drag-thumb img { width: 100%; height: 100%; object-fit: cover; border-radius: 6px; background: #ddd2bb; display: block; pointer-events: none; }
.chapter-step-thumbs .chapter-drag-thumb:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.chapter-step-fields { flex: 1; display: flex; flex-direction: row; align-items: center; gap: 16px; min-width: 0; }
.chapter-step-fields .chapter-title-input { flex: 0 1 300px; }
.chapter-step-meta { font-size: 0.78rem; color: rgba(40, 32, 24, 0.55); margin-left: auto; flex-shrink: 0; white-space: nowrap; }
.chapter-step-row .chapter-title-input:disabled { opacity: 0.55; background: rgba(40,32,24,0.04); }
/* CA9 — 30x30 is below the 44px minimum touch target, and this is the control
   that will eventually open chapter actions. */
.chapter-row-menu { flex-shrink: 0; margin-left: 4px; width: 44px; height: 44px; border: 0; background: none; border-radius: 8px; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; opacity: 0.8; transition: background .12s ease, opacity .12s ease; }
.chapter-row-menu:hover { background: rgba(40,32,24,0.06); opacity: 1; }
.chapter-row-menu img { width: 19px; height: auto; object-fit: contain; }
/* CH8 — a duplicate title is allowed, it just stops being silent. */
.chapter-title-input.is-dupe { border-color: rgba(154, 90, 18, .55); background: #fdf8ef; }
.chapter-title-cell { min-width: 0; display: block; }
.chapter-title-warn { display: block; font-size: 0.72rem; color: #8a6a2a; margin-top: 2px; min-height: 0.9em; }
/* CA7 — status text for assistive tech only. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}
/* Sparkle icon inside the Suggest buttons. */
.btn-with-icon { display: inline-flex; align-items: center; gap: 8px; }
.btn-sparkle { width: 15px; height: 15px; object-fit: contain; }
/* Nav arrows via CSS mask so they tint to the button's own text color
   (dark on the light button, cream/white on the brown one). */
.btn-arrow { display: inline-block; width: 17px; height: 15px; background-color: currentColor; flex-shrink: 0;
  -webkit-mask-position: center; mask-position: center; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; -webkit-mask-size: contain; mask-size: contain; }
.btn-arrow-back { -webkit-mask-image: url(/icons/arrow-back.png?v=5); mask-image: url(/icons/arrow-back.png?v=5); }
.btn-arrow-fwd { -webkit-mask-image: url(/icons/arrow-forward.png?v=5); mask-image: url(/icons/arrow-forward.png?v=5); }
/* Header: circular story icon on the left, intro text + title-cards toggle
   stacked on the right — this banner doubles as the step header. */
.chapters-banner { display: flex; flex-direction: row; align-items: flex-start; gap: 22px; }
.chapters-banner-icon { flex-shrink: 0; width: 72px; height: 72px; border-radius: 50%; background: rgba(122, 92, 62, 0.09); color: var(--accent); display: flex; align-items: center; justify-content: center; }
.chapters-banner-icon img { width: 82%; height: 82%; object-fit: contain; display: block; }
.chapters-banner-body { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.chapters-banner-text { display: flex; flex-direction: column; gap: 4px; }
.chapters-banner-toggle { margin-top: 14px !important; padding-top: 14px; border-top: 1px solid rgba(40, 32, 24, 0.12); }
@media (max-width: 560px) { .chapters-banner { flex-direction: column; gap: 14px; } }
/* Chapters uses the banner as its header, so the page title block is hidden;
   keep just a slim bar for the Reset Draft control. */
.page-head-slim { align-items: flex-start; margin-bottom: 6px; min-height: 0; }
/* Green checkbox for the chapters title-card toggle (matches the design). */
.chapters-banner-toggle input[type="checkbox"] { accent-color: var(--sage); }
/* "Our promise" panel — watercolor leaves tucked into the bottom-right. */
.promise-card { position: relative; overflow: hidden; }
.promise-card h3, .promise-card p { position: relative; z-index: 1; }
.promise-leaves { position: absolute; right: -6px; bottom: -6px; width: 112px; height: auto; opacity: 0.96; pointer-events: none; z-index: 0; }

/* ===== Chapters tab — compact density so the whole step fits one screen ===== */
/* Header banner */
.intake-banner.chapters-banner { padding: 0.8rem 0.95rem; margin-bottom: 0.7rem; gap: 16px; }
.chapters-banner-icon { width: 88px; height: 88px; }
.chapters-banner-toggle.checkbox-row { padding: 0.55rem 0.8rem; margin-top: 10px !important; padding-top: 0.55rem; }
/* Section shells (scoped to the two chapters cards via their contents).
   Force single-column (block) so content spans full width — the default
   module-card is a 2-column grid that was squeezing the rows to half width. */
.module-card:has(.story-card-grid), .module-card:has(.chapter-step-list) { display: block; padding: 0.8rem; }
/* Full-width chapter rows on a fixed grid so every column lines up:
   handle | preview | title | count | thumbnails | menu */
.chapter-step-list { width: 100%; }
/* CB4 removed the dead drag handle, so the leading `auto` track it occupied
   goes with it — otherwise the ellipsis lands in the thumbnails' track. */
.chapter-step-row { display: grid !important; width: 100%; grid-template-columns: 208px 300px 72px minmax(0, 1fr) 32px; align-items: center; gap: 16px; }
.chapter-step-row .chapter-step-fields { display: contents; }
.chapter-step-row .chapter-title-input { flex: none; width: 100%; }
.chapter-step-row .chapter-step-meta { margin: 0; text-align: left; white-space: nowrap; }
.chapter-step-row .chapter-step-thumbs { justify-content: flex-start; }
.chapter-step-row .chapter-card-preview { width: 208px; }
.chapter-thumbs-wrap { min-width: 0; }
/* CB1 — the row above is a fixed six-track grid (208px preview + 300px title +
   72px count + gaps ≈ 740px minimum) with no mobile variant, so at 390px the
   whole PAGE panned sideways: previews slid off the left, menus and Back sat off
   the right. Below 820px the row folds instead — handle · preview · menu on the
   first line, everything else full-width beneath it — and the thumbnails scroll
   inside their own strip rather than setting the page's width.
   The key line is `display: block` on .chapter-step-fields: `display: contents`
   dissolves that wrapper into grid items, which is exactly what stops the row
   from being able to reflow. */
@media (max-width: 820px) {
  .chapter-step-row {
    grid-template-columns: minmax(0, 1fr) 44px;
    align-items: center;
    gap: 10px;
    padding: 10px;
  }
  /* Auto-placement alone puts the full-width fields block on line one and pushes
     the ellipsis menu down to a line of its own, so pin all four children: the
     first line stays handle · preview · menu, the fields block takes line two. */
  .chapter-step-row .chapter-card-preview { grid-row: 1; grid-column: 1; width: 100%; }
  .chapter-step-row .chapter-row-menu { grid-row: 1; grid-column: 2; }
  .chapter-step-row .chapter-step-fields {
    display: block;
    grid-row: 2;
    grid-column: 1 / -1;
    min-width: 0;
  }
  .chapter-step-row .chapter-title-input { width: 100%; }
  .chapter-step-row .chapter-step-meta { display: block; margin: 6px 0 4px; text-align: left; }
  .chapter-step-row .chapter-step-thumbs {
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 3px;
  }
  .chapter-step-row .chapter-step-thumbs .chapter-drag-thumb { flex: 0 0 auto; scroll-snap-align: start; }
}
.module-card:has(.story-card-grid) .module-card-header, .module-card:has(.chapter-step-list) .module-card-header { margin-bottom: 2px; flex-direction: row; justify-content: space-between; align-items: flex-start; gap: 14px; }
.module-card:has(.story-card-grid) h3, .module-card:has(.chapter-step-list) h3 { font-size: 1.05rem; }
/* Structure story cards */
.story-card-grid { gap: 10px; margin-top: 8px; }
.story-card { padding: 12px 13px; gap: 7px; }
.story-card-icon { width: 36px; height: 36px; }
.story-card-chapters li { padding: 2.5px 0; font-size: 0.8rem; }
/* Chapter rows */
.chapter-step-list { gap: 6px; }
.chapter-step-row { padding: 5px 10px; }
.chapter-card-preview { width: 104px; }
.chapter-step-thumbs .chapter-drag-thumb { width: 74px; height: 74px; }
/* Process sidebar — denser rows (every step benefits; all overflow otherwise) */
.wizard-steps { gap: 0.3rem; }
.mini-step { padding: 0.32rem 0.62rem; gap: 0.5rem; }
.mini-step .step-num { width: 1.42rem; height: 1.42rem; font-size: 0.76rem; }
.mini-step-body b { font-size: 0.86rem; line-height: 1.2; }
.mini-step-body span { font-size: 0.74rem; margin-top: 0.02rem; line-height: 1.25; }
/* Divider-separated rows; only the active step is a filled pill. */
.wizard-steps { gap: 0; }
.mini-step { border: none !important; border-radius: 0; background: none; border-bottom: 1px solid rgba(40, 32, 24, 0.08) !important; box-shadow: none !important; }
.mini-step:last-child { border-bottom: none !important; }
.mini-step.active { background: #eef3ec; border-radius: 10px; border-bottom-color: transparent !important; }
.mini-step.completed:hover, .mini-step.reachable:hover { background: #f4f7f3; transform: none; }
.mini-step.locked, .mini-step:disabled:not(.active) { opacity: 0.72; }
/* Future steps: clean thin solid circle borders (not dashed). */
.mini-step.locked .step-num { border-style: solid; }
/* 3-column rows: status circle | number-or-mini-check | body */
.mini-step { grid-template-columns: auto 14px 1fr; }
.step-mid { font-size: 0.72rem; font-weight: 600; color: rgba(40, 32, 24, 0.5); display: inline-flex; align-items: center; justify-content: center; line-height: 1; }
.mini-step.reachable .step-mid { color: var(--sage); }
.mini-step.completed .step-mid { color: rgba(40, 32, 24, 0.55); }
/* Structure cards: natural height so the count sits close to the list (no blank band) */
.story-card-grid { align-items: start; }
/* Header: brown underline under the active nav item (e.g. Create Film) */
.nav button.active { position: relative; }
.nav button.active::after { content: ""; position: absolute; left: 2px; right: 2px; bottom: -5px; height: 2px; background: var(--accent); border-radius: 2px; }
/* Serif, lighter headings to match the design */
.chapters-banner-text strong { font-family: Georgia, "Times New Roman", serif; font-weight: 500; font-size: 1.18rem; }
.story-card-head strong { font-family: Georgia, "Times New Roman", serif; font-weight: 500; }
.promise-card h3 { font-family: Georgia, "Times New Roman", serif; font-weight: 500; }
/* Active top-nav step pill: dark filled green + white (was pale/low-contrast) */
.form-status-step.active { background: var(--sage) !important; border-color: var(--sage) !important; color: #fff !important; opacity: 1 !important; }
.form-status-step.active:disabled { color: #fff !important; }
/* Tighter left-column padding + section spacing on the chapters step */
.form-panel:has(.chapters-banner) { padding: 0.9rem; }
.module-card:has(.story-card-grid), .module-card:has(.chapter-step-list) { margin: 0; }
.module-card:has(.story-card-grid) .module-hint, .module-card:has(.chapter-step-list) .module-hint { font-size: 0.82rem; margin-top: 1px; }
.module-card:has(.story-card-grid) .module-card-header, .module-card:has(.chapter-step-list) .module-card-header { gap: 2px; }
/* Slimmer Suggest buttons in the section headers */
.module-card:has(.story-card-grid) .ghost-btn, .module-card:has(.chapter-step-list) .ghost-btn { padding: 6px 12px; font-size: 0.88rem; }
/* Tighter story-card list + card body */
.story-card { padding: 11px 12px; gap: 6px; }
.story-card-head { min-height: 30px; }
.story-card-meta { font-size: 0.72rem; }
/* Chapter rows a touch tighter still */
.chapter-step-row { padding: 5px 9px; gap: 12px; }
.chapter-step-fields { gap: 12px; }
/* Banner text tighter */
.intake-banner.chapters-banner { padding: 0.7rem 0.9rem; }
.chapters-banner-text strong { font-size: 1rem; }
.chapters-banner-text span { font-size: 0.9rem; line-height: 1.4; }
.chapters-banner-toggle.checkbox-row { padding: 0.5rem 0.72rem; margin-top: 8px !important; padding-top: 0.5rem; }
/* Step pills: denser so all 13 sit on one row (global — applies every step) */
.form-status { gap: 0.35rem; }
.form-status-step { padding: 0.3rem 0.56rem; font-size: 0.8rem; min-height: 1.7rem; }
/* Reclaim the big empty top gap on the chapters step — pills sit right under
   the nav like the design; Reset Draft removed from this step. */
.main:has(.chapters-banner) { position: relative; padding-top: 10px; }
.main:has(.chapters-banner) .page-head-slim { display: none; }
/* Full-width step nav above both columns (13 pills fit on one row). */
.form-status-top { margin: 0 0 0.85rem; }

/* ================= WHO (details) step — match the design ================= */
/* Header wreath logo */
.brand-mark-wreath { background: none !important; border: none !important; box-shadow: none !important; overflow: visible; display: inline-flex; align-items: center; justify-content: center; }
.brand-mark-wreath img { width: 100%; height: 100%; object-fit: contain; display: block; }
/* Softer, greener hero heading (global, memorial tone) */
.page-title { color: #3f4d3a; }
.subtitle-heart { width: 20px; height: 20px; object-fit: contain; vertical-align: -3px; margin-right: 7px; }
/* Sidebar "Process" heading: serif + sprig */
.process-heading { display: flex; align-items: center; gap: 7px; font-family: Georgia, "Times New Roman", serif; font-weight: 500; font-size: 1.05rem; letter-spacing: 0; text-transform: none; color: var(--ink); }
.process-sprig { width: 20px; height: 20px; object-fit: contain; }
/* Wider content + full-width pills on the Who step */
.main:has(.who-banner) { width: min(1560px, calc(100% - 2rem)); position: relative; }
.main:has(.who-banner) .wizard { grid-template-columns: minmax(0, 1fr) 360px; }
/* Start small banner: sprig left, candle-flowers right, soft cream */
.intake-banner.who-banner { display: flex; align-items: center; gap: 18px; background: linear-gradient(180deg, #f6f1e6, #f3ede1); border: 1px solid rgba(120, 100, 70, 0.14); border-radius: 16px; padding: 0.9rem 1.1rem; overflow: hidden; }
.who-banner-sprig { flex-shrink: 0; width: 46px; height: auto; object-fit: contain; }
.who-banner-text { flex: 1; display: flex; flex-direction: column; gap: 3px; }
.who-banner-text strong { font-family: Georgia, "Times New Roman", serif; font-weight: 500; font-size: 1.12rem; color: var(--ink); }
.who-banner-art { flex-shrink: 0; width: 168px; height: auto; object-fit: contain; align-self: center; }
/* Form rows: icon circle | label block | fields */
.who-row { grid-template-columns: auto minmax(190px, 0.5fr) minmax(0, 1fr) !important; align-items: start; gap: clamp(0.9rem, 2vw, 1.6rem) !important; }
.who-row-icon { width: 44px; height: 44px; border-radius: 50%; background: rgba(122, 92, 62, 0.09); display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; margin-top: 2px; }
.who-row-icon img { width: 60%; height: 60%; object-fit: contain; display: block; }
.who-row-label h3 { font-family: Georgia, "Times New Roman", serif; font-weight: 500; }
.who-row-help { margin: 3px 0 0; font-size: 0.86rem; color: var(--muted, #8a7f72); }
/* Primary module tint removed to match the neutral target */
.who-row.primary-module { background: rgba(255, 253, 248, 0.72); }
/* CTA: leaf (left) + arrow (right), white via mask */
.who-cta { display: inline-flex; align-items: center; gap: 10px; padding-left: 20px; padding-right: 20px; border-radius: 12px; }
.who-cta-leaf, .who-cta-arrow { display: inline-block; background-color: currentColor; flex-shrink: 0; -webkit-mask-position: center; mask-position: center; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; -webkit-mask-size: contain; mask-size: contain; }
.who-cta-leaf { width: 16px; height: 18px; -webkit-mask-image: url(/icons/who-btn-leaf.png?v=1); mask-image: url(/icons/who-btn-leaf.png?v=1); }
.who-cta-arrow { width: 18px; height: 15px; -webkit-mask-image: url(/icons/who-btn-arrow.png?v=1); mask-image: url(/icons/who-btn-arrow.png?v=1); }

/* ================= PHOTOS step ================= */
/* Reset Draft with reset-arrow icon */
.reset-draft-ico { width: 15px; height: 15px; object-fit: contain; }
/* Promise card upgrade: serif heading + heart bullet + bigger sprig */
.promise-card h3 { font-family: Georgia, "Times New Roman", serif; font-weight: 500; font-size: 1.32rem; }
.promise-heart { width: 15px; height: 14px; object-fit: contain; vertical-align: -2px; margin-right: 6px; }
.promise-leaves { width: 128px; }
/* Photos subtitle: emotional line then body */
.emotional-sub { display: flex; align-items: center; gap: 8px; margin-bottom: 5px; }
.emotional-sub .subtitle-heart { margin: 0; }
.body-sub { color: var(--body); max-width: 660px; }
/* Photos step: wider content + full-width pills, wider sidebar */
.main:has(.photos-approval-card) { width: min(1560px, calc(100% - 2rem)); position: relative; }
.main:has(.photos-approval-card) .wizard { grid-template-columns: minmax(0, 1fr) 360px; }
/* Faded decorative branch behind the hero, far left */
.main:has(.photos-approval-card)::before, .main:has(.who-banner)::before {
  content: ""; position: absolute; left: -155px; top: 18px; width: 250px; height: 360px;
  background: url(/icons/photos-left-branch.png?v=1) no-repeat left top / contain;
  opacity: 0.4; pointer-events: none; z-index: 0;
}
.main:has(.photos-approval-card) > *, .main:has(.who-banner) > * { position: relative; z-index: 1; }
/* Family photos approval card: shield badge + text */
.photos-approval-card { display: grid !important; grid-template-columns: auto 1fr !important; align-items: center; gap: 20px !important; }
.photos-approval-icon { width: 60px; height: 60px; flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; }
.photos-approval-icon img { width: 100%; height: 100%; object-fit: contain; }
.photos-approval-text strong { font-family: Georgia, "Times New Roman", serif; font-weight: 500; font-size: 1.12rem; display: block; color: var(--ink); }
.photos-approval-text p { margin: 5px 0 0; color: var(--body); line-height: 1.5; }
/* Upload plus circle icon */
.upload-icon-img { background: none !important; border: none !important; width: 58px; height: 58px; display: inline-flex; align-items: center; justify-content: center; }
.upload-icon-img img { width: 100%; height: 100%; object-fit: contain; }
/* ================= LEGACY MAP step ================= */
/* Wider content + full-width pills + branch (consistent with Who/Photos) */
.main:has(.lm-intro-banner) { width: min(1560px, calc(100% - 2rem)); position: relative; }
.main:has(.lm-intro-banner) .wizard { grid-template-columns: minmax(0, 1fr) 360px; }
.main:has(.lm-intro-banner)::before {
  content: ""; position: absolute; left: -155px; top: 18px; width: 250px; height: 360px;
  background: url(/icons/photos-left-branch.png?v=1) no-repeat left top / contain;
  opacity: 0.4; pointer-events: none; z-index: 0;
}
.main:has(.lm-intro-banner) > * { position: relative; z-index: 1; }
/* Icon-led intro cards (Take a moment / Photo restoration) */
.intake-banner.lm-intro-banner { display: flex; align-items: flex-start; gap: 18px; background: #faf6ee; border: 1px solid rgba(120, 100, 70, 0.16); border-radius: 16px; padding: 1rem 1.15rem; }
.lm-intro-icon { flex-shrink: 0; width: 52px; height: 52px; display: inline-flex; align-items: center; justify-content: center; }
.lm-intro-icon img { width: 100%; height: 100%; object-fit: contain; }
.lm-intro-text { flex: 1; display: flex; flex-direction: column; gap: 4px; }
.lm-intro-text > strong { font-family: Georgia, "Times New Roman", serif; font-weight: 500; font-size: 1.1rem; color: var(--ink); }
.restore-banner.lm-intro-banner .restore-banner-toggle { margin-top: 8px; }
/* Shield heading */
.lm-shield-h3 { display: flex; align-items: center; gap: 9px; font-family: Georgia, "Times New Roman", serif; font-weight: 500; }
.lm-shield-ico { width: 24px; height: 24px; object-fit: contain; }
/* Compact horizontal life-stage rows: badge | title+count | thumbnails */
.lm-stage-list { display: flex; flex-direction: column; gap: 10px; }
.lm-stage-row { display: grid !important; grid-template-columns: auto 190px 1fr; align-items: center; gap: 20px; padding: 14px 18px; }
.lm-stage-badge { width: 48px; height: 48px; border-radius: 50%; background: rgba(122, 92, 62, 0.08); display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.lm-stage-badge img { width: 62%; height: 62%; object-fit: contain; }
.lm-stage-info h3 { font-family: Georgia, "Times New Roman", serif; font-weight: 500; margin: 0; font-size: 1.05rem; }
.lm-stage-info p { margin: 2px 0 0; color: var(--muted, #8a7f72); font-size: 0.85rem; }
.lm-stage-row .chapter-photos { display: flex; gap: 10px; flex-wrap: wrap; margin: 0; }
.lm-stage-row .chapter-photo { width: auto; }
.lm-stage-row .chapter-photo img { width: 92px; height: 68px; object-fit: cover; border-radius: 8px; display: block; }
/* Detailed "A closer look" rows: thumbnail | text | fixed right-aligned Restore */
.photo-analysis-row { display: grid !important; grid-template-columns: 132px minmax(0, 1fr) 128px; align-items: center; gap: 20px; }
.photo-analysis-row .chapter-photo { width: auto; }
.photo-analysis-row .chapter-photo img { width: 132px; height: 96px; object-fit: cover; border-radius: 8px; display: block; }
.pa-info { min-width: 0; }
.pa-info > strong { font-weight: 600; }
.pa-restore { display: flex; justify-content: flex-end; }
/* Enlarged restoration previews with full-width Restore buttons */
.lm-restore-card .unassigned-photos { display: flex; gap: 18px; flex-wrap: wrap; }
.lm-restore-card .restore-review-photo { width: 300px; max-width: 100%; display: flex; flex-direction: column; gap: 0; }
.lm-restore-card .restore-review-photo img { width: 100%; height: 180px; object-fit: cover; border-radius: 12px 12px 0 0; display: block; }
.lm-restore-card .restore-review-photo .restore-toggle { width: 100%; justify-content: center; border-radius: 0 0 12px 12px; padding: 0.65rem; margin: 0 !important; border-top: none; }
/* Uploaded photos section header */
.uploaded-photos-header { display: flex; align-items: center; gap: 8px; margin: 1.3rem 0 0.7rem; font-size: 0.76rem; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; color: var(--body); }
.uploaded-photos-ico { width: 19px; height: 19px; object-fit: contain; }
/* Circular remove-photo icon */
.upload-thumb .thumb-remove-btn { position: absolute; top: 8px; right: 8px; width: 26px; height: 26px; padding: 0; border: none; background: none; z-index: 3; cursor: pointer; }
.upload-thumb .thumb-remove-btn img { width: 100%; height: 100%; object-fit: contain; display: block; }
/* Chapters: wider sidebar (~72/28) and no heavy left wrapper — the intro,
   structure picker and chapter editor become separate cards. */
.main:has(.chapters-banner) .wizard { grid-template-columns: minmax(0, 1fr) 360px; }
.form-panel:has(.chapters-banner) { border: none; background: none; padding: 0; display: flex; flex-direction: column; gap: 0.85rem; }
.form-panel:has(.chapters-banner) > .intake-banner { margin-bottom: 0; }
/* Wider content column on the chapters step (smaller side margins) so the
   structure cards are broad like the design. */
.main:has(.chapters-banner) { width: min(1560px, calc(100% - 2rem)); }
/* Four broad structure cards that fill the wider row. */
.story-card-grid { grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }

/* Restoration reveal controls + preview pane. */
.reveal-controls .reveal-enable { display:flex; align-items:center; gap:8px; font-size:0.92rem; margin:4px 0 12px; cursor:pointer; }
.reveal-controls .reveal-enable input { width:16px; height:16px; accent-color:#7a5c3e; }
.reveal-style-row { display:flex; gap:8px; margin-bottom:14px; }
.reveal-style-row.is-disabled { opacity:0.45; }
.reveal-style-btn { padding:7px 16px; border:1px solid rgba(40,32,24,0.25); border-radius:8px; background:#fff; font:inherit; font-size:0.9rem; cursor:pointer; }
.reveal-style-btn.active { border-color:#7a5c3e; background:#f3ead8; font-weight:500; }
.reveal-style-btn:disabled { cursor:not-allowed; }
.reveal-preview { display:flex; flex-direction:column; gap:10px; }
/* Two-column layout: controls on the left, big preview on the right.
   (.module-card is itself a 2-col grid — force block so the inner grid
   spans the full card width.) */
.reveal-controls { display:block !important; }
.reveal-grid { display:grid; width:100%; box-sizing:border-box; grid-template-columns: 230px minmax(0,1fr); gap:1.6rem; align-items:start; margin-top:0.8rem; }
.reveal-left-label { font-size:0.72rem; letter-spacing:0.06em; text-transform:uppercase; color:var(--muted); font-weight:600; margin:0 0 0.5rem; }
.reveal-thumbs-label { margin-top:1rem; }
.reveal-left .reveal-style-row { flex-wrap:wrap; margin-bottom:0; }
.reveal-right { margin:0; }
.reveal-right .reveal-prev-frame { max-width:100%; aspect-ratio:16/10; }
.reveal-prev-frame { position:relative; width:100%; max-width:340px; aspect-ratio:4/3; margin:0 auto; border-radius:10px; overflow:hidden; background:#f2efe8; border:1px solid rgba(120,100,70,0.14); }
@media (max-width: 820px) { .reveal-grid { grid-template-columns:1fr; } }
.reveal-prev-img { position:absolute; inset:0; width:100%; height:100%; object-fit:contain; }
.reveal-preview.is-off .reveal-prev-before { display:none; }
@keyframes rp-dissolve { 0%,22%{opacity:1} 46%,82%{opacity:0} 100%{opacity:1} }
@keyframes rp-wipe { 0%,22%{clip-path:inset(0 0 0 0)} 46%,82%{clip-path:inset(0 0 0 100%)} 100%{clip-path:inset(0 0 0 0)} }
@keyframes rp-bloom { 0%,22%{clip-path:circle(150% at 50% 42%)} 46%,82%{clip-path:circle(0% at 50% 42%)} 100%{clip-path:circle(150% at 50% 42%)} }

/* Reveal preview: clickable thumbnail strip instead of a name dropdown. */
.reveal-thumbs { display:flex; gap:8px; overflow-x:auto; padding:4px 2px 8px; scrollbar-width:thin; }
.reveal-thumb { flex:0 0 auto; width:56px; height:56px; padding:0; border:2px solid transparent; border-radius:8px; overflow:hidden; background:#2a2420; cursor:pointer; }
.reveal-thumb img { width:100%; height:100%; object-fit:cover; display:block; }
.reveal-thumb.active { border-color:#7a5c3e; }
.reveal-thumbs-hint { font-size:0.78rem; color:rgba(40,32,24,0.5); text-align:center; margin:2px 0 0; }

/* Final-film modal: separate View (switch player) + Download rows. */
.lm-final-grouplabel { font-size:0.72rem; text-transform:uppercase; letter-spacing:0.08em; color: var(--muted, #7a7066); margin:1rem 0 0.4rem; }
.lm-final-row { display:flex; gap:0.6rem; justify-content:center; flex-wrap:wrap; }
.lm-fmt-tab { padding:7px 16px; border:1px solid var(--line, #d8cdb8); border-radius:8px; background: var(--paper, #fff); color: var(--ink, #2a2018); font:inherit; font-size:0.9rem; cursor:pointer; transition: border-color .12s ease, background .12s ease; }
.lm-fmt-tab:hover { border-color: var(--accent); }
.lm-fmt-tab.active { background: var(--accent); border-color: var(--accent); color:#fff; font-weight:600; }

/* Near-duplicate review panel (Photos step). */
.dupe-panel { margin-top: 16px; border-color: var(--accent); }
.dupe-cluster { display: flex; flex-wrap: wrap; align-items: center; gap: 16px; padding: 12px 0; border-top: 1px solid rgba(40,32,24,0.1); }
.dupe-cluster:first-of-type { border-top: 0; }
.dupe-thumbs { display: flex; gap: 8px; flex-wrap: wrap; }
.dupe-thumb { position: relative; width: 92px; height: 92px; padding: 0; border: 2px solid transparent; border-radius: 8px; overflow: hidden; background: #2a2420; cursor: pointer; opacity: 0.55; }
.dupe-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.dupe-thumb.is-keep { opacity: 1; border-color: #2f8a52; }
.dupe-badge { position: absolute; left: 4px; bottom: 4px; font-size: 0.68rem; padding: 1px 6px; border-radius: 5px; background: rgba(40,32,24,0.7); color: #fff; }
.dupe-thumb.is-keep .dupe-badge { background: #2f8a52; }
.dupe-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.upload-thumb.is-dupe-skipped { opacity: 0.4; }
.upload-thumb.is-dupe-skipped .main-badge { opacity: 1; }

/* Dupe panel: enlargeable thumbnails + keep button; grid highlight. */
.dupe-thumb-wrap { display: flex; flex-direction: column; gap: 6px; align-items: center; }
.dupe-thumb { position: relative; }
.dupe-zoom { position: absolute; top: 4px; right: 4px; font-size: 0.8rem; color: #fff; background: rgba(40,32,24,0.6); border-radius: 5px; padding: 0 5px; }
.dupe-keepbtn { font-size: 0.78rem; padding: 4px 12px; border: 1px solid rgba(40,32,24,0.25); border-radius: 6px; background: #fff; cursor: pointer; }
.dupe-keepbtn.active { background: #2f8a52; color: #fff; border-color: #2f8a52; }
.upload-thumb.is-dupe-flagged { outline: 3px solid #d99a2b; outline-offset: 1px; border-radius: 8px; }

/* AI verdict + per-photo notes in the duplicates panel. */
.dupe-verdict { font-size: 0.86rem; margin: 0 0 8px; font-weight: 500; }
.dupe-verdict.is-dup { color: #8a4b2a; }
.dupe-verdict.is-distinct { color: #2f6d46; }
.dupe-note { display: block; max-width: 92px; font-size: 0.7rem; line-height: 1.25; color: rgba(40,32,24,0.6); text-align: center; }
.dupe-note.is-keep-note { color: #2f6d46; }

/* Duplicates: "reviewing" inline spinner. */
.dupe-reviewing { display: flex; align-items: center; gap: 8px; margin-top: 10px; }
.dupe-spin { width: 14px; height: 14px; border: 2px solid rgba(40,32,24,0.25); border-top-color: #7a5c3e; border-radius: 50%; display: inline-block; animation: dupe-spin 0.8s linear infinite; }
@keyframes dupe-spin { to { transform: rotate(360deg); } }

/* Chapters: AI "story" structure picker. */
.story-card-grid { display: grid; width: 100%; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 12px; margin-top: 10px; }
.story-card { position: relative; text-align: left; background: var(--paper, #fff); border: 1px solid var(--line, #e5ded3); border-radius: var(--radius, 12px); padding: 16px; cursor: pointer; display: flex; flex-direction: column; gap: 10px; font: inherit; transition: border-color .15s ease, box-shadow .15s ease, transform .08s ease; }
.story-card:hover { border-color: var(--accent); transform: translateY(-1px); }
.story-card.is-active { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent) inset; }
.story-card-icon { width: 40px; height: 40px; border-radius: 50%; background: rgba(122, 92, 62, 0.1); color: var(--accent); display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.story-card-icon img { width: 76%; height: 76%; object-fit: contain; display: block; }
.story-card-head { display: flex; align-items: center; gap: 10px; min-height: 34px; }
.story-card.is-active .story-card-head { padding-right: 60px; }
.story-card-head strong { font-size: .95rem; line-height: 1.2; color: var(--ink, #2a2018); }
.story-card-badge { position: absolute; top: 12px; right: 12px; font-size: .6rem; text-transform: uppercase; letter-spacing: .05em; color: #fff; background: var(--accent); border-radius: 999px; padding: 2px 8px; white-space: nowrap; }
.story-card-chapters { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0; }
.story-card-chapters li { display: flex; justify-content: space-between; gap: 8px; font-size: .82rem; padding: 4px 0; border-bottom: 1px dashed var(--line, #eee); }
.story-card-chapters li:last-child { border-bottom: 0; }
.cs-ch-name { color: var(--ink, #2a2a2a); }
.cs-ch-count { color: var(--muted, #999); font-variant-numeric: tabular-nums; }
.story-card-meta { font-size: .74rem; color: var(--muted, #999); margin-top: 8px; padding-top: 2px; }

/* Fallback chapter card (no opening template chosen): wrap text so it centers. */
.draft-player-chapter-card .draft-player-chapter-text { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1.5cqi; padding: 8cqi; text-align: center; }

/* Chapter title card built on the chosen opening title-card template — same
   background image + font, with the chapter name as the headline. Shared by the
   rough-cut player, the headless render, and the Chapters-step live preview. */
.lm-chapter-card-stage { position: relative; width: 100%; height: 100%; overflow: hidden; }
.lm-chapter-card-stage .titlecard-bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 0; }
.lm-chapter-card-center { position: absolute; inset: 0; z-index: 2; display: flex; align-items: center; justify-content: center; padding: 6cqi; }
/* Subtle scrim that hugs ONLY the text — the backdrop stays at full brightness
   everywhere else (matching the cover). */
.lm-chapter-card-plate { display: flex; flex-direction: column; align-items: center; gap: 1.4cqi; padding: 5cqi 9cqi; text-align: center; background: radial-gradient(ellipse at center, rgba(12,9,6,0.2) 0%, rgba(12,9,6,0.1) 50%, rgba(12,9,6,0) 78%); border-radius: 999px; }
/* Eyebrow inherits the cover's PREAMBLE treatment ("In Loving Memory"): the
   font comes from the applied .font-preset-<id> class; the :not() default below
   (italic serif) only applies when no preset is chosen. Matches the preamble's
   base letter-spacing + no forced case so it reads like the preamble line. */
.lm-chapter-card-eyebrow { font-size: 2.6cqi; margin: 0; opacity: 0.92; }
/* CH-MATCH — the tracking is the default's, not the line's: a preset (or the
   opening's own inline tracking) sets its own. */
.lm-chapter-card-eyebrow:not([class*="font-preset-"]) { font-family: "Cormorant Garamond", "EB Garamond", serif; font-style: italic; letter-spacing: 0.08em; }
/* CH-MATCH — the eyebrow and the title carry the opening's own line classes
   and inline style (colour, weight, tracking, case, shadow, backing), read off
   the opening as it renders. Each is its own stacking context so a backing
   span (z-index -1) sits behind its words and not behind the card. */
.lm-chapter-card-stage.is-cover-matched .lm-chapter-card-eyebrow,
.lm-chapter-card-stage.is-cover-matched .lm-chapter-card-title { position: relative; isolation: isolate; }
/* CH-MATCH — an opening with no font preset draws its name upright (the
   .titlecard-name base), so the matched title does too; and the catalogue's
   own "feel" classes (.font-script etc., otherwise scoped to .titlecard-name)
   read the same here, sized to the chapter title's 11cqi instead of the
   name's 7. */
.lm-chapter-card-stage.is-cover-matched .lm-chapter-card-title:not([class*="font-preset-"]) { font-style: normal; }
.lm-chapter-card-title.font-serif-uppercase,
.lm-chapter-card-title.font-serif-caps { font-style: normal; text-transform: uppercase; letter-spacing: 0.08em; font-size: 9.4cqi; }
.lm-chapter-card-title.font-sans-serif-caps,
.lm-chapter-card-title.font-thin-display { font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif; font-style: normal; font-weight: 300; text-transform: uppercase; letter-spacing: 0.15em; font-size: 7.9cqi; }
.lm-chapter-card-title.font-script { font-family: "Caveat", "Brush Script MT", cursive; font-style: normal; letter-spacing: 0; font-size: 12.6cqi; }
.lm-chapter-card-title.font-serif-italic { font-style: italic; font-weight: 500; }
/* Headline in the cover name's color + font, with the cover's exact 3-layer
   black halo so the treatment matches the loved-one name. The font-family/
   style/weight come from the applied .font-preset-<id> class (inherited from
   the cover name); the :not() default below only applies when no preset is set. */
.lm-chapter-card-title { font-size: 11cqi; line-height: 1.1; margin: 0; text-shadow: 0 0 0.4cqi rgba(0,0,0,calc(0.95 * var(--ts-a, 1))), 0 0 1.2cqi rgba(0,0,0,calc(0.7 * var(--ts-a, 1))), 0 0 2.2cqi rgba(0,0,0,calc(0.4 * var(--ts-a, 1))); }
.lm-chapter-card-title:not([class*="font-preset-"]) { font-family: "Cormorant Garamond", "EB Garamond", serif; font-style: italic; font-weight: 600; }
.lm-chapter-card-sub { font-family: "Inter", sans-serif; font-size: 2.4cqi; letter-spacing: 0.2em; margin: 0; opacity: 0.85; }

/* Live chapter-card preview on the Chapters step — a small 16:9 window that
   hosts the real card markup (container-query units scale to this width). */
.chapter-card-preview {
  container-type: inline-size;
  position: relative;
  flex-shrink: 0;
  width: 104px;
  aspect-ratio: 16 / 9;
  border-radius: 10px;
  overflow: hidden;
  box-shadow: 0 1px 5px rgba(0,0,0,0.16);
  background: #1f1813;
}
.chapter-card-preview .titlecard-stage,
.chapter-card-preview .draft-player-chapter-card { width: 100%; height: 100%; }
@media (max-width: 640px) { .chapter-card-preview { width: 150px; } }

/* Chapter-card preview is a button (click to enlarge) + hover zoom affordance. */
.chapter-card-preview { border: 0; padding: 0; cursor: pointer; display: block; }
.chapter-card-preview .chapter-card-zoom { position: absolute; top: 6px; right: 8px; z-index: 3; font-size: 13px; line-height: 1; color: #fff; opacity: 0; background: rgba(0,0,0,0.4); border-radius: 6px; padding: 3px 5px; transition: opacity .15s ease; pointer-events: none; }
.chapter-card-preview:hover .chapter-card-zoom, .chapter-card-preview:focus-visible .chapter-card-zoom { opacity: 1; }
/* Title cards turned off: dim the preview and label it so it's clear the
   card won't appear in the film until the toggle above is on. */
.chapter-card-preview.is-off .titlecard-stage,
.chapter-card-preview.is-off .draft-player-chapter-card { filter: grayscale(0.5) brightness(0.82); opacity: 0.6; }
.chapter-card-preview.is-off .chapter-card-offbadge {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 3;
  font-size: 11px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase;
  color: #fff; background: rgba(40, 32, 24, 0.72); border-radius: 8px; padding: 5px 9px;
  white-space: nowrap; pointer-events: none;
}

/* Enlarged chapter card (reuses the .lightbox overlay). */
.chapter-card-lightbox-stage { container-type: inline-size; width: min(92vw, 1080px); aspect-ratio: 16 / 9; border-radius: 14px; overflow: hidden; box-shadow: 0 24px 70px rgba(0,0,0,0.5); }
.chapter-card-lightbox-stage .titlecard-stage,
.chapter-card-lightbox-stage .draft-player-chapter-card { width: 100%; height: 100%; }
/* CB2 — shown under the card only when title cards are switched off, so a
   full-screen card can never imply it is in the film when it isn't. */
.chapter-card-lightbox { flex-direction: column; }
.chapter-card-lightbox-note {
  display: flex; align-items: center; justify-content: center; flex-wrap: wrap;
  gap: 10px 14px; margin-top: 14px; width: min(92vw, 1080px);
  color: rgba(255, 255, 255, 0.92); font-size: 0.92rem; text-align: center;
}
.chapter-card-lightbox-note .ghost-btn { min-height: 44px; background: rgba(255,255,255,0.1); color: #fff; border-color: rgba(255,255,255,0.45); }
.chapter-card-lightbox-note .ghost-btn:hover { background: rgba(255,255,255,0.2); }

/* Drag photos to reorder within / move between chapters, with a drop line. */
.chapter-step-thumbs { flex-wrap: wrap; row-gap: 6px; }
.chapter-drag-thumb { cursor: pointer; transition: margin .16s ease, opacity .12s ease, transform .1s ease; }
.chapter-drag-thumb:hover { transform: translateY(-1px); }
.chapter-drag-thumb.is-dragging { opacity: 0.3; cursor: grabbing; }

/* MH2 — "you have opened this tab" vs "you have chosen this" were indistinguishable. */
.no-audio-state { margin: 10px 0 14px; padding: 9px 12px; border-radius: 9px; font-size: 0.86rem; line-height: 1.4;
  background: #fdf3e2; color: #8a6a2a; border: 1px solid rgba(154,90,18,.25); }
.no-audio-state.is-chosen { background: #dcefe2; color: #2f6b46; border-color: rgba(47,107,70,.25); }

/* ML6 — the deliberate "quieter than normal" control. */
.music-level-row { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px; margin: 10px 0 2px; }
.music-level-label { font-size: 0.84rem; color: rgba(40,32,24,0.7); }
.music-level-btns { display: inline-flex; gap: 4px; background: rgba(40,32,24,0.05); border-radius: 10px; padding: 3px; }
.music-level-btn { min-height: 36px; padding: 0 14px; border: 0; border-radius: 8px; background: none; cursor: pointer; font: inherit; font-size: 0.84rem; color: var(--ink, #281f18); }
.music-level-btn.active { background: #fffdf7; box-shadow: 0 1px 3px rgba(40,32,24,0.14); font-weight: 600; }
.music-level-btn:focus-visible { outline: 3px solid var(--accent); outline-offset: -3px; }
.music-level-hint { flex: 1 1 100%; font-size: 0.76rem; color: rgba(40,32,24,0.5); }

/* MB4 — how the track's length compares with the film's. */
.music-length-note { margin: 10px 0 2px; font-size: 0.82rem; line-height: 1.45; color: #8a6a2a; background: #fdf3e2; border-radius: 8px; padding: 8px 10px; max-width: 68ch; }
.music-length-note.is-ok { color: rgba(40,32,24,0.62); background: rgba(40,32,24,0.04); }

/* MB2 — an unreadable upload must not look like a finished choice. */
.music-unreadable-note { display: block; margin-top: 4px; font-size: 0.78rem; line-height: 1.4; color: #8a6a2a; background: #fdf3e2; border-radius: 6px; padding: 6px 8px; max-width: 60ch; }

/* ML3 — a distinguisher under repeated titles (there is no artist field). */
.free-library-distinguish { display: block; font-size: 0.74rem; color: rgba(40,32,24,0.5); margin-top: 1px; }
/* ML7 / MW3 — the evidence behind "free to use". */
.track-licence-link { color: var(--accent); text-decoration: underline; }

/* MI7 — where the note goes, said where they type it. */
.suggestions-note-privacy { margin: 5px 0 0; font-size: 0.74rem; line-height: 1.4; color: rgba(40,32,24,0.55); }
/* MV4 — which of the two things Save will do. */
.manual-entry-scope { margin: 0 0 8px; font-size: 0.78rem; color: rgba(40,32,24,0.6); }
/* MW6 — what the film will actually play, always visible. */
.music-now-playing { margin: 2px 0 6px; font-size: 0.84rem; font-weight: 600; color: var(--accent); }

/* MV3 — the manual-entry form used to fail silently on a whitespace-only title. */
.manual-entry-error { margin: 8px 0 0; font-size: 0.82rem; color: #8a1c1c; }
.manual-entry-error[hidden] { display: none; }
/* ML2 — the Clear the empty-state message always referred to. */
.music-clear-search { background: none; border: 0; padding: 0; cursor: pointer; color: var(--accent); text-decoration: underline; font: inherit; }

/* PB1 / CG4 — the honest account of where photos go, and the short pointers to
   it that sit under any control which sends something away. */
.privacy-modal { cursor: default; }
.privacy-panel {
  width: min(94vw, 660px); max-height: 88vh; overflow: auto;
  background: #fffdf7; border-radius: 16px; padding: 24px 26px;
  box-shadow: 0 24px 70px rgba(0,0,0,0.45); color: var(--ink, #281f18);
}
.privacy-title { margin: 0 0 6px; font-size: 1.25rem; }
.privacy-h { margin: 18px 0 5px; font-size: 0.78rem; text-transform: uppercase; letter-spacing: .07em; color: rgba(40,32,24,0.5); }
.privacy-panel p { margin: 0 0 9px; font-size: 0.92rem; line-height: 1.5; }
.privacy-list { margin: 0 0 9px; padding-left: 1.1rem; }
.privacy-list li { margin: 0 0 7px; font-size: 0.92rem; line-height: 1.45; }
.privacy-fine { color: rgba(40,32,24,0.6); font-size: 0.84rem !important; }
.privacy-actions { display: flex; justify-content: flex-end; margin-top: 18px; }
.privacy-actions .primary-btn { min-height: 44px; }
.ai-sends-note { margin: 6px 0 0; font-size: 0.78rem; line-height: 1.4; color: rgba(40,32,24,0.58); max-width: 72ch; }
.ai-sends-link { background: none; border: 0; padding: 0; cursor: pointer; color: var(--accent); text-decoration: underline; font: inherit; font-size: inherit; }
@media (max-width: 560px) {
  .privacy-panel { padding: 18px 16px; }
  .privacy-actions .primary-btn { width: 100%; }
}

/* CG2 — the server always returned a one-line description of each grouping's
   angle; the card now shows it, so a two-word label isn't the only evidence. */
.story-card-blurb { display: block; font-size: 0.8rem; line-height: 1.35; color: rgba(40,32,24,0.6); margin: 2px 0 6px; }
/* CG3 — why a photo landed in "More Moments", said out loud in the row. */
.chapter-step-note { display: block; font-size: 0.76rem; line-height: 1.35; color: rgba(40,32,24,0.55); margin: 2px 0 4px; max-width: 60ch; }
/* CN3 — tone picker beside "Suggest chapter names". */
.chapter-tone { display: inline-flex; align-items: center; }
.chapter-tone select {
  min-height: 44px; padding: 0 30px 0 12px; border: 1px solid var(--line, #e9e2d6);
  border-radius: 10px; background: #fffdf7; color: var(--ink, #281f18);
  font: inherit; font-size: 0.86rem; cursor: pointer; appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, rgba(40,32,24,0.5) 50%), linear-gradient(135deg, rgba(40,32,24,0.5) 50%, transparent 50%);
  background-position: calc(100% - 16px) 50%, calc(100% - 11px) 50%;
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat;
}
.chapter-tone select:disabled { opacity: 0.5; cursor: default; }

/* CA8 — "Reset order" discards every hand edit, so it stops looking like a hint.
   A real (quiet) button: full target height, no underline-link disguise. */
.chapter-reset-btn { min-height: 44px; padding: 0 14px; font-size: 0.86rem; white-space: nowrap; }

/* CH5 — "suggested chapter names" review. Suggestions sit beside the current
   names; nothing is written until the family presses the button. */
.chapter-title-review { cursor: default; }
.ctr-panel {
  width: min(94vw, 620px); max-height: 86vh; overflow: auto;
  background: #fffdf7; border-radius: 16px; padding: 22px 24px;
  box-shadow: 0 24px 70px rgba(0,0,0,0.45);
}
.ctr-title { margin: 0 0 4px; font-size: 1.2rem; }
.ctr-lede { margin: 0 0 14px; font-size: 0.9rem; color: rgba(40,32,24,0.66); }
.ctr-bulk { display: flex; justify-content: flex-end; margin: 0 0 6px; }
.ctr-list { list-style: none; margin: 0 0 18px; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.ctr-row { border-radius: 10px; }
.ctr-row.is-on { background: rgba(122,92,62,0.07); }
.ctr-pick { display: flex; align-items: center; gap: 11px; min-height: 44px; padding: 7px 10px; cursor: pointer; }
.ctr-pick input { width: 19px; height: 19px; flex: 0 0 auto; accent-color: var(--accent); }
.ctr-pick input[disabled] { cursor: default; }
.ctr-names { display: flex; align-items: baseline; gap: 9px; min-width: 0; flex-wrap: wrap; font-size: 0.92rem; }
.ctr-cur { color: rgba(40,32,24,0.62); }
.ctr-yours { font-style: normal; font-size: 0.7rem; text-transform: uppercase; letter-spacing: .05em; color: #8a6a2a; background: #fdf3e2; border-radius: 5px; padding: 2px 6px; margin-left: 7px; }
.ctr-arrow { color: rgba(40,32,24,0.35); }
.ctr-next { font-weight: 600; color: var(--ink, #281f18); }
.ctr-same { font-weight: 400; color: rgba(40,32,24,0.42); }
.ctr-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.ctr-spacer { flex: 1 1 auto; }
.ctr-defaults { background: none; border: 0; padding: 0; cursor: pointer; color: var(--accent); text-decoration: underline; font: inherit; font-size: 0.84rem; }
.ctr-actions .ghost-btn, .ctr-actions .primary-btn { min-height: 44px; }
@media (max-width: 560px) {
  .ctr-panel { padding: 18px 16px; }
  .ctr-actions { flex-direction: column-reverse; align-items: stretch; }
  .ctr-actions .ghost-btn, .ctr-actions .primary-btn { width: 100%; }
  .ctr-spacer { display: none; }
  .ctr-defaults { text-align: center; margin-top: 4px; }
}

/* CB3 / CB5 — anchored action menu. */
.lm-menu {
  position: fixed; z-index: 200; min-width: 208px; max-width: min(88vw, 340px);
  background: #fffdf7; border: 1px solid var(--line, #e9e2d6); border-radius: 12px;
  box-shadow: 0 18px 44px rgba(40, 32, 24, 0.22); padding: 6px; overflow: hidden;
  animation: lm-menu-in .12s ease;
}
@keyframes lm-menu-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.lm-menu-head { padding: 8px 10px 4px; font-size: 0.72rem; letter-spacing: .06em; text-transform: uppercase; color: rgba(40, 32, 24, 0.5); }
.lm-menu-sep { height: 1px; margin: 5px 6px; background: var(--line, #e9e2d6); }
.lm-menu-item {
  display: flex; align-items: center; gap: 9px; width: 100%; min-height: 44px;
  padding: 8px 10px; border: 0; border-radius: 8px; background: none; cursor: pointer;
  font: inherit; font-size: 0.9rem; color: var(--ink, #281f18); text-align: left;
}
.lm-menu-item:hover:not([disabled]) { background: rgba(40, 32, 24, 0.06); }
.lm-menu-item:focus-visible { outline: 3px solid var(--accent); outline-offset: -3px; }
.lm-menu-item[disabled] { opacity: 0.45; cursor: default; }
.lm-menu-item.is-danger { color: #8a1c1c; }
/* The label is the action; the hint is context. When space runs out the HINT
   truncates, never the verb — "Suggest a na…" is useless, "from this chapter's…"
   is not. */
.lm-menu-label { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lm-menu-hint { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: right; font-size: 0.76rem; color: rgba(40, 32, 24, 0.5); }
.lm-menu-thumb { flex: 0 0 auto; width: 26px; height: 26px; border-radius: 5px; object-fit: cover; }
/* Thumbnails part to open a clear slot where the photo will drop. */
.chapter-drag-thumb.gap-before { margin-left: 54px; box-shadow: inset 3px 0 0 0 var(--accent); }
.chapter-drag-thumb.gap-after { margin-right: 54px; box-shadow: inset -3px 0 0 0 var(--accent); }
.chapter-step-row { border-radius: 12px; transition: background .12s ease, box-shadow .12s ease; }
.chapter-step-row.drag-over { background: rgba(122,92,62,0.07); box-shadow: inset 0 0 0 2px var(--accent); }

/* Natural 2 (and other tiers): show the exact prompt that drove the last
   generation, so the family can verify each run is distinct — especially
   the AI-written per-photo prompt. */
.animation-prompt-shown > .animation-advanced-summary { color: var(--accent); font-weight: 600; }
.animation-prompt-text {
  margin: 6px 0 2px; padding: 8px 10px;
  font-size: 12px; line-height: 1.5; color: #4a4038;
  background: rgba(122,92,62,0.06); border-left: 2px solid var(--accent);
  border-radius: 6px; white-space: pre-wrap;
}

/* ============================================================
   Animation v2 — intro gate, generating loader, style picker
   ============================================================ */

/* Phase A — intro gate */
.anim-intro { max-width: 560px; margin: 8px auto 0; text-align: center; padding: 8px 4px 24px; }
.anim-intro-emblem {
  width: 56px; height: 56px; margin: 0 auto 18px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--paper-2); border: 1px solid var(--line); color: var(--gold);
}
.anim-intro-emblem .anim-spark { font-size: 24px; font-style: normal; }
.anim-spark-ico { display:inline-block; width:24px; height:24px; background-color:#b98a3e; -webkit-mask:url(/icons/anim-sparkle.png?v=1) center/contain no-repeat; mask:url(/icons/anim-sparkle.png?v=1) center/contain no-repeat; }
.anim-intro-btn { display:inline-flex; align-items:center; justify-content:center; gap:0.5rem; background:#46604f; border-color:#46604f; color:#fff; }
.anim-intro-btn:hover { background:#3c5344; border-color:#3c5344; }
.anim-btn-spark { display:inline-block; width:15px; height:15px; flex-shrink:0; background-color:currentColor; -webkit-mask:url(/icons/anim-btn-sparkle.png?v=1) center/contain no-repeat; mask:url(/icons/anim-btn-sparkle.png?v=1) center/contain no-repeat; }
.anim-intro-title {
  font-family: "Cormorant Garamond", Georgia, serif; font-weight: 600;
  font-size: 30px; line-height: 1.2; color: var(--ink); margin: 0 0 12px;
}
.anim-intro-lede { font-size: 16px; line-height: 1.7; color: var(--body); margin: 0 auto 20px; max-width: 480px; }
.anim-intro-note {
  display: flex; gap: 10px; text-align: left; align-items: flex-start;
  background: var(--paper-2); border: 1px solid var(--line); border-radius: 12px;
  padding: 12px 14px; margin: 0 auto 22px; max-width: 480px;
  font-size: 13.5px; line-height: 1.6; color: var(--body);
}
.anim-intro-note-icon {
  flex: none; width: 20px; height: 20px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--gold); color: #fff; font-weight: 700; font-size: 13px;
}
.anim-intro-btn { font-size: 16px; padding: 13px 26px; }
.anim-intro-actions { justify-content: center; gap: 10px; margin-top: 18px; }

/* Phase B — generating loader */
.anim-loader { max-width: 460px; margin: 24px auto 0; text-align: center; padding: 12px 4px 32px; }
.anim-loader-orb { position: relative; width: 76px; height: 76px; margin: 0 auto 22px; }
.anim-loader-orb span {
  position: absolute; inset: 0; border-radius: 50%;
  border: 2px solid var(--gold); opacity: 0; animation: animOrbPulse 2.4s ease-out infinite;
}
.anim-loader-orb span:nth-child(2) { animation-delay: 0.8s; }
.anim-loader-orb span:nth-child(3) { animation-delay: 1.6s; }
@keyframes animOrbPulse {
  0% { transform: scale(0.4); opacity: 0.75; }
  100% { transform: scale(1); opacity: 0; }
}
.anim-loader-title { font-family: "Cormorant Garamond", Georgia, serif; font-weight: 600; font-size: 26px; color: var(--ink); margin: 0 0 8px; }
.anim-loader-sub { font-size: 14.5px; line-height: 1.6; color: var(--body); margin: 0 auto 20px; max-width: 400px; }
.anim-loader-bar { height: 6px; border-radius: 999px; background: var(--paper-2); border: 1px solid var(--line); overflow: hidden; margin: 0 auto; max-width: 320px; }
.anim-loader-fill { height: 100%; background: var(--gold); border-radius: 999px; transition: width 0.5s ease; }
.anim-loader-count { font-size: 13px; color: var(--muted); margin: 12px 0 0; }

/* Phase C — picker */
.anim-picker-lede { text-align: center; font-family: "Cormorant Garamond", Georgia, serif; font-size: 22px; color: var(--ink); margin: 4px 0 18px; }
.anim-live-wrap { max-width: 300px; margin: 0 auto; }
.anim-live { position: relative; border-radius: 14px; overflow: hidden; background: var(--paper-2); border: 1px solid var(--line); box-shadow: var(--shadow); }
.anim-live-video, .anim-live img { width: 100%; height: 100%; object-fit: cover; display: block; }
.anim-live-tag {
  position: absolute; left: 10px; bottom: 10px; display: flex; align-items: center; gap: 6px;
  background: rgba(255,253,247,0.92); border: 1px solid var(--line); border-radius: 999px;
  padding: 3px 10px; font-size: 12px; color: var(--body);
}
.anim-live-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--sage); }
.anim-live-name { text-align: center; font-size: 15px; font-weight: 600; color: var(--ink); margin: 12px 0 0; }
.anim-live-actions { display: flex; gap: 8px; justify-content: center; margin: 12px 0 0; }
.anim-use-btn.is-chosen { background: var(--sage); border-color: var(--sage); }

.anim-reveal-row { text-align: center; margin: 22px 0 0; }
.anim-sheet { margin: 18px auto 0; max-width: 560px; }
.anim-style-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.anim-style-tile {
  text-align: left; padding: 0; overflow: hidden; border-radius: 12px;
  border: 1px solid var(--line); background: var(--paper); cursor: pointer;
  transition: border-color 0.15s ease, transform 0.1s ease;
}
.anim-style-tile:hover { border-color: var(--line-strong); }
.anim-style-tile.is-active { border: 2px solid var(--accent); }
.anim-style-thumb { position: relative; display: block; aspect-ratio: 1 / 1; background: var(--paper-2); }
.anim-style-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.anim-hint-halo {
  position: absolute; top: 8%; left: 27%; width: 46%; height: 12%;
  border: 2.5px solid var(--gold); border-radius: 50%; opacity: 0.9;
}
.anim-hint-golden { position: absolute; inset: 0; background: var(--gold); opacity: 0.16; }
.anim-style-badge {
  position: absolute; top: 6px; right: 6px; font-size: 11px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
}
.anim-style-badge.ok { width: 18px; height: 18px; border-radius: 50%; background: var(--sage); color: #fff; }
.anim-style-badge.retry { padding: 3px 8px; border-radius: 999px; background: var(--paper); border: 1px solid var(--line-strong); color: var(--accent); font-size: 11px; cursor: pointer; }
.anim-style-meta { display: block; padding: 7px 9px; }
.anim-style-group-tag { display: block; font-size: 10px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); margin: 0 0 1px; }
.anim-style-name { display: block; font-size: 12.5px; color: var(--ink); }
.anim-picker-foot { justify-content: space-between; margin-top: 24px; }

/* Re-run busy states — thumbnail overlay + living-view overlay */
.anim-busy, .anim-live-busy {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  flex-direction: column; gap: 8px; background: rgba(255,253,247,0.66);
}
.anim-live-busy-label { font-size: 13px; color: var(--body); }
.anim-live.is-busy .anim-live-video { filter: saturate(0.7) brightness(0.98); }
.anim-spinner {
  width: 20px; height: 20px; border-radius: 50%;
  border: 2.5px solid var(--line-strong); border-top-color: var(--accent);
  animation: animSpin 0.8s linear infinite;
}
.anim-spinner.big { width: 34px; height: 34px; border-width: 3px; }
@keyframes animSpin { to { transform: rotate(360deg); } }

/* Projects: make draft cards read as clickable to open. */
.project-card { transition: box-shadow .15s ease, transform .1s ease; }
.project-card:hover { box-shadow: var(--shadow); }
.project-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.project-open-hint { display: inline-block; margin-top: 8px; font-size: 13px; font-weight: 500; color: var(--accent); }

/* Animation picker — bookend placement (Opening / Ending) */
.anim-bookends { max-width: 360px; margin: 22px auto 0; padding: 14px 16px; background: var(--paper-2); border: 1px solid var(--line); border-radius: 12px; }
.anim-bookends-title { font-size: 14px; font-weight: 600; color: var(--ink); margin: 0 0 2px; }
.anim-bookends-hint { font-size: 12px; color: var(--muted); line-height: 1.5; margin: 0 0 12px; }
.anim-bookend-row { display: flex; align-items: center; gap: 10px; margin: 8px 0; }
.anim-bookend-toggle { display: flex; align-items: center; gap: 7px; font-size: 14px; color: var(--ink); min-width: 96px; cursor: pointer; }
.anim-bookend-toggle input { width: 16px; height: 16px; accent-color: var(--accent); }
.anim-bookend-select { flex: 1; padding: 6px 8px; font-size: 13px; border: 1px solid var(--line); border-radius: 8px; background: var(--paper); color: var(--ink); }
.anim-bookend-select:disabled { opacity: .5; }
.anim-bookend-busy { display: inline-flex; }

/* ============================================================
   Accessibility & mobile usability pass (added in UX audit)
   ============================================================ */

/* Stop iOS from auto-zooming when a field is focused (needs >=16px), and keep
   form text comfortably legible for older eyes on small screens. */
@media (max-width: 768px) {
  input,
  textarea,
  select {
    font-size: 16px;
  }
}

/* Comfortable, WCAG-sized tap targets on touch/small screens. */
@media (max-width: 768px) {
  button,
  .primary-btn,
  .ghost-btn,
  .text-link,
  [role="button"] {
    min-height: 44px;
  }

  /* Wizard action rows stack instead of squishing. */
  .row-actions {
    flex-wrap: wrap;
  }

  .row-actions .primary-btn,
  .row-actions .ghost-btn {
    flex: 1 1 auto;
  }
}

/* Let the top navigation wrap gracefully rather than overflow narrow phones. */
@media (max-width: 640px) {
  .topbar {
    flex-wrap: wrap;
    gap: 0.75rem;
    min-height: 0;
    padding-top: 0.6rem;
    padding-bottom: 0.6rem;
  }

  .topbar .nav {
    flex-wrap: wrap;
    gap: 0.75rem 1rem;
  }

  /* Original + cropped previews sit below the text on small screens. */
  .main-photo-summary {
    grid-template-columns: 1fr;
  }
}

/* Respect users who prefer reduced motion for the added overlays. */
@media (prefers-reduced-motion: reduce) {
  .lm-modal,
  .lm-lightbox,
  .toast {
    animation: none !important;
    transition: none !important;
  }
}

/* Skip-to-content link — visually hidden until keyboard-focused. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--accent);
  color: #fffdf8;
  padding: 0.6rem 1rem;
  border-radius: 0 0 8px 0;
  font-weight: 700;
  text-decoration: none;
}

.skip-link:focus {
  left: 0;
}

#main-content:focus {
  outline: none;
}

/* Inline field validation message — dark red with a warning icon so it reads
   clearly as an error, placed directly under the fields it refers to. */
.field-error {
  display: flex;
  align-items: flex-start;
  gap: 0.4rem;
  margin: 0.55rem 0 0;
  color: #8f1616 !important; /* beat the more-specific .module-card p color */
  font-size: 0.85rem;
  font-weight: 700;
  line-height: 1.35;
}

.field-error-icon {
  flex: 0 0 auto;
  font-size: 0.95rem;
  color: #8f1616;
}

/* Red outline on the offending input. */
.input-error,
.input-error:focus,
.input-error:hover {
  border-color: #c0392b !important;
  box-shadow: 0 0 0 1px #c0392b !important;
}

/* Yellow caution note — softer than the red errors (a likely typo, not a block),
   with a warning symbol. */
.field-warn {
  display: flex;
  align-items: flex-start;
  gap: 0.4rem;
  margin: 0.55rem 0 0;
  padding: 0.45rem 0.6rem;
  border-radius: 6px;
  background: #fdf1cf;
  color: #7a5c00 !important; /* beat the more-specific .module-card p color */
  font-size: 0.85rem;
  font-weight: 700;
  line-height: 1.35;
}

.field-warn-icon {
  flex: 0 0 auto;
  font-size: 0.95rem;
  color: #a07800;
}

/* ---------- Film style v2 ---------- */
.fsv2-feelings {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 1rem 0 1.25rem;
}
.fsv2-feel {
  font: inherit;
  font-size: 0.9rem;
  padding: 8px 16px;
  border-radius: 999px;
  border: 1px solid rgba(96, 115, 101, 0.32);
  background: #fffdf8;
  color: var(--body, #4a463f);
  cursor: pointer;
}
.fsv2-feel:hover { background: #f4f1ea; }
.fsv2-feel.on {
  background: var(--sage);
  border-color: var(--sage);
  color: #fff;
  font-weight: 600;
}
.fsv2-feel:disabled { opacity: 0.45; cursor: default; }
.fsv2-empty { opacity: 0.7; }
.fsv2-hint { font-size: 0.9rem; color: var(--body, #4a463f); margin: 0 0 0.9rem; }
.fsv2-looks {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  margin-bottom: 1.25rem;
}
.fsv2-look {
  position: relative;
  padding: 0;
  border: 2px solid rgba(96, 115, 101, 0.28);
  border-radius: 12px;
  overflow: hidden;
  background: #e9e4d8;
  cursor: pointer;
  aspect-ratio: 16 / 10;
}
.fsv2-look img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Live opening-composition preview inside each look card: the family's main
   portrait sitting in that look's backdrop. Let the card take the frame's
   NATURAL 16/9 height (no forced 16/10 box) so there's no black letterbox
   strip under the composition. */
.fsv2-looks-live .fsv2-look {
  aspect-ratio: auto;
  height: auto;
}
.fsv2-look-stage { position: relative; width: 100%; line-height: 0; }
.fsv2-look-stage .preview-stage {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  border-radius: 0;
}
/* With the standalone preview pane removed the look grid owns the full width —
   give the cards more room so the opening portrait reads clearly. */
.fsv2-looks-live { gap: 16px; }
.fsv2-look:hover { border-color: rgba(96, 115, 101, 0.55); }
.fsv2-look.on { border-color: var(--sage); box-shadow: 0 0 0 2px rgba(96, 115, 101, 0.32); }
.fsv2-look-check {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--sage);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.9rem;
}
/* ===== Categories master / detail: small live previews left, big preview +
   docked Font/Color controls right. ===== */
.fsv2-md {
  display: grid;
  grid-template-columns: 258px minmax(0, 1fr);
  gap: 18px;
  align-items: start;
  margin-bottom: 1.25rem;
}
@media (max-width: 720px) { .fsv2-md { grid-template-columns: 1fr; } }
.fsv2-md-list {
  background: var(--paper, #faf5ec);
  border: 1px solid var(--line, #e6ddcb);
  border-radius: 14px;
  padding: 13px;
}
.fsv2-md-list .fsv2-look-label { margin: 0 0 10px; }
/* single-column list of small live previews */
.fsv2-looks-col { grid-template-columns: 1fr !important; gap: 11px !important; margin-bottom: 0 !important; }
/* LM1 — below 820px the looks column becomes a horizontal swipe strip: the four
   cards stop eating 904px of vertical space above the preview they describe.
   Desktop keeps the single-column master/detail list. */
.fs-hscroll-wrap { position: relative; }
@media (max-width: 820px) {
  .fsv2-looks-col {
    display: flex !important;
    flex-direction: row;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    gap: 10px !important;
    padding-bottom: 4px;
  }
  .fsv2-looks-col > .fsv2-look {
    flex: 0 0 46%;
    scroll-snap-align: start;
  }
  .fsv2-md-list { padding-bottom: 9px; }
}
.fsv2-look-mini { display: block; }
.fsv2-look-mini-name {
  position: absolute; left: 0; right: 0; bottom: 0;
  font-size: 0.7rem; font-weight: 600; color: #fff;
  padding: 12px 8px 5px; text-align: center; line-height: 1.15;
  background: linear-gradient(to top, rgba(20,14,8,.62), rgba(20,14,8,0));
  pointer-events: none;
}
.fsv2-look-mini.on .fsv2-look-mini-name { color: #fff; }
/* right: big preview + docked controls, as one card */
.fsv2-md-detail {
  border: 1px solid var(--line, #e6ddcb);
  border-radius: 14px;
  overflow: hidden;
  background: var(--paper, #faf5ec);
}
.fsv2-md-stagewrap { padding: 14px 14px 8px; }
.fsv2-md-stage { position: relative; border-radius: 12px; overflow: hidden; box-shadow: 0 1px 4px rgba(0,0,0,.12); }
/* Never let a drag start a native text/image selection over the stage
   (would draw a dark highlight box over the photo while dragging a line). */
.fsv2-md-stage, .fsv2-md-stage * { -webkit-user-select: none; user-select: none; }
.fsv2-md-stage img { -webkit-user-drag: none; user-drag: none; pointer-events: none; }
/* Each opening line is grab-to-move vertically. A dashed selection box
   (like the Elements editor) shows what you're about to move/resize. */
.fsv2-md-stage .fsv2-md-line {
  cursor: grab; touch-action: none;
  /* These titlecard lines are pointer-events:none by default (only the
     Elements editor's backdrop-stage-area re-enables them). Re-enable here
     so the line — not the photo underneath — receives the drag. */
  pointer-events: auto;
  /* No box at rest — the outline + drag badge appear only on hover. */
  outline: 1.5px dashed transparent; outline-offset: 4px; border-radius: 4px;
  transition: outline-color .12s;
}
.fsv2-md-stage .fsv2-md-line.is-dragging { cursor: grabbing; }
/* Vertical-drag badge — only visible while hovering this specific line. */
.fsv2-md-stage .fsv2-md-line::before {
  content: "\2195"; position: absolute; left: -9px; top: -9px; z-index: 7;
  width: 20px; height: 20px; border-radius: 6px;
  display: flex; align-items: center; justify-content: center;
  font: 400 12px/1 system-ui, -apple-system, sans-serif !important;
  letter-spacing: 0 !important; text-transform: none !important; text-shadow: none !important;
  color: #fff; background: rgba(30,22,14,.66); border: 1px solid rgba(226,197,124,.85);
  opacity: 0; transition: opacity .12s; pointer-events: none;
}
.fsv2-md-stage .fsv2-md-line:hover::before { opacity: .95; }
/* The portrait sits over the name's centre; let clicks fall through to the
   text line so dragging the name always works. */
.fsv2-md-stage .titlecard-portrait { pointer-events: none; }
.fsv2-md-stage .fsv2-md-line:hover {
  outline: 1.5px dashed rgba(226,197,124,.95); outline-offset: 4px;
}
.fsv2-md-stage .fsv2-md-line.is-dragging,
.fsv2-md-stage .fsv2-md-line.is-resizing {
  outline: 1.5px dashed rgba(226,197,124,1); outline-offset: 4px;
}
/* Gold snap guide drawn across the stage while a line snaps into alignment. */
.fsv2-md-snapline {
  position: absolute; left: 0; right: 0; height: 0;
  border-top: 1px dashed rgba(226,197,124,.95);
  box-shadow: 0 0 0 .5px rgba(0,0,0,.28);
  transform: translateY(-.5px); pointer-events: none; z-index: 8;
}
/* per-line corner resize grip (injected inside each opening text line) */
.fsv2-md-rhandle {
  position: absolute; right: -10px; bottom: -10px; z-index: 6;
  width: 22px !important; height: 22px !important; border-radius: 6px; padding: 0 !important;
  border: 1px solid rgba(255,255,255,.75);
  background: rgba(30,22,14,.62); color: #fff !important;
  font-family: system-ui, -apple-system, sans-serif !important;
  font-size: 12px !important; font-weight: 400 !important; font-style: normal !important;
  line-height: 1 !important; letter-spacing: 0 !important; text-transform: none !important;
  text-shadow: none !important; cursor: nwse-resize; opacity: 0.35;
  display: flex; align-items: center; justify-content: center;
  touch-action: none; transition: background .12s, transform .12s, opacity .12s;
}
.fsv2-md-stage .fsv2-md-line:hover .fsv2-md-rhandle { opacity: 0.9; }
.fsv2-md-rhandle:hover { background: rgba(30,22,14,.9); transform: scale(1.12); opacity: 1; }
.fsv2-md-edithint { margin: 7px 2px 0; font-size: 11.5px; color: var(--muted, #7c766c); text-align: center; }
.fsv2-md-edithint-row .fsv2-md-edithint { margin: 0; }
.fsv2-md-editacts { display: flex; gap: 8px; }
.fsv2-md-editbtn {
  font: 500 11.5px/1 system-ui, -apple-system, sans-serif;
  padding: 5px 11px; border-radius: 999px; cursor: pointer;
  border: 1px solid rgba(90,70,45,.28); background: #fff; color: #5a4a34;
  transition: background .12s, border-color .12s, opacity .12s, transform .06s;
}
.fsv2-md-editbtn:hover:not(:disabled) { background: #f4efe6; border-color: rgba(90,70,45,.45); }
.fsv2-md-editbtn:active:not(:disabled) { transform: translateY(1px); }
.fsv2-md-editbtn:disabled { opacity: .4; cursor: default; }
/* LH11 — the one visible way back, shown only when this look has been changed.
   Quiet by default: it should read as an exit, not an action to take. */
.fsv2-md-restore-row { justify-content: center; margin-top: 4px; }
.fsv2-md-restore { color: #6b6154; border-color: rgba(90,70,45,.22); }
.fsv2-md-restore:hover:not(:disabled) { background: #f4efe6; color: #46392a; }
/* LB2 — the detail pane is showing a look the family has NOT chosen (they're
   browsing another feeling, or haven't picked yet). Say so plainly and give
   them one obvious way to actually choose it. */
.fsv2-md-prevnote {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 8px; margin: 0 0 10px;
  padding: 8px 12px; border-radius: 10px;
  background: #fbf4e6; border: 1px solid rgba(150,110,40,.28);
  font: 400 12.5px/1.35 system-ui, -apple-system, sans-serif; color: #6b5326;
}
.fsv2-md-prevnote strong { font-weight: 600; color: #4a3a1c; }
.fsv2-md-uselook {
  font: 600 12px/1 system-ui, -apple-system, sans-serif;
  padding: 7px 14px; border-radius: 999px; cursor: pointer; white-space: nowrap;
  border: 1px solid rgba(90,70,45,.35); background: #5a4a34; color: #fff;
  transition: background .12s, transform .06s;
}
.fsv2-md-uselook:hover { background: #463927; }
.fsv2-md-uselook:active { transform: translateY(1px); }
.fsv2-md-stagewrap.is-preview-only .fsv2-md-stage,
.fsv2-md-stagewrap.is-preview-only .fsv2-md-fallback { opacity: .92; }
.fsv2-md-stage .preview-stage { border-radius: 12px; }
.fsv2-md-fallback { width: 100%; border-radius: 12px; display: block; }
.fsv2-md-dock {
  border-top: 1px solid var(--line, #e6ddcb);
  background: var(--paper2, #f2ead9);
  padding: 13px 15px 15px;
}
.fsv2-md-dock .f3-tstyle-dock { margin-top: 0; }
/* Center the docked Font/Color heads + chip rows (safe center keeps the left
   chips reachable if they ever overflow on a narrow screen). */
.f3-tstyle-dock .f3-tstyle-head { text-align: center; padding-left: 0.4rem; }
.f3-tstyle-dock .f3-tstyle-row { justify-content: safe center; padding-left: 0.4rem; padding-right: 0.4rem; }
.check-tog .check { width: 18px; height: 18px; border-radius: 50%; border: 1.5px solid rgba(96, 115, 101, 0.42); display: inline-flex; align-items: center; justify-content: center; font-size: 0.68rem; }
.check-tog.on .check { background: var(--sage); border-color: var(--sage); color: #fff; }
.v2dg.rev { flex-direction: row-reverse; }
.v2dg.main { font-style: italic; color: #6b5a38; font-size: 0.85rem; }
.v2dg .col { width: 100%; display: flex; flex-direction: column; align-items: center; gap: 7px; }
.v2dg .chap { position: absolute; top: 10%; left: 50%; transform: translateX(-50%); width: 26%; height: 4px; border-radius: 2px; background: #a88f61; }
@media (max-width: 640px) { }
.tog-mini .dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; opacity: 0.6; }
.tog-mini.on .dot { opacity: 1; }
/* Film style v2 — design polish */
.main:has(.fsv2) { width: min(1560px, calc(100% - 2rem)); }
.main:has(.fsv2) .wizard { grid-template-columns: minmax(0, 1fr) 360px; }
.fsv2-wip-banner { display: flex; align-items: flex-start; gap: 16px; background: #faf6ee; border: 1px solid rgba(120, 100, 70, 0.16); }
.fsv2-wip-icon { flex-shrink: 0; width: 46px; height: 46px; border-radius: 50%; background: rgba(96, 115, 101, 0.1); display: inline-flex; align-items: center; justify-content: center; }
.fsv2-wip-icon img { width: 60%; height: 60%; object-fit: contain; }
.fsv2-wip-text { display: flex; flex-direction: column; gap: 3px; }
.fsv2-look-label { font-size: 0.74rem; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; color: var(--muted, #7c766c); margin: 0 0 9px; }
.fsv2-builder-callout { display: flex; align-items: center; gap: 14px; width: 100%; text-align: left; background: #eef3ea; border: 1px solid rgba(96, 115, 101, 0.22); border-radius: 12px; padding: 12px 16px; cursor: pointer; font: inherit; margin-top: 14px; }
.fsv2-builder-icon { flex-shrink: 0; width: 40px; height: 40px; border-radius: 50%; background: rgba(96, 115, 101, 0.13); display: inline-flex; align-items: center; justify-content: center; }
.fsv2-builder-icon img { width: 60%; height: 60%; object-fit: contain; }
.fsv2-builder-text { display: flex; flex-direction: column; gap: 2px; }
.fsv2-builder-text strong { font-weight: 600; color: var(--ink); }
.fsv2-builder-text > span { font-size: 0.85rem; color: var(--muted, #7c766c); }

/* ============================================================
   Draft (Step 8) page redesign
   ============================================================ */
.main:has(.draft-hero) { width: min(1560px, calc(100% - 2rem)); position: relative; }
.main:has(.draft-hero) .wizard { grid-template-columns: minmax(0, 1fr) 360px; }
/* The inline rough-cut IS the live slideshow now (auto-advance + ‹ › arrows +
   real transitions), so show its own controls and keep them visible for
   discoverability. The old center-play/bottom-bar video chrome was removed. */
.draft-player-frame .draft-cinema-toggle { display: none !important; }
.draft-player-frame-slideshow .slideshow-controls { opacity: 1; }
/* Inline rough-cut slideshow is a touch smaller than full width, centered. */
.draft-player-frame-slideshow { max-width: 78%; margin-left: auto; margin-right: auto; }
/* Draft (review) tab — embedded full player inside a dark cinema container so
   the cream fullscreen-style controls read against a light page. */
.review-player { max-width: 900px; margin: 0.5rem auto 0.2rem; background: #1b1510; border-radius: 16px; padding: 0.75rem 0.9rem 0.9rem; box-shadow: 0 12px 34px rgba(0, 0, 0, 0.22); }
.review-player .draft-cinema { box-shadow: none; }
.review-player-controls { margin-top: 0.7rem; }
.review-player-preparing { color: #cdbfa8; text-align: center; margin: 0.9rem 0 0.4rem; font-size: 0.9rem; }

/* Build stamp — quiet enough to ship, legible enough to quote in a bug report. */
.lm-buildstamp {
  margin: 2rem 0 .75rem; text-align: center;
  font-size: .68rem; letter-spacing: .04em; color: var(--muted); opacity: .55;
  font-variant-numeric: tabular-nums; user-select: all;
}


/* ── Who-tab re-audit: name warning, pronoun preview, picker floor note ─────
   The name note is amber, not red: the name is not invalid, it just would not
   look the way the family expects on the card. */
.f3-name-warn {
  margin: .4rem 0 0; padding: .5rem .65rem; border-radius: 8px;
  background: #f6ecd9; color: #7a4a0e; font-size: .82rem; line-height: 1.4;
  border: 1px solid rgba(154, 90, 18, .22);
}
.f3-name-warn[hidden] { display: none; }
[data-f3-pron-preview] { font-style: normal; color: var(--ink); }
[data-f3-pron-blank][hidden] { display: none; }
/* The wall a family hits at the start of the range, explained where they hit it. */
.f3-dp-floor {
  margin: .1rem .75rem .6rem; font-size: .76rem; line-height: 1.4; color: var(--muted);
  text-align: center;
}
/* W-audit — text inputs measured 43px; the date buttons and the nickname switch
   were already 44. One line makes the whole step consistent. */
.wiz-input { min-height: 44px; }
.f3nick-chip[disabled] { opacity: .55; cursor: default; }


/* ── FB3/FH10: the way back from a skipped restoration ──────────────────────
   Sits directly under the master switch, because it is the control families
   reach for when the master switch turns out not to be the inverse they
   assumed. Quiet, not alarming — skipping restoration is a legitimate choice
   and this is an offer, not a correction. */
.f3-runskip { border-color: rgba(95, 113, 101, .34); }
.f3-runskip-strip {
  display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .85rem;
}
.f3-runskip-thumb {
  position: relative; width: 76px; height: 76px; padding: 0; cursor: pointer;
  border: 1px solid var(--line-strong); border-radius: 10px; overflow: hidden;
  background: var(--paper-2); flex: none;
}
.f3-runskip-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; opacity: .72; transition: opacity .15s; }
.f3-runskip-thumb:hover img, .f3-runskip-thumb:focus-visible img { opacity: 1; }
/* Always visible: a row of dimmed thumbnails reads as decoration, and the
   per-photo route is the whole reason this is not just a bulk button. */
.f3-runskip-badge {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 3px 0;
  font-size: .68rem; font-weight: 600; letter-spacing: .02em; text-align: center;
  color: #f3ead8; background: rgba(30, 22, 18, .74);
}
.f3-runskip-thumb:focus-visible { outline: 3px solid var(--accent, #764239); outline-offset: 2px; }
@media (hover: none) { .f3-runskip-thumb img { opacity: 1; } }
@media (max-width: 600px) {
  .f3-runskip-thumb { width: 64px; height: 64px; }
}


/* ── FH2/FH3 the film's own facts, and FH8's pre-purchase review ────────────
   FH2/FH3 — the one line that says how long the film runs and how many photos
   are in it, directly under the preview it describes.
   FH8 — the review card above the price. Deliberately quiet: sage, not red. A
   family has not done anything wrong by skipping restoration or choosing
   silence; this is a last chance to notice, not a warning. */
.f3-filmspec {
  max-width: 900px; margin: .5rem auto 0; text-align: center;
  font-size: .85rem; line-height: 1.45; color: #6b5a45;
}
.f3-filmspec .text-link { font-size: inherit; }
.f3-preflight { border-color: rgba(95, 113, 101, .38); background: linear-gradient(180deg, rgba(95,113,101,.05), transparent 60%); }
.f3-preflight-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .55rem; }
.f3-preflight-list li {
  display: flex; align-items: baseline; justify-content: space-between; gap: .9rem;
  padding: .6rem .75rem; border-radius: 10px; background: var(--paper-2);
  border: 1px solid var(--line); font-size: .9rem; line-height: 1.45; color: var(--ink);
}
.f3-preflight-list li > span { flex: 1 1 auto; min-width: 0; }
.f3-preflight-list .text-link { flex: none; white-space: nowrap; }
@media (max-width: 600px) {
  .f3-preflight-list li { flex-direction: column; align-items: flex-start; gap: .35rem; }
  .f3-filmspec { font-size: .82rem; }
}


/* ── Finish-step preview: FH4 full screen, FH5 soundtrack row, FM1/FM3 phones ──
   FM1 — at 390px the scrub bar was squeezed to about 165px between a 42px
   button and an 86px timecode: a fiddly target for an unsteady hand. On phones
   the bar now takes a full-width row of its own with a taller track.
   FM3 — and the player itself was eating most of the first screen, so nothing
   below it hinted there was anything below it. Cap the stage and tighten the
   chrome so the first choice card peeks above the fold.
   FH4 — .is-immersive is the full-screen view: the same element, the same live
   canvas and controller, promoted to cover the viewport. No second player, no
   second [data-draft-cinema-fs] host for setupDraftCinema() to pick wrong. */
.review-player-music {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  margin-top: .55rem; padding-top: .5rem;
  border-top: 1px solid rgba(231, 220, 200, 0.14);
}
.review-player-track {
  flex: 1 1 auto; min-width: 0; color: #cdbfa8; font-size: .82rem; line-height: 1.35;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.review-player-mute, .review-player-changemusic {
  flex: none; cursor: pointer; font: inherit; font-size: .78rem; font-weight: 600;
  padding: .4rem .7rem; min-height: 34px; border-radius: 999px;
  border: 1px solid rgba(231, 220, 200, 0.28); background: transparent; color: #e7dcc8;
}
.review-player-mute:hover, .review-player-changemusic:hover { background: rgba(231, 220, 200, 0.12); }
.review-player-mute.is-muted { background: rgba(231, 220, 200, 0.9); color: #1b1510; border-color: transparent; }
.review-player-mute:focus-visible, .review-player-changemusic:focus-visible,
.cinema-fs-full:focus-visible, .review-player-exit:focus-visible {
  outline: 2px solid #e7dcc8; outline-offset: 2px;
}
.cinema-fs-full span { font-size: 1rem; line-height: 1; }

/* FH4 — full-screen view.
   The animation/transform reset is load-bearing: .wiz-anim's entrance puts a
   transform on every direct child of the step, and a transformed ancestor makes
   position:fixed resolve against IT instead of the viewport. The toggle can't
   fire mid-animation today, but a future step animation shouldn't be able to
   quietly break full screen either. */
.review-player.is-immersive {
  position: fixed; inset: 0; z-index: 90; max-width: none; margin: 0;
  border-radius: 0; background: #0e0b09;
  display: flex; flex-direction: column; justify-content: center;
  padding: 3vmin 4vmin calc(3vmin + env(safe-area-inset-bottom, 0px));
  animation: none !important; transform: none !important;
}
.review-player.is-immersive .review-player-stage { max-width: calc(74vh * 16 / 9); margin-left: auto; margin-right: auto; }
.review-player.is-immersive .review-player-controls { margin-top: 1rem; }
.review-player-exit {
  position: absolute; top: 14px; right: 16px; z-index: 2;
  width: 44px; height: 44px; border-radius: 50%; border: none; cursor: pointer;
  background: rgba(60, 48, 36, 0.75); color: #f3ead8; font-size: 1.6rem; line-height: 1;
}

/* FM1 + FM3 — phones */
@media (max-width: 600px) {
  .cinema-fs-controls { flex-wrap: wrap; gap: 8px 10px; }
  .cinema-fs-controls .cinema-fs-scrub {
    order: 10; flex: 1 0 100%; padding: 13px 0;
  }
  .cinema-fs-controls .cinema-fs-time { flex: 1 1 auto; }
  .cinema-fs-scrub-track { height: 8px; border-radius: 4px; }
  .cinema-fs-scrub-fill { border-radius: 4px; }
  .cinema-fs-scrub-fill::after { width: 20px; height: 20px; right: -10px; }
  .review-player { padding: .5rem .55rem .65rem; border-radius: 12px; margin-top: .25rem; }
  .review-player-controls { margin-top: .5rem; }
  /* Cap by WIDTH, not height: .draft-cinema keeps its 16/9 aspect-ratio, and a
     max-height would leave the width at 100% and stretch the canvas. Also cap
     it as a share of the column so the film stays the biggest thing on the
     screen without being the ONLY thing on it. */
  .review-player-stage { max-width: min(78%, calc(30vh * 16 / 9)); margin-left: auto; margin-right: auto; }
  /* FM3 — the Finish step's header runs to ~313px on a 390px phone, and THAT
     is what actually pushed the timing and price choices off the first screen.
     It is the last step's header, not the first's: it doesn't need the full
     ceremonial spacing above the thing the family came here to watch. */
  .f3-watch-head .wiz-head { margin-bottom: 1rem; }
  .f3-watch-head .f3-startover { padding: .35rem .7rem; font-size: .78rem; }
  /* The autosave reassurance has been shown on all six previous steps, so on
     phones it goes to screen readers only — the [data-f3-savestate] live
     region inside it still announces. */
  .f3-watch-head .f3-savenote {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
  }
  .review-player-music { margin-top: .45rem; padding-top: .45rem; }
  /* Keeps the soundtrack name on ONE line with Mute and Change music. The
     flex-basis matters: wrapping is decided from hypothetical sizes, so an
     `auto` basis put each control on its own line (86px of chrome) no matter
     what min-width said. Basis 0 lets the title ellipsis instead (FM3). */
  .review-player-track { white-space: nowrap; flex-basis: 0; }
  .review-player.is-immersive { padding: 2vmin 3vmin calc(2vmin + env(safe-area-inset-bottom, 0px)); }
  .review-player.is-immersive .review-player-stage { max-width: calc(60vh * 16 / 9); }
}

/* Caption below the preview — tells the family the arrows step through and
   preview each transition. */
.draft-slideshow-hint { max-width: 78%; margin: 0.6rem auto 0; text-align: center; font-size: 0.85rem; line-height: 1.4; color: #6b5a45; }
.draft-slideshow-hint .dsh-arrows { display: inline-flex; align-items: center; justify-content: center; letter-spacing: 0.12em; font-weight: 600; color: #5f7165; margin-right: 0.15rem; }

/* ============================================================
   Consistent decorative leaf on EVERY create-film step header.
   (Same watercolor branch used on Who / Photos / Legacy Map.)
   ============================================================ */
.main:has(.wizard) { position: relative; }
.main:has(.wizard)::before {
  content: ""; position: absolute; left: -155px; top: 18px; width: 250px; height: 360px;
  background: url(/icons/photos-left-branch.png?v=1) no-repeat left top / contain;
  opacity: 0.4; pointer-events: none; z-index: 0;
}
.main:has(.wizard) > * { position: relative; z-index: 1; }

/* Sticky sidebar stack for the create-film wizard. */
.wizard > .side-panel { position: sticky; top: 1.25rem; align-self: start; }

/* Draft content spans the full panel (override the old 920px centering). */
.draft-hero, .draft-secondary, .draft-actions { max-width: none; }

/* Hero card — soft cream, not a dark screening mat. */
.draft-hero {
  background: var(--paper);
  border: 1px solid var(--line);
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.04);
  padding: 1.5rem 1.5rem 1.6rem;
}

/* Rough-cut header — left-aligned, clapperboard, badge. */
.draft-rough-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; margin-bottom: 0.6rem; }
.drh-left { display: flex; gap: 0.85rem; align-items: flex-start; }
.drh-icon { flex-shrink: 0; width: 42px; height: 42px; border-radius: 12px; background: rgba(95, 113, 101, 0.1); display: inline-flex; align-items: center; justify-content: center; }
.drh-icon img { width: 55%; height: 55%; object-fit: contain; }
.draft-rough-header .draft-hero-title { font-size: 1.3rem; margin: 0 0 0.12rem; text-align: left; }
.draft-rough-header .draft-hero-subtitle { max-width: 62ch; font-size: 0.9rem; line-height: 1.4; }
.drh-badge { flex-shrink: 0; display: inline-flex; align-items: center; gap: 0.4rem; padding: 0.38rem 0.8rem; background: #eef3ea; border: 1px solid rgba(95, 113, 101, 0.25); border-radius: 999px; font-size: 0.78rem; font-weight: 600; color: #4f5f52; white-space: nowrap; }
.drh-badge-ico { width: 14px; height: 14px; background-color: #5f7165; -webkit-mask: url(/icons/draft-shield.png?v=1) center/contain no-repeat; mask: url(/icons/draft-shield.png?v=1) center/contain no-repeat; }

/* Player frame — soft rounded, control bar overlay, center play. */
.draft-player-frame { position: relative; border-radius: 14px; }
.draft-player-frame .draft-cinema { box-shadow: 0 10px 30px rgba(0, 0, 0, 0.18); }
.draft-player-frame .draft-cinema-loader { background: #efe7d8; color: #5a4a35; }
.draft-player-frame .draft-cinema-spinner { border-color: rgba(90, 74, 53, 0.22); border-top-color: #8a6b3a; }

/* Stat cards. */
.draft-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.75rem; margin-top: 0.55rem; }
.draft-stat-card { display: flex; align-items: center; gap: 0.7rem; padding: 0.55rem 0.85rem; background: var(--paper); border: 1px solid var(--line); border-radius: 12px; }
.draft-stat-ico { width: 22px; height: 22px; flex-shrink: 0; background-color: #5f7165; }
.draft-stat-ico-scenes { -webkit-mask: url(/icons/draft-stat-scenes.png?v=1) center/contain no-repeat; mask: url(/icons/draft-stat-scenes.png?v=1) center/contain no-repeat; }
.draft-stat-ico-runtime { -webkit-mask: url(/icons/draft-stat-runtime.png?v=1) center/contain no-repeat; mask: url(/icons/draft-stat-runtime.png?v=1) center/contain no-repeat; }
.draft-stat-ico-photos { -webkit-mask: url(/icons/draft-stat-photos.png?v=1) center/contain no-repeat; mask: url(/icons/draft-stat-photos.png?v=1) center/contain no-repeat; }
.draft-stat-ico-restore { -webkit-mask: url(/icons/draft-stat-restore.png?v=1) center/contain no-repeat; mask: url(/icons/draft-stat-restore.png?v=1) center/contain no-repeat; }
.draft-stat-body { display: flex; flex-direction: column; min-width: 0; }
.draft-stat-label { font-size: 0.64rem; letter-spacing: 0.07em; text-transform: uppercase; color: var(--muted); font-weight: 600; }
.draft-stat-value { font-size: 1.15rem; font-weight: 600; color: var(--ink); font-family: "Cormorant Garamond", Georgia, serif; }
.draft-stat-restoration { background: #fbf3e2; border-color: rgba(180, 140, 60, 0.32); }
.draft-stat-restoration .draft-stat-ico { background-color: #b8860b; }
.draft-stat-restoration .draft-stat-value { color: #8a6a1f; }

/* Pre-restoration info strip. */
.draft-info-strip { position: relative; overflow: hidden; display: flex; align-items: center; gap: 0.7rem; margin-top: 1rem; padding: 0.85rem 1.1rem; padding-right: 120px; background: #f4f6f1; border: 1px solid rgba(95, 113, 101, 0.16); border-radius: 12px; }
.dis-icon { flex-shrink: 0; width: 18px; height: 18px; background-color: #5f7165; -webkit-mask: url(/icons/draft-info.png?v=1) center/contain no-repeat; mask: url(/icons/draft-info.png?v=1) center/contain no-repeat; }
.draft-info-strip p { margin: 0; font-size: 0.85rem; color: var(--body); line-height: 1.45; }
.dis-sprig { position: absolute; right: 8px; bottom: -8px; width: 96px; opacity: 0.8; pointer-events: none; }

/* How the film flows header. */
.draft-flow-header { display: flex; align-items: center; gap: 0.7rem; margin: 1.7rem 0 0.5rem; }
.draft-flow-ico { flex-shrink: 0; width: 24px; height: 24px; background-color: #5f7165; -webkit-mask: url(/icons/draft-sliders.png?v=1) center/contain no-repeat; mask: url(/icons/draft-sliders.png?v=1) center/contain no-repeat; }
.draft-flow-title { font-family: "Cormorant Garamond", Georgia, serif; font-size: 1.5rem; font-weight: 600; margin: 0; color: var(--ink); }
.draft-flow-sub { margin: 0.1rem 0 0; font-size: 0.88rem; color: var(--body); }

/* Transition selector — icon grid. */
.draft-transition-head { display: flex; flex-direction: row; align-items: flex-start; gap: 0.6rem; }
.draft-transition-ico { flex-shrink: 0; width: 22px; height: 22px; margin-top: 2px; background-color: #5f7165; -webkit-mask: url(/icons/draft-sparkle.png?v=1) center/contain no-repeat; mask: url(/icons/draft-sparkle.png?v=1) center/contain no-repeat; }
.draft-transition-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.6rem; margin-top: 0.3rem; }
@media (min-width: 900px) { .draft-transition-grid { grid-template-columns: repeat(6, 1fr); } }
.draft-transition-cell { display: flex; flex-direction: column; align-items: center; gap: 0.45rem; padding: 0.85rem 0.5rem; background: var(--paper); border: 1px solid var(--line); border-radius: 12px; cursor: pointer; font: inherit; transition: border-color 0.14s ease, background 0.14s ease, box-shadow 0.14s ease; }
.draft-transition-cell:hover { border-color: var(--sage); }
.draft-transition-cell.active { background: #eef3ea; border-color: var(--sage); box-shadow: inset 0 0 0 1px var(--sage); }
.draft-transition-cell.wide { grid-column: span 3; flex-direction: row; justify-content: center; gap: 0.6rem; }
/* Fine-tune slider(s) for Page Roll / Book Turn drop in directly under the tile
   row, full width, with an up-caret pointing at the selected tile. */
.transition-inline-controls { grid-column: 1 / -1; position: relative; display: flex; flex-wrap: wrap; align-items: center; gap: 10px 24px; margin: 4px 0 2px; padding: 0.7rem 0.95rem; background: #eef3ea; border: 1px solid var(--sage); border-radius: 12px; }
.transition-inline-controls::before { content: ""; position: absolute; top: -6px; left: var(--caret-left, 50%); transform: translateX(-50%) rotate(45deg); width: 11px; height: 11px; background: #eef3ea; border-left: 1px solid var(--sage); border-top: 1px solid var(--sage); }
.transition-inline-controls .trans-slider-row { flex: 1 1 220px; min-width: 170px; }
.dtc-ico { width: 30px; height: 30px; background-size: contain; background-repeat: no-repeat; background-position: center; flex-shrink: 0; }
.dtc-ico-cross-fade { background-image: url(/icons/draft-trans-crossfade.png?v=1); }
.dtc-ico-fade-background { background-image: url(/icons/draft-trans-fade.png?v=1); }
.dtc-ico-zoom-dissolve { background-image: url(/icons/draft-trans-zoom.png?v=1); }
.dtc-ico-page-turn { background-image: url(/icons/draft-trans-pageflip.png?v=1); }
.dtc-ico-page-roll { background-image: url(/icons/draft-trans-pageroll.png?v=1); }
.dtc-ico-book-turn { background-image: url(/icons/draft-trans-bookturn.png?v=1); }
.dtc-ico-life-scroll-h { background-image: url(/icons/draft-trans-scrollh.png?v=1); }
.dtc-ico-life-scroll-v { background-image: url(/icons/draft-trans-scrollv.png?v=1); }
.dtc-label { font-size: 0.8rem; color: var(--body); text-align: center; line-height: 1.2; }
.draft-transition-cell.active .dtc-label { color: var(--ink); font-weight: 600; }

/* Icon-led card headers (Timing, Film at a glance). */
.draft-icon-head { display: flex; align-items: flex-start; gap: 0.6rem; }
.draft-head-ico { flex-shrink: 0; width: 22px; height: 22px; margin-top: 2px; background-color: #5f7165; }
.draft-head-clock { -webkit-mask: url(/icons/draft-clock.png?v=1) center/contain no-repeat; mask: url(/icons/draft-clock.png?v=1) center/contain no-repeat; }
.draft-head-eye { -webkit-mask: url(/icons/draft-eye.png?v=1) center/contain no-repeat; mask: url(/icons/draft-eye.png?v=1) center/contain no-repeat; }

/* Music glyph → note icon. */
.draft-music-glyph.draft-music-glyph-ico { display: inline-flex; align-items: center; justify-content: center; font-size: 0; }
.draft-music-glyph.draft-music-glyph-ico::after { content: ""; width: 15px; height: 15px; background-color: #5f7165; -webkit-mask: url(/icons/draft-music-note.png?v=1) center/contain no-repeat; mask: url(/icons/draft-music-note.png?v=1) center/contain no-repeat; }

/* Tip strip. */
.draft-tip-strip { position: relative; overflow: hidden; display: flex; align-items: center; gap: 0.7rem; margin-top: 1rem; padding: 0.85rem 1.1rem; padding-right: 120px; background: #f4f6f1; border: 1px solid rgba(95, 113, 101, 0.16); border-radius: 12px; }
.dts-icon { flex-shrink: 0; width: 18px; height: 18px; background-color: #5f7165; -webkit-mask: url(/icons/draft-info.png?v=1) center/contain no-repeat; mask: url(/icons/draft-info.png?v=1) center/contain no-repeat; }
.draft-tip-strip p { margin: 0; font-size: 0.85rem; color: var(--body); line-height: 1.45; }
.dts-sprig { position: absolute; right: 8px; bottom: -8px; width: 96px; opacity: 0.8; pointer-events: none; }

/* Cost panel sparkle + wider. */
.draft-cost-panel { position: relative; margin-top: 1rem; }
.draft-cost-sparkle { position: absolute; top: 12px; right: 14px; width: 20px; height: 20px; background-color: #5f7165; opacity: 0.5; -webkit-mask: url(/icons/draft-sparkle.png?v=1) center/contain no-repeat; mask: url(/icons/draft-sparkle.png?v=1) center/contain no-repeat; }

/* Draft promise card — two heart bullets + flower sprig. */
.promise-card-draft .promise-list { list-style: none; margin: 0.4rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 0.55rem; }
.promise-card-draft .promise-list li { display: flex; align-items: flex-start; gap: 0.5rem; font-size: 0.9rem; color: var(--body); line-height: 1.4; position: relative; z-index: 1; }
.promise-card-draft .promise-list .promise-heart { margin: 0.1rem 0 0; flex-shrink: 0; }
.promise-card-draft .promise-flower { width: 118px !important; height: auto !important; }

/* Bottom nav — spacing. */
.draft-actions { display: flex; gap: 0.75rem; margin-top: 1.2rem; }
.draft-actions .primary-btn { margin-left: auto; }

@media (max-width: 820px) {
  .draft-stats { grid-template-columns: repeat(2, 1fr); }
  .draft-rough-header { flex-direction: column; }
  .main:has(.draft-hero)::before { display: none; }
}

/* ============================================================
   Restoration — active batch (in-progress) state
   ============================================================ */
.main:has(.restoration-progress-shell) { width: min(1560px, calc(100% - 2rem)); }
.main:has(.restoration-progress-shell) .wizard { grid-template-columns: minmax(0, 1fr) 360px; align-items: start; }
.restoration-progress-shell { display: block; padding: 1.4rem 1.5rem; }

/* What's happening 3-column summary */
.whats-happening { margin-bottom: 1.2rem; }
.wh-title { margin: 0 0 0.9rem; font-size: 1.05rem; }
.wh-grid { display: grid; grid-template-columns: repeat(3, 1fr); }
.wh-item { display: flex; align-items: center; gap: 0.7rem; padding: 0 1.2rem; }
.wh-item + .wh-item { border-left: 1px solid rgba(120, 100, 70, 0.14); }
.wh-item:first-child { padding-left: 0; }
.wh-ico { flex: 0 0 auto; width: 44px; height: 44px; }
.wh-ico img { width: 100%; height: 100%; object-fit: contain; }
.wh-text { display: flex; flex-direction: column; min-width: 0; }
.wh-text strong { font-size: 0.9rem; color: var(--ink); }
.wh-text span { font-size: 0.8rem; color: var(--body); line-height: 1.35; }

/* Batch progress card (green) */
.restoration-progress-card { background: #faf5ea; border: 1px solid rgba(120, 100, 70, 0.14); border-radius: 12px; padding: 1rem 1.2rem; margin-bottom: 1.2rem; }
.rpc-head strong { font-size: 0.98rem; color: var(--ink); }
.rpc-sub { margin: 0.2rem 0 0.7rem; font-size: 0.84rem; color: var(--body); }
.rpc-bar-row { display: flex; align-items: center; gap: 0.85rem; }
.rpc-track { flex: 1 1 auto; height: 8px; border-radius: 5px; background: rgba(95, 113, 101, 0.18); overflow: hidden; }
.rpc-fill { height: 100%; background: #46604f; border-radius: 5px; transition: width 0.3s ease; }
.rpc-pct { font-size: 0.85rem; font-weight: 600; color: #46604f; font-variant-numeric: tabular-nums; }

/* Compact photo cards */
.restoration-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
.restoration-tile-v2 { border: 1px solid rgba(120, 100, 70, 0.14); border-radius: 12px; padding: 0.9rem; background: var(--paper); display: flex; flex-direction: column; gap: 0.7rem; }
.restoration-tile-head { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; }
.rt-name { font-size: 0.9rem; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.rt-badge { flex-shrink: 0; font-size: 0.64rem; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; padding: 0.26rem 0.62rem; border-radius: 999px; white-space: nowrap; }
.rt-badge-restoring { background: #f3ecdb; color: #8a6b3a; }
.rt-badge-restored { background: #e6efe4; color: #3c5344; }
.rt-badge-failed { background: #f6e4e0; color: #a5453a; }
.rt-badge-queued { background: #eee9df; color: #7a6f5a; }
.restoration-tile-v2 .ba-slider,
.restoration-tile-v2 .restoration-tile-state { border-radius: 10px; overflow: hidden; }
.restoration-tile-v2 .ba-label { text-transform: uppercase; letter-spacing: 0.05em; font-size: 0.66rem; }

.rt-finished { display: flex; align-items: center; gap: 0.45rem; font-size: 0.85rem; color: #3c5344; font-weight: 600; margin-bottom: 0.55rem; }
.rt-check { width: 18px; height: 18px; border-radius: 50%; background: #46604f; position: relative; flex-shrink: 0; }
.rt-check::after { content: ""; position: absolute; left: 6px; top: 4px; width: 4px; height: 8px; border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg); }
.rt-buttons { display: flex; gap: 0.5rem; }
.rt-rerun { flex: 1 1 auto; padding: 0.55rem 0.7rem; font-size: 0.85rem; }
.rt-keep { flex: 1 1 auto; border: 0; border-radius: 9px; background: #46604f; color: #fff; font: inherit; font-weight: 600; font-size: 0.85rem; padding: 0.55rem 0.8rem; cursor: pointer; transition: background 0.15s ease; }
.rt-keep:hover { background: #3c5344; }
.rt-status-copy { margin: 0 0 0.5rem; font-size: 0.84rem; color: var(--body); }
.rt-mini-track { height: 6px; border-radius: 4px; background: rgba(95, 113, 101, 0.18); overflow: hidden; }
.rt-mini-fill { height: 100%; width: 55%; background: #46604f; border-radius: 4px; animation: rt-mini 1.6s ease-in-out infinite; }
@keyframes rt-mini { 0% { width: 22%; } 50% { width: 75%; } 100% { width: 22%; } }
.restoration-back-row { margin-top: 1.1rem; }

@media (max-width: 760px) {
  .restoration-grid { grid-template-columns: 1fr; }
  .wh-grid { grid-template-columns: 1fr; gap: 0; }
  .wh-item { padding: 0.6rem 0; }
  .wh-item + .wh-item { border-left: 0; border-top: 1px solid rgba(120, 100, 70, 0.14); }
}

/* Restoration tile — completed review choices (Use original / Remove) */
.rt-finished-alt { color: #6b5a3a; }
.rt-finished-warn { color: #a5453a; }
.rt-dot { width: 9px; height: 9px; border-radius: 50%; background: currentColor; flex-shrink: 0; }
.rt-alt-choices { display: flex; gap: 0.5rem; margin-top: 0.6rem; padding-top: 0.6rem; border-top: 1px solid rgba(120, 100, 70, 0.12); }
.rt-alt {
  flex: 1 1 auto; font: inherit; font-size: 0.8rem; font-weight: 500;
  padding: 0.45rem 0.6rem; border-radius: 8px; cursor: pointer;
  border: 1px solid var(--line); background: var(--paper); color: var(--body);
  transition: border-color 0.14s ease, background 0.14s ease, color 0.14s ease;
}
.rt-alt:hover { border-color: var(--sage); color: var(--ink); }
.rt-alt.active { background: rgba(95, 113, 101, 0.12); border-color: var(--sage); color: #3c5344; font-weight: 600; }
/* When an alternative is chosen, soften the "Keep this version" emphasis. */
.restoration-tile-v2.is-original-chosen .rt-keep,
.restoration-tile-v2.is-removed .rt-keep { background: #e6efe4; color: #3c5344; }
.restoration-tile-v2.is-removed .ba-slider,
.restoration-tile-v2.is-removed .restoration-tile-state { opacity: 0.5; filter: grayscale(0.4); }
.restoration-tile-v2.is-removed .rt-badge-restored { background: #f6e4e0; color: #a5453a; }

/* ============================================================
   Resolution (Step 11) — focused before/after review
   ============================================================ */
.main:has(.reso-review-card) { width: min(1560px, calc(100% - 2rem)); }
.main:has(.reso-review-card) .wizard { grid-template-columns: minmax(0, 1fr) 360px; align-items: start; }

/* Trust panel */
.reso-trust { display: grid; grid-template-columns: repeat(3, 1fr); background: #f4f1e9; border: 1px solid rgba(120, 100, 70, 0.14); border-radius: 14px; padding: 1rem 0.4rem; margin-bottom: 1rem; }
.reso-trust-item { display: flex; align-items: center; gap: 0.7rem; padding: 0 1.2rem; }
.reso-trust-item + .reso-trust-item { border-left: 1px solid rgba(120, 100, 70, 0.16); }
.reso-trust-ico { flex: 0 0 auto; width: 42px; height: 42px; }
.reso-trust-ico img { width: 100%; height: 100%; object-fit: contain; }
.reso-trust-text { display: flex; flex-direction: column; min-width: 0; }
.reso-trust-text strong { font-size: 0.9rem; color: var(--ink); }
.reso-trust-text span { font-size: 0.79rem; color: var(--body); line-height: 1.35; }

/* Review card */
.reso-review-card { display: block; padding: 1.4rem 1.5rem; }
.reso-review-grid { display: grid; grid-template-columns: 280px minmax(0, 1fr); gap: 1.6rem; align-items: start; }

/* Left info column */
.reso-eyebrow { display: flex; align-items: center; gap: 0.5rem; margin: 0 0 0.4rem; font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase; font-weight: 700; color: #a5894f; }
.reso-eye-ico { width: 18px; height: 14px; background-color: #a5894f; -webkit-mask: url(/icons/reso-eye.png?v=1) center/contain no-repeat; mask: url(/icons/reso-eye.png?v=1) center/contain no-repeat; }
.reso-review-sub { margin: 0 0 0.9rem; font-size: 0.86rem; color: var(--body); line-height: 1.45; }
.reso-tip { background: #faf5ea; border: 1px solid rgba(120, 100, 70, 0.16); border-radius: 10px; padding: 0.7rem 0.85rem; font-size: 0.8rem; color: #6b5a3a; line-height: 1.45; margin-bottom: 1.1rem; }
.reso-progress-line { display: flex; align-items: center; gap: 0.45rem; font-size: 0.82rem; color: var(--body); margin: 0.5rem 0 0.4rem; }
.reso-clock-ico { width: 15px; height: 15px; flex-shrink: 0; background-color: #8a7a5a; -webkit-mask: url(/icons/reso-clock.png?v=1) center/contain no-repeat; mask: url(/icons/reso-clock.png?v=1) center/contain no-repeat; }
.reso-progress-track { height: 7px; border-radius: 5px; background: rgba(95, 113, 101, 0.18); overflow: hidden; margin-bottom: 0.5rem; }
.reso-progress-fill { height: 100%; background: #46604f; border-radius: 5px; transition: width 0.3s ease; }
.reso-alldone { font-size: 0.82rem; color: var(--body); margin: 0.4rem 0 0; }
.reso-stop { margin-top: 0.5rem; }

/* Bulk apply-to-all */
.reso-bulk { margin-top: 1.1rem; padding-top: 1rem; border-top: 1px solid rgba(120, 100, 70, 0.14); }
.reso-bulk-label { display: block; font-size: 0.72rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); font-weight: 600; margin-bottom: 0.5rem; }
.reso-bulk-btns { display: flex; flex-direction: column; gap: 0.45rem; }
.reso-bulk-btn { font: inherit; font-size: 0.83rem; font-weight: 500; padding: 0.5rem 0.7rem; border: 1px solid var(--line); background: var(--paper); color: var(--body); border-radius: 9px; cursor: pointer; transition: border-color 0.14s ease, background 0.14s ease, color 0.14s ease; }
.reso-bulk-btn:hover { border-color: var(--sage); color: var(--ink); background: rgba(95, 113, 101, 0.06); }

/* Featured comparison */
.reso-review-main { min-width: 0; }
.reso-feature { position: relative; border-radius: 12px; overflow: hidden; background: #f2efe8; border: 1px solid rgba(120, 100, 70, 0.14); height: min(460px, 56vh); }
.reso-feature .ba-slider { border-radius: 12px; aspect-ratio: auto !important; height: 100% !important; width: 100% !important; background: #f2efe8 !important; }
.reso-feature .ba-img { object-fit: contain !important; background: #f2efe8; }
.reso-feature .ba-label { display: none; }
.reso-feature-single { aspect-ratio: auto !important; height: min(460px, 56vh); }
.reso-feature-single img { width: 100%; height: 100%; object-fit: contain; display: block; }
.reso-feature-overlay { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.6rem; background: rgba(20, 15, 10, 0.5); color: #f3ead8; font-size: 0.85rem; }
.reso-feature-cta { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; }

.reso-corner { position: absolute; top: 10px; display: flex; gap: 6px; z-index: 4; }
.reso-corner-tl { left: 10px; }
.reso-corner-tr { right: 10px; }
.reso-cpill { font-size: 0.6rem; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; padding: 0.24rem 0.5rem; border-radius: 6px; white-space: nowrap; }
.reso-cpill.dark { background: rgba(25, 20, 15, 0.72); color: #fff; }
.reso-cpill.amber { background: #d9a441; color: #3a2c10; }
.reso-cpill.green { background: #46604f; color: #fff; }

/* Featured actions */
.reso-feature-actions { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; margin-top: 0.9rem; }
.reso-feat-file { display: flex; align-items: center; gap: 0.7rem; flex-wrap: wrap; min-width: 0; }
.reso-feat-file strong { font-size: 0.92rem; color: var(--ink); }
.reso-feat-dims { display: inline-flex; align-items: center; gap: 0.4rem; }
.reso-dim { font-size: 0.7rem; font-weight: 600; letter-spacing: 0.03em; text-transform: uppercase; padding: 0.22rem 0.5rem; border-radius: 999px; background: #f3ecdb; color: #8a6b3a; white-space: nowrap; }
.reso-dim-out { background: #e6efe4; color: #3c5344; }
.reso-arrow { color: var(--muted); font-size: 0.85rem; }
.reso-feat-btns { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.reso-rerun { padding: 0.5rem 0.75rem; font-size: 0.82rem; }
.reso-keep { display: inline-flex; align-items: center; gap: 0.4rem; border: 0; border-radius: 9px; background: #46604f; color: #fff; font: inherit; font-weight: 600; font-size: 0.84rem; padding: 0.55rem 0.9rem; cursor: pointer; transition: background 0.15s ease; }
.reso-keep:hover { background: #3c5344; }
.reso-keep.is-kept { box-shadow: 0 0 0 2px rgba(70, 96, 79, 0.28); }
.reso-keep-orig { border: 1px solid var(--line); border-radius: 9px; background: var(--paper); color: var(--body); font: inherit; font-weight: 500; font-size: 0.84rem; padding: 0.55rem 0.9rem; cursor: pointer; transition: border-color 0.14s ease, color 0.14s ease; }
.reso-keep-orig:hover { border-color: var(--sage); color: var(--ink); }
.reso-keep-orig.is-kept { background: rgba(95, 113, 101, 0.12); border-color: var(--sage); color: #3c5344; font-weight: 600; }
.reso-sparkle { width: 14px; height: 14px; background-color: currentColor; -webkit-mask: url(/icons/restore-sparkle.png?v=1) center/contain no-repeat; mask: url(/icons/restore-sparkle.png?v=1) center/contain no-repeat; }

/* Filmstrip — up to 7 photos + a "more"/"less" tile in one 8-slot row. */
.reso-strip { display: grid; grid-template-columns: repeat(8, minmax(0, 1fr)); gap: 10px; margin-top: 1.3rem; }
.reso-thumb { position: relative; width: 100%; border: 1px solid var(--line); border-radius: 10px; background: var(--paper); padding: 0; cursor: pointer; overflow: hidden; display: flex; flex-direction: column; transition: border-color 0.14s ease, box-shadow 0.14s ease; }
.reso-thumb.active { border-color: var(--sage); box-shadow: 0 0 0 2px rgba(95, 113, 101, 0.3); }
.reso-thumb-img { display: block; width: 100%; aspect-ratio: 1 / 1; overflow: hidden; }
.reso-thumb-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.reso-thumb-name { font-size: 0.72rem; color: var(--body); padding: 0.35rem 0.5rem 0.1rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: left; }
.reso-chip { align-self: flex-start; margin: 0 0.5rem 0.45rem; font-size: 0.58rem; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; padding: 0.2rem 0.45rem; border-radius: 999px; }
.reso-chip-enhanced { background: #e6efe4; color: #3c5344; }
.reso-chip-ready { background: #eef2ec; color: #55705c; }
.reso-chip-pending { background: #faeede; color: #a5762a; }
.reso-chip-sharpening { background: #f3ecdb; color: #8a6b3a; }
.reso-thumb-more { align-items: center; justify-content: center; gap: 0.2rem; min-height: 0; color: var(--muted); }
.reso-more-plus { font-size: 1.5rem; line-height: 1; color: var(--body); }
.reso-more-label { font-size: 0.74rem; color: var(--body); }

@media (max-width: 860px) {
  .reso-review-grid { grid-template-columns: 1fr; }
  .reso-trust { grid-template-columns: 1fr; gap: 0; }
  .reso-trust-item { padding: 0.6rem 0; }
  .reso-trust-item + .reso-trust-item { border-left: 0; border-top: 1px solid rgba(120, 100, 70, 0.16); }
  .reso-strip { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* Resolution — everything already sharp */
.main:has(.reso-allsharp-card) { width: min(1560px, calc(100% - 2rem)); }
.main:has(.reso-allsharp-card) .wizard { grid-template-columns: minmax(0, 1fr) 360px; align-items: start; }
.reso-allsharp-card { display: flex; align-items: center; gap: 1rem; }
.reso-allsharp-ico { flex: 0 0 auto; width: 46px; height: 46px; }
.reso-allsharp-ico img { width: 100%; height: 100%; object-fit: contain; }
.reso-allsharp-card h3 { margin: 0 0 0.2rem; }

/* Resolution — compact "skip upscaling" bar (top of page) */
.reso-skip-bar { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 1rem; padding: 0.6rem 0.9rem; background: var(--paper); border: 1px solid var(--line); border-radius: 10px; cursor: pointer; }
.reso-skip-bar input[type="checkbox"] { flex-shrink: 0; accent-color: var(--sage); width: 16px; height: 16px; margin: 0; }
.reso-skip-text { font-size: 0.85rem; color: var(--body); line-height: 1.4; }
.reso-skip-text strong { color: var(--ink); font-weight: 600; }
.reso-skip-text em { font-style: normal; color: var(--accent); font-weight: 600; }

/* Resolution — batch-in-progress states */
.reso-processing { display: inline-flex; align-items: center; gap: 0.5rem; font-size: 0.85rem; font-weight: 600; color: #46604f; }
.reso-processing-dot { width: 16px; height: 16px; border-radius: 50%; border: 2.5px solid rgba(70, 96, 79, 0.25); border-top-color: #46604f; animation: lm-comp-spin 0.9s linear infinite; }
.reso-thumb-spin { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; background: rgba(30, 24, 16, 0.42); }
.reso-thumb-spin .restoration-tile-spinner { width: 22px; height: 22px; }
.reso-chip-sharpening { animation: reso-chip-pulse 1.3s ease-in-out infinite; }
@keyframes reso-chip-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }

/* Resolution — Keep this version / Keep original as a clear toggle
   (only the selected one is filled green). */
.reso-choice-btn { border: 1px solid var(--line); border-radius: 9px; background: var(--paper); color: var(--body); font: inherit; font-weight: 600; font-size: 0.84rem; padding: 0.55rem 0.9rem; cursor: pointer; transition: background 0.14s ease, border-color 0.14s ease, color 0.14s ease; }
.reso-choice-btn:hover { border-color: var(--sage); color: var(--ink); }
.reso-choice-btn.active { background: #46604f; border-color: #46604f; color: #fff; }

/* Resolution — "using originals" warning flag */
.reso-original-warning { display:flex; align-items:flex-start; gap:0.7rem; margin-bottom:1rem; padding:0.75rem 1rem; background:#faefdd; border:1px solid rgba(180,140,60,0.38); border-radius:10px; }
.reso-warn-ico { flex-shrink:0; width:22px; height:22px; border-radius:50%; background:#c08a2e; color:#fff; font-weight:700; font-size:0.85rem; display:inline-flex; align-items:center; justify-content:center; margin-top:1px; }
.reso-original-warning p { margin:0; font-size:0.85rem; color:#7a5a20; line-height:1.45; }
.reso-original-warning strong { color:#664a15; }
.reso-chip-original { background:#faeede; color:#a5762a; }
.reso-feat-warn { display:flex; align-items:center; gap:0.45rem; margin:0.6rem 0 0; font-size:0.8rem; color:#a5762a; }
.reso-warn-dot { width:8px; height:8px; border-radius:50%; background:#c08a2e; flex-shrink:0; }

/* Animation picker — fine-tune (trim + slow down) panel */
.anim-finetune { margin: 0.7rem auto 0; max-width: 320px; text-align: left; border: 1px solid var(--line); border-radius: 10px; background: var(--paper); overflow: hidden; }
.anim-finetune-summary { cursor: pointer; list-style: none; padding: 0.55rem 0.9rem; font-size: 0.82rem; font-weight: 600; color: var(--ink); }
.anim-finetune-summary::-webkit-details-marker { display: none; }
.anim-finetune-summary::after { content: "▾"; float: right; color: var(--muted); font-size: 0.75rem; }
.anim-finetune[open] .anim-finetune-summary::after { content: "▴"; }
.anim-finetune .animation-edit-rows { display: flex; flex-direction: column; gap: 0.6rem; padding: 0.2rem 0.9rem 0.7rem; }
.anim-finetune .anim-edit-row { display: flex; flex-direction: column; gap: 0.25rem; }
.anim-finetune .anim-edit-label { font-size: 0.78rem; color: var(--body); display: flex; justify-content: space-between; }
.anim-finetune .anim-edit-label strong { color: var(--ink); font-variant-numeric: tabular-nums; }
.anim-finetune input[type="range"] { width: 100%; accent-color: var(--sage); }
.anim-finetune-note { margin: 0; padding: 0 0.9rem 0.75rem; font-size: 0.74rem; color: var(--muted); line-height: 1.4; }

/* Animation — "Preview opening" button + modal */
.anim-opening-preview-row { display: flex; flex-direction: column; align-items: center; gap: 0.3rem; margin: 0.8rem auto 0; max-width: 320px; }
.anim-preview-opening-btn { width: 100%; }
.anim-preview-hint { font-size: 0.74rem; color: var(--muted); text-align: center; }
.opening-preview-modal { position: fixed; inset: 0; z-index: 9000; background: rgba(10, 8, 6, 0.75); -webkit-backdrop-filter: blur(5px); backdrop-filter: blur(5px); display: flex; align-items: center; justify-content: center; padding: 3vmin; }
.opening-preview-panel { position: relative; width: min(880px, 94vw); background: var(--paper); border-radius: 16px; padding: 1.4rem 1.5rem 1.6rem; box-shadow: 0 20px 60px rgba(0,0,0,0.4); }
.opening-preview-close { position: absolute; top: 12px; right: 14px; width: 34px; height: 34px; border-radius: 50%; border: 1px solid var(--line); background: var(--paper); color: var(--body); font-size: 1.3rem; line-height: 1; cursor: pointer; }
.opening-preview-title { margin: 0 0 1rem; font-family: "Cormorant Garamond", Georgia, serif; font-size: 1.5rem; font-weight: 600; color: var(--ink); }
.opening-preview-video { width: 100%; border-radius: 12px; background: #000; display: block; }
.opening-preview-note { margin: 0.7rem 0 0; font-size: 0.82rem; color: var(--muted); text-align: center; }
.opening-preview-loading { display: flex; flex-direction: column; align-items: center; gap: 1rem; padding: 2.5rem 1rem; text-align: center; color: var(--body); }
.opening-preview-loading p { margin: 0; line-height: 1.5; }
.opening-preview-error { text-align: center; padding: 1.5rem 1rem; color: var(--body); }
.opening-preview-errtext { font-size: 0.8rem; color: var(--accent); margin: 0.4rem 0 1rem; word-break: break-word; }
.anim-bookend-busy { display: inline-flex; align-items: center; gap: 6px; }
.anim-bookend-busy-label { font-size: 12px; color: var(--body); white-space: nowrap; }

/* ==========================================================================
   GUIDED MEMORIAL WIZARD  (state.view === "wizard")
   Calm, roomy, one-decision-at-a-time. Reuses .primary-btn / .ghost-btn.
   ========================================================================== */
.hero-wizard-note { margin: 0.75rem 0 0; font-size: 0.85rem; color: var(--muted); }
.hero-wizard-note strong { color: var(--accent); font-weight: 600; }

.wiz { max-width: 720px; margin: 0 auto; padding: 2.25rem 1.25rem 4rem; }

/* ── Gentle entrance ─────────────────────────────────────────────────────
   Each screen's blocks fade + rise in a soft stagger when the family arrives.
   The very first (welcome) card gets a slower, more ceremonial bloom plus a
   warm glow behind the title — the feeling of beginning something beautiful. */
@keyframes wizRise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
@keyframes wizGlow {
  from { opacity: 0; transform: translate(-50%, -50%) scale(0.55); }
  to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
@keyframes wizCardBloom {
  from { opacity: 0; transform: translateY(20px) scale(0.975); }
  to   { opacity: 1; transform: none; }
}
.wiz-anim > * { animation: wizRise 0.6s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
.wiz-anim > *:nth-child(1) { animation-delay: 0.04s; }
.wiz-anim > *:nth-child(2) { animation-delay: 0.13s; }
.wiz-anim > *:nth-child(3) { animation-delay: 0.22s; }
.wiz-anim > *:nth-child(4) { animation-delay: 0.31s; }
.wiz-anim > *:nth-child(5) { animation-delay: 0.40s; }

/* Welcome card: slower, warmer, with a blooming glow behind the title. */
.wiz-first.wiz-anim > * { animation-duration: 0.9s; }
.wiz-first .wiz-head { position: relative; }
.wiz-first .wiz-head::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 46%;
  width: 560px;
  max-width: 90vw;
  height: 340px;
  border-radius: 50%;
  background: radial-gradient(ellipse at center, rgba(202, 167, 101, 0.22), rgba(202, 167, 101, 0) 68%);
  z-index: -1;
  pointer-events: none;
  transform: translate(-50%, -50%) scale(0.55);
  animation: wizGlow 1.9s ease-out 0.05s both;
}
.wiz-first.wiz-anim .wiz-card { animation: wizCardBloom 1s cubic-bezier(0.2, 0.7, 0.2, 1) 0.3s both; }

@media (prefers-reduced-motion: reduce) {
  .wiz-anim > *,
  .wiz-first.wiz-anim .wiz-card,
  .wiz-first .wiz-head::before { animation: none !important; }
}
.wiz-head { text-align: center; margin: 0 auto 1.75rem; }
.wiz-title { font-family: "Cormorant Garamond", Georgia, serif; font-size: clamp(1.9rem, 4vw, 2.6rem); line-height: 1.1; margin: 0.4rem 0 0.5rem; color: var(--ink); font-weight: 600; }
.wiz-sub { margin: 0 auto; max-width: 34rem; color: var(--body); font-size: 0.98rem; line-height: 1.5; }

/* Progress trail */
.wiz-trail { display: flex; justify-content: center; flex-wrap: wrap; gap: 0.35rem 0.9rem; margin-bottom: 1.1rem; }
.wiz-dot { display: inline-flex; align-items: center; gap: 0.4rem; font-size: 0.72rem; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); }
.wiz-dot i { width: 9px; height: 9px; border-radius: 50%; background: var(--line-strong); transition: background 0.2s, transform 0.2s; }
.wiz-dot em { font-style: normal; opacity: 0.5; font-size: 0.66rem; transition: font-size 0.18s ease, color 0.18s ease, opacity 0.18s ease; }
.wiz-dot.done i { background: var(--sage); }
.wiz-dot.done em { color: var(--sage); opacity: 0.75; }
.wiz-dot.current i { background: var(--accent); transform: scale(1.5); box-shadow: 0 0 0 4px rgba(118,66,57,0.14); }
/* Current step reads loudest: bigger, bold, in the brand accent. */
.wiz-dot.current em { opacity: 1; color: var(--accent); font-weight: 700; font-size: 0.98rem; letter-spacing: 0.06em; }
/* Clickable already-visited steps in the guided flow. */
button.wiz-dot.is-nav { background: none; border: 0; padding: 2px 4px; margin: -2px -4px; font: inherit; text-transform: uppercase; letter-spacing: 0.04em; cursor: pointer; border-radius: 6px; transition: background 0.15s ease; }
button.wiz-dot.is-nav:hover { background: rgba(96,115,101,.1); }
button.wiz-dot.is-nav:hover em { opacity: 0.9; text-decoration: underline; text-underline-offset: 2px; }

/* Cards */
.wiz-card { background: var(--paper); border: 1px solid var(--line); border-radius: 14px; padding: 1.6rem; box-shadow: 0 12px 40px rgba(56, 44, 29, 0.07); }
.wiz-center { text-align: center; }

/* Fields */
.wiz-field { display: block; margin-bottom: 1.05rem; }
.wiz-field:last-child { margin-bottom: 0; }
.wiz-field-row { display: flex; gap: 1rem; }
.wiz-field-row .wiz-field { flex: 1; }
.wiz-label { display: block; font-size: 0.8rem; font-weight: 600; color: var(--ink); margin-bottom: 0.4rem; letter-spacing: 0.01em; }
.wiz-optional { font-weight: 400; color: var(--muted); }
.wiz-input { width: 100%; padding: 0.72rem 0.85rem; border: 1px solid var(--line-strong); border-radius: 10px; background: var(--paper-2); font: inherit; font-size: 0.95rem; color: var(--ink); transition: border-color 0.15s, box-shadow 0.15s; }
.wiz-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(118, 66, 57, 0.12); }

/* Actions */
.wiz-actions { display: flex; justify-content: space-between; align-items: center; gap: 0.75rem; margin-top: 1.5rem; }
/* AV8: on phones the Continue button could sit below the fold with a long name+
   nickname; make the action bar stick to the bottom so it's always reachable. */
@media (max-width: 600px) {
  .wiz-actions { position: sticky; bottom: 0; z-index: 5; margin-top: 1rem;
    padding: 0.6rem 0 calc(0.6rem + env(safe-area-inset-bottom, 0px));
    background: linear-gradient(to top, var(--paper) 62%, rgba(255,253,247,0)); }
  /* MM1 — being sticky, the bar floats OVER whatever is behind it, so the last
     rows of a long list (the music library especially) sat underneath it and
     couldn't be scrolled clear. Reserve its height at the end of the scroll. */
  .wiz > *:last-child { scroll-margin-bottom: 5rem; }
  .wiz .module-card:last-of-type,
  .free-library-list, .music-results-list { padding-bottom: 0.5rem; }
  .wiz { padding-bottom: 4.5rem; }
}
.wiz-actions.center { justify-content: center; }
.wiz-hint-center { text-align: center; color: var(--muted); font-size: 0.85rem; margin: 0.9rem 0 0; }

/* Photo upload */
.wiz-dropzone { display: flex; flex-direction: column; align-items: center; gap: 0.3rem; padding: 1.9rem 1rem; border: 2px dashed var(--line-strong); border-radius: 12px; background: var(--paper-2); cursor: pointer; transition: border-color 0.15s, background 0.15s; text-align: center; }
.wiz-dropzone:focus-visible { outline: 3px solid var(--accent, #764239); outline-offset: 2px; border-color: var(--accent, #764239); } /* PB4 */
.wiz-dropzone:hover { border-color: var(--accent); background: #fbf6ee; }
.wiz-dropzone-plus { font-size: 1.9rem; line-height: 1; color: var(--accent); }
.wiz-dropzone strong { color: var(--ink); font-size: 1rem; }
.wiz-dropzone-hint { font-size: 0.8rem; color: var(--muted); }
.wiz-grid-label { font-size: 0.82rem; color: var(--muted); margin: 1.15rem 0 0.6rem; text-align: center; }
.wiz-empty { text-align: center; color: var(--muted); padding: 1rem 0 0; }
.wiz-photo-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 0.6rem; }
.wiz-photo { position: relative; padding: 0; border: 2px solid transparent; border-radius: 10px; overflow: hidden; cursor: pointer; background: #000; aspect-ratio: 1; transition: border-color 0.15s, transform 0.12s; }
.wiz-photo:hover { transform: translateY(-1px); }
.wiz-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.wiz-photo.is-main { border-color: var(--gold); }
.wiz-photo-badge { position: absolute; left: 4px; bottom: 4px; background: rgba(30, 24, 16, 0.82); color: #f6e6c3; font-size: 0.64rem; font-weight: 600; padding: 2px 6px; border-radius: 6px; }

/* Choice cards */
.wiz-choice-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.9rem; }
.wiz-choice-grid.three { grid-template-columns: repeat(3, 1fr); }
.wiz-choice { position: relative; display: flex; flex-direction: column; gap: 0.35rem; text-align: left; padding: 1.25rem 1.1rem; border: 1.5px solid var(--line); border-radius: 12px; background: var(--paper); cursor: pointer; transition: border-color 0.15s, box-shadow 0.15s, transform 0.12s; font: inherit; }
.wiz-choice:hover { border-color: var(--accent); transform: translateY(-2px); box-shadow: 0 12px 30px rgba(56, 44, 29, 0.1); }
.wiz-choice.selected { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(118, 66, 57, 0.26); }
.wiz-choice-title { font-weight: 600; color: var(--ink); font-size: 1rem; }
.wiz-choice-desc { font-size: 0.85rem; color: var(--body); line-height: 1.4; }
.wiz-choice-tag { align-self: flex-start; margin-top: 0.25rem; font-size: 0.68rem; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--sage); }

/* Mood grid */
.wiz-mood-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.9rem; }
.wiz-mood { display: flex; flex-direction: column; text-align: left; padding: 0; border: 1.5px solid var(--line); border-radius: 12px; overflow: hidden; background: var(--paper); cursor: pointer; transition: border-color 0.15s, box-shadow 0.15s, transform 0.12s; font: inherit; }
.wiz-mood { position: relative; }
.wiz-mood:hover { border-color: var(--accent); transform: translateY(-2px); box-shadow: 0 12px 30px rgba(56, 44, 29, 0.1); }
.wiz-mood.selected { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(118, 66, 57, 0.28); }
/* Unmistakable "this is the one" badge on any selected card. */
.wiz-mood.selected::after, .wiz-choice.selected::after {
  content: "✓"; position: absolute; top: 8px; right: 8px; z-index: 2;
  width: 23px; height: 23px; display: flex; align-items: center; justify-content: center;
  border-radius: 50%; background: var(--accent); color: #fff; font-size: 13px; font-weight: 800;
  box-shadow: 0 2px 7px rgba(0,0,0,.28); pointer-events: none;
}
.wiz-mood-label { font-weight: 600; color: var(--ink); font-size: 1rem; padding: 0.75rem 0.9rem 0.2rem; }
.wiz-mood-desc { font-size: 0.82rem; color: var(--body); line-height: 1.4; padding: 0 0.9rem 0.9rem; }

/* Live mood preview — the family's main portrait placed on the real backdrop. */
.wiz-mood-preview {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  background-size: cover;
  background-position: center;
  overflow: hidden;
}
.wiz-mood-photo {
  position: absolute;
  transform: translate(-50%, -50%);
  aspect-ratio: 3 / 4;
  border-radius: 2px;
  overflow: hidden;
  box-shadow: 0 6px 18px rgba(20, 14, 8, 0.4);
  background: #fff;
  padding: 3px;
}
.wiz-mood-photo img { width: 100%; height: 100%; object-fit: cover; display: block; border-radius: 1px; }
.wiz-mood-photo.wiz-matte-antique { background: #efe4cf; }
.wiz-mood-photo.wiz-matte-cream { background: #fffdf7; }

/* When the real composed stage is available, it fills the preview box edge to
   edge (its own 16:9 .preview-stage sits inside). */
.wiz-mood-stage { padding: 0; background: #000; }
.wiz-mood-stage .preview-stage { border-radius: 0 !important; box-shadow: none !important; }
.wiz-mood-caption {
  position: absolute;
  left: 50%;
  bottom: 7%;
  transform: translateX(-50%);
  text-align: center;
  color: #fff;
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.65);
  line-height: 1.15;
  pointer-events: none;
}
.wiz-mood-caption b { display: block; font-family: "Cormorant Garamond", Georgia, serif; font-size: 0.95rem; font-weight: 600; }
.wiz-mood-caption i { font-style: normal; font-size: 0.62rem; letter-spacing: 0.04em; opacity: 0.9; }

/* Confirm main portrait step */
.wiz-mainpick-hero {
  width: min(260px, 70%);
  margin: 0 auto 0.85rem;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 14px 40px rgba(56, 44, 29, 0.18);
  border: 4px solid #fff;
  outline: 1px solid var(--line);
}
.wiz-mainpick-hero img { width: 100%; display: block; aspect-ratio: 3 / 4; object-fit: cover; }
.wiz-mainpick-name { text-align: center; color: var(--ink); margin: 0 0 0.4rem; font-size: 0.95rem; }
.wiz-mainpick-name b { font-family: "Cormorant Garamond", Georgia, serif; font-size: 1.15rem; font-weight: 600; }
.wiz-mainpick-name span { color: var(--muted); }
.wiz-mainpick-strip { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.5rem; margin-top: 0.5rem; }
.wiz-mainpick-thumb { padding: 0; width: 62px; height: 62px; border: 2px solid transparent; border-radius: 8px; overflow: hidden; cursor: pointer; background: #000; transition: border-color 0.14s, transform 0.12s; }
.wiz-mainpick-thumb:hover { transform: translateY(-1px); }
.wiz-mainpick-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.wiz-mainpick-thumb.is-main { border-color: var(--gold); }

/* Restore review tiles */
.wiz-restore-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 0.7rem; }
.wiz-restore-tile { position: relative; padding: 0; border: 2px solid transparent; border-radius: 10px; overflow: hidden; cursor: pointer; background: #1f1813; aspect-ratio: 4/3; transition: border-color 0.15s, opacity 0.15s; }
.wiz-restore-tile img { width: 100%; height: 100%; object-fit: cover; display: block; }
.wiz-restore-tile.off { opacity: 0.5; }
.wiz-restore-tile.on { border-color: var(--gold); }
.wiz-restore-flag { position: absolute; left: 0; right: 0; bottom: 0; padding: 4px 6px; font-size: 0.66rem; font-weight: 600; color: #fff; background: linear-gradient(to top, rgba(20, 14, 8, 0.85), transparent); }

/* Music */
.wiz-music-list { display: flex; flex-direction: column; gap: 0.5rem; margin-bottom: 0.9rem; }
.wiz-music-row { border: 1.5px solid var(--line); border-radius: 10px; padding: 0.35rem 0.35rem 0.35rem 0.2rem; transition: border-color 0.15s; }
.wiz-music-row.selected { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(118, 66, 57, 0.1); }
.wiz-music-pick { display: flex; align-items: center; gap: 0.6rem; width: 100%; padding: 0.45rem 0.55rem; background: none; border: none; cursor: pointer; font: inherit; text-align: left; }
.wiz-music-check { width: 18px; flex-shrink: 0; color: var(--accent); font-weight: 700; }
.wiz-music-name { flex: 1; font-weight: 600; color: var(--ink); font-size: 0.9rem; }
.wiz-music-cat { font-size: 0.72rem; color: var(--muted); text-transform: capitalize; }
.wiz-music-audio { width: 100%; height: 34px; margin-top: 0.25rem; }
.wiz-nomusic { width: 100%; padding: 0.7rem; border: 1.5px dashed var(--line-strong); border-radius: 10px; background: none; cursor: pointer; font: inherit; font-size: 0.9rem; color: var(--body); transition: border-color 0.15s, color 0.15s; }
.wiz-nomusic:hover { border-color: var(--accent); color: var(--accent); }
.wiz-nomusic.selected { border-style: solid; border-color: var(--accent); color: var(--accent); font-weight: 600; }

/* Toggle row (gentle motion) */
.wiz-toggle-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-top: 1.1rem; padding: 1rem 1.15rem; border: 1.5px solid var(--line); border-radius: 12px; background: var(--paper); }
.wiz-toggle-row span strong { display: block; color: var(--ink); font-size: 0.95rem; }
.wiz-toggle-row span em { font-style: normal; color: var(--muted); font-size: 0.82rem; }
.wiz-switch { position: relative; flex-shrink: 0; width: 46px; height: 26px; border-radius: 999px; background: #b6ada0; cursor: pointer; transition: background 0.18s; }
.wiz-switch i { position: absolute; top: 3px; left: 3px; width: 20px; height: 20px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,0.3); transition: transform 0.18s; }
.wiz-switch.on { background: var(--sage); }
.wiz-switch.on i { transform: translateX(20px); }

/* Preview player */
.wiz-player { margin: 0 auto; max-width: 100%; }

/* Gentle-motion preview: a soft continuous breathing zoom on the rough-cut
   player so the family can sense the drift. This is an approximation — the
   finished film applies a precise slow zoom to each photo scene. */
.wiz-motion .draft-cinema { overflow: hidden; }
.wiz-motion .draft-cinema-canvas { animation: wizBreathe 15s ease-in-out infinite; transform-origin: 50% 45%; will-change: transform; }
@keyframes wizBreathe {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.045); }
}
@media (prefers-reduced-motion: reduce) {
  .wiz-motion .draft-cinema-canvas { animation: none; }
}

/* Pacing controls live under the preview player so choices re-time the rough
   cut live. */
.wiz-pace-card { margin-top: 1.1rem; }
.wiz-pace-heading { font-family: "Cormorant Garamond", Georgia, serif; font-size: 1.25rem; font-weight: 600; color: var(--ink); margin: 0 0 0.85rem; text-align: center; }
.wiz-pace-options.is-sub { margin-top: 0.9rem; padding-top: 0.9rem; border-top: 1px solid var(--line); }
.wiz-pace-options .wiz-grid-label { margin-top: 0; }
.wiz-pace-card .wiz-toggle-row { margin-top: 1rem; }

/* Progress bar (analysis) */
.wiz-progress { width: 100%; max-width: 320px; height: 7px; margin: 0 auto 0.7rem; background: var(--line); border-radius: 999px; overflow: hidden; }
.wiz-progress-fill { height: 100%; background: var(--sage); border-radius: 999px; transition: width 0.3s ease; }
.wiz-creating-line { color: var(--body); font-size: 0.95rem; max-width: 30rem; margin: 0 auto; line-height: 1.5; }

/* Pay */
.wiz-pay { text-align: center; }
.wiz-price { font-family: "Cormorant Garamond", Georgia, serif; font-size: 2.9rem; font-weight: 600; color: var(--ink); line-height: 1; margin-bottom: 0.9rem; }
.wiz-pay-list { list-style: none; padding: 0; margin: 0 auto 1.1rem; max-width: 24rem; text-align: left; }
.wiz-pay-list li { position: relative; padding: 0.4rem 0 0.4rem 1.6rem; color: var(--body); font-size: 0.92rem; border-bottom: 1px solid var(--line); }
.wiz-pay-list li:last-child { border-bottom: none; }
.wiz-pay-list li::before { content: "✦"; position: absolute; left: 0; color: var(--gold); }
.wiz-pay-note { font-size: 0.78rem; color: var(--muted); margin: 0 0 1.1rem; }
.wiz-pay-btn { width: 100%; max-width: 24rem; }

/* Done */
.wiz-final-video { max-height: 58vh; max-width: 100%; width: auto; display: block; margin: 0 auto 1.1rem; background: #000; border-radius: 10px; }

@media (max-width: 560px) {
  .wiz-field-row { flex-direction: column; gap: 0; }
  .wiz-choice-grid, .wiz-choice-grid.three, .wiz-mood-grid { grid-template-columns: 1fr; }
  .wiz-dot em { display: none; }
}

/* ============================================================================
   GUIDED FILM — FLOW 3 (additive; reuses .wiz styles, adds its own extras)
   ============================================================================ */

/* Wider canvas than the wizard so embedded editors have room. */
.wiz.f3 { max-width: 860px; }

/* Autosave reassurance line under the trail. */
/* Darkened for readability (was #9a9184 — too faint for older eyes). */
.f3-savenote { text-align: center; font-size: 0.82rem; color: #6b6154; margin: 0.4rem 0 0; letter-spacing: 0.01em; } /* AV4: >=4.5:1 */
.f3-savestate { margin-left: 0.45rem; font-weight: 700; font-size: 0.8rem; opacity: 0; transition: opacity .2s; }
.f3-savestate.is-saving { color: #6b6154; opacity: 1; }
.f3-savestate.is-saved { color: #2f6b46; opacity: 1; }
/* G2: visible "Start over" control in the guided-flow header */
.f3-startover {
  display: block; margin: 0.5rem auto 0; padding: 4px 10px;
  background: none; border: 0; cursor: pointer;
  font: 600 0.78rem/1 inherit; letter-spacing: 0.02em;
  color: #6b6154; text-decoration: underline; text-underline-offset: 2px; /* AV2: >=4.5:1 */
  border-radius: 6px; transition: color .12s, background .12s;
}
.f3-startover:hover { color: #7a2e2e; background: rgba(122,46,46,.06); }
/* G3: inline locked-tab reason under the Opening/Slides/Transitions/Preview tabs */
.f3-looklocked {
  text-align: center; margin: 0.55rem auto 0; max-width: 34rem;
  font-size: 0.83rem; color: #8a7f6f;
}
.f3-looklocked b { color: #5a4a34; }
.f3-looklocked::before { content: "\1F512\00A0"; opacity: .7; }
/* Step counter above the trail */
.f3-progress { text-align: center; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--accent); margin: 0 0 0.5rem; }
/* Photos step — privacy reassurance + discoverability hint */
.f3-photo-privacy { display: flex; align-items: center; justify-content: center; gap: 0.4rem; font-size: 0.85rem; color: #5c6b52; background: rgba(95,113,101,.08); border-radius: 10px; padding: 0.5rem 0.8rem; margin: 0.9rem auto 0; max-width: 460px; }
.f3-photo-privacy .f3-lock { font-size: 0.9rem; }
.f3-photo-help { color: #7a7061; }

/* Lightweight hover/focus tooltip for abstract controls (add data-tip="…") */
[data-tip] { position: relative; }
[data-tip]:hover::after, [data-tip]:focus-visible::after {
  content: attr(data-tip);
  position: absolute; bottom: calc(100% + 9px); left: 50%; transform: translateX(-50%);
  background: #2f2a20; color: #fff; font-size: 0.74rem; font-weight: 500; line-height: 1.35;
  padding: 0.42rem 0.6rem; border-radius: 8px; width: max-content; max-width: 210px;
  white-space: normal; text-align: center; box-shadow: 0 8px 20px rgba(0,0,0,.24);
  z-index: 60; pointer-events: none;
}
[data-tip]:hover::before, [data-tip]:focus-visible::before {
  content: ""; position: absolute; bottom: calc(100% + 4px); left: 50%; transform: translateX(-50%);
  border: 5px solid transparent; border-top-color: #2f2a20; z-index: 60; pointer-events: none;
}
@media (hover: none) { [data-tip]:hover::after, [data-tip]:hover::before { display: none; } }

/* ---- Text-style picker: live-preview chip row (Opening editor) ---- */
.f3-tstyle-wrap { margin-top: 1.15rem; }
/* Per-look picker (Categories): a popover that drops directly below the
   selected look's row, spanning the full grid width, with an arrow pointing
   up at the chosen card's column. */
.fsv2-looks .f3-tstyle-perlook {
  grid-column: 1 / -1;
  /* One card wide, aligned under the selected card (the row uses a 12px gap). */
  width: calc(50% - 6px);
  position: relative;
  margin: 0.2rem 0 0.3rem;
  padding: 0.85rem 1rem 0.6rem;
  background: #fbf7ef;
  border: 1px solid #e6ddcb;
  border-radius: 12px;
  box-shadow: 0 6px 18px rgba(40, 30, 20, 0.06);
}
.fsv2-looks .f3-tstyle-perlook.arrow-left { justify-self: start; }
.fsv2-looks .f3-tstyle-perlook.arrow-right { justify-self: end; }
.fsv2-looks .f3-tstyle-perlook::before {
  content: "";
  position: absolute;
  top: -8px;
  left: 50%; margin-left: -7px; /* arrow centered on the card-width panel */
  width: 15px; height: 15px;
  background: #fbf7ef;
  border-left: 1px solid #e6ddcb;
  border-top: 1px solid #e6ddcb;
  transform: rotate(45deg);
}
.fsv2-looks .f3-tstyle-perlook .f3-tstyle-head { margin-top: 0; }
/* Default chip: the look's own typography — a quiet "original" tile. */
.f3-tstyle-default .f3-tstyle-tile { background: linear-gradient(135deg, #4a4136, #2b241b); }
.f3-tstyle-default .f3-tstyle-aa { font-family: "Cormorant Garamond", Georgia, serif; }
/* FONT target toggle — the same eight font buttons write either to the words
   & dates or to the name alone, so the row's heading says which is live. */
/* Panel lead — names what the toggle below controls, so its scope is never
   a guess. Both the FONT and COLOR rows under it follow that one choice. */
.f3-ft-lead {
  margin: 0 0 0.35rem; text-align: center;
  font-size: 0.68rem; letter-spacing: 0.13em; text-transform: uppercase;
  color: #9a9184;
}
/* One colour, one meaning — the old two-half swatch carried an accent and a
   name at once and needed a caption to explain which was which. */
.f3-col {
  flex: 0 0 auto; width: 3.4rem; border: none; background: none; padding: 0;
  cursor: pointer; text-align: center; display: block;
}
.f3-col-dot {
  position: relative; display: block; width: 2.5rem; height: 2.5rem;
  margin: 0 auto 0.25rem; border-radius: 50%;
  border: 1px solid rgba(36, 33, 31, 0.16);
  box-shadow: inset 0 1px 2px rgba(56, 44, 29, 0.10);
  overflow: hidden;
}
/* "Default" has no hex of its own — it means whatever this look shipped with,
   so it reads as an unpainted disc rather than a colour we invented. */
.f3-col-dot-default {
  background:
    linear-gradient(135deg, #fffdf7 0 50%, #e6dcc6 50% 100%);
}
.f3-col.on .f3-col-dot {
  border-color: var(--accent, #b8863b);
  box-shadow: 0 0 0 2px var(--paper, #fffdf7), 0 0 0 4px var(--accent, #b8863b);
}
.f3-col.on .f3-tstyle-nm { color: var(--accent, #b8863b); font-weight: 600; }
.f3-col-plus {
  position: absolute; inset: 0; display: flex; align-items: center;
  justify-content: center; font-size: 1rem; font-weight: 600;
  color: rgba(36, 33, 31, 0.5); pointer-events: none;
}
.f3-col-dot input[type="color"] {
  position: absolute; inset: 0; width: 100%; height: 100%;
  opacity: 0; border: 0; padding: 0; cursor: pointer;
}
/* Quick picks — secondary by design: text, not swatches, so they never
   compete with the colours above them. */
/* Shadow — the halo behind the letters. Kind first (Auto is the default and is
   right nearly always), then the one control families actually came for. */
.f3-sh-kinds {
  display: flex; justify-content: center; gap: 3px; padding: 3px;
  width: max-content; max-width: 100%; margin: 0 auto 0.5rem;
  border-radius: 999px; background: #ece2d2;
  border: 1px solid rgba(36, 33, 31, 0.10);
}
.f3-sh-k {
  border: none; background: none; cursor: pointer; font: inherit;
  font-size: 0.76rem; font-weight: 600; color: #7a7266;
  padding: 0.3rem 0.75rem; border-radius: 999px; white-space: nowrap;
  transition: background 0.12s ease, color 0.12s ease;
}
.f3-sh-k:hover { color: #4e483e; }
.f3-sh-k.on {
  background: #fffdf7; color: #332c23;
  box-shadow: 0 1px 3px rgba(56, 44, 29, 0.16);
}
.f3-sh-slider { display: flex; align-items: center; gap: 0.6rem; justify-content: center; }
.f3-sh-slider input[type="range"] { width: min(15rem, 70%); accent-color: var(--accent, #b8863b); cursor: pointer; }
.f3-sh-val { font-size: 0.76rem; color: #8a8378; min-width: 2.6rem; text-align: left; font-variant-numeric: tabular-nums; }
/* "None" leaves nothing to strengthen — the slider stays visible so the row
   does not jump, but it reads as inactive rather than pretending to work. */
.f3-sh-slider.is-off { opacity: 0.45; }
.f3-sh-slider.is-off input[type="range"] { cursor: not-allowed; }
.f3-col-quick {
  display: flex; justify-content: center; gap: 0.4rem; flex-wrap: wrap;
  margin-top: 0.15rem;
}
.f3-col-q {
  border: 1px solid rgba(36, 33, 31, 0.12); background: transparent;
  cursor: pointer; font: inherit; font-size: 0.74rem; color: #7a7266;
  padding: 0.22rem 0.7rem; border-radius: 999px; white-space: nowrap;
  transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.f3-col-q:hover { background: #f4ece0; color: #4e483e; border-color: rgba(36, 33, 31, 0.2); }
.f3-ft-target {
  display: flex; justify-content: center; gap: 3px; padding: 3px;
  width: max-content; max-width: 100%; margin: 0.1rem auto 0.65rem;
  border-radius: 999px; background: #ece2d2;
  border: 1px solid rgba(36, 33, 31, 0.10);
  box-shadow: inset 0 1px 2px rgba(56, 44, 29, 0.07);
}
.f3-ft-pill {
  border: none; background: none; cursor: pointer;
  font: inherit; font-size: 0.86rem; font-weight: 600; letter-spacing: 0.005em;
  text-transform: none; color: #7a7266;
  padding: 0.44rem 1.2rem; border-radius: 999px; white-space: nowrap;
  transition: background 0.14s ease, color 0.14s ease, box-shadow 0.14s ease;
}
.f3-ft-pill:hover { color: #4e483e; }
.f3-ft-pill.on {
  background: #fffdf7; color: #332c23;
  box-shadow: 0 1px 3px rgba(56, 44, 29, 0.18);
}
.f3-ft-pill:focus-visible { outline: 2px solid var(--accent, #b8863b); outline-offset: 2px; }
.f3-tstyle-row {
  display: flex; gap: 0.5rem; overflow-x: auto; padding: 0.15rem 0.1rem 0.5rem;
  scrollbar-width: thin; -webkit-overflow-scrolling: touch;
}
.f3-tstyle {
  flex: 0 0 auto; width: 3.4rem; border: none; background: none; padding: 0; cursor: pointer; text-align: center;
}
.f3-tstyle-tile {
  position: relative; display: flex; align-items: center; justify-content: center;
  height: 3rem; border-radius: 0.55rem; overflow: hidden;
  background: linear-gradient(135deg, #3a2c22, #241a10);
  border: 2px solid transparent; transition: border-color 0.12s ease, transform 0.12s ease;
}
.f3-tstyle-aa {
  font-size: 1.5rem; line-height: 1; max-width: 92%;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.f3-tstyle-nm { font-size: 0.66rem !important; }
.f3-tstyle:hover .f3-tstyle-tile { transform: translateY(-2px); }
.f3-tstyle.on .f3-tstyle-tile { border-color: var(--accent, #764239); }
.f3-tstyle.on .f3-tstyle-tile::after {
  content: "✓"; position: absolute; top: 0.15rem; right: 0.25rem;
  width: 0.95rem; height: 0.95rem; border-radius: 50%;
  background: var(--accent, #764239); color: #fff; font-size: 0.62rem;
  display: flex; align-items: center; justify-content: center;
}
.f3-tstyle-nm { display: block; font-size: 0.72rem; margin-top: 0.35rem; color: var(--muted, #726a5d); }
.f3-tstyle.on .f3-tstyle-nm { color: var(--accent, #764239); font-weight: 600; }
.f3-tstyle:focus-visible .f3-tstyle-tile { outline: 2px solid var(--accent, #764239); outline-offset: 2px; }
.f3-pal .f3-tstyle-nm { display: block; }
.f3-pal.on .f3-tstyle-nm { color: var(--accent, #764239); font-weight: 600; }
.f3-pal-cell.editing { overflow: visible; z-index: 5; }
.f3-pal-cell.editing .f3-pal-sw::after { display: none; }
.f3-pal-cell.on .f3-tstyle-nm { color: var(--accent, #764239); font-weight: 600; }
.f3-pal-cell.editing .f3-pal-edit { background: var(--accent, #764239); color: #fff; border-color: var(--accent, #764239); }

/* LH7 — a control whose data isn't there yet: visibly unavailable, with the
   reason in its own hint text rather than a toggle that does nothing. */
.fs-el-chip.is-unavailable,
.cyo-chip.is-unavailable,
.backdrop-element-row.is-unavailable,
.inline-toggle-row.is-unavailable { opacity: 0.45; cursor: default; }
.fs-el-chip.is-unavailable input,
.cyo-chip.is-unavailable input,
.backdrop-element-row.is-unavailable input,
.inline-toggle-row.is-unavailable input { cursor: default; }
.fs-el-why { font-size: 0.72rem; opacity: 0.75; margin-left: 0.3rem; }
.fs-el-why-line { align-self: center; }

/* Small helper note under fields. */
.f3-note { display: block; font-size: 0.78rem; color: #6b6154; margin-top: 0.35rem; } /* AV1: >=4.5:1 */

/* Look-step depth switch. */
/* Top-level Look sections: Opening, Slides, Transitions, and Preview. A larger underline-tab bar that
   sits ABOVE the Simple/Categories/Advanced pill toggle so the two levels read
   as clearly separate. */
.f3-looktabs {
  display: flex;
  justify-content: center;
  gap: 2.25rem;
  margin: 0 0 1.5rem;
  border-bottom: 1px solid #e3dccc;
}
.f3-looktab {
  border: 0;
  background: none;
  font-family: inherit;
  font-size: 1.02rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: #9a9081;
  cursor: pointer;
  padding: 0.55rem 0.35rem 0.7rem;
  margin-bottom: -1px;
  border-bottom: 2.5px solid transparent;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.f3-looktab:hover { color: #5c554a; }
.f3-looktab.on { color: var(--accent); border-bottom-color: var(--accent); font-weight: 700; }
.f3-looktab.is-locked { color: #c3bcae; cursor: not-allowed; opacity: .55; }
.f3-looktab.is-locked:hover { color: #c3bcae; }
.f3-looktabs.is-preparing { margin-bottom: 1rem; }
.f3-look-preparing {
  min-height: 16rem;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.8rem;
  text-align: left;
  color: #50483d;
}
.f3-look-preparing strong { display: block; font-size: 1rem; }
.f3-look-preparing p { margin: 0.2rem 0 0; color: #756b5d; font-size: 0.88rem; }
.f3-look-transitions { display: flex; flex-direction: column; gap: 0.75rem; }
.f3-look-transitions .draft-transition-card { margin: 0; }
@media (max-width: 620px) {
  .f3-looktabs { gap: 0.75rem; justify-content: space-between; }
  .f3-looktab { font-size: 0.9rem; padding-inline: 0.15rem; }
}

/* Look → Restoration tab */
.f3-restoration-tab { display: flex; flex-direction: column; gap: 1rem; }
.f3-restore-status { margin: 0; font-size: .95rem; color: #4a4438; line-height: 1.5; }
.f3-restore-status.f3-restore-done { color: #5c6b52; }
.f3-restore-status strong { color: #2f2a20; }
.f3-restore-spin, .f3-reveal-opt.on::after { }
.f3-restore-spin {
  display: inline-block; width: 13px; height: 13px; margin-right: 4px; vertical-align: -1px;
  border: 2px solid #d8cfbd; border-top-color: #8a7a53; border-radius: 50%;
  animation: f3spin .8s linear infinite;
}
@keyframes f3spin { to { transform: rotate(360deg); } }
.f3-reveal-opts.is-disabled { opacity: .5; }
.f3-reveal-opt-name { font-size: .92rem; font-weight: 600; color: #2f2a20; }
@media (max-width: 640px) { }

/* Compact restoration tab */
.f3-restoration-tab { display: flex; flex-direction: column; gap: .8rem; }
.f3-rcard { padding: .95rem 1.1rem; }
.f3-rrow { display: flex; align-items: center; gap: 1rem; }
.f3-rrow-txt { flex: 1; min-width: 0; }
.f3-rrow-title { display: flex; align-items: center; flex-wrap: wrap; gap: .5rem; font-size: .98rem; font-weight: 700; color: #2f2a20; }
.f3-rrow-sub { margin: .2rem 0 0; font-size: .82rem; color: #6b6353; line-height: 1.4; }
.f3-rchip { font-size: .68rem; font-weight: 700; padding: .16rem .5rem; border-radius: 999px; background: #efe7d7; color: #7a7060; display: inline-flex; align-items: center; gap: .3rem; white-space: nowrap; }
.f3-rchip.is-done { background: rgba(95,113,101,.16); color: var(--sage); }
.f3-reveal-seg { display: inline-flex; border: 1px solid #e2d8c5; border-radius: 999px; overflow: hidden; background: #fff; }
.f3-reveal-seg button { border: 0; background: none; font-family: inherit; font-size: .82rem; font-weight: 600; color: #6b6353; padding: .4rem .95rem; cursor: pointer; transition: background .12s, color .12s; }
.f3-reveal-seg button:hover:not(.on) { background: #f3ecdd; }
.f3-reveal-seg button.on { background: var(--accent); color: #fffdf8; }
.f3-reveal-seg-desc { margin: .5rem 0 0; font-size: .8rem; color: #6b6353; }
.f3-reveal-body { display: flex; gap: 1.1rem; align-items: flex-start; flex-wrap: wrap; margin-top: .9rem; }
.f3-reveal-body > div:first-child { flex: 1; min-width: 170px; }
.f3-reveal-body .f3-reveal-demo { max-width: 230px; margin: 0; flex: 0 0 auto; }

/* Expand-to-fullscreen affordances */
.f3-restore-shot { position: relative; }
.f3-expand-btn {
  position: absolute; top: 8px; right: 8px; z-index: 4;
  width: 30px; height: 30px; border: 0; border-radius: 8px;
  background: rgba(27,22,18,.55); color: #fff; font-size: 15px; line-height: 1;
  display: flex; align-items: center; justify-content: center; cursor: pointer;
  opacity: 0; transition: opacity .15s ease, background .15s ease;
}
.f3-restore-shot:hover .f3-expand-btn, .f3-expand-btn:focus-visible { opacity: 1; }
.f3-expand-btn:hover { background: var(--accent); }
.f3-reveal-demo[data-reveal-expand] { cursor: zoom-in; }
.f3-expand-badge {
  position: absolute; top: 8px; right: 8px; z-index: 3;
  width: 30px; height: 30px; border-radius: 8px; background: rgba(27,22,18,.5); color: #fff;
  display: flex; align-items: center; justify-content: center; font-size: 15px;
  opacity: 0; transition: opacity .15s ease; pointer-events: none;
}
.f3-reveal-demo[data-reveal-expand]:hover .f3-expand-badge { opacity: 1; }

/* Fullscreen lightbox for restored photos + reveal preview */
.f3-fx-lightbox { position: fixed; inset: 0; z-index: 9999; background: rgba(20,16,12,.85); display: flex; align-items: center; justify-content: center; padding: 4vw; animation: fxfade .16s ease; }
@keyframes fxfade { from { opacity: 0; } to { opacity: 1; } }
.f3-fx-lightbox-inner { position: relative; display: flex; flex-direction: column; align-items: center; gap: .7rem; max-width: 94vw; }
.f3-fx-lightbox-stage { width: min(1000px, 92vw); max-height: 84vh; display: flex; }
.f3-fx-lightbox-stage .ba-slider { width: 100%; max-height: 84vh; }
.f3-fx-lightbox-stage .f3-reveal-demo-lg { width: 100%; max-width: none; max-height: 84vh; }
.f3-fx-lightbox-close { z-index: 10; /* LB7 — same guard as the slide lightbox */ position: absolute; top: -44px; right: 0; width: 38px; height: 38px; border: 0; border-radius: 50%; background: rgba(255,255,255,.16); color: #fff; font-size: 18px; cursor: pointer; transition: background .15s ease; }
.f3-fx-lightbox-close:hover { background: rgba(255,255,255,.32); }
.f3-fx-lightbox-cap { color: #f3ece0; font-size: .85rem; margin: 0; }

/* Live looping reveal preview */
.f3-reveal-demo { position: relative; width: 100%; max-width: 440px; margin: 0 auto; border-radius: 12px; overflow: hidden; aspect-ratio: var(--rd-aspect, 3 / 2); background: #1b1612; box-shadow: 0 8px 22px rgba(40,32,16,.18); }
.f3-reveal-demo .rd-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.f3-reveal-demo .rd-after { opacity: 0; }
.f3-reveal-demo.style-dissolve .rd-after { animation: rdDissolve 4.6s ease-in-out infinite; }
@keyframes rdDissolve { 0%,14%{opacity:0} 44%,72%{opacity:1} 100%{opacity:0} }
.f3-reveal-demo.style-wipe .rd-after { opacity: 1; clip-path: inset(0 100% 0 0); animation: rdWipe 4.6s ease-in-out infinite; }
@keyframes rdWipe { 0%,14%{clip-path:inset(0 100% 0 0)} 50%,74%{clip-path:inset(0 0 0 0)} 100%{clip-path:inset(0 100% 0 0)} }
.f3-reveal-demo.style-bloom .rd-after { animation: rdBloom 4.6s ease-in-out infinite; }
@keyframes rdBloom { 0%,14%{opacity:0;filter:brightness(1.9) blur(5px)} 46%{opacity:1;filter:brightness(1.25) blur(1px)} 72%{opacity:1;filter:brightness(1) blur(0)} 100%{opacity:0;filter:brightness(1.9) blur(5px)} }
@media (prefers-reduced-motion: reduce) { .f3-reveal-demo .rd-after { animation: none !important; opacity: 1; clip-path: none; filter: none; } }

/* Per-photo use-restored / keep-original choice */
.f3-restore-item { display: flex; flex-direction: column; gap: .5rem; }
.f3-restore-item.is-original .ba-slider, .f3-restore-item.is-original .ba-wrap { opacity: .82; }
.f3-restore-choice { display: inline-flex; align-self: center; border: 1px solid #e2d8c5; border-radius: 999px; overflow: hidden; background: #fff; }
.f3-restore-choice button { border: 0; background: none; font-family: inherit; font-size: .78rem; font-weight: 600; color: #6b6353; padding: .38rem .8rem; cursor: pointer; transition: background .12s, color .12s; }
.f3-restore-choice button:hover:not(.on) { background: #f3ecdd; }
.f3-restore-choice button.on { background: var(--accent); color: #fffdf8; }

/* Photo Effects → Opening Animation tab */
.f3-effects-tab { display: flex; flex-direction: column; gap: 1rem; }
.f3-anim-hero { position: relative; width: 190px; margin: .4rem auto 0; border-radius: 12px; overflow: hidden; box-shadow: 0 8px 22px rgba(40,32,16,.16); }
.f3-anim-hero img { display: block; width: 100%; height: auto; }

/* Backdrop-only preview (guided path Backdrop step): just the selected
   backdrop image, no photo/composition overlaid. */
.backdrop-only-stage {
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

/* Guided path, Composition step — LIVE PREVIEW is the hero: centered on top,
   large; the compositions sit in a single horizontal scroll strip below it,
   each tile a live thumbnail of the photo in that composition. */
/* Guided path, Composition step — LIVE PREVIEW is the hero: centered on top,
   large; the compositions sit in a single horizontal scroll strip below it. */
.film-style-layout.fs-comp-hero {
  grid-template-columns: minmax(0, 1fr);
  justify-items: center;
}
.fs-comp-hero .film-style-body,
.fs-comp-hero .composition-page-card,
.fs-comp-hero .composition-page-body,
.fs-comp-hero .fs-comp-strip-wrap,
.fs-comp-hero .fs-comp-strip {
  min-width: 0;
  max-width: 100%;
}
.fs-comp-hero .preview-pane {
  order: -1;
  position: static;
  width: 100%;
  max-width: 760px;
  margin: 0 auto 0.5rem;
  text-align: center;
}
.fs-comp-hero .preview-pane .eyebrow { text-align: center; }
.fs-comp-hero .film-style-body {
  width: 100%;
  max-width: 980px;
}

/* Horizontal strip of live composition thumbnails. The wrap adds a soft fade +
   peek on the right so it's obvious there's more to scroll. */
.fs-comp-strip-wrap { position: relative; }
/* LM4 — the fade is the only sign that the strip scrolls, and it used to sit
   there permanently: still showing at the far right end (so it read as
   decoration) and giving no cue at all that you could scroll back left. It is
   now driven by the strip's actual scroll position — see bindCompStripAffordance. */
.fs-comp-strip-wrap::after,
.fs-comp-strip-wrap::before,
.fs-hscroll-wrap::after,
.fs-hscroll-wrap::before {
  content: "";
  position: absolute;
  top: 0; bottom: 12px;
  width: 44px;
  pointer-events: none;
  opacity: 0;
  transition: opacity .18s ease;
}
.fs-comp-strip-wrap::after,
.fs-hscroll-wrap::after {
  right: 0;
  background: linear-gradient(to right, rgba(255, 253, 249, 0), #fff);
}
.fs-comp-strip-wrap::before,
.fs-hscroll-wrap::before {
  left: 0;
  background: linear-gradient(to left, rgba(255, 253, 249, 0), #fff);
  z-index: 1;
}
.fs-comp-strip-wrap.has-more-right::after,
.fs-comp-strip-wrap.has-more-left::before,
.fs-hscroll-wrap.has-more-right::after,
.fs-hscroll-wrap.has-more-left::before { opacity: 1; }
/* A plain sentence beats a subtle gradient on a phone, where half the strip is
   off-screen. Only rendered while there is actually more to the right. */
.fs-comp-strip-hint {
  margin: 0.15rem 0 0; text-align: center;
  font-size: 0.78rem; color: #6b6154; opacity: 0;
  transition: opacity .18s ease;
}
.fs-comp-strip-wrap.has-more-right + .fs-comp-strip-hint,
.fs-hscroll-wrap.has-more-right + .fs-comp-strip-hint { opacity: 1; }
@media (min-width: 821px) { .fs-comp-strip-hint { display: none; } }
.fs-comp-strip {
  display: flex;
  gap: 0.7rem;
  overflow-x: auto;
  overflow-y: hidden;
  padding: 0.25rem 0.25rem 0.75rem;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
}
.fs-comp-strip-tile {
  flex: 0 0 auto;
  width: 172px;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding: 0;
  border: 2px solid transparent;
  border-radius: 11px;
  background: none;
  cursor: pointer;
  scroll-snap-align: start;
  text-align: center;
  transition: transform 0.12s ease;
}
.fs-comp-strip-tile:hover { transform: translateY(-2px); }
.fs-comp-strip-thumb {
  display: block;
  width: 100%;
  border-radius: 9px;
  overflow: hidden;
  border: 1px solid rgba(120, 100, 80, 0.22);
  box-shadow: 0 4px 12px -6px rgba(56, 44, 29, 0.35);
}
.fs-comp-strip-thumb .preview-stage {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  border-radius: 0;
}
.fs-comp-strip-diagram { display: block; width: 100%; aspect-ratio: 16 / 9; }
.fs-comp-strip-diagram svg { width: 100%; height: 100%; display: block; }
.fs-comp-strip-label {
  font-size: 0.74rem;
  font-weight: 600;
  color: #6a6255;
  line-height: 1.2;
}
.fs-comp-strip-tile.is-active .fs-comp-strip-thumb {
  border-color: var(--accent);
  box-shadow: 0 0 0 2.5px rgba(118, 66, 57, 0.55), 0 6px 16px -6px rgba(56, 44, 29, 0.4);
}
.fs-comp-strip-tile.is-active .fs-comp-strip-label { color: var(--accent); font-weight: 700; }

.fs-comp-edit-hint {
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--muted, #9a9081);
  font-size: 0.72rem;
  margin-left: 0.45rem;
}
/* Select-only edit mode (guided composition step): keep click-to-select + the
   floating toolbar, but hide every drag/resize affordance so nothing can be
   moved or scaled — the family only restyles. */
.titlecard-stage.is-select-only .backdrop-text-resize-handle,
.titlecard-stage.is-select-only .titlecard-handle,
.titlecard-stage.is-select-only .backdrop-group-box {
  display: none !important;
}
/* Softer selection affordance: pointer cursor on the editable words/photo. */
.titlecard-stage.is-select-only [data-selectable-element] { cursor: pointer; }

/* ── Guided edit bar (compact) ────────────────────────────────────────────
   A slim light pill bar docked below the preview. Tapping a pill reveals ONE
   small inline strip. Never floats over the photo, never overflows. */
/* The preview pane is display:grid; pin its column so a wide edit strip scrolls
   INSIDE its box instead of stretching the column (and the stage) to fit. */
.fs-comp-edit-pane { grid-template-columns: minmax(0, 1fr); }
.fs-comp-edit-dock { width: 100%; min-width: 0; max-width: 100%; margin: 0.7rem auto 0; }
.fs-comp-edit-dock:not(.is-open) { display: none; }

/* "Customize" entry button — top-left of the guided opening preview. */
.fs-comp-stage-wrap { position: relative; }
.fs-customize-open {
  position: absolute; top: 12px; left: 12px; z-index: 6;
  display: inline-flex; align-items: center; gap: 6px;
  background: rgba(255,253,248,.94); border: 1px solid #e5ddcc; border-radius: 999px;
  padding: 0.4rem 0.85rem; font: inherit; font-size: 0.8rem; font-weight: 600; color: #4a4438;
  cursor: pointer; box-shadow: 0 6px 16px -8px rgba(56,44,29,.5);
}
.fs-customize-open:hover { background: #fff; border-color: #b8ae9c; }
.fs-customize-open .ti { font-size: 0.95rem; }

/* Full-screen "Customize the opening" editor overlay. */
.fs-customize {
  position: fixed; inset: 0; z-index: 1000;
  background: rgba(38,30,20,.62); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
  display: flex; flex-direction: column; align-items: center;
  padding: 22px 20px 40px; overflow: auto;
}
.fs-customize-head {
  width: min(1080px, 94vw); display: flex; align-items: flex-start; justify-content: space-between;
  gap: 18px; margin-bottom: 16px;
}
.fs-customize-title { margin: 0; font-family: "Playfair Display", Georgia, serif; font-size: 1.2rem; color: #fff; }
.fs-customize-hint { margin: 3px 0 0; font-size: 0.82rem; line-height: 1.45; color: rgba(255,255,255,.78); max-width: 62ch; }
.fs-customize-done {
  flex: 0 0 auto; border: 0; background: #fffdf8; color: #3a332a; border-radius: 999px;
  padding: 0.55rem 1.4rem; font: inherit; font-size: 0.9rem; font-weight: 600; cursor: pointer;
  box-shadow: 0 6px 16px -8px rgba(0,0,0,.4);
}
.fs-customize-done:hover { background: #f3ede0; }
.fs-customize-stagewrap { width: min(1080px, 94vw); position: relative; }
.fs-customize-stagewrap > .preview-stage,
.fs-customize-stagewrap > .titlecard-stage { width: 100%; max-width: 100%; }

/* Show/hide (add / re-add) element chips in the Customize editor. */
.fs-customize-elements {
  width: min(1080px, 94vw); display: flex; align-items: center; gap: 8px;
  flex-wrap: wrap; margin: 0 0 12px;
}
.fs-el-label { font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase; color: rgba(255,255,255,.7); font-weight: 700; margin-right: 2px; }
.fs-el-chip {
  display: inline-flex; align-items: center; gap: 6px; cursor: grab;
  padding: 0.32rem 0.7rem 0.32rem 0.55rem; border-radius: 999px; font-size: 0.85rem;
  background: rgba(255,255,255,.12); border: 1px solid rgba(255,255,255,.28); color: rgba(255,255,255,.82);
  transition: background 0.14s ease, border-color 0.14s ease;
  touch-action: none; user-select: none;
}
.fs-el-chip input { position: absolute; opacity: 0; width: 0; height: 0; }
.fs-el-chip::before { content: "＋"; font-weight: 700; opacity: .8; }
.fs-el-chip.on { background: #fffdf8; border-color: #fffdf8; color: #3a332a; }
.fs-el-chip.on::before { content: "✓"; color: #607365; }
.fs-el-chip:hover { border-color: rgba(255,255,255,.55); }
/* Drag-to-reorder grip (two columns of dots). */
.fs-el-grip {
  width: 7px; height: 13px; flex: 0 0 auto; opacity: .4;
  background-image: radial-gradient(currentColor 1px, transparent 1.5px);
  background-size: 3.5px 4px; background-position: 0 1px; background-repeat: repeat;
}
.fs-el-chip:hover .fs-el-grip { opacity: .65; }
.fs-el-chip.is-chip-dragging {
  cursor: grabbing; z-index: 5; position: relative;
  box-shadow: 0 10px 24px -10px rgba(0,0,0,.55); opacity: .97;
}
.fs-el-chip.is-chip-shift { border-color: #607365; }

/* Header actions (Undo + Done). */
.fs-customize-headactions { display: flex; align-items: center; gap: 10px; }
.fs-customize-undo {
  display: inline-flex; align-items: center; gap: 5px; cursor: pointer;
  padding: 0.42rem 0.85rem; border-radius: 999px; font-size: 0.85rem; font-weight: 600;
  background: rgba(255,255,255,.12); border: 1px solid rgba(255,255,255,.32); color: rgba(255,255,255,.9);
  transition: background .14s ease, border-color .14s ease, opacity .14s ease;
}
.fs-customize-undo:hover:not(:disabled) { background: rgba(255,255,255,.2); border-color: rgba(255,255,255,.5); }
.fs-customize-undo:disabled { opacity: .38; cursor: default; }
.fs-customize-undo .ti { font-size: 1rem; }
/* Reset all — secondary/destructive, kept quiet so it doesn't compete. */
.fs-customize-resetall {
  cursor: pointer; padding: 0.42rem 0.7rem; border-radius: 999px; font-size: 0.82rem; font-weight: 600;
  background: transparent; border: 1px solid transparent; color: rgba(255,255,255,.58);
  transition: color .14s ease, background .14s ease;
}
.fs-customize-resetall:hover { color: #fff; background: rgba(255,255,255,.12); }

/* Status bar: empty-state coaching + "Editing: X" + per-element actions. */
.fs-cz-statusbar {
  width: min(1080px, 94vw); min-height: 34px; display: flex; align-items: center; gap: 12px;
  margin: 0 0 10px; padding: 0 2px; flex-wrap: wrap;
}
.fs-cz-hint { font-size: 0.82rem; color: rgba(255,255,255,.62); }
.fs-cz-editing { font-size: 0.85rem; color: rgba(255,255,255,.82); }
.fs-cz-editing b { color: #fffdf8; font-weight: 700; }
.fs-cz-acts { display: inline-flex; gap: 8px; }
.fs-cz-act {
  cursor: pointer; padding: 0.28rem 0.8rem; border-radius: 999px; font-size: 0.8rem; font-weight: 600;
  background: #fffdf8; border: 1px solid #fffdf8; color: #3a332a;
  transition: background .14s ease, transform .1s ease;
}
.fs-cz-act:hover { background: #efe9db; }
.fs-cz-act:active { transform: translateY(1px); }
.fs-cz-tip { font-size: 0.74rem; color: rgba(255,255,255,.44); margin-left: auto; }

/* Opening-photo picker strip. */
.fs-cz-photopick { width: min(1080px, 94vw); margin: 0 0 12px; }
.fs-cz-photopick-label { display: block; font-size: 0.74rem; letter-spacing: .08em; text-transform: uppercase; color: rgba(255,255,255,.6); font-weight: 700; margin: 0 0 6px; }
.fs-cz-photopick-strip { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 4px; }
.fs-cz-photothumb {
  flex: 0 0 auto; width: 66px; height: 66px; padding: 0; cursor: pointer; overflow: hidden;
  border-radius: 10px; border: 2px solid rgba(255,255,255,.28); background: none; transition: border-color .14s ease, transform .1s ease;
}
.fs-cz-photothumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.fs-cz-photothumb:hover { border-color: rgba(255,255,255,.7); }
.fs-cz-photothumb.is-current { border-color: #607365; box-shadow: 0 0 0 2px rgba(96,115,101,.4); }

/* Stage affordance: keep the card calm. The dashed box + resize dots stay
   hidden and only appear when you hover an element (or it's selected / being
   resized), rather than boxing every line all the time. */
.fs-customize .titlecard-preamble,
.fs-customize .titlecard-name,
.fs-customize .titlecard-dates,
.fs-customize .titlecard-year,
.fs-customize .titlecard-chapter {
  outline-color: rgba(96,115,101,0) !important;
}
.fs-customize .backdrop-text-resize-handle { opacity: 0; }
.fs-customize .titlecard-preamble:hover,
.fs-customize .titlecard-name:hover,
.fs-customize .titlecard-dates:hover,
.fs-customize .titlecard-year:hover,
.fs-customize .titlecard-chapter:hover {
  outline-color: rgba(96,115,101,.7) !important; background-color: rgba(96,115,101,.08);
}
/* Selected: solid sage box + its resize dots stay visible so you can grab it. */
.fs-customize .titlecard-preamble.is-selected,
.fs-customize .titlecard-name.is-selected,
.fs-customize .titlecard-dates.is-selected,
.fs-customize .titlecard-year.is-selected,
.fs-customize .titlecard-chapter.is-selected {
  outline: 2px solid #607365 !important; outline-offset: 3px;
  background-color: rgba(96,115,101,.1);
}
.fs-customize .titlecard-preamble.is-selected .backdrop-text-resize-handle,
.fs-customize .titlecard-name.is-selected .backdrop-text-resize-handle,
.fs-customize .titlecard-dates.is-selected .backdrop-text-resize-handle,
.fs-customize .titlecard-year.is-selected .backdrop-text-resize-handle,
.fs-customize .titlecard-chapter.is-selected .backdrop-text-resize-handle {
  opacity: 1;
}
.fs-customize .titlecard-portrait.is-selected { outline: 2px solid #607365; outline-offset: 2px; }

/* Keep the selected element's controls available at rest, but get them out of
   the way for the whole manipulation gesture. Pointer handlers already add
   these classes for move, resize, and in-frame pan, so the toolbar returns as
   soon as the gesture ends without rebuilding or losing the selection. */
.fs-customize:has(.is-dragging, .is-resizing, .is-panning) [data-backdrop-floating-toolbar] {
  opacity: 0 !important;
  visibility: hidden !important;
  pointer-events: none !important;
}

/* Nicer, lighter floating toolbar — scoped to the Customize overlay so the
   calm cream palette matches the rest of the guided flow (the shared dark
   pill stays as-is on the other path). */
.fs-customize .bft-pill { background: #fffdf9; color: #4a4438; border: 1px solid #e5ddcc; border-radius: 16px; box-shadow: 0 14px 34px -14px rgba(56,44,29,.6); }
.fs-customize .bft-element-label { color: #9a9081; border-right-color: #ece5d6; }
.fs-customize .bft-chip, .fs-customize .bft-segment { color: #4a4438; border-right-color: #ece5d6; }
.fs-customize .bft-chip:hover { background: #f3ede0; }
.fs-customize .bft-chip.is-open { background: rgba(96,115,101,.14); }
.fs-customize .bft-chip-label { color: #9a9081; }
.fs-customize .bft-chip-value { color: #4a4438; }
.fs-customize .bft-chip-caret { color: #9a9081; }
.fs-customize .bft-color-dot { border-color: rgba(0,0,0,.15); }
.fs-customize .bft-segment-item { color: #8b8375; }
.fs-customize .bft-segment-item:hover { color: #4a4438; }
.fs-customize .bft-segment-item.is-active { background: #607365; color: #fffdf8; }
.fs-customize .bft-arrow { background: #fffdf9; }
.fs-customize .bft-popover { background: #fffdf9; border: 1px solid #e5ddcc; box-shadow: 0 16px 36px -14px rgba(56,44,29,.5); }
.fs-customize .bft-popover-head { color: #9a9081; }
.fs-customize .bft-popover-divider { background: #ece5d6; }
.fs-customize .bft-popover-item { color: #4a4438; }
.fs-customize .bft-popover-item:hover { background: #f3ede0; }
.fs-customize .bft-popover-item.is-active { background: rgba(96,115,101,.14); color: #3f4a3f; }

.gedit-bar {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  background: #fffdf9; border: 1px solid #e5ddcc; border-radius: 999px;
  padding: 6px 8px; box-shadow: 0 10px 26px -20px rgba(56,44,29,.45);
  width: fit-content; max-width: 100%; margin: 0 auto;
}
.gedit-who { font-size: 0.78rem; color: #8b8375; padding: 0 4px 0 8px; white-space: nowrap; }
.gedit-who b { color: #4a4438; font-weight: 700; }
.gedit-sep { width: 1px; align-self: stretch; background: #e5ddcc; margin: 2px; }
.gedit-flex { flex: 1; min-width: 4px; }
.gedit-pill {
  border: 0; background: transparent; border-radius: 999px; padding: 0.42rem 0.8rem;
  font: inherit; font-size: 0.85rem; color: #5c554a; cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px; transition: background 0.14s ease;
}
.gedit-pill:hover { background: #f3ede0; }
.gedit-pill.on { background: rgba(96,115,101,.14); color: #3f4a3f; font-weight: 600; }
.gedit-swi { width: 14px; height: 14px; border-radius: 50%; border: 1px solid rgba(0,0,0,.15); }
.gedit-done {
  border: 0; background: #4a4438; color: #fffdf8; border-radius: 999px;
  padding: 0.42rem 0.95rem; font: inherit; font-size: 0.8rem; cursor: pointer;
}
.gedit-done:hover { background: #5c554a; }

/* ── Slides tab live preview (portrait + landscape sample slides) ── */
.f3-slides-preview { max-width: 1160px; margin: 0 auto 1.6rem; text-align: center; }
.f3-slides-preview-eyebrow {
  font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: #7a6f5c; font-weight: 700; margin: 0 0 0.85rem;
}
.f3-slides-preview-eyebrow span {
  text-transform: none; letter-spacing: normal; font-weight: 400;
  color: #a99e8b; margin-left: 0.45rem;
}
.f3-slide-pv { margin: 0; }
.f3-slide-pv-zoom {
  position: absolute; top: 9px; right: 9px; z-index: 5;
  background: rgba(30, 24, 16, 0.62); color: #fff; font-size: 0.72rem;
  padding: 4px 9px; border-radius: 999px; letter-spacing: 0.02em;
  opacity: 0; transition: opacity 0.14s ease; pointer-events: none;
}
.f3-slide-pv-stage:hover .f3-slide-pv-zoom,
.f3-slide-pv-stage:focus-visible .f3-slide-pv-zoom { opacity: 1; }
.f3-slide-pv figcaption { margin-top: 0.6rem; font-size: 0.84rem; color: #8b8375; }
.f3-slide-pv-empty {
  display: flex; align-items: center; justify-content: center;
  aspect-ratio: 16 / 9; background: #f3ede0; color: #a99e8b;
  font-size: 0.85rem; border: 1px dashed #d9cfb8; cursor: default;
}
.f3-slide-pv-empty:hover { transform: none; box-shadow: 0 12px 30px -18px rgba(56, 44, 29, 0.5); }
@media (max-width: 720px) {
}

/* Enlarge lightbox */
.f3-slide-lightbox {
  position: fixed; inset: 0; z-index: 4000;
  display: flex; align-items: center; justify-content: center;
  background: rgba(30, 24, 16, 0.72); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
  padding: 4vh 4vw; animation: f3lb-fade 0.16s ease-out;
}
@keyframes f3lb-fade { from { opacity: 0; } to { opacity: 1; } }
.f3-slide-lightbox-inner { position: relative; width: min(94vw, 1180px); }
.f3-slide-lightbox-stage {
  border-radius: 16px; overflow: hidden;
  box-shadow: 0 30px 70px -20px rgba(0, 0, 0, 0.7);
}
.f3-slide-lightbox-cap { margin: 0.85rem 0 0; color: #f3ecdd; font-size: 0.95rem; text-align: center; }
.f3-slide-lightbox-close {
  /* LB7 — this button is nudged over the corner of .f3-slide-lightbox-stage,
     which is a positioned sibling that comes later in the DOM: with both at
     z-index:auto the stage painted on top and ate every click on the ✕, so
     Escape was the only way out of an enlarged preview. */
  z-index: 10;
  position: absolute; top: -16px; right: -16px; width: 44px; height: 44px;
  border-radius: 50%; border: 0; background: #fffdf9; color: #4a4438;
  font-size: 1.1rem; line-height: 1; cursor: pointer;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.4);
}
.f3-slide-lightbox-close:hover { background: #fff; }

/* ── Slides tab: Portrait/Landscape inner tabs, big hero preview, tile strip ── */
.f3-slides { max-width: 1000px; margin: 0 auto; }
.f3-slides-oritabs { justify-content: center; margin: 0 auto 1.3rem; }
.f3-slides-hero { max-width: 760px; margin: 0 auto 1.6rem; text-align: center; }
.f3-slides-hero-stage {
  position: relative; border-radius: 16px; overflow: hidden;
  border: 1px solid #e5ddcc; box-shadow: 0 16px 40px -20px rgba(56, 44, 29, 0.55);
  cursor: pointer; transition: box-shadow 0.16s ease, transform 0.16s ease;
}
.f3-slides-hero-stage:hover { box-shadow: 0 22px 52px -18px rgba(56, 44, 29, 0.6); transform: translateY(-2px); }
.f3-slides-hero-stage:focus-visible { outline: 2px solid #6b7c8c; outline-offset: 3px; }
.f3-slides-hero-stage .preview-stage {
  width: 100%; height: auto; aspect-ratio: 16 / 9; border-radius: 0;
}
.f3-slides-hero-stage.f3-slide-pv-empty { cursor: default; }
.f3-slides-hero .preview-caption { margin-top: 0.6rem; color: #8b8375; font-size: 0.85rem; }
.f3-slides-comp { max-width: 1000px; margin: 0 auto; text-align: center; }
.f3-slides-comp-title {
  font-size: 0.9rem; font-weight: 700; color: #4a4438; margin: 0 0 0.7rem;
}
.f3-slides-comp-title span {
  display: block; font-weight: 400; font-size: 0.8rem; color: #8b8375; margin-top: 0.2rem;
}
.f3-slides-comp .fs-comp-strip { justify-content: flex-start; }

/* Shared Left/Right toggle for the collapsed split compositions. Sits centered
   below the Composition title; greyed + non-interactive unless the selected
   composition is a split. */
.f3-slides-side-toggle {
  display: inline-flex; align-items: center; gap: 0.35rem;
  margin: 0 auto 0.9rem; padding: 0.25rem;
  background: #f2ecdf; border: 1px solid #e2d9c6; border-radius: 999px;
  transition: opacity 0.16s ease;
}
.f3-slides-side-toggle .f3-slides-side-cap {
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
  color: #8b8375; padding: 0 0.4rem 0 0.55rem;
}
.f3-slides-side-toggle button {
  border: 0; background: transparent; cursor: pointer;
  font-size: 0.82rem; font-weight: 600; color: #6a6252;
  padding: 0.3rem 0.85rem; border-radius: 999px;
  transition: background 0.14s ease, color 0.14s ease, box-shadow 0.14s ease;
}
.f3-slides-side-toggle button:hover:not(.on):not(:disabled) { color: #4a4438; background: #e8e0cf; }
.f3-slides-side-toggle button.on {
  background: #4a4033; color: #fdfbf5;
  box-shadow: 0 2px 6px -2px rgba(56, 44, 29, 0.5);
}
.f3-slides-side-toggle.is-disabled { opacity: 0.42; }
.f3-slides-side-toggle.is-disabled button { cursor: not-allowed; }

/* "Preview" inner tab — all three live previews (Opening, Portrait, Landscape)
   stacked so the whole film's look is visible at a glance. */
/* Break out of the wizard's centered column so the previews are actually large.
   The negative margin shifts the wider block left by half its overflow past the
   parent, keeping it centered in the viewport. Triangle layout: Opening on top,
   the two slides side by side below. */
.f3-preview-all {
  --pw: min(62vw, 860px);
  width: var(--pw);
  margin-left: calc((100% - var(--pw)) / 2);
  margin-right: 0;
}
.f3-preview-eyebrow { text-align: center; margin-bottom: 1.1rem; }
.f3-preview-top { display: flex; justify-content: center; margin-bottom: 1.4rem; }
.f3-preview-top .f3-preview-card { flex: 0 1 60%; }
.f3-preview-bottom { display: flex; flex-direction: row; align-items: flex-start; gap: 1.4rem; }
.f3-preview-bottom .f3-preview-card { flex: 1 1 0; }
.f3-preview-card { min-width: 0; text-align: center; }
.f3-preview-card-label {
  margin: 0 0 0.6rem; font-weight: 700; color: #4a4438; font-size: 1rem;
}
.f3-preview-card .f3-slides-hero-stage { width: 100%; margin: 0 auto; }

/* ── "Create your own" Opening studio — professional three-pane editor ── */
.cyo-studio{
  --cy-surface:#fffefb; --cy-well:#f3ecdd; --cy-hair:#ece5d6; --cy-hair2:#e2d8c5;
  --cy-ink:#272219; --cy-ink2:#6b6353; --cy-ink3:#a79d88;
  --cy-brass:#b0894a; --cy-brass-tint:rgba(176,137,74,.14); --cy-green:#3d4a39;
  /* CYO-POPUP — one column: the card has the room. The piece's controls are a
     pill + card placed beside the piece (absolute, inside this box). */
  display:grid; grid-template-columns:minmax(0,1fr); gap:24px; align-items:start;
  margin-top:6px; text-align:left; position:relative;
}
.cyo-empty{grid-column:1/-1;text-align:center;color:var(--cy-ink3);padding:48px 0;}
.cyo-stagecol{min-width:0;}

.cyo-chips{display:flex;align-items:center;gap:9px;margin-bottom:16px;flex-wrap:wrap;}
.cyo-chips-lab{font-size:11px;letter-spacing:.13em;color:var(--cy-ink3);text-transform:uppercase;font-weight:600;}
.cyo-chip{display:flex;align-items:center;gap:7px;background:var(--cy-surface);border:1px solid var(--cy-hair);border-radius:999px;padding:7px 14px 7px 11px;font-size:13.5px;color:var(--cy-ink);cursor:pointer;box-shadow:0 1px 2px rgba(50,40,20,.05);}
.cyo-chip input{display:none;}
.cyo-chip .cyo-chip-ck{width:16px;height:16px;border-radius:5px;background:var(--cy-green);color:#fff;font-size:10px;display:grid;place-items:center;}
.cyo-chip:not(.on) .cyo-chip-ck{background:#d9cfba;}
/* LO61 — AVAILABLE, AND LOOKING IT. K: "why its gray".
   This chip was drawn in --cy-ink3, the panel's faintest ink, back when it was
   genuinely disabled unless the pencil was on — and there was no :disabled rule
   at all, so on and off looked the same. LO60 made it always work and the
   colour was left behind, which is worse than either: a button that works and
   says it does not. The dashed edge stays, because a dashed outline is what an
   "add" affordance looks like; the ink comes up to the panel's normal weight,
   and there is now a real disabled state so a future gate cannot repeat this. */
.cyo-chip.add{color:var(--cy-ink2);border-style:dashed;border-color:var(--cy-hair2);background:transparent;box-shadow:none;font-family:inherit;}
.cyo-chip.add:hover{color:var(--cy-ink);border-color:var(--cy-brass);background:var(--cy-brass-tint);}
.cyo-chip.add[disabled]{color:var(--cy-ink3);border-color:var(--cy-hair);opacity:.55;cursor:default;}
.cyo-chip.add[disabled]:hover{color:var(--cy-ink3);border-color:var(--cy-hair);background:transparent;}
/* LO25 — the whole-opening reset, beside Add a line. Sits to the right so it
   never reads as one of the Show toggles. */
.cyo-chip-reset{margin-left:auto;color:#8a5a2a;border-color:#e8d5b8;background:#fffdf9;}
.cyo-chip-reset:hover{border-color:#b0894a;color:#6d4520;}

.cyo-canvas.fs-comp-stage-wrap{width:100%;border-radius:18px;overflow:hidden;box-shadow:0 24px 60px -18px rgba(60,46,24,.34),0 4px 12px rgba(60,46,24,.10);position:relative;}
.cyo-canvas .fs-customize-open{display:none;}
/* full edit mode brings the in-canvas floating toolbar back — suppress it here,
   the docked Properties panel is the single home for controls in the studio */
.cyo-stagecol [data-backdrop-floating-toolbar]{display:none !important;}

.cyo-strip{margin-top:22px;}
.cyo-strip-head{font-size:11px;letter-spacing:.13em;text-transform:uppercase;color:var(--cy-ink3);font-weight:600;margin:0 2px 12px;}

.cyo-panel{background:var(--cy-surface);border:1px solid var(--cy-hair);border-radius:18px;box-shadow:0 1px 2px rgba(50,40,20,.05),0 10px 26px -8px rgba(50,40,20,.10),inset 0 1px 0 #fff;overflow:hidden;position:sticky;top:20px;}
.cyo-reset{font-size:12.5px;color:var(--cy-ink3);cursor:pointer;font-weight:500;background:none;border:none;font-family:inherit;}
.cyo-reset:hover{color:var(--cy-brass);}
.cyo-panel-body{padding:14px 15px 18px;min-height:120px;}
.cyo-panel-empty{color:var(--cy-ink3);font-size:13px;line-height:1.5;display:flex;flex-direction:column;align-items:center;gap:10px;text-align:center;padding:26px 12px;}
.cyo-panel-empty-ic{font-size:22px;opacity:.6;}
/* the existing floating-toolbar dock, restyled to sit calmly in the panel */
.cyo-panel .fs-comp-edit-dock{position:static;box-shadow:none;background:none;border:none;padding:0;}
.cyo-panel .fs-comp-edit-dock-toolbar{position:static !important;flex-wrap:wrap;gap:8px;}
/* once an element is selected the dock opens — hide the empty prompt */
.cyo-panel .fs-comp-edit-dock.is-open ~ .cyo-panel-empty{display:none;}

/* ── Restyle the docked element toolbar into a vertical property panel ── */
.cyo-panel .bft-pill{display:flex;flex-direction:column;align-items:stretch;gap:1px;background:none;border:none;box-shadow:none;padding:0;position:static;}
.cyo-panel .bft-arrow{display:none;}
/* element name becomes a small uppercase section header (updates on selection) */
.cyo-panel .bft-element-label{display:block;font-size:11px;letter-spacing:.13em;text-transform:uppercase;color:#a79d88;font-weight:600;margin:0 2px 8px;}

/* PROPERTY ROWS — transparent row, muted label left, compact control right */
.cyo-panel .bft-chip{display:flex;align-items:center;width:100%;min-height:38px;height:auto;background:transparent;border:none;border-radius:8px;padding:3px 4px;gap:0;cursor:pointer;justify-content:flex-start;box-shadow:none;}
.cyo-panel .bft-chip:hover{background:rgba(120,100,60,.045);}
.cyo-panel .bft-chip-label{font-size:13px;color:#6b6353;font-weight:500;margin-right:auto;}
/* text dropdown value + caret = one compact control pill */
.cyo-panel .bft-chip-value{background:#f0e8d6;padding:7px 4px 7px 11px;border-radius:8px 0 0 8px;font-size:13px;color:#272219;font-weight:500;white-space:normal;line-height:1.25;text-align:right;max-width:158px;}
.cyo-panel .bft-chip-caret{background:#f0e8d6;padding:7px 10px 7px 6px;border-radius:0 8px 8px 0;color:#a79d88;font-size:10px;}
.cyo-panel .bft-chip:hover .bft-chip-value,.cyo-panel .bft-chip:hover .bft-chip-caret{background:#eaddc4;}
.cyo-panel .bft-chip.is-open .bft-chip-value,.cyo-panel .bft-chip.is-open .bft-chip-caret{background:#fff;box-shadow:inset 0 0 0 1.5px #b0894a;}
/* color row: swatch + bare caret as the control */
.cyo-panel .bft-color-dot{width:22px;height:22px;border-radius:6px;border:1px solid rgba(0,0,0,.12);}
.cyo-panel .bft-chip[data-toolbar-popover-open="color"] .bft-chip-caret{background:transparent;padding:0 0 0 7px;}

/* SEGMENTED rows (Shadow / Lines / Format) — connected segmented control right */
.cyo-panel .bft-segment{display:flex;align-items:center;gap:0;padding:3px 4px;min-height:38px;}
.cyo-panel .bft-segment .bft-chip-label{margin-right:auto;font-size:13px;color:#6b6353;font-weight:500;}
.cyo-panel .bft-segment-item{padding:6px 12px;font-size:12px;color:#6b6353;background:#f0e8d6;border:none;border-right:1px solid #e4d8bf;cursor:pointer;font-family:inherit;}
.cyo-panel .bft-segment-item:first-of-type{border-radius:8px 0 0 8px;}
.cyo-panel .bft-segment-item:last-of-type{border-radius:0 8px 8px 0;border-right:none;}
.cyo-panel .bft-segment-item.is-active{background:#3d4a39;color:#fff;}
.cyo-panel .bft-shadow-intensity{display:flex;align-items:center;gap:10px;padding:5px 4px 3px;}
.cyo-panel .bft-shadow-intensity .bft-chip-label{font-size:13px;color:#6b6353;font-weight:500;flex:0 0 auto;}
.cyo-panel .bft-inline-slider{flex:1;accent-color:#b0894a;}
.cyo-panel .bft-slider-value{min-width:24px;text-align:right;font-size:12.5px;color:#272219;font-variant-numeric:tabular-nums;}

/* ACTIONS — demoted to light text rows, separated from the properties above */
.cyo-panel .bft-italic-chip,.cyo-panel .bft-pencil-chip,.cyo-panel .bft-copy-from-chip,.cyo-panel .bft-trash-chip{width:100%;min-height:36px;height:auto;justify-content:flex-start;background:transparent;padding:5px 4px;color:#6b6353;font-size:13px;}
.cyo-panel .bft-italic-chip:hover,.cyo-panel .bft-pencil-chip:hover,.cyo-panel .bft-copy-from-chip:hover{background:rgba(120,100,60,.045);border-radius:8px;}
/* Italic → real on/off toggle */
.cyo-panel .bft-italic-chip::before{content:"Italic";font-size:13px;color:#6b6353;font-weight:500;margin-right:auto;}
.cyo-panel .bft-italic-chip span{display:inline-flex;width:30px;height:23px;align-items:center;justify-content:center;border-radius:7px;background:#f0e8d6;font-size:14px;color:#272219;}
.cyo-panel .bft-italic-chip.is-active span{background:#3d4a39;color:#fff;}
/* Edit text / Edit line */
.cyo-panel .bft-pencil-chip::before{content:"Edit text";font-size:13px;color:#6b6353;font-weight:500;margin-right:auto;}
.cyo-panel .bft-pencil-numbered::before{content:"Edit line";}
.cyo-panel .bft-pencil-num{margin-left:6px;font-size:12px;color:#272219;}
/* Copy from others → quiet link */
.cyo-panel .bft-copy-from-chip{color:#b0894a;font-weight:500;}
/* Remove → subtle destructive */
.cyo-panel .bft-trash-chip{color:#a1543f;}
.cyo-panel .bft-trash-chip::before{content:"Remove";font-size:13px;color:#a1543f;font-weight:500;margin-right:auto;}
.cyo-panel .bft-trash-chip:hover{background:rgba(161,84,63,.07);border-radius:8px;}

/* popovers → inline dropdown menus below the pill */
.cyo-panel .bft-popover{position:static !important;transform:none !important;inset:auto !important;width:100%;margin-top:6px;background:#fff;border:1px solid #ece5d6;border-radius:11px;box-shadow:0 8px 24px rgba(40,32,16,.12);padding:6px;max-height:280px;overflow:auto;}
.cyo-panel .bft-popover-head{font-size:11px;letter-spacing:.1em;color:#a79d88;font-weight:600;padding:5px 9px;}
.cyo-panel .bft-popover-divider{height:1px;background:#ece5d6;margin:5px 0;}
.cyo-panel .bft-popover-item{display:flex;align-items:center;gap:9px;padding:8px 10px;border-radius:8px;cursor:pointer;width:100%;background:none;border:none;font-size:13px;color:#272219;text-align:left;font-family:inherit;}
.cyo-panel .bft-popover-item:hover{background:#f3ecdd;}
.cyo-panel .bft-popover-item.is-active{background:rgba(176,137,74,.14);}
.cyo-panel .bft-popover .bft-color-dot{margin-left:0;}

/* ── Sectioned studio inspector (Content / Typography / Appearance / Position) ── */
.cyo-panel .cyi{display:flex;flex-direction:column;}
.cyi-head{padding:2px 2px 12px;border-bottom:1px solid #ece5d6;margin-bottom:4px;}
.cyi-title{font-family:'Playfair Display',Georgia,serif;font-size:19px;font-weight:600;color:#272219;}
.cyi-sect{padding:14px 0 4px;border-top:1px solid #f0e9db;}
.cyi-sect:first-of-type{border-top:none;}
.cyi-sect-h{font-size:11px;letter-spacing:.13em;text-transform:uppercase;color:#b0894a;font-weight:600;margin:0 2px 11px;}
.cyi-field{display:flex;align-items:center;gap:10px;min-height:34px;margin-bottom:10px;padding:0 2px;}
.cyi-field:last-child{margin-bottom:2px;}
.cyi-field.cyi-stack{flex-direction:column;align-items:stretch;gap:6px;}
.cyi-lab{font-size:13px;color:#6b6353;font-weight:500;flex:0 0 52px;}
.cyi-stack .cyi-lab{flex:none;}
.cyi-ctl{flex:1;display:flex;align-items:center;min-width:0;}
/* inputs + selects — bordered white, the mock's control style */
.cyi-input,.cyi-select{width:100%;height:38px;border:1px solid #e2d8c5;border-radius:9px;background:#fff;padding:0 12px;font-family:inherit;font-size:13.5px;color:#272219;box-shadow:inset 0 1px 1px rgba(60,48,28,.03);}
.cyi-input:focus,.cyi-select:focus{outline:none;border-color:#b0894a;box-shadow:0 0 0 3px rgba(176,137,74,.15);}
.cyi-select{appearance:none;-webkit-appearance:none;cursor:pointer;text-align:left;text-align-last:left;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23a79d88' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat:no-repeat;background-position:right 11px center;padding-left:12px;padding-right:30px;}
/* numeric field: bordered container = input + unit + up/down stepper */
.cyi-num{display:flex;align-items:center;border:1px solid #e2d8c5;border-radius:9px;background:#fff;overflow:hidden;height:38px;box-shadow:inset 0 1px 1px rgba(60,48,28,.03);}
.cyi-num:focus-within{border-color:#b0894a;box-shadow:0 0 0 3px rgba(176,137,74,.15);}
.cyi-num .cyi-input{border:none !important;box-shadow:none !important;flex:1;min-width:0;height:36px;padding:0 8px;text-align:left;}
.cyi-num .cyi-unit{font-size:12px;color:#a79d88;pointer-events:none;padding:0 6px 0 0;flex:0 0 auto;}
.cyi-num input[type=number]::-webkit-outer-spin-button,.cyi-num input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0;}
.cyi-step{display:flex;flex-direction:column;flex:0 0 auto;border-left:1px solid #ece2cd;}
.cyi-step-btn{border:none;background:#f7f2e8;color:#8a8069;width:24px;height:18px;font-size:8px;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0;font-family:inherit;}
.cyi-step-btn:hover{background:#efe6d3;color:#272219;}
.cyi-step-btn:first-child{border-bottom:1px solid #ece2cd;}
/* color: swatch + hex input inside one control */
.cyi-color{gap:0;border:1px solid #e2d8c5;border-radius:9px;background:#fff;overflow:hidden;height:38px;}
.cyi-color:focus-within{border-color:#b0894a;box-shadow:0 0 0 3px rgba(176,137,74,.15);}
.cyi-swatch{width:44px;align-self:stretch;flex:0 0 44px;border-right:1px solid #ece2cd;}
/* color: swatch button that opens a preset palette + custom picker */
.cyi-colorbtn{position:relative;display:flex;align-items:center;justify-content:center;gap:9px;width:100%;height:38px;border:1px solid #e2d8c5;border-radius:9px;background:#fff;padding:0 26px;cursor:pointer;font-family:inherit;font-size:13.5px;color:#272219;box-shadow:inset 0 1px 1px rgba(60,48,28,.03);}
.cyi-colorbtn.is-open,.cyi-colorbtn:focus-visible{border-color:#b0894a;box-shadow:0 0 0 3px rgba(176,137,74,.15);outline:none;}
.cyi-colorbtn .cyi-swatch{position:absolute;left:11px;top:50%;transform:translateY(-50%);width:24px;height:24px;border-radius:6px;border:1px solid rgba(0,0,0,.12);}
.cyi-colorbtn .cyi-colorval{text-align:center;}
.cyi-colorbtn .cyi-caret{position:absolute;right:11px;top:50%;transform:translateY(-50%);color:#a79d88;font-size:10px;}
.cyi-colormenu{margin:0 0 6px;border:1px solid #ece4d4;border-radius:11px;background:#fff;padding:6px 8px 8px;}
.cyi-coloropt{display:flex;align-items:center;gap:9px;width:100%;background:none;border:none;padding:8px;border-radius:8px;cursor:pointer;font-family:inherit;font-size:13px;color:#272219;}
.cyi-coloropt:hover{background:#f3ecdd;}
.cyi-coloropt.on{background:rgba(176,137,74,.14);}
.cyi-copt-dot{width:18px;height:18px;border-radius:5px;border:1px solid rgba(0,0,0,.12);flex:0 0 auto;}
.cyi-swatchgrid{display:grid;grid-template-columns:repeat(6,1fr);gap:8px;padding:8px 4px;}
/* BD-PALETTE — the backdrop's own colours sit above the palettes, each row named. */
.cyi-colorsub{font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:#8a7b5c;padding:8px 6px 0;}
.cyi-swatchgrid-bd .cyi-swatchbtn{border-color:rgba(0,0,0,.2);}
.cyi-swatchbtn{width:100%;aspect-ratio:1;border-radius:7px;border:1px solid rgba(0,0,0,.12);background:var(--sw);cursor:pointer;padding:0;}
.cyi-swatchbtn:hover{transform:scale(1.06);}
.cyi-swatchbtn.on{outline:2px solid #b0894a;outline-offset:2px;}
.cyi-customrow{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:9px 8px 4px;border-top:1px solid #f0e9db;margin-top:4px;font-size:13px;color:#6b6353;cursor:pointer;}
.cyi-customrow input[type=color]{width:38px;height:28px;border:1px solid #e2d8c5;border-radius:7px;background:#fff;cursor:pointer;padding:2px;}

/* intensity slider */
.cyi-slider{gap:10px;}
.cyi-slider input[type=range]{flex:1;accent-color:#b0894a;}
.cyi-val{min-width:22px;text-align:right;font-size:12.5px;color:#272219;font-variant-numeric:tabular-nums;}
.cyi-slider .cyi-unit{position:static;transform:none;}
/* X / Y row */
.cyi-xy{gap:8px;}
.cyi-xy .cyi-lab{flex:0 0 auto;}
.cyi-xy .cyi-lab-y{margin-left:6px;}
.cyi-xy .cyi-ctl{flex:1;}
/* reset button */
.cyi-reset{margin-top:16px;width:100%;height:42px;border:1px solid #e2d8c5;border-radius:11px;background:#fff;color:#6b6353;font-family:inherit;font-size:13.5px;font-weight:600;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:8px;}
.cyi-reset:hover{border-color:#b0894a;color:#272219;}
/* LO60 — "Place it". The line-up button borrows the reset button's shape (same
   panel, same width, same height) but sits under its own heading rather than at
   the bottom of the card, because it is something a family DOES to the piece
   and not a way of undoing what they did. It carries no top margin: the section
   heading above it already provides the space. */
.cyi-lineup{margin-top:0;}
.cyi-nudge-hint{margin:8px 2px 0;min-height:0;line-height:1.45;}
/* LO2/LO3 — Fine-tune inspector: the small help line under the Name field, and
   the button for an added line, which removes rather than resets. Warm rather
   than red: removing a line the family added is undoable-by-retyping, not a
   catastrophe, and this panel should never look alarming. */
.cyi-help{display:block;font-size:11.5px;color:#a79d88;margin:-4px 2px 8px;min-height:14px;}
/* LO47 — THE DATES CONTROL.
   One control in place of Lines / Format / Label. Closed, it shows the card's
   own dates set the way they are set; open, the eight arrangements drawn the
   same way under a tab for the line count. Everything here borrows the panel's
   existing tokens — #e2d8c5 hairline, 9px radius, #b0894a for the live one —
   so it reads as the same family of controls as the selects around it and not
   as a widget that wandered in.
   The previews are set in the CARD's serif rather than the panel's UI face:
   the point of the control is that you are looking at the thing you will get,
   and a preview in Helvetica is a description of it instead. */
.cyi-dress-field{gap:6px;}
.cyi-dress-btn{width:100%;border:1px solid #e2d8c5;border-radius:9px;background:#fff;cursor:pointer;
  padding:9px 30px 8px 12px;position:relative;font-family:inherit;text-align:center;
  box-shadow:inset 0 1px 1px rgba(60,48,28,.03);}
.cyi-dress-btn::after{content:"";position:absolute;right:11px;top:50%;width:8px;height:8px;
  border-right:2.2px solid #a79d88;border-bottom:2.2px solid #a79d88;
  transform:translateY(-70%) rotate(45deg);border-radius:1px;transition:transform .15s ease;}
.cyi-dress-btn.is-open::after{transform:translateY(-30%) rotate(225deg);}
.cyi-dress-btn:hover{border-color:#d3c4a6;}
.cyi-dress-btn.is-open,.cyi-dress-btn:focus-visible{outline:none;border-color:#b0894a;box-shadow:0 0 0 3px rgba(176,137,74,.15);}
.cyi-dress-pop{margin:0 0 10px;background:#fff;border:1px solid #e8dfcc;border-radius:12px;padding:10px;
  box-shadow:0 12px 30px -10px rgba(50,40,20,.28);}
.cyi-dress-tabs{display:flex;gap:4px;background:#f4efe4;border:1px solid #e8dfcc;border-radius:10px;padding:3px;margin:0 0 10px;}
/* LO65 — "Side by side" wrapped to two lines in an equal third of a 264px
   strip, which made the whole strip taller than the other two labels needed
   and left the chosen tab looking ragged. The tabs size to their words
   instead: "One line" and "Two lines" are short and give the long one its
   room, and the three together measure under the strip's inner width. */
.cyi-dress-tab{flex:0 1 auto;height:28px;padding:0 9px;border:0;border-radius:7px;background:transparent;
  cursor:pointer;white-space:nowrap;
  font-family:inherit;font-size:12.5px;font-weight:500;color:#8a8069;}
.cyi-dress-tab.is-on{background:#fff;color:#272219;box-shadow:0 1px 2px rgba(50,40,20,.10);}
.cyi-dress-opt{display:block;width:100%;text-align:center;border:1px solid #e2d8c5;border-radius:9px;
  background:#fff;padding:9px 10px 7px;margin-bottom:7px;cursor:pointer;font-family:inherit;
  box-shadow:inset 0 1px 1px rgba(60,48,28,.03);}
.cyi-dress-opt:last-child{margin-bottom:0;}
.cyi-dress-opt:hover{border-color:#d3c4a6;}
.cyi-dress-opt.is-on{border-color:#b0894a;box-shadow:0 0 0 3px rgba(176,137,74,.15);}
/* LO49 — K: "hard to see dates." The previews were set at 10.5px in #3b3225
   with .07em tracking, which is smaller than every other word on the panel
   (the Font and Size labels are 13.5px) and set in the lightest ink on it. A
   preview exists to be READ; the label under it can be the quiet one.
   12.5px is the largest that still fits the longest string this control ever
   draws — "SUNSET: SEPTEMBER 13, 2026" — inside a 264px card, measured rather
   than guessed, with the tracking pulled back to .03em to buy the room and
   the ink taken to near-black. */
.cyi-dress-ink{display:block;font-family:Georgia,"Times New Roman",serif;text-transform:uppercase;
  letter-spacing:.03em;font-size:12.5px;color:#241d14;line-height:1.55;}
.cyi-dress-l{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.cyi-dress-split{display:flex;align-items:center;justify-content:center;gap:5px;}
.cyi-dress-split>span{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.cyi-dress-split i{width:1px;align-self:stretch;background:#d8ccb4;}
/* LO65 — K: "side by side text dont look good in tab." Two columns do have to
   be smaller than one line of the same words, but 10.5px with the label at
   8.5px in the panel's palest gold put this tab a whole step below the other
   two: the dates read as fine print and the labels as decoration. The ceiling
   is set by the widest string this can ever draw — a long month BOTH sides,
   "SEPTEMBER 28, 1952" against "SEPTEMBER 14, 2026" — which at 10.5px and
   .04em already measured 107.6px a column inside a 244px row. So the gutter
   comes down from 9px to 5px to buy the room, the tracking from .04 to .02em,
   and the type goes up to 11.5px with the label at 9px in ink you can read.
   The columns also clip with an ellipsis now rather than overflow, so the
   worst case degrades instead of breaking the row. */
.cyi-dress-split{font-size:11.5px;letter-spacing:.02em;}
.cyi-dress-cap{display:block;font-size:9px;letter-spacing:.1em;color:#8a7248;}
.cyi-dress-name{display:block;margin-top:5px;font-size:11px;font-weight:500;color:#a79d88;}
.cyi-dress-opt.is-on .cyi-dress-name{color:#b0894a;}
.cyi-sect .f3-name-warn{margin:2px 0 8px;font-size:11.5px;}
.cyi-sect .f3-name-warn[hidden]{display:none;}
.cyi-reset-remove{color:#8a5a2a;border-color:#e8d5b8;}
.cyi-reset-remove:hover{border-color:#b0894a;color:#6d4520;background:#fdf7ee;}

/* LO5 — the opening card's dim layer. It sits directly over the background
   image and under everything else: the portrait, the name and the dates must
   stay exactly as bright as they were, or "dim the background" would quietly
   mean "dim the person". pointer-events:none so it never eats a click meant for
   an element behind it in the editor. */
   z-index 1 is the whole trick and the only value this rule may set: the
   background sits at 0 and the portrait at 2, so one layer slots exactly
   between them. Every other title-card element already carries a deliberate
   z-index (portrait 2, extra 5, year/chapter 5, text 7) — restating any of them
   here would silently retune stacking this layer has no business touching. */
.titlecard-dim {
  position: absolute; inset: 0; background: #000; opacity: 0;
  pointer-events: none; z-index: 1;
}

@media (max-width:900px){
  .cyo-studio{grid-template-columns:1fr;}
  .cyo-panel{position:static;}
}

/* Slides tab: Customize pill sits over the live-preview hero (sibling of the
   click-to-enlarge stage, not nested in it). */
.f3-slides-hero-stagewrap { position: relative; }
.fs-customize-open.f3-slide-customize-open {
  position: absolute; top: 0.7rem; left: 0.7rem; z-index: 3;
}
@media (max-width: 820px) {
  .f3-preview-all { --pw: 100%; margin-left: 0; }
  .f3-preview-top .f3-preview-card { flex-basis: 100%; }
  /* LM3 — stacking alone wasn't enough: the base rule's `align-items:flex-start`
     is a CROSS-axis rule, so once the direction flipped to column the two slide
     cards kept their intrinsic width and collapsed to ~98px and ~126px — too
     small to judge text, cropping or composition, which is the whole job of this
     tab. Stretch them to the column's full width. */
  .f3-preview-bottom { flex-direction: column; align-items: stretch; }
  .f3-preview-bottom .f3-preview-card { flex: 0 0 auto; width: 100%; }
}

/* ── Selection feedback: per-element accent, pop-on-select, flash-on-change ── */
/* The guided toolbar takes on the selected element's accent (set inline as
   --gedit-accent) so it visually matches the ring/glow on the card. It also
   sits on a whiter surface with an accent ring so it reads as an active
   control panel, not page chrome. */
.gedit { --gedit-accent: #6b7c8c; }
.gedit-bar {
  background: #ffffff;
  border-color: #b4b6b2;
  border-color: color-mix(in srgb, var(--gedit-accent) 40%, #e5ddcc);
  box-shadow: 0 14px 30px -16px rgba(56, 44, 29, 0.55), 0 0 0 3px rgba(107, 124, 140, 0.15);
  box-shadow:
    0 14px 30px -16px rgba(56, 44, 29, 0.55),
    0 0 0 3px color-mix(in srgb, var(--gedit-accent) 15%, transparent);
}
.gedit-dot {
  width: 11px; height: 11px; border-radius: 50%;
  display: inline-block; vertical-align: -1px; margin-right: 7px;
  background: var(--gedit-accent);
  box-shadow: 0 0 0 3px rgba(107, 124, 140, 0.22);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--gedit-accent) 22%, transparent);
}
.gedit-who b { color: #5d6975; color: color-mix(in srgb, var(--gedit-accent) 78%, #2c2622); }
.gedit-pill.on {
  background: rgba(107, 124, 140, 0.18);
  background: color-mix(in srgb, var(--gedit-accent) 18%, transparent);
  color: #606c79;
  color: color-mix(in srgb, var(--gedit-accent) 82%, #2c2622);
}
.gedit-strip { border-color: #c5c4bb; border-color: color-mix(in srgb, var(--gedit-accent) 26%, #e5ddcc); }

/* Pop the moment an element is selected — a quick accent glow that hugs the
   element's shape (filter drop-shadow, so it works on the photo and on text
   without disturbing their own box-shadow / outline). */
@keyframes lm-sel-pop {
  0%   { filter: drop-shadow(0 0 0 rgba(201, 162, 90, 0.55)); filter: drop-shadow(0 0 0 color-mix(in srgb, var(--sel-accent, #c9a25a) 55%, transparent)); }
  35%  { filter: drop-shadow(0 0 7px var(--sel-accent, #c9a25a)); }
  100% { filter: drop-shadow(0 0 0 rgba(201, 162, 90, 0)); filter: drop-shadow(0 0 0 color-mix(in srgb, var(--sel-accent, #c9a25a) 0%, transparent)); }
}
.sel-pop { animation: lm-sel-pop 0.5s ease-out; }

/* Flash when a change is applied — same accent glow, slightly stronger, so a
   subtle edit (font swap on two words, shape/shadow tweak) registers at once. */
@keyframes lm-el-flash {
  0%   { filter: drop-shadow(0 0 0 rgba(201, 162, 90, 0)); filter: drop-shadow(0 0 0 color-mix(in srgb, var(--sel-accent, #c9a25a) 0%, transparent)); }
  40%  { filter: drop-shadow(0 0 9px var(--sel-accent, #c9a25a)); }
  100% { filter: drop-shadow(0 0 0 rgba(201, 162, 90, 0)); filter: drop-shadow(0 0 0 color-mix(in srgb, var(--sel-accent, #c9a25a) 0%, transparent)); }
}
.just-changed { animation: lm-el-flash 0.52s ease-out; }

@media (prefers-reduced-motion: reduce) {
  .sel-pop, .just-changed { animation: none; }
}

/* revealed strip — one line, scrolls horizontally if needed */
.gedit-strip {
  display: flex; gap: 8px; overflow-x: auto; align-items: center;
  background: #fffdf9; border: 1px solid #e5ddcc; border-radius: 14px;
  padding: 9px 11px; box-shadow: 0 10px 26px -20px rgba(56,44,29,.4);
  margin: 8px auto 0; width: fit-content; max-width: 100%;
}
.gedit-strip::-webkit-scrollbar { height: 0; }
.gedit-fsw {
  flex: 0 0 auto; padding: 6px 11px; border: 1.5px solid #d8d0c2; border-radius: 11px;
  background: #fff; cursor: pointer; display: flex; flex-direction: column; gap: 3px;
  align-items: center; transition: border-color 0.14s ease;
}
.gedit-fsw:hover { border-color: #b8ae9c; }
.gedit-fsw.on { border-color: #607365; box-shadow: 0 0 0 2px rgba(96,115,101,.14); }
.gedit-fsw-demo { font-size: 1.15rem; line-height: 1.1; color: #2f2a20; white-space: nowrap; }
.gedit-fsw-cap { font-size: 0.6rem; color: #9a9081; letter-spacing: 0.02em; }

.gedit-strip-dots { gap: 12px; }
.gedit-strip-color .gedit-seglbl { align-self: center; }
.gedit-cdot-wrap {
  flex: 0 0 auto; border: 0; background: none; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 5px; padding: 2px;
}
.gedit-cdot { width: 28px; height: 28px; border-radius: 50%; border: 1px solid rgba(0,0,0,.12); box-shadow: 0 1px 3px rgba(0,0,0,.1); transition: box-shadow 0.14s ease; }
.gedit-cdot-wrap.on .gedit-cdot { box-shadow: 0 0 0 3px rgba(96,115,101,.14), 0 0 0 1.5px #607365; }
.gedit-cdot-cap { font-size: 0.6rem; color: #6a6255; }
/* Custom color swatch — rainbow dot with an invisible native picker on top. */
.gedit-cdot-customwrap { position: relative; }
.gedit-cdot-custom { background: conic-gradient(#e26d6d, #e2c96d, #8fce7e, #6db6e2, #9a7ee2, #e26db4, #e26d6d); }
.gedit-color-input { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; border: 0; padding: 0; }

.gedit-chip {
  flex: 0 0 auto; border: 1.5px solid #d8d0c2; background: #fff; border-radius: 999px;
  padding: 0.5rem 1rem; font-family: "EB Garamond", Georgia, serif; font-style: italic;
  font-size: 1rem; color: #4a4438; cursor: pointer; white-space: nowrap; transition: border-color 0.14s ease;
}
.gedit-chip:hover { border-color: #b8ae9c; }
.gedit-chip.on { border-color: #607365; background: rgba(96,115,101,.14); color: #3f4a3f; }
.gedit-chip-custom { font-style: normal; font-family: Inter, system-ui, sans-serif; font-size: 0.85rem; }

/* Custom-wording text box revealed under the Wording chips. */
.gedit-custom-row { display: flex; justify-content: center; margin-top: 8px; }
.gedit-custom-input {
  width: min(440px, 92%); font-family: "EB Garamond", Georgia, serif; font-style: italic;
  font-size: 1rem; color: #4a4438; background: #fffdf9; border: 1px solid #e5ddcc;
  border-radius: 10px; padding: 0.5rem 0.8rem; text-align: center;
  resize: none; line-height: 1.35; display: block; margin: 0 auto;
}
.gedit-custom-input:focus { outline: none; border-color: #607365; box-shadow: 0 0 0 2px rgba(96,115,101,.14); }
.gedit-custom-input::placeholder { font-style: italic; color: #b3a992; font-size: 0.9rem; }

.gedit-strip-seg { gap: 6px; }
.gedit-seglbl { font-size: 0.68rem; letter-spacing: 0.08em; text-transform: uppercase; color: #9a9081; font-weight: 700; margin: 0 2px 0 6px; }
.gedit-seg {
  flex: 0 0 auto; border: 1px solid #d8d0c2; background: #fff; border-radius: 999px;
  padding: 0.4rem 0.8rem; font: inherit; font-size: 0.82rem; color: #5c554a; cursor: pointer;
}
.gedit-seg.on { background: #4a4438; border-color: #4a4438; color: #fffdf8; }
.gedit-slider { display: inline-flex; align-items: center; gap: 8px; }
.gedit-slider input[type=range] { width: 110px; }
.gedit-slider-val { font-size: 0.8rem; color: #5c554a; min-width: 2ch; text-align: right; }

.f3-depth { display: flex; gap: 0.5rem; justify-content: center; flex-wrap: wrap; margin: 0 0 1.35rem; }
.f3-depth button {
  border: 1px solid #d8d0c2; background: #fffdf9; color: #5c554a;
  border-radius: 999px; padding: 0.45rem 1.05rem; font-size: 0.88rem;
  cursor: pointer; transition: all 0.15s ease; font-family: inherit;
}
.f3-depth button:hover { border-color: #b8ae9c; }
.f3-depth button.on { background: var(--accent); border-color: var(--accent); color: #fffdf9; box-shadow: 0 4px 12px -4px rgba(118,66,57,.4); }

/* ── UX polish pass ─────────────────────────────────────────────────────────
   Consistent selected=accent language, clearer disabled states, pressed
   feedback, and keyboard focus rings across interactive elements. */

/* #7 — pressed feedback for buttons + pills */
.primary-btn:active, .ghost-btn:active, .quiet-btn:active, .f3-depth button:active,
.f3-slides-oritabs button:active { transform: translateY(1px); }

/* #6 — disabled reads as intentionally off, not broken */
.primary-btn:disabled, .primary-btn[disabled] {
  background: #ddd4c6; border-color: #ddd4c6; color: #9c9384;
  box-shadow: none; cursor: not-allowed; transform: none;
}
.primary-btn:disabled:hover, .primary-btn[disabled]:hover { background: #ddd4c6; border-color: #ddd4c6; }

/* #5 — visible keyboard focus ring (mouse clicks stay clean via :focus-visible) */
.f3-looktab:focus-visible, .f3-depth button:focus-visible, .f3-slides-oritabs button:focus-visible,
.wiz-choice:focus-visible, .wiz-mood:focus-visible, .fs-comp-strip-tile:focus-visible,
.primary-btn:focus-visible, .ghost-btn:focus-visible, .quiet-btn:focus-visible,
.wiz-dot.is-nav:focus-visible, .cyi-colorbtn:focus-visible, .f3-reveal-opt:focus-visible,
.wiz-switch:focus-visible {
  outline: 2.5px solid var(--accent); outline-offset: 2px; border-radius: 8px;
}


/* Full-width breakout for embedded step bodies (chapters, music, film style).
   Uses left + negative margin (not transform) so the wizard's entrance
   animation transforms can't override the centering. */
.f3-embed-wrap {
  width: min(1180px, calc(100vw - 2.5rem));
  position: relative;
  left: 50%;
  margin-left: max(-590px, calc((100vw - 2.5rem) / -2));
}
.f3-embed { text-align: left; }

/* Hide the embedded panels' own step-nav chrome + in-progress scaffolding —
   flow 3 provides its own navigation and voice. */
.f3 .f3-embed .row-actions,
.f3 .f3-embed .fsv2-wip-banner,
.f3 .f3-embed .fsv2-builder-callout,
.f3 .f3-embed [data-next-step],
.f3 .f3-embed [data-go-step],
.f3 .f3-embed .ai-cost-panel,
.f3 .f3-embed .cost-panel { display: none !important; }

/* Flow 3 — main-portrait reveal moment */
.f3-reveal {
  position: fixed; inset: 0; z-index: 220;
  background: rgba(30, 26, 20, 0.55); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  display: flex; align-items: center; justify-content: center;
  padding: 2rem 1.25rem; overflow-y: auto;
}
.f3-reveal-inner {
  background: #fffdf8; border-radius: 18px; box-shadow: 0 30px 80px rgba(0,0,0,0.35);
  max-width: 560px; width: 100%; padding: 2.25rem 2rem 1.75rem; text-align: center;
  max-height: calc(100vh - 4rem); max-height: calc(100dvh - 4rem); overflow-y: auto;
}
.f3-reveal-eyebrow { font-size: 0.8rem; letter-spacing: 0.14em; text-transform: uppercase; color: #9a9184; margin: 0 0 1.1rem; }
.f3-reveal-photo { max-width: 320px; margin: 0 auto 1.1rem; border-radius: 10px; overflow: hidden; box-shadow: 0 12px 34px rgba(0,0,0,0.18); }
.f3-reveal-photo img { display: block; width: 100%; height: auto; }
.f3-reveal-name { font-family: "Cormorant Garamond", serif; font-size: 1.9rem; color: #3c362c; margin: 0; }
.f3-reveal-dates { font-size: 0.9rem; color: #8a8378; margin: 0.15rem 0 0; }
.f3-reveal-sub { font-size: 0.95rem; color: #5c554a; margin: 0.9rem 0 0.35rem; }
.f3-reveal-strip {
  display: flex; gap: 0.5rem; flex-wrap: wrap; justify-content: center;
  margin-top: 1.1rem; padding-top: 1.1rem; border-top: 1px solid #eee6d8;
}

/* Flow 3 — one-tap song suggestion card */
.f3-suggest-card {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  text-align: left; flex-wrap: wrap;
}
.f3-suggest-card strong { display: block; font-size: 1rem; color: #3c362c; }
.f3-suggest-card em { display: block; font-style: normal; font-size: 0.85rem; color: #8a8378; margin-top: 0.2rem; }

/* Hide the embedded music step's own AI-suggest teaser (we seed the mood
   from the Look step instead — no re-picking). */
.f3 .f3-embed .music-ai-teaser { display: none !important; }

/* Flow 3 — finishing screen phase trail + restored reveals */
.f3-phase-trail { justify-content: center; margin-bottom: 1.4rem; }
.f3-restored { margin-top: 1.5rem; }
.f3-restored-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1rem; }

/* Flow 3 — Photos step: quiet lines + decision-free grid on first pass */
.f3-quiet-line { text-align: center; font-size: 0.82rem; color: #7a7061; margin: 0.65rem 0 0; }
.f3-quiet-line .text-link { font-size: inherit; }

/* Timeline is a permanent guided step. This quiet landing surface remains
   underneath the immersive timeline and gives Back/history a stable home. */
.f3-timeline-home {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(280px, .85fr);
  gap: clamp(1.4rem, 4vw, 3.2rem);
  align-items: center;
  overflow: hidden;
  padding: clamp(1.4rem, 4vw, 2.8rem);
}
.f3-timeline-home-art {
  position: relative;
  min-height: 320px;
  border-radius: 18px;
  background: radial-gradient(circle at 50% 46%, rgba(202,167,101,.20), transparent 56%), linear-gradient(145deg, #f5efe4, #ece2d3);
  overflow: hidden;
}
.f3-timeline-line {
  position: absolute;
  left: 7%; right: 7%; top: 50%;
  height: 2px;
  background: linear-gradient(90deg, transparent, rgba(118,66,57,.36) 10%, rgba(118,66,57,.36) 90%, transparent);
}
.f3-timeline-memory {
  position: absolute;
  width: clamp(62px, 9vw, 96px);
  aspect-ratio: 4 / 5;
  left: calc(8% + (var(--i) * 13.5%));
  top: calc(50% + 24px);
  transform: translate(-50%, 0) rotate(calc((var(--i) - 3) * .7deg));
  border: 5px solid #fffdf8;
  border-radius: 8px;
  background: #e7ddcf;
  box-shadow: 0 12px 25px rgba(62,45,28,.18);
}
.f3-timeline-memory:nth-of-type(even) { top: calc(50% - 24px); transform: translate(-50%, -100%) rotate(calc((var(--i) - 3) * .7deg)); }
.f3-timeline-memory::after {
  content: "";
  position: absolute;
  left: 50%;
  top: -29px;
  width: 1px;
  height: 24px;
  background: rgba(118,66,57,.32);
}
.f3-timeline-memory:nth-of-type(even)::after { top: auto; bottom: -29px; }
.f3-timeline-memory img { width: 100%; height: 100%; object-fit: cover; display: block; border-radius: 4px; }
.f3-timeline-home-copy h2 { margin: .2rem 0 .65rem; font-family: "Cormorant Garamond", Georgia, serif; font-size: clamp(1.65rem, 3vw, 2.2rem); color: var(--ink); }
.f3-timeline-home-copy > p:not(.eyebrow) { color: #675e52; line-height: 1.6; }
.f3-timeline-home-copy .primary-btn { margin-top: 1rem; }
.f3-timeline-opening { display: flex; align-items: center; gap: .75rem; margin-top: 1rem; padding: .65rem; border: 1px solid rgba(118,66,57,.14); border-radius: 12px; background: rgba(255,253,248,.72); }
.f3-timeline-opening img { width: 52px; height: 62px; object-fit: cover; border-radius: 7px; }
.f3-timeline-opening span { display: flex; flex-direction: column; min-width: 0; }
.f3-timeline-opening small { color: #83786a; font-size: .72rem; text-transform: uppercase; letter-spacing: .08em; }
.f3-timeline-opening strong { color: #3d362e; font-family: "Cormorant Garamond", Georgia, serif; font-size: 1.15rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 760px) {
  .f3-timeline-home { grid-template-columns: 1fr; }
  .f3-timeline-home-art { min-height: 230px; }
  .f3-timeline-memory { width: clamp(48px, 15vw, 72px); left: calc(9% + (var(--i) * 13.3%)); }
}

/* Canonical example gallery + read-only guided mode. */
.demo-gallery-section { padding: clamp(3.5rem, 8vw, 7rem) clamp(1rem, 5vw, 5rem); background: #f4efe6; border-block: 1px solid rgba(65,51,38,.09); }
.demo-gallery-grid { width: min(1180px, 100%); margin: 2rem auto 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(1rem, 2.5vw, 1.7rem); }
.demo-family-card { overflow: hidden; border: 1px solid rgba(69,51,34,.14); border-radius: 18px; background: #fffdf8; box-shadow: 0 20px 50px -34px rgba(52,36,23,.55); transition: transform .2s ease, box-shadow .2s ease; }
.demo-family-card:hover { transform: translateY(-3px); box-shadow: 0 24px 56px -32px rgba(52,36,23,.62); }
.demo-family-cover { position: relative; aspect-ratio: 4 / 3; overflow: hidden; background: linear-gradient(145deg,#e6dac9,#b8a58d); }
.demo-family-cover::after { content: ""; position: absolute; inset: 0; background: linear-gradient(to top, rgba(24,17,11,.58), transparent 52%); pointer-events: none; }
.demo-family-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.demo-family-badge, .demo-family-count { position: absolute; z-index: 1; bottom: .8rem; color: #fffdf8; font-size: .72rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; }
.demo-family-badge { left: .9rem; }
.demo-family-count { right: .9rem; }
.demo-family-copy { padding: 1.25rem 1.25rem 1.4rem; }
.demo-family-copy h3 { margin: .1rem 0 .45rem; font-family: "Cormorant Garamond", Georgia, serif; font-size: 1.75rem; color: var(--ink); }
.demo-family-copy > p:not(.eyebrow) { min-height: 4.5em; color: #675e52; line-height: 1.5; }
.demo-family-copy .ghost-btn { width: 100%; margin-top: .8rem; }
.demo-gallery-note { width: min(760px, 100%); margin: 1.5rem auto 0; color: #74695c; text-align: center; font-size: .85rem; }
.f3-demo-bar { position: sticky; top: 84px; z-index: 19; display: flex; align-items: center; justify-content: center; gap: 1rem; flex-wrap: wrap; padding: .65rem 1rem; border-bottom: 1px solid rgba(118,66,57,.18); background: rgba(255,250,241,.96); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); color: #5f5549; font-size: .86rem; }
.f3-demo-bar strong { color: #3e352c; }
.f3-demo-bar .ghost-btn { margin-left: auto; }
.f3-demo-readonly .f3-demo-note { color: #765d40; font-weight: 600; }
.f3-demo-readonly input:disabled,
.f3-demo-readonly select:disabled,
.f3-demo-readonly textarea:disabled,
.f3-demo-readonly button:disabled:not(.primary-btn) { opacity: .72; cursor: default; }
.f3-demo-readonly .wiz-dropzone { pointer-events: none; opacity: .72; }
.f3-demo-readonly [role="button"][aria-disabled="true"],
.f3-demo-readonly [role="switch"][aria-disabled="true"],
.f3-demo-readonly [role="tab"][aria-disabled="true"],
.f3-demo-readonly [role="slider"][aria-disabled="true"] { cursor: default; }
.f3-demo-readonly .wiz-switch[aria-disabled="true"] { opacity: .72; }
.f3-demo-readonly .chapter-drag-thumb[aria-disabled="true"]:hover { transform: none; }
.f3-demo-finish .wiz-final-video { width: min(100%, 960px); margin-inline: auto; }
.f3-demo-result-grid { display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: .75rem; width: min(860px,100%); margin: 1.5rem auto .5rem; }
.f3-demo-result-grid span { display: flex; flex-direction: column; gap: .15rem; padding: .9rem .6rem; border: 1px solid rgba(118,66,57,.14); border-radius: 12px; background: #faf5ec; color: #756b5e; font-size: .78rem; text-transform: uppercase; letter-spacing: .06em; }
.f3-demo-result-grid strong { color: #463b31; font-family: "Cormorant Garamond", Georgia, serif; font-size: 1.55rem; letter-spacing: 0; }
.f3-demo-film-pending { min-height: 260px; display: flex; flex-direction: column; justify-content: center; gap: .45rem; border-radius: 14px; background: linear-gradient(145deg,#272019,#55483b); color: #fffaf0; }
.f3-demo-film-pending strong { font-family: "Cormorant Garamond",Georgia,serif; font-size: 1.8rem; }
.f3-demo-film-pending span { color: rgba(255,250,240,.75); }
@media (max-width: 860px) { .demo-gallery-grid { grid-template-columns: 1fr; max-width: 560px; } .demo-family-copy > p:not(.eyebrow) { min-height: 0; } }
@media (max-width: 680px) { .f3-demo-result-grid { grid-template-columns: repeat(2,minmax(0,1fr)); } }
@media (max-width: 720px) { .f3-demo-bar { top: 0; } }
@media (max-width: 620px) { .f3-demo-bar { justify-content: flex-start; } .f3-demo-bar .ghost-btn { width: 100%; margin-left: 0; } }

/* Flow 3 — deterministic photo entrance (resumes via negative delay) */
.f3-photo-in { animation: f3PhotoIn 850ms cubic-bezier(0.2, 0.7, 0.2, 1) both; }
@keyframes f3PhotoIn {
  from { opacity: 0; transform: translateY(12px) scale(0.97); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) { .f3-photo-in { animation: none; } }

/* Flow 3 — quiet start-over link on the Photos step */
.f3-reset-line { margin-top: 0.9rem; }
.f3-reset-line .text-link { color: #9a9184; }
.f3-reset-line .text-link:hover { color: #6b5d4f; }

/* Flow 3 — photo tiles: remove button + pick hit-area + drag state */
.f3-tile { position: relative; }
.f3-tile-hit {
  position: absolute; inset: 0; z-index: 1;
  background: none; border: 0; cursor: pointer; border-radius: inherit;
}
.f3-tile:hover .f3-tile-remove, .f3-tile-remove:focus-visible { opacity: 1; }
@media (hover: none) { }
.wiz-dropzone.dragging { border-color: #6b5d4f; background: #f6efe3; }

/* Gentle licensing note under "Use my own" music upload */
.music-own-license-note {
  font-size: 0.82rem; color: #8a8378; line-height: 1.5;
  background: #faf6ee; border: 1px solid #eee6d8; border-radius: 8px;
  padding: 0.6rem 0.8rem; margin: 0.35rem 0 0.85rem;
}
.music-own-license-note strong { color: #6b5d4f; }

/* Flow 3 — silent visitation loop row on the done screen */
.f3-silent-row {
  margin-top: 1.1rem; padding-top: 1rem; border-top: 1px solid #eee6d8;
  display: flex; flex-direction: column; gap: 0.25rem; align-items: center;
}
.f3-silent-row .text-link { font-size: 0.92rem; }
.f3-silent-row .f3-note { max-width: 420px; text-align: center; }

/* Music trim/fade behind a quiet fold */
.music-trim-fold { margin: 0.6rem 0 0.2rem; display: flex; flex-direction: column; gap: 0.2rem; }
.music-trim-fold .text-link { font-size: 0.92rem; align-self: flex-start; }
.music-trim-fold-hint { font-size: 0.78rem; color: #9a9184; }
.trim-editor-close { margin-left: auto; font-size: 0.85rem; }

/* While a photo is still decoding, the tile shows a soft cream placeholder —
   never a black box. */
.f3-tile, .f3-tile img { background: #f0e9dc; }

/* Reveal "considering" drift — the frame breathes through their photos */
.f3-reveal-considering { max-width: 260px; }
.f3-reveal-considering img { transition: opacity 0.45s ease; }

/* W4 — custom WHO date picker + W1/W2 inline error */
.wiz-datebtn { display:flex; align-items:center; justify-content:space-between; text-align:left; cursor:pointer; font:inherit; }
.wiz-datebtn.is-empty > span:first-child { color:#9a9184; }
.wiz-datebtn-ico { opacity:.5; margin-left:8px; }
.wiz-date-err { color:#8a1c1c; background:#f6e4e0; border:1px solid #e6c4bd; border-radius:8px; padding:7px 11px; font-size:.85rem; margin:.2rem 0 .5rem; }
/* z-index: the popup is a body-level fixed element with no z-index, so it
   painted at level 0 — UNDERNEATH the sticky Continue bar (z-index 5). The
   service-date field is the last one on the step, so its picker overlapped that
   bar, clicks landed on the bar instead, and the outside-click handler closed
   the picker: "prev/next/month/year just close it". Above the bar, below the
   full-screen film player (90). */
.f3-datepop { z-index: 60; width:288px; background:#fff; border:1px solid #e2d8c8; border-radius:12px; box-shadow:0 18px 48px rgba(40,30,18,.22); padding:10px; font:14px/1.3 -apple-system,Segoe UI,Roboto,sans-serif; color:#2b241d; }
.f3-dp-head { display:flex; align-items:center; gap:6px; margin-bottom:8px; }
.f3-dp-nav { flex:0 0 auto; width:30px; height:30px; border:1px solid #e2d8c8; background:#fbf7f0; border-radius:8px; cursor:pointer; font-size:18px; line-height:1; color:#5a4a34; }
.f3-dp-nav:hover { background:#f0e8da; }
.f3-dp-wd { display:grid; grid-template-columns:repeat(7,1fr); gap:2px; margin-bottom:2px; }
.f3-dp-wd span { text-align:center; font-size:11px; color:#9a9184; padding:2px 0; }
.f3-dp-grid { display:grid; grid-template-columns:repeat(7,1fr); gap:2px; }
.f3-dp-week, .f3-dp-gc { display:contents; } /* keep ARIA row/gridcell wrappers out of the visual grid flow */
.f3-dp-empty { height:34px; }
.f3-dp-day { height:34px; border:0; background:none; border-radius:8px; cursor:pointer; font:inherit; color:#2b241d; }
/* DP7: ≥44px touch targets for calendar days on phones (widen the popup so the
   7 columns each clear 44px, and grow the day/empty cells to match). */
@media (max-width: 480px) {
  .f3-datepop { width: min(94vw, 340px); }
  .f3-dp-day, .f3-dp-empty { height: 44px; }
  .f3-dp-cell { min-height: 44px; }
  .f3-dp-useyear { min-height:44px; }
}
.f3-dp-day:hover:not(:disabled) { background:#f0e8da; }
.f3-dp-day.sel { background:#5a3d2b; color:#fff; }
.f3-dp-day:disabled { color:#cfc7b8; cursor:default; }
.f3-dp-foot { display:flex; justify-content:space-between; align-items:center; margin-top:8px; min-height:1.6rem; }
.f3-dp-clear, .f3-dp-today { border:0; background:none; color:#7a2e2e; font:600 12px/1 inherit; cursor:pointer; padding:6px 4px; }
.f3-dp-today { color:#5a4a34; }
.f3-dp-useyear {
  border:1px solid #8a6a45; background:#fbf7f0; color:#5a3d2b;
  border-radius:999px; padding:7px 11px; cursor:pointer;
  font:600 12px/1 inherit; white-space:nowrap;
}
.f3-dp-useyear:hover, .f3-dp-useyear:focus-visible { background:#f0e8da; border-color:#5a3d2b; }
.f3-dp-yearchoice {
  display:flex; align-items:center; gap:8px; margin:9px 1px 1px; padding-top:9px;
  border-top:1px solid #eee6d8;
}
.f3-dp-yearchoice span { color:#766d61; font-size:11px; line-height:1.3; }

/* P4a/P5a — per-photo toolbar (set-main / rotate / caption / remove), caption, drag-reorder */
.wiz-photo.f3-tile { position: relative; }
.wiz-photo.f3-tile img { transition: transform .2s ease; }
.f3-tile-bar {
  position: absolute; top: 5px; right: 5px; display: flex; gap: 4px;
  opacity: 0; transition: opacity .12s; z-index: 4;
}
.wiz-photo.f3-tile:hover .f3-tile-bar,
.wiz-photo.f3-tile:focus-within .f3-tile-bar { opacity: 1; }
/* .f3-hover is re-asserted synchronously after a background re-render so the
   toolbar survives the grid rebuild; show it instantly (no fade) so the
   rebuild can't produce even a soft flicker. */
.wiz-photo.f3-tile.f3-hover .f3-tile-bar { opacity: 1; transition: none; }
.f3-tb {
  width: 26px; height: 26px; border-radius: 7px; cursor: pointer;
  border: 1px solid rgba(255,255,255,.6); background: rgba(30,22,14,.62); color: #fff;
  font: 13px/1 system-ui, -apple-system, sans-serif; display: flex; align-items: center; justify-content: center;
  padding: 0; -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px); transition: background .12s, transform .06s;
}
.f3-tb:hover { background: rgba(30,22,14,.88); }
.f3-tb:active { transform: translateY(1px); }
.f3-tb.on { background: #5a3d2b; border-color: #caa765; }
.f3-tb-rm:hover { background: #7a2e2e; }
.f3-tile-cap {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
  font: 500 11.5px/1.25 -apple-system, Segoe UI, sans-serif; color: #fff;
  background: linear-gradient(to top, rgba(20,14,8,.82), rgba(20,14,8,0));
  padding: 16px 8px 6px; text-align: center; cursor: text;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.f3-tile-cap-input {
  position: absolute; left: 4px; right: 4px; bottom: 4px; z-index: 6;
  border: 1px solid #caa765; border-radius: 7px; padding: 5px 8px;
  font: 500 12px/1.2 -apple-system, Segoe UI, sans-serif; color: #2b241d; background: #fff;
}
.wiz-photo.f3-tile[draggable="true"] { cursor: grab; }
.wiz-photo.f3-tile.f3-dragging { opacity: .4; }
.wiz-photo.f3-tile.f3-dragover { outline: 2px dashed #caa765; outline-offset: 2px; }

/* Mu3 — rights acknowledgement on the "Use my own" music tab */
.music-own-ack { display:inline; color:#5a4a34; font-weight:600; }

/* W3 — quiet name character counter (only appears near the 50-char limit) */
.f3-namecount { color: #9a8f7f; font-variant-numeric: tabular-nums; }

/* P6a — soft nudge (120) and hard-cap (150) messaging on the Photos step */
.f3-photo-nudge { color: #8a6d3b; }
.f3-photo-cap { color: #8a1c1c; font-weight: 500; }

/* L6 — reassuring empty state for the landscape (and portrait) slide previews */
.f3-slide-empty-reassure { display:flex; flex-direction:column; gap:4px; align-items:center; justify-content:center; text-align:center; max-width:30rem; margin:0 auto; padding:14px 18px; color:#7c7266; font-size:.9rem; line-height:1.4; }
.f3-slide-empty-reassure strong { color:#5a4a34; font-weight:600; }

/* ===== P2a: near-duplicate review modal ===== */
.f3dm-scrim{position:fixed;inset:0;background:rgba(38,26,16,.5);z-index:1000}
.f3dm-modal{position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);z-index:1001;
  width:min(920px,94vw);max-height:92vh;display:flex;flex-direction:column;background:#fffdf8;
  border-radius:22px;box-shadow:0 24px 60px rgba(60,40,25,.32);border:1px solid #e8dfcd;overflow:hidden;
  animation:f3dmPop .3s cubic-bezier(.2,.8,.2,1)}
@keyframes f3dmPop{from{opacity:0;transform:translate(-50%,-46%) scale(.985)}to{opacity:1;transform:translate(-50%,-50%) scale(1)}}
.f3dm-hd{padding:20px 26px 12px;position:relative}
.f3dm-kicker{font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:#b58a4a;font-weight:700}
.f3dm-hd h2{font-family:Georgia,'Times New Roman',serif;font-weight:600;font-size:27px;line-height:1.12;margin:5px 0 4px;color:#3a3129}
.f3dm-hd p{margin:0;color:#8a7d6d;font-size:14px;max-width:64ch}
.f3dm-x{position:absolute;top:14px;right:16px;width:34px;height:34px;border-radius:50%;border:1px solid #e8dfcd;
  background:#fff;color:#8a7d6d;font-size:17px;cursor:pointer;line-height:1}
.f3dm-x:hover{background:#f6f0e4;color:#3a3129}
.f3dm-seg{display:inline-flex;margin:10px 26px 0;background:#f6f0e4;border:1px solid #e8dfcd;border-radius:999px;padding:4px;gap:4px}
.f3dm-seg button{border:0;background:transparent;font:inherit;font-size:13.5px;font-weight:600;color:#8a7d6d;padding:8px 16px;border-radius:999px;cursor:pointer}
.f3dm-seg button.on{background:#6e3f2f;color:#fff8ee}
.f3dm-body{padding:14px 26px 8px;overflow:auto}

.f3dm-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:16px;padding:4px 0}
.f3dm-gcard{border:1px solid #e8dfcd;border-radius:16px;background:#fff;overflow:hidden;display:flex;flex-direction:column}
.f3dm-gcard.ok{outline:2px solid #cdddb8;outline-offset:-1px}
.f3dm-pairwrap{position:relative}
.f3dm-dupflag{position:absolute;left:10px;top:10px;z-index:2;background:rgba(30,20,12,.74);color:#fff;font-size:11px;font-weight:700;padding:4px 10px;border-radius:999px}
.f3dm-pairstrip{display:flex;gap:5px;padding:5px;background:#efe7d6;cursor:pointer}
.f3dm-ptile{position:relative;flex:1;min-width:0;border:0;padding:0;background:#e2d8c4;border-radius:10px;overflow:hidden;cursor:pointer}
.f3dm-ptile img{display:block;width:100%;height:132px;object-fit:cover}
.f3dm-ptile.keep{outline:3px solid #5c7a4a;outline-offset:-3px}
.f3dm-ptile:not(.keep) img{filter:grayscale(.14) brightness(.93)}
.f3dm-pt-badge{position:absolute;font-size:10.5px;font-weight:700}
.f3dm-ptile.keep .f3dm-pt-badge{top:6px;right:6px;background:#5c7a4a;color:#fff;width:22px;height:22px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:12px}
.f3dm-ptile:not(.keep) .f3dm-pt-badge{left:6px;bottom:6px;background:rgba(30,20,12,.62);color:#fff;padding:3px 8px;border-radius:999px}
.f3dm-ptile:not(.keep):hover{outline:2px solid #8a5140;outline-offset:-2px}
.f3dm-ptile:not(.keep):hover .f3dm-pt-badge{background:#6e3f2f}
.f3dm-ptile.more{display:flex;flex-direction:column;align-items:center;justify-content:center;background:#e7ddc9;color:#6e3f2f}
.f3dm-ptile.more .plus{font-family:Georgia,serif;font-size:26px;font-weight:600;line-height:1}
.f3dm-ptile.more .sub{font-size:10.5px;color:#8a7d6d}
.f3dm-meta{padding:11px 13px 13px;display:flex;flex-direction:column;gap:9px}
.f3dm-why{font-size:12.5px;color:#8a7d6d}
.f3dm-why b{color:#3a3129;font-weight:600}
.f3dm-rowb{display:flex;align-items:center;justify-content:space-between;gap:8px}
.f3dm-kb{display:inline-flex;align-items:center;gap:7px;font:inherit;font-size:12.5px;color:#3a3129;cursor:pointer;background:none;border:0;padding:0}
.f3dm-switch{width:34px;height:20px;border-radius:999px;background:#d8cdb8;position:relative;transition:.18s;flex:none}
.f3dm-switch::after{content:"";position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;background:#fff;transition:.18s;box-shadow:0 1px 3px rgba(0,0,0,.3)}
.f3dm-kb.on .f3dm-switch{background:#5c7a4a}
.f3dm-kb.on .f3dm-switch::after{transform:translateX(14px)}
.f3dm-cfm{font:inherit;font-size:12.5px;font-weight:700;border:0;background:none;color:#8a5140;padding:6px 4px;cursor:pointer}
.f3dm-cfm:hover{text-decoration:underline}

.f3dm-morecard{border:1.5px dashed #d8cdb8;border-radius:16px;background:#fbf6ec;min-height:150px;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;cursor:pointer;padding:18px;font:inherit}
.f3dm-morecard:hover{background:#f4ecda;border-color:#8a5140}
.f3dm-morecard .mc-n{font-family:Georgia,serif;font-size:30px;font-weight:600;color:#6e3f2f;line-height:1}
.f3dm-morecard .mc-t{font-size:12.5px;color:#8a7d6d;margin-top:6px;max-width:22ch}
.f3dm-morecard .mc-cta{margin-top:10px;font-size:12.5px;font-weight:700;color:#8a5140}

.f3dm-rnav{display:flex;align-items:center;justify-content:center;gap:14px;margin:2px 0 14px}
.f3dm-arrow{width:38px;height:38px;border-radius:50%;border:1px solid #e8dfcd;background:#fff;font-size:16px;color:#6e3f2f;cursor:pointer}
.f3dm-arrow:hover{background:#f6f0e4}
.f3dm-arrow:disabled{opacity:.35;cursor:default}
.f3dm-rtitle{text-align:center;min-width:210px}
.f3dm-rtitle .n{font-family:Georgia,serif;font-size:22px;font-weight:600;line-height:1;color:#3a3129}
.f3dm-rtitle .s{font-size:12px;color:#8a7d6d;margin-top:2px}
.f3dm-dupgrid{max-width:560px;margin:0 auto}
.f3dm-cols{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.f3dm-leadrow{display:flex;justify-content:center;margin-bottom:12px}
.f3dm-leadrow .f3dm-tile{width:calc(50% - 6px)}
.f3dm-tile{position:relative;border:2px solid #e8dfcd;border-radius:14px;overflow:hidden;background:#efe7d6;cursor:pointer;padding:0;display:block;font:inherit}
.f3dm-tile img{display:block;width:100%;height:var(--th);object-fit:cover}
.f3dm-tbadge{position:absolute;left:8px;top:8px;font-size:11px;font-weight:700;padding:4px 9px;border-radius:999px}
.f3dm-tile:not(.keep) .f3dm-tbadge{background:rgba(30,20,12,.62);color:#fff}
.f3dm-tile.keep .f3dm-tbadge{background:#eaf1df;color:#5c7a4a;border:1px solid #cdddb8}
.f3dm-tile.keep{border-color:#5c7a4a;box-shadow:0 6px 16px rgba(92,122,74,.25)}
.f3dm-tile:not(.keep):hover{border-color:#8a5140;transform:translateY(-2px)}
.f3dm-tile:disabled{cursor:default}
.f3dm-racts{display:flex;gap:10px;justify-content:center;margin:16px 0 2px;flex-wrap:wrap}
.f3dm-film{display:flex;gap:9px;justify-content:center;align-items:center;margin:16px 0 4px;flex-wrap:wrap}
.f3dm-film .f3dm-ft{position:relative;border:2px solid transparent;border-radius:10px;overflow:hidden;cursor:pointer;background:#efe7d6;padding:0}
.f3dm-film .f3dm-ft img{width:56px;height:42px;object-fit:cover;display:block}
.f3dm-film .f3dm-ft.cur{border-color:#6e3f2f}
.f3dm-film .f3dm-ft .cnt{position:absolute;right:3px;top:3px;background:rgba(30,20,12,.7);color:#fff;font-size:9px;padding:1px 5px;border-radius:999px;font-weight:700}

.f3dm-btn{font:inherit;font-size:13px;font-weight:600;border-radius:999px;padding:9px 16px;cursor:pointer;border:1px solid #e8dfcd;background:#fff;color:#3a3129}
.f3dm-btn:hover{background:#f6f0e4}
.f3dm-btn.good.on{background:#eaf1df;border-color:#cdddb8;color:#5c7a4a}
.f3dm-btn.ghost{background:transparent;border-color:transparent;color:#8a7d6d}
.f3dm-btn.ghost:hover{color:#3a3129;background:#f6f0e4}
.f3dm-btn.primary{background:#6e3f2f;color:#fff8ee;border-color:#6e3f2f;padding:11px 22px;font-size:13.5px}
.f3dm-btn.primary:hover{background:#5c3427}

.f3dm-foot{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:16px 26px;border-top:1px solid #e8dfcd;background:linear-gradient(#fffdf8,#fbf6ec)}
.f3dm-foot .f3dm-re{font-size:12.5px;color:#8a7d6d;max-width:46ch}
.f3dm-foot .f3dm-acts{display:flex;gap:10px;flex:none}
@media (max-width:640px){.f3dm-hd h2{font-size:23px}.f3dm-foot{flex-direction:column;align-items:stretch}.f3dm-foot .f3dm-acts{justify-content:flex-end}}

/* Styles embed: cancel the fsv2 component negative top margin so it does not clip the depth hint above it */
.f3-embed .film-style-editorial.fsv2{margin-top:0}

/* L7: Fine-tune (Advanced) button on the Styles category row + studio popup */
.fsv2-feelrow{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;margin-bottom:6px}
.fsv2-feelrow .fsv2-feelings{margin-bottom:0}
.f3-finetune-btn{display:inline-flex;align-items:center;gap:7px;border:1px solid #6e3f2f;background:#fff;color:#6e3f2f;border-radius:999px;padding:9px 16px;font:inherit;font-size:13px;font-weight:700;cursor:pointer;white-space:nowrap}
.f3-finetune-btn:hover{background:#f6efe6}
.f3st-scrim{position:fixed;inset:0;background:rgba(38,26,16,.5);z-index:1000}
.f3st-modal{position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);z-index:1001;width:min(1120px,96vw);max-height:94vh;display:flex;flex-direction:column;background:#fffdf8;border:1px solid #e8dfcd;border-radius:22px;box-shadow:0 24px 60px rgba(60,40,25,.32);overflow:hidden;animation:f3dmPop .3s cubic-bezier(.2,.8,.2,1)}
.f3st-hd{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;padding:16px 24px 10px;border-bottom:1px solid #f0e8d8}
.f3st-kick{font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:#b58a4a;font-weight:700}
.f3st-hd h2{font-family:Georgia,'Times New Roman',serif;font-weight:600;font-size:24px;margin:3px 0 0;color:#3a3129}
/* LA8 — 34px was below the 44px minimum touch target on phones, where this
   is the only way out of the Fine-tune editor. */
.f3st-x{flex:none;width:34px;height:34px;border-radius:50%;border:1px solid #e8dfcd;background:#fff;color:#8a7d6d;font-size:17px;cursor:pointer;line-height:1}
@media (max-width:900px){.f3st-x{width:44px;height:44px;font-size:20px}}
.f3st-x:hover{background:#f6f0e4;color:#3a3129}
.f3st-body{padding:14px 24px;overflow:auto}
.f3st-foot{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:14px 24px;border-top:1px solid #e8dfcd;background:linear-gradient(#fffdf8,#fbf6ec)}
.f3st-re{font-size:12.5px;color:#8a7d6d}
@media (max-width:640px){.f3st-foot{flex-direction:column;align-items:stretch}}

/* Fit the opening studio grid inside the fine-tune popup (canvas column flexes; panel stays 316px) */
.f3st-modal .cyo-studio{grid-template-columns:minmax(0,1fr)}
.f3st-modal .f3-embed-wrap{position:static;width:auto;max-width:100%;margin:0;left:auto;right:auto}
.f3st-modal .f3-embed{width:auto;max-width:100%}

/* Studio preamble: preset-phrase chips (+ None / Custom) instead of free text */
.cyi-pchips{display:flex;flex-wrap:wrap;gap:6px;margin-top:2px}
.cyi-pchip{font:inherit;font-size:12px;font-weight:600;border:1px solid #e8dfcd;background:#fff;color:#3a3129;border-radius:999px;padding:6px 11px;cursor:pointer;line-height:1.1}
.cyi-pchip:hover{background:#f6f0e4}
.cyi-pchip.on{background:#6e3f2f;color:#fff8ee;border-color:#6e3f2f}
.cyi-pchip-custom{border-style:dashed;color:#8a5140}
.cyi-pchip-custom.on{color:#fff8ee}

/* L11: studio edit discoverability — hint under the canvas + clear selection cue */
.cyo-edithint{text-align:center;font-size:12.5px;color:#8a7d6d;margin:9px 0 4px;letter-spacing:.01em}

/* ══ LO1 — Fine-tune on a phone ══════════════════════════════════════════════
   Measured at 390x844 and 360x780: grid-template-columns resolved to
   `0px 316px`. The canvas was 0x0, the Show chips 0 wide (so "Add a line" wrapped
   to one word per line) and the composition strip a blank band. There was no
   opening card on screen at all, and the panel invited the family to "pick a
   line or the photo" with nothing to pick.

   The cause was not a missing rule but a specificity collision: the modal's own
   `.f3st-modal .cyo-studio{grid-template-columns:minmax(0,1fr)}` (0,2,0)
   outranked `@media (max-width:900px){.cyo-studio{...1fr}}` (0,1,0) and came
   later in the file, so that media query had never once applied inside
   Fine-tune. 316px of fixed panel then ate the whole content box.

   The breakpoint is 700px because that is where the two-column studio stops
   being possible, and because it happens to fall exactly on K's ruling: a phone
   is under it in portrait and over it in landscape, so portrait gets the stack
   with numeric controls and landscape keeps the side-by-side card it is wide
   enough to drag on. Tablets stay two-column in both orientations. */
@media (max-width:700px){
  /* minmax(0,1fr), never a bare 1fr. `display:contents` below promotes the
     composition strip to a grid item, and a bare 1fr takes its intrinsic width
     as a floor: 28 tiles in a row measured 5126px and the whole editor went
     with it. minmax(0,...) lets the column be narrower than its contents; the
     strip then scrolls sideways, which is what it is built to do. */
  .cyo-studio, .f3st-modal .cyo-studio{grid-template-columns:minmax(0,1fr);gap:14px;}
  .cyo-studio > *{min-width:0;}
  /* `.fs-comp-strip` is already the scroller (overflow-x:auto). It only needed
     permission to be narrower than its tiles — the wrap and the grid item above
     it were the ones holding it open. */
  .cyo-strip, .cyo-strip .fs-comp-strip-wrap, .cyo-strip .fs-comp-strip{min-width:0;max-width:100%;}
  /* Promote the stage column's children to grid items so the card can be
     ordered first and stick to the scroller rather than to its own column. */
  .cyo-stagecol{display:contents;}
  .cyo-canvas.fs-comp-stage-wrap{
    order:1;position:sticky;top:0;z-index:3;
    /* Pinned, it reads as a band rather than a floating card: square the
       corners so nothing scrolls through them, and give it a ground of its own
       so the chips pass underneath instead of showing through. */
    border-radius:0;background:#fffdf8;
    box-shadow:0 10px 18px -12px rgba(60,46,24,.45);
    margin:0 -16px;width:calc(100% + 32px);
  }
  .cyo-edithint{order:2;margin:8px 0 2px;}
  .cyo-chips{order:3;margin-bottom:4px;}
  .cyo-panel{order:4;position:static;}
  .cyo-strip{order:5;margin-top:14px;}
  /* The chips had collapsed to one word per line. Let them be buttons again. */
  .cyo-chips{gap:8px;}
  .cyo-chip{white-space:nowrap;}
  /* Position and size move to the panel's X / Y / Size steppers here, so the
     drag affordances would be lying. The binders are skipped in JS too — this
     only stops them being drawn. */
  .cyo-canvas .backdrop-text-resize-handle{display:none !important;}
  /* The dashed group box is a drag target too. Under 700px nothing on the card
     can be dragged, so leaving it drawn is an invitation to a gesture that will
     not work. */
  .cyo-canvas .backdrop-group-box,
  .cyo-canvas .backdrop-group-box-corner{display:none !important;}
  /* LO38 — these steppers are the ONLY way to position anything in portrait,
     because dragging is deliberately off. 34x22 was not a touch target. The
     pair goes side by side so each can be a full 44x44 without the control
     growing to 88px tall, and the field keeps a comfortable height between
     them. */
  .cyo-panel .cyi-num{height:auto;min-height:48px;}
  .cyo-panel .cyi-num .cyi-input{min-height:46px;font-size:16px;}
  .cyo-panel .cyi-step{flex-direction:row;}
  .cyo-panel .cyi-step-btn{min-width:44px;min-height:44px;width:44px;height:auto;font-size:12px;}
  .cyo-panel .cyi-step-btn + .cyi-step-btn{border-left:1px solid #ece2cd;}
  /* Two of these sit side by side in the X / Y row; on a phone they need the
     whole width each or the fields end up narrower than their own steppers. */
  .cyo-panel .cyi-xy{display:grid;grid-template-columns:auto 1fr;align-items:center;gap:10px 8px;}
}

/* ══ LO1 — a short viewport, which is what a phone in landscape is ══════════
   844x390 already resolves to a workable 420px + 316px; what fails there is
   vertical. The modal caps at 94vh = 367px and the header and footer take ~147
   of it, leaving a 220px window to scroll 582px of editor. Keyed on height
   rather than orientation because height is the actual constraint. */
@media (max-height:430px){
  .f3st-modal{max-height:98vh;}
  .f3st-hd{padding:6px 18px 4px;}
  .f3st-kick{display:none;}
  .f3st-hd h2{font-size:16px;margin:0;line-height:1.2;}
  .f3st-x{width:38px;height:38px;font-size:18px;}
  .f3st-body{padding:6px 18px;}
  .f3st-foot{padding:6px 18px;}
  .f3st-re{display:none;}
  .f3st-foot .primary-btn,.f3st-foot button{padding-top:8px;padding-bottom:8px;}
  .cyo-chips{margin-bottom:8px;}
  .f3st-modal .cyo-studio{gap:16px;}
  .cyo-strip{margin-top:12px;}
}
.f3st-modal .titlecard-preamble.is-selected .backdrop-text-resize-handle,
.f3st-modal .titlecard-name.is-selected .backdrop-text-resize-handle,
.f3st-modal .titlecard-dates.is-selected .backdrop-text-resize-handle{opacity:1}
.f3st-modal .titlecard-preamble.is-selected,
.f3st-modal .titlecard-name.is-selected,
.f3st-modal .titlecard-dates.is-selected{outline:1.5px solid rgba(110,63,47,.55);outline-offset:5px;border-radius:5px}

/* C2: targeted "help place these" age nudge in the guided Chapters step */
.f3-age-nudge{background:rgba(232,193,139,.10);border:1px solid rgba(141,95,63,.20);}
.f3-age-nudge .module-card-header h3{font-size:1.02rem;}
.f3-age-nudge .badge-edit{cursor:pointer;}

/* ── W6: nickname on the WHO step ─────────────────────────────────────────── */
.f3nick-panel{margin:2px 0 0;border-top:1px dashed rgba(141,95,63,.22);padding-top:0;
  opacity:0;max-height:0;overflow:hidden;transition:opacity .25s ease,max-height .3s ease,padding-top .25s ease}
.f3nick-panel.show{opacity:1;max-height:760px;padding-top:14px}
.f3nick-toggle-row{display:flex;align-items:center;justify-content:space-between;gap:14px}
.f3nick-tlabel{font-size:13.5px;font-weight:600;color:#2c2016}
.f3nick-thint{font-size:12px;color:#6b6154;margin-top:2px}/* AV3 */
.f3nick-switch{position:relative;width:44px;height:26px;flex:0 0 auto;border:0;border-radius:20px;
  background:#e4dccf;cursor:pointer;transition:background .18s;padding:0}
.f3nick-switch i{position:absolute;top:3px;left:3px;width:20px;height:20px;border-radius:50%;
  background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.18);transition:left .18s}
.f3nick-switch.on{background:#6e3f2f}
.f3nick-switch.on i{left:21px}
.f3nick-styleblock{margin-top:16px;transition:opacity .2s}
.f3nick-styleblock.is-off{opacity:.4;pointer-events:none;filter:grayscale(.3)}
.f3nick-q{font-size:13px;font-weight:600;margin:0 0 10px;color:#2c2016}
.f3nick-chips{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}
@media(max-width:560px){.f3nick-chips{grid-template-columns:1fr 1fr}}
.f3nick-chip{border:1px solid rgba(141,95,63,.22);background:#fbf5ea;border-radius:11px;
  padding:11px 8px;cursor:pointer;text-align:center;font-size:12px;font-weight:600;color:#2c2016;
  transition:border-color .15s,background .15s,box-shadow .15s}
.f3nick-chip:hover{border-color:#8d5f3f}
.f3nick-chip.on{border-color:#6e3f2f;background:#fff;box-shadow:0 0 0 2px rgba(110,63,47,.16)}
.f3nick-preview{margin-top:14px;border:1px solid rgba(141,95,63,.22);border-radius:12px;
  background:#fcf8f1;padding:24px 18px;min-height:104px;display:flex;flex-direction:column;
  align-items:center;justify-content:center;text-align:center}
.f3nick-pvcap{font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;color:#8a7d6d;margin:0 0 12px}
.f3nick-pvname{font-family:"Georgia","Times New Roman",serif;color:#2c2016;line-height:1.16;
  letter-spacing:.05em;display:flex;flex-direction:column;align-items:center;gap:6px}
.f3nick-pvname .nm{font-weight:600;font-size:23px;text-transform:uppercase}
.f3nick-pvname .nick-line{font-style:italic;font-size:16px;color:#8d5f3f;letter-spacing:.02em}
.f3nick-subnote{font-size:12px;color:#6b6154;margin:10px 2px 0;line-height:1.45;text-align:center}/* AV3: darker + 12px */

/* ── W6: nickname line on the opening/end title card (fit-engine-safe) ─────── */
.titlecard-name.tc-nick-below::after,
.titlecard-name.tc-nick-above::before{
  content:"\201C" attr(data-nickname) "\201D";
  display:block;font-style:italic;font-weight:500;font-size:.58em;
  letter-spacing:.02em;text-transform:none;opacity:.9;line-height:1.1}
.titlecard-name.tc-nick-above::before{margin-bottom:.16em}
.titlecard-name.tc-nick-below::after{margin-top:.14em}

/* WHO: read-only age-at-passing preview under the date row */
.f3-age-preview{font-size:12.5px;color:#8a7d6d;text-align:right;margin:1px 2px 2px;font-style:italic}
.f3-datehelp{font-size:12px;color:#7a7061;margin:5px 2px 2px;line-height:1.45}
.f3nick-dupwarn{font-size:12px;color:#7a5a2e;background:#f7efdd;border:1px solid #e6d4ad;border-radius:8px;padding:7px 10px;margin:8px 0 2px;line-height:1.45}
.f3nick-dupwarn[hidden]{display:none}

/* Modernized date-picker: month grid + decade→year drill-down (replaces <select>) */
.f3-dp-hbtn{flex:1 1 auto;min-width:0;padding:6px 8px;border:1px solid #e2d8c8;border-radius:8px;background:#fbf7f0;font:600 14px/1 inherit;color:#2b241d;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:5px}
.f3-dp-hbtn:hover{background:#f0e8da}
.f3-dp-caret{font-size:11px;color:#9a9184}
.f3-dp-yhead{display:flex;align-items:center;gap:8px;margin-bottom:8px}
.f3-dp-yback{border:1px solid #e2d8c8;background:#fbf7f0;border-radius:8px;height:30px;padding:0 10px;cursor:pointer;color:#5a4a34;font:600 13px/1 inherit;white-space:nowrap}
.f3-dp-yback:hover{background:#f0e8da}
.f3-dp-ytitle{flex:1;text-align:center;font-weight:700;font-size:14px;color:#2b241d}
.f3-dp-yspacer{width:44px;flex:0 0 auto}
.f3-dp-cellgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:6px;padding:2px 0 4px}
.f3-dp-cellgrid.f3-dp-yeargrid{grid-template-columns:repeat(4,1fr)}
.f3-dp-cell{height:44px;border:1px solid #ece3d4;background:#fff;border-radius:9px;cursor:pointer;font:inherit;color:#2b241d;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1px}
.f3-dp-cell:hover:not(.is-disabled){background:#f7f0e4;border-color:#d8ccb8}
.f3-dp-cell.on{background:#5a3d2b;color:#fff;border-color:#5a3d2b}
.f3-dp-cell.is-disabled{opacity:.32;cursor:default}
.f3-dp-dnum{font-weight:600;font-size:14px}
.f3-dp-drange{font-size:10px;color:#9a9184}
.f3-dp-cell.on .f3-dp-drange{color:#e6d8c6}

/* U2: guided-flow upload progress + per-tile saving state + all-set line. */
.f3-uprog { margin: 0.85rem auto 0; max-width: 460px; }
.f3-uprog-track {
  height: 8px;
  border-radius: 999px;
  background: rgba(118, 66, 57, 0.14);
  overflow: hidden;
}
.f3-uprog-fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--accent, #764239);
  transition: width 200ms ease;
}
.f3-uprog-label {
  margin: 0.5rem 0 0;
  text-align: center;
  font-size: 0.86rem;
  color: #6b6154;
}
.f3-allset {
  color: #456b3f;
  font-weight: 600;
}
.wiz-photo.is-uploading { position: relative; }
.wiz-photo.is-uploading img { opacity: 0.62; filter: saturate(0.9); }
.f3-tile-saving {
  position: absolute;
  left: 50%;
  bottom: 8px;
  transform: translateX(-50%);
  padding: 2px 9px;
  border-radius: 999px;
  background: rgba(30, 22, 18, 0.72);
  color: #fff;
  font-size: 0.7rem;
  letter-spacing: 0.02em;
  pointer-events: none;
}

/* PA8: Photos-grid touch ergonomics. On touch devices there's no hover to
   reveal the per-tile toolbar, so show it; and on small screens grow the
   rotate/caption/remove buttons to ≥44px tap targets. (Sticky Continue on
   mobile is already handled by the AV8 .wiz-actions rule.) */
@media (hover: none) {
  .wiz-photo.f3-tile .f3-tile-bar { opacity: 1; }
}
@media (max-width: 600px) {
  .f3-tb { width: 44px; height: 44px; border-radius: 9px; font-size: 16px; }
  .f3-tile-bar { gap: 6px; top: 6px; right: 6px; }
}

/* ── TB5: photos that failed to restore ─────────────────────────────────────
   These used to be invisible — the restored grid only renders photos that HAVE
   a restoredUrl, so a failure vanished from the page while the counter waited
   for it forever. This card shows them with a per-photo retry. */
.f3-restore-failed { border-color: rgba(138, 28, 28, .28); }
.f3-restore-failed-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: .9rem;
  margin-top: .8rem;
}
.f3-restore-failed-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .5rem;
  text-align: center;
}
.f3-restore-failed-item img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: 10px;
  filter: saturate(.55);
}
.f3-restore-failed-msg {
  font-size: .82rem;
  line-height: 1.35;
  color: #8a1c1c;
  display: inline-flex;
  align-items: center;
  gap: .4rem;
}
/* Comfortable tap target — these appear on mobile too (pairs with TM3). */
.f3-restore-failed-item .ghost-btn { min-height: 44px; padding-inline: 1rem; }

/* ── TB6: pause control for the living portrait ─────────────────────────────
   A moving portrait of someone who has died must be stoppable, and must not
   start moving on its own when the OS asks for reduced motion. */
.anim-live-playpause { min-height: 44px; min-width: 44px; }
.anim-live-rm-note {
  margin: .5rem 0 0;
  font-size: .82rem;
  opacity: .75;
  text-align: center;
}
@media (prefers-reduced-motion: reduce) {
  .anim-live-dot { animation: none !important; }
}

/* PC2: inline caption character counter. */
.f3-cap-count {
  position: absolute; left: 6px; bottom: 6px; z-index: 7;
  font: 600 10.5px/1 system-ui, -apple-system, sans-serif;
  color: #fff; background: rgba(30,22,14,.7); border-radius: 999px;
  padding: 2px 7px; pointer-events: none;
}
/* PC6: bulk-select-to-remove. */
.f3-tile-bar { flex-wrap: wrap; justify-content: flex-end; max-width: calc(100% - 10px); }
.f3-tile-sel {
  position: absolute; inset: 0; z-index: 5; cursor: pointer;
  background: rgba(20,14,8,.12); border: 0; border-radius: inherit;
  display: flex; align-items: flex-start; justify-content: flex-start;
}
.f3-tile-sel .f3-tile-selmark {
  margin: 8px; width: 26px; height: 26px; border-radius: 50%;
  border: 2px solid #fff; background: rgba(30,22,14,.45); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font: 700 15px/1 system-ui; box-shadow: 0 1px 4px rgba(0,0,0,.3);
}
.f3-tile-sel.on { background: rgba(118,66,57,.28); }
.f3-tile-sel.on .f3-tile-selmark { background: var(--accent, #764239); border-color: #fff; }
.wiz-photo.f3-tile.is-selected { outline: 3px solid var(--accent, #764239); outline-offset: -3px; }
.f3-selbar {
  display: flex; align-items: center; justify-content: space-between; gap: 0.75rem;
  margin: 1rem 0 0; padding: 0.6rem 0.85rem; border-radius: 12px;
  background: #f6efe3; border: 1px solid #e6dcc9;
}
.f3-selbar-n { font-weight: 600; color: #5a4a34; }
.f3-selbar-acts { display: flex; gap: 0.5rem; align-items: center; }
.f3-selbar-acts .ghost-btn, .f3-selbar-acts .primary-btn { margin: 0; }
.f3-selentry .text-link, .f3-order-note, .f3-estimate-note { }
@media (max-width: 600px) {
  .f3-tile-sel .f3-tile-selmark { width: 30px; height: 30px; }
}

/* ── TU1: the master restore row must not claim a configuration the film
   won't use (every photo flipped to Keep original). ───────────────────────── */
.f3-rcard.is-contradicted { border-color: rgba(154, 90, 18, .45); background: #fdf8ef; }
.f3-restore-contradiction { margin-top: .7rem; display: flex; justify-content: flex-end; }
.f3-restore-contradiction .ghost-btn { min-height: 44px; }

/* ── TU2: motion chosen, but both bookends off — it plays nowhere. ────────── */
.anim-bookends-warn {
  margin-top: .9rem;
  padding: .8rem .9rem;
  border: 1px solid rgba(154, 90, 18, .45);
  border-radius: 10px;
  background: #fdf8ef;
  display: flex;
  flex-direction: column;
  gap: .35rem;
}
.anim-bookends-warn strong { color: #8a5a12; }
.anim-bookends-warn span { font-size: .86rem; line-height: 1.4; color: var(--muted); }
.anim-bookends-warn-actions { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .35rem; }
.anim-bookends-warn-actions .ghost-btn { min-height: 44px; }

/* ── TU5: styles still being created are pending, not failed. ─────────────── */
.anim-style-tile.is-pending { opacity: .55; cursor: default; }
.anim-style-tile.is-pending:hover { transform: none; }
.anim-style-badge.pending {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, .45);
  color: #fff;
  border-radius: 999px;
  padding: .2rem .4rem;
}

/* ── TU6/TU7: say what Continue will do, and keep it reachable on a page that
   ran to ~4,255px with ten photos. ────────────────────────────────────────── */
.f3-continue-note {
  flex: 1 1 14rem;
  margin: 0;
  padding: 0 .75rem;
  font-size: .82rem;
  line-height: 1.35;
  color: var(--muted);
  text-align: center;
}
.wiz-actions.f3-actions-sticky {
  position: sticky;
  bottom: 0;
  z-index: 5;
  flex-wrap: wrap;
  row-gap: .5rem;
  padding: .7rem 0 calc(.7rem + env(safe-area-inset-bottom, 0px));
  background: linear-gradient(to top, var(--paper) 68%, rgba(255, 253, 247, 0));
}
@media (max-width: 600px) {
  /* On phones the sentence goes above the buttons rather than between them. */
  .f3-continue-note { order: -1; flex-basis: 100%; padding: 0; }
}

/* ── TU7: a one-tap way past the restored grid. ───────────────────────────── */
.f3-restored-summary {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  cursor: pointer;
  list-style: none;
  min-height: 44px;
}
.f3-restored-summary::-webkit-details-marker { display: none; }
.f3-restored-summary::after { content: "▾"; opacity: .6; font-size: .85em; }
.f3-restored-collapse:not([open]) .f3-restored-summary::after { content: "▸"; }
.f3-restored-summary .wiz-pace-heading { margin: 0; }
.f3-restored-count {
  font-size: .78rem;
  padding: .1rem .5rem;
  border-radius: 999px;
  background: var(--paper-2);
  border: 1px solid var(--line);
  color: var(--muted);
}
.f3-restored-summary:focus-visible { outline: 3px solid var(--accent, #764239); outline-offset: 2px; border-radius: 8px; }

/* ── TW6: "Trim start / Trim end" meant nothing on its own. A bar showing the
   kept span gives the two sliders something visible to move. ──────────────── */
.anim-trim-timeline { margin: .55rem 0 .25rem; }
.anim-trim-track {
  position: relative;
  height: 10px;
  border-radius: 999px;
  background: var(--paper-2);
  border: 1px solid var(--line);
  overflow: hidden;
}
.anim-trim-kept {
  position: absolute;
  top: 0;
  bottom: 0;
  background: var(--accent, #764239);
  opacity: .8;
  border-radius: 999px;
  transition: left .12s ease, width .12s ease;
}
.anim-trim-readout {
  margin: .35rem 0 0;
  font-size: .8rem;
  color: var(--muted);
  text-align: center;
}
@media (prefers-reduced-motion: reduce) {
  .anim-trim-kept { transition: none; }
}

/* ── TA4: the comparator is now focusable, so it needs a visible focus ring
   and a reachable handle. ─────────────────────────────────────────────────── */
.ba-slider:focus-visible { outline: 3px solid var(--accent, #764239); outline-offset: 3px; }
.ba-slider { touch-action: none; }

/* ── TA2: a real tablist — the panel is focusable, so mark it without a ring
   that looks like a control. ──────────────────────────────────────────────── */
#f3-effects-panel:focus { outline: none; }
#f3-effects-panel:focus-visible { outline: 3px solid var(--accent, #764239); outline-offset: 4px; border-radius: 10px; }
.f3-looktab:focus-visible { outline: 3px solid var(--accent, #764239); outline-offset: 2px; }

/* ── TA1: switches take focus from the keyboard now. ──────────────────────── */
.wiz-switch:focus-visible { outline: 3px solid var(--accent, #764239); outline-offset: 3px; border-radius: 999px; }

/* ── TA3/TA8: selection must not be colour-only. ──────────────────────────── */
.f3-reveal-seg button[aria-pressed="true"]::before,
.f3-restore-choice button[aria-pressed="true"]::before { content: "✓ "; }
.anim-style-tile[aria-pressed="true"] .anim-style-name::before { content: "✓ "; }
.anim-style-tile:focus-visible,
.f3-expand-btn:focus-visible,
.f3-reveal-demo:focus-visible { outline: 3px solid var(--accent, #764239); outline-offset: 2px; }

/* ── TA6: the fullscreen viewer is a modal dialog. ────────────────────────── */
.f3-fx-lightbox-close:focus-visible { outline: 3px solid #fff; outline-offset: 2px; }

/* ══ Mobile findings TM1–TM5 (measured at 390×844) ═══════════════════════════ */

/* TM3 — the restore/reveal switches measured 46×26. The pill stays the same
   shape on desktop, but the hit area is extended everywhere: a transparent
   pseudo-element gives ~50px of target without changing the visual. */
.wiz-switch::after { content: ""; position: absolute; inset: -10px -6px; border-radius: 999px; }

@media (max-width: 600px) {
  /* TM1 — motion styles were three tiny columns with 12.5px labels. */
  .anim-style-grid { grid-template-columns: repeat(2, 1fr); gap: 10px; }
  .anim-style-name { font-size: 14px; line-height: 1.25; }
  .anim-style-group-tag { font-size: 11px; }

  /* TM2 — the Opening/Ending toggles were ~22px and the dropdowns ~31.5px. */
  .anim-bookend-row { flex-wrap: wrap; row-gap: 6px; min-height: 44px; }
  .anim-bookend-toggle { min-height: 44px; font-size: 15px; }
  .anim-bookend-toggle input { width: 22px; height: 22px; }
  .anim-bookend-select { min-height: 44px; padding: 10px 12px; font-size: 15px; flex-basis: 100%; }

  /* TM3 — a bigger pill on touch. Travel stays 20px: 52 − 26 − (3+3). */
  .wiz-switch { width: 52px; height: 32px; }
  .wiz-switch i { width: 26px; height: 26px; }

  /* TM4 — "fullscreen" was a 92vw box over a scrolling page, which at 390px is
     the same size as the inline preview. Now it actually fills the screen.
     (The background scroll lock came with TA6.) */
  .f3-fx-lightbox { padding: 0; }
  .f3-fx-lightbox-inner { width: 100vw; max-width: 100vw; height: 100dvh; justify-content: center; gap: .5rem; }
  .f3-fx-lightbox-stage { width: 100vw; max-height: 74dvh; }
  .f3-fx-lightbox-stage .ba-slider,
  .f3-fx-lightbox-stage .f3-reveal-demo-lg { max-height: 74dvh; border-radius: 0; }
  /* The close button sat at top:-44px — off-screen once the stage is full-bleed. */
  .f3-fx-lightbox-close {
    top: max(10px, env(safe-area-inset-top, 0px));
    right: 10px;
    width: 44px;
    height: 44px;
    font-size: 20px;
    background: rgba(255, 255, 255, .28);
  }
  .f3-fx-lightbox-cap { padding: 0 1rem; text-align: center; }

  /* TM5 — the sticky bar must not sit on top of the last control, and the
     restored grid needs room to scroll clear of it. */
  #f3-effects-panel { padding-bottom: 4.5rem; }
  .wiz-actions.f3-actions-sticky { background: linear-gradient(to top, var(--paper) 78%, rgba(255, 253, 247, 0)); }
  .f3-restore-failed-item .ghost-btn,
  .f3-restore-choice button { min-height: 44px; }
}

/* ── TQ2: the spiritual-styles opt-in. Off by default, and it has to read as a
   real disclosure rather than a checkbox someone ticks without reading. ────── */
.anim-sensitive-optin {
  margin: .9rem auto 0;
  max-width: 34rem;
  padding: .75rem .9rem;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--paper-2);
}
.anim-sensitive-row {
  display: flex;
  align-items: flex-start;
  gap: .65rem;
  cursor: pointer;
  min-height: 44px;
}
.anim-sensitive-row input {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  margin-top: .15rem;
  accent-color: var(--accent);
}
.anim-sensitive-txt { display: flex; flex-direction: column; gap: .15rem; text-align: left; }
.anim-sensitive-title { font-size: .92rem; color: var(--ink); }
.anim-sensitive-desc { font-size: .82rem; line-height: 1.35; color: var(--muted); }
.anim-sensitive-row:focus-within { outline: 3px solid var(--accent, #764239); outline-offset: 3px; border-radius: 8px; }
@media (max-width: 600px) {
  .anim-sensitive-row input { width: 22px; height: 22px; }
}

/* ── PT2: the Photos tile keeps only ✕; tap the photo to open the enlarged
   editor (rotate / caption / opening ★ live there — K's ruling). The bar's
   flex container stays transparent to the pointer so the ✕'s corner is the
   only thing that intercepts a tap; everywhere else the tile itself answers
   (the auditor's dead-zone finding, fixed at the container). */
.f3-tile-bar { pointer-events: none; }
.f3-tb { pointer-events: auto; }

/* The enlarged photo editor. */
.f3pe { padding: 1.2rem; }
.f3pe-body {
  display: flex; flex-direction: column; align-items: center; gap: 14px;
  max-width: min(92vw, 720px);
}
.f3pe-fig { margin: 0; display: flex; align-items: center; justify-content: center; }
.f3pe-img {
  max-width: min(88vw, 680px); max-height: 60vh; border-radius: 10px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, .5); transition: transform .18s ease;
}
.f3pe-controls { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; }
.f3pe-btn {
  min-height: 44px; min-width: 44px; padding: 0 16px; border-radius: 10px; cursor: pointer;
  border: 1px solid rgba(255, 255, 255, .5); background: rgba(30, 22, 14, .62); color: #fff;
  font: 600 14px/1 system-ui, -apple-system, sans-serif;
  display: inline-flex; align-items: center; gap: 7px; -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
}
.f3pe-btn:hover { background: rgba(30, 22, 14, .9); }
.f3pe-btn:active { transform: translateY(1px); }
.f3pe-btn.on { background: #5a3d2b; border-color: #caa765; color: #f6e6c3; }
.f3pe-cap-row {
  display: flex; flex-direction: column; gap: 5px; width: min(88vw, 480px);
  color: #e8ddca; font: 600 12px/1 system-ui, -apple-system, sans-serif;
}
.f3pe-cap {
  min-height: 44px; border-radius: 10px; border: 1px solid rgba(255, 255, 255, .4);
  background: rgba(255, 255, 255, .96); padding: 0 12px;
  font: 500 14px/1.2 -apple-system, Segoe UI, sans-serif; color: #2b241d;
}
@media (max-height: 700px) { .f3pe-img { max-height: 46vh; } }

/* ── TR8: the inline full-screen button was 30px wide and hover-revealed —
   on touch that means invisible. It becomes 44x44 and always visible on
   coarse pointers / small screens. (The switches the same finding named
   already answer taps in a >=44px halo — TM3's ::after above extends the
   52x32 pill to ~52px of target; the audit measured the pill box.) */
@media (max-width: 600px), (hover: none) {
  .f3-expand-btn { width: 44px; height: 44px; font-size: 18px; opacity: 1; }
}

/* ── MP3/MP8/MP9: Moving portrait polish. The preview modal's close button
   meets 44px everywhere; the spiritual-styles note reads as a quiet aside;
   the fine-tune slider rows meet the 44px target on touch. */
.opening-preview-close { min-width: 44px; min-height: 44px; }
.anim-sensitive-note { display: block; margin-top: 4px; font-size: .78rem; color: #8a6d3b; }
@media (max-width: 600px), (hover: none) {
  .anim-finetune .anim-edit-row { min-height: 44px; justify-content: center; }
  .anim-finetune input[type="range"] { min-height: 44px; }
}

/* ── CH2/CH3: chapter photo thumbs drag on WebKit (which ignores `draggable`
   on form controls — the thumb is a div[role=button] now, and this is the
   WebKit opt-in for element dragging); chapter-name fields meet 44px on
   mobile (they measured 36px). */
.chapter-drag-thumb, .chapter-drag-thumb img { -webkit-user-drag: none; }
.chapter-drag-thumb { user-select: none; -webkit-user-select: none; touch-action: pan-x pan-y; }
.chapter-drag-thumb.is-dragging { cursor: grabbing; }
@media (max-width: 600px), (hover: none) {
  .chapter-step-row .chapter-title-input { min-height: 44px; }
}

/* ── CH9: 390px horizontal overflow on the Chapters step. Three culprits:
   the header actions row (Reset order · tone · Suggest) never wrapped; a
   long unbroken chapter name ran through the structure cards' summary list;
   and the fallback chapter-card title escaped its card. */
.chapter-header-actions { flex-wrap: wrap; min-width: 0; }
.module-card:has(.chapter-step-list) .module-card-header,
.module-card:has(.story-card-grid) .module-card-header { flex-wrap: wrap; min-width: 0; }
.story-card, .story-card-chapters li, .chapter-title-cell { min-width: 0; }
.cs-ch-name { min-width: 0; overflow-wrap: anywhere; }
.chapter-title-cell .f3-namecount { display: block; white-space: normal; }
.draft-player-chapter-text { max-width: 100%; }
.draft-player-chapter-title { max-width: 100%; overflow-wrap: anywhere; }

/* ── CH10: a 40-character unbroken name overflowed the chapter title card
   (clipped by the stage) and the move toast pushed its Undo button off a
   390px screen. Long names wrap AND shrink on both card variants; the toast
   message may break words and the toast spans the phone width so the Undo
   always stays on screen. */
.lm-chapter-card-title { overflow-wrap: anywhere; max-width: 96%; margin-inline: auto; }
.lm-chapter-card-title.is-long { font-size: 8.5cqi; }
.lm-chapter-card-title.is-xlong { font-size: 6.5cqi; }
.draft-player-chapter-title { margin-inline: auto; }
.draft-player-chapter-title.is-long { font-size: 6.5cqi; }
.draft-player-chapter-title.is-xlong { font-size: 5.5cqi; }
.toast-msg { min-width: 0; overflow-wrap: anywhere; }
@media (max-width: 600px) {
  .toast { left: 1rem; right: 1rem; max-width: none; justify-content: space-between; }
}

/* ── MA4/MA5: Music touch targets + the privacy dialog on a phone. Mood,
   genre, era and preference chips and the Music-level buttons meet 44px on
   touch; the privacy dialog gets a pinned header with a 44px ✕ so nobody has
   to scroll a full disclosure to close it. */
@media (max-width: 600px), (hover: none) {
  .suggestions-chip { min-height: 44px; display: inline-flex; align-items: center; }
  .music-level-btn { min-height: 44px; }
}
.privacy-panel { display: flex; flex-direction: column; padding: 0; overflow: hidden; }
.privacy-head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 16px 16px 8px 26px; border-bottom: 1px solid rgba(40,32,24,0.08);
  flex-shrink: 0;
}
.privacy-head .privacy-title { margin: 0; }
.privacy-x {
  width: 44px; height: 44px; flex: 0 0 auto; border: 0; border-radius: 10px;
  background: rgba(40,32,24,0.06); color: var(--ink, #281f18); font-size: 22px;
  line-height: 1; cursor: pointer;
}
.privacy-x:hover { background: rgba(40,32,24,0.12); }
.privacy-body { overflow: auto; padding: 12px 26px 24px; }
@media (max-width: 600px) { .privacy-head { padding-left: 16px; } .privacy-body { padding: 10px 16px 18px; } }

/* ── FN (Finish audit, 2026-08-24-j): the Finish page and player. */
/* FN5 — the preview is a shortened sample and says so. */
.f3-previewnote {
  text-align: center; font-size: .8rem; color: rgba(40,32,24,0.62);
  margin: .1rem auto .9rem; max-width: 46rem;
}
/* FN7 — the finished film stays reachable from the Finish step. */
.f3-donefilm {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; padding: 12px 16px; margin-bottom: .9rem;
}
.f3-donefilm span { min-width: 0; }
/* Demo checkout labeled where the price is, not in a footnote. */
.wiz-price-demo {
  display: block; font-size: .72rem; font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; color: #8a6d3b; margin-top: 2px;
}
/* FN10 — phone player targets: Change music (34px), the seek slider (34px),
   the Gentle-motion switch (32px) and the 42px-wide play / full-screen
   buttons all meet 44px on touch / small screens. The scrub keeps its thin
   visual track; the 44px is the focus/hit box around it. */
@media (max-width: 600px), (hover: none) {
  .review-player-changemusic, .review-player-mute { min-height: 44px; }
  .cinema-fs-btn { min-width: 44px; min-height: 44px; }
  .cinema-fs-scrub { min-height: 44px; display: flex; align-items: center; }
  .cinema-fs-scrub .cinema-fs-scrub-track { width: 100%; }
  .wiz-toggle-row .wiz-switch { position: relative; }
  .wiz-toggle-row .wiz-switch::after {
    content: ""; position: absolute; left: 50%; top: 50%;
    width: max(100%, 44px); height: 44px; transform: translate(-50%, -50%);
  }
}

/* ── FN13 (Finish re-audit): the guided trail's step buttons measured 17px
   wide at 390px (labels hide under 560px, leaving 9px dots + 4px padding as
   the whole target — a tap 10px off hit the neighboring step). Each step is
   now a 44px target on touch/small screens; the dots keep their look. */
@media (max-width: 600px), (hover: none) {
  .wiz-trail { gap: 0 2px; }
  .wiz-trail .wiz-dot { min-width: 44px; min-height: 44px; justify-content: center; }
  button.wiz-dot.is-nav { padding: 0; margin: 0; }
}

/* ── PH (K's report, 27 Aug): the enlarged photo editor paints the cached
   preview instantly and says so while full quality loads; the figure keeps
   a stable frame instead of collapsing to nothing while an image decodes. */
.f3pe-fig { min-height: 200px; display: flex; align-items: center; justify-content: center; }
.f3pe-quality {
  margin: 6px auto 0; text-align: center; font-size: .78rem;
  color: rgba(255, 253, 247, 0.85); background: rgba(30, 24, 18, 0.55);
  border-radius: 999px; padding: 4px 14px; width: fit-content; max-width: 92%;
}

/* FR1 — "Which one is he?" ------------------------------------------------
   Shown after the timeline settles, before the opening-portrait card, on the
   handful of photos where face recognition could not tell which person is the
   loved one. Our guess is pre-selected, so a correct guess costs one tap. */
.lm-fr{position:fixed;inset:0;z-index:9500;display:flex;align-items:center;justify-content:center;
  background:rgba(28,24,20,.62);-webkit-backdrop-filter: blur(3px); backdrop-filter:blur(3px);padding:16px}
.lm-fr-card{position:relative;background:var(--paper,#fffdf7);border:1px solid var(--line,rgba(36,33,31,.14));
  border-radius:16px;box-shadow:0 28px 90px rgba(56,44,29,.28);padding:18px 20px 16px;
  width:min(560px,96vw);max-height:calc(100dvh - 32px);overflow:auto;text-align:center}
.lm-fr-x{position:absolute;top:10px;right:12px;border:0;background:transparent;color:var(--muted,#9a9184);
  font-size:.78rem;cursor:pointer;padding:4px 6px;border-radius:8px}
.lm-fr-x:hover{background:#f0e8dc;color:var(--ink,#23211f)}
.lm-fr-eb{font-size:.68rem;letter-spacing:.13em;text-transform:uppercase;color:#9a9184;margin-bottom:.4rem}
.lm-fr-t{font-family:'Cormorant Garamond',Georgia,serif;font-size:1.55rem;color:#3c362c;margin:0 0 .2rem;line-height:1.1}
.lm-fr-w{font-size:.86rem;color:#8a8378;margin:0 0 .7rem}
.lm-fr-stage{position:relative;display:inline-block;max-width:100%;line-height:0;border-radius:10px;overflow:hidden}
.lm-fr-img{max-width:100%;max-height:min(46vh,380px);width:auto;height:auto;display:block}
.lm-fr-boxes{position:absolute;inset:0}
.lm-fr-box{position:absolute;padding:0;border:2px solid rgba(255,255,255,.9);border-radius:8px;
  background:transparent;cursor:pointer;transition:border-color .14s,box-shadow .14s;
  /* A pale old photograph swallows a white outline, so carry a dark edge too —
     the box has to read on a sepia print and on a dark suit alike. */
  box-shadow:0 0 0 2px rgba(30,24,18,.55),0 0 0 1px rgba(30,24,18,.45) inset}
.lm-fr-box:hover{border-color:#fff;box-shadow:0 0 0 2px rgba(30,24,18,.7),0 0 22px rgba(255,255,255,.55)}
.lm-fr-box.on{border-color:var(--accent,#b8863b);border-width:3px;
  box-shadow:0 0 0 2px rgba(30,24,18,.6),0 0 0 5px rgba(184,134,59,.34)}
.lm-fr-yr{display:flex;align-items:center;justify-content:center;gap:10px;flex-wrap:wrap;margin:.8rem 0 .2rem;
  font-size:.9rem;color:#5c554a}
.lm-fr-yr input{width:5.4rem;margin-left:.4rem;padding:.34rem .5rem;font:inherit;text-align:center;
  border:1px solid var(--line,rgba(36,33,31,.2));border-radius:8px;background:#fff}
.lm-fr-age{color:#8a8378;font-size:.85rem}
.lm-fr-row{display:flex;gap:10px;justify-content:center;flex-wrap:wrap;margin-top:.7rem}
.lm-fr-all{margin-top:.7rem;border:0;background:transparent;color:#8a8378;font-size:.8rem;cursor:pointer;
  text-decoration:underline;text-underline-offset:3px}
.lm-fr-list{margin-top:.6rem;max-height:190px;overflow-y:auto;border-top:1px solid var(--line,rgba(36,33,31,.12));
  padding-top:.5rem;text-align:left}
.lm-fr-li{display:flex;align-items:center;gap:10px;width:100%;padding:6px 8px;border:0;border-radius:9px;
  background:transparent;cursor:pointer;font:inherit}
.lm-fr-li:hover{background:#f4ece0}
.lm-fr-li.cur{background:#efe4d3}
.lm-fr-li img{width:42px;height:42px;object-fit:cover;border-radius:6px;flex:0 0 auto}
.lm-fr-li span{display:flex;flex-direction:column;font-size:.82rem;color:#5c554a;overflow:hidden}
.lm-fr-li em{font-style:normal;font-size:.7rem;color:#9a9184;letter-spacing:.04em;text-transform:uppercase}
@media (max-width:700px){
  .lm-fr{padding:8px}
  .lm-fr-card{padding:14px 14px 12px}
  .lm-fr-t{font-size:1.3rem}
  .lm-fr-img{max-height:38vh}
  .lm-fr-row{flex-direction:column-reverse}
  .lm-fr-row .primary-btn,.lm-fr-row .ghost-btn{width:100%}
}

/* ── TR1 — the scanner-edge review, shown before the timeline ─────────────
   Two panes side by side: the photo as it stands with the band we would cut
   marked on it, and the actual cropped result beside it. The family decides;
   nothing is cut until they do. */
.lm-tr{position:fixed;inset:0;z-index:9500;display:flex;align-items:center;justify-content:center;
  background:rgba(28,24,20,.62);-webkit-backdrop-filter: blur(3px); backdrop-filter:blur(3px);padding:16px}
.lm-tr-card{position:relative;background:var(--paper,#fffdf7);border:1px solid var(--line,rgba(36,33,31,.14));
  border-radius:16px;box-shadow:0 28px 90px rgba(56,44,29,.28);padding:18px 20px 16px;
  width:min(680px,96vw);max-height:calc(100dvh - 32px);overflow:auto;text-align:center}
.lm-tr-x{position:absolute;top:10px;right:12px;border:0;background:transparent;color:var(--muted,#9a9184);
  font-size:.78rem;cursor:pointer;padding:4px 6px;border-radius:8px}
.lm-tr-x:hover{background:#f0e8dc;color:var(--ink,#23211f)}
.lm-tr-eb{font-size:.68rem;letter-spacing:.13em;text-transform:uppercase;color:#9a9184;margin-bottom:.4rem}
.lm-tr-t{font-family:'Cormorant Garamond',Georgia,serif;font-size:1.55rem;color:#3c362c;margin:0 0 .2rem;line-height:1.15}
.lm-tr-w{font-size:.86rem;color:#8a8378;margin:0 auto .9rem;max-width:46ch}
.lm-tr-panes{display:flex;gap:14px;align-items:flex-start;justify-content:center;flex-wrap:wrap}
.lm-tr-fig{margin:0;flex:1 1 240px;min-width:0;max-width:300px;display:flex;flex-direction:column;align-items:center;gap:.4rem}
.lm-tr-fig figcaption{font-size:.7rem;letter-spacing:.1em;text-transform:uppercase;color:#9a9184}
.lm-tr-stage{position:relative;width:auto;max-width:100%;height:min(34vh,260px);line-height:0;border-radius:10px;
  overflow:hidden;background:#efe7db;display:inline-flex;align-items:center;justify-content:center}
.lm-tr-before{height:100%;width:auto;max-width:100%;display:block}
.lm-tr-bands{position:absolute;inset:0;pointer-events:none}
/* The band we would cut: hatched, with a hairline where the new edge lands. */
.lm-tr-band{position:absolute;display:block;
  background:repeating-linear-gradient(45deg,rgba(184,134,59,.55) 0 4px,rgba(184,134,59,.18) 4px 8px);
  outline:1px solid rgba(184,134,59,.85);outline-offset:-1px}
.lm-tr-crop{position:relative;height:min(34vh,260px);width:auto;max-width:100%;overflow:hidden;flex:0 0 auto}
.lm-tr-after{position:absolute;display:block;max-width:none}
.lm-tr-row{display:flex;gap:10px;justify-content:center;flex-wrap:wrap;margin-top:1rem}
.lm-tr-all{margin-top:.7rem;border:0;background:transparent;color:#8a8378;font-size:.8rem;cursor:pointer;
  padding:4px 8px;border-radius:8px}
.lm-tr-all:hover{background:#f4ece0;color:#5c554a}
@media (max-width:520px){
  .lm-tr-fig{flex:1 1 100%;max-width:100%}
  .lm-tr-stage{height:24vh}
  .lm-tr-crop{height:24vh}
}

/* ── Compact style panel ──────────────────────────────────────────────────
   The panel sits directly under the card it styles, so its height is not
   free: every row of chrome pushes the thing you are looking at off screen.
   Same controls as before, laid out as label-left rows instead of centred
   captions stacked over centred rows. Roughly half the height. */
.f3-style-panel { margin-top: 0.9rem; }
.f3-style-panel .f3-ft-top {
  display: flex; align-items: center; justify-content: center;
  gap: 0.55rem; margin-bottom: 0.55rem;
}
.f3-style-panel .f3-ft-lead { margin: 0; }
.f3-style-panel .f3-ft-target { margin: 0; padding: 2px; }
.f3-style-panel .f3-ft-pill { font-size: 0.8rem; padding: 0.34rem 0.95rem; }

/* One property per row: label, then its controls. */
.f3-srow {
  display: flex; align-items: flex-start; gap: 0.7rem;
  padding: 0.28rem 0; min-width: 0;
}
.f3-srow + .f3-srow { border-top: 1px solid rgba(36, 33, 31, 0.07); }
.f3-srow-lab {
  flex: 0 0 3.6rem; padding-top: 0.5rem;
  font-size: 0.68rem; font-weight: 600; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--muted, #9a9184); text-align: right;
}
.f3-srow-main { flex: 1 1 auto; min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem 0.7rem; }
.f3-srow > .f3-tstyle-row, .f3-srow-main > .f3-tstyle-row { flex: 1 1 auto; min-width: 0; padding: 0.1rem 0.1rem 0.2rem; }

/* Smaller tiles + swatches. The typeface itself is the preview, so the tile
   only has to be big enough to read "Ee" — it was sized like a thumbnail. */
.f3-style-panel .f3-tstyle { width: 2.85rem; }
.f3-style-panel .f3-tstyle-tile { height: 2.2rem; border-radius: 0.45rem; }
.f3-style-panel .f3-tstyle-nm {
  font-size: 0.6rem; line-height: 1.15; display: block;
}
.f3-style-panel .f3-col { width: 2.85rem; }
.f3-style-panel .f3-col-dot { width: 1.85rem; height: 1.85rem; margin-bottom: 0.18rem; }
.f3-style-panel .f3-col.on .f3-col-dot {
  box-shadow: 0 0 0 2px var(--paper, #fffdf7), 0 0 0 3px var(--accent, #b8863b);
}
.f3-style-panel .f3-col-quick { margin: 0; gap: 0.3rem; }
.f3-style-panel .f3-col-q { font-size: 0.7rem; padding: 0.18rem 0.6rem; }

/* Shadow: kinds and strength ride on one line when there is room for them. */
.f3-style-panel .f3-sh-main { gap: 0.45rem 0.8rem; }
.f3-style-panel .f3-sh-kinds { margin: 0; }
.f3-style-panel .f3-sh-k { font-size: 0.72rem; padding: 0.26rem 0.62rem; }
.f3-style-panel .f3-sh-slider { flex: 1 1 9rem; min-width: 8rem; gap: 0.5rem; }
.f3-style-panel .f3-sh-slider input[type="range"] { width: 100%; min-width: 5rem; }
.f3-style-panel .f3-sh-val { font-size: 0.72rem; min-width: 2.4rem; }

@media (max-width: 560px) {
  .f3-srow { flex-direction: column; gap: 0.15rem; }
  .f3-srow-lab { flex: 0 0 auto; text-align: left; padding-top: 0.2rem; }
}

/* Paper lift — the soft wash of cleaner paper a look can put under its text
   column, so small type on a mottled ground reads without a halo. Sits above
   the backdrop and below everything else, and is never interactive. The
   element's own opacity carries the strength, so the gradient stays a plain
   two-stop fade with nothing clever to fall back from. */
.titlecard-lift {
  position: absolute;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  pointer-events: none;
  opacity: var(--lift-a, .2);
  background: radial-gradient(
    ellipse at center,
    var(--lift-c, #fff8e8) 0%,
    var(--lift-c, #fff8e8) 52%,
    transparent 80%);
}

/* Divider — the small rule between the name and the dates. Six styles so a
   look can wear the one that suits it; the composition picks. Sits above the
   backdrop with the text, and is never interactive. */
.titlecard-div {
  position: absolute;
  /* --dv-shift is the descender-clearance nudge; --dv-shift-x centres an
     ornament drawn ON a line of type (divider.above) in the gap that line
     leaves for it. Both compose into the existing centring transform rather
     than overwriting the authored `left`/`top`, so the look's own placement
     stays the source of truth and each nudge is a visible, removable
     correction on top of it. */
  transform: translate(calc(-50% + var(--dv-shift-x, 0px)), calc(-50% + var(--dv-shift, 0px)));
  pointer-events: none;
  z-index: 3;
}
.tc-div-hair { height: 1px; background: var(--dv-c, #e8dcc6); }
.tc-div-double {
  height: 3px;
  background:
    linear-gradient(var(--dv-c, #e8dcc6), var(--dv-c, #e8dcc6)) top/100% 1px no-repeat,
    linear-gradient(var(--dv-c, #e8dcc6), var(--dv-c, #e8dcc6)) bottom/52% 1px no-repeat;
  background-position: top center, bottom center;
}
.tc-div-taper {
  height: 1px;
  background: linear-gradient(to right, transparent, var(--dv-c, #e8dcc6) 22%,
              var(--dv-c, #e8dcc6) 78%, transparent);
}
/* diamond / cross / sprig: a glyph flanked by two rules.
   Two bugs lived here. The box is centred on the composition's x (the parent
   translates -50%), but the flex row defaulted to flex-start, so the ink sat
   packed against the box's LEFT edge — with a 31.5% box that put the ornament
   ~10% of the card left of the name it is supposed to sit under, and it read as
   "off centre" because it WAS. And the rules were a fixed 4.6cqi, so the `w`
   the composition asks for moved the ornament without ever lengthening it —
   the same oversight the render side had already fixed for the container.
   The rules now flex to fill `w`, and the whole thing is drawn heavy enough to
   survive a bright cloud backdrop: a 1px hairline in muted gold was invisible.
   Only one composition uses this divider style, so this changes exactly it. */
.tc-div-flank { display: flex; align-items: center; justify-content: center; gap: 1.1cqi; color: var(--dv-c, #e8dcc6); }
.tc-div-flank i { display: block; flex: 1 1 auto; min-width: 0; width: auto; height: max(1.6px, 0.22cqi); background: var(--dv-c, #e8dcc6); }
.tc-div-g { font-size: 2.2cqi; line-height: 1; }
.tc-div-cross { font-size: 1.7cqi; }
.tc-div-sprig { font-size: 1.6cqi; }

/* ── PHOTO FRAME ────────────────────────────────────────────────────────────
   An ornamental surround drawn OVER the portrait — a gilt oval, a wreath. It
   sits above the picture (z 3) and below the type (z 5), and it never takes a
   click: the photo underneath stays selectable and draggable, and the frame
   follows it because app.js sizes this from the portrait's own box. */
/* FOREGROUND ART — scenery drawn in FRONT of the photograph, anchored to the
   card rather than to the picture. z-index 4 puts it over the photo (2) and the
   frame (3) and under the type (5), which is the whole point: flowers may cross
   a shoulder, never a name. Positioned from right/bottom so a corner piece keeps
   its corner at every stage size; height follows the artwork's own aspect. */
.titlecard-foreground {
  position: absolute;
  z-index: 4;
  height: auto;
  pointer-events: none;
  user-select: none;
  display: block;
}

/* LO41 — A PARTIAL FOREGROUND KEEPS ITS OWN ASPECT IN THE LOOK STRIP TOO.
   The tiles stretch every <img> inside them (`.fsv2-look img { height: 100% }`)
   so a tile's backdrop fills its card. That selector also catches the
   foreground layer and outranks the rule above, so a corner piece of scenery
   was drawn full-bleed and cover-cropped in the strip while the big preview
   had it right: in the Candlelit tile the oval ring sat off its own picture.
   Full-bleed foregrounds (right 0 / bottom 0 / w 100) were unaffected, which
   is why it stayed hidden until a look shipped a partial one. */
.titlecard-stage img.titlecard-foreground {
  height: auto;
  object-fit: fill;
}

/* A NAME WEARING A GRADIENT (LO-NAMEGRAD).
   The fill is transparent so the background shows through the glyphs, and that
   is exactly why text-shadow cannot stay: it paints behind the letter, so with
   nothing in the letter the halo appears INSIDE the stroke. The look's own
   drop-shadow (a filter, which shadows the painted result) is written inline.
   !important because the halo classes carry it too. */
.titlecard-name.tc-name-grad,
.titlecard-name.tc-name-grad.text-shadow-off,
.titlecard-name.tc-name-grad.text-shadow-light,
.titlecard-name.tc-name-grad.text-shadow-soft {
  text-shadow: none !important;
}

/* THE SWASH THAT GOT SLICED OFF.
   `background-clip: text` paints only inside the element's BORDER BOX, and the
   box is shrink-to-fit around the text's ADVANCE widths. A formal script's exit
   swash overhangs its own advance — Italianno's final `e` by about a third of an
   em — so that overhang had no background painted into it and disappeared on a
   dead vertical line. The glyph was always drawn; there was simply nothing in it.
   Read as a font that ended early, which is why it took three looks.

   Padding widens the paint area. The element is centred by translate(-50%,-50%),
   so symmetric padding grows the box around the same centre and the glyphs do
   not move: ink measured 11.97–47.74 before and after, to the hundredth.

   content-box is load-bearing. `visuals.nameMaxWidth` is authored as the width
   the TEXT may have; under the inherited border-box the padding would eat into
   it and wrap a name that fits. */
.titlecard-name.tc-name-grad {
  box-sizing: content-box;
  padding: 0.25em 0.5em;
}

/* A NAME LONG ENOUGH TO WRAP.
   The gradient is clipped to the element, so a two-line name came out navy on
   line one and gold on line two — it read as a mistake, because it is one.
   `tcSetNameTwoLines` marks a split with `br.tc-fit-br`, so a wrapped name can
   ask for one copy of the metal PER LINE instead: the band is exactly
   .titlecard-name's own 1.05 line-height, repeated down. Keep the two numbers
   in step if that line-height ever moves.
   A one-line name never matches this rule and is untouched.
   Caveat: ink overflows its line box, so a descender from line one samples the
   top of line two's band and comes back dark. Better than half a name in the
   wrong metal; the real answer is to stop a gradient name wrapping at all. */
.titlecard-name.tc-name-grad:has(.tc-fit-br) {
  background-size: 100% 1.05em;
  background-repeat: repeat-y;
  background-origin: content-box;
}

.titlecard-frame {
  position: absolute;
  transform: translate(-50%, -50%);
  pointer-events: none;
  z-index: 3;
  object-fit: fill;      /* the box is already the artwork's aspect ratio */
  user-select: none;
}

/* Drawn divider ornaments (sprig-heart, fleuron). The div carries the width
   from the composition and the SVG inside sets its own height from its aspect,
   so a sprig is never squashed no matter how wide the look asks for it. */
.titlecard-div.tc-div-art {
  color: var(--dv-c, #e8dcc6);
  line-height: 0;
}

/* Flush-left / flush-right dates. Same transform as the centred default, with
   the X translate swapped and the origin moved so --fit-scale still shrinks a
   long line toward its own edge rather than dragging it off the anchor. */
/* --dt-cx (LO26e): the measured nudge that centres UNLABELLED stacked date
   lines on each other. It sits OUTERMOST in the chain deliberately — ahead of
   scale() — so it is applied in the stage's own pixel space and the fit pass can
   write a plain measured px value without dividing it back out by --fit-scale.
   Absent everywhere else, where it resolves to 0px and changes nothing. */
.titlecard-dates.tc-al-left {
  text-align: left;
  transform-origin: left center;
  transform: translateX(var(--dt-cx, 0px)) translate(0, -50%) translateY(var(--fit-shift, 0px)) scale(var(--fit-scale, 1));
}
.titlecard-dates.tc-al-right {
  text-align: right;
  transform-origin: right center;
  transform: translateX(var(--dt-cx, 0px)) translate(-100%, -50%) translateY(var(--fit-shift, 0px)) scale(var(--fit-scale, 1));
}

/* Art divider — a supplied ornament PNG. The composition sets the width; the
   image keeps its own aspect so the sprig is never stretched, and its own
   colour, so --dv-c is deliberately not applied here. */
.titlecard-div.tc-div-img { line-height: 0; }
.titlecard-div.tc-div-img img { width: 100%; height: auto; display: block; }

/* SPLIT dates — the hairline standing between the two columns. Sits on the
   dates' own anchor x, centred on it, and takes the dates' colour unless the
   look gave the labels one of their own; quieter than the type it separates,
   the way a printed rule is. Its height comes from the render (it has to match
   the two lines beside it), so only the look of it lives here. */
/* It carries the SAME fit variables as the lines it separates (LO26p). The fit
   pass moves and scales the dates in PIXELS after the render has placed
   everything in per-cent; a rule positioned in per-cent alone therefore drifted
   off its own columns — down the card on a name that wrapped, and further still
   whenever the stage was drawn at another size. Reading the variables means the
   browser keeps the two in step, at any size, with no second measurement to go
   stale. Origin at the top, matching `.dates-multiline`, so a scaled block and
   its rule shrink the same way. */
.titlecard-dates-split-rule {
  position: absolute;
  width: 1px;
  transform-origin: top center;
  transform: translateX(var(--dt-cx, 0px)) translateX(-50%) translateY(var(--fit-shift, 0px)) scale(var(--fit-scale, 1));
  background: currentColor;
  opacity: 0.55;
  pointer-events: none;
}
/* ART SEPARATOR — the same box, but the artwork sets the width and there is no
   drawn line to tint or fade. Height is the block's; the image keeps its own
   aspect, so the piece is never squeezed and the look names no width. */
.titlecard-dates-split-rule.is-art {
  width: auto;
  background: none;
  opacity: 1;
}
.titlecard-dates-split-rule.is-art img {
  height: 100%;
  width: auto;
  display: block;
}

/* Stacked date labels — "SUNRISE" on its own line above the date. Small caps,
   widely letterspaced and a little quieter, so the label reads as a heading
   rather than competing with the date beneath it. The composition can override
   the size and colour per look (dates.labelSize / dates.labelColor). */
.titlecard-dates.tc-dt-lab {
  text-transform: uppercase;
  letter-spacing: 0.22em;
  opacity: 0.78;
}
/* The stacked dress sets its label a little lighter than the date beneath it —
   a small heading standing over a line, quieter on purpose. The SPLIT dress
   does not: there the label and its date are read together as one column, and
   a label set lighter than the date beside it looks like a mistake rather than
   a hierarchy. So a split label takes the same weight the date takes — the
   look's own, whatever the look asked for — and only the stacked one steps
   down. (K: "date should be same weight as label".) */
.titlecard-dates.tc-dt-lab:not(.tc-dt-split) {
  font-weight: 500;
}

/* Ranged-left / ranged-right for the name and the words, same as the dates. */
.titlecard-name.tc-al-left, .titlecard-preamble.tc-al-left {
  text-align: left;
  transform-origin: left center;
  transform: translate(0, -50%) translateY(var(--fit-shift, 0px)) scale(var(--fit-scale, 1));
}
.titlecard-name.tc-al-right, .titlecard-preamble.tc-al-right {
  text-align: right;
  transform-origin: right center;
  transform: translate(-100%, -50%) translateY(var(--fit-shift, 0px)) scale(var(--fit-scale, 1));
}

/* Photo bleed — the picture runs off one edge of the card and its inner edge
   dissolves into the backdrop. The mask is built in app.js from the look's own
   feather setting; overflow must stay visible-free so the mask does the work. */
.titlecard-portrait.tc-bleed {
  -webkit-mask-image: var(--bleed-mask);
  mask-image: var(--bleed-mask);
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}

/* Baskerville Regular Italic — the bokeh look's preamble. A macOS system face
   (also shipped with Office as "Baskerville Old Face"), so it resolves by name
   on the family's machine and in the headless renderer; Libre Baskerville is
   the web fallback when it does not. */
.font-preset-baskerville-italic,
.titlecard-name.font-preset-baskerville-italic,
.backdrop-text-name.font-preset-baskerville-italic,
.backdrop-text-preamble.font-preset-baskerville-italic,
.backdrop-text-dates.font-preset-baskerville-italic {
  font-family: "Baskerville", "Baskerville Old Face", "Libre Baskerville", "Baskervville", "EB Garamond", Georgia, serif;
  font-weight: 400;
  font-style: italic;
  text-transform: none;
  letter-spacing: 0.06em;
}

/* Avenir Next — the bokeh date line. macOS system face; Montserrat carries the
   same geometric-humanist proportions where it is absent. */
.font-preset-avenir-next,
.titlecard-name.font-preset-avenir-next,
.backdrop-text-name.font-preset-avenir-next,
.backdrop-text-preamble.font-preset-avenir-next,
.backdrop-text-dates.font-preset-avenir-next {
  font-family: "Avenir Next", "Avenir Next LT Pro", "Avenir", "Nunito Sans", "Montserrat", "Helvetica Neue", sans-serif;
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0.12em;
}

/* Graded wash over the backdrop (see `visuals.scrim`). Sits above the picture
   and below the dim, the ornaments and the type. */
.titlecard-scrim {
  position: absolute; inset: 0;
  pointer-events: none; z-index: 1;
}

/* Bodoni 72 — the parchment look's name. macOS system face (ships with Apple
   Fonts); Bodoni Moda carries the same high-contrast Didone shapes elsewhere. */
.font-preset-bodoni-72,
.titlecard-name.font-preset-bodoni-72,
.backdrop-text-name.font-preset-bodoni-72,
.backdrop-text-preamble.font-preset-bodoni-72,
.backdrop-text-dates.font-preset-bodoni-72 {
  font-family: "Bodoni 72", "Bodoni 72 Oldstyle", "Bodoni MT", "Bodoni Moda", "Playfair Display", Georgia, serif;
  font-weight: 400;
  font-style: normal;
  text-transform: none;
  letter-spacing: 0.04em;
}

/* Baskerville Roman — upright companion to the italic preset above. */
.font-preset-baskerville,
.titlecard-name.font-preset-baskerville,
.backdrop-text-name.font-preset-baskerville,
.backdrop-text-preamble.font-preset-baskerville,
.backdrop-text-dates.font-preset-baskerville {
  font-family: "Baskerville", "Baskerville Old Face", "Libre Baskerville", "Baskervville", "EB Garamond", Georgia, serif;
  font-weight: 400;
  font-style: normal;
  text-transform: none;
  letter-spacing: 0.08em;
}

/* Look layers — the studio's controls for the pieces that belong to the LOOK
   (frame artwork, ornaments, the graded wash, how the picture sits in its
   opening) rather than to a line of type. */
.cyo-looklayers {
  margin: 10px 0 4px; padding: 10px 12px;
  border: 1px solid rgba(120, 96, 64, 0.18); border-radius: 10px;
  background: rgba(255, 252, 245, 0.7);
}
.cyl-head {
  font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
  color: #8a7658; margin-bottom: 6px;
}
.cyl-row { display: flex; align-items: center; gap: 10px; padding: 3px 0; }
.cyl-lab { flex: 0 0 96px; font-size: 12px; color: #4a3f30; }
.cyl-range { flex: 1 1 auto; min-width: 90px; }
.cyl-val { flex: 0 0 40px; text-align: right; font-size: 11px; color: #6b5c44; font-variant-numeric: tabular-nums; }
.cyl-toggle {
  font: inherit; font-size: 11px; padding: 3px 10px; cursor: pointer;
  border-radius: 999px; border: 1px solid rgba(120, 96, 64, 0.35);
  background: #fff; color: #6b5c44;
}
.cyl-toggle.on { background: #5c4a32; border-color: #5c4a32; color: #fff; }
.cyl-note { margin-left: 8px; font-size: 11px; color: #9a8a70; font-style: italic; }
/* The pieces row: the name IS the switch. Filled = on the card, outlined and
   muted = hidden. The hint sits at the end of the row so nobody has to guess
   that the words are buttons. */
.cyl-pieces { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; padding: 3px 0 6px; }
.cyl-chip {
  font: inherit; font-size: 12px; padding: 4px 12px; cursor: pointer;
  border-radius: 999px; border: 1px solid rgba(120, 96, 64, 0.35);
  background: #fff; color: #8a7a62;
  transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
}
.cyl-chip:hover { border-color: #5c4a32; color: #4a3f30; }
.cyl-chip.on { background: #5c4a32; border-color: #5c4a32; color: #fff; }
.cyl-chip.on:hover { background: #4a3a26; color: #fff; }
.cyl-chip:focus-visible { outline: 2px solid #c9a25a; outline-offset: 2px; }
.cyl-hint { margin-left: auto; font-size: 11px; color: #9a8a70; font-style: italic; }

/* A frame drawn as a sliced border rather than a stretched image: the corner
   artwork keeps its drawn size at any proportion. Same box as .titlecard-frame. */
.titlecard-frame-sliced {
  position: absolute; transform: translate(-50%, -50%);
  pointer-events: none; border-style: solid; border-color: transparent;
  background: none;
}

/* LO-PENCIL — the studio card opens inert. The pencil arms drag/resize, and
   the armed state has to be visible: a mode you can only discover by trying
   to drag is a mode nobody finds. */
.fs-comp-stage-wrap.cyo-canvas { position: relative; }

/* LO75 — the bottom of the card was clipped off in the editor.
   .preview-stage is 16/9 with overflow:hidden; the .titlecard-stage inside it
   is 7/4 and the same width, so it is ~1.5% taller and its last ~9px were cut:
   not painted, and not hit-testable either. Any piece the fit pushed down
   there could not be tapped at all — on elegant-paper-texture the dates land
   at 98.4% once the real fonts load, and a tap on them selected nothing.
   The film does not clip it (the render frame forces the stage to 1920x1080),
   so the family was editing a card whose last strip they could not see or
   reach but which shows up in the finished film. The player already flattens
   this same nesting for the same reason — see
   .draft-player-stage-inner > .preview-stage. Match the card's own ratio
   rather than height:auto so the canvas can never collapse before the card
   has rendered. */
.cyo-canvas > .preview-stage { aspect-ratio: 7 / 4; }

.cyo-stage-lock {
  position: absolute; top: 10px; right: 10px; z-index: 6;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 10px; border-radius: 999px;
  border: 1px solid rgba(60, 48, 28, 0.14);
  background: rgba(255, 253, 248, 0.88);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  font-family: inherit; font-size: 12px; line-height: 1; color: #4a3f2f;
  cursor: pointer; box-shadow: 0 1px 3px rgba(60, 48, 28, 0.16);
  transition: background 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
}
.cyo-stage-lock:hover { background: rgba(255, 253, 248, 0.98); }
.cyo-stage-lock-ic { font-size: 13px; line-height: 1; }
/* The label stays out of the way until it is wanted — hover, keyboard focus,
   or while the mode is on, where it doubles as the "you are editing" badge. */
.cyo-stage-lock-lab {
  max-width: 0; overflow: hidden; white-space: nowrap; opacity: 0;
  transition: max-width 0.18s ease, opacity 0.18s ease;
}
.cyo-stage-lock:hover .cyo-stage-lock-lab,
.cyo-stage-lock:focus-visible .cyo-stage-lock-lab,
.cyo-stage-lock.is-on .cyo-stage-lock-lab { max-width: 150px; opacity: 1; }
.cyo-stage-lock.is-on {
  background: #4a3f2f; border-color: #4a3f2f; color: #fdf9f1;
  box-shadow: 0 1px 5px rgba(60, 48, 28, 0.3);
}
.cyo-stage-lock:focus-visible { outline: 2px solid #8c6e2c; outline-offset: 2px; }

.cyo-edithint.is-empty { display: none; }

/* Armed: show what can be moved — but ONE thing at a time. Outlining every
   element at once turned the card into a wireframe and buried the photograph,
   which is the thing the family came to look at. The affordance appears under
   the cursor, on the selected element, and for as long as a drag or resize is
   running (it must not vanish mid-gesture). Scoped to the studio canvas so the
   guided preview and the composition thumbnails are untouched.
   .cyo-canvas + .titlecard-stage beats the base rules on specificity, so every
   "show" case has to be restated here rather than left to the shorter
   selectors.
   NOT gated on the armed state. The pencil governs DRAGGING; picking a line to
   restyle it works either way, so the box that tells you what you are about to
   pick has to look the same in both. It was gated, and the result was that the
   dates box (which never was) looked loud while the name and preamble stayed
   faint — the same gesture answered two different ways. The drag-only
   affordances — corner dots, the group rectangle — stay armed-only below. */
.cyo-canvas .titlecard-stage.backdrop-stage-area [data-selectable-element]:hover,
.cyo-canvas .titlecard-stage.backdrop-stage-area [data-selectable-element]:focus-visible,
.cyo-canvas .titlecard-stage.backdrop-stage-area [data-selectable-element].is-selected,
.cyo-canvas .titlecard-stage.backdrop-stage-area [data-selectable-element].is-dragging,
.cyo-canvas .titlecard-stage.backdrop-stage-area [data-selectable-element].is-resizing {
  /* Loud enough to find on a bright backdrop: gold reads as "this is a
     control", the dark inner ring keeps it legible over pale cloud and white
     roses, and the soft drop shadow lifts it off busy artwork. A hairline in
     40%-alpha khaki was invisible on every card we actually ship. */
  outline: 3px dashed var(--tc-ink, #4f3310);
  outline-offset: 3px;
  background-color: var(--tc-wash, rgba(201, 162, 90, 0.2));
  box-shadow:
    0 0 0 3px var(--tc-halo, rgba(255, 255, 255, 0.95)),
    0 0 0 7px var(--tc-halo-soft, rgba(255, 255, 255, 0.6)),
    0 3px 14px rgba(40, 30, 10, 0.45);
  border-radius: 2px;
}
/* The photograph is selectable too, but its shape IS the content. The 2px
   corner above is for text boxes; on the portrait it squared off an oval the
   moment the cursor touched it — the frame stayed oval, the picture behind it
   did not, and the family saw the photo poking out of its own frame. Restate
   the round treatments at higher specificity so hover/selection never
   reshapes them. A rectangle opening's radius is inline, so it already wins. */
.cyo-canvas .titlecard-stage.backdrop-stage-area .titlecard-portrait.treatment-oval[data-selectable-element],
.cyo-canvas .titlecard-stage.backdrop-stage-area .titlecard-portrait.treatment-circular[data-selectable-element] {
  border-radius: 50%;
}
/* And the same ring as the text lines. The base rule gives a selected photo a
   solid accent-blue outline (!important, so hover can't repaint it gold);
   once that outline started hugging an oval it read as a blue border ON the
   card. Dashed ink with the white halo is unmistakably a control. */
.cyo-canvas .titlecard-stage.backdrop-stage-area .titlecard-portrait.is-selected,
.cyo-canvas .titlecard-stage.backdrop-stage-area .titlecard-portrait.is-editable.is-selected:hover {
  outline: 3px dashed var(--tc-ink, #4f3310) !important;
  outline-offset: 3px;
}

/* Corner dots: the base rule keeps them at opacity .75 always. In the studio
   that is eight dots on three lines before anyone has reached for anything. */
.cyo-canvas .backdrop-stage-area:not(.is-select-only) .backdrop-text-resize-handle {
  opacity: 0;
  pointer-events: none;
}
.cyo-canvas .backdrop-stage-area:not(.is-select-only) [data-selectable-element]:hover .backdrop-text-resize-handle,
.cyo-canvas .backdrop-stage-area:not(.is-select-only) [data-selectable-element].is-selected .backdrop-text-resize-handle,
.cyo-canvas .backdrop-stage-area:not(.is-select-only) [data-selectable-element].is-dragging .backdrop-text-resize-handle,
.cyo-canvas .backdrop-stage-area:not(.is-select-only) [data-selectable-element].is-resizing .backdrop-text-resize-handle {
  opacity: 1;
  transform: scale(1);
  pointer-events: auto;
}

/* The group box's dashed rectangle is the biggest single piece of furniture on
   the card. Keep the box (it still catches the group drag) and drop its ink. */
.cyo-canvas .backdrop-stage-area:not(.is-select-only) .backdrop-group-box {
  border-color: transparent;
  background: transparent;
}
.cyo-canvas .backdrop-stage-area:not(.is-select-only) .backdrop-group-box:has(.backdrop-group-box-edge:hover),
.cyo-canvas .backdrop-stage-area:not(.is-select-only) .backdrop-group-box:has(.backdrop-group-box-corner:hover),
.cyo-canvas .backdrop-stage-area:not(.is-select-only) .backdrop-group-box.is-dragging {
  border: 3px dashed var(--tc-ink, #4f3310);
  background: var(--tc-wash, rgba(201, 162, 90, 0.2));
  box-shadow:
    0 0 0 3px var(--tc-halo, rgba(255, 255, 255, 0.95)),
    0 0 0 7px var(--tc-halo-soft, rgba(255, 255, 255, 0.6)),
    0 3px 14px rgba(40, 30, 10, 0.45);
}
/* LO76 — WHILE A PIECE IS SELECTED, THE FRAME IS THERE.
   It used to vanish entirely the moment anything was selected, because as a
   filled rectangle it would otherwise reappear under the cursor and swallow the
   click that deselects. A frame cannot do that — its middle takes no pointer —
   so it can stay, and it should: "move all the words together" is exactly what
   a family wants next after they have tapped one of them, and with the pencil
   gone this is how they find out the handle exists. Quiet at rest, solid on
   hover, corners live throughout.
   The card at rest, with nothing selected, still shows nothing. */
.cyo-canvas .backdrop-stage-area.has-element-selected .backdrop-group-box {
  border-color: rgba(201, 162, 90, 0.5);
  border-style: dashed;
}
.cyo-canvas .backdrop-stage-area.has-element-selected .backdrop-group-box .backdrop-group-box-corner {
  opacity: 1;
}

/* .is-active/.is-selected deliberately NOT here: the group box carries one of
   those permanently once the group is picked, which is what kept the dashed
   rectangle painted on the card at rest. Hover and drag only. */

/* LO-DATES — one selection box across every date line. It is a sibling of the
   lines (they are independently positioned, so they cannot be wrapped without
   rewriting the per-line drag maths), sized in JS to their union, and it never
   takes a pointer: the lines underneath keep their own drag and click. */
/* LO67 — THE BOX IS THE TARGET, NOT JUST THE WORDS INSIDE IT. K: "why hover
   not on full date box just on text within."
   Because the hover was read off the date LINES and the rectangle is drawn
   bigger than they are: 6px of padding all round (PAD, below) and — side by
   side — a gutter between the two columns with no element in it at all. So the
   cursor crossed the drawn box, nothing happened, and then a few pixels later
   it lit up. The rectangle IS the affordance, so it is the hit area too: it
   takes the pointer, lights itself on hover, and resolves to the dates on a
   click (tcSelectableOwner). It stays at z-4, under the lines and their grips
   at z-7, so it only ever answers for the parts of itself that are empty.
   One thing it deliberately does not do is drag: the drag handles are the
   lines, and the empty gutter is not one of them. */
.cyo-canvas .tc-dates-box {
  position: absolute;
  pointer-events: auto;
  cursor: pointer;
  opacity: 0;
  border-radius: 2px;
  outline: 3px dashed var(--tc-ink, #4f3310);
  outline-offset: 3px;
  background-color: var(--tc-wash, rgba(201, 162, 90, 0.2));
  box-shadow:
    0 0 0 3px var(--tc-halo, rgba(255, 255, 255, 0.95)),
    0 0 0 7px var(--tc-halo-soft, rgba(255, 255, 255, 0.6)),
    0 3px 14px rgba(40, 30, 10, 0.45);
  z-index: 7;
  transition: opacity 0.12s ease;
}
.cyo-canvas .backdrop-stage-area.dates-selected .tc-dates-box,
.cyo-canvas .backdrop-stage-area.dates-hover .tc-dates-box { opacity: 1; }
/* LO-DATEGRIPS — the corner dots were there but nobody could see them. Two
   reasons: (1) the studio only reveals a line's dots while THAT line is
   hovered, and only line 0 carries the selectable attribute, so pointing at
   the second date lit the union box with no dots; (2) the dots are children
   of line 0, whose own z-index makes a stacking context, so the union box
   (z 7) painted its wash and halo OVER them even on line 0. Show the dots
   whenever the union box shows, and draw the box beneath the lines. */
.cyo-canvas .tc-dates-box { z-index: 4; }
.cyo-canvas .backdrop-stage-area:not(.is-select-only).dates-hover .titlecard-dates .backdrop-text-resize-handle,
.cyo-canvas .backdrop-stage-area:not(.is-select-only).dates-selected .titlecard-dates .backdrop-text-resize-handle {
  opacity: 1;
  transform: scale(1);
  pointer-events: auto;
}

/* Line 0 is the only date line carrying data-selectable-element, so the
   generic outline would draw a second box around "Sunrise: …" alone, inside
   the one that spans both. Let the union box speak for the whole element. */
/* The base sheet paints .titlecard-dates by CLASS on hover and when selected
   (outline-color + a faint wash). That hits BOTH date lines — line 1 has no
   data-selectable-element, so the attribute-based suppression below missed it,
   and two adjacent 1px outlines merged into a second tight box inside the union
   box, flickering as the cursor crossed from one line to the other. Extra
   .cyo-canvas on the front so this outranks the base rule by specificity rather
   than by file order. */
/* Two failures were stacked here, both of them specificity arithmetic:
   1. the attribute suppression was written at (0,4,0) — one class short of the
      generic loud rule above it at (0,5,0) — so line 0 got the 3px dashed box
      back on hover, drawn INSIDE the union box;
   2. the class suppression only zeroed outline-COLOR and background-color, so
      the generic rule's three box-shadow rings survived on line 0 and painted
      an inner box of their own even when the outline went transparent.
   Both selectors now sit at >= the generic rule's depth and clear every
   property it sets. The union box (.tc-dates-box) is the only date ink. */
.cyo-canvas .titlecard-stage.backdrop-stage-area .titlecard-dates,
.cyo-canvas .titlecard-stage.backdrop-stage-area .titlecard-dates:hover,
.cyo-canvas .titlecard-stage.backdrop-stage-area .titlecard-dates:focus-visible,
.cyo-canvas .titlecard-stage.backdrop-stage-area .titlecard-dates.is-selected,
.cyo-canvas .titlecard-stage.backdrop-stage-area .titlecard-dates.is-dragging,
.cyo-canvas .titlecard-stage.backdrop-stage-area .titlecard-dates.is-resizing,
.cyo-canvas .titlecard-stage.backdrop-stage-area [data-selectable-element="dates"],
.cyo-canvas .titlecard-stage.backdrop-stage-area [data-selectable-element="dates"]:hover,
.cyo-canvas .titlecard-stage.backdrop-stage-area [data-selectable-element="dates"]:focus-visible,
.cyo-canvas .titlecard-stage.backdrop-stage-area [data-selectable-element="dates"].is-selected,
.cyo-canvas .titlecard-stage.backdrop-stage-area [data-selectable-element="dates"].is-dragging,
.cyo-canvas .titlecard-stage.backdrop-stage-area [data-selectable-element="dates"].is-resizing {
  outline: none;
  outline-color: transparent;
  background-color: transparent;
  box-shadow: none;
}

/* LO-PENCIL — one place to tune how loud the editing affordance is. A single
   gold hairline vanished on cream cards; the pairing that survives ANY artwork
   is a dark dashed ink with a light halo on both sides of it, so there is
   always contrast against whatever is underneath. */
.cyo-canvas {
  --tc-ink: #4f3310;
  --tc-halo: rgba(255, 255, 255, 0.95);
  --tc-halo-soft: rgba(255, 255, 255, 0.6);
  --tc-wash: rgba(201, 162, 90, 0.2);
}

/* LO-ORNAMENT — the ornament is pickable in the editor, so it takes a pointer
   there (it is decorative and inert everywhere else) and wears the same
   hover/selected box as any other element on the card. */
.titlecard-div.is-pickable { pointer-events: auto; cursor: pointer; }
/* LO55 — a hairline is 1px tall, and a 1px target is not a target. The pointer
   has to be INSIDE an element's box before anything else gets a say (the ink
   hit test only mutes pieces already under it), so a pickable ornament carries
   an invisible pad that gives the hand something to land on. It changes no
   layout and paints nothing; the type above it is at a higher z-index, so the
   pad never takes a click meant for a line of words. */
.titlecard-div.is-pickable::before {
  content: "";
  position: absolute;
  inset: -10px 0;
  pointer-events: auto;
}
/* LO-ORNHOVER — with the pencil on, the dashed group box (z-index 6) is drawn
   over the text block, and an ornament sitting inside that block was under it
   (z-index 3): pointing at the ornament lit the whole box instead. With the
   pencil off the group box is not drawn at all, which is why it only happened
   "sometimes". Lift the pickable ornament above the box while the box exists,
   so the thing under the cursor is the thing that lights up and takes the
   drag. The box keeps the gap space between the lines, as before. */
.titlecard-stage:not(.is-select-only) .titlecard-div.is-pickable { z-index: 7; }

/* The gallery in the side panel. Two columns of real artwork: these ornaments
   differ by shape and weight, and a list of names would tell a family nothing
   about what they are choosing. */
.cyi-orns {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  margin-top: 4px;
}
.cyi-orn {
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  padding: 9px 7px 7px;
  border: 1px solid #e8dfcd; border-radius: 8px; background: #fff;
  cursor: pointer; font: inherit; line-height: 1.15;
  transition: border-color 0.12s ease, background 0.12s ease, box-shadow 0.12s ease;
}
.cyi-orn img { width: 100%; height: 22px; object-fit: contain; display: block; }
.cyi-orn-drawn { font-size: 11px; color: #8a7f6d; height: 22px; display: flex; align-items: center; }
.cyi-orn-lab { font-size: 10.5px; color: #6f675b; text-align: center; }
.cyi-orn:hover { background: #fdfaf3; border-color: #d8caa8; }
.cyi-orn.on {
  border-color: #6e3f2f; background: #fdf7ef;
  box-shadow: inset 0 0 0 1px #6e3f2f;
}
.cyi-orn.on .cyi-orn-lab { color: #6e3f2f; font-weight: 600; }

/* Size picker, floated right off the Show heading. */
.cyi-sect-h.cyi-sect-h-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
}
.cyi-sect-h-val{display:inline-flex;align-items:center;gap:6px;font-size:11.5px;font-weight:500;letter-spacing:0;text-transform:none;color:#6b6353;}
.cyi-sect-h-val .cyi-swatch{width:16px;height:16px;flex:0 0 16px;align-self:auto;border:1px solid rgba(0,0,0,.12);border-radius:5px;}
.cyi-sizes { display: inline-flex; gap: 3px; }
.cyi-size {
  font: inherit; font-size: 10.5px; font-weight: 600; letter-spacing: 0.02em;
  min-width: 26px; padding: 3px 6px; cursor: pointer;
  border: 1px solid #e8dfcd; background: #fff; color: #6f675b;
  border-radius: 5px; line-height: 1.2; text-transform: none;
}
.cyi-size:hover { background: #f6f0e4; }
.cyi-size.on { background: #6e3f2f; border-color: #6e3f2f; color: #fff8ee; }

/* Armed: the ornament drags, and four corner grips resize it (ORN-CORNERS —
   the same dots as the name and the photo). Width is symmetric about the
   centre, so a grip travels twice the edge. */
.titlecard-div[data-titlecard-div-drag] { cursor: grab; }
.titlecard-div[data-titlecard-div-drag].is-dragging { cursor: grabbing; }
.tc-div-grip {
  position: absolute;
  width: 11px; height: 11px; border-radius: 50%;
  background: #c9a25a; border: 2px solid #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
  cursor: nwse-resize; opacity: 0; pointer-events: auto; z-index: 8;
  transition: opacity 0.12s ease;
}
.tc-div-grip.corner-tl { top: -6px; left: -6px; cursor: nwse-resize; }
.tc-div-grip.corner-tr { top: -6px; right: -6px; cursor: nesw-resize; }
.tc-div-grip.corner-bl { bottom: -6px; left: -6px; cursor: nesw-resize; }
.tc-div-grip.corner-br { bottom: -6px; right: -6px; cursor: nwse-resize; }
.titlecard-div[data-titlecard-div-drag]:hover .tc-div-grip,
.titlecard-div[data-titlecard-div-drag].is-selected .tc-div-grip,
.titlecard-div[data-titlecard-div-drag].is-dragging .tc-div-grip { opacity: 1; }

/* LO-UNDO — Undo / Redo in the Fine-tune chips row. They sit with Reset all
   rather than in the panel because they are about the WHOLE card, not the
   selected line, and because that row is the only place a family already looks
   for a way back. Disabled has to read as "nothing to undo yet", not as a
   broken control, so it loses its ink rather than its shape. */
/* Undo, Redo and Reset all belong together on the right — they are the three
   "about the whole card" controls, as against the Show toggles on the left.
   The auto margin moves off Reset all onto Undo so the trio travels as one
   group; without it, adding two chips pushed Reset all onto a line of its own
   and the row read as two unrelated things. */
.cyo-chips-right {
  display: inline-flex; align-items: center; gap: 9px;
  margin-left: auto;
}
.cyo-chip-reset { margin-left: 0; }
.cyo-chip.cyo-chip-undo {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
  padding-left: 13px;
}
.cyo-chip.cyo-chip-undo:disabled {
  opacity: 0.38;
  cursor: default;
  pointer-events: none;
}

/* LO-TINT — recolouring an ornament from its own artwork.
   The <img> stays in flow and sizes the box (so nothing needed the file's
   aspect ratio); the metal sits behind it, masked by the same file's alpha;
   the img rides on top in a luminosity blend so the original's highlight and
   shading survive the recolour. `isolation` keeps the blend inside the
   ornament instead of picking up the backdrop photo underneath. */
.titlecard-div.tc-div-img.is-tinted { isolation: isolate; }
.titlecard-div.tc-div-img.is-tinted > .tc-div-metal {
  position: absolute; inset: 0; z-index: 0; display: block;
  background-image: var(--dv-metal);
  -webkit-mask-image: var(--dv-mask); mask-image: var(--dv-mask);
  -webkit-mask-size: 100% 100%; mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
  pointer-events: none;
}
.titlecard-div.tc-div-img.is-tinted > img {
  position: relative; z-index: 1;
  mix-blend-mode: luminosity;
  opacity: var(--dv-model, 0.55);
}

/* The Metal row in the ornament panel. Each swatch is the actual gradient the
   card will paint, so the choice is made from the thing itself. */
.cyi-metals {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 7px; margin-top: 4px;
}
.cyi-metal {
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  padding: 7px 5px 6px; border: 1px solid #e8dfcd; border-radius: 8px;
  background: #fff; cursor: pointer; font: inherit; line-height: 1.15;
  transition: border-color 0.12s ease, background 0.12s ease, box-shadow 0.12s ease;
}
.cyi-metal-sw {
  width: 100%; height: 16px; border-radius: 4px;
  box-shadow: inset 0 0 0 1px rgba(60, 46, 24, 0.12);
}
/* "As drawn" has no gradient — show the absence rather than an empty box. */
.cyi-metal.is-orig .cyi-metal-sw {
  background:
    linear-gradient(45deg, #efe8da 25%, transparent 25%, transparent 75%, #efe8da 75%) 0 0/8px 8px,
    linear-gradient(45deg, #efe8da 25%, #fff 25%, #fff 75%, #efe8da 75%) 4px 4px/8px 8px;
}
.cyi-metal-lab { font-size: 10.5px; color: #6f675b; text-align: center; }
.cyi-metal:hover { background: #fdfaf3; border-color: #d8caa8; }
.cyi-metal.on {
  border-color: #6e3f2f; background: #fdf7ef;
  box-shadow: inset 0 0 0 1px #6e3f2f;
}
.cyi-metal.on .cyi-metal-lab { color: #6e3f2f; font-weight: 600; }
/* Faint on this card's ground — said, not blocked. */
.cyi-metal.is-poor .cyi-metal-lab::after {
  content: " ·"; color: #b98a2a; font-weight: 700;
}
.cyi-metal-note {
  margin: 8px 0 0; font-size: 11.5px; line-height: 1.4; color: #8a5a2a;
  background: #fdf7e8; border: 1px solid #ecdcb4; border-radius: 7px; padding: 7px 9px;
}

/* LO-ORN-SCROLL — the gallery is 16 tiles, which pushed Metal (and everything
   under it) off the bottom of the panel. Cap it at five rows and let it scroll.
   The extra 14px deliberately reveals the top sliver of row six: a clean cut at
   exactly five rows looks like the end of the list, and nobody scrolls a list
   they think has ended. */
.cyi-orns {
  --orn-row: 57px;
  --orn-gap: 8px;
  max-height: calc(var(--orn-row) * 5 + var(--orn-gap) * 5 + 14px);
  overflow-y: auto;
  /* Don't hand the scroll to the panel behind when this hits its end. */
  overscroll-behavior: contain;
  /* Room for the scrollbar so the right-hand tiles aren't clipped by it. */
  padding-right: 5px;
  scrollbar-width: thin;
  scrollbar-color: #d8caa8 transparent;
}
.cyi-orns::-webkit-scrollbar { width: 8px; }
.cyi-orns::-webkit-scrollbar-track { background: transparent; }
.cyi-orns::-webkit-scrollbar-thumb {
  background: #ddd0b4; border-radius: 999px;
  border: 2px solid #fffdf8;
}
.cyi-orns::-webkit-scrollbar-thumb:hover { background: #c8b795; }

/* LO-ZOOM — "view this card full screen", on the Look preview and in Fine-tune.
   Both hosts are position:relative already (the pencil pill sits in one of
   them), so the button anchors to the card. */
.tc-zoom-btn {
  position: absolute; top: 10px; left: 10px; z-index: 6;
  width: 30px; height: 30px; padding: 0;
  display: grid; place-items: center;
  font: inherit; font-size: 15px; line-height: 1;
  color: #4a3f31; cursor: pointer;
  background: rgba(255, 253, 248, 0.9);
  border: 1px solid rgba(120, 100, 70, 0.22); border-radius: 999px;
  box-shadow: 0 2px 8px rgba(50, 40, 20, 0.16);
  opacity: 0; transition: opacity 0.14s ease, background 0.14s ease;
}
/* Quiet until wanted — the card should be the thing on the screen, not the
   furniture around it. Always visible on touch, where there is no hover. */
.fs-comp-stage-wrap:hover > .tc-zoom-btn,
.fsv2-md-stage:hover > .tc-zoom-btn,
.tc-zoom-btn:focus-visible { opacity: 1; }
.tc-zoom-btn:hover { background: #fff; }
@media (hover: none) { .tc-zoom-btn { opacity: 1; } }

.tc-zoom {
  position: fixed; inset: 0; z-index: 9000;
  display: grid; place-items: center; padding: 3vmin;
  background: rgba(28, 24, 18, 0.9);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
  animation: tcZoomIn 0.16s ease;
}
@keyframes tcZoomIn { from { opacity: 0 } to { opacity: 1 } }
body.tc-zoom-open { overflow: hidden; }
/* The card keeps its own shape and takes whichever of width/height runs out
   first, so it is as large as the screen allows and never cropped. */
.tc-zoom-inner {
  width: min(96vw, calc(94vh * 16 / 9));
  max-height: 94vh;
  border-radius: 14px; overflow: hidden;
  box-shadow: 0 30px 80px -20px rgba(0, 0, 0, 0.7);
}
.tc-zoom-inner > .titlecard-stage { width: 100%; height: auto; }
.tc-zoom-x {
  position: absolute; top: 16px; right: 18px;
  width: 38px; height: 38px; padding: 0;
  font: inherit; font-size: 22px; line-height: 1; color: #f3ece1;
  background: rgba(255, 255, 255, 0.12); border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: 999px; cursor: pointer;
}
.tc-zoom-x:hover { background: rgba(255, 255, 255, 0.22); }

/* The preamble's Custom text field. It is a textarea because that line may be
   two — see the note where it is rendered. Matches .cyi-input in every other
   respect; only the height and the resize affordance differ. */
.cyi-textarea {
  resize: vertical;
  min-height: 2.6rem;
  line-height: 1.35;
  font-family: inherit;
}

/* LO-REFRAME — "move the picture inside its shape" (Fine-tune, pencil on).
   The chip hangs just under the selected photo's box; the ghost is the full
   picture drawn faint behind the shape while the mode is on, so the family
   can see what they are pulling into the opening. */
.tc-reframe-chip {
  position: absolute; z-index: 11; display: none;
  transform: translate(-50%, 8px);
  font: inherit; font-size: 0.8rem; font-weight: 600; line-height: 1;
  padding: 0.42em 0.9em; border-radius: 999px; cursor: pointer; white-space: nowrap;
  border: 1px solid rgba(255, 255, 255, 0.85);
  background: rgba(46, 34, 18, 0.88); color: #fff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
}
.titlecard-portrait.is-selected + .tc-reframe-chip { display: inline-block; }
.tc-reframe-chip:hover { background: rgba(46, 34, 18, 1); }
.tc-reframe-chip[aria-pressed="true"] { background: #c9a25a; color: #2e2212; border-color: #fff; }
.tc-reframe-chip:focus-visible { outline: 2px solid #c9a25a; outline-offset: 2px; }
/* The ghost shows what is OUTSIDE the shape while the picture is being moved —
   a faint unclipped copy behind it. At 0.38 over the whole photo box it covered
   a third of the card as a hard-edged rectangle lying across the painted
   leaves, and read as the card being broken rather than as a hint (K: "this
   zoom is still not right" — half of that was this). Quieter, and faded out at
   its own edges so there is no rectangle to mistake for one. (LO26z) */
.tc-reframe-ghost {
  position: absolute; z-index: 1; pointer-events: none;
  width: var(--portrait-size, 30%); height: var(--portrait-height, 40%);
  transform: translate(-50%, -50%); opacity: 0.16;
  -webkit-mask-image: radial-gradient(closest-side at 50% 50%, #000 55%, transparent 100%);
  mask-image: radial-gradient(closest-side at 50% 50%, #000 55%, transparent 100%);
}
.tc-reframe-ghost { container-type: size; }
.tc-reframe-ghost > img { display: block; width: 100%; height: 100%; object-fit: cover; }
.titlecard-stage.is-reframing .titlecard-portrait { cursor: move; }
.titlecard-stage.is-reframing .titlecard-portrait.is-panning { cursor: grabbing; }
/* While the picture is being moved, the box must read as fixed: no corner dots
   to grab by mistake, and the selection ring stays as a still frame. */
.titlecard-stage.is-reframing .titlecard-portrait .titlecard-handle { display: none; }

/* ── CYO — Create your own (the builder on the Look step, and its tiles) ── */
.fsv2-cyo-tile{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;min-height:150px;border:1.5px dashed rgba(118,66,57,.45)!important;background:rgba(255,253,247,.6)!important;color:#764239;cursor:pointer;border-radius:8px;}
.fsv2-cyo-tile:hover{background:#fffdf7!important;border-color:#764239!important;}
.fsv2-cyo-plus{width:34px;height:34px;border-radius:50%;border:1.5px solid rgba(118,66,57,.45);display:grid;place-items:center;font-size:20px;line-height:1;}
.fsv2-cyo-lab{font-size:13.5px;font-weight:600;}
.fsv2-cyo-sub{font-size:11.5px;color:#726a5d;text-align:center;padding:0 10px;}
.fsv2-own{position:relative;cursor:pointer;}
.fsv2-own-name{position:absolute;left:8px;bottom:8px;background:rgba(35,33,31,.82);color:#fffdf8;font-size:11px;font-weight:600;padding:4px 9px;border-radius:999px;pointer-events:none;max-width:60%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.fsv2-own-acts{position:absolute;right:8px;bottom:8px;display:flex;gap:4px;opacity:0;transition:opacity .12s ease;}
.fsv2-own:hover .fsv2-own-acts,.fsv2-own:focus-within .fsv2-own-acts{opacity:1;}
.fsv2-own-edit,.fsv2-own-del{font:inherit;font-size:11px;font-weight:600;padding:4px 9px;border-radius:999px;border:1px solid rgba(118,66,57,.35);background:#fffdf7;color:#764239;cursor:pointer;}
.fsv2-own-del{padding:4px 7px;color:#8a7d6d;}
.fsv2-own-del:hover{color:#a54848;border-color:#a54848;}
.fsv2-own-empty{min-height:120px;background:#f3ecdd;}
.fsv2-md-startfrom{margin-left:8px;}
.fsv2.is-building .fsv2-feelrow .fsv2-feelings{opacity:.45;pointer-events:none;}

.cyo-builder{margin:0 0 18px;}
.cyo-b-hd{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;margin:0 0 16px;}
.cyo-b-h{font-family:Georgia,'Times New Roman',serif;font-weight:600;font-size:24px;margin:3px 0 4px;color:#3a3129;}
.cyo-b-h em{font-style:italic;color:#764239;}
.cyo-b-sub{margin:0;font-size:14px;color:#5b564e;}
.cyo-b-back{font:inherit;font-size:13.5px;font-weight:500;color:#764239;background:none;border:0;cursor:pointer;padding:6px 0;white-space:nowrap;}
.cyo-b-back:hover{color:#57312d;text-decoration:underline;}
.cyo-b-cols{display:grid;grid-template-columns:380px minmax(0,1fr);gap:28px;align-items:start;}
@media (max-width:1000px){.cyo-b-cols{grid-template-columns:1fr;}}
/* While a family is building, the Look step lets go of its 1180px column and
   takes the screen: the pieces panel stays a fixed width, the card gets the
   rest and stays put while the panel scrolls. The card is the point. */
.f3-embed-wrap:has(.fsv2.is-building){width:min(1640px,calc(100vw - 2.5rem));margin-left:max(-820px,calc((100vw - 2.5rem) / -2));}
@media (min-width:1001px){
  .cyo-b-stagecol{position:sticky;top:16px;max-width: calc((100vh - 130px) * 1.75); max-width: calc((100dvh - 130px) * 1.75);}
}
.cyo-b-filters{display:flex;flex-wrap:wrap;gap:6px;}
.cyo-b-filter{font:inherit;font-size:12px;font-weight:500;padding:5px 11px;border-radius:999px;border:1px solid rgba(36,33,31,.18);background:transparent;color:#5b564e;cursor:pointer;}
.cyo-b-filter.on{background:#5f7165;border-color:#5f7165;color:#fffdf8;}
.cyo-b-grid{display:grid;gap:8px;max-height:340px;overflow:auto;padding:3px;margin:-3px;}
.cyo-b-grid-bd{grid-template-columns:repeat(3,minmax(0,1fr));}
.cyo-b-grid-lay{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px 12px;max-height:420px;}
.cyo-b-tile{position:relative;aspect-ratio:16/10;border-radius:6px;overflow:hidden;border:1px solid rgba(36,33,31,.14);background:#f3ecdd;padding:0;cursor:pointer;}
.cyo-b-tile img{display:block;width:100%;height:100%;object-fit:cover;}
.cyo-b-tile.on{outline:2px solid #764239;outline-offset:-2px;box-shadow:0 0 0 3px rgba(118,66,57,.14);}
.cyo-b-check{position:absolute;right:5px;top:5px;width:18px;height:18px;border-radius:50%;background:#764239;color:#fff;font-size:10px;display:grid;place-items:center;}
.cyo-b-tile-soon{border-style:dashed;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;color:#a79d88;font-size:10.5px;font-weight:600;cursor:default;background:transparent;}
.cyo-b-tile-soon small{font-weight:400;font-size:10px;}
/* OWN-BACKDROP — the family's own pictures as backdrops. */
.cyo-b-sub{font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:#8a7b5c;margin:2px 0 -4px;}
.cyo-b-tile-yours,.cyo-b-tile-up{border-style:dashed;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;color:#5f7165;font:inherit;font-size:10.5px;font-weight:600;background:rgba(95,113,101,.06);cursor:pointer;}
.cyo-b-tile-yours span,.cyo-b-tile-up span{font-size:20px;line-height:1;}
.cyo-b-tile-yours small,.cyo-b-tile-up small{font-weight:600;font-size:10.5px;}
.cyo-b-tile-yours:hover,.cyo-b-tile-up:hover{background:rgba(95,113,101,.14);}
.cyo-b-tile-x{position:absolute;left:5px;top:5px;width:18px;height:18px;border-radius:50%;background:rgba(36,33,31,.72);color:#fff;font-size:13px;line-height:1;display:grid;place-items:center;opacity:0;transition:opacity 120ms ease;}
.cyo-b-tile:hover .cyo-b-tile-x{opacity:1;}
.cyo-b-own-tune{display:flex;flex-direction:column;gap:6px;padding:8px 10px;border-radius:8px;background:#f6f1e6;border:1px solid rgba(36,33,31,.10);}
.cyo-b-own-row{display:grid;grid-template-columns:38px 1fr 30px;align-items:center;gap:8px;font-size:12px;color:#5b564e;}
.cyo-b-own-row input[type=range]{width:100%;accent-color:#5f7165;}
.cyo-b-own-row b{text-align:right;font-weight:600;color:#23211f;font-size:11.5px;}
.cyo-b-lay{display:flex;flex-direction:column;gap:6px;font:inherit;background:transparent;border:0;padding:0;cursor:pointer;text-align:left;color:#23211f;}
.cyo-b-layart{display:block;position:relative;aspect-ratio:16/9;border-radius:6px;border:1px solid rgba(36,33,31,.14);background:linear-gradient(160deg,#f6f0e4,#e8dfcc);overflow:hidden;}
.cyo-b-lay.on .cyo-b-layart{border:2px solid #764239;box-shadow:0 0 0 3px rgba(118,66,57,.14);}
.cyo-skel{position:absolute;inset:0;display:block;}
.cyo-b-laylab{font-size:11.5px;font-weight:600;line-height:1.2;}
.cyo-b-note{margin:0;font-size:12px;color:#726a5d;line-height:1.4;}
.cyo-b-link{font:inherit;font-size:12.5px;font-weight:500;color:#764239;background:none;border:0;cursor:pointer;padding:0;}
.cyo-b-link:hover{text-decoration:underline;}
.cyo-b-row{display:flex;align-items:center;gap:12px;flex-wrap:wrap;}
.cyo-b-lab{flex:0 0 64px;font-size:12px;color:#4a3f30;}
.cyo-b-seg{display:flex;flex-wrap:wrap;gap:6px;}
.cyo-b-segbtn{font:inherit;font-size:12px;font-weight:500;padding:6px 12px;border-radius:999px;border:1px solid rgba(36,33,31,.18);background:#fffdf7;color:#5b564e;cursor:pointer;}
.cyo-b-segbtn.on{background:#5c4a32;border-color:#5c4a32;color:#fff;}
.cyo-b-segbtn[disabled]{opacity:.45;cursor:not-allowed;}
.cyo-b-chips{display:flex;flex-wrap:wrap;align-items:center;gap:6px 8px;}
.cyo-b-words .f3-tstyle-row,.cyo-b-words .fsv2-md-dock{margin:0;}
.cyo-b-foot{margin-top:auto;padding:14px 18px 18px;border-top:1px solid rgba(36,33,31,.10);background:#f9f4eb;display:flex;flex-direction:column;gap:10px;}
.cyo-b-actions{display:flex;gap:10px;}
.cyo-b-actions .primary-btn{flex-grow:1;}
.cyo-b-name{display:flex;gap:8px;align-items:center;}
.cyo-b-input{flex-grow:1;min-width:0;font:inherit;font-size:14px;padding:9px 12px;border-radius:8px;border:1px solid rgba(36,33,31,.24);background:#fffdf7;}
.cyo-b-stagecol{display:flex;flex-direction:column;gap:12px;min-width:0;}
.cyo-b-stagewrap{position:relative;background:#fffdf7;border:1px solid rgba(36,33,31,.14);border-radius:12px;padding:16px;}
.cyo-b-stagewrap .fsv2-md-stage{margin:0;}
.cyo-b-sheet{overflow:hidden;}
.cyo-b-sheethint{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin:0;padding:8px 14px;border-radius:999px;background:rgba(255,253,247,.82);color:#5a4f45;font:500 13px/1.3 "Inter",system-ui,sans-serif;letter-spacing:.01em;white-space:nowrap;pointer-events:none;}
.cyo-b-live{position:absolute;left:30px;top:30px;font-size:11px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;padding:5px 10px;border-radius:999px;background:rgba(35,33,31,.72);color:#fffdf8;pointer-events:none;}
.cyo-b-stagenote{display:flex;align-items:center;justify-content:space-between;gap:12px;font-size:13px;color:#5b564e;padding:0 4px;}

/* ── CYO-FREEFORM — "Put things on the card" ─────────────────────────────── */
.cyo-b-pieces{display:flex;flex-wrap:wrap;gap:8px;}
.cyo-b-piece{font:500 12.5px/1.2 "Inter",system-ui,sans-serif;padding:7px 12px;border-radius:999px;border:1px solid rgba(36,33,31,.18);background:#fffdf7;color:#3a3129;cursor:pointer;}
.cyo-b-piece:hover{border-color:#764239;color:#764239;}
.cyo-b-piece.on{border-style:dashed;color:#8d8477;}
.cyo-b-piece.on:hover{color:#764239;border-color:#764239;}
.cyo-b-piece.is-line{border-style:solid;background:rgba(95,113,101,.10);color:#3d4a39;border-color:rgba(95,113,101,.35);}
.cyo-b-note-dim{color:#8d8477;}
.cyo-b-or{display:flex;align-items:center;gap:10px;margin:2px 0;}
.cyo-b-or span{flex:1;height:1px;background:rgba(36,33,31,.10);}
.cyo-b-or em{font:600 11px/1 "Inter",system-ui,sans-serif;letter-spacing:.12em;text-transform:uppercase;color:#a79d88;font-style:normal;}
.cyo-b-sheettap{position:absolute;inset:0;background:transparent;border:0;cursor:pointer;z-index:2;}
.cyo-b-sheet .cyo-b-sheethint{z-index:3;}
/* the studio in the builder's card column: canvas + inspector, no modal */
.cyo-b-studio{min-width:0;}
.cyo-b-studio .f3-embed{width:auto;max-width:100%;}
.cyo-b-studio .cyo-studio{margin-top:0;}
.cyo-b-studio .cyo-chips [data-el-chip],.cyo-b-studio .cyo-chips-lab,.cyo-b-studio [data-cz-add-line]{display:none !important;}
.cyo-b-studio .cyo-chips{margin-bottom:10px;min-height:32px;}
.cyo-b-studio .cyo-edithint{margin:8px 0 0;}
/* CYO-CARD — the card is the whole builder now: size it so the whole card is
   on screen (7:4, under the app header, the builder header and the chips row),
   centred in the column. */
.cyo-b-stagecol.is-freeform{position:static;max-width: max(640px,calc((100vh - 250px) * 1.75)); max-width: max(640px,calc((100dvh - 250px) * 1.75));margin:0 auto;width:100%;}
/* the Add-here popover */
.cyo-add-pop{position:absolute;z-index:40;min-width:224px;max-width:260px;background:#fffdf7;border:1px solid rgba(36,33,31,.16);border-radius:12px;box-shadow:0 14px 40px rgba(30,20,10,.22);padding:4px 0 6px;font:13.5px/1.3 "Inter",system-ui,sans-serif;color:#23211f;text-align:left;}
.cyo-add-pop.is-wide{min-width:380px;max-width:420px;padding:10px 12px 12px;}
.cyo-add-kick{padding:8px 14px 5px;font:700 10.5px/1 "Inter",system-ui,sans-serif;letter-spacing:.14em;text-transform:uppercase;color:#a79d88;display:flex;justify-content:space-between;align-items:baseline;gap:10px;}
.cyo-add-kick small{font-weight:500;letter-spacing:0;text-transform:none;font-size:11px;color:#8d8477;}
.cyo-add-it{display:flex;align-items:center;gap:10px;width:100%;padding:9px 14px;background:none;border:0;border-top:1px solid rgba(36,33,31,.07);cursor:pointer;text-align:left;color:#23211f;font:inherit;}
.cyo-add-it:first-of-type{border-top:0;}
.cyo-add-it:hover{background:rgba(118,66,57,.07);}
.cyo-add-it.is-on{color:#8d8477;}
.cyo-add-ic{width:30px;flex-shrink:0;text-align:center;font:600 12px/1 Georgia,serif;color:#764239;}
.cyo-add-it.is-on .cyo-add-ic{color:#a79d88;}
.cyo-add-lab{display:flex;flex-direction:column;gap:2px;}
.cyo-add-lab small{font-size:11.5px;color:#8d8477;}
.cyo-add-more{margin-left:auto;color:#a79d88;}
.cyo-add-orns{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;max-height:220px;overflow:auto;padding:2px;}
.cyo-add-orn{border:1px solid rgba(36,33,31,.14);border-radius:8px;padding:8px 6px;background:#f6f0e4;display:grid;place-items:center;cursor:pointer;min-height:44px;}
.cyo-add-orn:hover{border-color:#764239;box-shadow:0 0 0 3px rgba(118,66,57,.12);}
.cyo-add-orn img{width:100%;max-height:36px;object-fit:contain;display:block;}
.cyo-add-note{margin-top:8px;font-size:11.5px;color:#8d8477;}


/* ── CYO-POPUP — no side panel: a pill beside the piece, one card under it ── */
/* NO-JUMP — keep the browser's scroll anchoring off the pill, the card and the
   popovers, so a re-placed card can never drag the page along with it. */
.cyo-studio,.cyo-b-studio,.f3st-modal,.cyo-panel,[data-cyo-pill],.cyo-add-pop,.cyo-b-pop,.cyo-b-chipwrap{overflow-anchor:none;}
.cyo-panel{position:absolute;top:0;left:0;width:316px;max-width:calc(100% - 8px);z-index:41;border-radius:14px;
  box-shadow:0 18px 44px rgba(40,28,12,.24),0 2px 6px rgba(40,28,12,.10),inset 0 1px 0 #fff;overflow:visible;}
.cyo-panel[hidden]{display:none !important;}
.cyo-panel-body{padding:8px 14px 14px;min-height:0;max-height: min(520px,calc(100vh - 160px)); max-height: min(520px,calc(100dvh - 160px));overflow:auto;border-radius:14px;}
.cyo-panel-empty{display:none !important;}
/* the little arrow that points at the pill */
.cyo-panel::before{content:"";position:absolute;top:-7px;left:var(--pop-arrow-x,50%);width:12px;height:12px;background:var(--cy-surface,#fffefb);
  border-left:1px solid var(--cy-hair,#ece5d6);border-top:1px solid var(--cy-hair,#ece5d6);transform:translateX(-50%) rotate(45deg);}
.cyo-panel.is-above::before{top:auto;bottom:-7px;transform:translateX(-50%) rotate(225deg);}
/* POP-NOCOVER — beside the piece there is no pill to point at */
.cyo-panel.is-side::before{display:none;}
/* one section at a time (cyoSyncPopup shows the open one) */
.cyo-panel .cyi-sect{border-top:none;padding:6px 0 2px;}
/* the card's title already says what this is — the section's own heading only
   earns its place when a second block follows (Corners, Border colour) */
.cyo-panel .cyi-sect > .cyi-sect-h:first-child{display:none;}
.cyo-panel[data-sect] .cyi-sect[data-cyi-sect]{display:none;}
.cyo-panel .cyi-head{display:flex;align-items:center;justify-content:space-between;padding:4px 0 8px;margin-bottom:6px;}
.cyo-panel .cyi-title{font-size:17px;}
.cyi-x{border:none;background:none;color:#a79d88;font-size:20px;line-height:1;cursor:pointer;padding:2px 4px;font-family:inherit;border-radius:6px;}
.cyi-x:hover{color:#272219;background:#f3ecdd;}
.cyi-help-quiet{margin:6px 2px 0;color:#8f8672;line-height:1.4;}
.cyi-reframe{margin-top:12px;background:#764239;border-color:#764239;color:#fffdf8;}
.cyi-reframe:hover{background:#5e342d;border-color:#5e342d;color:#fffdf8;}
.cyi-reframe[aria-pressed="true"]{background:#3d4a39;border-color:#3d4a39;}
/* option lists (photo shape) */
.cyi-opts{display:flex;flex-direction:column;gap:6px;}
.cyi-opt{display:flex;align-items:center;gap:10px;width:100%;padding:9px 10px;border-radius:9px;border:1px solid transparent;background:none;font-family:inherit;font-size:13.5px;color:#272219;cursor:pointer;text-align:left;}
.cyi-opt:hover{background:#f7f2e8;}
.cyi-opt.on{background:rgba(176,137,74,.14);border-color:rgba(176,137,74,.35);}
.cyi-opt-tick{margin-left:auto;color:#b0894a;font-weight:700;}
.cyi-shape{width:34px;height:26px;background:#d8ccb6;border:1px solid #b8ab92;box-sizing:border-box;flex:0 0 auto;}
.cyi-shape-oval{border-radius:50%;}
.cyi-shape-polaroid{background:#fff;border-color:#d0c6b0;box-shadow:inset 0 -6px 0 #fff,inset 0 0 0 2px #fff,0 1px 2px rgba(0,0,0,.2);}
/* FRAMES — the catalogue on the Photo card: the artwork over a soft swatch */
.cyi-finish{padding:2px 0 0;}
.cyi-finish .cyi-field{min-height:30px;margin-bottom:6px;}
.cyi-frames{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;}
.cyi-frame{display:flex;flex-direction:column;align-items:center;gap:5px;padding:6px 4px 7px;border:1px solid rgba(36,33,31,.12);border-radius:10px;background:#fffdf7;cursor:pointer;font:inherit;color:inherit;}
.cyi-frame:hover{background:#f6f0e4;}
.cyi-frame.on{background:rgba(176,137,74,.14);border-color:rgba(176,137,74,.45);box-shadow:inset 0 0 0 1px rgba(176,137,74,.35);}
.cyi-frame-art{width:64px;height:64px;border-radius:6px;background:linear-gradient(135deg,#d9cdb5,#b8ab92);display:flex;align-items:center;justify-content:center;overflow:hidden;}
.cyi-frame-art img{width:100%;height:100%;object-fit:contain;}
.cyi-frame-none{position:relative;}
.cyi-frame-none::after{content:"";position:absolute;inset:6px;border:1px dashed rgba(36,33,31,.35);border-radius:4px;}
.cyi-frame-lab{font-size:11px;line-height:1.2;text-align:center;color:var(--cy-ink2,#4a4238);}
/* CUTOUT — a head-and-shoulders silhouette fading out at the foot */
.cyi-shape-cutout{border-color:transparent;background:
  radial-gradient(circle at 50% 32%,#a08c74 0 24%,transparent 25%),
  radial-gradient(ellipse at 50% 100%,#a08c74 0 46%,transparent 47%);
  -webkit-mask-image:linear-gradient(#000 55%,transparent 98%);mask-image:linear-gradient(#000 55%,transparent 98%);}
.cyi-note{margin:8px 2px 0;font-size:12px;line-height:1.4;color:var(--cy-ink3,#7a6f60);}
/* segmented (shadow, border size) */
.cyi-seg{display:flex;border:1px solid #e2d8c5;border-radius:9px;overflow:hidden;background:#fff;}
.cyi-seg-b{flex:1;border:none;border-right:1px solid #e2d8c5;background:none;padding:9px 6px;font-family:inherit;font-size:13px;color:#6b6353;cursor:pointer;}
.cyi-seg-b:last-child{border-right:none;}
.cyi-seg-b:hover{background:#f7f2e8;}
.cyi-seg-b.on{background:#3d4a39;color:#fff;}
/* colour dots (border colour, polaroid corners) */
.cyi-dots{display:flex;flex-wrap:wrap;gap:8px;padding:2px 2px 4px;}
.cyi-dot{width:28px;height:28px;border-radius:50%;border:1px solid rgba(0,0,0,.14);background:var(--sw,#fff);cursor:pointer;padding:0;box-sizing:border-box;position:relative;}
.cyi-dot.on{box-shadow:0 0 0 2px #fffefb,0 0 0 4px #b0894a;}
.cyi-dot-custom{background:var(--sw,conic-gradient(#e66 0 25%,#ec6 0 50%,#6c9 0 75%,#69e 0));overflow:hidden;}
.cyi-dot-custom input[type=color]{position:absolute;inset:0;width:100%;height:100%;opacity:0;cursor:pointer;}
/* the zoom rows, in the card */
.cyo-panel .cyo-looklayers.cyl-inpanel{margin:0;padding:0;border:none;background:none;box-shadow:none;}
.cyo-panel .cyl-inpanel .cyl-row{padding:6px 0;}
.cyo-panel .cyl-inpanel .cyl-lab{flex:0 0 100px;font-size:13px;color:#6b6353;font-weight:500;}
.cyo-panel .cyl-inpanel .cyl-range{accent-color:#b0894a;}
.cyo-panel .cyl-inpanel .cyl-val{font-size:12.5px;color:#272219;}

/* the pill */
.cyo-pill{position:absolute;z-index:42;display:inline-flex;align-items:stretch;background:#1f1a14;border:.5px solid rgba(255,250,240,.14);border-radius:22px;
  box-shadow:0 4px 16px rgba(0,0,0,.45);color:#f4e9d4;white-space:nowrap;overflow:hidden;font-size:12px;max-width:calc(100% - 16px);}
.cyo-pill[hidden]{display:none !important;}
.cyo-pill-lab{display:inline-flex;align-items:center;font-size:11px;color:#a89878;text-transform:uppercase;letter-spacing:.06em;font-weight:500;padding:9px 12px;border-right:1px solid rgba(255,250,240,.14);}
.cyo-pill-b{display:inline-flex;align-items:center;gap:6px;padding:9px 12px;border:none;border-right:1px solid rgba(255,250,240,.14);background:transparent;color:#f4e9d4;font-family:inherit;font-size:12px;font-weight:500;cursor:pointer;line-height:1.2;}
.cyo-pill-b:last-child{border-right:none;}
.cyo-pill-b:hover{background:rgba(255,250,240,.08);}
.cyo-pill-b.on{background:rgba(201,162,90,.22);}
.cyo-pill-b:focus-visible{outline:2px solid #c9a25a;outline-offset:-2px;}
.cyo-pill-v{color:#a89878;font-weight:400;max-width:96px;overflow:hidden;text-overflow:ellipsis;}
.cyo-pill-dot{width:12px;height:12px;border-radius:50%;border:1px solid rgba(255,250,240,.35);display:inline-block;}
.cyo-pill-dup{font-size:15px;line-height:1;padding-left:9px;padding-right:9px;}
.cyo-pill-off{color:#e8a598;}
.cyo-pill-off:hover{background:rgba(232,165,152,.14);}
/* out of the way while a piece is being dragged, resized or the picture panned */
.cyo-studio:has(.is-dragging,.is-resizing,.is-panning) .cyo-pill,
.cyo-studio:has(.is-dragging,.is-resizing,.is-panning) .cyo-panel{opacity:0;pointer-events:none;}
/* the pencil, in the chips row with Undo / Redo */
.cyo-chips-right .cyo-stage-lock{position:static;box-shadow:0 1px 2px rgba(50,40,20,.05);padding:7px 12px;font-size:12.5px;}
.cyo-chips-right .cyo-stage-lock .cyo-stage-lock-lab{max-width:150px;opacity:1;}
@media (max-width:700px){
  .cyo-panel{position:fixed;left:8px;right:8px;bottom:8px;top:auto !important;width:auto;max-width:none;z-index:70;}
  .cyo-panel::before{display:none;}
  .cyo-panel-body{max-height:48vh;}
  .cyo-pill{z-index:71;max-width:calc(100vw - 16px);overflow-x:auto;scrollbar-width:none;}
  .cyo-pill::-webkit-scrollbar{display:none;}
}


/* ── CYO-CARD — the builder is the card: header, two chips, the studio ── */
.cyo-b-cols.cyo-b-cols-one{grid-template-columns:minmax(0,1fr);}
.cyo-b-hdr{display:flex;align-items:center;gap:14px;flex-shrink:0;}
.cyo-b-hdr .cyo-b-save{height:42px;padding:0 20px;}
.cyo-b-hdr .cyo-b-name{display:flex;align-items:center;gap:8px;}
.cyo-b-hdr .cyo-b-input{height:42px;width:220px;}
.cyo-b-topbar{display:flex;align-items:center;gap:9px;min-height:36px;margin-bottom:2px;}
.cyo-b-bar{display:inline-flex;align-items:center;gap:9px;}
.cyo-b-chipwrap{position:relative;display:inline-block;}
.cyo-b-chip{font-family:inherit;cursor:pointer;gap:6px;}
.cyo-b-chip b{font-weight:600;color:#272219;max-width:160px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.cyo-b-chip.on{border-color:#b0894a;box-shadow:0 0 0 3px rgba(176,137,74,.15);}
.cyo-b-chipcaret{color:#a79d88;font-size:10px;margin-left:2px;}
/* BACKDROP-CHIP — the backdrop button: swatch, eyebrow + name, Change cue */
.cyo-b-bd{display:inline-flex;align-items:center;gap:10px;padding:5px 12px 5px 5px;font-family:inherit;font-size:13.5px;cursor:pointer;
  background:#fffdf7;border:1.5px solid #c9b48e;border-radius:12px;color:#272219;text-align:left;
  box-shadow:0 1px 2px rgba(50,40,20,.06),0 4px 12px -6px rgba(50,40,20,.18);transition:border-color .12s ease,box-shadow .12s ease,background .12s ease;}
.cyo-b-bd:hover{background:#fff;border-color:#b0894a;box-shadow:0 1px 2px rgba(50,40,20,.08),0 8px 18px -8px rgba(50,40,20,.28);}
.cyo-b-bd.on{border-color:#b0894a;box-shadow:0 0 0 3px rgba(176,137,74,.18);}
.cyo-b-sw{width:44px;height:30px;border-radius:7px;overflow:hidden;flex:0 0 auto;background:#e6dcc8;box-shadow:inset 0 0 0 1px rgba(0,0,0,.08);}
.cyo-b-sw img{width:100%;height:100%;object-fit:cover;display:block;}
.cyo-b-sw-none{background:repeating-linear-gradient(135deg,#e6dcc8 0 6px,#f3ecdd 6px 12px);}
.cyo-b-bd-txt{display:flex;flex-direction:column;line-height:1.15;min-width:0;}
.cyo-b-bd-eyebrow{font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:#8a7c64;font-weight:600;}
.cyo-b-bd-txt b{font-weight:600;font-size:14px;max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.cyo-b-bd-cta{margin-left:6px;padding:5px 10px;border-radius:999px;background:#6e3f2f;color:#fff8ee;font-size:12.5px;font-weight:600;white-space:nowrap;}
.cyo-b-bd-cta .cyo-b-chipcaret{color:rgba(255,248,238,.8);}
.cyo-b-pop{position:absolute;left:0;top:calc(100% + 8px);z-index:60;width:min(600px,calc(100vw - 40px));box-sizing:border-box;padding:14px;
  background:#fffdf7;border:1px solid #e2d8c5;border-radius:14px;box-shadow:0 18px 44px rgba(40,28,12,.24),0 2px 6px rgba(40,28,12,.10);
  display:flex;flex-direction:column;gap:10px;text-align:left;}
.cyo-b-pop::before{content:"";position:absolute;top:-7px;left:26px;width:12px;height:12px;background:#fffdf7;border-left:1px solid #e2d8c5;border-top:1px solid #e2d8c5;transform:rotate(45deg);}
.cyo-b-pop .cyo-b-grid{max-height:min(46vh,420px);}
.cyo-b-pop .cyo-b-grid-bd{grid-template-columns:repeat(4,minmax(0,1fr));}
.cyo-b-pop-lay{width:min(520px,calc(100vw - 40px));}
.cyo-b-pop .cyo-b-note{margin:0;}
/* the builder's studio: the chips ride at the start of the row */
.cyo-b-studio .cyo-chips{justify-content:flex-start;}
.cyo-b-studio .cyo-chips .cyo-b-bar{margin-right:auto;}
@media (max-width:700px){
  .cyo-b-hd{flex-direction:column;align-items:stretch;}
  .cyo-b-hdr{justify-content:space-between;}
  .cyo-b-pop{position:fixed;left:8px;right:8px;top:auto;bottom:8px;width:auto;max-height:70vh;overflow:auto;z-index:80;}
  .cyo-b-pop::before{display:none;}
}

/* INTEGRATE-HOLD — a look's settled portrait is held until it exists, then
   fades in (never a plain cut-out swapped for the finished one). */
.titlecard-portrait.tc-portrait-hold img { opacity: 0 !important; }
.titlecard-portrait.tc-portrait-arrived img { animation: tcPortraitArrive 0.6s ease-out both; }
@keyframes tcPortraitArrive { from { opacity: 0; } to { opacity: 1; } }

/* Allura — K's pick (24 Sep) for cherry-blossoms-spring's closing line. A
   free Google script, shipped with the app. Fallbacks are the formal
   roundhands already on the machine: Snell Roundhand (every Mac and iPhone),
   Edwardian Script ITC (Office, Windows and Mac), Gabriola (every Windows). */
.font-preset-allura,
.titlecard-extra.font-preset-allura,
.titlecard-name.font-preset-allura,
.backdrop-text-name.font-preset-allura,
.backdrop-text-preamble.font-preset-allura,
.backdrop-text-dates.font-preset-allura {
  font-family: "Allura", "Snell Roundhand", "Edwardian Script ITC", "Gabriola", cursive;
  font-weight: 400;
  font-style: normal;
  text-transform: none;
  letter-spacing: 0;
}

/* PORTRAIT LIGHT — the glow behind a lit portrait, screened onto the scene.
   Same box as the portrait, under it, never clipped (the glow runs past it). */
.tc-portrait-glow { position: absolute; width: var(--portrait-size, 30%); height: var(--portrait-height, 40%); transform: translate(-50%, -50%); z-index: 1; pointer-events: none; mix-blend-mode: screen; }
.tc-portrait-glow img { position: absolute; display: block; max-width: none; }
.tc-portrait-glow.tc-portrait-arrived img { animation: tcPortraitArrive 0.6s ease-out both; }

/* EXTEND-SHOULDER — the Look-step card (see renderExtendCard). */
.lm-extend-card { margin: 10px 2px 0; padding: 12px 14px 14px; border: 1px solid var(--line, #d9cfc8); border-radius: 12px; background: #fff; }
.lm-extend-card.is-asking { border-color: var(--accent, #8a4a57); box-shadow: 0 0 0 3px rgba(138, 74, 87, .14); }
.lm-extend-card.is-chosen { display: flex; gap: 12px; align-items: center; justify-content: space-between; font-size: 13px; color: var(--muted, #7c766c); padding: 8px 12px; }
.lm-extend-head { display: grid; gap: 2px; margin-bottom: 10px; }
.lm-extend-head strong { font-size: 15px; }
.lm-extend-head span { font-size: 12.5px; color: var(--muted, #7c766c); }
.lm-extend-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.lm-extend-pair figure { margin: 0; display: grid; gap: 8px; }
.lm-extend-pair figcaption { font: 600 12px system-ui, sans-serif; letter-spacing: .04em; text-transform: uppercase; color: var(--muted, #7c766c); }
.lm-extend-pair .ghost-btn, .lm-extend-pair .primary-btn { justify-self: start; }
.lm-extend-stage { pointer-events: none; }
@media (max-width: 820px) { .lm-extend-pair { grid-template-columns: 1fr; } }

/* EXTEND-SHOULDER — the popup at Timeline → Look (see renderExtendPopup). */
.lm-extend-pop { z-index: 9600; }
.lm-extend-panel { width: min(760px, 92vw); max-height: 92vh; overflow: auto; background: #fbf7f1; color: #2d2426; border-radius: 16px; padding: 26px 28px 22px; box-shadow: 0 30px 80px rgba(0,0,0,.35); text-align: center; }
.lm-extend-panel.is-waiting { width: min(460px, 92vw); display: grid; gap: 10px; justify-items: center; padding: 34px 28px 26px; }
.lm-extend-eyebrow { margin: 0 0 6px; font: 600 11px system-ui, sans-serif; letter-spacing: .14em; text-transform: uppercase; color: #8a4a57; }
.lm-extend-title { margin: 0 0 8px; font-family: "Cormorant Garamond", Georgia, serif; font-weight: 500; font-size: 28px; line-height: 1.15; }
.lm-extend-body { margin: 0 auto 16px; max-width: 58ch; font-size: 15px; line-height: 1.5; color: #4e4446; }
.lm-extend-ask { margin: 14px 0 4px; font-size: 13px; color: #7c766c; }
.lm-extend-actions { margin-top: 8px; }
.lm-extend-pair-pop { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; text-align: center; }
.lm-extend-pair-pop figure { justify-items: center; }
.lm-extend-pair-pop .ghost-btn, .lm-extend-pair-pop .primary-btn { justify-self: center; }
.lm-extend-cut { height: clamp(220px, 38vh, 340px); display: flex; align-items: flex-end; justify-content: center; }
.lm-extend-cut img { height: 100%; width: auto; max-width: 100%; object-fit: contain; filter: drop-shadow(0 12px 22px rgba(60, 40, 30, .28)); }
@media (max-width: 640px) { .lm-extend-pair-pop { grid-template-columns: 1fr; } .lm-extend-cut { height: 200px; } }

/* FLOW v2 — the Portrait step (see renderF3Choose). */
.f3-choose { display: grid; gap: 16px; }
.f3-choose-hero { display: grid; justify-items: center; gap: 8px; }
.f3-choose-hero.is-finding { padding: 18px 0 6px; }
.f3-choose-tile { position: relative; padding: 0; border: 3px solid transparent; border-radius: 12px; background: #fff; cursor: pointer; overflow: hidden; box-shadow: 0 4px 14px rgba(40, 30, 20, .12); }
.f3-choose-tile img { display: block; width: 100%; height: 100%; object-fit: cover; }
.f3-choose-tile.on { border-color: #8a4a57; }
.f3-choose-tile:focus-visible { outline: 3px solid #8a4a57; outline-offset: 2px; }
.f3-choose-tile.is-big { width: min(320px, 70vw); aspect-ratio: 4 / 5; }
.f3-choose-tile.is-big img { object-fit: contain; background: #f4efe9; }
.f3-choose-tile .wiz-photo-badge { position: absolute; left: 8px; bottom: 8px; }
.f3-choose-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); gap: 10px; }
.f3-choose-grid .f3-choose-tile { aspect-ratio: 1; }

/* FLOW v2 — the Portrait step: a chosen photo LOOKS chosen (the app's own
   "this is the one" idiom: ring + check), a suggestion reads as not-yet
   (dashed), and the tap gets one small pop. */
.f3-choose-tile { transition: box-shadow .18s, border-color .18s, transform .18s; }
.f3-choose-tile.on:not(.is-chosen) { border-style: dashed; border-color: #b8929a; }
.f3-choose-tile.is-chosen { border-style: solid; border-color: var(--accent, #8a4a57); box-shadow: 0 0 0 4px rgba(138, 74, 87, .22), 0 10px 26px rgba(40, 30, 20, .18); }
.f3-choose-tile.is-chosen::after {
  content: "✓"; position: absolute; top: 10px; right: 10px; z-index: 2;
  width: 30px; height: 30px; display: flex; align-items: center; justify-content: center;
  border-radius: 50%; background: var(--accent, #8a4a57); color: #fff; font-size: 17px; font-weight: 800;
  box-shadow: 0 2px 8px rgba(0, 0, 0, .3); pointer-events: none;
}
.f3-choose-grid .f3-choose-tile.is-chosen::after { width: 22px; height: 22px; font-size: 13px; top: 6px; right: 6px; }
.f3-choose-tile.is-just-chosen { animation: f3ChoosePop .45s cubic-bezier(.2, .8, .2, 1) both; }
.f3-choose-tile.is-just-chosen::after { animation: f3CheckIn .35s .08s cubic-bezier(.2, .8, .2, 1) both; }
@keyframes f3ChoosePop { 0% { transform: scale(.985); } 55% { transform: scale(1.03); } 100% { transform: scale(1); } }
@keyframes f3CheckIn { from { transform: scale(0); opacity: 0; } to { transform: scale(1); opacity: 1; } }
.f3-choose-more { margin-top: 2px; font-size: .92rem; }
.f3-choose.is-settled { padding-bottom: 22px; }
@media (prefers-reduced-motion: reduce) { .f3-choose-tile.is-just-chosen, .f3-choose-tile.is-just-chosen::after { animation: none; } }

/* FR1 — the card is mounted hidden until its first photo is decoded and read,
   then arrives whole, with one short fade. */
.lm-fr.is-preparing{visibility:hidden}
.lm-fr.is-in .lm-fr-card{animation:lmFrIn .18s ease-out both}
@keyframes lmFrIn{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion: reduce){.lm-fr.is-in .lm-fr-card{animation:none}}

/* ── BEFORE-WE-START (2026-09-27) ───────────────────────────────────────────
   The optional-extras card above the upload button, the "faded" tile flag,
   the background-work line in the guided header, the Review step headings and
   the opening-portrait approval card. */
.f3-bs { border: 1px solid var(--line); border-radius: 12px; background: var(--paper-2, #faf6ee); padding: .8rem 1rem .9rem; margin: 0 0 1rem; }
.f3-bs legend { font-weight: 700; font-size: .95rem; color: var(--ink); padding: 0 .35rem; }
.f3-bs-lede { margin: .1rem 0 .6rem; font-size: .84rem; color: var(--body); }
.f3-bs-row { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: .35rem 1.2rem; padding: .55rem 0; border-top: 1px solid var(--line); }
.f3-bs-row:first-of-type { border-top: 0; }
.f3-bs-main { display: flex; gap: .6rem; align-items: flex-start; flex: 1 1 18rem; cursor: pointer; }
.f3-bs-main span { display: flex; flex-direction: column; gap: .12rem; }
.f3-bs-main strong { font-size: .92rem; color: var(--ink); }
.f3-bs-main small { font-size: .8rem; color: #7a7061; line-height: 1.35; }
.f3-bs-rev { display: flex; gap: .45rem; align-items: center; font-size: .84rem; color: var(--body); cursor: pointer; padding-top: .1rem; }
.f3-bs-rev.is-off { opacity: .45; cursor: default; }
.f3-bs input[type="checkbox"] { width: 1.05rem; height: 1.05rem; margin-top: .12rem; accent-color: var(--accent); flex: none; }
.f3-tile-flag { position: absolute; left: 4px; top: 4px; background: rgba(202, 167, 101, 0.95); color: #2f2412; font-size: 0.64rem; font-weight: 700; padding: 2px 6px; border-radius: 6px; pointer-events: none; }
.f3-jobs-line { display: flex; align-items: center; justify-content: center; gap: .45rem; margin: .5rem auto 0; max-width: 46rem; font-size: .8rem; color: #6f6556; }
.f3-review-h { font-size: 1.05rem; font-weight: 700; color: var(--ink); margin: 1.2rem 0 .5rem; }
.f3-approve-card { border-color: var(--gold); }
.f3-mainok-card { margin: .9rem auto 0; max-width: 46rem; }
.f3-mainok { display: flex; gap: 1rem; align-items: center; flex-wrap: wrap; }
.f3-mainok + .f3-mainok { margin-top: .9rem; padding-top: .9rem; border-top: 1px solid var(--line); }
.f3-mainok-shot { flex: 0 0 200px; max-width: 200px; }
.f3-mainok-txt { flex: 1 1 14rem; }

/* ── REVIEWC (2026-09-27): phone fixes K asked for.
   1. The guided trail's step dots wrapped at 390px once the flow had 8+ steps
      (44px targets × 8 > 350px), leaving one dot alone on a second line. Under
      560px (where the labels are already hidden) the steps share the row
      evenly, up to 44px each — ~37px with 9 steps on a 390px phone, ~29px on
      a 320px one: still above the 24px minimum target, with a 2px gap.
   2. On narrow screens the "Let me approve…" box drops under its option;
      indent it under the option's text so it reads as part of that option. */
@media (max-width: 560px) {
  .wiz-trail { flex-wrap: nowrap; }
  .wiz-trail .wiz-dot { flex: 1 1 0; min-width: 24px; max-width: 44px; }
}
@media (max-width: 680px) {
  .f3-bs-rev { flex-basis: 100%; padding-left: 1.65rem; }
}

/* ── FADED-FLAG (2026-09-27): the quiet "N photos look faded" row on Review,
   for a family who left Restore off. Collapsed by default, muted, one line —
   a flag they can open or ignore, never a call to action. */
.f3-faded-flag { border: 1px dashed var(--line-strong, #d8cfbf); border-radius: 10px; background: transparent; margin: 0 0 .9rem; }
.f3-faded-sum { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; padding: .6rem .85rem; cursor: pointer; list-style: none; font-size: .86rem; color: var(--body); }
.f3-faded-sum::-webkit-details-marker { display: none; }
.f3-faded-sum::after { content: "▸"; margin-left: auto; opacity: .55; font-size: .85em; }
.f3-faded-flag[open] .f3-faded-sum::after { content: "▾"; }
.f3-faded-ico { color: #b08a45; }
.f3-faded-txt { font-weight: 600; color: var(--ink); }
.f3-faded-hint { color: #8a7f6e; font-size: .8rem; }
.f3-faded-body { padding: 0 .85rem .85rem; }
.f3-faded-actions { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; margin-top: .75rem; }
.f3-faded-note { margin: .5rem 0 0; font-size: .78rem; color: #8a7f6e; }
.f3-faded-body > .f3-rrow-sub { margin: 0 0 .65rem; }
@media (max-width: 560px) { .f3-faded-hint { flex-basis: 100%; padding-left: 1.35rem; margin-top: -.2rem; } }

/* ═══ HOME-V2 (2026-09-27) — K's Claude Design "Homepage v2" ═══════════════
   Homepage only (.shell.is-home / .hp). The guided flow keeps its own fonts.
   Font stacks carry each face's Windows / Mac look-alike, per K's rule:
     Source Serif 4 → Georgia / Cambria (Windows), Georgia (Mac)
     Public Sans    → Segoe UI (Windows), -apple-system / Helvetica Neue (Mac)
     IBM Plex Mono  → Consolas (Windows), SF Mono / Menlo (Mac)            */
.shell.is-home {
  --hp-serif: "Source Serif 4", "Source Serif Pro", Georgia, Cambria, "Times New Roman", serif;
  --hp-sans: "Public Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  --hp-mono: "IBM Plex Mono", "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  --hp-bg: #f5f2ec; --hp-band: #faf8f4; --hp-ink: #231d1a; --hp-body: #403833; --hp-soft: #4f4640;
  --hp-accent: #6e3a32; --hp-accent-dark: #4f2822; --hp-rule: rgba(35, 29, 26, .12);
  background: var(--hp-bg); color: var(--hp-ink); font-family: var(--hp-sans);
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
}
.shell.is-home ::selection { background: #e8d9cf; }
.shell.is-home .topbar {
  min-height: 72px; gap: 32px; padding: 0 max(40px, calc((100% - 1120px) / 2));
  background: rgba(245, 242, 236, .9); -webkit-backdrop-filter: saturate(1.2) blur(12px); backdrop-filter: saturate(1.2) blur(12px);
  border-bottom: 1px solid rgba(35, 29, 26, .08);
}
.shell.is-home .brand { gap: 12px; }
.shell.is-home .hp-brand-mark {
  width: 34px; height: 34px; border-radius: 50%; border: 1px solid #bfa98a; background: transparent;
  font: 400 13px/1 var(--hp-serif); letter-spacing: .04em; color: var(--hp-accent);
}
.shell.is-home .brand-name { font: 400 19px var(--hp-serif); letter-spacing: .005em; color: var(--hp-ink); }
.shell.is-home .nav { gap: 32px; }
.shell.is-home .nav a { font: 500 15px var(--hp-sans); color: #4a413c; padding: 0; }
.shell.is-home .nav a:hover { color: var(--hp-ink); }
.shell.is-home .nav .primary-btn {
  min-height: 40px; height: 40px; padding: 0 18px; border-radius: 4px; box-shadow: none;
  background: var(--hp-accent); border-color: var(--hp-accent); font: 600 14px var(--hp-sans);
}
.shell.is-home .nav .primary-btn:hover { background: var(--hp-accent-dark); border-color: var(--hp-accent-dark); }
.shell.is-home .lm-buildstamp { font-family: var(--hp-sans); }

.hp { font-family: var(--hp-sans); color: var(--hp-ink); }
.hp h1, .hp h2, .hp h3, .hp p { margin: 0; }
.hp-wrap { max-width: 1200px; margin: 0 auto; padding-left: 40px; padding-right: 40px; box-sizing: border-box; }
.hp-mono { font-family: var(--hp-mono); }
.hp-eyebrow { display: flex; align-items: center; gap: 12px; font: 600 13px var(--hp-sans); letter-spacing: .16em; text-transform: uppercase; color: var(--hp-accent); }
.hp-eyebrow > span { width: 28px; height: 1px; background: currentColor; flex: none; }
.hp-eyebrow.is-dark { color: #d2a898; }
.hp-h1 { font: 400 clamp(44px, 5vw, 66px)/1.04 var(--hp-serif); letter-spacing: -.01em; text-wrap: balance; }
.hp-h2 { font: 400 clamp(36px, 4vw, 52px)/1.06 var(--hp-serif); letter-spacing: -.01em; text-wrap: balance; }
.hp-h2-lg { font-size: clamp(38px, 4.4vw, 58px); line-height: 1.05; }
.hp-h3 { font: 400 24px/1.2 var(--hp-serif); }
.hp-h3s { font: 400 22px var(--hp-serif); }
.hp-btn {
  height: 52px; padding: 0 24px; display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box;
  border-radius: 4px; font: 600 15px var(--hp-sans); text-decoration: none; cursor: pointer; transition: background .14s ease, border-color .14s ease;
}
.hp-btn-primary { padding: 0 26px; background: var(--hp-accent); border: 1px solid var(--hp-accent); color: #fff;
  box-shadow: 0 1px 0 rgba(255, 255, 255, .15) inset, 0 8px 20px -8px rgba(110, 58, 50, .5); }
.hp-btn-primary:hover { background: var(--hp-accent-dark); border-color: var(--hp-accent-dark); color: #fff; }
.hp-btn-ghost { background: transparent; border: 1px solid rgba(35, 29, 26, .2); color: var(--hp-ink); }
.hp-btn-ghost:hover { border-color: rgba(35, 29, 26, .45); color: var(--hp-ink); }
.hp-btn-dark { height: 48px; padding: 0 22px; font-size: 14px; background: transparent; border: 1px solid rgba(244, 237, 227, .32); color: #f4ede3; }
.hp-btn-dark:hover { border-color: rgba(244, 237, 227, .6); }
.hp-btn-lg { height: 54px; padding: 0 28px; }

/* Hero */
.hp-hero { padding-top: 88px; padding-bottom: 72px; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 440px), 1fr)); gap: 72px; align-items: center; }
.hp-hero-copy { display: flex; flex-direction: column; gap: 28px; }
.hp-lede { font-size: 18px; line-height: 1.65; color: var(--hp-body); max-width: 480px; text-wrap: pretty; }
.hp-actions { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; padding-top: 4px; }
.hp-note { font-size: 14px; line-height: 1.6; color: var(--hp-soft); max-width: 440px; }
.hp-studio { display: flex; gap: 16px; padding-top: 24px; border-top: 1px solid var(--hp-rule); max-width: 480px; }
.hp-studio .hp-mono { font-weight: 500; font-size: 13px; color: var(--hp-accent); padding-top: 4px; }
.hp-studio p { font-size: 17px; line-height: 1.6; color: #3d3531; }
.hp-frame-fig { margin: 0; display: flex; flex-direction: column; gap: 14px; }
.hp-frame-meta { display: flex; justify-content: space-between; gap: 12px; font-weight: 500; font-size: 13px; letter-spacing: .08em; text-transform: uppercase; color: var(--hp-soft); }
.hp-frame-meta .is-strong { color: var(--hp-ink); }
.hp-frame { position: relative; aspect-ratio: 1 / 1; background: #1a1512; overflow: hidden; box-shadow: 0 1px 2px rgba(0, 0, 0, .08), 0 30px 60px -20px rgba(30, 20, 15, .45); }
.hp-frame-glow { position: absolute; inset: 0; background: radial-gradient(ellipse 70% 55% at 50% 32%, rgba(120, 98, 78, .35), transparent 70%); }
.hp-print { position: absolute; width: 21%; aspect-ratio: 5 / 4; padding: 5px; box-sizing: border-box; background: #ece5d9; box-shadow: 0 12px 28px rgba(0, 0, 0, .45); opacity: .9; }
.hp-print img, .hp-print-main img { width: 100%; height: 100%; object-fit: cover; display: block; }
.hp-print-l { left: 8%; top: 17%; transform: rotate(-4deg); }
.hp-print-r { right: 8%; top: 23%; transform: rotate(3deg); }
.hp-print-r img { object-position: 50% 22%; }
.hp-print-main { position: absolute; left: 29%; top: 11%; width: 42%; aspect-ratio: 4 / 5; padding: 9px 9px 26px; box-sizing: border-box; background: #f4efe6; box-shadow: 0 24px 50px rgba(0, 0, 0, .55); }
.hp-frame-fade { position: absolute; left: 0; right: 0; bottom: 0; height: 42%; background: linear-gradient(transparent, rgba(20, 15, 12, .92)); }
.hp-frame-cap { position: absolute; left: 7%; right: 7%; bottom: 7%; display: flex; flex-direction: column; gap: 8px; }
.hp-frame-kicker { font-size: 13px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: #e6dacb; }
.hp-frame-title { font: 400 clamp(32px, 3.8vw, 48px)/1 var(--hp-serif); letter-spacing: -.01em; color: #f6efe4; }
.hp-frame-tc { position: absolute; right: 5%; top: 4.5%; font-size: 12px; letter-spacing: .08em; color: rgba(246, 239, 228, .85); }
.hp-frame-caps { display: grid; grid-template-columns: repeat(3, 1fr); font-size: 12px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: #4a413c; }
.hp-frame-caps span { padding: 14px 0 14px 16px; border-bottom: 1px solid rgba(35, 29, 26, .14); border-left: 1px solid rgba(35, 29, 26, .1); }
.hp-frame-caps span:first-child { padding-left: 0; border-left: 0; }

/* Bands */
.hp-band { background: var(--hp-band); border-top: 1px solid rgba(35, 29, 26, .1); border-bottom: 1px solid rgba(35, 29, 26, .1); }
.hp-proof-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); }
.hp-proof-grid > div { padding: 32px; border-left: 1px solid rgba(35, 29, 26, .1); display: flex; flex-direction: column; gap: 6px; }
.hp-proof-grid > div:first-child { padding-left: 0; border-left: 0; }
.hp-proof-grid p { font-size: 16px; line-height: 1.6; color: var(--hp-body); }
.hp-sec { scroll-margin-top: 72px; }
.hp-intro { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr)); gap: 24px 72px; align-items: end; }
.hp-intro-head { display: flex; flex-direction: column; gap: 18px; }
.hp-intro-copy { font-size: 18px; line-height: 1.65; color: var(--hp-body); text-wrap: pretty; }

/* Examples */
.hp-examples > .hp-wrap { padding-top: 112px; padding-bottom: 104px; display: flex; flex-direction: column; gap: 48px; }
.hp-ex-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); gap: 32px; }
.hp-ex-card { display: flex; }
.hp-ex-hit { all: unset; box-sizing: border-box; cursor: pointer; display: flex; flex-direction: column; gap: 20px; width: 100%; color: var(--hp-ink); }
.hp-ex-hit:hover { opacity: .92; }
.hp-ex-hit:focus-visible { outline: 3px solid rgba(110, 58, 50, .3); outline-offset: 6px; }
.hp-ex-hit:disabled { cursor: not-allowed; opacity: .6; }
.hp-ex-cover { position: relative; display: block; aspect-ratio: 4 / 5; background: #e4dbce; overflow: hidden; box-shadow: 0 1px 2px rgba(0, 0, 0, .05); }
.hp-ex-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.hp-ex-badges { position: absolute; left: 0; right: 0; bottom: 0; padding: 64px 18px 16px; display: flex; justify-content: space-between;
  background: linear-gradient(transparent, rgba(20, 15, 12, .8)); font-size: 13px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: #fff; }
.hp-ex-copy { display: flex; flex-direction: column; gap: 10px; }
.hp-ex-years { font: 500 13px var(--hp-mono); letter-spacing: .14em; color: var(--hp-accent); }
.hp-ex-name { font: 400 28px/1.15 var(--hp-serif); letter-spacing: -.005em; }
.hp-ex-desc { font-size: 17px; line-height: 1.6; color: var(--hp-body); }
.hp-ex-cta { margin-top: auto; padding-top: 16px; border-top: 1px solid rgba(35, 29, 26, .14); font-size: 14px; font-weight: 600; color: var(--hp-accent); }
.hp-ex-note { font-size: 15px; line-height: 1.5; color: var(--hp-soft); text-align: center; }

/* Deliverables */
#deliverables.hp-band { border-top-color: rgba(35, 29, 26, .08); border-bottom-color: rgba(35, 29, 26, .08); }
#deliverables > .hp-wrap { padding-top: 112px; padding-bottom: 112px; display: flex; flex-direction: column; gap: 56px; }
.hp-deliv { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); border-top: 1px solid var(--hp-ink); }
.hp-deliv-item { padding: 28px 28px 32px 0; display: flex; flex-direction: column; gap: 12px; border-bottom: 1px solid var(--hp-rule); }
.hp-deliv-item p { font-size: 16px; line-height: 1.6; color: var(--hp-body); }
.hp-num { font-weight: 500; font-size: 13px; color: var(--hp-accent); }

/* Process */
.hp-process { padding-top: 112px; padding-bottom: 112px; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr)); gap: 48px 88px; }
.hp-process-head { display: flex; flex-direction: column; gap: 18px; align-self: start; position: sticky; top: 120px; }
.hp-steps { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--hp-ink); }
.hp-step { display: grid; grid-template-columns: 56px 1fr; padding: 30px 0; border-bottom: 1px solid var(--hp-rule); }
.hp-step-n { font: 400 28px/1.1 var(--hp-serif); color: var(--hp-accent); }
.hp-step > div { display: flex; flex-direction: column; gap: 8px; }
.hp-step p { font-size: 17px; line-height: 1.65; color: var(--hp-body); }

/* Approach (dark) */
.hp-dark { background: #1f1916; color: #f4ede3; scroll-margin-top: 72px; }
.hp-dark-grid { padding-top: 120px; padding-bottom: 120px; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr)); gap: 40px 88px; align-items: start; }
.hp-dark-copy { display: flex; flex-direction: column; gap: 28px; padding-top: 36px; }
.hp-dark-copy p { font-size: 17px; line-height: 1.7; color: #ebe3d8; text-wrap: pretty; }
.hp-dark-copy .hp-btn { align-self: flex-start; }

/* Final CTA + footer */
.hp-final { max-width: 820px; margin: 0 auto; padding: 128px 40px 112px; box-sizing: border-box; display: flex; flex-direction: column; align-items: center; gap: 22px; text-align: center; scroll-margin-top: 72px; }
.hp-final-kicker { font-size: 13px; font-weight: 600; letter-spacing: .16em; text-transform: uppercase; color: var(--hp-body); }
.hp-h2-final { font-size: clamp(40px, 4.8vw, 60px); line-height: 1.05; }
.hp-final-copy { font-size: 17px; line-height: 1.65; color: var(--hp-body); max-width: 560px; text-wrap: pretty; }
.hp-final .hp-btn { margin-top: 10px; }
.hp-foot { border-top: 1px solid rgba(35, 29, 26, .1); }
.hp-foot-row { padding-top: 32px; padding-bottom: 32px; display: flex; flex-wrap: wrap; gap: 24px; align-items: center; font-size: 13px; color: var(--hp-soft); }
.hp-foot-name { font: 400 16px var(--hp-serif); color: var(--hp-ink); }
.hp-foot-gap { flex: 1; }
.hp-foot-link { all: unset; font: 400 13px var(--hp-sans); color: var(--hp-soft); cursor: pointer; }
.hp-foot-link:hover { color: var(--hp-ink); }
.hp-foot-link:focus-visible { outline: 3px solid rgba(110, 58, 50, .3); outline-offset: 3px; }
.hp-foot-link.is-inactive, .hp-foot-link.is-inactive:hover { cursor: default; color: var(--hp-soft); }

/* Phones: the design's grids already fold; the header and gutters need help. */
@media (max-width: 760px) {
  .shell.is-home .topbar { padding: 0 20px; min-height: 64px; flex-wrap: nowrap; }
  .shell.is-home .nav a { display: none; }
  .shell.is-home .brand-name { font-size: 17px; }
  .hp-wrap, .hp-final { padding-left: 20px; padding-right: 20px; }
  .hp-hero { padding-top: 48px; padding-bottom: 56px; gap: 48px; }
  .hp-examples > .hp-wrap, #deliverables > .hp-wrap, .hp-process, .hp-dark-grid { padding-top: 72px; padding-bottom: 72px; }
  .hp-final { padding-top: 88px; padding-bottom: 80px; }
  .hp-proof-grid > div { padding: 24px 0; border-left: 0; border-top: 1px solid rgba(35, 29, 26, .1); }
  .hp-proof-grid > div:first-child { border-top: 0; }
  .hp-deliv-item { padding-right: 0; }
  .hp-process-head { position: static; }
  .hp-frame-caps { font-size: 10.5px; letter-spacing: .06em; }
  .hp-frame-caps span { padding-left: 10px; }
  .hp-frame-meta { font-size: 11px; }
  .hp-dark-copy { padding-top: 0; }
}
/* HOME-V2 — the app's global h1/h2/h3 colours must not leak into the dark band. */
.hp-dark .hp-h2, .hp-dark h2 { color: #f4ede3; }
.hp .hp-h1, .hp .hp-h2, .hp .hp-h3, .hp .hp-h3s { color: inherit; }
/* HOME-V2 — the design's containers are 1200px of CONTENT (content-box) plus
   40px gutters; match that exactly (header, sections, final CTA). */
.hp-wrap { max-width: 1280px; }
.shell.is-home .topbar { padding: 0 max(40px, calc((100% - 1200px) / 2)); }
.hp-final { max-width: 900px; }
@media (max-width: 760px) { .shell.is-home .topbar { padding: 0 20px; } }
@media (max-width: 760px) {
  .hp-foot-row { gap: 12px 24px; }
  .hp-foot-name { flex-basis: 100%; }
  .hp-foot-gap { display: none; }
}

/* ── HOME-LOOKS (2026-09-27): the hero cycles the built-in looks, each a real
   opening card (16:9 like the films). Replaces the polaroid placeholder. */
@media (min-width: 1000px) { .hp-hero { grid-template-columns: minmax(0, .95fr) minmax(0, 1.05fr); gap: 56px; } }
.hp-looks { margin: 0; display: flex; flex-direction: column; gap: 14px; }
.hp-looks-frame { all: unset; box-sizing: border-box; display: block; position: relative; width: 100%; aspect-ratio: 16 / 9; cursor: pointer; overflow: hidden; border-radius: 2px;
  background: #e9e2d6; box-shadow: 0 1px 2px rgba(0, 0, 0, .08), 0 30px 60px -20px rgba(30, 20, 15, .45); }
.hp-looks-frame:focus-visible { outline: 3px solid rgba(110, 58, 50, .35); outline-offset: 4px; }
.hp-looks-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; opacity: 0; transition: opacity 1.1s ease; }
.hp-looks-img.is-on { opacity: 1; }
.hp-looks-img:not([src]) { visibility: hidden; }
@media (prefers-reduced-motion: reduce) { .hp-looks-img { transition: none; } }
.hp-looks-cap { display: flex; justify-content: space-between; align-items: baseline; gap: 16px; flex-wrap: wrap; font: 400 14px var(--hp-sans); color: #4f4640; }
.hp-looks-who b { font: 400 17px var(--hp-serif); color: var(--hp-ink); margin-right: 2px; }
.hp-looks-cta { all: unset; cursor: pointer; font: 600 14px var(--hp-sans); color: var(--hp-accent); white-space: nowrap; }
.hp-looks-cta:hover { color: var(--hp-accent-dark); }
.hp-looks-cta:focus-visible { outline: 3px solid rgba(110, 58, 50, .3); outline-offset: 3px; }

/* RW-HEART (2026-09-27) — a look's drawn connector, painted centred on the gap
   the dates line already leaves for it (see tcDatesConnectorOrn in app.js). The
   span keeps the gap's own characters, so the line measures exactly as before;
   the art is a pseudo-element, sized in em so it scales with the dates. */
.tc-date-orn { position: relative; }
.tc-date-orn::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: var(--tc-orn-w, 1.8em);
  aspect-ratio: 531 / 212;
  background: var(--tc-orn) center / contain no-repeat;
  transform: translate(-50%, -50%);
  pointer-events: none;
}

/* LEGAL (2026-09-27) — Terms + Contact dialogs; they wear the Privacy panel. */
.legal-modal { cursor: default; }
.legal-panel .text-link { font: inherit; padding: 0; }
.legal-ph { background: #fff1b8; color: #6b4a00; border-radius: 3px; padding: 0 3px; font-weight: 600; }
.legal-form { display: grid; gap: 12px; margin: 8px 0 4px; }
.legal-field { display: grid; gap: 5px; font-size: 0.86rem; font-weight: 600; color: rgba(40,32,24,0.78); }
.legal-field em { font-style: normal; font-weight: 400; color: rgba(40,32,24,0.5); }
.legal-field textarea { resize: vertical; min-height: 110px; }
.legal-check { display: flex; gap: 8px; align-items: flex-start; font-size: 0.86rem; color: rgba(40,32,24,0.75); }
.legal-check input { margin-top: 3px; }
.legal-hp { position: absolute !important; left: -9999px !important; width: 1px; height: 1px; opacity: 0; }
.legal-err { margin: 0; color: #9b2c2c; font-size: 0.88rem; }
.legal-actions { gap: 10px; margin-top: 4px; }
.legal-or { margin-top: 12px !important; }
.legal-sent { padding: 14px 16px; border-radius: 10px; background: rgba(46, 125, 72, 0.08); border: 1px solid rgba(46,125,72,0.2); }
.legal-sent-h { font-weight: 700; margin-bottom: 4px !important; }
@media (max-width: 600px) { .legal-actions { flex-direction: column-reverse; } .legal-actions .ghost-btn, .legal-actions .primary-btn { width: 100%; } }

/* ACCOUNTS phase 1a (2026-09-28) — Sign in button, account chip + menu, sign-in dialog. */
.lm-auth-signin { font: inherit; background: none; border: 1px solid var(--line-strong, rgba(40,32,24,.25)); border-radius: 999px; padding: 6px 14px; cursor: pointer; color: inherit; }
.lm-auth-signin:hover { background: rgba(40,32,24,.06); }
.lm-auth-wrap { position: relative; display: inline-flex; }
.lm-auth-chip { width: 34px; height: 34px; border-radius: 50%; border: none; cursor: pointer; background: var(--accent, #764239); color: #fff; font: 600 14px/1 inherit; display: inline-flex; align-items: center; justify-content: center; }
.lm-auth-chip:focus-visible, .lm-auth-signin:focus-visible { outline: 3px solid rgba(118,66,57,.35); outline-offset: 2px; }
.lm-auth-menu { position: absolute; right: 0; top: calc(100% + 8px); z-index: 60; min-width: 220px; background: #fffdf7; border: 1px solid rgba(40,32,24,.14); border-radius: 12px; box-shadow: 0 14px 40px rgba(0,0,0,.18); padding: 12px; }
.lm-auth-menu-who { margin: 0 0 10px; font-size: .84rem; color: rgba(40,32,24,.65); word-break: break-all; }
.lm-auth-menu-who b { color: var(--ink, #281f18); }
.lm-auth-menu button { width: 100%; text-align: left; font: inherit; background: none; border: none; padding: 8px 6px; border-radius: 8px; cursor: pointer; color: inherit; }
.lm-auth-menu button:hover { background: rgba(40,32,24,.06); }
.lm-auth-panel { width: min(94vw, 460px); }
.lm-auth-code { letter-spacing: .3em; font-size: 1.2rem; text-align: center; }
.shell.is-home .lm-auth-signin { font: 500 14px var(--hp-sans, inherit); }
.lm-auth-google { display: flex; align-items: center; justify-content: center; gap: 10px; width: 100%; min-height: 46px; margin: 6px 0 4px; border: 1px solid rgba(40,32,24,.22); border-radius: 10px; background: #fff; font: 600 .95rem inherit; color: #1f1f1f; cursor: pointer; }
.lm-auth-google:hover { background: #f7f5f1; }
.lm-auth-google:focus-visible { outline: 3px solid rgba(118,66,57,.35); outline-offset: 2px; }
.lm-auth-or { display: flex; align-items: center; gap: 10px; margin: 12px 0 2px !important; font-size: .8rem !important; color: rgba(40,32,24,.5); }
.lm-auth-or::before, .lm-auth-or::after { content: ""; flex: 1; height: 1px; background: rgba(40,32,24,.14); }

/* ONE-TAB: the "open in another tab" notice sits above every other popup
   (the welcome popup is z 9998). */
.lightbox.lm-paused-modal { z-index: 10050; }

/* SHARE LINKS — "Share with family" on the finished film. */
.f3-share { text-align: center; }
.f3-share-title { font-family: inherit; font-size: 1.15rem; font-weight: 600; margin: 0 0 8px; }
.f3-share .f3-note { max-width: 560px; margin: 8px auto; }
.lm-share-row { display: flex; gap: 10px; max-width: 620px; margin: 10px auto 4px; }
.lm-share-url { flex: 1; min-width: 0; padding: 10px 12px; border: 1px solid rgba(0,0,0,.18); border-radius: 10px; font: inherit; font-size: .92rem; background: #fff; color: inherit; }
.lm-share-more { display: flex; gap: 18px; justify-content: center; flex-wrap: wrap; margin-top: 6px; }
.lm-share-err { color: #9b2c2c; }
@media (max-width: 560px) { .lm-share-row { flex-direction: column; } }

/* ADULTS-ONLY (2026-09-28) — the agreement line under the sign-in buttons, and
   Terms / Privacy opened from the sign-in dialog sit above it. */
.lm-auth-fine { font-size: .82rem; opacity: .75; margin: 14px 0 0; text-align: center; line-height: 1.45; }
.lm-auth-fine .text-link { font-size: inherit; }
.lightbox.legal-terms, .lightbox.privacy-modal { z-index: 10020; }

/* EXAMPLES-FICTIONAL (2026-09-28) — the quiet "fictional" markers on the examples. */
.f3-demo-fict { opacity: .7; font-weight: 400; }
/* A small tag in the picture's corner (same place on every look), so the
   caption row never changes height as the homepage rotates between people. */
.hp-looks-frame { position: relative; }
.hp-looks-fict { position: absolute; left: 12px; bottom: 10px; z-index: 3; padding: 3px 9px; border-radius: 999px;
  background: rgba(20, 14, 10, .55); color: #fff; font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  pointer-events: none; font-family: "Public Sans", -apple-system, "Segoe UI", Roboto, Arial, sans-serif; }

/* MUSIC-CID (2026-09-28) — tag on tracks registered with YouTube Content ID, and the posting note. */
.free-library-cid { grid-column: 1 / -1; margin-top: 1px; font-size: 12px; font-weight: 400; color: #8a4f12; }
/* Two lines (title [+ its descriptor] / tag) so the tag never widens the list. */
.free-library-info:has(.free-library-cid) { display: grid !important; grid-template-columns: max-content 1fr; column-gap: .55em; align-items: baseline; }
.free-library-post-note.free-library-post-note { width: 0; min-width: 100%; margin: 4px 0 16px; font-size: 13px; line-height: 1.45; opacity: .8; }

/* REVEAL-PER-PHOTO (2026-09-28) — the per-photo "show the reveal" switch under each before/after. */
.f3-reveal-toggle { display: flex; align-items: center; justify-content: center; gap: .5rem; margin: .55rem auto 0; font-size: .86rem; color: var(--body, #4a4a4a); cursor: pointer; user-select: none; }
.f3-reveal-toggle input { width: 1.05rem; height: 1.05rem; accent-color: #6e3a32; cursor: pointer; }

/* HELP (2026-09-28) — Help dialog: "What's included" + questions. Reuses the
   Terms/Privacy panel; these rules only add the list and the questions. */
.lightbox.legal-help { z-index: 10020; }
.legal-help .help-sec-title { margin: 6px 0 2px; font-size: 1.12rem; font-weight: 600; color: #2a211b; }
.legal-help .help-faq-title { margin-top: 26px; }
.legal-help .help-list { margin: 0 0 4px; padding-left: 1.15em; }
.legal-help .help-list li { margin: 4px 0; line-height: 1.5; }
.legal-help .help-faq { border-top: 1px solid rgba(40,32,24,0.12); margin-top: 8px; }
.legal-help .help-q { border-bottom: 1px solid rgba(40,32,24,0.12); }
.legal-help .help-q summary { cursor: pointer; padding: 11px 26px 11px 0; font-weight: 600; list-style: none; position: relative; }
.legal-help .help-q summary::-webkit-details-marker { display: none; }
.legal-help .help-q summary::after { content: "+"; position: absolute; right: 4px; top: 9px; font-size: 1.15rem; font-weight: 400; color: rgba(40,32,24,0.55); }
.legal-help .help-q[open] summary::after { content: "–"; }
.legal-help .help-q summary:focus-visible { outline: 2px solid var(--accent, #6b3f35); outline-offset: 2px; border-radius: 4px; }
.legal-help .help-q p { margin: 0 0 12px; line-height: 1.55; }
.legal-help .help-more { margin-top: 16px; }
.wiz-pay-more { text-align: center; margin: 2px 0 10px; }
/* HELP — phones hide the text links in the top bar; Help stays reachable. */
@media (max-width: 760px) {
  .nav button.lm-help-nav { display: inline-block; padding: 0.35rem 0.2rem; font-size: 0.9rem; }
}
/* Home on a phone: no room beside "Start a film" — Help is in the footer there. */
@media (max-width: 760px) {
  .shell.is-home .nav button.lm-help-nav { display: none; }
}
/* LINK-PREVIEW — the portrait switch on the share card. */
.f3-share .lm-share-preview { margin-top: 12px; }
.f3-share .lm-share-preview-note { margin-top: 4px; }
/* TURNSTILE — Cloudflare's check only shows itself when it needs a click. */
.lm-turnstile-box { position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%); z-index: 10070; display: none; background: #fffdf9; border: 1px solid #e6dccf; border-radius: 12px; padding: 10px; box-shadow: 0 10px 30px rgba(0,0,0,.18); }
.lm-turnstile-box.show { display: block; }
/* ACCOUNT-DELETE — menu item, confirm dialog, pending banner. */
.lm-auth-menu .lm-auth-menu-danger, .nav .lm-auth-menu button.lm-auth-menu-danger { color: #9b2c2c; } /* beats .nav button:not(.primary-btn) */
.lightbox.legal-acctdel { z-index: 10020; }
.legal-acctdel .acctdel-label { display: block; margin: 16px 0 6px; font-size: 0.95rem; }
.legal-acctdel .acctdel-input { width: 100%; box-sizing: border-box; padding: 10px 12px; border: 1px solid rgba(40,32,24,.25); border-radius: 10px; font: inherit; }
.legal-acctdel .acctdel-actions { display: flex; gap: 10px; justify-content: flex-end; flex-wrap: wrap; }
.legal-acctdel .acctdel-go { background: #9b2c2c; border-color: #9b2c2c; }
.lm-acctdel-banner { display: flex; gap: 12px; align-items: center; justify-content: center; flex-wrap: wrap; padding: 10px 16px; background: #fbe9e7; color: #5a1f1a; font-size: 0.95rem; text-align: center; border-bottom: 1px solid #f1c9c3; }

/* SIGNIN-FLOW (2026-09-29) — the welcome card after signing in */
.lm-wb-row { display: flex; align-items: center; gap: 16px; margin: 4px 0 18px; }
.lm-wb-row p { margin: 0; }
.lm-wb-photo { width: 64px; height: 64px; flex: 0 0 64px; object-fit: cover; border-radius: 10px; box-shadow: 0 1px 4px rgba(0,0,0,.12); }
.lm-opening-cover { position: fixed; inset: 0; z-index: 20000; display: grid; place-items: center; background: #f6f2ec; color: #5b4a3f; font-size: 16px; }

/* NO-REFADE (2026-09-29) — a popup rebuilt by a redraw does not fade in again */
.lm-no-enter { animation: none !important; }

/* LAST-USED (2026-09-29) — how this device signed in last time */
.lm-auth-lastpill { display: inline-block; margin-left: 8px; padding: 2px 8px; border-radius: 99px; background: #efe4d6; color: #6b4a3a; font: 600 .68rem/1.4 inherit; letter-spacing: .02em; vertical-align: 1px; white-space: nowrap; }
.lm-auth-last { margin: 0 0 10px !important; font-size: .85rem !important; color: rgba(40,32,24,.72); }
.lm-auth-last .text-link { font-size: inherit; margin-left: 4px; }
.lm-auth-lastnote { margin: 6px 0 0 !important; font-size: .8rem !important; color: rgba(40,32,24,.6); text-align: right; }
.lm-auth-lastnote .lm-auth-lastpill { margin: 0 4px 0 0; }
