/* SensAI — direction « Encre et manga » : papier blanc, encre noire, traits épais, ombres
   franches, aplats rose et jaune, trames de points. Une seule apparence, claire. */

:root {
  --paper: #ffffff;
  --ink: #121212;
  --pink: #ff6b9a;
  --pink-mid: #ffc2d6;
  --pink-soft: #ffe9f0;
  --yellow: #ffd84d;
  --yellow-soft: #fff4c7;
  --rose: #c2185b; /* texte d'accent, lisible sur le blanc */
  --mint: #8fe3b0; /* une bonne réponse */
  --coral: #ff9f8f; /* une mauvaise réponse, une action qui détruit */
  --grey: #4d4d4d; /* texte secondaire */
  --dash: #b5b5b5;
  --stroke: 3px solid var(--ink);
  --shadow: 8px 8px 0 var(--ink);
  --shadow-small: 4px 4px 0 var(--ink);
  --dots: radial-gradient(var(--ink) 1.3px, transparent 1.7px);
  --display: "Dela Gothic One", "Arial Black", "Yu Gothic UI", "Hiragino Sans", sans-serif;
  --body: "M PLUS Rounded 1c", "Segoe UI", "Hiragino Maru Gothic ProN", "Yu Gothic UI", system-ui, sans-serif;
  color-scheme: light;
}

* {
  box-sizing: border-box;
}

/* Sans cela, les règles « display » ci-dessous l'emportent sur l'attribut hidden. */
[hidden] {
  display: none !important;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  font-size: 15px;
  line-height: 1.5;
}

h1,
h2,
h3,
h4,
p,
blockquote {
  margin: 0;
}

h1,
h2 {
  font-family: var(--display);
  font-weight: 400;
  line-height: 1.2;
  text-wrap: balance;
}

h2 {
  font-size: 22px;
}

h3,
h4 {
  font-size: 15px;
  font-weight: 800;
}

strong {
  font-weight: 800;
}

a {
  color: var(--ink);
  text-underline-offset: 3px;
}

a:hover {
  color: var(--rose);
}

:focus-visible {
  outline: 3px solid var(--rose);
  outline-offset: 3px;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* --- En-tête ------------------------------------------------------------------ */

.top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 28px;
  padding: 14px clamp(16px, 3vw, 40px);
  border-bottom: var(--stroke);
  background: var(--paper);
}

.brand {
  margin: 0;
  color: var(--ink);
  font-family: var(--display);
  font-size: 24px;
  font-weight: 400;
  line-height: 1.2;
  text-decoration: none;
}

.brand:hover {
  color: var(--ink);
}

.brand span {
  margin-left: 2px;
  padding: 0 6px;
  border: var(--stroke);
  border-radius: 8px;
  background: var(--pink);
}

.brand-large {
  font-size: 42px;
}

.top nav {
  display: flex;
  flex: 1;
  flex-wrap: wrap;
  gap: 8px;
  font-weight: 800;
}

.top nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 16px;
  border: var(--stroke);
  border-radius: 12px;
  background: var(--paper);
  color: var(--ink);
  text-decoration: none;
}

.top nav a:hover {
  background: var(--yellow);
}

.top nav a[aria-current="page"] {
  background: var(--ink);
  color: var(--paper);
}

.account {
  display: flex;
  align-items: center;
  gap: 14px;
  font-size: 13px;
}

.account span {
  font-weight: 800;
}

/* --- Mise en page --------------------------------------------------------------- */

.page {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 28px;
  padding: 32px clamp(16px, 3vw, 40px) 64px;
}

/* Les pages prennent toute la largeur de l'écran. Seul le formulaire de connexion reste étroit. */
.page-narrow {
  max-width: 500px;
  margin: 0 auto;
  padding-top: 7vh;
}

.page-title {
  font-size: clamp(28px, 4.75vw, 38px);
}

.card {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
  padding: clamp(18px, 3vw, 28px);
  border: var(--stroke);
  border-radius: 20px;
  background: var(--paper);
  box-shadow: var(--shadow);
}

/* Le titre d'un bloc à gauche, un chiffre ou un lien à droite. */
.card-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 6px 16px;
}

.lead {
  font-size: 17px;
  font-weight: 700;
}

.lead-small,
.stats,
.fiche-meta {
  color: var(--grey);
  font-size: 13px;
}

.notice {
  padding: 12px 16px;
  border: var(--stroke);
  border-radius: 14px;
  background: var(--pink-soft);
  font-weight: 700;
}

/* Un message d'information n'est pas une alerte. */
.notice[role="status"] {
  background: var(--yellow);
}

/* Une étiquette collée sur un bloc. */
.sticker,
.tag {
  display: inline-block;
  padding: 5px 14px;
  border: var(--stroke);
  border-radius: 10px;
  background: var(--paper);
  font-size: 12.5px;
  font-weight: 800;
  white-space: nowrap;
}

.tag {
  padding: 3px 10px;
  border-radius: 8px;
  background: var(--yellow);
  font-family: var(--body);
  font-size: 12px;
  line-height: 1.5;
  vertical-align: middle;
}

.tag-warn {
  background: var(--coral);
}

/* --- Boutons et champs ---------------------------------------------------------- */

button {
  min-height: 48px;
  padding: 0 20px;
  border: var(--stroke);
  border-radius: 14px;
  background: var(--paper);
  color: var(--ink);
  font: inherit;
  font-weight: 800;
  box-shadow: var(--shadow-small);
  cursor: pointer;
  transition:
    transform 0.08s,
    box-shadow 0.08s;
}

button:hover:not(:disabled) {
  transform: translate(-1px, -1px);
  box-shadow: 5px 5px 0 var(--ink);
}

button:active:not(:disabled) {
  transform: translate(3px, 3px);
  box-shadow: 1px 1px 0 var(--ink);
}

button:disabled {
  border-style: dashed;
  box-shadow: none;
  opacity: 0.55;
  cursor: not-allowed;
}

button.primary {
  min-height: 56px;
  background: var(--ink);
  color: var(--paper);
  font-size: 16px;
  box-shadow: 5px 5px 0 var(--pink);
}

button.primary:hover:not(:disabled) {
  box-shadow: 6px 6px 0 var(--pink);
}

button.primary:active:not(:disabled) {
  box-shadow: 1px 1px 0 var(--pink);
}

button.danger {
  background: var(--coral);
}

button[aria-pressed="true"] {
  background: var(--yellow);
}

/* Un bouton qui se lit comme un lien : retour, quitter, corriger. */
button.link {
  min-height: 0;
  padding: 0;
  border: 0;
  border-radius: 4px;
  background: none;
  box-shadow: none;
  color: var(--ink);
  font-weight: 800;
  text-align: left;
  text-decoration: underline;
  text-underline-offset: 3px;
  transform: none;
}

