/* Home-page widgets: app screens and cards rebuilt in HTML from the app's
   own data, in place of screenshots (Ean, 2026-10-15). Linked from
   index.html only; the shared design system stays in styles.css.

   UNITS. Every widget is sized in --u, one app point, so a number lifted
   from the SwiftUI source (padding 16, font 20, corner 18) goes in as-is.

   On a stage, --u is the stage width over the widget's design width,
   capped so it never draws larger than it reads well.

   MOTION. A [data-widget] gets .anim-wait from the script in index.html
   only when it is below the fold, motion is allowed and the observer
   exists; .is-live follows when it scrolls into view, once. Entrances use
   animation-fill-mode: backwards, so a piece is held at its start frame
   only until its delay ends and then lets go of its styles: a word that
   has landed still presses like a button. With no script, reduced motion,
   or a widget already scrolled past, nothing is hidden and nothing moves. */

@keyframes w-pop      { from { opacity: 0; transform: scale(0.9); } }
@keyframes w-slide-in { from { opacity: 0; transform: translateX(calc(var(--u) * 12)); } }
@keyframes w-draw     { from { stroke-dashoffset: 1; } }

/* ---------- Stage ----------
   A widget sits straight on its tinted panel, no phone around it (Ean,
   2026-10-15: "they dont have to be bound by a phone frame anymore").
   The stage is the container the widget's --u resolves against. */
.hf-shot.hf-widget { align-items: center; }

.w-stage {
  container-type: inline-size;
  width: 100%;
  display: flex;
  justify-content: center;
  padding: 0 24px;
  color: #1A1A2E;
  text-align: left;
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, sans-serif;
}

/* :where() keeps this reset at zero specificity, so a widget's own colour
   wins: as a plain `.w-stage button` it outranked `.rf-form { color: #fff }`
   and turned the root of each form dark on the purple tile. */
