/* ============================================================
   Chapter 1 screens in the light theme
   ------------------------------------------------------------
   Source: docs/previews/light-theme/{Intro,InApp,Mic,Anchor,...}.dc.html
   and SPEC.md («Chapter 1 screens»). The frame is Cards.screen() in
   shared/cards.js and stands on the cards' ground (.cs, .cs-art, .cs-bg in
   cards.css): the screen is a full-bleed flex column.

     art zone   312px at 390x844 (SPEC «Size scale»), the 390x844 picture
                anchored at y 156, so it sits exactly where the board has
                it; the picture itself is drawn at --art-scale around its
                centre (195, 220); on a short screen this zone is what gives
     text       the free space between the picture and the buttons, with
                the text centred in it (SPEC: never left hanging)
     foot       the board's own distance from the bottom: 118px with one
                button, 60px with none, 250px with two

   Every colour and every size is a token in style.css; motion is transform
   and opacity only, and none of it runs while the microphone is open
   (.c1-still) or under prefers-reduced-motion.
   ============================================================ */

.c1 .c1-art { --art-basis: 19.5rem; margin-top: 0; }
/* the picture's y 156 sits at the middle of the art zone, as on the board */
.c1 .cs-bg { --cs-anchor: 156; }
.c1-pic,
.c1-intro .c1-deco { transform-box: view-box; transform-origin: 195px 220px; transform: scale(var(--art-scale)); }
/* On a short screen the zone is far shorter than the screen, so the picture
   is also capped by the zone's own height (the circle and its shadow, about
   200 of the picture's 844, fit in it). A browser without container units
   keeps the cards' rule; at 390x844 the cap is never the smallest. */
.c1 .c1-art { container-type: size; }
.c1 .cs-bg { width: min(100%, 46.21dvh, 195cqh); }

.c1-text {
  /* grows into the free space, never below its words: the art zone gives */
  flex: 1 0 auto;
  box-sizing: border-box;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0 2.25rem;
}
.c1-foot {
  flex: none;
  box-sizing: border-box;
  width: 100%;
  height: calc(7.375rem + env(safe-area-inset-bottom, 0px));
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  padding-bottom: calc(2.5rem + env(safe-area-inset-bottom, 0px));
}
.c1-foot.is-empty { height: calc(3.75rem + env(safe-area-inset-bottom, 0px)); }
.c1-foot.is-two { height: calc(15.625rem + env(safe-area-inset-bottom, 0px)); }

.c1-title { font-size: var(--fs-title); font-weight: 700; line-height: 1.5; }
.c1-body { max-width: 19.375rem; font-size: var(--fs-body); line-height: var(--lh-body); color: var(--paper-ink-2); }
/* a line said while something is happening: a red dot that breathes */
.c1-live { display: flex; align-items: center; gap: 0.5rem; font-size: var(--fs-lead); font-weight: 700; color: var(--paper-ink); }
.c1-anchor .c1-live { font-size: var(--fs-live); }
.c1-live::before { content: ""; flex: none; width: 0.5rem; height: 0.5rem; border-radius: 50%; background: var(--brand); animation: c1-pulse 1.4s ease-in-out infinite; }
.c1-live:empty { display: none; }
.c1-small { padding: 0 2.75rem; font-size: var(--fs-small); line-height: var(--lh-body); color: var(--paper-ink-2); }

/* ── buttons (SPEC: red starts a test step, silver goes on, white is the
      second choice); --btn-h high, the bottom one 40px above the edge ── */