button.link:hover:not(:disabled) {
  box-shadow: none;
  color: var(--rose);
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  button {
    transition: none;
  }
}

select,
input[type="text"],
input[type="password"] {
  width: 100%;
  min-height: 48px;
  padding: 0 12px;
  border: var(--stroke);
  border-radius: 12px;
  background: var(--paper);
  color: var(--ink);
  font: inherit;
}

input[type="checkbox"] {
  appearance: none;
  flex: none;
  width: 26px;
  height: 26px;
  margin: 0;
  border: var(--stroke);
  border-radius: 8px;
  background: var(--paper);
  cursor: pointer;
}

input[type="checkbox"]:checked {
  background: var(--pink)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%23121212' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 10.5l4 4 8-9'/%3E%3C/svg%3E")
    center / 18px no-repeat;
}

.form label,
.settings label,
.check-row label {
  display: grid;
  gap: 6px;
  font-size: 13px;
  font-weight: 800;
}

.form .primary {
  width: 100%;
}

.form .link {
  justify-self: start;
}

/* --- Bulles et portrait de la sensei --------------------------------------------- */

.speech-big {
  position: relative;
  padding: 22px 26px;
  border: var(--stroke);
  border-radius: 28px;
  background: var(--paper);
}

/* La pointe de la bulle, tournée vers la sensei. */
.speech-big::after {
  content: "";
  position: absolute;
  top: 52px;
  right: -14px;
  width: 22px;
  height: 22px;
  border-top: var(--stroke);
  border-right: var(--stroke);
  background: var(--paper);
  transform: rotate(45deg);
}

.speech-left::after {
  top: auto;
  right: auto;
  bottom: 22px;
  left: -14px;
  border-top: 0;
  border-right: 0;
  border-bottom: var(--stroke);
  border-left: var(--stroke);
}

.portrait {
  position: relative;
  width: 100%;
  max-width: 250px;
  aspect-ratio: 8 / 9;
  overflow: hidden;
  border: var(--stroke);
  border-radius: 18px;
  background: #f4ecdc;
  box-shadow: 6px 6px 0 var(--ink);
  transform: rotate(2deg);
}

.portrait-small {
  flex: none;
  width: 116px;
  border-radius: 14px;
  box-shadow: var(--shadow-small);
  transform: rotate(-3deg);
}

/* La sensei. Un bras levé peut dépasser du cadre sur les côtés et vers le haut ; le bas reste coupé net. */
.avatar-svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
  clip-path: inset(-60% -45% 0 -45%);
}

/* Dans un petit portrait encadré, rien ne dépasse. */
.portrait .avatar-svg {
  overflow: hidden;
  clip-path: none;
}

.login-hello {
  display: flex;
  align-items: flex-end;
  gap: 22px;
}

.login-hello .speech-big {
  flex: 1;
  padding: 16px 20px;
  border-radius: 22px;
  box-shadow: var(--shadow-small);
  font-size: 16px;
  font-weight: 700;
}

/* --- Accueil : la planche ---------------------------------------------------------
   L'accueil est composé comme une page de manga : des cases serrées, aux angles vifs et sans
   ombre, une idée par case. La grande case porte le cours qui attend. */

.planche {
  gap: 12px;
}

.planche-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.case {
  flex: 1 1 300px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
  min-width: 0;
  padding: 26px 26px 28px;
  border: var(--stroke);
  border-radius: 6px;
  background: var(--paper);
}

/* Le cartouche d'une case : son titre, en réserve blanche sur noir, comme une légende de récit. */
.case-label {
  padding: 4px 12px;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--body);
  font-size: 12px;
  font-weight: 800;
  line-height: 1.5;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.case-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 16px;
  align-self: stretch;
}

/* Un texte posé sur un fond tramé : il garde son papier blanc pour rester lisible. */
.case .case-chip {
  padding: 0 8px;
  background: var(--paper);
}

.case-strong {
  font-size: 14px;
  font-weight: 800;
}

.case-lead {
  font-size: 17px;
  font-weight: 800;
  line-height: 1.4;
}

.case-plain {
  max-width: 68ch;
}

.case-link {
  font-weight: 800;
}

/* La grande case : la sensei annonce le cours. Des lignes de vitesse partent de derrière elle. */
.case-hero {
  flex: 2 1 560px;
  position: relative;
  overflow: hidden;
  gap: 20px;
  min-height: 470px;
  padding-bottom: 30px;
  background-color: var(--yellow);
  background-image: repeating-conic-gradient(from 0deg at 80% 66%, rgb(255 255 255 / 0.6) 0deg 2.5deg, rgb(255 255 255 / 0) 2.5deg 9deg);
}

/* Le texte passe devant la sensei quand la case se resserre. */
.case-hero > :not(.case-sensei, .case-sfx) {
  position: relative;
  z-index: 1;
}

.case-speech {
  max-width: 56%;
  padding: 22px 28px 24px;
  border: var(--stroke);
  border-radius: 40px;
  background: var(--paper);
}

/* La pointe de la bulle, tournée vers la sensei. */
.case-speech::after {
  content: "";
  position: absolute;
  right: -12px;
  bottom: 40px;
  width: 20px;
  height: 20px;
  border-top: var(--stroke);
  border-right: var(--stroke);
  background: var(--paper);
  transform: rotate(45deg);
}

.hero-hello {
  margin-bottom: 6px;
  color: var(--rose);
  font-weight: 800;
}

.case-speech h1 {
  font-size: clamp(24px, 2.93vw, 34px);
}

.case-note {
  padding: 2px 10px;
  border: var(--stroke);
  background: var(--paper);
  font-size: 12.5px;
  font-weight: 800;
}

/* La sensei, sans le décor de sa salle : le dessin est le même que pendant le cours, et il vit. */
.case-sensei {
  position: absolute;
  right: 0;
  bottom: -4px;
  width: min(390px, 48%);
  aspect-ratio: 8 / 9;
  pointer-events: none;
}

/* L'onomatopée : « よし ! », « allez ! ». */
.case-sfx {
  position: absolute;
  top: 16px;
  right: 24px;
  color: var(--pink);
  font-family: var(--display);
  font-size: clamp(36px, 4.83vw, 58px);
  line-height: 1;
  -webkit-text-stroke: 3px var(--ink);
  paint-order: stroke fill;
  transform: rotate(8deg);
}

