/* Sandy Rounded icons (assets/icons/sandy-rounded/: 24×24, stroke 1.65, round caps and joins).
   One shared, build-free way to draw them: a span whose colour comes from the text (currentColor) and whose shape is
   the SVG file used as a mask. Pages, nav.js and shared scripts all write the same markup:
     <span class="ui-icon ui-icon-read" aria-hidden="true"></span>
   The icon is always decorative; the button or link around it carries the accessible name.
   Sizes: 20px inline with text (default), 24px in the nav (assets/nav.css), 22px in icon-only buttons (.ui-icon-lg).
   Each class sets mask-image itself: a url() kept in a custom property can resolve against the page instead of this file.
   Linked on its own (not from site.css) because index.html (About + the nav for returning learners) doesn't load site.css.
   The class is .ui-icon, not .icon: vocab.html already has a .writing-action.icon button. */
/* :where() keeps the base at zero specificity, so a component rule (.sn-icon 24px, .ui-icon-lg) always sets the size */
:where(.ui-icon) {
  display: inline-block;
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  vertical-align: -.25em;
  background-color: currentColor;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}
.ui-icon-lg { width: 22px; height: 22px; }
/* Windows High Contrast: keep the shape and paint it in the forced text colour */
@media (forced-colors: active) { :where(.ui-icon) { forced-color-adjust: none; background-color: CanvasText; } }

.ui-icon-today { -webkit-mask-image: url("icons/sandy-rounded/today.svg"); mask-image: url("icons/sandy-rounded/today.svg"); }
.ui-icon-learn { -webkit-mask-image: url("icons/sandy-rounded/learn.svg"); mask-image: url("icons/sandy-rounded/learn.svg"); }
.ui-icon-practice { -webkit-mask-image: url("icons/sandy-rounded/practice.svg"); mask-image: url("icons/sandy-rounded/practice.svg"); }
.ui-icon-review { -webkit-mask-image: url("icons/sandy-rounded/review.svg"); mask-image: url("icons/sandy-rounded/review.svg"); }
.ui-icon-favorite { -webkit-mask-image: url("icons/sandy-rounded/favorite.svg"); mask-image: url("icons/sandy-rounded/favorite.svg"); }
.ui-icon-tag { -webkit-mask-image: url("icons/sandy-rounded/tag.svg"); mask-image: url("icons/sandy-rounded/tag.svg"); }
.ui-icon-read { -webkit-mask-image: url("icons/sandy-rounded/read.svg"); mask-image: url("icons/sandy-rounded/read.svg"); }
.ui-icon-muted { -webkit-mask-image: url("icons/sandy-rounded/muted.svg"); mask-image: url("icons/sandy-rounded/muted.svg"); }
.ui-icon-settings { -webkit-mask-image: url("icons/sandy-rounded/settings.svg"); mask-image: url("icons/sandy-rounded/settings.svg"); }
.ui-icon-menu { -webkit-mask-image: url("icons/sandy-rounded/menu.svg"); mask-image: url("icons/sandy-rounded/menu.svg"); }
.ui-icon-close { -webkit-mask-image: url("icons/sandy-rounded/close.svg"); mask-image: url("icons/sandy-rounded/close.svg"); }
.ui-icon-grammar { -webkit-mask-image: url("icons/sandy-rounded/grammar.svg"); mask-image: url("icons/sandy-rounded/grammar.svg"); }
.ui-icon-frequent { -webkit-mask-image: url("icons/sandy-rounded/frequent.svg"); mask-image: url("icons/sandy-rounded/frequent.svg"); }
.ui-icon-adverbs { -webkit-mask-image: url("icons/sandy-rounded/adverbs.svg"); mask-image: url("icons/sandy-rounded/adverbs.svg"); }
.ui-icon-comprehensive { -webkit-mask-image: url("icons/sandy-rounded/comprehensive.svg"); mask-image: url("icons/sandy-rounded/comprehensive.svg"); }
.ui-icon-write { -webkit-mask-image: url("icons/sandy-rounded/write.svg"); mask-image: url("icons/sandy-rounded/write.svg"); }
.ui-icon-contact { -webkit-mask-image: url("icons/sandy-rounded/contact.svg"); mask-image: url("icons/sandy-rounded/contact.svg"); }
.ui-icon-about { -webkit-mask-image: url("icons/sandy-rounded/about.svg"); mask-image: url("icons/sandy-rounded/about.svg"); }
.ui-icon-support { -webkit-mask-image: url("icons/sandy-rounded/support.svg"); mask-image: url("icons/sandy-rounded/support.svg"); }
.ui-icon-share { -webkit-mask-image: url("icons/sandy-rounded/share.svg"); mask-image: url("icons/sandy-rounded/share.svg"); }
.ui-icon-account { -webkit-mask-image: url("icons/sandy-rounded/account.svg"); mask-image: url("icons/sandy-rounded/account.svg"); }
.ui-icon-sidebar-close { -webkit-mask-image: url("icons/sandy-rounded/sidebar-close.svg"); mask-image: url("icons/sandy-rounded/sidebar-close.svg"); }
.ui-icon-play { -webkit-mask-image: url("icons/sandy-rounded/play.svg"); mask-image: url("icons/sandy-rounded/play.svg"); }
.ui-icon-pause { -webkit-mask-image: url("icons/sandy-rounded/pause.svg"); mask-image: url("icons/sandy-rounded/pause.svg"); }
.ui-icon-sidebar-open { -webkit-mask-image: url("icons/sandy-rounded/sidebar-open.svg"); mask-image: url("icons/sandy-rounded/sidebar-open.svg"); }

