/* voice.css - the Speak page, Shadowing and its pitch lines, a word's pitch-accent drawing (pitch-accent.js, used
   on every screen that shows a word), the tutor's talk mode, and choosing a voice (Settings, and the first-run card
   on Today); colours only through the tokens in app.css. The Speak page puts its practice card first (on a phone the
   microphone is on the first screen), More ways (a session, Hands-free chat) is a fold under it, Say it's cards come
   from one small From select, the numbers sit with Words to work on (shown once there are some), and the Talk live
   card is above the practice (on a phone, the first row inside More ways). Japanese is drawn in the serif (ruby from
   ja.js) with 14 px furigana at least. Every microphone row is a phone call's (.mic-row): three circles centred in one
   row, Mute (56 px) | the microphone (the biggest, the row's centre) | Skip or Next (56 px), 32 px apart, each side
   circle's word under it, in ink, never inside it (a tap on the word presses its circle). Mute is a phone call's
   toggle, always the slashed microphone; pressed, it fills with ink and its word says Muted, and the big microphone
   dims to the slashed one with "Muted: …" in its hint; never colour alone (Talk live's is in live.css). On an upright
   phone the card's sound buttons and the microphone row are one bar docked at the foot, above the tab bar (on the
   home indicator where the page is a session: Shadowing), (.say-dock): the page leaves its height free at its foot
   (--say-dock-h, set by the screen), so nothing is left under it, and its Next is the dock's (the page's own waits). */

/* More ways (a session, Hands-free chat), a fold under the practice card */
.speak-stats { justify-content: flex-end; }
.side-stats { display: none; }
.speak-ways { margin: var(--s-4) 0 18px; }
.speak-morelist { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-3); margin: var(--s-1) 0 var(--s-2); }
.speak-more { margin-top: var(--s-2); border-top: 0; }
.speak-morelist .mode { display: flex; gap: 12px; align-items: center; justify-content: flex-start; min-height: 68px; padding: 12px 16px; border-radius: var(--r); border: 1.5px solid var(--line);
  background: var(--panel); color: var(--fg); text-decoration: none; text-align: left; white-space: normal; font: inherit; box-shadow: var(--shadow); cursor: pointer; }
@media (hover: hover) { .speak-morelist .mode:hover { border-color: var(--line2); } }
.speak-morelist .mode[aria-current=page] { border-color: var(--accent); background: var(--accent-soft); }
.speak-morelist .mode b { display: block; font-size: 16px; }
.speak-morelist .mode small { display: block; color: var(--mute); font-size: 14px; font-weight: 500; line-height: 1.3; }
.speak-morelist .mode-ic { display: grid; place-items: center; width: 40px; height: 40px; border-radius: 12px; background: var(--sunk); color: var(--accent); flex: none; }
.speak-morelist .mode[aria-current=page] .mode-ic { background: var(--panel); }
.speak-morelist .mode-ic svg { width: 22px; height: 22px; }
/* The Talk live card as More ways' first row on a phone: a row like its neighbours (speak.js moves it there) */
.speak-morelist .live-card { margin: 0; min-height: 68px; background: var(--panel); border: 1.5px solid var(--line); box-shadow: var(--shadow); }
@media (hover: hover) { .speak-morelist .live-card:hover { border-color: var(--line2); } }
.speak-morelist .live-card .live-card-ic { width: 40px; height: 40px; border-radius: 12px; background: var(--sunk); color: var(--accent); }
.speak-morelist .live-card .live-card-go { display: none; }
.speak-off { margin: 0 0 16px; }
/* Say it's cards: one small select ("From: This week's lesson ▾") */
.speak-from { display: inline-flex; align-items: center; gap: var(--s-2); min-width: 0; max-width: 100%; }
.speak-fromlabel { font-size: var(--fs-14); font-weight: 700; color: var(--ink-3); }
.speak-from select { min-height: var(--tap); min-width: 0; max-width: calc(100vw - 2 * var(--gutter) - 120px); font-size: var(--fs-input); }
/* With nothing to work on yet, Say it has the row to itself */
.speak-grid:has(> .speak-side[hidden]) { grid-template-columns: minmax(0, 1fr); max-width: 760px; }