.cta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 58px;
  padding: 0 28px;
  border: var(--stroke);
  border-radius: 16px;
  background: var(--ink);
  color: var(--paper);
  font-size: 17px;
  font-weight: 800;
  text-decoration: none;
  box-shadow: 5px 5px 0 var(--pink);
  transition:
    transform 0.08s,
    box-shadow 0.08s;
}

.cta:hover {
  color: var(--paper);
  transform: translate(-1px, -1px);
  box-shadow: 6px 6px 0 var(--pink);
}

.cta:active {
  transform: translate(3px, 3px);
  box-shadow: 1px 1px 0 var(--pink);
}

/* Les devoirs : des vignettes posées un peu de travers, comme collées sur la planche. */
.homework-stack {
  display: grid;
  gap: 16px;
  align-self: stretch;
  margin: 0;
  padding: 0;
  list-style: none;
}

.homework-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px;
  border: var(--stroke);
  border-radius: 14px;
  background: var(--pink-soft);
  color: var(--ink);
  text-decoration: none;
  box-shadow: var(--shadow-small);
  transition:
    transform 0.08s,
    box-shadow 0.08s;
}

.homework-stack li:nth-child(odd) .homework-row {
  transform: rotate(-1.2deg);
}

.homework-stack li:nth-child(even) .homework-row {
  transform: rotate(1deg);
}

.homework-stack .homework-row:hover {
  color: var(--ink);
  transform: translate(-1px, -1px);
  box-shadow: 5px 5px 0 var(--ink);
}

.homework-row.is-done {
  background: var(--paper);
}

.homework-row .game-art {
  width: 66px;
  height: 66px;
  border-radius: 14px;
}

.homework-row-text {
  display: grid;
  justify-items: start;
  gap: 4px;
  min-width: 0;
}

.homework-row-text strong {
  font-size: 15px;
  line-height: 1.25;
}

.homework-row .tag {
  background: var(--pink);
}

.homework-row.is-done .tag {
  background: var(--mint);
}

/* Le défi du jour : une carte à tamponner, un tampon par jour réussi. */
.case-daily {
  gap: 14px;
  background: var(--pink);
}

.case-daily .daily-score {
  font-size: 15px;
}

/* Le lien vers les jeux reste au pied de la case, quelle que soit sa hauteur. */
.case-daily .case-link {
  margin-top: auto;
}

/* Sept tampons, un par jour : ils tiennent sur une ligne, même sur un téléphone. */
.stamps {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.stamp {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: 3px dashed var(--ink);
  border-radius: 50%;
  font-size: 12px;
  font-weight: 800;
}

.stamp.is-reached {
  border-style: solid;
  background: var(--paper);
  font-family: var(--display);
  font-size: 17px;
  font-weight: 400;
  transform: rotate(-8deg);
}

.stamp.is-reached:nth-child(even) {
  transform: rotate(6deg);
}

.stamp.is-today:not(.is-reached) {
  border-style: solid;
  background: var(--yellow);
  box-shadow: 3px 3px 0 var(--ink);
}

/* L'objectif de l'élève, et où il en est. La suite n'est pas écrite d'avance. */
.case-goal {
  flex: 2 1 560px;
  background-image: radial-gradient(var(--pink-mid) 1.6px, transparent 2px);
  background-size: 12px 12px;
}

/* Sur la trame, un paragraphe garde son papier blanc. */
.case-goal > p {
  padding: 2px 8px;
  background: var(--paper);
}

.goal-quote {
  display: grid;
  justify-items: start;
  gap: 10px;
  max-width: 100%;
  margin: 0;
}

.goal-quote blockquote {
  margin: 0;
  padding: 6px 14px;
  border: var(--stroke);
  background: var(--yellow);
  font-family: var(--display);
  font-size: clamp(16px, 2.02vw, 22px);
  line-height: 1.3;
  /* Peu penchée : sur un écran large, la bande est longue et un degré la ferait mordre sur la légende. */
  transform: rotate(-0.4deg);
  box-shadow: var(--shadow-small);
}

.goal-quote figcaption {
  padding: 0 8px;
  background: var(--paper);
  font-size: 12.5px;
  font-weight: 700;
}

.goal-form {
  display: grid;
  gap: 10px;
  width: min(560px, 100%);
}

.goal-quote:has(.goal-form) {
  align-self: stretch;
}

.goal-form textarea {
  width: 100%;
  resize: vertical;
}

.goal-form-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.goal-steps {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-self: stretch;
  margin: 0;
  padding: 0;
  list-style: none;
}

.goal-step {
  flex: 1 1 170px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  min-width: 0;
  padding: 12px 14px 14px;
  border: var(--stroke);
  border-radius: 6px;
  background: var(--paper);
  font-size: 13px;
  line-height: 1.4;
}

.goal-step.is-now {
  background: var(--yellow);
  box-shadow: var(--shadow-small);
}

.goal-step.is-now .tag {
  background: var(--pink);
}

.goal-step.is-open {
  border-style: dashed;
}

.goal-step-label {
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.goal-now {
  font-size: 15px;
  font-weight: 800;
  line-height: 1.3;
}

/* Un cours déjà fait : son tampon, son titre. Il ouvre la fiche. */
.goal-done {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  font: inherit;
  font-weight: 400;
  line-height: 1.3;
  text-align: left;
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}

/* Ce bouton se lit comme un lien : il ne bouge pas et n'a pas d'ombre, même survolé. */
button.goal-done:hover:not(:disabled),
button.goal-done:active:not(:disabled) {
  color: var(--rose);
  transform: none;
  box-shadow: none;
}

.goal-stamp {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border: var(--stroke);
  border-radius: 50%;
  background: var(--pink);
  color: var(--ink);
  font-family: var(--display);
  font-size: 12.5px;
  transform: rotate(-8deg);
}

/* La bande du bas : « つづく… », à suivre. Elle ouvre ce qui n'a pas sa place dans une case. */
.case-more {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 32px;
  padding: 14px 24px;
  background: var(--yellow-soft);
  font-weight: 800;
}

.more-mark {
  font-family: var(--display);
  font-size: 16px;
  font-weight: 400;
}

.case-more [aria-expanded="true"] {
  color: var(--rose);
}

/* Les cartes ouvertes depuis la bande du bas respirent davantage que les cases. */
.planche > .card {
  margin-top: 16px;
}

@media (max-width: 720px) {
  .case {
    padding: 20px 18px 22px;
  }

  /* La sensei descend sous le texte, au milieu de la case. */
  .case-hero {
    min-height: 0;
    padding-bottom: 0;
  }

  .case-speech {
    max-width: 100%;
    border-radius: 28px;
  }

  .case-speech::after {
    right: 48px;
    bottom: -12px;
    border-top: 0;
    border-bottom: var(--stroke);
  }

  .case-sensei {
    position: relative;
    right: auto;
    bottom: -4px;
    align-self: center;
    width: min(250px, 72%);
    margin-top: -8px;
  }

  .case-sfx {
    top: 14px;
    right: 14px;
  }

  .case-hero .cta {
    justify-content: center;
    align-self: stretch;
  }
}

/* Le défi du jour. */
.daily {
  flex: 1 1 280px;
  align-content: start;
}

.daily-score {
  display: flex;
  align-items: baseline;
  gap: 10px;
  font-weight: 800;
}

.daily-number {
  font-family: var(--display);
  font-size: 62px;
  font-weight: 400;
  line-height: 1;
}

.daily-bar {
  display: block;
  width: 100%;
  height: 20px;
  overflow: hidden;
  border: var(--stroke);
  border-radius: 999px;
  background: var(--paper);
  appearance: none;
}

.daily-bar::-webkit-progress-bar {
  background: var(--paper);
}

.daily-bar::-webkit-progress-value {
  background: var(--pink);
}

.daily-bar::-moz-progress-bar {
  background: var(--pink);
}

.daily-week {
  display: flex;
  justify-content: space-between;
  gap: 4px;
  max-width: 340px;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 12px;
  font-weight: 800;
}

.daily-day {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}

.daily-dot {
  width: 24px;
  height: 24px;
  border: var(--stroke);
  border-radius: 50%;
}

.daily-day.is-today .daily-dot {
  background-color: var(--yellow);
}

.daily-day.is-played .daily-dot {
  background-image: var(--dots);
  background-size: 6px 6px;
}

.daily-day.is-reached .daily-dot {
  background: var(--ink);
}

.daily-day.is-today {
  text-decoration: underline;
  text-decoration-thickness: 3px;
  text-underline-offset: 3px;
}

/* --- Devoirs et illustrations des jeux -------------------------------------------- */

.homework-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(330px, 100%), 1fr));
  gap: 24px 20px;
  margin: 0;
  padding: 10px 0 0;
  list-style: none;
}