/* ☆ / ★ favourite toggles (list pages, AI match chips): the state lives on the button's aria-pressed, so scripts only
   write the icon once. Saved = filled star in the AA accent; unsaved = outline in --muted (both ≥3:1 for UI). */
.ui-icon-favorite-filled,
[aria-pressed="true"] > .ui-icon-favorite { -webkit-mask-image: url("icons/sandy-rounded/favorite-filled.svg"); mask-image: url("icons/sandy-rounded/favorite-filled.svg"); }

/* Sandy's room objects, used by her dock buttons (assets/sandy.js) and matching Today's room: the lamp is her sleep
   switch, the fridge her snacks. Lit lamp = .is-lit (three short rays, a shape cue, not colour alone) plus a warm glow
   layer inside the shade in --color-accent-deco (decorative), stacked in .ui-lamp. The lamp is a desk lamp; the fridge
   always stays closed (an open one read awkwardly at 22px). */
.ui-icon-lamp { -webkit-mask-image: url("icons/sandy-rounded/lamp.svg"); mask-image: url("icons/sandy-rounded/lamp.svg"); }
.ui-icon-lamp.is-lit { -webkit-mask-image: url("icons/sandy-rounded/lamp-on.svg"); mask-image: url("icons/sandy-rounded/lamp-on.svg"); }
.ui-icon-lamp-glow { background-color: var(--color-accent-deco, #e39a63); -webkit-mask-image: url("icons/sandy-rounded/lamp-glow.svg"); mask-image: url("icons/sandy-rounded/lamp-glow.svg"); }
.ui-lamp { display: inline-grid; flex-shrink: 0; }
.ui-lamp > .ui-icon { grid-area: 1 / 1; }
/* Sleep toggle in the dock (owner, 2026-10-12: Today's lamp is just the light now, so her sleep button is a moon):
   awake = a thin outline moon; asleep = the same moon filled with a soft warm fill (--color-accent-deco, decorative)
   under the outline, stacked in .ui-moon. The fill is a shape cue as well as colour (solid vs hollow). */
.ui-icon-moon { -webkit-mask-image: url("icons/sandy-rounded/moon.svg"); mask-image: url("icons/sandy-rounded/moon.svg"); }
.ui-icon-moon-fill { background-color: var(--color-accent-deco, #e39a63); -webkit-mask-image: url("icons/sandy-rounded/moon-fill.svg"); mask-image: url("icons/sandy-rounded/moon-fill.svg"); }
.ui-moon { display: inline-grid; flex-shrink: 0; }
.ui-moon > .ui-icon { grid-area: 1 / 1; }
.ui-icon-fridge { -webkit-mask-image: url("icons/sandy-rounded/fridge.svg"); mask-image: url("icons/sandy-rounded/fridge.svg"); }
@media (forced-colors: active) { .ui-icon-lamp-glow { display: none; } .ui-icon-moon-fill { background-color: CanvasText; } }

/* an icon before a short label in a plain (non-flex) button, e.g. 语音：开 / 关 */
.ui-icon-lead { margin-inline-end: .35em; }

/* Functional controls share the menu's 24px grid, 1.65 stroke and round ends.
   Use the same masks for inline status marks and standalone buttons. */
.ui-icon-search { -webkit-mask-image: url("icons/sandy-rounded/search.svg"); mask-image: url("icons/sandy-rounded/search.svg"); }
.ui-icon-eye { -webkit-mask-image: url("icons/sandy-rounded/eye.svg"); mask-image: url("icons/sandy-rounded/eye.svg"); }
.ui-icon-eye-off { -webkit-mask-image: url("icons/sandy-rounded/eye-off.svg"); mask-image: url("icons/sandy-rounded/eye-off.svg"); }
.ui-icon-check { -webkit-mask-image: url("icons/sandy-rounded/check.svg"); mask-image: url("icons/sandy-rounded/check.svg"); }
.ui-icon-hint { -webkit-mask-image: url("icons/sandy-rounded/hint.svg"); mask-image: url("icons/sandy-rounded/hint.svg"); }
.ui-icon-privacy { -webkit-mask-image: url("icons/sandy-rounded/privacy.svg"); mask-image: url("icons/sandy-rounded/privacy.svg"); }
.sidebar-card-title .ui-icon { width: 16px; height: 16px; margin-inline-end: 4px; }
.mark .ui-icon { width: 16px; height: 16px; margin-inline-end: 4px; }
.ui-icon-status { width: 16px; height: 16px; }
.fb-label .ui-icon-status { margin-inline-end: 4px; }
.answer-mark .ui-icon { display: block; }
.search-box .ui-icon-search { width: 18px; height: 18px; }
.ui-action-icon { display: inline-flex; align-items: center; gap: 6px; }
.ui-action-icon::before { content: ""; flex: 0 0 20px; width: 20px; height: 20px; background-color: currentColor; -webkit-mask: url("icons/sandy-rounded/play.svg") center / contain no-repeat; mask: url("icons/sandy-rounded/play.svg") center / contain no-repeat; }
.answers .answer::before { content: ""; display: inline-block; width: 16px; height: 16px; margin-inline-end: 5px; vertical-align: -.2em; background-color: currentColor; }
.answers .answer.correct::before { -webkit-mask: url("icons/sandy-rounded/check.svg") center / contain no-repeat; mask: url("icons/sandy-rounded/check.svg") center / contain no-repeat; }
.answers .answer.wrong::before { -webkit-mask: url("icons/sandy-rounded/close.svg") center / contain no-repeat; mask: url("icons/sandy-rounded/close.svg") center / contain no-repeat; }