/* Say it */
.speak-grid { align-items: start; }
.speak-top { margin-bottom: 8px; }
.speak-setnote { margin: 12px 0 0; text-align: center; }
.speak .seg button { min-height: 40px; }
.speak-deck { max-width: 360px; margin: 10px 0 0; }
.speak-card { text-align: center; padding: 26px 8px 8px; display: grid; justify-items: center; gap: 4px; }
.speak-card .chip { margin-bottom: 6px; }
.say-es { font-size: clamp(28px, 5.4vw, 40px); line-height: 1.25; margin: 0; overflow-wrap: anywhere; max-width: 100%; }
/* A word large (44 px on a phone), a short phrase a step down, a sentence smaller so it keeps to a few lines */
.say-es.say-short { font-size: clamp(44px, 6vw, 56px); }
.say-es.say-mid { font-size: clamp(32px, 5.4vw, 44px); }
.say-es.say-long { font-size: clamp(26px, 4.6vw, 36px); }
.say-mean { margin: 4px 0 0; font-size: 16px; overflow-wrap: anywhere; }
.speak-hear { justify-content: center; }

/* The sound buttons over the microphone row (on an upright phone a bar docked at the foot, below) */
.say-dock { display: grid; justify-items: stretch; gap: 14px; margin-top: 14px; min-width: 0; }
.mic-zone { display: grid; justify-items: center; gap: 10px; padding: 4px 0 6px; }
/* The microphone row, a phone call's: Mute | the microphone | Skip or Next, the microphone in the middle whatever is
   beside it, 32 px apart; the side circles' words hang under them, in the room the row leaves at its foot. */
.mic-row { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; column-gap: var(--s-6); width: 100%; padding-bottom: 18px; }
.mic-row > .mic-mute { grid-column: 1; justify-self: end; }
.mic-row > .mic-big { grid-column: 2; }
.mic-row > .mic-side { grid-column: 3; justify-self: start; }
/* The side circles: Mute, a phone call's toggle (always the slashed microphone; pressed, filled with ink and "Muted"),
   and Skip or Next (the chevron; once there is a result, Next, its edge and chevron in the accent). */
.mic-mute, .mic-side { position: relative; width: 56px; height: 56px; min-height: 0; padding: 0; border-radius: 50%; flex: none;
  background: var(--surface-2); color: var(--ink); border: 1.5px solid var(--line-strong); }
.mic-mute svg, .mic-side svg { width: 22px; height: 22px; }
.mic-mute .lbl, .mic-side .lbl { position: absolute; top: calc(100% + 4px); left: 50%; transform: translateX(-50%); min-width: 100%; text-align: center;
  color: var(--ink); font-size: var(--fs-14); font-weight: 700; line-height: 18px; white-space: nowrap; }
.mic-mute[aria-pressed=true] { background: var(--ink); color: var(--surface); border-color: var(--ink); }
.mic-mute[aria-pressed=true] .lbl { color: var(--ink); }
.mic-side[data-next="1"] { border-color: var(--accent); color: var(--accent); }
.mic-side[data-next="1"] .lbl { color: var(--ink); }
@media (hover: hover) {
  .mic-mute:hover, .mic-side:hover { background: var(--accent-soft); border-color: var(--field); }
  .mic-mute[aria-pressed=true]:hover { background: var(--ink); border-color: var(--ink); filter: brightness(1.15); }
}
.mic-mute:focus-visible, .mic-side:focus-visible { outline: 3px solid var(--focus); outline-offset: 4px; border-radius: 50%; }
.mic-big { --lvl: 0; position: relative; width: 92px; height: 92px; min-height: 0; padding: 0; border-radius: 50%; border: 0; background: var(--accent); color: var(--accent-ink); box-shadow: var(--shadow); }
.mic-big:hover { border: 0; filter: brightness(1.06); }
.mic-big:focus-visible { outline: 3px solid var(--accent); outline-offset: 5px; border-radius: 50%; }
/* The microphone takes the focus with each card: its ring is for the keyboard (speak.js take()), so a fresh card never
   looks like a pressed microphone. */
