/* GENERATED by scripts/build-widgets.mjs from src/components/board/widgets.css — edit that file, not this one. */
/* ═══════════════════════════════════════════════════════════════════════════
   AOA widget cards — one stylesheet for every surface.

   Loaded three ways, which is why it is SELF-CONTAINED:
     • imported by the board bundle (React overlay + lesson board-embeds)
     • copied to /notes-runtime/widgets.css for the lesson player and blog
     • copied to /notes-runtime/preview/ for the CMS preview iframe
   (the copies are generated — scripts/build-widgets.mjs. Edit this file only.)

   On a lesson page none of board.css is present, so nothing here may depend on
   an --aoa-board-* variable. Every token is defined below with its own
   fallback, and light mode is opted into by whichever of the site's three
   theme hooks the host page happens to use.

   Layout note: a card is laid out at its WORLD size and scaled by the board
   overlay's transform, so type, bars and radii all shrink together. That is
   why there are no per-zoom font rules here — only the .is-mini collapse.
   ═══════════════════════════════════════════════════════════════════════════ */

.aoaw {
  /* ── Tokens ─────────────────────────────────────────────────────────────── */
  --aoaw-accent: #d4a437;
  --aoaw-accent-soft: rgba(212, 164, 55, 0.16);
  --aoaw-ink: #f3ece0;
  --aoaw-ink-dim: rgba(243, 236, 224, 0.58);
  --aoaw-surface: rgba(30, 22, 12, 0.82);
  --aoaw-surface-2: rgba(56, 42, 22, 0.5);
  --aoaw-hairline: rgba(212, 164, 55, 0.24);
  --aoaw-bar: rgba(243, 236, 224, 0.26);
  --aoaw-shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 14px 34px -20px rgba(0, 0, 0, 0.85);
  --aoaw-radius: 14px;
  /* Written by widgetRuntime, read by the ring and the waveform fill. */
  --aoaw-progress: 0;
  --aoaw-hover: 0;

  position: relative;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 7px;
  padding: 10px 13px;
  border: 1px solid var(--aoaw-hairline);
  border-radius: var(--aoaw-radius);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0) 42%),
    var(--aoaw-surface);
  box-shadow: var(--aoaw-shadow);
  color: var(--aoaw-ink);
  font-family: inherit;
  font-size: 13px;
  line-height: 1.35;
  text-align: start;
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  transition: border-color .18s ease, box-shadow .18s ease, transform .18s ease;
}

.aoaw * { box-sizing: border-box; }

.aoaw:hover { border-color: rgba(212, 164, 55, 0.44); }

/* The gold aura is the "this one is playing" signal at a glance, across a whole
   board of cards. Kept as a box-shadow so it costs no layout and no extra node. */
.aoaw.is-playing {
  border-color: rgba(212, 164, 55, 0.62);
  box-shadow: var(--aoaw-shadow), 0 0 0 1px rgba(212, 164, 55, 0.28),
              0 0 26px -6px rgba(212, 164, 55, 0.42);
}

.aoaw.is-error { border-color: rgba(232, 122, 106, 0.55); }
.aoaw.is-error::after {
  content: 'Не удалось загрузить';
  position: absolute;
  inset-inline-start: 13px;
  bottom: 3px;
  font-size: 10px;
  letter-spacing: .02em;
  color: #e87a6a;
}

/* ── Head row: who · what · who is listening ────────────────────────────── */

.aoaw-head {
  display: flex;
  align-items: center;
  gap: 7px;
  min-height: 16px;
  font-size: 10.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--aoaw-ink-dim);
}
.aoaw-head.is-foot { margin-top: auto; text-transform: none; letter-spacing: 0; }

.aoaw-by {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-width: 0;
  color: var(--aoaw-ink);
  text-transform: none;
  letter-spacing: 0;
  font-size: 11.5px;
  font-weight: 600;
}
.aoaw-by-dot {
  display: inline-grid;
  place-items: center;
  width: 17px;
  height: 17px;
  flex: 0 0 auto;
  border-radius: 999px;
  background: var(--aoaw-by-color, var(--aoaw-accent));
  color: #17110a;
  font-size: 8.5px;
  font-weight: 800;
  letter-spacing: 0;
  /* An author colour is a collab cursor colour — arbitrary, and sometimes pale.
     The ring keeps a light dot legible on the light surface too. */
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.25) inset;
}
.aoaw-by-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 11ch;
}