.homework-grid li {
  display: grid;
}

.homework-card {
  position: relative;
  display: flex;
  align-items: center;
  gap: 16px;
  width: 100%;
  min-height: 0;
  padding: 22px 18px 18px;
  border: var(--stroke);
  border-radius: 16px;
  background: var(--pink-soft);
  color: var(--ink);
  font: inherit;
  font-weight: 400;
  text-align: left;
  text-decoration: none;
  box-shadow: var(--shadow-small);
  transition:
    transform 0.08s,
    box-shadow 0.08s;
}

a.homework-card:hover {
  color: var(--ink);
  transform: translate(-1px, -1px);
  box-shadow: 5px 5px 0 var(--ink);
}

.homework-card.is-done {
  background: var(--paper);
}

.homework-card .sticker {
  position: absolute;
  top: -15px;
  right: 16px;
  background: var(--pink);
  transform: rotate(3deg);
}

.homework-card.is-done .sticker {
  background: var(--mint);
  transform: rotate(-2deg);
}

.homework-text {
  display: grid;
  gap: 4px;
  min-width: 0;
}

.homework-text strong {
  font-size: 18px;
  line-height: 1.25;
}

.homework-text span {
  font-size: 13.5px;
}

.homework-text .action-advice {
  font-weight: 800;
}

/* La vignette d'un jeu : un carré de couleur, son dessin dedans. */
.game-art {
  flex: none;
  display: block;
  width: 92px;
  height: 92px;
  padding: 6px;
  border: var(--stroke);
  border-radius: 16px;
  background: var(--paper);
}

.game-art-yellow {
  background: var(--yellow);
}

.game-art-pink {
  background: var(--pink-mid);
}

.game-art svg {
  display: block;
  width: 100%;
  height: 100%;
  font-family: var(--body);
}

.game-art-small {
  width: 52px;
  height: 52px;
  padding: 3px;
  border-radius: 12px;
}

@media (max-width: 420px) {
  .game-art:not(.game-art-small) {
    width: 76px;
    height: 76px;
    padding: 4px;
  }
}

/* --- Parcours et fiche de cours ---------------------------------------------------- */

.view {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 14px;
  min-height: 0;
}

.view ul,
.view ol {
  display: grid;
  gap: 6px;
  margin: 0;
  padding-left: 1.2em;
}

.view h3 {
  margin-top: 10px;
}

.next-lesson {
  display: grid;
  gap: 10px;
  padding: 18px 20px;
  border: var(--stroke);
  border-radius: 16px;
  background: var(--yellow-soft);
}

.next-lesson h3 {
  margin: 0;
  font-size: 12.5px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.next-title {
  font-size: 18px;
  font-weight: 800;
  line-height: 1.3;
}

.view .history,
.view .expressions,
.view .patterns,
.view .homework-grid {
  padding-left: 0;
  list-style: none;
}

.view .homework-grid {
  gap: 24px 20px;
  padding-top: 10px;
}

.view .history {
  gap: 0;
}

.history li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 16px;
  padding: 12px 0;
  border-top: var(--stroke);
}

.history-number {
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border: var(--stroke);
  border-radius: 50%;
  font-family: var(--display);
  font-size: 15px;
}

.history .link {
  flex: 1 1 240px;
  font-size: 16px;
}

.history-date {
  font-size: 12.5px;
  font-weight: 700;
}

.reset {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  font-size: 13px;
}

.reset .link {
  font-weight: 700;
}

.rename-form {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.rename-form input {
  flex: 1 1 180px;
  width: auto;
}

.fiche-section {
  display: grid;
  gap: 10px;
}

.view-fiche > button {
  align-self: flex-start;
}

.view .expressions,
.view .patterns {
  gap: 10px;
}

.expression {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  column-gap: 16px;
  padding: 10px 14px;
  border: var(--stroke);
  border-radius: 14px;
  background: var(--paper);
}

.expression-ja {
  font-size: 21px;
  font-weight: 800;
  line-height: 1.3;
}

.expression-reading {
  grid-column: 1;
  color: var(--grey);
  font-size: 12.5px;
  font-weight: 700;
}

.expression-meaning {
  grid-column: 2;
  grid-row: 1 / span 2;
  align-self: center;
  font-weight: 700;
}

.expression-note {
  grid-column: 1 / -1;
  margin-top: 4px;
  color: var(--grey);
  font-size: 13px;
}

.pattern {
  display: grid;
  gap: 8px;
  padding: 16px;
  border: var(--stroke);
  border-radius: 16px;
  background: var(--yellow-soft);
}

.pattern-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 14px;
  font-weight: 700;
}