.mic-big[data-by=pointer]:focus-visible { outline: none; }
.mic-big :is(.ic-on, .ic-off) { display: grid; place-items: center; position: relative; z-index: 1; }
.mic-big .ic-off { display: none; }
.mic-big svg { width: 38px; height: 38px; }
/* Muted: dimmed, the slashed microphone on a quiet face (and "Muted: …" in its hint) */
.mic-big[data-state=muted] { background: var(--surface-2); color: var(--ink-3); box-shadow: none; outline: 2px solid var(--line-strong); outline-offset: -2px; }
.mic-big[data-state=muted] .ic-on { display: none; }
.mic-big[data-state=muted] .ic-off { display: grid; }
@media (hover: hover) { .mic-big[data-state=muted]:hover { background: var(--surface-2); filter: none; } }
.mic-big .ring { position: absolute; inset: -6px; border-radius: 50%; border: 3px solid var(--bad); opacity: 0; transform: scale(calc(1 + var(--lvl) * .35)); transition: transform .08s linear, opacity .2s; pointer-events: none; }
.mic-big .spinner { display: none; position: absolute; inset: 0; margin: auto; width: 34px; height: 34px; border-color: color-mix(in srgb, var(--accent-ink) 35%, transparent); border-top-color: var(--accent-ink); }
.mic-big[data-state=rec] { background: var(--bad); color: var(--panel); }
.mic-big[data-state=rec] .ring { opacity: .7; }
.mic-big[data-state=busy] .ic-on { opacity: 0; }
.mic-big[data-state=busy] .spinner { display: block; }
.mic-big:disabled { opacity: .55; }
.mic-big[data-state=busy]:disabled { opacity: 1; }
.mic-hint { min-height: 1.5em; margin: 0; text-align: center; max-width: 420px; }
.speak-err { margin: 6px 0 0; padding: 10px 14px; border-radius: var(--r-sm); background: var(--bad-soft); color: var(--fg); font-weight: 600; max-width: 520px; }
.speak-err a { color: var(--bad); }

.speak-result { margin-top: 14px; padding-top: 16px; border-top: 1px solid var(--line); }
/* A result (or an answer in the session) takes the focus when it comes in, so Space says it again. */
.speak-result:focus-visible, .speak-answer:focus-visible { outline-offset: 6px; border-radius: 12px; }
/* Its ring is for the keyboard: after a mouse or touch press (data-by=pointer, speak.js take()) none. */
.speak-result[data-by=pointer]:focus-visible, .speak-answer[data-by=pointer]:focus-visible { outline: none; }
.result-top { display: flex; gap: 16px; align-items: flex-start; }
/* The score tile belongs to the Speak result only: voice.css is on every page, and a bare .score is also
   the big number on a Study, Quiz or Drill summary (app.css). */
.result-top .score { flex: none; display: grid; justify-items: center; min-width: 84px; padding: 10px 12px; border-radius: 14px; background: var(--sunk); }
.result-top .score b { font-size: 34px; line-height: 1; letter-spacing: -.02em; }
.result-top .score span { font-size: 14px; color: var(--mute); font-weight: 600; }
.result-top .score.good { background: var(--good-soft); color: var(--good); }
.result-top .score.warn { background: var(--warn-soft); color: var(--warn); }
.result-top .score.bad { background: var(--bad-soft); color: var(--bad); }
.words { margin: 0 0 6px; font-family: var(--serif); font-size: 21px; line-height: 1.7; overflow-wrap: anywhere; }
.words .w { padding: 1px 6px; border-radius: 8px; }
.words .w.ok { background: var(--good-soft); color: var(--good); }
.words .w.no { background: var(--bad-soft); color: var(--bad); text-decoration: underline wavy; text-underline-offset: 4px; }
.words .w.stress, .words .w.near { background: var(--warn-soft); color: var(--warn); }
/* Japanese words marked by reading: each word as written (with furigana), its reading under it mora by mora. */
.speak-result .words { display: flex; flex-wrap: wrap; gap: 6px 4px; align-items: flex-end; line-height: 1.4; }
.words .w:has(.w-ja) { display: inline-grid; justify-items: center; gap: 2px; padding: 4px 6px 3px; }
.words .w.punct { padding: 4px 0; background: none; color: var(--mute); }
.words .w-ja { font-size: 22px; }
.words .w-ja rt { font-size: 14px; color: var(--mute); }
.words .w-kana { display: flex; gap: 1px; font-family: var(--font); font-size: 14px; letter-spacing: .02em; }
.words .w-kana .m { font-style: normal; padding: 0 1px; border-radius: 4px; }
.words .w-kana .m.ok { color: var(--good); }
.words .w-kana .m.near { background: var(--warn); color: var(--panel); }
.words .w-kana .m.no { background: var(--bad); color: var(--panel); }
.words .w.no { text-decoration: none; }
.words .w.no .w-ja { text-decoration: underline wavy; text-underline-offset: 5px; }
.speak-result .heard-kana { color: var(--faint); }
.say-ja rt, .q rt, .shadow-ja rt { font-size: max(14px, .42em); }
.q-show { margin: -4px 0 12px; font-size: 18px; color: var(--mute); overflow-wrap: anywhere; }
.speak-hear .sp-shadow-it { min-height: 44px; }
.speak-result .heard { margin: 0; overflow-wrap: anywhere; }
.speak-result .tip { font-weight: 600; margin: 12px 0; }
.speak-done { text-align: center; padding: 24px 8px 10px; }
.speak-done .row { justify-content: center; }
.speak-side .needs .es { font-weight: 600; }
.speak-keys { margin: 14px 0 0; }
.badge.good { background: var(--good-soft); color: var(--good); }