.c1-btn {
  position: relative;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  width: max-content;
  max-width: 20.625rem;
  min-width: var(--btn-min-w);
  min-height: var(--btn-h);
  font-size: var(--fs-btn);
  margin: 0 auto;
  border: 0;
  border-radius: 999px;
  font-family: Vazirmatn, Tahoma, sans-serif;
  font-weight: 800;
  overflow: hidden;
  cursor: pointer;
}
/* gradient, edge and shine are .ruby's (splash.css) */
.c1-ruby { padding: var(--btn-pad); }
.c1-silver {
  padding: var(--btn-pad);
  background: linear-gradient(180deg,
    var(--btn-secondary-0) 0%, var(--btn-secondary-1) 38%, var(--btn-secondary-2) 52%,
    var(--btn-secondary-3) 70%, var(--btn-secondary-4) 100%);
  color: var(--btn-secondary-ink);
  box-shadow: inset 0 1px 0 var(--btn-secondary-hi),
    inset 0 -3px 0 rgba(var(--btn-secondary-shade-rgb), 0.22),
    0 14px 30px -10px rgba(var(--btn-secondary-glow-rgb), 0.45),
    0 0 0 1px var(--btn-secondary-edge);
}
.c1-silver:after {
  content: "";
  position: absolute;
  top: 0; bottom: 0; left: 0;
  width: 38%;
  background: linear-gradient(90deg, transparent, rgba(var(--btn-secondary-hi-rgb), 0.95), transparent);
  animation: cs-sweep 3.4s ease-in-out infinite;
}
.c1-ghost {
  padding: var(--btn-pad-ghost);
  background: var(--art-white);
  color: var(--paper-ink);
  box-shadow: 0 0 0 1px var(--guide-edge), 0 10px 24px -16px rgba(var(--mark-shadow-rgb), 0.45);
}
/* the line above two buttons keeps the board's place (186px from the
   bottom) whatever height the red button takes in each script */
.c1-foot.is-two { position: relative; }
.c1-foot.is-two .c1-small {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(11.625rem + env(safe-area-inset-bottom, 0px));
}
/* the board's two buttons: the red one 112 from the bottom, the white 40 */
.c1-foot .c1-btn + .c1-btn { margin-top: calc(4.5rem - var(--btn-h)); }

/* the spoken guide is shared/guide.css; the intro's board pads it a little
   tighter than the anchor's */
.c1-intro .guide-btn { padding-block: 0.3125rem; padding-inline: 0.375rem 1rem; }

/* ── a soft panel with an icon: the device note, the anchor's tip ── */
.c1-note {
  display: flex;
  align-items: flex-start;
  gap: 0.625rem;
  /* content-box, as on the board: 318 is the text's width, not the panel's */
  max-width: 19.875rem;
  box-sizing: content-box;
  padding: 0.625rem 0.875rem;
  border-radius: 1rem;
  background: var(--soft-fill);
  font-size: var(--fs-small);
  line-height: var(--lh-body);
  color: var(--paper-ink-2);
  text-align: start;
}
.c1-note svg { flex: none; width: 1.125rem; height: 1.125rem; margin-top: 3px; }
.c1-pill {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.375rem 0.875rem;
  border-radius: 999px;
  background: var(--soft-fill);
  font-size: var(--fs-small);
  color: var(--paper-ink-2);
}
.c1-pill svg { flex: none; width: 0.875rem; height: 1rem; }
.c1-alert {
  max-width: 19.875rem;
  box-sizing: content-box;
  padding: 0.625rem 0.875rem;
  border-radius: 1rem;
  background: var(--notice-red-bg);
  color: var(--notice-red-ink);
  font-size: var(--fs-small);
  font-weight: 700;
  line-height: var(--lh-body);
}

/* ── the note in the middle of the picture (the anchor) ── */
.c1-center {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(191 / 844 * 100%);
  height: calc(58 / 844 * 100%);
  display: grid;
  place-items: center;
  /* 40 x --art-scale (34px) at the board's 390x844, scaled with the
     picture below that */
  font-size: calc(2.5rem * var(--art-scale));
  font-size: calc(min(2.5rem, 10.25642vw, 4.73934dvh) * var(--art-scale));
  font-weight: 800;
  line-height: 1;
  color: var(--lilac-1);
  pointer-events: none;
}
/* lit: a note has been held long enough to show (range.js, ringProgress) */
.c1-center.lit { color: var(--paper-ink); }
.c1-gap { flex: none; height: 0.625rem; }