.pattern-head strong {
  padding: 0 10px;
  border: var(--stroke);
  border-radius: 10px;
  background: var(--pink);
  font-size: 22px;
}

/* Le mot de la sensei : une bulle. */
.sensei-note {
  display: grid;
  gap: 4px;
  padding: 18px 22px;
  border: var(--stroke);
  border-radius: 24px 24px 24px 4px;
  background: var(--paper);
  box-shadow: var(--shadow-small);
  font-size: 16px;
  font-weight: 700;
}

.sensei-note cite {
  color: var(--rose);
  font-size: 12px;
  font-style: normal;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.snapshots {
  display: grid;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

.snapshots li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 16px;
  padding: 14px 0;
  border-top: var(--stroke);
}

.snapshots li > div:first-child {
  display: grid;
  gap: 2px;
}

.snapshots li span {
  color: var(--grey);
  font-size: 13px;
}

.snapshot-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
}

/* --- Cours : le tête-à-tête ----------------------------------------------------------
   Une seule scène : la sensei d'un côté, ce qu'elle dit de l'autre. Avant le cours, elle annonce
   ce qui attend l'élève et il n'y a qu'un geste à faire. Pendant, sa dernière phrase, le tableau
   et la réponse de l'élève prennent la place de l'annonce. */

.lesson {
  display: flex;
  flex-direction: column;
  gap: 22px;
  padding: 32px clamp(16px, 3vw, 40px) 56px;
}

/* Pendant le cours : le thème à gauche, le temps à droite. */
.lesson-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 24px;
}

.lesson-title {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  font-family: var(--body);
  font-size: 19px;
  font-weight: 800;
  line-height: 1.3;
}

.lesson-time {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 13px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.time-track {
  width: 170px;
  height: 16px;
  overflow: hidden;
  border: var(--stroke);
  border-radius: 999px;
  background: var(--paper);
}

.time-fill {
  --done: 0;
  display: block;
  width: 100%;
  height: 100%;
  background: var(--pink);
  transform: scaleX(var(--done));
  transform-origin: left;
}

/* La scène. La sensei est posée en bas à gauche ; sur un écran étroit, elle passe au-dessus. */
.stage {
  display: flex;
  flex-wrap: wrap-reverse;
  gap: 0 36px;
  padding: 36px clamp(18px, 4vw, 44px) 0;
  border: var(--stroke);
  border-radius: 24px;
  background-color: var(--pink-soft);
  background-image: radial-gradient(var(--pink-mid) 1.6px, transparent 2px);
  background-size: 12px 12px;
  box-shadow: var(--shadow);
}

.stage-sensei {
  position: relative;
  flex: 0 1 380px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-width: 0;
  margin: 0 auto;
}

/* La sensei sans le décor de sa salle : le même dessin que sur l'accueil, et il vit. */
.stage-avatar {
  position: relative;
  width: 100%;
  aspect-ratio: 8 / 9;
}

/* Les bulles et le tableau passent devant la sensei : sa main levée ne cache jamais ce qui est écrit. */
.stage-side {
  position: relative;
  z-index: 1;
  flex: 1 1 420px;
  align-self: center;
  display: flex;
  flex-direction: column;
  gap: 22px;
  min-width: 0;
  padding-bottom: 40px;
}

.stage-before,
.stage-live,
.draft {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 22px;
}

.stage-live {
  align-items: stretch;
}

/* Une bulle : ce que dit la sensei. Sa pointe est tournée vers elle. */
.says {
  position: relative;
  padding: 24px 30px 26px;
  border: var(--stroke);
  border-radius: 36px;
  background: var(--paper);
}

.says::after {
  content: "";
  position: absolute;
  bottom: 44px;
  left: -12px;
  width: 20px;
  height: 20px;
  border-bottom: var(--stroke);
  border-left: var(--stroke);
  background: var(--paper);
  transform: rotate(45deg);
}

.says-hello {
  margin-bottom: 6px;
  color: var(--rose);
  font-weight: 800;
}

.says h1 {
  font-size: clamp(24px, 3.03vw, 36px);
  line-height: 1.2;
}

.says-text {
  margin-top: 14px;
  font-size: 16px;
}

/* Pendant le cours : sa dernière phrase, en grand. */
.says-live {
  align-self: flex-start;
  padding: 20px 28px 22px;
  border-radius: 34px;
  font-size: clamp(17px, 2.02vw, 22px);
  font-weight: 800;
  line-height: 1.35;
  overflow-wrap: anywhere;
}

.says-live::after {
  bottom: 28px;
}

/* Ce que l'élève vient de dire : à droite, sur jaune, la pointe vers le bas. */
.says-user {
  align-self: flex-end;
  padding: 12px 24px 14px;
  border-radius: 30px;
  background: var(--yellow);
  font-size: 18px;
  font-weight: 800;
  line-height: 1.35;
  overflow-wrap: anywhere;
}

.says-user::after {
  right: 34px;
  bottom: -12px;
  left: auto;
  border-right: var(--stroke);
  border-left: 0;
  background: var(--yellow);
}

.says-user small {
  display: block;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* Le bouton d'entrée en cours. */
button.cta {
  min-height: 64px;
  padding: 0 34px;
  border-radius: 18px;
  font-size: 19px;
  box-shadow: 6px 6px 0 var(--pink);
}

button.cta:hover:not(:disabled) {
  box-shadow: 7px 7px 0 var(--pink);
}

button.cta:active:not(:disabled) {
  box-shadow: 1px 1px 0 var(--pink);
}

/* Le démarrage à la voix : une ligne sous le bouton, avec une oreille qui bat quand elle écoute. */
.voice-start {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: baseline;
  gap: 4px 10px;
  padding: 6px 12px 8px;
  background: var(--paper);
  font-size: 13px;
  font-weight: 700;
}

.voice-start button {
  grid-column: 2;
  justify-self: start;
}

.voice-ear {
  align-self: center;
  width: 14px;
  height: 14px;
  border: var(--stroke);
  border-radius: 50%;
  background: var(--paper);
}

.voice-ear[data-on="true"] {
  background: var(--mint);
  animation: voice-ear 1.6s ease-in-out infinite;
}

@keyframes voice-ear {
  50% {
    scale: 1.35;
  }
}

@media (prefers-reduced-motion: reduce) {
  .voice-ear[data-on="true"] {
    animation: none;
  }
}

.level-field {
  display: grid;
  gap: 4px;
  padding: 2px 10px 8px;
  background: var(--paper);
  font-size: 13px;
  font-weight: 800;
}

/* Un cours interrompu : la sensei propose de le reprendre, ou d'en tirer la fiche. */
.draft .says {
  font-size: 16px;
  font-weight: 800;
}

.draft-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
}

/* L'image de l'élève, en vignette dans un coin comme en visio. Elle est en miroir : on se
   reconnaît mieux ainsi. */
.self {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
  display: grid;
  gap: 6px;
  width: 34%;
  pointer-events: none;
}

.self-view {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border: var(--stroke);
  border-radius: 12px;
  background: var(--ink);
  transform: scaleX(-1);
}

/* Ce que la sensei voit de l'élève, dit à l'élève : rien ne lui est caché. */
.seen {
  justify-self: start;
  width: max-content;
  max-width: 260%;
  padding: 4px 10px;
  border-radius: 8px;
  background: var(--ink);
  color: var(--paper);
  font-size: 12px;
  font-weight: 700;
  line-height: 1.3;
}

/* La sensei prépare le cours, ou la fiche : une bulle au-dessus d'elle, dont la pointe descend. */
.thinking {
  position: absolute;
  top: 0;
  right: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: 62%;
  padding: 8px 14px;
  border: var(--stroke);
  border-radius: 18px;
  background: var(--paper);
  box-shadow: var(--shadow-small);
  font-size: 13px;
  font-weight: 800;
  line-height: 1.3;
}

.thinking::after {
  content: "";
  position: absolute;
  bottom: -10px;
  left: 26px;
  width: 14px;
  height: 14px;
  border-right: var(--stroke);
  border-bottom: var(--stroke);
  background: var(--paper);
  transform: rotate(45deg);
}

.thinking-dots {
  display: inline-flex;
  gap: 4px;
}

.thinking-dots i {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--ink);
  animation: thinking-dot 1.2s ease-in-out infinite;
}