/* The speaking session */
.speak-session h2 { margin: 0; }
.session-intro { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); gap: 20px 34px; align-items: center; }
.session-intro h2 { margin-bottom: 8px; }
.session-steps { list-style: none; counter-reset: step; margin: 0; padding: 0; display: grid; gap: 10px; }
.session-steps li { counter-increment: step; display: grid; grid-template-columns: 34px minmax(0, 1fr); column-gap: 12px; align-items: start; padding: 12px 14px; border-radius: var(--r-sm); background: var(--sunk); }
.session-steps li::before { content: counter(step); grid-row: span 2; display: grid; place-items: center; width: 30px; height: 30px; border-radius: 50%; background: var(--accent-soft); color: var(--accent); font-weight: 700; }
.session-steps span { color: var(--mute); font-size: 14px; }
.speak-session > p { max-width: 70ch; }
.speak-session .progressline { margin: 12px 0 4px; }
.speak-q { padding: 16px 0 0; }
.speak-q .q-lead { margin: 0 0 4px; font-weight: 600; }
.speak-q .q { font-size: clamp(22px, 4.2vw, 30px); line-height: 1.3; margin: 0 0 12px; overflow-wrap: anywhere; }
.speak-answer { display: grid; gap: 10px; margin-top: 10px; }
.speak-answer .you { margin: 0; padding: 12px 14px; border-radius: 14px; background: var(--accent-soft); overflow-wrap: anywhere; }
.lola-says { padding: 12px 14px; border-radius: 14px; background: var(--sunk); overflow-wrap: anywhere; }
.lola-says p { margin: 0; }
.lola-says .fix, .fixline { color: var(--accent-2); font-weight: 600; }
.lola-says .fix { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line2); }
.speak-summary { scroll-margin-top: 0; }   /* the page's scroll-padding (app.css) already clears the bar */
.speak-summary .grid { margin: 8px 0 16px; }
.speak-summary h3 { margin-top: 8px; }
.speak-summary .answers { margin-bottom: 16px; }
.speak-summary .answers small + small { margin-top: 2px; }

/* Lola's talk mode, in her chat */
.chat-head .talk-btn { min-height: 40px; padding: 0 12px; gap: 6px; font-size: 14px; }
.chat-head .talk-btn svg { width: 18px; height: 18px; }
.chat-head .talk-btn.on { background: var(--bad-soft); color: var(--bad); }
.talkbar { display: flex; gap: 10px; align-items: center; padding: 10px 10px 10px 14px; border-top: 1px solid var(--line); }
.talkbar[hidden] { display: none; }
.talk-lvl { display: flex; gap: 3px; align-items: center; height: 26px; flex: none; }
.talk-lvl i { width: 4px; height: 22px; border-radius: 2px; background: var(--accent); transform: scaleY(.15); transition: transform .06s linear; }
.tutor[data-talk=speaking] .talk-lvl i, .tutor[data-talk=thinking] .talk-lvl i, .tutor[data-talk=hearing] .talk-lvl i { background: var(--faint); }
.talk-state { font-weight: 600; font-size: 14.5px; }
.chat .msg.note a { color: var(--accent); font-weight: 600; }