/* ── 1. intro: the text keeps its place while the three steps cycle ── */
.c1-intro .c1-text {
  flex: 0 1 10.125rem;
  justify-content: flex-start;
  margin-top: 0.875rem;
  padding: 0 2.5rem;
}
.c1-intro .c1-body { max-width: 18.75rem; min-height: 3.5625rem; }
.c1-intro .cs-dots { margin-top: 0.375rem; }
.c1-mid {
  flex: none;
  box-sizing: border-box;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.875rem;
  padding: 0 1.75rem;
}
.c1-mid:empty { display: none; }
.c1-intro .c1-foot { height: auto; margin-top: auto; }
.c1-panel { display: none; }
.c1-panel.on { display: inline; animation: c1-fade 0.5s ease-out both; }

/* ── 2. mic: ask, listen (the room is being measured), done ── */
.c1-mic .c1-mic-rings,
.c1-mic .c1-mic-done { display: none; }
.c1-mic.is-listen .c1-mic-rings,
.c1-mic.is-done .c1-mic-done { display: inline; }
.c1-mic .c1-body { max-width: 18.75rem; }

/* ── 5. analyzing: the warm arc turns (the microphone is closed) ── */
.c1-spin { transform-box: fill-box; transform-origin: center; animation: c1-spin 1.2s linear infinite; }

/* ── 4. the walk (Steps.dc.html): the pill and the keyboard card in the
      top 360px, the exchange under it, top-aligned so nothing moves while
      singing. Only the waves of the ground; no dots, no orbs. ── */
/* child selectors: the brief's own frame sits inside this one */
.c1-steps > .c1-art .c1-deco { display: none; }
.c1-steps > .c1-art { --art-basis: 22.5rem; flex-shrink: 0; }
.c1-steps > .c1-art .cs-bg { --cs-anchor: 180; }
.c1.c1-steps .walk-dir {
  position: absolute;
  top: 5.75rem;
  left: 50%;
  transform: translateX(-50%);
  padding: 0.4375rem 1rem;
  border: 0;
  border-radius: 999px;
  background: var(--art-white);
  box-shadow: 0 0 0 1px var(--guide-edge);
  font-size: var(--fs-body);
  font-weight: 700;
  line-height: normal;
  white-space: nowrap;
}
.c1.c1-steps .walk-dir:empty { display: none; }
.c1.c1-steps .walk-dir.down { color: var(--walk-down-ink); background: var(--art-white); }
.c1.c1-steps .walk-dir.up { color: var(--walk-up-ink); background: var(--art-white); }
/* its arrow nudges toward the keyboard (down) or away from it (up); a small
   HTML transform, composited, so it runs with the microphone open too */
.c1.c1-steps .walk-arrow { display: inline-block; animation: c1-nudge-down 1.6s ease-in-out infinite; }
.c1.c1-steps .walk-dir.up .walk-arrow { animation-name: c1-nudge-up; }
/* the keyboard (UI.piano, as before) on a white card */
.c1-kb-card {
  position: absolute;
  top: 9.375rem;
  left: 1.375rem;
  right: 1.375rem;
  box-sizing: border-box;
  padding: 0.625rem 0.4375rem;
  border: 1px solid var(--card-stroke);
  border-radius: 1.375rem;
  background: var(--kb-card);
}
.c1.c1-steps .piano-container,
.c1.c1-steps .piano-container.tall {
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
}
.c1-steps > .c1-text { flex: 1 0 auto; justify-content: flex-start; }
.c1-target { font-size: var(--fs-small); color: var(--paper-ink-2); }
.c1.c1-steps .note-target {
  font-size: var(--fs-note);
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: 0;
  color: var(--paper-ink);
  text-shadow: none;
}
.c1.c1-steps .walk-say-row { gap: 0.5rem; margin-top: 0.25rem; }
/* With a result glyph alone the word is empty; a zero-width letter of the
   same script keeps the row its height, so nothing under it moves while
   singing (ZWNJ is in Vazirmatn, ZWSP falls back like the Latin words). */