.thinking-dots i:nth-child(2) {
  animation-delay: 0.2s;
}

.thinking-dots i:nth-child(3) {
  animation-delay: 0.4s;
}

@keyframes thinking-dot {
  0%,
  60%,
  100% {
    opacity: 0.25;
  }
  30% {
    opacity: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .thinking-dots i {
    animation: none;
  }
}

/* Le tableau : la phrase que la sensei enseigne, découpée, entre ce qu'elle dit et ce que l'élève répond. */
.board {
  display: grid;
  gap: 10px;
  padding: 16px 20px 18px;
  border: var(--stroke);
  border-radius: 18px;
  background: var(--ink);
  color: var(--paper);
  box-shadow: 6px 6px 0 var(--pink);
}

/* « À toi » : la sensei attend une phrase. Le tableau ne montre que sa question. */
.board-turn {
  justify-self: start;
  padding: 2px 10px;
  border-radius: 999px;
  background: var(--yellow);
  color: var(--ink);
  font-size: 12.5px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.board-pattern {
  color: var(--yellow);
  font-size: 12.5px;
  font-weight: 800;
}

.board-meaning {
  font-size: 14px;
  font-weight: 700;
}

/* Une phrase découpée en groupes : japonais, lecture, sens. */
.segments {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 6px;
}

.seg {
  display: grid;
  justify-items: center;
  align-content: center;
  padding: 4px 9px;
  border: 2px solid var(--ink);
  border-radius: 10px;
  background: var(--paper);
}

.seg-ja {
  font-size: 20px;
  font-weight: 800;
  line-height: 1.25;
}

.seg-reading,
.seg-gloss {
  font-size: 12px;
  line-height: 1.25;
}

.seg-reading {
  font-weight: 700;
}

/* Les particules portent le rôle du mot qui précède : elles ressortent. */
.seg-particule {
  background: var(--pink);
  transform: rotate(-3deg);
}

.seg-verbe {
  background: var(--yellow-soft);
}

.board .segments {
  gap: 8px;
}

.board .seg {
  padding: 5px 13px;
  border-color: var(--paper);
  border-radius: 12px;
  background: none;
}

.board .seg-ja {
  font-size: clamp(20px, 2.43vw, 28px);
}

.board .seg-reading,
.board .seg-gloss {
  font-size: 12px;
}

.board .seg-particule {
  border-color: var(--pink);
  background: var(--pink);
  color: var(--ink);
}

.board .seg-verbe .seg-ja {
  color: var(--yellow);
}

/* Le morceau qui vient de changer. */
.seg-focus {
  outline: 3px solid var(--yellow);
  outline-offset: 2px;
  animation: seg-pop 0.5s ease-out;
}

@keyframes seg-pop {
  from {
    scale: 1.18;
  }
  to {
    scale: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .seg-focus {
    animation: none;
  }
}

/* Sous la scène : l'état du cours, d'un mot. */
.status {
  align-self: center;
  min-height: 38px;
  padding: 5px 18px;
  border: var(--stroke);
  border-radius: 999px;
  font-size: 13px;
  font-weight: 800;
  text-align: center;
}

.lesson-retry {
  align-self: center;
}

.lesson > .lead-small {
  text-align: center;
}

/* Une aide à suivre sans parler : un constat, puis des étapes numérotées. */
.check-help {
  display: grid;
  gap: 10px;
  justify-items: start;
  padding: 14px 16px;
  border: var(--stroke);
  border-radius: 14px;
  background: var(--yellow);
  font-size: 13px;
}

.check-help p {
  font-weight: 800;
}

.check-help ol {
  display: grid;
  gap: 4px;
  margin: 6px 0 0;
  padding-left: 1.3em;
}

.check-help label {
  display: grid;
  gap: 4px;
  font-weight: 800;
}

/* Les gestes du cours, en ligne sous la scène. */
.controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 14px 16px;
  margin-top: 4px;
}

.controls button {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 56px;
  padding: 0 22px;
  border-radius: 999px;
  box-shadow: none;
}

.controls #lost {
  background: var(--yellow);
  box-shadow: var(--shadow-small);
}

.controls #stop {
  background: var(--ink);
  color: var(--paper);
}

/* Le niveau du micro, dans son bouton. */
.meter-track {
  height: 16px;
  overflow: hidden;
  border: var(--stroke);
  border-radius: 999px;
  background: var(--paper);
}

.meter-mini {
  width: 46px;
  height: 14px;
  border-width: 2px;
}

.meter-fill {
  --level: 0;
  display: block;
  width: 100%;
  height: 100%;
  background: var(--ink);
  transform: scaleX(var(--level));
  transform-origin: left;
  transition: transform 0.08s linear;
}

@media (prefers-reduced-motion: reduce) {
  .meter-fill {
    transition: none;
  }
}

.lesson-foot {
  font-size: 13px;
  text-align: center;
}