@media (max-width: 900px) { .session-intro { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 720px) {
  /* Her chat sheet sits in its own layer above the dimmed page, so what is drawn on top is what a
     contrast check measures. */
  .tutor.open .chat { position: relative; z-index: 1; }
  .speak-stats { justify-content: flex-start; }
  .speak-morelist { grid-template-columns: minmax(0, 1fr); }
  .mic-big { width: 80px; height: 80px; }
  .result-top { gap: 12px; }
  .result-top .score { min-width: 70px; }
  .result-top .score b { font-size: 28px; }
  .words { font-size: 19px; }
  /* Try again, Shadow it and Next on one row, each word whole: Next takes what is left */
  .speak-result .row { flex-wrap: nowrap; gap: var(--s-2); }
  .speak-result .row > button, .speak-result .row > .btn { flex: 0 0 auto; padding: 0 var(--s-3); white-space: nowrap; }
  .speak-result .row > #sp-next { flex: 1 1 auto; }
  .chat-head .talk-btn { padding: 0 10px; }
}
/* Her chat's head on a narrow phone: "Tu tutora ·" and "Talk live" each stay whole (at most two lines, never
   a word per line), and from 360 px down Hands-free is its microphone alone, 44 px square (its name stays
   for screen readers and the title). */
.chat-head small .nowrap, .chat-head .chat-live { white-space: nowrap; }
@media (max-width: 360px) {
  .chat-head .talk-btn { width: 44px; height: 44px; min-height: 44px; padding: 0; flex: none; }
  .chat-head .talk-btn span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
}
/* Speak on a phone, upright or sideways: the microphone on the first screen. The ways in are one short row
   of pills; the numbers sit with Words to work on; the card and the microphone sit closer together; the Talk
   live card comes after Say it (speak.js moves it, and uses this same query). */
@media (max-width: 720px), (orientation: landscape) and (max-height: 500px) {
  .speak .pagehead { margin-bottom: 12px; }
  .speak .pagehead > div:first-child p { margin-top: 2px; }
  .pagehead .speak-stats { display: none; }
  .speak-side .side-stats { display: flex; margin: 0 0 10px; }
  .speak-ways { margin: var(--s-3) 0 14px; }
  .speak-main { padding-top: 14px; }
  .speak-card { padding: 12px 4px 4px; }
  .say-dock { gap: 10px; margin-top: 10px; }
  .mic-zone { padding: 2px 0 4px; gap: 6px; }
}
/* The smallest phones (320 wide) and short screens: the heading alone, Hear it and Hear it slowly on one
   row, a slightly smaller microphone. */
@media (max-width: 340px), (max-height: 600px) and (max-width: 720px), (orientation: landscape) and (max-height: 500px) {
  .speak .pagehead > div:first-child p { display: none; }
  .speak-top { margin-bottom: 4px; }
  .speak-hear { flex-wrap: nowrap; gap: 8px; }
  .speak-hear button { padding: 0 12px; }
  .say-es { font-size: 24px; }
  .say-es.say-short { font-size: 40px; }
  .say-es.say-mid { font-size: 28px; }
  .say-es.say-long { font-size: 22px; }
  .speak-card { gap: 2px; }
  .mic-big { width: 72px; height: 72px; }
  .mic-big svg { width: 32px; height: 32px; }
  .mic-mute { width: 56px; height: 56px; }
}
/* Sideways: the heading and the ways in on one line, the card on the left with the microphone beside it,
   and the session's start beside its steps. (560 px wide or more: not an upright phone with the keyboard up.) */
@media (orientation: landscape) and (max-height: 500px) and (min-width: 560px) {
  .speak { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 18px; align-items: center; }
  .speak > :not(.pagehead) { grid-column: 1 / -1; }
  .speak .pagehead { margin-bottom: 12px; }
  .session-intro { grid-template-columns: minmax(0, 1fr); gap: 10px; padding: 14px 18px; }
  .session-intro h2 { margin-bottom: 4px; }
  .session-intro p { margin: 0 0 6px; }
  .session-steps { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
  .session-steps li { padding: 8px 10px; }
  #sp-say:has(> .say-dock) { display: grid; grid-template-columns: minmax(0, 1fr) minmax(250px, 300px); column-gap: 16px; align-items: center; }
  #sp-say > .say-dock { margin-top: 0; gap: 8px; }
  #sp-say > .speak-result { grid-column: 1 / -1; }
  .speak-q + .say-dock { margin-top: 4px; }
}
@media (prefers-reduced-motion: reduce) { .mic-big .ring { transition: none; } }

/* Shadowing: the title with its level chip; every sentence as one row that opens a sheet; How it works a fold */
.sh-titlerow { display: flex; align-items: center; flex-wrap: wrap; gap: var(--s-2) var(--s-3); }
.sh-titlerow h1 { margin: 0; }
.shadow-grid { align-items: start; }
.shadow-top { margin-bottom: var(--s-2); gap: var(--s-2); justify-content: flex-end; min-height: 1.5em; }
.shadow-side { min-width: 0; }
.shadow-all { margin: 0; }
.sh-allrow { display: flex; align-items: center; gap: var(--s-3); width: 100%; min-height: 56px; padding: var(--s-2) 2px; border: 0; border-radius: var(--r-1); background: none; color: var(--ink); text-align: left; font-weight: 400; white-space: normal; }
@media (hover: hover) { .sh-allrow:hover { background: var(--surface-2); } }
.sh-allrow .main { flex: 1; min-width: 0; }
.sh-allrow .main b { display: block; font-size: var(--fs-16); }
.sh-allrow .main small { display: block; color: var(--ink-3); font-size: var(--fs-14); }
.sh-allrow svg { width: 20px; height: 20px; color: var(--ink-3); flex: none; }
.shadow-how { margin-top: var(--s-2); }
.shadow-card { text-align: center; padding: 22px 8px 4px; display: grid; justify-items: center; gap: 4px; }
.shadow-ja { font-family: var(--serif); font-size: clamp(24px, 4.6vw, 36px); line-height: 1.5; margin: 0; overflow-wrap: anywhere; max-width: 100%; }
.shadow-hear { justify-content: center; align-items: stretch; }
/* Previous by the count at the card's top; Next, a circle to the microphone's right (the call row's) */
.shadow-top { align-items: center; }
.sh-prev { display: inline-flex; align-items: center; gap: var(--s-1); min-height: var(--tap); padding: 0 var(--s-2) 0 0; text-decoration: none; font-weight: 600; }
.sh-prev svg { width: 20px; height: 20px; flex: none; }
/* Listen and Slower: one pair, one height, the icon on the label's line (never wrapped over it) */
.page .shadow-hear > button:not(.icon), .page .speak-hear > :is(#sp-hear, #sp-slow) { flex-wrap: nowrap; gap: var(--s-2); }
.pitch-figure { margin: 10px 0 0; padding: 12px 12px 10px; border-radius: var(--r); background: var(--sunk); min-width: 0; }
.pitch-figure[hidden] { display: none; }
.pitch-scroll { overflow-x: auto; overflow-y: hidden; max-width: 100%; -webkit-overflow-scrolling: touch; }
.pitch-legend { display: flex; gap: 16px; justify-content: flex-end; font-size: 14px; font-weight: 600; color: var(--mute); margin-bottom: 4px; }
.pitch-legend span::before { content: ""; display: inline-block; width: 18px; height: 4px; border-radius: 2px; margin-right: 6px; vertical-align: middle; }
.pitch-legend .key-native::before { background: var(--accent); }
.pitch-legend .key-you::before { background: var(--accent-2); }
.pitch-figure.only-you .key-native { opacity: .45; }
.pitch-lines { display: block; max-width: none; }
.pitch-lines .pl-native, .pitch-lines .pl-learner { fill: none; stroke-width: 4; stroke-linecap: round; stroke-linejoin: round; }
.pitch-lines .pl-native { stroke: var(--accent); }
.pitch-lines .pl-learner { stroke: var(--accent-2); stroke-dasharray: 1 0; }
.pitch-lines .pl-mid { stroke: var(--line2); stroke-width: 1; stroke-dasharray: 4 4; }
.pitch-lines .pl-tick { stroke: var(--line); stroke-width: 1; }
.pitch-lines .pl-kana { fill: var(--fg); font-family: var(--font); }
.pitch-word { margin: 8px 2px 0; font-weight: 600; overflow-wrap: anywhere; }
.shadow-words { margin-top: 14px; }
.shadow-words h3 { margin: 0 0 6px; font-size: var(--fs-16); }
/* each word a row of its own: the word at 18 px, its pitch line under it, drawn large enough to read */
.pa-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s-3); }
.pa-list li { display: grid; justify-items: start; gap: var(--s-1); padding-top: var(--s-2); border-top: 1px solid var(--line); min-width: 0; }
.pa-list li:first-child { border-top: 0; padding-top: 0; }
/* one word: the heading names it, so the drawing stands alone */
.pa-list.one li { padding-top: var(--s-1); }
.pa-w { font-family: var(--serif); font-size: var(--fs-18); font-weight: 700; }
.pa-draw { max-width: 100%; overflow-x: auto; }
.pa-draw svg { display: block; }
/* the words after the first two wait under "All the words (n)", so the sentence and its card clear the dock */
.sh-words-more { margin-top: var(--s-2); }
.sh-words-more > .pa-list { margin-top: var(--s-2); }
.sh-words-more > .pa-list li:first-child { border-top: 1px solid var(--line); padding-top: var(--s-2); }
.shadow-steps { list-style: none; counter-reset: step; margin: 0 0 12px; padding: 0; display: grid; gap: 8px; }
.shadow-steps li { counter-increment: step; display: grid; grid-template-columns: 30px minmax(0, 1fr); column-gap: 10px; padding: 10px 12px; border-radius: var(--r-sm); background: var(--sunk); }
.shadow-steps li::before { content: counter(step); grid-row: span 2; display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; background: var(--accent-soft); color: var(--accent); font-weight: 700; }
.shadow-steps span { color: var(--mute); font-size: 14px; }
.shadow-list { margin: 0; }
.shadow-pick { display: grid; gap: 2px; min-height: 44px; padding: 6px 4px; color: var(--fg); text-decoration: none; overflow-wrap: anywhere; }
.shadow-pick[aria-current=true] { color: var(--accent); font-weight: 600; }
.shadow-pick small { color: var(--mute); font-size: 14px; }
@media (max-width: 720px) {
  .shadow .pagehead .btn { display: none; }
  .shadow-card { padding-top: 4px; }
  .shadow-hear button { flex: 1 1 0; }
}
/* A phone held sideways: the sentence on the left, its sound buttons, Mute, the microphone and Next on the right, so
   all of it is on the first screen (as Speak's card is). */
@media (orientation: landscape) and (max-height: 500px) and (min-width: 560px) {
  .shadow .pagehead > div:first-child > p { display: none; }
  #sh-stage { display: grid; grid-template-columns: minmax(0, 1fr) minmax(260px, 320px); column-gap: var(--s-4); align-items: center; }
  #sh-stage > .say-dock { grid-column: 2; grid-row: 1; margin-top: 0; gap: var(--s-2); }
  #sh-stage > :not(.shadow-card, .say-dock) { grid-column: 1 / -1; }
  #sh-stage .shadow-card { padding-top: 0; }
}

/* ---- the dock (an upright phone): Play and Slowly (or Hear it again and Skip), then Mute | the microphone | Next,
   then what the microphone is doing, one full-width bar at the foot, above the tab bar (on the home indicator in a
   session), under the thumb, as Talk live's controls are. The page leaves the dock's height free at its foot
   (--say-dock-h, set by speak.js and shadow.js), and whatever is brought into sight clears it. ---- */
@media (max-width: 720px) and (min-height: 501px) {
  .say-dock { position: fixed; z-index: 6; left: 0; right: 0; bottom: var(--dock-at, 0px); margin: 0; gap: var(--s-2);
    padding: var(--s-2) max(var(--s-4), env(safe-area-inset-right)) calc(var(--s-2) + var(--dock-pad, 0px)) max(var(--s-4), env(safe-area-inset-left));
    background: var(--surface); border-top: 1px solid var(--line); }
  .say-dock :is(.speak-hear, .shadow-hear) { flex-wrap: nowrap; gap: var(--s-2); margin: 0; }
  .say-dock :is(.speak-hear, .shadow-hear) > button { flex: 1 1 0; min-width: 0; padding: 0 var(--s-2); }
  .say-dock .mic-zone { padding: 0; gap: var(--s-1); }
  .say-dock .mic-big { width: 72px; height: 72px; }
  .say-dock .mic-big svg { width: 32px; height: 32px; }
  .say-dock .mic-hint { font-size: var(--fs-14); line-height: 1.35; min-height: 0; }
  /* the dock's Skip says Next once there is a result: the one Next on the screen, under the thumb */
  .say-dock ~ .speak-result #sp-next, .say-dock ~ .speak-answer #sp-nextq { display: none; }
  .say-dock .speak-err { margin: 0; padding: 6px 10px; }
  /* with no connection the site's note sits over the tab bar (app.css): the dock rises above it */
  body:has(> .offline-note) .say-dock { bottom: calc(var(--dock-at, 0px) + 48px); }
  #main.page:has(.say-dock) { padding-bottom: calc(var(--dock-at, 0px) + var(--say-dock-h, 200px) + var(--s-4)); }
  html:has(#main .say-dock) { scroll-padding-bottom: calc(var(--dock-at, 0px) + var(--say-dock-h, 200px) + var(--s-2)); }
}
/* A short upright phone (an SE): a tighter dock, so the sentence keeps the room above it; Shadowing's line under its
   title waits, as Speak's does. */
@media (max-width: 720px) and (min-height: 501px) and (max-height: 700px) {
  .say-dock { gap: 6px; padding-top: 6px; padding-bottom: calc(6px + var(--dock-pad, 0px)); }
  .say-dock .mic-big { width: 64px; height: 64px; }
  .say-dock .mic-big svg { width: 28px; height: 28px; }
  .say-dock :is(.mic-mute, .mic-side) { width: 52px; height: 52px; }
  .say-dock .mic-row { padding-bottom: 20px; }
  .shadow .pagehead > div:first-child > p { display: none; }
  .shadow .pagehead { margin-bottom: var(--s-3); }
}

/* A word's pitch accent (pitch-accent.js): a line over the kana, high and low per mora, the particle after the
   word faint. */
.pa { display: inline-block; vertical-align: middle; overflow: visible; }
.pa .pa-line, .pa .pa-tail { fill: none; stroke: var(--accent); stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.pa .pa-tail { stroke-dasharray: 3 3; opacity: .7; }
.pa .pa-dot { fill: var(--accent); }
.pa .pa-dot.pa-part { fill: var(--panel); stroke: var(--accent); stroke-width: 1.6; }
.pa .pa-kana { fill: var(--fg); font-family: var(--font); }
.pa .pa-kana.pa-part { fill: var(--mute); }

/* Your Spanish: the kinds of Spanish and the levels as large cards, Lola's voices as rows with a sample each
   (Settings), and the same question on Today until it is answered. */
.vset { border: 0; padding: 0; margin: 18px 0 0; min-width: 0; }
.vset legend { padding: 0; margin-bottom: 8px; font-weight: 700; font-size: 15.5px; }
.vgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 240px), 1fr)); gap: 10px; }
.vgrid.three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.vcard { position: relative; display: flex; gap: 12px; align-items: flex-start; justify-content: flex-start; min-height: 64px; height: auto; padding: 12px 14px;
  border-radius: 14px; border: 1.5px solid var(--line2); background: var(--panel); color: var(--fg); text-align: left; white-space: normal; font: inherit; cursor: pointer; }