.aoaw-kicker {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* With an author present the kicker is secondary; alone, it carries the row. */
.aoaw-by ~ .aoaw-kicker { opacity: .62; }

.aoaw-live {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-inline-start: auto;
  padding: 2px 7px 2px 4px;
  border-radius: 999px;
  background: var(--aoaw-accent-soft);
  color: var(--aoaw-ink);
  font-size: 9.5px;
  letter-spacing: .04em;
  white-space: nowrap;
}
.aoaw-live[hidden] { display: none; }
.aoaw-live-dot {
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: var(--aoaw-accent);
  animation: aoaw-listen 1.5s ease-in-out infinite;
}
.aoaw-live-dot:nth-child(2) { animation-delay: .18s; }
.aoaw-live-dot:nth-child(3) { animation-delay: .36s; }
.aoaw-live-dot:nth-child(4) { animation-delay: .54s; }
@keyframes aoaw-listen {
  0%, 100% { transform: scale(1);   opacity: .55; }
  50%      { transform: scale(1.4); opacity: 1; }
}

/* ── Main row ───────────────────────────────────────────────────────────── */

.aoaw-row {
  display: flex;
  align-items: center;
  gap: 11px;
  min-width: 0;
}

/* ── Play button + progress ring ────────────────────────────────────────── */

.aoaw-play {
  position: relative;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: radial-gradient(120% 120% at 30% 20%, #f0c463 0%, var(--aoaw-accent) 55%, #a97d1f 100%);
  color: #17110a;
  cursor: pointer;
  box-shadow: 0 2px 8px -2px rgba(212, 164, 55, 0.55);
  transition: transform .14s ease, box-shadow .18s ease;
}
.aoaw-play:hover { transform: scale(1.06); }
.aoaw-play:active { transform: scale(0.97); }
.aoaw-play:focus-visible { outline: 2px solid var(--aoaw-accent); outline-offset: 3px; }

.aoaw-ring {
  position: absolute;
  inset: -4px;
  width: calc(100% + 8px);
  height: calc(100% + 8px);
  transform: rotate(-90deg);
  pointer-events: none;
}
.aoaw-ring circle {
  fill: none;
  stroke-width: 2;
  /* r=20 → 2πr. Hard-coded because the viewBox is fixed and a CSS round-trip
     through calc() for a constant would only invite it to drift from the SVG. */
  stroke-dasharray: 125.664;
}
.aoaw-ring-bg { stroke: rgba(212, 164, 55, 0.16); }
.aoaw-ring-fg {
  stroke: var(--aoaw-accent);
  stroke-linecap: round;
  stroke-dashoffset: calc(125.664 * (1 - var(--aoaw-progress)));
  opacity: 0;
  transition: opacity .2s ease;
}
.aoaw.is-playing .aoaw-ring-fg { opacity: 1; }

.aoaw-play-ico { display: grid; place-items: center; width: 17px; height: 17px; }
.aoaw-play-ico svg { width: 100%; height: 100%; fill: currentColor; }
.aoaw-ico-pause { display: none; }
.aoaw.is-playing .aoaw-ico-play { display: none; }
.aoaw.is-playing .aoaw-ico-pause { display: block; }

/* Loading: the button breathes rather than swapping in a spinner, so the
   control never moves or changes size under a finger already on it. */
.aoaw.is-loading .aoaw-play { animation: aoaw-breathe 1.1s ease-in-out infinite; }
@keyframes aoaw-breathe {
  0%, 100% { box-shadow: 0 2px 8px -2px rgba(212, 164, 55, 0.55); }
  50%      { box-shadow: 0 2px 18px 0 rgba(212, 164, 55, 0.85); }
}

/* ── Waveform ───────────────────────────────────────────────────────────── */

.aoaw-wave {
  position: relative;
  flex: 1 1 auto;
  min-width: 40px;
  height: 30px;
  cursor: pointer;
  touch-action: none;          /* a horizontal drag scrubs; it must not scroll */
}
.aoaw-wave:focus-visible { outline: 2px solid var(--aoaw-accent); outline-offset: 4px; border-radius: 4px; }

.aoaw-wave-row {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  gap: 2px;
}
.aoaw-wave-row i {
  flex: 1 1 0;
  min-width: 1.5px;
  border-radius: 2px;
  background: var(--aoaw-bar);
  transition: background-color .2s ease;
}
/* The played half is a second, identical row clipped to the progress. One
   custom-property write per frame repaints the whole waveform — as opposed to
   toggling a class on all 48 bars, which is what audio.js does today and what
   a board holding a dozen cards cannot afford over a live canvas. */
.aoaw-wave-row.is-fill {
  clip-path: inset(0 calc(100% * (1 - var(--aoaw-progress))) 0 0);
}
.aoaw-wave-row.is-fill i {
  background: linear-gradient(180deg, #f0c463, var(--aoaw-accent));
}
.aoaw:dir(rtl) .aoaw-wave-row.is-fill {
  clip-path: inset(0 0 0 calc(100% * (1 - var(--aoaw-progress))));
}

.aoaw-wave-cursor {
  position: absolute;
  top: -2px;
  bottom: -2px;
  width: 1px;
  inset-inline-start: calc(100% * var(--aoaw-hover));
  background: var(--aoaw-ink);
  opacity: 0;
  transition: opacity .12s ease;
  pointer-events: none;
}
.aoaw-wave:hover .aoaw-wave-cursor { opacity: .5; }

.aoaw-time {
  flex: 0 0 auto;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
  color: var(--aoaw-ink-dim);
  min-width: 4ch;
  text-align: end;
}
.aoaw.is-playing .aoaw-time { color: var(--aoaw-accent); }

/* ── Title ──────────────────────────────────────────────────────────────── */

.aoaw-title {
  margin: 0;
  font-size: 12px;
  line-height: 1.4;
  color: var(--aoaw-ink-dim);
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
}
.aoaw-title[lang='ar'] { font-size: 14px; line-height: 1.6; }

/* ── Media ──────────────────────────────────────────────────────────────── */

.aoaw-thumb {
  flex: 0 0 auto;
  width: 52px;
  height: 40px;
  border-radius: 8px;
  background: var(--aoaw-surface-2) center / cover no-repeat;
  border: 1px solid var(--aoaw-hairline);
}
.aoaw-thumb.is-icon { display: grid; place-items: center; }
.aoaw-thumb.is-icon::before {
  content: '📄';
  font-size: 17px;
  line-height: 1;
  filter: grayscale(.3);
}
.aoaw-thumb.is-icon[data-variant='video']::before { content: '🎬'; }
.aoaw-thumb.is-icon[data-variant='pdf']::before   { content: '📕'; }
.aoaw-thumb.is-icon[data-variant='image']::before { content: '🖼'; }
.aoaw-thumb.is-icon[data-variant='link']::before  { content: '🔗'; }

.aoaw-media-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 auto; }
.aoaw-media-name {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--aoaw-ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.aoaw-media-meta {
  font-size: 10.5px;
  color: var(--aoaw-ink-dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.aoaw-open {
  flex: 0 0 auto;
  padding: 6px 11px;
  border: 1px solid var(--aoaw-hairline);
  border-radius: 999px;
  background: var(--aoaw-accent-soft);
  color: var(--aoaw-ink);
  font: inherit;
  font-size: 11px;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color .16s ease, border-color .16s ease;
}
.aoaw-open:hover { background: rgba(212, 164, 55, 0.28); border-color: rgba(212, 164, 55, 0.5); }

.aoaw-video {
  width: 100%;
  margin-top: 6px;
  border-radius: 10px;
  background: #000;
  display: none;
}
.aoaw--media.is-playing .aoaw-video { display: block; }

.aoaw-link { color: var(--aoaw-ink); font-weight: 600; font-size: 12.5px; text-decoration: none; }
.aoaw-link:hover { color: var(--aoaw-accent); text-decoration: underline; }

/* ── Embedded material ───────────────────────────────────────────────────────
   The content ON the board, instead of a row with «Открыть» that threw the
   board away to show it. An image is mounted at rest; a video, a player or a
   PDF is a poster until asked for — a dozen live iframes is a page that never
   finishes loading. */
.aoaw--media:has(.aoaw-embed) { gap: 6px; }
.aoaw-embed {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  border-radius: 9px;
  overflow: hidden;
  background: rgba(0, 0, 0, 0.28);
}
.aoaw-embed-img,
.aoaw-embed-media {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  object-fit: contain;
  background: rgba(0, 0, 0, 0.35);
}
/* A PDF wants the page top, not its middle. */
.aoaw--media[data-aoaw-embed-kind='pdf'] .aoaw-embed-media { object-fit: fill; }
.aoaw-embed-open {
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  position: relative;
}
.aoaw-embed-poster {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
}
.aoaw-embed-poster.is-icon {
  display: grid;
  place-items: center;
  background: rgba(var(--aoaw-ink-rgb, 243, 236, 224), 0.05);
}
.aoaw-embed-play {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.55);
  border: 1px solid var(--aoaw-hairline);
  color: var(--aoaw-ink);
  font-size: 18px;
}
.aoaw-embed-play svg { width: 17px; height: 17px; fill: currentColor; }
.aoaw-embed-open:hover .aoaw-embed-play { background: rgba(0, 0, 0, 0.72); }
.aoaw-embed-foot {
  display: flex;
  align-items: center;
  gap: 7px;
  flex: 0 0 auto;
  min-width: 0;
}
.aoaw-embed-foot .aoaw-media-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.aoaw-embed-out {
  flex: 0 0 auto;
  color: var(--aoaw-ink-dim);
  text-decoration: none;
  font-size: 13px;
  padding: 2px 4px;
  border-radius: 6px;
}
.aoaw-embed-out:hover { color: var(--aoaw-accent); }
/* A frame the CSP refused renders as a silent blank box; say so. */
.aoaw--media.is-error .aoaw-embed::after {
  content: 'Не удалось показать здесь — открой по стрелке';
  position: absolute;
  inset: auto 0 0;
  padding: 5px 8px;
  font-size: 10.5px;
  background: rgba(232, 122, 106, 0.9);
  color: #1b0806;
}
/* Zoomed far out an embed is a chip like everything else — but a PLAYING one
   keeps its picture, because that is what the room is looking at. */
.aoaw--media.is-mini .aoaw-embed,
.aoaw--media.is-mini .aoaw-embed-foot { display: none; }

/* ── Timer ──────────────────────────────────────────────────────────────── */

/* A clock, not a number with buttons next to it.
   Geometry and behaviour follow the app's practice «Timed» dial (GameChrome's
   TimedClockDial): an emptying arc, 60 tick marks with every fifth long, and
   the last fifth in red. Deliberately the same object a student already reads
   in the app — a countdown should not have to be learned twice.

   Everything is unitless (a 0–100 viewBox, em-based type), because this card is
   scaled by the canvas zoom, re-laid-out in a lesson and rendered into a
   poster, and a pixel-sized dial would only be right in one of the three. */
.aoaw-timer {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  min-height: 0;
}
.aoaw-dial {
  position: relative;
  /* Fills the card's height, never wider than tall — a dial is a circle. */
  flex: 1 1 auto;
  min-height: 0;
  aspect-ratio: 1;
  max-width: 100%;
  display: grid;
  place-items: center;
}
.aoaw-dial > svg { display: block; width: 100%; height: 100%; overflow: visible; }
.aoaw-dial-track {
  fill: none;
  stroke: rgba(243, 236, 224, 0.1);
  stroke-width: 5;
}
.aoaw-dial-arc {
  fill: none;
  stroke: var(--aoaw-accent);
  stroke-width: 5;
  stroke-linecap: round;
  /* Matches the app's 0.6s linear sweep: fast enough to look live, slow enough
     that a 60-frame update does not shimmer. */
  transition: stroke-dashoffset .6s linear, stroke .3s ease;
}
.aoaw-dial-tick {
  stroke: rgba(243, 236, 224, 0.2);
  stroke-width: 0.7;
}
.aoaw-dial-tick.is-major { stroke: rgba(243, 236, 224, 0.34); stroke-width: 1.3; }
.aoaw-dial-face {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  pointer-events: none;
}
.aoaw-dial-kicker {
  font-size: 8px;
  font-weight: 800;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--aoaw-ink-dim);
}
.aoaw-clock {
  font-size: 26px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
  letter-spacing: -.02em;
  line-height: 1;
  color: var(--aoaw-ink);
}
.aoaw--timer.is-playing .aoaw-clock { color: var(--aoaw-accent); }
/* The last fifth: the app's danger colour, on the arc AND the digits, so the
   cue is visible from the back of a room. */
.aoaw--timer.is-urgent .aoaw-dial-arc { stroke: #e87a6a; }
.aoaw--timer.is-urgent .aoaw-clock { color: #e87a6a; }
.aoaw--timer.is-done .aoaw-dial-arc { stroke: #e87a6a; }
.aoaw--timer.is-done .aoaw-clock { color: #e87a6a; animation: aoaw-flash 1s steps(2) 4; }
@keyframes aoaw-flash { 50% { opacity: .25; } }
.aoaw-timer-btns { display: flex; gap: 6px; flex: 0 0 auto; }
/* Mini zoom collapses every card to a disc; for a timer the DIAL is the disc,
   so it survives where the buttons do not. */
.aoaw--timer.is-mini > .aoaw-timer { display: flex; }
.aoaw--timer.is-mini .aoaw-timer-btns,
.aoaw--timer.is-mini .aoaw-dial-kicker { display: none; }
.aoaw--timer.is-mini .aoaw-clock { font-size: 13px; }
.aoaw-tbtn {
  padding: 6px 12px;
  border: 1px solid var(--aoaw-hairline);
  border-radius: 999px;
  background: var(--aoaw-accent-soft);
  color: var(--aoaw-ink);
  font: inherit;
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
}
.aoaw-tbtn.is-ghost { background: transparent; color: var(--aoaw-ink-dim); }
.aoaw-tbtn:hover { border-color: rgba(212, 164, 55, 0.5); }
/* The timer's ring lives on the card edge — there is no play button to hang it
   on, and a countdown wants a bar you can read from the back of a room. */
.aoaw--timer::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  height: 3px;
  width: calc(100% * (1 - var(--aoaw-progress)));
  background: linear-gradient(90deg, var(--aoaw-accent), #f0c463);
  border-radius: 0 0 0 var(--aoaw-radius);
  transition: width .25s linear;
}

/* ── Sticky ─────────────────────────────────────────────────────────────── */

.aoaw--sticky {
  --aoaw-surface: rgba(212, 164, 55, 0.92);
  --aoaw-ink: #241a09;
  --aoaw-ink-dim: rgba(36, 26, 9, 0.65);
  --aoaw-hairline: rgba(0, 0, 0, 0.12);
  justify-content: flex-start;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
.aoaw--sticky[data-tone='sky']  { --aoaw-surface: rgba(122, 178, 214, 0.92); }
.aoaw--sticky[data-tone='mint'] { --aoaw-surface: rgba(126, 199, 160, 0.92); }
.aoaw--sticky[data-tone='rose'] { --aoaw-surface: rgba(226, 141, 141, 0.92); }
.aoaw--sticky[data-tone='plum'] { --aoaw-surface: rgba(174, 145, 214, 0.92); }
.aoaw-sticky-text {
  margin: 0;
  font-size: 15px;
  line-height: 1.45;
  font-weight: 600;
  color: var(--aoaw-ink);
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 8;
  line-clamp: 8;
  -webkit-box-orient: vertical;
}

/* ── Poll ───────────────────────────────────────────────────────────────── */

.aoaw-q { margin: 0; font-size: 13px; font-weight: 600; color: var(--aoaw-ink); }
.aoaw-opts { display: flex; flex-direction: column; gap: 5px; }
.aoaw-opt {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  border: 1px solid var(--aoaw-hairline);
  border-radius: 9px;
  background: transparent;
  color: var(--aoaw-ink);
  font: inherit;
  font-size: 12px;
  text-align: start;
  cursor: pointer;
  overflow: hidden;
}
/* The result bar grows behind the label, so voting reveals the tally without
   the row changing height and shoving the options below it. */
.aoaw-opt-bar {
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  width: calc(100% * var(--aoaw-share, 0));
  background: var(--aoaw-accent-soft);
  transition: width .35s cubic-bezier(.22, 1, .36, 1);
}
.aoaw.is-voted .aoaw-opt-bar { background: rgba(212, 164, 55, 0.22); }
.aoaw-opt.is-mine { border-color: rgba(212, 164, 55, 0.6); }
.aoaw-opt-text { position: relative; flex: 1 1 auto; }
.aoaw-opt-count {
  position: relative;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--aoaw-ink-dim);
}

/* ── Poll as a mini-test ─────────────────────────────────────────────────────
   Same card, one extra fact (a correct index), so a question the class answers
   for practice needs no second widget. Nothing below applies until the card is
   answered — before that a test looks exactly like a poll, which is the point:
   the styling must not leak which option is right. */
.aoaw-opt-mark {
  position: relative;
  width: 15px;
  height: 15px;
  flex: 0 0 auto;
  display: none;
  place-items: center;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
}
.aoaw.is-answered .aoaw-opt.is-correct .aoaw-opt-mark,
.aoaw.is-answered .aoaw-opt.is-incorrect .aoaw-opt-mark { display: grid; }
.aoaw-opt.is-correct .aoaw-opt-mark {
  background: rgba(78, 190, 122, 0.9);
  color: #08130c;
}
.aoaw-opt.is-correct .aoaw-opt-mark::after { content: '✓'; }
.aoaw-opt.is-incorrect .aoaw-opt-mark {
  background: rgba(238, 108, 92, 0.9);
  color: #1b0806;
}
.aoaw-opt.is-incorrect .aoaw-opt-mark::after { content: '✕'; }

.aoaw.is-answered .aoaw-opt { cursor: default; }
.aoaw-opt.is-correct {
  border-color: rgba(78, 190, 122, 0.65);
  background: rgba(78, 190, 122, 0.09);
}
.aoaw-opt.is-incorrect {
  border-color: rgba(238, 108, 92, 0.6);
  background: rgba(238, 108, 92, 0.08);
}
/* The tally still shows — a class wants to see how the room split, and a
   student who got it wrong is not alone. */
.aoaw.is-answered .aoaw-opt:not(.is-correct):not(.is-incorrect) { opacity: 0.72; }

.aoaw-verdict {
  margin: 0;
  min-height: 15px;          /* reserved, so the card does not jump on answer */
  font-size: 11.5px;
  font-weight: 600;
  color: var(--aoaw-ink-dim);
}
.aoaw.is-right .aoaw-verdict { color: rgba(120, 214, 156, 0.95); }
.aoaw.is-wrong .aoaw-verdict { color: rgba(245, 146, 132, 0.95); }

/* ── Flashcard ───────────────────────────────────────────────────────────────
   The app's card, on the board (design/icons/flashcardWidget + the app's
   FigmaInfoView): a warm gradient face, a category kicker, the picture, the
   word in both languages — and on the back the Info / Dialect-info tables.

   Two faces, flipped in 3D. Both are in the DOM from the start, so the flip is
   a transform and nothing loads at the moment of turning it over. */

.aoaw--card {
  --aoaw-fc-tint: #9f4c2f;
  padding: 0;                    /* the faces run to the card's edge */
  overflow: visible;             /* the flip must not be clipped mid-turn */
  background: transparent;
  border: none;
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
.aoaw-fc-scene {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  perspective: 1100px;
  cursor: pointer;
}
.aoaw-fc-flip {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  transition: transform .55s cubic-bezier(.2, .8, .25, 1);
}
.aoaw--card.is-flipped .aoaw-fc-flip { transform: rotateY(180deg); }
.aoaw-fc-side {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 16px 14px;
  box-sizing: border-box;
  border-radius: var(--aoaw-radius);
  overflow: hidden;
  /* Faces are opaque and BOTH hidden when turned away — without this the back
     shows through the front on every WebKit build. */
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  background:
    linear-gradient(to bottom, var(--aoaw-fc-tint) 5%, rgba(0, 0, 0, 0.42) 190%);
  box-shadow: var(--aoaw-shadow);
  color: #dedede;
}
.aoaw-fc-side.is-back { transform: rotateY(180deg); justify-content: flex-start; gap: 10px; }

/* A face that IS a picture — image mode draws nothing of its own. */
.aoaw-fc-img.is-full { width: 100%; height: 100%; object-fit: cover; border-radius: inherit; }
.aoaw-fc-side:has(> .aoaw-fc-img.is-full) { padding: 0; }

.aoaw-fc-kicker {
  align-self: flex-start;
  margin: 0;
  font-family: 'Abhaya Libre', 'Playfair Display', Georgia, serif;
  font-size: 21px;
  font-weight: 700;
  letter-spacing: -.02em;
  line-height: 1;
  color: #ededed;
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);
}
/* The art fills whatever is left between the kicker and the words. */
.aoaw-fc-art {
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  display: grid;
  place-items: center;
}
.aoaw-fc-art img {
  max-width: 82%;
  max-height: 100%;
  object-fit: contain;
  filter: drop-shadow(0 10px 18px rgba(0, 0, 0, 0.35));
}
.aoaw-fc-art.is-empty { opacity: .25; }
.aoaw-fc-words {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  flex: 0 0 auto;
}
.aoaw-fc-ru { font-size: 19px; font-weight: 700; line-height: 1.1; text-align: center; }
.aoaw-fc-ar {
  font-family: 'Amiri', 'Tajawal', 'Cairo', serif;
  font-size: 17px;
  line-height: 1.35;
  opacity: .92;
  text-align: center;
}

/* The back: word header, then the two bordered tables the app shows. */
.aoaw-fc-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
  width: 100%;
  padding-bottom: 2px;
}
.aoaw-fc-head .aoaw-fc-ru { font-size: 22px; }
.aoaw-fc-head .aoaw-fc-ar { font-size: 20px; }
.aoaw-fc-table {
  width: 100%;
  border: 1.5px solid rgba(222, 222, 222, 0.85);
  border-radius: 14px;
  padding: 8px 11px 9px;
  box-sizing: border-box;
}
.aoaw-fc-tlabel {
  margin: 0 0 4px;
  font-family: 'Abhaya Libre', 'Playfair Display', Georgia, serif;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -.02em;
}
.aoaw-fc-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  font-size: 11.5px;
  line-height: 1.7;
}
.aoaw-fc-k { font-weight: 600; opacity: .95; }
.aoaw-fc-v {
  font-family: 'Amiri', 'Tajawal', 'Cairo', serif;
  font-size: 12.5px;
  text-align: end;
  opacity: .92;
}

/* The flip button. On the board the card body is transparent to the pointer
   (so the element underneath can be selected), which makes this the only thing
   that can catch a click there — it is not decoration. */
.aoaw-fc-btn {
  position: absolute;
  right: 8px;
  bottom: 8px;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  padding: 0;
  border-radius: 999px;
  border: 1px solid rgba(222, 222, 222, 0.4);
  background: rgba(0, 0, 0, 0.28);
  color: #ededed;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  z-index: 2;
}
.aoaw-fc-btn:hover { background: rgba(0, 0, 0, 0.45); }
/* Mini zoom: the picture is still worth showing, the tables are not. */
.aoaw--card.is-mini { width: 100% !important; height: 100% !important; border-radius: var(--aoaw-radius); }
.aoaw--card.is-mini > .aoaw-fc-scene { display: block; }
.aoaw--card.is-mini .aoaw-fc-btn,
.aoaw--card.is-mini .aoaw-fc-kicker,
.aoaw--card.is-mini .aoaw-fc-table { display: none; }

/* ── Board placement ────────────────────────────────────────────────────── */

/* The overlay itself: above the canvas, transparent to the pointer except
   where a card is, so drawing anywhere else still works. Mirrors what
   .aoa-audio-layer did for the old pins. */
.aoa-widget-layer {
  position: absolute;
  inset: 0;
  z-index: 3;
  overflow: hidden;
  pointer-events: none;
}

/* The overlay positions this and scales it by the canvas zoom; the card inside
   is laid out at world size, so type and bars scale together instead of the
   card growing a second set of breakpoints. */
.aoaw-anchor {
  position: absolute;
  transform-origin: 0 0;
  pointer-events: none;
}
.aoaw-anchor > .aoaw {
  pointer-events: auto;
  width: 100%;
  height: 100%;
}

/* ── Selecting a card on the board ───────────────────────────────────────────
   A widget is a real Excalidraw element, but the card covering it used to eat
   every pointer event — so clicking one selected NOTHING. Moving or deleting a
   voice note meant rubber-banding around it from empty canvas, and on a busy
   board there often is none.

   So an on-board card's BODY is transparent to the pointer and its CONTROLS are
   not: click the padding, the title, the author chip or the waveform's
   surroundings and the canvas gets the event (select, drag, marquee, delete);
   click play, scrub, an option or ✎ and the card gets it. Two behaviours, no
   modifier key to remember.

   Scoped to `--onboard` because it is only true where a canvas is underneath.
   In a lesson the card is the whole thing and must keep catching everything. */
.aoaw-anchor > .aoaw--onboard { pointer-events: none; }
.aoaw--onboard button,
.aoaw--onboard a[href],
.aoaw--onboard input,
.aoaw--onboard [data-aoaw-wave] { pointer-events: auto; }

/* …except a FLASHCARD, whose whole face is the control: you flip it by
   pressing it anywhere. It cannot use the rule above — "the body is the
   canvas's" — because then there would be nothing left to press.

   So it takes the gesture and decides on the way UP (tapOrDrag): a press in
   place flips, and a movement past the threshold releases the card mid-gesture
   so the canvas gets the drag. That release is a `pointer-events: none` the
   runtime sets inline, which is why this rule only covers the resting state. */
.aoaw--card.aoaw--onboard .aoaw-fc-scene { pointer-events: auto; }
/* Feedback that a press registered before the flip animation starts — 120ms of
   nothing reads as a dead card. */
.aoaw--card.aoaw--onboard .aoaw-fc-scene:active .aoaw-fc-flip { transform: scale(.985); }
.aoaw--card.aoaw--onboard.is-flipped .aoaw-fc-scene:active .aoaw-fc-flip {
  transform: rotateY(180deg) scale(.985);
}

/* Excalidraw's own selection outline is drawn on the canvas UNDER the card, so
   on a card that fills its element it is invisible. This is that outline,
   repeated where it can be seen. */
.aoaw--onboard.is-selected {
  outline: 1.5px solid var(--aoaw-accent);
  outline-offset: 3px;
  border-radius: var(--aoaw-radius);
}

/* ✎ — re-open the note that is already on the board (caption, trim). Board
   only: a student has nothing to edit. Quiet until the card is hovered, so a
   dozen cards do not read as a dozen buttons. */
.aoaw-edit {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 24px;
  height: 24px;
  display: grid;
  place-items: center;
  padding: 0;
  border-radius: 7px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--aoaw-ink-dim);
  cursor: pointer;
  opacity: 0;
  transition: opacity .12s ease, color .12s ease, background-color .12s ease;
}
.aoaw-edit svg { width: 13px; height: 13px; display: block; }
.aoaw--onboard:hover .aoaw-edit,
.aoaw--onboard.is-selected .aoaw-edit,
.aoaw-edit:focus-visible { opacity: 1; }
.aoaw-edit:hover,
.aoaw-edit:focus-visible {
  color: var(--aoaw-ink);
  background: var(--aoaw-surface-2);
  border-color: var(--aoaw-hairline);
}
/* At mini zoom the card is a play button; a 13px pencil on it is a mis-tap. */
.aoaw.is-mini .aoaw-edit { display: none; }

/* ── Far zoom ────────────────────────────────────────────────────────────────
   Past FAR_SCALE the overlay stops shrinking the card and swaps it for this: a
   chip carrying the widget's key content, held at a readable size. A board at
   10 % renders a 320-wide card as 32 px — not small, gone — and the mini disc
   below is a play button with no words on it, so a zoomed-out board used to
   say only "there are twenty somethings here".

   Same DOM, one class: nothing remounts on a pinch. */
.aoaw-far {
  position: absolute;
  inset: 0;
  display: none;
  align-items: center;
  gap: 6px;
  padding: 0 9px;
  border-radius: var(--aoaw-radius);
  background: var(--aoaw-surface);
  border: 1px solid var(--aoaw-hairline);
  box-shadow: var(--aoaw-shadow);
  color: var(--aoaw-ink);
  overflow: hidden;
}
.aoaw.is-far > .aoaw-far { display: flex; }
/* Everything else steps aside. `> *` and not a descendant selector: the chip's
   own children must survive. */
.aoaw.is-far > *:not(.aoaw-far) { display: none; }
.aoaw.is-far {
  /* The chip is the card now — the card's own frame would double it. */
  background: transparent;
  border-color: transparent;
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  padding: 0;
}
.aoaw-far-ico { font-size: 13px; line-height: 1; flex: 0 0 auto; }
.aoaw-far-text {
  font-size: 13px;
  font-weight: 600;
  line-height: 1.2;
  /* Two lines, then ellipsis: one line loses the end of a poll question, and
     three make the chip taller than the thing it stands for. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* A sticky is its own colour at any zoom — that is how a board of stickies is
   read from across the room. */
.aoaw--sticky.is-far > .aoaw-far {
  background: var(--aoaw-surface);
  color: var(--aoaw-ink);
}
/* A flashcard keeps its tint, for the same reason. */
.aoaw--card.is-far > .aoaw-far {
  background: linear-gradient(to bottom, var(--aoaw-fc-tint, #9f4c2f), rgba(0, 0, 0, .35) 220%);
  border-color: rgba(222, 222, 222, .35);
  color: #ededed;
}
/* A running timer must be readable at ANY zoom — it is the one widget the whole
   room is watching, and it is why they zoomed out. */
.aoaw--timer.is-far > .aoaw-far { justify-content: center; }
.aoaw--timer.is-far .aoaw-far-text {
  font-size: 15px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.aoaw--timer.is-far.is-urgent > .aoaw-far { border-color: #e87a6a; }
.aoaw--timer.is-far.is-urgent .aoaw-far-text { color: #e87a6a; }

/* Below MINI_SCALE the card would be a smear of 4px type, so it collapses to
   its play button. Same DOM, one class — nothing remounts on a zoom gesture. */
.aoaw.is-mini {
  width: 56px !important;
  height: 56px !important;
  padding: 0;
  border-radius: 999px;
  gap: 0;
  place-items: center;
  display: grid;
}
.aoaw.is-mini > *:not(.aoaw-row) { display: none; }
.aoaw.is-mini .aoaw-row > *:not(.aoaw-play) { display: none; }
.aoaw.is-mini .aoaw-play { width: 40px; height: 40px; }
/* …except a timer, whose dial IS the disc — collapsing it to nothing would
   hide the one widget a zoomed-out room is actually watching. */
.aoaw--timer.is-mini > .aoaw-timer { display: flex; }
.aoaw--timer.is-mini .aoaw-dial { width: 100%; height: 100%; }

/* ── Over a poster ──────────────────────────────────────────────────────── */

/* `inset:0; margin:auto` + max-width/height 100% + the poster's own aspect
   ratio lands this EXACTLY where `object-fit: contain` puts the image in the
   same box. That equivalence is what lets the cards line up with the picture
   without measuring the image — at any container size, and before the image
   has even loaded. */
.aoaw-poster {
  position: absolute;
  inset: 0;
  margin: auto;
  max-width: 100%;
  max-height: 100%;
  z-index: 2;
  pointer-events: none;
  --aoaw-scale: 1;
}
/* Positioned in PERCENT of the poster, sized in WORLD px, scaled to match —
   so a card keeps its proportions inside the picture at every width. */
.aoaw-poster > .aoaw-anchor { transform: scale(var(--aoaw-scale)); }

.aoaw--embed { width: 100%; height: 100%; }

/* ── Markdown flow ──────────────────────────────────────────────────────── */

/* A `:::voice` block in prose: full width up to a comfortable measure, with the
   vertical rhythm the other note blocks use. */
.aoaw--flow {
  width: 100%;
  max-width: 560px;
  margin: 22px 0;
}

/* ── Light mode ─────────────────────────────────────────────────────────── */

:root[data-theme='light'] .aoaw,
html[data-sah-theme='light'] .aoaw,
html[data-admin-theme='light'] .aoaw,
.aoaw.is-light {
  --aoaw-ink: #2a2015;
  --aoaw-ink-dim: rgba(42, 32, 21, 0.6);
  --aoaw-surface: rgba(255, 252, 246, 0.92);
  --aoaw-surface-2: rgba(212, 164, 55, 0.1);
  --aoaw-hairline: rgba(154, 115, 31, 0.3);
  --aoaw-bar: rgba(42, 32, 21, 0.22);
  --aoaw-shadow: 0 1px 2px rgba(90, 70, 30, 0.1), 0 14px 30px -22px rgba(90, 70, 30, 0.5);
}
:root[data-theme='light'] .aoaw--sticky,
html[data-sah-theme='light'] .aoaw--sticky,
html[data-admin-theme='light'] .aoaw--sticky,
.aoaw--sticky.is-light { --aoaw-ink: #241a09; --aoaw-ink-dim: rgba(36, 26, 9, 0.65); }

/* ── Motion + print ─────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .aoaw,
  .aoaw-play,
  .aoaw-live-dot,
  .aoaw-opt-bar,
  .aoaw--timer::after { transition: none !important; animation: none !important; }
}

/* Lessons get printed. A card should still read as a labelled voice note with
   its duration, rather than as a dark rectangle with an invisible button. */
@media print {
  .aoaw {
    --aoaw-ink: #1a1a1a;
    --aoaw-ink-dim: #555;
    --aoaw-surface: #fff;
    --aoaw-bar: #c9c9c9;
    box-shadow: none;
    border-color: #bbb;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  .aoaw-live, .aoaw-video { display: none !important; }
}