.c1.c1-steps .walk-say:empty::before { content: "\200c"; }
.c1.c1-steps[dir="ltr"] .walk-say:empty::before { content: "\200b"; }
.c1.c1-steps .state-icon {
  display: flex;
  align-items: center;
  min-height: 0;
  font-size: var(--fs-state);
  line-height: 1;
  color: var(--paper-ink-2);
  text-shadow: none;
  animation: none;
}
.c1.c1-steps .state-icon svg { display: block; width: 1.375rem; height: 1.375rem; }
/* «بخون»: a breathing red dot (information, so it moves with the mic open) */
.c1.c1-steps .state-icon.sing::before {
  content: "";
  width: 0.625rem;
  height: 0.625rem;
  border-radius: 50%;
  background: var(--brand);
  animation: c1-pulse 1.4s ease-in-out infinite;
}
.c1.c1-steps .walk-say,
.c1.c1-steps .walk-say.sing {
  font-size: var(--fs-state);
  font-weight: 800;
  line-height: normal;
  letter-spacing: 0;
  color: var(--paper-ink);
}
.c1.c1-steps .cue-bar {
  width: 16.25rem;
  max-width: 100%;
  height: 0.375rem;
  margin-top: 0.375rem;
  border-radius: 0.375rem;
  background: var(--paper-edge);
  opacity: 1;
}
.c1.c1-steps .cue-bar > i,
.c1.c1-steps .cue-bar.lead > i,
.c1.c1-steps .cue-bar.live > i { background: linear-gradient(90deg, var(--violet), var(--brand)); }
.c1-steps[dir="ltr"] .cue-bar > i { transform-origin: left center; }
/* «صدای تو: G2», dimmed when the tracker has nothing new (as before) */
.c1.c1-steps .note-heard {
  min-height: 0;
  margin-top: 0.5rem;
  padding: 0.375rem 0.875rem;
  border-radius: 999px;
  background: var(--art-white);
  box-shadow: 0 0 0 1px var(--guide-edge);
  font-size: var(--fs-body);
  font-weight: 700;
  letter-spacing: 0;
  color: var(--paper-ink);
  text-shadow: none;
}
.c1.c1-steps .note-heard::before { content: attr(data-label) " "; font-weight: 400; color: var(--paper-ink-2); }
.c1.c1-steps .note-heard:empty { display: none; }
/* every message under the bar, one look (SPEC answer 5) */
.c1.c1-steps .pitch-hint,
.c1.c1-steps .pitch-hint.warn {
  min-height: 0;
  max-width: 18.75rem;
  margin-top: 0.5rem;
  font-size: var(--fs-body);
  font-weight: 700;
  line-height: 1.7;
  color: var(--hint-ink);
}
.c1.c1-steps .pitch-hint:empty { display: none; }

/* ── 3b. the briefs (Brief.dc.html), over the walk ── */
.c1-cap { font-weight: 700; }
.c1-bk { fill: var(--kb-key); stroke: var(--kb-key-stroke); }
.c1-brief-down .c1-bk.anchor,
.c1-brief-down .c1-bk.lo { fill: var(--brief-down-tint); }
.c1-brief-up .c1-bk.hi,
.c1-brief-up .c1-bk:nth-child(13).hi + .c1-bk { fill: var(--brief-up-tint); }

/* ── the trouble screens: two buttons, the silver one 112 from the bottom,
      the white one 40, the text above them (Offpitch, Insufficient) ── */
.c1-foot.is-pair { height: calc(11.5rem + env(safe-area-inset-bottom, 0px)); }
/* the admin link is a link dressed as the white button (Insufficient) */
a.c1-btn { display: block; text-align: center; text-decoration: none; box-sizing: border-box; }
/* error: a smaller title, the numbered steps, the technical detail */
.c1-title.c1-err { font-size: var(--fs-title-err); }
.c1-steps-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  max-width: 19.875rem;
  margin-top: 0.375rem;
  padding: 0.75rem 1rem;
  border-radius: 1rem;
  background: var(--soft-fill);
  text-align: start;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--paper-ink);
}
.c1-steps-list > div { display: flex; gap: 0.625rem; }
.c1-steps-list b { color: var(--lilac-1); }
.c1-detail { font-size: var(--fs-small); color: var(--paper-ink-2); }
/* off-pitch: the tuner is not drawn at --art-scale, and has its own dots */
.c1-offpitch .c1-pic { transform: none; }
.c1-offpitch .c1-deco { display: none; }