.vcard:hover { border-color: var(--faint); }
.vcard input { width: 20px; height: 20px; margin: 1px 0 0; flex: none; accent-color: var(--accent); }
.vcard:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }
.vcard:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
.vcard input:focus-visible { outline: none; }
.vtext { display: grid; gap: 2px; min-width: 0; }
.vtext b { font-size: 16px; line-height: 1.25; }
.vtext small { color: var(--mute); font-size: 14px; font-weight: 500; line-height: 1.35; overflow-wrap: anywhere; }
.vcard.small { min-height: 0; }
.vlist { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.vrow { display: flex; align-items: center; gap: 10px; padding: 4px 6px 4px 12px; border: 1.5px solid var(--line); border-radius: 14px; background: var(--panel); }
.vrow:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }
.vrow:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
.vpick { flex: 1; min-width: 0; display: flex; align-items: center; gap: 10px; min-height: 48px; cursor: pointer; font-weight: 600; overflow-wrap: anywhere; }
.vpick input { width: 20px; height: 20px; margin: 0; flex: none; accent-color: var(--accent); }
.vpick input:focus-visible { outline: none; }
.vrow .chip { flex: none; }
.play { width: 44px; height: 44px; min-height: 44px; padding: 0; border-radius: 50%; flex: none; }
.play svg { width: 18px; height: 18px; }
.play.playing { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
#sp-about { margin: 12px 0 0; }
#sp-heard:empty { display: none; }
#sp-heard { margin: 8px 0 0; }
.firstrun { margin-top: 18px; }
.firstrun > p { max-width: 70ch; }
.fr-level { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 4px 0 14px; }
.fr-label { font-weight: 700; }
.firstrun .seg button { min-height: 44px; }
.fr-unsure { margin-top: 10px; }
.fr-unsure button { min-height: 44px; }
/* On a narrow phone the three levels are one row of equal cells under their label, never a wrapped pill; on
   the narrowest (320 px) "Intermediate" does not fit a third, so they are three rows. */
@media (max-width: 420px) {
  .fr-level { display: grid; gap: 6px; }
  .fr-level .seg { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); width: 100%; border-radius: 14px; }
  .fr-level .seg button { padding: 0 6px; border-radius: 11px; }
}
@media (max-width: 340px) { .fr-level .seg { grid-template-columns: minmax(0, 1fr); } }
.hero .talk-live { min-height: 44px; padding: 0 14px; color: var(--accent); }
.chat-head .chat-live { display: inline-block; padding: 13px 2px; margin: -13px -2px; font-weight: 600; color: var(--accent); }

@media (max-width: 720px) {
  .vgrid.three { grid-template-columns: minmax(0, 1fr); }
  .vcard { min-height: 0; padding: 10px 12px; }
  .vtext b { font-size: 15.5px; }
}