.w-stage :where(button) {
  font: inherit;
  text-align: inherit;
  color: inherit;
  border: 0;
  margin: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* Display only, except sound (Ean, 2026-10-16: "let viewer tap the buttons
   with sounds"): a stage takes no pointer, a button with a clip does. A
   quiz tile already moved into its slot is a placeholder, so it is silent.
   The index script takes every other button out of the tab order. */
.w-stage { pointer-events: none; }
.w-stage [data-audio] { pointer-events: auto; }
.w-stage .qz-tile.used { pointer-events: none; }

/* ---------- Root family (V2RootFamilyView) ----------
   The root on the left, its forms in a column on the right, 44pt apart,
   forms 14pt apart, a dashed S-curve from the root to each form. Each
   form is 64pt plus its 3pt edge, so the lines' viewBox (44 x 229) is
   exact: centres at 32, 113 and 194, the root's at 113. */
/* 308pt wide (105 + 44 + 159); the 340 leaves a margin either side. */
.rf {
  --u: min(1.25px, calc(100cqw / 340));
  display: flex;
  align-items: center;
  justify-content: center;
}

.rf-speaker { flex: none; fill: currentColor; }

.rf-root {
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 8);
  margin-bottom: calc(var(--u) * 3);
  padding: calc(var(--u) * 10) calc(var(--u) * 18);
  border-radius: calc(var(--u) * 16);
  background: #fff;
  box-shadow: inset 0 0 0 calc(var(--u) * 1.5) #E5E7EB, 0 calc(var(--u) * 3) 0 #E5E7EB;
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.rf-root .rf-speaker { width: calc(var(--u) * 19); height: calc(var(--u) * 19); color: #5B48E0; }

.rf-text { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.15; }
.rf-root .rf-text { align-items: center; }

.rf-word {
  font-family: 'Nunito', system-ui, sans-serif;
  font-size: calc(var(--u) * 22);
  font-weight: 900;
  white-space: nowrap;
}

.rf-gloss {
  margin-top: calc(var(--u) * 2);
  font-family: 'Nunito', system-ui, sans-serif;
  font-size: calc(var(--u) * 13);
  font-weight: 600;
  color: #6B7280;
  white-space: nowrap;
}

.rf-lines { flex: none; width: calc(var(--u) * 44); height: calc(var(--u) * 229); overflow: visible; }

.rf-line { fill: none; stroke: #C4B8F8; stroke-width: 2; stroke-linecap: round; stroke-dasharray: 6 5; }

/* The mask's own stroke, drawn 0 to 1 along the path; the dashes show
   only where it has reached, which is SwiftUI's .trim on a dashed line. */
.rf-reveal { fill: none; stroke: #fff; stroke-width: 6; stroke-dasharray: 1 1; }

.rf-forms { display: flex; flex-direction: column; align-items: flex-start; gap: calc(var(--u) * 14); }

.rf-form {
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 10);
  height: calc(var(--u) * 64);
  margin-bottom: calc(var(--u) * 3);
  padding: 0 calc(var(--u) * 16);
  border-radius: calc(var(--u) * 18);
  background: linear-gradient(135deg, #7C64F0, #5B48E0);
  box-shadow: 0 calc(var(--u) * 3) 0 #3D2BA8;
  color: #fff;
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.rf-form .rf-speaker { width: calc(var(--u) * 21); height: calc(var(--u) * 21); }
.rf-form .rf-word { font-size: calc(var(--u) * 20); font-weight: 800; }
.rf-form .rf-word b { color: #F5A100; font-weight: inherit; }
.rf-form .rf-gloss { color: rgba(255, 255, 255, 0.8); font-weight: 500; }

/* The app's press: the face drops onto its edge. */
.rf-form:active, .rf-form.playing { transform: translateY(calc(var(--u) * 3)); box-shadow: 0 0 0 #3D2BA8; }
.rf-root:active, .rf-root.playing {
  transform: translateY(calc(var(--u) * 3));
  box-shadow: inset 0 0 0 calc(var(--u) * 1.5) #E5E7EB, 0 0 0 #E5E7EB;
}

/* The app's timing: the root in 0.7s, then each line (0.6s) and its form
   (0.7s) together, 0.8s apart, top to bottom. */
.anim-wait:not(.is-live) .rf-root,
.anim-wait:not(.is-live) .rf-form { opacity: 0; }
.anim-wait:not(.is-live) .rf-reveal { stroke-dashoffset: 1; }

.is-live .rf-root { animation: w-pop 0.7s ease-out backwards; }
.is-live .rf-form { animation: w-slide-in 0.7s ease-out backwards; }
.is-live .rf-reveal { animation: w-draw 0.6s ease-out backwards; }
.is-live .rf-form:nth-child(1), .is-live mask:nth-of-type(1) .rf-reveal { animation-delay: 0.8s; }
.is-live .rf-form:nth-child(2), .is-live mask:nth-of-type(2) .rf-reveal { animation-delay: 1.6s; }
.is-live .rf-form:nth-child(3), .is-live mask:nth-of-type(3) .rf-reveal { animation-delay: 2.4s; }

/* ---------- Feature card grid ----------
   Eleven cards in three columns left a hole in the last row. Quizzes spans
   two, which makes twelve cells: four full rows at three columns and six
   at two. `dense` lets Recall fill the cell beside Hear every word at two
   columns instead of leaving it empty above the wide card. One column on
   a phone, where a span of two would invent a second column. */
.cards { grid-auto-flow: row dense; }
.card.card-wide { grid-column: span 2; }

@media (max-width: 720px) {
  .card.card-wide { grid-column: auto; }
}

/* A widget card: the tinted panel stays, the phone goes. */
.card-frame.w-frame { align-items: center; justify-content: center; }
.card-frame.w-frame .w-stage { padding: 0 20px; }

/* ---------- Card widgets: shared ----------
   Designed 300pt wide, the width of the app's content column, so a
   card's panel (about 309px of stage on desktop) shows them near 1:1. */
@keyframes w-fade  { from { opacity: 0; } }
@keyframes w-drop  { from { opacity: 0; transform: translateY(calc(var(--u) * -8)); } }
@keyframes w-lift  { from { opacity: 0; transform: translateY(calc(var(--u) * 12)); } }
@keyframes w-rise  { from { transform: scaleY(0); } }

.sk, .lb, .ins, .idc {
  --u: min(1.1px, calc(100cqw / 300));
  width: calc(var(--u) * 300);
}

/* The tier headline at the top of an Insight page (InsightHeroBanner).
   "A HEADLINE, NOT A BANNER (2026-10-11)": the glyph in a circle of the
   tier's colour at 14%, the words straight on the page. */
.w-banner { display: flex; align-items: center; gap: calc(var(--u) * 12); }

.w-banner-badge {
  flex: none;
  width: calc(var(--u) * 46);
  height: calc(var(--u) * 46);
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  display: grid;
  place-items: center;
}

.w-banner-badge svg { width: calc(var(--u) * 21); height: calc(var(--u) * 21); fill: var(--accent); }
.w-banner-text { display: flex; flex-direction: column; gap: calc(var(--u) * 2); line-height: 1.2; }
.w-banner-text b { font-family: 'Nunito', system-ui, sans-serif; font-size: calc(var(--u) * 18); font-weight: 900; color: #1A1A2E; }
.w-banner-text span { font-family: 'Nunito', system-ui, sans-serif; font-size: calc(var(--u) * 12.5); font-weight: 600; color: #6B7280; }

.w-card {
  margin-top: calc(var(--u) * 10);
  background: #fff;
  border: 1px solid #ECEAF2;
  border-radius: calc(var(--u) * 18);
}

/* ---------- Streak (StreakView: milestone banner over the month) ---------- */
.sk-banner { --accent: #BE185D; }   /* "Two months deep": #DB2777 to #BE185D, the deeper stop */
.sk-cal { padding: calc(var(--u) * 10) calc(var(--u) * 12) calc(var(--u) * 12); }

.sk-month {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: calc(var(--u) * 6);
  font-size: calc(var(--u) * 11);
  font-weight: 800;
  letter-spacing: 0.08em;
}

.sk-month i { font-style: normal; font-size: calc(var(--u) * 17); line-height: 1; color: #6B7280; }
.sk-month i.off { color: #D1D5DB; }

.sk-dow, .sk-days { display: grid; grid-template-columns: repeat(7, 1fr); }
.sk-dow { margin-bottom: calc(var(--u) * 4); font-size: calc(var(--u) * 9); font-weight: 600; color: #6B7280; text-align: center; }
.sk-days { gap: calc(var(--u) * 3); }

.sk-days span {
  height: calc(var(--u) * 22);
  border-radius: calc(var(--u) * 7);
  display: grid;
  place-items: center;
  background: #F2F0EC;
  color: #BDB7AE;
  font-size: calc(var(--u) * 10.5);
  font-weight: 700;
}

.sk-days .blank { background: none; }
.sk-days .on { background: #FF9D2B; color: #fff; }
.sk-days .on.mid { background: #FFB46A; }
.sk-days .today { box-shadow: inset 0 0 0 calc(var(--u) * 1.5) #F5880A; }

@keyframes w-day { from { background: #F2F0EC; color: #BDB7AE; transform: scale(0.85); } }

.anim-wait:not(.is-live) .sk-banner { opacity: 0; }
.anim-wait:not(.is-live) .sk-days .on { background: #F2F0EC; color: #BDB7AE; }
.is-live .sk-banner { animation: w-drop 0.5s ease-out backwards; }
.is-live .sk-days .on { animation: w-day 0.35s ease-out backwards; animation-delay: calc(0.45s + var(--i) * 70ms); }

/* ---------- Leaderboard (podium, then your row) ---------- */
.lb-tabs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  padding: calc(var(--u) * 3);
  border-radius: 999px;
  background: #fff;
  border: 1px solid #E5E7EB;
}

.lb-tab {
  height: calc(var(--u) * 26);
  text-align: center;
  border-radius: 999px;
  background: transparent;
  color: #6B7280;
  font-size: calc(var(--u) * 12);
  font-weight: 700;
  transition: background 0.2s ease, color 0.2s ease;
}

.lb-tab[aria-pressed="true"] { background: #5B48E0; color: #fff; }
.lb-tab:focus-visible { outline: 2px solid #A99BFF; outline-offset: 2px; }

.lb-podium {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  align-items: end;
  gap: calc(var(--u) * 4);
  margin-top: calc(var(--u) * 10);
}

.lb-place { display: flex; flex-direction: column; align-items: center; text-align: center; min-width: 0; }

.lb-av {
  flex: none;
  width: calc(var(--u) * 34);
  height: calc(var(--u) * 34);
  border-radius: 50%;
  background: #5B48E0;
  display: grid;
  place-items: end center;
  overflow: hidden;
}

.lb-av img { width: 88%; height: 88%; object-fit: contain; }
.p1 .lb-av { width: calc(var(--u) * 44); height: calc(var(--u) * 44); }

.lb-name { margin-top: calc(var(--u) * 4); font-size: calc(var(--u) * 10.5); font-weight: 800; white-space: nowrap; }
.lb-xp { font-size: calc(var(--u) * 8.5); font-weight: 700; color: #6B7280; white-space: nowrap; }
.lb-n { font-size: calc(var(--u) * 12); font-weight: 800; color: #1A1A2E; }

.lb-block {
  width: 100%;
  margin-top: calc(var(--u) * 5);
  border-radius: calc(var(--u) * 10) calc(var(--u) * 10) calc(var(--u) * 4) calc(var(--u) * 4);
  display: grid;
  place-items: center;
  font-family: 'Nunito', system-ui, sans-serif;
  font-size: calc(var(--u) * 22);
  font-weight: 900;
  color: rgba(26, 26, 46, 0.3);
  transform-origin: 50% 100%;
}

.p1 .lb-block { height: calc(var(--u) * 62); background: linear-gradient(#D9A21A, #FBE7A1); }
.p2 .lb-block { height: calc(var(--u) * 46); background: linear-gradient(#8C929C, #E6E8EC); }
.p3 .lb-block { height: calc(var(--u) * 36); background: linear-gradient(#8B5A2B, #E3AE7E); }

.lb-rows {
  display: grid;
  grid-template-columns: calc(var(--u) * 12) 1fr;
  align-items: center;
  column-gap: calc(var(--u) * 6);
  row-gap: calc(var(--u) * 5);
  margin-top: calc(var(--u) * 8);
}

.lb-rank { font-size: calc(var(--u) * 11); font-weight: 800; color: #6B7280; text-align: center; }

.lb-row {
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 8);
  height: calc(var(--u) * 36);
  padding: 0 calc(var(--u) * 10);
  border-radius: calc(var(--u) * 12);
  background: #fff;
  border: 1px solid #E5E7EB;
}

.lb-row .lb-av { width: calc(var(--u) * 24); height: calc(var(--u) * 24); }
.lb-who { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.15; }
.lb-who b { font-size: calc(var(--u) * 11.5); font-weight: 800; }
.lb-who small { font-size: calc(var(--u) * 9); color: #6B7280; }
.lb-row-xp { font-size: calc(var(--u) * 11); font-weight: 800; white-space: nowrap; }
.lb-row.me { background: #EEE9FF; border-color: #A99BFF; }
.lb-row.me .lb-row-xp { color: #5B48E0; }

/* The overtake: your row starts one place down and swaps up past the row
   above it, once the podium has risen. The ranks stay put. */
@keyframes w-row-up   { from { transform: translateY(calc(var(--u) * 41)); } }
@keyframes w-row-down { from { transform: translateY(calc(var(--u) * -41)); } }

.anim-wait:not(.is-live) .lb-block { transform: scaleY(0); }
.anim-wait:not(.is-live) .lb-row.me { transform: translateY(calc(var(--u) * 41)); }
.anim-wait:not(.is-live) .lb-row.other { transform: translateY(calc(var(--u) * -41)); }
.is-live .lb-block, .lb-replay .lb-block { animation: w-rise 0.6s cubic-bezier(0.2, 0.8, 0.2, 1) backwards; }
.is-live .p2 .lb-block, .lb-replay .p2 .lb-block { animation-delay: 0.1s; }
.is-live .p1 .lb-block, .lb-replay .p1 .lb-block { animation-delay: 0.25s; }
.is-live .p3 .lb-block, .lb-replay .p3 .lb-block { animation-delay: 0.4s; }
.is-live .lb-av { animation: w-pop 0.5s ease-out 0.5s backwards; }
.is-live .lb-row.me { animation: w-row-up 0.6s cubic-bezier(0.4, 0, 0.2, 1) 1.5s backwards; }
.is-live .lb-row.other { animation: w-row-down 0.6s cubic-bezier(0.4, 0, 0.2, 1) 1.5s backwards; }

/* ---------- Insights (PaceInsight: banner, sentence, minutes chart) ---------- */
.ins-banner { --accent: #7E22CE; }  /* "On a tear": #F5680A to #7E22CE, the deeper stop */
.ins-card { padding: calc(var(--u) * 10) calc(var(--u) * 12) calc(var(--u) * 8); }
.ins-head { display: flex; align-items: center; gap: calc(var(--u) * 6); font-size: calc(var(--u) * 13); }
.ins-head b { font-weight: 700; }

.ins-dot { width: calc(var(--u) * 16); height: calc(var(--u) * 16); border-radius: 50%; background: #FF9D2B; display: grid; place-items: center; }
.ins-dot svg { width: calc(var(--u) * 11); height: calc(var(--u) * 11); fill: none; stroke: #fff; stroke-width: 2.8; stroke-linecap: round; stroke-linejoin: round; }

.ins-line { margin: calc(var(--u) * 5) 0 calc(var(--u) * 7); font-size: calc(var(--u) * 12); line-height: 1.35; }

.ins-plot { position: relative; aspect-ratio: 260 / 100; }
.ins-chart { display: block; width: 100%; height: 100%; overflow: visible; }
.ins-future { fill: #F4F2EE; }
.ins-grid { stroke: #ECE9E4; stroke-width: 0.8; }
.ins-area { fill: url(#insArea); }
.ins-line-path { fill: none; stroke: #FF9D2B; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; stroke-dasharray: 1 1; }
.ins-today { stroke: #9CA3AF; stroke-width: 0.8; stroke-dasharray: 3 3; }
.ins-proj { fill: none; stroke: #B8B2AA; stroke-width: 1.4; stroke-dasharray: 4 3; }

.ins-star {
  position: absolute;
  left: 62.96%;
  top: 23.3%;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
}

.ins-star svg { width: calc(var(--u) * 15); height: calc(var(--u) * 15); fill: #FF9D2B; }

.ins-star em {
  margin-top: calc(var(--u) * 2);
  padding: calc(var(--u) * 1) calc(var(--u) * 6);
  border-radius: 999px;
  background: #FFF1DE;
  color: #F5680A;
  font-size: calc(var(--u) * 8.5);
  font-style: normal;
  font-weight: 700;
}

.ins-axis { display: flex; justify-content: space-between; margin-top: calc(var(--u) * 3); font-size: calc(var(--u) * 9); color: #6B7280; }

.anim-wait:not(.is-live) .ins-banner,
.anim-wait:not(.is-live) .ins-area,
.anim-wait:not(.is-live) .ins-proj,
.anim-wait:not(.is-live) .ins-star { opacity: 0; }
.anim-wait:not(.is-live) .ins-line-path { stroke-dashoffset: 1; }
.is-live .ins-banner { animation: w-drop 0.5s ease-out backwards; }
.is-live .ins-line-path { animation: w-draw 1.3s ease-in-out 0.35s backwards; }
.is-live .ins-area { animation: w-fade 0.6s ease-out 1.3s backwards; }
.is-live .ins-proj { animation: w-fade 0.5s ease-out 1.6s backwards; }
.is-live .ins-star { animation: w-star 0.5s cubic-bezier(0.3, 1.6, 0.5, 1) 1.9s backwards; }
@keyframes w-star { from { opacity: 0; transform: translate(-50%, -50%) scale(0.4); } }

/* ---------- Ube (the counter in the lesson header) ----------
   Two pills, centred, each with its label under it: what a free learner
   sees, and Super's infinity. Sized to fill the panel; the first build
   sat in the top half with the second row hidden until 3.4s, which left
   the panel half empty (Ean, 2026-10-16: "fix any others"). */
.ube {
  --u: min(1.3px, calc(100cqw / 220));
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--u) * 20);
}

.ube-row { display: flex; flex-direction: column; align-items: center; gap: calc(var(--u) * 8); }

.ube-pill {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: calc(var(--u) * 9);
  height: calc(var(--u) * 60);
  padding: 0 calc(var(--u) * 22) 0 calc(var(--u) * 15);
  border-radius: 999px;
  background: #fff;
  box-shadow: 0 calc(var(--u) * 6) calc(var(--u) * 18) rgba(91, 72, 224, 0.14), inset 0 0 0 1px #ECE9F7;
}

.ube-pill img { width: calc(var(--u) * 38); height: calc(var(--u) * 38); }

.ube-count {
  display: block;
  min-width: 1.15em;
  height: calc(var(--u) * 38);
  overflow: hidden;
  font-family: 'Nunito', system-ui, sans-serif;
  font-size: calc(var(--u) * 32);
  font-weight: 900;
  line-height: calc(var(--u) * 38);
  text-align: center;
}

.ube-roll { display: flex; flex-direction: column; }
.ube-count b { display: block; height: calc(var(--u) * 38); font-weight: inherit; }
/* Drawn, not typed: Nunito has no infinity glyph, so the fallback font set
   it thin and off the baseline (Ean, 2026-10-16: "The infinite looks weird"). */
.ube-pill.super .ube-count { display: flex; align-items: center; justify-content: center; }
.ube-inf { width: calc(var(--u) * 34); height: calc(var(--u) * 18); fill: none; stroke: #1A1A2E; stroke-width: 3.4; stroke-linejoin: round; }
.ube-cap { font-size: calc(var(--u) * 14); font-weight: 800; color: #4B4A63; }

.ube-delta {
  position: absolute;
  right: calc(var(--u) * -6);
  top: calc(var(--u) * -10);
  font-style: normal;
  font-size: calc(var(--u) * 15);
  font-weight: 900;
  opacity: 0;
}

.ube-delta.minus { color: #FF4B4B; }
.ube-delta.plus { color: #58CC02; }

/* EnergyManager.swift: every quiz card costs 1, and three right in a row
   earns +3 back. Three cards, 30 to 27, then the bonus: 30. */
@keyframes w-ube-roll {
  0%, 12%   { transform: translateY(0); }
  16%, 28%  { transform: translateY(calc(var(--u) * -38)); }
  32%, 44%  { transform: translateY(calc(var(--u) * -76)); }
  48%, 64%  { transform: translateY(calc(var(--u) * -114)); }
  70%, 100% { transform: translateY(calc(var(--u) * -152)); }
}
@keyframes w-ube-minus {
  0%, 12% { opacity: 0; transform: none; }
  15% { opacity: 1; transform: none; }
  24% { opacity: 0; transform: translateY(calc(var(--u) * -12)); }
  28% { opacity: 0; transform: none; }
  31% { opacity: 1; transform: none; }
  40% { opacity: 0; transform: translateY(calc(var(--u) * -12)); }
  44% { opacity: 0; transform: none; }
  47% { opacity: 1; transform: none; }
  56%, 100% { opacity: 0; transform: translateY(calc(var(--u) * -12)); }
}
@keyframes w-ube-plus { 0%, 64% { opacity: 0; transform: none; } 70% { opacity: 1; } 90%, 100% { opacity: 0; transform: translateY(calc(var(--u) * -14)); } }

.is-live .ube-roll { animation: w-ube-roll 4.2s ease-in-out 0.5s; }
.is-live .ube-delta.minus { animation: w-ube-minus 4.2s ease-out 0.5s; }
.is-live .ube-delta.plus { animation: w-ube-plus 4.2s ease-out 0.5s; }
.anim-wait:not(.is-live) .ube-row { opacity: 0; }
.is-live .ube-row { animation: w-lift 0.5s ease-out backwards; }
.is-live .ube-row:last-child { animation-delay: 0.15s; }

/* ---------- Backed up (Tarsier ID card + the iCloud Backup row) ---------- */
.idc-card {
  padding: calc(var(--u) * 10) calc(var(--u) * 14) calc(var(--u) * 9);
  border-radius: calc(var(--u) * 16);
  background: linear-gradient(135deg, #6A55F0, #4B36C9);
  box-shadow: 0 calc(var(--u) * 10) calc(var(--u) * 24) rgba(75, 54, 201, 0.28);
  color: #fff;
}

.idc-top {
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 8);
  font-size: calc(var(--u) * 8.5);
  font-weight: 800;
  letter-spacing: 0.2em;
  color: rgba(255, 255, 255, 0.72);
}

.idc-top::before, .idc-top::after { content: ""; flex: 1; height: 1px; background: rgba(255, 255, 255, 0.28); }

.idc-body { display: flex; align-items: center; gap: calc(var(--u) * 12); margin: calc(var(--u) * 8) 0; }
.idc-mascot { width: calc(var(--u) * 72); height: calc(var(--u) * 72); flex: none; }
.idc-who { display: flex; flex-direction: column; align-items: flex-start; gap: calc(var(--u) * 2); line-height: 1.2; }
.idc-name { font-family: 'Nunito', system-ui, sans-serif; font-size: calc(var(--u) * 19); font-weight: 900; }
.idc-handle { font-size: calc(var(--u) * 11); color: #DCD5FF; }
.idc-from { font-size: calc(var(--u) * 9.5); }
.idc-from em { font-style: normal; font-weight: 800; letter-spacing: 0.1em; color: rgba(255, 255, 255, 0.7); }

.idc-super {
  margin-top: calc(var(--u) * 3);
  padding: calc(var(--u) * 2) calc(var(--u) * 8);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.15);
  color: #FFE08A;
  font-size: calc(var(--u) * 9);
  font-weight: 800;
}

.idc-foot {
  display: flex;
  justify-content: space-between;
  padding-top: calc(var(--u) * 6);
  border-top: 1px solid rgba(255, 255, 255, 0.2);
  font-size: calc(var(--u) * 8.5);
  letter-spacing: 0.04em;
  color: rgba(255, 255, 255, 0.75);
}

.idc-backup {
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 10);
  margin-top: calc(var(--u) * 10);
  padding: calc(var(--u) * 9) calc(var(--u) * 12);
  border-radius: calc(var(--u) * 14);
  background: #fff;
  border: 1px solid #E5E7EB;
  cursor: pointer;
}

.idc-backup-text { flex: 1; display: flex; flex-direction: column; gap: calc(var(--u) * 2); }
.idc-backup-text b { font-size: calc(var(--u) * 12.5); font-weight: 700; }
.idc-backup-text span { font-size: calc(var(--u) * 9.5); line-height: 1.35; color: #6B7280; }

.idc-switch {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  flex: none;
  width: calc(var(--u) * 40);
  height: calc(var(--u) * 24);
  margin: 0;
  border-radius: 999px;
  background: #D1D5DB;
  cursor: pointer;
  transition: background 0.2s ease;
}

.idc-switch::before {
  content: "";
  position: absolute;
  top: calc(var(--u) * 2);
  left: calc(var(--u) * 2);
  width: calc(var(--u) * 20);
  height: calc(var(--u) * 20);
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
  transition: transform 0.2s ease;
}

.idc-switch:checked { background: #34C759; }
.idc-switch:checked::before { transform: translateX(calc(var(--u) * 16)); }
.idc-switch:focus-visible { outline: 2px solid #A99BFF; outline-offset: 2px; }

@keyframes w-switch-bg   { from { background: #D1D5DB; } }
@keyframes w-switch-knob { from { transform: none; } }

.anim-wait:not(.is-live) .idc-card { opacity: 0; }
.anim-wait:not(.is-live) .idc-switch:checked { background: #D1D5DB; }
.anim-wait:not(.is-live) .idc-switch:checked::before { transform: none; }
.is-live .idc-card { animation: w-lift 0.6s ease-out backwards; }
.is-live .idc-switch:checked { animation: w-switch-bg 0.25s ease 0.9s backwards; }
.is-live .idc-switch:checked::before { animation: w-switch-knob 0.25s ease 0.9s backwards; }
.idc-super { display: inline-flex; align-items: center; gap: calc(var(--u) * 4); }
.idc-super img { width: calc(var(--u) * 11); height: calc(var(--u) * 11); }
.idc-foot span:last-child { overflow: hidden; white-space: nowrap; }

/* ---------- More shared pieces ---------- */
@keyframes w-stamp { from { opacity: 0; transform: scale(1.8) rotate(-8deg); } }
@keyframes w-karaoke {
  30% { transform: translateY(calc(var(--u) * -3)); box-shadow: inset 0 0 0 calc(var(--u) * 2) #5B48E0, 0 calc(var(--u) * 3) 0 #A99BFF; }
}
@keyframes w-pulse { 40% { transform: scale(1.05); } }

.mp, .wd, .au, .pr {
  --u: min(1.1px, calc(100cqw / 300));
  width: calc(var(--u) * 300);
}

.w-speaker { flex: none; fill: currentColor; }

/* The app's 3D press for a white chip: face on a 3pt edge. */
.w-chip {
  background: #fff;
  box-shadow: inset 0 0 0 calc(var(--u) * 1.5) #E5E7EB, 0 calc(var(--u) * 3) 0 #E5E7EB;
  transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}

/* ---------- Map (the end of Unit 3) ---------- */
.mp { position: relative; }

.mp-unit {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: calc(var(--u) * 34);
  padding: 0 calc(var(--u) * 10) 0 calc(var(--u) * 14);
  border-radius: calc(var(--u) * 12);
  background: var(--accent);
  box-shadow: 0 calc(var(--u) * 3) 0 #C14677;
  color: #fff;
}

.mp-unit b { font-family: 'Nunito', system-ui, sans-serif; font-size: calc(var(--u) * 14.5); font-weight: 900; }
.mp-unit span { padding: calc(var(--u) * 3) calc(var(--u) * 9); border-radius: 999px; background: rgba(255, 255, 255, 0.25); font-size: calc(var(--u) * 10.5); font-weight: 700; }

.mp-field { position: relative; height: calc(var(--u) * 214); margin: calc(var(--u) * 6) 0 calc(var(--u) * 26); }
.mp-road { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.mp-road path { fill: none; stroke-width: 12; stroke-linecap: round; stroke-dasharray: 1 1; }
.mp-road-done { stroke: #E576A3; }   /* completed road: the accent, 0.22 toward the page */
.mp-road-next { stroke: #F3C46B; }   /* into the medal */

.mp-node, .mp-medal {
  position: absolute;
  left: calc(var(--x) * var(--u));
  top: calc(var(--y) * var(--u));
  display: grid;
  place-items: center;
}

.mp-node {
  width: calc(var(--u) * 50);
  height: calc(var(--u) * 50);
  margin: calc(var(--u) * -25) 0 0 calc(var(--u) * -25);
  border-radius: 50%;
  background: #E0518A;
  box-shadow: 0 calc(var(--u) * 4) 0 #C14677;
  color: #fff;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.mp-node svg { width: calc(var(--u) * 24); height: calc(var(--u) * 24); fill: #fff; }
.mp-node .ink { fill: #E0518A; }
.mp-node:hover { transform: translateY(calc(var(--u) * -2)); }
.mp-node:active, .mp-node.is-open { transform: translateY(calc(var(--u) * 3)); box-shadow: 0 calc(var(--u) * 1) 0 #C14677; }
.mp-node:focus-visible { outline: 2px solid #A99BFF; outline-offset: 3px; }

.mp-medal {
  width: calc(var(--u) * 52);
  height: calc(var(--u) * 52);
  margin: calc(var(--u) * -26) 0 0 calc(var(--u) * -26);
  border-radius: calc(var(--u) * 14);
  background: #F5A100;
  box-shadow: 0 0 0 calc(var(--u) * 5) rgba(245, 161, 0, 0.25), 0 calc(var(--u) * 4) 0 #C98400;
}

.mp-medal svg { width: calc(var(--u) * 28); height: calc(var(--u) * 28); fill: #fff; }

.mp-pop {
  position: absolute;
  left: 50%;
  z-index: 3;
  width: calc(var(--u) * 210);
  margin-left: calc(var(--u) * -105);
  padding: calc(var(--u) * 9) calc(var(--u) * 12);
  border-radius: calc(var(--u) * 14);
  background: #E0518A;
  box-shadow: 0 calc(var(--u) * 10) calc(var(--u) * 24) rgba(26, 26, 46, 0.2);
  color: #fff;
  animation: w-pop 0.2s ease-out;
}

.mp-pop[hidden] { display: none; }

.mp-pop::before {
  content: "";
  position: absolute;
  top: calc(var(--u) * -6);
  left: var(--ax, 50%);
  width: calc(var(--u) * 12);
  height: calc(var(--u) * 12);
  margin-left: calc(var(--u) * -6);
  background: inherit;
  transform: rotate(45deg);
}

.mp-pop.above::before { top: auto; bottom: calc(var(--u) * -6); }
.mp-pop-kind { display: block; font-size: calc(var(--u) * 10); font-weight: 700; opacity: 0.85; }
.mp-pop-title { display: block; font-family: 'Nunito', system-ui, sans-serif; font-size: calc(var(--u) * 16); font-weight: 900; line-height: 1.2; }
.mp-pop-sub { display: block; font-size: calc(var(--u) * 11); opacity: 0.9; }

.anim-wait:not(.is-live) .mp-node,
.anim-wait:not(.is-live) .mp-medal { opacity: 0; }
.anim-wait:not(.is-live) .mp-road path { stroke-dashoffset: 1; }
.is-live .mp-road-done { animation: w-draw 1.3s ease-in-out backwards; }
.is-live .mp-node { animation: w-pop 0.45s cubic-bezier(0.3, 1.5, 0.5, 1) backwards; animation-delay: calc(0.2s + var(--i) * 0.28s); }
.is-live .mp-road-next { animation: w-draw 0.5s ease-out 1.3s backwards; }
.is-live .mp-medal { animation: w-medal 0.6s cubic-bezier(0.3, 1.6, 0.5, 1) 1.7s backwards; }
@keyframes w-medal { from { opacity: 0; transform: scale(0.3) rotate(-20deg); } }

/* ---------- Word page (kahel) ---------- */
.wd { display: flex; flex-direction: column; align-items: center; text-align: center; }
.wd-img { width: calc(var(--u) * 92); height: calc(var(--u) * 92); object-fit: contain; }
.wd-word { margin-top: calc(var(--u) * 2); font-family: 'Nunito', system-ui, sans-serif; font-size: calc(var(--u) * 28); font-weight: 900; line-height: 1.1; }
.wd-pron { margin-top: calc(var(--u) * 2); font-size: calc(var(--u) * 11); color: #6B7280; }

.wd-listen, .au-listen {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--u) * 7);
  height: calc(var(--u) * 34);
  padding: 0 calc(var(--u) * 18);
  border-radius: 999px;
  background: #5B48E0;
  border: max(2px, calc(var(--u) * 2)) solid #3D2BA8;
  box-shadow: 0 max(4px, calc(var(--u) * 4)) 0 #3D2BA8;
  color: #fff;
  font-size: calc(var(--u) * 13);
  font-weight: 700;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.wd-listen { margin-top: calc(var(--u) * 8); }
.wd-listen svg, .au-listen svg { width: calc(var(--u) * 16); height: calc(var(--u) * 16); fill: currentColor; }
.wd-listen:active, .wd-listen.playing, .au-listen:active, .au-listen.playing { transform: translateY(max(4px, calc(var(--u) * 4))); box-shadow: 0 0 0 #3D2BA8; }

.wd-mastered {
  margin-top: calc(var(--u) * 9);
  padding: calc(var(--u) * 2) calc(var(--u) * 9);
  border-radius: 999px;
  background: #E8F5E9;
  color: #58CC02;
  font-size: calc(var(--u) * 9);
  font-weight: 900;
  letter-spacing: 0.06em;
}

.wd-type { align-self: flex-start; margin-top: calc(var(--u) * 8); font-size: calc(var(--u) * 10); font-weight: 900; color: #5B48E0; }

.wd-def {
  align-self: stretch;
  margin-top: calc(var(--u) * 4);
  padding: calc(var(--u) * 10) calc(var(--u) * 12);
  border-radius: calc(var(--u) * 14);
  /* White, not the app's purple card: Ean is changing that card in 2.2
     (2026-10-16: "fix the [NOUN] definition to not be a purple card"). */
  background: #fff;
  box-shadow: inset 0 0 0 1px #E5E7EB;
  color: #1A1A2E;
  font-size: calc(var(--u) * 11.5);
  line-height: 1.4;
  text-align: left;
}

.anim-wait:not(.is-live) .wd-img,
.anim-wait:not(.is-live) .wd-mastered { opacity: 0; }
.is-live .wd-img { animation: w-pop 0.5s cubic-bezier(0.3, 1.5, 0.5, 1) backwards; }
.is-live .wd-mastered { animation: w-stamp 0.35s cubic-bezier(0.3, 1.4, 0.5, 1) 0.9s backwards; }

/* ---------- Hear every word (kain) ---------- */
/* Centred as one stack. Left-aligned in a 300pt column it pushed Listen
   to the far edge, away from the word it plays, and left the tiles and
   the sentence a dead strip on the right (Ean, 2026-10-16: "this looks
   off"). */
.au { display: flex; flex-direction: column; align-items: center; text-align: center; }
.au-head { display: flex; align-items: center; justify-content: center; gap: calc(var(--u) * 10); }
.au-head img { width: calc(var(--u) * 56); height: calc(var(--u) * 56); object-fit: contain; }
.au-word { display: flex; flex-direction: column; align-items: flex-start; margin-right: calc(var(--u) * 6); }
.au-word b { font-family: 'Nunito', system-ui, sans-serif; font-size: calc(var(--u) * 26); font-weight: 900; line-height: 1.05; }
.au-word span { font-size: calc(var(--u) * 11); color: #6B7280; }
.au-label { margin-top: calc(var(--u) * 12); font-size: calc(var(--u) * 10); font-weight: 600; letter-spacing: 0.06em; color: #6B7280; }
.au-tiles { display: flex; justify-content: center; gap: calc(var(--u) * 8); margin-top: calc(var(--u) * 6); }
.au-cell { display: flex; flex-direction: column; align-items: center; gap: calc(var(--u) * 4); }
.au-cell small { font-size: calc(var(--u) * 9); color: #6B7280; white-space: nowrap; }

.au-tile {
  height: calc(var(--u) * 36);
  padding: 0 calc(var(--u) * 12);
  border-radius: calc(var(--u) * 12);
  background: #fff;
  box-shadow: inset 0 0 0 calc(var(--u) * 1.5) #E5E7EB, 0 calc(var(--u) * 3) 0 #E5E7EB;
  font-family: 'Nunito', system-ui, sans-serif;
  font-size: calc(var(--u) * 16);
  font-weight: 800;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.w-stage .au-key { color: #5B48E0; }
.au-tile:active, .au-tile.playing { transform: translateY(calc(var(--u) * 3)); box-shadow: inset 0 0 0 calc(var(--u) * 1.5) #E5E7EB, 0 0 0 #E5E7EB; }

.au-sentence {
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 10);
  margin-top: calc(var(--u) * 12);
  padding: calc(var(--u) * 10) calc(var(--u) * 16);
  padding-inline: calc(var(--u) * 22);
  border-radius: 999px;
  background: #5B48E0;
  border: max(2px, calc(var(--u) * 2)) solid #3D2BA8;
  box-shadow: 0 max(4px, calc(var(--u) * 4)) 0 #3D2BA8;
  color: #fff;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.w-stage .au-sentence { color: #fff; }
.w-stage .au-sentence { text-align: left; }
.au-sentence svg { width: calc(var(--u) * 22); height: calc(var(--u) * 22); fill: #fff; }
.au-sentence b { display: block; font-family: 'Nunito', system-ui, sans-serif; font-size: calc(var(--u) * 16); font-weight: 800; }
.au-sentence small { font-size: calc(var(--u) * 11); opacity: 0.85; }
.au-sentence:active, .au-sentence.playing { transform: translateY(max(4px, calc(var(--u) * 4))); box-shadow: 0 0 0 #3D2BA8; }

/* Each word lights in turn, then the whole sentence. */
.is-live .au-tile { animation: w-karaoke 0.7s ease-in-out backwards; animation-delay: calc(0.5s + var(--i) * 0.5s); }
.is-live .au-cell:nth-child(1) .au-tile { animation-delay: 0.5s; }
.is-live .au-cell:nth-child(2) .au-tile { animation-delay: 1s; }
.is-live .au-cell:nth-child(3) .au-tile { animation-delay: 1.5s; }
.is-live .au-sentence { animation: w-pulse 0.6s ease-in-out 2.1s; }

/* ---------- Quizzes (three real cards, playable) ---------- */
.qz-set {
  --u: min(1.1px, calc(100cqw / 700));
  width: calc(var(--u) * 700);
}

/* Stretched to one height with Check pinned to the bottom: at their own
   heights (273, 252, 245px) the three Check buttons sat on three lines. */
.qz-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: calc(var(--u) * 14); align-items: stretch; }
.qz-row .qz-check { margin-top: auto; }
.qz-row .qz > :nth-last-child(2) { margin-bottom: calc(var(--u) * 12); }
.qz-tabs { display: none; }

.qz {
  display: flex;
  flex-direction: column;
  padding: calc(var(--u) * 12);
  border-radius: calc(var(--u) * 18);
  background: #fff;
  box-shadow: 0 calc(var(--u) * 8) calc(var(--u) * 20) rgba(26, 26, 46, 0.07);
}

.qz-title { margin: 0 0 calc(var(--u) * 8); font-family: 'Nunito', system-ui, sans-serif; font-size: calc(var(--u) * 14); font-weight: 900; }
.qz-prompt { display: flex; align-items: center; gap: calc(var(--u) * 6); margin-bottom: calc(var(--u) * 8); }
.qz-mascot { width: calc(var(--u) * 44); height: calc(var(--u) * 44); object-fit: contain; }

.qz-bubble {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--u) * 5);
  padding: calc(var(--u) * 6) calc(var(--u) * 10);
  border-radius: calc(var(--u) * 12);
  background: #F5F5F5;
  box-shadow: inset 0 0 0 1px #E5E7EB;
  font-family: 'Nunito', system-ui, sans-serif;
  font-size: calc(var(--u) * 14);
  font-weight: 800;
}

.w-stage .qz-bubble { color: #5B48E0; }
.w-stage .qz-bubble.plain { color: #1A1A2E; }
.qz-bubble svg { width: calc(var(--u) * 15); height: calc(var(--u) * 15); fill: currentColor; }
.qz-bubble u { text-decoration-style: dashed; text-decoration-color: #A99BFF; text-underline-offset: calc(var(--u) * 3); }

.qz-opt {
  border-radius: calc(var(--u) * 12);
  background: #fff;
  box-shadow: inset 0 0 0 calc(var(--u) * 1.5) #E5E7EB, 0 calc(var(--u) * 3) 0 #E5E7EB;
  transition: box-shadow 0.15s ease, background 0.15s ease, transform 0.15s ease;
}

.qz-opt[aria-pressed="true"] { background: #F5F3FF; box-shadow: inset 0 0 0 calc(var(--u) * 2) #5B48E0, 0 calc(var(--u) * 3) 0 #A99BFF; }
.qz.checked .qz-opt.is-right { background: #E8F5E9; box-shadow: inset 0 0 0 calc(var(--u) * 2) #58CC02, 0 calc(var(--u) * 3) 0 #58CC02; }
.qz.checked .qz-opt.is-wrong { background: #FDECEA; box-shadow: inset 0 0 0 calc(var(--u) * 2) #FF4B4B, 0 calc(var(--u) * 3) 0 #FF4B4B; }

/* minmax(0, 1fr), not 1fr: a bare 1fr track cannot shrink below its
   content, and each picture's 220px intrinsic width pushed the grid out of
   the card. */
.qz-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: calc(var(--u) * 6); }
.qz-pic { position: relative; min-width: 0; aspect-ratio: 1.6; overflow: hidden; }
.qz-pic img { position: absolute; inset: calc(var(--u) * 5); width: calc(100% - var(--u) * 10); height: calc(100% - var(--u) * 10); object-fit: contain; }

.qz-check {
  width: 100%;
  height: calc(var(--u) * 34);
  margin-top: calc(var(--u) * 12);
  border-radius: 999px;
  background: #5B48E0;
  border: max(2px, calc(var(--u) * 2)) solid #3D2BA8;
  box-shadow: 0 max(4px, calc(var(--u) * 4)) 0 #3D2BA8;
  font-size: calc(var(--u) * 13);
  font-weight: 700;
  text-align: center;
  transition: background 0.2s ease, transform 0.15s ease, box-shadow 0.15s ease;
}

.w-stage .qz-check { color: #fff; }
.qz-check:active { transform: translateY(max(4px, calc(var(--u) * 4))); box-shadow: 0 0 0 #3D2BA8; }
.w-stage .qz-check:disabled { background: #E5E7EB; border-color: #D1D5DB; box-shadow: 0 max(4px, calc(var(--u) * 4)) 0 #D1D5DB; color: #9CA3AF; cursor: default; transform: none; }
.qz.right .qz-check { background: #58CC02; border-color: #46A302; box-shadow: 0 max(4px, calc(var(--u) * 4)) 0 #46A302; }
.qz.wrong .qz-check { background: #FF4B4B; border-color: #D93B3B; box-shadow: 0 max(4px, calc(var(--u) * 4)) 0 #D93B3B; }

.qz-who { display: flex; align-items: center; gap: calc(var(--u) * 8); }
.qz-who img { width: calc(var(--u) * 34); height: calc(var(--u) * 34); border-radius: 50%; object-fit: cover; }
.qz-who span { display: flex; flex-direction: column; line-height: 1.2; }
.qz-who b { font-size: calc(var(--u) * 12.5); font-weight: 700; }
.qz-who small { font-size: calc(var(--u) * 9.5); color: #6B7280; }

.qz-line {
  align-self: flex-start;
  margin: calc(var(--u) * 6) 0 calc(var(--u) * 10) calc(var(--u) * 42);
  padding: calc(var(--u) * 7) calc(var(--u) * 12);
  border-radius: calc(var(--u) * 4) calc(var(--u) * 14) calc(var(--u) * 14) calc(var(--u) * 14);
  background: #F5F5F5;
  box-shadow: inset 0 0 0 1px #ECECEC;
  font-family: 'Nunito', system-ui, sans-serif;
  font-size: calc(var(--u) * 14);
  font-weight: 800;
}

.qz-replies { display: flex; flex-direction: column; gap: calc(var(--u) * 7); }
.qz-reply { padding: calc(var(--u) * 8) calc(var(--u) * 12); text-align: left; }
.qz-reply b { display: block; font-family: 'Nunito', system-ui, sans-serif; font-size: calc(var(--u) * 13.5); font-weight: 800; }
.qz-reply small { display: none; font-size: calc(var(--u) * 10); color: #6B7280; }
.qz.checked .qz-reply small { display: block; }

.qz-en { margin: 0 0 calc(var(--u) * 10); font-size: calc(var(--u) * 12.5); color: #4B4A63; }
.qz-slots { display: flex; flex-wrap: wrap; align-items: center; gap: calc(var(--u) * 5); min-height: calc(var(--u) * 40); }
.qz-given, .qz-stop { font-family: 'Nunito', system-ui, sans-serif; font-size: calc(var(--u) * 15); font-weight: 800; }

.qz-slot {
  min-width: calc(var(--u) * 42);
  height: calc(var(--u) * 34);
  padding: 0 calc(var(--u) * 8);
  border-radius: calc(var(--u) * 10);
  background: transparent;
  box-shadow: inset 0 0 0 calc(var(--u) * 1.5) #D1D5DB;
  font-family: 'Nunito', system-ui, sans-serif;
  font-size: calc(var(--u) * 15);
  font-weight: 800;
}

.qz-slot:not(.filled) { background-image: repeating-linear-gradient(90deg, #fff 0 calc(var(--u) * 5), transparent 0 calc(var(--u) * 8)); }
.qz-slot.filled { background: #fff; box-shadow: inset 0 0 0 calc(var(--u) * 1.5) #E5E7EB, 0 calc(var(--u) * 3) 0 #E5E7EB; }
.qz.right .qz-slot.filled { background: #E8F5E9; box-shadow: inset 0 0 0 calc(var(--u) * 2) #58CC02; }
.qz.wrong .qz-slot.filled { background: #FDECEA; box-shadow: inset 0 0 0 calc(var(--u) * 2) #FF4B4B; }

.qz-bank { display: flex; flex-wrap: wrap; gap: calc(var(--u) * 6); margin-top: calc(var(--u) * 12); }

.qz-tile {
  height: calc(var(--u) * 34);
  padding: 0 calc(var(--u) * 12);
  border-radius: calc(var(--u) * 10);
  background: #fff;
  box-shadow: inset 0 0 0 calc(var(--u) * 1.5) #E5E7EB, 0 calc(var(--u) * 3) 0 #E5E7EB;
  font-family: 'Nunito', system-ui, sans-serif;
  font-size: calc(var(--u) * 15);
  font-weight: 800;
}

/* A placed tile leaves a grey placeholder, as in the app, so the bank keeps
   its shape instead of opening gaps. */
.qz-tile.used { color: transparent; background: #F3F4F6; box-shadow: inset 0 0 0 calc(var(--u) * 1.5) #E5E7EB; }
.qz-bubble:active, .qz-bubble.playing, .qz-line:active, .qz-line.playing, .qz-opt:active, .qz-opt.playing, .qz-tile:active, .qz-tile.playing { transform: translateY(calc(var(--u) * 2)); }
.qz-opt:focus-visible, .qz-tile:focus-visible, .qz-slot:focus-visible, .qz-check:focus-visible, .qz-tab:focus-visible, .qz-bubble:focus-visible, .qz-line:focus-visible { outline: 2px solid #A99BFF; outline-offset: 2px; }

.anim-wait:not(.is-live) .qz-row .qz { opacity: 0; }
.is-live .qz-row .qz { animation: w-lift 0.5s ease-out backwards; animation-delay: calc(var(--i) * 0.15s); }

/* A narrow card (tablet halves, phones): one quiz at a time, behind tabs. */
@container (max-width: 559px) {
  .qz-set { --u: min(1.1px, calc(100cqw / 250)); width: calc(var(--u) * 250); }
  .qz-tabs {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    margin-bottom: calc(var(--u) * 10);
    padding: calc(var(--u) * 3);
    border-radius: 999px;
    background: #fff;
  }
  .qz-tab { height: calc(var(--u) * 26); border-radius: 999px; background: transparent; color: #6B7280; font-size: calc(var(--u) * 12); font-weight: 700; text-align: center; }
  .qz-tab[aria-selected="true"] { background: #5B48E0; color: #fff; }
  .qz-row { display: block; }
  .qz-row .qz:not(.is-shown) { display: none; }
}

/* ---------- Recall (TGL_U01_L01_002) ---------- */
.rc { --u: min(1.1px, calc(100cqw / 260)); width: calc(var(--u) * 260); }
.rc-choices { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: calc(var(--u) * 8); }
.rc-opt { height: calc(var(--u) * 80); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: calc(var(--u) * 3); text-align: center; }
.rc-opt b { font-family: 'Nunito', system-ui, sans-serif; font-size: calc(var(--u) * 15); font-weight: 800; }
.rc-opt small { font-size: calc(var(--u) * 10); color: #6B7280; opacity: 0; transition: opacity 0.4s ease 0.15s; }
.rc.checked .rc-opt small { opacity: 1; }
.anim-wait:not(.is-live) .rc { opacity: 0; }
.is-live .rc { animation: w-lift 0.5s ease-out backwards; }

/* ---------- Practice (the 2.0 tiles) ---------- */
.pr { display: flex; flex-direction: column; gap: calc(var(--u) * 8); }

.pr-tile {
  position: relative;
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 10);
  height: calc(var(--u) * 50);
  padding: 0 calc(var(--u) * 12);
  border-radius: calc(var(--u) * 14);
  background: #fff;
  box-shadow: inset 0 0 0 1px #E5E7EB, 0 calc(var(--u) * 3) 0 #E5E7EB;
}

.pr-tile b { flex: 1; font-size: calc(var(--u) * 13); font-weight: 700; }
.pr-ic svg { display: block; width: calc(var(--u) * 22); height: calc(var(--u) * 22); fill: var(--c); }
.pr-due { font-size: calc(var(--u) * 11); font-weight: 700; color: #0EA5A1; }
.pr-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: calc(var(--u) * 8); }
.pr-pair .pr-tile { height: calc(var(--u) * 64); flex-direction: column; align-items: flex-start; justify-content: center; gap: calc(var(--u) * 5); }
.pr-pair .pr-tile b { flex: none; font-size: calc(var(--u) * 12); }
.pr-n { position: absolute; right: calc(var(--u) * 12); top: calc(var(--u) * 9); font-family: 'Nunito', system-ui, sans-serif; font-size: calc(var(--u) * 20); font-weight: 900; }

.pr-words { display: flex; flex-wrap: wrap; justify-content: center; gap: calc(var(--u) * 5); margin-top: calc(var(--u) * 4); }

/* Word over gloss, like the app's word tiles: side by side the three
   needed 358px of a 310px row and wrapped "magkano" onto a line alone. */
.pr-word {
  display: inline-grid;
  grid-template-columns: auto auto;
  align-items: center;
  column-gap: calc(var(--u) * 6);
  padding: calc(var(--u) * 6) calc(var(--u) * 11) calc(var(--u) * 6) calc(var(--u) * 9);
  border-radius: calc(var(--u) * 12);
  background: #fff;
  box-shadow: inset 0 0 0 1px #F6C9C9, 0 calc(var(--u) * 2) 0 #F6C9C9;
  text-align: left;
  line-height: 1.15;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.pr-word svg { grid-row: 1 / span 2; }

.pr-word svg { width: calc(var(--u) * 13); height: calc(var(--u) * 13); fill: #FF4B4B; }
.pr-word b { font-family: 'Nunito', system-ui, sans-serif; font-size: calc(var(--u) * 13); font-weight: 800; }
.pr-word small { grid-column: 2; font-size: calc(var(--u) * 9.5); color: #6B7280; }
.pr-word:active, .pr-word.playing { transform: translateY(calc(var(--u) * 2)); box-shadow: inset 0 0 0 1px #F6C9C9, 0 0 0 #F6C9C9; }

.anim-wait:not(.is-live) .pr-tile,
.anim-wait:not(.is-live) .pr-word { opacity: 0; }
.is-live .pr-tile { animation: w-lift 0.45s ease-out backwards; }
.is-live .pr-pair .pr-tile:nth-child(1) { animation-delay: 0.12s; }
.is-live .pr-pair .pr-tile:nth-child(2) { animation-delay: 0.2s; }
.is-live .pr-word { animation: w-pop 0.4s cubic-bezier(0.3, 1.5, 0.5, 1) backwards; animation-delay: calc(0.5s + var(--i) * 0.12s); }

.w-stage .speak:focus-visible, .w-stage .pr-word:focus-visible, .w-stage .au-tile:focus-visible { outline: 2px solid #A99BFF; outline-offset: 3px; }

/* A phone shows the wide quiz card at its natural height, not cropped to
   the 300px panel the other cards use. */
@media (max-width: 720px) {
  .card.card-wide .card-frame.w-frame { height: auto; padding: 18px 0 52px; }
}

/* ---------- Square panels ----------
   Every widget panel is as tall as one column is wide (Ean, 2026-10-16:
   "make all the cards taller (maybe 1:1) because a lot of these look
   squished"). The height comes from the grid's own width rather than
   aspect-ratio, so the two-column Quizzes card matches the height of its
   row: a column at three columns (32px gaps), a column at two, and a
   plain square on a phone, where the quiz card keeps its natural height. */
.cards { container-type: inline-size; }
.card-frame.w-frame { height: calc((100cqw - 64px) / 3); }

@media (max-width: 980px) {
  .card-frame.w-frame { height: calc((100cqw - 32px) / 2); }
}

@media (max-width: 720px) {
  .card-frame.w-frame { height: auto; aspect-ratio: 1 / 1; }
  .card.card-wide .card-frame.w-frame { aspect-ratio: auto; }
}

/* ---------- Culture from lesson one (2.0: TGL_U02 and TGL_U05) ----------
   Lola's chat beside the "yes to an elder" sheet, the Alam Mo Ba? across
   the bottom. Two columns on a wide row; one column on a phone, where the
   row grows to fit instead of cropping at 300px. */
@keyframes w-typing {
  0%   { opacity: 0; height: 0; margin-top: 0; }
  12%  { opacity: 1; height: calc(var(--u) * 22); margin-top: calc(var(--u) * 6); }
  88%  { opacity: 1; height: calc(var(--u) * 22); margin-top: calc(var(--u) * 6); }
  100% { opacity: 0; height: 0; margin-top: 0; }
}
@keyframes w-dot { 0%, 60%, 100% { transform: none; opacity: 0.4; } 30% { transform: translateY(calc(var(--u) * -3)); opacity: 1; } }
@keyframes w-glow { 50% { background: #FFE6A8; } }

.cu {
  --u: min(1.1px, calc(100cqw / 460));
  width: calc(var(--u) * 460);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: calc(var(--u) * 14);
  align-items: start;
}

.cu-chat, .cu-sheet {
  padding: calc(var(--u) * 14);
  border-radius: calc(var(--u) * 18);
  background: #fff;
  box-shadow: 0 calc(var(--u) * 8) calc(var(--u) * 20) rgba(26, 26, 46, 0.07);
}

.cu-title { margin-bottom: calc(var(--u) * 10); font-family: 'Nunito', system-ui, sans-serif; font-size: calc(var(--u) * 14); font-weight: 900; }

.cu-msg { display: flex; align-items: flex-end; gap: calc(var(--u) * 8); }
.cu-msg.me { justify-content: flex-end; margin-top: calc(var(--u) * 10); }
.cu-col { display: flex; flex-direction: column; align-items: flex-start; gap: calc(var(--u) * 3); }
.cu-who { font-size: calc(var(--u) * 10); font-weight: 700; color: #6B7280; }

.cu-av { flex: none; width: calc(var(--u) * 34); height: calc(var(--u) * 34); border-radius: 50%; object-fit: cover; }
.cu-av.me { display: grid; place-items: end center; overflow: hidden; background: #5B48E0; }
.cu-av.me img { width: 88%; height: 88%; object-fit: contain; }

.cu-bubble {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: calc(var(--u) * 2);
  padding: calc(var(--u) * 8) calc(var(--u) * 12);
  border-radius: calc(var(--u) * 4) calc(var(--u) * 16) calc(var(--u) * 16) calc(var(--u) * 16);
  background: #F5F5F5;
  box-shadow: inset 0 0 0 1px #ECECEC;
  text-align: left;
  transition: transform 0.15s ease;
}

.cu-bubble.mine { border-radius: calc(var(--u) * 16) calc(var(--u) * 4) calc(var(--u) * 16) calc(var(--u) * 16); background: #EEE9FF; box-shadow: inset 0 0 0 1px #DCD4FF; }
.cu-bubble b { font-family: 'Nunito', system-ui, sans-serif; font-size: calc(var(--u) * 14); font-weight: 800; }
.cu-bubble small { font-size: calc(var(--u) * 10); color: #6B7280; }
/* Highlight without padding: padded, the word's own spaces looked doubled. */
.cu-bubble em { font-style: normal; color: #5B48E0; border-radius: calc(var(--u) * 3); box-decoration-break: clone; }
.cu-bubble:active, .cu-bubble.playing { transform: scale(0.97); }

.cu-typing {
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 4);
  width: max-content;
  height: 0;
  margin-left: calc(var(--u) * 42);
  padding: 0 calc(var(--u) * 10);
  border-radius: 999px;
  background: #F5F5F5;
  overflow: hidden;
  opacity: 0;
}

.cu-typing i { width: calc(var(--u) * 5); height: calc(var(--u) * 5); border-radius: 50%; background: #9CA3AF; }

.cu-sheet-title { display: flex; align-items: center; gap: calc(var(--u) * 7); font-family: 'Nunito', system-ui, sans-serif; font-size: calc(var(--u) * 14); font-weight: 900; line-height: 1.2; }
.cu-sheet-title svg { flex: none; width: calc(var(--u) * 18); height: calc(var(--u) * 18); fill: #5B48E0; }
.cu-text { margin-top: calc(var(--u) * 8); font-size: calc(var(--u) * 11.5); line-height: 1.45; color: #4B4A63; }
.cu-text em, .cu-example em, .cu-dyk em { font-style: normal; font-weight: 800; color: #5B48E0; }

.cu-tiles { display: flex; align-items: flex-start; gap: calc(var(--u) * 5); margin-top: calc(var(--u) * 10); }
.cu-op { align-self: center; margin-top: calc(var(--u) * -14); font-size: calc(var(--u) * 15); font-weight: 800; color: #9CA3AF; }

.cu-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--u) * 4);
  min-width: 0;
  background: none;
  text-align: center;
}

.cu-tile b {
  display: grid;
  place-items: center;
  min-width: calc(var(--u) * 44);
  height: calc(var(--u) * 34);
  padding: 0 calc(var(--u) * 10);
  border-radius: calc(var(--u) * 10);
  background: #fff;
  box-shadow: inset 0 0 0 calc(var(--u) * 1.5) #E5E7EB, 0 calc(var(--u) * 3) 0 #E5E7EB;
  font-family: 'Nunito', system-ui, sans-serif;
  font-size: calc(var(--u) * 15);
  font-weight: 800;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.cu-tile small { max-width: calc(var(--u) * 74); font-size: calc(var(--u) * 8.5); line-height: 1.2; color: #6B7280; }
.cu-tile.hl b { background: #EEE9FF; box-shadow: inset 0 0 0 calc(var(--u) * 1.5) #A99BFF, 0 calc(var(--u) * 3) 0 #A99BFF; color: #5B48E0; }
.cu-tile.res b { background: #5B48E0; box-shadow: 0 calc(var(--u) * 3) 0 #3D2BA8; color: #fff; }
.cu-tile:active b, .cu-tile.playing b { transform: translateY(calc(var(--u) * 3)); box-shadow: none; }

.cu-example {
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 8);
  width: 100%;
  margin-top: calc(var(--u) * 12);
  padding: calc(var(--u) * 8) calc(var(--u) * 10);
  border-radius: calc(var(--u) * 12);
  background: #F8F7FF;
  box-shadow: inset 0 0 0 1px #E7E3FF;
  text-align: left;
  transition: transform 0.15s ease;
}

.cu-example span { display: flex; flex-direction: column; }
.cu-example b { font-family: 'Nunito', system-ui, sans-serif; font-size: calc(var(--u) * 13.5); font-weight: 800; }
.cu-example small { font-size: calc(var(--u) * 10); color: #6B7280; }
.cu-spk { flex: none; width: calc(var(--u) * 18); height: calc(var(--u) * 18); fill: #5B48E0; color: #5B48E0; }
.cu-example:active, .cu-example.playing { transform: scale(0.98); }

.cu-dyk {
  grid-column: 1 / -1;
  display: flex;
  align-items: baseline;
  gap: calc(var(--u) * 8);
  padding: calc(var(--u) * 10) calc(var(--u) * 14);
  border-radius: calc(var(--u) * 14);
  background: rgba(255, 255, 255, 0.7);
  box-shadow: inset 0 0 0 1px rgba(88, 204, 2, 0.25);
  font-size: calc(var(--u) * 11.5);
  line-height: 1.45;
  color: #4B4A63;
}

.cu-dyk b { flex: none; font-family: 'Nunito', system-ui, sans-serif; font-size: calc(var(--u) * 12); font-weight: 900; color: #3D8B00; }

/* The chat plays first: Lola asks, the dots, the reply with po lit up.
   The sheet's tiles assemble beside it: oo, po, opo. */
.anim-wait:not(.is-live) .cu-chat,
.anim-wait:not(.is-live) .cu-sheet,
.anim-wait:not(.is-live) .cu-msg,
.anim-wait:not(.is-live) .cu-tile,
.anim-wait:not(.is-live) .cu-op,
.anim-wait:not(.is-live) .cu-example,
.anim-wait:not(.is-live) .cu-dyk { opacity: 0; }

.is-live .cu-chat { animation: w-lift 0.5s ease-out backwards; }
.is-live .cu-sheet { animation: w-lift 0.5s ease-out 0.15s backwards; }
.is-live .cu-msg.them { animation: w-pop 0.4s ease-out 0.4s backwards; }
.is-live .cu-typing { animation: w-typing 1.1s ease-in-out 0.8s; }
.is-live .cu-typing i { animation: w-dot 0.9s ease-in-out infinite; }
.is-live .cu-typing i:nth-child(2) { animation-delay: 0.15s; }
.is-live .cu-typing i:nth-child(3) { animation-delay: 0.3s; }
.is-live .cu-msg.me { animation: w-lift 0.45s ease-out 1.9s backwards; }
.is-live .cu-bubble.mine em { animation: w-glow 0.9s ease-in-out 2.4s; }
.is-live .cu-tile, .is-live .cu-op { animation: w-pop 0.4s cubic-bezier(0.3, 1.5, 0.5, 1) backwards; animation-delay: calc(0.7s + var(--i) * 0.28s); }
.is-live .cu-example { animation: w-lift 0.45s ease-out 2.2s backwards; }
.is-live .cu-dyk { animation: w-lift 0.5s ease-out 2.7s backwards; }

/* One column once the stage is under 400px (tablet halves, phones), and
   from 980px down the row grows to fit rather than crop at its fixed
   height. Two columns need about 400px to keep 14pt text near 12px. */
@container (max-width: 399px) {
  .cu { --u: min(1.1px, calc(100cqw / 280)); width: calc(var(--u) * 280); grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 980px) {
  .hf-row:has(.cult-shot) { height: auto; }
  .hf-row .hf-shot.cult-shot { height: auto; padding: 28px 0 56px; }
}

@media (prefers-reduced-motion: reduce) {
  .cu-typing i { animation: none !important; }
}

/* ---------- Replay ----------
   A bare icon in the panel's bottom-left corner, shown once the entrance
   has finished (the script in index.html adds .w-done); it plays the
   entrance again. Hidden, not just faded, while the animation runs, so it
   cannot be pressed halfway through. */
/* The bottom strip is the icon's own, so it never sits on a widget's
   content (the word page's definition card ran under it). */
.w-host { position: relative; padding-bottom: 38px; }

.w-replay {
  position: absolute;
  left: 12px;
  bottom: 12px;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: rgba(26, 26, 46, 0.42);
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s ease, color 0.2s ease, visibility 0s linear 0.3s;
}

.w-replay svg { width: 18px; height: 18px; }
.w-done > .w-replay { opacity: 1; visibility: visible; transition: opacity 0.3s ease, color 0.2s ease, visibility 0s; }
.w-replay:hover { color: rgba(26, 26, 46, 0.75); }
.w-replay:active svg { transform: rotate(-40deg); transition: transform 0.15s ease; }
.w-replay:focus-visible { outline: 2px solid #A99BFF; outline-offset: 2px; }