/* ── 8. gender: two silver choices side by side, 48px from the bottom ── */
.c1-foot.is-choice {
  height: calc(7.75rem + env(safe-area-inset-bottom, 0px));
  flex-direction: row;
  align-items: flex-end;
  justify-content: center;
  gap: 0.875rem;
  padding-inline: 2rem;
  padding-bottom: calc(3rem + env(safe-area-inset-bottom, 0px));
}
.c1-choice {
  flex: 1;
  width: auto;
  min-width: 0;
  max-width: 9.375rem;
  margin: 0;
  padding: var(--btn-pad-choice);
}

/* ── shorter screens (the same threshold as the cards) ─────────
   The art zone gives first; the picture is then centred on its circle
   (y 220) so the circle never runs under the words, and the line above two
   buttons joins the flow so it can never ride up into them. The bottom
   button keeps its 40px (SPEC: the home indicator). */
@media (max-height: 720px) {
  .c1 .cs-bg { --cs-anchor: 220; }
  .c1-intro .c1-mid { margin-top: 0.5rem; }
  /* the walk: the pill and the card move up (the keyboard is 128 tall
     below 680, style.css) */
  .c1-steps > .c1-art { --art-basis: 15.5rem; }
  .c1.c1-steps .walk-dir { top: 0.75rem; }
  .c1-kb-card { top: 3.5rem; }
  /* the intro carries the most words: a little more line */
  .c1-intro .c1-text { padding: 0 1.75rem; }
  .c1-foot.is-two { height: auto; padding-top: 0.75rem; }
  .c1-foot.is-two .c1-small { position: static; margin-bottom: 0.5rem; }
  .c1-foot .c1-btn + .c1-btn { margin-top: 0.75rem; }
}

/* ── motion: transform and opacity only ── */
.c1-fade { animation: c1-fade 0.5s ease-out both; }
.c1-ring { transform-box: fill-box; transform-origin: center; animation: c1-ring 2.4s ease-out infinite; }
.c1-ring + .c1-ring { animation-delay: 1.2s; }
.c1-k { opacity: 0; }
.c1-k.k { animation: c1-keyon 4s ease-in-out infinite both; }

/* the microphone is open: decoration stops, only information moves */
.c1-still .cs-flow,
.c1-still .cs-bob,
.c1-still .cs-bob2,
.c1-still .c1-ring { animation: none; }
.c1-still .c1-ring { opacity: 0; }

@keyframes c1-spin { to { transform: rotate(360deg); } }
@keyframes c1-fade { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes c1-ring { 0% { opacity: 0.9; transform: scale(0.82); } 100% { opacity: 0; transform: scale(1.35); } }
@keyframes c1-keyon { 0%, 6% { opacity: 0; } 16%, 90% { opacity: 1; } 100% { opacity: 0; } }
@keyframes c1-pulse { 0%, 100% { opacity: 0.35; } 50% { opacity: 1; } }
@keyframes c1-nudge-down { 0%, 100% { transform: translateY(-2px); } 50% { transform: translateY(3px); } }
@keyframes c1-nudge-up { 0%, 100% { transform: translateY(2px); } 50% { transform: translateY(-3px); } }
/* the brief's curve, along its own direction */
.c1-nudge-l { animation: c1-nudge-l 1.6s ease-in-out infinite; }
.c1-nudge-r { animation: c1-nudge-r 1.6s ease-in-out infinite; }
@keyframes c1-nudge-l { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(-7px); } }
@keyframes c1-nudge-r { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(7px); } }

@media (prefers-reduced-motion: reduce) {
  /* .cs * (cards.css) is not specific enough for these; named one by one,
     with the end state each one rests in */
  .c1 .c1-fade,
  .c1 .c1-panel.on,
  .c1 .c1-ring,
  .c1 .c1-k.k,
  .c1 .c1-live::before,
  .c1.c1-steps .walk-arrow,
  .c1 .c1-nudge-l,
  .c1 .c1-nudge-r,
  .c1 .c1-spin,
  .c1.c1-steps .state-icon.sing::before { animation: none; }
  /* the silver shine is hidden, not parked (SPEC; .ruby in splash.css) */
  .c1 .c1-silver:after { display: none; }
  .c1 .c1-ring { opacity: 0; }
  .c1 .c1-k.k { opacity: 1; }
}