/* Avant le cours : trois rappels, sans cadre. */
.reminders {
  display: flex;
  flex-wrap: wrap;
  gap: 24px 40px;
  margin: 14px 0 0;
  padding: 0;
  list-style: none;
  font-size: 14px;
}

.reminder {
  flex: 1 1 260px;
  display: flex;
  align-items: flex-start;
  gap: 14px;
  min-width: 0;
}

.reminder strong {
  display: block;
}

.reminder a {
  font-weight: 800;
}

.reminder-icon {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border: var(--stroke);
  border-radius: 14px;
  background: var(--paper);
}

.reminder-yellow {
  background: var(--yellow);
}

.reminder-pink {
  background: var(--pink-mid);
}

/* Sous la scène, à la demande : toute la conversation, puis la fiche du cours. */
.lesson > .view {
  padding: clamp(18px, 3vw, 28px);
  border: var(--stroke);
  border-radius: 20px;
  background: var(--paper);
  box-shadow: var(--shadow);
}

.view-transcript h2 {
  margin-bottom: 14px;
  font-family: var(--body);
  font-size: 12.5px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* La marge laisse la place aux ombres des bulles. */
.log {
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-height: 460px;
  overflow-y: auto;
  padding: 2px 10px 10px 2px;
}

.empty {
  margin: auto;
  color: var(--grey);
  text-align: center;
}

.bubble {
  max-width: 86%;
  padding: 10px 16px;
  border: var(--stroke);
  font-weight: 700;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.bubble small {
  display: block;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.bubble.sensei-line {
  align-self: flex-start;
  border-radius: 22px 22px 22px 4px;
  background: var(--paper);
  box-shadow: var(--shadow-small);
}

.bubble.sensei-line small {
  color: var(--rose);
}

.bubble.user-line {
  align-self: flex-end;
  border-radius: 22px 22px 4px 22px;
  background: var(--yellow);
}

@media (max-width: 720px) {
  /* Sur un téléphone, la sensei passe au-dessus, plus petite, comme derrière un comptoir. */
  .stage {
    flex-direction: column;
    flex-wrap: nowrap;
    gap: 22px;
    padding-top: 22px;
  }

  .stage-sensei {
    flex: none;
    align-self: stretch;
    align-items: center;
    margin: 0;
    border-bottom: var(--stroke);
  }

  .stage-avatar {
    width: min(250px, 78%);
  }

  .stage-side {
    align-self: stretch;
    padding-bottom: 26px;
  }

  /* La pointe des bulles monte vers elle. */
  .says::after,
  .says-live::after {
    top: -12px;
    bottom: auto;
    left: 44px;
    border-top: var(--stroke);
    border-bottom: 0;
  }

  .says-user::after {
    top: auto;
    bottom: -12px;
    left: auto;
    border-top: 0;
    border-bottom: var(--stroke);
  }

  button.cta {
    align-self: stretch;
    justify-content: center;
    padding: 0 18px;
  }

  .time-track {
    width: 110px;
  }
}

/* --- Jeux ---------------------------------------------------------------------------
   Grandes cibles tactiles, une seule colonne : le téléphone d'abord. */

.hub {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 28px;
}

.game {
  gap: 18px;
}

.game-head {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 12px;
}

.game-head .link {
  justify-self: start;
  min-height: 44px;
  text-decoration: none;
}

.game-progress {
  padding: 2px 12px;
  border: var(--stroke);
  border-radius: 999px;
  font-size: 12.5px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.game-progress:empty {
  visibility: hidden;
}

.game-title {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 14px;
}

.game-title h2 {
  font-size: 24px;
}

.question {
  display: grid;
  gap: 16px;
}

.prompt {
  font-size: 19px;
  font-weight: 800;
  line-height: 1.35;
}

.verdict {
  font-weight: 800;
}

.score {
  font-size: 54px;
  line-height: 1.1;
}

.phrase {
  display: grid;
  gap: 2px;
}

.phrase-ja {
  font-size: 22px;
  font-weight: 800;
  line-height: 1.3;
}

.phrase-reading {
  font-size: 12.5px;
  font-weight: 700;
}

.particle-sentence {
  font-size: 22px;
  font-weight: 800;
}

/* Une tuile : une réponse à toucher. */
.tile {
  min-height: 62px;
  padding: 8px 16px;
  font-weight: 700;
  text-align: left;
}

.tile-ja,
.tile[lang="ja"] {
  font-size: 22px;
  font-weight: 800;
  text-align: center;
}

/* Une tuile jouée reste lisible : elle se pose, sans pâlir. */
.tile:disabled {
  border-style: solid;
  opacity: 1;
}

.tile.is-chosen {
  background: var(--yellow);
}

.tile.is-right,
.builder-answer.is-right .tile {
  background: var(--mint);
}

.tile.is-wrong,
.builder-answer.is-wrong .tile {
  background: var(--coral);
}

.choices {
  display: grid;
  gap: 12px;
}

.choices:has(.tile[lang="ja"]) {
  grid-template-columns: repeat(2, 1fr);
}

.pairs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

.pairs-column {
  display: grid;
  align-content: start;
  gap: 12px;
}

.builder-answer,
.builder-pool {
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
  gap: 10px;
  min-height: 86px;
  padding: 12px;
  border-radius: 18px;
}

.builder-answer {
  border: 3px dashed var(--ink);
}

.builder-pool {
  border: 3px dashed var(--dash);
}

.builder-pool .tile {
  background: var(--yellow);
}

.missed {
  display: grid;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.missed li {
  display: grid;
  gap: 2px;
  padding: 10px 14px;
  border: var(--stroke);
  border-radius: 14px;
}

.game-actions {
  display: grid;
  gap: 12px;
}

.game .game-actions .link {
  justify-self: start;
}

.challenge-line {
  padding: 12px 16px;
  border: var(--stroke);
  border-radius: 14px;
  background: var(--yellow);
  font-weight: 800;
}

/* Karuta : les cartes sont étalées, comme sur un tatami. */
.karuta {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}

.karuta .tile {
  min-height: 88px;
}

/* Ce que dit un personnage, dans « la bonne réplique » et le shiritori. */
.speech {
  display: grid;
  gap: 2px;
  padding: 12px 16px;
  border: var(--stroke);
  border-radius: 4px 20px 20px 20px;
  background: var(--paper);
  box-shadow: var(--shadow-small);
}

.speech strong,
.story-speaker {
  color: var(--rose);
  font-size: 12px;
  font-weight: 800;
}

.story {
  display: grid;
  gap: 12px;
  margin: 0;
  padding-left: 1.5em;
}

.story li {
  display: grid;
  gap: 2px;
}

.story li::marker {
  font-weight: 800;
}

/* Dans une tuile japonaise, la lecture et le sens restent discrets. */
.tile .phrase-reading {
  font-weight: 400;
}

/* Pluie de kana : le kana descend dans le couloir, les lectures sont en dessous. */
.kana-lane {
  --fall: 190px;
  position: relative;
  height: 270px;
  overflow: hidden;
  border: var(--stroke);
  border-radius: 18px;
  /* Deux couches de fond : le sol du couloir (une bande rose sous un trait d'encre, coupée par
     les coins arrondis du cadre), puis la trame de points. */
  background-color: var(--paper);
  background-image:
    linear-gradient(to top, var(--pink) 10px, var(--ink) 10px, var(--ink) 13px, transparent 13px),
    var(--dots);
  background-repeat: no-repeat, repeat;
  background-position: 0 0;
  background-size: 100% 100%, 14px 14px;
}

.kana-drop {
  position: absolute;
  top: 4px;
  left: 50%;
  padding: 0 14px;
  border: var(--stroke);
  border-radius: 14px;
  background: var(--yellow);
  font-size: 48px;
  font-weight: 800;
  line-height: 1.25;
  translate: -50% 0;
  animation: kana-fall linear forwards;
}

.kana-drop.is-right {
  background: var(--mint);
}

.kana-drop.is-wrong {
  background: var(--coral);
}

@keyframes kana-fall {
  to {
    translate: -50% var(--fall);
  }
}

.choices.kana-choices {
  grid-template-columns: repeat(3, 1fr);
}

.kana-choices .tile {
  font-size: 18px;
  font-weight: 800;
  text-align: center;
}

/* Sans mouvement : le kana reste au milieu du couloir, le temps pour répondre est le même. */
@media (prefers-reduced-motion: reduce) {
  .kana-drop {
    top: 35%;
    animation: none;
  }
}

/* --- Administration -----------------------------------------------------------------
   Des tableaux à lire sur un écran d'ordinateur ; sur un téléphone, ils défilent de côté. */

.admin-view {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 28px;
}

.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(250px, 100%), 1fr));
  gap: 24px;
}

.stat {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 20px 22px;
  border: var(--stroke);
  border-radius: 18px;
  background: var(--paper);
  box-shadow: 6px 6px 0 var(--ink);
  font-size: 13px;
}

.stat:first-child {
  background: var(--yellow);
}

.stat-label {
  font-weight: 800;
}

.stat strong {
  font-family: var(--display);
  font-size: 32px;
  font-weight: 400;
  line-height: 1.25;
}

.card h2 .tag {
  margin-left: 12px;
}

.table-wrap {
  overflow-x: auto;
}

.grid {
  width: 100%;
  min-width: 620px;
  border-collapse: collapse;
  font-size: 14px;
  font-variant-numeric: tabular-nums;
}

.grid th,
.grid td {
  padding: 14px 20px 14px 0;
  border-top: var(--stroke);
  text-align: left;
  vertical-align: top;
}

.grid th:last-child,
.grid td:last-child {
  padding-right: 0;
}

.grid th {
  padding-top: 0;
  padding-bottom: 12px;
  border-top: 0;
  font-size: 12.5px;
  font-weight: 800;
  white-space: nowrap;
}

.grid tfoot td {
  font-weight: 800;
}

.grid .num,
.grid td:first-child {
  white-space: nowrap;
}

.grid .num {
  font-weight: 800;
  text-align: right;
}

.grid td:first-child .link {
  font-size: 17px;
}

.grid .sub {
  display: block;
  color: var(--grey);
  font-size: 12.5px;
  font-weight: 400;
}

.grid .tag {
  margin-left: 10px;
}

.grid .read {
  display: block;
  margin-top: 4px;
  font-size: 13px;
}

.facts {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 10px 24px;
  margin: 0;
  font-size: 14px;
}

.facts dt {
  font-weight: 800;
}

.facts dd {
  margin: 0;
}

@media (max-width: 520px) {
  .facts {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
  }

  .facts dd {
    margin-bottom: 10px;
  }
}

/* Un réglage : son titre, ce qu'il fait, puis son bouton. */
.setting {
  display: grid;
  gap: 10px;
  padding-top: 18px;
  border-top: var(--stroke);
}

.inline-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 14px;
}

.inline-actions label {
  font-size: 13px;
  font-weight: 800;
}

.inline-actions input[type="text"],
.inline-actions input[type="password"] {
  flex: 1 1 180px;
  width: auto;
  max-width: 280px;
}

.inline-actions .check {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 48px;
  font-weight: 700;
  cursor: pointer;
}

/* Les jeux qu'on peut donner à un élève : une case, le dessin du jeu, son nom. */
.game-toggles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(250px, 100%), 1fr));
  gap: 12px;
}

.game-toggles label {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 12px;
  border: var(--stroke);
  border-radius: 14px;
  font-weight: 800;
  cursor: pointer;
}

.game-toggles label:has(input:not(:checked)) {
  border-style: dashed;
  color: var(--grey);
}

.game-toggles label:has(input:not(:checked)) .game-art {
  filter: grayscale(1);
  opacity: 0.6;
}

.errors {
  display: grid;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 12.5px;
}

.errors li {
  display: grid;
  gap: 2px;
}

.errors time {
  font-weight: 800;
}

.errors code {
  overflow-wrap: anywhere;
  white-space: pre-wrap;
}

/* Ce qui s'est dit pendant un cours, ligne après ligne. */
.transcript {
  display: grid;
  gap: 12px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.transcript li {
  display: grid;
  gap: 2px;
  justify-self: start;
  max-width: min(46rem, 92%);
  padding: 10px 16px;
  border: var(--stroke);
  border-radius: 22px 22px 22px 4px;
}

.transcript li.is-user {
  justify-self: end;
  border-radius: 22px 22px 4px 22px;
  background: var(--yellow);
}

.transcript-who {
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

/* --- Écrans étroits ------------------------------------------------------------------ */

@media (max-width: 560px) {
  :root {
    --shadow: 6px 6px 0 var(--ink);
  }

  .top {
    justify-content: space-between;
    gap: 10px 14px;
  }

  .top nav {
    flex: 1 1 100%;
    order: 3;
  }

  .top nav a {
    flex: 1 1 auto;
    justify-content: center;
    min-height: 42px;
    padding: 0 12px;
  }

  .page {
    gap: 24px;
    padding-top: 24px;
  }

  .login-hello {
    gap: 18px;
  }

  .portrait-small {
    width: 92px;
  }

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

  .expression-meaning {
    grid-column: 1;
    grid-row: auto;
  }
}
